No OneTemporary

File Metadata

Created
Sat, Apr 20, 12:16 AM
This file is larger than 256 KB, so syntax highlighting was skipped.
diff --git a/.arcconfig b/.arcconfig
new file mode 100644
index 000000000..45e5d4710
--- /dev/null
+++ b/.arcconfig
@@ -0,0 +1,4 @@
+{
+ "phabricator.uri": "https://phabricator.kde.org/",
+ "project.name": "GCompris"
+}
diff --git a/.gitignore b/.gitignore
index 2606c91dd..1d905bb88 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,9 +1,12 @@
CMakeLists.txt.user
GCompris.pro.user
.directory
*.aac
*.qrc
+*.qmlc
+*.jsc
+*~
build/*
*.DS_Store
src/activities/activities_out.txt
po
diff --git a/.reviewboardrc b/.reviewboardrc
deleted file mode 100644
index 867c1a7ac..000000000
--- a/.reviewboardrc
+++ /dev/null
@@ -1,3 +0,0 @@
-REPOSITORY = "git://anongit.kde.org/gcompris"
-REVIEWBOARD_URL = "https://git.reviewboard.kde.org"
-TARGET_GROUPS = "kdeedu"
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b767910f1..dd1013320 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,487 +1,416 @@
cmake_minimum_required(VERSION 2.8.12)
cmake_policy(SET CMP0043 NEW)
project(gcompris-qt C CXX)
# get all the redist dll needed for windows when compiling with vc
set(CMAKE_INSTALL_UCRT_LIBRARIES 1)
include(InstallRequiredSystemLibraries)
# Set c++11 support
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
if(COMPILER_SUPPORTS_CXX11)
set(my_cxx_flags "-std=c++11")
elseif(COMPILER_SUPPORTS_CXX0X)
set(my_cxx_flags "-std=c++0x")
else()
message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${my_cxx_flags}")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${my_cxx_flags}")
# enable qml debugging for DEBUG builds:
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DQT_QML_DEBUG")
set(GCOMPRIS_MAJOR_VERSION 0)
-set(GCOMPRIS_MINOR_VERSION 95)
+set(GCOMPRIS_MINOR_VERSION 98)
set(GCOMPRIS_PATCH_VERSION 0)
# Set the BUILD_DATE
-string(TIMESTAMP BUILD_DATE %Y%M)
+string(TIMESTAMP BUILD_DATE %Y%m)
# cmake modules setup
find_package(ECM 1.4.0 QUIET NO_MODULE)
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR} ${CMAKE_SOURCE_DIR}/cmake/)
set(CMAKE_PREFIX_PATH "${Qt5_DIR}/lib/cmake/Qt5")
# KDE po to qm tools
if(ECM_FOUND)
+ include(kdeFetchTranslation)
include(ECMAddTests)
include(ECMPoQmTools)
if (IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/po")
ecm_install_po_files_as_qm(po)
endif()
option(BUILD_TESTING "Build and enable unit tests" OFF)
include(ECMCoverageOption)
endif(ECM_FOUND)
+# add tools (cppcheck, clang-tidy...) if build on testing mode only
+# (slower compilation)
+if(BUILD_TESTING)
+ include(CodeQualityUtils)
+endif()
+
+set(QT_REQUIRED_VERSION 5.6.0)
+
if(CMAKE_SYSTEM_NAME STREQUAL Android)
find_package(ECM)
set(ANDROID 1)
# TODO: possibly should be setup by toolchain one day
set(QT_QMAKE_EXECUTABLE "${_qt5Core_install_prefix}/bin/qmake")
+ if(ECM_VERSION VERSION_GREATER "5.55.0")
+ set(QT_REQUIRED_VERSION 5.12.0)
+ endif()
+
# workaround until this fix is in released ECM
if(ECM_VERSION VERSION_LESS "5.15.0")
add_definitions(-DANDROID)
endif()
endif()
# Set executable filename
if(ANDROID)
set(GCOMPRIS_EXECUTABLE_NAME GCompris)
- if("${ANDROID_ARCHITECTURE}" STREQUAL "x86")
- # We always want x86 to be a release above to arm one because the play
- # store want x86 to be pushed after arm.
- MATH(EXPR GCOMPRIS_MINOR_VERSION "${GCOMPRIS_MINOR_VERSION}+1")
- endif("${ANDROID_ARCHITECTURE}" STREQUAL "x86")
elseif(SAILFISHOS)
set(GCOMPRIS_EXECUTABLE_NAME harbour-gcompris-qt)
elseif(WIN32)
set(GCOMPRIS_EXECUTABLE_NAME GCompris)
else()
set(GCOMPRIS_EXECUTABLE_NAME gcompris-qt)
endif()
set(GCOMPRIS_VERSION ${GCOMPRIS_MAJOR_VERSION}.${GCOMPRIS_MINOR_VERSION})
# An integer value that represents the version of the application
# Increase it at each release
math(EXPR GCOMPRIS_VERSION_CODE "${GCOMPRIS_MAJOR_VERSION}*10000 + ${GCOMPRIS_MINOR_VERSION}*100 + ${GCOMPRIS_PATCH_VERSION}")
# prevent build in source directory
if("${CMAKE_BINARY_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}")
message(SEND_ERROR "Building in the source directory is not supported.")
message(FATAL_ERROR "Please remove the created \"CMakeCache.txt\" file, the \"CMakeFiles\"
directory and create a build directory and call \"${CMAKE_COMMAND} <path to the sources>\".")
endif("${CMAKE_BINARY_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}")
-set(QT_REQUIRED_VERSION 5.6.0)
-
find_package(Qt5 ${QT_REQUIRED_VERSION} REQUIRED
- Qml Quick Gui Multimedia Core Svg Xml XmlPatterns LinguistTools Sensors)
-
+ Qml Quick Gui Multimedia Core Svg Xml XmlPatterns LinguistTools Sensors)
+
if(ANDROID)
find_package(Qt5 ${QT_REQUIRED_VERSION} REQUIRED AndroidExtras)
endif(ANDROID)
if(SAILFISHOS)
find_package(Qt5 ${QT_REQUIRED_VERSION} REQUIRED Widgets)
endif(SAILFISHOS)
+## For now we workaround CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION to clang with a command variable, so not needed
+# if(ANDROID AND ECM_VERSION VERSION_LESS "5.56.0" AND Qt5Core_VERSION VERSION_GREATER "5.11.99")
+# message(FATAL_ERROR "ECM ${ECM_VERSION} not compatible with Qt ${Qt5Core_VERSION} version for android.")
+# endif()
+
+if((UNIX AND NOT APPLE AND NOT SAILFISHOS AND NOT ANDROID) OR WIN32)
+ find_package(OpenSSL REQUIRED)
+endif()
+
find_package (KF5 QUIET COMPONENTS
DocTools
)
if(ECM_FOUND)
include(KDEInstallDirs)
if(ECM_VERSION VERSION_GREATER "1.6.0")
add_subdirectory(images)
install(FILES org.kde.gcompris.appdata.xml DESTINATION ${KDE_INSTALL_METAINFODIR})
install(FILES org.kde.gcompris.desktop DESTINATION ${KDE_INSTALL_APPDIR})
else()
message(STATUS "ECM_VERSION is ${ECM_VERSION}, icons and desktop files won't be installed.")
endif()
endif()
# Tell CMake to run moc when necessary:
set(CMAKE_AUTOMOC ON)
# As moc files are generated in the binary dir, tell CMake
# to always look for includes there:
set(CMAKE_INCLUDE_CURRENT_DIR ON)
#get_cmake_property(_variableNames VARIABLES)
#foreach (_variableName ${_variableNames})
# message("${_variableName}=${${_variableName}}")
#endforeach()
set(ACTIVATION_MODE "no" CACHE STRING "Policy for activation [no|inapp|internal]")
option(WITH_DEMO_ONLY "Include only demo activities" OFF)
option(WITH_DOWNLOAD "Internal download" ON)
# @FIXME These permissions should be removed if download is disable
# but it makes the application crash on exit (tested on Android 6)
set(ANDROID_INTERNET_PERMISSION "<uses-permission android:name=\"android.permission.INTERNET\" />")
set(ANDROID_ACCESS_NETWORK_STATE_PERMISSION "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\" />")
set(GRAPHICAL_RENDERER "auto" CACHE STRING "Policy for choosing the renderer backend [opengl|software|auto]")
# Set output directory
if(CMAKE_HOST_APPLE)
set(_bundle_bin gcompris-qt.app/Contents/MacOS)
set(_data_dest_dir bin/${_bundle_bin}/../Resources)
-elseif(ANDROID)
- set(_data_dest_dir android/assets)
else()
set(_data_dest_dir share/${GCOMPRIS_EXECUTABLE_NAME})
endif()
if(ANDROID)
# Android .so output
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/android/libs/${ANDROID_ABI}/)
set(GCOMPRIS_TRANSLATIONS_DIR ${CMAKE_BINARY_DIR}/${_data_dest_dir} CACHE INTERNAL "" FORCE)
- set(GCOMPRIS_RCC_DIR ${CMAKE_BINARY_DIR}/${_data_dest_dir} CACHE INTERNAL "" FORCE)
+ set(GCOMPRIS_RCC_DIR ${CMAKE_BINARY_DIR}/android/assets/${_data_dest_dir}/rcc CACHE INTERNAL "" FORCE)
if(ACTIVATION_MODE STREQUAL "inapp")
set(ANDROID_BILLING_PERMISSION "<uses-permission android:name=\"com.android.vending.BILLING\"/>")
set(ANDROID_PACKAGE "net.gcompris")
else(ACTIVATION_MODE)
set(ANDROID_PACKAGE "net.gcompris.full")
endif()
add_subdirectory(android)
elseif(CMAKE_HOST_APPLE)
# MacOSX build
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(GCOMPRIS_TRANSLATIONS_DIR ${CMAKE_BINARY_DIR}/${_data_dest_dir}/translations CACHE INTERNAL "" FORCE)
set(GCOMPRIS_RCC_DIR ${CMAKE_BINARY_DIR}/${_data_dest_dir}/rcc CACHE INTERNAL "" FORCE)
else()
# Desktop build
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(GCOMPRIS_TRANSLATIONS_DIR ${CMAKE_BINARY_DIR}/${_data_dest_dir}/translations CACHE INTERNAL "" FORCE)
set(GCOMPRIS_RCC_DIR ${CMAKE_BINARY_DIR}/${_data_dest_dir}/rcc CACHE INTERNAL "" FORCE)
endif(ANDROID)
# Always create these folders
add_custom_command(
OUTPUT shareFolders
COMMAND cmake -E make_directory ${GCOMPRIS_TRANSLATIONS_DIR}
COMMAND cmake -E make_directory ${GCOMPRIS_RCC_DIR}
)
add_custom_target(
createShareFolders ALL
DEPENDS shareFolders
)
include(cmake/rcc.cmake)
# Translations handling
# Simple command calling the python script
add_custom_command(
OUTPUT retrievePoFilesFromSvn
COMMAND python2 tools/l10n-fetch-po-files.py
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
# Install translations
add_custom_target(getSvnTranslations
DEPENDS retrievePoFilesFromSvn
COMMENT "Re-run cmake after this to be able to run BuildTranslations with the latest files"
)
# Get all po files in po/. You can get them doing: python2 tools/l10n-fetch-po-files.py
file(GLOB TRANSLATIONS_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "po/*.po")
# Set the output dir for the translation files to /bin
foreach(PoSource ${TRANSLATIONS_FILES})
# Changes the .po extension to .ts
string(REPLACE ".po" ".ts" TsSource ${PoSource})
# Removes the po/ folder
string(REPLACE "po/" "" TsSource ${TsSource})
# qm filename
string(REPLACE ".ts" ".qm" QmOutput ${TsSource})
set(OutTsFile ${CMAKE_BINARY_DIR}/tmp/${TsSource})
add_custom_command(
OUTPUT ${QmOutput}
COMMAND cmake -E make_directory ${GCOMPRIS_TRANSLATIONS_DIR}
COMMAND cmake -E make_directory ${CMAKE_BINARY_DIR}/tmp
# Remove the obsolete translations and set po in the ts output file
COMMAND msgattrib --no-obsolete ${CMAKE_CURRENT_SOURCE_DIR}/${PoSource} -o ${OutTsFile}
# Convert the po into ts
COMMAND Qt5::lconvert -if po -of ts -i ${OutTsFile} -o ${OutTsFile}
# Convert the ts in qm removing non finished translations
COMMAND Qt5::lrelease -compress -nounfinished ${OutTsFile} -qm ${GCOMPRIS_TRANSLATIONS_DIR}/${QmOutput}
)
list(APPEND QM_FILES ${QmOutput})
endforeach()
# Install translations
if (WIN32)
add_custom_target(BuildTranslations
DEPENDS ${QM_FILES}
COMMENT "If you don't have the .po, you need to run make getSvnTranslations first then re-run cmake"
)
else()
add_custom_target(BuildTranslations ALL
DEPENDS ${QM_FILES}
COMMENT "If you don't have the .po, you need to run make getSvnTranslations first then re-run cmake"
)
endif()
add_custom_command(
OUTPUT doBundleTranslations
COMMAND 7z a -w${CMAKE_BINARY_DIR}/share/${GCOMPRIS_EXECUTABLE_NAME}
${CMAKE_BINARY_DIR}/translations-${GCOMPRIS_VERSION}.7z
${CMAKE_BINARY_DIR}/share/${GCOMPRIS_EXECUTABLE_NAME}/translations
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
# Bundle translations
add_custom_target(BundleTranslations
DEPENDS doBundleTranslations
COMMENT "If you want to provide a zip of the translations on a server (run make BuildTranslations first)"
)
add_custom_command(
OUTPUT doDlAndInstallBundledTranslations
COMMAND curl -fsS -o translations-${GCOMPRIS_VERSION}.7z
http://gcompris.net/download/translations-${GCOMPRIS_VERSION}.7z
COMMAND 7z x -y -o${CMAKE_BINARY_DIR}/share/${GCOMPRIS_EXECUTABLE_NAME}
translations-${GCOMPRIS_VERSION}.7z
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)
# Download and install bundled translations
add_custom_target(DlAndInstallBundledTranslations
DEPENDS doDlAndInstallBundledTranslations
COMMENT "Download the bundled translation and install them in the build dir"
)
if(CMAKE_HOST_APPLE)
install(DIRECTORY ${GCOMPRIS_TRANSLATIONS_DIR} DESTINATION ${_bundle_bin})
+elseif(ANDROID)
+ install(DIRECTORY ${GCOMPRIS_TRANSLATIONS_DIR} DESTINATION "share")
else()
install(DIRECTORY ${GCOMPRIS_TRANSLATIONS_DIR} DESTINATION ${_data_dest_dir})
endif()
# Build standalone package option -> if ON, we will copy the required Qt files in the build package.
# If OFF, "make install" will not copy Qt files so only GCompris files will be packaged.
# By default, it is true on Windows (as we deliver NSIS package), macOS (bundled), android (apk) and false on linux (to do make install)
# If you want to create a STGZ package for linux (auto-extractible), override this variable by typing : cmake -DBUILD_STANDALONE=ON
if(UNIX AND NOT ANDROID AND NOT APPLE)
option(BUILD_STANDALONE "Build a standalone package when typing 'make package'" OFF)
else()
option(BUILD_STANDALONE "Build a standalone package when typing 'make package'" ON)
endif()
option(WITH_KIOSK_MODE "Set the kiosk mode by default" OFF)
if(WIN32)
set(COMPRESSED_AUDIO "mp3" CACHE STRING "Compressed Audio format [ogg|aac|mp3]")
elseif(APPLE)
set(COMPRESSED_AUDIO "aac" CACHE STRING "Compressed Audio format [ogg|aac|mp3]")
else()
set(COMPRESSED_AUDIO "ogg" CACHE STRING "Compressed Audio format [ogg|aac|mp3]")
endif()
file(GLOB_RECURSE OGG_FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/ "*.ogg")
foreach(OGG_FILE ${OGG_FILES})
# This should only replace the extension
string(REGEX REPLACE "ogg$" "aac" AAC_FILE ${OGG_FILE})
add_custom_command(
OUTPUT ${AAC_FILE}
# Put the good line depending on your installation
COMMAND avconv -v warning -i ${OGG_FILE} -acodec libvo_aacenc ${AAC_FILE}
#COMMAND ffmpeg -v warning -i ${OGG_FILE} -acodec aac -strict -2 ${AAC_FILE}
)
list(APPEND AAC_FILES ${AAC_FILE})
# This should only replace the extension
string(REGEX REPLACE "ogg$" "mp3" MP3_FILE ${OGG_FILE})
add_custom_command(
OUTPUT ${MP3_FILE}
# Put the good line depending on your installation
#COMMAND avconv -v warning -i ${OGG_FILE} -acodec mp3 ${MP3_FILE}
COMMAND ffmpeg -v warning -i ${OGG_FILE} -acodec mp3 -strict -2 ${MP3_FILE}
)
list(APPEND MP3_FILES ${MP3_FILE})
endforeach()
add_custom_target(
createAacFromOgg
DEPENDS ${AAC_FILES}
)
add_custom_target(
createMp3FromOgg
DEPENDS ${MP3_FILES}
)
# predownload assets (voices and images) and install them in the rcc folder
set(DOWNLOAD_ASSETS "" CACHE STRING "Download and packages images and voices. use a list like: words,en,fr,pt_BR to retrieve multiple files")
add_custom_command(
OUTPUT predownloadAssets
- COMMAND python2 tools/download-assets.py ${DOWNLOAD_ASSETS} ${COMPRESSED_AUDIO} ${GCOMPRIS_RCC_DIR}
+ COMMAND python tools/download-assets.py ${DOWNLOAD_ASSETS} ${COMPRESSED_AUDIO} ${GCOMPRIS_RCC_DIR}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
add_custom_command(
OUTPUT assetsFolders
COMMAND cmake -E make_directory "${GCOMPRIS_RCC_DIR}/data2"
COMMAND cmake -E make_directory "${GCOMPRIS_RCC_DIR}/data2/voices-${COMPRESSED_AUDIO}"
COMMAND cmake -E make_directory "${GCOMPRIS_RCC_DIR}/data2/words"
)
# Install assets
add_custom_target(getAssets
DEPENDS assetsFolders predownloadAssets
)
add_custom_command(
OUTPUT doBundleConvertedOggs
COMMAND 7z a converted_ogg_to_${COMPRESSED_AUDIO}-${GCOMPRIS_VERSION}.7z '-ir!src/*${COMPRESSED_AUDIO}'
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
# Bundle oggs ready to be uploaded on a server. This ease build on system without the appropriate audio
# convertion tools.
add_custom_target(BundleConvertedOggs
DEPENDS doBundleConvertedOggs
COMMENT "Bundle the converted oggs to upload them on a server. First set COMPRESSED_AUDIO appropriately."
)
add_custom_command(
OUTPUT doDlAndInstallBundledConvertedOggs
COMMAND curl -fsS -o converted_ogg_to_${COMPRESSED_AUDIO}-${GCOMPRIS_VERSION}.7z
http://gcompris.net/download/converted_ogg_to_${COMPRESSED_AUDIO}-${GCOMPRIS_VERSION}.7z
COMMAND 7z x -y converted_ogg_to_${COMPRESSED_AUDIO}-${GCOMPRIS_VERSION}.7z
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
)
# Download and install bundled converted oggs
add_custom_target(DlAndInstallBundledConvertedOggs
DEPENDS doDlAndInstallBundledConvertedOggs
COMMENT "Download the bundled converted oggs and install them in the source dir"
)
set(ARCHIVE_NAME ${CMAKE_PROJECT_NAME}-${GCOMPRIS_VERSION})
add_custom_target(dist
COMMAND git archive --prefix=${ARCHIVE_NAME}/ HEAD
| xz > ${CMAKE_BINARY_DIR}/${ARCHIVE_NAME}.tar.xz
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
if(KF5_FOUND)
add_subdirectory(docs/docbook)
endif(KF5_FOUND)
-#
# qml-box2d
-#
-
-set(QML_BOX2D_MODULE "auto" CACHE STRING "Policy for qml-box2d module [auto|submodule|system|disabled]")
-
-if (${QML_BOX2D_MODULE} STREQUAL "disabled")
- # disable all activities depending on qml-box2d
- set(_disabled_activities "balancebox,land_safe,submarine")
- message(STATUS "Disabling qml-box2d module and depending activities: ${_disabled_activities}")
-else()
- include(qt_helper)
-
- getQtQmlPath(_qt_qml_system_path)
- set (_box2d_system_dir "${_qt_qml_system_path}/Box2D.2.0")
-
- if (${QML_BOX2D_MODULE} STREQUAL "submodule")
- message(STATUS "Building qml-box2d module from submodule")
- set(_need_box2d_submodule "TRUE")
- else()
- # try to find module in system scope
- find_library(QML_BOX2D_LIBRARY NAMES Box2D libBox2D PATHS ${_box2d_system_dir} NO_DEFAULT_PATH)
- if (QML_BOX2D_LIBRARY)
- message(STATUS "Using system qml-box2d plugin at ${QML_BOX2D_LIBRARY}")
- # for packaging builds, copy the module manually to the correct location
- if(SAILFISHOS)
- file(COPY ${_box2d_system_dir}/qmldir ${QML_BOX2D_LIBRARY} DESTINATION share/harbour-gcompris-qt/lib/qml/Box2D.2.0)
- elseif(ANDROID)
- file(COPY ${_box2d_system_dir}/qmldir ${QML_BOX2D_LIBRARY} DESTINATION lib/qml/Box2D.2.0)
- endif()
- # FIXME: add others as needed
- else()
- if (${QML_BOX2D_MODULE} STREQUAL "auto")
- message(STATUS "Did not find the qml-box2d module in system scope, falling back to submodule build ...")
- set (_need_box2d_submodule "TRUE")
- else()
- message(FATAL_ERROR "Did not find the qml-box2d module in system scope and submodule build was not requested. Can't continue!")
- endif()
- endif()
- endif()
-
- if (_need_box2d_submodule)
- # build qml-box2d ourselves from submodule
- include(ExternalProject)
- get_property(_qmake_program TARGET ${Qt5Core_QMAKE_EXECUTABLE} PROPERTY IMPORT_LOCATION)
- set (_box2d_source_dir ${CMAKE_CURRENT_SOURCE_DIR}/external/qml-box2d)
- if(WIN32)
- set (_box2d_library_dir "release/")
- set (_box2d_library_file "Box2D.dll")
- elseif(CMAKE_HOST_APPLE)
- set (_box2d_library_dir "")
- set (_box2d_library_file "libBox2D.dylib")
- else()
- set (_box2d_library_dir "")
- set (_box2d_library_file "libBox2D.so")
- endif()
- set (_box2d_install_dir ${CMAKE_CURRENT_BINARY_DIR}/lib/qml/Box2D.2.0)
- # make sure submodule is up2date
- find_package(Git)
- if(GIT_FOUND)
- execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init)
- endif()
-
- # for visual studio, we need to create a vcxproj
- if(WIN32 AND NOT MINGW)
- set(_qmake_options -spec win32-msvc -tp vc)
- else()
- set(_qmake_options "")
- endif()
- ExternalProject_Add(qml_box2d
- DOWNLOAD_COMMAND ""
- SOURCE_DIR ${_box2d_source_dir}
- CONFIGURE_COMMAND ${_qmake_program} ${_qmake_options} ${_box2d_source_dir}/box2d.pro
- BUILD_COMMAND ${CMAKE_MAKE_PROGRAM}
- INSTALL_DIR ${_box2d_install_dir}
- INSTALL_COMMAND cp ${_box2d_library_dir}${_box2d_library_file} ${_box2d_source_dir}/qmldir ${_box2d_install_dir}
- )
-
- add_library(qml-box2d SHARED IMPORTED)
- set_target_properties(qml-box2d PROPERTIES IMPORTED_LOCATION ${_box2d_install_dir}/${_box2d_library_file})
-
- if(SAILFISHOS)
- install(DIRECTORY ${_box2d_install_dir} DESTINATION share/harbour-gcompris-qt/lib/qml)
- else()
- install(DIRECTORY ${_box2d_install_dir} DESTINATION lib/qml)
- endif()
- endif()
-endif()
+include(cmake/box2d.cmake)
add_subdirectory(src)
if(SAILFISHOS)
# Need to be done at the end, after src
add_subdirectory(platforms/sailfishOS)
endif()
# only enable unit tests for linux
if(BUILD_TESTING)
enable_testing()
add_subdirectory(tests)
endif(BUILD_TESTING)
add_custom_target(binaries)
add_dependencies(binaries ${GCOMPRIS_EXECUTABLE_NAME} rcc_core rcc_menu rcc_activities all_activities)
diff --git a/COPYING b/COPYING
index 94a9ed024..e60008693 100644
--- a/COPYING
+++ b/COPYING
@@ -1,674 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
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.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can 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 <http://www.gnu.org/licenses/>.
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
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:
<program> Copyright (C) <year> <name of author>
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
-<http://www.gnu.org/licenses/>.
+<https://www.gnu.org/licenses/>.
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
-<http://www.gnu.org/philosophy/why-not-lgpl.html>.
+<https://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/HACKING b/HACKING
index 6dda4b141..718df48f0 100644
--- a/HACKING
+++ b/HACKING
@@ -1,80 +1,80 @@
GCompris HACKING
Official repository
-------------------
The official repository requires a KDE developer account, we will ask regular
contributors to get an account and work on the KDE repository.
https://cgit.kde.org/gcompris.git
For new developers and those interested only in smaller contributions use the
https://phabricator.kde.org/ or GitHub repository.
Source code from GitHub
-----------------------
Checkout the source code by cloning it from GitHub
git clone git://github.com/gcompris/GCompris-qt.git
If you want to have a personal fork, in order to commit occasional patches,
fork it on GitHub then clone your fork
git clone git@github.com:<username>/GCompris-qt.git
When asking for a pull request, create a new topic branch and commit your
changes there then open a pull request to gcompris-qt repository on GitHub.
See GitHub's documentation for more information.
https://help.github.com/categories/collaborating/
Dependencies
------------
In order to be able to compile GCompris the following Qt5 dependencies need to
be installed
Qt 5 Development Defaults
Qt 5 qmake
Qt Creator
Qt Linguist Tools
Qt Core
Qt Graphical Effects QML Module
Qt Gui
Qt Multimedia
Qt Multimedia QML Module
Qt Network
Qt Qml
Qt Quick
Qt Svg
Qt Xml
Qt XmlPatterns
Installing dependencies on a Debian based systems can be done like this:
sudo aptitude install libqt5svg5-dev libqt5xmlpatterns5-dev \
qml-module-qtmultimedia qt5-default \
qml-module-qtgraphicaleffects qt5-qmake qtcreator \
qtdeclarative5-dev qtdeclarative5-dev \
qtmultimedia5-dev qtquick1-5-dev qttools5-dev \
qttools5-dev-tools libqt5multimedia5-plugins \
qml-module-qtsensors libqt5quickparticles5 \
qml-module-qtquick2 qml-module-qtquick-particles2 \
libqt5sensors5-dev libqt5sensors5
To build for Android, Qt 5 AndroidExtras also needs to be installed.
Build
-----
Start QtCreator and select Open Project and open CMakeLists.txt in the
gcompris-qt root directory. Follow the wizard instructions.
Use the buttons on the lower left side to build, run, and debug GCompris.
More Details
------------
Go To this Link:
- http://gcompris.net/wiki/Qt_Quick_development_process
+ https://gcompris.net/wiki/Qt_Quick_development_process
diff --git a/README b/README
index 8c1506519..f654b33e3 100644
--- a/README
+++ b/README
@@ -1,54 +1,54 @@
GCompris / I Got IT
GCompris is a GNU package
- http://gcompris.net
+ https://gcompris.net
GCompris is a high quality educational software suite, including a large
number of activities for children aged 2 to 10. Some of the activities
are game orientated, but nonetheless still educational.
Currently GCompris offers in excess of 100 activities and more are
being developed. GCompris is free software, that means that you can
adapt it to your own needs, improve it and, most importantly, share it
with children everywhere.
This version is a full rewrite of GCompris using the QtQuick technology.
-------------------------------------------------------------------------------
GCompris MOTIVATION
Big Issue:
There are many simple activities dedicated to children on any
platforms, desktops, web and tablets. When they exist, they are hard
to find and request the teacher/parent to manage a lot of
independant small tools.
Big Goal:
Build an educational game suite all accessible from a single user interface.
GCompris provides a simple to use user interface that makes it easy to select
appropriate activities.
How:
GCompris is designed in a way that it is easy to add new activities to it.
The activity is free to implement the game scheme it wants.
The status bar is a common facility provided to the activities.
GCompris provides some tools to let teacher/educator to easily add
activities to GCompris.
About You:
Yes you can help by:
Creating new activities.
Providing fancy graphics to incorporate as icons or backgrounds.
Translate GCompris.
Just giving your ideas.
-------------------------------------------------------------------------------
NOTE TO TRANSLATORS
You will get all the information to translate GCompris or to provide
voices on our developers wiki:
-http://gcompris.net/wiki/Developer%27s_corner
+https://gcompris.net/wiki/Developer%27s_corner
diff --git a/README.rst b/README.rst
index 2000cd7f0..2a44be750 100644
--- a/README.rst
+++ b/README.rst
@@ -1,62 +1,62 @@
*********************************
-`GCompris <http://gcompris.net>`_
+`GCompris <https://gcompris.net>`_
*********************************
.. image:: src/core/resource/gcompris.png
Presentation
============
-`GCompris <http://gcompris.net>`_ is a high quality educational software suite,
+`GCompris <https://gcompris.net>`_ is a high quality educational software suite,
including a large number of activities for children aged 2 to 10.
Some of the activities are game orientated, but nonetheless still educational.
Currently GCompris offers in excess of 100 activities and more are being
developed. GCompris is free software, that means that you can use it as you
wish, adapt it to your own needs, improve it, and, most importantly, share it
with everyone.
This version is a full rewrite of GCompris using the QtQuick technology. It is
developed within the `KDE community <https://www.kde.org>`_ and is part of the
`GNU Project <https://www.gnu.org/education/edu-software-gcompris.en.html>`_.
Goal
====
There are many simple activities dedicated to children on any platforms,
desktops, web and tablets. When they exist, they are hard to find and request
the teacher or parent to manage a lot of independant small tools.
GCompris is an educational suite of activities all accessible from a
single unified user interface.
How
===
GCompris is designed in a way that it is easy to add new activities to it. The
activity is free to implement the game scheme it wants. The status bar is a
common facility provided to the activities.
GCompris provides some tools to let teacher/educator to easily add activities
to GCompris.
About You
=========
You can help by:
-* `Creating new activities <http://gcompris.net/wiki/Qt_Quick_development_process>`_.
+* `Creating new activities <https://gcompris.net/wiki/Qt_Quick_development_process>`_.
* Providing fancy graphics to incorporate as icons or backgrounds.
* `Translating GCompris
- <http://gcompris.net/wiki/Developer%27s_corner#Translation>`_.
-* `Recording voices <http://gcompris.net/wiki/Voice_translation_Qt>`_.
+ <https://gcompris.net/wiki/Developer%27s_corner#Translation>`_.
+* `Recording voices <https://gcompris.net/wiki/Voice_translation_Qt>`_.
* `Just giving your ideas
- <http://gcompris.net/wiki/Ideas_for_activities>`_.
+ <https://gcompris.net/wiki/Ideas_for_activities>`_.
Get more information on our `developer's wiki
-<http://gcompris.net/wiki/Developer%27s_corner>`_.
+<https://gcompris.net/wiki/Developer%27s_corner>`_.
Licence
=======
GCompris is free software released under the `GPL V3+
-<http://www.gnu.org/licenses/gpl-3.0.fr.html>`_.
+<https://www.gnu.org/licenses/gpl-3.0.fr.html>`_.
diff --git a/android/AndroidManifest.xml.cmake b/android/AndroidManifest.xml.cmake
index 9fd6e8334..f3457d8e1 100644
--- a/android/AndroidManifest.xml.cmake
+++ b/android/AndroidManifest.xml.cmake
@@ -1,41 +1,41 @@
<?xml version="1.0"?>
<manifest android:versionName="@GCOMPRIS_VERSION@" package="@ANDROID_PACKAGE@" android:installLocation="auto" xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="@GCOMPRIS_VERSION_CODE@">
<application android:label="GCompris" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:icon="@drawable/icon">
<activity android:label="@string/app_name" android:name="net.gcompris.GComprisActivity" android:screenOrientation="unspecified" android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|locale|fontScale|keyboard|keyboardHidden|navigation">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
- <meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --"/>
+ <meta-data android:name="android.app.lib_name" android:value="GCompris"/>
<meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
<meta-data android:name="android.app.repository" android:value="default"/>
<meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/>
<meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/>
<!-- Deploy Qt libs as part of package -->
<meta-data android:name="android.app.bundle_local_qt_libs" android:value="-- %%BUNDLE_LOCAL_QT_LIBS%% --"/>
<meta-data android:name="android.app.bundled_in_lib_resource_id" android:resource="@array/bundled_in_lib"/>
<meta-data android:name="android.app.bundled_in_assets_resource_id" android:resource="@array/bundled_in_assets"/>
<!-- Run with local libs -->
<meta-data android:name="android.app.use_local_qt_libs" android:value="-- %%USE_LOCAL_QT_LIBS%% --"/>
<meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/>
<meta-data android:name="android.app.load_local_libs" android:value="-- %%INSERT_LOCAL_LIBS%% --"/>
<meta-data android:name="android.app.load_local_jars" android:value="-- %%INSERT_LOCAL_JARS%% --"/>
<meta-data android:name="android.app.static_init_classes" android:value="-- %%INSERT_INIT_CLASSES%% --"/>
<!-- Messages maps -->
<meta-data android:name="android.app.ministro_not_found_msg" android:value="@string/ministro_not_found_msg"/>
<meta-data android:name="android.app.ministro_needed_msg" android:value="@string/ministro_needed_msg"/>
<meta-data android:name="android.app.fatal_error_msg" android:value="@string/fatal_error_msg"/>
<!-- Splash screen -->
<meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/splash"/>
<!-- Splash screen -->
</activity>
</application>
<supports-screens android:anyDensity="true" android:normalScreens="true" android:smallScreens="true" android:largeScreens="true"/>
- <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="19"/>
+ <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="26"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
@ANDROID_INTERNET_PERMISSION@
@ANDROID_ACCESS_NETWORK_STATE_PERMISSION@
@ANDROID_BILLING_PERMISSION@
</manifest>
diff --git a/android/CMakeLists.txt b/android/CMakeLists.txt
index d0963f3c6..373df6e98 100644
--- a/android/CMakeLists.txt
+++ b/android/CMakeLists.txt
@@ -1,133 +1,183 @@
#android build
# copied/inspired from stellarium project (http://www.stellarium.org/wiki/index.php/Building_for_Android)
LIST(APPEND JAVA_SRCS "src/com/android/vending/billing/IInAppBillingService.aidl" "src/net/gcompris/GComprisActivity.java")
FOREACH(JavaSource ${JAVA_SRCS})
ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${JavaSource}
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/${JavaSource} ${CMAKE_CURRENT_BINARY_DIR}/${JavaSource}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${JavaSource}
)
LIST(APPEND TARGET_JAVA_FILES ${CMAKE_CURRENT_BINARY_DIR}/${JavaSource})
ENDFOREACH()
ADD_CUSTOM_TARGET (java_src DEPENDS ${TARGET_JAVA_FILES})
find_program(ANDROID_DEPLOY_QT NAMES androiddeployqt PATHS ${_qt5Core_install_prefix}/bin/ )
# Look for androiddeployqt program
if (NOT ANDROID_DEPLOY_QT)
message(FATAL_ERROR "Could not find androiddeployqt. Make sure you set all the Qt5_* paths to the Qt for android compiled version.")
endif(NOT ANDROID_DEPLOY_QT)
# Set version
set(ANDROID_VERSION_NAME ${GCOMPRIS_VERSION})
# Set a name representing the build type
set(APK_SUFFIX "-")
if(ACTIVATION_MODE STREQUAL "inapp")
set(APK_SUFFIX "-inapp${APK_SUFFIX}")
elseif(ACTIVATION_MODE STREQUAL "internal")
set(APK_SUFFIX "-internal${APK_SUFFIX}")
endif(ACTIVATION_MODE STREQUAL "inapp")
+# _HOST have been removed from ECM in https://cgit.kde.org/extra-cmake-modules.git/commit/?id=731ba7036effcc430f98031e7f2a9826f6234cba
+set(_HOST "${CMAKE_HOST_SYSTEM_NAME}-${CMAKE_HOST_SYSTEM_PROCESSOR}")
+string(TOLOWER "${_HOST}" _HOST)
+
if(WITH_DEMO_ONLY)
set(APK_SUFFIX "-demo${APK_SUFFIX}")
endif(WITH_DEMO_ONLY)
if(WITH_DOWNLOAD)
set(APK_SUFFIX "-dl${APK_SUFFIX}")
endif(WITH_DOWNLOAD)
if(WITH_KIOSK_MODE)
set(APK_SUFFIX "-kiosk${APK_SUFFIX}")
endif(WITH_KIOSK_MODE)
+# specific clang addition
+if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
+ set(STDCPP_PATH ",\"stdcpp-path\": \"${ANDROID_NDK}/sources/cxx-stl/llvm-libc++/libs/${ANDROID_ABI}/libc++_shared.so\"")
+ set(REMOVE_mandroid_FLAG_FOR_CLANG "sed -i -e 's/-mandroid//' Configure")
+endif()
+
+set(ANDROID_TOOLCHAIN arm-linux-androideabi)
# set android package source for androiddeployqt json file
set(PACKAGE_SOURCE_ANDROID ${CMAKE_BINARY_DIR}/tmpAndroid)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/AndroidManifest.xml.cmake ${PACKAGE_SOURCE_ANDROID}/AndroidManifest.xml @ONLY)
# create json file parsed by the androiddeployqt
set(ANDROID_SDK_ROOT $ENV{ANDROID_SDK_ROOT})
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/configAndroid.json.cmake ${PACKAGE_SOURCE_ANDROID}/configAndroid.json @ONLY)
# Get all po files in po/ to create the values-{locale} in order to have the locales available in android
file(GLOB TRANSLATIONS_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "../po/*.po")
foreach(PoSource ${TRANSLATIONS_FILES})
# Remove suffix ".po"
string(REPLACE ".po" "" PoSource ${PoSource})
# Remove prefix "../po/gcompris_"
string(REPLACE "../po/gcompris_" "" locale ${PoSource})
# replace _ par -r for locales with country
string(REPLACE "_" "-r" locale ${locale})
add_custom_command(
OUTPUT ${locale}
COMMAND cmake -E make_directory ${GCOMPRIS_TRANSLATIONS_DIR}
COMMAND cmake -E make_directory ${CMAKE_BINARY_DIR}/android/res/values-${locale}
COMMAND cmake -E copy ${CMAKE_SOURCE_DIR}/android/strings.xml ${CMAKE_BINARY_DIR}/android/res/values-${locale}/strings.xml
)
list(APPEND ALL_LOCALES ${locale})
endforeach()
add_custom_command (
OUTPUT createApkFromAndroidDeployQtDebug
DEPENDS ${PACKAGE_SOURCE_ANDROID}/AndroidManifest.xml
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR} ${PACKAGE_SOURCE_ANDROID}
COMMAND ${ANDROID_DEPLOY_QT} --output ${CMAKE_CURRENT_BINARY_DIR}/ --input ${PACKAGE_SOURCE_ANDROID}/configAndroid.json --debug
COMMAND ${CMAKE_COMMAND} -E rename ${CMAKE_CURRENT_BINARY_DIR}/bin/QtApp-debug.apk ${CMAKE_CURRENT_BINARY_DIR}/bin/GCompris-Android-debug-${ANDROID_ABI}${APK_SUFFIX}${GCOMPRIS_VERSION}.apk
)
add_custom_command (
OUTPUT createApkFromAndroidDeployQtRelease
DEPENDS ${PACKAGE_SOURCE_ANDROID}/AndroidManifest.xml
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR} ${PACKAGE_SOURCE_ANDROID}
COMMAND ${ANDROID_DEPLOY_QT} --output ${CMAKE_CURRENT_BINARY_DIR}/ --input ${PACKAGE_SOURCE_ANDROID}/configAndroid.json --release
COMMAND ${CMAKE_COMMAND} -E rename ${CMAKE_CURRENT_BINARY_DIR}/bin/QtApp-release-unsigned.apk ${CMAKE_CURRENT_BINARY_DIR}/bin/GCompris-Android-release-${ANDROID_ABI}${APK_SUFFIX}${GCOMPRIS_VERSION}.apk
)
add_custom_command (
OUTPUT createApkSignedFromAndroidDeployQtRelease
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/bin/GCompris-Android-release-${ANDROID_ABI}${APK_SUFFIX}${GCOMPRIS_VERSION}.apk
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/bin/GCompris-Android-release-${ANDROID_ABI}${APK_SUFFIX}${GCOMPRIS_VERSION}.apk ${CMAKE_CURRENT_BINARY_DIR}/bin/GCompris-Android-release-signed-${ANDROID_ABI}${APK_SUFFIX}${GCOMPRIS_VERSION}.apk
COMMAND jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore $ENV{ANDROID_KEYSTORE} -storepass $ENV{ANDROID_KEYSTORE_PASSWD} ${CMAKE_CURRENT_BINARY_DIR}/bin/GCompris-Android-release-signed-${ANDROID_ABI}${APK_SUFFIX}${GCOMPRIS_VERSION}.apk gcompris
)
add_custom_command (
OUTPUT createApkSignedAlignedFromAndroidDeployQtRelease
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/bin/GCompris-Android-release-signed-${ANDROID_ABI}${APK_SUFFIX}${GCOMPRIS_VERSION}.apk
COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_CURRENT_BINARY_DIR}/bin/GCompris-Android-release-signed-aligned-${ANDROID_ABI}${APK_SUFFIX}${GCOMPRIS_VERSION}.apk
COMMAND ${ANDROID_SDK_ROOT}/build-tools/21.1.2/zipalign -v 4 ${CMAKE_CURRENT_BINARY_DIR}/bin/GCompris-Android-release-signed-${ANDROID_ABI}${APK_SUFFIX}${GCOMPRIS_VERSION}.apk ${CMAKE_CURRENT_BINARY_DIR}/bin/GCompris-Android-release-signed-aligned-${ANDROID_ABI}${APK_SUFFIX}${GCOMPRIS_VERSION}.apk
)
add_custom_command (
OUTPUT apkInstall
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/bin/GCompris-Android-release-signed-aligned-${ANDROID_ABI}${APK_SUFFIX}${GCOMPRIS_VERSION}.apk
COMMAND ${ANDROID_SDK_ROOT}/platform-tools/adb install -r ${CMAKE_CURRENT_BINARY_DIR}/bin/GCompris-Android-release-signed-aligned-${ANDROID_ABI}${APK_SUFFIX}${GCOMPRIS_VERSION}.apk
)
# Command to create apk from Makefile
add_custom_target (apk_debug
- DEPENDS ${ALL_LOCALES} createApkFromAndroidDeployQtDebug java_src
+ DEPENDS ${ALL_LOCALES} move_translations_to_assets package_openssl createApkFromAndroidDeployQtDebug java_src
)
# Command to create apk from Makefile
add_custom_target (apk_release
- DEPENDS ${ALL_LOCALES} createApkFromAndroidDeployQtRelease java_src
+ DEPENDS ${ALL_LOCALES} move_translations_to_assets package_openssl createApkFromAndroidDeployQtRelease java_src
)
# Command to create signed apk from Makefile
add_custom_target (apk_signed
- DEPENDS ${ALL_LOCALES} createApkSignedFromAndroidDeployQtRelease java_src
+ DEPENDS ${ALL_LOCALES} move_translations_to_assets package_openssl createApkSignedFromAndroidDeployQtRelease java_src
)
# Command to create signed aligned apk from Makefile
add_custom_target (apk_signed_aligned
- DEPENDS ${ALL_LOCALES} createApkSignedAlignedFromAndroidDeployQtRelease java_src
+ DEPENDS ${ALL_LOCALES} move_translations_to_assets package_openssl createApkSignedAlignedFromAndroidDeployQtRelease java_src
)
# Command to install the signed aligned apk through adb from Makefile
add_custom_target (apk_install
DEPENDS apkInstall
)
+
+# compile openssl needed to download from https
+include(ExternalProject)
+set(OPENSSL_DIR "${CMAKE_BINARY_DIR}/external/openssl/")
+configure_file("build_openssl.sh.in" "build_openssl.sh" @ONLY)
+
+ExternalProject_Add(
+ ext_openssl
+ DOWNLOAD_DIR ${CMAKE_BINARY_DIR}
+ SOURCE_DIR ${OPENSSL_DIR}
+ URL https://www.openssl.org/source/openssl-1.0.2q.tar.gz
+ URL_HASH SHA256=5744cfcbcec2b1b48629f7354203bc1e5e9b5466998bbccc5b5fcde3b18eb684
+ CONFIGURE_COMMAND echo "Configuration not needed"
+ BUILD_COMMAND sh "${CMAKE_CURRENT_BINARY_DIR}/build_openssl.sh" <SOURCE_DIR>
+ INSTALL_COMMAND ""
+ )
+
+add_custom_command(
+ OUTPUT package_openssl
+ COMMAND ${CMAKE_COMMAND} -E copy "${OPENSSL_DIR}/libcrypto.so.1.0.0" "${CMAKE_BINARY_DIR}/android/libs/${ANDROID_ABI}/libcrypto.so"
+ COMMAND ${CMAKE_COMMAND} -E copy "${OPENSSL_DIR}/libssl.so.1.0.0" "${CMAKE_BINARY_DIR}/android/libs/${ANDROID_ABI}/libssl.so"
+ )
+
+#
+add_custom_command(
+ OUTPUT move_translations_to_assets
+ COMMAND ${CMAKE_COMMAND} -E copy_directory ${GCOMPRIS_TRANSLATIONS_DIR} ${CMAKE_BINARY_DIR}/android/assets/share/GCompris
+ )
+
+if (TARGET create-apk)
+ set(PACKAGE_DIR ${PACKAGE_SOURCE_ANDROID})
+ set_target_properties(create-apk-GCompris PROPERTIES ANDROID_APK_DIR "${PACKAGE_DIR}")
+ add_custom_target(gcompris-move-metadata ALL
+ COMMAND cmake -E echo "Moving GCompris shared Android resources"
+ COMMAND cmake -E make_directory ${PACKAGE_SOURCE_ANDROID}
+ COMMAND cmake -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}" "${PACKAGE_SOURCE_ANDROID}"
+ )
+ add_dependencies(create-apk gcompris-move-metadata)
+endif()
diff --git a/android/build_openssl.sh.in b/android/build_openssl.sh.in
new file mode 100644
index 000000000..362a637e4
--- /dev/null
+++ b/android/build_openssl.sh.in
@@ -0,0 +1,17 @@
+#!/usr/bin/sh
+
+# The only argument to the script is source directory.
+source_dir=$1
+
+export PATH=@ANDROID_NDK@/toolchains/@ANDROID_TOOLCHAIN@-4.9/prebuilt/@_HOST@/bin/:$PATH
+echo $PATH
+export CROSS_COMPILE="@ANDROID_TOOLCHAIN_PATH@@ANDROID_TOOLCHAIN@-"
+export NDK_SYSROOT=@ANDROID_NDK@
+export ANDROID_NDK_ROOT=@ANDROID_NDK@
+export ANDROID_DEV=@ANDROID_NDK@/platforms/android-@CMAKE_ANDROID_API@/arch-arm/usr
+export SYSROOT=@ANDROID_NDK@/platforms/android-@CMAKE_ANDROID_API@/arch-arm/
+cd ${source_dir}
+@REMOVE_mandroid_FLAG_FOR_CLANG@
+./Configure --prefix=. --openssldir=./ssl android-armv7 no-asm shared
+make && make libssl.so.1.0.0 libcrypto.so.1.0.0
+cd -
diff --git a/android/configAndroid.json.cmake b/android/configAndroid.json.cmake
index 0b04894fe..4c57898c9 100644
--- a/android/configAndroid.json.cmake
+++ b/android/configAndroid.json.cmake
@@ -1,15 +1,16 @@
{
"description": "This file is to be read by androiddeployqt",
"qt": "@_qt5Core_install_prefix@",
"sdk": "@ANDROID_SDK_ROOT@",
"ndk": "@ANDROID_NDK@",
"toolchain-prefix": "@ANDROID_TOOLCHAIN@",
"tool-prefix": "@ANDROID_TOOLCHAIN@",
- "toolchain-version": "@ANDROID_GCC_VERSION@",
+ "toolchain-version": "4.9",
"ndk-host": "@_HOST@",
"target-architecture": "@ANDROID_ABI@",
"application-binary": "@CMAKE_LIBRARY_OUTPUT_DIRECTORY@/libGCompris.so",
"android-package-source-directory": "@PACKAGE_SOURCE_ANDROID@/",
"android-package": "net.gcompris",
"android-extra-plugins": "@CMAKE_BINARY_DIR@/lib/qml"
+ @STDCPP_PATH@
}
diff --git a/android/src/net/gcompris/GComprisActivity.java b/android/src/net/gcompris/GComprisActivity.java
index 177496aee..b379205ad 100644
--- a/android/src/net/gcompris/GComprisActivity.java
+++ b/android/src/net/gcompris/GComprisActivity.java
@@ -1,269 +1,269 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtAndroidExtras module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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.
+** will be met: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
+** met: https://www.gnu.org/copyleft/gpl.html.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
package net.gcompris;
import org.qtproject.qt5.android.bindings.QtApplication;
import org.qtproject.qt5.android.bindings.QtActivity;
import com.android.vending.billing.*;
import android.media.AudioManager;
import android.util.Log;
import android.os.Bundle;
import android.os.IBinder;
import android.content.ServiceConnection;
import android.content.Intent;
import android.content.ComponentName;
import android.content.Context;
import android.app.PendingIntent;
import org.json.JSONObject;
import java.util.ArrayList;
import android.view.WindowManager;
import java.text.Collator;
import java.util.Locale;
public class GComprisActivity extends QtActivity
{
private static GComprisActivity m_instance;
// public static final String SKU_NAME = "android.test.purchased"; // for testing
public static final String SKU_NAME = "full";
private IInAppBillingService m_service;
private ServiceConnection m_serviceConnection = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name)
{
m_service = null;
}
@Override
public void onServiceConnected(ComponentName name, IBinder service)
{
if(service.isBinderAlive()) {
m_service = IInAppBillingService.Stub.asInterface(service);
}
}
};
public GComprisActivity()
{
m_instance = this;
}
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Intent intent = new Intent("com.android.vending.billing.InAppBillingService.BIND");
intent.setPackage("com.android.vending");
bindService(intent,
m_serviceConnection, Context.BIND_AUTO_CREATE);
}
@Override
public void onDestroy()
{
super.onDestroy();
unbindService(m_serviceConnection);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK && data != null && requestCode == 1001) {
int responseCode = data.getIntExtra("RESPONSE_CODE", -1);
String purchaseData = data.getStringExtra("INAPP_PURCHASE_DATA");
try {
JSONObject jo = new JSONObject(purchaseData);
String sku = jo.getString("productId");
int purchaseState = jo.getInt("purchaseState");
String payload = jo.getString("developerPayload");
String purchaseToken = jo.getString("purchaseToken");
if (sku.equals(SKU_NAME) && purchaseState == 0) {
bought(true);
return;
}
} catch (Exception e) {
e.printStackTrace();
}
Log.e(QtApplication.QtTAG, "Buying full version failed: Result code == " + resultCode);
}
}
private static native void bought(boolean b);
public static void buyGCompris()
{
if (m_instance.m_service == null) {
Log.e(QtApplication.QtTAG, "Buying full version failed: No billing service");
return;
}
try {
Bundle buyIntentBundle = m_instance.m_service.getBuyIntent(3,
m_instance.getPackageName(),
SKU_NAME,
"inapp",
"");
int responseCode = buyIntentBundle.getInt("RESPONSE_CODE");
if (responseCode == 0 /* BILLING_RESPONSE_RESULT_OK */) {
PendingIntent pendingIntent = buyIntentBundle.getParcelable("BUY_INTENT");
m_instance.startIntentSenderForResult(pendingIntent.getIntentSender(),
1001, new Intent(), Integer.valueOf(0), Integer.valueOf(0),
Integer.valueOf(0));
return;
} else if (responseCode == 7 /* BILLING_RESPONSE_RESULT_ITEM_ALREADY_OWNED */) {
bought(true);
} else {
Log.e(QtApplication.QtTAG, "Buying full version failed: Response code == " + responseCode);
}
} catch (Exception e) {
Log.e(QtApplication.QtTAG, "Exception caught when buying full version!", e);
}
}
public static void checkPayment()
{
if (m_instance.m_service == null) {
Log.e(QtApplication.QtTAG, "Check full version is bought failed: No billing service");
return;
}
try {
Bundle ownedItems = m_instance.m_service.getPurchases(3, m_instance.getPackageName(),
"inapp", null);
int responseCode = ownedItems.getInt("RESPONSE_CODE");
if (responseCode == 0) {
ArrayList ownedSkus = ownedItems.getStringArrayList("INAPP_PURCHASE_ITEM_LIST");
ArrayList purchaseDataList = ownedItems.getStringArrayList("INAPP_PURCHASE_DATA_LIST");
for(int i=0; i<purchaseDataList.size(); ++i)
{
String purchaseData = (String) purchaseDataList.get(i);
String sku = (String) ownedSkus.get(i);
if(sku.equals(SKU_NAME)) {
bought(true);
return;
} else {
Log.e(QtApplication.QtTAG, "Unknown item bought " + sku);
}
}
bought(false);
return;
} else {
bought(false);
Log.e(QtApplication.QtTAG, "Item not owed " + responseCode);
}
} catch (Exception e) {
Log.e(QtApplication.QtTAG, "Exception caught when checking if full version is bought!", e);
}
}
public static boolean requestAudioFocus() {
Context mContext = m_instance.getApplicationContext();
AudioManager am = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
// Request audio focus for playback
int result = am.requestAudioFocus(null,
// Use the music stream.
AudioManager.STREAM_MUSIC,
// Request permanent focus.
AudioManager.AUDIOFOCUS_GAIN);
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
return true;
}
return false;
}
public static void abandonAudioFocus() {
// Abandon audio focus
Context mContext = m_instance.getApplicationContext();
AudioManager am = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
am.abandonAudioFocus(null);
}
/**
* Toggle activation of screen-saver
*
* Note that the window flags *must* be modified from the UI thread
* otherwise it has no effect.
*
* @param value Whether screensaver should be enabled or disabled
*/
public void setKeepScreenOn(boolean value) {
if (value)
GComprisActivity.this.runOnUiThread(new Runnable() {
public void run() {
Log.d(QtApplication.QtTAG, "Disabling screensaver");
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
});
else
GComprisActivity.this.runOnUiThread(new Runnable() {
public void run() {
Log.d(QtApplication.QtTAG, "Enabling screensaver");
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
});
}
public int localeCompare(String a, String b, String locale)
{
String[] parts = locale.split("[\\._]");
Locale l;
if (parts.length == 1)
l = new Locale(parts[0]);
else if (parts.length == 2)
l = new Locale(parts[0], parts[1]);
else
l = Locale.getDefault();
Collator collator = Collator.getInstance(l);
// Note: This works only if the device supports the
// passed locale. If it does not or if an invalid locale string has been
// passed, the collator seems to sort according to Locale.getDefault()
return collator.compare(a, b);
}
}
diff --git a/appveyor.yml b/appveyor.yml
index 76b8b5892..2cc281da5 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,51 +1,51 @@
version: 1.0.{build}
branches:
only:
- - KDE/0.90
+ - KDE/0.95
skip_tags: true
-image: Visual Studio 2015
+image: Visual Studio 2017
configuration: Release
platform:
- x64
- x86
init:
- cmd:
environment:
- CMAKE_GENERATOR: Visual Studio 14
- QT5: C:\Qt\5.9\msvc2015
+ CMAKE_GENERATOR: Visual Studio 15
+ QT5: C:\Qt\5.12.1\msvc2017
install:
- cmd: >-
- if "%platform%"=="x86" set CMAKE_GENERATOR=Visual Studio 14
+ if "%platform%"=="x86" set CMAKE_GENERATOR=Visual Studio 15
- if "%platform%"=="x86" set QT5=C:\Qt\5.9\msvc2015
+ if "%platform%"=="x86" set QT5=C:\Qt\5.12.1\msvc2017
- if "%platform%"=="x64" set CMAKE_GENERATOR=Visual Studio 14 2015 Win64
+ if "%platform%"=="x64" set CMAKE_GENERATOR=Visual Studio 15 2017 Win64
- if "%platform%"=="x64" set QT5=C:\Qt\5.9\msvc2015_64
+ if "%platform%"=="x64" set QT5=C:\Qt\5.12.1\msvc2017_64
set Path=%QT5%\bin;%Path%
- cmake -H. -Bbuild -G "%CMAKE_GENERATOR%" -DCMAKE_SYSTEM_VERSION=10.0 "-DCMAKE_PREFIX_PATH=%QT5%" -DACTIVATION_MODE=internal -DVCREDIST_DIR="build -DGRAPHICAL_RENDERER=software"
+ cmake -H. -Bbuild -G "%CMAKE_GENERATOR%" -DCMAKE_SYSTEM_VERSION=10.0 "-DCMAKE_PREFIX_PATH=%QT5%" -DACTIVATION_MODE=internal -DVCREDIST_DIR="build" -DGRAPHICAL_RENDERER=software
cmake --build build --config RelWithDebInfo --target DlAndInstallBundledConvertedOggs
- cmake -H. -Bbuild -G "%CMAKE_GENERATOR%" -DCMAKE_SYSTEM_VERSION=10.0 "-DCMAKE_PREFIX_PATH=%QT5%" -DACTIVATION_MODE=internal -DVCREDIST_DIR="build -DGRAPHICAL_RENDERER=software"
+ cmake -H. -Bbuild -G "%CMAKE_GENERATOR%" -DCMAKE_SYSTEM_VERSION=10.0 "-DCMAKE_PREFIX_PATH=%QT5%" -DACTIVATION_MODE=internal -DVCREDIST_DIR="build" -DGRAPHICAL_RENDERER=software
cmake --build build --config RelWithDebInfo
cmake --build build --config RelWithDebInfo --target DlAndInstallBundledTranslations
cmake --build build --config RelWithDebInfo --target package
build: off
artifacts:
- path: build/*.exe
deploy:
- provider: FTP
host: gcompris.net
protocol: sftp
username: releaser
password:
secure: kt7OLxDoaFlmFwDtcGfa/X3uVhQj0y1q2YVdBroxp9U=
folder: www
diff --git a/cmake/CodeQualityUtils.cmake b/cmake/CodeQualityUtils.cmake
new file mode 100644
index 000000000..78f79734d
--- /dev/null
+++ b/cmake/CodeQualityUtils.cmake
@@ -0,0 +1,25 @@
+# These tools are run (for now) only if BUILD_TESTING is ON
+# Another useful tool could be clazy compiler too
+
+# Run cppcheck on the code
+find_program(CPPCHECK_EXE NAMES cppcheck)
+if(CPPCHECK_EXE)
+ set(CMAKE_CXX_CPPCHECK ${CPPCHECK_EXE})
+ list(
+ APPEND CMAKE_CXX_CPPCHECK
+ "--enable=all"
+ "--inconclusive"
+ "--force"
+ "--inline-suppr"
+ )
+endif()
+
+# Run clang-tidy
+find_program(CLANG_TIDY_EXE NAMES clang-tidy)
+if(CLANG_TIDY_EXE)
+ set(CMAKE_CXX_CLANG_TIDY ${CLANG_TIDY_EXE})
+ list(
+ APPEND CMAKE_CXX_CLANG_TIDY
+ "-checks=*,-fuchsia*,-google*,-hicpp*,-llvm*,-cppcoreguidelines-*,-modernize-use-auto,-readability-braces-around-statements,-readability-static-accessed-through-instance"
+ )
+endif()
diff --git a/cmake/box2d.cmake b/cmake/box2d.cmake
new file mode 100644
index 000000000..1179f9044
--- /dev/null
+++ b/cmake/box2d.cmake
@@ -0,0 +1,83 @@
+
+set(QML_BOX2D_MODULE "auto" CACHE STRING "Policy for qml-box2d module [auto|submodule|system|disabled]")
+
+if (NOT ${QML_BOX2D_MODULE} STREQUAL "disabled")
+ include(qt_helper)
+
+ getQtQmlPath(_qt_qml_system_path)
+ set (_box2d_system_dir "${_qt_qml_system_path}/Box2D.2.0")
+
+ if (${QML_BOX2D_MODULE} STREQUAL "submodule")
+ message(STATUS "Building qml-box2d module from submodule")
+ set(_need_box2d_submodule "TRUE")
+ else()
+ # try to find module in system scope
+ find_library(QML_BOX2D_LIBRARY NAMES Box2D libBox2D PATHS ${_box2d_system_dir} NO_DEFAULT_PATH)
+ if (QML_BOX2D_LIBRARY)
+ message(STATUS "Using system qml-box2d plugin at ${QML_BOX2D_LIBRARY}")
+ # for packaging builds, copy the module manually to the correct location
+ if(SAILFISHOS)
+ file(COPY ${_box2d_system_dir}/qmldir ${QML_BOX2D_LIBRARY} DESTINATION share/harbour-gcompris-qt/lib/qml/Box2D.2.0)
+ elseif(ANDROID)
+ file(COPY ${_box2d_system_dir}/qmldir ${QML_BOX2D_LIBRARY} DESTINATION lib/qml/Box2D.2.0)
+ endif()
+ # FIXME: add others as needed
+ else()
+ if (${QML_BOX2D_MODULE} STREQUAL "auto")
+ message(STATUS "Did not find the qml-box2d module in system scope, falling back to submodule build ...")
+ set (_need_box2d_submodule "TRUE")
+ else()
+ message(FATAL_ERROR "Did not find the qml-box2d module in system scope and submodule build was not requested. Can't continue!")
+ endif()
+ endif()
+ endif()
+
+ if (_need_box2d_submodule)
+ # build qml-box2d ourselves from submodule
+ include(ExternalProject)
+ get_property(_qmake_program TARGET ${Qt5Core_QMAKE_EXECUTABLE} PROPERTY IMPORT_LOCATION)
+ set (_box2d_source_dir ${CMAKE_CURRENT_SOURCE_DIR}/external/qml-box2d)
+ if(WIN32)
+ set (_box2d_library_dir "release/")
+ set (_box2d_library_file "Box2D.dll")
+ elseif(CMAKE_HOST_APPLE)
+ set (_box2d_library_dir "")
+ set (_box2d_library_file "libBox2D.dylib")
+ else()
+ set (_box2d_library_dir "")
+ set (_box2d_library_file "libBox2D.so")
+ endif()
+ set (_box2d_install_dir ${CMAKE_CURRENT_BINARY_DIR}/lib/qml/Box2D.2.0)
+ # make sure submodule is up2date
+ find_package(Git)
+ if(GIT_FOUND)
+ execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
+ endif()
+
+ # for visual studio, we need to create a vcxproj
+ if(WIN32 AND NOT MINGW)
+ set(_qmake_options -spec win32-msvc -tp vc)
+ else()
+ set(_qmake_options "")
+ endif()
+ ExternalProject_Add(qml_box2d
+ DOWNLOAD_COMMAND ""
+ SOURCE_DIR ${_box2d_source_dir}
+ CONFIGURE_COMMAND ${_qmake_program} ${_qmake_options} ${_box2d_source_dir}/box2d.pro
+ BUILD_COMMAND ${CMAKE_MAKE_PROGRAM}
+ INSTALL_DIR ${_box2d_install_dir}
+ INSTALL_COMMAND cp ${_box2d_library_dir}${_box2d_library_file} ${_box2d_source_dir}/qmldir ${_box2d_install_dir}
+ )
+
+ add_library(qml-box2d SHARED IMPORTED)
+ set_target_properties(qml-box2d PROPERTIES IMPORTED_LOCATION ${_box2d_install_dir}/${_box2d_library_file})
+
+ if(SAILFISHOS)
+ install(DIRECTORY ${_box2d_install_dir} DESTINATION share/harbour-gcompris-qt/lib/qml)
+ elseif(APPLE)
+ install(DIRECTORY ${_box2d_install_dir} DESTINATION gcompris-qt.app/Contents/lib/qml)
+ else()
+ install(DIRECTORY ${_box2d_install_dir} DESTINATION lib/qml)
+ endif()
+ endif()
+endif()
diff --git a/cmake/kdeFetchTranslation.cmake b/cmake/kdeFetchTranslation.cmake
new file mode 100644
index 000000000..55d89f6b6
--- /dev/null
+++ b/cmake/kdeFetchTranslation.cmake
@@ -0,0 +1,90 @@
+#
+# This file is mostly copied from the KDECMakeSettings.cmake:
+# https://github.com/KDE/extra-cmake-modules/blob/master/kde-modules/KDECMakeSettings.cmake#L320
+# Once the last version of ECM will be available on most distributions, we'll
+# need to switch to it (or at least use it if available else switch to existing
+# l10n-fetch-po-files.py script to retrieve the po)
+#
+# License of KDECMakeSettings.cmake
+#=============================================================================
+# Copyright 2014 Alex Merry <alex.merry@kde.org>
+# Copyright 2013 Aleix Pol <aleixpol@kde.org>
+# Copyright 2012-2013 Stephen Kelly <steveire@gmail.com>
+# Copyright 2007 Matthias Kretz <kretz@kde.org>
+# Copyright 2006-2007 Laurent Montel <montel@kde.org>
+# Copyright 2006-2013 Alex Neundorf <neundorf@kde.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. The name of the author may not be used to endorse or promote products
+# derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+if(NOT TARGET fetch-translations AND KDE_L10N_AUTO_TRANSLATIONS)
+ set(KDE_L10N_BRANCH "trunk" CACHE STRING "Branch from l10n.kde.org to fetch from: trunk | stable | lts | trunk_kde4 | stable_kde4")
+
+ set(_reponame "gcompris")
+
+ set(releaseme_clone_commands
+ COMMAND git clone --depth 1 https://anongit.kde.org/releaseme.git
+ )
+ add_custom_command(
+ OUTPUT "${CMAKE_BINARY_DIR}/releaseme"
+ ${releaseme_clone_commands}
+ COMMENT "Fetching releaseme scripts to download translations..."
+ )
+
+ set(_l10n_po_dir "${CMAKE_BINARY_DIR}/po")
+ set(_l10n_poqm_dir "${CMAKE_BINARY_DIR}/poqm")
+
+ if(CMAKE_VERSION VERSION_GREATER 3.2)
+ set(extra BYPRODUCTS ${_l10n_po_dir} ${_l10n_poqm_dir})
+ endif()
+
+ set(fetch_commands
+ COMMAND ruby "${CMAKE_BINARY_DIR}/releaseme/fetchpo.rb"
+ --origin ${KDE_L10N_BRANCH}
+ --project "${_reponame}"
+ --output-dir "${_l10n_po_dir}"
+ --output-poqm-dir "${_l10n_poqm_dir}"
+ "${CMAKE_SOURCE_DIR}"
+ )
+
+ add_custom_target(fetch-translations ${_EXTRA_ARGS}
+ COMMENT "Downloading translations for ${_reponame} branch ${KDE_L10N_BRANCH}..."
+ COMMAND git -C "${CMAKE_BINARY_DIR}/releaseme" pull
+ COMMAND cmake -E remove_directory ${_l10n_po_dir}
+ COMMAND cmake -E remove_directory ${_l10n_poqm_dir}
+ ${fetch_commands}
+ ${extra}
+ ${move_translations}
+ DEPENDS "${CMAKE_BINARY_DIR}/releaseme"
+ )
+
+ set(move_translations COMMAND
+ bash ${CMAKE_SOURCE_DIR}/tools/move_translations.sh ${_l10n_poqm_dir} ${CMAKE_SOURCE_DIR}/po
+ )
+
+ if (NOT EXISTS ${_l10n_po_dir} OR NOT EXISTS ${_l10n_poqm_dir})
+ execute_process(${releaseme_clone_commands})
+ execute_process(${fetch_commands})
+ execute_process(${move_translations})
+ endif()
+endif()
diff --git a/cmake/qt_helper.cmake b/cmake/qt_helper.cmake
index 9e005e906..81696e56c 100644
--- a/cmake/qt_helper.cmake
+++ b/cmake/qt_helper.cmake
@@ -1,102 +1,106 @@
function(getQtPluginPaths _plugin_target _absolute_path _subdir _file)
getQtPluginsPath(_qt_plugins_path)
get_target_property(_plugin_path ${_plugin_target} LOCATION)
if(NOT _plugin_path)
message(FATAL_ERROR "Could not find ${_plugin_target} plugin path")
endif()
get_filename_component(_plugin_file ${_plugin_path} NAME)
get_filename_component(_plugin_dir ${_plugin_path} PATH)
file(RELATIVE_PATH _plugin_subdir ${_qt_plugins_path} ${_plugin_dir})
set(${_absolute_path} ${_plugin_path} PARENT_SCOPE)
set(${_subdir} ${_plugin_subdir} PARENT_SCOPE)
set(${_file} ${_plugin_file} PARENT_SCOPE)
endfunction()
# Determine Qt5's plugin-path deriving from lib-dir and trying different
# locations corresponding to different directory layouts, e.g.:
#
# Debian:
# /usr/lib/i386-linux-gnu/libQt5Qml.so.5.4.1
# /usr/lib/i386-linux-gnu/qt5/plugins/
# Opensuse:
# /usr/lib64/libQt5Multimedia.so.5
# /usr/lib64/qt5/plugins/
# Qt installer:
# /opt/Qt5.5.1/5.5/gcc/lib/libQt5Qml.so.5.5.1
# /opt/Qt5.5.1/5.5/gcc/plugins/
#
# The qml/-dir is always a sibling of the plugins/ dir.
function(getQtPluginsPath _path)
get_target_property(_lib_file Qt5::Qml LOCATION)
get_filename_component(_lib_dir ${_lib_file} PATH)
# try $_lib_dir/qt5/plugins (Debian/Opensuse)
set(_plugin_root ${_lib_dir}/qt5/plugins)
if (NOT IS_DIRECTORY ${_plugin_root})
# try $_lib_dir/../plugins (Qt installer)
get_filename_component(_lib_dir_base ${_lib_dir} PATH)
- set(_plugin_root ${_lib_dir_base}/plugins)
+ if(APPLE)
+ set(_plugin_root ${_lib_dir_base}/../plugins)
+ else()
+ set(_plugin_root ${_lib_dir_base}/plugins)
+ endif()
endif()
set(${_path} ${_plugin_root} PARENT_SCOPE)
endfunction()
function(getQtQmlPath _path)
getQtPluginsPath(_qt_plugins_path)
get_filename_component(_root ${_qt_plugins_path} PATH)
set(${_path} ${_root}/qml PARENT_SCOPE)
endfunction()
function(installQtPlugin _plugin _dest_dir _lib)
getQtPluginPaths(${_plugin} _absolute_path _plugin_subdir _plugin_file)
#needed to build with msys2
if(MINGW)
string(REGEX REPLACE "share/qt5/" "" _plugin_subdir ${_plugin_subdir})
endif()
install(FILES ${_absolute_path} DESTINATION ${_dest_dir}/${_plugin_subdir})
set(_lib "\${CMAKE_INSTALL_PREFIX}/${_dest_dir}/${_plugin_subdir}/${_plugin_file}" PARENT_SCOPE)
endfunction()
function(installQtPlugin2 _plugin _dest_dir _lib )
get_filename_component(_plugin_file ${_plugin} NAME)
set(_ext ${CMAKE_SHARED_LIBRARY_SUFFIX})
get_filename_component(_plugin_subdir ${_plugin} PATH)
get_filename_component(_plugin_subdir_root ${_plugin_subdir} PATH)
getQtPluginsPath(_qt_plugin_path)
install(DIRECTORY ${_qt_plugin_path}/${_plugin_subdir} DESTINATION ${_dest_dir}/${_plugin_subdir_root})
if(CMAKE_HOST_WIN32)
set(_dbg_suffix "d")
else()
set(_dbg_suffix "_debug")
endif()
set(_install_path \${CMAKE_INSTALL_PREFIX}/${_dest_dir}/${_plugin_subdir})
if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
install(CODE "file(REMOVE \"${_install_path}/${_plugin_file}${_ext}\")")
set(_plugin_file ${_plugin_file}${_dbg_suffix}${_ext})
else()
install(CODE "file(REMOVE \"${_install_path}/${_plugin_file}${_dbg_suffix}${_ext}\")")
set(_plugin_file ${_plugin_file}${_ext})
endif()
set(_lib "${_install_path}/${_plugin_file}" PARENT_SCOPE)
endfunction()
function(installQmlPlugin _plugin _dest_dir _lib )
get_filename_component(_plugin_file ${_plugin} NAME)
set(_ext ${CMAKE_SHARED_LIBRARY_SUFFIX})
get_filename_component(_qml_subdir ${_plugin} PATH)
get_filename_component(_qml_subdir_root ${_qml_subdir} PATH)
getQtQmlPath(_qt_qml_path)
install(DIRECTORY ${_qt_qml_path}/${_qml_subdir} DESTINATION ${_dest_dir}/${_qml_subdir_root})
if(CMAKE_HOST_WIN32)
set(_dbg_suffix "d")
else()
set(_dbg_suffix "_debug")
endif()
set(_install_path \${CMAKE_INSTALL_PREFIX}/${_dest_dir}/${_qml_subdir})
if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
install(CODE "file(REMOVE \"${_install_path}/${_plugin_file}${_ext}\")")
set(_plugin_file ${_plugin_file}${_dbg_suffix}${_ext})
else()
install(CODE "file(REMOVE \"${_install_path}/${_plugin_file}${_dbg_suffix}${_ext}\")")
set(_plugin_file ${_plugin_file}${_ext})
endif()
set(_lib "${_install_path}/${_plugin_file}" PARENT_SCOPE)
endfunction()
diff --git a/docs/docbook/index.docbook b/docs/docbook/index.docbook
index d54895ba0..42b407468 100644
--- a/docs/docbook/index.docbook
+++ b/docs/docbook/index.docbook
@@ -1,361 +1,361 @@
<?xml version="1.0" ?>
<!DOCTYPE book PUBLIC "-//KDE//DTD DocBook XML V4.5-Based Variant V1.1//EN" "dtd/kdedbx45.dtd" [
<!-- Define an entity for your application if it is not part of KDE
Git -->
<!ENTITY gcompris "<application>GCompris</application>">
<!ENTITY kappname "&gcompris;"><!-- replace kmyapplication here
do *not* replace kappname-->
<!ENTITY % addindex "IGNORE">
<!ENTITY % English "INCLUDE"> <!-- ONLY If you are writing non-English
original documentation, change
the language here -->
<!-- Do not define any other entities; instead, use the entities
from entities/general.entities and en/user.entities. -->
]>
<book id="gcompris" lang="&language;">
<bookinfo>
<title>The &gcompris; Administration Handbook</title>
<authorgroup>
<author>
<personname>
<firstname>This documentation was converted from the
-<ulink url="http://gcompris.net/wiki/Manual">&gcompris; Manual</ulink>
+<ulink url="https://gcompris.net/wiki/Manual">&gcompris; Manual</ulink>
page.</firstname>
<surname></surname>
</personname>
</author>
<!-- TRANS:ROLES_OF_TRANSLATORS -->
</authorgroup>
<legalnotice>&FDLNotice;</legalnotice>
<!-- Date of the documentation
Don't forget to include this last date.
Please respect the format of the date (YYYY-MM-DD),it is used by scripts.
-->
<date>2016-01-24</date>
<!--version information of the application and kde this documentation is valid for.
for example 'xx.yy.zz'
-->
<releaseinfo>0.52</releaseinfo>
<!-- Abstract about this handbook -->
<abstract>
<para>
&gcompris; is a multi-activity educational software.
</para>
</abstract>
<keywordset>
<keyword>KDE</keyword>
<keyword>education</keyword>
<keyword>children</keyword>
<keyword>games</keyword>
</keywordset>
</bookinfo>
<chapter id="administration-handbook">
<title>Administration Handbook</title>
<sect1 id="introduction">
<title>Introduction</title>
<para>&gcompris; is a completely free educational software suite which contains a wide range of activities.</para>
<para>It offers various activities aimed at covering a variety of fields such as the functioning of the computer,
using the mouse and keyboard, general learning, reading, writing, foreign languages, algebra, as well as various
activities such as memory and logic games, scientific experiments &etc;.</para>
<para>In &gcompris; you will find many individual software packages which together make up the complete &gcompris;
suite of activities. Unfortunately, it is difficult to follow and maintain them as each one offers different
graphic interfaces which vary widely in quality.</para>
<para>The purpose of &gcompris; is to provide a development platform for educational activities.</para>
-<para>&gcompris; is part of &kde; project and is placed under the <ulink url="http://www.gnu.org/licenses/gpl.html">GPL license</ulink>.</para>
+<para>&gcompris; is part of &kde; project and is placed under the <ulink url="https://www.gnu.org/licenses/gpl.html">GPL license</ulink>.</para>
</sect1>
<sect1 id="minimal-configuration">
<title>Minimal configuration</title>
<itemizedlist>
<listitem><para>Processor : 1.6GHz Atom CPU</para></listitem>
<listitem><para>Memory (RAM) : 1 Giga Byte</para></listitem>
<listitem><para>Disk : 300 Mega Bytes</para></listitem>
<listitem><para>Operating system : &GNU;/&Linux;, &BSD;, MacOSX, &Windows;, Android, SailfishOS</para></listitem>
<listitem><para>Video : A 3D card with support of <emphasis>OpenGL 2.1</emphasis> or higher is required. 32 bits color depth mandatory</para></listitem>
</itemizedlist>
</sect1>
<sect1 id="installation">
<title>Installation</title>
<para>The software is delivered under several forms. Follow the process according to your case. </para>
<itemizedlist>
<listitem><para>&GNU;/&Linux; : Use the packages delivered by your &GNU;/&Linux; distribution. You may have to install
the package gcompris-sound-en to have the English voices. If &gcompris; is not packaged in your &Linux; distribution,
please contact them to ask for the inclusion of &gcompris; in your &Linux; distribution.</para></listitem>
<listitem><para>&Windows; : Delivered under a classic installer for &Windows;. This version requires an activation code. </para></listitem>
<listitem><para>MacOSX : Delivered under a classic installer. This version requires an activation code.</para></listitem>
</itemizedlist>
</sect1>
<sect1 id="user-interface">
<title>The User Interface</title>
<para>The interface is designed for easy use by small children. &gcompris; is controlled with a mouse,
it cannot be used without a mouse or a pointing system.</para>
<sect2 id="main-window">
<title>Main window</title>
<para>When you start the program, &gcompris; shows a graphic interface which presents the list of activities
with a control bar at the bottom.</para>
<screenshot>
<screeninfo>Here's a screenshot of &gcompris; Main Window</screeninfo>
<mediaobject>
<imageobject>
<imagedata fileref="gcompris-main-menu.png" format="PNG"/>
</imageobject>
<textobject>
<phrase>&gcompris; Main Window</phrase>
</textobject>
</mediaobject>
</screenshot>
<para>Each icon represents an activity. Around each one, you can find small icons which give additional information
about the activity. A simple click on the icon will lead you to an activity or a menu of activities. There are 8 sections
(categories) of activities, which placed on the top or on the left (only if your orientation is portrait). For example,
there is section "Board games", which includes board games, like chess, tic tac toe or align four</para>
<para>The stars indicates the age group for which each game is designed:</para>
<itemizedlist>
<listitem><para><inlinemediaobject><imageobject><imagedata fileref="difficulty1.svg" format="SVG"/></imageobject>
</inlinemediaobject>1, 2 or 3 yellow stars - for 2 to 6 years old.</para></listitem>
<listitem><para><inlinemediaobject><imageobject><imagedata fileref="difficulty4.svg" format="SVG"/></imageobject>
</inlinemediaobject>1, 2 or 3 red stars - greater than 6 years old.</para></listitem>
</itemizedlist>
<para>At the bottom of the screen there is a control bar for &gcompris;. The following icons are described below from
the right to the left (the icons are only displayed if they are available in the activity):</para>
<itemizedlist>
<listitem><para><inlinemediaobject><imageobject><imagedata fileref="bar_home.svg" format="SVG"/></imageobject>
</inlinemediaobject> Home - Leaves the current activity, returns to the previous menu.</para></listitem>
<listitem><para><inlinemediaobject><imageobject><imagedata fileref="bar_ok.svg" format="SVG"/></imageobject>
</inlinemediaobject> "OK" - Validate, confirm your answer. Some activities do not detect automatically whether or
not the child has completed the task. In this case, you have to click on this icon. You can also use the &Enter;
key on your keyboard.</para></listitem>
<listitem><para><inlinemediaobject><imageobject><imagedata fileref="bar_previous.svg" format="SVG"/></imageobject></inlinemediaobject>
<inlinemediaobject><imageobject><imagedata fileref="bar_next.svg" format="SVG"/></imageobject></inlinemediaobject>
Arrows - The present level is displayed. Click on one of the arrows to select another level.
Generally, the activities offer several levels whose numbers depend on the activity.
In &gcompris;, it is possible to go to the next level without having completed the current level.</para></listitem>
<listitem><para><inlinemediaobject><imageobject><imagedata fileref="bar_repeat.svg" format="SVG"/></imageobject>
</inlinemediaobject> Lips - Ask &gcompris; to repeat the question.</para></listitem>
<listitem><para><inlinemediaobject><imageobject><imagedata fileref="bar_help.svg" format="SVG"/></imageobject>
</inlinemediaobject> Question mark - Display the help dialog box. Sometimes, an activity can be too complex
to be described easily in the description area. In this case, this function gives access to additional information.</para></listitem>
<listitem><para><inlinemediaobject><imageobject><imagedata fileref="bar_config.svg" format="SVG"/></imageobject>
</inlinemediaobject> Tool box - Configuration menu. The configuration is saved in the user repository (folder)
under the name <filename>.config/gcompris/gcompris.conf</filename>. This is a text file which can be edited manually.</para></listitem>
<listitem><para><inlinemediaobject><imageobject><imagedata fileref="bar_about.svg" format="SVG"/></imageobject>
</inlinemediaobject> Capital "G" - Information box on &gcompris;, presents the main contributors and the version of the software.</para></listitem>
<listitem><para><inlinemediaobject><imageobject><imagedata fileref="bar_exit.svg" format="SVG"/></imageobject>
</inlinemediaobject> Power - Quit &gcompris;. You can also use the short cut on your keyboard
<keycombo action="simul">&Ctrl;<keycap>Q</keycap></keycombo></para></listitem>
</itemizedlist>
</sect2>
<sect2 id="kiosk-mode">
<title>Kiosk Mode</title>
<para>When you use &gcompris; with small children or on a self-service kiosk, you can disable a certain number of options:</para>
<itemizedlist>
<listitem><para><userinput><command>gcompris --disable-quit</command></userinput> : disable the <guiicon>Quit</guiicon> button.</para></listitem>
<listitem><para><userinput><command>gcompris -f</command></userinput> : run &gcompris; in fullscreen mode</para></listitem>
<listitem><para><userinput><command>gcompris -C</command></userinput> : disable the cursor (touch screen mode)</para></listitem>
</itemizedlist>
<para>These options can of course be combined.</para>
</sect2>
<sect2 id="keyboard-shortcuts">
<title>Keyboard Shortcuts</title>
<informaltable>
<tgroup cols="2">
<tbody>
<row>
<entry>Shortcut</entry>
<entry>Action</entry>
</row>
<row>
<entry>&Esc; or <keycombo action="simul">&Ctrl;<keycap>W</keycap></keycombo></entry>
<entry>Quit the current activity or dialog then return to the main menu</entry>
</row>
<row>
<entry><keycombo action="simul">&Ctrl;<keycap>Q</keycap></keycombo></entry>
<entry>Quit &gcompris; without further notice</entry>
</row>
<row>
<entry><keycombo action="simul">&Ctrl;<keycap>F</keycap></keycombo></entry>
<entry>Toggle fullscreen mode</entry>
</row>
<row>
<entry><keycombo action="simul">&Ctrl;<keycap>M</keycap></keycombo></entry>
<entry>Toggle sound mute</entry>
</row>
<row>
<entry><keycombo action="simul">&Ctrl;<keycap>B</keycap></keycombo></entry>
<entry>Display or Hide the control bar</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</sect2>
</sect1>
<sect1 id="internationalization">
<title>Notes on Internationalization</title>
<para>&gcompris; is internationalized and is available in more than 50 languages. If you want
to check if your language is available, you can start &gcompris; and select your language in
the option of configuration.</para>
<para>Be careful, your operating system must support your language so that &gcompris; can use it.
If you find a red cross while selecting a language in &gcompris;, this means that your system does not
support it, even if a translation is available in &gcompris;.</para>
<para>On &GNU;/&Linux;, if your language is not available, select another language support on your
distribution to add it. In most cases, you have to install an additional package 'locale-xx' or
'language-pack-xx' - xx is a language code such as 'En' for English. </para>
<para>If your language is not supported, you can contribute to the software and add the
translation of your language. If you are interested, you can contact the
-<ulink url="http://l10n.kde.org/teams">translation team</ulink> of
+<ulink url="https://l10n.kde.org/teams">translation team</ulink> of
the &kde; project for your language. You can check the level of translation for your language on
-the <ulink url="http://l10n.kde.org/">&kde; translation web site</ulink>.</para>
+the <ulink url="https://l10n.kde.org/">&kde; translation web site</ulink>.</para>
</sect1>
<sect1 id="learning-language">
<title>Language learning</title>
<para>You can use &gcompris; in a foreign language that you are learning. Select a foreign language
in the configuration menu. Do not forget to install the optional audio modules for this language in
your &GNU;/&Linux; distribution.</para>
<para>&Windows; version is provided with all audio support that are available. Whilst using &gcompris;
in another language it is possible to configure some activities more precisely using the audio set
through the administration module.</para>
</sect1>
<sect1 id="customizing-activities">
<title>Customizing activities</title>
<para>You can customize some activities using tool button in them. For example, you can set lang in
some text activities (like wordsgame), or make it show real car images instead of filled rectangles
(traffic)</para>
<screenshot>
<screeninfo>Select mode of activity "Traffic"</screeninfo>
<mediaobject>
<imageobject>
<imagedata fileref="traffic-select-mode.png" format="PNG"/>
</imageobject>
<textobject>
<phrase>Select mode of activity "Traffic"</phrase>
</textobject>
</mediaobject>
</screenshot>
</sect1>
<sect1 id="console-switches">
<title>Console Switches</title>
<para>Running &gcompris; from a command console with the --help option will display all the parameters it accepts:</para>
<informaltable>
<tgroup cols="2">
<tbody>
<row>
<entry>-f, --fullscreen</entry>
<entry>Run &gcompris; in fullscreen mode</entry>
</row>
<row>
<entry>-w, --window</entry>
<entry>Run &gcompris; in window mode</entry>
</row>
<row>
<entry>-s, --sound</entry>
<entry>Run &gcompris; with sound enabled</entry>
</row>
<row>
<entry>-m, --mute</entry>
<entry>Run &gcompris; without sound</entry>
</row>
<row>
<entry>-c, --cursor</entry>
<entry>Run &gcompris; with the default system cursor</entry>
</row>
<row>
<entry>-C, --nocursor</entry>
<entry>Run &gcompris; without cursor (touch screen mode)</entry>
</row>
<row>
<entry>-v, --version</entry>
<entry>Print the version of &gcompris;</entry>
</row>
<row>
<entry>--export-activities-as-sql</entry>
<entry>Export activities as SQL</entry>
</row>
<row>
<entry>--enable-config</entry>
<entry>Enable the config button (default)</entry>
</row>
<row>
<entry>--disable-config</entry>
<entry>Disable the config button</entry>
</row>
</tbody>
</tgroup>
</informaltable>
<sect2 id="windows-example">
<title>&Windows; Example</title>
<para>You can add these switches in the desktop icon properties. Here is an example that runs &gcompris; in kiosk mode in full screen, without config button and cursor:</para>
<para><userinput><command>"C:\Program Files\Gcompris\gcompris-qt.exe" --disable-config -f -C</command></userinput></para>
</sect2>
<sect2 id="gnu-linux-example">
<title>&GNU;/&Linux; Example</title>
<para>Create an application launcher and configure the command line parameters. Here is an example that runs &gcompris; in kiosk mode in full screen, without config button and cursor:</para>
<para><userinput><command>gcompris-qt --disable-config -f -C</command></userinput></para>
</sect2>
</sect1>
</chapter>
<chapter id="credits">
<title>Credits and License</title>
<para>
&gcompris;
</para>
<para>
-Program copyright 2000-2015 Bruno Coudoin and others
+Program copyright 2000-2018 Bruno Coudoin and others
</para>
<para>
Documentation Copyright see the
-<ulink url="http://gcompris.net/mediawiki-1.22.0/index.php?title=Manual&amp;action=history">Manual page history</ulink>
+<ulink url="https://gcompris.net/mediawiki-1.31.0/index.php?title=Manual&amp;action=history">Manual page history</ulink>
</para>
<!-- TRANS:CREDIT_FOR_TRANSLATORS -->
&underFDL; <!-- FDL: do not remove -->
&underGPL; <!-- GPL License -->
</chapter>
&documentation.index;
</book>
<!--
Local Variables:
mode: xml
sgml-minimize-attributes:nil
sgml-general-insert-case:lower
sgml-indent-step:0
sgml-indent-data:nil
End:
vim:tabstop=2:shiftwidth=2:expandtab
kate: space-indent on; indent-width 2; tab-width 2; indent-mode none;
-->
diff --git a/org.kde.gcompris.appdata.xml b/org.kde.gcompris.appdata.xml
index ca64b7904..cc1b2abc0 100644
--- a/org.kde.gcompris.appdata.xml
+++ b/org.kde.gcompris.appdata.xml
@@ -1,613 +1,739 @@
<?xml version="1.0" encoding="utf-8"?>
<component type="desktop">
<id>org.kde.gcompris.desktop</id>
<metadata_license>CC0-1.0</metadata_license>
<project_license>GPL-3.0+</project_license>
<name>GCompris Educational Game</name>
<name xml:lang="ar">لعبة «فهمت» التعليميّة</name>
<name xml:lang="ca">Joc educatiu GCompris</name>
<name xml:lang="ca-valencia">Joc educatiu GCompris</name>
<name xml:lang="de">GCompris-Lernspiel</name>
<name xml:lang="el">Εκπαιδευτικό παιχνίδι GCompris</name>
<name xml:lang="en-GB">GCompris Educational Game</name>
<name xml:lang="es">Juego educativo GCompris</name>
<name xml:lang="et">Hariv mäng GCompris</name>
<name xml:lang="fi">GCompris, opettavainen peli</name>
<name xml:lang="fr">Jeu éducatif GCompris</name>
<name xml:lang="gl">Xogo educativo GCompris</name>
<name xml:lang="hi">जीकोंप्रिस शेक्षणिक अनुप्रयोग</name>
- <name xml:lang="id">GCompris Permainan Edukatif</name>
+ <name xml:lang="id">Permainan Pendidikan GCompris</name>
<name xml:lang="it">Gioco didattico GCompris</name>
<name xml:lang="ko">GCompris 교육용 게임</name>
+ <name xml:lang="ml">ജികോംപ്രി വിദ്യാഭ്യാസപരമായ കളി</name>
<name xml:lang="nl">Educatief spel GCompris</name>
<name xml:lang="nn">GCompris leik-og-lær-spel</name>
<name xml:lang="pl">Gra edukacyjna GCompris</name>
<name xml:lang="pt">Jogo Educativo GCompris</name>
<name xml:lang="pt-BR">Jogo educacional GCompris</name>
- <name xml:lang="ro">Joc educațional GCompris</name>
+ <name xml:lang="ro">Jocul educațional GCompris</name>
<name xml:lang="ru">Набор обучающих игр GCompris</name>
<name xml:lang="sk">Výuková hra GCompris</name>
<name xml:lang="sl">Izobraževalna igra GCompris</name>
<name xml:lang="sv">GCompris pedagogiskt spel</name>
<name xml:lang="tr">GCompris Eğitici Oyun</name>
<name xml:lang="uk">Освітня гра GCompris</name>
<name xml:lang="x-test">xxGCompris Educational Gamexx</name>
<name xml:lang="zh-CN">GCompris 教育游戏</name>
<name xml:lang="zh-TW">GCompris 教育遊戲</name>
<summary>Multi-Activity Educational game for children 2 to 10</summary>
<summary xml:lang="ar">لعبة تعليميّة متعدّدة الأنشطة للأطفال من سنتين إلى ١٠ سنوات</summary>
- <summary xml:lang="ca">Joc educatiu amb múltiples activitats per a nens dels 2 a 10 anys</summary>
- <summary xml:lang="ca-valencia">Joc educatiu amb múltiples activitats per a nens dels 2 a 10 anys</summary>
+ <summary xml:lang="ca">Joc educatiu amb múltiples activitats per a infants de 2 a 10 anys</summary>
+ <summary xml:lang="ca-valencia">Joc educatiu amb múltiples activitats per a infants de 2 a 10 anys</summary>
<summary xml:lang="de">Lernspiel mit vielen Aktivitäten für Kinder von 2 bis 10 Jahren</summary>
<summary xml:lang="el">Εκπαιδευτικό παιχνίδι πολλαπλών δραστηριοτήτων για ηλικίες 2 έως 10 ετών</summary>
<summary xml:lang="en-GB">Multi-Activity Educational game for children 2 to 10</summary>
<summary xml:lang="es">Juego educativo multiactividad para niños de 2 a 10 años</summary>
<summary xml:lang="et">Rohkete tegevustega hariv mäng lastele vanuses 2-10</summary>
<summary xml:lang="fi">Useampitoimintoinen opettavainen peli 2–10-vuotiaille lapsille</summary>
<summary xml:lang="fr">Jeu éducatif multi-activités pour les enfants de 2 à 10 ans</summary>
<summary xml:lang="gl">Xogo educativo con varias actividades para nenos de entre 2 e 10 anos</summary>
<summary xml:lang="hi">२ से १० वर्ष के बच्चों के लिओ विभिन्न क्रियाओं वाला शेक्षणिक खेल</summary>
- <summary xml:lang="id">Permainan Edukatif Multi Aktivitas untuk anak berusia 2 sampai 10 tahun</summary>
+ <summary xml:lang="id">Permainan Pendidikan berisi berbagai kegiatan untuk anak-anak 2 hingga 10 tahun</summary>
<summary xml:lang="it">Gioco didattico multi-attività per bambini da 2 a 10 anni</summary>
<summary xml:lang="ko">2-10세 어린이를 위한 다양한 활동이 있는 교육용 게임</summary>
+ <summary xml:lang="ml">2 തൊട്ട് 10 വയസ്സുവരെയുള്ള കുട്ടികൾക്ക് വേണ്ടിയുള്ള വിവിധ-പ്രവർത്തനങ്ങളിലൂടെയുള്ള വിദ്യാഭ്യാസപരമായ കളി</summary>
<summary xml:lang="nl">Educatief spel met meerdere activiteiten voor kinderen van 2 tot 10</summary>
<summary xml:lang="nn">Leik-og-lærspel med mange aktivitetar – for barn frå 2 til 10 år</summary>
<summary xml:lang="pl">Gra edukacyjna z wieloma aktywnościami dla dzieci w wieku od 2 do 10 lat</summary>
<summary xml:lang="pt">Jogo Educativo Multi-Actividades para crianças dos 2 aos 10 anos</summary>
<summary xml:lang="pt-BR">Jogo educacional com várias atividades para crianças de 2 a 10 anos</summary>
<summary xml:lang="ro">Joc educațional cu activități multiple pentru copii între 2 și 10 ani</summary>
<summary xml:lang="ru">Интерактивные обучающие игры для детей от 2 до 10 лет</summary>
<summary xml:lang="sk">Viac-aktivitová výuková hra pre deti od 2 do 10 rokov</summary>
<summary xml:lang="sl">Izobraževalna igra z več dejavnostmi za otroke med drugim in desetim letom starosti</summary>
<summary xml:lang="sv">Pedagogiskt multiaktivitetsspel för barn från 2 till 10 år</summary>
<summary xml:lang="tr">2 ile 10 yaş arasındaki çocuklar için çok Etkinlikli oyun</summary>
<summary xml:lang="uk">Набір освітніх ігор для дітей від 2 до 10 років</summary>
<summary xml:lang="x-test">xxMulti-Activity Educational game for children 2 to 10xx</summary>
<summary xml:lang="zh-CN">为 2 到 10 岁儿童准备的多功能教育游戏</summary>
<summary xml:lang="zh-TW">為 2-10 歲孩子設計的教育遊戲</summary>
<description>
<p>GCompris is a high quality educational software suite, including a large number of activities for children aged 2 to 10.</p>
<p xml:lang="ar">«فهمت» هو طقم برمجيّات تعليميّة عالية الجودة يضمّ مختلف الأنشطة للأطفال من سنتين إلى ١٠ سنوات.</p>
<p xml:lang="ca">El GCompris és una suite de programari educatiu d'alta qualitat, que inclou una gran quantitat d'activitats per a nens i nenes entre els 2 i els 10 anys.</p>
<p xml:lang="ca-valencia">El GCompris és una suite de programari educatiu d'alta qualitat, que inclou una gran quantitat d'activitats per a nens i nenes entre els 2 i els 10 anys.</p>
<p xml:lang="cs">GCompris je vysoce kvalitní vzdělávací softwarový balík, skládající se z mnoha aktivit pro děti ve věku 2-10.</p>
<p xml:lang="de">GCompris ist eine Lernsoftware mit vielen Aktivitäten für Kinder im Alter von 2 bis 10 Jahren.</p>
<p xml:lang="el">Το GCompris είναι μια σουίτα εκπαιδευτικού λογισμικού με πολυάριθμες δραστηριότητες για παιδιά ηλικίας 2 έως 10 ετών.</p>
<p xml:lang="en-GB">GCompris is a high quality educational software suite, including a large number of activities for children aged 2 to 10.</p>
<p xml:lang="es">GCompris es un conjunto de programas educativos de alta calidad que contiene un gran número de actividades para niños entre 2 y 10 años.</p>
+ <p xml:lang="fi">GCompris on laadukas monitoimintoinen opetusohjelmisto 2–10-vuotiaille lapsille.</p>
<p xml:lang="fr">GCompris est un logiciel éducatif qui propose des activités variées aux enfants de 2 à 10 ans. Il est plébiscité par les écoles maternelles et primaires de part sa qualité et son spectre couvrant les cycles 1, 2 et 3.</p>
<p xml:lang="gl">GCompris é unha colección de programas educativos que inclúe numerosas actividades para nenas e nenos de entre 2 e 10 anos.</p>
<p xml:lang="hi">जीकॉम्परी एक शैक्षिक सॉफ्टवेयर सूट है जिसमें 2 से 10 वर्ष की आयु के बच्चों के लिए कई गतिविधियां शामिल हैं।</p>
- <p xml:lang="id">GCompris adalah kumpulan permainan mendidik yang berisi berbagai kegiatan untuk anak umur 2 sampai dengan 10 Tahun.</p>
+ <p xml:lang="id">GCompris adalah kumpulan permainan mendidik yang berisi berbagai kegiatan untuk anak umur 2 hingga 10 tahun.</p>
<p xml:lang="it">GCompris è una raccolta di alta qualità di programmi didattici che comprende numerose attività per bambini da 2 a 10 anni.</p>
+ <p xml:lang="ml">ജികോംപ്രി, വളരെ ഗുണനിലവാരമുള്ള വിദ്യാഭ്യാസപരമായ ഒരു സോഫ്റ്റുവെയർ ആണ്, ഇതിൽ 2 തൊട്ട് 10 വയസ്സുവരെയുള്ള കുട്ടികൾക്ക് വേണ്ടിയുള്ള വിവിധ-പ്രവർത്തനങ്ങൾ അടങ്ങിയിരിക്കുന്നു.</p>
<p xml:lang="nl">GCompris is een educatief softwarepakket van hoge kwaliteit, inclusief een groot aantal activiteiten voor kinderen van 2 tot 10 jaar.</p>
<p xml:lang="nn">GCompris er eit leik og lær-spel med mange ulike aktivitetar for ungar frå 2 til 10 år.</p>
<p xml:lang="pl">GCompris to wysokiej jakości pakiet oprogramowania edukacyjnego z licznymi aktywnościami dla dzieci w wieku od 2 do 10 lat.</p>
- <p xml:lang="pt">O GCompris é um pacote de aplicações educativas que é composto por diversas actividades para as crianças dos 2 aos 10 anos de idade.</p>
- <p xml:lang="pt-BR">O GCompris é uma suíte educacional de alta qualidade, que inclui uma grande quantidade de atividades para crianças com idade entre 2 e 10 anos.</p>
+ <p xml:lang="pt">O GCompris é um pacote aplicacional educativo de alta qualidade, composto por uma grande quantidade de actividades para crianças dos 2 aos 10 anos.</p>
+ <p xml:lang="pt-BR">O GCompris é uma suíte de software educacional de alta qualidade que inclui um grande número de atividades para crianças com idade entre 2 e 10 anos.</p>
<p xml:lang="ro">GCompris este un pachet de software educațional compus din numeroase activități pentru copii între 2 și 10 ani.</p>
<p xml:lang="ru">GCompris — большая коллекция обучающих игр и упражнений для детей от 2 до 10 лет.</p>
<p xml:lang="sl">Program GCompris je visokokakovostna izobraževalna zbirka, sestavljena iz velikega števila dejavnosti, ki so namenjena otrokom med drugim in desetim letom starosti.</p>
<p xml:lang="sv">GCompris är en högkvalitativ pedagogisk programvarusvit som innehåller ett stort antal aktiviteter för barn mellan 2 och 10 år.</p>
<p xml:lang="tr">GCompris, 2 ile 10 yaş arasındaki çocuklar için çok sayıda etkinlik içeren bir eğitim yazılımı paketidir.</p>
<p xml:lang="uk">GCompris — високоякісний комплекс навчального програмного забезпечення, що складається з багатьох вправ для дітей від 2 до 10 років.</p>
<p xml:lang="x-test">xxGCompris is a high quality educational software suite, including a large number of activities for children aged 2 to 10.xx</p>
+ <p xml:lang="zh-TW">GCompris 是一套教育軟體的集合,它提供適合兩歲到十歲兒童各種不同的遊戲。</p>
<p>Some of the activities are game orientated, but nonetheless
still educational.</p>
<p xml:lang="ar">بعض الأنشطة هدفها الترفيه، ولكنّها -مع ذلك- تعليميّة.</p>
<p xml:lang="ca">Algunes de les activitats estan orientades a joc, però sempre són educatives.</p>
<p xml:lang="ca-valencia">Algunes de les activitats estan orientades a joc, però sempre són educatives.</p>
<p xml:lang="cs">Některé aktivity jsou v podobě her, ale přesto jsou poučné.</p>
<p xml:lang="de">Einige Aktivitäten sind eher spielerisch, aber immer lehrreich.</p>
<p xml:lang="el">Ορισμένες από τις δραστηριότητες είναι απλώς παιχνίδια, αλλά οπωσδήποτε με εκπαιδευτικό χαρακτήρα.</p>
<p xml:lang="en-GB">Some of the activities are game orientated, but nonetheless still educational.</p>
<p xml:lang="es">Algunas de las actividades son juegos, aunque siguen siendo educativas.</p>
<p xml:lang="et">Mõned tegevused on mängulisemad, aga siiski õppeotstarbega.</p>
<p xml:lang="fi">Jotkin toiminnoista ovat pelimäisiä mutta silti opettavaisia.</p>
<p xml:lang="fr">Certaines activités sont ludiques mais ont toujours un intérêt pédagogique.</p>
<p xml:lang="gl">Algunhas das actividades están orientadas ao xogo, pero son aínda así educativas.</p>
<p xml:lang="hi">कुछ गतिविधियां खेल केंद्रित हैं, लेकिन फिर भी शैक्षिक हैं।</p>
- <p xml:lang="id">Beberapa aktivitas mengacu ke permainan, namun tetap saja mendidik.</p>
+ <p xml:lang="id">Beberapa kegiatan berorientasi pada permainan, tetapi masih memiliki nilai pendidikan.</p>
<p xml:lang="it">Alcune delle attività sono orientate al gioco, ma comunque didattiche.</p>
<p xml:lang="ko">일부 활동은 기능성 게임을 지향합니다.</p>
+ <p xml:lang="ml">ചില പ്രവർത്തനങ്ങൾ കളിയെ അടിസ്ഥാനമാക്കിയാണ്, പക്ഷേ അവയും വിദ്യാഭ്യാസപരമാണ്.</p>
<p xml:lang="nl">Sommige activiteiten zijn spelletjes, maar toch leerzaam.</p>
<p xml:lang="nn">Nokre av aktivitetane er mest som spel, men er likevel lærerike.</p>
<p xml:lang="pl">Niektóre z aktywności są bardziej grą, lecz nadal bardzo pouczającą.</p>
<p xml:lang="pt">Algumas das actividades são apresentadas como jogos, mas são educativas à mesma.</p>
- <p xml:lang="pt-BR">Algumas das atividades são de orientação lúdica, mas mesmo assim ainda educacional.</p>
+ <p xml:lang="pt-BR">Algumas das atividades são de orientação lúdica, mas mesmo assim ainda educacionais.</p>
<p xml:lang="ro">Unele activități sunt orientate pe joacă, dar totuși educative.</p>
<p xml:lang="ru">Некоторые из заданий представлены в игровой форме, но и они являются обучающими.</p>
<p xml:lang="sk">Niektoré z aktivít sú herne orientované, ale stále výukové.</p>
<p xml:lang="sl">Nekatere dejavnosti so bolj podobne igram, vendar še vedno poučne.</p>
<p xml:lang="sv">Vissa av aktiviteterna är spelorienterade, men trots det ändå pedagogiska.</p>
<p xml:lang="tr">Bazı etkinlikler oyun odaklıdır, ancak yine de eğiticidir.</p>
<p xml:lang="uk">Деякі із вправ є суто ігровими, але містять і елементи навчання.</p>
<p xml:lang="x-test">xxSome of the activities are game orientated, but nonetheless still educational.xx</p>
<p xml:lang="zh-CN">一些活动是游戏导向的,不过尽管如此仍是教育性的。</p>
<p xml:lang="zh-TW">有些活動是遊戲性質,但還是有很棒的教育意義。</p>
<p>Below you can find a list of categories with some of the
activities available in that category.</p>
<p xml:lang="ar">يمكنك أن تجد أدناه قائمة بالفئات وبعض الأنشطة الموجودة في كل فئة.</p>
<p xml:lang="ca">A continuació trobareu una llista de les categories amb algunes de les activitats disponibles en cadascuna.</p>
<p xml:lang="ca-valencia">A continuació trobareu una llista de les categories amb algunes de les activitats disponibles en cadascuna.</p>
<p xml:lang="de">Sie können Aktivitäten aus folgenden Bereichen in GCompris finden:</p>
<p xml:lang="el">Παρακάτω θα βρείτε μια λίστα με κατηγορίες που περιέχουν ορισμένες από το σύνολο των δραστηριοτήτων σε κάθε κατηγορία.</p>
<p xml:lang="en-GB">Below you can find a list of categories with some of the activities available in that category.</p>
<p xml:lang="es">A continuación puede encontrar una lista de categorías con algunas de las actividades disponibles en cada una de ellas.</p>
<p xml:lang="et">Allpool leiab kategooriate loetelu koos mõningate neile omaste tegevustega.</p>
<p xml:lang="fi">Alta löydät luettelot luokista sekä maininnan joistakin kuhunkin luokkaan kuuluvista toiminnoista.</p>
<p xml:lang="fr">Vous pouvez trouver ci-dessous une liste des catégories avec certaines de leurs activités.</p>
<p xml:lang="gl">A continuación atopará unha lista de categorías e as actividades dispoñíbeis en cada unha desas categorías.</p>
<p xml:lang="hi">नीचे आप उस श्रेणी में उपलब्ध कुछ गतिविधियों के साथ श्रेणियों की एक सूची पा सकते हैं।</p>
- <p xml:lang="id">Di bawah ini kamu dapat menemukan daftar kategori-kategori dengan beberapa aktivitas-aktivitas yang tersedia dalam kategori tersebut.</p>
+ <p xml:lang="id">Di bawah ini kamu dapat menemukan daftar kategori dengan beberapa kegiatan yang tersedia di dalam setiap kategori tersebut.</p>
<p xml:lang="it">Di seguito puoi trovare un elenco di categorie con alcune delle attività disponibili per categoria.</p>
<p xml:lang="ko">아래에서 분류 목록과 해당 분류의 활동을 찾을 수 있습니다.</p>
+ <p xml:lang="ml">താഴെ, വിഭാഗങ്ങളുടെ ഒരു പട്ടിക നിങ്ങൾക്ക് കാണാം, ആ വിഭാഗങ്ങളിൽ ചില പ്രവർത്തനങ്ങളും ലഭ്യമാണ്.</p>
<p xml:lang="nl">Hieronder vindt u een lijst met categorieën met enige van de activiteiten beschikbaar in die categorie.</p>
<p xml:lang="nn">Nedanfor finn du ei oversikt over kategoriar, saman med nokre av aktivitetane i kvar kategori.</p>
<p xml:lang="pl">Poniżej znajdziesz wykaz kategorii z niektórymi aktywnościami dostępnymi w tej kategorii.</p>
<p xml:lang="pt">Em baixo, poderá encontrar uma lista de categorias, com algumas das actividades disponíveis para essa categoria.</p>
<p xml:lang="pt-BR">Abaixo está relacionada uma lista de categorias com algumas das atividades disponíveis em cada uma delas.</p>
<p xml:lang="ro">Dedesubt puteți găsi o listă de categorii cu unele din activitățile disponibile în acea categorie.</p>
<p xml:lang="ru">Ниже представлен список категорий с доступными в этих категориях заданиями.</p>
<p xml:lang="sk">Tu môžete nájsť zoznam kategórií s niektorými aktivitami dostupnými v kategórii.</p>
<p xml:lang="sl">Spodaj lahko najdete seznam kategorij in nekaj dejavnosti, ki so na voljo v tisti kategoriji.</p>
<p xml:lang="sv">Nedan finns en lista över kategorier med några av aktiviteterna tillgängliga i varje kategori.</p>
<p xml:lang="tr">Aşağıda, bazı etkinliklerin bulunduğu kategorilerin bir listesini bulabilirsiniz.</p>
<p xml:lang="uk">Нижче наведено список категорій із деякими вправами у цих категоріях.</p>
<p xml:lang="x-test">xxBelow you can find a list of categories with some of the activities available in that category.xx</p>
<p xml:lang="zh-CN">下面列出了一些分类和对应分类中的活动。</p>
- <p xml:lang="zh-TW">下方您可以看到該類別的活動清單。</p>
+ <p xml:lang="zh-TW">下方您可以看到該類別的遊戲清單。</p>
<ul>
<li>computer discovery: keyboard, mouse, different mouse gestures, ...</li>
<li xml:lang="ar">استكشاف الحاسوب: لوحة المفاتيح والفأرة ومختلف إيماءات الفأرة وغيرها.</li>
<li xml:lang="ca">descobrir l'ordinador: teclat, ratolí, diferents gestos del ratolí...</li>
<li xml:lang="ca-valencia">descobrir l'ordinador: teclat, ratolí, diferents gestos del ratolí...</li>
<li xml:lang="de">Entdeckung des Computers: Tastatur, Maus, verschiedene Mausgesten ...</li>
<li xml:lang="el">ανακαλύπτω τον υπολογιστή: πληκτρολόγιο, ποντίκι, διάφορες ενδείξεις δείκτη ποντικιού, ...</li>
<li xml:lang="en-GB">computer discovery: keyboard, mouse, different mouse gestures, ...</li>
<li xml:lang="es">descubrimiento del ordenador: teclado, ratón, distintos gestos con el ratón...</li>
<li xml:lang="et">arvuti tundmaõppimine: klaviatuur, hiir, erinevad hiireliigutused ...</li>
<li xml:lang="fi">tietokoneen oppiminen: näppäimistö, hiiri, eri hiirieleet…</li>
<li xml:lang="fr">découverte de l'ordinateur : clavier, souris, mouvements de la souris…</li>
<li xml:lang="gl">Descubrimento do computador: teclado, rato, xestos do rato, etc.</li>
<li xml:lang="hi">कंप्यूटर की खोज: कीबोर्ड, माउस, अलग माउस इशारों, ...</li>
- <li xml:lang="id">penemuan komputer: keyboard, mos, perbedaan pergerakan mos, ..</li>
+ <li xml:lang="id">Pengenalan komputer: keyboard, mouse, gerakan mouse yang berbeda, ...</li>
<li xml:lang="it">scoperta del computer: tastiera, mouse, vari gesti con il mouse, ...</li>
<li xml:lang="ko">컴퓨터와 친해지기: 키보드, 마우스, 마우스 제스처, ...</li>
+ <li xml:lang="ml">കമ്പ്യൂട്ടർ പഠിക്കാം: കീബോർഡ്, മൗസ്, മൗസ് കൊണ്ടുള്ള വ്യത്യസ്ത ചലനങ്ങൾ, ...</li>
<li xml:lang="nl">ontdekken van de computer: toetsenbord, muis, verschillende muisbewegingen, ...</li>
<li xml:lang="nn">datamaskin: tastatur, mus, ulike muserørsler, …</li>
<li xml:lang="pl">odkrywanie komputera: klawiatura, mysz, różne ruchy myszą, ...</li>
<li xml:lang="pt">descoberta do computador: teclado, rato, os diferentes gestos com o rato, ...</li>
<li xml:lang="pt-BR">conhecendo o computador: teclado, mouse, diferentes movimentações com o mouse, ...</li>
<li xml:lang="ro">descoperirea calculatorului: tastatura, mausul, diferite gesturi cu mausul, ...</li>
<li xml:lang="ru">знакомство с компьютером: клавиатура, мышь, различные жесты мышью, ...</li>
<li xml:lang="sk">objavovanie počítača: klávesnica, myš, rôzne gestá myši...</li>
<li xml:lang="sl">delo z računalnikom: tipkovnica, miška, kretnje miške, ...</li>
<li xml:lang="sv">upptäcka datorn: tangentbord, mus, olika musgester, ...</li>
<li xml:lang="tr">bilgisayarı keşfetme: klavye, fare, farklı fare hareketleri, ...</li>
<li xml:lang="uk">Знайомство з комп’ютером: клавіатура, миша, керування мишею…</li>
<li xml:lang="x-test">xxcomputer discovery: keyboard, mouse, different mouse gestures, ...xx</li>
<li xml:lang="zh-CN">探索电脑:键盘、鼠标、不同的鼠标手势……</li>
<li xml:lang="zh-TW">電腦探索:鍵盤、滑鼠、不同的滑鼠手勢等</li>
<li>arithmetic: table memory, enumeration, mirror image, balance
the scale, change giving, ...</li>
<li xml:lang="ar">الحساب: جدول الضرب والعدّ وصورة المرآة وموازنة كفّتا الميزان وإعطاء الباقي وغيرها.</li>
<li xml:lang="ca">aritmètica: memoritzar la taula, enumeració, imatge al mirall, equilibrar la balança, donar el canvi...</li>
<li xml:lang="ca-valencia">aritmètica: memoritzar la taula, enumeració, imatge al mirall, equilibrar la balança, donar el canvi...</li>
<li xml:lang="de">Arithmetik: Kombitabellen, Aufzählungen, Bilder spiegeln, Gewichte ausgleichen, Wechselgeld geben...</li>
<li xml:lang="el">αριθμητική: μνημονικός πίνακας, απαρίθμηση, κάτοπτρο, ισορροπώ τη ζυγαριά, δίνω ρέστα, ...</li>
<li xml:lang="en-GB">arithmetic: table memory, enumeration, mirror image, balance the scale, change giving, ...</li>
<li xml:lang="es">aritmética: memorización de tablas, enumeración, imagen especular, equilibrar la balanza, devolver cambios...</li>
<li xml:lang="et">aritmeetika: nähtu mäletamine, loendamine, peegelpildid, kaalu tasakaalustamine, raha tagasiandmine...</li>
<li xml:lang="fi">aritmetiikka: kertotaulujen opettelu, laskutehtävät, peilikuvan piirtäminen, vaa’an tasapainottaminen, vaihtorahan antaminen, …</li>
<li xml:lang="fr">arithmétique : apprentissage des tables d'opérations mathématiques, l'énumération, de symétrie d'image, équilibrage de la balance, rendre la monnaie…</li>
<li xml:lang="gl">Aritmética: táboas de memoria, enumeración, imaxes espello, equilibrio de balanzas, cálculo do cambio, etc.</li>
<li xml:lang="hi">अंकगणितीय: तालिका मेमोरी, गणण, दर्पण छवि, पैमाने संतुलन, देय परिवर्तन, ...</li>
<li xml:lang="id">aritmatika: tabel ingatan, pencacahan, cerminan gambar, menyeimbangkan skala, ganti memberi, ..</li>
<li xml:lang="it">aritmetica: tabelline, enumerazione, immagine speculare, allineare la bilancia, dare il resto, ...</li>
<li xml:lang="ko">산술 연산: 표 기억하기, 배열하기, 그림 뒤집기, 저울 맞추기, 거스름돈 계산하기, ...</li>
+ <li xml:lang="ml">ഗണിതശാസ്ത്രം: പട്ടിക ഓർക്കാം, എണ്ണൽ, കണ്ണാടി ചിത്രം, തൂക്കമൊപ്പിക്കാം, ബാക്കി കൊടുക്കാം, ...</li>
<li xml:lang="nl">rekenen: tafels oefenen, reeksen, afbeelding spiegelen, de schaal in evenwicht brengen, wisselgeld geven, ...</li>
<li xml:lang="nn">rekning: gongetabellen, teljing, spegelbilete, måling av vekt, vekslepengar, …</li>
<li xml:lang="pl">arytmetyka: tablice pamięciowe, wyliczanie, obraz lustrzany, wyrównoważanie wagi, wydawanie reszty, ...</li>
<li xml:lang="pt">aritmética: memória da tabuada, enumeração, imagem-espelho, equilíbrio de balanças, trocos, ...</li>
<li xml:lang="pt-BR">matemática: memória matemática, enumeração, imagens espelhadas, balanceamento de escalas, moedas e troco, ...</li>
- <li xml:lang="ro">aritmetică: tabla înmulțirii, enumerări, imagini în oglindă, echilibrează balanța, darea restului, ...</li>
+ <li xml:lang="ro">aritmetică: tabla înmulțirii, enumerări, imagini în oglindă, echilibrarea balanței, datul restului, ...</li>
<li xml:lang="ru">арифметика: игра «память» с подсчётом, счёт, отражение рисунка, уравновешивание весов, подсчёт сдачи, ...</li>
<li xml:lang="sk">aritmetické: tabuľková pamäť, výpočet, zrkalový obrázok, vyváženie mierky, zmena dávky...</li>
<li xml:lang="sl">računstvo: spomin z računi, štetje, uravnoteži tehtnico, vračanje drobiža, ...</li>
<li xml:lang="sv">aritmetik: tabellminne, uppräkning, spegelbild, balansera vågen, ge växel, ...</li>
<li xml:lang="tr">aritmetik: tablo belleği, numaralandırma, ayna görüntüsü, ölçeği dengelemek, para üstü, ...</li>
<li xml:lang="uk">Арифметика: запам’ятовування таблиць, нумерація, віддзеркалення, балансування масштабу, обчислення решти…</li>
<li xml:lang="x-test">xxarithmetic: table memory, enumeration, mirror image, balance the scale, change giving, ...xx</li>
<li xml:lang="zh-CN">算数:表格记忆、枚举、镜像、天平、找零……</li>
<li xml:lang="zh-TW">數學運算:表格記憶、列舉、影像映射、平衡、找零計算等</li>
<li>science: the canal lock, color mixing, gravity concept, ...</li>
<li xml:lang="ar">العلوم: قفل القناة ومزج الألوان ومفهوم الجاذبيّة وغيرها.</li>
<li xml:lang="ca">ciència: blocar el canal, barreja de colors, el concepte de la gravetat...</li>
<li xml:lang="ca-valencia">ciència: blocar el canal, barreja de colors, el concepte de la gravetat...</li>
<li xml:lang="de">Wissenschaft: Kanalschleuse, Farbmischung, Gravitation,...</li>
<li xml:lang="el">επιστήμη: σύστημα αλλαγής στάθμης ροής, ανάμειξη χρωμάτων, η έννοια της βαρύτητας, ...</li>
<li xml:lang="en-GB">science: the canal lock, colour mixing, gravity concept, ...</li>
<li xml:lang="es">ciencia: la esclusa de un canal, mezcla de colores, concepto de gravedad...</li>
<li xml:lang="et">loodusteadused: kanali lüüs, värvide segamine, gravitatsiooni mõistmine...</li>
<li xml:lang="fi">tiede: kanavasulku, värien sekoitus, painovoiman käsite…</li>
<li xml:lang="fr">science : fonctionnement d'une écluse, mélange des couleurs, concept de la gravité…</li>
<li xml:lang="gl">Ciencia: o bloqueo da canle, mestura de cores, o concepto de gravidade, etc.</li>
<li xml:lang="hi">विज्ञान: नहर लॉक, रंग मिश्रण, गुरुत्वाकर्षण अवधारणा, ...</li>
<li xml:lang="id">ilmu pengetahuan: kunci kanal, pencampuran warna, konsep gravitasi, ...</li>
<li xml:lang="it">scienza: la chiusa del canale, miscelazione dei colori, il concetto di gravità, ...</li>
<li xml:lang="ko">과학: 운하 갑문, 색 섞기, 중력, ...</li>
+ <li xml:lang="ml">ശാസ്ത്രം: കനാലിൻ്റെ പൂട്ട്, നിറം ചേർക്കാം, ഗുരുത്വം എന്ന ആശയം, ...</li>
<li xml:lang="nl">natuurkunde: de sluizen bedienen, mengen van kleuren, concept van zwaartekracht, ...</li>
<li xml:lang="nn">vitskap: kanalsluse, blanding av fargar, tyngdekraft, …</li>
<li xml:lang="pl">nauka: śluza na kanale, mieszanie barw, poczucie grawitacji, ...</li>
<li xml:lang="pt">ciência: bloqueio de canais, misturas de cores, conceito de gravidade, ...</li>
<li xml:lang="pt-BR">ciência: comporta de canal, mistura de cores, conceito de gravidade, ...</li>
- <li xml:lang="ro">științe: podul mobil, combinarea culorilor, gravitația, ...</li>
+ <li xml:lang="ro">științe: ecluza unui canal, amestecul culorilor, conceptul de gravitație, ...</li>
<li xml:lang="ru">наука: работа судоходного шлюза, смешивание цветов, представление о гравитации, ...</li>
<li xml:lang="sk">veda: zamknutý kanál, miešanie farieb, koncept grvitácie...</li>
<li xml:lang="sl">znanost: zapornica kanala, mešanje barv, koncept težnosti ...</li>
<li xml:lang="sv">vetenskap: kanalslussen, färgblandning, gravitationskonceptet, ...</li>
<li xml:lang="tr">bilim: kanal kilidi, renk karışımı, yerçekimi kavramı, ...</li>
<li xml:lang="uk">Наука: шлюзування, змішування кольорів, поняття тяжіння…</li>
<li xml:lang="x-test">xxscience: the canal lock, color mixing, gravity concept, ...xx</li>
<li xml:lang="zh-CN">科学:运河闸门、颜料色彩混合、重力的概念……</li>
<li xml:lang="zh-TW">科學:顏色混合、重力觀念、運河鎖等等</li>
<li>games: memory, connect 4, tic tac toe, sudoku, hanoi tower, ...</li>
<li xml:lang="ar">الألعاب: الذاكرة و«وصّل ٤» و"إكس-أُو" و«سودوكو»، وبرج هانوي وغيرها.</li>
<li xml:lang="ca">jocs: memòria, connectar 4, tres en ratlla, sudoku, torre de Hanoi...</li>
<li xml:lang="ca-valencia">jocs: memòria, connectar 4, tres en ratlla, sudoku, torre de Hanoi...</li>
<li xml:lang="de">Spiele: Memory, Vier gewinnt, Tic-Tac-Toe, Sudoku, Türme von Hanoi,...</li>
<li xml:lang="el">παιχνίδια: μνήμη, τετράδες, τρίλιζα, σουντόκου, πύργος του Ανόι, ...</li>
<li xml:lang="en-GB">games: memory, connect 4, tic tac toe, sudoku, hanoi tower, ...</li>
<li xml:lang="es">juegos: memoria, conectar 4, tres en raya, sudoku, torres de hanoi...</li>
<li xml:lang="et">mängud: mälu, nelja ühendamine, trips-traps-trull, sudoku, Hanoi tornid...</li>
<li xml:lang="fi">pelit: muisti, neljän suora, ristinolla, sudoku, Hanoin tornit…</li>
<li xml:lang="fr">jeux : trouve les paires, puissance 4, morpion, sudoku, la tour d'hanoï…</li>
<li xml:lang="gl">Xogos: memoria, conectar 4, pai nai fillo, sudoku, torre de Hanoi, etc.</li>
<li xml:lang="hi">खेल: स्मृति, कनेक्ट 4, टिक टैक टो , सुडोकू, हनोई टॉवर, ...</li>
- <li xml:lang="id">permainan: ingatan, menyambung 4, tic tac toe, sudoku, menara hanoi, ...</li>
+ <li xml:lang="id">permainan: ingatan, menyambungkan 4, tic tac toe, sudoku, menara hanoi, ...</li>
<li xml:lang="it">giochi: memory, forza 4, filetto, sudoku, torre di hanoi, ...</li>
<li xml:lang="ko">게임: 메모리 게임, 4개 연결하기, 삼목, 수도쿠, 하노이 탑, ...</li>
+ <li xml:lang="ml">കളികൾ: ഓർമ്മ, 4 എണ്ണം ബന്ധിപ്പിക്കുക, ടിക് ടാക് ടോ, ഹാനോയിയുടെ ഗോപുരം, ...</li>
<li xml:lang="nl">spellen: geheugenspel, vier op een rij, boter kaas en eieren, sudoku, torens van hanoi, ...</li>
<li xml:lang="nn">spel: hugsespel, fire på rad, bondesjakk, sudoku, tårnet i Hanoi, …</li>
<li xml:lang="pl">gry: na pamięć, łączenie czwórek, tic tac toe, sudoku, wieża hanoi, ...</li>
<li xml:lang="pt">jogos: memória, 4 em linha, jogo do galo, sudoku, torres de Hanói, ...</li>
- <li xml:lang="pt-BR">jogos: memória, ligue 4, jogo da velha, sudoku, torre de Hanoi, ...</li>
+ <li xml:lang="pt-BR">jogos: memória, ligue 4, jogo da velha, sudoku, torre de Hanói, ...</li>
<li xml:lang="ro">jocuri: memorie, leagă 4, X și 0, sudoku, turnul hanoi, ...</li>
<li xml:lang="ru">игры: память, соедини 4, крестики-нолики, судоку, Ханойская башня, ...</li>
<li xml:lang="sk">hry: pamäť, spojenie 4, tic tac toe, sudoku, hanojská veža...</li>
<li xml:lang="sl">igre: spomin, štiri v vrsto, križci in krožci, sudoku, Hanojski stolpi, ...</li>
<li xml:lang="sv">spel: memory, koppla 4, tre-i-rad, sudoku, tornen i Hanoi, ...</li>
<li xml:lang="tr">oyunlar: hafıza, dörtleme, üç taş, sudoku, hanoi kulesi, ...</li>
<li xml:lang="uk">Ігри: запам’ятовування, чотири-у-рядок, хрестики-нулики, судоку, ханойські вежі…</li>
<li xml:lang="x-test">xxgames: memory, connect 4, tic tac toe, sudoku, hanoi tower, ...xx</li>
<li xml:lang="zh-CN">游戏:记忆、四子棋、井子棋、数独、汉诺塔……</li>
<li xml:lang="zh-TW">遊戲:記憶遊戲、四子棋、井字遊戲、數獨、河內塔等等</li>
<li>reading: reading practice, ...</li>
<li xml:lang="ar">القراءة: ممارسة القراءة وغيرها.</li>
<li xml:lang="ca">lectura: practicar la lectura...</li>
<li xml:lang="ca-valencia">lectura: practicar la lectura...</li>
<li xml:lang="de">Lesen: Leseübungen ...</li>
<li xml:lang="el">ανάγνωση: εξάσκηση στην ανάγνωση, ...</li>
<li xml:lang="en-GB">reading: reading practice, ...</li>
<li xml:lang="es">lectura: prácticas de lectura...</li>
<li xml:lang="et">lugemine</li>
<li xml:lang="fi">lukeminen: lukemisen harjoittelu…</li>
<li xml:lang="fr">lecture : entraînement à la lecture…</li>
<li xml:lang="gl">Lectura: práctica de lectura, etc.</li>
<li xml:lang="hi">पढ़ना: पढ़ना अभ्यास, ...</li>
<li xml:lang="id">membaca: latihan membaca, ...</li>
<li xml:lang="it">lettura: esercitare la lettura, ...</li>
<li xml:lang="ko">읽기: 읽기 연습, ...</li>
+ <li xml:lang="ml">വായന: വായന പരിശീലനം, ...</li>
<li xml:lang="nl">lezen: lees oefening, ...</li>
<li xml:lang="nn">lesing: leseøvingar, …</li>
<li xml:lang="pl">czytanie: nauka czytania, ...</li>
<li xml:lang="pt">leitura: exercícios de leitura, ...</li>
<li xml:lang="pt-BR">leitura: prática de leitura, ...</li>
<li xml:lang="ro">citire: exerciții de citire, ...</li>
<li xml:lang="ru">чтение: упражнение в чтении, ...</li>
<li xml:lang="sk">čítanie: precvičovanie čítania...</li>
<li xml:lang="sl">branje: bralna vaja, ...</li>
<li xml:lang="sv">läsning: läsningsövning, ...</li>
<li xml:lang="tr">okuma: okuma egzersizi, ...</li>
<li xml:lang="uk">Читання: вправи із читання…</li>
<li xml:lang="x-test">xxreading: reading practice, ...xx</li>
<li xml:lang="zh-CN">阅读:阅读练习……</li>
<li xml:lang="zh-TW">閱讀:閱讀練習等等</li>
<li>other: learn to tell time, the braille system, maze, music
instruments, ...</li>
<li xml:lang="ar">أخرى: تعلّم قراءة الوقت ونظام «بريل» وألغاز متاهات والآلات الموسيقيّة وغيرها.</li>
<li xml:lang="ca">altres: aprendre a dir l'hora, el sistema braille, laberint, instruments musicals...</li>
<li xml:lang="ca-valencia">altres: aprendre a dir l'hora, el sistema braille, laberint, instruments musicals...</li>
<li xml:lang="de">Sonstiges: Uhrzeit, Braille-System, Labyrinthe, Musikinstrumente ...</li>
<li xml:lang="el">άλλα: μαθαίνω να λέω την ώρα, το σύστημα braille, λαβύρινθος, μουσικά όργανα, ...</li>
<li xml:lang="en-GB">other: learn to tell time, the braille system, maze, music instruments, ...</li>
<li xml:lang="es">otras: aprender a decir la hora, el sistema braille, laberintos, instrumentos musicales...</li>
<li xml:lang="et">muu: kellaaja väljendamine, Braille'i kiri, labürint, muusikariistad...</li>
<li xml:lang="fi">muuta: kellonajan kertominen, Braille-järjestelmä, sokkelo, soittimet…</li>
<li xml:lang="fr">autre : apprendre à dire l'heure, le système braille, le labyrinthe, les instruments de musique…</li>
<li xml:lang="gl">Outros: aprender a dicir as horas, o sistema braille, labirinto, instrumentos musicais, etc.</li>
<li xml:lang="hi">अन्य: समय बताओ, ब्रेल प्रणाली, भूलभुलैया, संगीत वाद्ययंत्र, ...</li>
<li xml:lang="id">lainnya: belajar menceritakan waktu, sistem braille, labirin, alat musik, ...</li>
<li xml:lang="it">altro: impara a leggere l'ora, il sistema braille, labirinto, strumenti musicali, ...</li>
<li xml:lang="ko">기타: 시간 읽기, 점자, 미로, 악기, ...</li>
+ <li xml:lang="ml">മറ്റുള്ളവ: സമയം പറയാൻ പഠിക്കാം, ബ്രായി ലിപി, കുടുക്കുവഴി, സംഗീതോപകരണങ്ങൾ, ...</li>
<li xml:lang="nl">overig: leren klokkijken, het braille-systeem, doolhof, muziekinstrumenten, ...</li>
<li xml:lang="nn">anna: lær klokka, lær blindeskrift, labyrint, musikkinstrument, …</li>
<li xml:lang="pl">inne: naucz się godzin na zegarze, systemu brajla, labiryntów, instrumentów muzycznych, ...</li>
<li xml:lang="pt">outros: aprender a dizer as horas, o sistema Braille, labirintos, instrumentos musicais, ...</li>
<li xml:lang="pt-BR">outros: aprendendo a ver as horas, o sistema Braille, labirintos, instrumentos musicais, ...</li>
<li xml:lang="ro">altele: învață să citești ceasul, sistemul braille, labirint, instrumente muzicale, ...</li>
<li xml:lang="ru">другое: определение времени по часам, шрифт Брайля, лабиринт, музыкальные инструменты, ...</li>
<li xml:lang="sk">iné: ako povedať čas, braillov systém, bludisko, hudobná nástroje...</li>
<li xml:lang="sl">ostalo: prepoznavanje časa, brajica, blodnjak, glasbila, ...</li>
<li xml:lang="sv">annat: lära sig klockan, punktskrift, labyrint, musikinstrument, ...</li>
<li xml:lang="tr">diğer: saati söylemeyi öğrenme, braille sistemi, labirent, müzik, enstrümanlar, ...</li>
<li xml:lang="uk">Інше: навчання позначенням часу, система Брайля, лабіринти, музичні інструменти…</li>
<li xml:lang="x-test">xxother: learn to tell time, the braille system, maze, music instruments, ...xx</li>
<li xml:lang="zh-CN">其他:学认钟表、盲文系统、迷宫、乐器……</li>
<li xml:lang="zh-TW">其他:看時間、點字系統、迷宮、認識樂器等等</li>
</ul>
<p>Currently GCompris offers in excess of 100 activities and more
are being developed. GCompris is free software, that means that
you can adapt it to your own needs, improve it and, most
importantly, share it with children everywhere.</p>
<p xml:lang="ar">في «فهمت» حاليًا أكثر من ١٠٠ نشاط وثمّة غيرها يجري تطويرها. «فهمت» برمجيّة حرّة، هذا يعني أنك تستطيع تطويعها حسب احتياجك، وكذلك تطويرها، والأهم من ذلك هو مشاركتها مع الأطفال في كل مكان.</p>
- <p xml:lang="ca">Actualment el GCompris ofereix més de 100 activitats i encara se'n desenvolupen més. El GCompris és programari lliure, el qual vol dir que podeu adaptar-lo a les vostres pròpies necessitats, millorar-lo i, el més important, compartir-lo amb nens de tot arreu.</p>
- <p xml:lang="ca-valencia">Actualment el GCompris ofereix més de 100 activitats i encara se'n desenvolupen més. El GCompris és programari lliure, el qual vol dir que podeu adaptar-lo a les vostres pròpies necessitats, millorar-lo i, el més important, compartir-lo amb nens de tot arreu.</p>
+ <p xml:lang="ca">Actualment el GCompris ofereix més de 100 activitats i encara se'n desenvolupen més. El GCompris és programari lliure, el qual vol dir que podeu adaptar-lo a les vostres pròpies necessitats, millorar-lo i, el més important, compartir-lo amb infants de tot arreu.</p>
+ <p xml:lang="ca-valencia">Actualment el GCompris ofereix més de 100 activitats i encara se'n desenvolupen més. El GCompris és programari lliure, el qual vol dir que podeu adaptar-lo a les vostres pròpies necessitats, millorar-lo i, el més important, compartir-lo amb infants de tot arreu.</p>
<p xml:lang="de">Insgesamt beinhaltet GCompris mehr als 100 Aktivitäten und wird ständig weiterentwickelt. GCompris ist freie Software. Sie haben also die Möglichkeit, sie ihren Bedürfnissen anzupassen und zu verbessern, und gerne auch alle Kinder der Welt von Ihrer Arbeit profitieren zu lassen.</p>
<p xml:lang="el">Προς το παρόν το GCompris προσφέρει περισσότερες από 100 δραστηριότητες και αναπτύσσονται και άλλες. Το GCompris είναι ελεύθερο λογισμικό, το οποίο σημαίνει ότι μπορείτε να το προσαρμόσετε στις ανάγκες σας, να το βελτιώσετε, και, το σπουδαιότερο, να το μοιραστείτε με παιδιά από όλον τον κόσμο.</p>
<p xml:lang="en-GB">Currently GCompris offers in excess of 100 activities and more are being developed. GCompris is free software, that means that you can adapt it to your own needs, improve it and, most importantly, share it with children everywhere.</p>
<p xml:lang="es">En la actualidad, GCompris ofrece más de 100 actividades y hay muchas más en desarrollo. GCompris es software libre, lo que significa que puede adaptarlo a sus necesidades, mejorarlo y, lo que es más importante, compartirlo con los niños de todo el mundo.</p>
<p xml:lang="et">Praegu pakub GCompris üle 100 tegevuse ja neid tuleb aina juurde. GCompris on vaba tarkvara, mis tähendab, et seda saab kohandada oma vajadustele, täiustada, ja mis peamine, jagada oma täiustusi lastega kogu maailmas.</p>
<p xml:lang="fi">GComprisissa on nykyisellään yli sata toimintoa, ja lisää kehitetään. GCompris on vapaata ohjelmistoa, mikä tarkoittaa, että voit muokata sitä tarpeisiisi, parannella sitä ja mikä tärkeintä jakaa sitä lapsille kaikkialla.</p>
<p xml:lang="fr">Actuellement, GCompris contient plus de 100 activités et d'autres sont en cours de développement. GCompris est un logiciel libre, ce qui veut dire que vous pouvez l'adapter à vos propres besoins, le modifier et, le plus important, le partager avec des enfants où que ce soit.</p>
<p xml:lang="gl">Actualmente GCompris ofrece máis de 100 actividades e hai máis en desenvolvemento. GCompris é software libre, o que significa que pode adaptalo para axustalo ás súas necesidades, melloralo e, o máis importante, compartilo con nenos de todo o mundo.</p>
<p xml:lang="hi">वर्तमान में जी कॉम्पप्रस 100 गतिविधियों से अधिक प्रदान करता है और अधिक विकसित किए जा रहे हैं। जी कॉम्पप्रस मुफ्त सॉफ्टवेयर है, इसका मतलब है कि आप इसे अपनी आवश्यकताओं के अनुसार अनुकूलित कर सकते हैं, इसमें सुधार कर सकते हैं, और सबसे महत्वपूर्ण बात, इसे हर जगह बच्चों के साथ साझा कर सकते हैं।</p>
- <p xml:lang="id">Saat ini GCompris menawarkan lebih dari 100 aktivitas dan masih banyak lagi yang sedang dikembangkan. GCompris adalah perangkat lunak bebas, itu berarti kamu dapat menyesuaikannya dengan kebutuhanmu sendiri, memperbaikinya dan yang terpenting, bagikan dengan anak-anak di mana-mana.</p>
+ <p xml:lang="id">Saat ini GCompris menawarkan lebih dari 100 aktivitas dan masih banyak lagi yang sedang dikembangkan. GCompris adalah software bebas, itu berarti kamu dapat menyesuaikannya dengan kebutuhanmu sendiri, memperbaikinya dan yang terpenting, bagikan dengan anak-anak di mana-mana.</p>
<p xml:lang="it">Attualmente GCompris offre più di 100 attività e altre sono in fase di sviluppo. GCompris è software libero, che significa che puoi adattarlo alle tue necessità, migliorarlo e, cosa più importante, condividerlo con tutti i bambini.</p>
<p xml:lang="ko">GCompris는 100개 이상의 활동을 포함하고 있으며 더 많은 활동을 개발하고 있습니다. GCompris는 자유 소프트웨어이며, 필요에 따라서 활동을 개선할 수 있으며 전 세계의 사람들과 공유할 수 있습니다.</p>
+ <p xml:lang="ml">ഇപ്പോൾ ജികോംപ്രിയിൽ 100 ലധികം പ്രവർത്തനങ്ങൾ ഉണ്ട്, അതിൽ കൂടുതൽ ഡെവലപ്പ് ചെയ്തുകൊണ്ടിരിക്കുന്നുമുണ്ട്. ജികോംപ്രി ഒരു സ്വതന്ത്ര സോഫ്റ്റുവെയർ ആണ്, അതായത് നിങ്ങൾക്ക് അതിനെ നിങ്ങളുടെ ആവശ്യങ്ങൾക്കനുസരിച്ച് രൂപപ്പെടുത്താം, അതിനെ മെച്ചപ്പെടുത്താം, ഏറ്റവും പ്രധാനമായി, എല്ലായിടങ്ങളിലുള്ള കുട്ടികളുമായി അത് പങ്കുവെയ്ക്കാം.</p>
<p xml:lang="nl">Op dit moment biedt GCompris meer dan 100 activiteiten en meer zijn er in ontwikkeling. GCompris is vrije software, dat betekent dat u het kunt aanpassen aan uw eigen behoeften, het verbeteren en, meest belangrijk, het met kinderen overal kun delen.</p>
<p xml:lang="nn">GCompris har over 100 aktivitetar, og fleire vert utvikla. GCompris er fri programvare. Det vil seia at du kan tilpassa spelet slik du ønskjer, forbetra det og dela det med ungar i heile verda.</p>
<p xml:lang="pl">Obecnie GCompris zapewnia ponad 100 aktywności, a jeszcze więcej jest opracowywanych. GCompris jest darmowym oprogramowaniem, co oznacza, że możesz je dopasować do własnych potrzeb, ulepszać je i co najważniejsze udostępniać je dzieciom.</p>
<p xml:lang="pt">De momento, o GCompris oferece mais de 100 actividades, estando ainda mais em desenvolvimento. O GCompris é uma aplicação de 'software' livre, o que significa que o poderá adaptar às suas próprias necessidades, melhorá-lo e, o mais importante, partilhá-lo com as crianças em todo o lado.</p>
<p xml:lang="pt-BR">Atualmente o GCompris oferece mais de 100 atividades e outras mais estão sendo desenvolvidas. O GCompris é um software livre, o que significa que você pode adaptá-lo para as suas próprias necessidades, melhorá-lo e, mais importante, compartilhar com as crianças de todo o mundo.</p>
<p xml:lang="ro">Momentan GCompris oferă peste 100 de activități și multe altele sunt în lucru. GCompris este software liber, ceea ce înseamnă că poate fi adaptat nevoilor dumneavoastră, îmbunătățit, dar mai ales, partajat cu copii de pretutindeni.</p>
<p xml:lang="ru">В настоящее время GCompris содержит более 100 упражнений, и новые находятся в разработке. GCompris — свободное ПО, и это значит, что вы можете приспособить его для своих нужд, улучшить, а самое главное — поделиться им с детьми во всём мире.</p>
<p xml:lang="sk">Aktuálne GCompris ponúka vyše 100 aktivít a ďalšie sa vyvíjajú. GCompris je slobodný softvér, čo znamená, že si ho môžete prispôsobiť na vlastné potreby, zlepšiť, a hlavne zdieľať s deťmi všade.</p>
<p xml:lang="sl">GCompris trenutno ponuja več kot 100 dejavnosti, še več pa jih je v razvoju. GCompris je prosta programska oprema, kar pomeni, da jo lahko prilagodite po svoje, še pomembneje pa je, da jo lahko delite z otroki širom sveta.</p>
<p xml:lang="sv">För närvarande erbjuder GCompris över 100 aktiviteter och ännu fler håller på att utvecklas. GCompris är fri programvara, vilket betyder att man kan anpassa det till sina egna behov, och viktigast av allt, dela det med barn överallt.</p>
<p xml:lang="tr">Şu anda GCompris 100'den fazla etkinlik sunuyor ve daha fazlasını geliştiriliyor. GCompris bir özgür yazılımdır; bu, onu kendi ihtiyaçlarınıza uyarlayabilir, geliştirebilir ve en önemlisi, her yerde çocuklarla paylaşabileceğiniz anlamına gelir.</p>
<p xml:lang="uk">У поточній версії GCompris понад 100 вправ. Розробники постійно працюють над новими вправами. GCompris є вільним програмним забезпеченням, це означає, що ви можете адаптувати програму до власних потреб, покращувати її і, що найважливіше, ділитися вашими творіннями із усіма дітьми.</p>
<p xml:lang="x-test">xxCurrently GCompris offers in excess of 100 activities and more are being developed. GCompris is free software, that means that you can adapt it to your own needs, improve it and, most importantly, share it with children everywhere.xx</p>
<p xml:lang="zh-CN">当前 GCompris 提供超过100个活动,还有更多的正在开发中。GCompris 是自由软件,这意味着您可以根据您的需要进行调整、改进,以及最重要的一点,和世界各地的孩子们分享。</p>
- <p xml:lang="zh-TW">目前 GCompris 提供超過 100 個活動,還有更多正在開發中。GCompris 是一套自由軟體,表示您可以根據您自己的需求來改進,並分享給所有的孩子們。</p>
+ <p xml:lang="zh-TW">目前 GCompris 提供超過 100 個遊戲,還有更多正在開發中。GCompris 是一套自由軟體,表示您可以根據您自己的需求來改進,並分享給所有的孩子們。</p>
</description>
<screenshots>
<screenshot type="default">
<caption>GCompris main menu</caption>
<caption xml:lang="ar">قائمة «فهمت» الرئيسيّة</caption>
<caption xml:lang="ca">Menú principal del GCompris</caption>
<caption xml:lang="ca-valencia">Menú principal del GCompris</caption>
<caption xml:lang="cs">Hlavní nabídka GCompris</caption>
<caption xml:lang="de">GCompris-Hauptmenü</caption>
+ <caption xml:lang="el">Κύριο μενού του GCompris</caption>
<caption xml:lang="en-GB">GCompris main menu</caption>
<caption xml:lang="es">Menú principal de GCompris</caption>
+ <caption xml:lang="fi">GComprisin päävalikko</caption>
<caption xml:lang="fr">Menu principal de GCompris</caption>
<caption xml:lang="gl">Menú principal de GCompris</caption>
<caption xml:lang="it">Menu principale di GCompris</caption>
+ <caption xml:lang="ml">ജികോംപ്രി പ്രധാന മെനു</caption>
<caption xml:lang="nl">GCompris-hoofdmenu</caption>
<caption xml:lang="nn">Hovudmenyen i GCompris</caption>
<caption xml:lang="pl">Główne menu GCompris</caption>
<caption xml:lang="pt">Menu principal do GCompris</caption>
<caption xml:lang="pt-BR">Menu principal do GCompris</caption>
+ <caption xml:lang="ro">Meniul principal GCompris</caption>
<caption xml:lang="sv">GCompris-huvudmeny</caption>
<caption xml:lang="uk">Головне меню GCompris</caption>
<caption xml:lang="x-test">xxGCompris main menuxx</caption>
+ <caption xml:lang="zh-TW">GCompris 主畫面</caption>
<image width="1080" height="720">https://gcompris.net/screenshots-qt/middle/main_menu.png</image>
</screenshot>
<screenshot>
<caption>"Click on an uppercase letter" activity</caption>
<caption xml:lang="ca">Activitat «Fes clic en una lletra en majúscula»</caption>
<caption xml:lang="ca-valencia">Activitat «Fes clic en una lletra en majúscula»</caption>
<caption xml:lang="cs">Aktivita "Klikni na velké písmeno"</caption>
+ <caption xml:lang="el">Δραστηριότητα "Κλικ σε κεφαλαίο γράμμα"</caption>
<caption xml:lang="en-GB">"Click on an uppercase letter" activity</caption>
+ <caption xml:lang="es">Actividad «Pulsa en una letra mayúscula»</caption>
+ <caption xml:lang="fi">”Napsauta suuraakkosta” -toiminto</caption>
<caption xml:lang="fr">L'activité « Trouver la lettre majuscule »</caption>
+ <caption xml:lang="gl">Actividade de «Premer unha letra maiúscula»</caption>
<caption xml:lang="it">Attività «Fai clic su una lettera maiuscola»</caption>
+ <caption xml:lang="ml">"ഒരു വലിയ അക്ഷരത്തിൽ ക്ലിക്ക് ചെയ്യുക" പ്രവർത്തനം</caption>
<caption xml:lang="nl">"Click op een hoofdletter" activiteit</caption>
+ <caption xml:lang="nn">Aktiviteten «Trykk på ein stor bokstav»</caption>
+ <caption xml:lang="pl">Aktywność "klikania na wielkie litery"</caption>
<caption xml:lang="pt">Actividade para "Carregar numa letra maiúscula"</caption>
+ <caption xml:lang="pt-BR">Atividade "Clique em uma letra maiúscula"</caption>
+ <caption xml:lang="ro">Activitatea "Clic pe o literă mare"</caption>
<caption xml:lang="sv">Aktiviteten "Klicka på en stor bokstav"</caption>
<caption xml:lang="uk">Вправа «Клацніть на великій літері»</caption>
<caption xml:lang="x-test">xx"Click on an uppercase letter" activityxx</caption>
+ <caption xml:lang="zh-TW">「在大寫字母上按一下」遊戲</caption>
<image width="1080" height="720">https://gcompris.net/screenshots-qt/middle/click_on_letter_up.png</image>
</screenshot>
<screenshot>
<caption>"Learning Clock" activity</caption>
<caption xml:lang="ca">Activitat «Rellotge d'aprenentatge»</caption>
<caption xml:lang="ca-valencia">Activitat «Rellotge d'aprenentatge»</caption>
<caption xml:lang="cs">Aktivita "Nauč se hodiny"</caption>
+ <caption xml:lang="el">Δραστηριότητα "Ρολόι"</caption>
<caption xml:lang="en-GB">"Learning Clock" activity</caption>
+ <caption xml:lang="es">Actividad «Juego del reloj»</caption>
+ <caption xml:lang="fi">”Kellon oppiminen” -toiminto</caption>
<caption xml:lang="fr">L'activité « Trouver l'heure »</caption>
+ <caption xml:lang="gl">Actividade de «Aprender o reloxo»</caption>
<caption xml:lang="it">Attività «Impara l'orologio»</caption>
+ <caption xml:lang="ml">"സമയം പഠിക്കൽ" പ്രവർത്തനം</caption>
<caption xml:lang="nl">Activiteit "Leren klok kijken</caption>
+ <caption xml:lang="nn">Aktiviteten «Lær klokka»</caption>
+ <caption xml:lang="pl">Aktywność "nauki zegara"</caption>
<caption xml:lang="pt">Actividade para "Descobrir o Relógio"</caption>
+ <caption xml:lang="pt-BR">Atividade "O Relógio"</caption>
+ <caption xml:lang="ro">Activitatea de "Învățarea ceasului clasic"</caption>
<caption xml:lang="sv">Aktiviteten "Lära sig klockan"</caption>
<caption xml:lang="uk">Вправа «Вивчення годинника»</caption>
<caption xml:lang="x-test">xx"Learning Clock" activityxx</caption>
+ <caption xml:lang="zh-TW">「學習時鐘」遊戲</caption>
<image width="1080" height="720">https://gcompris.net/screenshots-qt/middle/clockgame.png</image>
</screenshot>
<screenshot>
<caption>"Mixing color of paint" activity</caption>
<caption xml:lang="ca">Activitat «Barreja els colors de la pintura»</caption>
<caption xml:lang="ca-valencia">Activitat «Barreja els colors de la pintura»</caption>
<caption xml:lang="cs">Aktivita "Míchání tiskařských barev"</caption>
+ <caption xml:lang="el">Δραστηριότητα "Μείξη χρωμάτων"</caption>
<caption xml:lang="en-GB">"Mixing colour of paint" activity</caption>
+ <caption xml:lang="es">Actividad «Mezcla de colores»</caption>
+ <caption xml:lang="fi">”Värien sekoitus” -toiminto</caption>
<caption xml:lang="fr">L'activité « Mélange de la couleur de peinture »</caption>
+ <caption xml:lang="gl">Actividade de «Mesturar a cor da pintura»</caption>
<caption xml:lang="it">Attività «Miscela la vernice colorata»</caption>
+ <caption xml:lang="ml">"ചായത്തിൻ്റെ നിറങ്ങൾ കൂട്ടിക്കലർത്താം" പ്രവർത്തനം</caption>
<caption xml:lang="nl">Activiteit "Verfkleuren mengen"</caption>
+ <caption xml:lang="nn">Aktiviteten «Blanda målingsfargar»</caption>
+ <caption xml:lang="pl">Aktywność "mieszania barw"</caption>
<caption xml:lang="pt">Actividade para "Misturar a cor das tintas"</caption>
+ <caption xml:lang="pt-BR">Atividade "Mistura de tintas coloridas"</caption>
+ <caption xml:lang="ro">Activitatea "Amestecul culorilor din vopsea"</caption>
<caption xml:lang="sv">Aktiviteten "Blanda målarfärger"</caption>
<caption xml:lang="uk">Вправа «Змішування кольорів малюнка»</caption>
<caption xml:lang="x-test">xx"Mixing color of paint" activityxx</caption>
+ <caption xml:lang="zh-TW">「混合顏色」遊戲</caption>
<image width="1080" height="720">https://gcompris.net/screenshots-qt/middle/color_mix.png</image>
</screenshot>
<screenshot>
<caption>"Colors" activity</caption>
<caption xml:lang="ca">Activitat «Colors»</caption>
<caption xml:lang="ca-valencia">Activitat «Colors»</caption>
<caption xml:lang="cs">Aktivita "Barvy"</caption>
+ <caption xml:lang="el">Δραστηριότητα "Χρώματα"</caption>
<caption xml:lang="en-GB">"Colours" activity</caption>
+ <caption xml:lang="es">Actividad «Colores»</caption>
+ <caption xml:lang="fi">”Värit”-toiminto</caption>
<caption xml:lang="fr">L'activité « Trouver la couleur »</caption>
+ <caption xml:lang="gl">Actividade de «Cores»</caption>
<caption xml:lang="it">Attività «Colori»</caption>
+ <caption xml:lang="ml">"നിറങ്ങൾ" പ്രവർത്തനം</caption>
<caption xml:lang="nl">Activiteit "Kleuren"</caption>
+ <caption xml:lang="nn">Aktiviteten «Fargar»</caption>
+ <caption xml:lang="pl">Aktywność "barw"</caption>
<caption xml:lang="pt">Actividade de "Cores"</caption>
+ <caption xml:lang="pt-BR">Atividade "Cores"</caption>
+ <caption xml:lang="ro">Activitatea "Culorile"</caption>
<caption xml:lang="sv">Aktiviteten "Färger"</caption>
<caption xml:lang="uk">Вправа з кольорами</caption>
<caption xml:lang="x-test">xx"Colors" activityxx</caption>
+ <caption xml:lang="zh-TW">「顏色」遊戲</caption>
<image width="1080" height="720">https://gcompris.net/screenshots-qt/middle/colors.png</image>
</screenshot>
<screenshot>
<caption>"Build the same model" activity</caption>
<caption xml:lang="ca">Activitat «Construeix el mateix model»</caption>
<caption xml:lang="ca-valencia">Activitat «Construeix el mateix model»</caption>
<caption xml:lang="cs">Aktivita "Postav stejný model"</caption>
+ <caption xml:lang="el">Δραστηριότητα "Φτιάξε το ίδιο"</caption>
<caption xml:lang="en-GB">"Build the same model" activity</caption>
+ <caption xml:lang="es">Actividad «Grúa»</caption>
+ <caption xml:lang="fi">”Rakenna sama malli” -toiminto</caption>
<caption xml:lang="fr">L'activité « Reconstruire le modèle »</caption>
+ <caption xml:lang="gl">Actividade de «Constrúe o mesmo modelo»</caption>
<caption xml:lang="it">Attività «Costruisci lo stesso modello»</caption>
+ <caption xml:lang="ml">"മാതൃക പോലെ നിർമ്മിക്കുക " പ്രവർത്തനം</caption>
<caption xml:lang="nl">Activiteit "Bouw hetzelfde model"</caption>
+ <caption xml:lang="nn">Aktiviteten «Bygg opp modellen»</caption>
+ <caption xml:lang="pl">Aktywność "zbudowania tego samego modelu"</caption>
<caption xml:lang="pt">Actividade para "Construir o mesmo modelo"</caption>
+ <caption xml:lang="pt-BR">Atividade "Construa o mesmo modelo"</caption>
+ <caption xml:lang="ro">Activitatea "Construiește același model"</caption>
<caption xml:lang="sv">Aktiviteten "Bygg samma modell"</caption>
<caption xml:lang="uk">Вправа «Відтворіть модель»</caption>
<caption xml:lang="x-test">xx"Build the same model" activityxx</caption>
+ <caption xml:lang="zh-TW">「建立相同的模型」遊戲</caption>
<image width="1080" height="720">https://gcompris.net/screenshots-qt/middle/crane.png</image>
</screenshot>
<screenshot>
<caption>"Count the items" activity</caption>
<caption xml:lang="ca">Activitat «Compta els elements»</caption>
<caption xml:lang="ca-valencia">Activitat «Compta els elements»</caption>
<caption xml:lang="cs">Aktivita "Spočítej položky"</caption>
+ <caption xml:lang="el">Δραστηριότητα "Μέτρα τα αντικείμενα"</caption>
<caption xml:lang="en-GB">"Count the items" activity</caption>
+ <caption xml:lang="es">Actividad «Enumeración»</caption>
+ <caption xml:lang="fi">”Laske kohteet” -toiminto</caption>
<caption xml:lang="fr">L'activité « Compter les éléments »</caption>
+ <caption xml:lang="gl">Actividade de «Contar os elementos»</caption>
<caption xml:lang="it">Attività «Conta gli oggetti»</caption>
+ <caption xml:lang="ml">"എത്രയെണ്ണം?" പ്രവർത്തനം</caption>
<caption xml:lang="nl">Activiteit "Tel het aantal items"</caption>
+ <caption xml:lang="nn">Aktiviteten «Tel gjenstandane»</caption>
+ <caption xml:lang="pl">Aktywność "zliczania elementów"</caption>
<caption xml:lang="pt">Actividade para "Contar os itens"</caption>
+ <caption xml:lang="pt-BR">Atividade "Contagem de itens"</caption>
+ <caption xml:lang="ro">Activitatea "Numără elementele"</caption>
<caption xml:lang="sv">Aktiviteten "Räkna sakerna"</caption>
<caption xml:lang="uk">Вправа «Порахувати предмети»</caption>
<caption xml:lang="x-test">xx"Count the items" activityxx</caption>
+ <caption xml:lang="zh-TW">「數一數物品」遊戲</caption>
<image width="1080" height="720">https://gcompris.net/screenshots-qt/middle/enumerate.png</image>
</screenshot>
<screenshot>
<caption>"The fifteen game" activity</caption>
<caption xml:lang="ca">Activitat «El joc dels quinze»</caption>
<caption xml:lang="ca-valencia">Activitat «El joc dels quinze»</caption>
<caption xml:lang="cs">Aktivita "Hra patnáct"</caption>
+ <caption xml:lang="el">Δραστηριότητα "Δεκαπέντε"</caption>
<caption xml:lang="en-GB">"The fifteen game" activity</caption>
+ <caption xml:lang="es">Actividad «Quince»</caption>
<caption xml:lang="fr">L'activité « Le jeu du taquin »</caption>
+ <caption xml:lang="gl">Actividade de «O xogo dos quince»</caption>
<caption xml:lang="it">Attività «Il gioco del quindici»</caption>
+ <caption xml:lang="ml">"പതിനഞ്ചിന്റെ കളി" പ്രവർത്തനം</caption>
<caption xml:lang="nl">Activiteit "Het vijftien-spel"</caption>
+ <caption xml:lang="nn">Aktiviteten «Spelet 15»</caption>
+ <caption xml:lang="pl">Aktywność "gra w piętnaście"</caption>
<caption xml:lang="pt">Actividade do "Jogo dos quinze"</caption>
+ <caption xml:lang="pt-BR">Atividade "O jogo do quinze"</caption>
+ <caption xml:lang="ro">Activitatea "Jocul de cincisprezece"</caption>
<caption xml:lang="sv">Aktiviteten "Femtonspel"</caption>
<caption xml:lang="uk">Вправа «Гра „П'ятнадцять“»</caption>
<caption xml:lang="x-test">xx"The fifteen game" activityxx</caption>
+ <caption xml:lang="zh-TW">「遊戲十五」</caption>
<image width="1080" height="720">https://gcompris.net/screenshots-qt/middle/fifteen.png</image>
</screenshot>
<screenshot>
<caption>"Hexagon" activity</caption>
<caption xml:lang="ca">Activitat «Hexàgon»</caption>
<caption xml:lang="ca-valencia">Activitat «Hexàgon»</caption>
<caption xml:lang="cs">Aktivita "Hexagon"</caption>
+ <caption xml:lang="el">Δραστηριότητα "Εξάγωνο"</caption>
<caption xml:lang="en-GB">"Hexagon" activity</caption>
+ <caption xml:lang="es">Actividad «Hexágono»</caption>
<caption xml:lang="fr">L'activité « Localiser la fraise »</caption>
+ <caption xml:lang="gl">Actividade de «Hexágono»</caption>
<caption xml:lang="it">Attività «Esagono»</caption>
+ <caption xml:lang="ml">"ഷഡ്ഭുജം" പ്രവർത്തനം</caption>
<caption xml:lang="nl">Activiteit "Hexagon"</caption>
+ <caption xml:lang="nn">Aktiviteten «Heksagon»</caption>
+ <caption xml:lang="pl">Aktywność "sześciokąta"</caption>
<caption xml:lang="pt">Actividade de "Hexágono"</caption>
+ <caption xml:lang="pt-BR">Atividade "Hexágono"</caption>
+ <caption xml:lang="ro">Activitatea "Hexagonul"</caption>
<caption xml:lang="sv">Aktiviteten "Hexagon"</caption>
<caption xml:lang="uk">Вправа «Шестикутник»</caption>
<caption xml:lang="x-test">xx"Hexagon" activityxx</caption>
+ <caption xml:lang="zh-TW">「六角形」遊戲</caption>
<image width="1080" height="720">https://gcompris.net/screenshots-qt/middle/hexagon.png</image>
</screenshot>
<screenshot>
<caption>"Balance the scales properly" activity</caption>
<caption xml:lang="ca">Activitat «Equilibra correctament la balança»</caption>
<caption xml:lang="ca-valencia">Activitat «Equilibra correctament la balança»</caption>
<caption xml:lang="cs">Aktivita "Správně vyrovnat váhy"</caption>
+ <caption xml:lang="el">Δραστηριότητα "Ισορρόπησε τη ζυγαριά"</caption>
<caption xml:lang="en-GB">"Balance the scales properly" activity</caption>
+ <caption xml:lang="es">Actividad «Balanzas»</caption>
+ <caption xml:lang="fi">”Tasapainota vaaka oikein” -toiminto</caption>
<caption xml:lang="fr">L'activité « Trouver le poids »</caption>
+ <caption xml:lang="gl">Actividade de «Equilibra a balanza de forma axeitada»</caption>
<caption xml:lang="it">Attività «Allinea correttamente i piatti della bilancia»</caption>
+ <caption xml:lang="ml">"തട്ടുകളിലെ തൂക്കമൊപ്പിക്കൂ" പ്രവർത്തനം</caption>
<caption xml:lang="nl">Activiteit "Breng de weegschaal in evenwicht"</caption>
+ <caption xml:lang="nn">Aktiviteten «Få vekta i likevekt»</caption>
+ <caption xml:lang="pl">Aktywność "zrównoważenia skal"</caption>
<caption xml:lang="pt">Actividade para "Equilibrar as balanças adequadamente"</caption>
+ <caption xml:lang="pt-BR">Atividade "Equilibre a balança"</caption>
+ <caption xml:lang="ro">Activitatea "Echilibrează balanța"</caption>
<caption xml:lang="sv">Aktiviteten "Balansera vågen rätt"</caption>
<caption xml:lang="uk">Вправа «Рівновага на вагах»</caption>
<caption xml:lang="x-test">xx"Balance the scales properly" activityxx</caption>
+ <caption xml:lang="zh-TW">「讓天平平衡」遊戲</caption>
<image width="1080" height="720">https://gcompris.net/screenshots-qt/middle/scalesboard.png</image>
</screenshot>
<screenshot>
<caption>"End of chess game" activity</caption>
<caption xml:lang="ca">Activitat «Final de la partida d'escacs»</caption>
<caption xml:lang="ca-valencia">Activitat «Final de la partida d'escacs»</caption>
<caption xml:lang="cs">Aktivita "Konec šachové partie"</caption>
+ <caption xml:lang="el">Δραστηριότητα "Το σκάκι στο τέλος"</caption>
<caption xml:lang="en-GB">"End of chess game" activity</caption>
+ <caption xml:lang="es">Actividad «Final de partida de ajedrez»</caption>
+ <caption xml:lang="fi">”Šakin loppupeli” -toiminto</caption>
<caption xml:lang="fr">L'activité « Le jeu des échecs »</caption>
+ <caption xml:lang="gl">Actividade de «Final dunha partida de xadrez»</caption>
<caption xml:lang="it">Attività «Fine della partita a scacchi»</caption>
+ <caption xml:lang="ml">"ചെസ്സു കളിയുടെ അവസാനം" പ്രവർത്തനം</caption>
<caption xml:lang="nl">Activiteit "Eindspel van schaken"</caption>
+ <caption xml:lang="nn">Aktiviteten «Sluttspel i sjakk»</caption>
+ <caption xml:lang="pl">Aktywność "zakończeń partii szachowych"</caption>
<caption xml:lang="pt">Actividade de "Fim de jogo de xadrez"</caption>
+ <caption xml:lang="pt-BR">Atividade "Finalize o jogo de xadrez"</caption>
+ <caption xml:lang="ro">Activitatea "Sfârșitul jocului de șah"</caption>
<caption xml:lang="sv">Aktiviteten "Slutspel i schack"</caption>
<caption xml:lang="uk">Вправа «Завершення гри у шахи»</caption>
<caption xml:lang="x-test">xx"End of chess game" activityxx</caption>
+ <caption xml:lang="zh-TW">「西洋棋殘局」遊戲</caption>
<image width="1080" height="720">https://gcompris.net/screenshots-qt/middle/chess_partyend.png</image>
</screenshot>
<screenshot>
<caption>"A sliding-block puzzle game" activity</caption>
<caption xml:lang="ca">Activitat «Un joc de trencaclosques amb blocs que es desplacen»</caption>
<caption xml:lang="ca-valencia">Activitat «Un joc de trencaclosques amb blocs que es desplacen»</caption>
<caption xml:lang="cs">Aktivita "Hra s posouváním bloků"</caption>
+ <caption xml:lang="el">Δραστηριότητα "Βγάζω το αυτοκίνητο"</caption>
<caption xml:lang="en-GB">"A sliding-block puzzle game" activity</caption>
+ <caption xml:lang="es">Actividad «Tráfico»</caption>
<caption xml:lang="fr">L'activité « Sortir la voiture du parking »</caption>
+ <caption xml:lang="gl">Actividade de «Un crebacabezas de bloques que se moven»</caption>
<caption xml:lang="it">Attività «Un rompicapo con blocchi scorrevoli»</caption>
+ <caption xml:lang="ml">"വഴി കണ്ടെത്തൽ" പ്രവർത്തനം</caption>
<caption xml:lang="nl">Activiteit "Een puzzel met schuivende blokken"</caption>
+ <caption xml:lang="nn">Aktiviteten «Skyvespel»</caption>
+ <caption xml:lang="pl">Aktywność "puzzli z przesuwającym się puzzlem"</caption>
<caption xml:lang="pt">Actividade de "Puzzle de blocos deslizantes"</caption>
+ <caption xml:lang="pt-BR">Atividade "Quebra-cabeça com peças deslizantes"</caption>
+ <caption xml:lang="ro">Activitatea "Un joc de puzzle cu blocuri glisante"</caption>
<caption xml:lang="sv">Aktiviteten "Pusselspel med glidande block"</caption>
<caption xml:lang="uk">Вправа «Головоломка з пересувними блоками»</caption>
<caption xml:lang="x-test">xx"A sliding-block puzzle game" activityxx</caption>
+ <caption xml:lang="zh-TW">「滑動方塊」解謎遊戲</caption>
<image width="1080" height="720">https://gcompris.net/screenshots-qt/middle/traffic.png</image>
</screenshot>
</screenshots>
<url type="homepage">https://gcompris.net/</url>
<url type="bugtracker">https://bugs.kde.org/enter_bug.cgi?format=guided&amp;product=gcompris</url>
- <url type="help">http://gcompris.net/wiki/Manual</url>
+ <url type="help">https://gcompris.net/wiki/Manual</url>
<url type="donation">https://gcompris.net/buy-en.html</url>
- <url type="translate">http://gcompris.net/wiki/Developer%27s_corner#Translation</url>
+ <url type="translate">https://gcompris.net/wiki/Developer%27s_corner#Translation</url>
<update_contact>gcompris-devel@kde.org</update_contact>
<project_group>KDE</project_group>
<provides>
<binary>gcompris-qt</binary>
</provides>
<content_rating type="oars-1.1">
<content_attribute id="violence-cartoon">none</content_attribute>
<content_attribute id="violence-fantasy">none</content_attribute>
<content_attribute id="violence-realistic">none</content_attribute>
<content_attribute id="violence-bloodshed">none</content_attribute>
<content_attribute id="violence-sexual">none</content_attribute>
<content_attribute id="violence-desecration">none</content_attribute>
<content_attribute id="violence-slavery">none</content_attribute>
<content_attribute id="violence-worship">none</content_attribute>
<content_attribute id="drugs-alcohol">none</content_attribute>
<content_attribute id="drugs-narcotics">none</content_attribute>
<content_attribute id="drugs-tobacco">none</content_attribute>
<content_attribute id="sex-nudity">none</content_attribute>
<content_attribute id="sex-themes">none</content_attribute>
<content_attribute id="sex-homosexuality">none</content_attribute>
<content_attribute id="sex-prostitution">none</content_attribute>
<content_attribute id="sex-adultery">none</content_attribute>
<content_attribute id="sex-appearance">none</content_attribute>
<content_attribute id="language-profanity">none</content_attribute>
<content_attribute id="language-humor">none</content_attribute>
<content_attribute id="language-discrimination">none</content_attribute>
<content_attribute id="social-chat">none</content_attribute>
<content_attribute id="social-info">none</content_attribute>
<content_attribute id="social-audio">none</content_attribute>
<content_attribute id="social-location">none</content_attribute>
<content_attribute id="social-contacts">none</content_attribute>
<content_attribute id="money-purchasing">none</content_attribute>
<content_attribute id="money-gambling">none</content_attribute>
</content_rating>
</component>
diff --git a/org.kde.gcompris.desktop b/org.kde.gcompris.desktop
index f688da2c5..42733b820 100644
--- a/org.kde.gcompris.desktop
+++ b/org.kde.gcompris.desktop
@@ -1,106 +1,107 @@
[Desktop Entry]
Name=GCompris Educational Game
Name[ar]=لعبة «فهمت» التعليميّة
-Name[ast]=Xuegu educativu GCompris
Name[ca]=Joc educatiu GCompris
Name[ca@valencia]=Joc educatiu GCompris
Name[cs]=Výuková hra GCompris
Name[de]=GCompris-Lernspiel
Name[el]=Εκπαιδευτικό παιχνίδι GCompris
Name[en_GB]=GCompris Educational Game
Name[es]=Juego educativo GCompris
Name[et]=Hariv mäng GCompris
Name[fi]=GCompris, opettavainen peli
Name[fr]=Jeu éducatif GCompris
Name[gl]=Xogo educativo GCompris
Name[hi]=जीकोंप्रिस शेक्षणिक खेल
-Name[id]=GCompris Permainan Edukatif
+Name[id]=Permainan Pendidikan GCompris
Name[it]=Gioco didattico GCompris
Name[ko]=GCompris 교육용 게임
+Name[ml]=ജികോംപ്രി വിദ്യാഭ്യാസപരമായ കളി
Name[nl]=Educatief spel GCompris
Name[nn]=GCompris leik-og-lær-spel
Name[pl]=Gra edukacyjna GCompris
Name[pt]=Jogo Educativo GCompris
Name[pt_BR]=Jogo educacional GCompris
Name[ro]=Joc educațional GCompris
Name[ru]=Набор обучающих игр GCompris
Name[sk]=Výuková hra GCompris
Name[sl]=Izobraževalna igra GCompris
Name[sv]=GCompris pedagogiskt spel
Name[tr]=GCompris Eğitici Oyun
Name[uk]=Освітня гра GCompris
Name[x-test]=xxGCompris Educational Gamexx
Name[zh_CN]=GCompris 教育游戏
Name[zh_TW]=GCompris 教育遊戲
GenericName=Educational game
GenericName[ar]=لعبة تعليميّة
-GenericName[ast]=Xuegu educativu
GenericName[ca]=Joc educatiu
GenericName[ca@valencia]=Joc educatiu
GenericName[cs]=Výuková hra
GenericName[da]=Læringsspil
GenericName[de]=Lernspiel
GenericName[el]=Εκπαιδευτικό παιχνίδι
GenericName[en_GB]=Educational game
GenericName[es]=Juego educativo
GenericName[et]=Hariv mäng
GenericName[fi]=Opettavainen peli
GenericName[fr]=Jeu éducatif
GenericName[gl]=Xogo educativo
GenericName[hi]=शेक्षणिक खेल
-GenericName[id]=Permainan edukatif
+GenericName[id]=Permainan Pendidikan
GenericName[it]=Gioco didattico
GenericName[ko]=교육용 게임
+GenericName[ml]=വിദ്യാഭ്യാസപരമായ കളി
GenericName[nl]=Educatief spel
GenericName[nn]=Leik-og-lær-spel
GenericName[pl]=Gra edukacyjna
GenericName[pt]=Jogo educativo
GenericName[pt_BR]=Jogo educacional
GenericName[ro]=Joc educațional
GenericName[ru]=Обучающие игры
GenericName[sk]=Výuková hra
GenericName[sl]=Izobraževalna igra
GenericName[sv]=Pedagogiskt spel
GenericName[tr]=Eğitici oyun
GenericName[uk]=Освітня гра
GenericName[x-test]=xxEducational gamexx
GenericName[zh_CN]=教育游戏
GenericName[zh_TW]=教育遊戲
Comment=Multi-Activity Educational game for children 2 to 10
Comment[ar]=لعبة تعليميّة متعدّدة الأنشطة للأطفال من سنتين إلى ١٠ سنوات
-Comment[ca]=Joc educatiu amb múltiples activitats per a nens dels 2 a 10 anys
-Comment[ca@valencia]=Joc educatiu amb múltiples activitats per a nens dels 2 a 10 anys
+Comment[ca]=Joc educatiu amb múltiples activitats per a infants de 2 a 10 anys
+Comment[ca@valencia]=Joc educatiu amb múltiples activitats per a infants de 2 a 10 anys
Comment[de]=Lernspiel mit vielen Aktivitäten für Kinder von 2 bis 10 Jahren
Comment[el]=Εκπαιδευτικό παιχνίδι πολλαπλών δραστηριοτήτων για ηλικίες 2 έως 10 ετών
Comment[en_GB]=Multi-Activity Educational game for children 2 to 10
Comment[es]=Juego educativo multiactividad para niños de 2 a 10 años
Comment[et]=Rohkete tegevustega hariv mäng lastele vanuses 2-10
Comment[fi]=Useampitoimintoinen opettavainen peli 2–10-vuotiaille lapsille
Comment[fr]=Jeu éducatif multi-activités pour les enfants de 2 à 10 ans
Comment[gl]=Xogo educativo con varias actividades para nenos de entre 2 e 10 anos
Comment[hi]=२ से १० वर्ष के बच्चों के लिए विभिन्न क्रियाएं वाला शेक्षणिक खेल
-Comment[id]=Permainan Edukatif Multi Aktivitas untuk anak berusia 2 sampai 10 tahun
+Comment[id]=GCompris adalah kumpulan permainan kegiatan pendidikan untuk anak umur 2 sampai 10 tahun
Comment[it]=Gioco didattico multi-attività per bambini da 2 a 10 anni
Comment[ko]=2-10세 어린이를 위한 다양한 활동이 있는 교육용 게임
+Comment[ml]=2 തൊട്ട് 10 വയസ്സുവരെയുള്ള കുട്ടികൾക്ക് വേണ്ടിയുള്ള വിവിധ-പ്രവർത്തനങ്ങളിലൂടെയുള്ള വിദ്യാഭ്യാസപരമായ കളി
Comment[nl]=Educatief spel met meerdere activiteiten voor kinderen van 2 tot 10
Comment[nn]=Leik-og-lærspel med mange aktivitetar – for barn frå 2 til 10 år
Comment[pl]=Gra edukacyjna z wieloma aktywnościami dla dzieci w wieku od 2 do 10 lat
Comment[pt]=Jogo educativo multi-actividades para crianças dos 2 aos 10 anos
-Comment[pt_BR]=Jogo educacional com várias atividades para crianças de 2 a 10 anos
+Comment[pt_BR]=Jogo educacional com várias atividades, para crianças de 2 a 10 anos
Comment[ro]=Joc educațional cu activități multiple pentru copii între 2 și 10 ani
Comment[ru]=Обучающие игры для детей от 2 до 10 лет
Comment[sk]=Viac-aktivitová výuková hra pre deti od 2 do 10 rokov
Comment[sl]=Izobraževalna igra z več dejavnostmi za otroke med drugim in desetim letom starosti
Comment[sv]=Pedagogiskt multiaktivitetsspel för barn från 2 till 10 år
Comment[tr]=2-10 yaş arası çocuklar için Çoklu Etkileşimli Eğitici oyun
Comment[uk]=Набір освітніх ігор для дітей від 2 до 10 років
Comment[x-test]=xxMulti-Activity Educational game for children 2 to 10xx
Comment[zh_CN]=为 2 到 10 岁儿童准备的多功能教育游戏
Comment[zh_TW]=為 2-10 歲孩子設計的教育遊戲
Exec=gcompris-qt
Icon=gcompris-qt
Terminal=false
Type=Application
Categories=Education;Game;KidsGame;
StartupNotify=true
X-DocPath=gcompris/index.html
diff --git a/platforms/ios/config.h b/platforms/ios/config.h
index 3edab6e1b..9250921e2 100644
--- a/platforms/ios/config.h
+++ b/platforms/ios/config.h
@@ -1,45 +1,45 @@
/* GCompris - config.h
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
#ifndef GCOMPRIS_CONFIG_H
#define GCOMPRIS_CONFIG_H
/* Version number of package (string) */
#define VERSION "0.80"
/* Version number of package (integer) */
#define VERSION_CODE 8000
/* Folder where rccs and translations are installed */
#ifdef Q_OS_MAC
#define GCOMPRIS_DATA_FOLDER "."
#else
#define GCOMPRIS_DATA_FOLDER "../bin/gcompris-qt.app/Contents/MacOS"
#endif
/* GCompris for android, gcompris-qt for others */
#define GCOMPRIS_APPLICATION_NAME "gcompris-qt"
/* Compressed audio format */
#define COMPRESSED_AUDIO "aac"
/* Download Allowed */
#define DOWNLOAD_ALLOWED "ON"
/* Date at which GCompris has been built */
#define BUILD_DATE "201757"
/* Type of activation system */
#define ACTIVATION_MODE "no"
#endif // GCOMPRIS_CONFIG_H
diff --git a/platforms/ios/createAppicon.py b/platforms/ios/createAppicon.py
index 81fab1f86..712c89dc5 100755
--- a/platforms/ios/createAppicon.py
+++ b/platforms/ios/createAppicon.py
@@ -1,92 +1,92 @@
#!/usr/bin/python
#
# GCompris - createAppicon.py
#
# Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
#
# This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+# along with this program; if not, see <https://www.gnu.org/licenses/>.
import json
import subprocess
import sys
import os
if len(sys.argv) < 3:
print 'Usage: createAppicon.py Images.xcassets/AppIcon.appiconset icon_no_corner.svg'
sys.exit(1)
outdir = sys.argv[1]
image_source = sys.argv[2]
try:
os.makedirs(outdir)
except:
pass
images = [
[ 29, "iphone", 1 ],
[ 29, "iphone", 2 ],
[ 29, "iphone", 3 ],
[ 40, "iphone", 2 ],
[ 40, "iphone", 3 ],
[ 57, "iphone", 1 ],
[ 57, "iphone", 2 ],
[ 60, "iphone", 2 ],
[ 60, "iphone", 3 ],
[ 29, "ipad", 1 ],
[ 29, "ipad", 2 ],
[ 40, "ipad", 1 ],
[ 40, "ipad", 2 ],
[ 50, "ipad", 1 ],
[ 50, "ipad", 2 ],
[ 72, "ipad", 1 ],
[ 72, "ipad", 2 ],
[ 76, "ipad", 1 ],
[ 76, "ipad", 2 ],
[ 83.5, "ipad", 2 ]
]
content = {
"images": [],
"info": {
"version": 1,
"author": "GCompris"
}
}
for image in images:
size = image[0]
idiom = image[1]
scale = image[2]
scalestr = str(scale) + 'x'
filesizestr = str(int(size * scale)) + 'x' + str(int(size * scale))
sizestr = str(size) + 'x' + str(size)
filename = "appicon-" + filesizestr + ".png"
content['images'].append(
{
"size": sizestr,
"idiom": idiom,
"filename": filename,
"scale": scalestr
}
)
subprocess.call(["inkscape", image_source,
"-e", outdir + '/' + filename,
"-w", str(int(size * scale)),
"-h", str(int(size * scale))])
with open(outdir + '/Contents.json', 'w') as f:
f.write(json.dumps(content, sort_keys=True,
indent=4, separators=(',', ': ')))
diff --git a/platforms/ios/createLaunchImage.py b/platforms/ios/createLaunchImage.py
index 6936abd64..b859ab642 100755
--- a/platforms/ios/createLaunchImage.py
+++ b/platforms/ios/createLaunchImage.py
@@ -1,242 +1,242 @@
#!/usr/bin/python3
#
# GCompris - createLaunchImage.py
#
# Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
#
# This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+# along with this program; if not, see <https://www.gnu.org/licenses/>.
import json
import subprocess
import sys
import os
from shutil import copyfile
if len(sys.argv) < 3:
print('Usage: createLaunchImage.py Images.xcassets/LaunchImage.launchimage ../../src/activities/menu/resource/background.svg')
sys.exit(1)
outdir = sys.argv[1]
image_source = sys.argv[2]
# Should be extracted from the source image
source_width = 1052
source_height = 610
try:
os.makedirs(outdir)
except:
pass
images = [
{
"extent" : "full-screen",
"idiom" : "iphone",
"subtype" : "736h",
"width": 1242, "height": 2208,
"minimum-system-version" : "8.0",
"orientation" : "portrait",
"scale" : "3x"
},
{
"extent" : "full-screen",
"idiom" : "iphone",
"subtype" : "736h",
"width": 2208, "height": 1242,
"minimum-system-version" : "8.0",
"orientation" : "landscape",
"scale" : "3x"
},
{
"extent" : "full-screen",
"idiom" : "iphone",
"subtype" : "667h",
"width": 750, "height": 1334,
"minimum-system-version" : "8.0",
"orientation" : "portrait",
"scale" : "2x"
},
{
"orientation" : "portrait",
"idiom" : "iphone",
"width": 640, "height": 960,
"extent" : "full-screen",
"minimum-system-version" : "7.0",
"scale" : "2x"
},
{
"extent" : "full-screen",
"idiom" : "iphone",
"subtype" : "retina4",
"width": 640, "height": 1136,
"minimum-system-version" : "7.0",
"orientation" : "portrait",
"scale" : "2x"
},
{
"orientation" : "portrait",
"idiom" : "ipad",
"width": 768, "height": 1024,
"extent" : "full-screen",
"minimum-system-version" : "7.0",
"scale" : "1x"
},
{
"orientation" : "landscape",
"idiom" : "ipad",
"width": 1024, "height": 768,
"extent" : "full-screen",
"minimum-system-version" : "7.0",
"scale" : "1x"
},
{
"orientation" : "portrait",
"idiom" : "ipad",
"width": 1536, "height": 2048,
"extent" : "full-screen",
"minimum-system-version" : "7.0",
"scale" : "2x"
},
{
"orientation" : "landscape",
"idiom" : "ipad",
"width": 2048, "height": 1536,
"extent" : "full-screen",
"minimum-system-version" : "7.0",
"scale" : "2x"
},
{
"orientation" : "portrait",
"idiom" : "iphone",
"width": 320, "height": 480,
"extent" : "full-screen",
"scale" : "1x"
},
{
"orientation" : "portrait",
"idiom" : "iphone",
"width": 640, "height": 960,
"extent" : "full-screen",
"scale" : "2x"
},
{
"orientation" : "portrait",
"idiom" : "iphone",
"width": 640, "height": 1136,
"extent" : "full-screen",
"subtype" : "retina4",
"scale" : "2x"
},
{
"orientation" : "portrait",
"idiom" : "ipad",
"width": 768, "height": 1004,
"extent" : "to-status-bar",
"scale" : "1x"
},
{
"orientation" : "portrait",
"idiom" : "ipad",
"width": 768, "height": 1024,
"extent" : "full-screen",
"scale" : "1x"
},
{
"orientation" : "landscape",
"idiom" : "ipad",
"width": 1024, "height": 748,
"extent" : "to-status-bar",
"scale" : "1x"
},
{
"orientation" : "landscape",
"idiom" : "ipad",
"width": 1024, "height": 768,
"extent" : "full-screen",
"scale" : "1x"
},
{
"orientation" : "portrait",
"idiom" : "ipad",
"width": 1536, "height": 2008,
"extent" : "to-status-bar",
"scale" : "2x"
},
{
"orientation" : "portrait",
"idiom" : "ipad",
"width": 1536, "height": 2048,
"extent" : "full-screen",
"scale" : "2x"
},
{
"orientation" : "landscape",
"idiom" : "ipad",
"width": 2048, "height": 1496,
"extent" : "to-status-bar",
"scale" : "2x"
},
{
"orientation" : "landscape",
"idiom" : "ipad",
"width": 2048, "height": 1536,
"extent" : "full-screen",
"scale" : "2x"
}
]
content = {
"images": [],
"info": {
"version": 1,
"author": "GCompris"
}
}
for image in images:
print(image)
width = int(image['width'])
height = int(image['height'])
sizestr = str(width) + 'x' + str(height)
image['filename'] = "appicon-" + sizestr + ".png"
content['images'].append(image)
# Calc the cropping area
rw = source_width / width
rh = source_height / height
r = min(rw, rh)
width_final = int(width * r)
height_final = int(height * r)
area_x = int((source_width - width_final) / 2)
area_y = int((source_height - height_final) / 2)
area = str(area_x) + ':' + \
str(area_y) + ':' + \
str(area_x + width_final) + ':' + \
str(area_y + height_final)
subprocess.call(["inkscape", image_source,
"-e", outdir + '/' + image['filename'],
"-a", area,
"-w", str(width),
"-h", str(height)])
with open(outdir + '/Contents.json', 'w') as f:
f.write(json.dumps(content, sort_keys=True,
indent=4, separators=(',', ': ')))
# Create the Default-658h.png
copyfile(outdir + '/appicon-640x1136.png', outdir + '/../Default-568h@2x.png')
diff --git a/platforms/ios/icon_no_corner.svg b/platforms/ios/icon_no_corner.svg
index bbc9cefb1..7e60b0413 100644
--- a/platforms/ios/icon_no_corner.svg
+++ b/platforms/ios/icon_no_corner.svg
@@ -1,3012 +1,3012 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="svg2"
viewBox="0 0 1024 1024"
version="1.1"
inkscape:version="0.91 r13725"
width="100%"
height="100%"
sodipodi:docname="icon_no_corner.svg"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1366"
inkscape:window-height="748"
id="namedview317"
showgrid="false"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:zoom="0.38670774"
inkscape:cx="528.62884"
inkscape:cy="448.49475"
inkscape:window-x="-2"
inkscape:window-y="-3"
inkscape:window-maximized="1"
inkscape:current-layer="svg2"
borderlayer="true" />
<defs
id="defs4">
<linearGradient
id="linearGradient7776">
<stop
id="stop7778"
stop-color="#187d31"
offset="0" />
<stop
id="stop7780"
stop-color="#75b652"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient3615">
<stop
id="stop3617"
stop-color="#80c93b"
offset="0" />
<stop
id="stop3619"
stop-color="#2b4900"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient3635"
x1="677.16998"
xlink:href="#linearGradient3615"
gradientUnits="userSpaceOnUse"
x2="570.04999"
y1="740.35999"
y2="1180.4" />
<linearGradient
id="linearGradient3637"
x1="547.54999"
xlink:href="#linearGradient3615"
gradientUnits="userSpaceOnUse"
x2="555.88"
y1="723.64001"
y2="1180.4" />
<linearGradient
id="linearGradient3639"
x1="548.04999"
xlink:href="#linearGradient3615"
gradientUnits="userSpaceOnUse"
x2="454.01999"
y1="590.64001"
y2="1180.4" />
<linearGradient
id="linearGradient3669"
x1="210.61"
xlink:href="#linearGradient3615"
gradientUnits="userSpaceOnUse"
y1="860.51001"
gradientTransform="matrix(0.79828,0,0,0.79828,-66.513,218.48)"
x2="203.3"
y2="1180.4" />
<linearGradient
id="linearGradient3671"
x1="230.17999"
xlink:href="#linearGradient3615"
gradientUnits="userSpaceOnUse"
y1="774.64001"
gradientTransform="matrix(0.79828,0,0,0.79828,-66.513,218.48)"
x2="245.14999"
y2="1180.4" />
<linearGradient
id="linearGradient3741"
x1="210.61"
xlink:href="#linearGradient3615"
gradientUnits="userSpaceOnUse"
x2="203.3"
y1="860.51001"
y2="1180.4" />
<linearGradient
id="linearGradient3743"
x1="230.17999"
xlink:href="#linearGradient3615"
gradientUnits="userSpaceOnUse"
x2="245.14999"
y1="774.64001"
y2="1180.4" />
<linearGradient
id="linearGradient4716"
x1="856.59998"
xlink:href="#linearGradient3615"
gradientUnits="userSpaceOnUse"
y1="727.64001"
gradientTransform="translate(-4,-7.9992)"
x2="886"
y2="1180.4" />
<linearGradient
id="linearGradient4718"
x1="776.96002"
xlink:href="#linearGradient3615"
gradientUnits="userSpaceOnUse"
x2="777.91998"
y1="794.64001"
y2="1180.4" />
<linearGradient
id="linearGradient4720"
x1="865.71002"
xlink:href="#linearGradient3615"
gradientUnits="userSpaceOnUse"
x2="838.04999"
y1="828.64001"
y2="1180.4" />
<linearGradient
id="linearGradient4738"
x1="210.61"
xlink:href="#linearGradient3615"
gradientUnits="userSpaceOnUse"
y1="860.51001"
gradientTransform="translate(586,293.73)"
x2="203.3"
y2="1180.4" />
<linearGradient
id="linearGradient7774"
x1="251.44"
xlink:href="#linearGradient7776"
gradientUnits="userSpaceOnUse"
y1="744.09003"
gradientTransform="matrix(1.4065,0,0,0.69405639,0,536.69946)"
x2="223.73"
y2="469.32001" />
<linearGradient
id="linearGradient7788"
x1="895.71997"
gradientUnits="userSpaceOnUse"
y1="693.59003"
gradientTransform="matrix(1.047,0,0,0.62289339,-49.458,397.62601)"
x2="669.35999"
y2="1204.9">
<stop
id="stop7784"
stop-color="#77b753"
offset="0" />
<stop
id="stop7786"
stop-color="#006e29"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient7792"
x1="375.14999"
gradientUnits="userSpaceOnUse"
y1="875.35999"
gradientTransform="matrix(1.1721,0,0,0.61652755,0,482.95443)"
x2="228"
y2="548.09003">
<stop
id="stop7796"
stop-color="#00892c"
offset="0" />
<stop
id="stop7798"
stop-color="#b1d28f"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient7810"
x1="854"
gradientUnits="userSpaceOnUse"
y1="670.41998"
gradientTransform="matrix(1,0,0,0.81928394,0,200.78485)"
x2="826"
y2="839.39001">
<stop
id="stop7806"
stop-color="#d8e8c2"
offset="0" />
<stop
id="stop7808"
stop-color="#5da854"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient7841"
x1="480"
gradientUnits="userSpaceOnUse"
y1="222.09"
gradientTransform="matrix(1,0,0,0.94176689,0,371.97423)"
x2="484.17999"
y2="440.09">
<stop
id="stop7837"
stop-color="#a8dde0"
offset="0" />
<stop
id="stop7839"
stop-color="#a8dde0"
stop-opacity="0"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient7990"
x1="208.62"
xlink:href="#linearGradient7776"
gradientUnits="userSpaceOnUse"
x2="371.25"
y1="564.64001"
y2="480.64001"
gradientTransform="matrix(1,0,0,0.81928394,0,443.5141)" />
<linearGradient
id="linearGradient4676"
x1="593.96997"
gradientUnits="userSpaceOnUse"
y1="619.60999"
gradientTransform="matrix(0.97268,0,0,0.72174819,-318.82,234.01009)"
x2="624.39001"
y2="531.92999">
<stop
id="stop4672"
stop-color="#e5f5f6"
offset="0" />
<stop
id="stop4674"
stop-color="#e5f5f6"
stop-opacity="0"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient4709"
x1="803.09003"
gradientUnits="userSpaceOnUse"
y1="605.83002"
gradientTransform="matrix(0.67113,0,0,0.54984603,358.52,323.05479)"
x2="803.09003"
y2="478.35999">
<stop
id="stop4705"
stop-color="#e8f6f7"
offset="0" />
<stop
id="stop4707"
stop-color="#e8f6f7"
stop-opacity="0"
offset="1" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3294"
gradientUnits="userSpaceOnUse"
x1="210.61"
y1="860.51001"
x2="203.3"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3296"
gradientUnits="userSpaceOnUse"
x1="230.17999"
y1="774.64001"
x2="245.14999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3298"
gradientUnits="userSpaceOnUse"
x1="210.61"
y1="860.51001"
x2="203.3"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3300"
gradientUnits="userSpaceOnUse"
x1="230.17999"
y1="774.64001"
x2="245.14999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3302"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-4,-7.9992)"
x1="856.59998"
y1="727.64001"
x2="886"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3304"
gradientUnits="userSpaceOnUse"
x1="776.96002"
y1="794.64001"
x2="777.91998"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3306"
gradientUnits="userSpaceOnUse"
x1="865.71002"
y1="828.64001"
x2="838.04999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3308"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.79828,0,0,0.79828,-66.513,218.48)"
x1="210.61"
y1="860.51001"
x2="203.3"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3310"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.79828,0,0,0.79828,-66.513,218.48)"
x1="230.17999"
y1="774.64001"
x2="245.14999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3312"
gradientUnits="userSpaceOnUse"
x1="548.04999"
y1="590.64001"
x2="454.01999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3314"
gradientUnits="userSpaceOnUse"
x1="677.16998"
y1="740.35999"
x2="570.04999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3316"
gradientUnits="userSpaceOnUse"
x1="547.54999"
y1="723.64001"
x2="555.88"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3318"
gradientUnits="userSpaceOnUse"
x1="210.61"
y1="860.51001"
x2="203.3"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3320"
gradientUnits="userSpaceOnUse"
x1="230.17999"
y1="774.64001"
x2="245.14999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3322"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(586,293.73)"
x1="210.61"
y1="860.51001"
x2="203.3"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3324"
gradientUnits="userSpaceOnUse"
x1="230.17999"
y1="774.64001"
x2="245.14999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3326"
gradientUnits="userSpaceOnUse"
x1="548.04999"
y1="590.64001"
x2="454.01999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3328"
gradientUnits="userSpaceOnUse"
x1="677.16998"
y1="740.35999"
x2="570.04999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3330"
gradientUnits="userSpaceOnUse"
x1="547.54999"
y1="723.64001"
x2="555.88"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3332"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-4,-7.9992)"
x1="856.59998"
y1="727.64001"
x2="886"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3334"
gradientUnits="userSpaceOnUse"
x1="776.96002"
y1="794.64001"
x2="777.91998"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3336"
gradientUnits="userSpaceOnUse"
x1="865.71002"
y1="828.64001"
x2="838.04999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3338"
gradientUnits="userSpaceOnUse"
x1="548.04999"
y1="590.64001"
x2="454.01999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3340"
gradientUnits="userSpaceOnUse"
x1="677.16998"
y1="740.35999"
x2="570.04999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3342"
gradientUnits="userSpaceOnUse"
x1="547.54999"
y1="723.64001"
x2="555.88"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3344"
gradientUnits="userSpaceOnUse"
x1="210.61"
y1="860.51001"
x2="203.3"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3346"
gradientUnits="userSpaceOnUse"
x1="230.17999"
y1="774.64001"
x2="245.14999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3348"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.79828,0,0,0.79828,-66.513,218.48)"
x1="210.61"
y1="860.51001"
x2="203.3"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3350"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.79828,0,0,0.79828,-66.513,218.48)"
x1="230.17999"
y1="774.64001"
x2="245.14999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3352"
gradientUnits="userSpaceOnUse"
x1="548.04999"
y1="590.64001"
x2="454.01999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3354"
gradientUnits="userSpaceOnUse"
x1="677.16998"
y1="740.35999"
x2="570.04999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3356"
gradientUnits="userSpaceOnUse"
x1="547.54999"
y1="723.64001"
x2="555.88"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3358"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(586,293.73)"
x1="210.61"
y1="860.51001"
x2="203.3"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3360"
gradientUnits="userSpaceOnUse"
x1="230.17999"
y1="774.64001"
x2="245.14999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3362"
gradientUnits="userSpaceOnUse"
x1="210.61"
y1="860.51001"
x2="203.3"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3364"
gradientUnits="userSpaceOnUse"
x1="230.17999"
y1="774.64001"
x2="245.14999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3366"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-4,-7.9992)"
x1="856.59998"
y1="727.64001"
x2="886"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3368"
gradientUnits="userSpaceOnUse"
x1="776.96002"
y1="794.64001"
x2="777.91998"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3370"
gradientUnits="userSpaceOnUse"
x1="865.71002"
y1="828.64001"
x2="838.04999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3372"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-4,-7.9992)"
x1="856.59998"
y1="727.64001"
x2="886"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3374"
gradientUnits="userSpaceOnUse"
x1="776.96002"
y1="794.64001"
x2="777.91998"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3376"
gradientUnits="userSpaceOnUse"
x1="865.71002"
y1="828.64001"
x2="838.04999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3378"
gradientUnits="userSpaceOnUse"
x1="210.61"
y1="860.51001"
x2="203.3"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3380"
gradientUnits="userSpaceOnUse"
x1="230.17999"
y1="774.64001"
x2="245.14999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3382"
gradientUnits="userSpaceOnUse"
x1="210.61"
y1="860.51001"
x2="203.3"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3384"
gradientUnits="userSpaceOnUse"
x1="230.17999"
y1="774.64001"
x2="245.14999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3386"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-4,-7.9992)"
x1="856.59998"
y1="727.64001"
x2="886"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3388"
gradientUnits="userSpaceOnUse"
x1="776.96002"
y1="794.64001"
x2="777.91998"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3390"
gradientUnits="userSpaceOnUse"
x1="865.71002"
y1="828.64001"
x2="838.04999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3392"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.79828,0,0,0.79828,-66.513,218.48)"
x1="210.61"
y1="860.51001"
x2="203.3"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3394"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.79828,0,0,0.79828,-66.513,218.48)"
x1="230.17999"
y1="774.64001"
x2="245.14999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3396"
gradientUnits="userSpaceOnUse"
x1="548.04999"
y1="590.64001"
x2="454.01999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3398"
gradientUnits="userSpaceOnUse"
x1="677.16998"
y1="740.35999"
x2="570.04999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3400"
gradientUnits="userSpaceOnUse"
x1="547.54999"
y1="723.64001"
x2="555.88"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3402"
gradientUnits="userSpaceOnUse"
x1="210.61"
y1="860.51001"
x2="203.3"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3404"
gradientUnits="userSpaceOnUse"
x1="230.17999"
y1="774.64001"
x2="245.14999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3406"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(586,293.73)"
x1="210.61"
y1="860.51001"
x2="203.3"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3408"
gradientUnits="userSpaceOnUse"
x1="230.17999"
y1="774.64001"
x2="245.14999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3410"
gradientUnits="userSpaceOnUse"
x1="548.04999"
y1="590.64001"
x2="454.01999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3412"
gradientUnits="userSpaceOnUse"
x1="677.16998"
y1="740.35999"
x2="570.04999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3414"
gradientUnits="userSpaceOnUse"
x1="547.54999"
y1="723.64001"
x2="555.88"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3416"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-4,-7.9992)"
x1="856.59998"
y1="727.64001"
x2="886"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3418"
gradientUnits="userSpaceOnUse"
x1="776.96002"
y1="794.64001"
x2="777.91998"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3420"
gradientUnits="userSpaceOnUse"
x1="865.71002"
y1="828.64001"
x2="838.04999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3422"
gradientUnits="userSpaceOnUse"
x1="548.04999"
y1="590.64001"
x2="454.01999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3424"
gradientUnits="userSpaceOnUse"
x1="677.16998"
y1="740.35999"
x2="570.04999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3426"
gradientUnits="userSpaceOnUse"
x1="547.54999"
y1="723.64001"
x2="555.88"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3428"
gradientUnits="userSpaceOnUse"
x1="210.61"
y1="860.51001"
x2="203.3"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3430"
gradientUnits="userSpaceOnUse"
x1="230.17999"
y1="774.64001"
x2="245.14999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3432"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.79828,0,0,0.79828,-66.513,218.48)"
x1="210.61"
y1="860.51001"
x2="203.3"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3434"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.79828,0,0,0.79828,-66.513,218.48)"
x1="230.17999"
y1="774.64001"
x2="245.14999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3436"
gradientUnits="userSpaceOnUse"
x1="548.04999"
y1="590.64001"
x2="454.01999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3438"
gradientUnits="userSpaceOnUse"
x1="677.16998"
y1="740.35999"
x2="570.04999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3440"
gradientUnits="userSpaceOnUse"
x1="547.54999"
y1="723.64001"
x2="555.88"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3442"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(586,293.73)"
x1="210.61"
y1="860.51001"
x2="203.3"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3444"
gradientUnits="userSpaceOnUse"
x1="230.17999"
y1="774.64001"
x2="245.14999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3446"
gradientUnits="userSpaceOnUse"
x1="210.61"
y1="860.51001"
x2="203.3"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3448"
gradientUnits="userSpaceOnUse"
x1="230.17999"
y1="774.64001"
x2="245.14999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3450"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-4,-7.9992)"
x1="856.59998"
y1="727.64001"
x2="886"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3452"
gradientUnits="userSpaceOnUse"
x1="776.96002"
y1="794.64001"
x2="777.91998"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3454"
gradientUnits="userSpaceOnUse"
x1="865.71002"
y1="828.64001"
x2="838.04999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3456"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-4,-7.9992)"
x1="856.59998"
y1="727.64001"
x2="886"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3458"
gradientUnits="userSpaceOnUse"
x1="776.96002"
y1="794.64001"
x2="777.91998"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3460"
gradientUnits="userSpaceOnUse"
x1="865.71002"
y1="828.64001"
x2="838.04999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3462"
gradientUnits="userSpaceOnUse"
x1="210.61"
y1="860.51001"
x2="203.3"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3464"
gradientUnits="userSpaceOnUse"
x1="230.17999"
y1="774.64001"
x2="245.14999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3466"
gradientUnits="userSpaceOnUse"
x1="210.61"
y1="860.51001"
x2="203.3"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3468"
gradientUnits="userSpaceOnUse"
x1="230.17999"
y1="774.64001"
x2="245.14999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3470"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-4,-7.9992)"
x1="856.59998"
y1="727.64001"
x2="886"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3472"
gradientUnits="userSpaceOnUse"
x1="776.96002"
y1="794.64001"
x2="777.91998"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3474"
gradientUnits="userSpaceOnUse"
x1="865.71002"
y1="828.64001"
x2="838.04999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3476"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.79828,0,0,0.79828,-66.513,218.48)"
x1="210.61"
y1="860.51001"
x2="203.3"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3478"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.79828,0,0,0.79828,-66.513,218.48)"
x1="230.17999"
y1="774.64001"
x2="245.14999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3480"
gradientUnits="userSpaceOnUse"
x1="548.04999"
y1="590.64001"
x2="454.01999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3482"
gradientUnits="userSpaceOnUse"
x1="677.16998"
y1="740.35999"
x2="570.04999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3484"
gradientUnits="userSpaceOnUse"
x1="547.54999"
y1="723.64001"
x2="555.88"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3486"
gradientUnits="userSpaceOnUse"
x1="210.61"
y1="860.51001"
x2="203.3"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3488"
gradientUnits="userSpaceOnUse"
x1="230.17999"
y1="774.64001"
x2="245.14999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3490"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(586,293.73)"
x1="210.61"
y1="860.51001"
x2="203.3"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3492"
gradientUnits="userSpaceOnUse"
x1="230.17999"
y1="774.64001"
x2="245.14999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3494"
gradientUnits="userSpaceOnUse"
x1="548.04999"
y1="590.64001"
x2="454.01999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3496"
gradientUnits="userSpaceOnUse"
x1="677.16998"
y1="740.35999"
x2="570.04999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3498"
gradientUnits="userSpaceOnUse"
x1="547.54999"
y1="723.64001"
x2="555.88"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3500"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-4,-7.9992)"
x1="856.59998"
y1="727.64001"
x2="886"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3502"
gradientUnits="userSpaceOnUse"
x1="776.96002"
y1="794.64001"
x2="777.91998"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3504"
gradientUnits="userSpaceOnUse"
x1="865.71002"
y1="828.64001"
x2="838.04999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3506"
gradientUnits="userSpaceOnUse"
x1="548.04999"
y1="590.64001"
x2="454.01999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3508"
gradientUnits="userSpaceOnUse"
x1="677.16998"
y1="740.35999"
x2="570.04999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3510"
gradientUnits="userSpaceOnUse"
x1="547.54999"
y1="723.64001"
x2="555.88"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3512"
gradientUnits="userSpaceOnUse"
x1="210.61"
y1="860.51001"
x2="203.3"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3514"
gradientUnits="userSpaceOnUse"
x1="230.17999"
y1="774.64001"
x2="245.14999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3516"
gradientUnits="userSpaceOnUse"
x1="230.17999"
y1="774.64001"
x2="245.14999"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3518"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(-4,-7.9992)"
x1="856.59998"
y1="727.64001"
x2="886"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3520"
gradientUnits="userSpaceOnUse"
x1="776.96002"
y1="794.64001"
x2="777.91998"
y2="1180.4" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient3615"
id="linearGradient3522"
gradientUnits="userSpaceOnUse"
x1="865.71002"
y1="828.64001"
x2="838.04999"
y2="1180.4" />
<linearGradient
id="linearGradient738-7">
<stop
id="stop739-2"
offset="0"
style="stop-color:#f19e9e;stop-opacity:1;" />
<stop
id="stop740-4"
offset="1"
style="stop-color:#ff0000;stop-opacity:1;" />
</linearGradient>
<linearGradient
y2="1015.9534"
x2="112.09986"
y1="1017.7301"
x1="102.07376"
spreadMethod="reflect"
gradientTransform="matrix(0.52171355,0,0,0.09229801,87.668261,762.46005)"
gradientUnits="userSpaceOnUse"
id="linearGradient3106-2"
xlink:href="#linearGradient738-7"
inkscape:collect="always" />
<linearGradient
id="linearGradient635-22">
<stop
id="stop636-3"
offset="0"
style="stop-color:#ff8200;stop-opacity:1;" />
<stop
id="stop637-3"
offset="1"
style="stop-color:#ffe700;stop-opacity:1;" />
</linearGradient>
<linearGradient
y2="603.40045"
x2="315.1499"
y1="633.70721"
x1="293.72403"
gradientTransform="scale(1.3436351,0.7442497)"
gradientUnits="userSpaceOnUse"
id="linearGradient3104-8"
xlink:href="#linearGradient635-22"
inkscape:collect="always" />
<radialGradient
r="3.2000804"
fy="448.45496"
fx="398.81259"
cy="448.45496"
cx="398.81259"
gradientUnits="userSpaceOnUse"
id="radialGradient3102-4"
xlink:href="#linearGradient716-16"
inkscape:collect="always" />
<linearGradient
id="linearGradient716-16">
<stop
id="stop717-2"
offset="0"
style="stop-color:#ffffff;stop-opacity:1;" />
<stop
id="stop718-0"
offset="1"
style="stop-color:#000000;stop-opacity:1;" />
</linearGradient>
<radialGradient
r="3.2000804"
fy="448.45496"
fx="398.81259"
cy="448.45496"
cx="398.81259"
gradientUnits="userSpaceOnUse"
id="radialGradient3100-7"
xlink:href="#linearGradient716-16"
inkscape:collect="always" />
<linearGradient
gradientUnits="userSpaceOnUse"
gradientTransform="scale(2.2558569,0.44329054)"
y2="119.12351"
x2="258.64993"
y1="545.64081"
x1="194.26202"
id="linearGradient637"
xlink:href="#linearGradient628" />
<linearGradient
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.6192581,0,0,0.61756676,-66.801789,-74.621212)"
y2="580.16156"
x2="205.19817"
y1="456.88339"
x1="322.31024"
id="linearGradient632"
xlink:href="#linearGradient633" />
<linearGradient
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(2.0877407,-0.84804708,0.16700936,0.41114727,-222.15059,-6.2881116)"
y2="946.07745"
x2="127.97075"
y1="705.98572"
x1="112.32906"
id="linearGradient631"
xlink:href="#linearGradient628" />
<linearGradient
id="linearGradient628">
<stop
id="stop629"
offset="0"
style="stop-color:#ff9700;stop-opacity:0.9059;" />
<stop
id="stop630"
offset="1"
style="stop-color:#ffffff;stop-opacity:1;" />
</linearGradient>
<linearGradient
id="linearGradient633">
<stop
id="stop634"
offset="0"
style="stop-color:#ff9700;stop-opacity:0.7922;" />
<stop
id="stop635"
offset="1"
style="stop-color:#ffc500;stop-opacity:0.0706;" />
</linearGradient>
</defs>
<rect
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect3937"
width="2125.6072"
height="1037.894"
x="-460"
y="-13.894101" />
<g
id="layer1"
transform="matrix(2.019771,0,0,2.0757882,-460,-1157.3795)"
inkscape:export-filename="/home/bdoin/Projets/gcompris/gcompris-gtk/macosx/promotional.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
<rect
id="rect7833"
height="365.40063"
width="1052.4"
y="556.64899"
x="0"
style="fill:url(#linearGradient7841)" />
<path
id="path7800"
d="M 1052.4,787.5642 C 985.12,759.45457 378.09,678.05871 176.36,904.02541 l 876,57.34988 V 787.5642 z"
style="fill:url(#linearGradient7810)"
inkscape:connector-curvature="0" />
<path
id="path7790"
d="m 0,785.11454 c 349.92,-31.24749 663.29,13.15934 908,120.54944 L 0,941.71248 V 785.11454 z"
style="fill:url(#linearGradient7792)"
inkscape:connector-curvature="0" />
<path
id="path7772"
d="m 747.44,807.43184 c 2.8246,5.11725 6.9832,14.00566 10.844,22.96535 -0.48961,0.0164 -0.97963,0.0342 -1.4688,0.0512 -4.8827,-4.85532 -11.656,-9.00311 -21.25,-10.7785 5.9514,1.73041 11.129,5.95554 15.375,10.95792 -38.997,1.54739 -76.415,4.98748 -112.41,10.6507 2.0814,-4.18696 4.7173,-7.87447 7.9375,-10.34346 -4.911,2.89215 -8.616,6.44432 -11.406,10.24104 -0.16907,-8.13516 -0.84545,-15.30668 -2.4688,-18.33147 0.0418,4.59364 -0.33431,11.85749 -0.9375,19.5604 -1.0719,0.17808 -2.1494,0.35555 -3.2188,0.53766 -2.2022,-4.46756 -5.7629,-8.69097 -11.438,-12.03365 3.8089,2.92042 6.1528,7.55937 7.5312,12.6989 -13.704,2.40378 -27.171,5.15027 -40.469,8.24364 -0.0212,-4.36457 0.66168,-8.44764 2.4062,-11.6494 -2.9891,4.00368 -4.6712,8.20677 -5.5,12.36627 -0.15449,0.0367 -0.31431,0.0656 -0.46875,0.10241 -3.9028,-7.18897 -7.8054,-13.32975 -10.656,-15.54099 2.0066,3.82376 4.7287,9.79699 7.5312,16.30866 -1.6574,0.40246 -3.3176,0.81521 -4.9688,1.22893 -3.5926,-2.32652 -7.8964,-4.14754 -13.094,-5.12053 3.5561,1.07564 6.8334,3.22356 9.7812,5.96537 -120.31,30.77231 -224.25,91.80896 -318.7,197.61951 H 1052.3919 V 846.54113 c -29.105,-3.37725 -57.46305,-6.30291 -85.12505,-8.7565 1.1335,-6.75442 3.6365,-13.21833 8.4688,-16.92313 -7.5464,4.4442 -11.384,10.44177 -13.219,16.51349 -0.35455,-0.0308 -0.70818,-0.0718 -1.0625,-0.10241 -0.83769,-9.44307 -1.3944,-18.93693 -1.3438,-24.50151 -1.6233,3.02504 -2.2684,10.22221 -2.4375,18.35688 -2.7902,-3.79673 -6.5265,-7.3489 -11.438,-10.24105 4.602,3.52841 8.0055,9.55203 10.312,15.95064 -12.541,-1.05967 -24.934,-2.00242 -37.188,-2.84194 1.1734,-6.56803 3.6648,-12.79967 8.375,-16.41107 -7.366,4.33794 -11.207,10.15584 -13.094,16.07844 -0.40531,-0.0269 -0.81375,-0.0501 -1.2188,-0.0768 -0.8175,-9.30625 -1.3624,-18.6084 -1.3125,-24.09187 -1.6233,3.02505 -2.2684,10.22221 -2.4375,18.35688 -2.7902,-3.79673 -6.5265,-7.3489 -11.438,-10.24105 4.5273,3.47114 7.8829,9.36114 10.188,15.64341 -33.532,-2.12457 -65.972,-3.32384 -97.438,-3.53316 2.1959,-4.90317 5.0861,-9.30052 8.75,-12.10984 -4.911,2.89215 -8.6473,6.44432 -11.438,10.24105 -0.16907,-8.13516 -0.8142,-15.33208 -2.4375,-18.35688 0.0429,4.71015 -0.36975,12.24912 -1,20.17487 -1.0445,-0.002 -2.0827,1.5e-4 -3.125,0 -2.2092,-4.48771 -5.8024,-8.72865 -11.5,-12.08444 3.6621,2.80777 5.9678,7.2079 7.375,12.10984 -11.527,0.0326 -22.926,0.18284 -34.188,0.51205 -1.1304,-7.14252 -0.87696,-14.42513 2.2812,-19.45799 -3.5679,4.17605 -5.5851,8.58118 -6.5312,12.95451 -4.2564,-7.50652 -8.541,-13.96551 -11.719,-16.28326 z"
style="fill:url(#linearGradient7788)"
inkscape:connector-curvature="0" />
<path
id="rect7769"
d="M 0,876.84977 C 419.91,841.67381 709.55,860.30515 948,1053.1433 H 0 V 876.84977 z"
style="fill:url(#linearGradient7774)"
inkscape:connector-curvature="0" />
<path
id="path7764"
d="m 983.59,891.30193 c 5.3725,10.20173 5.627,42.89853 4.7744,70.27081 2.5959,-10.83995 7.3248,-22.65648 15.688,-33.34322 -0.6565,-0.58547 -1.3041,-1.15863 -1.9861,-1.69149 0.7529,0.45175 1.481,0.92341 2.2067,1.38999 5.4744,-6.92508 12.504,-13.3576 21.445,-18.72309 -6.7394,5.26521 -12.218,13.17818 -16.53,22.13951 17.901,13.45592 26.4,31.57192 30.231,47.56189 -0.8516,-27.36654 -0.5963,-60.05597 4.7744,-70.25442 -0.1157,12.94714 1.3316,36.00999 3.3702,57.84472 0.9809,-4.96797 2.5119,-9.98789 4.7945,-14.87164 V 1056.649 H 5.9581 v -56.1193 c 2.6615,-13.0594 4.7208,-32.96062 0,-49.33729 V 944.996 c 2.096,2.9645 3.8305,6.04894 5.2559,9.19401 5.5071,12.15243 6.4385,25.26262 5.978,36.291 2.0076,-18.47076 2.9343,-41.74088 2.7884,-53.45664 1.2199,1.66224 2.2311,4.17392 3.0893,7.26819 0.27037,0.97462 -0.95993,3.2515 -0.72214,4.33754 0.25572,1.16691 1.6058,-2.7183 1.8255,-1.44022 1.5288,8.89251 2.3028,21.17112 2.5678,32.89097 2.9228,-8.04586 7.8877,-16.62163 16.149,-24.88657 1.0478,-1.04827 -0.07272,2.39362 1.0834,1.35657 0.85284,-0.7651 3.9605,-6.00846 4.8747,-6.76581 3.7473,-3.10451 8.0139,-6.12406 12.879,-9.04325 -21.384,16.70684 -28.984,49.03086 -27.523,65.29691 l -1.6249,20.7164 20.682,26.3933 3.7513,-22.7425 11.675,22.9432 c -1.1536,-22.1141 3.915,-117.24774 11.354,-129.03723 -1.0937,10.59334 -0.72013,28.87156 0.50154,46.47306 1.9284,-9.33492 4.6285,-17.35325 8.3853,-20.51487 -2.1733,12.22208 -2.7111,40.56684 -1.2036,55.76784 h 7.1015 c 0.92401,-12.53505 0.43793,-32.89917 -1.1835,-42.01862 3.2086,2.70077 5.4447,9.83715 7.0011,17.95297 0.95463,-10.62939 1.5193,-21.70856 1.3039,-30.32907 -0.076,-3.04069 -4.2982,-3.74994 -4.5336,-6.02895 0.84076,1.3329 7.0693,1.52387 7.6431,3.85187 1.2837,5.20859 1.9469,12.58092 2.2268,20.54846 1.3851,3.34587 2.5025,7.63523 3.3902,12.25894 0.90322,-10.06244 1.4326,-20.49111 1.3039,-28.88877 -0.0867,-0.57817 -0.168,-1.18657 -0.26075,-1.70821 0.0784,0.0657 0.14302,0.14753 0.22069,0.21773 -0.16042,-2.96106 -4.2808,-3.69006 -4.5137,-5.94522 0.841,1.33298 7.0894,1.52387 7.6632,3.85179 0.68676,2.78663 1.1961,6.20075 1.5647,9.98133 1.4215,3.70071 2.6146,8.20349 3.5908,13.04628 0.54861,-8.50335 0.79987,-16.99687 0.66203,-24.53428 -0.3173,-0.9117 -0.65759,-1.79702 -1.0231,-2.67955 -0.68443,-1.6529 -1.2612,-1.8687 -2.1265,-3.3997 -1.7705,-3.13335 -2.2309,-4.54268 -4.1324,-6.39738 2.7143,2.43549 5.0815,5.0123 7.1215,7.70365 -0.11517,-2.61254 -0.2702,-5.07948 -0.50156,-7.3185 1.8891,2.99399 3.3624,7.72707 4.5137,13.44772 0.83567,1.4793 1.6002,2.97302 2.2869,4.48821 5.5403,12.22535 6.4377,25.43958 5.958,36.50893 2.023,-18.50271 2.9351,-41.899 2.7885,-53.65737 1.2201,1.66217 2.251,4.15721 3.1094,7.25149 0.27033,0.97462 -0.94005,3.25149 -0.70214,4.33753 0.25549,1.16699 1.6057,-2.70159 1.8255,-1.42351 1.5281,8.88924 2.2826,21.15801 2.5477,32.87459 2.9228,-8.04619 7.8873,-16.58804 16.149,-24.85298 1.0478,-1.04819 -0.073,2.3602 1.0832,1.32298 0.50411,-0.45199 1.7703,-2.40926 2.9289,-4.13656 -0.0698,-0.44934 -0.1269,-0.943 -0.20067,-1.35649 0.23264,0.1956 0.45764,0.40442 0.68213,0.63636 0.60753,-0.88605 1.167,-1.64602 1.4644,-1.89238 2.138,-1.77113 4.4491,-3.52456 6.941,-5.24186 -0.11119,-3.24133 -0.3021,-6.28366 -0.5818,-8.99328 1.1194,1.77457 2.0975,4.18056 2.949,7.017 0.21293,-0.49282 0.49609,-0.91694 0.84255,-1.27275 1.6875,-1.73328 3.3555,-0.31745 4.6942,1.22253 4.6132,2.80613 8.687,5.71746 12.277,8.69178 0.20004,0.16567 0.49982,0.57127 0.86264,1.07179 0.13719,-4.71039 0.20345,-9.23005 0.16049,-13.38054 -0.0135,-1.32462 -0.0699,-4.84959 -0.5818,-5.05769 -1.4947,-0.6076 -4.7118,4.98682 -4.9951,2.2441 0.71923,1.13979 3.1082,-4.44076 5.7574,-4.23701 0.49057,0.0383 0.98416,0.2732 1.4845,0.78707 1.2903,1.32528 1.4438,3.57904 2.0262,6.88305 0.93416,5.30159 1.6376,11.50357 2.1464,18.05374 7.707,7.97008 12.415,16.19233 15.226,23.93129 0.26512,-11.71986 1.0391,-23.99847 2.5678,-32.89098 0.21986,-1.27808 1.5701,2.59042 1.8256,1.42351 0.23777,-1.08604 -0.99244,-3.363 -0.72219,-4.33753 0.85847,-3.09428 1.9094,-5.58932 3.1295,-7.25149 -0.14597,11.71576 0.741,34.98589 2.7483,53.45664 -0.4604,-11.0292 0.49102,-24.15577 5.9982,-36.30739 3.0444,-6.71755 7.4708,-13.14704 13.862,-18.75668 -2.3009,2.08123 -2.6696,3.46303 -4.5738,6.83283 -0.86527,1.53091 -1.4421,1.73 -2.1265,3.3829 -7.8457,18.94676 -2.6616,54.07028 0.68212,68.06038 l 13.942,-9.0433 c -0.41039,-17.47119 0.23117,-42.73954 3.1496,-59.30137 0.58205,-3.30401 0.73586,-5.5912 2.0261,-6.91656 0.60046,-0.61675 1.2016,-0.81651 1.7854,-0.77035 2.53,0.19984 4.764,5.33452 5.4565,4.237 -0.28316,2.7428 -3.5004,-2.86847 -4.9951,-2.26081 -0.51214,0.20816 -0.58815,3.7497 -0.60182,5.0744 -0.10095,9.75275 0.34459,21.54635 1.1435,33.04172 0.31563,-1.531 0.64482,-3.02652 1.003,-4.47149 1.0228,-7.28949 2.6205,-13.32483 5.0152,-16.07763 -0.078,0.95046 -0.17126,2.01741 -0.22069,3.14843 0.79914,-1.31036 1.6651,-2.38846 2.5878,-3.16514 -1.2246,6.88731 -1.9467,18.89597 -2.0662,30.7977 0.34068,5.8202 0.80153,11.5896 1.344,16.6634 l 15.627,22.9605 c 0.74267,-14.0557 -1.323,-63.88535 -12.217,-83.6981 -3.9174,-7.12605 -9.378,-3.77501 -14.985,-8.15589 7.623,4.57456 14.559,0.35861 19.619,6.12948 10.494,11.96892 16.025,25.73862 18.797,38.08277 -0.0977,-12.3335 0.33946,-25.55264 1.8856,-38.56861 0.803,-6.7559 -5.9754,-29.27793 -4.2929,-32.47232 -0.0373,4.18294 8.5908,8.7901 8.8467,14.70369 0.27205,6.28694 -1.4147,11.18978 -1.0231,18.53876 0.43909,8.23708 1.1699,17.07306 2.0663,25.74026 1.7192,-9.97724 5.5557,-20.24532 13.2,-29.30742 4.1125,-4.87507 15.609,-1.36141 22.187,-5.30888 -5.2091,4.06971 -15.393,1.69411 -18.255,8.1894 -8.9818,20.37887 -7.7815,49.0538 -5.1355,63.17006 l 25.617,26.4268 c -1.4542,-17.2688 -1.3537,-68.29876 -19.098,-82.15776 20.143,12.08771 30.099,26.13515 34.845,38.93728 0.41129,-17.67031 2.2237,-36.2828 6.9008,-42.6552 -0.0874,7.0075 0.20529,18.16681 0.88267,29.94401 2.099,-12.28762 8.424,-24.77842 23.371,-34.68356 -0.0489,-0.11269 -0.0909,-0.23951 -0.14039,-0.3517 -2.8627,-6.49529 -13.046,-4.13641 -18.255,-8.20595 6.5782,3.94747 18.095,0.4673 22.207,5.3423 7.6415,9.05882 11.46,19.31626 13.18,29.29104 0.89575,-8.66229 1.6476,-17.50728 2.0863,-25.74026 0.39183,-7.34922 -1.3152,-12.23519 -1.0432,-18.52237 8.8887,-29.58926 11.272,4.05816 4.5738,17.75224 1.5477,13.02662 1.9844,26.26051 1.8857,38.6022 1.7296,-7.72003 4.5437,-15.98423 8.9671,-24.03205 0.40826,-3.81746 0.88921,-7.43672 1.4644,-10.70149 0.58217,-3.30409 0.73567,-5.57449 2.0262,-6.89985 2.5144,-2.58279 5.0076,1.84651 6.3792,3.21537 -2.7986,-5.93383 -6.5057,-11.10048 -11.354,-14.88803 6.2067,3.72471 11.207,7.9813 15.206,12.54324 4.4961,-1.60506 9.926,0.01 15.748,-3.48335 -4.9628,3.87718 -9.8334,1.70747 -13.601,6.09588 6.2598,8.06093 9.6838,16.9518 11.414,25.70667 2.0373,-21.82654 3.4859,-44.86972 3.3702,-57.81113 5.3709,10.19844 5.6461,42.87149 4.7945,70.23721 2.602,-10.85879 7.3563,-22.69416 15.748,-33.39401 -3.8954,-7.04027 -8.5892,-13.179 -14.143,-17.51711 6.7966,4.07856 12.454,8.78928 17.192,13.84999 4.9954,-5.61816 11.11,-10.83831 18.556,-15.30668 -6.0041,4.69073 -11.015,11.49619 -15.086,19.25891 8.972,10.99888 13.994,23.31272 16.69,34.56641 -0.48595,-15.61801 -0.62114,-32.95734 0.36109,-46.87533 -0.1583,-0.11194 -0.30274,-0.22786 -0.46142,-0.35171 0.15644,0.0938 0.30556,0.18131 0.46142,0.26796 0.74035,-10.42703 2.0946,-18.93038 4.3933,-23.29552 -0.0572,6.36862 0.29933,15.22066 0.88266,25.13727 5.3421,0.95971 10.146,-0.24724 13.902,4.03604 0.42027,0.47936 0.81931,0.95536 1.2237,1.44022 0.62454,-0.75064 1.2889,-1.4938 1.966,-2.22731 -0.0912,-3.99548 -0.27513,-7.63097 -0.58179,-10.60071 1.1763,1.86436 2.1822,4.64992 3.0492,8.07216 2.9756,-2.8584 6.3941,-5.55418 10.331,-8.03865 -0.3139,-8.37309 -5.8559,-27.56645 -4.313,-30.49621 -0.0373,4.18294 8.5708,8.82369 8.8267,14.73728 0.27206,6.28694 -1.4148,11.17339 -1.0231,18.52237 0.61992,11.63137 2.9164,26.46615 5.4364,40.37759 0.16614,0.30447 0.34216,0.62456 0.50156,0.95463 0.53716,-6.20903 1.7599,-12.67678 4.1324,-19.00821 -1.2888,-1.27513 -3.1938,-2.08688 -3.3501,-3.60059 0.4371,0.69284 2.3322,1.06851 4.1325,1.60777 1.036,-2.49472 2.2583,-4.9679 3.6912,-7.38552 -1.0585,-0.97052 -2.1543,-1.90959 -3.2899,-2.79671 1.2495,0.74982 2.4587,1.51338 3.6309,2.27761 1.4793,-2.43499 3.152,-4.81354 5.0955,-7.11753 0.11554,-0.13688 0.23418,-0.26105 0.36103,-0.38522 -0.0488,-0.1106 -0.0992,-0.19277 -0.16049,-0.21763 -1.4948,-0.60769 -4.7118,5.00361 -4.9951,2.26081 0.85225,1.35084 4.0399,-6.73885 7.2419,-3.44992 0.0141,0.0141 0.0267,0.0192 0.0401,0.0333 5.1715,-2.19781 14.167,-0.26413 19.699,-3.58387 -5.1453,4.01981 -15.132,1.76793 -18.135,7.97163 0.12716,0.74923 0.26229,1.57606 0.4213,2.47858 0.55393,3.14359 1.0055,6.62227 1.4042,10.28283 10.691,9.32345 16.822,19.19664 20.241,28.42014 0.41103,-17.67277 2.223,-36.28199 6.9008,-42.6552 -0.0873,7.01692 0.22348,18.18319 0.90278,29.9776 1.2521,-7.37241 4.013,-14.81675 9.248,-21.73806 -1.245,-1.17559 -2.5372,-2.30792 -3.8918,-3.36619 1.5073,0.90449 2.9579,1.82127 4.3532,2.74649 3.9693,-5.07981 9.2995,-9.87483 16.369,-14.11791 -4.4975,3.51383 -7.8223,8.07528 -10.231,13.23062 1.358,1.81742 2.4872,4.62429 3.4304,8.08879 1.1413,0.97495 2.2478,1.94449 3.29,2.93083 -0.0315,-4.61569 -0.23065,-8.74013 -0.64194,-11.95745 2.4143,3.09083 4.1258,9.26364 5.316,16.78057 0.21646,0.24258 0.43081,0.4772 0.64193,0.72013 0.37324,-4.07184 0.89449,-7.7374 1.6249,-10.70149 0.23669,-0.9602 1.4406,-1.5609 2.8286,-2.02642 -2.204,-3.79836 -4.9955,-7.17201 -8.5057,-9.91415 4.6209,2.77295 8.496,5.79315 11.735,8.95969 0.77162,-0.25431 1.3827,-0.5355 1.6049,-0.88762 -0.0629,0.61243 -0.42234,1.11169 -0.90276,1.57434 2.2828,2.31382 4.2564,4.71351 5.9178,7.16775 1.0926,-7.28597 2.68,-13.20604 4.935,-16.27835 -0.0821,6.58 0.17049,16.79368 0.76225,27.76635 0.11431,0.33598 0.23449,0.68503 0.34105,1.02157 0.54681,-2.84652 1.32,-5.69919 2.3872,-8.52465 0.17133,-5.58383 0.24739,-10.56795 0.20067,-14.31863 1.2268,1.67142 2.2481,4.20031 3.1094,7.3185 1.7049,-2.9586 3.7958,-5.85812 6.3392,-8.64181 -2.4382,-5.55638 -5.8936,-10.46799 -10.672,-14.20146 5.643,3.38626 10.163,7.119 13.782,11.07016 3.028,-2.81481 6.5806,-5.4969 10.732,-7.98834 -3.6264,2.83316 -6.5099,6.34617 -8.7464,10.29921 4.9464,6.09048 7.8945,12.62927 9.5087,19.19255 0.34587,-0.33265 0.70646,-0.65649 1.0632,-0.98806 0.49165,-9.93873 0.71718,-19.06637 0.64194,-25.10368 2.6205,3.5702 4.3307,11.0079 5.4163,19.94547 1.2734,-0.98871 2.6253,-1.9766 4.0121,-2.94754 -0.0861,-0.57259 -0.16883,-1.17444 -0.26075,-1.69141 0.37886,0.31885 0.74567,0.69117 1.1034,1.10522 1.8127,-1.24269 3.7067,-2.46113 5.7172,-3.66761 -1.7902,1.39868 -3.4757,2.90592 -5.0753,4.50491 1.7101,2.32898 3.1533,5.73622 4.3932,9.76341 0.43337,-0.59571 0.90142,-1.17977 1.3641,-1.77514 -0.32238,-4.08897 -0.71114,-7.73077 -1.2036,-10.50076 0.92278,0.77667 1.7685,1.87165 2.5678,3.18193 -0.0494,-1.13102 -0.10262,-2.19797 -0.18058,-3.14843 0.2338,0.26871 0.46367,0.57517 0.68212,0.90433 0.0105,-0.35544 0.0311,-0.7187 0.0401,-1.07179 -1.92,-2.02453 -3.9894,-3.93444 -6.1987,-5.66051 2.1936,1.31642 4.2802,2.67693 6.2389,4.03604 0.12421,-5.88689 0.10438,-11.40362 -0.0802,-16.1612 -2.6597,-3.55848 -5.621,-6.69076 -8.8468,-9.21121 3.1287,1.87764 6.0341,3.88062 8.7063,5.99552 -0.0916,-1.51813 -0.22673,-2.93574 -0.36108,-4.23701 0.93062,1.47496 1.7528,3.5303 2.4875,6.01224 0.59136,0.5028 1.1768,1.01067 1.7453,1.52395 1.283,-1.38984 2.8347,-2.4885 4.3933,-0.88762 1.2903,1.32544 1.4439,3.59584 2.0261,6.89977 0.0364,0.20641 0.0647,0.41066 0.10033,0.61965 0.2218,0.25506 0.44466,0.5138 0.66199,0.77036 -0.0543,-0.64337 -0.11726,-1.27956 -0.18055,-1.89238 0.71374,1.13127 1.3832,2.51799 1.986,4.10314 0.7208,0.91727 1.4181,1.84707 2.0863,2.77999 2.5863,-1.89689 5.3953,-3.77518 8.4255,-5.59358 -2.6874,2.09958 -5.1614,4.45347 -7.4224,6.98358 6.5458,9.56842 10.426,19.80701 12.698,29.29104 -0.85158,-27.36654 -0.57619,-60.05597 4.7945,-70.25442 -0.0783,8.75405 0.5549,22.14279 1.6049,36.64247 0.2294,-0.3986 0.47741,-0.77175 0.72218,-1.10529 -0.0156,1.25637 -0.0288,2.68463 -0.02,4.18679 1.9496,1.30831 3.7989,2.62662 5.5368,3.96902 4.4775,-9.92235 11.99,-19.34494 24.293,-26.72832 -7.6612,5.98544 -12.494,15.39598 -15.366,25.87462 2.1713,-2.97514 4.7453,-5.81872 7.7234,-8.49106 -1.9016,1.8547 -2.3617,3.26403 -4.1325,6.39746 -0.8652,1.53092 -1.442,1.7468 -2.1264,3.39971 -0.89858,2.16995 -1.6493,4.43675 -2.2668,6.76581 0.0747,-0.0133 0.16478,0.0449 0.32097,0.20101 8.2614,8.26493 13.246,16.80679 16.169,24.85298 0.26517,-11.71658 1.0195,-23.96816 2.5477,-32.85821 0.21974,-1.27808 1.5701,2.5737 1.8255,1.4068 0.23777,-1.08613 -0.99256,-3.363 -0.72219,-4.33754 0.49217,-1.77408 1.0575,-3.33629 1.665,-4.67246 -1.478,-1.77719 -3.1341,-3.41944 -4.9951,-4.87343 1.9923,1.19559 3.8326,2.44204 5.5568,3.71792 0.28332,-0.52095 0.57519,-0.98782 0.88267,-1.40672 -0.008,0.63805 -0.0185,1.37271 -0.02,2.07664 4.4649,3.42461 8.0391,7.09746 10.853,10.93581 2.8034,-5.05097 6.5162,-9.86091 11.354,-14.20147 -1.9016,1.85469 -2.3617,3.26403 -4.1325,6.39746 -0.8652,1.53099 -1.442,1.74679 -2.1264,3.3997 -1.0734,2.59213 -1.9507,5.32805 -2.6279,8.13909 3.3883,5.65273 5.3431,11.55764 6.3392,17.41716 0.67931,-11.79441 0.97012,-22.96043 0.88267,-29.9776 4.6806,6.3769 6.5114,24.9898 6.9209,42.67159 3.2439,-8.76388 8.911,-18.11929 18.636,-27.02982 1.1387,-7.01921 2.7567,-12.80623 4.975,-15.94327 -2.8601,-6.46857 -6.744,-12.10492 -11.936,-16.16119 9.9905,5.99519 16.847,13.32729 21.465,21.18504 0.56335,-0.35129 1.125,-0.69018 1.7052,-1.03827 -0.53185,0.41557 -1.0499,0.85516 -1.5647,1.28955 3.654,6.2903 5.8912,12.90782 7.1817,19.44324 2.0379,-21.83145 3.4859,-44.88365 3.3702,-57.82751 2.2965,4.36064 3.6525,12.84883 4.3933,23.26193 6.6213,1.80971 15.523,-0.14679 19.038,4.01932 0.91104,1.07998 1.782,2.18757 2.5878,3.29917 2.5435,-2.60786 5.3385,-5.12191 8.4255,-7.48596 -0.34878,-1.02377 -0.71447,-2.0269 -1.1234,-3.01447 -0.68442,-1.65282 -1.2612,-1.85199 -2.1264,-3.3829 -1.9044,-3.36972 -2.2729,-4.75161 -4.5738,-6.83283 4.0887,3.58871 7.3512,7.5207 9.9902,11.63956 0.50063,-0.35735 1.0299,-0.70497 1.5447,-1.05507 -0.31235,-2.66226 -0.60598,-5.26111 -0.48145,-8.13909 0.2559,-5.91392 8.8641,-10.53763 8.8267,-14.7209 1.6825,3.19488 -5.0756,25.71732 -4.2729,32.47232 0.16097,1.35485 0.28362,2.72781 0.42127,4.08626 2.9342,8.63771 3.889,17.51301 3.9118,25.6059 0.19545,-0.59961 0.37179,-1.18976 0.58175,-1.79194 1.5271,-17.02881 2.2144,-36.22382 2.0863,-46.50665 1.22,1.66216 2.251,4.17392 3.1094,7.26828 0.27037,0.97454 -0.93989,3.25141 -0.70211,4.33753 0.25546,1.16691 1.5857,-2.71838 1.8054,-1.4403 0.92275,5.36746 1.5789,11.99022 2.0061,18.95741 2.152,-3.4305 4.6088,-6.78309 7.4425,-10.01492 3.6481,-4.16066 8.3021,-3.15179 13.461,-3.96911 0.69857,-1.03524 1.3457,-1.97734 1.7052,-2.31103 -1.1355,-0.39803 -2.1878,-0.88663 -3.0893,-1.59105 1.0171,0.61034 2.1635,1.02672 3.3702,1.33977 2.4094,-1.98348 5.0466,-3.91421 7.9039,-5.82797 -0.0731,-1.0228 -0.16644,-2.01708 -0.2608,-2.93075 0.41455,0.657 0.80889,1.44096 1.1836,2.31112 1.2401,-0.8126 2.5045,-1.6153 3.8316,-2.41164 -1.2358,0.96544 -2.4263,1.96759 -3.5708,3.03118 0.0483,0.12117 0.0928,0.26072 0.14042,0.38522 0.12553,-0.22671 0.25168,-0.44801 0.38115,-0.65318 -0.044,0.42664 -0.081,0.88876 -0.12036,1.33978 0.60606,1.70484 1.1282,3.6812 1.6249,5.89507 3.2216,0.28393 6.0578,0.87959 7.7033,2.8303 7.64,9.05718 11.459,19.31872 13.18,29.29104 0.89575,-8.66229 1.6475,-17.50728 2.0863,-25.74026 0.39173,-7.34939 -1.2951,-12.23519 -1.0231,-18.52237 0.2559,-5.91392 8.8641,-10.52125 8.8267,-14.70369 1.6825,3.19488 -5.0756,25.70011 -4.2729,32.45593 1.5486,13.03399 1.9851,26.30475 1.8857,38.65218 2.6577,-11.87306 7.8506,-25.0791 17.573,-36.72686 0.96949,-6.2862 2.2113,-11.55273 3.8115,-15.00519 -2.9434,-7.74559 -7.1866,-14.51034 -13.18,-19.19254 13.092,7.85627 20.78,17.99966 25.136,28.62086 1.577,-0.3355 3.1807,-0.88827 4.8346,-1.84216 1.3663,-17.15744 2.2575,-33.59146 2.1666,-43.76041 z m -71.877,37.7649 c -1.7093,1.67691 -3.2928,3.44697 -4.7945,5.30888 0.19676,0.0233 0.3836,0.0466 0.58176,0.0673 0.1487,-0.0832 0.29211,-0.16167 0.44133,-0.25124 -0.11553,0.0903 -0.20555,0.18404 -0.32096,0.26795 0.98614,0.0982 1.9731,0.16251 2.969,0.21773 0.37867,-1.3791 0.79129,-2.63302 1.2237,-3.75134 -0.0308,-0.63413 -0.0629,-1.25621 -0.10033,-1.85887 z m 53.562,0.201 c -0.18742,2.83988 -0.29938,6.06213 -0.34104,9.5463 0.88599,-0.43288 1.8262,-0.70316 2.7884,-0.88761 -0.67027,-2.95893 -1.4767,-5.87009 -2.4474,-8.6582 z m -436.14,0.0333 c -3.8349,3.34825 -6.8948,7.58223 -9.3282,12.39249 0.57037,2.99965 1.0473,6.32774 1.4645,9.86418 0.30107,0.49849 0.61472,0.98961 0.90276,1.49044 2.0834,-0.94938 5.3472,-1.32445 5.9379,-2.26081 -0.20958,2.02969 -3.5856,2.82718 -4.3733,5.12462 2.255,4.30485 4.0614,8.65655 5.4967,12.94551 -1.0289,-13.00368 -1.497,-26.44813 -0.14045,-37.86485 0.0584,-0.49133 0.0562,-1.04696 0.0401,-1.69149 z m 334.51,1.82545 c -0.3474,0.34853 -0.68337,0.69243 -1.0231,1.05499 0.48751,0.79481 0.94293,1.58728 1.3842,2.39477 -0.0949,-1.18911 -0.23056,-2.32906 -0.36109,-3.44984 z m 144.88,1.64119 c -6.7295,14.56359 -10.451,42.15707 -11.515,62.8186 l 10.231,36.81033 23.732,-26.3596 c 1.2527,-16.58471 -5.5625,-53.55818 -22.448,-73.26851 z m -178.68,0.61967 c 0.96479,13.87948 0.82437,31.09182 0.34102,46.62381 2.7082,-11.30121 7.7458,-23.66502 16.791,-34.69996 -0.62337,-1.84379 -1.3005,-3.63844 -2.0662,-5.37581 -2.3528,-5.33845 -9.6502,-4.68901 -15.066,-6.54813 z m -142.49,0.10046 c -0.0488,-0.008 -0.10762,0 -0.16048,0 -0.30055,0.02 -0.63833,0.22936 -1.003,0.50239 0.61093,0.56769 1.2011,1.1293 1.7854,1.70821 -0.0777,-1.09481 -0.22176,-2.05485 -0.48145,-2.16037 -0.0466,-0.0192 -0.0916,-0.0424 -0.14043,-0.0499 z m 173.08,1.1891 c -2.3644,2.86758 -4.5359,6.05771 -6.4996,9.49551 4.3363,7.13481 6.8003,14.72253 8.0844,22.15671 0.48464,-4.68819 0.93288,-9.41357 1.3039,-14.08431 -0.3182,-6.01346 -1.2054,-12.00251 -2.8887,-17.56791 z m 46.059,0.21772 c -0.0318,0.0407 -0.0686,0.0774 -0.10032,0.11718 0.0694,-0.0316 0.13098,-0.0673 0.2006,-0.10046 -0.0362,-0.008 -0.0643,-0.009 -0.10033,-0.0166 z m 0.36109,0.0674 c -0.25203,0.15577 -0.51131,0.28784 -0.7623,0.41865 -15.734,20.29694 -19.75,49.54292 -16.149,60.42383 l 5.8376,23.6634 8.0243,-13.4314 c 1.415,-15.37137 0.83322,-42.99517 -1.304,-55.01406 1.7176,1.44571 3.2112,3.8961 4.5136,7.0338 0.72498,-8.61559 1.7972,-16.49547 3.31,-22.40742 -1.1505,-0.23527 -2.3116,-0.44883 -3.4705,-0.68661 z m 74.565,0.13398 c -1.5907,1.18247 -3.1605,1.76548 -4.6942,2.16037 1.5832,3.93101 2.7077,7.92911 3.4906,11.89027 0.43598,-4.67041 0.8314,-9.37834 1.2036,-14.05072 z m -482.2,1.67462 c 0.60189,10.13372 1.4659,21.34726 2.4875,32.2888 1.4898,-7.55298 4.2441,-15.21738 8.9872,-22.35744 -0.70883,-1.46865 -1.4544,-2.91583 -2.2268,-4.32074 -2.5522,-4.64256 -5.7669,-4.82517 -9.2479,-5.61029 z m 402.18,0.13398 c -3.1734,0.66881 -6.0894,1.17363 -8.4455,5.45963 -1.0547,1.91852 -2.0524,3.89586 -2.989,5.9285 2.1599,-2.97375 4.6688,-5.94063 7.603,-8.87612 1.0479,-1.04827 -0.0729,2.37691 1.0833,1.33978 0.47491,-0.42597 1.6452,-2.19888 2.7483,-3.85187 z m 13.942,0.33498 c 1.2529,6.39861 2.1519,14.31535 2.7282,22.69253 1.2201,-2.75468 2.5845,-4.92684 4.1526,-6.24663 -2.0194,11.3561 -2.6156,36.62773 -1.4845,52.35142 h 2.6079 c 2.9353,-13.12247 4.7646,-43.87347 -4.7142,-65.38049 -0.70637,-1.60268 -1.8775,-2.66308 -3.29,-3.41642 z m -230.14,1.25597 c 0.72419,3.82859 1.3258,8.18104 1.8055,12.82834 0.31493,-1.24359 0.66105,-2.40656 1.0231,-3.48334 0.0271,-1.44129 0.0308,-2.86635 0.0402,-4.25381 -0.9075,-1.75212 -1.866,-3.44787 -2.8687,-5.09119 z m -259.99,1.03836 c -0.10572,-0.008 -0.22745,0.0125 -0.32097,0.0499 -0.51201,0.20808 -0.54803,3.7497 -0.56169,5.0744 -0.011,1.00723 0,2.05001 0,3.0982 1.3477,-1.87427 2.7886,-3.70455 4.3532,-5.50984 -1.0362,-0.78557 -2.4848,-2.6476 -3.4705,-2.71298 z m 543.1,1.20574 c -0.57827,0.62299 -1.1194,1.38852 -1.645,2.34462 -0.59299,1.07867 -1.1697,2.18192 -1.7252,3.29918 0.003,0.18737 -0.003,0.38115 0,0.56943 1.3496,-0.53376 3.046,-0.86894 4.2127,-1.28956 -0.24061,-1.6479 -0.52509,-3.29426 -0.84255,-4.92365 z m -582.38,1.57433 c -15.712,15.16413 -14.519,44.62886 -11.194,63.72312 h 4.4535 c 0.97389,-12.7571 0.3238,-32.11186 -1.6249,-40.96341 3.7562,2.55346 6.4369,9.04162 8.3652,16.57985 1.2217,-14.21621 1.5955,-28.99118 0.50148,-37.54696 0.14483,0.18504 0.28162,0.37956 0.42131,0.58622 -0.30287,-0.80528 -0.59123,-1.59474 -0.92279,-2.37805 z m -208.69,0.0837 c -0.0456,3.3e-4 -0.0936,0.0141 -0.14039,0.0333 -0.51208,0.20815 -0.58815,3.74978 -0.60182,5.07448 -0.0225,2.15127 0.0116,4.42429 0.0399,6.74901 1.0312,6.726 1.6941,14.36287 2.0662,22.00597 0.0147,-0.0599 0.0257,-0.12409 0.0404,-0.18421 1.0227,-7.2895 2.6006,-13.30763 4.9951,-16.06042 -0.0779,0.95045 -0.15124,2.00061 -0.20061,3.13171 0.34434,-0.5646 0.7166,-1.08539 1.0833,-1.55754 -0.31962,-3.99589 -0.72025,-7.53045 -1.2036,-10.24924 0.92272,0.77675 1.7685,1.85486 2.5678,3.16514 -0.0494,-1.13102 -0.10272,-2.18118 -0.18051,-3.13163 2.3944,2.75238 3.9721,8.75405 4.9951,16.04403 0.35601,1.43514 0.68905,2.95123 1.003,4.47149 0.34048,-4.90513 0.6282,-9.85598 0.82252,-14.6873 -2.9661,-4.53974 -6.4266,-8.78109 -10.452,-12.44329 -0.31353,2.40165 -3.1241,-2.24041 -4.6942,-2.34454 -0.0526,0 -0.095,-0.0166 -0.14047,-0.0166 z m 2.6079,0.46897 c 1.0094,1.21352 1.827,2.33627 2.2066,1.87567 -0.71165,-0.64694 -1.4606,-1.26571 -2.2066,-1.87567 z m 625.51,0.43544 c -0.35952,3.18874 -0.50162,7.15767 -0.52157,11.57239 1.1578,-0.92448 2.3759,-1.83676 3.631,-2.74649 -0.85768,-3.05527 -1.8939,-6.01854 -3.1094,-8.82533 z m -51.235,0.11719 c 0.083,12.57519 1.0131,32.79839 2.8085,49.22012 -0.43133,-9.95512 0.24159,-21.63073 4.4133,-32.77381 -1.4593,-6.03649 -3.776,-11.68381 -7.2218,-16.44549 z m -151.88,1.74172 c -0.57499,1.24547 -1.0925,2.52519 -1.5648,3.83506 0.69606,0.5158 1.3612,1.03705 2.0262,1.55754 -0.10002,-1.98258 -0.26667,-3.78443 -0.46136,-5.39252 z m -430.56,0.88761 c -2.4053,2.50258 -4.605,5.20704 -6.5799,8.05536 2.2093,3.59502 3.9646,9.0236 5.3562,15.18953 0.3254,-4.81076 0.74773,-9.45864 1.2839,-13.78282 0.0462,-3.28516 0.0186,-6.45563 -0.0604,-9.46191 z m 797.61,0.65308 c -1.3269,1.15101 -3.3182,2.13907 -3.3702,4.2203 -0.14372,5.75244 0.0496,12.59813 0.48146,19.67756 1.0648,-4.83935 2.3668,-9.23825 3.9118,-12.71119 -0.17362,-3.69022 -0.51106,-7.43918 -1.0231,-11.18732 z m -252.06,0.26796 c 0.0188,1.96366 0.0425,4.0489 0.10032,6.31373 0.29411,3.54225 0.61376,7.07533 0.94286,10.60071 0.78192,-3.95534 1.9108,-7.94853 3.4906,-11.87388 -1.4254,-1.75884 -2.9224,-3.44763 -4.5337,-5.04097 z m -285.66,0.90432 c -2.73,5.59432 -4.9716,11.59041 -6.8006,17.63509 0.18289,4.02268 0.42053,8.10698 0.70216,12.15817 0.31384,-1.52018 0.62704,-3.01955 0.98293,-4.45469 1.0229,-7.28958 2.6008,-13.30763 4.9951,-16.06042 -0.0779,0.95045 -0.13115,2.00061 -0.18051,3.13171 0.79915,-1.31036 1.645,-2.38846 2.5678,-3.16522 -1.2246,6.88731 -1.9266,18.91235 -2.0462,30.81491 0.37373,6.38451 0.90828,12.69808 1.5246,18.10368 h 1.5246 c 2.431,-13.02003 3.5833,-38.33017 -3.2698,-58.16257 z m 217.28,1.89247 c -4.0685,10.99397 -4.5739,24.11562 -3.651,35.82237 1.6619,-3.96329 3.8194,-8.0398 6.6601,-12.1082 0.0443,-8.01383 -0.75082,-16.25132 -3.0091,-23.71417 z m -96.01,0.98805 c -1.1727,4.52917 -2.0092,9.2448 -2.5477,13.94995 0.34908,1.70108 0.65465,3.51481 0.92285,5.42612 0.35723,1.44071 0.70818,2.92845 1.0231,4.45477 0.54693,-7.87454 0.91412,-15.87772 1.0632,-23.27831 -0.15138,-0.18712 -0.30801,-0.36716 -0.46143,-0.55262 z m 67.143,0.16741 c -0.48743,0.57051 -0.82143,1.23032 -0.84261,2.07672 -0.11138,4.45928 -0.0289,9.58071 0.22069,14.95521 1.3051,1.90057 2.4572,3.80705 3.4906,5.69402 0.69151,-2.08295 1.4673,-3.90536 2.327,-5.39253 -0.91227,-6.15544 -2.5479,-12.09099 -5.1957,-17.33359 z m -19.94,0.0333 c -1.8842,5.93915 -2.8247,12.39577 -3.1294,18.85746 1.7666,2.87364 3.1934,6.7092 4.3733,10.98578 -0.33381,-6.28694 -0.91213,-12.00825 -1.7453,-15.79252 1.1216,0.76254 2.1289,1.89681 3.0692,3.28246 0.20934,-4.94921 0.30904,-9.65936 0.22071,-13.86638 -0.88813,-1.18419 -1.822,-2.34463 -2.7885,-3.46672 z m -126.28,2.47866 c -8.0334,18.50107 -11.366,40.36694 -10.732,52.60294 l 28.045,25.7403 c 0.31596,-12.7947 -9.1283,-60.24116 -17.312,-78.34324 z m 375.49,0.18423 c -7.9784,18.45928 -11.317,40.21783 -10.692,52.41861 h 10.853 c 2.4406,-10.196 4.2668,-32.60833 -0.16048,-52.41861 z m -40.302,0.26795 c -1.4566,1.633 -2.8066,3.35587 -4.0924,5.12462 0.10241,6.57385 0.50869,13.84426 1.1234,21.00071 1.3604,-5.31339 3.0894,-10.09522 5.3161,-13.34778 -0.53122,-4.31107 -1.2798,-8.6246 -2.3471,-12.77837 z m -136.23,1.00477 c -1.3592,1.4444 -2.6541,2.95778 -3.8717,4.52171 0.63026,6.20239 0.96907,12.96107 1.1234,19.594 1.0512,-2.83587 2.3547,-5.73343 3.972,-8.6582 -0.26686,-5.83674 -0.66955,-11.22746 -1.2237,-15.45743 z m -158.08,1.0885 c -0.7978,3.20832 -1.4295,6.50143 -1.9058,9.8142 0.94358,2.92296 1.7712,6.19535 2.4875,9.66346 0.35763,-5.15248 0.6476,-10.34674 0.84262,-15.40746 -0.45777,-1.36197 -0.92067,-2.72379 -1.4244,-4.06954 z m -351.3,0.83739 c -10.535,16.72405 -14.32,37.30446 -13.24,49.2201 l 10.432,21.5702 c 1.2131,-13.247 4.2705,-57.1738 2.8085,-70.7903 z m 567.37,0.80387 c -0.092,0.3631 -0.19497,0.72254 -0.28084,1.08858 0.30136,0.0449 0.27928,-0.57493 0.28084,-1.08858 z m -171.56,2.16037 c 1.2612,15.90312 1.3685,53.34936 0.9027,65.73286 l 11.394,-19.4769 c 0.69343,-11.63958 -2.9061,-30.43969 -12.297,-46.25514 z m 399.67,1.65798 c -5.6312,17.06814 -15.2,57.89798 -14.183,67.55818 l 13.661,-22.9604 c -0.52781,-11.40039 -0.53151,-28.70039 0.52158,-44.59778 z m -351.28,0.15069 c 0.45077,2.85144 0.83818,5.91097 1.1434,9.06046 0.11562,-2.19543 0.21691,-4.36916 0.28085,-6.48111 -0.46046,-0.86328 -0.931,-1.73057 -1.4243,-2.5791 z m 121.91,2.12695 c -2.3634,14.94373 -0.34939,31.295 1.986,42.32014 h 8.5659 c 0.46338,-10.89323 -2.6783,-27.56894 -10.552,-42.32014 z m 69.53,4.80641 c -6.6976,12.8095 -9.851,26.97656 -10.211,37.51343 h 9.3884 c -0.49533,-9.90602 -0.42396,-24.52451 0.82249,-37.51343 z m -614,0.0333 c -0.57742,6.46218 -0.94397,14.3727 -1.0231,22.25667 0.10231,1.74868 0.23842,3.47024 0.36109,5.19155 0.4201,-4.35138 0.78323,-9.07029 1.0632,-13.84999 -0.0462,-4.61863 -0.18025,-9.25054 -0.40122,-13.59848 z m 14.424,1.6747 c 0.55059,13.27731 0.45995,26.54726 0.0199,35.80513 h 7.1215 c 0.51284,-9.19151 -1.633,-22.75722 -7.1416,-35.80513 z m 426.69,9.04325 c -0.0179,0.3636 -0.0434,0.73709 -0.0603,1.10538 0.025,0.0615 0.0559,0.12241 0.0802,0.18421 -0.006,-0.43013 -0.0105,-0.85869 -0.02,-1.28955 z m 74.024,6.24663 c 0.21716,7.33202 0.17685,14.43415 -0.0401,20.51485 h 1.3039 c 0.57034,-3.7633 0.56613,-9.11533 -0.02,-15.34025 -0.3589,-1.70124 -0.7707,-3.42493 -1.2438,-5.17484 z m 274.55,7.78746 -0.0803,0.97126 -0.02,-0.35162 c 0.002,-0.009 -0.0183,0.8042 -0.02,0.90433 l -0.0803,0.75354 h 0.0603 c 0.003,-0.14802 0.0187,-0.67039 0.02,-0.75354 l 0.0402,-0.55272 0.02,0.51919 c -0.0133,0.40303 -0.008,0.41391 -0.02,0.78707 h 0.0803 l -0.0602,-0.78707 c 0.0252,-0.76677 0.0315,-0.61142 0.0602,-1.49044 z"
inkscape:connector-curvature="0"
style="fill:#304e15" />
<path
id="path5536"
d="m 69.031,906.86833 c -5.3931,10.05016 -5.6371,42.2644 -4.7812,69.22949 -2.6058,-10.67854 -7.3555,-22.31975 -15.75,-32.84837 0.65892,-0.57672 1.2841,-1.13929 1.9688,-1.66413 -0.75575,0.44505 -1.4591,0.89728 -2.1875,1.3569 -5.4953,-6.82218 -12.556,-13.14869 -21.531,-18.43389 6.7652,5.18697 12.265,12.98483 16.594,21.81344 -17.97,13.25601 -26.498,31.10002 -30.344,46.84665 0.855,-26.95444 0.579,-59.1523 -4.8125,-69.19672 0.1162,12.74806 -1.3286,35.45042 -3.375,56.96481 C 3.8279,976.0372 2.2915,971.09691 1e-4,966.28772 v 88.48268 h 987.53 c -0.34,-32.9352 -5.03,-105.30258 -11.53,-115.42074 1.0979,10.43604 0.72634,28.43735 -0.5,45.77749 -1.9358,-9.19646 -4.6663,-17.08535 -8.4375,-20.20026 2.1816,12.04019 2.732,39.96791 1.2188,54.94281 h -7.125 c -0.92754,-12.3482 -0.44017,-32.41578 1.1875,-41.39923 -3.2209,2.66062 -5.4688,9.69622 -7.0312,17.69162 -0.95828,-10.47127 -1.5288,-21.38577 -1.3125,-29.87847 0.0763,-2.99555 4.3262,-3.69472 4.5625,-5.93981 -0.84397,1.31315 -7.1115,1.49585 -7.6875,3.78919 -1.2886,5.13117 -1.9378,12.40232 -2.2188,20.25188 -1.3904,3.29614 -2.5151,7.50398 -3.4062,12.05904 -0.90667,-9.91334 -1.4417,-20.17159 -1.3125,-28.44472 0.087,-0.56959 0.15689,-1.17592 0.25,-1.68977 -0.0787,0.065 -0.14078,0.13565 -0.21875,0.20482 0.16104,-2.91706 4.2975,-3.61583 4.5312,-5.8374 -0.84422,1.31315 -7.1116,1.49585 -7.6875,3.78919 -0.68938,2.74517 -1.1924,6.10702 -1.5625,9.83141 -1.4269,3.64565 -2.645,8.08166 -3.625,12.85292 -0.5507,-8.37718 -0.79461,-16.74288 -0.65625,-24.16887 0.31852,-0.89818 0.66439,-1.76769 1.0312,-2.63712 0.68705,-1.62832 1.2564,-1.84576 2.125,-3.35398 1.7773,-3.08682 2.2475,-4.47116 4.1562,-6.29824 -2.7247,2.39927 -5.1084,4.927 -7.1562,7.57837 0.11561,-2.57378 0.26776,-4.98862 0.5,-7.19429 -1.8963,2.94942 -3.3756,7.60066 -4.5312,13.23635 -0.83887,1.45726 -1.5919,2.93647 -2.2812,4.42921 -5.5614,12.04347 -6.4503,25.06681 -5.9688,35.9715 -2.0307,-18.22745 -2.9597,-41.28538 -2.8125,-52.86923 -1.2248,1.63742 -2.2633,4.09486 -3.125,7.14317 -0.27136,0.96004 0.95757,3.2057 0.71875,4.27568 -0.25647,1.14954 -1.6231,-2.66726 -1.8438,-1.40819 -1.5339,8.75733 -2.2964,20.84505 -2.5625,32.38712 -2.934,-7.92657 -7.8944,-16.33407 -16.188,-24.47611 -1.0518,-1.03262 0.0669,2.3275 -1.0938,1.30578 -0.50604,-0.44533 -1.7745,-2.39494 -2.9375,-4.09642 0.0701,-0.44266 0.11346,-0.92399 0.1875,-1.33134 -0.23353,0.1927 -0.46215,0.41154 -0.6875,0.64006 -0.60985,-0.87286 -1.1702,-1.62619 -1.4688,-1.86895 -2.1462,-1.74482 -4.4673,-3.47999 -6.9688,-5.17173 0.11161,-3.19315 0.31298,-6.18928 0.59375,-8.85809 -1.1237,1.74818 -2.114,4.11845 -2.9688,6.9127 -0.21375,-0.48556 -0.49597,-0.90408 -0.84375,-1.25448 -1.6939,-1.70755 -3.3749,-0.31373 -4.7188,1.20336 -4.6309,2.76443 -8.7087,5.64683 -12.312,8.57708 -0.2008,0.16325 -0.51079,0.55664 -0.875,1.04967 -0.13771,-4.64034 -0.19936,-9.09569 -0.15625,-13.18555 0.0135,-1.30496 0.0799,-4.78749 0.59375,-4.99256 1.5004,-0.59858 4.7156,4.92939 5,2.22747 -0.72198,1.12283 -3.1219,-4.37391 -5.7812,-4.17327 -0.49245,0.0374 -0.96651,0.26183 -1.4688,0.76808 -1.2952,1.30561 -1.4779,3.52981 -2.0625,6.78466 -0.93773,5.22277 -1.6142,11.34134 -2.125,17.79402 -7.7364,7.85169 -12.49,15.93016 -15.312,23.55442 -0.26614,-11.54617 -1.028,-23.62651 -2.5625,-32.38712 -0.2207,-1.25907 -1.5873,2.55773 -1.8438,1.40819 -0.23868,-1.0699 1.0213,-3.31556 0.75,-4.27568 -0.86175,-3.04823 -1.9315,-5.50567 -3.1562,-7.14317 0.14653,11.54125 -0.73505,34.46891 -2.75,52.66443 0.46216,-10.86457 -0.50306,-23.79532 -6.0312,-35.7667 -3.056,-6.61768 -7.4907,-12.95943 -13.906,-18.48469 2.3097,2.05026 2.6822,3.41388 4.5938,6.73354 0.86858,1.50813 1.438,1.70001 2.125,3.32834 7.8757,18.66574 2.669,53.27061 -0.6875,67.05341 l -14,-8.9097 c 0.41196,-17.2115 -0.22671,-42.10951 -3.1562,-58.42473 -0.58427,-3.25493 -0.73608,-5.50468 -2.0312,-6.8103 -0.60276,-0.60754 -1.1952,-0.81354 -1.7812,-0.76807 -2.5397,0.19692 -4.8049,5.25447 -5.5,4.17326 0.28425,2.702 3.5309,-2.82595 5.0312,-2.22746 0.5141,0.20506 0.58003,3.68759 0.59375,4.99255 0.1013,9.60774 -0.3543,21.24157 -1.1562,32.56653 -0.31684,-1.50822 -0.64049,-2.98022 -1,-4.40365 -1.0267,-7.1811 -2.6274,-13.1364 -5.0312,-15.84823 0.0783,0.93636 0.16913,1.98365 0.21875,3.09788 -0.8022,-1.29086 -1.6676,-2.33275 -2.5938,-3.09788 1.2292,6.7849 1.9425,18.61414 2.0625,30.3389 -0.34198,5.7337 -0.79918,11.4134 -1.3438,16.411 l -15.688,22.6074 c -0.7455,-13.8476 1.3458,-62.91854 12.281,-82.43634 3.9324,-7.02012 9.4025,-3.72349 15.031,-8.03923 -7.6521,4.50656 -14.608,0.35714 -19.688,6.04222 -10.534,11.79032 -16.093,25.34701 -18.875,37.50764 0.0981,-12.14998 -0.35416,-25.17168 -1.9062,-37.99429 -0.80607,-6.65546 6.0015,-28.856 4.3125,-32.00287 0.0374,4.12075 -8.6181,8.66474 -8.875,14.49149 -0.27309,6.19346 1.4243,11.03985 1.0312,18.27986 -0.44077,8.11493 -1.1627,16.80843 -2.0625,25.34701 -1.7258,-9.82895 -5.5766,-19.95284 -13.25,-28.87976 -4.1282,-4.80264 -15.678,-1.33412 -22.281,-5.22293 5.229,4.00916 15.439,1.66609 18.312,8.06486 9.0161,20.07656 7.8123,48.33364 5.1562,62.24014 l -25.71,26.0532 c 1.4598,-17.0116 1.3757,-67.29836 19.188,-80.95501 -20.22,11.90829 -30.205,25.74108 -34.969,38.35231 -0.41286,-17.40732 -2.2424,-35.73634 -6.9375,-42.01369 0.0877,6.90345 -0.19504,17.89234 -0.875,29.49422 -2.107,-12.10492 -8.465,-24.39663 -23.469,-34.15431 0.049,-0.11098 0.0754,-0.24792 0.125,-0.35843 2.8736,-6.39877 13.115,-4.08127 18.344,-8.09043 -6.6033,3.88881 -18.184,0.47157 -22.312,5.27414 -7.6707,8.92446 -11.492,19.02869 -13.219,28.85436 -0.89918,-8.53366 -1.6534,-17.2361 -2.0938,-25.34701 -0.39333,-7.24009 1.3356,-12.06149 1.0625,-18.25446 -8.9227,-29.14931 -11.317,3.99646 -4.5938,17.48679 -1.5536,12.83327 -2.0054,25.86152 -1.9062,38.01969 -1.7362,-7.60533 -4.5597,-15.72861 -9,-23.65682 -0.40983,-3.76068 -0.89131,-7.33218 -1.4688,-10.54828 -0.5844,-3.25493 -0.73583,-5.50469 -2.0312,-6.8103 -2.524,-2.54437 -5.0294,1.82619 -6.4062,3.17473 2.8093,-5.84568 6.5391,-10.93826 11.406,-14.6701 -6.2304,3.66933 -11.267,7.87168 -15.281,12.36627 -4.5133,-1.58122 -9.9686,0.0107 -15.812,-3.43075 4.9818,3.81958 9.8742,1.66773 13.656,5.99101 -6.2837,7.94108 -9.7002,16.72159 -11.438,25.34701 -2.0451,-21.50211 -3.5224,-44.21675 -3.4062,-56.96563 -5.3914,10.04688 -5.6674,42.24474 -4.8125,69.20409 -2.612,-10.69739 -7.3579,-22.35907 -15.781,-32.89916 3.9103,-6.93557 8.6127,-12.98156 14.188,-17.25576 -6.8226,4.01793 -12.494,8.66065 -17.25,13.64599 -5.0145,-5.53459 -11.15,-10.67772 -18.625,-15.07974 6.027,4.62101 11.039,11.32415 15.125,18.97134 -9.0062,10.83585 -14.043,22.96535 -16.75,34.05108 0.48781,-15.38615 0.61099,-32.4756 -0.375,-46.18713 0.15891,-0.11026 0.30946,-0.21084 0.46875,-0.33284 -0.15704,0.0924 -0.31229,0.17068 -0.46875,0.25603 -0.74318,-10.27218 -2.0987,-18.63953 -4.4062,-22.93995 0.0574,6.27391 -0.28944,14.9888 -0.875,24.75794 -5.3625,0.94546 -10.199,-0.25123 -13.969,3.96845 -0.42188,0.47219 -0.81285,0.93046 -1.2188,1.40818 -0.62693,-0.73947 -1.289,-1.45357 -1.9688,-2.17618 0.0915,-3.93608 0.28592,-7.52004 0.59375,-10.44587 -1.1808,1.83667 -2.1921,4.56538 -3.0625,7.93682 -2.987,-2.81588 -6.4229,-5.46373 -10.375,-7.91117 0.3151,-8.24855 5.8613,-27.14534 4.3125,-30.03168 0.0374,4.12076 -8.5869,8.69097 -8.8438,14.5169 -0.2731,6.19345 1.4245,11.01445 1.0312,18.25446 -0.62229,11.45851 -2.9391,26.05569 -5.4688,39.76067 -0.16677,0.29987 -0.33999,0.62212 -0.5,0.94726 -0.53922,-6.11661 -1.7746,-12.50392 -4.1562,-18.74112 1.2938,-1.25629 3.2181,-2.04191 3.375,-3.53317 -0.43877,0.68253 -2.3491,1.05623 -4.1562,1.58737 -1.0399,-2.45761 -2.2804,-4.88949 -3.7188,-7.27115 1.0625,-0.9561 2.1725,-1.89107 3.3125,-2.76508 -1.2543,0.73866 -2.4795,1.50011 -3.6562,2.25303 -1.4849,-2.3987 -3.1428,-4.74538 -5.0938,-7.01512 -0.11599,-0.13489 -0.24767,-0.26175 -0.375,-0.38404 0.049,-0.109 0.0947,-0.18029 0.15625,-0.20482 1.5005,-0.59858 4.7469,4.92947 5.0312,2.22747 -0.8555,1.33076 -4.067,-6.64521 -7.2812,-3.40511 -0.0142,0.014 -0.0177,0.0111 -0.0312,0.0256 -5.1913,-2.1652 -14.228,-0.26277 -19.781,-3.53316 5.165,3.96009 15.205,1.74852 18.219,7.86005 -0.12765,0.73807 -0.27789,1.54312 -0.4375,2.43229 -0.55605,3.09689 -1.006,6.53256 -1.4062,10.13864 -10.732,9.18417 -16.881,18.923 -20.312,28.00968 -0.4126,-17.40979 -2.2418,-35.76093 -6.9375,-42.0391 0.0877,6.91262 -0.22435,17.92675 -0.90625,29.54502 -1.2569,-7.26279 -4.0263,-14.61111 -9.2812,-21.4292 1.2498,-1.15813 2.5464,-2.26015 3.9062,-3.30269 -1.513,0.89105 -2.9744,1.77678 -4.375,2.68823 -3.9845,-5.00427 -9.3405,-9.72244 -16.438,-13.90243 4.5147,3.46156 7.8634,7.95345 10.281,13.03153 -1.3632,1.79038 -2.4907,4.57497 -3.4375,7.98802 -1.1457,0.96037 -2.2664,1.89582 -3.3125,2.8675 0.0316,-4.54695 0.24339,-8.6074 0.65625,-11.77721 -2.4236,3.04479 -4.149,9.13338 -5.3438,16.5397 -0.21728,0.23895 -0.44431,0.47758 -0.65625,0.71688 -0.37465,-4.0113 -0.89181,-7.62836 -1.625,-10.54828 -0.23759,-0.94595 -1.4505,-1.53846 -2.8438,-1.99701 2.2125,-3.74191 5.0389,-7.07861 8.5625,-9.78061 -4.6386,2.73174 -8.5293,5.71344 -11.781,8.8327 -0.77456,-0.25058 -1.402,-0.5236 -1.625,-0.87049 0.0631,0.60329 0.42399,1.10603 0.90625,1.56172 -2.2915,2.27949 -4.2697,4.62305 -5.9375,7.04076 -1.0968,-7.17774 -2.7052,-13.0004 -4.9688,-16.02683 0.0824,6.48226 -0.15599,16.53315 -0.75,27.3436 -0.11476,0.33098 -0.23678,0.69253 -0.34375,1.02411 -0.5489,-2.80425 -1.335,-5.61456 -2.4062,-8.39766 -0.17199,-5.50084 -0.23441,-10.41147 -0.1875,-14.10725 -1.2315,1.64659 -2.2604,4.12255 -3.125,7.19429 -1.7114,-2.9146 -3.8219,-5.75801 -6.375,-8.50007 2.4475,-5.4738 5.9219,-10.32707 10.719,-14.00484 -5.6646,3.33596 -10.212,7.01455 -13.844,10.90631 -3.0395,-2.77295 -6.5822,-5.40555 -10.75,-7.86005 3.6403,2.79106 6.5361,6.24417 8.7812,10.13864 -4.9653,5.99986 -7.9421,12.45476 -9.5625,18.92054 -0.3472,-0.32768 -0.70435,-0.64626 -1.0625,-0.9729 -0.49354,-9.79044 -0.73177,-18.78372 -0.65625,-24.73254 -2.6305,3.51719 -4.3478,10.83257 -5.4375,19.63742 -1.2782,-0.97405 -2.6078,-1.93654 -4,-2.89306 0.0864,-0.56412 0.15773,-1.15486 0.25,-1.66413 -0.38032,0.31417 -0.73469,0.6674 -1.0938,1.07531 -1.8196,-1.22417 -3.7318,-2.42139 -5.75,-3.60993 1.7971,1.37788 3.488,2.87962 5.0938,4.45486 -1.7167,2.29432 -3.1615,5.63348 -4.4062,9.60119 -0.43503,-0.5869 -0.91052,-1.15437 -1.375,-1.74098 0.32361,-4.02817 0.72437,-7.61492 1.2188,-10.34346 -0.92632,0.76516 -1.7914,1.83274 -2.5938,3.12352 0.0496,-1.11423 0.10927,-2.16152 0.1875,-3.09788 -0.23469,0.26474 -0.46822,0.57184 -0.6875,0.89614 -0.01,-0.35014 -0.0222,-0.70185 -0.0312,-1.04967 1.9273,-1.99446 4.001,-3.88095 6.2188,-5.58137 -2.202,1.29684 -4.3151,2.62949 -6.2812,3.96845 -0.12469,-5.79939 -0.0915,-11.23812 0.0937,-15.92524 2.6698,-3.50556 5.6369,-6.58058 8.875,-9.06292 -3.1407,1.84961 -6.0363,3.83072 -8.7188,5.91424 0.092,-1.49552 0.20888,-2.89125 0.34375,-4.17327 -0.93418,1.453 -1.7625,3.46918 -2.5,5.91425 -0.59362,0.4954 -1.1793,1.00494 -1.75,1.5106 -1.2879,-1.36911 -2.8417,-2.47309 -4.4062,-0.89614 -1.2953,1.3057 -1.4468,3.55545 -2.0312,6.8103 -0.0365,0.20333 -0.058,0.40852 -0.0937,0.61447 -0.22265,0.25121 -0.46933,0.48971 -0.6875,0.74247 0.0545,-0.63386 0.12398,-1.23974 0.1875,-1.84339 -0.71647,1.11447 -1.3949,2.4581 -2,4.01957 -0.72355,0.90367 -1.423,1.82045 -2.0938,2.73952 -2.5962,-1.86862 -5.3958,-3.71324 -8.4375,-5.5046 2.6977,2.06836 5.1678,4.39464 7.4375,6.88706 -6.5709,9.42669 -10.469,19.51125 -12.75,28.85437 0.85483,-26.95936 0.57871,-59.15722 -4.8125,-69.2041 0.0786,8.62378 -0.53978,21.81507 -1.5938,36.09929 -0.23028,-0.39274 -0.47305,-0.7724 -0.71875,-1.10095 0.0157,1.23777 0.009,2.64219 0,4.12198 -1.957,1.28889 -3.818,2.59467 -5.5625,3.91716 -4.4946,-9.77488 -12.025,-19.07211 -24.375,-26.3449 7.6905,5.89647 12.554,15.17724 15.438,25.50022 -2.1796,-2.93091 -4.7606,-5.73974 -7.75,-8.37227 1.9089,1.82709 2.3474,3.23708 4.125,6.32389 0.8685,1.50822 1.4692,1.70002 2.1562,3.32834 0.90201,2.13776 1.6301,4.38792 2.25,6.68225 -0.075,-0.0131 -0.15572,0.0254 -0.3125,0.17922 -8.293,8.14204 -13.285,16.57493 -16.219,24.5015 -0.26617,-11.54207 -1.0284,-23.62979 -2.5625,-32.38711 -0.22058,-1.25908 -1.5873,2.55772 -1.8438,1.40818 -0.23868,-1.06998 0.99014,-3.31556 0.71875,-4.27568 -0.49405,-1.74769 -1.0464,-3.29221 -1.6562,-4.60847 1.4837,-1.75081 3.1319,-3.38102 5,-4.81329 -1.9999,1.17772 -3.8318,2.40427 -5.5625,3.66121 -0.2844,-0.51323 -0.56633,-0.96986 -0.875,-1.38254 0.008,0.62859 -0.002,1.35477 0,2.04821 -4.482,3.37373 -8.0505,6.99734 -10.875,10.7785 -2.8142,-4.97592 -6.5496,-9.72818 -11.406,-14.00484 1.9089,1.82709 2.3787,3.23707 4.1562,6.32389 0.8685,1.50822 1.438,1.70002 2.125,3.32834 1.0775,2.55363 1.9452,5.26996 2.625,8.03923 -3.4012,5.56867 -5.3439,11.38149 -6.3438,17.15416 -0.6819,-11.61908 -0.99403,-22.63272 -0.90625,-29.54501 -4.6985,6.2821 -6.5264,24.62112 -6.9375,42.03909 -3.2563,-8.63361 -8.9562,-17.8481 -18.719,-26.62673 -1.143,-6.91492 -2.7419,-12.60468 -4.9688,-15.6942 2.871,-6.37247 6.7568,-11.92877 11.969,-15.92524 -10.029,5.90605 -16.927,13.12575 -21.562,20.86634 -0.56551,-0.3461 -1.1052,-0.68114 -1.6875,-1.0241 0.53388,0.40936 1.0457,0.85222 1.5625,1.28013 -3.6679,6.19682 -5.9233,12.71201 -7.2188,19.15076 -2.0457,-21.50702 -3.4912,-44.21348 -3.375,-56.96563 -2.3052,4.29592 -3.6626,12.6563 -4.4062,22.91455 -6.6466,1.78285 -15.597,-0.16135 -19.125,3.94281 -0.91452,1.06392 -1.7849,2.15643 -2.5938,3.25157 -2.5532,-2.56919 -5.3388,-5.04474 -8.4375,-7.37355 0.35011,-1.00854 0.71451,-1.99709 1.125,-2.96991 0.68704,-1.62833 1.2565,-1.82012 2.125,-3.32834 1.9116,-3.31966 2.284,-4.68319 4.5938,-6.73353 -4.1043,3.53537 -7.3822,7.41272 -10.031,11.46997 -0.50255,-0.35207 -1.0458,-0.67925 -1.5625,-1.0241 0.31355,-2.62269 0.62501,-5.20401 0.5,-8.03922 -0.25688,-5.82601 -8.9126,-10.3705 -8.875,-14.4915 -1.6889,3.14736 5.1182,25.32243 4.3125,31.97747 -0.16159,1.33478 -0.29932,2.70692 -0.4375,4.04522 -2.9454,8.5099 -3.9146,17.2451 -3.9375,25.21838 -0.1962,-0.59073 -0.35173,-1.1733 -0.5625,-1.76654 -1.533,-16.77566 -2.2224,-35.67245 -2.0938,-45.80289 -1.2247,1.63742 -2.2633,4.09486 -3.125,7.14317 -0.2714,0.96004 0.92619,3.2057 0.6875,4.27568 -0.25644,1.14962 -1.5919,-2.66726 -1.8125,-1.40819 -0.92628,5.28758 -1.5712,11.80097 -2,18.66411 -2.1602,-3.37946 -4.6242,-6.67331 -7.4688,-9.8568 -3.6621,-4.0988 -8.353,-3.11205 -13.531,-3.91716 -0.70124,-1.01985 -1.3266,-1.94982 -1.6875,-2.2786 1.1398,-0.39211 2.1887,-0.86786 3.0938,-1.56171 -1.021,0.60124 -2.1637,0.99731 -3.375,1.30577 -2.4186,-1.95399 -5.0693,-3.84965 -7.9375,-5.73499 0.0734,-1.00764 0.15529,-1.99307 0.25,-2.89305 -0.41612,0.64724 -0.81137,1.42145 -1.1875,2.27859 -1.2448,-0.8005 -2.5116,-1.57098 -3.8438,-2.35544 1.2405,0.9511 2.4448,1.92204 3.5938,2.9699 -0.0485,0.11934 -0.10849,0.26136 -0.15625,0.38404 -0.12602,-0.22334 -0.24503,-0.43795 -0.375,-0.64006 0.0442,0.42026 0.0855,0.86139 0.125,1.30577 -0.60838,1.67953 -1.1264,3.6309 -1.625,5.81184 -3.234,0.27971 -6.0982,0.86893 -7.75,2.79064 -7.6692,8.922 -11.492,19.03033 -13.219,28.85436 -0.89916,-8.53366 -1.6532,-17.23609 -2.0938,-25.347 -0.39324,-7.2401 1.3043,-12.0615 1.0312,-18.25447 -0.25688,-5.82601 -8.9125,-10.37049 -8.875,-14.49149 -1.6889,3.14736 5.087,25.32242 4.2812,31.97747 -1.5545,12.83982 -1.9748,25.90658 -1.875,38.0713 -2.6679,-11.69609 -7.8966,-24.70223 -17.656,-36.1763 -0.97319,-6.1928 -2.2061,-11.37084 -3.8125,-14.77251 2.9546,-7.63048 7.2027,-14.30797 13.219,-18.92054 -13.142,7.73953 -20.847,17.75061 -25.219,28.2145 -1.583,-0.33056 -3.1835,-0.87811 -4.8438,-1.81783 C 69.8573,933.07059 68.95,916.8758 69.0413,906.8576 z m 72.156,37.20041 c 1.7159,1.65192 3.3051,3.38872 4.8125,5.22293 -0.19751,0.0228 -0.39483,0.0569 -0.59375,0.0768 -0.14927,-0.0817 -0.28771,-0.16777 -0.4375,-0.25603 0.11597,0.0889 0.19665,0.199 0.3125,0.28163 -0.98991,0.0967 -1.9691,0.15044 -2.9688,0.20482 -0.38013,-1.35862 -0.7847,-2.585 -1.2188,-3.68678 0.0309,-0.62471 0.0562,-1.24965 0.0937,-1.84338 z m -53.781,0.20482 c 0.18814,2.79769 0.30194,5.96422 0.34375,9.39636 -0.88937,-0.42637 -1.8154,-0.68878 -2.7812,-0.87048 0.67284,-2.91494 1.4631,-5.77891 2.4375,-8.52547 z m 437.81,0.0256 c 3.8495,3.29844 6.9322,7.47326 9.375,12.21225 -0.57255,2.95507 -1.05,6.24531 -1.4688,9.72899 -0.30222,0.49113 -0.61711,0.96594 -0.90625,1.45931 -2.0913,-0.93529 -5.3757,-1.30496 -5.9688,-2.22747 0.21039,1.99955 3.5843,2.78041 4.375,5.04368 -2.2636,4.24086 -4.0592,8.52465 -5.5,12.74969 1.0328,-12.81032 1.4867,-26.05568 0.125,-37.30281 -0.0586,-0.48401 -0.0474,-1.02919 -0.0312,-1.66413 z m -335.78,1.79218 c 0.34872,0.34336 0.69024,0.69245 1.0312,1.04967 -0.48938,0.78296 -0.96332,1.55992 -1.4062,2.35544 0.0953,-1.17149 0.24397,-2.30112 0.375,-3.40511 z m -145.44,1.63857 c 6.7552,14.3473 10.494,41.52705 11.562,61.88129 l -10.281,36.2533 -23.812,-25.9614 c -1.258,-16.3366 5.581,-52.7537 22.531,-72.17073 z m 179.38,0.58886 c -0.96847,13.67303 -0.82894,30.62975 -0.34375,45.9307 -2.7186,-11.13325 -7.7955,-23.30863 -16.875,-34.17971 0.62576,-1.81643 1.3251,-3.58814 2.0938,-5.29978 2.3618,-5.25907 9.6889,-4.62036 15.125,-6.45186 z m 143.03,0.10241 c 0.049,-0.007 0.10318,-0.003 0.15625,0 0.30169,0.0198 0.63391,0.24301 1,0.51205 -0.61327,0.55918 -1.1947,1.09383 -1.7812,1.66413 0.078,-1.07858 0.20806,-2.02109 0.46875,-2.12506 0.0469,-0.0186 0.10729,-0.0438 0.15625,-0.0512 z m -173.75,1.17772 c 2.3734,2.82497 4.56,5.95816 6.5312,9.34475 -4.3529,7.02864 -6.836,14.51526 -8.125,21.83884 -0.4865,-4.61847 -0.94003,-9.27512 -1.3125,-13.87703 0.31942,-5.92408 1.2164,-11.82473 2.9062,-17.30738 z m -46.25,0.20482 c 0.0319,0.0397 0.0932,0.0883 0.125,0.12802 -0.0697,-0.0315 -0.14887,-0.0697 -0.21875,-0.10241 0.0363,-0.007 0.0576,-0.0185 0.0937,-0.0256 z m -0.34375,0.0768 c 0.253,0.1535 0.49805,0.28077 0.75,0.40964 15.794,19.99545 19.833,48.8072 16.219,59.52594 l -5.875,23.3242 -8.0312,-13.2363 c -1.4204,-15.1429 -0.83284,-42.36036 1.3125,-54.20065 -1.7242,1.42416 -3.2238,3.84719 -4.5312,6.93835 -0.72775,-8.48778 -1.8252,-16.27098 -3.3438,-22.09527 1.1549,-0.23177 2.3367,-0.43137 3.5,-0.66566 z m -74.844,0.12801 c 1.5968,1.16486 3.1479,1.73598 4.6875,2.12506 -1.5892,3.87259 -2.7142,7.82359 -3.5,11.72559 -0.43765,-4.60093 -0.81384,-9.24807 -1.1875,-13.85081 z m 484.02,1.65496 c -0.60419,9.98297 -1.4745,21.01954 -2.5,31.79804 -1.4954,-7.44073 -4.27,-14.9847 -9.0312,-22.01825 0.71154,-1.44677 1.4747,-2.89158 2.25,-4.27568 2.562,-4.57357 5.787,-4.73112 9.2812,-5.50461 z m -403.72,0.12801 c 3.1856,0.65888 6.1036,1.15437 8.4688,5.37655 1.0587,1.89001 2.0597,3.83507 3,5.8374 -2.1682,-2.92943 -4.6796,-5.86435 -7.625,-8.75651 -1.0519,-1.03271 0.0669,2.35307 -1.0938,1.33134 -0.47673,-0.41964 -1.6427,-2.16078 -2.75,-3.78919 z m 884.75005,0.10241 c -1.2246,1.6375 -2.2322,4.12051 -3.0937,7.16873 -0.2714,0.96004 0.9575,3.2057 0.7187,4.27568 -0.2566,1.14954 -1.6231,-2.69282 -1.8437,-1.43374 -1.5346,8.7606 -2.2965,20.86716 -2.5625,32.41251 -2.934,-7.92625 -7.9262,-16.38568 -16.219,-24.52772 -1.0517,-1.03279 0.067,2.37862 -1.0937,1.35689 -0.8561,-0.75368 -3.9573,-5.93612 -4.875,-6.68224 -3.7616,-3.05839 -8.05385,-6.0337 -12.93805,-8.90971 21.46605,16.45777 29.09105,48.31569 27.62505,64.33919 l 1.625,20.4052 -11.562,14.4651 h 38.312 v -40.2989 c -2.6717,-12.866 -4.7388,-32.48623 0,-48.61957 v -6.09342 c -2.104,2.92042 -3.8503,5.96479 -5.2812,9.06292 -5.5282,11.97137 -6.4622,24.87673 -6,35.74127 -2.0154,-18.19549 -2.959,-41.12315 -2.8126,-52.6644 z m -898.75005,0.23042 c -1.2577,6.30349 -2.1402,14.09906 -2.7188,22.35089 -1.2248,-2.71372 -2.6134,-4.86999 -4.1875,-6.17019 2.0271,11.18732 2.6354,36.09927 1.5,51.58947 h -2.625 c -2.9465,-12.9274 -4.7651,-43.22868 4.75,-64.41618 0.70907,-1.57884 1.8634,-2.6118 3.2812,-3.35399 z m 231.03,1.22893 c -0.72696,3.77165 -1.331,8.06945 -1.8125,12.6481 -0.31614,-1.22507 -0.66783,-2.3955 -1.0312,-3.45639 -0.0272,-1.41982 -0.0218,-2.80638 -0.0312,-4.17327 0.91097,-1.72607 1.8685,-3.39921 2.875,-5.01811 z m 260.97,1.0241 c 0.10613,-0.007 0.21861,0.0139 0.3125,0.0512 0.51397,0.20502 0.54878,3.6876 0.5625,4.99255 0.011,0.99224 0,2.01413 0,3.04676 -1.3529,-1.84643 -2.7732,-3.64934 -4.3438,-5.42776 1.0402,-0.77389 2.4792,-2.59828 3.4688,-2.66267 z m -545.19,1.17772 c 0.58048,0.61371 1.1287,1.36231 1.6562,2.30424 0.59525,1.06261 1.1923,2.15095 1.75,3.25158 -0.0026,0.18456 0.0032,0.37777 0,0.56325 -1.3548,-0.52578 -3.0788,-0.84009 -4.25,-1.25448 0.24152,-1.62342 0.52508,-3.25928 0.84375,-4.8645 z m 584.62,1.56172 c 15.772,14.93883 14.557,43.9677 11.219,62.7777 h -4.4688 c -0.97761,-12.567 -0.33112,-31.62934 1.625,-40.3498 -3.7706,2.51561 -6.4393,8.90808 -8.375,16.33488 -1.2264,-14.00483 -1.5982,-28.56761 -0.5,-36.99558 -0.14538,0.18229 -0.29728,0.35969 -0.4375,0.56326 0.30403,-0.79323 0.60467,-1.55812 0.9375,-2.32988 z m 209.47,0.0768 c 0.0458,3e-4 0.10932,0.007 0.15625,0.0256 0.51404,0.20507 0.58003,3.71316 0.59375,5.01812 0.0226,2.11932 -0.003,4.34089 -0.0312,6.63112 -1.0352,6.62596 -1.689,14.1564 -2.0625,21.68562 -0.0148,-0.0593 -0.0477,-0.11999 -0.0625,-0.17921 -1.0266,-7.18111 -2.5963,-13.11101 -5,-15.82202 0.0782,0.93636 0.13794,1.95801 0.1875,3.07232 -0.34566,-0.55622 -0.72567,-1.04549 -1.0938,-1.5106 0.32085,-3.93657 0.73352,-7.43467 1.2188,-10.11324 -0.92625,0.76518 -1.7602,1.83266 -2.5625,3.12352 0.0496,-1.11431 0.0782,-2.1616 0.15625,-3.09787 -2.4036,2.71158 -3.9732,8.64098 -5,15.82201 -0.35738,1.41384 -0.68482,2.906 -1,4.40365 -0.34178,-4.83222 -0.64869,-9.70606 -0.84375,-14.46528 2.9774,-4.47214 6.4596,-8.65573 10.5,-12.26386 0.31473,2.36593 3.1426,-2.20166 4.7188,-2.30424 0.0528,-0.003 0.0794,-0.026 0.125,-0.0256 z m -2.5938,0.46085 c -1.0132,1.1955 -1.8377,2.29711 -2.2188,1.84339 0.71437,-0.63731 1.4699,-1.24245 2.2188,-1.84339 z m -627.92,0.43422 c 0.3609,3.1413 0.51122,7.0442 0.53125,11.39296 -1.1623,-0.91072 -2.3964,-1.81766 -3.6562,-2.71388 0.86095,-3.00988 1.9049,-5.91383 3.125,-8.67949 z m 51.438,0.10241 c -0.0833,12.38839 -1.0415,32.3142 -2.8438,48.49182 0.43298,-9.80769 -0.21855,-21.30716 -4.4062,-32.28475 1.4649,-5.94669 3.791,-11.51503 7.25,-16.20625 z m 152.44,1.71542 c 0.57719,1.22696 1.1197,2.49881 1.5938,3.78918 -0.69872,0.50809 -1.395,1.02345 -2.0625,1.53616 0.10039,-1.95309 0.27331,-3.74109 0.46875,-5.32534 z m 432.22,0.89613 c 2.4145,2.46547 4.6113,5.1052 6.5938,7.91117 -2.2178,3.5416 -3.978,8.90316 -5.375,14.97733 -0.32664,-4.73923 -0.74305,-9.30953 -1.2812,-13.56898 -0.0464,-3.23634 -0.0168,-6.35756 0.0625,-9.31936 z m -800.66,0.65543 c 1.332,1.13388 3.3228,2.09736 3.375,4.14762 0.14427,5.66682 -0.03526,12.40724 -0.46875,19.38098 -1.0689,-4.76741 -2.3866,-9.09815 -3.9375,-12.51948 0.17429,-3.63532 0.51727,-7.31686 1.0312,-11.00953 z m 253.03,0.25602 c -0.0189,1.9345 -0.067,3.99032 -0.125,6.22148 -0.29523,3.48958 -0.60714,6.97268 -0.9375,10.44587 -0.78491,-3.89651 -1.9142,-7.83358 -3.5,-11.70019 1.4308,-1.73263 2.945,-3.39725 4.5625,-4.96691 z m 286.75,0.89613 c 2.7404,5.51116 4.9765,11.40362 6.8125,17.35899 -0.18359,3.96288 -0.4048,7.99081 -0.6875,11.98203 -0.31504,-1.49765 -0.64275,-2.96425 -1,-4.37809 -1.0268,-7.18119 -2.5965,-13.111 -5,-15.82201 0.0782,0.93636 0.1067,1.95801 0.15625,3.07231 -0.8022,-1.29086 -1.6362,-2.35839 -2.5625,-3.12352 1.2293,6.7849 1.9424,18.63953 2.0625,30.36428 -0.37516,6.2897 -0.91257,12.5195 -1.5312,17.8448 h -1.5312 c -2.4403,-12.8258 -3.5981,-37.76075 3.2812,-57.29821 z m -218.12,1.86896 c 4.084,10.83011 4.6139,23.74858 3.6875,35.28 -1.6682,-3.90438 -3.8359,-7.92289 -6.6875,-11.93041 -0.0445,-7.8947 0.73309,-15.99734 3,-23.34959 z m 96.375,0.97289 c 1.1772,4.46183 2.0219,9.0875 2.5625,13.72301 -0.35042,1.67568 -0.63702,3.46803 -0.90625,5.35091 -0.3586,1.41933 -0.71517,2.90002 -1.0312,4.40365 -0.54902,-7.75747 -0.9128,-15.64914 -1.0625,-22.93995 0.15195,-0.18437 0.28349,-0.35493 0.4375,-0.53766 z m -67.375,0.15362 c 0.48929,0.56199 0.82249,1.21443 0.84375,2.04821 0.1118,4.393 0.0318,9.4275 -0.21875,14.72171 -1.3101,1.87231 -2.4939,3.74806 -3.5312,5.60702 -0.69415,-2.05198 -1.4495,-3.83466 -2.3125,-5.29978 0.91575,-6.06394 2.5609,-11.91239 5.2188,-17.07716 z m 20,0.0256 c 1.8914,5.85084 2.8504,12.22126 3.1562,18.58792 -1.7733,2.83087 -3.2218,6.61653 -4.4062,10.83011 0.33509,-6.19346 0.91364,-11.83783 1.75,-15.56639 -1.1259,0.75116 -2.1185,1.86084 -3.0625,3.22593 -0.21014,-4.87573 -0.30742,-9.50124 -0.21875,-13.646 0.89152,-1.16658 1.8111,-2.32537 2.7812,-3.43075 z m 126.78,2.45785 c 8.0641,18.22579 11.386,39.76557 10.75,51.81967 l -28.125,25.347 c -0.31717,-12.6047 9.1597,-59.33331 17.375,-77.16667 z m -376.94,0.17926 c 8.0089,18.18483 11.345,39.62131 10.719,51.64021 h -10.875 c -2.4499,-10.0444 -4.2879,-32.12486 0.15625,-51.64021 z m 40.438,0.25603 c 1.4622,1.60875 2.8343,3.30122 4.125,5.04368 -0.10279,6.47611 -0.50796,13.63616 -1.125,20.68691 -1.3656,-5.2344 -3.1086,-9.92972 -5.3438,-13.13394 0.53325,-4.247 1.2724,-8.50498 2.3438,-12.59649 z m 136.78,0.99854 c 1.3644,1.42294 2.6528,2.91411 3.875,4.45486 -0.63267,6.11022 -0.97009,12.77018 -1.125,19.30397 -1.0552,-2.79376 -2.3766,-5.64438 -4,-8.52547 0.26788,-5.75006 0.69376,-11.06607 1.25,-15.23377 z m 158.66,1.07531 c 0.80085,3.16064 1.4594,6.38903 1.9375,9.65199 -0.94719,2.87953 -1.7809,6.108 -2.5,9.52417 -0.359,-5.07587 -0.64798,-10.19762 -0.84375,-15.18215 0.45952,-1.34174 0.90065,-2.66824 1.4062,-3.99401 z m 352.66,0.81929 c 10.575,16.47498 14.365,36.75384 13.281,48.49094 l -10.469,21.2506 c -1.2177,-13.0504 -4.2801,-56.32741 -2.8125,-69.74154 z m -569.52,0.7947 c 0.0924,0.35775 0.19505,0.7147 0.28125,1.07531 -0.30251,0.0446 -0.27968,-0.5693 -0.28125,-1.07531 z m 172.19,2.12506 c -1.266,15.66635 -1.3738,52.54968 -0.90625,64.74878 l -11.438,-19.1761 c -0.69608,-11.4667 2.9168,-29.99154 12.344,-45.57268 z m -401.19,1.63857 c 5.6528,16.81416 15.271,57.02461 14.25,66.54141 l -13.719,-22.6073 c 0.52983,-11.2308 0.52586,-28.2735 -0.53125,-43.93411 z m 352.62,0.15361 c -0.45249,2.80908 -0.84984,5.80725 -1.1562,8.90972 -0.11606,-2.16283 -0.21707,-4.29452 -0.28125,-6.37501 0.46222,-0.85042 0.94235,-1.69879 1.4375,-2.53471 z m -122.38,2.07378 c 2.3724,14.72171 0.34431,30.84522 -2,41.70642 h -8.5938 c -0.46515,-10.7318 2.6901,-27.17478 10.594,-41.70642 z m -69.781,4.73644 c 6.7232,12.61861 9.8888,26.58978 10.25,36.97018 h -9.4375 c 0.49723,-9.7585 0.43871,-24.17378 -0.8125,-36.97018 z m 616.34,0.0512 c 0.57963,6.36608 0.9518,14.14903 1.0312,21.91578 -0.10271,1.7227 -0.25186,3.4247 -0.375,5.1206 -0.42169,-4.2867 -0.78141,-8.9376 -1.0625,-13.64601 0.0464,-4.54997 0.18445,-9.10716 0.40625,-13.39037 z m -14.5,1.63856 c -0.55269,13.07987 -0.44171,26.16052 0,35.28002 h -7.1562 c -0.5148,-9.0548 1.6266,-22.42627 7.1562,-35.28002 z m -428.31,8.90972 c 0.018,0.35822 0.0457,0.73812 0.0625,1.10095 -0.0251,0.061 -0.0693,0.11835 -0.0937,0.17922 0.006,-0.42371 0.0211,-0.85566 0.0312,-1.28013 z m -74.312,6.14463 c -0.21799,7.22297 -0.15532,14.23587 0.0625,20.22567 h -1.3125 c -0.57253,-3.7074 -0.5884,-8.9991 0,-15.1314 0.36026,-1.6759 0.77512,-3.3709 1.25,-5.09493 z m -275.59,7.68077 0.09375,0.9472 -0.03125,0.5121 c 0.01327,0.397 0.01934,0.426 0.03125,0.7937 h -0.09375 l 0.0625,-0.7937 c -0.02526,-0.7554 -0.03369,-0.5934 -0.0625,-1.4593 z m 0.125,1.5106 0.09375,0.7425 h -0.0625 c -0.0032,-0.1459 -0.02996,-0.6606 -0.03125,-0.7425 z m 921.03,35.0244 -5.625,10.8809 h 7.43755 l -1.81255,-10.8809 z"
inkscape:connector-curvature="0"
style="fill:#4b7e1d" />
<g
id="g5329"
transform="matrix(0.60834,0,0,0.49840319,5.8688,527.64637)">
<g
id="g3735"
transform="matrix(0.31347,0,0,0.25318,73.106,789.51)">
<path
id="path3737"
d="m 175.92,665.27 c 13.029,87.769 15.361,304.13 3.6326,390.48 l 65.744,-8.8997 c -3.9927,-89.586 -19.294,-331.09 -69.377,-381.58 z"
style="fill:url(#linearGradient3294)"
inkscape:connector-curvature="0" />
<path
id="path3739"
d="m 224,496.92 c 11.137,129.2 -5.5755,435.02 -28.781,555.44 h 66.344 c 8.06,-128.08 5.3,-474.11 -37.56,-555.48 z"
style="fill:url(#linearGradient3296)"
inkscape:connector-curvature="0" />
</g>
<g
id="g3677"
transform="matrix(0.31347,0,0,0.31347,446.66,725.86)">
<path
id="path2818"
d="m 175.92,665.27 c 13.029,87.769 15.361,304.13 3.6326,390.48 l 65.744,-8.8997 c -3.9927,-89.586 -19.294,-331.09 -69.377,-381.58 z"
style="fill:url(#linearGradient3298)"
inkscape:connector-curvature="0" />
<path
id="path3653"
d="m 224,496.92 c 11.137,129.2 -5.5755,435.02 -28.781,555.44 h 66.344 c 8.06,-128.08 5.3,-474.11 -37.56,-555.48 z"
style="fill:url(#linearGradient3300)"
inkscape:connector-curvature="0" />
</g>
<g
id="g3687"
transform="matrix(0.31347,0,0,0.31347,299,725.04)">
<g
id="g3648">
<path
id="path3605"
d="m 850,574.92 c 1.1375,109.33 -9.5755,373.93 -32.781,477.44 h 66.344 c 8.06,-110.1 9.3,-407.54 -33.56,-477.48 z"
style="fill:url(#linearGradient3302)"
inkscape:connector-curvature="0" />
<path
id="path3601"
d="m 704,532.92 c 131.14,122.72 78.424,439.44 55.219,523.44 h 64.344 c 8.06,-89.35 101.3,-364.72 -119.56,-523.48 z"
style="fill:url(#linearGradient3304)"
inkscape:connector-curvature="0" />
<path
id="path3603"
d="M 1076,598.92 C 944.91,721.65 909.62,974.36 932.83,1058.4 h -64.344 c -8.07,-89.35 -13.3,-300.72 207.51,-459.48 z"
style="fill:url(#linearGradient3306)"
inkscape:connector-curvature="0" />
</g>
</g>
<g
id="g3673"
transform="matrix(0.31347,0,0,0.31347,479.99,724.13)">
<path
id="path3665"
d="m 73.919,749.55 c 10.401,70.065 12.262,242.78 2.8998,311.71 l 52.482,-7.1044 c -3.1873,-71.514 -15.402,-264.3 -55.382,-304.61 z"
style="fill:url(#linearGradient3308)"
inkscape:connector-curvature="0" />
<path
id="path3667"
d="m 94.301,630.16 c 1.2739,14.777 24.091,19.448 24.503,39.164 2.4588,117.89 -13.607,306.87 -29.478,389.23 h 52.961 c 5.5786,-88.61 13.68,-305 -6.5541,-403.34 -3.1057,-15.094 -36.879,-16.408 -41.431,-25.05 z"
style="fill:url(#linearGradient3310)"
inkscape:connector-curvature="0" />
</g>
<g
id="g3681"
transform="matrix(0.31347,0,0,0.31347,126.41,725.04)">
<g
id="g3643">
<path
id="path3595"
d="m 384,500.92 c 131.14,122.72 108.42,467.44 85.219,551.44 h 64.344 c 8.06,-89.35 71.3,-392.72 -149.56,-551.48 z"
style="fill:url(#linearGradient3312)"
inkscape:connector-curvature="0" />
<path
id="path3597"
d="M 786.05,506.92 C 654.91,629.65 611.62,974.36 634.83,1058.4 h -64.344 c -8.0609,-89.311 -5.2939,-392.68 215.56,-551.44 z"
style="fill:url(#linearGradient3314)"
inkscape:connector-curvature="0" />
<path
id="path3599"
d="m 558,390.92 c 1.1375,152.39 -25.576,521.17 -48.781,665.44 h 66.344 c 8.06,-153.43 25.3,-568 -17.56,-665.48 z"
style="fill:url(#linearGradient3316)"
inkscape:connector-curvature="0" />
</g>
</g>
<g
id="g4722"
transform="matrix(-0.31347,0,0,0.31347,1624.2,725.86)">
<path
id="path4724"
d="m 175.92,665.27 c 13.029,87.769 15.361,304.13 3.6326,390.48 l 65.744,-8.8997 c -3.9927,-89.586 -19.294,-331.09 -69.377,-381.58 z"
style="fill:url(#linearGradient3318)"
inkscape:connector-curvature="0" />
<path
id="path4726"
d="m 222,564.92 c 11.137,129.2 -3.5755,367.02 -26.781,487.44 h 66.344 c 8.06,-128.08 3.3,-406.11 -39.56,-487.48 z"
style="fill:url(#linearGradient3320)"
inkscape:connector-curvature="0" />
</g>
<g
id="g4732"
transform="matrix(0.31347,0,0,0.31347,1140.9,725.85)">
<path
id="path4734"
transform="translate(-586,-293.73)"
d="m 761.91,959 c 6.6291,44.656 10.508,122.61 11.156,199.78 -3.5177,71.971 -9.3503,142.65 -16.25,183.25 l 9.7812,-0.8124 c -0.33219,2.8738 -0.67291,5.6427 -1.0312,8.2812 l 65.719,-8.9062 c -2.6347,-59.117 -10.178,-184.4 -29.406,-277.28 -5.5372,-47.264 -14.07,-86.309 -27.031,-104.16 0.42149,6.1627 0.76369,13.01 1.0312,20.344 -4.3264,-8.496 -8.9737,-15.464 -13.969,-20.5 z"
style="fill:url(#linearGradient3322)"
inkscape:connector-curvature="0" />
<path
id="path4736"
d="m 197.31,566.12 c 1.533,17.783 18.937,-18.566 27.028,-14.626 2.7723,1.3499 3.047,24.28 3.1212,32.869 1.2822,148.46 -13.32,369.83 -32.237,468 h 66.344 c 6.2183,-98.771 5.9931,-327.27 -14.108,-463.92 -3.1514,-21.423 -3.9869,-36.092 -10.971,-44.685 -17.332,-21.325 -34.563,31.126 -39.176,22.367 z"
style="fill:url(#linearGradient3324)"
inkscape:connector-curvature="0" />
</g>
<g
id="g4751"
transform="matrix(0.31347,0,0,0.31347,32.374,725.04)">
<g
id="g4753">
<path
id="path4755"
d="m 350,552.92 c 28.196,26.387 83.28,11.038 98.776,53.153 56.572,153.76 38.659,380.35 20.443,446.28 h 64.344 c 6.76,-74.95 52.34,-300.46 -63.47,-464.92 -22.26,-31.61 -84.48,-8.96 -120.09,-34.56 z"
style="fill:url(#linearGradient3326)"
inkscape:connector-curvature="0" />
<path
id="path4757"
d="m 790.05,568.92 c -30.352,28.405 -59.999,6.7027 -81.203,52.907 -70.41,153.42 -91.85,371.97 -74.015,436.53 h -64.344 c -6.5549,-72.625 -5.9498,-286.8 113.26,-449.65 27.389,-37.417 65.04,-10.126 106.3,-39.787 z"
style="fill:url(#linearGradient3328)"
inkscape:connector-curvature="0" />
<path
id="path4759"
d="m 543.96,382.16 c 0.20245,27.122 -46.477,57.098 -47.862,95.443 -1.4726,40.764 58.775,85.225 56.655,132.88 -7.0921,159.38 -28.848,354.58 -43.533,445.88 h 66.344 c 6.3479,-120.8 12.384,-288.56 -3.7169,-450.88 -4.3448,-43.804 -18.779,-202.6 -27.886,-223.31 z"
style="fill:url(#linearGradient3330)"
inkscape:connector-curvature="0" />
</g>
</g>
<g
id="g4767"
transform="matrix(0.31347,0,0,0.31347,883.95,725.04)">
<g
id="g4769">
<path
id="path4771"
d="m 850,574.92 c 1.1375,109.33 -9.5755,373.93 -32.781,477.44 h 66.344 c 6.0072,-82.019 6.2224,-293.1 -10.776,-411.54 -1.1894,-8.2873 -8.4728,16.757 -9.8556,9.1906 -1.287,-7.0422 5.3398,-21.747 3.8764,-28.066 -4.64,-20.1 -10.2,-36.28 -16.8,-47.06 z"
style="fill:url(#linearGradient3332)"
inkscape:connector-curvature="0" />
<path
id="path4773"
d="m 720,556.92 c 19.657,18.396 20.183,26.15 32.297,51.826 4.6832,9.9265 7.8565,11.29 11.561,22.007 50.642,146.49 13.743,359.06 -4.6392,425.6 h 64.344 c 6.06,-67.2 32.58,-228.85 -20.92,-370.28 -17.65,-46.63 -43.99,-91.07 -82.64,-129.2 z"
style="fill:url(#linearGradient3334)"
inkscape:connector-curvature="0" />
<path
id="path4775"
d="M 1076,598.92 C 944.91,721.65 909.62,974.36 932.83,1058.4 h -64.344 c -6.5474,-72.542 -11.229,-225.61 105.59,-365.6 5.672,-6.7972 -0.3695,15.436 5.8891,8.7117 4.6165,-4.9604 21.396,-38.898 26.345,-43.809 20.284,-20.129 43.403,-39.806 69.737,-58.735 z"
style="fill:url(#linearGradient3336)"
inkscape:connector-curvature="0" />
</g>
</g>
<g
id="g4783"
transform="matrix(-0.31347,0,0,0.31347,1307.3,725.04)">
<g
id="g4785">
<path
id="path4787"
d="m 384,500.92 c 131.14,122.72 108.42,467.44 85.219,551.44 h 64.344 c 8.06,-89.35 71.3,-392.72 -149.56,-551.48 z"
style="fill:url(#linearGradient3338)"
inkscape:connector-curvature="0" />
<path
id="path4789"
d="M 786.05,506.92 C 654.91,629.65 611.62,974.36 634.83,1058.4 h -64.344 c -8.0609,-89.311 -5.2939,-392.68 215.56,-551.44 z"
style="fill:url(#linearGradient3340)"
inkscape:connector-curvature="0" />
<path
id="path4791"
d="m 558,390.92 c 1.1375,152.39 -25.576,521.17 -48.781,665.44 h 66.344 c 8.06,-153.43 25.3,-568 -17.56,-665.48 z"
style="fill:url(#linearGradient3342)"
inkscape:connector-curvature="0" />
</g>
</g>
<g
id="g4799"
transform="matrix(-0.31347,0,0,0.25318,1557.5,789.51)">
<path
id="path4801"
d="m 175.92,665.27 c 13.029,87.769 15.361,304.13 3.6326,390.48 l 65.744,-8.8997 c -3.9927,-89.586 -19.294,-331.09 -69.377,-381.58 z"
style="fill:url(#linearGradient3344)"
inkscape:connector-curvature="0" />
<path
id="path4803"
d="m 224,496.92 c 11.137,129.2 -5.5755,435.02 -28.781,555.44 h 66.344 c 8.06,-128.08 5.3,-474.11 -37.56,-555.48 z"
style="fill:url(#linearGradient3346)"
inkscape:connector-curvature="0" />
</g>
<g
id="g4809"
transform="matrix(-0.31347,0,0,0.31347,585.56,724.13)">
<path
id="path4811"
d="m 73.919,749.55 c 10.401,70.065 12.262,242.78 2.8998,311.71 l 52.482,-7.1044 c -3.1873,-71.514 -15.402,-264.3 -55.382,-304.61 z"
style="fill:url(#linearGradient3348)"
inkscape:connector-curvature="0" />
<path
id="path4813"
d="m 94.301,630.16 c 1.2739,14.777 24.091,19.448 24.503,39.164 2.4588,117.89 -13.607,306.87 -29.478,389.23 h 52.961 c 5.5786,-88.61 13.68,-305 -6.5541,-403.34 -3.1057,-15.094 -36.879,-16.408 -41.431,-25.05 z"
style="fill:url(#linearGradient3350)"
inkscape:connector-curvature="0" />
</g>
<g
id="g4819"
transform="matrix(-0.31347,0,0,0.31347,238.01,725.04)">
<g
id="g4821">
<path
id="path4823"
d="m 350,552.92 c 28.196,26.387 83.28,11.038 98.776,53.153 56.572,153.76 38.659,380.35 20.443,446.28 h 64.344 c 6.76,-74.95 52.34,-300.46 -63.47,-464.92 -22.26,-31.61 -84.48,-8.96 -120.09,-34.56 z"
style="fill:url(#linearGradient3352)"
inkscape:connector-curvature="0" />
<path
id="path4825"
d="m 790.05,568.92 c -30.352,28.405 -59.999,6.7027 -81.203,52.907 -70.41,153.42 -91.85,371.97 -74.015,436.53 h -64.344 c -6.5549,-72.625 -5.9498,-286.8 113.26,-449.65 27.389,-37.417 65.04,-10.126 106.3,-39.787 z"
style="fill:url(#linearGradient3354)"
inkscape:connector-curvature="0" />
<path
id="path4827"
d="m 595,394.92 c 0.20245,27.122 -46.477,57.098 -47.862,95.443 -1.4726,40.764 7.7345,72.465 5.614,120.12 -7.0921,159.38 -28.848,354.58 -43.533,445.88 h 66.344 c 6.35,-120.84 12.39,-288.6 -3.71,-450.92 -4.35,-43.81 32.26,-189.84 23.15,-210.56 z"
style="fill:url(#linearGradient3356)"
inkscape:connector-curvature="0" />
</g>
</g>
<g
id="g4835"
transform="matrix(-0.31347,0,0,0.31347,287.66,725.85)">
<path
id="path4837"
transform="translate(-586,-293.73)"
d="m 761.91,959 c 6.6291,44.656 10.508,122.61 11.156,199.78 -3.5177,71.971 -9.3503,142.65 -16.25,183.25 l 9.7812,-0.8124 c -0.33219,2.8738 -0.67291,5.6427 -1.0312,8.2812 l 65.719,-8.9062 c -2.6347,-59.117 -10.178,-184.4 -29.406,-277.28 -5.5372,-47.264 -14.07,-86.309 -27.031,-104.16 0.42149,6.1627 0.76369,13.01 1.0312,20.344 -4.3264,-8.496 -8.9737,-15.464 -13.969,-20.5 z"
style="fill:url(#linearGradient3358)"
inkscape:connector-curvature="0" />
<path
id="path4839"
d="m 197.31,566.12 c 1.533,17.783 18.937,-18.566 27.028,-14.626 2.7723,1.3499 3.047,24.28 3.1212,32.869 1.2822,148.46 -13.32,369.83 -32.237,468 h 66.344 c 6.2183,-98.771 5.9931,-327.27 -14.108,-463.92 -3.1514,-21.423 -3.9869,-36.092 -10.971,-44.685 -17.332,-21.325 -34.563,31.126 -39.176,22.367 z"
style="fill:url(#linearGradient3360)"
inkscape:connector-curvature="0" />
</g>
<g
id="g4845"
transform="matrix(-0.31347,0,0,0.31347,1599.6,725.86)">
<path
id="path4847"
d="m 175.92,665.27 c 13.029,87.769 15.361,304.13 3.6326,390.48 l 65.744,-8.8997 c -3.9927,-89.586 -19.294,-331.09 -69.377,-381.58 z"
style="fill:url(#linearGradient3362)"
inkscape:connector-curvature="0" />
<path
id="path4849"
d="m 224,496.92 c 11.137,129.2 -5.5755,435.02 -28.781,555.44 h 66.344 c 8.06,-128.08 5.3,-474.11 -37.56,-555.48 z"
style="fill:url(#linearGradient3364)"
inkscape:connector-curvature="0" />
</g>
<g
id="g4855"
transform="matrix(-0.31347,0,0,0.31347,886.73,725.04)">
<g
id="g4857">
<path
id="path4859"
d="m 850,574.92 c 1.1375,109.33 -9.5755,373.93 -32.781,477.44 h 66.344 c 6.0072,-82.019 6.2224,-293.1 -10.776,-411.54 -1.1894,-8.2873 -8.4728,16.757 -9.8556,9.1906 -1.287,-7.0422 5.3398,-21.747 3.8764,-28.066 -4.64,-20.1 -10.2,-36.28 -16.8,-47.06 z"
style="fill:url(#linearGradient3366)"
inkscape:connector-curvature="0" />
<path
id="path4861"
d="m 720,556.92 c 19.657,18.396 20.183,26.15 32.297,51.826 4.6832,9.9265 7.8565,11.29 11.561,22.007 50.642,146.49 13.743,359.06 -4.6392,425.6 h 64.344 c 6.06,-67.2 32.58,-228.85 -20.92,-370.28 -17.65,-46.63 -43.99,-91.07 -82.64,-129.2 z"
style="fill:url(#linearGradient3368)"
inkscape:connector-curvature="0" />
<path
id="path4863"
d="M 1076,598.92 C 944.91,721.65 909.62,974.36 932.83,1058.4 h -64.344 c -6.5474,-72.542 -11.229,-225.61 105.59,-365.6 5.672,-6.7972 -0.3695,15.436 5.8891,8.7117 4.6165,-4.9604 21.396,-38.898 26.345,-43.809 20.284,-20.129 43.403,-39.806 69.737,-58.735 z"
style="fill:url(#linearGradient3370)"
inkscape:connector-curvature="0" />
</g>
</g>
<g
id="g4877"
transform="matrix(-0.31347,0,0,0.31347,1325.4,725.04)">
<g
id="g4879">
<path
id="path4881"
d="m 850,574.92 c 1.1375,109.33 -9.5755,373.93 -32.781,477.44 h 66.344 c 8.06,-110.1 9.3,-407.54 -33.56,-477.48 z"
style="fill:url(#linearGradient3372)"
inkscape:connector-curvature="0" />
<path
id="path4883"
d="m 704,532.92 c 131.14,122.72 78.424,439.44 55.219,523.44 h 64.344 c 8.06,-89.35 101.3,-364.72 -119.56,-523.48 z"
style="fill:url(#linearGradient3374)"
inkscape:connector-curvature="0" />
<path
id="path4885"
d="M 1076,598.92 C 944.91,721.65 909.62,974.36 932.83,1058.4 h -64.344 c -8.07,-89.35 -13.3,-300.72 207.51,-459.48 z"
style="fill:url(#linearGradient3376)"
inkscape:connector-curvature="0" />
</g>
</g>
<g
id="g4893"
transform="matrix(0.31347,0,0,0.25318,1173.2,789.51)">
<path
id="path4895"
d="m 175.92,665.27 c 13.029,87.769 15.361,304.13 3.6326,390.48 l 65.744,-8.8997 c -3.9927,-89.586 -19.294,-331.09 -69.377,-381.58 z"
style="fill:url(#linearGradient3378)"
inkscape:connector-curvature="0" />
<path
id="path4897"
d="m 224,496.92 c 11.137,129.2 -5.5755,435.02 -28.781,555.44 h 66.344 c 8.06,-128.08 5.3,-474.11 -37.56,-555.48 z"
style="fill:url(#linearGradient3380)"
inkscape:connector-curvature="0" />
</g>
<g
id="g4899"
transform="matrix(0.31347,0,0,0.31347,100.42,725.86)">
<path
id="path4901"
d="m 175.92,665.27 c 13.029,87.769 15.361,304.13 3.6326,390.48 l 65.744,-8.8997 c -3.9927,-89.586 -19.294,-331.09 -69.377,-381.58 z"
style="fill:url(#linearGradient3382)"
inkscape:connector-curvature="0" />
<path
id="path4903"
d="m 224,496.92 c 11.137,129.2 -5.5755,435.02 -28.781,555.44 h 66.344 c 8.06,-128.08 5.3,-474.11 -37.56,-555.48 z"
style="fill:url(#linearGradient3384)"
inkscape:connector-curvature="0" />
</g>
<g
id="g4905"
transform="matrix(0.31347,0,0,0.31347,-163.59,725.04)">
<g
id="g4907">
<path
id="path4909"
d="m 850,574.92 c 1.1375,109.33 -9.5755,373.93 -32.781,477.44 h 66.344 c 8.06,-110.1 9.3,-407.54 -33.56,-477.48 z"
style="fill:url(#linearGradient3386)"
inkscape:connector-curvature="0" />
<path
id="path4911"
d="m 704,532.92 c 131.14,122.72 78.424,439.44 55.219,523.44 h 64.344 c 8.06,-89.35 101.3,-364.72 -119.56,-523.48 z"
style="fill:url(#linearGradient3388)"
inkscape:connector-curvature="0" />
<path
id="path4913"
d="M 1076,598.92 C 944.91,721.65 909.62,974.36 932.83,1058.4 h -64.344 c -8.07,-89.35 -13.3,-300.72 207.51,-459.48 z"
style="fill:url(#linearGradient3390)"
inkscape:connector-curvature="0" />
</g>
</g>
<g
id="g4915"
transform="matrix(0.31347,0,0,0.31347,1556.4,724.13)">
<path
id="path4917"
d="m 73.919,749.55 c 10.401,70.065 12.262,242.78 2.8998,311.71 l 52.482,-7.1044 c -3.1873,-71.514 -15.402,-264.3 -55.382,-304.61 z"
style="fill:url(#linearGradient3392)"
inkscape:connector-curvature="0" />
<path
id="path4919"
d="m 94.301,630.16 c 1.2739,14.777 24.091,19.448 24.503,39.164 2.4588,117.89 -13.607,306.87 -29.478,389.23 h 52.961 c 5.5786,-88.61 13.68,-305 -6.5541,-403.34 -3.1057,-15.094 -36.879,-16.408 -41.431,-25.05 z"
style="fill:url(#linearGradient3394)"
inkscape:connector-curvature="0" />
</g>
<g
id="g4921"
transform="matrix(0.31347,0,0,0.31347,514.98,725.04)">
<g
id="g4923">
<path
id="path4925"
d="m 384,500.92 c 131.14,122.72 108.42,467.44 85.219,551.44 h 64.344 c 8.06,-89.35 71.3,-392.72 -149.56,-551.48 z"
style="fill:url(#linearGradient3396)"
inkscape:connector-curvature="0" />
<path
id="path4927"
d="M 786.05,506.92 C 654.91,629.65 611.62,974.36 634.83,1058.4 h -64.344 c -8.0609,-89.311 -5.2939,-392.68 215.56,-551.44 z"
style="fill:url(#linearGradient3398)"
inkscape:connector-curvature="0" />
<path
id="path4929"
d="m 558,390.92 c 1.1375,152.39 -25.576,521.17 -48.781,665.44 h 66.344 c 8.06,-153.43 25.3,-568 -17.56,-665.48 z"
style="fill:url(#linearGradient3400)"
inkscape:connector-curvature="0" />
</g>
</g>
<g
id="g4931"
transform="matrix(-0.31347,0,0,0.31347,324.06,725.86)">
<path
id="path4933"
d="m 175.92,665.27 c 13.029,87.769 15.361,304.13 3.6326,390.48 l 65.744,-8.8997 c -3.9927,-89.586 -19.294,-331.09 -69.377,-381.58 z"
style="fill:url(#linearGradient3402)"
inkscape:connector-curvature="0" />
<path
id="path4935"
d="m 222,564.92 c 11.137,129.2 -3.5755,367.02 -26.781,487.44 h 66.344 c 8.06,-128.08 3.3,-406.11 -39.56,-487.48 z"
style="fill:url(#linearGradient3404)"
inkscape:connector-curvature="0" />
</g>
<g
id="g4937"
transform="matrix(0.31347,0,0,0.31347,1257.6,725.85)">
<path
id="path4939"
transform="translate(-586,-293.73)"
d="m 761.91,959 c 6.6291,44.656 10.508,122.61 11.156,199.78 -3.5177,71.971 -9.3503,142.65 -16.25,183.25 l 9.7812,-0.8124 c -0.33219,2.8738 -0.67291,5.6427 -1.0312,8.2812 l 65.719,-8.9062 c -2.6347,-59.117 -10.178,-184.4 -29.406,-277.28 -5.5372,-47.264 -14.07,-86.309 -27.031,-104.16 0.42149,6.1627 0.76369,13.01 1.0312,20.344 -4.3264,-8.496 -8.9737,-15.464 -13.969,-20.5 z"
style="fill:url(#linearGradient3406)"
inkscape:connector-curvature="0" />
<path
id="path4941"
d="m 197.31,566.12 c 1.533,17.783 18.937,-18.566 27.028,-14.626 2.7723,1.3499 3.047,24.28 3.1212,32.869 1.2822,148.46 -13.32,369.83 -32.237,468 h 66.344 c 6.2183,-98.771 5.9931,-327.27 -14.108,-463.92 -3.1514,-21.423 -3.9869,-36.092 -10.971,-44.685 -17.332,-21.325 -34.563,31.126 -39.176,22.367 z"
style="fill:url(#linearGradient3408)"
inkscape:connector-curvature="0" />
</g>
<g
id="g4943"
transform="matrix(0.31347,0,0,0.31347,1275.8,725.04)">
<g
id="g4945">
<path
id="path4947"
d="m 350,552.92 c 28.196,26.387 83.28,11.038 98.776,53.153 56.572,153.76 38.659,380.35 20.443,446.28 h 64.344 c 6.76,-74.95 52.34,-300.46 -63.47,-464.92 -22.26,-31.61 -84.48,-8.96 -120.09,-34.56 z"
style="fill:url(#linearGradient3410)"
inkscape:connector-curvature="0" />
<path
id="path4949"
d="m 790.05,568.92 c -30.352,28.405 -59.999,6.7027 -81.203,52.907 -70.41,153.42 -91.85,371.97 -74.015,436.53 h -64.344 c -6.5549,-72.625 -5.9498,-286.8 113.26,-449.65 27.389,-37.417 65.04,-10.126 106.3,-39.787 z"
style="fill:url(#linearGradient3412)"
inkscape:connector-curvature="0" />
<path
id="path4951"
d="m 595,394.92 c 0.20245,27.122 -46.477,57.098 -47.862,95.443 -1.4726,40.764 7.7345,72.465 5.614,120.12 -7.0921,159.38 -28.848,354.58 -43.533,445.88 h 66.344 c 6.35,-120.84 12.39,-288.6 -3.71,-450.92 -4.35,-43.81 32.26,-189.84 23.15,-210.56 z"
style="fill:url(#linearGradient3414)"
inkscape:connector-curvature="0" />
</g>
</g>
<g
id="g4953"
transform="matrix(0.31347,0,0,0.31347,110.83,725.04)">
<g
id="g4955">
<path
id="path4957"
d="m 850,574.92 c 1.1375,109.33 -9.5755,373.93 -32.781,477.44 h 66.344 c 6.0072,-82.019 6.2224,-293.1 -10.776,-411.54 -1.1894,-8.2873 -8.4728,16.757 -9.8556,9.1906 -1.287,-7.0422 5.3398,-21.747 3.8764,-28.066 -4.64,-20.1 -10.2,-36.28 -16.8,-47.06 z"
style="fill:url(#linearGradient3416)"
inkscape:connector-curvature="0" />
<path
id="path4959"
d="m 720,556.92 c 19.657,18.396 20.183,26.15 32.297,51.826 4.6832,9.9265 7.8565,11.29 11.561,22.007 50.642,146.49 13.743,359.06 -4.6392,425.6 h 64.344 c 6.06,-67.2 32.58,-228.85 -20.92,-370.28 -17.65,-46.63 -43.99,-91.07 -82.64,-129.2 z"
style="fill:url(#linearGradient3418)"
inkscape:connector-curvature="0" />
<path
id="path4961"
d="M 1076,598.92 C 944.91,721.65 909.62,974.36 932.83,1058.4 h -64.344 c -6.5474,-72.542 -11.229,-225.61 105.59,-365.6 5.672,-6.7972 -0.3695,15.436 5.8891,8.7117 4.6165,-4.9604 21.396,-38.898 26.345,-43.809 20.284,-20.129 43.403,-39.806 69.737,-58.735 z"
style="fill:url(#linearGradient3420)"
inkscape:connector-curvature="0" />
</g>
</g>
<g
id="g4963"
transform="matrix(-0.31347,0,0,0.31347,1840.6,725.04)">
<g
id="g4965">
<path
id="path4967"
d="m 384,500.92 c 131.14,122.72 108.42,467.44 85.219,551.44 h 64.344 c 8.06,-89.35 71.3,-392.72 -149.56,-551.48 z"
style="fill:url(#linearGradient3422)"
inkscape:connector-curvature="0" />
<path
id="path4969"
d="M 786.05,506.92 C 654.91,629.65 611.62,974.36 634.83,1058.4 h -64.344 c -8.0609,-89.311 -5.2939,-392.68 215.56,-551.44 z"
style="fill:url(#linearGradient3424)"
inkscape:connector-curvature="0" />
<path
id="path4971"
d="m 558,390.92 c 1.1375,152.39 -25.576,521.17 -48.781,665.44 h 66.344 c 8.06,-153.43 25.3,-568 -17.56,-665.48 z"
style="fill:url(#linearGradient3426)"
inkscape:connector-curvature="0" />
</g>
</g>
<g
id="g4973"
transform="matrix(-0.31347,0,0,0.25318,171.19,789.51)">
<path
id="path4975"
d="m 175.92,665.27 c 13.029,87.769 15.361,304.13 3.6326,390.48 l 65.744,-8.8997 c -3.9927,-89.586 -19.294,-331.09 -69.377,-381.58 z"
style="fill:url(#linearGradient3428)"
inkscape:connector-curvature="0" />
<path
id="path4977"
d="m 224,496.92 c 11.137,129.2 -5.5755,435.02 -28.781,555.44 h 66.344 c 8.06,-128.08 5.3,-474.11 -37.56,-555.48 z"
style="fill:url(#linearGradient3430)"
inkscape:connector-curvature="0" />
</g>
<g
id="g4979"
transform="matrix(-0.31347,0,0,0.31347,571.48,724.13)">
<path
id="path4981"
d="m 73.919,749.55 c 10.401,70.065 12.262,242.78 2.8998,311.71 l 52.482,-7.1044 c -3.1873,-71.514 -15.402,-264.3 -55.382,-304.61 z"
style="fill:url(#linearGradient3432)"
inkscape:connector-curvature="0" />
<path
id="path4983"
d="m 94.301,630.16 c 1.2739,14.777 24.091,19.448 24.503,39.164 2.4588,117.89 -13.607,306.87 -29.478,389.23 h 52.961 c 5.5786,-88.61 13.68,-305 -6.5541,-403.34 -3.1057,-15.094 -36.879,-16.408 -41.431,-25.05 z"
style="fill:url(#linearGradient3434)"
inkscape:connector-curvature="0" />
</g>
<g
id="g4985"
transform="matrix(-0.31347,0,0,0.31347,1063.7,725.04)">
<g
id="g4987">
<path
id="path4989"
d="m 350,552.92 c 28.196,26.387 83.28,11.038 98.776,53.153 56.572,153.76 38.659,380.35 20.443,446.28 h 64.344 c 6.76,-74.95 52.34,-300.46 -63.47,-464.92 -22.26,-31.61 -84.48,-8.96 -120.09,-34.56 z"
style="fill:url(#linearGradient3436)"
inkscape:connector-curvature="0" />
<path
id="path4991"
d="m 790.05,568.92 c -30.352,28.405 -59.999,6.7027 -81.203,52.907 -70.41,153.42 -91.85,371.97 -74.015,436.53 h -64.344 c -6.5549,-72.625 -5.9498,-286.8 113.26,-449.65 27.389,-37.417 65.04,-10.126 106.3,-39.787 z"
style="fill:url(#linearGradient3438)"
inkscape:connector-curvature="0" />
<path
id="path4993"
d="m 547.14,490.37 c -1.4726,40.764 7.7345,72.465 5.614,120.12 -7.0921,159.38 -28.848,354.58 -43.533,445.88 h 66.344 c 6.3479,-120.8 12.384,-288.56 -3.7169,-450.88 36.255,-88.789 23.406,-306.96 -24.708,-115.11 z"
style="fill:url(#linearGradient3440)"
inkscape:connector-curvature="0" />
</g>
</g>
<g
id="g4995"
transform="matrix(-0.31347,0,0,0.31347,908.35,725.85)">
<path
id="path4997"
transform="translate(-586,-293.73)"
d="m 761.91,959 c 6.6291,44.656 10.508,122.61 11.156,199.78 -3.5177,71.971 -9.3503,142.65 -16.25,183.25 l 9.7812,-0.8124 c -0.33219,2.8738 -0.67291,5.6427 -1.0312,8.2812 l 65.719,-8.9062 c -2.6347,-59.117 -10.178,-184.4 -29.406,-277.28 -5.5372,-47.264 -14.07,-86.309 -27.031,-104.16 0.42149,6.1627 0.76369,13.01 1.0312,20.344 -4.3264,-8.496 -8.9737,-15.464 -13.969,-20.5 z"
style="fill:url(#linearGradient3442)"
inkscape:connector-curvature="0" />
<path
id="path4999"
d="m 197.31,566.12 c 1.533,17.783 18.937,-18.566 27.028,-14.626 2.7723,1.3499 3.047,24.28 3.1212,32.869 1.2822,148.46 -13.32,369.83 -32.237,468 h 66.344 c 6.2183,-98.771 5.9931,-327.27 -14.108,-463.92 -3.1514,-21.423 -3.9869,-36.092 -10.971,-44.685 -17.332,-21.325 -34.563,31.126 -39.176,22.367 z"
style="fill:url(#linearGradient3444)"
inkscape:connector-curvature="0" />
</g>
<g
id="g5001"
transform="matrix(-0.31347,0,0,0.31347,1433.5,725.86)">
<path
id="path5003"
d="m 175.92,665.27 c 13.029,87.769 15.361,304.13 3.6326,390.48 l 65.744,-8.8997 c -3.9927,-89.586 -19.294,-331.09 -69.377,-381.58 z"
style="fill:url(#linearGradient3446)"
inkscape:connector-curvature="0" />
<path
id="path5005"
d="m 224,496.92 c 11.137,129.2 -5.5755,435.02 -28.781,555.44 h 66.344 c 8.06,-128.08 5.3,-474.11 -37.56,-555.48 z"
style="fill:url(#linearGradient3448)"
inkscape:connector-curvature="0" />
</g>
<g
id="g5007"
transform="matrix(-0.31347,0,0,0.31347,1211,725.04)">
<g
id="g5009">
<path
id="path5011"
d="m 850,574.92 c 1.1375,109.33 -9.5755,373.93 -32.781,477.44 h 66.344 c 6.0072,-82.019 6.2224,-293.1 -10.776,-411.54 -1.1894,-8.2873 -8.4728,16.757 -9.8556,9.1906 -1.287,-7.0422 5.3398,-21.747 3.8764,-28.066 -4.64,-20.1 -10.2,-36.28 -16.8,-47.06 z"
style="fill:url(#linearGradient3450)"
inkscape:connector-curvature="0" />
<path
id="path5013"
d="m 720,556.92 c 19.657,18.396 20.183,26.15 32.297,51.826 4.6832,9.9265 7.8565,11.29 11.561,22.007 50.642,146.49 13.743,359.06 -4.6392,425.6 h 64.344 c 6.06,-67.2 32.58,-228.85 -20.92,-370.28 -17.65,-46.63 -43.99,-91.07 -82.64,-129.2 z"
style="fill:url(#linearGradient3452)"
inkscape:connector-curvature="0" />
<path
id="path5015"
d="M 1076,598.92 C 944.91,721.65 909.62,974.36 932.83,1058.4 h -64.344 c -6.5474,-72.542 -11.229,-225.61 105.59,-365.6 5.672,-6.7972 -0.3695,15.436 5.8891,8.7117 4.6165,-4.9604 21.396,-38.898 26.345,-43.809 20.284,-20.129 43.403,-39.806 69.737,-58.735 z"
style="fill:url(#linearGradient3454)"
inkscape:connector-curvature="0" />
</g>
</g>
<g
id="g5017"
transform="matrix(-0.31347,0,0,0.31347,346.98,725.04)">
<g
id="g5019">
<path
id="path5021"
d="m 850,574.92 c 1.1375,109.33 -9.5755,373.93 -32.781,477.44 h 66.344 c 8.06,-110.1 9.3,-407.54 -33.56,-477.48 z"
style="fill:url(#linearGradient3456)"
inkscape:connector-curvature="0" />
<path
id="path5023"
d="m 704,532.92 c 131.14,122.72 78.424,439.44 55.219,523.44 h 64.344 c 8.06,-89.35 101.3,-364.72 -119.56,-523.48 z"
style="fill:url(#linearGradient3458)"
inkscape:connector-curvature="0" />
<path
id="path5025"
d="M 1076,598.92 C 944.91,721.65 909.62,974.36 932.83,1058.4 h -64.344 c -8.07,-89.35 -13.3,-300.72 207.51,-459.48 z"
style="fill:url(#linearGradient3460)"
inkscape:connector-curvature="0" />
</g>
</g>
<g
id="g5027"
transform="matrix(0.31347,0,0,0.25318,537.25,789.51)">
<path
id="path5029"
d="m 175.92,665.27 c 13.029,87.769 15.361,304.13 3.6326,390.48 l 65.744,-8.8997 c -3.9927,-89.586 -19.294,-331.09 -69.377,-381.58 z"
style="fill:url(#linearGradient3462)"
inkscape:connector-curvature="0" />
<path
id="path5031"
d="m 224,496.92 c 11.137,129.2 -5.5755,435.02 -28.781,555.44 h 66.344 c 8.06,-128.08 5.3,-474.11 -37.56,-555.48 z"
style="fill:url(#linearGradient3464)"
inkscape:connector-curvature="0" />
</g>
<g
id="g5033"
transform="matrix(0.31347,0,0,0.31347,1448.5,725.86)">
<path
id="path5035"
d="m 175.92,665.27 c 13.029,87.769 15.361,304.13 3.6326,390.48 l 65.744,-8.8997 c -3.9927,-89.586 -19.294,-331.09 -69.377,-381.58 z"
style="fill:url(#linearGradient3466)"
inkscape:connector-curvature="0" />
<path
id="path5037"
d="m 224,496.92 c 11.137,129.2 -5.5755,435.02 -28.781,555.44 h 66.344 c 8.06,-128.08 5.3,-474.11 -37.56,-555.48 z"
style="fill:url(#linearGradient3468)"
inkscape:connector-curvature="0" />
</g>
<g
id="g5039"
transform="matrix(0.31347,0,0,0.31347,1015.1,725.04)">
<g
id="g5041">
<path
id="path5043"
d="m 850,574.92 c 1.1375,109.33 -9.5755,373.93 -32.781,477.44 h 66.344 c 8.06,-110.1 9.3,-407.54 -33.56,-477.48 z"
style="fill:url(#linearGradient3470)"
inkscape:connector-curvature="0" />
<path
id="path5045"
d="m 704,532.92 c 131.14,122.72 78.424,439.44 55.219,523.44 h 64.344 c 8.06,-89.35 101.3,-364.72 -119.56,-523.48 z"
style="fill:url(#linearGradient3472)"
inkscape:connector-curvature="0" />
<path
id="path5047"
d="M 1076,598.92 C 944.91,721.65 909.62,974.36 932.83,1058.4 h -64.344 c -8.07,-89.35 -13.3,-300.72 207.51,-459.48 z"
style="fill:url(#linearGradient3474)"
inkscape:connector-curvature="0" />
</g>
</g>
<g
id="g5049"
transform="matrix(0.31347,0,0,0.31347,862.01,724.13)">
<path
id="path5051"
d="m 73.919,749.55 c 10.401,70.065 12.262,242.78 2.8998,311.71 l 52.482,-7.1044 c -3.1873,-71.514 -15.402,-264.3 -55.382,-304.61 z"
style="fill:url(#linearGradient3476)"
inkscape:connector-curvature="0" />
<path
id="path5053"
d="m 94.301,630.16 c 1.2739,14.777 24.091,19.448 24.503,39.164 2.4588,117.89 -13.607,306.87 -29.478,389.23 h 52.961 c 5.5786,-88.61 13.68,-305 -6.5541,-403.34 -3.1057,-15.094 -36.879,-16.408 -41.431,-25.05 z"
style="fill:url(#linearGradient3478)"
inkscape:connector-curvature="0" />
</g>
<g
id="g5055"
transform="matrix(0.31347,0,0,0.31347,539.6,725.04)">
<g
id="g5057">
<path
id="path5059"
d="m 384,500.92 c 131.14,122.72 108.42,467.44 85.219,551.44 h 64.344 c 8.06,-89.35 71.3,-392.72 -149.56,-551.48 z"
style="fill:url(#linearGradient3480)"
inkscape:connector-curvature="0" />
<path
id="path5061"
d="M 786.05,506.92 C 654.91,629.65 611.62,974.36 634.83,1058.4 h -64.344 c -8.0609,-89.311 -5.2939,-392.68 215.56,-551.44 z"
style="fill:url(#linearGradient3482)"
inkscape:connector-curvature="0" />
<path
id="path5063"
d="m 558,390.92 c 1.1375,152.39 -25.576,521.17 -48.781,665.44 h 66.344 c 8.06,-153.43 25.3,-568 -17.56,-665.48 z"
style="fill:url(#linearGradient3484)"
inkscape:connector-curvature="0" />
</g>
</g>
<g
id="g5065"
transform="matrix(-0.31347,0,0,0.31347,563.63,725.86)">
<path
id="path5067"
d="m 175.92,665.27 c 13.029,87.769 15.361,304.13 3.6326,390.48 l 65.744,-8.8997 c -3.9927,-89.586 -19.294,-331.09 -69.377,-381.58 z"
style="fill:url(#linearGradient3486)"
inkscape:connector-curvature="0" />
<path
id="path5069"
d="m 222,564.92 c 11.137,129.2 -3.5755,367.02 -26.781,487.44 h 66.344 c 8.06,-128.08 3.3,-406.11 -39.56,-487.48 z"
style="fill:url(#linearGradient3488)"
inkscape:connector-curvature="0" />
</g>
<g
id="g5071"
transform="matrix(0.31347,0,0,0.31347,1543.6,725.85)">
<path
id="path5073"
transform="translate(-586,-293.73)"
d="m 761.91,959 c 6.6291,44.656 10.508,122.61 11.156,199.78 -3.5177,71.971 -9.3503,142.65 -16.25,183.25 l 9.7812,-0.8124 c -0.33219,2.8738 -0.67291,5.6427 -1.0312,8.2812 l 65.719,-8.9062 c -2.6347,-59.117 -10.178,-184.4 -29.406,-277.28 -5.5372,-47.264 -14.07,-86.309 -27.031,-104.16 0.42149,6.1627 0.76369,13.01 1.0312,20.344 -4.3264,-8.496 -8.9737,-15.464 -13.969,-20.5 z"
style="fill:url(#linearGradient3490)"
inkscape:connector-curvature="0" />
<path
id="path5075"
d="m 197.31,566.12 c 1.533,17.783 18.937,-18.566 27.028,-14.626 2.7723,1.3499 3.047,24.28 3.1212,32.869 1.2822,148.46 -13.32,369.83 -32.237,468 h 66.344 c 6.2183,-98.771 5.9931,-327.27 -14.108,-463.92 -3.1514,-21.423 -3.9869,-36.092 -10.971,-44.685 -17.332,-21.325 -34.563,31.126 -39.176,22.367 z"
style="fill:url(#linearGradient3492)"
inkscape:connector-curvature="0" />
</g>
<g
id="g5077"
transform="matrix(0.31347,0,0,0.31347,259.22,725.04)">
<g
id="g5079">
<path
id="path5081"
d="m 350,552.92 c 28.196,26.387 83.28,11.038 98.776,53.153 56.572,153.76 38.659,380.35 20.443,446.28 h 64.344 c 6.76,-74.95 52.34,-300.46 -63.47,-464.92 -22.26,-31.61 -84.48,-8.96 -120.09,-34.56 z"
style="fill:url(#linearGradient3494)"
inkscape:connector-curvature="0" />
<path
id="path5083"
d="m 790.05,568.92 c -30.352,28.405 -59.999,6.7027 -81.203,52.907 -70.41,153.42 -91.85,371.97 -74.015,436.53 h -64.344 c -6.5549,-72.625 -5.9498,-286.8 113.26,-449.65 27.389,-37.417 65.04,-10.126 106.3,-39.787 z"
style="fill:url(#linearGradient3496)"
inkscape:connector-curvature="0" />
<path
id="path5085"
d="m 620.52,337.5 c 0.20245,27.122 -46.477,57.098 -47.862,95.443 -1.4726,40.764 7.7345,72.465 5.614,120.12 -7.0921,159.38 -54.368,412 -69.053,503.3 h 66.344 c 6.3479,-120.8 37.904,-345.98 21.804,-508.31 -4.3448,-43.804 32.262,-189.84 23.154,-210.55 z"
style="fill:url(#linearGradient3498)"
inkscape:connector-curvature="0" />
</g>
</g>
<g
id="g5087"
transform="matrix(0.31347,0,0,0.31347,502.63,725.04)">
<g
id="g5089">
<path
id="path5091"
d="m 850,574.92 c 1.1375,109.33 -9.5755,373.93 -32.781,477.44 h 66.344 c 6.0072,-82.019 6.2224,-293.1 -10.776,-411.54 -1.1894,-8.2873 -8.4728,16.757 -9.8556,9.1906 -1.287,-7.0422 5.3398,-21.747 3.8764,-28.066 -4.64,-20.1 -10.2,-36.28 -16.8,-47.06 z"
style="fill:url(#linearGradient3500)"
inkscape:connector-curvature="0" />
<path
id="path5093"
d="m 720,556.92 c 19.657,18.396 20.183,26.15 32.297,51.826 4.6832,9.9265 7.8565,11.29 11.561,22.007 50.642,146.49 13.743,359.06 -4.6392,425.6 h 64.344 c 6.06,-67.2 32.58,-228.85 -20.92,-370.28 -17.65,-46.63 -43.99,-91.07 -82.64,-129.2 z"
style="fill:url(#linearGradient3502)"
inkscape:connector-curvature="0" />
<path
id="path5095"
d="M 1076,598.92 C 944.91,721.65 909.62,974.36 932.83,1058.4 h -64.344 c -6.5474,-72.542 -11.229,-225.61 105.59,-365.6 5.672,-6.7972 -0.3695,15.436 5.8891,8.7117 4.6165,-4.9604 21.396,-38.898 26.345,-43.809 20.284,-20.129 43.403,-39.806 69.737,-58.735 z"
style="fill:url(#linearGradient3504)"
inkscape:connector-curvature="0" />
</g>
</g>
<g
id="g5097"
transform="matrix(-0.31347,0,0,0.31347,1588.4,725.04)">
<g
id="g5099">
<path
id="path5101"
d="m 384,500.92 c 131.14,122.72 108.42,467.44 85.219,551.44 h 64.344 c 8.06,-89.35 71.3,-392.72 -149.56,-551.48 z"
style="fill:url(#linearGradient3506)"
inkscape:connector-curvature="0" />
<path
id="path5103"
d="M 786.05,506.92 C 654.91,629.65 611.62,974.36 634.83,1058.4 h -64.344 c -8.0609,-89.311 -5.2939,-392.68 215.56,-551.44 z"
style="fill:url(#linearGradient3508)"
inkscape:connector-curvature="0" />
<path
id="path5105"
d="m 558,390.92 c 1.1375,152.39 -25.576,521.17 -48.781,665.44 h 66.344 c 8.06,-153.43 25.3,-568 -17.56,-665.48 z"
style="fill:url(#linearGradient3510)"
inkscape:connector-curvature="0" />
</g>
</g>
<g
id="g5107"
transform="matrix(-0.31347,0,0,0.25318,1091.2,789.51)">
<path
id="path5109"
d="m 175.92,665.27 c 13.029,87.769 15.361,304.13 3.6326,390.48 l 65.744,-8.8997 c -3.9927,-89.586 -19.294,-331.09 -69.377,-381.58 z"
style="fill:url(#linearGradient3512)"
inkscape:connector-curvature="0" />
<path
id="path5111"
d="m 224,496.92 c 11.137,129.2 -5.5755,435.02 -28.781,555.44 h 66.344 c 8.06,-128.08 5.3,-474.11 -37.56,-555.48 z"
style="fill:url(#linearGradient3514)"
inkscape:connector-curvature="0" />
</g>
<g
id="g5113"
transform="matrix(-0.31347,0,0,0.31347,1315.7,724.13)">
<path
id="path5115"
d="m 73.919,749.55 c 10.401,70.065 12.262,242.78 2.8998,311.71 l 52.482,-7.1044 c -3.1873,-71.514 -15.402,-264.3 -55.382,-304.61 z"
style="fill:url(#linearGradient3669)"
inkscape:connector-curvature="0" />
<path
id="path5117"
d="m 94.301,630.16 c 1.2739,14.777 24.091,19.448 24.503,39.164 2.4588,117.89 -13.607,306.87 -29.478,389.23 h 52.961 c 5.5786,-88.61 13.68,-305 -6.5541,-403.34 -3.1057,-15.094 -36.879,-16.408 -41.431,-25.05 z"
style="fill:url(#linearGradient3671)"
inkscape:connector-curvature="0" />
</g>
<g
id="g5119"
transform="matrix(-0.31347,0,0,0.31347,1009.6,725.04)">
<g
id="g5121">
<path
id="path5123"
d="m 350,552.92 c 28.196,26.387 83.28,11.038 98.776,53.153 56.572,153.76 38.659,380.35 20.443,446.28 h 64.344 c 6.76,-74.95 52.34,-300.46 -63.47,-464.92 -22.26,-31.61 -84.48,-8.96 -120.09,-34.56 z"
style="fill:url(#linearGradient3639)"
inkscape:connector-curvature="0" />
<path
id="path5125"
d="m 790.05,568.92 c -30.352,28.405 -59.999,6.7027 -81.203,52.907 -70.41,153.42 -91.85,371.97 -74.015,436.53 h -64.344 c -6.5549,-72.625 -5.9498,-286.8 113.26,-449.65 27.389,-37.417 65.04,-10.126 106.3,-39.787 z"
style="fill:url(#linearGradient3635)"
inkscape:connector-curvature="0" />
<path
id="path5127"
d="m 595,394.92 c 0.20245,27.122 -46.477,57.098 -47.862,95.443 -1.4726,40.764 7.7345,72.465 5.614,120.12 -7.0921,159.38 -28.848,354.58 -43.533,445.88 h 66.344 c 6.35,-120.84 12.39,-288.6 -3.71,-450.92 -4.35,-43.81 32.26,-189.84 23.15,-210.56 z"
style="fill:url(#linearGradient3637)"
inkscape:connector-curvature="0" />
</g>
</g>
<g
id="g5129"
transform="matrix(-0.31347,0,0,0.31347,324.91,725.85)">
<path
id="path5131"
transform="translate(-586,-293.73)"
d="m 761.91,959 c 6.6291,44.656 10.508,122.61 11.156,199.78 -3.5177,71.971 -9.3503,142.65 -16.25,183.25 l 9.7812,-0.8124 c -0.33219,2.8738 -0.67291,5.6427 -1.0312,8.2812 l 65.719,-8.9062 c -2.6347,-59.117 -10.178,-184.4 -29.406,-277.28 -5.5372,-47.264 -14.07,-86.309 -27.031,-104.16 0.42149,6.1627 0.76369,13.01 1.0312,20.344 -4.3264,-8.496 -8.9737,-15.464 -13.969,-20.5 z"
style="fill:url(#linearGradient4738)"
inkscape:connector-curvature="0" />
<path
id="path5133"
d="m 197.31,566.12 c 1.533,17.783 18.937,-18.566 27.028,-14.626 2.7723,1.3499 3.047,24.28 3.1212,32.869 1.2822,148.46 -13.32,369.83 -32.237,468 h 66.344 c 6.2183,-98.771 5.9931,-327.27 -14.108,-463.92 -3.1514,-21.423 -3.9869,-36.092 -10.971,-44.685 -17.332,-21.325 -34.563,31.126 -39.176,22.367 z"
style="fill:url(#linearGradient3516)"
inkscape:connector-curvature="0" />
</g>
<g
id="g5135"
transform="matrix(-0.31347,0,0,0.31347,423.96,725.86)">
<path
id="path5137"
d="m 175.92,665.27 c 13.029,87.769 15.361,304.13 3.6326,390.48 l 65.744,-8.8997 c -3.9927,-89.586 -19.294,-331.09 -69.377,-381.58 z"
style="fill:url(#linearGradient3741)"
inkscape:connector-curvature="0" />
<path
id="path5139"
d="m 224,496.92 c 11.137,129.2 -5.5755,435.02 -28.781,555.44 h 66.344 c 8.06,-128.08 5.3,-474.11 -37.56,-555.48 z"
style="fill:url(#linearGradient3743)"
inkscape:connector-curvature="0" />
</g>
<g
id="g5141"
transform="matrix(-0.31347,0,0,0.31347,1261.4,725.04)">
<g
id="g5143">
<path
id="path5145"
d="m 850,574.92 c 1.1375,109.33 -9.5755,373.93 -32.781,477.44 h 66.344 c 6.0072,-82.019 6.2224,-293.1 -10.776,-411.54 -1.1894,-8.2873 -8.4728,16.757 -9.8556,9.1906 -1.287,-7.0422 5.3398,-21.747 3.8764,-28.066 -4.64,-20.1 -10.2,-36.28 -16.8,-47.06 z"
style="fill:url(#linearGradient3518)"
inkscape:connector-curvature="0" />
<path
id="path5147"
d="m 720,556.92 c 19.657,18.396 20.183,26.15 32.297,51.826 4.6832,9.9265 7.8565,11.29 11.561,22.007 50.642,146.49 13.743,359.06 -4.6392,425.6 h 64.344 c 6.06,-67.2 32.58,-228.85 -20.92,-370.28 -17.65,-46.63 -43.99,-91.07 -82.64,-129.2 z"
style="fill:url(#linearGradient3520)"
inkscape:connector-curvature="0" />
<path
id="path5149"
d="M 1076,598.92 C 944.91,721.65 909.62,974.36 932.83,1058.4 h -64.344 c -6.5474,-72.542 -11.229,-225.61 105.59,-365.6 5.672,-6.7972 -0.3695,15.436 5.8891,8.7117 4.6165,-4.9604 21.396,-38.898 26.345,-43.809 20.284,-20.129 43.403,-39.806 69.737,-58.735 z"
style="fill:url(#linearGradient3522)"
inkscape:connector-curvature="0" />
</g>
</g>
<g
id="g5151"
transform="matrix(-0.31347,0,0,0.31347,1849.4,725.04)">
<g
id="g5153">
<path
id="path5155"
d="m 850,574.92 c 1.1375,109.33 -9.5755,373.93 -32.781,477.44 h 66.344 c 8.06,-110.1 9.3,-407.54 -33.56,-477.48 z"
style="fill:url(#linearGradient4716)"
inkscape:connector-curvature="0" />
<path
id="path5157"
d="m 704,532.92 c 131.14,122.72 78.424,439.44 55.219,523.44 h 64.344 c 8.06,-89.35 101.3,-364.72 -119.56,-523.48 z"
style="fill:url(#linearGradient4718)"
inkscape:connector-curvature="0" />
<path
id="path5159"
d="M 1076,598.92 C 944.91,721.65 909.62,974.36 932.83,1058.4 h -64.344 c -8.07,-89.35 -13.3,-300.72 207.51,-459.48 z"
style="fill:url(#linearGradient4720)"
inkscape:connector-curvature="0" />
</g>
</g>
</g>
<path
id="path7904"
style="color:#000000;fill:#382509;fill-opacity:0.35931014;fill-rule:evenodd"
d="m 850.03,849.62496 c -12.982,0.10806 -26.682,1.11873 -37.875,6.98948 -10.079,-0.0474 -20.214,-0.83846 -30.188,0.81928 -8.125,1.03353 -16.464,3.06093 -22.656,7.68079 -1.2641,1.66249 -1.3941,3.31416 -0.8125,4.83885 -4.266,1.57327 -7.4121,3.39397 -9.0938,5.35091 -1.5348,-0.0368 -3.0796,-0.0387 -4.625,0.0256 -8.4752,0.12992 -17.318,0.8614 -24.875,4.19883 -5.4809,5.22974 5.0734,9.23415 10.625,9.26774 10.683,1.68846 21.676,1.50961 32.344,-0.10241 10.035,2.86979 24.296,4.68532 40.125,4.68532 8.9136,0 17.304,-0.57814 24.75,-1.58736 14.748,5.27553 31.715,4.59864 47.469,3.40511 7.573,-0.85566 15.501,-2.37183 21.406,-6.57984 3.1018,-5.34001 -4.6312,-8.92364 -10.031,-9.8822 -1.8048,-0.39465 -3.6114,-0.7399 -5.4375,-1.04967 2.1956,-1.69067 3.4375,-3.586 3.4375,-5.58137 0,-2.23058 -1.5447,-4.33442 -4.25,-6.17019 2.485,-0.85992 4.8848,-1.90303 7.125,-3.20029 4.0271,-6.68486 -7.0378,-10.32297 -13.438,-10.95792 -7.8256,-1.61317 -15.952,-2.09868 -24,-2.15062 z"
inkscape:connector-curvature="0" />
<path
id="path7971"
style="opacity:0.38776018;color:#000000;fill:url(#linearGradient7990);fill-rule:evenodd"
d="m 304.19,807.07135 c -31.679,0 -58.247,5.72409 -65.281,13.39038 -10.417,-1.78727 -22.486,-2.81629 -35.375,-2.81629 -39.19,0 -70.938,9.43569 -70.938,21.09656 0,6.08704 8.6498,11.5855 22.5,15.43859 -15,2.19568 -25.09,6.27571 -25.09,10.95383 0,0.81112 0.3276,1.61226 0.90625,2.381 69.732,-3.94543 135.62,-5.77292 198.12,-4.83886 11.001,-3.10164 17.719,-7.22731 17.719,-11.7772 0,-4.00286 -5.1954,-7.70914 -13.938,-10.65069 22.732,-2.78917 38.438,-8.78437 38.438,-15.74582 0,-9.62003 -30.01,-17.43518 -67.062,-17.43518 z"
inkscape:connector-curvature="0" />
<g
id="g8010"
transform="matrix(0.24173,0,0,0.19804551,125.66,726.93719)">
<path
id="path8012"
d="m 228.96,1225.2 c -6.3307,0.7144 -3.805,25.524 2.3841,47.52 -15.124,-11.252 -32.639,-20.037 -40.856,-18.502 -9.4064,1.7574 8.5513,22.457 28.081,37.871 -18.851,-0.2145 -38.186,2.9692 -43.932,9.0412 -6.5745,6.948 20.102,13.098 44.954,14.092 -15.376,10.907 -29.148,24.868 -30.227,33.157 -1.2354,9.4891 24.015,-1.2064 44.71,-15.018 -6.0295,17.863 -8.9911,37.244 -4.9917,44.585 4.5772,8.4015 18.683,-15.07 27.308,-38.403 5.6212,17.999 14.639,35.38 22.19,38.968 8.6413,4.1065 6.2763,-23.162 -0.46109,-47.108 15.124,11.252 32.639,20.038 40.856,18.502 9.4081,-1.7576 -8.5784,-22.453 -28.112,-37.868 18.861,0.2184 38.214,-2.9687 43.963,-9.0442 6.5745,-6.9479 -20.102,-13.098 -44.954,-14.092 15.376,-10.907 29.117,-24.865 30.196,-33.154 1.2354,-9.4891 -23.984,1.2034 -44.679,15.014 6.0295,-17.863 8.9911,-37.244 4.9917,-44.585 -4.5772,-8.4014 -18.683,15.07 -27.308,38.403 -5.6212,-17.999 -14.673,-35.408 -22.225,-38.997 -0.70379,-0.3344 -1.3277,-0.4475 -1.889,-0.3842 z"
inkscape:connector-curvature="0"
style="fill:#eeeeec" />
<path
id="path8014"
style="color:#000000;fill:#ffdd00;fill-rule:evenodd"
d="m 344.41,1001.6 a 54.205,33.500618 0 1 1 -108.41,0 54.205,33.500618 0 1 1 108.41,0 z"
transform="matrix(0.55723,0,0,0.8806,96.494,416.86)"
inkscape:connector-curvature="0" />
</g>
<g
id="g8016"
transform="matrix(0.17199,0,0,0.19431776,383.1,716.66337)">
<path
id="path8018"
d="m 228.96,1225.2 c -6.3307,0.7144 -3.805,25.524 2.3841,47.52 -15.124,-11.252 -32.639,-20.037 -40.856,-18.502 -9.4064,1.7574 8.5513,22.457 28.081,37.871 -18.851,-0.2145 -38.186,2.9692 -43.932,9.0412 -6.5745,6.948 20.102,13.098 44.954,14.092 -15.376,10.907 -29.148,24.868 -30.227,33.157 -1.2354,9.4891 24.015,-1.2064 44.71,-15.018 -6.0295,17.863 -8.9911,37.244 -4.9917,44.585 4.5772,8.4015 18.683,-15.07 27.308,-38.403 5.6212,17.999 14.639,35.38 22.19,38.968 8.6413,4.1065 6.2763,-23.162 -0.46109,-47.108 15.124,11.252 32.639,20.038 40.856,18.502 9.4081,-1.7576 -8.5784,-22.453 -28.112,-37.868 18.861,0.2184 38.214,-2.9687 43.963,-9.0442 6.5745,-6.9479 -20.102,-13.098 -44.954,-14.092 15.376,-10.907 29.117,-24.865 30.196,-33.154 1.2354,-9.4891 -23.984,1.2034 -44.679,15.014 6.0295,-17.863 8.9911,-37.244 4.9917,-44.585 -4.5772,-8.4014 -18.683,15.07 -27.308,38.403 -5.6212,-17.999 -14.673,-35.408 -22.225,-38.997 -0.70379,-0.3344 -1.3277,-0.4475 -1.889,-0.3842 z"
inkscape:connector-curvature="0"
style="fill:#eeeeec" />
<path
id="path8020"
style="color:#000000;fill:#ffdd00;fill-rule:evenodd"
d="m 344.41,1001.6 a 54.205,33.500618 0 1 1 -108.41,0 54.205,33.500618 0 1 1 108.41,0 z"
transform="matrix(0.55723,0,0,0.8806,96.494,416.86)"
inkscape:connector-curvature="0" />
</g>
<g
id="g8022"
transform="matrix(0.16009,-0.02627771,0.047488,0.19418668,657.85,723.97138)">
<path
id="path8024"
d="m 228.96,1225.2 c -6.3307,0.7144 -3.805,25.524 2.3841,47.52 -15.124,-11.252 -32.639,-20.037 -40.856,-18.502 -9.4064,1.7574 8.5513,22.457 28.081,37.871 -18.851,-0.2145 -38.186,2.9692 -43.932,9.0412 -6.5745,6.948 20.102,13.098 44.954,14.092 -15.376,10.907 -29.148,24.868 -30.227,33.157 -1.2354,9.4891 24.015,-1.2064 44.71,-15.018 -6.0295,17.863 -8.9911,37.244 -4.9917,44.585 4.5772,8.4015 18.683,-15.07 27.308,-38.403 5.6212,17.999 14.639,35.38 22.19,38.968 8.6413,4.1065 6.2763,-23.162 -0.46109,-47.108 15.124,11.252 32.639,20.038 40.856,18.502 9.4081,-1.7576 -8.5784,-22.453 -28.112,-37.868 18.861,0.2184 38.214,-2.9687 43.963,-9.0442 6.5745,-6.9479 -20.102,-13.098 -44.954,-14.092 15.376,-10.907 29.117,-24.865 30.196,-33.154 1.2354,-9.4891 -23.984,1.2034 -44.679,15.014 6.0295,-17.863 8.9911,-37.244 4.9917,-44.585 -4.5772,-8.4014 -18.683,15.07 -27.308,38.403 -5.6212,-17.999 -14.673,-35.408 -22.225,-38.997 -0.70379,-0.3344 -1.3277,-0.4475 -1.889,-0.3842 z"
inkscape:connector-curvature="0"
style="fill:#eeeeec" />
<path
id="path8026"
style="color:#000000;fill:#ffdd00;fill-rule:evenodd"
d="m 344.41,1001.6 a 54.205,33.500618 0 1 1 -108.41,0 54.205,33.500618 0 1 1 108.41,0 z"
transform="matrix(0.55723,0,0,0.8806,96.494,416.86)"
inkscape:connector-curvature="0" />
</g>
<g
id="g8028"
transform="matrix(0.11647,0,0,0.05474046,375.73,810.24198)">
<path
id="path8030"
d="m 228.96,1225.2 c -6.3307,0.7144 -3.805,25.524 2.3841,47.52 -15.124,-11.252 -32.639,-20.037 -40.856,-18.502 -9.4064,1.7574 8.5513,22.457 28.081,37.871 -18.851,-0.2145 -38.186,2.9692 -43.932,9.0412 -6.5745,6.948 20.102,13.098 44.954,14.092 -15.376,10.907 -29.148,24.868 -30.227,33.157 -1.2354,9.4891 24.015,-1.2064 44.71,-15.018 -6.0295,17.863 -8.9911,37.244 -4.9917,44.585 4.5772,8.4015 18.683,-15.07 27.308,-38.403 5.6212,17.999 14.639,35.38 22.19,38.968 8.6413,4.1065 6.2763,-23.162 -0.46109,-47.108 15.124,11.252 32.639,20.038 40.856,18.502 9.4081,-1.7576 -8.5784,-22.453 -28.112,-37.868 18.861,0.2184 38.214,-2.9687 43.963,-9.0442 6.5745,-6.9479 -20.102,-13.098 -44.954,-14.092 15.376,-10.907 29.117,-24.865 30.196,-33.154 1.2354,-9.4891 -23.984,1.2034 -44.679,15.014 6.0295,-17.863 8.9911,-37.244 4.9917,-44.585 -4.5772,-8.4014 -18.683,15.07 -27.308,38.403 -5.6212,-17.999 -14.673,-35.408 -22.225,-38.997 -0.70379,-0.3344 -1.3277,-0.4475 -1.889,-0.3842 z"
inkscape:connector-curvature="0"
style="fill:#eeeeec" />
<path
id="path8032"
style="color:#000000;fill:#ffdd00;fill-rule:evenodd"
d="m 344.41,1001.6 a 54.205,33.500618 0 1 1 -108.41,0 54.205,33.500618 0 1 1 108.41,0 z"
transform="matrix(0.55723,0,0,0.8806,96.494,416.86)"
inkscape:connector-curvature="0" />
</g>
<g
id="g8034"
transform="matrix(0.11647,0,0,0.05474046,211.73,828.26623)">
<path
id="path8036"
d="m 228.96,1225.2 c -6.3307,0.7144 -3.805,25.524 2.3841,47.52 -15.124,-11.252 -32.639,-20.037 -40.856,-18.502 -9.4064,1.7574 8.5513,22.457 28.081,37.871 -18.851,-0.2145 -38.186,2.9692 -43.932,9.0412 -6.5745,6.948 20.102,13.098 44.954,14.092 -15.376,10.907 -29.148,24.868 -30.227,33.157 -1.2354,9.4891 24.015,-1.2064 44.71,-15.018 -6.0295,17.863 -8.9911,37.244 -4.9917,44.585 4.5772,8.4015 18.683,-15.07 27.308,-38.403 5.6212,17.999 14.639,35.38 22.19,38.968 8.6413,4.1065 6.2763,-23.162 -0.46109,-47.108 15.124,11.252 32.639,20.038 40.856,18.502 9.4081,-1.7576 -8.5784,-22.453 -28.112,-37.868 18.861,0.2184 38.214,-2.9687 43.963,-9.0442 6.5745,-6.9479 -20.102,-13.098 -44.954,-14.092 15.376,-10.907 29.117,-24.865 30.196,-33.154 1.2354,-9.4891 -23.984,1.2034 -44.679,15.014 6.0295,-17.863 8.9911,-37.244 4.9917,-44.585 -4.5772,-8.4014 -18.683,15.07 -27.308,38.403 -5.6212,-17.999 -14.673,-35.408 -22.225,-38.997 -0.70379,-0.3344 -1.3277,-0.4475 -1.889,-0.3842 z"
inkscape:connector-curvature="0"
style="fill:#eeeeec" />
<path
id="path8038"
style="color:#000000;fill:#ffdd00;fill-rule:evenodd"
d="m 344.41,1001.6 a 54.205,33.500618 0 1 1 -108.41,0 54.205,33.500618 0 1 1 108.41,0 z"
transform="matrix(0.55723,0,0,0.8806,96.494,416.86)"
inkscape:connector-curvature="0" />
</g>
<g
id="g8040"
transform="matrix(0.097975,0,0,0.04604785,704.94,792.88955)">
<path
id="path8042"
d="m 228.96,1225.2 c -6.3307,0.7144 -3.805,25.524 2.3841,47.52 -15.124,-11.252 -32.639,-20.037 -40.856,-18.502 -9.4064,1.7574 8.5513,22.457 28.081,37.871 -18.851,-0.2145 -38.186,2.9692 -43.932,9.0412 -6.5745,6.948 20.102,13.098 44.954,14.092 -15.376,10.907 -29.148,24.868 -30.227,33.157 -1.2354,9.4891 24.015,-1.2064 44.71,-15.018 -6.0295,17.863 -8.9911,37.244 -4.9917,44.585 4.5772,8.4015 18.683,-15.07 27.308,-38.403 5.6212,17.999 14.639,35.38 22.19,38.968 8.6413,4.1065 6.2763,-23.162 -0.46109,-47.108 15.124,11.252 32.639,20.038 40.856,18.502 9.4081,-1.7576 -8.5784,-22.453 -28.112,-37.868 18.861,0.2184 38.214,-2.9687 43.963,-9.0442 6.5745,-6.9479 -20.102,-13.098 -44.954,-14.092 15.376,-10.907 29.117,-24.865 30.196,-33.154 1.2354,-9.4891 -23.984,1.2034 -44.679,15.014 6.0295,-17.863 8.9911,-37.244 4.9917,-44.585 -4.5772,-8.4014 -18.683,15.07 -27.308,38.403 -5.6212,-17.999 -14.673,-35.408 -22.225,-38.997 -0.70379,-0.3344 -1.3277,-0.4475 -1.889,-0.3842 z"
inkscape:connector-curvature="0"
style="fill:#eeeeec" />
<path
id="path8044"
style="color:#000000;fill:#ffdd00;fill-rule:evenodd"
d="m 344.41,1001.6 a 54.205,33.500618 0 1 1 -108.41,0 54.205,33.500618 0 1 1 108.41,0 z"
transform="matrix(0.55723,0,0,0.8806,96.494,416.86)"
inkscape:connector-curvature="0" />
</g>
<g
id="g8046"
transform="matrix(0.097975,0,0,0.04604785,755.94,846.96229)">
<path
id="path8048"
d="m 228.96,1225.2 c -6.3307,0.7144 -3.805,25.524 2.3841,47.52 -15.124,-11.252 -32.639,-20.037 -40.856,-18.502 -9.4064,1.7574 8.5513,22.457 28.081,37.871 -18.851,-0.2145 -38.186,2.9692 -43.932,9.0412 -6.5745,6.948 20.102,13.098 44.954,14.092 -15.376,10.907 -29.148,24.868 -30.227,33.157 -1.2354,9.4891 24.015,-1.2064 44.71,-15.018 -6.0295,17.863 -8.9911,37.244 -4.9917,44.585 4.5772,8.4015 18.683,-15.07 27.308,-38.403 5.6212,17.999 14.639,35.38 22.19,38.968 8.6413,4.1065 6.2763,-23.162 -0.46109,-47.108 15.124,11.252 32.639,20.038 40.856,18.502 9.4081,-1.7576 -8.5784,-22.453 -28.112,-37.868 18.861,0.2184 38.214,-2.9687 43.963,-9.0442 6.5745,-6.9479 -20.102,-13.098 -44.954,-14.092 15.376,-10.907 29.117,-24.865 30.196,-33.154 1.2354,-9.4891 -23.984,1.2034 -44.679,15.014 6.0295,-17.863 8.9911,-37.244 4.9917,-44.585 -4.5772,-8.4014 -18.683,15.07 -27.308,38.403 -5.6212,-17.999 -14.673,-35.408 -22.225,-38.997 -0.70379,-0.3344 -1.3277,-0.4475 -1.889,-0.3842 z"
inkscape:connector-curvature="0"
style="fill:#eeeeec" />
<path
id="path8050"
style="color:#000000;fill:#ffdd00;fill-rule:evenodd"
d="m 344.41,1001.6 a 54.205,33.500618 0 1 1 -108.41,0 54.205,33.500618 0 1 1 108.41,0 z"
transform="matrix(0.55723,0,0,0.8806,96.494,416.86)"
inkscape:connector-curvature="0" />
</g>
<g
id="g8052"
transform="matrix(0.075519,0,0,0.03549384,439.48,764.02617)">
<path
id="path8054"
d="m 228.96,1225.2 c -6.3307,0.7144 -3.805,25.524 2.3841,47.52 -15.124,-11.252 -32.639,-20.037 -40.856,-18.502 -9.4064,1.7574 8.5513,22.457 28.081,37.871 -18.851,-0.2145 -38.186,2.9692 -43.932,9.0412 -6.5745,6.948 20.102,13.098 44.954,14.092 -15.376,10.907 -29.148,24.868 -30.227,33.157 -1.2354,9.4891 24.015,-1.2064 44.71,-15.018 -6.0295,17.863 -8.9911,37.244 -4.9917,44.585 4.5772,8.4015 18.683,-15.07 27.308,-38.403 5.6212,17.999 14.639,35.38 22.19,38.968 8.6413,4.1065 6.2763,-23.162 -0.46109,-47.108 15.124,11.252 32.639,20.038 40.856,18.502 9.4081,-1.7576 -8.5784,-22.453 -28.112,-37.868 18.861,0.2184 38.214,-2.9687 43.963,-9.0442 6.5745,-6.9479 -20.102,-13.098 -44.954,-14.092 15.376,-10.907 29.117,-24.865 30.196,-33.154 1.2354,-9.4891 -23.984,1.2034 -44.679,15.014 6.0295,-17.863 8.9911,-37.244 4.9917,-44.585 -4.5772,-8.4014 -18.683,15.07 -27.308,38.403 -5.6212,-17.999 -14.673,-35.408 -22.225,-38.997 -0.70379,-0.3344 -1.3277,-0.4475 -1.889,-0.3842 z"
inkscape:connector-curvature="0"
style="fill:#eeeeec" />
<path
id="path8056"
style="color:#000000;fill:#ffdd00;fill-rule:evenodd"
d="m 344.41,1001.6 a 54.205,33.500618 0 1 1 -108.41,0 54.205,33.500618 0 1 1 108.41,0 z"
transform="matrix(0.55723,0,0,0.8806,96.494,416.86)"
inkscape:connector-curvature="0" />
</g>
<g
id="g8058"
transform="matrix(0.075519,0,0,0.03549384,199.48,739.44766)">
<path
id="path8060"
d="m 228.96,1225.2 c -6.3307,0.7144 -3.805,25.524 2.3841,47.52 -15.124,-11.252 -32.639,-20.037 -40.856,-18.502 -9.4064,1.7574 8.5513,22.457 28.081,37.871 -18.851,-0.2145 -38.186,2.9692 -43.932,9.0412 -6.5745,6.948 20.102,13.098 44.954,14.092 -15.376,10.907 -29.148,24.868 -30.227,33.157 -1.2354,9.4891 24.015,-1.2064 44.71,-15.018 -6.0295,17.863 -8.9911,37.244 -4.9917,44.585 4.5772,8.4015 18.683,-15.07 27.308,-38.403 5.6212,17.999 14.639,35.38 22.19,38.968 8.6413,4.1065 6.2763,-23.162 -0.46109,-47.108 15.124,11.252 32.639,20.038 40.856,18.502 9.4081,-1.7576 -8.5784,-22.453 -28.112,-37.868 18.861,0.2184 38.214,-2.9687 43.963,-9.0442 6.5745,-6.9479 -20.102,-13.098 -44.954,-14.092 15.376,-10.907 29.117,-24.865 30.196,-33.154 1.2354,-9.4891 -23.984,1.2034 -44.679,15.014 6.0295,-17.863 8.9911,-37.244 4.9917,-44.585 -4.5772,-8.4014 -18.683,15.07 -27.308,38.403 -5.6212,-17.999 -14.673,-35.408 -22.225,-38.997 -0.70379,-0.3344 -1.3277,-0.4475 -1.889,-0.3842 z"
inkscape:connector-curvature="0"
style="fill:#eeeeec" />
<path
id="path8062"
style="color:#000000;fill:#ffdd00;fill-rule:evenodd"
d="m 344.41,1001.6 a 54.205,33.500618 0 1 1 -108.41,0 54.205,33.500618 0 1 1 108.41,0 z"
transform="matrix(0.55723,0,0,0.8806,96.494,416.86)"
inkscape:connector-curvature="0" />
</g>
<g
id="g8064"
transform="matrix(0.075519,0,0,0.03549384,409.48,803.3518)">
<path
id="path8066"
d="m 228.96,1225.2 c -6.3307,0.7144 -3.805,25.524 2.3841,47.52 -15.124,-11.252 -32.639,-20.037 -40.856,-18.502 -9.4064,1.7574 8.5513,22.457 28.081,37.871 -18.851,-0.2145 -38.186,2.9692 -43.932,9.0412 -6.5745,6.948 20.102,13.098 44.954,14.092 -15.376,10.907 -29.148,24.868 -30.227,33.157 -1.2354,9.4891 24.015,-1.2064 44.71,-15.018 -6.0295,17.863 -8.9911,37.244 -4.9917,44.585 4.5772,8.4015 18.683,-15.07 27.308,-38.403 5.6212,17.999 14.639,35.38 22.19,38.968 8.6413,4.1065 6.2763,-23.162 -0.46109,-47.108 15.124,11.252 32.639,20.038 40.856,18.502 9.4081,-1.7576 -8.5784,-22.453 -28.112,-37.868 18.861,0.2184 38.214,-2.9687 43.963,-9.0442 6.5745,-6.9479 -20.102,-13.098 -44.954,-14.092 15.376,-10.907 29.117,-24.865 30.196,-33.154 1.2354,-9.4891 -23.984,1.2034 -44.679,15.014 6.0295,-17.863 8.9911,-37.244 4.9917,-44.585 -4.5772,-8.4014 -18.683,15.07 -27.308,38.403 -5.6212,-17.999 -14.673,-35.408 -22.225,-38.997 -0.70379,-0.3344 -1.3277,-0.4475 -1.889,-0.3842 z"
inkscape:connector-curvature="0"
style="fill:#eeeeec" />
<path
id="path8068"
style="color:#000000;fill:#ffdd00;fill-rule:evenodd"
d="m 344.41,1001.6 a 54.205,33.500618 0 1 1 -108.41,0 54.205,33.500618 0 1 1 108.41,0 z"
transform="matrix(0.55723,0,0,0.8806,96.494,416.86)"
inkscape:connector-curvature="0" />
</g>
<g
id="g8070"
transform="matrix(0.075519,0,0,0.03549384,469.48,786.96612)">
<path
id="path8072"
d="m 228.96,1225.2 c -6.3307,0.7144 -3.805,25.524 2.3841,47.52 -15.124,-11.252 -32.639,-20.037 -40.856,-18.502 -9.4064,1.7574 8.5513,22.457 28.081,37.871 -18.851,-0.2145 -38.186,2.9692 -43.932,9.0412 -6.5745,6.948 20.102,13.098 44.954,14.092 -15.376,10.907 -29.148,24.868 -30.227,33.157 -1.2354,9.4891 24.015,-1.2064 44.71,-15.018 -6.0295,17.863 -8.9911,37.244 -4.9917,44.585 4.5772,8.4015 18.683,-15.07 27.308,-38.403 5.6212,17.999 14.639,35.38 22.19,38.968 8.6413,4.1065 6.2763,-23.162 -0.46109,-47.108 15.124,11.252 32.639,20.038 40.856,18.502 9.4081,-1.7576 -8.5784,-22.453 -28.112,-37.868 18.861,0.2184 38.214,-2.9687 43.963,-9.0442 6.5745,-6.9479 -20.102,-13.098 -44.954,-14.092 15.376,-10.907 29.117,-24.865 30.196,-33.154 1.2354,-9.4891 -23.984,1.2034 -44.679,15.014 6.0295,-17.863 8.9911,-37.244 4.9917,-44.585 -4.5772,-8.4014 -18.683,15.07 -27.308,38.403 -5.6212,-17.999 -14.673,-35.408 -22.225,-38.997 -0.70379,-0.3344 -1.3277,-0.4475 -1.889,-0.3842 z"
inkscape:connector-curvature="0"
style="fill:#eeeeec" />
<path
id="path8074"
style="color:#000000;fill:#ffdd00;fill-rule:evenodd"
d="m 344.41,1001.6 a 54.205,33.500618 0 1 1 -108.41,0 54.205,33.500618 0 1 1 108.41,0 z"
transform="matrix(0.55723,0,0,0.8806,96.494,416.86)"
inkscape:connector-curvature="0" />
</g>
<g
id="g8076"
transform="matrix(0.075519,0,0,0.03549384,329.48,786.96612)">
<path
id="path8078"
d="m 228.96,1225.2 c -6.3307,0.7144 -3.805,25.524 2.3841,47.52 -15.124,-11.252 -32.639,-20.037 -40.856,-18.502 -9.4064,1.7574 8.5513,22.457 28.081,37.871 -18.851,-0.2145 -38.186,2.9692 -43.932,9.0412 -6.5745,6.948 20.102,13.098 44.954,14.092 -15.376,10.907 -29.148,24.868 -30.227,33.157 -1.2354,9.4891 24.015,-1.2064 44.71,-15.018 -6.0295,17.863 -8.9911,37.244 -4.9917,44.585 4.5772,8.4015 18.683,-15.07 27.308,-38.403 5.6212,17.999 14.639,35.38 22.19,38.968 8.6413,4.1065 6.2763,-23.162 -0.46109,-47.108 15.124,11.252 32.639,20.038 40.856,18.502 9.4081,-1.7576 -8.5784,-22.453 -28.112,-37.868 18.861,0.2184 38.214,-2.9687 43.963,-9.0442 6.5745,-6.9479 -20.102,-13.098 -44.954,-14.092 15.376,-10.907 29.117,-24.865 30.196,-33.154 1.2354,-9.4891 -23.984,1.2034 -44.679,15.014 6.0295,-17.863 8.9911,-37.244 4.9917,-44.585 -4.5772,-8.4014 -18.683,15.07 -27.308,38.403 -5.6212,-17.999 -14.673,-35.408 -22.225,-38.997 -0.70379,-0.3344 -1.3277,-0.4475 -1.889,-0.3842 z"
inkscape:connector-curvature="0"
style="fill:#eeeeec" />
<path
id="path8080"
style="color:#000000;fill:#ffdd00;fill-rule:evenodd"
d="m 344.41,1001.6 a 54.205,33.500618 0 1 1 -108.41,0 54.205,33.500618 0 1 1 108.41,0 z"
transform="matrix(0.55723,0,0,0.8806,96.494,416.86)"
inkscape:connector-curvature="0" />
</g>
<g
id="g8082"
transform="matrix(0.075519,0,0,0.03549384,107.48,803.3518)">
<path
id="path8084"
d="m 228.96,1225.2 c -6.3307,0.7144 -3.805,25.524 2.3841,47.52 -15.124,-11.252 -32.639,-20.037 -40.856,-18.502 -9.4064,1.7574 8.5513,22.457 28.081,37.871 -18.851,-0.2145 -38.186,2.9692 -43.932,9.0412 -6.5745,6.948 20.102,13.098 44.954,14.092 -15.376,10.907 -29.148,24.868 -30.227,33.157 -1.2354,9.4891 24.015,-1.2064 44.71,-15.018 -6.0295,17.863 -8.9911,37.244 -4.9917,44.585 4.5772,8.4015 18.683,-15.07 27.308,-38.403 5.6212,17.999 14.639,35.38 22.19,38.968 8.6413,4.1065 6.2763,-23.162 -0.46109,-47.108 15.124,11.252 32.639,20.038 40.856,18.502 9.4081,-1.7576 -8.5784,-22.453 -28.112,-37.868 18.861,0.2184 38.214,-2.9687 43.963,-9.0442 6.5745,-6.9479 -20.102,-13.098 -44.954,-14.092 15.376,-10.907 29.117,-24.865 30.196,-33.154 1.2354,-9.4891 -23.984,1.2034 -44.679,15.014 6.0295,-17.863 8.9911,-37.244 4.9917,-44.585 -4.5772,-8.4014 -18.683,15.07 -27.308,38.403 -5.6212,-17.999 -14.673,-35.408 -22.225,-38.997 -0.70379,-0.3344 -1.3277,-0.4475 -1.889,-0.3842 z"
inkscape:connector-curvature="0"
style="fill:#eeeeec" />
<path
id="path8086"
style="color:#000000;fill:#ffdd00;fill-rule:evenodd"
d="m 344.41,1001.6 a 54.205,33.500618 0 1 1 -108.41,0 54.205,33.500618 0 1 1 108.41,0 z"
transform="matrix(0.55723,0,0,0.8806,96.494,416.86)"
inkscape:connector-curvature="0" />
</g>
<g
id="g8088"
transform="matrix(0.075519,0,0,0.03549384,87.479,770.58045)">
<path
id="path8090"
d="m 228.96,1225.2 c -6.3307,0.7144 -3.805,25.524 2.3841,47.52 -15.124,-11.252 -32.639,-20.037 -40.856,-18.502 -9.4064,1.7574 8.5513,22.457 28.081,37.871 -18.851,-0.2145 -38.186,2.9692 -43.932,9.0412 -6.5745,6.948 20.102,13.098 44.954,14.092 -15.376,10.907 -29.148,24.868 -30.227,33.157 -1.2354,9.4891 24.015,-1.2064 44.71,-15.018 -6.0295,17.863 -8.9911,37.244 -4.9917,44.585 4.5772,8.4015 18.683,-15.07 27.308,-38.403 5.6212,17.999 14.639,35.38 22.19,38.968 8.6413,4.1065 6.2763,-23.162 -0.46109,-47.108 15.124,11.252 32.639,20.038 40.856,18.502 9.4081,-1.7576 -8.5784,-22.453 -28.112,-37.868 18.861,0.2184 38.214,-2.9687 43.963,-9.0442 6.5745,-6.9479 -20.102,-13.098 -44.954,-14.092 15.376,-10.907 29.117,-24.865 30.196,-33.154 1.2354,-9.4891 -23.984,1.2034 -44.679,15.014 6.0295,-17.863 8.9911,-37.244 4.9917,-44.585 -4.5772,-8.4014 -18.683,15.07 -27.308,38.403 -5.6212,-17.999 -14.673,-35.408 -22.225,-38.997 -0.70379,-0.3344 -1.3277,-0.4475 -1.889,-0.3842 z"
inkscape:connector-curvature="0"
style="fill:#eeeeec" />
<path
id="path8092"
style="color:#000000;fill:#ffdd00;fill-rule:evenodd"
d="m 344.41,1001.6 a 54.205,33.500618 0 1 1 -108.41,0 54.205,33.500618 0 1 1 108.41,0 z"
transform="matrix(0.55723,0,0,0.8806,96.494,416.86)"
inkscape:connector-curvature="0" />
</g>
<g
id="g8094"
transform="matrix(0.075519,0,0,0.03549384,667.48,770.58045)">
<path
id="path8096"
d="m 228.96,1225.2 c -6.3307,0.7144 -3.805,25.524 2.3841,47.52 -15.124,-11.252 -32.639,-20.037 -40.856,-18.502 -9.4064,1.7574 8.5513,22.457 28.081,37.871 -18.851,-0.2145 -38.186,2.9692 -43.932,9.0412 -6.5745,6.948 20.102,13.098 44.954,14.092 -15.376,10.907 -29.148,24.868 -30.227,33.157 -1.2354,9.4891 24.015,-1.2064 44.71,-15.018 -6.0295,17.863 -8.9911,37.244 -4.9917,44.585 4.5772,8.4015 18.683,-15.07 27.308,-38.403 5.6212,17.999 14.639,35.38 22.19,38.968 8.6413,4.1065 6.2763,-23.162 -0.46109,-47.108 15.124,11.252 32.639,20.038 40.856,18.502 9.4081,-1.7576 -8.5784,-22.453 -28.112,-37.868 18.861,0.2184 38.214,-2.9687 43.963,-9.0442 6.5745,-6.9479 -20.102,-13.098 -44.954,-14.092 15.376,-10.907 29.117,-24.865 30.196,-33.154 1.2354,-9.4891 -23.984,1.2034 -44.679,15.014 6.0295,-17.863 8.9911,-37.244 4.9917,-44.585 -4.5772,-8.4014 -18.683,15.07 -27.308,38.403 -5.6212,-17.999 -14.673,-35.408 -22.225,-38.997 -0.70379,-0.3344 -1.3277,-0.4475 -1.889,-0.3842 z"
inkscape:connector-curvature="0"
style="fill:#eeeeec" />
<path
id="path8098"
style="color:#000000;fill:#ffdd00;fill-rule:evenodd"
d="m 344.41,1001.6 a 54.205,33.500618 0 1 1 -108.41,0 54.205,33.500618 0 1 1 108.41,0 z"
transform="matrix(0.55723,0,0,0.8806,96.494,416.86)"
inkscape:connector-curvature="0" />
</g>
<g
id="g8100"
transform="matrix(0.075519,0,0,0.02493982,727.48,750.73739)">
<path
id="path8102"
d="m 228.96,1225.2 c -6.3307,0.7144 -3.805,25.524 2.3841,47.52 -15.124,-11.252 -32.639,-20.037 -40.856,-18.502 -9.4064,1.7574 8.5513,22.457 28.081,37.871 -18.851,-0.2145 -38.186,2.9692 -43.932,9.0412 -6.5745,6.948 20.102,13.098 44.954,14.092 -15.376,10.907 -29.148,24.868 -30.227,33.157 -1.2354,9.4891 24.015,-1.2064 44.71,-15.018 -6.0295,17.863 -8.9911,37.244 -4.9917,44.585 4.5772,8.4015 18.683,-15.07 27.308,-38.403 5.6212,17.999 14.639,35.38 22.19,38.968 8.6413,4.1065 6.2763,-23.162 -0.46109,-47.108 15.124,11.252 32.639,20.038 40.856,18.502 9.4081,-1.7576 -8.5784,-22.453 -28.112,-37.868 18.861,0.2184 38.214,-2.9687 43.963,-9.0442 6.5745,-6.9479 -20.102,-13.098 -44.954,-14.092 15.376,-10.907 29.117,-24.865 30.196,-33.154 1.2354,-9.4891 -23.984,1.2034 -44.679,15.014 6.0295,-17.863 8.9911,-37.244 4.9917,-44.585 -4.5772,-8.4014 -18.683,15.07 -27.308,38.403 -5.6212,-17.999 -14.673,-35.408 -22.225,-38.997 -0.70379,-0.3344 -1.3277,-0.4475 -1.889,-0.3842 z"
inkscape:connector-curvature="0"
style="fill:#eeeeec" />
<path
id="path8104"
style="color:#000000;fill:#ffdd00;fill-rule:evenodd"
d="m 344.41,1001.6 a 54.205,33.500618 0 1 1 -108.41,0 54.205,33.500618 0 1 1 108.41,0 z"
transform="matrix(0.55723,0,0,0.8806,96.494,416.86)"
inkscape:connector-curvature="0" />
</g>
<g
id="g3865"
transform="matrix(0.15725,0.05706476,-0.096054,0.17766992,707.09,749.29545)">
<path
id="path3867"
d="m 228.96,1225.2 c -6.3307,0.7144 -3.805,25.524 2.3841,47.52 -15.124,-11.252 -32.639,-20.037 -40.856,-18.502 -9.4064,1.7574 8.5513,22.457 28.081,37.871 -18.851,-0.2145 -38.186,2.9692 -43.932,9.0412 -6.5745,6.948 20.102,13.098 44.954,14.092 -15.376,10.907 -29.148,24.868 -30.227,33.157 -1.2354,9.4891 24.015,-1.2064 44.71,-15.018 -6.0295,17.863 -8.9911,37.244 -4.9917,44.585 4.5772,8.4015 18.683,-15.07 27.308,-38.403 5.6212,17.999 14.639,35.38 22.19,38.968 8.6413,4.1065 6.2763,-23.162 -0.46109,-47.108 15.124,11.252 32.639,20.038 40.856,18.502 9.4081,-1.7576 -8.5784,-22.453 -28.112,-37.868 18.861,0.2184 38.214,-2.9687 43.963,-9.0442 6.5745,-6.9479 -20.102,-13.098 -44.954,-14.092 15.376,-10.907 29.117,-24.865 30.196,-33.154 1.2354,-9.4891 -23.984,1.2034 -44.679,15.014 6.0295,-17.863 8.9911,-37.244 4.9917,-44.585 -4.5772,-8.4014 -18.683,15.07 -27.308,38.403 -5.6212,-17.999 -14.673,-35.408 -22.225,-38.997 -0.70379,-0.3344 -1.3277,-0.4475 -1.889,-0.3842 z"
inkscape:connector-curvature="0"
style="fill:#eeeeec" />
<path
id="path3869"
style="color:#000000;fill:#ffdd00;fill-rule:evenodd"
d="m 344.41,1001.6 a 54.205,33.500618 0 1 1 -108.41,0 54.205,33.500618 0 1 1 108.41,0 z"
transform="matrix(0.55723,0,0,0.8806,96.494,416.86)"
inkscape:connector-curvature="0" />
</g>
<g
id="g3871"
transform="matrix(0.12715,0.04614207,-0.077669,0.14366144,231.18,743.0607)"
style="fill:#304e15">
<path
id="path3873"
d="m 228.96,1225.2 c -6.3307,0.7144 -3.805,25.524 2.3841,47.52 -15.124,-11.252 -32.639,-20.037 -40.856,-18.502 -9.4064,1.7574 8.5513,22.457 28.081,37.871 -18.851,-0.2145 -38.186,2.9692 -43.932,9.0412 -6.5745,6.948 20.102,13.098 44.954,14.092 -15.376,10.907 -29.148,24.868 -30.227,33.157 -1.2354,9.4891 24.015,-1.2064 44.71,-15.018 -6.0295,17.863 -8.9911,37.244 -4.9917,44.585 4.5772,8.4015 18.683,-15.07 27.308,-38.403 5.6212,17.999 14.639,35.38 22.19,38.968 8.6413,4.1065 6.2763,-23.162 -0.46109,-47.108 15.124,11.252 32.639,20.038 40.856,18.502 9.4081,-1.7576 -8.5784,-22.453 -28.112,-37.868 18.861,0.2184 38.214,-2.9687 43.963,-9.0442 6.5745,-6.9479 -20.102,-13.098 -44.954,-14.092 15.376,-10.907 29.117,-24.865 30.196,-33.154 1.2354,-9.4891 -23.984,1.2034 -44.679,15.014 6.0295,-17.863 8.9911,-37.244 4.9917,-44.585 -4.5772,-8.4014 -18.683,15.07 -27.308,38.403 -5.6212,-17.999 -14.673,-35.408 -22.225,-38.997 -0.70379,-0.3344 -1.3277,-0.4475 -1.889,-0.3842 z"
inkscape:connector-curvature="0" />
<path
id="path3875"
style="color:#000000;fill-rule:evenodd"
transform="matrix(0.55723,0,0,0.8806,96.494,416.86)"
d="m 344.41,1001.6 a 54.205,33.500618 0 1 1 -108.41,0 54.205,33.500618 0 1 1 108.41,0 z"
inkscape:connector-curvature="0" />
</g>
<path
id="path3877"
style="color:#000000;fill:#f6fbfc;fill-rule:evenodd"
d="m 260.22,640.6584 a 57.276,35.918227 0 1 1 -114.55,0 57.276,35.918227 0 1 1 114.55,0 z"
inkscape:connector-curvature="0" />
<path
id="path3879"
style="color:#000000;fill:#f6fbfc;fill-rule:evenodd"
d="m 352.14,655.72503 a 65.055,32.442504 0 0 1 -130.11,0 65.055,32.442504 0 1 1 130.11,0 z"
inkscape:connector-curvature="0" />
<path
id="path3881"
style="color:#000000;fill:#f6fbfc;fill-rule:evenodd"
d="m 438.41,634.86606 a 111.02,38.235162 0 1 1 -222.03,0 111.02,38.235162 0 1 1 222.03,0 z"
inkscape:connector-curvature="0" />
<path
id="path3883"
style="color:#000000;fill:#f6fbfc;fill-rule:evenodd"
d="m 316.78,603.5858 a 55.155,25.490843 0 0 1 -110.31,0 55.155,25.490843 0 1 1 110.31,0 z"
inkscape:connector-curvature="0" />
<path
id="path3885"
style="color:#000000;fill:#f6fbfc;fill-rule:evenodd"
d="m 384.67,611.69671 a 36.0625,22.014465 0 0 1 -72.125,0 36.0625,22.014465 0 1 1 72.125,0 z"
inkscape:connector-curvature="0" />
<path
id="path4659"
style="color:#000000;fill:url(#linearGradient4676);fill-rule:evenodd"
d="m 262.37,595.47489 c -26.198,0 -47.437,8.87776 -47.437,19.84306 0,0.32293 0.0173,0.65803 0.0538,0.97716 -1.026,-0.0362 -2.0487,-0.0598 -3.0908,-0.0598 -27.206,0 -49.265,12.52767 -49.265,27.98018 0,15.4517 22.059,27.95971 49.265,27.95971 8.7122,0 16.9,-1.27604 24.001,-3.52989 9.6963,7.51382 27.734,12.56372 48.378,12.56372 20.131,0 37.77,-4.7992 47.625,-12.00579 46.59,-1.97578 82.511,-14.44069 82.511,-29.51552 0,-11.30202 -20.175,-21.13916 -49.91,-26.18513 -5.2387,-5.37016 -15.524,-9.01376 -27.333,-9.01376 -8.9584,0 -17.022,2.10637 -22.684,5.46429 -2.1294,0.0306 -4.2521,0.0862 -6.3429,0.15954 -5.48,-8.43043 -23.89,-14.63241 -45.77,-14.63241 z"
inkscape:connector-curvature="0" />
<path
id="path4684"
style="color:#000000;fill:#f6fbfc;fill-rule:evenodd"
d="m 880.87,573.0347 c -16.668,0 -31.189,6.95884 -38.728,17.24101 -1.3695,-0.12629 -2.7742,-0.18873 -4.2007,-0.18873 -14.05,0 -25.697,6.34798 -27.833,14.65454 -16.42,2.58074 -28.11,9.20055 -28.11,16.96737 0,8.89824 15.358,16.28818 35.598,17.8186 0.64745,9.25955 12.993,16.6413 28.145,16.6413 10.116,0 18.986,-3.29369 23.958,-8.2379 8.1395,3.75666 19.648,6.10596 32.413,6.10596 15.216,0 28.644,-3.33162 36.709,-8.41487 6.8224,2.1779 14.902,3.44157 23.565,3.44157 24.427,0 44.229,-10.02066 44.229,-22.3812 0,-12.36054 -19.802,-22.3812 -44.229,-22.3812 -3.2801,0 -6.4766,0.17902 -9.5532,0.52179 -0.15186,-10.50731 -12.894,-18.99509 -28.605,-18.99509 -2.7073,0 -5.3228,0.26182 -7.8052,0.73271 -8.0585,-8.20594 -20.988,-13.52228 -35.557,-13.52228 z"
inkscape:connector-curvature="0" />
<path
id="path4701"
style="color:#000000;fill:url(#linearGradient4709);fill-rule:evenodd"
d="m 886.16,586.0777 c -14.053,0 -26.295,5.86698 -32.651,14.53574 -1.1546,-0.10648 -2.339,-0.15912 -3.5416,-0.15912 -11.846,0 -21.665,5.35189 -23.466,12.3548 -13.842,2.17536 -23.694,7.75796 -23.694,14.30224 0,7.50185 12.948,13.73284 30.012,15.02239 0.54587,7.80663 10.954,14.03024 23.729,14.03024 8.5292,0 16.007,-2.77688 20.199,-6.94507 6.8624,3.16718 16.565,5.14797 27.327,5.14797 12.828,0 24.15,-2.80892 30.949,-7.09484 5.752,1.83618 12.564,2.90158 19.867,2.90158 20.594,0 37.29,-8.44846 37.29,-18.86975 0,-10.42129 -16.695,-18.86975 -37.29,-18.86975 -2.7655,0 -5.4604,0.15093 -8.0543,0.43993 -0.13,-8.85646 -10.88,-16.01701 -24.12,-16.01701 -2.2825,0 -4.4876,0.22074 -6.5805,0.61775 -6.7941,-6.91819 -17.695,-11.40033 -29.978,-11.40033 z"
inkscape:connector-curvature="0" />
</g>
<metadata
id="metadata315">
<rdf:RDF>
<cc:Work>
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<cc:license
- rdf:resource="http://www.gnu.org/licenses/gpl-3.0.en.html" />
+ rdf:resource="https://www.gnu.org/licenses/gpl-3.0.en.html" />
<dc:publisher>
<cc:Agent
rdf:about="http://gcompris.net/">
<dc:title>GCompris</dc:title>
</cc:Agent>
</dc:publisher>
<dc:title />
<dc:date>2010-12-03T20:18:24</dc:date>
<dc:description>clip art, clipart, cloud, grass, hill, landscape, </dc:description>
<dc:source>http://openclipart.org/detail/99229/landscape-by-rg1024</dc:source>
<dc:creator>
<cc:Agent>
<dc:title>rg1024</dc:title>
</cc:Agent>
</dc:creator>
<dc:subject>
<rdf:Bag>
<rdf:li>clip art</rdf:li>
<rdf:li>clipart</rdf:li>
<rdf:li>cloud</rdf:li>
<rdf:li>grass</rdf:li>
<rdf:li>hill</rdf:li>
<rdf:li>landscape</rdf:li>
</rdf:Bag>
</dc:subject>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/publicdomain/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
</cc:License>
</rdf:RDF>
</metadata>
<g
id="g4444"
transform="matrix(1.6159315,0,0,1.6159315,21.356709,171.59724)">
<path
sodipodi:nodetypes="csccccccc"
id="path610"
d="m 387.64861,221.38149 c -28.5011,-17.2502 -130.3129,-85.979 -157.5342,-73.0095 l -32.0397,15.2652 c -25.6023,10.1264 33.0943,80.8154 61.5953,98.0654 l 91.0352,55.8847 c 28.5008,17.2503 110.4344,63.3165 159.4224,43.1677 l 22.099,-13.4899 c 27.2727,-16.808 -6.8409,-55.3106 -35.3419,-72.5608 l -109.2361,-53.3228 z"
style="font-size:12px;fill:#ffc400;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.61883813;stroke-opacity:1"
inkscape:connector-curvature="0" />
<path
sodipodi:nodetypes="ccccc"
id="path613"
d="m 253.63481,32.001488 -30.5817,145.020102 26.3397,-12.7276 18.5965,-140.503412 -14.3545,8.21091 z"
style="font-size:12px;fill:#ffc400;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.61883813;stroke-opacity:1"
inkscape:connector-curvature="0" />
<path
sodipodi:nodetypes="cccccccccc"
id="path607"
d="m 321.04251,131.34929 c -14.2551,14.091 -37.9936,59.9089 -74.273,33.5221 -69.6144,35.5625 -222.073829,113.8916 -216.334919,131.4875 l 11.60392,12.1132 c 11.4778,35.1921 233.102299,5.0447 284.998499,-3.0924 33,-27.4364 99.7137,-74.878 128.7045,-50.695 23.5174,-6.5192 88.0545,-42.2441 83.2584,-79.1065 l -13.0005,-36.9615 c -16.4891,-35.1919 -49.0494,-54.283102 -84.2414,-42.805302 l -120.7155,35.537902 z"
style="font-size:12px;fill:#ffc400;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.61883813;stroke-opacity:1"
inkscape:connector-curvature="0" />
<path
sodipodi:nodetypes="ccccc"
id="path612"
d="m 522.17601,213.76399 -65.0699,131.0471 c 12.4802,-11.861 30.5854,-20.5972 37.4407,-22.4582 l 47.8764,-114.3427 -20.2472,5.7538 z"
style="font-size:12px;fill:#ffc400;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.61883813;stroke-opacity:1"
inkscape:connector-curvature="0" />
<path
sodipodi:nodetypes="cccccccc"
id="path615"
d="m 21.701861,183.71679 c -14.2898101,11.4396 -16.6266101,32.8465 -20.2208201,55.4884 -3.78548,30.4199 1.96229,78.5226 42.6874701,80.7481 16.6788,2.623 54.7788,6.8719 23.0589,-42.5638 25.1848,-9.044 79.861699,-28.946 74.977099,-39.4318 l -57.130699,-42.8179 c -14.7803,-15.9602 -37.8578,-23.3082 -58.82925,-13.5391 l -4.5427,2.1161 z"
style="font-size:12px;fill:#ffc400;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.61883813;stroke-opacity:1"
inkscape:connector-curvature="0" />
<path
sodipodi:nodetypes="ccccc"
id="path616"
d="m 133.40481,379.65109 c -35.115599,3.275 -73.571999,-26.8582 -75.279199,-60.3323 2.6611,-26.1606 83.024199,-60.0081 92.627999,-38.9603 l 8.4363,52.0354 c 2.626,24.0205 2.8897,42.1353 -25.7851,47.2572 z"
style="font-size:12px;fill:#ffc400;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.61883813;stroke-opacity:1"
inkscape:connector-curvature="0" />
<path
sodipodi:nodetypes="ccccc"
id="path619"
d="m 319.73891,136.87159 c 20.5516,4.0358 20.7814,33.3664 -14.0379,50.7624 -23.413,5.0112 -59.747,-1.8946 -59.747,-22.652 33.7471,15.1495 35.7782,2.7257 42.4522,0.954 22.3505,-18.7973 27.1986,-35.0572 31.3327,-29.0644 z"
style="font-size:12px;fill:#333332;fill-opacity:1;fill-rule:evenodd;stroke-width:1"
inkscape:connector-curvature="0" />
<path
sodipodi:nodetypes="cc"
id="path620"
d="m 78.524411,294.54059 75.371399,73.701"
style="fill:none;stroke:#000000;stroke-width:0.61883817pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0" />
<path
sodipodi:nodetypes="ccc"
id="path621"
d="m 73.513211,187.63399 -43.43084,24.2209 37.33984,65.4923"
style="fill:none;stroke:#000000;stroke-width:0.61883817pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0" />
<path
sodipodi:nodetypes="ccccccc"
id="path625"
d="m 329.06884,168.97674 c -3.22923,32.40151 -48.33213,40.35657 -103.88899,62.92395 -47.29751,20.67557 -104.79982,36.97196 -152.248029,52.54199 -14.630265,1.02523 53.110579,-22.75374 70.680459,-44.90642 0.66814,-2.16901 -3.14891,-3.39428 -14.36635,-12.60951 33.29676,-19.03804 62.77534,-35.93591 116.66189,-61.8442 23.81894,34.22679 71.35656,21.60528 83.16102,3.89419 z"
style="font-size:12px;fill:url(#linearGradient631);fill-opacity:1;fill-rule:evenodd;stroke-width:1"
inkscape:connector-curvature="0" />
<path
sodipodi:nodetypes="ccccccccc"
id="path609"
d="M 384.50861,38.099488 C 354.80841,23.007458 261.97771,-7.9169216 233.74031,2.6592084 l -50.0346,30.6426796 c -21.0791,16.7449 62.1965,91.044802 87.2704,111.505402 40.5832,-20.366 73.0933,8.4432 47.728,24.8 29.7003,15.0922 186.0885,89.872 233.4499,66.1504 l 54.7848,-34.3453 C 629.43641,181.21229 505.31461,98.220688 475.61441,83.128488 l -91.1058,-45.029 z"
style="font-size:12px;fill:#ffc400;fill-rule:evenodd;stroke:#000000;stroke-width:0.61883813"
inkscape:connector-curvature="0" />
<path
transform="matrix(0.914033,0.461359,-0.441951,0.942117,-18.533209,-251.00741)"
sodipodi:ry="37.584381"
sodipodi:rx="191.26279"
sodipodi:cy="114.42296"
sodipodi:cx="527.0166"
d="M 718.27939,114.42296 A 191.26279,37.584381 0 0 1 527.0166,152.00734 191.26279,37.584381 0 0 1 335.75381,114.42296 191.26279,37.584381 0 0 1 527.0166,76.838577 191.26279,37.584381 0 0 1 718.27939,114.42296 Z"
id="path636"
style="fill:url(#linearGradient637);fill-opacity:1;fill-rule:evenodd;stroke:none"
sodipodi:type="arc" />
<path
sodipodi:nodetypes="ccccc"
id="path639"
d="m 328.44601,304.84629 16.106,8.4101 c 31.3021,-28.8021 63.8725,-44.6047 83.0851,-50.8364 l -19.856,-9.1423 c -16.7126,6.4634 -58.033,32.1057 -79.3351,51.5686 z"
style="font-size:12px;fill:#413f3f;fill-opacity:1;fill-rule:evenodd"
inkscape:connector-curvature="0" />
<path
sodipodi:nodetypes="ccc"
id="path622"
d="m 196.75991,24.774078 74.7314,72.24261 c -2.3805,1.4033 -16.011,10.306602 -29.6415,19.209902"
style="fill:none;stroke:#000000;stroke-width:0.61883817pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0" />
<path
sodipodi:nodetypes="ccc"
id="path623"
d="m 356.66561,185.54319 c 16.2726,-12.0983 31.2951,-19.1965 37.5676,-21.2948 l 161.5088,66.7602"
style="fill:none;stroke:#000000;stroke-width:0.61883817pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0" />
<path
sodipodi:nodetypes="cccccccccccccsc"
id="path640"
d="m 240.25081,235.52349 c -6.4983,0.9616 -13.2273,4.2056 -28.2262,10.1634 -11.6531,5.9064 -18.5552,16.0322 -16.9108,25.9166 0.6193,1.189 6.8477,17.3898 7.9906,29.3396 -1.404,18.394 37.8652,8.1016 48.4825,1.3435 11.0309,-6.307 12.9118,-11.9466 13.5562,-15.8893 -2.8229,-8.6166 -2.4794,-10.1663 -6.834,-17.7989 -8.0119,0.5218 -11.7146,-0.3662 -18.6121,3.0123 -9.6727,4.7378 -3.1872,13.7483 6.6253,8.5117 10.3061,-0.988 11.047,7.9139 -2.8894,14.9261 -10.5924,4.134 -23.6794,3.3322 -25.7379,-1.7495 -0.6362,-8.3599 -4.9671,-19.5277 -7.392,-25.0757 1.8642,-8.8926 16.6013,-18.4825 36.3921,-16.0085 7.83,-0.7648 5.6117,-5.8112 4.4202,-8.4257 -2.3157,-4.1117 -7.2524,-8.8392 -10.8645,-8.2656 z"
style="font-size:12px;fill:#393938;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.4147608"
inkscape:connector-curvature="0" />
<path
sodipodi:nodetypes="ccccccc"
id="path627"
d="m 495.74671,237.26509 -40.098,17.5423 c -23.4214,-21.4156 -79.9818,11.2811 -125.1391,46.335 -30.818,6.4012 -59.5032,10.7942 -77.3703,13.3592 -211.498499,25.0563 144.4347,-49.8758 80.9589,-53.3693 113.5883,-40.2426 18.9215,-49.9178 55.0263,-59.9403 34.4344,13.4607 81.0065,33.7759 106.6222,36.0731 z"
style="font-size:12px;fill:url(#linearGradient632);fill-opacity:1;fill-rule:evenodd;stroke-width:1"
inkscape:connector-curvature="0" />
<g
transform="matrix(5.6991496,0,0,5.6991496,-621.46715,-4739.6152)"
id="g3083">
<path
sodipodi:nodetypes="cccccccc"
id="path756"
d="m 159.12825,842.0454 c -3.70604,0 -7.65738,2.29247 -7.2728,8.82794 l -0.51837,3.8103 c -1.03678,3.70602 -0.29479,6.46705 3.37462,8.19011 3.39113,1.29443 7.58813,2.98076 12.45832,-1.08516 l -1.40909,-10.72085 c 2e-5,-6.10354 -2.78917,-9.02234 -6.49522,-9.02234 l -0.13746,0 z"
style="font-size:12px;fill:#000037;fill-rule:evenodd"
inkscape:connector-curvature="0" />
<g
style="font-size:12px"
transform="matrix(0.2194382,0,0,0.2194382,66.932838,752.02752)"
id="g720">
<g
transform="translate(17.12181,33.19958)"
id="g685">
<rect
transform="matrix(0.999947,0.01026074,-0.01026074,0.999947,0,0)"
y="388.58585"
x="398.63693"
height="4.1340609"
width="7.0869694"
id="rect748"
style="font-size:12px;fill:#bc7900;fill-rule:evenodd" />
<path
sodipodi:nodetypes="ccccccccccccccc"
id="path683"
d="m 396.6563,394.1438 c -0.0502,4.8923 -2.0295,8.8384 -8.0633,8.7765 -6.0339,-0.0619 -13.8373,-4.1084 -13.7871,-9.0007 0.0502,-4.8924 4.9459,-5.2648 10.9798,-5.2029 6.0338,0.0619 10.9208,0.5347 10.8706,5.4271 z m -2.1525,0.3909 c -0.0384,3.7425 -1.5525,6.7614 -6.1685,6.714 -4.6159,-0.0474 -10.5854,-3.1429 -10.5471,-6.8856 0.0385,-3.7426 3.7836,-4.0276 8.3996,-3.9802 4.6158,0.0473 8.3544,0.4091 8.316,4.1518 z m -11.8999,-4.1383 -0.0481,9.5203 1.8708,0.7583 0.0481,-10.3324 -1.8708,0.0538 z"
style="font-size:12px;fill:#bc7900;fill-rule:evenodd"
inkscape:connector-curvature="0" />
<path
sodipodi:nodetypes="ccccccccccccccc"
id="path684"
d="m 399.5092,394.1438 c 0.0502,4.8923 2.0295,8.8384 8.0633,8.7765 6.0339,-0.0619 13.8373,-4.1084 13.7871,-9.0007 -0.0502,-4.8924 -4.9459,-5.2648 -10.9798,-5.2029 -6.0338,0.0619 -10.9208,0.5347 -10.8706,5.4271 z m 2.1525,0.3909 c 0.0384,3.7425 1.5525,6.7614 6.1685,6.714 4.6159,-0.0474 10.5854,-3.1429 10.5471,-6.8856 -0.0385,-3.7426 -3.7836,-4.0276 -8.3996,-3.9802 -4.6158,0.0473 -8.3544,0.4091 -8.316,4.1518 z m 11.8999,-4.1383 0.0481,9.5203 -1.8708,0.7583 -0.0481,-10.3324 1.8708,0.0538 z"
style="font-size:12px;fill:#bc7900;fill-rule:evenodd"
inkscape:connector-curvature="0" />
</g>
<path
sodipodi:nodetypes="ccccc"
id="path699"
d="m 409.6376,449.1857 c -3.2748,0.0622 -7.9752,2.6611 -11.9877,4.8207 -1.772,1.2526 -4.099,-4.2023 -4.099,-8.2836 0,-5.5074 2.3164,-9.5871 8.2571,-9.5871 5.4491,0 8.7184,6.2541 7.8296,13.05 z"
style="font-size:12px;fill:#ffffff;fill-rule:evenodd"
inkscape:connector-curvature="0" />
<path
sodipodi:nodetypes="ccccc"
id="path703"
d="m 416.2332,449.481 c 4.6129,0.3575 10.3826,2.3658 14.1764,4.2302 1.9645,1.2525 3.3632,-3.6118 3.3632,-7.6931 0,-4.3262 -2.7286,-10.1777 -9.3149,-10.1777 -6.9271,0 -9.2101,5.0729 -8.2247,13.6406 z"
style="font-size:12px;fill:#ffffff;fill-rule:evenodd"
inkscape:connector-curvature="0" />
<path
transform="translate(-0.590592,-0.88588)"
sodipodi:ry="5.3152466"
sodipodi:rx="5.3152466"
sodipodi:cy="448.78644"
sodipodi:cx="401.89166"
d="m 407.20691,448.78644 a 5.3152466,5.3152466 0 0 1 -5.31525,5.31524 5.3152466,5.3152466 0 0 1 -5.31524,-5.31524 5.3152466,5.3152466 0 0 1 5.31524,-5.31525 5.3152466,5.3152466 0 0 1 5.31525,5.31525 z"
id="path714"
style="fill:url(#radialGradient3100-7);fill-opacity:1;fill-rule:evenodd;stroke:none"
sodipodi:type="arc" />
<path
transform="translate(22.44213,-1.476471)"
sodipodi:ry="5.3152466"
sodipodi:rx="5.3152466"
sodipodi:cy="448.78644"
sodipodi:cx="401.89166"
d="m 407.20691,448.78644 a 5.3152466,5.3152466 0 0 1 -5.31525,5.31524 5.3152466,5.3152466 0 0 1 -5.31524,-5.31524 5.3152466,5.3152466 0 0 1 5.31524,-5.31525 5.3152466,5.3152466 0 0 1 5.31525,5.31525 z"
id="path719"
style="fill:url(#radialGradient3102-4);fill-opacity:1;fill-rule:evenodd;stroke:none"
sodipodi:type="arc" />
<path
sodipodi:nodetypes="ccscs"
id="path691"
d="m 435.2039,458.1105 c 0.2577,4.7306 -16.6315,14.4075 -23.0726,14.4075 -7.0675,0 -17.2673,-8.9073 -17.6438,-14.4075 -0.201,-2.6403 10.5761,-8.352 19.3142,-8.1432 10.1995,0 21.2572,5.4815 21.4022,8.1432 z"
style="font-size:12px;fill:url(#linearGradient3104-8);fill-rule:evenodd"
inkscape:connector-curvature="0" />
<path
sodipodi:nodetypes="csc"
id="path692"
d="m 395.0273,458.1467 c 2.2872,2.5006 8.0463,8.4926 17.1785,8.2225 11.0584,-0.3167 17.0785,-7.3746 19.737,-7.874"
style="font-size:12px;fill:none;stroke:#000000;stroke-width:0.16280808"
inkscape:connector-curvature="0" />
</g>
<path
sodipodi:nodetypes="cccccccccccccccccccc"
id="path736"
d="m 119.09539,850.75141 c -4.79508,-2.18693 0,2.47853 0,2.62432 2.85111,4.68167 5.66984,0.17821 7.59758,0.17821 1.92775,0 2.55953,1.03676 4.4873,1.03676 1.92774,0 4.37386,-0.51838 6.30162,-0.51838 1.79815,0.90716 3.07791,-1.42556 5.00565,-1.42556 1.92777,0 3.85549,2.72149 5.52405,1.55516 1.79817,-0.648 2.68913,1.29596 4.35769,2.07351 1.34455,1.36078 3.40191,2.00876 7.85679,1.68478 1.92775,0 4.24429,-2.72151 6.17203,-2.72151 1.94394,0.63176 -2e-5,-3.59631 -0.5832,-3.6125 -0.1944,1.27978 -6.28541,4.66547 -7.58137,4.1309 -2.05736,0.38878 -3.98511,-0.9072 -5.65367,-1.68478 -2.38132,-0.2592 0.35641,-2.46232 -1.76573,-2.59192 -1.92775,0 -1.39317,0 -3.32092,0 -1.92774,0 -2.68912,-2.33274 -4.61687,-2.33274 -1.92774,0 -0.48599,3.8879 -6.43123,1.16636 -1.92774,0 -2.55952,1.55516 -4.48729,1.55516 -1.92774,0 -4.76266,-2.85112 -7.07918,-1.55516 -1.27977,0.51838 -2.02496,1.32837 -5.78325,0.43739 z"
style="font-size:12px;fill:url(#linearGradient3106-2);fill-rule:evenodd"
inkscape:connector-curvature="0" />
<path
sodipodi:nodetypes="cccsc"
id="path758"
d="m 150.40768,851.67983 c 0,2.97336 3.07102,5.44395 2.00817,5.44395 -1.06281,0 -5.30716,-1.82913 -5.30716,-4.80247 0,-2.97341 2.4707,-5.85955 3.39061,-6.39182 1.06282,-0.6873 -0.0916,2.77695 -0.0916,5.75034 z"
style="font-size:12px;fill-rule:evenodd"
inkscape:connector-curvature="0" />
</g>
</g>
<style
type="text/css"
id="style14207">
.FF {fill:#fff}
</style>
</svg>
diff --git a/platforms/macosx/config.h b/platforms/macosx/config.h
index f2cd07ddc..7c771158f 100644
--- a/platforms/macosx/config.h
+++ b/platforms/macosx/config.h
@@ -1,41 +1,41 @@
/* GCompris - config.h
*
* Copyright (C) 2016 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
#ifndef GCOMPRIS_CONFIG_H
#define GCOMPRIS_CONFIG_H
/* Version number of package (string) */
#define VERSION "0.80"
/* Version number of package (integer) */
#define VERSION_CODE 8000
/* Folder where rccs and translations are installed */
#define GCOMPRIS_DATA_FOLDER "../Resources"
/* GCompris for android, gcompris-qt for others */
#define GCOMPRIS_APPLICATION_NAME "gcompris-qt"
/* Compressed audio format */
#define COMPRESSED_AUDIO "aac"
/* Download Allowed */
#define DOWNLOAD_ALLOWED "ON"
/* Date at which GCompris has been built */
#define BUILD_DATE "201757"
/* Type of activation system */
#define ACTIVATION_MODE "no"
#endif // GCOMPRIS_CONFIG_H
diff --git a/platforms/sailfishOS/harbour-gcompris-qt.desktop b/platforms/sailfishOS/harbour-gcompris-qt.desktop
index 9e52d42b4..b27b335e1 100644
--- a/platforms/sailfishOS/harbour-gcompris-qt.desktop
+++ b/platforms/sailfishOS/harbour-gcompris-qt.desktop
@@ -1,106 +1,107 @@
[Desktop Entry]
Name=GCompris Educational Game
Name[ar]=لعبة «فهمت» التعليميّة
-Name[ast]=Xuegu educativu GCompris
Name[ca]=Joc educatiu GCompris
Name[ca@valencia]=Joc educatiu GCompris
Name[cs]=Výuková hra GCompris
Name[de]=GCompris-Lernspiel
Name[el]=Εκπαιδευτικό παιχνίδι GCompris
Name[en_GB]=GCompris Educational Game
Name[es]=Juego educativo GCompris
Name[et]=Hariv mäng GCompris
Name[fi]=GCompris, opettavainen peli
Name[fr]=Jeu éducatif GCompris
Name[gl]=Xogo educativo GCompris
Name[hi]=जीकोंप्रिस शेक्षणिक खेल
-Name[id]=GCompris Permainan Edukatif
+Name[id]=Permainan Pendidikan GCompris
Name[it]=Gioco didattico GCompris
Name[ko]=GCompris 교육용 게임
+Name[ml]=ജികോംപ്രി വിദ്യാഭ്യാസപരമായ കളി
Name[nl]=Educatief spel GCompris
Name[nn]=GCompris leik-og-lær-spel
Name[pl]=Gra edukacyjna GCompris
Name[pt]=Jogo Educativo GCompris
Name[pt_BR]=Jogo educacional GCompris
Name[ro]=Joc educațional GCompris
Name[ru]=Набор обучающих игр GCompris
Name[sk]=Výuková hra GCompris
Name[sl]=Izobraževalna igra GCompris
Name[sv]=GCompris pedagogiskt spel
Name[tr]=GCompris Eğitici Oyun
Name[uk]=Освітня гра GCompris
Name[x-test]=xxGCompris Educational Gamexx
Name[zh_CN]=GCompris 教育游戏
Name[zh_TW]=GCompris 教育遊戲
GenericName=Educational game
GenericName[ar]=لعبة تعليميّة
-GenericName[ast]=Xuegu educativu
GenericName[ca]=Joc educatiu
GenericName[ca@valencia]=Joc educatiu
GenericName[cs]=Výuková hra
GenericName[da]=Læringsspil
GenericName[de]=Lernspiel
GenericName[el]=Εκπαιδευτικό παιχνίδι
GenericName[en_GB]=Educational game
GenericName[es]=Juego educativo
GenericName[et]=Hariv mäng
GenericName[fi]=Opettavainen peli
GenericName[fr]=Jeu éducatif
GenericName[gl]=Xogo educativo
GenericName[hi]=शेक्षणिक खेल
-GenericName[id]=Permainan edukatif
+GenericName[id]=Permainan Pendidikan
GenericName[it]=Gioco didattico
GenericName[ko]=교육용 게임
+GenericName[ml]=വിദ്യാഭ്യാസപരമായ കളി
GenericName[nl]=Educatief spel
GenericName[nn]=Leik-og-lær-spel
GenericName[pl]=Gra edukacyjna
GenericName[pt]=Jogo educativo
GenericName[pt_BR]=Jogo educacional
GenericName[ro]=Joc educațional
GenericName[ru]=Обучающие игры
GenericName[sk]=Výuková hra
GenericName[sl]=Izobraževalna igra
GenericName[sv]=Pedagogiskt spel
GenericName[tr]=Eğitici oyun
GenericName[uk]=Освітня гра
GenericName[x-test]=xxEducational gamexx
GenericName[zh_CN]=教育游戏
GenericName[zh_TW]=教育遊戲
Comment=Multi-Activity Educational game for children 2 to 10
Comment[ar]=لعبة تعليميّة متعدّدة الأنشطة للأطفال من سنتين إلى ١٠ سنوات
-Comment[ca]=Joc educatiu amb múltiples activitats per a nens dels 2 a 10 anys
-Comment[ca@valencia]=Joc educatiu amb múltiples activitats per a nens dels 2 a 10 anys
+Comment[ca]=Joc educatiu amb múltiples activitats per a infants de 2 a 10 anys
+Comment[ca@valencia]=Joc educatiu amb múltiples activitats per a infants de 2 a 10 anys
Comment[de]=Lernspiel mit vielen Aktivitäten für Kinder von 2 bis 10 Jahren
Comment[el]=Εκπαιδευτικό παιχνίδι πολλαπλών δραστηριοτήτων για ηλικίες 2 έως 10 ετών
Comment[en_GB]=Multi-Activity Educational game for children 2 to 10
Comment[es]=Juego educativo multiactividad para niños de 2 a 10 años
Comment[et]=Rohkete tegevustega hariv mäng lastele vanuses 2-10
Comment[fi]=Useampitoimintoinen opettavainen peli 2–10-vuotiaille lapsille
Comment[fr]=Jeu éducatif multi-activités pour les enfants de 2 à 10 ans
Comment[gl]=Xogo educativo con varias actividades para nenos de entre 2 e 10 anos
Comment[hi]=२ से १० वर्ष के बच्चों के लिए विभिन्न क्रियाएं वाला शेक्षणिक खेल
-Comment[id]=Permainan Edukatif Multi Aktivitas untuk anak berusia 2 sampai 10 tahun
+Comment[id]=GCompris adalah kumpulan permainan kegiatan pendidikan untuk anak umur 2 sampai 10 tahun
Comment[it]=Gioco didattico multi-attività per bambini da 2 a 10 anni
Comment[ko]=2-10세 어린이를 위한 다양한 활동이 있는 교육용 게임
+Comment[ml]=2 തൊട്ട് 10 വയസ്സുവരെയുള്ള കുട്ടികൾക്ക് വേണ്ടിയുള്ള വിവിധ-പ്രവർത്തനങ്ങളിലൂടെയുള്ള വിദ്യാഭ്യാസപരമായ കളി
Comment[nl]=Educatief spel met meerdere activiteiten voor kinderen van 2 tot 10
Comment[nn]=Leik-og-lærspel med mange aktivitetar – for barn frå 2 til 10 år
Comment[pl]=Gra edukacyjna z wieloma aktywnościami dla dzieci w wieku od 2 do 10 lat
Comment[pt]=Jogo educativo multi-actividades para crianças dos 2 aos 10 anos
-Comment[pt_BR]=Jogo educacional com várias atividades para crianças de 2 a 10 anos
+Comment[pt_BR]=Jogo educacional com várias atividades, para crianças de 2 a 10 anos
Comment[ro]=Joc educațional cu activități multiple pentru copii între 2 și 10 ani
Comment[ru]=Обучающие игры для детей от 2 до 10 лет
Comment[sk]=Viac-aktivitová výuková hra pre deti od 2 do 10 rokov
Comment[sl]=Izobraževalna igra z več dejavnostmi za otroke med drugim in desetim letom starosti
Comment[sv]=Pedagogiskt multiaktivitetsspel för barn från 2 till 10 år
Comment[tr]=2-10 yaş arası çocuklar için Çoklu Etkileşimli Eğitici oyun
Comment[uk]=Набір освітніх ігор для дітей від 2 до 10 років
Comment[x-test]=xxMulti-Activity Educational game for children 2 to 10xx
Comment[zh_CN]=为 2 到 10 岁儿童准备的多功能教育游戏
Comment[zh_TW]=為 2-10 歲孩子設計的教育遊戲
Exec=harbour-gcompris-qt
Icon=harbour-gcompris-qt
Terminal=false
Type=Application
Categories=Education;Game;KidsGame;
StartupNotify=true
X-Nemo-Application-Type=generic
diff --git a/src/StaticMessages.sh b/src/StaticMessages.sh
new file mode 100755
index 000000000..7c16af70d
--- /dev/null
+++ b/src/StaticMessages.sh
@@ -0,0 +1,23 @@
+#!/usr/bin/env bash
+# Copied from https://cgit.kde.org/plasma-browser-integration.git/tree/StaticMessages.sh
+
+# We fill in the en "translations" manually. We extract this to the KDE system as pot as normal, then populate the other json files
+
+# The name of catalog we create (without the.pot extension), sourced from the scripty scripts
+FILENAME="gcompris_lang"
+
+function export_pot_file # First parameter will be the path of the pot file we have to create, includes $FILENAME
+{
+ potfile=$1
+ python3 ./activities/lang/resource/datasetToPo.py ./activities/lang/resource/words.json $potfile
+}
+
+function import_po_files # First parameter will be a path that will contain several .po files with the format LANG.po
+{
+ podir=$1
+ for file in `ls $podir`
+ do
+ lang=${file%.po} #remove .po from end of file
+ python3 ./activities/lang/resource/poToDataset.py $podir/$file ./activities/lang/resource/content-$lang.json
+ done
+}
diff --git a/src/activities/CMakeLists.txt b/src/activities/CMakeLists.txt
index d1ca10bc2..721f99710 100644
--- a/src/activities/CMakeLists.txt
+++ b/src/activities/CMakeLists.txt
@@ -1,34 +1,34 @@
add_subdirectory(menu)
# Read the activities.txt file
file(READ activities.txt ACTIVITIES)
# Split the output on a list containing each line
string(REGEX REPLACE ";" "\\\\;" ACTIVITIES "${ACTIVITIES}")
string(REGEX REPLACE "\n" ";" ACTIVITIES "${ACTIVITIES}")
file(REMOVE "activities_out.txt")
add_custom_target(all_activities)
foreach(ACTIVITY ${ACTIVITIES})
# For each line found, we remove comments
string(FIND "${ACTIVITY}" "#" match)
if(${match})
file(STRINGS "${ACTIVITY}/ActivityInfo.qml" demoline REGEX "demo:[ ]+")
string(REGEX REPLACE ".*demo:.*(true|false).*" "\\1" demo "${demoline}" )
set(DEFAULT_MODE ON)
if((${WITH_DEMO_ONLY}) AND (${demo} STREQUAL "false"))
set(DEFAULT_MODE OFF)
endif()
# Set activities as options (enabled by default)
option("USE_${ACTIVITY}" "Enable ${ACTIVITY} activity" ${DEFAULT_MODE})
- if(USE_${ACTIVITY} AND NOT (${_disabled_activities} MATCHES ${ACTIVITY}))
+ if(USE_${ACTIVITY})
# Add the directory for compilation
add_subdirectory(${ACTIVITY})
file(APPEND "activities_out.txt" "${ACTIVITY}\n")
add_dependencies(all_activities "rcc_${ACTIVITY}")
endif()
endif(${match})
endforeach(ACTIVITY ${ACTIVITIES})
GCOMPRIS_ADD_RCC(activities activities_out.txt)
diff --git a/src/activities/activities.txt b/src/activities/activities.txt
index beb7171a0..50e830e0c 100644
--- a/src/activities/activities.txt
+++ b/src/activities/activities.txt
@@ -1,149 +1,154 @@
# The list of activities that will be loaded at GCompris start.
# Keep it sorted
advanced_colors
algebra_by
algebra_div
algebra_minus
algebra_plus
algorithm
align4
align4-2players
alphabet-sequence
babymatch
babyshapes
baby_wordprocessor
balancebox
ballcatch
bargame
bargame_2players
+binary_bulb
braille_alphabets
braille_fun
calendar
canal_lock
categorization
checkers
checkers_2players
chess
chess_2players
chess_partyend
chronos
clickanddraw
clickgame
click_on_letter
click_on_letter_up
clockgame
color_mix
color_mix_light
colors
crane
details
digital_electricity
drawletters
drawnumbers
enumerate
erase
erase_2clic
erase_clic
explore_farm_animals
explore_monuments
explore_world_animals
explore_world_music
family
family_find_relative
fifteen
find_the_day
followline
football
geo-country
geography
gletters
gnumch-equality
gnumch-factors
gnumch-inequality
gnumch-multiples
gnumch-primes
graph-coloring
guesscount
guessnumber
hangman
hanoi
hanoi_real
hexagon
imagename
instruments
intro_gravity
land_safe
lang
leftright
letter-in-word
lightsoff
louis-braille
magic-hat-minus
magic-hat-plus
maze
mazeinvisible
mazerelative
melody
memory
memory-case-association
memory-case-association-tux
memory-enumerate
memory-math-add
memory-math-add-minus
memory-math-add-minus-mult-div
memory-math-add-minus-mult-div-tux
memory-math-add-minus-tux
memory-math-add-tux
memory-math-div
memory-math-div-tux
memory-math-minus
memory-math-minus-tux
memory-math-mult
memory-math-mult-div
memory-math-mult-div-tux
memory-math-mult-tux
memory-sound
memory-sound-tux
memory-tux
memory-wordnumber
mining
missing-letter
money
money_back
money_back_cents
money_cents
mosaic
nine_men_morris
nine_men_morris_2players
+note_names
number_sequence
numbers-odd-even
paintings
penalty
+piano_composition
photo_hunter
planegame
+play_piano
+play_rhythm
railroad
readingh
readingv
redraw
redraw_symmetrical
renewable_energy
reversecount
roman_numerals
scalesboard
scalesboard_weight
scalesboard_weight_avoirdupois
share
simplepaint
smallnumbers
smallnumbers2
solar_system
submarine
sudoku
superbrain
tangram
target
tic_tac_toe
tic_tac_toe_2players
traffic
watercycle
wordsgame
diff --git a/src/activities/advanced_colors/ActivityInfo.qml b/src/activities/advanced_colors/ActivityInfo.qml
index 5fb84f3bd..2e3bdc3e8 100644
--- a/src/activities/advanced_colors/ActivityInfo.qml
+++ b/src/activities/advanced_colors/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "advanced_colors/AdvancedColors.qml"
difficulty: 6
icon: "advanced_colors/advanced_colors.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
//: Activity title
title: qsTr("Advanced colors")
//: Help title
description: qsTr("Select the butterfly of the correct color")
//intro: "click on the required color"
//: Help goal
goal: qsTr("Learn to recognize unusual colors.")
//: Help prerequisite
prerequisite: qsTr("Can read")
//: Help manual
manual: qsTr("You will see dancing butterflies of different colors and a question. You have to find the correct butterfly and touch it.")
credit: ""
section: "discovery colors"
createdInVersion: 0
}
diff --git a/src/activities/advanced_colors/AdvancedColors.qml b/src/activities/advanced_colors/AdvancedColors.qml
index 1217576b5..e1502b10d 100644
--- a/src/activities/advanced_colors/AdvancedColors.qml
+++ b/src/activities/advanced_colors/AdvancedColors.qml
@@ -1,32 +1,32 @@
/* GCompris - AdvancedColors.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Original activity in the Gtk+ version of GCompris by
* Pascal Georges <pascal.georges1@free.fr>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../colors"
import "advanced_colors.js" as Dataset
FindIt {
mode: "AdvancedColors"
dataset: Dataset
backgroundImg: "qrc:/gcompris/src/activities/menu/resource/background.svg"
}
diff --git a/src/activities/advanced_colors/advanced_colors.js b/src/activities/advanced_colors/advanced_colors.js
index fd6a37f71..77403a70d 100644
--- a/src/activities/advanced_colors/advanced_colors.js
+++ b/src/activities/advanced_colors/advanced_colors.js
@@ -1,868 +1,868 @@
/* GCompris
*
* Copyright (C) 2014 Bruno Coudoin
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
var advanced_colors =
[
[ // Level 1
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/coral_butterfly.svg",
- //: Look at http://gcompris.net/wiki/Advanced_color_translation to see all the advanced colors
+ //: Look at https://gcompris.net/wiki/Advanced_color_translation to see all the advanced colors
//: Color #FF7F50
"text": qsTr("Find the coral butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/claret_butterfly.svg",
//: Color #7F1734
"text": qsTr("Find the claret butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/navy_butterfly.svg",
//: Color #000080
"text": qsTr("Find the navy butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/corn_butterfly.svg",
//: Color #FBEC5D
"text": qsTr("Find the corn butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/cobalt_butterfly.svg",
//: Color #0047AB
"text": qsTr("Find the cobalt butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/cyan_butterfly.svg",
//: Color #00FFFF
"text": qsTr("Find the cyan butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/chestnut_butterfly.svg",
//: Color #954535
"text": qsTr("Find the chestnut butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/almond_butterfly.svg",
//: Color #AB784E
"text": qsTr("Find the almond butterfly")
}
],
[ // Level 2
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/claret_butterfly.svg",
//: Color #7F1734
"text": qsTr("Find the claret butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/sapphire_butterfly.svg",
//: Color #0F52BA
"text": qsTr("Find the sapphire butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/corn_butterfly.svg",
//: Color #FBEC5D
"text": qsTr("Find the corn butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/cobalt_butterfly.svg",
//: Color #0047AB
"text": qsTr("Find the cobalt butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/cyan_butterfly.svg",
//: Color #00FFFF
"text": qsTr("Find the cyan butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/chestnut_butterfly.svg",
//: Color #954535
"text": qsTr("Find the chestnut butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/almond_butterfly.svg",
//: Color #AB784E
"text": qsTr("Find the almond butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/ruby_butterfly.svg",
//: Color #E0115F
"text": qsTr("Find the ruby butterfly")
}
],
[ // Level 3
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/sienna_butterfly.svg",
//: Color #882D17
"text": qsTr("Find the sienna butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/sage_butterfly.svg",
//: Color #BCB88A
"text": qsTr("Find the sage butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/salmon_butterfly.svg",
//: Color #FF8C69
"text": qsTr("Find the salmon butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/sepia_butterfly.svg",
//: Color #704214
"text": qsTr("Find the sepia butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/sulphur_butterfly.svg",
//: Color #E4BB25
"text": qsTr("Find the sulfur butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/tea_butterfly.svg",
//: Color #DB6D7B
"text": qsTr("Find the tea butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/lime_butterfly.svg",
//: Color #BFFF00
"text": qsTr("Find the lime butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/turquoise_butterfly.svg",
//: Color #40E0D0
"text": qsTr("Find the turquoise butterfly")
}
],
[ // Level 4
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/absinthe_butterfly.svg",
//: Color #73B881
"text": qsTr("Find the absinthe butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/mahogany_butterfly.svg",
//: Color #C04000
"text": qsTr("Find the mahogany butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/aquamarine_butterfly.svg",
//: Color #7FFFD4
"text": qsTr("Find the aquamarine butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/alabaster_butterfly.svg",
//: Color #F2F0E6
"text": qsTr("Find the alabaster butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/amber_butterfly.svg",
//: Color #FFBF00
"text": qsTr("Find the amber butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/amethyst_butterfly.svg",
//: Color #9966CC
"text": qsTr("Find the amethyst butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/anise_butterfly.svg",
//: Color #F5EACC
"text": qsTr("Find the anise butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/vermilion_butterfly.svg",
//: Color #E34234
"text": qsTr("Find the vermilion butterfly")
}
],
[ // Level 5
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/ceruse_butterfly.svg",
//: Color #EEEBEB
"text": qsTr("Find the ceruse butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/fawn_butterfly.svg",
//: Color #E5AA70
"text": qsTr("Find the fawn butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/chartreuse_butterfly.svg",
//: Color #7FFF00
"text": qsTr("Find the chartreuse butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/emerald_butterfly.svg",
//: Color #50C878
"text": qsTr("Find the emerald butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/aubergine_butterfly.svg",
//: Color #614051
"text": qsTr("Find the aubergine butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/fuchsia_butterfly.svg",
//: Color #CC397B
"text": qsTr("Find the fuchsia butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/ruby_butterfly.svg",
//: Color #E0115F
"text": qsTr("Find the ruby butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/glaucous_butterfly.svg",
//: Color #6082B6
"text": qsTr("Find the glaucous butterfly")
}
],
[ // Level 6
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/aubergine_butterfly.svg",
//: Color #614051
"text": qsTr("Find the aubergine butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/auburn_butterfly.svg",
//: Color #A52A2A
"text": qsTr("Find the auburn butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/azure_butterfly.svg",
//: Color #458AC6
"text": qsTr("Find the azure butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/greyish-brown_butterfly.svg",
//: Color #9F7F58
"text": qsTr("Find the grayish brown butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/bistre_butterfly.svg",
//: Color #3D2B1F
"text": qsTr("Find the bistre butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/crimson_butterfly.svg",
//: Color #DC143C
"text": qsTr("Find the crimson butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/celadon_butterfly.svg",
//: Color #ACE1AF
"text": qsTr("Find the celadon butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/cerulean_butterfly.svg",
//: Color #007BA7
"text": qsTr("Find the cerulean butterfly")
}
],
[ // Level 7
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/dove_butterfly.svg",
//: Color #8B8E8D
"text": qsTr("Find the dove butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/garnet_butterfly.svg",
//: Color #943543
"text": qsTr("Find the garnet butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/indigo_butterfly.svg",
//: Color #4B0082
"text": qsTr("Find the indigo butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/ivory_butterfly.svg",
//: Color #FFFFF0
"text": qsTr("Find the ivory butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/jade_butterfly.svg",
//: Color #00A86B
"text": qsTr("Find the jade butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/lavender_butterfly.svg",
//: Color #B57EDC
"text": qsTr("Find the lavender butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/lichen_butterfly.svg",
//: Color #9BC4AF
"text": qsTr("Find the lichen butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/wine_butterfly.svg",
//: Color #722F37
"text": qsTr("Find the wine butterfly")
}
],
[ // Level 8
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/lilac_butterfly.svg",
//: Color #9955BB
"text": qsTr("Find the lilac butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/magenta_butterfly.svg",
//: Color #FF00FF
"text": qsTr("Find the magenta butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/malachite_butterfly.svg",
//: Color #0BDA51
"text": qsTr("Find the malachite butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/navy_butterfly.svg",
//: Color #000080
"text": qsTr("Find the navy butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/larch_butterfly.svg",
//: Color #D9C3AD
"text": qsTr("Find the larch butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/mimosa_butterfly.svg",
//: Color #EFC050
"text": qsTr("Find the mimosa butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/ochre_butterfly.svg",
//: Color #CC7722
"text": qsTr("Find the ochre butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/olive_butterfly.svg",
//: Color #808000
"text": qsTr("Find the olive butterfly")
}
],
[ // Level 9
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/opaline_butterfly.svg",
//: Color #F7F9F4
"text": qsTr("Find the opaline butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/vermilion_butterfly.svg",
//: Color #E34234
"text": qsTr("Find the vermilion butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/ultramarine_butterfly.svg",
//: Color #120A8F
"text": qsTr("Find the ultramarine butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/mauve_butterfly.svg",
//: Color #E0B0FF
"text": qsTr("Find the mauve butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/greyish_blue_butterfly.svg",
//: Color #91A3B0
"text": qsTr("Find the grayish blue butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/pistachio_butterfly.svg",
//: Color #93C572
"text": qsTr("Find the pistachio butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/platinum_butterfly.svg",
//: Color #AEADA5
"text": qsTr("Find the platinum butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/purple_butterfly.svg",
//: Color #32004A
"text": qsTr("Find the purple butterfly")
}
],
[ // Level 10
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/plum_butterfly.svg",
//: Color #5C3960
"text": qsTr("Find the plum butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/prussian_blue_butterfly.svg",
//: Color #003153
"text": qsTr("Find the prussian blue butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/rust_butterfly.svg",
//: Color #B7410E
"text": qsTr("Find the rust butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/saffron_butterfly.svg",
//: Color #F4C430
"text": qsTr("Find the saffron butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/vanilla_butterfly.svg",
//: Color #F3E5AB
"text": qsTr("Find the vanilla butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/veronese_butterfly.svg",
//: Color #40826D
"text": qsTr("Find the veronese butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/verdigris_butterfly.svg",
//: Color #529371
"text": qsTr("Find the verdigris butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/dark_purple_butterfly.svg",
//: Color #32004A
"text": qsTr("Find the dark purple butterfly")
}
],
[ // Level 11 Now all the colors have been seen, propose here
// a new random set of them
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/olive_butterfly.svg",
//: Color #808000
"text": qsTr("Find the olive butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/auburn_butterfly.svg",
//: Color #A52A2A
"text": qsTr("Find the auburn butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/dark_purple_butterfly.svg",
//: Color #32004A
"text": qsTr("Find the dark purple butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/mauve_butterfly.svg",
//: Color #E0B0FF
"text": qsTr("Find the mauve butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/azure_butterfly.svg",
//: Color #458AC6
"text": qsTr("Find the azure butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/plum_butterfly.svg",
//: Color #5C3960
"text": qsTr("Find the plum butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/sepia_butterfly.svg",
//: Color #704214
"text": qsTr("Find the sepia butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/aubergine_butterfly.svg",
//: Color #614051
"text": qsTr("Find the aubergine butterfly")
}
],
[ // Level 12
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/aubergine_butterfly.svg",
//: Color #614051
"text": qsTr("Find the aubergine butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/cyan_butterfly.svg",
//: Color #00FFFF
"text": qsTr("Find the cyan butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/fawn_butterfly.svg",
//: Color #E5AA70
"text": qsTr("Find the fawn butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/mimosa_butterfly.svg",
//: Color #EFC050
"text": qsTr("Find the mimosa butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/ochre_butterfly.svg",
//: Color #CC7722
"text": qsTr("Find the ochre butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/prussian_blue_butterfly.svg",
//: Color #003153
"text": qsTr("Find the prussian blue butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/rust_butterfly.svg",
//: Color #B7410E
"text": qsTr("Find the rust butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/salmon_butterfly.svg",
//: Color #FF8C69
"text": qsTr("Find the salmon butterfly")
}
],
[ // Level 13
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/alabaster_butterfly.svg",
//: Color #F2F0E6
"text": qsTr("Find the alabaster butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/chestnut_butterfly.svg",
//: Color #954535
"text": qsTr("Find the chestnut butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/coral_butterfly.svg",
//: Color #FF7F50
"text": qsTr("Find the coral butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/ivory_butterfly.svg",
//: Color #FFFFF0
"text": qsTr("Find the ivory butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/mauve_butterfly.svg",
//: Color #E0B0FF
"text": qsTr("Find the mauve butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/plum_butterfly.svg",
//: Color #5C3960
"text": qsTr("Find the plum butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/rust_butterfly.svg",
//: Color #B7410E
"text": qsTr("Find the rust butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/vermilion_butterfly.svg",
//: Color #E34234
"text": qsTr("Find the vermilion butterfly")
}
],
[ // Level 14
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/navy_butterfly.svg",
//: Color #000080
"text": qsTr("Find the navy butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/cerulean_butterfly.svg",
//: Color #007BA7
"text": qsTr("Find the cerulean butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/malachite_butterfly.svg",
//: Color #0BDA51
"text": qsTr("Find the malachite butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/opaline_butterfly.svg",
//: Color #F7F9F4
"text": qsTr("Find the opaline butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/wine_butterfly.svg",
//: Color #722F37
"text": qsTr("Find the wine butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/pistachio_butterfly.svg",
//: Color #93C572
"text": qsTr("Find the pistachio butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/chestnut_butterfly.svg",
//: Color #954535
"text": qsTr("Find the chestnut butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/claret_butterfly.svg",
//: Color #7F1734
"text": qsTr("Find the claret butterfly")
}
],
[ // Level 15
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/chestnut_butterfly.svg",
//: Color #954535
"text": qsTr("Find the chestnut butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/dark_purple_butterfly.svg",
//: Color #32004A
"text": qsTr("Find the dark purple butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/aubergine_butterfly.svg",
//: Color #614051
"text": qsTr("Find the aubergine butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/opaline_butterfly.svg",
//: Color #F7F9F4
"text": qsTr("Find the opaline butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/wine_butterfly.svg",
//: Color #722F37
"text": qsTr("Find the wine butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/fawn_butterfly.svg",
//: Color #E5AA70
"text": qsTr("Find the fawn butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/magenta_butterfly.svg",
//: Color #FF00FF
"text": qsTr("Find the magenta butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/anise_butterfly.svg",
//: Color #F5EACC
"text": qsTr("Find the anise butterfly")
}
],
[ // Level 16
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/claret_butterfly.svg",
//: Color #7F1734
"text": qsTr("Find the claret butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/fawn_butterfly.svg",
//: Color #E5AA70
"text": qsTr("Find the fawn butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/platinum_butterfly.svg",
//: Color #AEADA5
"text": qsTr("Find the platinum butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/indigo_butterfly.svg",
//: Color #4B0082
"text": qsTr("Find the indigo butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/dove_butterfly.svg",
//: Color #8B8E8D
"text": qsTr("Find the dove butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/crimson_butterfly.svg",
//: Color #DC143C
"text": qsTr("Find the crimson butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/veronese_butterfly.svg",
//: Color #40826D
"text": qsTr("Find the veronese butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/greyish-brown_butterfly.svg",
//: Color #9F7F58
"text": qsTr("Find the grayish brown butterfly")
}
],
[ // Level 17
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/chestnut_butterfly.svg",
//: Color #954535
"text": qsTr("Find the chestnut butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/greyish_blue_butterfly.svg",
//: Color #91A3B0
"text": qsTr("Find the grayish blue butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/aubergine_butterfly.svg",
//: Color #614051
"text": qsTr("Find the aubergine butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/salmon_butterfly.svg",
//: Color #FF8C69
"text": qsTr("Find the salmon butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/amber_butterfly.svg",
//: Color #FFBF00
"text": qsTr("Find the amber butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/chartreuse_butterfly.svg",
//: Color #7FFF00
"text": qsTr("Find the chartreuse butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/claret_butterfly.svg",
//: Color #7F1734
"text": qsTr("Find the claret butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/purple_butterfly.svg",
//: Color #32004A
"text": qsTr("Find the purple butterfly")
}
],
[ // Level 18
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/plum_butterfly.svg",
//: Color #5C3960
"text": qsTr("Find the plum butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/claret_butterfly.svg",
//: Color #7F1734
"text": qsTr("Find the claret butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/ultramarine_butterfly.svg",
//: Color #120A8F
"text": qsTr("Find the ultramarine butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/greyish_blue_butterfly.svg",
//: Color #91A3B0
"text": qsTr("Find the grayish blue butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/dark_purple_butterfly.svg",
//: Color #32004A
"text": qsTr("Find the dark purple butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/lilac_butterfly.svg",
//: Color #9955BB
"text": qsTr("Find the lilac butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/aquamarine_butterfly.svg",
//: Color #7FFFD4
"text": qsTr("Find the aquamarine butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/magenta_butterfly.svg",
//: Color #FF00FF
"text": qsTr("Find the magenta butterfly")
}
],
[ // Level 19
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/anise_butterfly.svg",
//: Color #F5EACC
"text": qsTr("Find the anise butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/cerulean_butterfly.svg",
//: Color #007BA7
"text": qsTr("Find the cerulean butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/ivory_butterfly.svg",
//: Color #FFFFF0
"text": qsTr("Find the ivory butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/sepia_butterfly.svg",
//: Color #704214
"text": qsTr("Find the sepia butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/verdigris_butterfly.svg",
//: Color #529371
"text": qsTr("Find the verdigris butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/fuchsia_butterfly.svg",
//: Color #CC397B
"text": qsTr("Find the fuchsia butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/plum_butterfly.svg",
//: Color #5C3960
"text": qsTr("Find the plum butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/purple_butterfly.svg",
//: Color #32004A
"text": qsTr("Find the purple butterfly")
}
],
[ // Level 20
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/tea_butterfly.svg",
//: Color #DB6D7B
"text": qsTr("Find the tea butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/dark_purple_butterfly.svg",
//: Color #32004A
"text": qsTr("Find the dark purple butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/sienna_butterfly.svg",
//: Color #882D17
"text": qsTr("Find the sienna butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/aubergine_butterfly.svg",
//: Color #614051
"text": qsTr("Find the aubergine butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/rust_butterfly.svg",
//: Color #B7410E
"text": qsTr("Find the rust butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/pistachio_butterfly.svg",
//: Color #93C572
"text": qsTr("Find the pistachio butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/sapphire_butterfly.svg",
//: Color #0F52BA
"text": qsTr("Find the sapphire butterfly")
},
{
"image": "qrc:/gcompris/src/activities/advanced_colors/resource/claret_butterfly.svg",
//: Color #7F1734
"text": qsTr("Find the claret butterfly")
}
]
]
function get() {
return advanced_colors
}
diff --git a/src/activities/algebra_by/ActivityInfo.qml b/src/activities/algebra_by/ActivityInfo.qml
index 7f14046f1..7c0eb95f7 100644
--- a/src/activities/algebra_by/ActivityInfo.qml
+++ b/src/activities/algebra_by/ActivityInfo.qml
@@ -1,41 +1,41 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "algebra_by/AlgebraBy.qml"
difficulty: 3
icon: "algebra_by/algebra_by.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
//: Activity title
title: qsTr("Multiplication of numbers")
//: Help title
description: qsTr("Practice the multiplication operation")
// intro: "Multiply the two numbers together and type in your answer before the balloon lands in the water"
//: Help goal
goal: qsTr("Learn to multiply numbers within a limited period of time")
//: Help prerequisite
prerequisite: qsTr("Multiplication tables from 1 to 10")
//: Help manual
manual: qsTr("A multiplication is displayed on the screen. Quickly find the result and use your computer's keyboard or the on-screen keypad to type the product of the numbers. You have to be fast and submit the answer before the penguins in their balloon land!")
credit: ""
section: "math multiplication"
createdInVersion: 0
levels: "1,2,3,4"
}
diff --git a/src/activities/algebra_by/Algebra.qml b/src/activities/algebra_by/Algebra.qml
index 16d27d6d5..922fc8fcf 100644
--- a/src/activities/algebra_by/Algebra.qml
+++ b/src/activities/algebra_by/Algebra.qml
@@ -1,175 +1,179 @@
/* GCompris - Algebra.qml
*
* Copyright (C) 2014 Aruna Sankaranarayanan <aruna.evam@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "algebra.js" as Activity
ActivityBase {
id: activity
property alias operand: operand
onStart: {
focus = true;
}
pageComponent: Image {
id: background
source: "qrc:/gcompris/src/activities/algebra_by/resource/background.svg"
fillMode: Image.PreserveAspectCrop
sourceSize.width: Math.max(parent.width, parent.height)
signal start
signal stop
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
Item {
id: coreItems
property alias background: background
property alias bar: bar
property alias bonus: bonus
property alias score: score
property alias balloon: balloon
- property alias timer:timer
+ property alias timer: timer
property GCSfx audioEffects: activity.audioEffects
}
onStart: Activity.start(coreItems, otherItems, operand)
onStop: Activity.stop()
DialogHelp {
id: dialogHelpLeftRight
onClose: home()
}
Timer {
id: timer
interval: 1000
onTriggered: Activity.run()
}
- Bar {
- id: bar
- content: BarEnumContent { value: help | home | level }
- onHelpClicked: {
- displayDialog(dialogHelpLeftRight)
- }
- onPreviousLevelClicked: {
- Activity.previousLevel()
- }
- onNextLevelClicked: {
- Activity.nextLevel()
-
+ Item {
+ width: background.width - 60 * ApplicationInfo.ratio
+ height: background.height
+ Bar {
+ id: bar
+
+ content: BarEnumContent { value: help | home | level }
+ onHelpClicked: {
+ displayDialog(dialogHelpLeftRight)
+ }
+ onPreviousLevelClicked: {
+ Activity.previousLevel()
+ }
+ onNextLevelClicked: {
+ Activity.nextLevel()
+ }
+ onHomeClicked: home()
}
- onHomeClicked: home()
}
Balloon {
id: balloon
onTimeout: bonus.bad("smiley")
}
Bonus {
id: bonus
Component.onCompleted: {
loose.connect(Activity.run)
win.connect(Activity.nextLevel)
}
}
Score {
id: score
x: parent.width * 0.25
y: parent.height * 0.65
anchors.right: undefined
anchors.bottom: undefined
currentSubLevel: 0
numberOfSubLevels: 10
}
}
Item {
id: otherItems
property alias iAmReady: iAmReady
property alias firstOp: firstOp
property alias secondOp: secondOp
property alias numpad: numpad
property int result
}
NumPad {
id: numpad
onAnswerChanged: Activity.questionsLeft()
maxDigit: ('' + otherItems.result).length + 1
}
ReadyButton {
id: iAmReady
onClicked: Activity.run()
}
Flow {
- id:textFlow
- x: 200 * ApplicationInfo.ratio
+ id: textFlow
+ x: parent.width / 2 - width / 2
y: 80
width: parent.width / 2
height: 100
anchors.margins: 4
spacing: 10
AlgebraText {
id: firstOp
visible: !iAmReady.visible
}
AlgebraText {
id: operand
visible: firstOp.visible
}
AlgebraText {
id: secondOp
visible: !iAmReady.visible
}
AlgebraText {
id: equals
visible: firstOp.visible
text: "="
}
AlgebraText {
id: result
visible: !iAmReady.visible
text: numpad.answer
}
}
Keys.onPressed: {
numpad.updateAnswer(event.key, true);
}
Keys.onReleased: {
numpad.updateAnswer(event.key, false);
}
}
diff --git a/src/activities/algebra_by/AlgebraBy.qml b/src/activities/algebra_by/AlgebraBy.qml
index 503cfe12c..add88b17a 100644
--- a/src/activities/algebra_by/AlgebraBy.qml
+++ b/src/activities/algebra_by/AlgebraBy.qml
@@ -1,31 +1,31 @@
/* GCompris - AlgebraBy.qml
*
* Copyright (C) 2014 Aruna Sankaranarayanan <aruna.evam@gmail.com>
*
* Authors:
* Bruno Coudoin (GTK+ version)
* Aruna Sankaranarayanan <aruna.evam@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
import "../algebra_by"
Algebra {
onStart: {
operand.text = "x"
}
}
diff --git a/src/activities/algebra_by/AlgebraText.qml b/src/activities/algebra_by/AlgebraText.qml
index 26af495c7..4d9a54d55 100644
--- a/src/activities/algebra_by/AlgebraText.qml
+++ b/src/activities/algebra_by/AlgebraText.qml
@@ -1,49 +1,49 @@
/* GCompris - Algebra.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import QtGraphicalEffects 1.0
import "../../core"
Item {
width: text.width
height: text.height
property alias text: text.text
GCText {
id: text
fontSize: hugeSize
font.bold: true
style: Text.Outline
styleColor: "white"
color: "black"
}
DropShadow {
anchors.fill: text
cached: true
horizontalOffset: 1
verticalOffset: 1
radius: 3.0
samples: 16
color: "#422a2a2a"
source: text
}
}
diff --git a/src/activities/algebra_by/algebra.js b/src/activities/algebra_by/algebra.js
index 3d3806946..3fac1158a 100644
--- a/src/activities/algebra_by/algebra.js
+++ b/src/activities/algebra_by/algebra.js
@@ -1,165 +1,165 @@
/* GCompris - algebra.js
*
* Copyright (C) 2014 Aruna Sankaranarayanan and Bruno Coudoin
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
.import "qrc:/gcompris/src/core/core.js" as Core
var currentLevel
var coreItems
var otherItems
var operand
var secondOperandVal
var firstOperandVal
var operations = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
var nbLevel = operations.length
function start(coreItems_, otherItems_, operand_) {
operand = operand_
coreItems = coreItems_
otherItems = otherItems_
currentLevel = 0
coreItems.score.numberOfSubLevels = 10
// for multiplication and addition, the first levels will display
// currentLevel * N (N behind random)
// where the last levels will do:
// N * currentLevel
if(operand.text === "x" || operand.text === "+")
nbLevel = 2 * operations.length
else
nbLevel = operations.length
initLevel()
}
function stop() {
coreItems.balloon.stopMoving()
}
function initLevel() {
coreItems.bar.level = currentLevel + 1
coreItems.score.visible = false
coreItems.score.currentSubLevel = 1
operations = Core.shuffle(operations)
calculateOperands()
otherItems.iAmReady.visible = true
otherItems.firstOp.visible = false
otherItems.secondOp.visible = false
coreItems.balloon.stopMoving()
}
function nextLevel() {
if(++currentLevel >= nbLevel) {
currentLevel = 0
}
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = nbLevel - 1
}
initLevel();
}
function calculateOperands()
{
switch(operand.text)
{
case "x":
firstOperandVal = coreItems.bar.level
secondOperandVal = operations[coreItems.score.currentSubLevel - 1]
break;
case "+":
firstOperandVal = coreItems.bar.level
secondOperandVal = operations[coreItems.score.currentSubLevel - 1]
break;
case "-":
firstOperandVal = coreItems.bar.level + 9
secondOperandVal = operations[coreItems.score.currentSubLevel - 1]
break;
case "/":
firstOperandVal = coreItems.bar.level * operations[coreItems.score.currentSubLevel - 1]
secondOperandVal = coreItems.bar.level
break;
}
if(currentLevel < operations.length) {
otherItems.firstOp.text = firstOperandVal
otherItems.secondOp.text = secondOperandVal
} else {
otherItems.firstOp.text = secondOperandVal
// Don't forget to remove the first operations.length levels
firstOperandVal -= operations.length
otherItems.secondOp.text = firstOperandVal
}
}
// Return the expected answer
function getAnswer() {
switch(operand.text)
{
case "x":
return (firstOperandVal * secondOperandVal)
case "+":
return (firstOperandVal + secondOperandVal)
case "-":
return (firstOperandVal - secondOperandVal)
case "/":
return (firstOperandVal / secondOperandVal)
}
}
function validateAnswer(screenAnswer)
{
return (getAnswer() === screenAnswer)
}
function run() {
calculateOperands()
otherItems.numpad.resetText()
coreItems.score.visible = true
otherItems.iAmReady.visible = false
otherItems.firstOp.visible = true
otherItems.secondOp.visible = true
otherItems.numpad.answerFlag = false
otherItems.result = getAnswer()
// TODO adjusting or disabling the difficulty
coreItems.balloon.startMoving(20000)
}
function questionsLeft() {
if(validateAnswer(parseInt(otherItems.numpad.answer))) {
otherItems.numpad.answerFlag = true
if(coreItems.score.currentSubLevel < coreItems.score.numberOfSubLevels) {
coreItems.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/win.wav")
coreItems.score.currentSubLevel++
coreItems.timer.start()
} else {
coreItems.score.currentSubLevel = 1
coreItems.balloon.stopMoving()
coreItems.bonus.good("smiley");
}
}
}
diff --git a/src/activities/algebra_div/ActivityInfo.qml b/src/activities/algebra_div/ActivityInfo.qml
index b95e56ff4..048017c21 100644
--- a/src/activities/algebra_div/ActivityInfo.qml
+++ b/src/activities/algebra_div/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Sayan Biswas <techsayan01@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "algebra_div/AlgebraDiv.qml"
difficulty: 6
icon: "algebra_div/algebra_div.svg"
author: "Sayan Biswas &lt;techsayan01@gmail.com&gt;"
demo: false
//: Activity title
title: qsTr("Division of numbers")
//: Help title
description: qsTr("Practice the division operation")
// intro: "Find the result of the division and type in your answer before the balloon lands in the water"
//: Help goal
goal: qsTr("Find the result of the division within a limited period of time")
//: Help prerequisite
prerequisite: qsTr("Division of small numbers")
//: Help manual
manual: qsTr("A division is displayed on the screen. Quickly find the result and use your computer's keyboard or the on-screen keypad to type it. You have to be fast and submit the answer before the penguins in their balloon land!")
credit: ""
section: "math division"
createdInVersion: 4000
}
diff --git a/src/activities/algebra_div/AlgebraDiv.qml b/src/activities/algebra_div/AlgebraDiv.qml
index 23f8252c7..120d78d54 100644
--- a/src/activities/algebra_div/AlgebraDiv.qml
+++ b/src/activities/algebra_div/AlgebraDiv.qml
@@ -1,30 +1,30 @@
/* GCompris - AlgebraDiv.qml
*
* Copyright (C) 2015 Sayan Biswas <techsayan01@gmail.com>
*
* Authors:
* Sayan Biswas (Qt version)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
import "../algebra_by/"
Algebra {
- onStart:{
+ onStart: {
operand.text = "/"
}
}
diff --git a/src/activities/algebra_minus/ActivityInfo.qml b/src/activities/algebra_minus/ActivityInfo.qml
index 2fc6fecb9..a6b780b62 100644
--- a/src/activities/algebra_minus/ActivityInfo.qml
+++ b/src/activities/algebra_minus/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "algebra_minus/AlgebraMinus.qml"
difficulty: 4
icon: "algebra_minus/algebra_minus.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
//: Activity title
title: qsTr("Subtraction of numbers")
//: Help title
description: qsTr("Practice the subtraction operation")
// intro: "Subtract the two numbers and type in your answer before the balloon lands in the water"
//: Help goal
goal: qsTr("Learn to find the difference between two numbers within a limited period of time")
//: Help prerequisite
prerequisite: qsTr("Subtraction of small numbers")
//: Help manual
manual: qsTr("A subtraction is displayed on the screen. Quickly find the result and use your computer's keyboard or the on-screen keypad to type it. You have to be fast and submit the answer before the penguins in their balloon land!")
credit: ""
section: "math subtraction"
createdInVersion: 0
}
diff --git a/src/activities/algebra_minus/AlgebraMinus.qml b/src/activities/algebra_minus/AlgebraMinus.qml
index 432e6d525..091301fdb 100644
--- a/src/activities/algebra_minus/AlgebraMinus.qml
+++ b/src/activities/algebra_minus/AlgebraMinus.qml
@@ -1,32 +1,32 @@
/* GCompris - AlgebraMinus.qml
*
* Copyright (C) 2014 Aruna Sankaranarayanan <aruna.evam@gmail.com>
*
* Authors:
* Bruno Coudoin (GTK+ version)
* Aruna Sankaranarayanan <aruna.evam@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
import "../algebra_by/"
Algebra {
- onStart:{
+ onStart: {
operand.text = "-"
}
}
diff --git a/src/activities/algebra_plus/ActivityInfo.qml b/src/activities/algebra_plus/ActivityInfo.qml
index 4cb5d1715..8e5fb3225 100644
--- a/src/activities/algebra_plus/ActivityInfo.qml
+++ b/src/activities/algebra_plus/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "algebra_plus/AlgebraPlus.qml"
difficulty: 3
icon: "algebra_plus/algebra_plus.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
//: Activity title
title: qsTr("Addition of numbers")
//: Help title
description: qsTr("Practice the addition of numbers")
// intro: "Add the two numbers together and type in your answer before the balloon lands in the water"
//: Help goal
goal: qsTr("Learn to find the sum of two numbers within a limited period of time")
//: Help prerequisite
prerequisite: qsTr("Simple addition. Can recognize written numbers")
//: Help manual
manual: qsTr("An addition is displayed on the screen. Quickly find the result and use your computer's keyboard or the on-screen keypad to type it. You have to be fast and submit the answer before the penguins land in their balloon!")
credit: ""
section: "math addition"
createdInVersion: 0
}
diff --git a/src/activities/algebra_plus/AlgebraPlus.qml b/src/activities/algebra_plus/AlgebraPlus.qml
index 7083e081e..134d006ee 100644
--- a/src/activities/algebra_plus/AlgebraPlus.qml
+++ b/src/activities/algebra_plus/AlgebraPlus.qml
@@ -1,30 +1,30 @@
/* GCompris - AlgebraPlus.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
import "../algebra_by/"
Algebra {
onStart: {
operand.text = "+"
}
}
diff --git a/src/activities/algorithm/ActivityInfo.qml b/src/activities/algorithm/ActivityInfo.qml
index 8beec35c2..0a2d2829a 100644
--- a/src/activities/algorithm/ActivityInfo.qml
+++ b/src/activities/algorithm/ActivityInfo.qml
@@ -1,38 +1,38 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bharath M S <brat.197@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "algorithm/Algorithm.qml"
difficulty: 2
icon: "algorithm/algorithm.svg"
author: "Bharath M S &lt;brat.197@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Logical associations")
//: Help title
description: qsTr("Complete the arrangement of fruits")
// intro: "Click on the missing items on the table and follow the logical sequence displayed above it."
//: Help goal
goal: qsTr("Logic training activity")
//: Help manual
manual: qsTr("Look at the two sequences. Each fruit in the first sequence has been replaced by another fruit in the second sequence. Complete the second sequence by using the correct fruits, after studying this pattern.")
credit: ""
section: "discovery"
createdInVersion: 0
}
diff --git a/src/activities/algorithm/Algorithm.qml b/src/activities/algorithm/Algorithm.qml
index e3200019f..9d43a5786 100644
--- a/src/activities/algorithm/Algorithm.qml
+++ b/src/activities/algorithm/Algorithm.qml
@@ -1,279 +1,281 @@
/* GCompris - algorithm.qml
*
* Copyright (C) 2014 Bharath M S <brat.197@gmail.com>
*
* Authors:
* Christof Petig and Ingo Konrad (GTK+ version)
* Bharath M S <brat.197@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "algorithm.js" as Activity
ActivityBase {
id: activity
onStart: focus = true
onStop: {}
pageComponent: Image {
id: background
anchors.fill: parent
source: Activity.url + "desert_scene.svg"
sourceSize.width: parent.width
signal start
signal stop
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property alias questionTray: questionTray
property alias answerTray: answerTray
property alias choiceTray: choiceTray
property alias question: question
property alias answer: answer
property GCSfx audioEffects: activity.audioEffects
property alias background: background
property alias bar: bar
property alias bonus: bonus
property int nbSubLevel: 3
property int currentSubLevel: 0
property bool blockClicks: false
}
onStart: { Activity.start(items) }
onStop: { Activity.stop() }
property bool keyNavigationVisible: false
Keys.enabled: !items.blockClicks
Keys.onPressed: {
keyNavigationVisible = true
if(event.key === Qt.Key_Left)
choiceGridView.moveCurrentIndexLeft()
if(event.key === Qt.Key_Right)
choiceGridView.moveCurrentIndexRight()
if(event.key === Qt.Key_Space || event.key === Qt.Key_Enter || event.key === Qt.Key_Return)
choiceGridView.currentItem.clicked()
}
Column {
id: column
spacing: 10
y: parent.height * 0.05
width: itemWidth * Activity.images.length
anchors.horizontalCenter: parent.horizontalCenter
property int itemWidth: Math.min(background.width * 0.75 / Activity.images.length, background.height * 0.19)
Rectangle {
id: questionTray
height: column.itemWidth
width: parent.width
color: "#55333333"
radius: 5
Row {
anchors.topMargin: 4
anchors.bottomMargin: 4
anchors.leftMargin: 5
anchors.fill: parent
spacing: 5.7 * ApplicationInfo.ratio
Repeater {
id: question
+ // workaround for https://bugreports.qt.io/browse/QTBUG-72643 (qml binding with global variable in Repeater do not work)
+ property alias itemWidth: column.itemWidth
Image {
source: Activity.url + modelData + '.svg'
sourceSize.height: height
sourceSize.width: width
- width: column.itemWidth - 6 * ApplicationInfo.ratio
+ width: question.itemWidth - 6 * ApplicationInfo.ratio
height: width
fillMode: Image.PreserveAspectFit
}
}
}
}
Rectangle {
id: answerTray
height: column.itemWidth
width: parent.width
color: "#55333333"
radius: 5
Row {
anchors.topMargin: 4
anchors.bottomMargin: 4
anchors.leftMargin: 5
anchors.fill: parent
spacing: 5.7 * ApplicationInfo.ratio
Repeater {
id: answer
Image {
source: "qrc:/gcompris/src/activities/algorithm/resource/" +
modelData + '.svg'
sourceSize.height: height
sourceSize.width: width
- width: column.itemWidth - 6 * ApplicationInfo.ratio
+ width: question.itemWidth - 6 * ApplicationInfo.ratio
height: width
fillMode: Image.PreserveAspectFit
}
}
}
}
// A spacer
Item {
height: column.itemWidth / 2
width: parent.width
}
Rectangle {
id: choiceTray
height: column.itemWidth + 3 * ApplicationInfo.ratio
width: parent.width
color: "#55333333"
radius: 5
GridView {
id: choiceGridView
anchors.fill: parent
model: Activity.images
cellWidth: column.itemWidth
cellHeight: cellWidth
interactive: false
keyNavigationWraps: true
highlightFollowsCurrentItem: true
highlight: Rectangle {
width: parent.cellWidth
height: parent.cellHeight
color: "#AAFFFFFF"
border.width: 2
border.color: "white"
visible: background.keyNavigationVisible
Behavior on x { SpringAnimation { spring: 2; damping: 0.2 } }
Behavior on y { SpringAnimation { spring: 2; damping: 0.2 } }
}
delegate: Item {
id: cellItem
width: choiceGridView.cellWidth
height: choiceTray.height
signal clicked
onClicked: {
if(Activity.clickHandler(modelData)) {
particle.burst(20)
}
}
Image {
id: img
source: Activity.url + modelData + '.svg'
- width: column.itemWidth - 6 * ApplicationInfo.ratio
+ width: question.itemWidth - 6 * ApplicationInfo.ratio
height: width
sourceSize.width: width
sourceSize.height: height
anchors.centerIn: parent
fillMode: Image.PreserveAspectFit
state: "notclicked"
MouseArea {
id: mouseArea
hoverEnabled: enabled
enabled: !items.blockClicks
anchors.fill: parent
onClicked: cellItem.clicked()
}
states: [
State {
name: "notclicked"
PropertyChanges {
target: img
scale: 1.0
}
},
State {
name: "clicked"
when: mouseArea.pressed
PropertyChanges {
target: img
scale: 0.9
}
},
State {
name: "hover"
when: mouseArea.containsMouse
PropertyChanges {
target: img
scale: 1.1
}
}
]
Behavior on scale { NumberAnimation { duration: 70 } }
ParticleSystemStarLoader {
id: particle
clip: false
}
}
}
}
}
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level }
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
}
Bonus {
id: bonus
onStop: items.blockClicks = false
Component.onCompleted: win.connect(Activity.nextSubLevel)
}
Score {
anchors {
bottom: bar.top
bottomMargin: 10 * ApplicationInfo.ratio
right: parent.right
rightMargin: 5 * ApplicationInfo.ratio
top: undefined
left: undefined
}
numberOfSubLevels: items.nbSubLevel
currentSubLevel: items.currentSubLevel + 1
}
}
}
diff --git a/src/activities/algorithm/algorithm.js b/src/activities/algorithm/algorithm.js
index 8f806a1cd..2c675270d 100644
--- a/src/activities/algorithm/algorithm.js
+++ b/src/activities/algorithm/algorithm.js
@@ -1,191 +1,191 @@
/* GCompris - algorithm.js
*
* Copyright (C) 2014 Bharath M S" <brat.197@gmail.com>
*
* Authors:
* Christof Petig and Ingo Konrad (GTK+ version)
* "Bharath M S" <brat.197@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
.import "qrc:/gcompris/src/core/core.js" as Core
/*
functions :-
setUp() - the function is called to set the basic game layout each time (questionTray, answerTray)
getImages() - returns a random array of length 8 that is based on the chosen sample
setQuestion() - the function is called to set questionTray
setAnswer() - the function is called to set answerTray
clickHandler() - called to handle click event
variables :-
sample - this array has an array of arrays for each level
choiceCount (int) - initialised with the value 5 and the game is won when choiceCount is 8
Example 1:
sample: [0,1,0,1,0,1,0,1]
getImages() sample output - names of images with indexes [6,7,6,7,6,7,6,7]
Example 2:
sample: [0,1,2,0,1,2,0,1]
getImages() sample output - names of images with indexes [3,5,7,3,5,7,3,5]
Example 3:
sample: [0,1,2,3,3,2,1,0]
getImages() sample output - names of images with indexes [1,3,2,5,5,2,3,1]
*/
var matchesVisible = 4
var currentLevel = 0
var max = 8
var index
var answerIndex
var items
var number
var images = ["apple",
'banana',
'cherries',
'lemon',
'orange',
'pear',
'pineapple',
'plum']
var url = "qrc:/gcompris/src/activities/algorithm/resource/"
function start(items_) {
items = items_
currentLevel = 0
initLevel()
}
function stop() {
}
function initLevel() {
items.bar.level = currentLevel + 1
setUp()
}
// Add more cases to sample and differentiate arrange according to level of difficulty.
// Develop an algo to choose them accordingly for each level.
var sample = [[[0,1,0,1,0,1,0,1],[0,1,1,0,0,1,1,0],[1,1,0,0,0,0,1,1],[1,0,0,1,0,1,1,0]],//level1
[[0,1,2,0,1,2,0,1],[0,1,2,3,0,1,2,3],[0,1,2,3,3,2,1,0],[0,1,2,1,0,1,2,0]],//2
[[0,1,2,3,1,0,0,1],[0,1,2,3,0,1,0,1],[0,1,2,3,1,2,1,2],[0,1,2,3,2,3,2,3]],//3
[[0,1,2,3,0,1,2,0],[0,1,2,3,1,2,3,1],[0,1,2,3,2,1,3,1],[0,1,2,3,3,1,2,1]],//4
[[0,1,2,3,1,2,3,0],[0,1,2,3,2,3,0,1],[0,1,2,3,3,0,1,2],[0,1,2,3,3,0,1,2]],//5
[[0,1,2,3,3,1,2,0],[0,1,2,3,0,2,1,3],[0,1,2,3,2,3,1,0],[0,1,2,3,2,1,3,0]],//6
[[0,1,2,3,3,0,1,1],[0,1,2,3,2,2,3,2],[0,1,2,3,1,1,0,3],[0,1,2,3,1,2,3,2]]]//7
var numberOfLevel = sample.length
function setUp(){
number = Math.floor(Math.random() * 10000) % sample[currentLevel].length
index = getImages(number, currentLevel)
setQuestion(index)
answerIndex = getImages(number, currentLevel)
setAnswer(answerIndex)
}
// Returns a set of images that is used to set either the Sample algorithm or the Answer tray.
function getImages(number, level) {
var substitution = Core.shuffle(images)
// Create results table based on sample and substitution
var results = []
for(var i=0; i<sample[level][number].length; i++) {
results.push(substitution[sample[level][number][i]])
}
return results
}
// The source of questionTray is changed to reflect the chosen
// set of random indices
function setQuestion(indices){
items.question.model = indices
}
// The first `matchesVisible` images of answerTray are set and the `matchesVisible+1`th is a question mark.
function setAnswer(indices){
var tempIndex = []
for(var i=0; i < matchesVisible; i++) {
tempIndex.push(indices[i])
}
tempIndex.push('question_mark')
items.answer.model = tempIndex
}
// Game is won when choiceCount == 8.
var choiceCount = matchesVisible
function clickHandler(id){
var tempIndex = []
// Correct answer
if(id === answerIndex[choiceCount]) {
tempIndex = items.answer.model
choiceCount++;
items.audioEffects.play('qrc:/gcompris/src/core/resource/sounds/bleep.wav')
if(choiceCount < max) {
tempIndex.push('question_mark')
}
tempIndex[choiceCount - 1] = answerIndex[choiceCount - 1]
items.answer.model = tempIndex
if(choiceCount == max) {
items.blockClicks = true
if(items.currentSubLevel+1 === items.nbSubLevel)
items.bonus.good("tux")
else
items.bonus.good("flower")
}
return 1
} else { // Wrong answer, try again
items.audioEffects.play('qrc:/gcompris/src/core/resource/sounds/brick.wav')
}
}
function nextLevel() {
if(numberOfLevel <= ++currentLevel) {
currentLevel = 0
}
items.currentSubLevel = 0;
initLevel();
}
function nextSubLevel() {
choiceCount = matchesVisible
items.currentSubLevel++
// Increment level after 3 successful games.
if (items.currentSubLevel === items.nbSubLevel) {
nextLevel()
}
setUp()
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
items.currentSubLevel = 0;
initLevel();
}
diff --git a/src/activities/align4-2players/ActivityInfo.qml b/src/activities/align4-2players/ActivityInfo.qml
index 0dadb0d93..6ea6f94e8 100644
--- a/src/activities/align4-2players/ActivityInfo.qml
+++ b/src/activities/align4-2players/ActivityInfo.qml
@@ -1,38 +1,38 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bharath M S <brat.197@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "align4-2players/Align42players.qml"
difficulty: 2
icon: "align4-2players/align4-2players.svg"
author: "Bharath M S &lt;brat.197@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Align four (with a friend)")
//: Help title
description: qsTr("Arrange four tokens in a row")
// intro: "Click on the column where you wish your token to fall and try to align 4 tokens to win."
//: Help goal
goal: qsTr("Create a line of 4 tokens either horizontally (lying down), vertically (standing up) or diagonally.")
//: Help manual
manual: qsTr("Play with a friend. Take turns to click the line in which you want to drop a token. You can also use the arrow keys to move the token left or right, and the down or space key to drop a token. First player to create a line of 4 tokens wins")
credit: ""
section: "strategy"
createdInVersion: 0
}
diff --git a/src/activities/align4-2players/Align42players.qml b/src/activities/align4-2players/Align42players.qml
index 38ed2fa01..99b7ca09e 100644
--- a/src/activities/align4-2players/Align42players.qml
+++ b/src/activities/align4-2players/Align42players.qml
@@ -1,236 +1,237 @@
/* GCompris - align4-2players.qml
*
* Copyright (C) 2014 Bharath M S <brat.197@gmail.com>
*
* Authors:
* Laurent Lacheny <laurent.lacheny@wanadoo.fr> (GTK+ version)
* Bharath M S <brat.197@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
import "align4.js" as Activity
import GCompris 1.0
ActivityBase {
id: activity
property bool twoPlayer: true
onStart: focus = true
onStop: {}
pageComponent: Image {
id: background
anchors.fill: parent
source: Activity.url + "background.svg"
sourceSize.width: Math.max(parent.width, parent.height)
fillMode: Image.PreserveAspectCrop
signal start
signal stop
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property alias background: background
property alias fallingPiece: fallingPiece
property alias pieces: pieces
property alias dynamic: dynamic
property alias drop: drop
property alias player1score: player1score
property alias player2score: player2score
property alias bar: bar
property alias bonus: bonus
property alias repeater: repeater
property alias columns: grid.columns
property alias rows: grid.rows
property alias trigTuxMove: trigTuxMove
- property int cellSize: background.width < background.height ? (background.width / (columns + 3)) : (background.height / (rows + 4))
+ property int cellSize: background.width <= background.height ? (background.width / (columns + 3)) : (background.height / (rows + 4))
property bool gameDone
property int counter
+ property int nextPlayerStart: 1
}
onStart: { Activity.start(items, twoPlayer) }
onStop: { Activity.stop() }
Keys.onRightPressed: Activity.moveCurrentIndexRight();
Keys.onLeftPressed: Activity.moveCurrentIndexLeft();
Keys.onDownPressed: Activity.handleDrop(Activity.currentLocation);
Keys.onSpacePressed: Activity.handleDrop(Activity.currentLocation);
ListModel {
id: pieces
}
// Tux move delay
Timer {
id: trigTuxMove
repeat: false
interval: 1500
onTriggered: {
Activity.doMove()
items.player2score.endTurn()
items.player1score.beginTurn()
}
}
Grid {
id: grid
z: 2
anchors.horizontalCenter: parent.horizontalCenter
anchors {
verticalCenter: parent.verticalCenter
horizontalCenter: parent.horizontalCenter
}
spacing: 5
columns: 7
rows: 6
Repeater {
id: repeater
model: pieces
delegate: blueSquare
Component {
id: blueSquare
Rectangle {
color: "#DDAAAAAA";
width: items.cellSize
height: items.cellSize
radius: width / 2
border.color: "#FFFFFFFF"
border.width: 0
Piece {
anchors.fill: parent
state: stateTemp
sourceSize.width: items.cellSize
}
}
}
}
Piece {
id: fallingPiece
state: items.gameDone ? "invisible" : items.counter % 2 ? "2": "1"
sourceSize.width: items.cellSize
Behavior on x { PropertyAnimation { duration: 200 } }
}
}
PropertyAnimation {
id: drop
target: fallingPiece
properties: "y"
duration: 720
onStarted: activity.audioEffects.play(Activity.url + 'slide.wav')
onStopped: {
dynamic.display()
Activity.continueGame()
}
}
MouseArea {
id: dynamic
anchors.fill: parent
enabled: hoverEnabled
hoverEnabled: (!drop.running && !items.gameDone && (items.counter % 2 == 0 || twoPlayer))
property bool holdMode: true
function display() {
var coord = grid.mapFromItem(background, mouseX, mouseY)
Activity.setPieceLocation(coord.x, coord.y)
}
onPositionChanged: items.dynamic.enabled ? display() : ''
onPressed: holdMode = false
onPressAndHold: holdMode = true
onClicked: {
display()
if(!holdMode) {
var coord = grid.mapFromItem(background, mouseX, mouseY)
var column = Activity.whichColumn(coord.x, coord.y)
Activity.handleDrop(column)
}
}
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | reload | (twoPlayer ? 0 : level) }
onHelpClicked: {
displayDialog(dialogHelp)
}
onHomeClicked: activity.home()
onReloadClicked: {
Activity.reset()
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
}
ScoreItem {
id: player1score
z: 1
player: 1
height: Math.min(background.height/7, Math.min(background.width/7, bar.height * 1.05))
width: height*11/8
anchors {
top: background.top
topMargin: 5
left: background.left
leftMargin: 5
}
playerImageSource: Activity.url + "player_1.svg"
backgroundImageSource: Activity.url + "score_1.svg"
}
ScoreItem {
id: player2score
z: 1
player: 2
height: Math.min(background.height/7, Math.min(background.width/7, bar.height * 1.05))
width: height*11/8
anchors {
top: background.top
topMargin: 5
right: background.right
rightMargin: 5
}
playerImageSource: Activity.url + "player_2.svg"
backgroundImageSource: Activity.url + "score_2.svg"
playerScaleOriginX: player2score.width
}
Bonus {
id: bonus
}
}
}
diff --git a/src/activities/align4-2players/Piece.qml b/src/activities/align4-2players/Piece.qml
index ce18d9bd7..9c46d1532 100644
--- a/src/activities/align4-2players/Piece.qml
+++ b/src/activities/align4-2players/Piece.qml
@@ -1,74 +1,74 @@
/* GCompris - align4-2players.qml
*
* Copyright (C) 2014 Bharath M S <brat.197@gmail.com>
*
* Authors:
* Laurent Lacheny <laurent.lacheny@wanadoo.fr> (GTK+ version)
* Bharath M S <brat.197@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "align4.js" as Activity
import GCompris 1.0
Image {
id: piece
fillMode: Image.PreserveAspectFit
opacity: 1.0
states: [
State {
name: "invisible"
PropertyChanges {
target: piece
opacity: 0
}
},
State {
name: "2" // Player 2
PropertyChanges{
target: piece
opacity: 1.0
source: Activity.url + "stone_2.svg"
}
},
State {
name: "1" // Player 1
PropertyChanges {
target: piece
opacity: 1.0
source: Activity.url + "stone_1.svg"
}
},
State {
name: "crossed1"
PropertyChanges {
target: piece
opacity: 1.0
source: Activity.url + "win1.svg"
}
},
State {
name: "crossed2"
PropertyChanges {
target: piece
opacity: 1.0
source: Activity.url + "win2.svg"
}
}
]
}
diff --git a/src/activities/align4-2players/align4.js b/src/activities/align4-2players/align4.js
index 86a455124..e57b7cd26 100644
--- a/src/activities/align4-2players/align4.js
+++ b/src/activities/align4-2players/align4.js
@@ -1,515 +1,530 @@
/* GCompris - align4.js
*
* Copyright (C) 2014 Bharath M S
*
* Authors:
* Laurent Lacheny <laurent.lacheny@wanadoo.fr> (GTK+ version)
* Bharath M S <brat.197@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
var currentLevel
var numberOfLevel
var items
var url = "qrc:/gcompris/src/activities/align4-2players/resource/"
var currentPiece
var currentPlayer
var currentLocation
var twoPlayer
var weight = [[100, 50, 20, 100, 50, 20],
[100, 50, 20, 100, 50, 20],
[110, 55, 20, 100, 50, 20],
[100, 50, 20, 110, 55, 20],
[100, 50, 20, 110, 55, 20],
[100, 50, 20, 110, 55, 20]];
var nextColumn
var depthMax
var randomMiss
function start(items_, twoPlayer_) {
items = items_
currentLevel = 0
twoPlayer = twoPlayer_
initLevel()
}
function stop() {
}
function initLevel() {
numberOfLevel = twoPlayer ? 1 : weight.length
items.bar.level = currentLevel + 1
- items.counter = 0
+ items.counter = items.nextPlayerStart+1
- items.player2score.endTurn();
- items.player1score.beginTurn();
+ if(items.nextPlayerStart === 1) {
+ items.player2score.endTurn();
+ items.player1score.beginTurn();
+ }
+ else {
+ items.player1score.endTurn();
+ items.player2score.beginTurn();
+ if(!twoPlayer) {
+ items.trigTuxMove.start();
+ }
+ }
items.gameDone = false
items.pieces.clear()
for(var y = 0; y < items.rows; y++) {
for(var x = 0; x < items.columns; x++) {
items.pieces.append({'stateTemp': "invisible"})
}
}
nextColumn = 3
if(currentLevel < 2)
depthMax = 2
else
depthMax = 4
if(currentLevel < 2)
randomMiss = 1
else if(currentLevel < 4)
randomMiss = 0.5
else
randomMiss = 1
setPieceLocationByIndex(3)
}
function nextLevel() {
- if(numberOfLevel <= ++currentLevel ) {
+ if(numberOfLevel <= ++currentLevel) {
currentLevel = 0
}
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
initLevel();
}
function reset() {
+ // If the previous game is not won, we switch the starting player
+ // Else, the next player is the one who lost (set in continueGame())
+ if(!items.gameDone) {
+ items.nextPlayerStart = (items.nextPlayerStart == 1) ? 2 : 1;
+ }
items.trigTuxMove.stop();
items.drop.stop() // stop animation
items.pieces.clear() // Clear the board
initLevel()
}
function whichColumn(mouseX, mouseY) {
for(var i = 0; i < items.columns - 1; i++) {
if(mouseX < items.repeater.itemAt(i + 1).x) {
return i
}
}
return items.columns - 1
}
/* To move the piece before a column is chosen */
function setPieceLocation(mouseX, mouseY) {
currentLocation = whichColumn(mouseX, mouseY)
items.fallingPiece.y = items.repeater.itemAt(0).y - items.cellSize
items.fallingPiece.x = items.repeater.itemAt(currentLocation).x
}
function setPieceLocationByIndex(index) {
setPieceLocation(items.repeater.itemAt(index).x,
items.repeater.itemAt(0).y)
}
function moveCurrentIndexRight() {
if(currentLocation++ > items.columns)
currentLocation = 0
setPieceLocationByIndex(currentLocation)
}
function moveCurrentIndexLeft() {
if(currentLocation-- <= 0)
currentLocation = items.columns - 1
setPieceLocationByIndex(currentLocation)
}
function isModelEmpty(model) {
var state = model.stateTemp
- return (state == "1" || state == "2") ? false : true
+ return (state === "1" || state === "2") ? false : true
}
function getPieceAt(col, row) {
return items.pieces.get(row * items.columns + col)
}
function getNextFreeStop(col) {
for(var row = items.rows - 1; row >= 0; row--) {
if(isModelEmpty(getPieceAt(col, row)))
return row
}
// Full column
return -1
}
function handleDrop(column) {
var singleDropSize = items.cellSize
var nextFreeStop = getNextFreeStop(column)
if(nextFreeStop >= 0) {
items.drop.to = items.repeater.itemAt(nextFreeStop * items.columns).y
currentPiece = nextFreeStop * items.columns + column
items.drop.start()
}
-
}
function setPieceState(col, row, state) {
items.pieces.set(row * items.columns + col, {"stateTemp": state})
}
function getPieceState(col, row) {
return items.pieces.get(row * items.columns + col).stateTemp
}
function getBoardFromModel() {
var board = []
var temp
for(var i = 0; i < items.rows; i++) {
temp = []
for(var j = 0; j < items.columns; j++) {
temp.push(getPieceState(j, i))
}
board.push(temp)
}
-
return board
-
}
function getFreeStopFromBoard(column, board) {
for(var row = items.rows-1; row > -1; row--) {
if(board[row][column] === "invisible") {
return row
}
}
return -1
}
function alphabeta(depth, alpha, beta, player, board) {
var value = evaluateBoard(player, player % 2 ? 2 : 1, board)
if(depth === 0 || value === 100000 || value < -100000) {
return value
}
if(player === 2) {
var scores = [];
for(var c = 0; c < items.columns; c++) {
var r = getFreeStopFromBoard(c, board)
if(r === -1) continue;
board[r][c] = "2"
alpha = Math.max(alpha, alphabeta(depth - 1, alpha, beta, 1, board))
board[r][c] = "invisible"
scores[c] = alpha;
if(beta <= alpha) break;
}
if(depth === depthMax) {
var max = -10000;
for(var i = 0; i < scores.length; i++) {
if(scores[i] > max) {
max = scores[i]
nextColumn = i
}
}
}
return alpha;
} else {
for(var c = 0; c < items.columns; c++) {
var r = getFreeStopFromBoard(c, board)
if(r === -1) continue;
board[r][c] = "1"
beta = Math.min(beta, alphabeta(depth - 1, alpha, beta, 2, board))
board[r][c] = "invisible"
if(beta <= alpha) break;
}
return beta;
}
}
function doMove() {
var board = getBoardFromModel()
alphabeta(depthMax, -10000, 10000, 2, board)
setPieceLocation(items.repeater.itemAt(nextColumn).x,
items.repeater.itemAt(0).y)
handleDrop(nextColumn)
}
function checkLine() {
var score = 0
var count1, count2
// Make the game easier, forget to analyse some line depending on the level
if(Math.random() > randomMiss)
return 0
// Performance improvement, do not enter the processing loop
// if there is nothing to look at.
var gotOne = false
for(var i = 2; i < (arguments.length - 1); i++) {
if(arguments[i] !== "invisible") {
gotOne = true
break
}
}
if(!gotOne)
return 0
var player1 = arguments[0].toString()
var player2 = arguments[1].toString()
for(var i = 2; i < (arguments.length - 3); i++) {
count1 = 0
count2 = 0
for(var j = 0; j < 4; j++) {
if(arguments[i + j] === player1) {
count1++
} else if( arguments[i + j] === player2) {
count2++
}
}
if((count1 > 0) && (count2 === 0)) {
if(count1 === 4) {
return 10000
}
score += ((count1 / 3) * weight[currentLevel][0] +
(count1 / 2) * weight[currentLevel][1] +
count1 * weight[currentLevel][2])
} else if((count1 === 0) && (count2 > 0)) {
if(count2 === 4) {
return -10000
}
score -= ((count2 / 3) * weight[currentLevel][3] +
(count2 / 2) * weight[currentLevel][4] +
count2 * weight[currentLevel][5])
}
}
return score
}
function evaluateBoard(player1, player2, board) {
var score = 0
//Horizontal
for(var i = 0; i < items.rows; i++) {
score += checkLine(player1, player2, board[i][0],
board[i][1], board[i][2], board[i][3],
board[i][4], board[i][5], board[i][6]);
}
//Vertical
for(var i = 0; i < items.columns; i++) {
score += checkLine(player1, player2, board[0][i],
board[1][i], board[2][i],
board[3][i], board[4][i], board[5][i])
}
//Diagonal Bottom-Right
score += checkLine(player1, player2, board[0][3],
board[1][4], board[2][5], board[3][6]);
score += checkLine(player1, player2, board[0][2], board[1][3],
board[2][4], board[3][5], board[4][6]);
score += checkLine(player1, player2, board[0][1], board[1][2],
board[2][3], board[3][4], board[4][5], board[5][6]);
score += checkLine(player1, player2, board[0][0], board[1][1],
board[2][2], board[3][3], board[4][4], board[5][5]);
score += checkLine(player1, player2, board[1][0], board[2][1],
board[3][2], board[4][3], board[5][4]);
score += checkLine(player1, player2, board[2][0],
board[3][1], board[4][2], board[5][3]);
//Diagonal Top-Left
score += checkLine(player1, player2, board[3][0],
board[2][1], board[1][2], board[0][3])
score += checkLine(player1, player2, board[4][0], board[3][1],
board[2][2], board[1][3], board[0][4]);
score += checkLine(player1, player2, board[5][0], board[4][1],
board[3][2], board[2][3], board[1][4], board[0][5]);
score += checkLine(player1, player2, board[5][1], board[4][2],
board[3][3], board[2][4], board[1][5], board[0][6]);
score += checkLine(player1, player2, board[5][2], board[4][3],
board[3][4], board[2][5], board[1][6]);
score += checkLine(player1, player2, board[5][3], board[4][4],
board[3][5], board[2][6]);
return score
-
}
function checkGameWon(currentPieceRow, currentPieceColumn) {
currentPlayer = getPieceState(currentPieceColumn, currentPieceRow)
var crossed = "crossed" + currentPlayer
// Horizontal
var sameColor = 0
for(var col = 0; col < items.columns; col++) {
if(getPieceState(col, currentPieceRow) === currentPlayer) {
if(++sameColor == 4) {
setPieceState(col, currentPieceRow, crossed)
setPieceState(col - 1, currentPieceRow, crossed)
setPieceState(col - 2, currentPieceRow, crossed)
setPieceState(col - 3, currentPieceRow, crossed)
return true
}
} else {
sameColor = 0
}
}
// Vertical
sameColor = 0
for(var row = 0; row < items.rows; row++) {
if(getPieceState(currentPieceColumn, row) === currentPlayer) {
if(++sameColor == 4) {
setPieceState(currentPieceColumn, row, crossed)
setPieceState(currentPieceColumn, row - 1, crossed)
setPieceState(currentPieceColumn, row - 2, crossed)
setPieceState(currentPieceColumn, row - 3, crossed)
return true
}
} else {
sameColor = 0
}
}
// Diagonal top left / bottom right
sameColor = 0
var row = 0
for(var col = currentPieceColumn - currentPieceRow;
col < items.columns; col++) {
row++
if(col < 0)
continue
if(row > items.rows)
break
if(getPieceState(col, row-1) === currentPlayer) {
if(++sameColor == 4) {
setPieceState(col, row - 1, crossed)
setPieceState(col - 1, row - 2, crossed)
setPieceState(col - 2, row - 3, crossed)
setPieceState(col - 3, row - 4, crossed)
return true
}
} else {
sameColor = 0
}
}
// Diagonal top right / bottom left
sameColor = 0
var row = 0
for(var col = currentPieceColumn + currentPieceRow;
col >= 0; col--) {
row++
if(col >= items.columns)
continue
if(row > items.rows)
break
if(getPieceState(col, row-1) === currentPlayer) {
if(++sameColor == 4) {
setPieceState(col, row - 1, crossed)
setPieceState(col + 1, row - 2, crossed)
setPieceState(col + 2, row - 3, crossed)
setPieceState(col + 3, row - 4, crossed)
return true
}
} else {
sameColor = 0
}
}
}
function continueGame() {
items.pieces.set(currentPiece, {"stateTemp": items.counter++ % 2 ? "2": "1"})
/* Update score if game won */
if(twoPlayer) {
if(checkGameWon(parseInt(currentPiece / items.columns),
parseInt(currentPiece % items.columns))) {
items.gameDone = true
if(currentPlayer === "1") {
items.player1score.win();
items.player2score.endTurn();
+ items.nextPlayerStart = 2;
} else {
items.player2score.win();
items.player1score.endTurn();
+ items.nextPlayerStart = 1;
}
items.bonus.good("flower")
}
else {
if(currentPlayer === "2") {
items.player1score.beginTurn();
items.player2score.endTurn();
} else {
items.player2score.beginTurn();
items.player1score.endTurn();
}
}
} else {
if(checkGameWon(parseInt(currentPiece / items.columns),
parseInt(currentPiece % items.columns))) {
items.gameDone = true
if(currentPlayer === "1") {
items.player1score.win()
items.player2score.endTurn()
items.bonus.good("flower")
items.counter--
+ items.nextPlayerStart = 2;
} else {
items.player2score.win()
items.player1score.endTurn()
items.bonus.bad("flower")
+ items.nextPlayerStart = 1;
}
}
if(items.counter % 2) {
items.player1score.endTurn()
items.player2score.beginTurn()
items.trigTuxMove.start()
}
}
if(items.counter === 42) {
items.player1score.endTurn()
items.player2score.endTurn()
items.bonus.bad("flower")
+ items.nextPlayerStart = (items.nextPlayerStart == 1) ? 2 : 1;
}
}
diff --git a/src/activities/align4/ActivityInfo.qml b/src/activities/align4/ActivityInfo.qml
index 9f7a6640a..9109ccfc0 100644
--- a/src/activities/align4/ActivityInfo.qml
+++ b/src/activities/align4/ActivityInfo.qml
@@ -1,38 +1,38 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bharath M S <brat.197@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "align4/Align4.qml"
difficulty: 2
icon: "align4/align4.svg"
author: "Bharath M S &lt;brat.197@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Align four (against Tux)")
//: Help title
description: qsTr("Arrange four tokens in a row")
// intro: "Click on the column where you wish your token to fall and try to align of 4 tokens before Tux."
//: Help goal
goal: qsTr("Create a line of 4 tokens either horizontally (lying down), vertically (standing up) or diagonally.")
//: Help manual
manual: qsTr("Play with the computer. Take turns to click the line in which you want to drop a token. You can also use the arrow keys to move the token left or right, and the down or space key to drop a token. First player to create a line of 4 tokens wins")
credit: ""
section: "strategy"
createdInVersion: 0
}
diff --git a/src/activities/align4/Align4.qml b/src/activities/align4/Align4.qml
index 9ba756d87..49f6a0792 100644
--- a/src/activities/align4/Align4.qml
+++ b/src/activities/align4/Align4.qml
@@ -1,29 +1,29 @@
/* GCompris - align4.qml
*
* Copyright (C) 2014 Bharath M S <brat.197@gmail.com>
*
* Authors:
* Laurent Lacheny <laurent.lacheny@wanadoo.fr> (GTK+ version)
* Bharath M S <brat.197@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
import "../align4-2players"
Align42players {
twoPlayer: false
}
diff --git a/src/activities/alphabet-sequence/ActivityInfo.qml b/src/activities/alphabet-sequence/ActivityInfo.qml
index 9b44223a0..b7ffdbe04 100644
--- a/src/activities/alphabet-sequence/ActivityInfo.qml
+++ b/src/activities/alphabet-sequence/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "alphabet-sequence/AlphabetSequence.qml"
difficulty: 2
icon: "alphabet-sequence/alphabet-sequence.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
//: Activity title
title: qsTr("Alphabet sequence")
//: Help title
description: qsTr("Move the helicopter to catch the clouds following the order of the alphabet")
// intro: "Move the helicopter to catch the clouds following the order of the alphabet."
//: Help goal
goal: qsTr("Alphabet sequence")
//: Help prerequisite
prerequisite: qsTr("Can decode letters")
//: Help manual
manual: qsTr("Catch the alphabet letters. With a keyboard use the arrow keys to move the helicopter. With a pointing device you just click or tap on the target location. To know which letter you have to catch you can either remember it or check the bottom right corner.")
credit: ""
section: "reading"
createdInVersion: 0
}
diff --git a/src/activities/alphabet-sequence/AlphabetSequence.qml b/src/activities/alphabet-sequence/AlphabetSequence.qml
index 9f4481af3..70d4c93e7 100644
--- a/src/activities/alphabet-sequence/AlphabetSequence.qml
+++ b/src/activities/alphabet-sequence/AlphabetSequence.qml
@@ -1,49 +1,49 @@
/* gcompris - AlphabetSequence.qml
Copyright (C) 2014 Johnny Jazeix <jazeix@gmail.com>
Bruno Coudoin: initial Gtk+ version
This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../planegame"
Planegame {
id: activity
// Put here the alphabet in your language, letters separated by: /
// Supports multigraphs, e.g. /sh/ or /sch/ gets treated as one letter
property string alphabet: qsTr("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");
dataset: [
{
data: activity.alphabet.split("/"),
showNext: true
},
{
data: activity.alphabet.toUpperCase().split("/"),
showNext: true
},
{
data: activity.alphabet.split("/"),
showNext: false
},
{
data: activity.alphabet.toUpperCase().split("/"),
showNext: false
}
]
}
diff --git a/src/activities/baby_wordprocessor/ActivityInfo.qml b/src/activities/baby_wordprocessor/ActivityInfo.qml
index 8a17a2b4b..3b01d84f0 100644
--- a/src/activities/baby_wordprocessor/ActivityInfo.qml
+++ b/src/activities/baby_wordprocessor/ActivityInfo.qml
@@ -1,43 +1,43 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "baby_wordprocessor/BabyWordprocessor.qml"
difficulty: 1
icon: "baby_wordprocessor/baby_wordprocessor.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
//: Activity title
title: qsTr("A baby wordprocessor")
//: Help title
description: qsTr("A simplistic word processor to let the children play around with a keyboard and see letters.")
//intro: "A simplistic word processor to play around with the keyboard"
//: Help goal
goal: qsTr("Discover the keyboard and the letters.")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("Just type on the real or virtual keyboard like in a wordprocessor.
Clicking on the 'Title' button will make the text bigger. Similarly, the 'subtitle' button will make the text slightly less bigger. Clicking on 'paragraph' will remove the formatting.
Press 'Shift' and use the arrow keys to select the text. Use Ctrl+C to copy, Ctrl+V to paste and Crtl+X to cut text. Ctrl+Z can be used to undo changes.
Try to fiddle around and find more shortcuts. For example, what is the shortcut to select all the text?")
credit: ""
section: "computer keyboard reading"
createdInVersion: 6000
}
diff --git a/src/activities/baby_wordprocessor/BabyWordprocessor.qml b/src/activities/baby_wordprocessor/BabyWordprocessor.qml
index 4859ff1be..92d6a19b1 100644
--- a/src/activities/baby_wordprocessor/BabyWordprocessor.qml
+++ b/src/activities/baby_wordprocessor/BabyWordprocessor.qml
@@ -1,267 +1,317 @@
/* GCompris - baby_wordprocessor.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import QtQuick.Controls 1.5
import "../../core"
ActivityBase {
id: activity
onStart: focus = true
onStop: {}
pageComponent: Rectangle {
id: background
anchors.fill: parent
color: 'white'
signal start
signal stop
Component.onCompleted: {
activity.start.connect(start)
}
onStart: {
keyboard.populate();
edit.forceActiveFocus();
}
+ property bool horizontalMode: height <= width
+
+ GCCreationHandler {
+ id: creationHandler
+ onFileLoaded: {
+ edit.clear()
+ edit.text = data["text"]
+ edit.cursorPosition = edit.length
+ }
+ onClose: edit.forceActiveFocus()
+ }
+
Column {
id: controls
width: 120 * ApplicationInfo.ratio
anchors {
right: parent.right
top: parent.top
- bottom: bar.top
margins: 10
}
spacing: 10
Button {
style: GCButtonStyle { textSize: "title"}
text: qsTr("Title")
width: parent.width
onClicked: edit.formatLineWith('h2')
}
Button {
style: GCButtonStyle { textSize: "subtitle"}
text: qsTr("Subtitle")
width: parent.width
onClicked: edit.formatLineWith('h3')
}
Button {
style: GCButtonStyle { textSize: "regular"}
width: parent.width
text: qsTr("Paragraph")
onClicked: edit.formatLineWith('p')
}
}
+ Column {
+ id: saveAndLoadButtons
+ width: controls.width
+
+ property bool isEnoughSpace: {
+ if(ApplicationInfo.isMobile && parent.horizontalMode)
+ return false
+ return (parent.height - keyboard.height - controls.height) > 2.5 * loadButton.height
+ }
+
+ anchors {
+ right: !isEnoughSpace ? controls.left : parent.right
+ top: !isEnoughSpace ? parent.top : controls.bottom
+ margins: 10
+ }
+ spacing: 10
+
+ Button {
+ id: loadButton
+ style: GCButtonStyle { textSize: "regular"}
+ width: parent.width
+ text: qsTr("Load")
+ onClicked: {
+ creationHandler.loadWindow()
+ }
+ }
+ Button {
+ id: saveButton
+ style: GCButtonStyle { textSize: "regular"}
+ width: parent.width
+ text: qsTr("Save")
+ onClicked: {
+ var textToSave = {}
+ textToSave["text"] = edit.getFormattedText(0, edit.length)
+ creationHandler.saveWindow(textToSave)
+ }
+ }
+ }
+
Flickable {
id: flick
anchors {
left: parent.left
- right: controls.left
+ right: saveAndLoadButtons.left
top: parent.top
bottom: bar.top
margins: 10
}
contentWidth: edit.paintedWidth
contentHeight: edit.paintedHeight
clip: true
flickableDirection: Flickable.VerticalFlick
function ensureVisible(r)
{
if (contentX >= r.x)
contentX = r.x;
else if (contentX+width <= r.x+r.width)
contentX = r.x+r.width-width;
if (contentY >= r.y)
contentY = r.y;
else if (contentY+height <= r.y+r.height)
contentY = r.y+r.height-height;
}
TextEdit {
id: edit
width: flick.width
height: flick.height
focus: true
wrapMode: TextEdit.Wrap
onCursorRectangleChanged: flick.ensureVisible(cursorRectangle)
textFormat: TextEdit.RichText
color: "#373737"
font {
pointSize: (18 + ApplicationSettings.baseFontSize) * ApplicationInfo.fontRatio
capitalization: ApplicationSettings.fontCapitalization
weight: Font.DemiBold
family: GCSingletonFontLoader.fontLoader.name
letterSpacing: ApplicationSettings.fontLetterSpacing
wordSpacing: 10
}
cursorDelegate: Rectangle {
id: cursor
width: 10
// height should be set automatically as mention in cursorRectangle property
// documentation but it does not work
height: parent.cursorRectangle.height
color: '#DF543D'
SequentialAnimation on opacity {
running: true
loops: Animation.Infinite
PropertyAnimation {
to: 0.2
duration: 1000
}
PropertyAnimation {
to: 1
duration: 1000
}
}
}
function insertText(text) {
edit.insert(cursorPosition, text)
}
function backspace() {
if(cursorPosition > 0) {
moveCursorSelection(cursorPosition - 1, TextEdit.SelectCharacters)
cut()
}
}
function newline() {
insert(cursorPosition, "<br></br>")
}
function formatLineWith(tag) {
var text = getText(0, length)
var initialPosition = cursorPosition
var first = cursorPosition - 1
for(; first >= 0; first--) {
if(text.charCodeAt(first) === 8233)
break
}
first++
var last = cursorPosition
for(; last < text.length; last++) {
if(text.charCodeAt(last) === 8233)
break
}
var line = getText(first, last)
remove(first, last)
insert(first, '<' + tag + '>' + line + '</' + tag + '>')
cursorPosition = initialPosition
}
}
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
anchors.bottom: keyboard.top
content: BarEnumContent { value: help | home | reload }
onHelpClicked: {
displayDialog(dialogHelp)
}
onHomeClicked: activity.home()
onReloadClicked: edit.text = ''
}
VirtualKeyboard {
id: keyboard
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
width: parent.width
visible: ApplicationSettings.isVirtualKeyboard && !ApplicationInfo.isMobile
onKeypress: {
if(text == backspace)
edit.backspace()
else if(text == newline)
edit.newline()
else
edit.insertText(text)
}
shiftKey: true
onError: console.log("VirtualKeyboard error: " + msg);
readonly property string newline: "\u21B2"
function populate() {
layout = [
[
{ label: "0" },
{ label: "1" },
{ label: "2" },
{ label: "3" },
{ label: "4" },
{ label: "5" },
{ label: "6" },
{ label: "7" },
{ label: "8" },
{ label: "9" }
],
[
{ label: "A" },
{ label: "B" },
{ label: "C" },
{ label: "D" },
{ label: "E" },
{ label: "F" },
{ label: "G" },
{ label: "H" },
{ label: "I" }
],
[
{ label: "J" },
{ label: "K" },
{ label: "L" },
{ label: "M" },
{ label: "N" },
{ label: "O" },
{ label: "P" },
{ label: "Q" },
{ label: "R" }
],
[
{ label: "S" },
{ label: "T" },
{ label: "U" },
{ label: "V" },
{ label: "W" },
{ label: "X" },
{ label: "Y" },
{ label: "Z" },
{ label: " " },
{ label: backspace },
{ label: newline }
]
]
}
}
}
}
diff --git a/src/activities/babymatch/ActivityInfo.qml b/src/activities/babymatch/ActivityInfo.qml
index a052a9b53..f972e95a3 100644
--- a/src/activities/babymatch/ActivityInfo.qml
+++ b/src/activities/babymatch/ActivityInfo.qml
@@ -1,43 +1,43 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Pulkit Gupta <pulkitgenius@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "babymatch/Babymatch.qml"
difficulty: 1
icon: "babymatch/babymatch.svg"
author: "Pulkit Gupta &lt;pulkitgenius@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Matching Items")
//: Help title
description: qsTr("Drag and Drop the items to make them match")
// intro: "Drag and drop the objects matching the pictures"
//: Help goal
goal: qsTr("Motor coordination. Conceptual matching.")
//: Help prerequisite
prerequisite: qsTr("Cultural references.")
//: Help manual
manual: qsTr("In the main board area, a set of objects is displayed. In the vertical box (at the left of the main board) another set of objects is shown, each object in the group on the left matching exactly one object in the main board area. This game challenges you to find the logical link between these objects. How do they fit together? Drag each object to the correct red space in the main area.")
credit: ""
section: "discovery"
createdInVersion: 4000
}
diff --git a/src/activities/babymatch/Babymatch.qml b/src/activities/babymatch/Babymatch.qml
index 2e9803507..ca60ee468 100644
--- a/src/activities/babymatch/Babymatch.qml
+++ b/src/activities/babymatch/Babymatch.qml
@@ -1,316 +1,316 @@
/* GCompris - Babymatch.qml
*
* Copyright (C) 2015 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "babymatch.js" as Activity
ActivityBase {
id: activity
// In most cases, these 3 are the same.
// But for imageName for example, we reuse the images of babymatch, so we need to differentiate them
property string imagesUrl: boardsUrl
property string soundsUrl: boardsUrl
property string boardsUrl: "qrc:/gcompris/src/activities/babymatch/resource/"
property int levelCount: 7
property bool answerGlow: true //For highlighting the answers
property bool displayDropCircle: true //For displaying drop circles
onStart: focus = true
onStop: {}
pageComponent: Image {
id: background
anchors.fill: parent
source: "qrc:/gcompris/src/activities/guesscount/resource/backgroundW01.svg"
signal start
signal stop
- property bool vert: background.width > background.height
+ property bool vert: background.width >= background.height
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property alias background: background
property alias bar: bar
property alias bonus: bonus
property alias availablePieces: availablePieces
property alias backgroundPiecesModel: backgroundPiecesModel
property alias file: file
property alias grid: grid
property alias backgroundImage: backgroundImage
property alias leftWidget: leftWidget
property alias instruction: instruction
property alias toolTip: toolTip
property alias score: score
property alias dataset: dataset
}
Loader {
id: dataset
asynchronous: false
}
onStart: { Activity.start(items, imagesUrl, soundsUrl, boardsUrl, levelCount, answerGlow, displayDropCircle) }
onStop: { Activity.stop() }
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level }
onHelpClicked: {displayDialog(dialogHelp)}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
}
Score {
id: score
visible: numberOfSubLevels > 1
}
Bonus {
id: bonus
Component.onCompleted: win.connect(Activity.nextSubLevel)
}
File {
id: file
name: ""
}
Image {
id: leftWidget
source: "qrc:/gcompris/src/activities/guesscount/resource/backgroundW02.svg"
width: background.vert ?
90 * ApplicationInfo.ratio :
background.width
height: background.vert ?
background.height :
90 * ApplicationInfo.ratio
anchors.left: parent.left
ListWidget {
id: availablePieces
vert: background.vert
}
MouseArea {
anchors.fill: parent
onPressed: (instruction.opacity == 0 ?
instruction.show() : instruction.hide())
}
}
Rectangle {
id: toolTip
anchors {
bottom: bar.top
bottomMargin: 10
left: leftWidget.left
leftMargin: 5
}
width: toolTipTxt.width + 10
height: toolTipTxt.height + 5
opacity: 1
radius: 10
z: 100
color: "#E8E8E8"
property alias text: toolTipTxt.text
Behavior on opacity { NumberAnimation { duration: 120 } }
function show(newText) {
if(newText) {
text = newText
opacity = 0.8
} else {
opacity = 0
}
}
Rectangle {
width: parent.width - anchors.margins
height: parent.height - anchors.margins
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: parent.height/8
radius: 10
color: "#87A6DD" //light blue
}
Rectangle {
width: parent.width - anchors.margins
height: parent.height - anchors.margins
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: parent.height/4
radius: 10
color: "#E8E8E8" //paper white
}
GCText {
id: toolTipTxt
anchors.centerIn: parent
fontSize: regularSize
color: "#373737"
horizontalAlignment: Text.AlignHCenter
wrapMode: TextEdit.WordWrap
}
}
Rectangle {
id: grid
color: "transparent"
z: 2
x: background.vert ? 90 * ApplicationInfo.ratio : 0
y: background.vert ? 0 : 90 * ApplicationInfo.ratio
width: background.vert ?
background.width - 90 * ApplicationInfo.ratio : background.width
height: background.vert ?
background.height - (bar.height * 1.1) :
background.height - (bar.height * 1.1) - 90 * ApplicationInfo.ratio
Image {
id: backgroundImage
fillMode: Image.PreserveAspectFit
property double ratio: sourceSize.width / sourceSize.height
property double gridRatio: grid.width / grid.height
property alias instruction: instruction
source: ""
z: 2
width: source == "" ? grid.width : (ratio > gridRatio ? grid.width : grid.height * ratio)
height: source == "" ? grid.height : (ratio < gridRatio ? grid.height : grid.width / ratio)
anchors.topMargin: 10
anchors.centerIn: parent
//Inserting static background images
Repeater {
id: backgroundPieces
model: backgroundPiecesModel
delegate: piecesDelegate
z: 2
Component {
id: piecesDelegate
Image {
id: shapeBackground
source: Activity.imagesUrl + imgName
x: posX * backgroundImage.width - width / 2
y: posY * backgroundImage.height - height / 2
height:
imgHeight ?
imgHeight * backgroundImage.height :
(backgroundImage.source == "" ?
backgroundImage.height * shapeBackground.sourceSize.height / backgroundImage.height :
backgroundImage.height * shapeBackground.sourceSize.height /
backgroundImage.sourceSize.height)
width:
imgWidth ?
imgWidth * backgroundImage.width :
(backgroundImage.source == "" ?
backgroundImage.width * shapeBackground.sourceSize.width / backgroundImage.width :
backgroundImage.width * shapeBackground.sourceSize.width /
backgroundImage.sourceSize.width)
fillMode: Image.PreserveAspectFit
}
}
}
MouseArea {
anchors.fill: parent
onPressed: (instruction.opacity == 0 ?
instruction.show() : instruction.hide())
}
}
}
Rectangle {
id: instruction
anchors.horizontalCenter: instructionTxt.horizontalCenter
anchors.verticalCenter: instructionTxt.verticalCenter
width: instructionTxt.width + 40
height: instructionTxt.height + 40
opacity: 0.8
radius: 10
z: 3
color: "#87A6DD" //light blue
property alias text: instructionTxt.text
Behavior on opacity { PropertyAnimation { duration: 200 } }
function show() {
if(text)
opacity = 1
}
function hide() {
opacity = 0
}
Rectangle {
id: insideFill
width: parent.width - anchors.margins
height: parent.height - anchors.margins
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: parent.height/8
radius: 10
color: "#E8E8E8" //paper white
}
}
GCText {
id: instructionTxt
anchors {
top: background.vert ? grid.top : leftWidget.bottom
topMargin: -10
horizontalCenter: background.vert ? grid.horizontalCenter : leftWidget.horizontalCenter
}
opacity: instruction.opacity
z: instruction.z
fontSize: regularSize
color: "#373737"
horizontalAlignment: Text.AlignHCenter
width: Math.max(Math.min(parent.width * 0.9, text.length * 11), parent.width * 0.3)
wrapMode: TextEdit.WordWrap
}
ListModel {
id: backgroundPiecesModel
}
}
}
diff --git a/src/activities/babymatch/DragListItem.qml b/src/activities/babymatch/DragListItem.qml
index 70ef0cbb9..14a6526e6 100644
--- a/src/activities/babymatch/DragListItem.qml
+++ b/src/activities/babymatch/DragListItem.qml
@@ -1,286 +1,286 @@
/* gcompris - DragListItem.qml
*
* Copyright (C) 2015 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Pulkit Gupta <pulkitgenius@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import QtGraphicalEffects 1.0
import GCompris 1.0
import "babymatch.js" as Activity
Item {
id: item
width: tile.width
height: tile.height
property string source: imgName
property double heightInColumn
property double widthInColumn
property double tileWidth
property double tileHeight
property QtObject answer: tileImage.parent
property bool selected: false
property alias dropStatus: tileImage.dropStatus
signal pressed
ParallelAnimation {
id: tileImageAnimation
NumberAnimation {
target: tileImage
easing.type: Easing.OutQuad
property: "x"
to: tileImage.moveImageX
duration: 430
}
NumberAnimation {
target: tileImage
easing.type: Easing.OutQuad
property: "y"
to: tileImage.moveImageY
duration: 430
}
onStarted: {
tileImage.anchors.centerIn = undefined
view.showGlow = false
}
onStopped: {
tileImage.parent = tileImage.tileImageParent
tileImage.anchors.centerIn = tileImage.currentTargetSpot == null ? tileImage.parent : tileImage.currentTargetSpot
updateOkButton()
}
}
Rectangle {
id: tile
width: tileWidth
height: tileHeight
color: (parent.selected && tileImage.parent == tile) ? "#33FF294D" : "transparent"
border.color: (parent.selected && tileImage.parent == tile) ? "white" : "transparent"
border.width: 3
radius: 2
property double xCenter: tile.x + tile.width / 2
property double yCenter: tile.y + tile.height / 2
Image {
id: tileImage
anchors.centerIn: parent
width: smallWidth
height: smallHeight
fillMode: Image.PreserveAspectFit
source: Activity.imagesUrl + imgName
property double smallWidth: Activity.glowEnabled ? widthInColumn * 1.1 : widthInColumn
property double smallHeight: Activity.glowEnabled ? heightInColumn * 1.1 : heightInColumn
property double fullWidth: imgWidth ? imgWidth * backgroundImage.width : (backgroundImage.source == "" ?
tileImage.sourceSize.width :
backgroundImage.width * tileImage.sourceSize.width/backgroundImage.sourceSize.width)
property double fullHeight: imgHeight ? imgHeight * backgroundImage.height : (backgroundImage.source == "" ?
tileImage.sourceSize.height :
backgroundImage.height * tileImage.sourceSize.height/backgroundImage.sourceSize.height)
property QtObject tileImageParent
property double moveImageX
property double moveImageY
property int dropStatus: -1 // -1: Nothing / 0: Bad pos / 1: Good pos
property bool small: true
property Item currentTargetSpot
property bool pressedOnce
property bool parentIsTile : parent == tile ? true : false
onFullWidthChanged: correctDroppedImageSize()
onFullHeightChanged: correctDroppedImageSize()
function correctDroppedImageSize() {
if(tileImage.dropStatus == 0 || tileImage.dropStatus == 1) {
tileImage.width = tileImage.fullWidth
tileImage.height = tileImage.fullHeight
}
}
function imageRemove() {
dropStatus = -1
if(backgroundImage.source == "")
leftWidget.z = 1
var coord = tileImage.parent.mapFromItem(tile, tile.xCenter - tileImage.width/2,
tile.yCenter - tileImage.height/2)
tileImage.moveImageX = coord.x
tileImage.moveImageY = coord.y
tileImage.currentTargetSpot = null
tileImage.tileImageParent = tile
toSmall()
tileImageAnimation.start()
}
function toSmall() {
width = smallWidth
height = smallHeight
small = true
}
function toFull() {
width = fullWidth
height = fullHeight
small = false
}
MultiPointTouchArea {
id: mouseArea
touchPoints: [ TouchPoint { id: point1 } ]
property real startX
property real startY
anchors.fill: parent
onPressed: {
Activity.hideInstructions()
item.pressed()
tileImage.toSmall()
tileImage.anchors.centerIn = undefined
tileImage.dropStatus = -1
item.hideOkButton()
startX = point1.x
startY = point1.y
toolTip.show(toolTipText)
if(tileImage.parent == tile)
leftWidget.z = 3
else
leftWidget.z = 1
if(tileImage.currentTargetSpot) {
tileImage.currentTargetSpot.currentTileImageItem = null
tileImage.currentTargetSpot = null
}
if(imgSound)
- activity.audioEffects.play(ApplicationInfo.getAudioFilePath(imgSound))
+ activity.audioVoices.play(ApplicationInfo.getAudioFilePath(imgSound))
tileImage.pressedOnce = true
}
onUpdated: {
var moveX = point1.x - startX
var moveY = point1.y - startY
parent.x = parent.x + moveX
parent.y = parent.y + moveY
tileImage.opacity = 1
Activity.highLightSpot(getClosestSpot(), tileImage)
}
onReleased: {
if (tileImage.pressedOnce) {
tileImage.opacity = 1
tileImage.pressedOnce = false
Activity.highLightSpot(null, tileImage)
var closestSpot = getClosestSpot()
updateFoundStatus(closestSpot)
if(closestSpot === null) {
if(tileImage.currentTargetSpot)
tileImage.currentTargetSpot.imageRemove()
else
tileImage.imageRemove()
} else {
if(tileImage.currentTargetSpot !== closestSpot) {
closestSpot.imageRemove()
closestSpot.imageAdd(tileImage)
}
tileImage.currentTargetSpot = closestSpot
tileImage.tileImageParent = backgroundImage
tileImage.toFull()
var coord = tileImage.parent.mapFromItem(backgroundImage,
closestSpot.xCenter - tileImage.fullWidth/2,
closestSpot.yCenter - tileImage.fullHeight/2)
tileImage.moveImageX = coord.x
tileImage.moveImageY = coord.y
tileImage.z = 100
tileImageAnimation.start()
}
}
}
function getClosestSpot() {
var coordImg = tileImage.parent.mapToItem(backgroundImage,
tileImage.x + tileImage.width/2,
tileImage.y + tileImage.height/2)
return Activity.getClosestSpot(coordImg.x, coordImg.y)
}
function updateFoundStatus(closestSpot) {
if(!closestSpot) {
tileImage.dropStatus = -1
return
}
if(closestSpot.imgName === imgName)
tileImage.dropStatus = 1
else
tileImage.dropStatus = 0
}
}
Image {
id: wrongAnswer
anchors.centerIn: parent
height: heightInColumn * 0.3
width: widthInColumn * 0.3
fillMode: Image.PreserveAspectFit
z: 10
source:"qrc:/gcompris/src/activities/babymatch/resource/error.svg"
visible: view.showGlow && tileImage.dropStatus === 0
}
}
Glow {
id: tileImageGlow
parent: tileImage.parent
anchors.fill: tileImage
radius: tileImage.dropStatus === 0 ? 9 : 0.7
samples: tileImage.dropStatus === 0 ? 18 : 2
color: view.showGlow && Activity.glowEnabled ?
(tileImage.dropStatus === 0 ? "red" : "black") :
'transparent'
source: tileImage
spread: tileImage.dropStatus === 0 ? 0.95 : 1
opacity: tileImage.opacity
}
}
function hideOkButton() {
if(view.okShowed) {
hideOk.start()
view.okShowed = false
view.showGlow = false
}
}
function updateOkButton() {
if(view.areAllPlaced()) {
showOk.start()
}
if(!view.okShowed && tileImage.dropStatus >= 0)
view.checkDisplayedGroup()
if(!view.okShowed && tileImage.dropStatus == -1) {
view.displayedGroup[parseInt(index/view.nbItemsByGroup)] = true
view.setPreviousNavigation()
view.setNextNavigation()
view.checkDisplayedGroup()
}
}
}
diff --git a/src/activities/babymatch/DropAnswerItem.qml b/src/activities/babymatch/DropAnswerItem.qml
index 642c12bbd..1c824abe5 100644
--- a/src/activities/babymatch/DropAnswerItem.qml
+++ b/src/activities/babymatch/DropAnswerItem.qml
@@ -1,94 +1,94 @@
/* gcompris - DropAnswerItem.qml
*
* Copyright (C) 2015 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Pulkit Gupta <pulkitgenius@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "babymatch.js" as Activity
Rectangle {
id: dropCircle
property string dropCircleColor: currentTileImageItem ? 'transparent' : 'pink'
property string text
property double posX
property double posY
property string imgName
property double xCenter: x + width / 2
property double yCenter: y + height / 2
property Item currentTileImageItem
- width: parent.width > parent.height ? parent.height/35 : parent.width/35
+ width: parent.width >= parent.height ? parent.height/35 : parent.width/35
height: width
radius: width/2
z: 200
border.width: 1
color: Activity.displayDropCircle ? dropCircleColor : "transparent"
border.color: dropCircle.color == "#000000" ? "transparent" : "red"
x: posX * parent.width - width/2
y: posY * parent.height - height/2
// Display a shadow of image, when the image is hovered over a target area
Image {
id: targetImage
fillMode: Image.PreserveAspectFit
anchors.centerIn: parent
- z : -1
+ z: -1
}
function imageRemove() {
if(currentTileImageItem)
currentTileImageItem.imageRemove()
currentTileImageItem = null
}
function imageAdd(tileImageItem) {
currentTileImageItem = tileImageItem
dropCircle.color = dropCircleColor
}
function show(tileImageItem) {
if(Activity.displayDropCircle)
dropCircle.color = "lightgreen"
targetImage.source = tileImageItem.source
targetImage.width = tileImageItem.fullWidth
targetImage.height = tileImageItem.fullHeight
if(currentTileImageItem) {
currentTileImageItem.opacity = 0
}
if (tileImageItem.parentIsTile) {
targetImage.opacity = 1
tileImageItem.opacity = 0.5
dropCircle.z = 100
}
else
targetImage.opacity = 0.5
}
function hide() {
dropCircle.color = Activity.displayDropCircle ? dropCircleColor : "transparent"
targetImage.opacity = 0
dropCircle.z = 200
if(currentTileImageItem)
currentTileImageItem.opacity = 1
}
}
diff --git a/src/activities/babymatch/ListWidget.qml b/src/activities/babymatch/ListWidget.qml
index e5c043501..e6b2c658e 100644
--- a/src/activities/babymatch/ListWidget.qml
+++ b/src/activities/babymatch/ListWidget.qml
@@ -1,278 +1,278 @@
/* gcompris - ListWidget.qml
*
* Copyright (C) 2015 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Pulkit Gupta <pulkitgenius@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "babymatch.js" as Activity
Item {
id: listWidget
anchors.fill: parent
anchors.topMargin: 5 * ApplicationInfo.ratio
anchors.leftMargin: 5 * ApplicationInfo.ratio
z: 10
property bool vert
property alias model: mymodel
property alias view: view
property alias showOk: showOk
property alias hideOk: hideOk
property alias repeater: repeater
ListModel {
id: mymodel
}
PropertyAnimation {
id: showOk
target: ok
properties: "height"
from: 0
to: view.iconSize * 0.9
duration: 300
onStopped: {
view.okShowed = true
instruction.show()
}
}
PropertyAnimation {
id: hideOk
target: ok
properties: "height"
from: view.iconSize * 0.9
to: 0
duration: 200
onStopped: view.checkDisplayedGroup()
}
Image {
id: ok
source:"qrc:/gcompris/src/core/resource/bar_ok.svg"
sourceSize.width: view.iconSize
fillMode: Image.PreserveAspectFit
anchors.horizontalCenter: parent.horizontalCenter
MouseArea {
anchors.fill: parent
onClicked: view.checkAnswer()
}
}
Grid {
id: view
width: listWidget.vert ? leftWidget.width : 2 * bar.height
height: listWidget.vert ? background.height - 2 * bar.height : bar.height
spacing: 10
z: 20
columns: listWidget.vert ? 1 : nbItemsByGroup + 1
property int currentDisplayedGroup: 0
property int setCurrentDisplayedGroup
property int nbItemsByGroup:
listWidget.vert ?
parent.height / iconSize - 2 :
parent.width / iconSize - 2
property int nbDisplayedGroup: nbItemsByGroup > 0 ? Math.ceil(model.count / nbItemsByGroup) : 0
property int iconSize: 80 * ApplicationInfo.ratio
property int previousNavigation: 1
property int nextNavigation: 1
property bool okShowed: false
property bool showGlow: false
property var displayedGroup: []
property alias ok: ok
onNbDisplayedGroupChanged: correctDisplayedGroup()
add: Transition {
NumberAnimation { property: "opacity"; from: 0; to: 1.0; duration: 400 }
NumberAnimation { property: "scale"; from: 0; to: 1.0; duration: 400 }
}
move: Transition {
NumberAnimation { properties: "x,y"; duration: 400; easing.type: Easing.OutBounce }
}
// For correcting values of Displayed Groups when height or width is changed
function correctDisplayedGroup() {
if (nbDisplayedGroup > 0) {
for(var i = 0 ; i < nbDisplayedGroup ; i++) {
var groupEmpty = true
for(var j = 0 ; j < nbItemsByGroup, i*nbItemsByGroup + j < model.count ; j++) {
if (repeater.itemAt(i*nbItemsByGroup + j).dropStatus < 0) {
groupEmpty = false
break
}
}
if (groupEmpty)
displayedGroup[i] = false
else
displayedGroup[i] = true
}
view.refreshLeftWidget()
view.checkDisplayedGroup()
}
}
//For setting navigation buttons
function setNextNavigation() {
nextNavigation = 0
for(var i = currentDisplayedGroup + 1 ; i < nbDisplayedGroup ; i++) {
if(displayedGroup[i]) {
nextNavigation = i - currentDisplayedGroup
break
}
}
}
function setPreviousNavigation() {
previousNavigation = 0
for(var i = currentDisplayedGroup - 1 ; i >= 0 ; i--) {
if(displayedGroup[i]) {
previousNavigation = currentDisplayedGroup - i
break
}
}
}
function checkDisplayedGroup() {
var i = currentDisplayedGroup * nbItemsByGroup
var groupEmpty = true
while(i < model.count && i < (currentDisplayedGroup + 1) * nbItemsByGroup) {
if (repeater.itemAt(i).dropStatus < 0) {
groupEmpty = false
break
}
i++
}
if (groupEmpty) {
displayedGroup[currentDisplayedGroup] = false
previousNavigation = 0
nextNavigation = 0
for(var i = 0 ; i < nbDisplayedGroup ; ++i) {
if(displayedGroup[i]) {
view.setCurrentDisplayedGroup = i
view.refreshLeftWidget()
break
}
}
}
}
function refreshLeftWidget() {
availablePieces.view.currentDisplayedGroup = availablePieces.view.setCurrentDisplayedGroup
availablePieces.view.setNextNavigation()
availablePieces.view.setPreviousNavigation()
}
function areAllPlaced() {
for(var i = 0 ; i < model.count ; ++i) {
if(repeater.itemAt(i).dropStatus < 0) {
return false
}
}
return true
}
function checkAnswer() {
view.showGlow = true
for(var i = 0 ; i < model.count ; ++i) {
if(repeater.itemAt(i).dropStatus !== 1) {
return
}
}
Activity.win()
}
Repeater {
id: repeater
property int currentIndex
onCurrentIndexChanged: {
for(var i = 0; i < mymodel.count; i++) {
if(currentIndex != i)
repeater.itemAt(i).selected = false
else
repeater.itemAt(i).selected = true
}
if(currentIndex == -1)
toolTip.opacity = 0
}
DragListItem {
id: contactsDelegate
z: 1
heightInColumn: view.iconSize * 0.85
widthInColumn: view.iconSize * 0.85
tileWidth: view.iconSize
tileHeight: view.iconSize
visible: view.currentDisplayedGroup * view.nbItemsByGroup <= index &&
index <= (view.currentDisplayedGroup+1) * view.nbItemsByGroup-1
onPressed: repeater.currentIndex = index
}
clip: true
model: mymodel
onModelChanged: repeater.currentIndex = -1
}
Row {
spacing: view.iconSize * 0.20
Image {
id: previous
opacity: (model.count > view.nbItemsByGroup &&
view.previousNavigation != 0 && view.currentDisplayedGroup != 0) ? 1 : 0
source:"qrc:/gcompris/src/core/resource/bar_previous.svg"
sourceSize.width: view.iconSize * 0.35
fillMode: Image.PreserveAspectFit
MouseArea {
anchors.fill: parent
onClicked: {
repeater.currentIndex = -1
if(previous.opacity == 1) {
view.setCurrentDisplayedGroup = view.currentDisplayedGroup - view.previousNavigation
view.refreshLeftWidget()
}
}
}
}
Image {
id: next
visible: model.count > view.nbItemsByGroup && view.nextNavigation != 0 && view.currentDisplayedGroup <
view.nbDisplayedGroup - 1
source:"qrc:/gcompris/src/core/resource/bar_next.svg"
sourceSize.width: view.iconSize * 0.35
fillMode: Image.PreserveAspectFit
MouseArea {
anchors.fill: parent
onClicked: {
repeater.currentIndex = -1
view.setCurrentDisplayedGroup = view.currentDisplayedGroup + view.nextNavigation
view.refreshLeftWidget()
}
}
}
}
}
}
diff --git a/src/activities/babymatch/TextItem.qml b/src/activities/babymatch/TextItem.qml
index f5532d5ab..e1c0d738c 100644
--- a/src/activities/babymatch/TextItem.qml
+++ b/src/activities/babymatch/TextItem.qml
@@ -1,78 +1,78 @@
/* GCompris - TextItem.qml
*
* Copyright (C) 2015 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Pulkit Gupta <pulkitgenius@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
Item {
id: displayText
property double posX
property double posY
property double textWidth
property string showText
x: posX * parent.width
y: posY * parent.height
GCText {
id: displayTxt
anchors {
horizontalCenter: parent.horizontalCenter
}
property bool firstTime: true
fontSize: Math.max(Math.min(displayText.parent.width / 20 , 12), 5)
color: "white"
style: Text.Outline
styleColor: "black"
horizontalAlignment: Text.AlignHCenter
width: Math.min(implicitWidth, textWidth * displayText.parent.width)
wrapMode: TextEdit.WordWrap
z: 2
text: showText
onHeightChanged: {
if(firstTime) {
displayTxtContainer.height = displayTxt.height * Math.ceil(displayTxt.implicitWidth / displayTxt.width)
firstTime = false
}
else
displayTxtContainer.height = displayTxt.height
}
}
Rectangle {
id: displayTxtContainer
anchors.top: displayTxt.top
anchors.horizontalCenter: displayTxt.horizontalCenter
width: displayTxt.width + 10
height: displayTxt.fontSize * 2.25 * Math.ceil(displayTxt.implicitWidth / displayTxt.width)
z: 1
opacity: 0.8
radius: 10
border.width: 2
border.color: "black"
gradient: Gradient {
GradientStop { position: 0.0; color: "#000" }
GradientStop { position: 0.9; color: "#666" }
GradientStop { position: 1.0; color: "#AAA" }
}
}
}
diff --git a/src/activities/babymatch/babymatch.js b/src/activities/babymatch/babymatch.js
index 41ee496fa..ad3af13a5 100644
--- a/src/activities/babymatch/babymatch.js
+++ b/src/activities/babymatch/babymatch.js
@@ -1,254 +1,254 @@
/* GCompris - babymatch.js
*
* Copyright (C) 2015 Pulkit Gupta
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
.import GCompris 1.0 as GCompris //for ApplicationInfo
var currentLevel = 1
var currentSubLevel = 0
var numberOfLevel
var numberOfSubLevel
var items
var imagesUrl
var soundsUrl
var boardsUrl
var glowEnabled
var glowEnabledDefault
var spots = []
var showText = []
var displayDropCircle
function start(items_, imagesUrl_, soundsUrl_, boardsUrl_, levelCount_, answerGlow_, displayDropCircle_) {
items = items_
imagesUrl = imagesUrl_
soundsUrl = soundsUrl_
boardsUrl = boardsUrl_
numberOfLevel = levelCount_
glowEnabledDefault = answerGlow_
displayDropCircle = displayDropCircle_
currentLevel = 1
currentSubLevel = 0
numberOfSubLevel = 0
spots = []
showText = []
initLevel()
}
function stop() {
for(var i = 0 ; i < spots.length ; ++ i)
spots[i].destroy()
}
function initLevel() {
items.bar.level = currentLevel
var filename = boardsUrl + "board" + "/" + "board" + currentLevel + "_" + currentSubLevel + ".qml"
items.dataset.source = filename
var levelData = items.dataset.item
items.availablePieces.model.clear()
for(var i = 0 ; i < spots.length ; ++ i)
spots[i].destroy()
spots = []
for(var i = 0 ; i < showText.length ; ++ i)
showText[i].destroy()
showText = []
items.backgroundPiecesModel.clear()
items.backgroundImage.source = ""
items.availablePieces.view.currentDisplayedGroup = 0
items.availablePieces.view.previousNavigation = 1
items.availablePieces.view.nextNavigation = 1
items.availablePieces.view.okShowed = false
items.availablePieces.view.showGlow = false
items.availablePieces.view.ok.height = 0
var dropItemComponent = Qt.createComponent("qrc:/gcompris/src/activities/babymatch/DropAnswerItem.qml")
var textItemComponent = Qt.createComponent("qrc:/gcompris/src/activities/babymatch/TextItem.qml")
//print(dropItemComponent.errorString())
if(currentSubLevel == 0 && levelData.numberOfSubLevel != undefined)
numberOfSubLevel = levelData.numberOfSubLevel
items.score.currentSubLevel = currentSubLevel + 1
items.score.numberOfSubLevels = numberOfSubLevel + 1
- if(levelData.glow == undefined)
+ if(levelData.glow === undefined)
glowEnabled = glowEnabledDefault
else
glowEnabled = levelData.glow
items.toolTip.show('')
- if(levelData.instruction == undefined) {
+ if(levelData.instruction === undefined) {
items.instruction.opacity = 0
items.instruction.text = ""
} else if(!displayDropCircle) {
items.instruction.opacity = 0
items.instruction.text = levelData.instruction
}
else {
items.instruction.opacity = 1
items.instruction.text = levelData.instruction
}
// Fill available pieces
var arr=[], levelDataLength = levelData.levels.length
for(var i=0 ; i < levelDataLength ; i++)
arr[i] = i
var i = 0, j = 0, k = 0, n = 0
while(levelDataLength--) {
//Randomize the order of pieces
var rand = Math.floor(Math.random() * levelDataLength)
i = arr[rand]
arr.splice(rand,1)
//Create answer pieces
if(levelData.levels[i].type === undefined) {
items.availablePieces.model.append( {
"imgName": levelData.levels[i].pixmapfile,
"imgSound": levelData.levels[i].soundFile ?
soundsUrl + levelData.levels[i].soundFile :
"qrc:/gcompris/src/core/resource/sounds/scroll.wav",
- "imgHeight": levelData.levels[i].height == undefined ? 0 : levelData.levels[i].height,
- "imgWidth": levelData.levels[i].width == undefined ? 0 : levelData.levels[i].width,
+ "imgHeight": levelData.levels[i].height === undefined ? 0 : levelData.levels[i].height,
+ "imgWidth": levelData.levels[i].width === undefined ? 0 : levelData.levels[i].width,
"toolTipText":
// We remove the text before the pipe symbol if any (translation disembiguation)
- levelData.levels[i].toolTipText == undefined ?
+ levelData.levels[i].toolTipText === undefined ?
"" :
(levelData.levels[i].toolTipText.split('|').length > 1 ?
levelData.levels[i].toolTipText.split('|')[1] :
levelData.levels[i].toolTipText),
});
spots[j++] = dropItemComponent.createObject(
items.backgroundImage, {
"posX": levelData.levels[i].x,
"posY": levelData.levels[i].y,
"imgName" : levelData.levels[i].pixmapfile,
});
}
//Create Text pieces for the level which has to display additional information
- else if(levelData.levels[i].type == "DisplayText") {
+ else if(levelData.levels[i].type === "DisplayText") {
showText[k++] = textItemComponent.createObject(
items.backgroundImage, {
"posX": levelData.levels[i].x,
"posY": levelData.levels[i].y,
"textWidth": levelData.levels[i].width,
"showText" : levelData.levels[i].text
});
}
//Create static background pieces
else {
if(levelData.levels[i].type === "SHAPE_BACKGROUND_IMAGE") {
items.backgroundImage.source = imagesUrl + levelData.levels[i].pixmapfile
if(levelData.levels[i].width)
items.backgroundImage.sourceSize.width = levelData.levels[i].width
if(levelData.levels[i].height)
items.backgroundImage.sourceSize.height = levelData.levels[i].height
}
else {
items.backgroundPiecesModel.append( {
"imgName": levelData.levels[i].pixmapfile,
"posX": levelData.levels[i].x,
"posY": levelData.levels[i].y,
- "imgHeight": levelData.levels[i].height == undefined ? 0 : levelData.levels[i].height,
- "imgWidth": levelData.levels[i].width == undefined ? 0 : levelData.levels[i].width,
+ "imgHeight": levelData.levels[i].height === undefined ? 0 : levelData.levels[i].height,
+ "imgWidth": levelData.levels[i].width === undefined ? 0 : levelData.levels[i].width,
});
}
}
}
//Initialize displayedGroup variable which is used for showing navigation bars
for(var i=0;i<items.availablePieces.view.nbDisplayedGroup;++i)
items.availablePieces.view.displayedGroup[i] = true
}
function hideInstructions() {
items.instruction.opacity = 0
}
function nextSubLevel() {
if(numberOfSubLevel < ++currentSubLevel) {
currentSubLevel = 0
numberOfSubLevel = 0
nextLevel()
}
else
initLevel()
}
function nextLevel() {
currentSubLevel = 0
numberOfSubLevel = 0
if(numberOfLevel < ++currentLevel) {
currentLevel = 1
}
initLevel()
}
function previousLevel() {
currentSubLevel = 0
numberOfSubLevel = 0
if(--currentLevel < 1) {
currentLevel = numberOfLevel
}
initLevel();
}
function win() {
items.bonus.good("flower")
}
function getClosestSpot(x, y) {
var minDist = 200 * GCompris.ApplicationInfo.ratio
var closestDist = Number.MAX_VALUE
var closestItem
for(var i = 0 ; i < spots.length ; ++ i) {
// Calc Distance
var spot = spots[i]
var dist = Math.floor(Math.sqrt(Math.pow(x - spot.x, 2) +
Math.pow(y - spot.y, 2)))
if(dist < closestDist) {
closestDist = dist
closestItem = spot
}
}
if(closestDist < minDist) {
return closestItem
} else {
return null
}
}
function highLightSpot(stopItem, tile) {
for(var i = 0 ; i < spots.length ; ++ i) {
if(spots[i] === stopItem) {
spots[i].show(tile)
} else {
spots[i].hide()
}
}
}
diff --git a/src/activities/babymatch/resource/board/board1_0.qml b/src/activities/babymatch/resource/board/board1_0.qml
index f166f0f1a..2369db721 100644
--- a/src/activities/babymatch/resource/board/board1_0.qml
+++ b/src/activities/babymatch/resource/board/board1_0.qml
@@ -1,74 +1,74 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Drag and Drop the items to make them match")
property var levels : [
{
"pixmapfile" : "images/lamp.svg",
"x" : "0.2",
"y" : "0.8",
"height" : 0.25,
"width" : 0.25
},
{
"pixmapfile" : "images/postpoint.svg",
"x" : "0.5",
"y" : "0.8",
"height" : 0.25,
"width" : 0.25
},
{
"pixmapfile" : "images/sailingboat.svg",
"x" : "0.8",
"y" : "0.8",
"height" : 0.25,
"width" : 0.25
},
{
"pixmapfile" : "images/light.svg",
"x" : "0.2",
"y" : "0.4",
"type" : "SHAPE_BACKGROUND",
"height" : 0.25,
"width" : 0.25
},
{
"pixmapfile" : "images/postcard.svg",
"x" : "0.5",
"y" : "0.4",
"type" : "SHAPE_BACKGROUND",
"height" : 0.25,
"width" : 0.25
},
{
"pixmapfile" : "images/fishingboat.svg",
"x" : "0.8",
"y" : "0.4",
"type" : "SHAPE_BACKGROUND",
"height" : 0.25,
"width" : 0.25
}
]
}
diff --git a/src/activities/babymatch/resource/board/board2_0.qml b/src/activities/babymatch/resource/board/board2_0.qml
index 3775cf2fe..51e6b6880 100644
--- a/src/activities/babymatch/resource/board/board2_0.qml
+++ b/src/activities/babymatch/resource/board/board2_0.qml
@@ -1,72 +1,72 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property var levels: [
{
"pixmapfile" : "images/flowerpot.svg",
"x" : "0.8",
"y" : "0.7",
"height" : 0.25,
"width" : 0.25
},
{
"pixmapfile" : "images/glass.svg",
"x" : "0.2",
"y" : "0.7",
"height" : 0.25,
"width" : 0.25
},
{
"pixmapfile" : "images/eggpot.svg",
"x" : "0.5",
"y" : "0.7",
"height" : 0.25,
"width" : 0.25
},
{
"pixmapfile" : "images/bottle.svg",
"x" : "0.2",
"y" : "0.3",
"type" : "SHAPE_BACKGROUND",
"height" : 0.25,
"width" : 0.25
},
{
"pixmapfile" : "images/egg.svg",
"x" : "0.5",
"y" : "0.3",
"type" : "SHAPE_BACKGROUND",
"height" : 0.25,
"width" : 0.25
},
{
"pixmapfile" : "images/flower.svg",
"x" : "0.8",
"y" : "0.3",
"type" : "SHAPE_BACKGROUND",
"height" : 0.25,
"width" : 0.25
}
]
}
diff --git a/src/activities/babymatch/resource/board/board3_0.qml b/src/activities/babymatch/resource/board/board3_0.qml
index 23b17022b..e7d2dc010 100644
--- a/src/activities/babymatch/resource/board/board3_0.qml
+++ b/src/activities/babymatch/resource/board/board3_0.qml
@@ -1,73 +1,73 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property var levels: [
{
"pixmapfile" : "images/house.svg",
"x" : "0.5",
"y" : "0.7",
"height" : 0.25,
"width" : 0.25
},
{
"pixmapfile" : "images/star.svg",
"x" : "0.2",
"y" : "0.7",
"height" : 0.25,
"width" : 0.25
},
{
"pixmapfile" : "images/sailingboat.svg",
"x" : "0.8",
"y" : "0.7",
"height" : 0.25,
"width" : 0.25
},
{
"pixmapfile" : "images/fusee.svg",
"x" : "0.2",
"y" : "0.3",
"type" : "SHAPE_BACKGROUND",
"height" : 0.25,
"width" : 0.25
},
{
"pixmapfile" : "images/sofa.svg",
"x" : "0.5",
"y" : "0.3",
"type" : "SHAPE_BACKGROUND",
"height" : 0.25,
"width" : 0.25
},
{
"pixmapfile" : "images/lighthouse.svg",
"x" : "0.8",
"y" : "0.3",
"type" : "SHAPE_BACKGROUND",
"height" : 0.25,
"width" : 0.25
}
]
}
diff --git a/src/activities/babymatch/resource/board/board4_0.qml b/src/activities/babymatch/resource/board/board4_0.qml
index c0a8b1e1f..98160b117 100644
--- a/src/activities/babymatch/resource/board/board4_0.qml
+++ b/src/activities/babymatch/resource/board/board4_0.qml
@@ -1,73 +1,73 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property var levels: [
{
"pixmapfile" : "images/rape.svg",
"x" : "0.8",
"y" : "0.7",
"height" : 0.25,
"width" : 0.25
},
{
"pixmapfile" : "images/car.svg",
"x" : "0.5",
"y" : "0.7",
"height" : 0.25,
"width" : 0.25
},
{
"pixmapfile" : "images/tree.svg",
"x" : "0.2",
"y" : "0.7",
"height" : 0.25,
"width" : 0.25
},
{
"pixmapfile" : "images/apple.svg",
"x" : "0.2",
"y" : "0.3",
"type" : "SHAPE_BACKGROUND",
"height" : 0.25,
"width" : 0.25
},
{
"pixmapfile" : "images/bicycle.svg",
"x" : "0.5",
"y" : "0.3",
"type" : "SHAPE_BACKGROUND",
"height" : 0.25,
"width" : 0.25
},
{
"pixmapfile" : "images/carrot.svg",
"x" : "0.8",
"y" : "0.3",
"type" : "SHAPE_BACKGROUND",
"height" : 0.25,
"width" : 0.25
}
]
}
diff --git a/src/activities/babymatch/resource/board/board5_0.qml b/src/activities/babymatch/resource/board/board5_0.qml
index 675e04792..4db457256 100644
--- a/src/activities/babymatch/resource/board/board5_0.qml
+++ b/src/activities/babymatch/resource/board/board5_0.qml
@@ -1,73 +1,73 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property var levels: [
{
"pixmapfile" : "images/postcard.svg",
"x" : "0.2",
"y" : "0.7",
"height" : 0.25,
"width" : 0.25
},
{
"pixmapfile" : "images/tuxplane.svg",
"x" : "0.5",
"y" : "0.7",
"height" : 0.25,
"width" : 0.25
},
{
"pixmapfile" : "images/minivan.svg",
"x" : "0.8",
"y" : "0.7",
"height" : 0.25,
"width" : 0.25
},
{
"pixmapfile" : "images/pencil.svg",
"x" : "0.2",
"y" : "0.3",
"type" : "SHAPE_BACKGROUND",
"height" : 0.25,
"width" : 0.25
},
{
"pixmapfile" : "images/tuxhelico.svg",
"x" : "0.5",
"y" : "0.3",
"type" : "SHAPE_BACKGROUND",
"height" : 0.25,
"width" : 0.25
},
{
"pixmapfile" : "images/truck.svg",
"x" : "0.8",
"y" : "0.3",
"type" : "SHAPE_BACKGROUND",
"height" : 0.25,
"width" : 0.25
}
]
}
diff --git a/src/activities/babymatch/resource/board/board6_0.qml b/src/activities/babymatch/resource/board/board6_0.qml
index fd52349bb..099c9b143 100644
--- a/src/activities/babymatch/resource/board/board6_0.qml
+++ b/src/activities/babymatch/resource/board/board6_0.qml
@@ -1,73 +1,73 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property var levels: [
{
"pixmapfile" : "images/crown.svg",
"x" : "0.2",
"y" : "0.7",
"height" : 0.25,
"width" : 0.25
},
{
"pixmapfile" : "images/windflag5.svg",
"x" : "0.5",
"y" : "0.7",
"height" : 0.25,
"width" : 0.25
},
{
"pixmapfile" : "images/football.svg",
"x" : "0.8",
"y" : "0.7",
"height" : 0.25,
"width" : 0.25
},
{
"pixmapfile" : "images/castle.svg",
"x" : "0.2",
"y" : "0.3",
"type" : "SHAPE_BACKGROUND",
"height" : 0.25,
"width" : 0.25
},
{
"pixmapfile" : "images/sailingboat.svg",
"x" : "0.5",
"y" : "0.3",
"type" : "SHAPE_BACKGROUND",
"height" : 0.25,
"width" : 0.25
},
{
"pixmapfile" : "images/raquette.svg",
"x" : "0.8",
"y" : "0.3",
"type" : "SHAPE_BACKGROUND",
"height" : 0.25,
"width" : 0.25
}
]
}
diff --git a/src/activities/babymatch/resource/board/board7_0.qml b/src/activities/babymatch/resource/board/board7_0.qml
index 3c4f9bd16..adb1c2890 100644
--- a/src/activities/babymatch/resource/board/board7_0.qml
+++ b/src/activities/babymatch/resource/board/board7_0.qml
@@ -1,73 +1,73 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property var levels: [
{
"pixmapfile" : "images/bell.svg",
"x" : "0.5",
"y" : "0.7",
"height" : 0.25,
"width" : 0.25
},
{
"pixmapfile" : "images/lamp.svg",
"x" : "0.2",
"y" : "0.7",
"height" : 0.25,
"width" : 0.25
},
{
"pixmapfile" : "images/lifebuoy.svg",
"x" : "0.8",
"y" : "0.7",
"height" : 0.25,
"width" : 0.25
},
{
"pixmapfile" : "images/sun.svg",
"x" : "0.2",
"y" : "0.3",
"type" : "SHAPE_BACKGROUND",
"height" : 0.25,
"width" : 0.25
},
{
"pixmapfile" : "images/sound.svg",
"x" : "0.5",
"y" : "0.3",
"type" : "SHAPE_BACKGROUND",
"height" : 0.25,
"width" : 0.25
},
{
"pixmapfile" : "images/umbrella.svg",
"x" : "0.8",
"y" : "0.3",
"type" : "SHAPE_BACKGROUND",
"height" : 0.25,
"width" : 0.25
}
]
}
diff --git a/src/activities/babyshapes/ActivityInfo.qml b/src/activities/babyshapes/ActivityInfo.qml
index e7fb2770f..28d978b19 100644
--- a/src/activities/babyshapes/ActivityInfo.qml
+++ b/src/activities/babyshapes/ActivityInfo.qml
@@ -1,44 +1,44 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Pulkit Gupta <pulkitgenius@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "babyshapes/Babyshapes.qml"
difficulty: 1
icon: "babyshapes/babyshapes.svg"
author: "Pulkit Gupta &lt;pulkitgenius@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Complete the puzzle")
//: Help title
description: qsTr("Drag and Drop the shapes on their respective targets")
// intro: "Drag and drop the objects matching the shapes."
//: Help goal
goal: ""
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("Complete the puzzle by dragging each piece from the set of pieces on the left, to the matching space in the puzzle.")
credit: qsTr("The dog is provided by Andre Connes and released under the GPL")
section: "discovery"
createdInVersion: 4000
}
diff --git a/src/activities/babyshapes/Babyshapes.qml b/src/activities/babyshapes/Babyshapes.qml
index 636c78f4b..c4108a241 100644
--- a/src/activities/babyshapes/Babyshapes.qml
+++ b/src/activities/babyshapes/Babyshapes.qml
@@ -1,34 +1,34 @@
/* GCompris - Babyshapes.qml
*
* Copyright (C) 2015 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Bruno Coudoin (bruno.coudoin@gcompris.net) / Andre Connes (andre.connes@toulouse.iufm.fr) (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../babymatch"
Babymatch {
id: activity
onStart: focus = true
onStop: {}
boardsUrl: "qrc:/gcompris/src/activities/babyshapes/resource/"
levelCount: 7
}
diff --git a/src/activities/babyshapes/resource/board/board1_0.qml b/src/activities/babyshapes/resource/board/board1_0.qml
index 9f718ff1f..4ab12aad0 100644
--- a/src/activities/babyshapes/resource/board/board1_0.qml
+++ b/src/activities/babyshapes/resource/board/board1_0.qml
@@ -1,95 +1,95 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Drag and Drop the items to make them match")
property var levels: [
{
"pixmapfile" : "food/baby_bottle.png",
"x" : "0.5",
"y" : "0.25"
},
{
"pixmapfile" : "food/orange.png",
"x" : "0.2",
"y" : "0.75"
},
{
"pixmapfile" : "food/cookie.png",
"x" : "0.8",
"y" : "0.75"
},
{
"pixmapfile" : "food/chocolate.png",
"x" : "0.5",
"y" : "0.75"
},
{
"pixmapfile" : "food/marmelade.png",
"x" : "0.8",
"y" : "0.25"
},
{
"pixmapfile" : "food/butter.png",
"x" : "0.2",
"y" : "0.25"
},
{
"pixmapfile" : "shapeBackground/T_butter.png",
"x" : "0.2",
"y" : "0.25",
"type" : "SHAPE_BACKGROUND"
},
{
"pixmapfile" : "shapeBackground/T_baby_bottle.png",
"x" : "0.5",
"y" : "0.25",
"type" : "SHAPE_BACKGROUND"
},
{
"pixmapfile" : "shapeBackground/T_marmelade.png",
"x" : "0.8",
"y" : "0.25",
"type" : "SHAPE_BACKGROUND"
},
{
"pixmapfile" : "shapeBackground/T_orange.png",
"x" : "0.2",
"y" : "0.75",
"type" : "SHAPE_BACKGROUND"
},
{
"pixmapfile" : "shapeBackground/T_chocolate.png",
"x" : "0.5",
"y" : "0.75",
"type" : "SHAPE_BACKGROUND"
},
{
"pixmapfile" : "shapeBackground/T_cookie.png",
"x" : "0.8",
"y" : "0.75",
"type" : "SHAPE_BACKGROUND"
}
]
}
diff --git a/src/activities/babyshapes/resource/board/board2_0.qml b/src/activities/babyshapes/resource/board/board2_0.qml
index 4cce2c4a2..06c65c327 100644
--- a/src/activities/babyshapes/resource/board/board2_0.qml
+++ b/src/activities/babyshapes/resource/board/board2_0.qml
@@ -1,93 +1,93 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property var levels: [
{
"pixmapfile" : "food/bread_slice.png",
"x" : "0.5",
"y" : "0.75"
},
{
"pixmapfile" : "food/banana.png",
"x" : "0.8",
"y" : "0.25"
},
{
"pixmapfile" : "food/yahourt.png",
"x" : "0.5",
"y" : "0.25"
},
{
"pixmapfile" : "food/suggar_box.png",
"x" : "0.2",
"y" : "0.75"
},
{
"pixmapfile" : "food/french_croissant.png",
"x" : "0.2",
"y" : "0.25"
},
{
"pixmapfile" : "food/baby_bottle.png",
"x" : "0.8",
"y" : "0.75"
},
{
"pixmapfile" : "shapeBackground/T_french_croissant.png",
"x" : "0.2",
"y" : "0.25",
"type" : "SHAPE_BACKGROUND"
},
{
"pixmapfile" : "shapeBackground/T_yahourt.png",
"x" : "0.5",
"y" : "0.25",
"type" : "SHAPE_BACKGROUND"
},
{
"pixmapfile" : "shapeBackground/T_banana.png",
"x" : "0.8",
"y" : "0.25",
"type" : "SHAPE_BACKGROUND"
},
{
"pixmapfile" : "shapeBackground/T_suggar_box.png",
"x" : "0.2",
"y" : "0.75",
"type" : "SHAPE_BACKGROUND"
},
{
"pixmapfile" : "shapeBackground/T_bread_slice.png",
"x" : "0.5",
"y" : "0.75",
"type" : "SHAPE_BACKGROUND"
},
{
"pixmapfile" : "shapeBackground/T_baby_bottle.png",
"x" : "0.8",
"y" : "0.75",
"type" : "SHAPE_BACKGROUND"
}
]
}
diff --git a/src/activities/babyshapes/resource/board/board3_0.qml b/src/activities/babyshapes/resource/board/board3_0.qml
index 67badd18f..51d60cab8 100644
--- a/src/activities/babyshapes/resource/board/board3_0.qml
+++ b/src/activities/babyshapes/resource/board/board3_0.qml
@@ -1,93 +1,93 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property var levels: [
{
"pixmapfile" : "food/pear.png",
"x" : "0.2",
"y" : "0.75"
},
{
"pixmapfile" : "food/yahourt.png",
"x" : "0.5",
"y" : "0.75"
},
{
"pixmapfile" : "food/milk_shake.png",
"x" : "0.8",
"y" : "0.25"
},
{
"pixmapfile" : "food/grapefruit.png",
"x" : "0.2",
"y" : "0.25"
},
{
"pixmapfile" : "food/chocolate_cake.png",
"x" : "0.5",
"y" : "0.25"
},
{
"pixmapfile" : "food/milk_cup.png",
"x" : "0.8",
"y" : "0.75"
},
{
"pixmapfile" : "shapeBackground/T_grapefruit.png",
"x" : "0.2",
"y" : "0.25",
"type" : "SHAPE_BACKGROUND"
},
{
"pixmapfile" : "shapeBackground/T_chocolate_cake.png",
"x" : "0.5",
"y" : "0.25",
"type" : "SHAPE_BACKGROUND"
},
{
"pixmapfile" : "shapeBackground/T_milk_shake.png",
"x" : "0.8",
"y" : "0.25",
"type" : "SHAPE_BACKGROUND"
},
{
"pixmapfile" : "shapeBackground/T_pear.png",
"x" : "0.2",
"y" : "0.75",
"type" : "SHAPE_BACKGROUND"
},
{
"pixmapfile" : "shapeBackground/T_yahourt.png",
"x" : "0.5",
"y" : "0.75",
"type" : "SHAPE_BACKGROUND"
},
{
"pixmapfile" : "shapeBackground/T_milk_cup.png",
"x" : "0.8",
"y" : "0.75",
"type" : "SHAPE_BACKGROUND"
}
]
}
diff --git a/src/activities/babyshapes/resource/board/board4_0.qml b/src/activities/babyshapes/resource/board/board4_0.qml
index 715620984..cf1bf848a 100644
--- a/src/activities/babyshapes/resource/board/board4_0.qml
+++ b/src/activities/babyshapes/resource/board/board4_0.qml
@@ -1,93 +1,93 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property var levels: [
{
"pixmapfile" : "food/yahourt.png",
"x" : "0.5",
"y" : "0.75"
},
{
"pixmapfile" : "food/baby_bottle.png",
"x" : "0.5",
"y" : "0.25"
},
{
"pixmapfile" : "food/pear.png",
"x" : "0.2",
"y" : "0.75"
},
{
"pixmapfile" : "food/banana.png",
"x" : "0.2",
"y" : "0.25"
},
{
"pixmapfile" : "food/milk_cup.png",
"x" : "0.8",
"y" : "0.75"
},
{
"pixmapfile" : "food/round_cookie.png",
"x" : "0.8",
"y" : "0.25"
},
{
"pixmapfile" : "shapeBackground/T_banana.png",
"x" : "0.2",
"y" : "0.25",
"type" : "SHAPE_BACKGROUND"
},
{
"pixmapfile" : "shapeBackground/T_baby_bottle.png",
"x" : "0.5",
"y" : "0.25",
"type" : "SHAPE_BACKGROUND"
},
{
"pixmapfile" : "shapeBackground/T_round_cookie.png",
"x" : "0.8",
"y" : "0.25",
"type" : "SHAPE_BACKGROUND"
},
{
"pixmapfile" : "shapeBackground/T_pear.png",
"x" : "0.2",
"y" : "0.75",
"type" : "SHAPE_BACKGROUND"
},
{
"pixmapfile" : "shapeBackground/T_yahourt.png",
"x" : "0.5",
"y" : "0.75",
"type" : "SHAPE_BACKGROUND"
},
{
"pixmapfile" : "shapeBackground/T_milk_cup.png",
"x" : "0.8",
"y" : "0.75",
"type" : "SHAPE_BACKGROUND"
}
]
}
diff --git a/src/activities/babyshapes/resource/board/board5_0.qml b/src/activities/babyshapes/resource/board/board5_0.qml
index c66cd81da..7abc53565 100644
--- a/src/activities/babyshapes/resource/board/board5_0.qml
+++ b/src/activities/babyshapes/resource/board/board5_0.qml
@@ -1,47 +1,47 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Hello! My name is Lock.")
property var levels: [
{
"pixmapfile" : "dog1/dog.png",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "dog1/dog1.png",
"x" : "0.295",
"y" : "0.745"
},
{
"pixmapfile" : "dog1/dog2.png",
"x" : "0.793",
"y" : "0.45"
},
{
"pixmapfile" : "dog1/dog3.png",
"x" : "0.355",
"y" : "0.25"
}
]
}
diff --git a/src/activities/babyshapes/resource/board/board6_0.qml b/src/activities/babyshapes/resource/board/board6_0.qml
index e3029d986..3e7afd48a 100644
--- a/src/activities/babyshapes/resource/board/board6_0.qml
+++ b/src/activities/babyshapes/resource/board/board6_0.qml
@@ -1,63 +1,63 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Lock with colored shapes.")
property bool glow: false
property var levels: [
{
"pixmapfile" : "dog3/dog.png",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "dog3/dog1.png",
"x" : "0.74",
"y" : "0.771"
},
{
"pixmapfile" : "dog3/dog2.png",
"x" : "0.199",
"y" : "0.726"
},
{
"pixmapfile" : "dog3/dog3.png",
"x" : "0.28",
"y" : "0.303"
},
{
"pixmapfile" : "dog3/dog4.png",
"x" : "0.859",
"y" : "0.301"
},
{
"pixmapfile" : "dog3/dog5.png",
"x" : "0.568",
"y" : "0.206"
},
{
"pixmapfile" : "dog3/dog6.png",
"x" : "0.473",
"y" : "0.692"
}
]
}
diff --git a/src/activities/babyshapes/resource/board/board7_0.qml b/src/activities/babyshapes/resource/board/board7_0.qml
index 416d54b5a..182e77449 100644
--- a/src/activities/babyshapes/resource/board/board7_0.qml
+++ b/src/activities/babyshapes/resource/board/board7_0.qml
@@ -1,51 +1,51 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property int numberOfSubLevel: 4
property string instruction: qsTr("Paul Gauguin, Arearea - 1892")
property var levels: [
{
"pixmapfile" : "image/Paul_Gauguin_006_background.png",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "image/Paul_Gauguin_006_chien.png",
"dropAreaSize" : "10",
"x" : "0.278",
"y" : "0.807"
},
{
"pixmapfile" : "image/Paul_Gauguin_006_jeunes_filles.png",
"dropAreaSize" : "10",
"x" : "0.666",
"y" : "0.46"
},
{
"pixmapfile" : "image/Paul_Gauguin_006_statue.png",
"dropAreaSize" : "10",
"x" : "0.19",
"y" : "0.133"
}
]
}
diff --git a/src/activities/babyshapes/resource/board/board7_1.qml b/src/activities/babyshapes/resource/board/board7_1.qml
index 5f39fc8c8..2400c57d3 100644
--- a/src/activities/babyshapes/resource/board/board7_1.qml
+++ b/src/activities/babyshapes/resource/board/board7_1.qml
@@ -1,56 +1,56 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Pieter Bruegel the Elder, The peasants wedding - 1568")
property var levels: [
{
"pixmapfile" : "image/Pieter_Bruegel_background.png",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "image/Pieter_Bruegel_service.png",
"dropAreaSize" : "10",
"x" : "0.684",
"y" : "0.628"
},
{
"pixmapfile" : "image/Pieter_Bruegel_mur.png",
"dropAreaSize" : "10",
"x" : "0.866",
"y" : "0.143"
},
{
"pixmapfile" : "image/Pieter_Bruegel_musicien.png",
"dropAreaSize" : "10",
"x" : "0.257",
"y" : "0.453"
},
{
"pixmapfile" : "image/Pieter_Bruegel_fillette.png",
"dropAreaSize" : "10",
"x" : "0.354",
"y" : "0.87"
}
]
}
diff --git a/src/activities/babyshapes/resource/board/board7_2.qml b/src/activities/babyshapes/resource/board/board7_2.qml
index dd55cb79a..355e82a40 100644
--- a/src/activities/babyshapes/resource/board/board7_2.qml
+++ b/src/activities/babyshapes/resource/board/board7_2.qml
@@ -1,62 +1,62 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("The Lady and the Unicorn - XVe century")
property var levels: [
{
"pixmapfile" : "image/lady_unicorn_background.png",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "image/lady_unicorn_5.png",
"dropAreaSize" : "10",
"x" : "0.07",
"y" : "0.818"
},
{
"pixmapfile" : "image/lady_unicorn_4.png",
"dropAreaSize" : "10",
"x" : "0.256",
"y" : "0.666"
},
{
"pixmapfile" : "image/lady_unicorn_2.png",
"dropAreaSize" : "10",
"x" : "0.462",
"y" : "0.553"
},
{
"pixmapfile" : "image/lady_unicorn_3.png",
"dropAreaSize" : "10",
"x" : "0.724",
"y" : "0.883"
},
{
"pixmapfile" : "image/lady_unicorn_1.png",
"dropAreaSize" : "10",
"x" : "0.877",
"y" : "0.039"
}
]
}
diff --git a/src/activities/babyshapes/resource/board/board7_3.qml b/src/activities/babyshapes/resource/board/board7_3.qml
index d6880581e..02b7470a5 100644
--- a/src/activities/babyshapes/resource/board/board7_3.qml
+++ b/src/activities/babyshapes/resource/board/board7_3.qml
@@ -1,62 +1,62 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Vincent van Gogh, Bedroom in Arles - 1888")
property var levels: [
{
"pixmapfile" : "image/Van_Gogh_0011_background.png",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "image/Van_Gogh_0011_5.png",
"dropAreaSize" : "10",
"x" : "0.695",
"y" : "0.54"
},
{
"pixmapfile" : "image/Van_Gogh_0011_4.png",
"dropAreaSize" : "10",
"x" : "0.673",
"y" : "0.068"
},
{
"pixmapfile" : "image/Van_Gogh_0011_3.png",
"dropAreaSize" : "10",
"x" : "0.491",
"y" : "0.14"
},
{
"pixmapfile" : "image/Van_Gogh_0011_1.png",
"dropAreaSize" : "10",
"x" : "0.25",
"y" : "0.434"
},
{
"pixmapfile" : "image/Van_Gogh_0011_2.png",
"dropAreaSize" : "10",
"x" : "0.086",
"y" : "0.61"
}
]
}
diff --git a/src/activities/babyshapes/resource/board/board7_4.qml b/src/activities/babyshapes/resource/board/board7_4.qml
index 838c7ead7..6b6eaa219 100644
--- a/src/activities/babyshapes/resource/board/board7_4.qml
+++ b/src/activities/babyshapes/resource/board/board7_4.qml
@@ -1,68 +1,68 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Ambrosius Bosschaert the Elder, Flower Still Life - 1614")
property var levels: [
{
"pixmapfile" : "image/Bosschaert_04_background.png",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "image/Bosschaert_04_6.png",
"dropAreaSize" : "10",
"x" : "0.432",
"y" : "0.732"
},
{
"pixmapfile" : "image/Bosschaert_04_5.png",
"dropAreaSize" : "10",
"x" : "0.553",
"y" : "0.3"
},
{
"pixmapfile" : "image/Bosschaert_04_4.png",
"dropAreaSize" : "10",
"x" : "0.481",
"y" : "0.486"
},
{
"pixmapfile" : "image/Bosschaert_04_3.png",
"dropAreaSize" : "10",
"x" : "0.217",
"y" : "0.233"
},
{
"pixmapfile" : "image/Bosschaert_04_2.png",
"dropAreaSize" : "10",
"x" : "0.167",
"y" : "0.582"
},
{
"pixmapfile" : "image/Bosschaert_04_1.png",
"dropAreaSize" : "10",
"x" : "0.653",
"y" : "0.749"
}
]
}
diff --git a/src/activities/balancebox/ActivityInfo.qml b/src/activities/balancebox/ActivityInfo.qml
index 7d7421f01..10a9bafd7 100644
--- a/src/activities/balancebox/ActivityInfo.qml
+++ b/src/activities/balancebox/ActivityInfo.qml
@@ -1,60 +1,60 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Holger Kaelberer <holger.k@elberer.de>
*
* Authors:
* Holger Kaelberer <holger.k@elberer.de>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "balancebox/Balancebox.qml"
difficulty: 2
icon: "balancebox/balancebox.svg"
author: "Holger Kaelberer &lt;holger.k@elberer.de&gt;"
demo: true
//: Activity title
title: qsTr("Balance Box")
//: Help title
description: qsTr("Navigate the ball to the door by tilting the box.")
// intro: "Tilt the box to navigate the ball to the door."
//: Help goal
goal: qsTr("Practice fine motor skills and basic counting.")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("Navigate the ball to the door. Be careful not to make it fall into the holes. Numbered-contact buttons in the box need to be touched in the correct order to unlock the door. You can move the ball by tilting your mobile device. On desktop platforms use the arrow keys to simulate tilting.
In the <b>configuration dialog</b> you can choose between the default 'Built-in' level set and one that you can define yourself ('User'). A user-defined level set can be created by choosing the 'user' level set and start the level editor by clicking on the corresponding button.
In the <b>level editor</b> you can create your own levels. Choose one of the editing tools on the left side to modify the map cells of the currently active level in the editor:
Cross: Clear a map cell completely
Horizontal Wall: Set/remove a horizontal wall on the lower edge of a cell
Vertical Wall: Set/remove a vertical wall on the right edge of a cell
Hole: Set/remove a hole on a cell
Ball: Set the starting position of the ball
Door: Set the door position
Contact: Set/remove a contact button. With the spin-box you can adjust the value of the contact button. It is not possible to set a value more than once on a map.
All tools (except the clear-tool) toggle their respective target on the clicked cell: An item can be placed by clicking on an empty cell, and by clicking again on the same cell with the same tool, you can remove it again.
You can test a modified level by clicking on the 'Test' button on the right side of the editor view. You can return from testing mode by clicking on the home-button on the bar or by pressing escape on your keyboard or the back-button on your mobile device.
In the editor you can change the level currently edited by using the arrow buttons on the bar. Back in the editor you can continue editing the current level and test it again if needed.
When your level is finished you can save it to the user level file by clicking on the 'Save' button on the right side.
To return to the configuration dialog click on the home-button on the bar or press Escape on your keyboard or the back button on your mobile device.")
credit: ""
section: "mobile fun"
- enabled: !ApplicationInfo.isMobile || ApplicationInfo.sensorIsSupported("QTiltSensor")
+ enabled: ApplicationInfo.isBox2DInstalled && (!ApplicationInfo.isMobile || ApplicationInfo.sensorIsSupported("QTiltSensor"))
createdInVersion: 5000
}
diff --git a/src/activities/balancebox/BalanceContact.qml b/src/activities/balancebox/BalanceContact.qml
index 051a385f2..0cd2c9b9f 100644
--- a/src/activities/balancebox/BalanceContact.qml
+++ b/src/activities/balancebox/BalanceContact.qml
@@ -1,53 +1,53 @@
/* GCompris - BalanceContact.qml
*
* Copyright (C) 2014-2015 Holger Kaelberer <holger.k@elberer.de>
*
* Authors:
* Holger Kaelberer <holger.k@elberer.de>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import Box2D 2.0
import "../../core"
import "balancebox.js" as Activity
BalanceItem {
id: item
property var pressed: false
property int orderNum
property alias text: itemText.text
imageSource: pressed ? Activity.baseUrl + "/button-pressed.svg"
: Activity.baseUrl + "/button-normal.svg"
GCText {
id: itemText
anchors.fill: item
anchors.centerIn: item
width: item.width
height: item.height
font.pointSize: NaN
font.pixelSize: width / 2
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
diff --git a/src/activities/balancebox/BalanceItem.qml b/src/activities/balancebox/BalanceItem.qml
index c0955209d..0df046466 100644
--- a/src/activities/balancebox/BalanceItem.qml
+++ b/src/activities/balancebox/BalanceItem.qml
@@ -1,94 +1,94 @@
/* GCompris - BalanceItem.qml
*
* Copyright (C) 2014-2015 Holger Kaelberer <holger.k@elberer.de>
*
* Authors:
* Holger Kaelberer <holger.k@elberer.de>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import Box2D 2.0
import QtGraphicalEffects 1.0
import "../../core"
Item {
id: item
z: 2 // above most
property alias world: itemBody.world
property alias imageSource: itemImage.source
property alias body: itemBody
property alias bodyType: itemBody.bodyType
property alias linearDamping: itemBody.linearDamping
property alias fixtures: itemBody.fixtures
property alias sensor: itemFixture.sensor
property alias categories: itemFixture.categories
property alias collidesWith: itemFixture.collidesWith
property alias density: itemFixture.density
property alias friction: itemFixture.friction
property alias restitution: itemFixture.restitution
property alias shadow: itemShadow.visible
property alias shadowHorizontalOffset: itemShadow.horizontalOffset
property alias shadowVerticalOffset: itemShadow.verticalOffset
signal beginContact(Item item, Item other)
signal endContact(Item item, Item other)
Image {
id: itemImage
width: item.width
height: item.height
source: item.imageSource
anchors.centerIn: parent
}
DropShadow {
id: itemShadow
anchors.fill: itemImage
cached: true
visible: false // note: dropping shadows for the walls is really expensive
// in terms of CPU usage!
radius: 0
samples: 16
color: "#80000000"
source: itemImage
}
Body {
id: itemBody
target: item
bodyType: Body.Static
sleepingAllowed: false
fixedRotation: true
linearDamping: 0
fixtures: Circle {
id: itemFixture
radius: itemImage.width / 2
onBeginContact: item.beginContact(getBody().target, other.getBody().target)
onEndContact: item.endContact(getBody().target, other.getBody().target)
}
}
}
diff --git a/src/activities/balancebox/Balancebox.qml b/src/activities/balancebox/Balancebox.qml
index a9d32bc0f..6cf717bb8 100644
--- a/src/activities/balancebox/Balancebox.qml
+++ b/src/activities/balancebox/Balancebox.qml
@@ -1,572 +1,609 @@
/* GCompris - balancebox.qml
*
* Copyright (C) 2014-2016 Holger Kaelberer <holger.k@elberer.de>
*
* Authors:
* Holger Kaelberer <holger.k@elberer.de>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
-import QtQuick.Window 2.1
+import QtQuick.Window 2.2
import QtSensors 5.0
import QtGraphicalEffects 1.0
import GCompris 1.0
import Box2D 2.0
import QtQuick.Controls 1.5
import "../../core"
import "editor/"
import "balancebox.js" as Activity
import "qrc:/gcompris/src/core/core.js" as Core
ActivityBase {
id: activity
property string mode: "play" // "play" or "test"
property string levelSet: "builtin" // "builtin" or "user"
+ // When the user launches the activity in "user" mode by default(due to previously save config mode) for the first time after updating GCompris, default user file must be loaded as they must be having created levels in it.
+ // From next time onwards, the saved file path is loaded. Refer to line 567.
+ property string loadedFilePath: (levelSet == "builtin") ? Activity.builtinFile : Activity.userFile
property var testLevel
property bool inForeground: false // to avoid unneeded reconfigurations
property bool alwaysStart: true // enforce start signal for editor-to-testing- and returning from config-transition
property bool needRestart: true
- onWidthChanged:if (inForeground && pageView.currentItem === activity)
+ onWidthChanged: if (inForeground && pageView.currentItem === activity)
Activity.reconfigureScene();
onHeightChanged: if (inForeground && pageView.currentItem === activity)
Activity.reconfigureScene();
onStart: {
inForeground = true;
focus = true;
}
onStop: inForeground = false;
Keys.onPressed: Activity.processKeyPress(event.key)
Keys.onReleased: Activity.processKeyRelease(event.key)
pageComponent: Image {
id: background
source: Activity.baseUrl + "/maze_bg.svg"
sourceSize.width: parent.width
anchors.fill: parent
signal start
signal stop
function startEditor() {
editorLoader.active = true;
if (activity.mode == "test")
displayDialogs([dialogActivityConfig, editorLoader.item]);
else
displayDialog(editorLoader.item);
}
function handleBackEvent() {
if (activity.mode == "test") {
startEditor();
return true;
} else
return false;
}
Keys.onEscapePressed: event.accepted = handleBackEvent();
Keys.onReleased: {
if (event.key === Qt.Key_Back)
event.accepted = handleBackEvent();
}
Component.onCompleted: {
dialogActivityConfig.getInitialConfiguration()
activity.start.connect(start)
activity.stop.connect(stop)
items.dpi = Math.round(Screen.pixelDensity*25.4);
}
onStart: if (activity.needRestart) {
Activity.start(items);
activity.needRestart = false;
} else
Activity.initLevel();
onStop: {
Activity.stop();
activity.needRestart = true;
}
QtObject {
id: items
property string mode: activity.mode
property string levelSet: activity.levelSet
+ property string filePath: activity.loadedFilePath
property var testLevel: activity.testLevel
property Item main: activity.main
property alias background: background
property alias bar: bar
property alias bonus: bonus
property alias tilt: tilt
property alias timer: timer
property alias ball: ball
+ property alias file: file
property int ballSize: cellSize - 2*wallSize
property alias mapWrapper: mapWrapper
property int cellSize: mapWrapper.length / Math.min(mapWrapper.rows, mapWrapper.columns)
property int wallSize: cellSize / 5
property var world: physicsWorld
property alias keyboardTimer: keyboardTimer
property var ballType: Fixture.Category1
property var wallType: Fixture.Category2
property var holeType: Fixture.Category3
property var goalType: Fixture.Category4
property var buttonType: Fixture.Category5
property alias parser: parser
property double dpi
property GCSfx audioEffects: activity.audioEffects
property Loading loading: activity.loading
}
Loader {
id: editorLoader
active: false
sourceComponent: BalanceboxEditor {
id: editor
visible: true
testBox: activity
onClose: activity.home()
}
}
JsonParser {
id: parser
onError: console.error("Balancebox: Error parsing JSON: " + msg);
}
Rectangle {
id: mapWrapper
property double margin: 20
property int columns: 0
property int rows: 0
property double length: Math.min(background.height -
2*mapWrapper.margin, background.width - 2*mapWrapper.margin);
color: "#E3DEDB"
width: length
height: length
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
transform: [
Rotation {
origin.x: mapWrapper.width / 2
origin.y: mapWrapper.height / 2
axis { x: 1; y: 0; z: 0 }
angle: ApplicationInfo.isMobile ? 0 : -items.tilt.xRotation
},
Rotation {
origin.x: mapWrapper.width / 2
origin.y: mapWrapper.height / 2
axis { x: 0; y: 1; z: 0 }
angle: ApplicationInfo.isMobile ? 0 : items.tilt.yRotation
}
]
// right:
Wall {
id: rightWall
width: items.wallSize
height: parent.height + items.wallSize
anchors.left: mapWrapper.right
anchors.leftMargin: - items.wallSize/2
anchors.top: parent.top
anchors.topMargin: -items.wallSize/2
shadow: false
shadowHorizontalOffset: Math.min(items.tilt.yRotation, items.wallSize)
shadowVerticalOffset: Math.min(items.tilt.xRotation, items.wallSize)
}
// bottom:
Wall {
id: bottomWall
width: parent.width + items.wallSize
height: items.wallSize
anchors.left: mapWrapper.left
anchors.leftMargin: - items.wallSize/2
anchors.top: parent.bottom
anchors.topMargin: -items.wallSize/2
shadow: false
shadowHorizontalOffset: Math.min(items.tilt.yRotation, items.wallSize)
shadowVerticalOffset: Math.min(items.tilt.xRotation, items.wallSize)
}
// top:
Wall {
id: topWall
width: parent.width + items.wallSize
height: items.wallSize
anchors.left: mapWrapper.left
anchors.leftMargin: - items.wallSize/2
anchors.top: parent.top
anchors.topMargin: -items.wallSize/2
shadow: false
shadowHorizontalOffset: Math.min(items.tilt.yRotation, items.wallSize)
shadowVerticalOffset: Math.min(items.tilt.xRotation, items.wallSize)
}
// left:
Wall {
id: leftWall
width: items.wallSize
height: parent.height + items.wallSize
anchors.left: mapWrapper.left
anchors.leftMargin: - items.wallSize/2
anchors.top: parent.top
anchors.topMargin: -items.wallSize/2
shadow: false
shadowHorizontalOffset: Math.min(items.tilt.yRotation, items.wallSize)
shadowVerticalOffset: Math.min(items.tilt.xRotation, items.wallSize)
}
BalanceItem {
id: ball
world: physicsWorld
imageSource: Activity.baseUrl + "/ball.svg"
visible: false
scale: 1.0
width: items.ballSize
height: items.ballSize
z: 3 // above other BalanceItems
categories: items.ballType
collidesWith: items.wallType | items.holeType | items.goalType
| items.buttonType
density: 1
friction: Activity.friction
linearDamping: Activity.friction
restitution: Activity.restitution
bodyType: Body.Dynamic
shadow: true
shadowHorizontalOffset: (items.tilt.yRotation > 0) ? Math.min(items.tilt.yRotation, items.wallSize) : Math.max(items.tilt.yRotation, -items.wallSize)
shadowVerticalOffset: (items.tilt.xRotation > 0) ? Math.min(items.tilt.xRotation, items.wallSize) : Math.max(items.tilt.xRotation, -items.wallSize)
Behavior on scale {
NumberAnimation {
id: fallAnimation
duration: 1000
}
}
-
+
onBeginContact: {
if (other.categories !== items.wallType)
Activity.addBallContact(other);
else {
// sound-effect on each contact with a wall might be too annoying:
//items.audioEffects.stop();
//items.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/brick.wav");
}
}
onEndContact: {
if (other.categories !== items.wallType)
Activity.removeBallContact(other);
}
}
World {
id: physicsWorld
gravity: Qt.point(0, 0) // we calculate acceleration ourselves
pixelsPerMeter: Activity.box2dPpm // default: 32
timeStep: Activity.step/1000 // default: 1/60
}
DebugDraw {
id: debugDraw
world: physicsWorld
visible: Activity.debugDraw
z: 100
}
}
-
+
Timer {
id: timer
interval: Activity.step;
running: false;
repeat: true
onTriggered: Activity.moveBall()
}
Item {
id: tilt
property double xRotation: 0
property double yRotation: 0
property bool swapAxes: false
property bool invertX: false
property bool invertY: false
onXRotationChanged: {
if (xRotation > 90)
xRotation = 90;
else if (xRotation < -90)
xRotation = -90;
}
onYRotationChanged: {
if (yRotation > 90)
yRotation = 90;
else if (yRotation < -90)
yRotation = -90;
}
-
+
TiltSensor {
id: tiltSensor
active: ApplicationInfo.isMobile ? true : false
onReadingChanged: {
if (!tilt.swapAxes) {
tilt.xRotation = tilt.invertX ? -reading.xRotation : reading.xRotation;
tilt.yRotation = tilt.invertY ? -reading.yRotation : reading.yRotation;
} else {
tilt.xRotation = tilt.invertX ? -reading.yRotation : reading.yRotation;
tilt.yRotation = tilt.invertY ? -reading.xRotation : reading.xRotation;
}
tiltText.text = "X/Y Rotation: "
+ tiltSensor.reading.xRotation
+ "/" + tiltSensor.reading.yRotation
}
}
}
Item {
id: textWrapper
anchors.left: parent.left
anchors.top: parent.top
width: parent.width
height: parent.height / 3
visible: Activity.debugDraw
Text {
id: tiltText
anchors.left: parent.left
anchors.top: parent.top
text: "X/Y Rotation: " + tilt.xRotation + "/" + tilt.yRotation
font.pointSize: 12
}
Text {
id: posText
anchors.left: parent.left
anchors.top: tiltText.bottom
text: "X/Y = " + ball.x + "/" + ball.y
font.pointSize: 12
}
}
MultiPointTouchArea {
anchors.fill: parent
touchPoints: [ TouchPoint { id: point1 } ]
property real startX
property real startY
property int offset: 30
function reset() {
startX = point1.x
startY = point1.y
}
onPressed: {
reset()
}
onUpdated: {
var moveX = point1.x - startX
var moveY = point1.y - startY
// Find the direction with the most move
if(Math.abs(moveX) * ApplicationInfo.ratio > offset &&
Math.abs(moveX) > Math.abs(moveY)) {
if(moveX > offset * ApplicationInfo.ratio) {
Activity.processKeyPress(Qt.Key_Right)
reset()
} else if(moveX < -offset * ApplicationInfo.ratio) {
Activity.processKeyPress(Qt.Key_Left)
reset()
}
} else if(Math.abs(moveY) * ApplicationInfo.ratio > offset &&
Math.abs(moveX) < Math.abs(moveY)) {
if(moveY > offset * ApplicationInfo.ratio) {
Activity.processKeyPress(Qt.Key_Down)
reset()
} else if(moveY < -offset * ApplicationInfo.ratio) {
Activity.processKeyPress(Qt.Key_Up)
reset()
}
}
}
onReleased: {
Activity.keyboardIsTilting = false
}
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: BarEnumContent {
value: activity.mode == "play"
? (help | home | level | config )
: ( help | home )
}
onHelpClicked: {
// stop everything or the ball keeps moving while we're away:
items.timer.stop();
displayDialog(dialogHelp);
}
onPreviousLevelClicked: if (!Activity.finishRunning)
Activity.previousLevel()
onNextLevelClicked: if (!Activity.finishRunning)
Activity.nextLevel()
onHomeClicked: {
if (activity.mode == "test")
background.startEditor();
else
activity.home()
}
onConfigClicked: {
items.timer.stop();
dialogActivityConfig.active = true
// Set default values
dialogActivityConfig.setDefaultValues();
displayDialog(dialogActivityConfig)
}
}
Bonus {
id: bonus
looseSound: "qrc:/gcompris/src/core/resource/sounds/crash.wav"
Component.onCompleted: {
win.connect(Activity.nextLevel);
loose.connect(Activity.initLevel);
}
}
Timer {
id: keyboardTimer
interval: Activity.keyboardTimeStep;
running: false
repeat: false
onTriggered: Activity.keyboardHandler()
}
+ GCCreationHandler {
+ id: creationHandler
+ readonly property bool isEditorActive: editorLoader.active && editorLoader.item.visible
+ onFileLoaded: {
+ if(!isEditorActive)
+ activity.loadedFilePath = filePath
+ else
+ editorLoader.item.filename = filePath
+ close()
+ }
+ parent: isEditorActive ? editorLoader.item : dialogActivityConfig
+ }
+
+ File {
+ id: file
+ }
+
DialogActivityConfig {
id: dialogActivityConfig
currentActivity: activity
content: Component {
Item {
property alias levelsBox: levelsBox
-
property var availableLevels: [
{ "text": qsTr("Built-in"), "value": "builtin" },
{ "text": qsTr("User"), "value": "user" },
]
Flow {
id: flow
spacing: 5
width: dialogActivityConfig.width
GCComboBox {
id: levelsBox
model: availableLevels
background: dialogActivityConfig
label: qsTr("Select your level set")
}
- Button {
- id: editorButton
- style: GCButtonStyle {}
- height: levelsBox.height
- text: qsTr("Start Editor")
- visible: levelsBox.currentIndex == 1
- onClicked: background.startEditor()
+ Column {
+ spacing: 5
+ Button {
+ id: editorButton
+ style: GCButtonStyle {}
+ height: levelsBox.height
+ text: qsTr("Start Editor")
+ visible: levelsBox.currentIndex == 1
+ onClicked: background.startEditor()
+ }
+
+ Button {
+ id: loadButton
+ style: GCButtonStyle {}
+ height: levelsBox.height
+ text: qsTr("Load saved levels")
+ visible: levelsBox.currentIndex == 1
+ onClicked: creationHandler.loadWindow()
+ }
}
}
}
}
onClose: home();
onLoadData: {
if(dataToSave && dataToSave["levels"]) {
activity.levelSet = dataToSave["levels"];
+ if(dataToSave['filePath'])
+ activity.loadedFilePath = dataToSave["filePath"]
}
}
onSaveData: {
var newLevels = dialogActivityConfig.configItem
.availableLevels[dialogActivityConfig.configItem.levelsBox.currentIndex].value;
- if (newLevels !== activity.levelSet) {
+ var initialFilePath = dataToSave['filePath'] ? dataToSave['filePath'] : ""
+ if(newLevels === "builtin")
+ activity.loadedFilePath = Activity.builtinFile
+ if (newLevels !== activity.levelSet || initialFilePath != activity.loadedFilePath) {
activity.levelSet = newLevels;
- dataToSave = {"levels": activity.levelSet};
+ dataToSave = {"levels": activity.levelSet, "filePath": activity.loadedFilePath};
activity.needRestart = true;
}
}
dataValidationFunc: function() {
var newLevels = dialogActivityConfig.configItem
- .availableLevels[dialogActivityConfig.configItem.levelsBox.currentIndex].value;
- if (newLevels === "user" &&
- !parser.jsonFile.exists(Activity.userFile)) {
+ .availableLevels[dialogActivityConfig.configItem.levelsBox.currentIndex].value
+ if (newLevels === "user" && activity.loadedFilePath === Activity.builtinFile) {
Core.showMessageDialog(dialogActivityConfig,
qsTr("You selected the user-defined level set, but you have not yet defined any user levels!<br/> " +
"Either create your user levels by starting the level editor or choose the 'built-in' level set."),
qsTr("Ok"), null,
"", null,
null);
return false;
}
return true;
}
function setDefaultValues() {
for(var i = 0 ;
i < dialogActivityConfig.configItem.availableLevels.length;
i ++) {
if(dialogActivityConfig.configItem.availableLevels[i].value === activity.levelSet) {
dialogActivityConfig.configItem.levelsBox.currentIndex = i;
break;
}
}
}
}
}
}
diff --git a/src/activities/balancebox/CMakeLists.txt b/src/activities/balancebox/CMakeLists.txt
index e11e390e7..a9c22279a 100644
--- a/src/activities/balancebox/CMakeLists.txt
+++ b/src/activities/balancebox/CMakeLists.txt
@@ -1,3 +1 @@
-if(NOT QML_BOX2D_MODULE STREQUAL disabled)
- GCOMPRIS_ADD_RCC(activities/balancebox *.qml *.svg *.js resource/* editor/*)
-endif()
+GCOMPRIS_ADD_RCC(activities/balancebox *.qml *.svg *.js resource/* editor/*)
diff --git a/src/activities/balancebox/Goal.qml b/src/activities/balancebox/Goal.qml
index 07947ea18..eff9e3bb2 100644
--- a/src/activities/balancebox/Goal.qml
+++ b/src/activities/balancebox/Goal.qml
@@ -1,77 +1,77 @@
/* GCompris - Goal.qml
*
* Copyright (C) 2014-2015 Holger Kaelberer <holger.k@elberer.de>
*
* Authors:
* Holger Kaelberer <holger.k@elberer.de>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import Box2D 2.0
import "../../core"
import "balancebox.js" as Activity
Item {
id: goal
property alias world: itemBody.world
property alias imageSource: goalImage.source
property alias body: itemBody
property alias bodyType: itemBody.bodyType
property alias linearDamping: itemBody.linearDamping
property alias fixtures: itemBody.fixtures
property alias sensor: itemFixture.sensor
property alias categories: itemFixture.categories
property alias collidesWith: itemFixture.collidesWith
property alias density: itemFixture.density
property alias friction: itemFixture.friction
property alias restitution: itemFixture.restitution
signal beginContact(Item item, Item other)
signal endContact(Item item, Item other)
Image {
id: goalImage
width: goal.width
height: goal.height
source: Activity.baseUrl + "/door_closed.svg"
anchors.centerIn: parent
}
Body {
id: itemBody
target: goal
bodyType: Body.Static
world: physicsWorld
sleepingAllowed: false
fixedRotation: true
linearDamping: 0
fixtures: Box {
id: itemFixture
categories: Circle.Category4
width: goal.width
height: goal.height
density: 0
friction: 0
restitution: 0
sensor: true
}
}
}
diff --git a/src/activities/balancebox/Wall.qml b/src/activities/balancebox/Wall.qml
index 524f2ad8d..b96196eb1 100644
--- a/src/activities/balancebox/Wall.qml
+++ b/src/activities/balancebox/Wall.qml
@@ -1,81 +1,81 @@
/* GCompris - Wall.qml
*
* Copyright (C) 2014-2015 Holger Kaelberer <holger.k@elberer.de>
*
* Authors:
* Holger Kaelberer <holger.k@elberer.de>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import Box2D 2.0
import QtGraphicalEffects 1.0
import "balancebox.js" as Activity
Item {
id: item
transformOrigin: Item.TopLeft
property alias body: itemBody
property alias world: itemBody.world
property alias categories: itemFixture.categories
property alias shadow: itemShadow.visible
//property bool shadow: false //itemShadow.visible
property alias shadowHorizontalOffset: itemShadow.horizontalOffset
property alias shadowVerticalOffset: itemShadow.verticalOffset
Body {
id: itemBody
target: item
world: physicsWorld
active: item.visible
fixtures: Box {
id: itemFixture
width: item.width
height: item.height
friction: 0.0
density: 1
restitution: Activity.restitution
categories: Box.Category2
- collidesWith: Box.Category1 | Box.Category2
+ collidesWith: Box.Category1
}
}
Rectangle {
id: itemRectangle
anchors.fill: parent
width: parent.width
height: parent.height
radius: height / 2
color: "#B38B56"
z: 2
}
DropShadow {
id: itemShadow
anchors.fill: itemRectangle
cached: true
visible: false // note: dropping shadows for the walls is really expensive
// in terms of CPU usage!
radius: 0
samples: 16
color: "#80000000"
source: itemRectangle
z: 1
}
}
diff --git a/src/activities/balancebox/balancebox.js b/src/activities/balancebox/balancebox.js
index 7515a3f2a..af3c2eb1b 100644
--- a/src/activities/balancebox/balancebox.js
+++ b/src/activities/balancebox/balancebox.js
@@ -1,556 +1,564 @@
/* GCompris - balancebox.js
*
* Copyright (C) 2014-2016 Holger Kaelberer <holger.k@elberer.de>
*
* Authors:
* Holger Kaelberer <holger.k@elberer.de>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
/* ToDo:
- make sensitivity configurable
- editor: add 'clear' button
- editor: allow going back: level 1 -> last level
- add new item: unordered contact, that has to be collected but in an
arbitrary order
*/
.pragma library
.import QtQuick 2.6 as Quick
.import GCompris 1.0 as GCompris
.import Box2D 2.0 as Box2D
.import "qrc:/gcompris/src/core/core.js" as Core
.import QtQml 2.2 as Qml
Qt.include("balancebox_common.js")
var dataset = null;
// Parameters that control the ball's dynamics
var m = 0.2; // without ppm-correction: 10
var g = 9.81; // without ppm-correction: 50.8
var box2dPpm = 32; // pixelsPerMeter used in Box2D's world
var boardSizeM = 0.9; // board's real edge length, fixed to 90 cm
var boardSizePix = 500; // board's current size in pix (acquired dynamically)
var dpiBase=139;
var boardSizeBase = 760;
var curDpi = null;
var pixelsPerMeter = null;
var vFactor = pixelsPerMeter / box2dPpm; // FIXME: calculate!
var step = 20; // time step (in ms)
var friction = 0.15;
var restitution = 0.3; // rebounce factor
// stuff for keyboard based tilting
var keyboardTiltStep = 0.5; // degrees
var keyboardTimeStep = 20; // ms
var lastKey;
var keyboardIsTilting = false; // tilting or resetting to horizontal
var debugDraw = false;
var currentLevel = 0;
var numberOfLevel = 0;
var items;
var level;
var map; // current map
var goal = null;
var holes = new Array();
var walls = new Array();
var contacts = new Array();
var ballContacts = new Array();
var goalUnlocked;
var lastContact;
var wallComponent = Qt.createComponent("qrc:/gcompris/src/activities/balancebox/Wall.qml");
var contactComponent = Qt.createComponent("qrc:/gcompris/src/activities/balancebox/BalanceContact.qml");
var balanceItemComponent = Qt.createComponent("qrc:/gcompris/src/activities/balancebox/BalanceItem.qml");
var goalComponent = Qt.createComponent("qrc:/gcompris/src/activities/balancebox/Goal.qml");
var contactIndex = -1;
var pendingObjects = 0;
var pendingReconfigure = false;
var finishRunning = false;
function start(items_) {
items = items_;
currentLevel = 0;
if (items.mode === "play") {
if (GCompris.ApplicationInfo.isMobile) {
// we don't have many touch events, therefore disable screensaver on android:
GCompris.ApplicationInfo.setKeepScreenOn(true);
// lock screen orientation to landscape:
GCompris.ApplicationInfo.setRequestedOrientation(0);
if (GCompris.ApplicationInfo.getNativeOrientation() === Qt.PortraitOrientation) {
/*
* Adjust tilting if native orientation != landscape.
*
* Note: As of Qt 5.4.1 QTiltSensor as well as QRotationSensor
* report on Android
* isFeatureSupported(AxesOrientation) == false.
* Therefore we honour rotation manually.
*/
items.tilt.swapAxes = true;
items.tilt.invertX = true;
}
}
var levelsFile;
- if (items.levelSet === "user")
- levelsFile = userFile;
+ if (items.levelSet === "user" && items.file.exists(items.filePath))
+ levelsFile = items.filePath;
else {
+ if(items.levelSet === "user") {
+ Core.showMessageDialog(items.background,
+ // The argument represents the file path name to be loaded.
+ qsTr("The file '%1' is missing!<br>Falling back to builtin levels.").arg(items.filePath),
+ "", null,
+ "", null,
+ null);
+ }
levelsFile = builtinFile;
currentLevel = GCompris.ApplicationSettings.loadActivityProgress(
"balancebox");
}
dataset = items.parser.parseFromUrl(levelsFile, validateLevels);
if (dataset == null) {
console.error("Balancebox: Error loading levels from " + levelsFile
+ ", can't continue!");
return;
}
} else {
// testmode:
dataset = [items.testLevel];
}
numberOfLevel = dataset.length;
reconfigureScene();
}
function reconfigureScene()
{
if (items === undefined || items.mapWrapper === undefined)
return;
if (pendingObjects > 0) {
pendingReconfigure = true;
return;
}
// set up dynamic variables for movement:
pixelsPerMeter = (items.mapWrapper.length / boardSizeBase) * boardSizePix / boardSizeM;
vFactor = pixelsPerMeter / box2dPpm;
// console.log("Starting: mode=" + items.mode
// + " pixelsPerM=" + items.world.pixelsPerMeter
// + " timeStep=" + items.world.timeStep
// + " posIterations=" + items.world.positionIterations
// + " velIterations=" + items.world.velocityIterations
// + " boardSizePix" + boardSizePix + " (real " + items.mapWrapper.length + ")"
// + " pixelsPerMeter=" + pixelsPerMeter
// + " vFactor=" + vFactor
// + " dpi=" + items.dpi
// + " nativeOrientation=" + GCompris.ApplicationInfo.getNativeOrientation());
initLevel();
}
function sinDeg(num)
{
return Math.sin(num/180*Math.PI);
}
function moveBall()
{
var dt = step / 1000;
var dvx = g*dt * sinDeg(items.tilt.yRotation);
var dvy = g*dt * sinDeg(items.tilt.xRotation);
// console.log("moving ball: dv: " + items.ball.body.linearVelocity.x
// + "/" + items.ball.body.linearVelocity.y
// + " -> " + (items.ball.body.linearVelocity.x+dvx)
// + "/" + (items.ball.body.linearVelocity.y+dvy));
items.ball.body.linearVelocity.x += dvx * vFactor;
items.ball.body.linearVelocity.y += dvy * vFactor;
checkBallContacts();
}
function checkBallContacts()
{
for (var k = 0; k < ballContacts.length; k++) {
if (items.ball.x > ballContacts[k].x - items.ballSize/2 &&
items.ball.x < ballContacts[k].x + items.ballSize/2 &&
items.ball.y > ballContacts[k].y - items.ballSize/2 &&
items.ball.y < ballContacts[k].y + items.ballSize/2) {
// collision
- if (ballContacts[k].categories == items.holeType)
+ if (ballContacts[k].categories === items.holeType)
finishBall(false, ballContacts[k].x, ballContacts[k].y);
- else if (ballContacts[k].categories == items.goalType && goalUnlocked)
+ else if (ballContacts[k].categories === items.goalType && goalUnlocked)
finishBall(true,
ballContacts[k].x + (items.cellSize - items.wallSize - items.ballSize)/2,
ballContacts[k].y + (items.cellSize - items.wallSize - items.ballSize)/2);
- else if (ballContacts[k].categories == items.buttonType) {
+ else if (ballContacts[k].categories === items.buttonType) {
if (!ballContacts[k].pressed
- && ballContacts[k].orderNum == lastContact + 1)
+ && ballContacts[k].orderNum === lastContact + 1)
{
ballContacts[k].pressed = true;
lastContact = ballContacts[k].orderNum;
- if (lastContact == contacts.length) {
+ if (lastContact === contacts.length) {
items.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/win.wav");
goalUnlocked = true;
goal.imageSource = baseUrl + "/door.svg";
} else
items.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/scroll.wav"); // bleep
}
}
}
}
}
function finishBall(won, x, y)
{
finishRunning = true;
items.timer.stop();
items.keyboardTimer.stop();
items.ball.x = x;
items.ball.y = y;
items.ball.scale = 0.4;
items.ball.body.linearVelocity = Qt.point(0, 0);
if (won) {
items.bonus.good("flower");
if (items.levelSet === "builtin" && items.mode === "play") {
GCompris.ApplicationSettings.saveActivityProgress("balancebox",
currentLevel+1 >= numberOfLevel ? 0 : currentLevel+1);
}
} else
items.bonus.bad("flower");
}
function stop() {
// reset everything
tearDown();
if(goal) {
goal.destroy()
goal = null
}
// unlock screen orientation
if (GCompris.ApplicationInfo.isMobile) {
GCompris.ApplicationInfo.setKeepScreenOn(false);
GCompris.ApplicationInfo.setRequestedOrientation(-1);
}
// make sure loading overlay is really stopped
items.loading.stop();
}
function createObject(component, properties)
{
var p = properties;
p.world = items.world;
var object = component.createObject(items.mapWrapper, p);
return object;
}
var incubators; // need to reference all returned incubators in global scope
// or things don't work
function incubateObject(targetArr, component, properties)
{
var p = properties;
p.world = items.world;
var incubator = component.incubateObject(items.mapWrapper, p);
if (incubator === null) {
console.error("Error during object incubation!");
items.loading.stop();
return;
}
incubators.push(incubator);
if (incubator.status === Qml.Component.Ready)
targetArr.push(incubator.object);
else if (incubator.status === Qml.Component.Loading) {
pendingObjects++;
incubator.onStatusChanged = function(status) {
if (status === Qml.Component.Ready)
targetArr.push(incubator.object);
else
console.error("Error during object creation!");
if (--pendingObjects === 0) {
// initMap completed
if (pendingReconfigure) {
pendingReconfigure = false;
reconfigureScene();
} else {
items.timer.start();
items.loading.stop();
}
}
}
} else
console.error("Error during object creation!");
}
function initMap()
{
incubators = new Array();
goalUnlocked = true;
finishRunning = false;
items.mapWrapper.rows = map.length;
items.mapWrapper.columns = map[0].length;
pendingObjects = 0;
for (var row = 0; row < map.length; row++) {
for (var col = 0; col < map[row].length; col++) {
var x = col * items.cellSize;
var y = row * items.cellSize;
var currentCase = map[row][col];
var orderNum = (currentCase & 0xFF00) >> 8;
// debugging:
if (debugDraw) {
try {
var rect = Qt.createQmlObject(
"import QtQuick 2.6;Rectangle{"
+"width:" + items.cellSize +";"
+"height:" + items.cellSize+";"
+"x:" + x + ";"
+"y:" + y +";"
+"color: \"transparent\";"
+"border.color: \"blue\";"
+"border.width: 1;"
+"}", items.mapWrapper);
} catch (e) {
console.error("Error creating object: " + e);
}
}
if (currentCase & NORTH) {
incubateObject(walls, wallComponent, {
x: x-items.wallSize/2,
y: y-items.wallSize/2,
width: items.cellSize + items.wallSize,
height: items.wallSize,
shadow: false});
}
if (currentCase & SOUTH) {
incubateObject(walls, wallComponent, {
x: x-items.wallSize/2,
y: y+items.cellSize-items.wallSize/2,
width: items.cellSize+items.wallSize,
height: items.wallSize,
shadow: false});
}
if (currentCase & EAST) {
incubateObject(walls, wallComponent, {
x: x+items.cellSize-items.wallSize/2,
y: y-items.wallSize/2,
width: items.wallSize,
height: items.cellSize+items.wallSize,
shadow: false});
}
if (currentCase & WEST) {
incubateObject(walls, wallComponent, {
x: x-items.wallSize/2,
y: y-items.wallSize/2,
width: items.wallSize,
height: items.cellSize+items.wallSize,
shadow: false});
}
if (currentCase & START) {
items.ball.x = col * items.cellSize + items.wallSize;
items.ball.y = row * items.cellSize + items.wallSize;
items.ball.visible = true;
}
if (currentCase & GOAL) {
var goalX = col * items.cellSize + items.wallSize/2;
var goalY = row * items.cellSize + items.wallSize/2;
if(goal === null) {
goal = createObject(goalComponent, {
x: goalX,
y: goalY,
width: items.cellSize - items.wallSize,
height: items.cellSize - items.wallSize,
imageSource: baseUrl + "/door_closed.svg",
categories: items.goalType,
sensor: true});
}
else {
goal.x = goalX;
goal.y = goalY;
goal.width = items.cellSize - items.wallSize;
goal.height = goal.width;
goal.imageSource = baseUrl + "/door_closed.svg";
}
}
if (currentCase & HOLE) {
var holeX = col * items.cellSize + items.wallSize;
var holeY = row * items.cellSize + items.wallSize;
incubateObject(holes, balanceItemComponent, {
x: holeX,
y: holeY,
width: items.ballSize,
height: items.ballSize,
imageSource: baseUrl + "/hole.svg",
density: 0,
friction: 0,
restitution: 0,
categories: items.holeType,
sensor: true});
}
if (orderNum > 0) {
var contactX = col * items.cellSize + items.wallSize/2;
var contactY = row * items.cellSize + items.wallSize/2;
goalUnlocked = false;
incubateObject(contacts, contactComponent, {
x: contactX,
y: contactY,
width: items.cellSize - items.wallSize,
height: items.cellSize - items.wallSize,
pressed: false,
density: 0,
friction: 0,
restitution: 0,
categories: items.buttonType,
sensor: true,
orderNum: orderNum,
text: level.targets[orderNum-1]});
}
}
}
if (goalUnlocked && goal) // if we have no contacts at all
goal.imageSource = baseUrl + "/door.svg";
if (pendingObjects === 0) {
// don't have any pending objects (e.g. empty map!): stop overlay
items.timer.start();
items.loading.stop();
}
}
function addBallContact(item)
{
if (ballContacts.indexOf(item) !== -1)
return;
ballContacts.push(item);
}
function removeBallContact(item)
{
var index = ballContacts.indexOf(item);
if (index > -1)
ballContacts.splice(index, 1);
}
function tearDown()
{
items.ball.body.linearVelocity = Qt.point(0, 0);
items.ball.scale = 1;
items.ball.visible = false;
items.timer.stop();
items.keyboardTimer.stop();
if (holes.length > 0) {
for (var i = 0; i< holes.length; i++)
holes[i].destroy();
holes.length = 0;
}
if (walls.length > 0) {
for (var i = 0; i< walls.length; i++)
walls[i].destroy();
walls.length = 0;
}
if (contacts.length > 0) {
for (var i = 0; i< contacts.length; i++)
contacts[i].destroy();
contacts.length = 0;
}
lastContact = 0;
items.tilt.xRotation = 0;
items.tilt.yRotation = 0;
ballContacts = new Array();
}
function initLevel(testLevel) {
items.loading.start();
items.bar.level = currentLevel + 1;
// reset everything
tearDown();
level = dataset[currentLevel];
map = level.map
initMap();
}
// keyboard tilting stuff:
function keyboardHandler()
{
var MAX_TILT = 5
if (keyboardIsTilting) {
if (lastKey == Qt.Key_Left && items.tilt.yRotation > -MAX_TILT)
items.tilt.yRotation -= keyboardTiltStep;
else if (lastKey == Qt.Key_Right && items.tilt.yRotation < MAX_TILT)
items.tilt.yRotation += keyboardTiltStep;
else if (lastKey == Qt.Key_Up && items.tilt.xRotation > -MAX_TILT)
items.tilt.xRotation -= keyboardTiltStep;
else if (lastKey == Qt.Key_Down && items.tilt.xRotation < MAX_TILT)
items.tilt.xRotation += keyboardTiltStep;
items.keyboardTimer.start();
} else {// is resetting
// yRotation:
if (items.tilt.yRotation < 0)
items.tilt.yRotation = Math.min(items.tilt.yRotation + keyboardTiltStep, 0);
else if (items.tilt.yRotation > 0)
items.tilt.yRotation = Math.max(items.tilt.yRotation - keyboardTiltStep, 0);
// xRotation:
if (items.tilt.xRotation < 0)
items.tilt.xRotation = Math.min(items.tilt.xRotation + keyboardTiltStep, 0);
else if (items.tilt.xRotation > 0)
items.tilt.xRotation = Math.max(items.tilt.xRotation - keyboardTiltStep, 0);
// resetting done?
if (items.tilt.yRotation != 0 || items.tilt.xRotation != 0)
items.keyboardTimer.start();
}
}
function processKeyPress(key)
{
if (key == Qt.Key_Left
|| key == Qt.Key_Right
|| key == Qt.Key_Up
|| key == Qt.Key_Down) {
lastKey = key;
keyboardIsTilting = true;
items.keyboardTimer.stop();
keyboardHandler();
}
}
function processKeyRelease(key)
{
if (key == Qt.Key_Left
|| key == Qt.Key_Right
|| key == Qt.Key_Up
|| key == Qt.Key_Down) {
lastKey = key;
keyboardIsTilting = false;
items.keyboardTimer.stop();
keyboardHandler();
}
}
function nextLevel() {
if(numberOfLevel <= ++currentLevel) {
currentLevel = 0
}
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
initLevel();
}
diff --git a/src/activities/balancebox/balancebox_common.js b/src/activities/balancebox/balancebox_common.js
index 86861b8de..070ffa252 100644
--- a/src/activities/balancebox/balancebox_common.js
+++ b/src/activities/balancebox/balancebox_common.js
@@ -1,77 +1,77 @@
/* GCompris - balancebox_common.js
*
* Copyright (C) 2015 Holger Kaelberer <holger.k@elberer.de>
*
* Authors:
* Holger Kaelberer <holger.k@elberer.de>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
/**
* Level description format:
*
* Example:
* [ { "level": 1,
* "map": [ [ 0x0000, 0x0308, ... ],
* [ 0x0010, 0x0008, ... ],
* ...
* ],
* "targets": [ 1, 2, 3, 5, 10, ... ]
* },
* { "level": 2, ... }
* ...
* ]
*
* "level": Number of the level.
* "map": Definition of the map inside the balancebox.
* The map is a 2-dimensional array of map cells. A cell is
* described by a bitmask of 16 bit with the lower 8bit defining walls,
* objects, etc. (cf. below) and the higher 8 bit defining the order of
* buttons present on the map. The values of the buttons are described
* in the "targets" property.
* "targets": Values of the buttons present on the map. Most likely these will
* be numbers, but letters are also possible. The order in which they
* need to be pressed by the ball is defined in the higher 8 bits of
* the map fields.
*/
var EMPTY = 0x0000;
var NORTH = 0x0001;
var EAST = 0x0002;
var SOUTH = 0x0004;
var WEST = 0x0008;
// all the following are mutually exclusive:
var START = 0x0010;
var GOAL = 0x0020;
var HOLE = 0x0040;
var CONTACT = 0x0080;
var baseUrl = "qrc:/gcompris/src/activities/balancebox/resource";
var builtinFile = baseUrl + "/levels-default.json";
-var userFile = "file://" + GCompris.ApplicationInfo.getSharedWritablePath()
+var userFile = "file://" + GCompris.ApplicationSettings.userDataPath
+ "/balancebox/" + "levels-user.json"
function validateLevels(doc)
{
// minimal syntax check:
if (undefined === doc || !Array.isArray(doc) || doc.length < 1)
return false;
for (var i = 0; i < doc.length; i++) {
if (undefined === doc[i].map || !Array.isArray(doc[i].map) ||
doc[i].map.length < 1)
return false;
}
return true;
}
diff --git a/src/activities/balancebox/editor/BalanceboxEditor.qml b/src/activities/balancebox/editor/BalanceboxEditor.qml
index ab410d18d..a0d42899c 100644
--- a/src/activities/balancebox/editor/BalanceboxEditor.qml
+++ b/src/activities/balancebox/editor/BalanceboxEditor.qml
@@ -1,670 +1,679 @@
/* GCompris - BalanceboxEditor.qml
*
* Copyright (C) 2015 Holger Kaelberer <holger.k@elberer.de>
*
* Authors:
* Holger Kaelberer <holger.k@elberer.de>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import QtGraphicalEffects 1.0
import GCompris 1.0
import QtQuick.Controls 1.5
import "../../../core"
import ".."
import "balanceboxeditor.js" as Activity
Item {
id: editor
- property string filename: Activity.userFile
+ property string filename: ""
+ onFilenameChanged: Activity.initEditor(props)
property ActivityBase currentActivity
property var testBox
property bool isTesting: false
// props needed for stackView integration:
signal close
signal start
signal stop
property bool isDialog: true
property bool alwaysStart: true // enforce start signal for configDialog-to-editor-transition
function handleBackEvent()
{
if (!isTesting) {
if (Activity.levelChanged)
Activity.warnUnsavedChanges(function() {stop(); home();},
function() {});
else {
stop();
home();
}
return true;
} else
return false;
}
Keys.onEscapePressed: event.accepted = handleBackEvent();
Keys.onReleased: {
if (event.key === Qt.Key_Back) {
event.accepted = handleBackEvent();
} else
event.accepted = false;
}
onStart: {
focus = true;
if (!isTesting)
Activity.initEditor(props);
else
stopTesting();
}
onStop: testBox.focus = true;
QtObject {
id: props
property int columns: 10
property int rows: 10
property int currentTool
property alias editor: editor
property alias mapModel: mapModel
property alias mapWrapper: mapWrapper
property int cellSize: mapWrapper.length / Math.min(mapWrapper.rows, mapWrapper.columns)
property int wallSize: cellSize / 5
property int ballSize: cellSize - 2*wallSize
property alias toolBox: toolBox
property string contactValue: "1"
property int lastOrderNum: 0
property alias file: file
property alias parser: parser
property alias bar: bar
property int lastGoalIndex: -1
property int lastBallIndex: -1
property alias editorWorker: editorWorker
}
function startTesting() {
editor.isTesting = true;
testBox.mode = "test";
testBox.testLevel = Activity.modelToLevel();
testBox.needRestart = true;
back(testBox);
}
function stopTesting() {
editor.isTesting = false;
testBox.mode = "play";
testBox.testLevel = null;
testBox.needRestart = true;
}
Rectangle {
id: background
anchors.fill: parent
File {
id: file
onError: console.error("File error: " + msg);
}
JsonParser {
id: parser
onError: console.error("Balanceboxeditor: Error parsing JSON: " + msg);
}
Column {
id: toolBox2
anchors.top: mapWrapper.top
anchors.left: mapWrapper.right
anchors.leftMargin: 10 * ApplicationInfo.ratio
anchors.topMargin: 20 * ApplicationInfo.ratio
spacing: 5 * ApplicationInfo.ratio
width: (background.width - mapWrapper.width - props.wallSize - 20 * ApplicationInfo.ratio) / 2
height: parent.height
// anchors.topMargin: 20
+ Button {
+ id: loadButton
+ width: parent.width
+ height: props.cellSize
+ style: GCButtonStyle {}
+ text: qsTr("Load")
+ onClicked: creationHandler.loadWindow()
+ }
Button {
id: saveButton
width: parent.width
height: props.cellSize
style: GCButtonStyle {}
text: qsTr("Save")
- onClicked: Activity.saveModel();
+ onClicked: creationHandler.saveWindow(Activity.saveModel())
}
Button {
id: testButton
width: parent.width
height: props.cellSize
style: GCButtonStyle {}
text: qsTr("Test")
onClicked: editor.startTesting();
}
}
Column {
id: toolBox
anchors.top: mapWrapper.top
anchors.topMargin: 20 * ApplicationInfo.ratio
anchors.left: parent.left
anchors.leftMargin: 10
width: (mapWrapper.x - 20)
spacing: 5 * ApplicationInfo.ratio
Component.onCompleted: clearTool.selected = true;
function setCurrentTool(item)
{
props.currentTool = item.type;
if (clearTool !== item) clearTool.selected = false;
if (hWallTool !== item) hWallTool.selected = false;
if (vWallTool !== item) vWallTool.selected = false;
if (holeTool !== item) holeTool.selected = false;
if (ballTool !== item) ballTool.selected = false;
if (contactTool !== item) contactTool.selected = false;
if (goalTool !== item) goalTool.selected = false;
}
EditorTool {
id: clearTool
type: Activity.TOOL_CLEAR
anchors.horizontalCenter: parent.horizontalCenter
width: parent.width
height: props.cellSize - 2
onSelectedChanged: {
if (selected) {
toolBox.setCurrentTool(clearTool);
}
}
Image {
id: clear
source: "qrc:/gcompris/src/core/resource/cancel.svg"
width: props.cellSize - 4
height: props.cellSize - 4
anchors.centerIn: parent
anchors.margins: 3
}
}
EditorTool {
id: hWallTool
type: Activity.TOOL_H_WALL
anchors.horizontalCenter: parent.horizontalCenter
width: parent.width
height: props.cellSize
onSelectedChanged: {
if (selected) {
toolBox.setCurrentTool(hWallTool);
}
}
Wall {
id: hWall
width: props.cellSize
height: props.wallSize
anchors.centerIn: parent
anchors.margins: 3
}
}
EditorTool {
id: vWallTool
anchors.horizontalCenter: parent.horizontalCenter
width: parent.width
height: props.cellSize
type: Activity.TOOL_V_WALL
onSelectedChanged: {
if (selected) {
toolBox.setCurrentTool(vWallTool);
}
}
Wall {
id: vWall
width: props.wallSize
height: props.cellSize - 4
anchors.centerIn: parent
anchors.margins: 3
}
}
EditorTool {
id: holeTool
anchors.horizontalCenter: parent.horizontalCenter
width: parent.width
height: props.cellSize
type: Activity.TOOL_HOLE
onSelectedChanged: {
if (selected) {
toolBox.setCurrentTool(holeTool);
}
}
BalanceItem {
id: hole
width: props.cellSize - props.wallSize / 2
height: props.cellSize - props.wallSize / 2
anchors.centerIn: parent
anchors.margins: props.wallSize / 2
visible: true
imageSource: Activity.baseUrl + "/hole.svg"
}
}
EditorTool {
id: ballTool
anchors.horizontalCenter: parent.horizontalCenter
width: parent.width
height: props.cellSize
type: Activity.TOOL_BALL
onSelectedChanged: {
if (selected) {
toolBox.setCurrentTool(ballTool);
}
}
BalanceItem {
id: ball
width: props.cellSize - props.wallSize / 2
height: parent.height - props.wallSize / 2
anchors.centerIn: parent
anchors.margins: props.wallSize / 2
visible: true
imageSource: Activity.baseUrl + "/ball.svg"
}
}
EditorTool {
id: goalTool
anchors.horizontalCenter: parent.horizontalCenter
width: parent.width
height: props.cellSize
type: Activity.TOOL_GOAL
onSelectedChanged: {
if (selected) {
toolBox.setCurrentTool(goalTool);
}
}
BalanceItem {
id: goal
width: props.cellSize - props.wallSize
height: props.cellSize - props.wallSize
anchors.centerIn: parent
anchors.margins: props.wallSize / 2
z: 1
imageSource: Activity.baseUrl + "/door.svg"
}
}
EditorTool {
id: contactTool
anchors.horizontalCenter: parent.horizontalCenter
width: parent.width
height: props.cellSize
type: Activity.TOOL_CONTACT
onSelectedChanged: {
if (selected) {
toolBox.setCurrentTool(contactTool);
}
}
Row {
id: contactToolRow
spacing: 5
width: contact.width + contactTextInput.width + spacing
anchors.centerIn: parent
BalanceContact {
id: contact
width: props.cellSize - props.wallSize
height: props.cellSize - props.wallSize
anchors.margins: props.wallSize / 2
pressed: false
orderNum: 99
text: props.contactValue
z: 1
}
SpinBox {
id: contactTextInput
width: contact.width * 2
height: contact.height
value: props.contactValue
maximumValue: 99
minimumValue: 1
decimals: 0
horizontalAlignment: Qt.AlignHCenter
font.family: GCSingletonFontLoader.fontLoader.name
font.pixelSize: height / 2
onValueChanged: if (value != props.contactValue) props.contactValue = value;
}
}
}
}
WorkerScript {
id: editorWorker
source: "editor_worker.js"
onMessage: {
// worker finished, update all changed values (except the model):
props.contactValue = messageObject.maxContactValue;
props.lastBallIndex = messageObject.lastBallIndex;
props.lastGoalIndex = messageObject.lastGoalIndex;
props.lastOrderNum = messageObject.lastOrderNum;
Activity.targetList = messageObject.targetList;
testBox.loading.stop();
}
}
ListModel {
id: mapModel
}
Rectangle {
id: mapWrapper
property double margin: 20
property int columns: props.columns
property int rows: props.rows
property double length: Math.min(background.height -
2*mapWrapper.margin, background.width - 2*mapWrapper.margin);
color: "#E3DEDB"
width: length
height: length
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
Grid {
id: mapGrid
columns: mapWrapper.columns
rows: mapWrapper.rows
anchors.fill: parent
width: parent.width
height: parent.height
spacing: 0
Repeater {
id: mapGridRepeater
model: mapModel//mapGrid.columns * mapGrid.rows
delegate: Item { // cell wrapper
id: cell
width: props.cellSize
height: props.cellSize
property bool highlighted: false
Loader {
id: northWallLoader
active: value & Activity.NORTH
width: props.cellSize + props.wallSize
height: props.wallSize
anchors.top: parent.top
anchors.left: parent.left
anchors.topMargin: -props.wallSize / 2
anchors.leftMargin: -props.wallSize / 2
sourceComponent: Wall {
id: northWall
shadow: false
anchors.centerIn: parent
z: 1
}
}
Loader {
id: eastWallLoader
active: value & Activity.EAST || (cell.highlighted && props.currentTool === Activity.TOOL_V_WALL)
width: props.wallSize
height: props.cellSize + props.wallSize
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.bottomMargin: -props.wallSize / 2
anchors.rightMargin: -props.wallSize / 2
sourceComponent: Wall {
id: eastWall
anchors.centerIn: parent
shadow: false
z: 1
}
}
Loader {
id: southWallLoader
active: value & Activity.SOUTH || (cell.highlighted && props.currentTool === Activity.SOUTH)
width: props.cellSize + props.wallSize
height: props.wallSize
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.bottomMargin: -props.wallSize / 2
anchors.leftMargin: -props.wallSize / 2
sourceComponent: Wall {
id: southWall
anchors.centerIn: parent
shadow: false
z: 1
}
}
Loader {
id: westWallLoader
active: value & Activity.WEST
width: props.wallSize
height: props.cellSize + props.wallSize
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.bottomMargin: -props.wallSize / 2
anchors.leftMargin: -props.wallSize / 2
sourceComponent: Wall {
id: westWall
anchors.centerIn: parent
shadow: false
z: 1
}
}
Loader {
id: doorLoader
active: value & Activity.GOAL || (cell.highlighted && props.currentTool === Activity.TOOL_GOAL)
anchors.centerIn: parent
width: props.cellSize - props.wallSize
height: props.cellSize - props.wallSize
sourceComponent: BalanceItem {
id: goal
anchors.centerIn: parent
z: 1
imageSource: Activity.baseUrl + "/door.svg"
}
}
Loader {
id: holeLoader
active: value & Activity.HOLE || (cell.highlighted && props.currentTool === Activity.TOOL_HOLE)
anchors.centerIn: parent
sourceComponent: BalanceItem {
id: hole
width: props.ballSize
height:props.ballSize
anchors.centerIn: parent
z: 1
imageSource: Activity.baseUrl + "/hole.svg"
}
}
Loader {
id: ballLoader
active: value & Activity.START || (cell.highlighted && props.currentTool === Activity.TOOL_BALL)
anchors.centerIn: parent
sourceComponent: BalanceItem {
id: ball
width: props.ballSize
height:props.ballSize
anchors.centerIn: parent
visible: true
imageSource: Activity.baseUrl + "/ball.svg"
z: 1
}
}
Loader {
id: contactLoader
active: (value & Activity.CONTACT) || (cell.highlighted && props.currentTool === Activity.TOOL_CONTACT)
width: props.cellSize - props.wallSize
height: props.cellSize - props.wallSize
anchors.centerIn: parent
sourceComponent: BalanceContact {
id: contact
anchors.centerIn: parent
visible: true
pressed: false
text: contactValue
z: 1
}
}
Rectangle { // bounding rect
id: cellRect
width: props.cellSize
height: props.cellSize
color: "transparent"
border.width: 1
border.color: cell.highlighted ? "yellow": "lightgray"
z: 10
MouseArea {
id: cellMouse
anchors.fill: parent
hoverEnabled: ApplicationInfo.isMobile ? false : true
onEntered: cell.highlighted = true
onExited: cell.highlighted = false
onClicked: {
editor.focus = true;
Activity.modifyMap(props, row, col);
}
}
}
}
}
}
// right:
Wall {
id: rightWall
width: props.wallSize
height: parent.height + props.wallSize
anchors.left: mapWrapper.right
anchors.leftMargin: - props.wallSize/2
anchors.top: parent.top
anchors.topMargin: -props.wallSize/2
shadow: false
}
// bottom:
Wall {
id: bottomWall
width: parent.width + props.wallSize
height: props.wallSize
anchors.left: mapWrapper.left
anchors.leftMargin: - props.wallSize/2
anchors.top: parent.bottom
anchors.topMargin: -props.wallSize/2
shadow: false
}
// top:
Wall {
id: topWall
width: parent.width + props.wallSize
height: props.wallSize
anchors.left: mapWrapper.left
anchors.leftMargin: - props.wallSize/2
anchors.top: parent.top
anchors.topMargin: -props.wallSize/2
shadow: false
}
// left:
Wall {
id: leftWall
width: props.wallSize
height: parent.height + props.wallSize
anchors.left: mapWrapper.left
anchors.leftMargin: - props.wallSize/2
anchors.top: parent.top
anchors.topMargin: -props.wallSize/2
shadow: false
}
}
}
Bar {
id: bar
content: BarEnumContent { value: home | level } // FIXME: add dedicated editor help?
onPreviousLevelClicked: {
if (Activity.currentLevel > 0) {
if (Activity.levelChanged)
Activity.warnUnsavedChanges(Activity.previousLevel,
function() {});
else
Activity.previousLevel();
}
}
onNextLevelClicked: {
if (Activity.levelChanged)
Activity.warnUnsavedChanges(function() {
Activity.levelChanged = false; // mark unchanged early to make check in nextLevel() work
Activity.nextLevel();
}, function() {});
else
Activity.nextLevel();
}
onHomeClicked: {
if (Activity.levelChanged)
Activity.warnUnsavedChanges(activity.home,
function() {});
- else
+ else {
activity.home()
+ }
}
}
-
}
diff --git a/src/activities/balancebox/editor/EditorTool.qml b/src/activities/balancebox/editor/EditorTool.qml
index 626715fb6..f4ee240e4 100644
--- a/src/activities/balancebox/editor/EditorTool.qml
+++ b/src/activities/balancebox/editor/EditorTool.qml
@@ -1,53 +1,53 @@
/* GCompris - EditorTool.qml
*
* Copyright (C) 2015 Holger Kaelberer <holger.k@elberer.de>
*
* Authors:
* Holger Kaelberer <holger.k@elberer.de>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
Item {
id: root
property bool highlighted: false
property bool selected: false
property int type
Rectangle {
id: bounding
anchors.fill: parent
radius: 10
border.width: 2
border.color: (root.selected || root.highlighted) ? "red" : "black"
gradient: Gradient {
GradientStop { position: 0 ; color: root.selected ? "#87ff5c" : "#ffe85c" }
GradientStop { position: 1 ; color: root.selected ? "#44ff00" : "#f8d600" }
}
}
MouseArea {
id: mouse
anchors.fill: parent
hoverEnabled: ApplicationInfo.isMobile ? false : true
onEntered: root.highlighted = true
onExited: root.highlighted = false
onClicked: root.selected = true
}
}
diff --git a/src/activities/balancebox/editor/balanceboxeditor.js b/src/activities/balancebox/editor/balanceboxeditor.js
index ed72afc55..2bcbe6acb 100644
--- a/src/activities/balancebox/editor/balanceboxeditor.js
+++ b/src/activities/balancebox/editor/balanceboxeditor.js
@@ -1,319 +1,303 @@
/* GCompris - balanceboxeditor.js
*
* Copyright (C) 2015 Holger Kaelberer <holger.k@elberer.de>
*
* Authors:
* Holger Kaelberer <holger.k@elberer.de>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
.import GCompris 1.0 as GCompris
.import "qrc:/gcompris/src/core/core.js" as Core
Qt.include("../balancebox_common.js")
var TOOL_CLEAR = EMPTY
var TOOL_H_WALL = SOUTH
var TOOL_V_WALL = EAST
var TOOL_HOLE = HOLE
var TOOL_CONTACT = CONTACT
var TOOL_GOAL = GOAL
var TOOL_BALL = START
var levels;
var level;
var currentLevel;
var numberOfLevel;
var levelChanged = false; // whether current level has unsaved changes
var props;
var currentIsNewLevel;
var targetList = [];
function initEditor(_props)
{
props = _props;
console.log("init editor");
currentLevel = 0;
numberOfLevel = 0;
props.lastBallIndex = -1;
props.lastGoalIndex = -1;
levels = [];
if (props.file.exists(props.editor.filename)) {
levels = props.parser.parseFromUrl(props.editor.filename, validateLevels);
if (levels == null) {
console.error("BalanceboxEditor: Error loading levels from "
+ props.editor.filename);
levels = []; // restart with an empty level-set
}
}
numberOfLevel = levels.length;
initLevel();
}
function createEmptyLevel()
{
var map = [];
var num = currentLevel + 1;
for (var row = 0; row < props.rows; row++)
for (var col = 0; col < props.columns; col++) {
if (col === 0)
map[row] = [];
map[row][col] = 0;
}
return {
level: currentLevel + 1,
map: map,
targets: []
};
}
function initLevel()
{
props.editor.testBox.loading.start();
if (currentLevel >= numberOfLevel) {
levels.push(createEmptyLevel());
levelChanged = false;
numberOfLevel++;
currentIsNewLevel = true;
} else
currentIsNewLevel = false;
level = levels[currentLevel];
props.bar.level = currentLevel + 1;
// populate model in the worker-thread:
props.editorWorker.sendMessage({
lastBallIndex: props.lastBallIndex,
lastGoalIndex: props.lastGoalIndex,
lastOrderNum: props.lastOrderNum,
mapModel: props.mapModel,
targetList: targetList,
level: level
});
}
function dec2hex(i) {
return (i+0x10000).toString(16).substr(-4).toUpperCase();
}
function modelToLevel()
{
var map = new Array();
var targets = new Array();
targetList.sort(function(a,b) { return a - b;})
for (var i = 0; i < props.mapModel.count; i++) {
var row = Math.floor(i / props.columns);
var col = i % props.columns;
if (col === 0) {
map[row] = new Array();
}
var obj = props.mapModel.get(i);
var value = obj.value;
value &= ~(0xff00); // always clear order-number bits
if (obj.value & CONTACT) {
value |= ((targetList.indexOf(parseInt(obj.contactValue)) + 1) << 8);
}
map[row][col] = "0x" + dec2hex(value);
}
var level = {
level: currentLevel + 1,
map: map,
targets: targetList
}
return level;
}
function saveModel()
{
var l = modelToLevel();
- var path = userFile.substring(0, userFile.lastIndexOf("/"));
- if (!props.file.exists(path)) {
- if (!props.file.mkpath(path))
- console.error("Could not create directory " + path);
- else
- console.debug("Created directory " + path);
- }
levels[currentLevel] = l;
// renumber levels before saving:
for(var i = 0; i < levels.length; i++)
levels[i].level = i + 1;
- if (!props.file.write(JSON.stringify(levels), userFile))
- Core.showMessageDialog(props.editor,
- //~ singular Error saving %n level to your levels file (%1)
- //~ plural Error saving %n levels to your levels file (%1)
- qsTr("Error saving %n level(s) to your levels file (%1)", "", numberOfLevel)
- .arg(userFile),
- "", null, "", null, null);
- else {
- Core.showMessageDialog(props.editor,
- //~ singular Saved %n level to your levels file (%1)
- //~ plural Saved %n levels to your levels file (%1)
- qsTr("Saved %n level(s) to your levels file (%1)", "", numberOfLevel)
- .arg(userFile),
- "", null, "", null, null);
- levelChanged = false;
- currentIsNewLevel = false;
- }
+
+ levelChanged = false;
+ currentIsNewLevel = false;
+ return levels
}
function modifyMap(props, row, col)
{
var modelIndex = row * level.map.length + col;
var obj = props.mapModel.get(modelIndex);
var oldValue = obj.value;
var newValue = oldValue;
// contact-tool: check for already existing value early
if (props.currentTool === TOOL_CONTACT // have contact tool and ...
&& targetList.indexOf(parseInt(props.contactValue)) !== -1 // already have this contact value ...
&& !(obj.value & TOOL_CONTACT // which is not set at the same cell
&& obj.contactValue === props.contactValue))
{
console.debug("Avoiding to set duplicate contact value " + props.contactValue
+ " current targets=" + JSON.stringify(targetList));
return;
}
if (props.currentTool === TOOL_CLEAR) {
newValue = 0;
// remove contact stuff:
if (obj.value & TOOL_CONTACT) {
if (targetList.indexOf(parseInt(obj.contactValue)) !== -1)
targetList.splice(targetList.indexOf(parseInt(obj.contactValue)), 1);
props.mapModel.setProperty(row * level.map.length + col,
"contactValue", "");
}
} else { // all other tools
// special treatment for mutually exclusive ones:
if (props.currentTool === TOOL_HOLE
|| props.currentTool === TOOL_GOAL
|| props.currentTool === TOOL_CONTACT
|| props.currentTool === TOOL_BALL) {
// helper:
var MUTEX_MASK = (START | GOAL | HOLE | CONTACT) ^ props.currentTool;
newValue &= ~MUTEX_MASK;
}
// special treatment for singletons:
if (props.currentTool === TOOL_GOAL) {
if ((obj.value & TOOL_GOAL) === 0) {
// setting a new one
if (props.lastGoalIndex > -1) {
// clear last one first:
props.mapModel.setProperty(props.lastGoalIndex, "value",
props.mapModel.get(props.lastGoalIndex).value &
(~TOOL_GOAL));
}
// now memorize the new one:
props.lastGoalIndex = modelIndex;
}
} else
if (props.currentTool === TOOL_BALL) {
if ((obj.value & TOOL_BALL) === 0) {
// setting a new one
if (props.lastBallIndex > -1)
// clear last one first:
props.mapModel.setProperty(props.lastBallIndex, "value",
props.mapModel.get(props.lastBallIndex).value & (~TOOL_BALL));
// now memorize the new one:
props.lastBallIndex = modelIndex;
}
}
// special treatment for contacts:
if (props.currentTool === TOOL_CONTACT) {
if (obj.value & TOOL_CONTACT && // have old contact value ...
obj.contactValue === props.contactValue) { // ... which is == the new one
// clear contact
if (targetList.indexOf(parseInt(obj.contactValue)) !== -1)
targetList.splice(targetList.indexOf(parseInt(obj.contactValue)), 1);
props.mapModel.setProperty(row * level.map.length + col,
"contactValue", "");
newValue &= ~(CONTACT);
} else {
if (obj.value & TOOL_CONTACT) { // have old contact that is different
if (targetList.indexOf(parseInt(obj.contactValue)) !== -1)
targetList.splice(targetList.indexOf(parseInt(obj.contactValue)), 1);
// no change to newValue
}
// -> set new one:
if (targetList.indexOf(parseInt(props.contactValue)) === -1)
targetList.push(parseInt(props.contactValue));
props.mapModel.setProperty(row * level.map.length + col,
"contactValue", props.contactValue);
- props.contactValue = Number(Number(props.contactValue) + 1).toString();
+ // the grid is 10*10 so 99 max goals
+ var contactValue = Number(props.contactValue);
+ if(contactValue < 99) {
+ props.contactValue = Number(contactValue + 1).toString();
+ }
newValue |= CONTACT;
}
} else {
// for other than contact-tool: update value by current tool bit:
newValue ^= props.currentTool;
}
}
if (oldValue !== newValue)
levelChanged = true;
props.mapModel.setProperty(modelIndex, "value", newValue);
}
var warningVisible = false;
function warnUnsavedChanges(yesFunc, noFunc)
{
if (!warningVisible) {
warningVisible = true;
Core.showMessageDialog(props.editor,
qsTr("You have unsaved changes!<br/> " +
"Really leave this level and lose changes?"),
qsTr("Yes"), function() {
warningVisible = false;
if (yesFunc !== undefined)
yesFunc();
},
qsTr("No"), function() {
warningVisible = false;
if (noFunc !== undefined)
noFunc();
},
function() {
warningVisible = false;
if (noFunc !== undefined)
noFunc();
});
}
}
function nextLevel() {
if(numberOfLevel === currentLevel + 1
&& !levelChanged && currentIsNewLevel ) {
console.log("BalanceboxEditor: Current level is new and unchanged, nogo!");
return;
}
currentLevel++;
levelChanged = false;
initLevel();
}
function previousLevel() {
if (currentLevel === 0)
return;
currentLevel--;
levelChanged = false;
initLevel();
}
diff --git a/src/activities/balancebox/editor/editor_worker.js b/src/activities/balancebox/editor/editor_worker.js
index 6d06b1478..507ace429 100644
--- a/src/activities/balancebox/editor/editor_worker.js
+++ b/src/activities/balancebox/editor/editor_worker.js
@@ -1,76 +1,76 @@
/* GCompris - editor_worker.js
*
* Copyright (C) 2015 Holger Kaelberer <holger.k@elberer.de>
*
* Authors:
* Holger Kaelberer <holger.k@elberer.de>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
Qt.include("../balancebox_common.js")
WorkerScript.onMessage = function(msg) {
var maxContactValue = 1;
msg.lastBallIndex = -1;
msg.lastGoalIndex = -1;
msg.lastOrderNum = 0;
msg.mapModel.clear();
msg.targetList = [];
for (var row = 0; row < msg.level.map.length; row++) {
for (var col = 0; col < msg.level.map[row].length; col++) {
var contactValue = "";
var value = parseInt(msg.level.map[row][col]); // always enforce number
var orderNum = (value & 0xFF00) >> 8;
if (orderNum > 0 && msg.level.targets[orderNum - 1] === undefined) {
console.error("Invalid level: orderNum " + orderNum
+ " without target value!");
} else if (orderNum > 0) {
if (orderNum > msg.lastOrderNum)
msg.lastOrderNum = orderNum;
var target = msg.level.targets[orderNum-1]
msg.targetList.push(parseInt(target));
contactValue = Number(target).toString();
if (target >= maxContactValue)
maxContactValue = target + 1;
}
msg.mapModel.append({
"row": row,
"col": col,
"value": value,
"contactValue": (orderNum > 0) ? contactValue : ""
});
if (value & GOAL) {
if (msg.lastGoalIndex > -1) {
console.error("Invalid level: multiple goal locations: row/col="
+ row + "/" + col);
return;
}
msg.lastGoalIndex = row * msg.level.map.length + col;
}
if (value & START) {
if (msg.lastBallIndex > -1) {
console.error("Invalid level: multiple start locations: row/col="
+ row + "/" + col);
return;
}
msg.lastBallIndex = row * msg.level.map.length + col;
}
}
msg.mapModel.sync(); // sync per row
}
msg.maxContactValue = maxContactValue;
// send result back to the gui-thread
WorkerScript.sendMessage(msg);
}
diff --git a/src/activities/ballcatch/ActivityInfo.qml b/src/activities/ballcatch/ActivityInfo.qml
index 6d8dfbed3..073fb172e 100644
--- a/src/activities/ballcatch/ActivityInfo.qml
+++ b/src/activities/ballcatch/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Johnny Jazeix <jazeix@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "ballcatch/Ballcatch.qml"
difficulty: 1
icon: "ballcatch/ballcatch.svg"
author: "Johnny Jazeix &lt;jazeix@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Make the ball go to Tux")
//: Help title
description: qsTr("Press the left and right arrow keys at the same time, to make the ball go in a straight line.")
// intro: "Press the left and right arrow key at the same time to send the ball straight on"
//: Help goal
goal: ""
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("Press the left and right arrow at the same time, to make the ball go in a straight line. On a touch screen you have to hit the two hands at the same time.")
credit: ""
section: "computer keyboard"
createdInVersion: 0
}
diff --git a/src/activities/ballcatch/Ball.qml b/src/activities/ballcatch/Ball.qml
index a25174835..952c3bc52 100644
--- a/src/activities/ballcatch/Ball.qml
+++ b/src/activities/ballcatch/Ball.qml
@@ -1,98 +1,98 @@
/* gcompris - Ball.qml
Copyright (C) 2014 Johnny Jazeix <jazeix@gmail.com>
Bruno Coudoin: initial Gtk+ version
This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "ballcatch.js" as Activity
import GCompris 1.0
Image {
id: ball
property bool isVertical: background.width <= background.height // To check if in Vertical mode
source: "qrc:/gcompris/src/activities/ballcatch/resource/ball.svg"
sourceSize.height: background.isVertical ? 175 * Application.ratio : 200 * ApplicationInfo.ratio
z: 3
readonly property real initScale: 1.0
// If won, ball goes on tux, if lose, depends on the side clicked first
property int finishX
readonly property int finishY: tux.y + tux.height / 4
readonly property real finishScale: initScale / 2
property int radius: initScale
ParallelAnimation {
id: animation
running: false
NumberAnimation { target: ball; property: "x";
to: finishX; duration: 1000
easing.type: Easing.InOutQuad }
NumberAnimation { target: ball; property: "y";
to: finishY; duration: 1000
easing.type: Easing.InOutQuad }
NumberAnimation { target: ball; property: "scale";
to: finishScale; duration: 1000
easing.type: Easing.InOutQuad }
NumberAnimation { target: ball; property: "rotation";
to: 360; duration: 1000
easing.type: Easing.InOutQuad }
onStarted: {
items.background.playSound("brick")
}
onStopped: {
// We are done with the ballon move
if(Activity.gameWon) {
// This is a win
items.background.playSound("completetask")
bonus.good("tux")
}
else {
// This is a lose
bonus.bad("tux")
}
}
}
function startAnimation() {
if(Activity.gameWon) {
finishX = x
}
else if(Activity.items.leftPressed) {
finishX = tux.x + tux.width * 2
}
else {
finishX = tux.x - tux.width * 2
}
/* Only start the timer if the game is at init state.
In init state, radius is initScale */
if(ball.radius == ball.initScale)
animation.start()
}
function reinitBall() {
x = background.width / 2 - width / 2;
y = leftHand.y - height / 3;
ball.scale = initScale;
ball.rotation = 0;
}
}
diff --git a/src/activities/ballcatch/Ballcatch.qml b/src/activities/ballcatch/Ballcatch.qml
index 78f8f6651..3bb040380 100644
--- a/src/activities/ballcatch/Ballcatch.qml
+++ b/src/activities/ballcatch/Ballcatch.qml
@@ -1,267 +1,267 @@
/* gcompris - Ballcatch.qml
Copyright (C) 2014 Johnny Jazeix <jazeix@gmail.com>
Bruno Coudoin: initial Gtk+ version
This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "../ballcatch"
import "ballcatch.js" as Activity
ActivityBase {
id: activity
onStart: {
focus = true;
}
onStop: {}
Keys.onPressed: {
Activity.processKey(event)
}
pageComponent: Image {
id: background
signal start
signal stop
focus: true
fillMode: Image.PreserveAspectCrop
source: "qrc:/gcompris/src/activities/ballcatch/resource/beach1.svg"
sourceSize.width: Math.max(parent.width, parent.height)
property bool isVertical: background.width <= background.height // To check if in Vertical mode
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
QtObject {
id: items
property alias background: background
property alias bar: bar
property alias ball: ball
property alias rightHand: rightHand
property alias leftHand: leftHand
property alias deltaPressedTimer: deltaPressedTimer
/* when the corresponding arrow key is pressed, the following boolean pass
- to true and is reseted at the end of the level */
+ to true and is reset at the end of the level */
property bool leftPressed
property bool rightPressed
}
onStart: {
Activity.start(items)
}
onStop: { Activity.stop() }
onWidthChanged: {
leftHand.reinitPosition();
rightHand.reinitPosition();
ball.reinitBall();
}
onHeightChanged: {
leftHand.reinitPosition();
rightHand.reinitPosition();
ball.reinitBall();
}
DialogHelp {
id: dialogHelpLeftRight
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level }
onHelpClicked: {
displayDialog(dialogHelpLeftRight)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: home()
}
Bonus {
id: bonus
winSound: "qrc:/gcompris/src/activities/ballcatch/resource/tuxok.wav"
looseSound: "qrc:/gcompris/src/activities/ballcatch/resource/youcannot.wav"
Component.onCompleted: {
win.connect(Activity.nextLevel)
loose.connect(Activity.restartLevel)
}
onStart: tux.opacity = 0
onStop: tux.opacity = 1
}
Image {
id: tux
x: background.width / 2 - width / 2
y: leftHand.y - height / 3 - height / 2
sourceSize.height: 200 * ApplicationInfo.ratio
source: "qrc:/gcompris/src/activities/ballcatch/resource/tux.svg"
Behavior on opacity { PropertyAnimation { easing.type: Easing.InQuad; duration: 250 } }
}
Image {
id: leftHand
y: background.height - 1.5 * height
z: 5
sourceSize.height: 150 * ApplicationInfo.ratio
source: "qrc:/gcompris/src/activities/ballcatch/resource/hand.svg"
NumberAnimation {
id: leftHandAnimation
target: leftHand; property: "x";
to: background.width/2 - leftHand.width - 5;
duration: 1000
easing.type: Easing.InOutQuad
}
function animate(newTime) {
leftHandAnimation.duration = newTime
leftHandAnimation.start();
}
function reinitPosition() {
leftHand.x = background.width / 2 - width * 2
leftHand.y = background.height - 1.5 * height
}
MultiPointTouchArea {
id: mouseAreaLeftShift
anchors.fill: parent
onTouchUpdated: {
// left
if(!items.leftPressed && !Activity.gameFinished) {
Activity.leftShiftPressed();
items.leftPressed = true
}
}
}
}
Image {
id: rightHand
mirror: true
y: background.height - 1.5 * height
z: 5
sourceSize.height: 150 * ApplicationInfo.ratio
source: "qrc:/gcompris/src/activities/ballcatch/resource/hand.svg"
function animate(newTime) {
rightHandAnimation.duration = newTime
rightHandAnimation.start();
}
function reinitPosition() {
rightHand.x = background.width / 2 + width
rightHand.y = background.height - 1.5 * height
}
NumberAnimation {
id: rightHandAnimation
target: rightHand; property: "x";
to: background.width / 2 + 5;
duration: 1000;
easing.type: Easing.InOutQuad
}
MultiPointTouchArea {
id: mouseAreaRightShift
anchors.fill: parent
onTouchUpdated: {
// right
if(!items.rightPressed && !Activity.gameFinished) {
Activity.rightShiftPressed();
items.rightPressed = true
}
}
}
}
Image {
id: leftShift
x: background.width / 4 - width
y: background.isVertical ? rightHand.y - height : rightHand.y - height / 2
source: "qrc:/gcompris/src/activities/ballcatch/resource/arrow_key.svg"
scale: background.isVertical ? 0.75 : 1.0
smooth: true
opacity: items.leftPressed ? 1 : 0.5
visible: !ApplicationInfo.isMobile
}
Image {
id: rightShift
mirror: true
x: background.width - background.width / 4
y: background.isVertical ? rightHand.y - height : rightHand.y - height / 2
source: "qrc:/gcompris/src/activities/ballcatch/resource/arrow_key.svg"
scale: background.isVertical ? 0.75 : 1.0
smooth: true
opacity: items.rightPressed ? 1 : 0.5
visible: !ApplicationInfo.isMobile
}
// Instructions
IntroMessage {
id: instructions
intro: ApplicationInfo.isMobile ?
[qsTr("Tap both hands at the same time, " +
"to make the ball go in a straight line.")] :
[qsTr("Press left and right arrow keys at the same time, " +
"to make the ball go in a straight line.")]
anchors {
top: parent.top
topMargin: 10
}
- z : 10
+ z: 10
index: bar.level === 1 &&
!(items.leftPressed && items.rightPressed) ? 0 : -1
opacity: items.leftPressed ^ items.rightPressed ? 0 : 1
Behavior on opacity { NumberAnimation { duration: 120 } }
}
function playSound(identifier) {
activity.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/"+ identifier + ".wav")
}
/* Timer starting when user first presses a first key.
If still running when the user presses the other key, he wins !
*/
Timer {
id: deltaPressedTimer
running: false; repeat: false
onTriggered: {
Activity.endTimer()
ball.startAnimation()
}
}
Ball {
id: ball
}
}
}
diff --git a/src/activities/ballcatch/ballcatch.js b/src/activities/ballcatch/ballcatch.js
index 01fd3e7b3..55ad5e30e 100644
--- a/src/activities/ballcatch/ballcatch.js
+++ b/src/activities/ballcatch/ballcatch.js
@@ -1,176 +1,176 @@
/*
gcompris - ballcatch.js
Copyright (C)
2003, 2014: Bruno Coudoin: initial version
2014: Johnny Jazeix: Qt port
This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import GCompris 1.0 as GCompris //for ApplicationInfo
var levelProperties = [
{
"timerInc": 900,
"backgroundImage": 1
},
{
"timerInc": 350,
"backgroundImage": 1
},
{
"timerInc": 300,
"backgroundImage": 2
},
{
"timerInc": 200,
"backgroundImage": 2
},
{
"timerInc": 150,
"backgroundImage": 3
},
{
"timerInc": 100,
"backgroundImage": 3
},
{
"timerInc": 60,
"backgroundImage": 4
},
{
"timerInc": 30,
"backgroundImage": 4
},
{
"timerInc": 15,
"backgroundImage": 4
},
]
var gameWon = false
// When the timer is finished we set this variable to true to disabled key press
var gameFinished = false
// Store the time diff between left and right key
var timerDiff = 0
// The child has to press both key between this laps of time
var timerinc = 900
var currentLevel = 0
var items
function start(items_) {
items = items_
currentLevel = 0
initLevel()
}
function stop() {
// Nothing to do
}
function leftShiftPressed() {
if(!items.deltaPressedTimer.running && !items.rightPressed) {
items.leftHand.animate(timerinc)
items.deltaPressedTimer.start()
}
if(items.rightPressed) {
items.leftHand.animate(timerinc)
items.background.playSound("smudge")
}
}
function rightShiftPressed() {
if(!items.deltaPressedTimer.running && !items.leftPressed) {
items.deltaPressedTimer.start()
items.rightHand.animate(timerinc)
}
if(items.leftPressed) {
items.rightHand.animate(timerinc)
items.background.playSound("smudge")
}
}
function endTimer() {
gameFinished = true
gameWon = items.rightPressed && items.leftPressed
}
function initLevel() {
items.bar.level = currentLevel + 1
timerinc = levelProperties[currentLevel].timerInc
timerDiff = 0
items.deltaPressedTimer.interval = timerinc
items.background.source = "qrc:/gcompris/src/activities/ballcatch/resource/beach" +
levelProperties[currentLevel].backgroundImage + ".svg"
items.ball.reinitBall();
items.leftPressed = false
items.rightPressed = false
gameWon = false
gameFinished = false
items.leftHand.reinitPosition()
items.rightHand.reinitPosition()
}
function nextLevel() {
if(levelProperties.length <= ++ currentLevel) {
currentLevel = 0
}
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = levelProperties.length - 1
}
initLevel();
}
function restartLevel() {
initLevel();
}
function processKey(event) {
if(!gameFinished) {
- if(event.key == Qt.Key_Left) {
+ if(event.key === Qt.Key_Left) {
// left
if(!items.leftPressed) {
leftShiftPressed();
items.leftPressed = true
}
}
- else if(event.key == Qt.Key_Right) {
+ else if(event.key === Qt.Key_Right) {
// right
if(!items.rightPressed) {
rightShiftPressed();
items.rightPressed = true
}
}
}
event.accepted = true;
}
diff --git a/src/activities/bargame/ActivityInfo.qml b/src/activities/bargame/ActivityInfo.qml
index 46d90580b..31e81653b 100644
--- a/src/activities/bargame/ActivityInfo.qml
+++ b/src/activities/bargame/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2017 UTKARSH TIWARI <iamutkarshtiwari@kde.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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "bargame/Bargame.qml"
difficulty: 1
icon: "bargame/bargame.svg"
author: "Utkarsh Tiwari &lt;iamutkarshtiwari@kde.org&gt;"
demo: true
//: Activity title
title: qsTr("Bargame (against Tux)")
//: Help title
description: qsTr("Click the number of balls you wish to place in the holes and then click the OK button. The winner is the one who hasn't put a ball in the red hole.")
// intro: "Click the number of balls you wish to place in the holes and then click the OK button. The winner is the one who hasn't put a ball in the red hole."
//: Help goal
goal: qsTr("Don't put the ball in the last hole")
//: Help prerequisite
prerequisite: qsTr("Ability to count")
//: Help manual
manual: qsTr("Place balls in the holes. You win if the computer has to place the last ball. If you want Tux to begin, just click on him")
credit: ""
section: "strategy"
createdInVersion: 8000
}
diff --git a/src/activities/bargame/Bargame.qml b/src/activities/bargame/Bargame.qml
index cfcda8e07..b1ac60fd3 100644
--- a/src/activities/bargame/Bargame.qml
+++ b/src/activities/bargame/Bargame.qml
@@ -1,448 +1,451 @@
/* GCompris - bargame.qml
*
* Copyright (C) 2016 UTKARSH TIWARI <iamutkarshtiwari@kde.org>
*
* Authors:
* Yves Combe (GTK+ version)
* UTKARSH TIWARI <iamutkarshtiwari@kde.org> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "bargame.js" as Activity
ActivityBase {
id: activity
property int gameMode: 1
onStart: focus = true
onStop: {}
pageComponent: Image {
id: rootWindow
source: Activity.url + "background.svg"
sourceSize.width: Math.max(parent.width, parent.height)
fillMode: Image.PreserveAspectCrop
signal start
signal stop
+ property bool horizontalLayout: background.width >= background.height
Component.onCompleted: {
dialogActivityConfig.getInitialConfiguration()
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property int numberOfBalls: 1
property alias answerBallsPlacement: answerBallsPlacement
property alias bar: bar
property alias bonus: bonus
property alias okArea: okArea
property alias trigTuxMove: trigTuxMove
property alias player1score: player1score
property alias player2score: player2score
property int mode: 1
+ property int gridSize: (horizontalLayout ? rootWindow.width : (rootWindow.height - bar.height * 1.2)) / Activity.levelsProperties[items.mode - 1].boardSize
property bool isPlayer1Beginning: true
property bool isPlayer1Turn: true
}
onStart: {
Activity.start(items, gameMode);
Activity.calculateWinPlaces();
}
onStop: { Activity.stop() }
// Tux move delay
Timer {
id: trigTuxMove
repeat: false
interval: 1500
onTriggered: Activity.machinePlay()
}
// Tux image
Image {
id: tux
visible: gameMode == 1
source: Activity.url + "tux1.svg"
- height: rootWindow.height / 4
+ height: rootWindow.height * 0.2
width: tux.height
- y: rootWindow.height - rootWindow.height / 1.8
+ y: rootWindow.height * 0.4
anchors {
right: rootWindow.right
- rightMargin: 16 * ApplicationInfo.ratio
+ rightMargin: 23 * ApplicationInfo.ratio
}
MouseArea {
id: tuxArea
hoverEnabled: enabled
enabled: gameMode == 1 && !answerBallsPlacement.children[0].visible
anchors.fill: parent
onClicked: {
items.isPlayer1Turn = false;
Activity.machinePlay();
}
}
states: State {
name: "tuxHover"
when: tuxArea.containsMouse
PropertyChanges {
target: tux
scale: 1.1
}
}
}
// Box row
Item {
id: boxModel
- x: 0
- anchors.top: tux.bottom
+
+ states: [
+ State {
+ name: "horizontalBar"
+ when: horizontalLayout
+ PropertyChanges { target: boxModel; x: 0; y: rootWindow.height - bar.height * 2}
+ },
+ State {
+ name: "verticalBar"
+ when: !horizontalLayout
+ PropertyChanges { target: boxModel; x: rootWindow.width * 0.5; y: 0}
+ }
+ ]
transform: Rotation {
origin.x: 0;
origin.y: 0;
- angle: (rootWindow.width > rootWindow.height) ? 0 : 90
- onAngleChanged: {
- if (angle === 90) {
- boxModel.anchors.top = undefined;
- boxModel.y = 0;
- boxModel.anchors.horizontalCenter = rootWindow.horizontalCenter;
- } else {
- boxModel.anchors.horizontalCenter = undefined;
- boxModel.x = 0;
- boxModel.anchors.top = tux.bottom;
- }
- }
+ angle: horizontalLayout ? 0 : 90
}
// The empty boxes grid
Grid {
id: boxes
rows: 1
columns: Activity.levelsProperties[items.mode - 1].boardSize
anchors.centerIn: boxModel.Center
Repeater {
id: startCase
model: boxes.columns
Image {
id: greenCase
source: Activity.url + ((index == boxes.columns - 1) ? "case_last.svg" : "case.svg")
- sourceSize.width: ((rootWindow.width > rootWindow.height) ? rootWindow.width : (rootWindow.height * 0.86)) / (15 + (items.mode - 1) * Activity.levelsProperties[items.mode - 1].elementSizeFactor)
+ sourceSize.width: items.gridSize
width: sourceSize.width
height: sourceSize.width
visible: true
}
}
}
// Hidden Answer Balls
Grid {
// All green balls placement
id: answerBallsPlacement
anchors.centerIn: boxModel.Center
columns: Activity.levelsProperties[items.mode - 1].boardSize
rows: 1
Repeater {
model: answerBallsPlacement.columns
Image {
source: Activity.url + "ball_1.svg"
- sourceSize.width: ((rootWindow.width > rootWindow.height) ? rootWindow.width : (rootWindow.height * 0.86)) / (15 + (items.mode - 1) * Activity.levelsProperties[items.mode - 1].elementSizeFactor)
+ sourceSize.width: items.gridSize
width: sourceSize.width
height: sourceSize.width
visible: false
}
}
}
// Masks
Grid {
id: masks
anchors.centerIn: boxModel.Center
rows: 1
columns: Activity.levelsProperties[items.mode - 1].boardSize
Repeater {
id: startMask
model: masks.columns
Image {
id: greenMask
source: Activity.url + ((index == boxes.columns - 1) ? "mask_last.svg" : "mask.svg")
- sourceSize.width: ((rootWindow.width > rootWindow.height) ? rootWindow.width : (rootWindow.height * 0.86)) / (15 + (items.mode - 1) * Activity.levelsProperties[items.mode - 1].elementSizeFactor)
+ sourceSize.width: items.gridSize
width: sourceSize.width
height: sourceSize.width
// Numbering label
Rectangle {
id: bgNbTxt
visible: ((index + 1) % 5 == 0 && index > 0) ? true : false
color: "#42FFFFFF"
height: numberText.height * 1.2
width: height
radius: height / 2
anchors {
horizontalCenter: parent.horizontalCenter
bottom: parent.top
- bottomMargin: ((rootWindow.width > rootWindow.height) ? 4 * ApplicationInfo.ratio : -16 * ApplicationInfo.ratio)
+ bottomMargin: (horizontalLayout ? 4 * ApplicationInfo.ratio : -16 * ApplicationInfo.ratio)
}
GCText {
id: numberText
text: index + 1
color: "#373737"
fontSize: smallSize
font.bold: true
visible: ((index + 1) % 5 == 0 && index > 0) ? true : false
anchors {
horizontalCenter: bgNbTxt.horizontalCenter
verticalCenter: bgNbTxt.verticalCenter
}
}
transform: Rotation {
- angle: (rootWindow.width > rootWindow.height) ? 0 : -90
+ angle: horizontalLayout ? 0 : -90
}
}
}
}
}
}
// ok button
Image {
id: playLabel
width: ballNumberPlate.height
height: width
sourceSize.width: width
sourceSize.height: width
source: Activity.url + "bar_ok.svg"
anchors {
left: ballNumberPlate.right
verticalCenter: ballNumberPlate.verticalCenter
leftMargin: width / 4
}
MouseArea {
id: okArea
anchors.fill: parent
hoverEnabled: enabled
enabled: true
onClicked: {
var value = items.numberOfBalls
if (gameMode == 1 || items.isPlayer1Turn) {
Activity.play(1, value);
} else {
Activity.play(2, value);
}
// reset next action
items.numberOfBalls = Activity.levelsProperties[items.mode - 1].minNumberOfBalls
}
}
states: State {
name: "mouseHover"
when: okArea.containsMouse
PropertyChanges {
target: playLabel
scale: 1.2
}
}
}
// Number of balls to be placed
Image {
id: ballNumberPlate
y: rootWindow.height * 0.32
source: items.isPlayer1Turn ? Activity.url + "score_1.svg" :
Activity.url + "score_2.svg"
width: bar.height
height: bar.height * 0.7
sourceSize.width: width
sourceSize.height: height
anchors {
left: rootWindow.left
leftMargin: 16 * ApplicationInfo.ratio
}
MouseArea {
id: numberPlateArea
anchors.fill: parent
- hoverEnabled: true
+ hoverEnabled: enabled
+ enabled: (gameMode == 1 && items.isPlayer1Turn == false) ? false : true
onClicked: {
items.numberOfBalls ++;
var max = Activity.levelsProperties[items.mode - 1].maxNumberOfBalls
if (items.numberOfBalls > max) {
items.numberOfBalls = Activity.levelsProperties[items.mode - 1].minNumberOfBalls;
}
}
}
states: State {
name: "numberHover"
when: numberPlateArea.containsMouse
PropertyChanges {
target: ballNumberPlate
scale: 1.1
}
}
// Ball Icon
Image {
id: ballIcon
source: items.isPlayer1Turn ? Activity.url + "ball_1b.svg" :
Activity.url + "ball_2b.svg"
sourceSize.width: parent.height * 0.8
width: sourceSize.width
height: sourceSize.width
anchors {
verticalCenter: ballNumberPlate.verticalCenter
left: ballNumberPlate.left
leftMargin: 10
}
}
// Number label
GCText {
id: numberLabel
text: items.numberOfBalls
color: "#C04040"
font.bold: true
fontSize: smallSize
anchors {
right: ballNumberPlate.right
rightMargin: 10
verticalCenter: ballNumberPlate.verticalCenter
}
}
}
ScoreItem {
id: player1score
player: 1
height: Math.min(rootWindow.height/7, Math.min(rootWindow.width/7, bar.height * 1.05))
width: height*11/8
anchors {
top: rootWindow.top
topMargin: 5
left: rootWindow.left
leftMargin: 5
}
playerImageSource: Activity.url + "player_1.svg"
backgroundImageSource: Activity.url + "score_1.svg"
}
ScoreItem {
id: player2score
player: 2
height: Math.min(rootWindow.height/7, Math.min(rootWindow.width/7, bar.height * 1.05))
width: height*11/8
anchors {
top: rootWindow.top
topMargin: 5
right: rootWindow.right
rightMargin: 5
}
playerImageSource: Activity.url + "player_2.svg"
backgroundImageSource: Activity.url + "score_2.svg"
playerScaleOriginX: player2score.width
}
DialogHelp {
id: dialogHelp
onClose: home()
}
DialogActivityConfig {
id: dialogActivityConfig
currentActivity: activity
content: Component {
Item {
property alias modeBox: modeBox
property var availableModes: [
{ "text": qsTr("Easy"), "value": 1 },
{ "text": qsTr("Medium"), "value": 2 },
{ "text": qsTr("Difficult"), "value": 3 }
]
Flow {
id: flow
spacing: 5
width: dialogActivityConfig.width
GCComboBox {
id: modeBox
model: availableModes
background: dialogActivityConfig
label: qsTr("Select your difficulty")
}
}
}
}
onClose: home()
onLoadData: {
if(dataToSave && dataToSave["mode"]) {
items.mode = dataToSave["mode"];
}
}
onSaveData: {
var newMode = dialogActivityConfig.configItem.availableModes[dialogActivityConfig.configItem.modeBox.currentIndex].value;
if (newMode !== items.mode) {
items.mode = newMode;
dataToSave = {"mode": items.mode};
}
Activity.initLevel();
}
function setDefaultValues() {
for(var i = 0 ; i < dialogActivityConfig.configItem.availableModes.length ; i++) {
if(dialogActivityConfig.configItem.availableModes[i].value === items.mode) {
dialogActivityConfig.configItem.modeBox.currentIndex = i;
break;
}
}
}
}
Bar {
id: bar
level: 1
content: BarEnumContent { value: help | home | level | reload | config }
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
onConfigClicked: {
dialogActivityConfig.active = true
// Set default values
dialogActivityConfig.setDefaultValues();
displayDialog(dialogActivityConfig)
}
onReloadClicked: Activity.restartLevel()
}
Bonus {
id: bonus
Component.onCompleted: {
win.connect(Activity.initLevel)
loose.connect(Activity.initLevel)
}
}
}
}
diff --git a/src/activities/bargame/bargame.js b/src/activities/bargame/bargame.js
index e4b50728a..7ed957b0e 100644
--- a/src/activities/bargame/bargame.js
+++ b/src/activities/bargame/bargame.js
@@ -1,241 +1,243 @@
/* GCompris - bargame.js
*
* Copyright (C) 2016 UTKARSH TIWARI <iamutkarshtiwari@kde.org >
*
* Authors:
* Yves Combe (GTK+ version)
* UTKARSH TIWARI <iamutkarshtiwari@kde.org > (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import GCompris 1.0 as GCompris
.import QtQuick 2.6 as Quick
var levelsProperties = [
{
"minNumberOfBalls": 1,
"maxNumberOfBalls": 4,
"elementSizeFactor": 0,
"boardSize": 15
},
{
"minNumberOfBalls": 2,
"maxNumberOfBalls": 6,
"elementSizeFactor": 4,
"boardSize": 19
},
{
"minNumberOfBalls": 3,
"maxNumberOfBalls": 6,
"elementSizeFactor": 7,
"boardSize": 29
}
];
var moveCount = -1
var currentLevel = 1
var maxLevel = 4
var listWin = []
var items
var gameMode
var url= "qrc:/gcompris/src/activities/bargame/resource/";
function start(items_, gameMode_) {
items = items_;
gameMode = gameMode_;
currentLevel = 1;
initLevel();
}
function stop() {
}
function initLevel() {
if (items.isPlayer1Beginning === true) {
initiatePlayer1();
items.isPlayer1Turn = true;
} else {
initiatePlayer2();
items.isPlayer1Turn = false;
}
items.okArea.enabled = true;
calculateWinPlaces();
moveCount = -1;
items.numberOfBalls = levelsProperties[items.mode - 1].minNumberOfBalls
items.bar.level = currentLevel;
// Hiding all visible balls
for (var x = 0; x < items.answerBallsPlacement.columns; x++) {
items.answerBallsPlacement.children[x].visible = false;
}
}
function nextLevel() {
currentLevel ++;
if (currentLevel > maxLevel) {
currentLevel = 1;
}
initLevel();
}
function previousLevel() {
currentLevel--;
if (currentLevel < 1) {
currentLevel = maxLevel;
}
initLevel();
}
function restartLevel() {
items.trigTuxMove.stop();
initLevel();
}
function calculateWinPlaces() {
/* Calculates all the possible winning moves in the
available board size. It generates a list all winning
moves for the computer */
var winners = [];
var winnersList = [];
var min = levelsProperties[items.mode - 1].minNumberOfBalls;
var max = levelsProperties[items.mode - 1].maxNumberOfBalls;
var boardSize = levelsProperties[items.mode - 1].boardSize;
var period = (min + max);
for (var x = 0; x < min; x++) {
winnersList.push((boardSize - 1 - x) % period);
}
- for (var x = 0; x < boardSize; x++) {
+ for (var x = period + 1; x < boardSize; x++) {
if (winnersList.indexOf((x + 1) % period) >= 0) {
winners.push(x);
}
}
var levelWin = (currentLevel - 1) * min;
if (levelWin == 0) {
winners = [];
} else {
winners = winners.slice(-levelWin);
+ if (currentLevel == maxLevel - 1) {
+ winners = winners.slice(1);
+ }
}
-
listWin = winners;
}
function machinePlay() {
function accessible(x) {
if (listWin.indexOf(x + moveCount) >= 0) {
return true;
} else {
return false;
}
}
function randomNumber(minimum, maximum) {
return Math.round(Math.random() * (maximum - minimum) + minimum);
}
var playable = [];
var min = levelsProperties[items.mode - 1].minNumberOfBalls;
var max = levelsProperties[items.mode - 1].maxNumberOfBalls;
- for (var x = min; x < max; x++) {
+ for (var x = min; x <= max; x++) {
if (accessible(x)) {
playable.push(x);
}
}
var value;
if (playable.length != 0) {
value = playable[Math.floor(Math.random()*playable.length)];
} else {
value = randomNumber(min, max);
}
play(2, value);
}
function play(player, value) {
for (var x = 0; x < value ; x++) {
moveCount++;
var boardSize = levelsProperties[items.mode - 1].boardSize;
if (moveCount <= (boardSize - 1)) {
items.answerBallsPlacement.children[moveCount].visible = true;
- if (player == 1) {
+ if (player === 1) {
items.answerBallsPlacement.children[moveCount].source = url + "ball_1.svg";
} else {
items.answerBallsPlacement.children[moveCount].source = url + "ball_2.svg";
}
}
// one of the players has won
if (moveCount == (boardSize - 1)) {
items.okArea.enabled = false;
- if (gameMode == 2) {
+ if (gameMode === 2) {
items.isPlayer1Beginning = !items.isPlayer1Beginning;
}
- if (player == 2) {
+ if (player === 2) {
items.player1score.win();
items.player2score.endTurn();
items.bonus.good("flower");
} else {
items.player1score.endTurn();
items.player2score.win();
- if (gameMode == 1) {
+ if (gameMode === 1) {
items.bonus.bad("flower");
}
else {
items.bonus.good("flower");
}
}
return;
}
}
items.isPlayer1Turn = !items.isPlayer1Turn;
- if (player == 1 && gameMode == 1) {
+ if (player === 1 && gameMode === 1) {
items.player1score.endTurn();
items.player2score.beginTurn();
items.okArea.enabled = false;
items.trigTuxMove.start();
- } else if (player == 2 && gameMode == 1) {
+ } else if (player === 2 && gameMode === 1) {
items.player2score.endTurn();
items.player1score.beginTurn();
items.okArea.enabled = true;
- } else if (gameMode == 2) {
- if (player == 1) {
+ } else if (gameMode === 2) {
+ if (player === 1) {
items.player1score.endTurn();
items.player2score.beginTurn();
} else {
items.player2score.endTurn();
items.player1score.beginTurn();
}
}
}
//Initial values at the start of game when its player 1 turn
function initiatePlayer1() {
items.player2score.endTurn();
items.player1score.beginTurn();
}
//Initial values at the start of game when its player 2 turn
function initiatePlayer2() {
items.player1score.endTurn();
items.player2score.beginTurn();
}
diff --git a/src/activities/bargame_2players/ActivityInfo.qml b/src/activities/bargame_2players/ActivityInfo.qml
index 30fd432f9..e1467d601 100644
--- a/src/activities/bargame_2players/ActivityInfo.qml
+++ b/src/activities/bargame_2players/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2017 UTKARSH TIWARI <iamutkarshtiwari@kde.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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "bargame_2players/Bargame2players.qml"
difficulty: 2
icon: "bargame_2players/bargame_2players.svg"
author: "Utkarsh Tiwari &lt;iamutkarshtiwari@kde.org&gt;"
demo: true
//: Activity title
title: qsTr("Bargame (with a friend)")
//: Help title
description: qsTr("Click the number of balls you wish to place in the holes and then click the OK button. The winner is the one who hasn't put a ball in the red hole.")
// intro: "Click the number of balls you wish to place in the holes and then click the OK button. The winner is the one who hasn't put a ball in the red hole."
//: Help goal
goal: qsTr("Don't put the ball in the last hole")
//: Help prerequisite
prerequisite: qsTr("Ability to count")
//: Help manual
manual: qsTr("Place balls in the holes. You win if your friend has to place the last ball.")
credit: ""
section: "strategy"
createdInVersion: 8000
}
diff --git a/src/activities/bargame_2players/Bargame2players.qml b/src/activities/bargame_2players/Bargame2players.qml
index e0836f10f..adbfad6d6 100644
--- a/src/activities/bargame_2players/Bargame2players.qml
+++ b/src/activities/bargame_2players/Bargame2players.qml
@@ -1,27 +1,27 @@
/* GCompris - Bargame_2players.qml
*
* Copyright (C) 2017 UTKARSH TIWARI <iamutkarshtiwari@kde.org>
*
* Authors:
* Yves Combe (GTK+ version)
* UTKARSH TIWARI <iamutkarshtiwari@kde.org> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../bargame"
Bargame {
gameMode: 2
}
diff --git a/src/activities/binary_bulb/ActivityInfo.qml b/src/activities/binary_bulb/ActivityInfo.qml
new file mode 100644
index 000000000..4bfe56eb6
--- /dev/null
+++ b/src/activities/binary_bulb/ActivityInfo.qml
@@ -0,0 +1,40 @@
+/* GCompris - ActivityInfo.qml
+ *
+ * Copyright (C) 2018 Rajat Asthana <rajatasthana4@gmail.com>
+ *
+ * This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+ */
+import GCompris 1.0
+
+ActivityInfo {
+ name: "binary_bulb/BinaryBulb.qml"
+ difficulty: 3
+ icon: "binary_bulb/binary_bulb.svg"
+ author: "Rajat Asthana &lt;rajatasthana4@gmail.com&gt;"
+ demo: true
+ //: Activity title
+ title: qsTr("Binary bulbs")
+ //: Help title
+ description: qsTr("This activity helps you to learn the concept of conversion of decimal number system to binary number system.")
+ //intro: "Turn on the right bulbs to represent the binary of the given decimal number. When you have achieved it, press OK"
+ //: Help goal
+ goal: qsTr("To get familiar with the binary number system")
+ //: Help prerequisite
+ prerequisite: qsTr("Decimal number system")
+ //: Help manual
+ manual: qsTr("Turn on the right bulbs to represent the binary of the given decimal number. When you have achieved it, press OK.")
+ credit: ""
+ section: "experiment"
+ createdInVersion: 9500
+}
diff --git a/src/activities/binary_bulb/BinaryBulb.qml b/src/activities/binary_bulb/BinaryBulb.qml
new file mode 100644
index 000000000..7000e547e
--- /dev/null
+++ b/src/activities/binary_bulb/BinaryBulb.qml
@@ -0,0 +1,209 @@
+/* GCompris - BinaryBulb.qml
+ *
+ * Copyright (C) 2018 Rajat Asthana <rajatasthana4@gmail.com>
+ *
+ * Authors:
+ * RAJAT ASTHANA <rajatasthana4@gmail.com>
+ *
+ * This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+ */
+import QtQuick 2.6
+import GCompris 1.0
+
+import "../../core"
+import "binary_bulb.js" as Activity
+import "numbers.js" as Dataset
+
+ActivityBase {
+ id: activity
+
+ onStart: focus = true
+ onStop: {}
+
+ property var dataset: Dataset
+
+ pageComponent: Image {
+ id: background
+ anchors.fill: parent
+ source: "../digital_electricity/resource/texture01.png"
+ fillMode: Image.Tile
+ signal start
+ signal stop
+
+ Component.onCompleted: {
+ activity.start.connect(start)
+ activity.stop.connect(stop)
+ }
+
+ // Add here the QML items you need to access in javascript
+ QtObject {
+ id: items
+ property Item main: activity.main
+ property alias background: background
+ property alias bar: bar
+ property alias bonus: bonus
+ property alias bulbs: bulbs
+ property int numberSoFar: 0
+ property int numberToConvert: 0
+ property int numberOfBulbs: 0
+ property int currentSelectedBulb: -1
+ property int currentLevel: 0
+ property alias score: score
+ }
+
+ onStart: { Activity.start(items, dataset) }
+ onStop: { Activity.stop() }
+
+ // Tutorial section starts
+ Image {
+ id: tutorialImage
+ source: "../digital_electricity/resource/texture01.png"
+ anchors.fill: parent
+ fillMode: Image.Tile
+ z: 5
+ visible: true
+ Tutorial {
+ id: tutorialSection
+ tutorialDetails: Activity.tutorialInstructions
+ useImage: false
+ onSkipPressed: {
+ Activity.initLevel()
+ tutorialImage.visible = false
+ }
+ }
+ }
+ // Tutorial section ends
+
+
+ Keys.onPressed: {
+ if(event.key === Qt.Key_Enter || event.key === Qt.Key_Return) {
+ Activity.equalityCheck()
+ }
+ else if(event.key === Qt.Key_Space) {
+ if(items.currentSelectedBulb != -1) {
+ Activity.changeState(items.currentSelectedBulb)
+ }
+ }
+ else if(event.key === Qt.Key_Left) {
+ if(--items.currentSelectedBulb < 0) {
+ items.currentSelectedBulb = items.numberOfBulbs-1
+ }
+ }
+ else if(event.key === Qt.Key_Right) {
+ if(++items.currentSelectedBulb >= items.numberOfBulbs) {
+ items.currentSelectedBulb = 0
+ }
+ }
+ }
+
+ Rectangle {
+ id: questionItemBackground
+ opacity: 0
+ z: 10
+ anchors {
+ horizontalCenter: parent.horizontalCenter
+ bottomMargin: 10
+ }
+ height: background.height / 6
+ width: parent.width - 20 * ApplicationInfo.ratio
+ }
+
+ GCText {
+ id: questionItem
+ anchors.fill: questionItemBackground
+ anchors.bottom: questionItemBackground.bottom
+ fontSizeMode: Text.Fit
+ wrapMode: Text.Wrap
+ z: 4
+ color: "white"
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignHCenter
+ text: qsTr("What is the binary representation of %1?").arg(items.numberToConvert)
+ }
+
+ Row {
+ id: row
+ anchors.top: questionItem.bottom
+ anchors.topMargin: 30 * ApplicationInfo.ratio
+ anchors.horizontalCenter: parent.horizontalCenter
+ spacing: 10 * ApplicationInfo.ratio
+ Repeater {
+ id: bulbs
+ model: items.numberOfBulbs
+ LightBulb {
+ height: background.height / 5
+ width: (background.width >= background.height) ? (background.width / 20) : ((background.width - (16 * row.spacing)) / 8)
+ valueVisible: Dataset.get()[items.currentLevel].bulbValueVisible
+ }
+ }
+ }
+
+ GCText {
+ id: reachedSoFar
+ anchors.horizontalCenter: row.horizontalCenter
+ anchors.top: row.bottom
+ anchors.topMargin: 30 * ApplicationInfo.ratio
+ color: "white"
+ fontSize: largeSize
+ text: items.numberSoFar
+ visible: Dataset.get()[items.currentLevel].enableHelp
+ }
+
+ BarButton {
+ id: okButton
+ anchors {
+ bottom: bar.top
+ right: parent.right
+ rightMargin: 10 * ApplicationInfo.ratio
+ bottomMargin: 10 * ApplicationInfo.ratio
+ }
+ source: "qrc:/gcompris/src/core/resource/bar_ok.svg"
+ sourceSize.width: 60 * ApplicationInfo.ratio
+ onClicked: Activity.equalityCheck()
+ enabled: !bonus.isPlaying && !score.isWinAnimationPlaying
+ }
+
+ DialogHelp {
+ id: dialogHelp
+ onClose: home()
+ }
+
+ Bar {
+ id: bar
+ content: BarEnumContent { value: help | home | level}
+ onHelpClicked: {
+ displayDialog(dialogHelp)
+ }
+ onPreviousLevelClicked: Activity.previousLevel()
+ onNextLevelClicked: Activity.nextLevel()
+ onHomeClicked: activity.home()
+ }
+
+ Score {
+ id: score
+ visible: !tutorialImage.visible
+ anchors.bottom: bar.top
+ anchors.right: bar.right
+ anchors.left: parent.left
+ anchors.bottomMargin: 10 * ApplicationInfo.ratio
+ anchors.leftMargin: 10 * ApplicationInfo.ratio
+ anchors.rightMargin: 0
+ }
+
+ Bonus {
+ id: bonus
+ Component.onCompleted: win.connect(Activity.nextLevel)
+ }
+ }
+}
diff --git a/src/activities/binary_bulb/CMakeLists.txt b/src/activities/binary_bulb/CMakeLists.txt
new file mode 100644
index 000000000..e8eda2a29
--- /dev/null
+++ b/src/activities/binary_bulb/CMakeLists.txt
@@ -0,0 +1 @@
+GCOMPRIS_ADD_RCC(activities/binary_bulb *.qml *.svg *.js resource/*)
diff --git a/src/activities/binary_bulb/LightBulb.qml b/src/activities/binary_bulb/LightBulb.qml
new file mode 100644
index 000000000..0a34e34cf
--- /dev/null
+++ b/src/activities/binary_bulb/LightBulb.qml
@@ -0,0 +1,98 @@
+/* GCompris - LightBulb.qml
+ *
+ * Copyright (C) 2018 Rajat Asthana <rajatasthana4@gmail.com>
+ *
+ * Authors:
+ * RAJAT ASTHANA <rajatasthana4@gmail.com>
+ *
+ * This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+ */
+import QtQuick 2.6
+import "../../core"
+import GCompris 1.0
+import "binary_bulb.js" as Activity
+
+Item {
+ id: bulb
+ anchors.verticalCenter: parent.verticalCenter
+ state: "off"
+ focus: true
+
+ property alias valueVisible: valueText.visible
+
+ Rectangle {
+ color: "transparent"
+ width: parent.width + 10
+ height: parent.height + 10
+ border.color: "red"
+ border.width: 3
+ anchors.centerIn: bulbImage
+ radius: 5
+ visible: index == items.currentSelectedBulb
+ }
+ Image {
+ id: bulbImage
+ width: parent.width
+ sourceSize.width: parent.width
+ fillMode: Image.PreserveAspectFit
+ source: "resource/bulb_off.svg"
+ }
+ property string bit: ""
+ readonly property int value: Math.pow(2, items.numberOfBulbs - index - 1)
+
+ GCText {
+ id: valueText
+ anchors.bottom: parent.top
+ anchors.horizontalCenter: parent.horizontalCenter
+ text: value
+ color: "white"
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: Activity.changeState(index)
+ }
+
+ GCText {
+ anchors.top: bulb.bottom
+ anchors.horizontalCenter: parent.horizontalCenter
+ text: bit
+ color: "white"
+ }
+
+ states: [
+ State {
+ name: "off"
+ PropertyChanges {
+ target: bulb
+ bit: "0"
+ }
+ PropertyChanges {
+ target: bulbImage
+ source: "resource/bulb_off.svg"
+ }
+ },
+ State {
+ name: "on"
+ PropertyChanges {
+ target: bulb
+ bit: "1"
+ }
+ PropertyChanges {
+ target: bulbImage
+ source: "resource/bulb_on.svg"
+ }
+ }
+ ]
+}
diff --git a/src/activities/binary_bulb/binary_bulb.js b/src/activities/binary_bulb/binary_bulb.js
new file mode 100644
index 000000000..c9e73ea77
--- /dev/null
+++ b/src/activities/binary_bulb/binary_bulb.js
@@ -0,0 +1,149 @@
+/* GCompris - binary_bulb.js
+ *
+ * Copyright (C) 2018 Rajat Asthana <rajatasthana4@gmail.com>
+ *
+ * Authors:
+ * "RAJAT ASTHANA" <rajatasthana4@gmail.com>
+ *
+ * This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+ */
+.pragma library
+.import QtQuick 2.6 as Quick
+.import "qrc:/gcompris/src/core/core.js" as Core
+
+var numberOfLevel
+var items
+var dataset
+var url = "qrc:/gcompris/src/activities/binary_bulb/resource/"
+var tutorialInstructions = [
+ {
+ "instruction": qsTr("This activity teaches how to convert decimal numbers to binary numbers."),
+ "instructionQml" : "qrc:/gcompris/src/activities/binary_bulb/resource/tutorial1.qml"
+ },
+ {
+ "instruction": qsTr("Computers use transistors to count and transistors have only two states, 0 and 1. Mathematically, these states are represented by 0 and 1, which makes up the binary system of numeration."),
+ "instructionQml" : "qrc:/gcompris/src/activities/binary_bulb/resource/tutorial2.qml"
+ },
+ {
+ "instruction": qsTr("In the activity 0 and 1 are simulated by bulbs, switched on or off."),
+ "instructionQml": "qrc:/gcompris/src/activities/binary_bulb/resource/tutorial3.qml"
+ },
+ {
+ "instruction": qsTr("Binary system uses these numbers very efficiently, allowing to count from 0 to 255 with 8 bits only."),
+ "instructionQml": "qrc:/gcompris/src/activities/binary_bulb/resource/tutorial4.qml"
+ },
+ {
+ "instruction": qsTr("Each bit adds a progressive value, corresponding to the powers of 2, ascending from right to left: bit 1 → 2⁰=1 , bit 2 → 2¹=2 , bit 3 → 2²=4 , bit 4 → 2³=8 , bit 5 → 2⁴=16 , bit 6 → 2⁵=32 , bit 7 → 2⁶=64 , bit 8 → 2⁷=128."),
+ "instructionQml": "qrc:/gcompris/src/activities/binary_bulb/resource/tutorial5.qml"
+ },
+ {
+ "instruction": qsTr("To convert a decimal 5 to a binary value, 1 and 4 are added."),
+ "instructionQml": "qrc:/gcompris/src/activities/binary_bulb/resource/tutorial6.qml"
+ },
+ {
+ "instruction": qsTr("Their corresponding bits are set to 1, the others set to 0. Decimal 5 is equal to binary 101."),
+ "instructionQml": "qrc:/gcompris/src/activities/binary_bulb/resource/tutorial7.qml"
+ },
+ {
+ "instruction": qsTr("This image will help you to compute bits' value."),
+ "instructionQml": "qrc:/gcompris/src/activities/binary_bulb/resource/tutorial5.qml"
+ }
+ ]
+var levelDataset
+
+function start(items_, dataset_) {
+ items = items_
+ dataset = dataset_.get()
+ items.currentLevel = 0
+ numberOfLevel = dataset.length
+}
+
+function stop() {
+}
+
+function resetBulbs() {
+ for(var i = 0; i < items.numberOfBulbs; i++) {
+ items.bulbs.itemAt(i).state = "off"
+ }
+}
+
+function initializeValues() {
+ items.currentSelectedBulb = -1
+ items.numberSoFar = 0
+ items.numberToConvert = levelDataset[items.score.currentSubLevel - 1]
+}
+
+function equalityCheck() {
+ if(items.numberSoFar == items.numberToConvert) {
+ if(items.score.currentSubLevel < items.score.numberOfSubLevels) {
+ items.score.currentSubLevel++;
+ items.score.playWinAnimation()
+ resetBulbs()
+ initializeValues()
+ }
+ else {
+ items.bonus.good("lion")
+ resetBulbs()
+ }
+ }
+ else {
+ items.bonus.bad("lion")
+ resetBulbs()
+ items.numberSoFar = 0
+ }
+}
+
+function changeState(index) {
+ var currentBulb = items.bulbs.itemAt(index)
+ if(currentBulb.state == "off") {
+ currentBulb.state = "on"
+ items.numberSoFar += currentBulb.value
+ }
+ else {
+ currentBulb.state = "off"
+ items.numberSoFar -= currentBulb.value
+ }
+}
+
+function initLevel() {
+ items.bar.level = items.currentLevel + 1
+ items.score.numberOfSubLevels = dataset[items.currentLevel].numbersToBeConverted.length
+ items.score.currentSubLevel = 1
+ items.numberOfBulbs = dataset[items.currentLevel].bulbCount
+ levelDataset = Core.shuffle(dataset[items.currentLevel].numbersToBeConverted)
+ initializeValues()
+ resetBulbs()
+}
+
+function nextLevel() {
+ if(numberOfLevel <= items.currentLevel + 1) {
+ items.currentLevel = 0
+ }
+ else {
+ ++ items.currentLevel
+ }
+ items.score.currentSubLevel = 1
+ initLevel();
+}
+
+function previousLevel() {
+ if(items.currentLevel-1 < 0) {
+ items.currentLevel = numberOfLevel - 1
+ }
+ else {
+ --items.currentLevel
+ }
+ items.score.currentSubLevel = 1
+ initLevel();
+}
diff --git a/src/activities/binary_bulb/binary_bulb.svg b/src/activities/binary_bulb/binary_bulb.svg
new file mode 100644
index 000000000..e87f38ed4
--- /dev/null
+++ b/src/activities/binary_bulb/binary_bulb.svg
@@ -0,0 +1,439 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100"
+ height="100"
+ id="svg9131"
+ sodipodi:version="0.32"
+ inkscape:version="0.92.1 r15371"
+ version="1.0"
+ sodipodi:docname="binary_bulb.svg">
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="4.458712"
+ inkscape:cx="27.901705"
+ inkscape:cy="45.302435"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ height="100px"
+ width="100px"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ showgrid="false"
+ inkscape:snap-global="false"
+ inkscape:window-maximized="1" />
+ <defs
+ id="defs9133">
+ <linearGradient
+ gradientTransform="matrix(0.125,0,0,0.125,5,33.500001)"
+ inkscape:collect="always"
+ xlink:href="#linearGradient880"
+ id="linearGradient837"
+ x1="96"
+ y1="200"
+ x2="96"
+ y2="184"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient880">
+ <stop
+ style="stop-color:#8c8472;stop-opacity:0.86666667"
+ offset="0"
+ id="stop876" />
+ <stop
+ style="stop-color:#c3b9a7;stop-opacity:0.78039217"
+ offset="1"
+ id="stop878" />
+ </linearGradient>
+ <linearGradient
+ gradientTransform="matrix(0.125,0,0,0.125,5,33.500001)"
+ inkscape:collect="always"
+ xlink:href="#linearGradient874"
+ id="linearGradient829"
+ x1="104"
+ y1="184"
+ x2="104"
+ y2="8"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient874"
+ inkscape:collect="always">
+ <stop
+ id="stop870"
+ offset="0"
+ style="stop-color:#635946;stop-opacity:0.54901963" />
+ <stop
+ id="stop872"
+ offset="1"
+ style="stop-color:#a79980;stop-opacity:0.2358804" />
+ </linearGradient>
+ <linearGradient
+ gradientTransform="matrix(0.125,0,0,0.125,49,33.500001)"
+ inkscape:collect="always"
+ xlink:href="#linearGradient880"
+ id="linearGradient837-3"
+ x1="96"
+ y1="200"
+ x2="96"
+ y2="184"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ gradientTransform="matrix(0.125,0,0,0.125,49,33.500001)"
+ inkscape:collect="always"
+ xlink:href="#linearGradient874"
+ id="linearGradient829-5"
+ x1="104"
+ y1="184"
+ x2="104"
+ y2="8"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ gradientTransform="matrix(0.125,0,0,0.125,27,33.5)"
+ inkscape:collect="always"
+ xlink:href="#linearGradient974"
+ id="linearGradient837-7"
+ x1="96"
+ y1="208"
+ x2="96"
+ y2="192"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient974"
+ inkscape:collect="always">
+ <stop
+ id="stop970"
+ offset="0"
+ style="stop-color:#a79980;stop-opacity:0.02990033" />
+ <stop
+ id="stop972"
+ offset="1"
+ style="stop-color:#fafabd;stop-opacity:0.70588237" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient974"
+ id="linearGradient829-5-3"
+ x1="104"
+ y1="184"
+ x2="104"
+ y2="160"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.125,0,0,0.125,27,33.5)" />
+ <linearGradient
+ gradientTransform="matrix(0.125,0,0,0.125,71,33.5)"
+ inkscape:collect="always"
+ xlink:href="#linearGradient974"
+ id="linearGradient837-7-6"
+ x1="96"
+ y1="208"
+ x2="96"
+ y2="192"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient974"
+ id="linearGradient829-5-3-2"
+ x1="104"
+ y1="184"
+ x2="104"
+ y2="160"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.125,0,0,0.125,71,33.5)" />
+ </defs>
+ <metadata
+ id="metadata9136">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ <dc:date>2018</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Timothée Giet</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ style="display:inline"
+ id="layer1"
+ inkscape:groupmode="layer"
+ inkscape:label="Calque 1">
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:1;vector-effect:none;fill:#7f7767;fill-opacity:0.96078431;stroke:none;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ d="m 17,34.500002 c -4.986,0 -9,4.46 -9,10 v 2 1 9 H 7 v 2.999999 h 20 v -2.999999 h -1 v -9 -1 -2 c 0,-5.54 -4.014,-10 -9,-10 z"
+ id="rect816-3-3" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:1;vector-effect:none;fill:#d1c9bc;fill-opacity:0.70431896;stroke:none;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ d="m 17,34.750002 c -4.986,0 -8.5,4.21 -8.5,9.75 v 2 1 8.499999 h 17 v -8.499999 -1 -2 c 0,-5.54 -3.514,-9.75 -8.5,-9.75 z m -9.5,22.25 v 2 h 19 v -2 z"
+ id="rect816-3" />
+ <circle
+ style="opacity:1;vector-effect:none;fill:#9c9c99;fill-opacity:1;stroke:none;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ id="path864"
+ cx="13"
+ cy="63.499996"
+ r="2" />
+ <circle
+ style="opacity:1;vector-effect:none;fill:#9c9c99;fill-opacity:1;stroke:none;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ id="path866"
+ cx="21"
+ cy="63.499996"
+ r="2" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#6e6f70;fill-opacity:1;stroke:none;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ id="rect839-3"
+ width="2"
+ height="8"
+ x="12"
+ y="56.499996"
+ ry="1" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#6e6f70;fill-opacity:1;stroke:none;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ id="rect839-6"
+ width="2"
+ height="8"
+ x="20"
+ y="56.499996"
+ ry="1" />
+ <path
+ style="opacity:1;vector-effect:none;fill:url(#linearGradient829);fill-opacity:1;stroke:none;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ d="m 17,34.750002 c -4.986,0 -8.5,4.21 -8.5,9.75 v 2 1 8.499999 h 8.5 8.5 v -8.499999 -1 -2 c 0,-5.54 -3.514,-9.75 -8.5,-9.75 z"
+ id="rect816"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="sscccccccss" />
+ <path
+ style="opacity:1;vector-effect:none;fill:url(#linearGradient837);fill-opacity:1;stroke:none;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ d="m 7.5,56.750002 h 19 v 2.25 h -19 z"
+ id="rect820"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ style="display:inline;opacity:1;vector-effect:none;fill:#7f7767;fill-opacity:0.96078431;stroke:none;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ d="m 61,34.500002 c -4.986,0 -9,4.46 -9,10 v 2 1 9 h -1 v 2.999999 h 20 v -2.999999 h -1 v -9 -1 -2 c 0,-5.54 -4.014,-10 -9,-10 z"
+ id="rect816-3-3-6" />
+ <path
+ inkscape:connector-curvature="0"
+ style="display:inline;opacity:1;vector-effect:none;fill:#d1c9bc;fill-opacity:0.70431896;stroke:none;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ d="m 61,34.750002 c -4.986,0 -8.5,4.21 -8.5,9.75 v 2 1 8.499999 h 17 v -8.499999 -1 -2 c 0,-5.54 -3.514,-9.75 -8.5,-9.75 z m -9.5,22.25 v 2 h 19 v -2 z"
+ id="rect816-3-2" />
+ <circle
+ style="display:inline;opacity:1;vector-effect:none;fill:#9c9c99;fill-opacity:1;stroke:none;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ id="path864-9"
+ cx="57"
+ cy="63.499996"
+ r="2" />
+ <circle
+ style="display:inline;opacity:1;vector-effect:none;fill:#9c9c99;fill-opacity:1;stroke:none;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ id="path866-1"
+ cx="65"
+ cy="63.499996"
+ r="2" />
+ <rect
+ style="display:inline;opacity:1;vector-effect:none;fill:#6e6f70;fill-opacity:1;stroke:none;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ id="rect839-3-2"
+ width="2"
+ height="8"
+ x="56"
+ y="56.499996"
+ ry="1" />
+ <rect
+ style="display:inline;opacity:1;vector-effect:none;fill:#6e6f70;fill-opacity:1;stroke:none;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ id="rect839-6-7"
+ width="2"
+ height="8"
+ x="64"
+ y="56.499996"
+ ry="1" />
+ <path
+ style="display:inline;opacity:1;vector-effect:none;fill:url(#linearGradient829-5);fill-opacity:1;stroke:none;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ d="m 61,34.750002 c -4.986,0 -8.5,4.21 -8.5,9.75 v 2 1 8.499999 h 8.5 8.5 v -8.499999 -1 -2 c 0,-5.54 -3.514,-9.75 -8.5,-9.75 z"
+ id="rect816-0"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="sscccccccss" />
+ <path
+ style="display:inline;opacity:1;vector-effect:none;fill:url(#linearGradient837-3);fill-opacity:1;stroke:none;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ d="m 51.5,56.750002 h 19 v 2.25 h -19 z"
+ id="rect820-9"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ <circle
+ style="opacity:1;vector-effect:none;fill:#9c9c99;fill-opacity:1;stroke:none;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ id="path864-6"
+ cx="35"
+ cy="63.5"
+ r="2" />
+ <circle
+ style="opacity:1;vector-effect:none;fill:#9c9c99;fill-opacity:1;stroke:none;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ id="path866-2"
+ cx="43"
+ cy="63.5"
+ r="2" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#6e6f70;fill-opacity:1;stroke:none;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ id="rect839-3-9"
+ width="2"
+ height="8"
+ x="34"
+ y="56.5"
+ ry="1" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#6e6f70;fill-opacity:1;stroke:none;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ id="rect839-6-1"
+ width="2"
+ height="8"
+ x="42"
+ y="56.5"
+ ry="1" />
+ <path
+ style="opacity:1;vector-effect:none;fill:#e4ba13;fill-opacity:1;stroke:none;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ d="m 39,34.5 c -4.986,0 -9,4.46 -9,10 v 2 1 9 h -1 v 3 h 20 v -3 h -1 v -9 -1 -2 c 0,-5.54 -4.014,-10 -9,-10 z"
+ id="rect816-2-6-1"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:1;vector-effect:none;fill:#efed38;fill-opacity:1;stroke:none;stroke-width:1.25000012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ d="m 39,34.75 c -4.986,0 -8.5,4.21 -8.5,9.749999 V 46.5 47.500001 56 H 39 47.5 V 47.500001 46.5 44.499999 C 47.5,38.96 43.986,34.75 39,34.75 Z"
+ id="rect816-2-2"
+ sodipodi:nodetypes="sscccccccss" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:1;vector-effect:none;fill:url(#linearGradient829-5-3);fill-opacity:1;stroke:none;stroke-width:1.25000012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ d="m 39,34.75 c -4.986,0 -8.75,4.21 -8.75,9.749999 V 46.5 47.500001 56 H 39 47.75 V 47.500001 46.5 44.499999 C 47.75,38.96 43.986,34.75 39,34.75 Z"
+ id="rect816-2"
+ sodipodi:nodetypes="sscccccccss" />
+ <path
+ style="opacity:1;vector-effect:none;fill:#efed38;fill-opacity:1;stroke:none;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ d="m 29.5,56.75 h 19 V 59 h -19 z"
+ id="rect820-7-7"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ style="opacity:1;vector-effect:none;fill:url(#linearGradient837-7);fill-opacity:1;stroke:none;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ d="m 29.5,56.75 h 19 V 59 h -19 z"
+ id="rect820-7"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ <circle
+ style="opacity:1;vector-effect:none;fill:#f7f7f7;fill-opacity:1;stroke:none;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ id="path976"
+ cx="38"
+ cy="38.5"
+ r="2" />
+ <circle
+ style="opacity:1;vector-effect:none;fill:#f7f7f7;fill-opacity:1;stroke:none;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ id="path978"
+ cx="35"
+ cy="41.5"
+ r="1" />
+ <circle
+ style="display:inline;opacity:1;vector-effect:none;fill:#9c9c99;fill-opacity:1;stroke:none;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ id="path864-6-6"
+ cx="79"
+ cy="63.5"
+ r="2" />
+ <circle
+ style="display:inline;opacity:1;vector-effect:none;fill:#9c9c99;fill-opacity:1;stroke:none;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ id="path866-2-1"
+ cx="87"
+ cy="63.5"
+ r="2" />
+ <rect
+ style="display:inline;opacity:1;vector-effect:none;fill:#6e6f70;fill-opacity:1;stroke:none;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ id="rect839-3-9-8"
+ width="2"
+ height="8"
+ x="78"
+ y="56.5"
+ ry="1" />
+ <rect
+ style="display:inline;opacity:1;vector-effect:none;fill:#6e6f70;fill-opacity:1;stroke:none;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ id="rect839-6-1-7"
+ width="2"
+ height="8"
+ x="86"
+ y="56.5"
+ ry="1" />
+ <path
+ style="display:inline;opacity:1;vector-effect:none;fill:#e4ba13;fill-opacity:1;stroke:none;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ d="m 83,34.5 c -4.986,0 -9,4.46 -9,10 v 2 1 9 h -1 v 3 h 20 v -3 h -1 v -9 -1 -2 c 0,-5.54 -4.014,-10 -9,-10 z"
+ id="rect816-2-6-1-9"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ style="display:inline;opacity:1;vector-effect:none;fill:#efed38;fill-opacity:1;stroke:none;stroke-width:1.25000012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ d="m 83,34.75 c -4.986,0 -8.5,4.21 -8.5,9.749999 V 46.5 47.500001 56 H 83 91.5 V 47.500001 46.5 44.499999 C 91.5,38.96 87.986,34.75 83,34.75 Z"
+ id="rect816-2-2-2"
+ sodipodi:nodetypes="sscccccccss" />
+ <path
+ inkscape:connector-curvature="0"
+ style="display:inline;opacity:1;vector-effect:none;fill:url(#linearGradient829-5-3-2);fill-opacity:1;stroke:none;stroke-width:1.25000012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ d="m 83,34.75 c -4.986,0 -8.75,4.21 -8.75,9.749999 V 46.5 47.500001 56 H 83 91.75 V 47.500001 46.5 44.499999 C 91.75,38.96 87.986,34.75 83,34.75 Z"
+ id="rect816-2-0"
+ sodipodi:nodetypes="sscccccccss" />
+ <path
+ style="display:inline;opacity:1;vector-effect:none;fill:#efed38;fill-opacity:1;stroke:none;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ d="m 73.5,56.75 h 19 V 59 h -19 z"
+ id="rect820-7-7-2"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ style="display:inline;opacity:1;vector-effect:none;fill:url(#linearGradient837-7-6);fill-opacity:1;stroke:none;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ d="m 73.5,56.75 h 19 V 59 h -19 z"
+ id="rect820-7-3"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ <circle
+ style="display:inline;opacity:1;vector-effect:none;fill:#f7f7f7;fill-opacity:1;stroke:none;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ id="path976-7"
+ cx="82"
+ cy="38.5"
+ r="2" />
+ <circle
+ style="display:inline;opacity:1;vector-effect:none;fill:#f7f7f7;fill-opacity:1;stroke:none;stroke-width:1.25;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ id="path978-5"
+ cx="79"
+ cy="41.5"
+ r="1" />
+ </g>
+</svg>
diff --git a/src/activities/binary_bulb/numbers.js b/src/activities/binary_bulb/numbers.js
new file mode 100644
index 000000000..52d570c1a
--- /dev/null
+++ b/src/activities/binary_bulb/numbers.js
@@ -0,0 +1,70 @@
+/* GCompris - numbers.js
+ *
+ * Copyright (C) 2018 Rajat Asthana <rajatasthana4@gmail.com>
+ *
+ * This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+ */
+
+function get() {
+ return [
+ { //level1
+ "bulbCount": 2,
+ "numbersToBeConverted": [1, 2, 3],
+ "enableHelp": true,
+ "bulbValueVisible": true
+ },
+ { //level 2
+ "bulbCount": 2,
+ "numbersToBeConverted": [1, 2, 3],
+ "enableHelp": false,
+ "bulbValueVisible": true
+ },
+ { //level3
+ "bulbCount": 4,
+ "numbersToBeConverted": [4, 9, 13, 15],
+ "enableHelp": true,
+ "bulbValueVisible": true
+ },
+ { //level4
+ "bulbCount": 4,
+ "numbersToBeConverted": [5, 10, 14, 7],
+ "enableHelp": false,
+ "bulbValueVisible": true
+ },
+ { //level5
+ "bulbCount": 8,
+ "numbersToBeConverted": [57, 152, 248, 239, 89, 101],
+ "enableHelp": true,
+ "bulbValueVisible": true
+ },
+ { //level6
+ "bulbCount": 8,
+ "numbersToBeConverted": [58, 153, 240, 236, 231, 255],
+ "enableHelp": false,
+ "bulbValueVisible": true
+ },
+ { //level7
+ "bulbCount": 4,
+ "numbersToBeConverted": [3, 12, 5, 10, 15, 11],
+ "enableHelp": false,
+ "bulbValueVisible": false
+ },
+ { //level8
+ "bulbCount": 8,
+ "numbersToBeConverted": [57, 152, 248, 239, 89, 101],
+ "enableHelp": false,
+ "bulbValueVisible": false
+ }
+ ];
+}
diff --git a/src/activities/binary_bulb/resource/README b/src/activities/binary_bulb/resource/README
new file mode 100644
index 000000000..068c39479
--- /dev/null
+++ b/src/activities/binary_bulb/resource/README
@@ -0,0 +1,16 @@
+Copyright: Timothee Giet, 2018
+License: CC-BY-SA 4.0
+Files:
+bulb_on.svg
+bulb_off.svg
+../binary_bulb.svg
+tutorial1.qml
+tutorial2.qml
+tutorial3.qml
+tutorial4.qml
+tutorial5.qml
+tutorial6.qml
+
+Copyright: Timothee Giet, Inductiveload, 2018
+License: CC-BY-SA 4.0
+transistor.svg
diff --git a/src/activities/binary_bulb/resource/bulb_off.svg b/src/activities/binary_bulb/resource/bulb_off.svg
new file mode 100644
index 000000000..61106c619
--- /dev/null
+++ b/src/activities/binary_bulb/resource/bulb_off.svg
@@ -0,0 +1,174 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg3390"
+ version="1.1"
+ inkscape:version="0.92.1 r15371"
+ width="192"
+ height="256"
+ viewBox="0 0 192 256"
+ sodipodi:docname="bulb_off.svg">
+ <metadata
+ id="metadata3396">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ <dc:date>2018</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Timothée Giet</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs3394">
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient880">
+ <stop
+ style="stop-color:#8c8472;stop-opacity:0.86666667"
+ offset="0"
+ id="stop876" />
+ <stop
+ style="stop-color:#c3b9a7;stop-opacity:0.78039217"
+ offset="1"
+ id="stop878" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient874"
+ inkscape:collect="always">
+ <stop
+ id="stop870"
+ offset="0"
+ style="stop-color:#635946;stop-opacity:0.54901963" />
+ <stop
+ id="stop872"
+ offset="1"
+ style="stop-color:#a79980;stop-opacity:0.2358804" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient874"
+ id="linearGradient829"
+ x1="104"
+ y1="184"
+ x2="104"
+ y2="8"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient880"
+ id="linearGradient837"
+ x1="96"
+ y1="200"
+ x2="96"
+ y2="184"
+ gradientUnits="userSpaceOnUse" />
+ </defs>
+ <sodipodi:namedview
+ pagecolor="#cfbe84"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ id="namedview3392"
+ showgrid="true"
+ inkscape:zoom="1.9992484"
+ inkscape:cx="-38.245484"
+ inkscape:cy="123.74796"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg3390">
+ <inkscape:grid
+ type="xygrid"
+ id="grid812"
+ empspacing="4" />
+ </sodipodi:namedview>
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:1;vector-effect:none;fill:#7f7767;fill-opacity:0.96078431;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ d="M 96,8 C 56.112,8 24,43.68 24,88 v 16 8 72 h -8 v 24 h 160 v -24 h -8 V 112 104 88 C 168,43.68 135.888,8 96,8 Z"
+ id="rect816-3-3" />
+ <path
+ style="opacity:1;vector-effect:none;fill:#d1c9bc;fill-opacity:0.70431896;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ d="M 96 10 C 56.112 10 28 43.68 28 88 L 28 104 L 28 112 L 28 180 L 164 180 L 164 112 L 164 104 L 164 88 C 164 43.68 135.888 10 96 10 z M 20 188 L 20 204 L 172 204 L 172 188 L 20 188 z "
+ id="rect816-3" />
+ <circle
+ style="opacity:1;vector-effect:none;fill:#9c9c99;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.5016288"
+ id="path864"
+ cx="64"
+ cy="240"
+ r="16" />
+ <circle
+ style="opacity:1;vector-effect:none;fill:#9c9c99;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.5016288"
+ id="path866"
+ cx="128"
+ cy="240"
+ r="16" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#6e6f70;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ id="rect839-3"
+ width="16"
+ height="64"
+ x="56"
+ y="184"
+ ry="8" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#6e6f70;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ id="rect839-6"
+ width="16"
+ height="64"
+ x="120"
+ y="184"
+ ry="8" />
+ <path
+ style="opacity:1;vector-effect:none;fill:url(#linearGradient829);fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ d="M 96,10 C 56.112,10 28,43.68 28,88 v 16 8 68 h 68 68 V 112 104 88 C 164,43.68 135.888,10 96,10 Z"
+ id="rect816"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="sscccccccss" />
+ <path
+ style="opacity:1;vector-effect:none;fill:url(#linearGradient837);fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ d="m 20,186 h 152 v 18 H 20 Z"
+ id="rect820"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+</svg>
diff --git a/src/activities/binary_bulb/resource/bulb_on.svg b/src/activities/binary_bulb/resource/bulb_on.svg
new file mode 100644
index 000000000..8d368ec76
--- /dev/null
+++ b/src/activities/binary_bulb/resource/bulb_on.svg
@@ -0,0 +1,183 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg3390"
+ version="1.1"
+ inkscape:version="0.92.1 r15371"
+ width="192"
+ height="256"
+ viewBox="0 0 192 256"
+ sodipodi:docname="bulb_on.svg">
+ <metadata
+ id="metadata3396">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ <dc:date>2018</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Timothée Giet</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs3394">
+ <linearGradient
+ id="linearGradient974"
+ inkscape:collect="always">
+ <stop
+ id="stop970"
+ offset="0"
+ style="stop-color:#a79980;stop-opacity:0.02990033" />
+ <stop
+ id="stop972"
+ offset="1"
+ style="stop-color:#fafabd;stop-opacity:0.70588237" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient974"
+ id="linearGradient837-7"
+ x1="96"
+ y1="208"
+ x2="96"
+ y2="192"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient974"
+ id="linearGradient829-5"
+ x1="104"
+ y1="184"
+ x2="104"
+ y2="160"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,2e-6)" />
+ </defs>
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ id="namedview3392"
+ showgrid="true"
+ inkscape:zoom="1.9992484"
+ inkscape:cx="-12.48496"
+ inkscape:cy="123.74796"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg3390">
+ <inkscape:grid
+ type="xygrid"
+ id="grid812"
+ empspacing="4" />
+ </sodipodi:namedview>
+ <circle
+ style="opacity:1;vector-effect:none;fill:#9c9c99;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ id="path864-6"
+ cx="64"
+ cy="240"
+ r="16" />
+ <circle
+ style="opacity:1;vector-effect:none;fill:#9c9c99;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ id="path866-2"
+ cx="128"
+ cy="240"
+ r="16" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#6e6f70;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ id="rect839-3-9"
+ width="16"
+ height="64"
+ x="56"
+ y="184"
+ ry="8" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#6e6f70;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ id="rect839-6-1"
+ width="16"
+ height="64"
+ x="120"
+ y="184"
+ ry="8" />
+ <path
+ style="opacity:1;vector-effect:none;fill:#e4ba13;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ d="M 96,8 C 56.112,8 24,43.68 24,88 v 16 8 72 h -8 v 24 h 160 v -24 h -8 V 112 104 88 C 168,43.68 135.888,8 96,8 Z"
+ id="rect816-2-6-1"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:1;vector-effect:none;fill:#efed38;fill-opacity:1;stroke:none;stroke-width:10.00000095;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ d="M 96,10 C 56.112,10 28,43.68 28,87.999994 V 104 112.00001 180 h 68 68 V 112.00001 104 87.999994 C 164,43.68 135.888,10 96,10 Z"
+ id="rect816-2-2"
+ sodipodi:nodetypes="sscccccccss" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:1;vector-effect:none;fill:url(#linearGradient829-5);fill-opacity:1;stroke:none;stroke-width:10.00000095;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ d="M 96,10 C 56.112,10 26,43.68 26,87.99999 V 104 112.00001 180 h 70 70 V 112.00001 104 87.99999 C 166,43.68 135.888,10 96,10 Z"
+ id="rect816-2"
+ sodipodi:nodetypes="sscccccccss" />
+ <path
+ style="opacity:1;vector-effect:none;fill:#efed38;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ d="m 20,186 h 152 v 18 H 20 Z"
+ id="rect820-7-7"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ style="opacity:1;vector-effect:none;fill:url(#linearGradient837-7);fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ d="m 20,186 h 152 v 18 H 20 Z"
+ id="rect820-7"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ <circle
+ style="opacity:1;vector-effect:none;fill:#f7f7f7;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ id="path976"
+ cx="88"
+ cy="40"
+ r="16" />
+ <circle
+ style="opacity:1;vector-effect:none;fill:#f7f7f7;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ id="path978"
+ cx="64"
+ cy="64"
+ r="8" />
+</svg>
diff --git a/src/activities/binary_bulb/resource/multipleTwo.svg b/src/activities/binary_bulb/resource/multipleTwo.svg
new file mode 100644
index 000000000..d3a2bac05
--- /dev/null
+++ b/src/activities/binary_bulb/resource/multipleTwo.svg
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg3390"
+ version="1.1"
+ inkscape:version="0.92.1 r15371"
+ width="192"
+ height="112"
+ viewBox="0 0 192 112"
+ sodipodi:docname="multipleTwo.svg">
+ <metadata
+ id="metadata3396">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ <dc:date>2018</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Timothée Giet</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs3394" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ id="namedview3392"
+ showgrid="true"
+ inkscape:zoom="1.9992484"
+ inkscape:cx="174.97252"
+ inkscape:cy="57.168987"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg3390">
+ <inkscape:grid
+ type="xygrid"
+ id="grid812"
+ empspacing="4" />
+ </sodipodi:namedview>
+ <rect
+ style="opacity:1;vector-effect:none;fill:#ea594e;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ id="rect831"
+ width="70"
+ height="16"
+ x="77"
+ y="72"
+ ry="0" />
+ <path
+ style="fill:#ea594e;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 45,80 40,24 V 56 Z"
+ id="path833"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc" />
+ <g
+ aria-label="* 2"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:53.33333206px;line-height:1.25;font-family:Kabel;-inkscape-font-specification:Kabel;letter-spacing:0px;word-spacing:0px;fill:#ea594e;fill-opacity:1;stroke:none"
+ id="text837"
+ transform="translate(-7.269532)">
+ <path
+ d="m 73.25,15.791668 -0.429688,-6.6666669 4.270833,-1.015625 v 7.6822919 l 5.234375,-3.632813 3.085938,3.203125 -6.666667,3.789063 6.184896,2.877604 -1.380208,4.153645 -6.458334,-3.841145 0.221355,6.562499 -4.0625,1.171875 v -7.408854 l -5.442708,3.73698 -3.085938,-3.203125 6.770833,-3.945313 -6.080729,-2.825521 1.276042,-4.270833 z"
+ id="path847"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 107.84635,56 16.15886,-19.361979 q 5.27344,-6.822916 5.27344,-9.70052 0,-0.169271 0,-0.325521 -0.3125,-2.825521 -1.8099,-4.205729 -1.38021,-1.289063 -3.35938,-1.289063 -0.15625,0 -0.3125,0 -2.13541,0.05208 -3.52864,1.549479 -1.38021,1.497396 -1.48438,3.632813 0,0.104167 0,0.208333 0,2.929688 3.72396,4.804688 l -6.23698,8.203124 q -0.0521,-0.05208 -1.27604,-0.846354 -1.22396,-0.807291 -2.34375,-1.705729 -4.375,-4.114583 -4.375,-10.507812 0,-0.429688 0,-0.859375 0.15625,-4.049479 2.29167,-7.356771 2.08333,-3.255208 5.80729,-5.01302 3.58073,-1.70573 7.89062,-1.70573 0.11719,0 0.22136,0 4.15364,0 7.72135,1.601563 3.58073,1.601562 5.82032,4.635416 2.18749,3.046875 2.40885,7.304688 0,0.325521 0,0.638021 0,3.307291 -1.92708,7.421874 -2.13542,4.583334 -5.16927,7.890625 l -4.47917,4.960938 h 12.95573 L 139.20052,56 Z"
+ id="path849"
+ inkscape:connector-curvature="0" />
+ </g>
+</svg>
diff --git a/src/activities/binary_bulb/resource/transistor.svg b/src/activities/binary_bulb/resource/transistor.svg
new file mode 100644
index 000000000..8fe8bbaa2
--- /dev/null
+++ b/src/activities/binary_bulb/resource/transistor.svg
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ style="overflow:visible"
+ xml:space="preserve"
+ enable-background="new 0 0 164.033 107.219"
+ overflow="visible"
+ viewBox="0 0 239.99998 157.49999"
+ height="168"
+ width="256"
+ id="Layer_1"
+ version="1.0"
+ sodipodi:docname="transistor.svg"
+ inkscape:version="0.92.1 r15371"><sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ id="namedview158"
+ showgrid="true"
+ units="px"
+ inkscape:zoom="1.7133353"
+ inkscape:cx="144.18561"
+ inkscape:cy="42.710223"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="g3367"><inkscape:grid
+ type="xygrid"
+ id="grid930"
+ empspacing="4" /></sodipodi:namedview><metadata
+ id="metadata3565"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /><dc:source>https://upload.wikimedia.org/wikipedia/commons/b/bc/BC548_NPN_Transistor.svg</dc:source><dc:description>based on https://upload.wikimedia.org/wikipedia/commons/b/bc/BC548_NPN_Transistor.svg by commons.wikimedia.org/wiki/User:Inductiveload
+adapted by Timothee Giet for GCompris, 2018</dc:description><dc:date>2018</dc:date><dc:creator><cc:Agent><dc:title>Timothee Giet , Inductiveload</dc:title></cc:Agent></dc:creator><cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" /></cc:Work><cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/4.0/"><cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" /><cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" /><cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" /><cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" /><cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" /><cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" /></cc:License></rdf:RDF></metadata><defs
+ id="defs3563" /><g
+ transform="translate(51.039361,-136.84591)"
+ id="g3571"><g
+ id="XMLID_1_"
+ transform="matrix(2,0,0,2,8.9838284,43.171497)"><path
+ inkscape:connector-curvature="0"
+ style="fill:#353634;fill-opacity:1;stroke-width:0.67972672"
+ id="path3327"
+ d="m 58.009311,92.56294 c 2.297475,-1.339059 3.704509,-4.316264 3.391835,-8.999582 0,-0.0068 0,-0.02039 0,-0.02718 L 85.504258,69.656152 c 0.203912,3.310269 -0.387444,7.150724 -3.446219,9.040364 l -0.0197,-0.02718 -24.021543,13.900411 z" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#40423e;fill-opacity:1;stroke-width:0.67972672"
+ id="path3331"
+ d="m 61.401146,83.536849 c -0.142741,-2.882041 -1.155535,-5.84565 -2.324664,-8.455799 l -0.0204,-0.0136 24.0834,-13.893614 c 1.257498,2.664529 2.100359,5.539774 2.364776,8.48299 z" /><path
+ style="fill:#40423e;fill-opacity:1;stroke-width:0.67972666"
+ d="m 37.419414,69.697549 -0.03983,1.26453 0.03983,1.30498 0.164291,1.346053 0.278794,1.344808 4.329398,-2.500434 z m 7.015903,4.057449 v 2.386553 l -5.260991,3.099717 0.482287,1.094016 0.863142,-0.482287 0.0069,-0.01369 0.564433,0.339782 7.170859,-4.214894 z m 6.117292,3.535334 v 2.398376 l -6.688569,3.875115 v 0.611729 l -1.474871,0.883053 0.0069,0.01368 0.352851,0.509672 h 0.01432 l 3.832795,-2.222264 0.0074,-0.01306 0.604885,0.339777 7.177085,-4.181286 z m 6.076217,3.514175 v 2.392777 l -6.647497,3.914942 v 0.611102 l -3.43265,1.984544 0.0069,0.01432 c 4.08516,3.568565 8.502952,4.56117 11.452959,2.841461 2.297476,-1.339059 3.704877,-4.316508 3.39221,-8.999823 l -0.02052,-0.01307 -4.750698,-2.746244 z"
+ id="path3333"
+ inkscape:connector-curvature="0" /><path
+ inkscape:connector-curvature="0"
+ style="fill:#40423e;fill-opacity:1;stroke-width:0.67972672"
+ id="path3341"
+ d="m 37.419708,69.684019 c 0.184207,-2.079963 0.842862,-4.234697 2.365449,-5.736892 l 0.0068,-0.0136 19.263455,11.133923 0.02039,0.0136 c 1.16913,2.610149 2.181922,5.573758 2.324665,8.455799 l -0.02039,0.0136 -4.750609,-2.746095 v -0.0136 l -0.03467,-0.0204 -2.18872,-1.271087 -0.0136,0.0068 h -0.0074 l -3.83366,-2.222706 -0.03263,-0.0204 -2.229505,-1.311873 -0.02039,0.0068 -3.833719,-2.215999 v -0.0068 l -0.03399,-0.0204 h -0.0068 L 42.21246,72.4436 42.19819,72.4504 Z" /><polygon
+ style="fill:#555753"
+ id="polygon3329"
+ points="159.99,16.95 124.56,37.39 96.22,21.01 96.2,21 131.67,0.57 131.68,0.55 "
+ transform="matrix(0.67972667,0,0,0.67972667,-25.610666,49.652474)" /><g
+ id="g3367"
+ style="stroke:#2a2a2a;stroke-opacity:1"
+ transform="matrix(0.95148216,0,0,0.95148216,1.6023902,93.265603)"><path
+ style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#3a3a3a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.72867495;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ d="m 65.424802,-45.839785 a 0.36437389,0.36437389 0 0 0 -0.34058,0.20874 l -25.017696,14.408568 a 0.36437389,0.36437389 0 0 0 -0.0038,0 0.36437389,0.36437389 0 0 0 -0.34058,0.310365 c -1.562423,1.639798 -2.236809,3.889155 -2.434383,6.043395 a 0.36437389,0.36437389 0 0 0 -0.01097,0.137329 l -0.03937,1.278992 a 0.36437389,0.36437389 0 0 0 0,0.02197 l 0.0412,1.37146 a 0.36437389,0.36437389 0 0 0 0.0038,0.03388 l 0.171201,1.41449 a 0.36437389,0.36437389 0 0 0 0.0055,0.0293 l 0.292054,1.407165 0.0055,0.03571 a 0.36437389,0.36437389 0 1 0 0.718692,-0.118102 l -0.0073,-0.04395 a 0.36437389,0.36437389 0 0 0 -0.0028,-0.01465 l -0.289303,-1.39801 -0.16846,-1.384277 -0.04209,-1.343994 0.02288,-0.708618 4.48791,2.596435 2.297063,1.325684 0.05315,0.03387 a 0.36437389,0.36437389 0 0 0 0.0082,0.0037 l 4.020994,2.321777 2.365725,1.37146 a 0.36437389,0.36437389 0 0 0 0.01463,0.0082 l 0.03478,0.01831 4.021912,2.324524 2.091066,1.205749 0.210572,0.127259 a 0.36437389,0.36437389 0 0 0 0.188596,0.0531 h -0.09613 l 4.805606,2.7767944 c 0.27263,4.7255899 -1.155576,7.6260239 -3.392943,8.930053 -2.911017,1.69697712 -7.392816,0.74167265 -11.613468,-2.9452512 a 0.36471316,0.36471316 0 1 0 -0.479733,0.5493164 c 4.28024,3.73898225 8.977916,4.88989 12.260741,3.1274412 a 0.36483195,0.36483195 0 0 0 0.120849,-0.0448594 l 0.08606,-0.0494386 25.060729,-14.5019518 a 0.36437392,0.36437392 0 0 0 0.25635,-0.119019 l -0.04303,0.03479 c 0.0075,-0.0046 0.01,-0.01276 0.01739,-0.01739 0.0028,-0.0018 0.0053,-0.0036 0.0082,-0.0055 0.006,-0.0038 0.01134,-0.0081 0.01739,-0.0119 1.662834,-1.045793 2.66662,-2.620167 3.210754,-4.356079 0.543,-1.732304 0.646645,-3.627281 0.543825,-5.379638 a 0.36437389,0.36437389 0 0 0 -0.01008,-0.13916 c -0.287208,-3.092997 -1.171495,-6.10722 -2.481994,-8.903503 a 0.36437389,0.36437389 0 0 0 0,-9.37e-4 0.36437389,0.36437389 0 0 0 -0.222473,-0.254517 l -20.1782,-11.688511 a 0.36437389,0.36437389 0 0 0 -0.0047,-0.0027 l -0.05035,-0.02747 a 0.36437389,0.36437389 0 0 0 -0.173034,-0.05035 z m 0.0531,0.820312 19.487914,11.290283 -24.582823,14.183348 -19.529113,-11.288451 z m 20.04913,11.808471 c 1.180416,2.593987 1.979691,5.368525 2.263186,8.203125 L 63.160702,-10.82636 c -0.241167,-2.80778 -1.191407,-5.631061 -2.300718,-8.153685 z m -45.319516,2.843628 19.829408,11.461486 a 0.36437389,0.36437389 0 0 0 0.108028,0.110779 c 1.098122,2.479208 2.034361,5.240478 2.283328,7.933959 l -4.402771,-2.545165 -0.03295,-0.02197 a 0.36437389,0.36437389 0 0 0 -0.202332,-0.06134 h 0.0943 l -0.128175,-0.0769 a 0.36437389,0.36437389 0 0 0 -0.0055,-0.0028 l -2.094727,-1.208495 -4.027401,-2.327271 a 0.36437389,0.36437389 0 0 0 -0.01556,-0.0082 l -0.03478,-0.01831 -2.356565,-1.367798 -4.019166,-2.31903 -0.05219,-0.03296 a 0.36437389,0.36437389 0 0 0 -0.0091,-0.0046 l -2.298886,-1.32843 -4.809267,-2.781372 c 0.204816,-1.9757 0.835645,-3.96857 2.174376,-5.401611 z m 47.625728,6.175232 c 0.0483,1.535096 -0.0739,3.136641 -0.526425,4.580383 -0.497409,1.586853 -1.374309,2.969285 -2.822573,3.909301 a 0.36437389,0.36437389 0 0 0 -0.129089,0.04669 L 61.64184,-2.5124563 c 1.162458,-1.7540994 1.763775,-4.2645096 1.57837,-7.5064087 z"
+ id="polyline3523"
+ inkscape:connector-curvature="0" /><g
+ style="overflow:visible;stroke:none"
+ id="g1120"
+ transform="matrix(0.71438718,0,0,0.71438718,38.373092,-45.837043)"><path
+ style="fill:#d8d9da;fill-opacity:1;stroke:none;stroke-width:1.45008361"
+ d="m 74.035156,54.65625 -9.238281,5.333984 -6.162109,3.56836 -1.203125,-0.72461 -0.01563,0.02734 -8.179688,4.742188 v 0.04492 l 1.146484,0.652343 -1.146484,0.666016 -119.021484,68.808589 v 5.21875 L -65,145.69336 55.152344,76.175781 v -5.132812 l 1.21875,0.783203 v 5.21875 l 8.267578,-4.873047 v -1.304687 l 2.957031,-1.738282 11.224609,-6.613281 v -5.091797 l -0.117187,-0.07031 z m 12.949219,7.480469 -15.298828,8.992187 -1.203125,-0.724609 -0.01563,0.0293 -1.841797,1.029297 v 0.01367 l -6.423828,3.595704 v 0.05859 l 1.146484,0.652344 -1.146484,0.667969 -118.935547,68.806639 1.832031,1.05078 -2.085937,-1.17578 v 5.21875 l 4.785156,2.69922 v -5.19336 l 0.167969,0.0957 v 5.22266 L 68.203125,83.744141 v -5.132813 l 1.21875,0.697266 v 5.21875 l 5.033203,-2.988282 3.146484,-1.882812 v -1.306641 l 14.269532,-8.265625 v -5.117187 l -0.08789,-0.04492 z m -22.345703,4.816406 v 0.08594 l -0.07227,-0.04297 z m 35.408208,2.738281 -15.310552,8.919922 -1.291016,-0.724609 -0.01562,0.02734 -8.177735,4.742188 v 0.04492 l 1.146485,0.65039 -1.146485,0.667969 -118.935547,68.720694 3.671875,2.1758 -3.802734,-2.14455 v 5.21875 l 4.785156,2.69922 v -5.19336 l 0.04492,0.0273 v 5.21875 L 81.167969,91.226562 V 86.09375 l 1.21875,0.695312 v 5.220704 l 0.943359,-0.552735 7.322266,-4.232422 v -1.304687 l 14.181636,-8.351563 v -5.105468 l -0.0859,-0.05859 h -0.0156 l -0.43554,-0.261719 z m -22.445318,4.742188 v 0.08789 l -0.07227,-0.04297 z m 13.050782,7.570312 v 0.08789 l -0.07227,-0.04492 z"
+ transform="matrix(0.68961539,0,0,0.68961539,-45.055317,-4.1417646)"
+ id="polygon3335"
+ inkscape:connector-curvature="0" /></g><path
+ style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#5e5e5e;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.72867495;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ d="m 42.654937,-22.264803 a 0.36437389,0.36437389 0 0 0 -0.289625,0.145294 l -4.438683,2.562369 -2.850071,1.650194 -0.40894,-0.246326 a 0.36437389,0.36437389 0 0 0 -0.0087,-0.0058 l -0.051,-0.0279 a 0.36437389,0.36437389 0 0 0 -0.173198,-0.05004 h -9.62e-4 a 0.36437389,0.36437389 0 0 0 -0.340624,0.209762 l -3.715099,2.15343 a 0.36437389,0.36437389 0 0 0 -0.219384,0.129899 0.36437389,0.36437389 0 0 0 -0.08083,0.467634 v 0.248251 L -28.21104,18.667682 a 0.36437389,0.36437389 0 0 0 -0.346397,0.343511 0.36437391,0.36437391 0 0 0 0,0.129898 v 2.285252 a 0.36437389,0.36437389 0 0 0 0.06062,0.437805 0.36437389,0.36437389 0 0 0 0.255949,0.158768 l 2.131299,1.220083 a 0.36437391,0.36437391 0 0 0 0.202064,0.10392 0.36437391,0.36437391 0 0 0 0.313682,-0.0866 l 58.905638,-34.081539 0.381036,0.245364 a 0.36437391,0.36437391 0 0 0 9.63e-4,9.62e-4 0.36437389,0.36437389 0 0 0 9.62e-4,9.62e-4 0.36437391,0.36437391 0 0 0 0.01155,0.01059 0.36437389,0.36437389 0 0 0 0.506123,-0.0048 l 2.201541,-1.296099 a 0.36437389,0.36437389 0 0 0 0.05196,0.294437 v 0.227082 l -58.244601,33.695675 a 0.36437389,0.36437389 0 0 0 -0.348321,0.331964 0.36437391,0.36437391 0 0 0 0,9.61e-4 0.36437391,0.36437391 0 0 0 -9.62e-4,0.149145 v 2.273705 a 0.36437389,0.36437389 0 0 0 0.06639,0.448392 0.36437389,0.36437389 0 0 0 0.250176,0.152028 l 2.112054,1.231631 a 0.36437391,0.36437391 0 0 0 0.425298,0.05292 0.36437389,0.36437389 0 0 0 0.07601,-0.05099 l 58.947977,-34.0392028 0.388734,0.2232331 a 0.36437389,0.36437389 0 0 0 0.501312,-0.00674 l 2.11879,-1.2566484 0.08756,0.1270117 a 0.36437391,0.36437391 0 0 0 0.04907,0.1462567 v 0.2492126 l -58.2446,33.6533521 a 0.36437389,0.36437389 0 0 0 -0.346396,0.312721 0.36437389,0.36437389 0 0 0 -0.0029,0.198214 v 2.250614 a 0.36437389,0.36437389 0 0 0 0.06062,0.435884 0.36437389,0.36437389 0 0 0 0.234779,0.155876 l 2.07934,1.244144 a 0.36437391,0.36437391 0 0 0 0.340623,0.128931 0.36437391,0.36437391 0 0 0 0.05581,-0.01058 0.36437389,0.36437389 0 0 0 0.171274,-0.09333 l 58.895055,-34.0719182 0.383922,0.2193841 a 0.36437389,0.36437389 0 0 0 0.5042,-0.00192 l 0.394506,-0.231893 3.448567,-1.9927405 a 0.36486611,0.36486611 0 0 0 0.340623,-0.3502448 0.36437389,0.36437389 0 0 0 0,-0.1193145 v -0.3714136 l 6.627713,-3.9036925 a 0.36437389,0.36437389 0 0 0 0.358907,-0.358905 0.36437391,0.36437391 0 0 0 0,-0.125088 v -2.408416 a 0.36437389,0.36437389 0 0 0 0.0019,-0.09333 0.36437389,0.36437389 0 0 0 -0.345433,-0.372376 l -2.0447,-1.188332 a 0.36437389,0.36437389 0 0 0 -0.298286,-0.140483 0.36437389,0.36437389 0 0 0 -0.01636,9.63e-4 0.36437389,0.36437389 0 0 0 -0.03945,-9.63e-4 0.36437389,0.36437389 0 0 0 -0.276154,0.136635 l -7.251227,4.225071 -0.45224,-0.254024 -0.04811,-0.0279 a 0.36437389,0.36437389 0 0 0 -0.210725,-0.05004 0.36437389,0.36437389 0 0 0 -0.303097,0.204951 l -2.164976,1.2556862 a 0.36486611,0.36486611 0 0 0 0.03079,-0.122201 0.36437389,0.36437389 0 0 0 0.0019,-0.1443314 v -0.3608294 l 6.687372,-3.8748264 a 0.36486969,0.36486969 0 0 0 0.340623,-0.336774 0.36437391,0.36437391 0 0 0 0.0019,-0.140483 v -2.451716 -0.0077 a 0.36437389,0.36437389 0 0 0 0,-9.62e-4 0.36437389,0.36437389 0 0 0 -0.342547,-0.40894 l -2.081264,-1.224896 a 0.36437389,0.36437389 0 0 0 -0.305984,-0.148181 0.36437389,0.36437389 0 0 0 -0.02502,0.0029 0.36437389,0.36437389 0 0 0 -0.03079,-9.62e-4 0.36437389,0.36437389 0 0 0 -0.283853,0.147218 l -7.236794,4.252976 -0.407978,-0.245364 a 0.36437389,0.36437389 0 0 0 -0.0087,-0.0058 l -0.05196,-0.0279 a 0.36437389,0.36437389 0 0 0 -0.2088,-0.04811 0.36437389,0.36437389 0 0 0 -0.30021,0.201102 l -0.711074,0.396431 a 0.36461257,0.36461257 0 0 0 -0.05966,0.04138 l -1.373076,0.767844 a 0.36437389,0.36437389 0 0 0 0.01058,-0.08083 0.36437391,0.36437391 0 0 0 0,-0.12605 v -0.368527 l 1.277817,-0.75245 5.373952,-3.164714 a 0.36486969,0.36486969 0 0 0 0.333888,-0.339661 0.36437389,0.36437389 0 0 0 0.0019,-0.131823 v -2.407453 a 0.36437389,0.36437389 0 0 0 0.0038,-0.07601 0.36437391,0.36437391 0 0 0 -0.352169,-0.389696 h -9.63e-4 L 42.9953,-22.122392 a 0.36437389,0.36437389 0 0 0 -0.301172,-0.142407 0.36437389,0.36437389 0 0 0 -0.01539,9.62e-4 0.36437389,0.36437389 0 0 0 -0.02406,-9.62e-4 z m 0.02694,0.803447 1.569368,0.914101 -6.883663,4.026856 a 0.36437389,0.36437389 0 0 0 -0.03849,0 0.36437389,0.36437389 0 0 0 -0.247288,0.620626 0.36437389,0.36437389 0 0 0 0.162613,0.127974 l -3.278255,1.934046 -0.285777,-0.184745 a 0.36437391,0.36437391 0 0 0 -0.211687,-0.168387 0.36437389,0.36437389 0 0 0 -0.01924,-0.0058 0.36437391,0.36437391 0 0 0 -0.0019,0 0.36437389,0.36437389 0 0 0 -0.09622,-0.01155 0.36437389,0.36437389 0 0 0 -0.227081,0.08371 l -58.961451,34.112362 -1.619402,-0.912175 57.915523,-33.482082 a 0.36437389,0.36437389 0 0 0 0.292512,-0.171274 l 0.315605,-0.183782 a 0.36444829,0.36444829 0 0 0 0.340623,-0.348321 0.36437389,0.36437389 0 0 0 -0.21361,-0.395469 l 3.290763,-1.908066 0.314644,0.189556 a 0.36437389,0.36437389 0 0 0 0.24825,0.110654 0.36437389,0.36437389 0 0 0 0.305021,-0.111616 l 2.937633,-1.701191 z m 1.969648,1.523181 v 1.732943 l -5.348935,3.151243 -0.908328,0.534028 v -1.134448 a 0.36437389,0.36437389 0 0 0 0.0019,-0.203989 0.36437389,0.36437389 0 0 0 -0.218422,-0.29155 z m 4.412702,2.160165 1.626139,0.957401 -6.891361,3.986443 a 0.36437389,0.36437389 0 0 0 -9.62e-4,0 0.36437389,0.36437389 0 0 0 -0.03464,-0.0019 0.36437389,0.36437389 0 0 0 -0.280004,0.589835 0.36437389,0.36437389 0 0 0 0.162614,0.155878 l -3.26286,1.94463 -0.286739,-0.164538 a 0.36437391,0.36437391 0 0 0 -0.09911,-0.102957 0.36437389,0.36437389 0 0 0 -0.216497,-0.06735 0.36437389,0.36437389 0 0 0 -0.227082,0.08467 l -59.003781,34.068046 -1.5838,-0.908328 57.813528,-33.445519 a 0.36437389,0.36437389 0 0 0 0.389696,-0.226119 l 0.289626,-0.16935 a 0.36448117,0.36448117 0 0 0 0.33485,-0.354094 0.36437389,0.36437389 0 0 0 -0.207838,-0.385846 l 2.586425,-1.448129 a 0.36437389,0.36437389 0 0 0 0.05485,-0.03753 l 0.68317,-0.381999 0.35217,0.211687 a 0.36437389,0.36437389 0 0 0 0.424335,0.03368 z m 2.016796,1.573216 v 1.726208 l -6.2996,3.649669 v -1.247027 a 0.36437389,0.36437389 0 0 0 0,-0.0019 0.36437389,0.36437389 0 0 0 -0.133748,-0.33485 0.36437389,0.36437389 0 0 0 -0.02117,-0.01636 0.36437389,0.36437389 0 0 0 -9.62e-4,0 0.36437389,0.36437389 0 0 0 -0.0356,-0.02213 z m -13.415155,1.031491 v 1.236442 a 0.36437389,0.36437389 0 0 0 0,0.113541 v 0.374301 l -3.344648,1.972533 v -1.726207 z m 17.826894,1.122901 1.581877,0.918912 -6.849984,4.0258941 a 0.36437389,0.36437389 0 0 0 -0.03945,-9.621e-4 0.36437389,0.36437389 0 0 0 -0.225157,0.6408329 0.36437389,0.36437389 0 0 0 0.116427,0.095259 l -3.304235,1.9109524 -0.285777,-0.1626137 a 0.36437391,0.36437391 0 0 0 -0.178009,-0.1462562 0.36437389,0.36437389 0 0 0 -0.0096,-0.00385 0.36437391,0.36437391 0 0 0 -0.03464,-0.00962 0.36437389,0.36437389 0 0 0 -0.09526,-0.012509 0.36437389,0.36437389 0 0 0 -0.219384,0.077939 L -13.017671,27.399753 -14.613018,26.454861 43.273639,-6.9916165 a 0.36437389,0.36437389 0 0 0 0.294437,-0.1703115 l 0.296362,-0.1731983 a 0.36437389,0.36437389 0 0 0 0.362753,-0.4657102 0.36437389,0.36437389 0 0 0 -0.216497,-0.2896259 l 3.296537,-1.9109526 0.422411,0.2376666 a 0.36496892,0.36496892 0 0 0 0.05485,0.030791 0.36437389,0.36437389 0 0 0 9.62e-4,0 0.36496892,0.36496892 0 0 0 0.0048,0.00192 0.36437389,0.36437389 0 0 0 0.422411,-0.077939 z m -22.500357,0.84386 v 1.729094 l -58.464946,33.826554 v -1.731018 z m 24.47674,0.687981 v 1.728132 l -6.258223,3.6862335 v -1.1969911 a 0.36437389,0.36437389 0 0 0 0.0029,-0.052922 0.36437389,0.36437389 0 0 0 -0.197254,-0.3694893 0.36437389,0.36437389 0 0 0 -0.0029,-9.622e-4 z m -13.417078,1.03534 v 1.287439 0.43492 l -1.372114,0.8217289 -1.929235,1.1459943 v -1.7242834 z m -4.630163,2.0033251 v 1.7319806 L -19.08634,26.036298 v -1.732939 z m 11.059661,1.7165852 v 1.2960995 0.4329951 l -3.343685,1.9330833 v -1.728132 z m -4.671537,1.9706096 v 1.7300568 L -12.655879,29.763908 v -1.730057 z m -73.639024,25.4947611 1.628063,0.917949 v 1.730057 l -1.628063,-0.931418 z m 6.429499,3.692971 1.584763,0.909289 v 1.72717 l -1.584763,-0.925649 z m 6.429499,3.695854 1.584763,0.939119 V 29.7514 l -1.584763,-0.94874 z"
+ id="polyline3369"
+ inkscape:connector-curvature="0" /></g></g><g
+ id="g3555"
+ transform="matrix(2,0,0,2,8.9838285,29.171497)" /></g></svg>
\ No newline at end of file
diff --git a/src/activities/binary_bulb/resource/tutorial1.qml b/src/activities/binary_bulb/resource/tutorial1.qml
new file mode 100644
index 000000000..9d52ab1bb
--- /dev/null
+++ b/src/activities/binary_bulb/resource/tutorial1.qml
@@ -0,0 +1,61 @@
+/* GCompris - tutorial1.qml
+ *
+ * Copyright (C) 2018 Timothée Giet <animtim@gcompris.net>
+ *
+ * Authors:
+ * Timothée Giet <animtim@gcompris.net>
+ *
+ * This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+ */
+import QtQuick 2.6
+import GCompris 1.0
+
+import "../../../core"
+
+Rectangle {
+ anchors.fill: parent
+ color: "#80FFFFFF"
+
+ GCText {
+ id: firstList
+ anchors {
+ left: parent.left
+ verticalCenter: parent.verticalCenter
+ leftMargin: parent.height * 0.1
+ }
+ text:
+ "0 = 0000\n1 = 0001\n2 = 0010\n3 = 0011\n4 = 0100\n5 = 0101\n6 = 0110\n7 = 0111\n"
+ font.pixelSize: parent.height / 15
+ color: "black"
+ horizontalAlignment: Text.AlignHLeft
+ width: 0.4 * parent.width
+ height: 0.9 * parent.height
+ z: 2
+ }
+
+ GCText {
+ anchors {
+ left: parent.horizontalCenter
+ verticalCenter: parent.verticalCenter
+ }
+ text:
+ "08 = 1000\n09 = 1001\n10 = 1010\n11 = 1011\n12 = 1100\n13 = 1101\n14 = 1110\n15 = 1111"
+ font.pixelSize: firstList.font.pixelSize
+ color: "black"
+ horizontalAlignment: Text.AlignHLeft
+ width: 0.4 * parent.width
+ height: 0.9 * parent.height
+ z: 2
+ }
+}
diff --git a/src/activities/binary_bulb/resource/tutorial2.qml b/src/activities/binary_bulb/resource/tutorial2.qml
new file mode 100644
index 000000000..740c2d858
--- /dev/null
+++ b/src/activities/binary_bulb/resource/tutorial2.qml
@@ -0,0 +1,115 @@
+/* GCompris - tutorial2.qml
+ *
+ * Copyright (C) 2018 Timothée Giet <animtim@gcompris.net>
+ *
+ * Authors:
+ * Timothée Giet <animtim@gcompris.net>
+ *
+ * This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+ */
+import QtQuick 2.6
+import GCompris 1.0
+
+import "../../../core"
+
+Rectangle {
+ anchors.fill: parent
+ color: "#80FFFFFF"
+
+ Item {
+ width: parent.width
+ height: parent.height * 0.5
+
+ Image {
+ source: "transistor.svg"
+ fillMode: Image.PreserveAspectFit
+ anchors.fill: parent
+ sourceSize.height: implicitHeight
+ }
+ }
+
+ Item {
+ width: parent.width * 0.2
+ height: parent.height * 0.5
+ anchors.bottom: parent.bottom
+ anchors.left: parent.left
+
+ GCText {
+ anchors {
+ right: parent.right
+ verticalCenter: parent.verticalCenter
+ }
+ text: "0"
+ font.pixelSize: parent.height * 0.5
+ color: "black"
+ horizontalAlignment: Text.AlignRight
+ width: 0.9 * parent.width
+ height: 0.9 * parent.height
+ z: 2
+ }
+ }
+
+ Item {
+ width: parent.width * 0.3
+ height: parent.height * 0.4
+ anchors.bottom: parent.bottom
+ anchors.right: parent.horizontalCenter
+ anchors.bottomMargin: parent.height * 0.05
+
+ Image {
+ source: ""
+ fillMode: Image.PreserveAspectFit
+ anchors.fill: parent
+ sourceSize.width: implicitWidth
+ }
+
+ }
+
+ Item {
+ width: parent.width * 0.3
+ height: parent.height * 0.4
+ anchors.bottom: parent.bottom
+ anchors.left: parent.horizontalCenter
+ anchors.bottomMargin: parent.height * 0.05
+
+ Image {
+ source: ""
+ fillMode: Image.PreserveAspectFit
+ anchors.fill: parent
+ sourceSize.width: implicitWidth
+ }
+
+ }
+
+ Item {
+ width: parent.width * 0.2
+ height: parent.height * 0.5
+ anchors.bottom: parent.bottom
+ anchors.right: parent.right
+
+ GCText {
+ anchors {
+ left: parent.left
+ verticalCenter: parent.verticalCenter
+ }
+ text: "1"
+ font.pixelSize: parent.height * 0.5
+ color: "black"
+ horizontalAlignment: Text.AlignLeft
+ width: 0.9 * parent.width
+ height: 0.9 * parent.height
+ z: 2
+ }
+ }
+}
diff --git a/src/activities/binary_bulb/resource/tutorial3.qml b/src/activities/binary_bulb/resource/tutorial3.qml
new file mode 100644
index 000000000..0e16f4312
--- /dev/null
+++ b/src/activities/binary_bulb/resource/tutorial3.qml
@@ -0,0 +1,115 @@
+/* GCompris - tutorial3.qml
+ *
+ * Copyright (C) 2018 Timothée Giet <animtim@gcompris.net>
+ *
+ * Authors:
+ * Timothée Giet <animtim@gcompris.net>
+ *
+ * This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+ */
+import QtQuick 2.6
+import GCompris 1.0
+
+import "../../../core"
+
+Rectangle {
+ anchors.fill: parent
+ color: "#80FFFFFF"
+
+ Item {
+ width: parent.width
+ height: parent.height * 0.5
+
+ Image {
+ source: "transistor.svg"
+ fillMode: Image.PreserveAspectFit
+ anchors.fill: parent
+ sourceSize.height: implicitHeight
+ }
+ }
+
+ Item {
+ width: parent.width * 0.2
+ height: parent.height * 0.5
+ anchors.bottom: parent.bottom
+ anchors.left: parent.left
+
+ GCText {
+ anchors {
+ right: parent.right
+ verticalCenter: parent.verticalCenter
+ }
+ text: "0"
+ font.pixelSize: parent.height * 0.5
+ color: "black"
+ horizontalAlignment: Text.AlignRight
+ width: 0.9 * parent.width
+ height: 0.9 * parent.height
+ z: 2
+ }
+ }
+
+ Item {
+ width: parent.width * 0.3
+ height: parent.height * 0.4
+ anchors.bottom: parent.bottom
+ anchors.right: parent.horizontalCenter
+ anchors.bottomMargin: parent.height * 0.05
+
+ Image {
+ source: "bulb_off.svg"
+ fillMode: Image.PreserveAspectFit
+ anchors.fill: parent
+ sourceSize.width: implicitWidth
+ }
+
+ }
+
+ Item {
+ width: parent.width * 0.3
+ height: parent.height * 0.4
+ anchors.bottom: parent.bottom
+ anchors.left: parent.horizontalCenter
+ anchors.bottomMargin: parent.height * 0.05
+
+ Image {
+ source: "bulb_on.svg"
+ fillMode: Image.PreserveAspectFit
+ anchors.fill: parent
+ sourceSize.width: implicitWidth
+ }
+
+ }
+
+ Item {
+ width: parent.width * 0.2
+ height: parent.height * 0.5
+ anchors.bottom: parent.bottom
+ anchors.right: parent.right
+
+ GCText {
+ anchors {
+ left: parent.left
+ verticalCenter: parent.verticalCenter
+ }
+ text: "1"
+ font.pixelSize: parent.height * 0.5
+ color: "black"
+ horizontalAlignment: Text.AlignLeft
+ width: 0.9 * parent.width
+ height: 0.9 * parent.height
+ z: 2
+ }
+ }
+}
diff --git a/src/activities/binary_bulb/resource/tutorial4.qml b/src/activities/binary_bulb/resource/tutorial4.qml
new file mode 100644
index 000000000..669c00177
--- /dev/null
+++ b/src/activities/binary_bulb/resource/tutorial4.qml
@@ -0,0 +1,142 @@
+/* GCompris - tutorial4.qml
+ *
+ * Copyright (C) 2018 Timothée Giet <animtim@gcompris.net>
+ *
+ * Authors:
+ * Timothée Giet <animtim@gcompris.net>
+ *
+ * This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+ */
+import QtQuick 2.6
+import GCompris 1.0
+
+import "../../../core"
+
+Rectangle {
+ anchors.fill: parent
+ color: "#80FFFFFF"
+
+ Item {
+ id: topBlock
+ width: parent.width
+ height: parent.height * 0.2
+
+ GCText {
+ anchors {
+ right: parent.right
+ verticalCenter: parent.verticalCenter
+ }
+ text: qsTr("0 to 255 with")
+ fontSizeMode: Text.Fit
+ minimumPixelSize: 15
+ color: "black"
+ horizontalAlignment: Text.AlignHCenter
+ width: 0.9 * parent.width
+ height: 0.9 * parent.height
+ wrapMode: Text.WordWrap
+ z: 2
+ }
+ }
+
+ Row {
+ id: tableBlock1
+ width: parent.width * 0.9
+ height: parent.height * 0.2
+ anchors.top: topBlock.bottom
+ anchors.left: parent.left
+ anchors.leftMargin: parent.width * 0.05
+ Repeater {
+ model: ["", "", "", "", "", "", "", ""]
+ Item {
+ id: item128
+ width: parent.width / 8
+ height: parent.height
+ anchors.verticalCenter: parent.verticalCenter
+ GCText {
+ anchors {
+ right: parent.right
+ verticalCenter: parent.verticalCenter
+ horizontalCenter: parent.horizontalCenter
+ }
+ text: modelData
+ fontSizeMode: Text.Fit
+ minimumPixelSize: 15
+ color: "black"
+ horizontalAlignment: Text.AlignHCenter
+ width: 0.9 * parent.width
+ height: 0.9 * parent.height
+ wrapMode: Text.WordWrap
+ z: 2
+ }
+ }
+ }
+ }
+
+ Row {
+ id: bulbBlock
+ width: parent.width * 0.9
+ height: parent.height * 0.4
+ anchors.top: tableBlock1.bottom
+ anchors.left: parent.left
+ anchors.leftMargin: parent.width * 0.05
+ Repeater {
+ model: ["off", "off", "off", "off", "off", "off", "off", "off"]
+ Item {
+ id: item128
+ width: parent.width / 8
+ height: parent.height
+ anchors.verticalCenter: parent.verticalCenter
+ Image {
+ source: "bulb_" + modelData + ".svg"
+ fillMode: Image.PreserveAspectFit
+ anchors.fill: parent
+ sourceSize.width: implicitWidth
+ }
+ }
+ }
+ }
+
+ Row {
+ width: parent.width * 0.9
+ height: parent.height * 0.2
+ anchors.top: bulbBlock.bottom
+ anchors.left: parent.left
+ anchors.leftMargin: parent.width * 0.05
+ Repeater {
+ model: ["0", "0", "0", "0", "0", "0", "0", "0"]
+ Item {
+ id: item128
+ width: parent.width / 8
+ height: parent.height
+ anchors.verticalCenter: parent.verticalCenter
+ GCText {
+ anchors {
+ right: parent.right
+ verticalCenter: parent.verticalCenter
+ horizontalCenter: parent.horizontalCenter
+ }
+ text: modelData
+ fontSizeMode: Text.Fit
+ minimumPixelSize: 15
+ color: "black"
+ horizontalAlignment: Text.AlignHCenter
+ width: 0.9 * parent.width
+ height: 0.9 * parent.height
+ wrapMode: Text.WordWrap
+ z: 2
+ }
+ }
+ }
+ }
+}
diff --git a/src/activities/binary_bulb/resource/tutorial5.qml b/src/activities/binary_bulb/resource/tutorial5.qml
new file mode 100644
index 000000000..72e4069e2
--- /dev/null
+++ b/src/activities/binary_bulb/resource/tutorial5.qml
@@ -0,0 +1,165 @@
+/* GCompris - tutorial5.qml
+ *
+ * Copyright (C) 2018 Timothée Giet <animtim@gcompris.net>
+ *
+ * Authors:
+ * Timothée Giet <animtim@gcompris.net>
+ *
+ * This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+ */
+import QtQuick 2.6
+import GCompris 1.0
+
+import "../../../core"
+
+Rectangle {
+ anchors.fill: parent
+ color: "#80FFFFFF"
+
+ Item {
+ id: topBlock
+ width: parent.width
+ height: parent.height * 0.2
+
+ GCText {
+ anchors {
+ right: parent.right
+ verticalCenter: parent.verticalCenter
+ }
+ text: qsTr("0 to 255 with")
+ fontSizeMode: Text.Fit
+ minimumPixelSize: 15
+ color: "black"
+ horizontalAlignment: Text.AlignHCenter
+ width: 0.9 * parent.width
+ height: 0.9 * parent.height
+ wrapMode: Text.WordWrap
+ z: 2
+ }
+ }
+
+ Row {
+ id: tableBlock1
+ width: parent.width * 0.9
+ height: parent.height * 0.2
+ anchors.top: topBlock.bottom
+ anchors.left: parent.left
+ anchors.leftMargin: parent.width * 0.05
+ Repeater {
+ model: ["128", "64", "32", "16", "8", "4", "2", "1"]
+ Item {
+ id: item128
+ width: parent.width / 8
+ height: parent.height
+ anchors.verticalCenter: parent.verticalCenter
+ GCText {
+ anchors {
+ right: parent.right
+ verticalCenter: parent.verticalCenter
+ horizontalCenter: parent.horizontalCenter
+ }
+ text: modelData
+ fontSizeMode: Text.Fit
+ minimumPixelSize: 15
+ color: "black"
+ horizontalAlignment: Text.AlignHCenter
+ width: 0.9 * parent.width
+ height: 0.9 * parent.height
+ wrapMode: Text.WordWrap
+ z: 2
+ }
+ }
+ }
+ }
+
+ Row {
+ id: tableBlock2
+ width: parent.width * 0.9
+ height: parent.height * 0.1
+ anchors.verticalCenter: tableBlock1.top
+ anchors.left: parent.left
+ anchors.leftMargin: parent.width * 0.05 + tableBlock1.width/20
+ Repeater {
+ model: 7
+ Item {
+ width: parent.width / 8
+ height: parent.height
+ anchors.verticalCenter: parent.verticalCenter
+ Image {
+ source: "multipleTwo.svg"
+ fillMode: Image.PreserveAspectFit
+ anchors.fill: parent
+ sourceSize.width: implicitWidth
+ }
+ }
+ }
+ }
+
+ Row {
+ id: bulbBlock
+ width: parent.width * 0.9
+ height: parent.height * 0.4
+ anchors.top: tableBlock1.bottom
+ anchors.left: parent.left
+ anchors.leftMargin: parent.width * 0.05
+ Repeater {
+ model: ["off", "off", "off", "off", "off", "off", "off", "off"]
+ Item {
+ id: item128
+ width: parent.width / 8
+ height: parent.height
+ anchors.verticalCenter: parent.verticalCenter
+ Image {
+ source: "bulb_" + modelData + ".svg"
+ fillMode: Image.PreserveAspectFit
+ anchors.fill: parent
+ sourceSize.width: implicitWidth
+ }
+ }
+ }
+ }
+
+ Row {
+ width: parent.width * 0.9
+ height: parent.height * 0.2
+ anchors.top: bulbBlock.bottom
+ anchors.left: parent.left
+ anchors.leftMargin: parent.width * 0.05
+ Repeater {
+ model: ["0", "0", "0", "0", "0", "0", "0", "0"]
+ Item {
+ id: item128
+ width: parent.width / 8
+ height: parent.height
+ anchors.verticalCenter: parent.verticalCenter
+ GCText {
+ anchors {
+ right: parent.right
+ verticalCenter: parent.verticalCenter
+ horizontalCenter: parent.horizontalCenter
+ }
+ text: modelData
+ fontSizeMode: Text.Fit
+ minimumPixelSize: 15
+ color: "black"
+ horizontalAlignment: Text.AlignHCenter
+ width: 0.9 * parent.width
+ height: 0.9 * parent.height
+ wrapMode: Text.WordWrap
+ z: 2
+ }
+ }
+ }
+ }
+}
diff --git a/src/activities/binary_bulb/resource/tutorial6.qml b/src/activities/binary_bulb/resource/tutorial6.qml
new file mode 100644
index 000000000..078005ded
--- /dev/null
+++ b/src/activities/binary_bulb/resource/tutorial6.qml
@@ -0,0 +1,142 @@
+/* GCompris - tutorial6.qml
+ *
+ * Copyright (C) 2018 Timothée Giet <animtim@gcompris.net>
+ *
+ * Authors:
+ * Timothée Giet <animtim@gcompris.net>
+ *
+ * This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+ */
+import QtQuick 2.6
+import GCompris 1.0
+
+import "../../../core"
+
+Rectangle {
+ anchors.fill: parent
+ color: "#80FFFFFF"
+
+ Item {
+ id: topBlock
+ width: parent.width
+ height: parent.height * 0.2
+
+ GCText {
+ anchors {
+ right: parent.right
+ verticalCenter: parent.verticalCenter
+ }
+ text: "5 ="
+ fontSizeMode: Text.Fit
+ minimumPixelSize: 15
+ color: "black"
+ horizontalAlignment: Text.AlignHCenter
+ width: 0.9 * parent.width
+ height: 0.9 * parent.height
+ wrapMode: Text.WordWrap
+ z: 2
+ }
+ }
+
+ Row {
+ id: tableBlock1
+ width: parent.width * 0.9
+ height: parent.height * 0.2
+ anchors.top: topBlock.bottom
+ anchors.left: parent.left
+ anchors.leftMargin: parent.width * 0.05
+ Repeater {
+ model: ["", "", "", "", "", "4", "+", "1"]
+ Item {
+ id: item128
+ width: parent.width / 8
+ height: parent.height
+ anchors.verticalCenter: parent.verticalCenter
+ GCText {
+ anchors {
+ right: parent.right
+ verticalCenter: parent.verticalCenter
+ horizontalCenter: parent.horizontalCenter
+ }
+ text: modelData
+ fontSizeMode: Text.Fit
+ minimumPixelSize: 15
+ color: "black"
+ horizontalAlignment: Text.AlignHCenter
+ width: 0.9 * parent.width
+ height: 0.9 * parent.height
+ wrapMode: Text.WordWrap
+ z: 2
+ }
+ }
+ }
+ }
+
+ Row {
+ id: bulbBlock
+ width: parent.width * 0.9
+ height: parent.height * 0.4
+ anchors.top: tableBlock1.bottom
+ anchors.left: parent.left
+ anchors.leftMargin: parent.width * 0.05
+ Repeater {
+ model: ["off", "off", "off", "off", "off", "on", "off", "on"]
+ Item {
+ id: item128
+ width: parent.width / 8
+ height: parent.height
+ anchors.verticalCenter: parent.verticalCenter
+ Image {
+ source: "bulb_" + modelData + ".svg"
+ fillMode: Image.PreserveAspectFit
+ anchors.fill: parent
+ sourceSize.width: implicitWidth
+ }
+ }
+ }
+ }
+
+ Row {
+ width: parent.width * 0.9
+ height: parent.height * 0.2
+ anchors.top: bulbBlock.bottom
+ anchors.left: parent.left
+ anchors.leftMargin: parent.width * 0.05
+ Repeater {
+ model: ["0", "0", "0", "0", "0", "1", "0", "1"]
+ Item {
+ id: item128
+ width: parent.width / 8
+ height: parent.height
+ anchors.verticalCenter: parent.verticalCenter
+ GCText {
+ anchors {
+ right: parent.right
+ verticalCenter: parent.verticalCenter
+ horizontalCenter: parent.horizontalCenter
+ }
+ text: modelData
+ fontSizeMode: Text.Fit
+ minimumPixelSize: 15
+ color: "black"
+ horizontalAlignment: Text.AlignHCenter
+ width: 0.9 * parent.width
+ height: 0.9 * parent.height
+ wrapMode: Text.WordWrap
+ z: 2
+ }
+ }
+ }
+ }
+}
diff --git a/src/activities/binary_bulb/resource/tutorial7.qml b/src/activities/binary_bulb/resource/tutorial7.qml
new file mode 100644
index 000000000..86fc36608
--- /dev/null
+++ b/src/activities/binary_bulb/resource/tutorial7.qml
@@ -0,0 +1,142 @@
+/* GCompris - tutorial7.qml
+ *
+ * Copyright (C) 2018 Timothée Giet <animtim@gcompris.net>
+ *
+ * Authors:
+ * Timothée Giet <animtim@gcompris.net>
+ *
+ * This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+ */
+import QtQuick 2.6
+import GCompris 1.0
+
+import "../../../core"
+
+Rectangle {
+ anchors.fill: parent
+ color: "#80FFFFFF"
+
+ Item {
+ id: topBlock
+ width: parent.width
+ height: parent.height * 0.2
+
+ GCText {
+ anchors {
+ right: parent.right
+ verticalCenter: parent.verticalCenter
+ }
+ text: "5 = 101"
+ fontSizeMode: Text.Fit
+ minimumPixelSize: 15
+ color: "black"
+ horizontalAlignment: Text.AlignHCenter
+ width: 0.9 * parent.width
+ height: 0.9 * parent.height
+ wrapMode: Text.WordWrap
+ z: 2
+ }
+ }
+
+ Row {
+ id: tableBlock1
+ width: parent.width * 0.9
+ height: parent.height * 0.2
+ anchors.top: topBlock.bottom
+ anchors.left: parent.left
+ anchors.leftMargin: parent.width * 0.05
+ Repeater {
+ model: ["", "", "", "", "", "4", "+", "1"]
+ Item {
+ id: item128
+ width: parent.width / 8
+ height: parent.height
+ anchors.verticalCenter: parent.verticalCenter
+ GCText {
+ anchors {
+ right: parent.right
+ verticalCenter: parent.verticalCenter
+ horizontalCenter: parent.horizontalCenter
+ }
+ text: modelData
+ fontSizeMode: Text.Fit
+ minimumPixelSize: 15
+ color: "black"
+ horizontalAlignment: Text.AlignHCenter
+ width: 0.9 * parent.width
+ height: 0.9 * parent.height
+ wrapMode: Text.WordWrap
+ z: 2
+ }
+ }
+ }
+ }
+
+ Row {
+ id: bulbBlock
+ width: parent.width * 0.9
+ height: parent.height * 0.4
+ anchors.top: tableBlock1.bottom
+ anchors.left: parent.left
+ anchors.leftMargin: parent.width * 0.05
+ Repeater {
+ model: ["off", "off", "off", "off", "off", "on", "off", "on"]
+ Item {
+ id: item128
+ width: parent.width / 8
+ height: parent.height
+ anchors.verticalCenter: parent.verticalCenter
+ Image {
+ source: "bulb_" + modelData + ".svg"
+ fillMode: Image.PreserveAspectFit
+ anchors.fill: parent
+ sourceSize.width: implicitWidth
+ }
+ }
+ }
+ }
+
+ Row {
+ width: parent.width * 0.9
+ height: parent.height * 0.2
+ anchors.top: bulbBlock.bottom
+ anchors.left: parent.left
+ anchors.leftMargin: parent.width * 0.05
+ Repeater {
+ model: ["0", "0", "0", "0", "0", "1", "0", "1"]
+ Item {
+ id: item128
+ width: parent.width / 8
+ height: parent.height
+ anchors.verticalCenter: parent.verticalCenter
+ GCText {
+ anchors {
+ right: parent.right
+ verticalCenter: parent.verticalCenter
+ horizontalCenter: parent.horizontalCenter
+ }
+ text: modelData
+ fontSizeMode: Text.Fit
+ minimumPixelSize: 15
+ color: "black"
+ horizontalAlignment: Text.AlignHCenter
+ width: 0.9 * parent.width
+ height: 0.9 * parent.height
+ wrapMode: Text.WordWrap
+ z: 2
+ }
+ }
+ }
+ }
+}
diff --git a/src/activities/braille_alphabets/ActivityInfo.qml b/src/activities/braille_alphabets/ActivityInfo.qml
index 728846bec..e65b305e1 100644
--- a/src/activities/braille_alphabets/ActivityInfo.qml
+++ b/src/activities/braille_alphabets/ActivityInfo.qml
@@ -1,41 +1,41 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Arkit Vora <arkitvora123@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "braille_alphabets/BrailleAlphabets.qml"
difficulty: 5
icon: "braille_alphabets/braille_alphabets.svg"
author: "Arkit Vora &lt;arkitvora123@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Discover the Braille system")
//: Help title
description: qsTr("Learn and memorize the Braille system")
//intro: "Click on Tux to start and then re-create the Braille cells."
//: Help goal
goal: qsTr("Let children discover the Braille system.")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("The screen has 3 sections: an interactive braille cell, an instruction telling you the letter to reproduce, " +
"and at the top the Braille letters to use as a reference. Each level teaches a set of 10 letters.")
credit: ""
section: "discovery braille"
createdInVersion: 0
}
diff --git a/src/activities/braille_alphabets/BrailleAlphabets.qml b/src/activities/braille_alphabets/BrailleAlphabets.qml
index e00048cf7..837c9a082 100644
--- a/src/activities/braille_alphabets/BrailleAlphabets.qml
+++ b/src/activities/braille_alphabets/BrailleAlphabets.qml
@@ -1,30 +1,320 @@
-/* GCompris - Braille_alphabets.qml
+/* GCompris - BrailleAlphabets.qml
*
* Copyright (C) 2014 Arkit Vora <arkitvora123@gmail.com>
*
* Authors:
* Srishti Sethi <srishakatux@gmail.com> (GTK+ version)
* Arkit Vora <arkitvora123@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
-
import QtQuick 2.6
import GCompris 1.0
-
+import "../../core"
+import "braille_alphabets.js" as Activity
import "questions.js" as Dataset
-Screen {
- dataset: Dataset
+ActivityBase {
+ id: activity
+
+ onStart: focus = true
+ onStop: {}
+
+ property var dataset: Dataset
+
+ pageComponent: Image {
+ id: background
+ anchors.fill: parent
+ fillMode: Image.PreserveAspectCrop
+ source: Activity.url + "background.svg"
+ sourceSize.width: Math.max(parent.width, parent.height)
+ signal start
+ signal stop
+ Component.onCompleted: {
+ activity.start.connect(start)
+ activity.stop.connect(stop)
+ }
+
+ Keys.onPressed: {
+ if(first_screen.visible) {
+ // If return, we hide the screen
+ first_screen.visible = false
+ return;
+ }
+ var keyValue;
+ switch(event.key)
+ {
+ case Qt.Key_1:
+ keyValue = 1;
+ break;
+ case Qt.Key_2:
+ keyValue = 2;
+ break;
+ case Qt.Key_3:
+ keyValue = 3;
+ break;
+ case Qt.Key_4:
+ keyValue = 4;
+ break;
+ case Qt.Key_5:
+ keyValue = 5;
+ break;
+ case Qt.Key_6:
+ keyValue = 6;
+ break;
+ }
+ if(keyValue)
+ playableChar.switchState(keyValue)
+ }
+
+ // Add here the QML items you need to access in javascript
+ QtObject {
+ id: items
+ property Item main: activity.main
+ property alias background: background
+ property alias bar: bar
+ property alias bonus: bonus
+ property alias containerModel: containerModel
+ property alias questionItem: questionItem
+ property string instructions
+ property alias playableChar: playableChar
+ property alias score: score
+ property bool brailleCodeSeen
+ }
+
+ onStart: {
+ first_screen.visible = true
+ Activity.start(items, dataset)
+ }
+ onStop: { Activity.stop() }
+
+
+ ListModel {
+ id: containerModel
+ }
+
+ Image {
+ id: charList
+ y: 20 * ApplicationInfo.ratio
+ anchors.horizontalCenter: parent.horizontalCenter
+ source: Activity.url + "top_back.svg"
+ sourceSize.width: parent.width * 0.94
+ visible: items.brailleCodeSeen
+
+ Row {
+ id: row
+ spacing: 10 * ApplicationInfo.ratio
+ anchors.centerIn: charList
+ anchors.horizontalCenterOffset: 5
+
+ Repeater {
+ id: cardRepeater
+ model: containerModel
+
+ // workaround for https://bugreports.qt.io/browse/QTBUG-72643 (qml binding with global variable in Repeater do not work)
+ property alias rowSpacing: row.spacing
+ Item {
+ id: inner
+ height: charList.height * 0.9
+ width: (charList.width - containerModel.count * cardRepeater.rowSpacing)/ containerModel.count
+
+ Rectangle {
+ id: rect1
+ width: charList.width / 13
+ height: ins.height
+ border.width: 0
+ border.color: "black"
+ color: "#a5cbd9"
+
+ BrailleChar {
+ id: ins
+ width: parent.width * 0.9
+ anchors.centerIn: parent
+ clickable: false
+ brailleChar: letter
+ }
+ }
+
+ GCText {
+ text: letter
+ font.weight: Font.DemiBold
+ color: "#2a2a2a"
+ font.pointSize: NaN // need to clear font.pointSize explicitly
+ font.pixelSize: rect1.width * 0.5
+ anchors {
+ top: rect1.bottom
+ topMargin: 4 * ApplicationInfo.ratio
+ horizontalCenter: rect1.horizontalCenter
+ }
+ }
+ }
+ }
+ }
+ }
+
+ Image {
+ id: playableCharBg
+ anchors {
+ top: charList.bottom
+ topMargin: 10 * ApplicationInfo.ratio
+ }
+ verticalAlignment: Image.AlignTop
+ x: 10 * ApplicationInfo.ratio
+ source: Activity.url + "char_background.svg"
+ sourceSize.width: playableChar.width * 1.8
+ height: (playableChar.height + playableCharDisplay.height) * 1.2
+
+ BrailleChar {
+ id: playableChar
+ clickable: true
+ anchors {
+ horizontalCenter: parent.horizontalCenter
+ top: parent.top
+ topMargin: 20 * ApplicationInfo.ratio
+ }
+ width: Math.min(background.width * 0.18, background.height * 0.2)
+ isLetter: true
+ onBrailleCharChanged: {
+ if(brailleChar === Activity.getCurrentLetter()) {
+ particles.burst(40)
+ Activity.nextQuestion()
+ }
+ }
+ }
+
+ GCText {
+ id: playableCharDisplay
+ font.pointSize: NaN // need to clear font.pointSize explicitly
+ font.pixelSize: Math.max(playableChar.width * 0.4, 24)
+ font.weight: Font.DemiBold
+ color: "#2a2a2a"
+ text: playableChar.brailleChar
+ anchors {
+ top: playableChar.bottom
+ topMargin: 4 * ApplicationInfo.ratio
+ horizontalCenter: playableChar.horizontalCenter
+ }
+ }
+ }
+
+ Rectangle {
+ id: instructionsArea
+ height: parent.height * 0.3
+ width: parent.width / 1.1
+ anchors {
+ top: charList.bottom
+ topMargin: 10 * ApplicationInfo.ratio
+ left: playableCharBg.right
+ leftMargin: 10 * ApplicationInfo.ratio
+ right: parent.right
+ rightMargin: 10 * ApplicationInfo.ratio
+ }
+ color: "#55333333"
+ border.width: 0
+ radius: 5
+
+ GCText {
+ id: questionItem
+ anchors.centerIn: parent
+ fontSize: largeSize
+ fontSizeMode: Text.Fit
+ horizontalAlignment: Text.AlignHCenter
+ font.weight: Font.DemiBold
+ style: Text.Outline
+ styleColor: "black"
+ color: "white"
+ width: parent.width * 0.94
+ height: parent.height * 0.94
+ wrapMode: Text.WordWrap
+
+ function initQuestion() {
+ playableChar.clearLetter()
+ text = Activity.getCurrentTextQuestion()
+ if(items.instructions)
+ text += "\n" + items.instructions
+ opacity = 1.0
+ }
+
+ onOpacityChanged: opacity == 0 ? initQuestion() : ""
+ Behavior on opacity { PropertyAnimation { duration: 500 } }
+ }
+ }
+
+ ParticleSystemStarLoader {
+ id: particles
+ clip: false
+ }
+
+ FirstScreen {
+ id: first_screen
+ }
+
+ Score {
+ id: score
+ anchors {
+ top: instructionsArea.bottom
+ left: instructionsArea.horizontalCenter
+ bottom: braille_map.top
+ bottomMargin: 30 * ApplicationInfo.ratio
+ }
+ visible: !(dialogMap.visible || first_screen.visible)
+ }
+
+ DialogHelp {
+ id: dialogHelp
+ onClose: home()
+ }
+
+ BrailleMap {
+ id: dialogMap
+ // Make is non visible or we get some rendering artefacts before
+ // until it is created
+ visible: false
+ onClose: home()
+ }
+
+ Bar {
+ id: bar
+ content: BarEnumContent { value: first_screen.visible ? help | home : help | home | level }
+ onHelpClicked: {
+ displayDialog(dialogHelp)
+ }
+ onPreviousLevelClicked: Activity.previousLevel()
+ onNextLevelClicked: Activity.nextLevel()
+ onHomeClicked: activity.home()
+ }
+
+ BarButton {
+ id: braille_map
+ source: Activity.url + "target.svg"
+ anchors {
+ right: parent.right
+ bottom: parent.bottom
+ }
+ sourceSize.width: 66 * bar.barZoom
+ visible: true
+ onClicked: {
+ dialogMap.visible = true
+ displayDialog(dialogMap)
+ }
+ }
+
+ Bonus {
+ id: bonus
+ Component.onCompleted: win.connect(Activity.nextLevel)
+ }
+ }
+
}
+
diff --git a/src/activities/braille_alphabets/BrailleChar.qml b/src/activities/braille_alphabets/BrailleChar.qml
index 55d468a6d..dd88dc582 100644
--- a/src/activities/braille_alphabets/BrailleChar.qml
+++ b/src/activities/braille_alphabets/BrailleChar.qml
@@ -1,202 +1,202 @@
/* GCompris - BrailleChar.qml
*
* Copyright (C) 2014 Arkit Vora <arkitvora123@gmail.com>
*
* Authors:
* Srishti Sethi <srishakatux@gmail.com> (GTK+ version)
* Arkit Vora <arkitvora123@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "braille_alphabets.js" as Activity
import "../../core"
import GCompris 1.0
Item {
id: brailleCharItem
height: dotWidth * 3 + grid.spacing * 4
property string brailleChar: ""
property real dotWidth: width * 0.4
property real dotHeight: dotWidth
property alias circles: circles
property bool clickable
property bool isLetter: brailleChar >= 'A' && brailleChar <= 'Z'
property var brailleCodesLetter: {
// For ASCII each letter, this represent the active dots in Braille.
"A": [1], "B": [1, 2], "C": [1, 4], "D": [1, 4, 5], "E": [1, 5],
"F": [1, 2, 4], "G": [1, 2, 4, 5], "H": [1, 2, 5], "I": [2, 4],
"J": [2, 4, 5], "K": [1, 3], "L": [1, 2, 3], "M": [1, 3, 4],
"N": [1, 3, 4, 5], "O": [1, 3, 5], "P": [1, 2, 3, 4], "Q": [1, 2, 3, 4, 5],
"R": [1, 2, 3, 5], "S": [2, 3, 4], "T": [2, 3, 4, 5], "U": [1, 3, 6],
"V": [1, 2, 3, 6], "W": [2, 4, 5, 6], "X": [1, 3, 4, 6], "Y": [1, 3, 4, 5, 6],
"Z": [1, 3, 5, 6]
}
property var brailleCodesNumber: {
// For ASCII each letter, this represent the active dots in Braille.
"+": [3, 4, 6], "-": [3, 6], "*": [1, 6], "/": [3, 4],
"#": [3, 4, 5, 6], "1": [1], "2" :[1, 2], "3": [1, 4], "4": [1, 4, 5],
"5": [1, 5], "6": [1, 2, 4], "7": [1, 2, 4, 5], "8": [1, 2, 5],
"9": [2, 4], "0" :[3, 5, 6]
}
property var brailleCodes: isLetter ? brailleCodesLetter : brailleCodesNumber
function updateDotsFromBrailleChar() {
var dots = []
for(var car in brailleCodes) {
if(car === brailleChar) {
dots = brailleCodes[car]
}
}
// Clear all the dots
for(var i = 0; i < 6; i++) {
circles.itemAt(i).state = "off"
}
for(var i in dots) {
circles.itemAt(i).state = "on"
}
}
function updateBrailleCharFromDots() {
var dots = []
for( var i = 0; i < 6; i++) {
if(circles.itemAt(i).state === "on")
dots.push(i + 1)
}
var stringifiedDots = JSON.stringify(dots)
for(var car in brailleCodes) {
if(JSON.stringify(brailleCodes[car]) === stringifiedDots) {
brailleChar = car
return
}
}
brailleChar = ""
}
function clearLetter() {
brailleChar = ""
updateDotsFromBrailleChar()
}
function switchState(value) {
circles.itemAt(value-1).switchState()
}
Grid {
id: grid
anchors.centerIn: brailleCharItem
spacing: (brailleCharItem.width - brailleCharItem.dotWidth * 2) / 2
columns: 2
rows: 3
flow: Grid.TopToBottom
Repeater {
id: circles
model: 6
Rectangle {
id: incircle1
border.width: 2 * ApplicationInfo.ratio
color: on ? "#e4421c" : "#f0f0f0"
border.color: "#2a2a2a"
width: dotWidth
height: dotHeight
radius: width * 0.5
property bool on: clickable ? false : click_on_off()
function click_on_off() {
var code = brailleCodes[brailleChar]
if(!code)
return false
for(var i = 0; i < code.length; i++) {
if(code[i] === index + 1) {
return true
}
}
return false
}
function switchState() {
if (state == "on") {
state = "off"
} else {
state = "on"
}
activity.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/scroll.wav")
// On touch screens we don't get the exit event.
border.width = 2 * ApplicationInfo.ratio
brailleCharItem.updateBrailleCharFromDots()
}
Behavior on color {
ColorAnimation {
duration: 200
}
}
GCText {
id: numtext
text: clickable ? modelData+1 : ""
anchors.left: index >= 3 ? incircle1.right : undefined
anchors.right: index < 3 ? incircle1.left : undefined
anchors.verticalCenter: incircle1.verticalCenter
font.weight: Font.DemiBold
font.pointSize: NaN // need to clear font.pointSize explicitly
font.pixelSize: Math.min(30 * ApplicationInfo.ratio,
Math.max(parent.height, 20))
anchors.margins: 10
}
MouseArea {
id : mouse1
enabled: clickable ? true : false
anchors.fill: parent
hoverEnabled: true
onEntered: incircle1.border.width = 4 * ApplicationInfo.ratio
onExited: incircle1.border.width = 2 * ApplicationInfo.ratio
onClicked: {
incircle1.switchState();
}
}
states: [
State {
name: "on"
PropertyChanges {
target: incircle1
on: true
}
},
State {
name: "off"
PropertyChanges {
target: incircle1
on: false
}
}
]
}
}
}
}
diff --git a/src/activities/braille_alphabets/BrailleMap.qml b/src/activities/braille_alphabets/BrailleMap.qml
index 5f05f5e0e..895f32e63 100644
--- a/src/activities/braille_alphabets/BrailleMap.qml
+++ b/src/activities/braille_alphabets/BrailleMap.qml
@@ -1,186 +1,186 @@
/* GCompris - BrailleMap.qml
*
* Copyright (C) 2014 Arkit Vora <arkitvora123@gmail.com>
*
* Authors:
* Srishti Sethi <srishakatux@gmail.com> (GTK+ version)
* Arkit Vora <arkitvora123@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "braille_alphabets.js" as Activity
Rectangle {
id: brailleMap
color: "#808080"
border.color: "black"
border.width: 1
z: 1000
property bool isDialog: true
signal close
signal start
signal stop
Flickable {
id: flick
anchors.fill: parent
contentWidth: parent.width
contentHeight: (grid1.height + grid2.height) * 1.1
flickableDirection: Flickable.VerticalFlick
clip: true
Flow {
id: grid1
width: parent.width * 0.9
anchors {
top: parent.top
topMargin: 10 * ApplicationInfo.ratio
horizontalCenter: parent.horizontalCenter
}
spacing: 5 * ApplicationInfo.ratio
Repeater {
id: cardRepeater
model: [
"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"
]
Column {
- width: (grid1.width - grid1.spacing * 10) / 10
+ width: (grid1.width - grid1.spacing * 10) / 10
Rectangle {
id: rect1
width: parent.width
height: ins.height
border.width: 3
border.color: "black"
color: "white"
BrailleChar {
id: ins
width: parent.width * 0.9
anchors.centerIn: parent
clickable: false
brailleChar: modelData
}
}
GCText {
id: text1
text: modelData
font.weight: Font.DemiBold
style: Text.Outline
styleColor: "black"
color: "white"
fontSize: Math.max(Math.min(parent.width * 0.2, 24), 12)
anchors {
horizontalCenter: parent.horizontalCenter
}
}
}
}
}
Flow {
id: grid2
width : parent.width * 0.9
anchors {
horizontalCenter: parent.horizontalCenter
top: grid1.bottom
topMargin: 10 * ApplicationInfo.ratio
}
spacing: 6
Repeater {
id: cardRepeater2
model: [
"1", "2", "3", "4", "5", "6", "7", "8", "9", "0",
"+", "-", "*", "/", "#"
]
Column {
width: (grid1.width - grid1.spacing * 10) / 10
Rectangle {
id: rect2
width: parent.width
height: ins2.height
border.width: 3
border.color: "black"
color: "white"
BrailleChar {
id: ins2
width: parent.width * 0.9
anchors.centerIn: parent
clickable: false
brailleChar: modelData
}
}
GCText {
id: text2
text: modelData
font.weight: Font.DemiBold
style: Text.Outline
styleColor: "black"
color: "white"
fontSize: Math.max(Math.min(parent.width * 0.2, 24), 12)
anchors {
horizontalCenter: parent.horizontalCenter
}
}
}
}
}
// The back button
Image {
id: cancel
source: Activity.url + "back.svg"
fillMode: Image.PreserveAspectFit
anchors.right: parent.right
anchors.bottom: parent.bottom
smooth: true
sourceSize.width: 60 * ApplicationInfo.ratio
anchors.margins: 10
SequentialAnimation {
id: anim
running: true
loops: Animation.Infinite
NumberAnimation {
target: cancel
property: "rotation"
from: -10; to: 10
duration: 500
easing.type: Easing.InOutQuad
}
NumberAnimation {
target: cancel
property: "rotation"
from: 10; to: -10
duration: 500
easing.type: Easing.InOutQuad
}
}
MouseArea {
anchors.fill: parent
onClicked: close()
}
}
}
}
diff --git a/src/activities/braille_alphabets/FirstScreen.qml b/src/activities/braille_alphabets/FirstScreen.qml
index db565d60f..b0caf5875 100644
--- a/src/activities/braille_alphabets/FirstScreen.qml
+++ b/src/activities/braille_alphabets/FirstScreen.qml
@@ -1,142 +1,142 @@
/* GCompris - FirstScreen.qml
*
* Copyright (C) 2014 Arkit Vora <arkitvora123@gmail.com>
*
* Authors:
* Srishti Sethi <srishakatux@gmail.com> (GTK+ version)
* Arkit Vora <arkitvora123@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "braille_alphabets.js" as Activity
Image {
id: first_screen
anchors.fill: parent
fillMode: Image.PreserveAspectCrop
source: Activity.url + "intro_bg.svg"
sourceSize.width: Math.max(parent.width, parent.height)
GCText {
id: heading
text: qsTr("Braille: Unlocking the Code")
fontSize: largeSize
fontSizeMode: Text.Fit
horizontalAlignment: Text.AlignHCenter
font.weight: Font.DemiBold
anchors.centerIn: parent.Center
color: "#2a2a2a"
width: parent.width
height: parent.height * 0.16
wrapMode: Text.WordWrap
}
Image {
id: introChar
source: Activity.url + "intro_braille_char.svg"
sourceSize.height: parent.height * 0.25
fillMode: Image.PreserveAspectFit
anchors {
top: heading.bottom
topMargin: 30 * ApplicationInfo.ratio
left: parent.left
leftMargin: 30 * ApplicationInfo.ratio
}
}
GCText {
id: body_text1
z: 1
text: qsTr('The Braille system is a method that is used by blind people to read and write.') + '\n \n ' +
qsTr('Each Braille character, or cell, is made up of six dot positions, arranged in ' +
'a rectangle containing two columns of three dots each. As seen on the left, each ' +
'dot is referenced by a number from 1 to 6.')
fontSize: regularSize
fontSizeMode: Text.Fit
font.weight: Font.DemiBold
horizontalAlignment: Text.AlignJustify
anchors {
top: heading.bottom
topMargin: 15 * ApplicationInfo.ratio
right: parent.right
rightMargin: 15 * ApplicationInfo.ratio
left: introChar.right
leftMargin: 15 * ApplicationInfo.ratio
}
color: "#2a2a2a"
width: parent.width * 0.5
height: parent.height * 0.33
wrapMode: Text.WordWrap
}
GCText {
id: bottom_text
z: 2
text: qsTr("When you are ready, click on me and try reproducing Braille characters.")
fontSize: regularSize
fontSizeMode: Text.Fit
font.weight: Font.Bold
horizontalAlignment: Text.AlignRight
color: "#2a2a2a"
wrapMode: Text.WordWrap
anchors {
top: body_text1.bottom
topMargin: 15 * ApplicationInfo.ratio
left: parent.left
leftMargin: 30 * ApplicationInfo.ratio
}
height: parent.height * 0.25
width: parent.width * 0.5
}
Image {
id: introTux
- z:3
+ z: 3
source: Activity.url + "tux_braille.svg"
fillMode: Image.PreserveAspectFit
sourceSize.width: parent.width * 0.2
anchors {
top: body_text1.bottom
topMargin: 5 * ApplicationInfo.ratio
left: bottom_text.right
leftMargin: 30 * ApplicationInfo.ratio
}
Behavior on scale { PropertyAnimation { duration: 100 } }
MouseArea {
id: tux_click
anchors.fill: parent
hoverEnabled: true
onClicked: first_screen.visible = false
onEntered: introTux.scale = 1.1
onExited: introTux.scale = 1
}
}
Rectangle {
id: bgTux
- z:0
+ z: 0
color: "#94c1d2"
width: introTux.width * 1.5
height: introTux.height * 1.1
radius: bgTux.width * 0.5
anchors {
horizontalCenter: introTux.horizontalCenter
verticalCenter: introTux.verticalCenter
}
}
}
diff --git a/src/activities/braille_alphabets/Screen.qml b/src/activities/braille_alphabets/Screen.qml
deleted file mode 100644
index 49e5c193e..000000000
--- a/src/activities/braille_alphabets/Screen.qml
+++ /dev/null
@@ -1,318 +0,0 @@
-/* GCompris - Screen.qml
- *
- * Copyright (C) 2014 Arkit Vora <arkitvora123@gmail.com>
- *
- * Authors:
- * Srishti Sethi <srishakatux@gmail.com> (GTK+ version)
- * Arkit Vora <arkitvora123@gmail.com> (Qt Quick port)
- *
- * This program is free software; you can 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 <http://www.gnu.org/licenses/>.
- */
-import QtQuick 2.6
-import GCompris 1.0
-import "../../core"
-import "braille_alphabets.js" as Activity
-
-ActivityBase {
- id: activity
-
- onStart: focus = true
- onStop: {}
-
- property var dataset
-
- pageComponent: Image {
- id: background
- anchors.fill: parent
- fillMode: Image.PreserveAspectCrop
- source: Activity.url + "background.svg"
- sourceSize.width: Math.max(parent.width, parent.height)
- signal start
- signal stop
- Component.onCompleted: {
- activity.start.connect(start)
- activity.stop.connect(stop)
- }
-
- Keys.onPressed: {
- if(first_screen.visible) {
- // If return, we hide the screen
- first_screen.visible = false
- return;
- }
- var keyValue;
- switch(event.key)
- {
- case Qt.Key_1:
- keyValue = 1;
- break;
- case Qt.Key_2:
- keyValue = 2;
- break;
- case Qt.Key_3:
- keyValue = 3;
- break;
- case Qt.Key_4:
- keyValue = 4;
- break;
- case Qt.Key_5:
- keyValue = 5;
- break;
- case Qt.Key_6:
- keyValue = 6;
- break;
- }
- if(keyValue)
- playableChar.switchState(keyValue)
- }
-
- // Add here the QML items you need to access in javascript
- QtObject {
- id: items
- property Item main: activity.main
- property alias background: background
- property alias bar: bar
- property alias bonus: bonus
- property alias containerModel: containerModel
- property alias questionItem: questionItem
- property string instructions
- property alias playableChar: playableChar
- property alias score: score
- property bool brailleCodeSeen
- }
-
- onStart: {
- first_screen.visible = true
- Activity.start(items, dataset)
- }
- onStop: { Activity.stop() }
-
-
- ListModel {
- id: containerModel
- }
-
- Image {
- id: charList
- y: 20 * ApplicationInfo.ratio
- anchors.horizontalCenter: parent.horizontalCenter
- source: Activity.url + "top_back.svg"
- sourceSize.width: parent.width * 0.94
- visible: items.brailleCodeSeen
-
- Row {
- id: row
- spacing: 10 * ApplicationInfo.ratio
- anchors.centerIn: charList
- anchors.horizontalCenterOffset: 5
-
- Repeater {
- id: cardRepeater
- model: containerModel
-
- Item {
- id: inner
- height: charList.height * 0.9
- width: (charList.width - containerModel.count * row.spacing)/ containerModel.count
-
- Rectangle {
- id: rect1
- width: charList.width / 13
- height: ins.height
- border.width: 0
- border.color: "black"
- color: "#a5cbd9"
-
- BrailleChar {
- id: ins
- width: parent.width * 0.9
- anchors.centerIn: parent
- clickable: false
- brailleChar: letter
- }
- }
-
- GCText {
- text: letter
- font.weight: Font.DemiBold
- color: "#2a2a2a"
- font.pointSize: NaN // need to clear font.pointSize explicitly
- font.pixelSize: rect1.width * 0.5
- anchors {
- top: rect1.bottom
- topMargin: 4 * ApplicationInfo.ratio
- horizontalCenter: rect1.horizontalCenter
- }
- }
- }
-
- }
- }
- }
-
- Image {
- id: playableCharBg
- anchors {
- top: charList.bottom
- topMargin: 10 * ApplicationInfo.ratio
- }
- verticalAlignment: Image.AlignTop
- x: 10 * ApplicationInfo.ratio
- source: Activity.url + "char_background.svg"
- sourceSize.width: playableChar.width * 1.8
- height: (playableChar.height + playableCharDisplay.height) * 1.2
-
- BrailleChar {
- id: playableChar
- clickable: true
- anchors {
- horizontalCenter: parent.horizontalCenter
- top: parent.top
- topMargin: 20 * ApplicationInfo.ratio
- }
- width: Math.min(background.width * 0.18, background.height * 0.2)
- isLetter: true
- onBrailleCharChanged: {
- if(brailleChar === Activity.getCurrentLetter()) {
- particles.burst(40)
- Activity.nextQuestion()
- }
- }
- }
-
- GCText {
- id: playableCharDisplay
- font.pointSize: NaN // need to clear font.pointSize explicitly
- font.pixelSize: Math.max(playableChar.width * 0.4, 24)
- font.weight: Font.DemiBold
- color: "#2a2a2a"
- text: playableChar.brailleChar
- anchors {
- top: playableChar.bottom
- topMargin: 4 * ApplicationInfo.ratio
- horizontalCenter: playableChar.horizontalCenter
- }
- }
- }
-
- Rectangle {
- id: instructionsArea
- height: parent.height * 0.3
- width: parent.width / 1.1
- anchors {
- top: charList.bottom
- topMargin: 10 * ApplicationInfo.ratio
- left: playableCharBg.right
- leftMargin: 10 * ApplicationInfo.ratio
- right: parent.right
- rightMargin: 10 * ApplicationInfo.ratio
- }
- color: "#55333333"
- border.width: 0
- radius: 5
-
- GCText {
- id: questionItem
- anchors.centerIn: parent
- fontSize: largeSize
- fontSizeMode: Text.Fit
- horizontalAlignment: Text.AlignHCenter
- font.weight: Font.DemiBold
- style: Text.Outline
- styleColor: "black"
- color: "white"
- width: parent.width * 0.94
- height: parent.height * 0.94
- wrapMode: Text.WordWrap
-
- function initQuestion() {
- playableChar.clearLetter()
- text = Activity.getCurrentTextQuestion()
- if(items.instructions)
- text += "\n" + items.instructions
- opacity = 1.0
- }
-
- onOpacityChanged: opacity == 0 ? initQuestion() : ""
- Behavior on opacity { PropertyAnimation { duration: 500 } }
- }
- }
-
- ParticleSystemStarLoader {
- id: particles
- clip: false
- }
-
- FirstScreen {
- id: first_screen
- }
-
- Score {
- id: score
- anchors {
- top: instructionsArea.bottom
- left: instructionsArea.horizontalCenter
- bottom: braille_map.top
- bottomMargin: 30 * ApplicationInfo.ratio
- }
- visible: !(dialogMap.visible || first_screen.visible)
- }
-
- DialogHelp {
- id: dialogHelp
- onClose: home()
- }
-
- BrailleMap {
- id: dialogMap
- // Make is non visible or we get some rendering artefacts before
- // until it is created
- visible: false
- onClose: home()
- }
-
- Bar {
- id: bar
- content: BarEnumContent { value: first_screen.visible ? help | home : help | home | level }
- onHelpClicked: {
- displayDialog(dialogHelp)
- }
- onPreviousLevelClicked: Activity.previousLevel()
- onNextLevelClicked: Activity.nextLevel()
- onHomeClicked: activity.home()
- }
-
- BarButton {
- id: braille_map
- source: Activity.url + "target.svg"
- anchors {
- right: parent.right
- bottom: parent.bottom
- }
- sourceSize.width: 66 * bar.barZoom
- visible: true
- onClicked: {
- dialogMap.visible = true
- displayDialog(dialogMap)
- }
- }
-
- Bonus {
- id: bonus
- Component.onCompleted: win.connect(Activity.nextLevel)
- }
- }
-
-}
-
diff --git a/src/activities/braille_alphabets/braille_alphabets.js b/src/activities/braille_alphabets/braille_alphabets.js
index 42442443f..e1e1153c6 100644
--- a/src/activities/braille_alphabets/braille_alphabets.js
+++ b/src/activities/braille_alphabets/braille_alphabets.js
@@ -1,155 +1,155 @@
/* GCompris - braille_alphabets.js
*
* Copyright (C) 2014 Arkit Vora <arkitvora123@gmail.com>
*
* Authors:
* Srishti Sethi <srishakatux@gmail.com> (GTK+ version)
* Arkit Vora <arkitvora123@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
.import "qrc:/gcompris/src/core/core.js" as Core
var url = "qrc:/gcompris/src/activities/braille_alphabets/resource/"
var currentLevel
var numberOfLevel
var items
var dataset
var currentQuestion
var currentDataSet
function start(items_, dataset_) {
items = items_
dataset = dataset_.get()
currentLevel = 0
numberOfLevel = dataset.length * 2
initLevel()
}
function stop() {
}
function initLevel() {
items.bar.level = currentLevel + 1
items.containerModel.clear()
currentQuestion = 0
switch(currentLevel) {
case 0:
items.instructions = ""
items.brailleCodeSeen = true
currentDataSet = dataset[0]
break
case 1:
items.instructions = qsTr("Now it's a little bit harder without the braille map.")
items.brailleCodeSeen = false
currentDataSet = dataset[0]
break
case 2:
items.instructions = qsTr("Look at the Braille character map and observe how similar the first and second line are.")
items.brailleCodeSeen = true
currentDataSet = dataset[1]
break
case 3:
items.instructions = qsTr("Now it's a little bit harder without the braille map.")
items.brailleCodeSeen = false
currentDataSet = dataset[1]
break
case 4:
items.instructions = qsTr("Again, similar as the first line but take care, the 'W' letter was added afterwards.")
items.brailleCodeSeen = true
currentDataSet = dataset[2]
break
case 5:
items.instructions = qsTr("Now it's a little bit harder without the braille map.")
items.brailleCodeSeen = false
currentDataSet = dataset[2]
break
case 6:
items.instructions = qsTr("This is easy, numbers are the same as letters from A to J.")
items.brailleCodeSeen = true
currentDataSet = dataset[3]
break
case 7:
items.instructions = qsTr("Now it's a little bit harder without the braille map.")
items.brailleCodeSeen = false
currentDataSet = dataset[3]
break
case 8:
items.instructions = ""
items.brailleCodeSeen = true
currentDataSet = dataset[4]
break
case 9:
items.instructions = qsTr("Now it's a little bit harder without the braille map.")
items.brailleCodeSeen = false
currentDataSet = dataset[4]
break
}
for(var i = 0; i < currentDataSet.length; ++i) {
items.containerModel.append(currentDataSet[i])
}
// Shuffle not to ask the question in the model order
currentDataSet = Core.shuffle(currentDataSet)
items.score.numberOfSubLevels = currentDataSet.length;
items.score.currentSubLevel = 0;
items.playableChar.isLetter = currentDataSet[0].letter >= "A" && currentDataSet[0].letter <= "Z"
// Trig the next question
items.questionItem.opacity = 0.1
items.questionItem.opacity = 0
}
function nextLevel() {
if(numberOfLevel <= ++currentLevel) {
currentLevel = 0
}
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
initLevel();
}
function nextQuestion() {
if(currentDataSet.length <= ++currentQuestion) {
items.bonus.good("flower")
} else {
// Let's not change the question immediately to let the
// children see his answer.
// We just set the opacity to 0, the questionItem will then grab
// the new question by itself
items.questionItem.opacity = 0.1
items.questionItem.opacity = 0
items.score.currentSubLevel ++
}
}
function getCurrentTextQuestion() {
return currentDataSet[currentQuestion].text.arg(getCurrentLetter())
}
function getCurrentLetter() {
return currentDataSet[currentQuestion].letter
}
diff --git a/src/activities/braille_alphabets/questions.js b/src/activities/braille_alphabets/questions.js
index 018ca3030..22e823c87 100644
--- a/src/activities/braille_alphabets/questions.js
+++ b/src/activities/braille_alphabets/questions.js
@@ -1,197 +1,197 @@
/* GCompris - questions.js
*
* Copyright (C) 2014 Arkit Vora <arkitvora123@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
function get() {
return [
[ // Level 1
{
"text": qsTr("Click on the dots in braille cell area to produce the letter %1."),
"letter": "A"
},
{
"text": qsTr("Click on the dots in braille cell area to produce the letter %1."),
"letter": "B"
},
{
"text": qsTr("Click on the dots in braille cell area to produce the letter %1."),
"letter": "C"
},
{
"text": qsTr("Click on the dots in braille cell area to produce the letter %1."),
"letter": "D"
},
{
"text": qsTr("Click on the dots in braille cell area to produce the letter %1."),
"letter": "E"
},
{
"text": qsTr("Click on the dots in braille cell area to produce the letter %1."),
"letter": "F"
},
{
"text": qsTr("Click on the dots in braille cell area to produce the letter %1."),
"letter": "G"
},
{
"text": qsTr("Click on the dots in braille cell area to produce the letter %1."),
"letter": "H"
},
{
"text": qsTr("Click on the dots in braille cell area to produce the letter %1."),
"letter": "I"
},
{
"text": qsTr("Click on the dots in braille cell area to produce the letter %1."),
"letter": "J"
}
],
[ // Level 2
{
"text": qsTr("Click on the dots in braille cell area to produce the letter %1."),
"letter": "K"
},
{
"text": qsTr("Click on the dots in braille cell area to produce the letter %1."),
"letter": "L"
},
{
"text": qsTr("Click on the dots in braille cell area to produce the letter %1."),
"letter": "M"
},
{
"text": qsTr("Click on the dots in braille cell area to produce the letter %1."),
"letter": "N"
},
{
"text": qsTr("Click on the dots in braille cell area to produce the letter %1."),
"letter": "O"
},
{
"text": qsTr("Click on the dots in braille cell area to produce the letter %1."),
"letter": "P"
},
{
"text": qsTr("Click on the dots in braille cell area to produce the letter %1."),
"letter": "Q"
},
{
"text": qsTr("Click on the dots in braille cell area to produce the letter %1."),
"letter": "R"
},
{
"text": qsTr("Click on the dots in braille cell area to produce the letter %1."),
"letter": "S"
},
{
"text": qsTr("Click on the dots in braille cell area to produce the letter %1."),
"letter": "T"
}
],
[ // Level 3
{
"text": qsTr("Click on the dots in braille cell area to produce the letter %1."),
"letter": "U"
},
{
"text": qsTr("Click on the dots in braille cell area to produce the letter %1."),
"letter": "V"
},
{
"text": qsTr("Click on the dots in braille cell area to produce the letter %1."),
"letter": "X"
},
{
"text": qsTr("Click on the dots in braille cell area to produce the letter %1."),
"letter": "Y"
},
{
"text": qsTr("Click on the dots in braille cell area to produce the letter %1."),
"letter": "Z"
},
{
"text": qsTr("Click on the dots in braille cell area to produce the letter %1."),
"letter": "W"
}
],
[ // Level 4
{
"text": qsTr("Click on the dots in braille cell area to produce the number %1."),
"letter": "1"
},
{
"text": qsTr("Click on the dots in braille cell area to produce the number %1."),
"letter": "2"
},
{
"text": qsTr("Click on the dots in braille cell area to produce the number %1."),
"letter": "3"
},
{
"text": qsTr("Click on the dots in braille cell area to produce the number %1."),
"letter": "4",
"braille_letter":[{"pos":1},{"pos":4},{"pos":5}]
},
{
"text": qsTr("Click on the dots in braille cell area to produce the number %1."),
"letter": "5"
},
{
"text": qsTr("Click on the dots in braille cell area to produce the number %1."),
"letter": "6"
},
{
"text": qsTr("Click on the dots in braille cell area to produce the number %1."),
"letter": "7"
},
{
"text": qsTr("Click on the dots in braille cell area to produce the number %1."),
"letter": "8"
},
{
"text": qsTr("Click on the dots in braille cell area to produce the number %1."),
"letter": "9"
},
{
"text": qsTr("Click on the dots in braille cell area to produce the number %1."),
"letter": "0"
}
],
[ // Level 5
{
"text": qsTr("Click on the dots in braille cell area to produce the symbol %1."),
"letter": "+"
},
{
"text": qsTr("Click on the dots in braille cell area to produce the symbol %1."),
"letter": "-"
},
{
"text": qsTr("Click on the dots in braille cell area to produce the symbol %1."),
"letter": "*"
},
{
"text": qsTr("Click on the dots in braille cell area to produce the symbol %1."),
"letter": "/"
},
{
"text": qsTr("Click on the dots in braille cell area to produce the symbol %1."),
"letter": "#"
}
]
];
}
diff --git a/src/activities/braille_fun/ActivityInfo.qml b/src/activities/braille_fun/ActivityInfo.qml
index 7aa066789..3d31b7ce3 100644
--- a/src/activities/braille_fun/ActivityInfo.qml
+++ b/src/activities/braille_fun/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Arkit Vora <arkitvora123@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "braille_fun/BrailleFun.qml"
difficulty: 6
icon: "braille_fun/braille_fun.svg"
author: "Arkit Vora &lt;arkitvora123@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Braille Fun")
//: Help title
description: qsTr("Braille the letters")
//intro: "Create the Braille cell for the letter."
//: Help goal
goal: ""
//: Help prerequisite
prerequisite: qsTr("Braille Alphabet Codes")
//: Help manual
manual: qsTr("Enter the braille code in the tile for the letters on the banner pulled by Tux in his plane across the screen. Check the braille chart by clicking on the toggle button for help.")
credit: ""
section: "discovery braille"
createdInVersion: 4000
}
diff --git a/src/activities/braille_fun/BrailleFun.qml b/src/activities/braille_fun/BrailleFun.qml
index 0fb9aa064..596e7b87f 100644
--- a/src/activities/braille_fun/BrailleFun.qml
+++ b/src/activities/braille_fun/BrailleFun.qml
@@ -1,255 +1,255 @@
/* GCompris - braille_fun.qml
*
* Copyright (C) 2014 Arkit Vora <arkitvora123@gmail.com>
*
* Authors:
* Srishti Sethi (GTK+ version)
* Arkit Vora <arkitvora123@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "../braille_alphabets"
import "braille_fun.js" as Activity
ActivityBase {
id: activity
onStart: focus = true
onStop: {}
pageComponent: Image {
id: background
anchors.fill: parent
fillMode: Image.PreserveAspectCrop
sourceSize.width: Math.max(parent.width, parent.height)
source: Activity.url + "hillside.svg"
signal start
signal stop
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property alias background: background
property alias bar: bar
property alias bonus: bonus
property alias questionItem: questionItem
property alias score: score
property alias cardRepeater: cardRepeater
property alias animateX: animateX
property alias charBg: charBg
property string question
}
onStart: { Activity.start(items) }
onStop: { Activity.stop() }
Item {
id: planeText
width: plane.width
height: plane.height
x: - width
anchors.top: parent.top
anchors.topMargin: 20 * ApplicationInfo.ratio
Image {
id: plane
anchors.centerIn: planeText
anchors.top: parent.top
source: Activity.url + "plane.svg"
sourceSize.height: 90 * ApplicationInfo.ratio
}
GCText {
id: questionItem
anchors.right: planeText.right
anchors.rightMargin: plane.width / 2
anchors.verticalCenter: planeText.verticalCenter
fontSize: hugeSize
font.weight: Font.DemiBold
color: "#2a2a2a"
text: items.question
}
PropertyAnimation {
id: animateX
target: planeText
properties: "x"
from: - planeText.width
to: background.width
duration: 11000
easing.type: Easing.OutInCirc
loops: Animation.Infinite
}
}
Rectangle {
id: charBg
anchors {
horizontalCenter: parent.horizontalCenter
verticalCenter: parent.verticalCenter
rightMargin: 20 * ApplicationInfo.ratio
}
width: charWidth * cardRepeater.model
height: charWidth * 1.5
color: "#AAFFFFFF"
border.width: 0
radius: 5
property int charWidth: Math.min(150 * ApplicationInfo.ratio,
parent.width * 0.3)
function clickable(status) {
for(var i=0 ; i < cardRepeater.model ; i++) {
cardRepeater.itemAt(i).ins.clickable = status
}
}
function clearAllLetters() {
for(var i=0 ; i < cardRepeater.model ; i++) {
cardRepeater.itemAt(i).ins.clearLetter()
}
}
Row {
id: row
spacing: 5 * ApplicationInfo.ratio
anchors.centerIn: parent
Repeater {
id: cardRepeater
Item {
id: inner
height: charBg.height * 0.9
width: charBg.charWidth
property string brailleChar: ins.brailleChar
property alias ins: ins
Rectangle {
id: rect1
width: charBg.charWidth * 0.6
height: ins.height
anchors.horizontalCenter: inner.horizontalCenter
border.width: 0
color: ins.found ? '#FFa3f9a3' : "#ffef6949"
BrailleChar {
id: ins
clickable: true
anchors.centerIn: rect1
width: parent.width * 0.9
isLetter: true
onBrailleCharChanged: {
inner.brailleChar = ins.brailleChar
var answerString = "" ;
for(var i = 0 ; i < Activity.currentLevel + 1 ; i++ ) {
answerString = answerString + cardRepeater.itemAt(i).brailleChar;
}
if(answerString === items.question) {
charBg.clickable(false)
bonus.good("tux")
score.currentSubLevel ++;
}
}
property string question: items.question[modelData] ? items.question[modelData] : ""
property bool found: question === brailleChar
}
}
GCText {
text: brailleChar
font.weight: Font.DemiBold
color: "#2a2a2a"
fontSize: hugeSize
anchors {
top: rect1.bottom
topMargin: 4 * ApplicationInfo.ratio
horizontalCenter: rect1.horizontalCenter
}
}
}
}
}
}
Score {
id: score
// @FIXME We have no way to get the real bar width, that would make this
// calculation formal
anchors.bottom: parent.width - bar.width * 6 > width ? parent.bottom : bar.top
anchors.bottomMargin: 10 * ApplicationInfo.ratio
anchors.rightMargin: 10 * ApplicationInfo.ratio
anchors.right: parent.right
}
DialogHelp {
id: dialogHelp
onClose: home()
}
BrailleMap {
id: dialogMap
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level }
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
}
BarButton {
id: brailleMap
source: Activity.url + "target.svg"
anchors {
right: score.left
bottom: score.bottom
}
sourceSize.width: 66 * bar.barZoom
visible: true
onClicked: {
dialogMap.visible = true
displayDialog(dialogMap)
}
}
Bonus {
id: bonus
Component.onCompleted: {
win.connect(Activity.nextQuestion)
loose.connect(Activity.initQuestion)
}
}
}
}
diff --git a/src/activities/braille_fun/braille_fun.js b/src/activities/braille_fun/braille_fun.js
index 63589f016..6825dab55 100644
--- a/src/activities/braille_fun/braille_fun.js
+++ b/src/activities/braille_fun/braille_fun.js
@@ -1,105 +1,105 @@
/* GCompris - braille_fun.js
*
* Copyright (C) 2014 Arkit Vora <arkitvora123@gmail.com>
*
* Authors:
* Srishti Sethi (GTK+ version)
* Arkit Vora <arkitvora123@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
.import "qrc:/gcompris/src/core/core.js" as Core
var currentLevel = 0
var numberOfLevel = 3
var items
var currentQuestion
var maxSubLevel;
var set = ["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"];
var questionArray = [];
var url = "qrc:/gcompris/src/activities/braille_fun/resource/"
function start(items_ ) {
items = items_
currentLevel = 0
initLevel()
}
function stop() {
items.animateX.stop()
}
function initQuestion() {
items.question = questionArray[currentQuestion]
items.charBg.clickable(true)
items.charBg.clearAllLetters()
items.animateX.restart()
}
function nextQuestion() {
if(++currentQuestion == set.length) {
nextLevel()
} else {
initQuestion()
}
}
function initLevel() {
items.bar.level = currentLevel + 1
currentQuestion = 0
items.score.numberOfSubLevels = set.length;
items.score.currentSubLevel = 0;
questionArray = []
switch(currentLevel) {
case 0:
for(var i = 0; i < set.length; i++) {
questionArray[i] = set[i];
}
break
case 1:
for(var i = 0; i < set.length; i++) {
questionArray[i] = set[i] +
set[Math.floor(Math.random() * set.length)];
}
break
case 2:
for(var i = 0; i < set.length; i++) {
questionArray[i] = set[i] +
set[Math.floor(Math.random() * set.length)] +
set[Math.floor(Math.random() * set.length)];
}
break
}
initQuestion()
items.cardRepeater.model = currentLevel + 1;
}
function nextLevel() {
if(numberOfLevel <= ++currentLevel ) {
currentLevel = 0
}
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
initLevel();
}
diff --git a/src/activities/calendar/ActivityInfo.qml b/src/activities/calendar/ActivityInfo.qml
index 8c2b81538..799a059e0 100644
--- a/src/activities/calendar/ActivityInfo.qml
+++ b/src/activities/calendar/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2017 Amit Sagtani <asagtani06@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "calendar/Calendar.qml"
difficulty: 4
icon: "calendar/calendar.svg"
author: "Amit Sagtani &lt;asagtani06@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Calendar")
//: Help title
description: qsTr("Read the instructions and select the correct date on the calendar")
//intro: "Select the asked date on the calendar"
//: Help goal
goal: qsTr("Learn how to use a calendar")
//: Help prerequisite
prerequisite: qsTr("Concept of week, month and year")
//: Help manual
manual: qsTr("Read the instructions and select the correct date on the calendar.")
credit: ""
section: "discovery"
createdInVersion: 9000
}
diff --git a/src/activities/calendar/Calendar.qml b/src/activities/calendar/Calendar.qml
index 993d80b65..627bac502 100644
--- a/src/activities/calendar/Calendar.qml
+++ b/src/activities/calendar/Calendar.qml
@@ -1,434 +1,434 @@
/* GCompris - Calendar.qml
*
* Copyright (C) 2017 Amit Sagtani <asagtani06@gmail.com>
*
* Authors:
* Amit Sagtani <asagtani06@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import QtQuick.Controls 1.5
import QtQuick.Controls.Private 1.0
import QtQuick.Controls.Styles 1.4
import "../../core"
import "calendar.js" as Activity
import "calendar_dataset.js" as Dataset
ActivityBase {
id: activity
property var dataset: Dataset
onStart: focus = true
onStop: {}
pageComponent: Image {
id: background
signal start
signal stop
fillMode: Image.PreserveAspectCrop
source: "qrc:/gcompris/src/activities/fifteen/resource/background.svg"
sourceSize.width: Math.max(parent.width, parent.height)
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property alias background: background
property alias bar: bar
property alias bonus: bonus
property alias calendar: calendar
property alias okButton: okButton
property alias questionItem: questionItem
property alias score: score
property alias answerChoices: answerChoices
property alias questionDelay: questionDelay
property alias okButtonParticles: okButtonParticles
- property bool horizontalLayout: background.width > background.height * 1.5
+ property bool horizontalLayout: background.width >= background.height * 1.5
property alias daysOfTheWeekModel: daysOfTheWeekModel
}
onStart: { Activity.start(items, dataset) }
onStop: { Activity.stop() }
Keys.onPressed: (answerChoices.visible) ? answerChoices.handleKeys(event) : handleKeys(event);
// Question time delay
Timer {
id: questionDelay
repeat: false
interval: 1600
onTriggered: {
Activity.initQuestion()
}
onRunningChanged: okButtonMouseArea.enabled = !okButtonMouseArea.enabled
}
Rectangle {
id: calendarBox
width: items.horizontalLayout ? (answerChoices.visible ? parent.width * 0.75 : parent.width * 0.80) :
(answerChoices.visible ? parent.width * 0.65 : parent.width * 0.85)
height: items.horizontalLayout ? parent.height * 0.68 : parent.height - bar.height - questionItemBackground.height - okButton.height * 1.5
anchors.top: questionItem.bottom
anchors.topMargin: 5
anchors.rightMargin: answerChoices.visible ? 100 : undefined
anchors.horizontalCenterOffset: answerChoices.visible ? 80 : 0
anchors.horizontalCenter: parent.horizontalCenter
color: "black"
opacity: 0.3
}
Calendar {
id: calendar
weekNumbersVisible: false
width: calendarBox.width * 0.96
height: calendarBox.height * 0.96
anchors.centerIn: calendarBox
frameVisible: true
focus: !answerChoices.visible
__locale: Qt.locale(ApplicationInfo.localeShort)
style: CalendarStyle {
navigationBar: Rectangle {
height: calendar.height * 0.12
color: "#f2f2f2"
BarButton {
id: previousMonth
height: parent.height * 0.8
width: previousMonth.height
sourceSize.height: previousMonth.height
sourceSize.width: previousMonth.width
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.leftMargin: parent.height * 0.1
source: "qrc:/gcompris/src/core/resource/scroll_down.svg"
rotation: 90
visible: ((calendar.visibleYear + calendar.visibleMonth) > Activity.minRange) ? true : false
onClicked: calendar.showPreviousMonth()
}
GCText {
id: dateText
text: styleData.title
color: "#373737"
horizontalAlignment: Text.AlignHCenter
fontSizeMode: Text.Fit
anchors.verticalCenter: parent.verticalCenter
anchors.left: previousMonth.right
anchors.leftMargin: 2
anchors.right: nextMonth.left
anchors.rightMargin: 2
}
BarButton {
id: nextMonth
height: previousMonth.height
width: nextMonth.height
sourceSize.height: nextMonth.height
sourceSize.width: nextMonth.width
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: previousMonth.anchors.leftMargin
source: "qrc:/gcompris/src/core/resource/scroll_down.svg"
rotation: 270
visible: ((calendar.visibleYear + calendar.visibleMonth) < Activity.maxRange) ? true : false
onClicked: calendar.showNextMonth()
}
}
dayDelegate: Rectangle {
anchors.fill: parent
anchors.leftMargin: (!addExtraMargin || control.weekNumbersVisible) && styleData.index % CalendarUtils.daysInAWeek === 0 ? 0 : -1
anchors.rightMargin: !addExtraMargin && styleData.index % CalendarUtils.daysInAWeek === CalendarUtils.daysInAWeek - 1 ? 0 : -1
anchors.bottomMargin: !addExtraMargin && styleData.index >= CalendarUtils.daysInAWeek * (CalendarUtils.weeksOnACalendarMonth - 1) ? 0 : -1
anchors.topMargin: styleData.selected ? -1 : 0
color: styleData.date !== undefined && styleData.selected ? selectedDateColor : "#F2F2F2"
border.color: "#cec4c4"
radius: 5
property bool addExtraMargin: control.frameVisible && styleData.selected
readonly property color sameMonthDateTextColor: "#373737"
readonly property color selectedDateColor: "#3778d0"
readonly property color selectedDateTextColor: "white"
readonly property color differentMonthDateTextColor: "#bbb"
readonly property color invalidDateColor: "#dddddd"
Label {
id: dayDelegateText
text: styleData.date.getDate()
anchors.centerIn: parent
horizontalAlignment: Text.AlignRight
font.family: GCSingletonFontLoader.fontLoader.name
font.pixelSize: Math.min(parent.height/3, parent.width/3)
color: {
var theColor = invalidDateColor;
if (styleData.valid) {
// Date is within the valid range.
theColor = styleData.visibleMonth ? sameMonthDateTextColor : differentMonthDateTextColor;
if (styleData.selected)
theColor = selectedDateTextColor;
}
theColor;
}
}
}
dayOfWeekDelegate: Rectangle {
color: "lightgray"
implicitHeight: Math.round(TextSingleton.implicitHeight * 2.25)
Label {
text: control.__locale.dayName(styleData.dayOfWeek, control.dayOfWeekFormat)
font.family: GCSingletonFontLoader.fontLoader.name
fontSizeMode: Text.Fit
minimumPixelSize: 1
font.pixelSize: items.horizontalLayout ? parent.height * 0.7 : parent.width * 0.2
color: "#373737"
anchors.centerIn: parent
}
}
}
onVisibleMonthChanged: {
Activity.monthSelected = visibleMonth
Activity.daySelected = selectedDate.getDate()
}
onVisibleYearChanged: {
Activity.yearSelected = visibleYear
Activity.daySelected = selectedDate.getDate()
}
onClicked: {
Activity.daySelected = selectedDate.getDate()
}
onSelectedDateChanged: {
Activity.daySelected = selectedDate.getDate()
}
}
function handleKeys(event) {
if(event.key === Qt.Key_Space && okButtonMouseArea.enabled) {
Activity.checkAnswer()
event.accepted = true
}
if(event.key === Qt.Key_Enter && okButtonMouseArea.enabled) {
Activity.checkAnswer()
event.accepted = true
}
if(event.key === Qt.Key_Return && okButtonMouseArea.enabled) {
Activity.checkAnswer()
event.accepted = true
}
if(event.key === Qt.Key_Home) {
calendar.__selectFirstDayOfMonth();
event.accepted = true;
}
if(event.key === Qt.Key_End) {
calendar.__selectLastDayOfMonth();
event.accepted = true;
}
if(event.key === Qt.Key_PageUp) {
calendar.__selectPreviousMonth();
event.accepted = true;
}
if(event.key === Qt.Key_PageDown) {
calendar.__selectNextMonth();
event.accepted = true;
}
if(event.key === Qt.Key_Left) {
calendar.__selectPreviousDay();
event.accepted = true;
}
if(event.key === Qt.Key_Up) {
calendar.__selectPreviousWeek();
event.accepted = true;
}
if(event.key === Qt.Key_Down) {
calendar.__selectNextWeek();
event.accepted = true;
}
if(event.key === Qt.Key_Right) {
calendar.__selectNextDay();
event.accepted = true;
}
}
ListModel {
id: daysOfTheWeekModel
ListElement { text: qsTr("Sunday"); dayIndex: 0 }
ListElement { text: qsTr("Monday"); dayIndex: 1 }
ListElement { text: qsTr("Tuesday"); dayIndex: 2 }
ListElement { text: qsTr("Wednesday"); dayIndex: 3 }
ListElement { text: qsTr("Thursday"); dayIndex: 4 }
ListElement { text: qsTr("Friday"); dayIndex: 5 }
ListElement { text: qsTr("Saturday"); dayIndex: 6 }
}
// Creates a table consisting of days of weeks.
GridView {
id: answerChoices
model: daysOfTheWeekModel
anchors.top: calendarBox.top
anchors.left: questionItem.left
anchors.topMargin: 5
interactive: false
property bool keyNavigation: false
width: calendarBox.x - anchors.rightMargin
height: (calendar.height / 6.5) * 7
cellWidth: calendar.width * 0.5
cellHeight: calendar.height / 6.5
keyNavigationWraps: true
anchors.rightMargin: 10 * ApplicationInfo.ratio
delegate: ChoiceTable {
width: answerChoices.width
height: answerChoices.height / 7
choices.text: text
anchors.rightMargin: 2
}
Keys.enabled: answerChoices.visible
function handleKeys(event) {
if(event.key === Qt.Key_Down) {
keyNavigation = true
answerChoices.moveCurrentIndexDown()
}
if(event.key === Qt.Key_Up) {
keyNavigation = true
answerChoices.moveCurrentIndexUp()
}
if(event.key === Qt.Key_Enter && !questionDelay.running) {
keyNavigation = true
Activity.dayOfWeekSelected = model.get(currentIndex).dayIndex
answerChoices.currentItem.select()
}
if(event.key === Qt.Key_Space && !questionDelay.running) {
keyNavigation = true
Activity.dayOfWeekSelected = model.get(currentIndex).dayIndex
answerChoices.currentItem.select()
}
if(event.key === Qt.Key_Return && !questionDelay.running) {
keyNavigation = true
Activity.dayOfWeekSelected = model.get(currentIndex).dayIndex
answerChoices.currentItem.select()
}
}
highlight: Rectangle {
width: parent.width * 1.2
height: parent.height / 7
anchors.horizontalCenter: parent.horizontalCenter
color: "#e99e33"
border.width: 2
border.color: "#f2f2f2"
radius: 5
visible: answerChoices.keyNavigation
y: answerChoices.currentItem.y
Behavior on y {
SpringAnimation {
spring: 3
damping: 0.2
}
}
}
highlightFollowsCurrentItem: false
focus: answerChoices.visible
}
Rectangle {
id: questionItemBackground
color: "#373737"
border.width: 2
border.color: "#f2f2f2"
radius: 10
opacity: 0.85
z: 10
anchors {
horizontalCenter: parent.horizontalCenter
bottomMargin: 10
}
width: parent.width - 20
height: parent.height * 0.1
}
// Displays the question.
GCText {
id: questionItem
anchors.fill: questionItemBackground
anchors.bottom: questionItemBackground.bottom
fontSizeMode: Text.Fit
wrapMode: Text.Wrap
z: 10
color: "white"
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
}
// Answer Submission button.
BarButton {
id: okButton
source: "qrc:/gcompris/src/core/resource/bar_ok.svg"
- height: bar.height * 0.6
+ height: bar.height * 0.8
width: okButton.height
sourceSize.width: okButton.width
sourceSize.height: okButton.height
z: 10
anchors.top: calendarBox.bottom
anchors.right: calendarBox.right
anchors.margins: items.horizontalLayout ? 30 : 6
ParticleSystemStarLoader {
id: okButtonParticles
clip: false
}
MouseArea {
id: okButtonMouseArea
anchors.fill: parent
onClicked: {
Activity.checkAnswer()
}
}
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level }
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
}
Bonus {
id: bonus
Component.onCompleted: win.connect(Activity.nextLevel)
}
Score {
id: score
height: okButton.height
- fontSize: items.horizontalLayout ? internalTextComponent.mediumSize : (answerChoices.visible ? internalTextComponent.smallSize : internalTextComponent.tinySize)
+ width: height
anchors.top: calendarBox.bottom
anchors.bottom: undefined
anchors.left: undefined
anchors.right: answerChoices.visible ? calendarBox.right : okButton.left
anchors.margins: items.horizontalLayout ? 30 : 8
}
}
}
diff --git a/src/activities/calendar/ChoiceTable.qml b/src/activities/calendar/ChoiceTable.qml
index f1df2e541..3be5a02c6 100644
--- a/src/activities/calendar/ChoiceTable.qml
+++ b/src/activities/calendar/ChoiceTable.qml
@@ -1,134 +1,134 @@
/* GCompris - ChoiceTable.qml
*
* Copyright (C) 2017 Amit Sagtani <asagtani06@gmail.com>
*
* Authors:
* Amit Sagtani <asagtani06@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
// Creates a active button for making a table of days of weeks.
// Set different behaviours and animations on selecting a day from day table here.
import QtQuick 2.6
import GCompris 1.0
import QtQuick.Controls 1.5
import "../../core"
import "calendar.js" as Activity
Rectangle {
id: choiceBox
property alias choices: choices
color: "#AAFFFFFF"
radius: 10
anchors.margins: 30
border.color: "#373737"
border.width: 2
function select() {
if(Activity.dayOfWeekSelected === Activity.correctAnswer["dayOfWeek"]) {
particles.burst(40)
animWin.start()
Activity.checkAnswer()
}
else {
crossAnim.start()
}
}
Image {
id: cross
z: 10
source: "qrc:/gcompris/src/core/resource/cancel.svg"
sourceSize.width: choiceBox.height
sourceSize.height: choiceBox.height
anchors.centerIn: parent
height: 0
width: cross.height
opacity: 1
property int size: parent.height
}
SequentialAnimation {
id: crossAnim
ParallelAnimation {
PropertyAnimation {
target: cross
property: "height"
duration: 300
from: 0
to: choiceBox.height
easing.type: Easing.InOutQuad
}
}
PauseAnimation { duration: 800 }
ParallelAnimation {
PropertyAnimation {
target: cross
property: "height"
duration: 300
from: choiceBox.height
to: 0
easing.type: Easing.InOutQuad
}
}
}
ParticleSystemStarLoader {
id: particles
clip: false
}
GCText {
id: choices
anchors.fill: parent
anchors.leftMargin: choiceBox.border.width
anchors.rightMargin: choiceBox.border.width
fontSizeMode: Text.Fit
font.bold: true
color: "#373737"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
MouseArea {
id: mouseArea
anchors.fill: parent
onClicked: {
if(!questionDelay.running) {
Activity.dayOfWeekSelected = dayIndex
select()
choiceBox.scale = 1
}
}
hoverEnabled: true
enabled: !crossAnim.running && !animWin.running
onEntered: choiceBox.scale = 1.1
onExited: choiceBox.scale = 1
}
SequentialAnimation {
id: animWin
running: false
loops: 1
NumberAnimation {
target: choiceBox
property: "rotation"
from: 0; to: 360
duration: 600
easing.type: Easing.InOutQuad
}
}
}
diff --git a/src/activities/calendar/calendar.js b/src/activities/calendar/calendar.js
index 323d84f82..edef10d82 100644
--- a/src/activities/calendar/calendar.js
+++ b/src/activities/calendar/calendar.js
@@ -1,145 +1,145 @@
/* GCompris - calendar.js
*
* Copyright (C) 2017 Amit Sagtani <asagtani06@gmail.com>
*
* Authors:
* Amit Sagtani <asagtani06@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
.import QtQml 2.2 as Qml
.import GCompris 1.0 as GCompris //for ApplicationInfo
.import "qrc:/gcompris/src/core/core.js" as Core
var currentLevel = 0
var numberOfLevel
var currentSubLevel = 1
var currentDataSet
var currentLevelConfig
var dataset
var items
var daySelected = 1
var monthSelected = 2
var yearSelected = 2018
var dayOfWeekSelected
var minRange //sum of min. visible month and year on calendar for navigation bar next/prev button visibility.
var maxRange //sum of max. visible month and year on calendar for navigation bar next/prev button visibility.
var correctAnswer
var mode
function start(items_, dataset_) {
items = items_
dataset = dataset_.get()
numberOfLevel = dataset.length
currentLevel = 0
if(Qt.locale(GCompris.ApplicationSettings.locale).firstDayOfWeek == Qml.Locale.Monday) {
items.daysOfTheWeekModel.move(0, items.daysOfTheWeekModel.count - 1, 1)
}
initLevel();
}
function stop() {
}
function initLevel() {
currentSubLevel = 1;
items.bar.level = currentLevel + 1
currentLevelConfig = dataset[currentLevel][0][0]
setCalendarConfigurations()
initQuestion();
}
function nextLevel() {
if(numberOfLevel <= ++currentLevel) {
currentLevel = 0
}
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
initLevel();
}
// Configure calendar properties for every level.
function setCalendarConfigurations() {
minRange = Number(currentLevelConfig["minimumDate"].slice(5,7)) + Number(currentLevelConfig["minimumDate"].slice(0,4)) - 1;
maxRange = Number(currentLevelConfig["maximumDate"].slice(5,7)) + Number(currentLevelConfig["maximumDate"].slice(0,4)) - 1;
mode = currentLevelConfig["mode"]
items.calendar.navigationBarVisible = currentLevelConfig["navigationBarVisible"]
items.calendar.minimumDate = currentLevelConfig["minimumDate"]
items.calendar.maximumDate = currentLevelConfig["maximumDate"]
items.calendar.visibleYear = currentLevelConfig["visibleYear"]
yearSelected = currentLevelConfig["visibleYear"]
items.calendar.visibleMonth = currentLevelConfig["visibleMonth"]
monthSelected = currentLevelConfig["visibleMonth"]
items.answerChoices.visible = (mode === "findDayOfWeek") ? true : false
items.okButton.visible = !items.answerChoices.visible
currentDataSet = dataset[currentLevel][1]
currentDataSet = Core.shuffle(currentDataSet)
items.score.numberOfSubLevels = currentDataSet.length
items.score.currentSubLevel = currentSubLevel
}
function initQuestion() {
if(currentDataSet.length < currentSubLevel) {
items.bonus.good("lion")
}
else {
items.score.currentSubLevel = currentSubLevel
items.questionItem.text = currentDataSet[currentSubLevel-1]["question"]
correctAnswer = currentDataSet[currentSubLevel-1]["answer"]
}
}
function updateScore(isCorrectAnswer) {
if(isCorrectAnswer) {
items.questionDelay.start()
items.okButtonParticles.burst(20)
items.score.playWinAnimation()
currentSubLevel++;
}
else
items.bonus.bad("lion")
}
function checkAnswer() {
var isCorrectAnswer = false
// For levels having questions based on day of week only.
if(mode === "findDayOfWeek") {
if(dayOfWeekSelected === correctAnswer["dayOfWeek"]) {
isCorrectAnswer = true
}
}
// For levels having question based on month only.
else if(mode === "findMonthOnly") {
if(correctAnswer["month"].indexOf(monthSelected) >= 0) {
isCorrectAnswer = true
}
}
// For levels having questions based on dayOfWeek, month and year.
else if(mode !== "findDayOfWeek") {
if(monthSelected === correctAnswer["month"] && daySelected === correctAnswer["day"] && yearSelected === correctAnswer["year"]) {
isCorrectAnswer = true
}
}
updateScore(isCorrectAnswer)
}
diff --git a/src/activities/calendar/calendar_dataset.js b/src/activities/calendar/calendar_dataset.js
index 2d3e2ede0..309108779 100644
--- a/src/activities/calendar/calendar_dataset.js
+++ b/src/activities/calendar/calendar_dataset.js
@@ -1,317 +1,317 @@
/* GCompris - calendar_dataset.js
*
* Copyright (C) 2017 Amit Sagtani <asagtani06@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
// Contains the questions, answers and calendar configurations of every level.
// Add more levels by inserting questions and answers below.
// Days of weeks are indexed from 0 i.e (Sunday = 0, Monday = 1, Tuesday = 2, .... ..... .... , Saturday = 6)
// Months of year are indexed from 0 i.e (January = 0, February = 1, March = 2, .... ..... ...., December = 11)
//[
//MODES
// findMonthOnly --> For questions based on finding month only.
// findYearMonthDay --> For questions based on finding year, month and day.
// findDayOfWeek --> For questions based on finding day of week only.
// findDay --> For questions based on finding day of a given month and year.
// ]
function get() {
return [
[ // Level 1
[ // Level 1 Configurations
{
"navigationBarVisible" : false,
"minimumDate": "2018-03-01",
"maximumDate": "2018-03-31",
"visibleMonth": 2,
"visibleYear": 2018,
"mode": "findDay"
}
],
[ // Level 1 Questions
{
"question": qsTr("Select day 23"),
"answer": {"year": 2018, "month": 2, "day": 23}
},
{
"question": qsTr("Select day 1"),
"answer": {"year": 2018, "month": 2, "day": 1}
},
{
"question": qsTr("Select day 16"),
"answer": {"year": 2018, "month": 2, "day": 16}
},
{
"question": qsTr("Select day 28"),
"answer": {"year": 2018, "month": 2, "day": 28}
},
{
"question": qsTr("Select day 11"),
"answer": {"year": 2018, "month": 2, "day": 11}
},
{
"question": qsTr("Select day 20"),
"answer": {"year": 2018, "month": 2, "day": 20}
}
]
],
[ // Level 2
[ // Level 2 Configurations
{
"navigationBarVisible" : false,
"minimumDate": "2018-03-01",
"maximumDate": "2018-03-31",
"visibleMonth": 2,
"visibleYear": 2018,
"mode": "findDayOfWeek"
}
],
[ // Level 2 Questions
{
"question": qsTr("What day of week is the 4th of given month?"),
"answer": {"dayOfWeek": 0}
},
{
"question": qsTr("What day of the week is the 12th of given month?"),
"answer": {"dayOfWeek": 1}
},
{
"question": qsTr("What day of the week is the 20th of given month?"),
"answer": {"dayOfWeek": 2}
},
{
"question": qsTr("What day of the week is the 28th of given month?"),
"answer": {"dayOfWeek": 3}
},
{
"question": qsTr("What day of the week is the 22nd of given month?"),
"answer": {"dayOfWeek": 4}
},
{
"question": qsTr("What day of the week is the 16th of given month?"),
"answer": {"dayOfWeek": 5}
},
{
"question": qsTr("What day of the week is the 10th of given month?"),
"answer": {"dayOfWeek": 6}
}
]
],
[ // Level 3
[ // Level 3 configurations
{
"navigationBarVisible": false,
"minimumDate": "2018-03-01",
"maximumDate": "2018-03-31",
"visibleMonth": 2,
"visibleYear": 2018,
"mode": "findDay"
}
],
[ // Level 3 Questions
{
"question": qsTr("Select a Monday between days 1 and 7 of given month"),
"answer": {"year": 2018, "month": 2, "day": 5}
},
{
"question": qsTr("Select a Tuesday between days 8 and 16 of given month"),
"answer": {"year": 2018, "month": 2, "day": 13}
},
{
"question": qsTr("Select a Wednesday between days 15 and 22 of given month"),
"answer": {"year": 2018, "month": 2, "day": 21}
},
{
"question": qsTr("Select a Thursday between days 26 and 31 of given month"),
"answer": {"year": 2018, "month": 2, "day": 29}
},
{
"question": qsTr("Select a Friday between days 20 and 25 of given month"),
"answer": {"year": 2018, "month": 2, "day": 23}
},
{
"question": qsTr("Select a Saturday between days 13 and 23 of given month"),
"answer": {"year": 2018, "month": 2, "day": 17}
},
{
"question": qsTr("Select a Sunday between days 5 and 17 of given month"),
"answer": {"year": 2018, "month": 2, "day": 11}
}
]
],
[ // level 4
[ // Level 4 Configurations
{
"navigationBarVisible" : false,
"minimumDate": "2018-03-01",
"maximumDate": "2018-03-31",
"visibleMonth": 2,
"visibleYear": 2018,
"mode": "findDay"
}
],
[ // Level 4 Questions
{
"question": qsTr("Select second day before the 15th of given month"),
"answer": {"year": 2018, "month": 2, "day": 13}
},
{
"question": qsTr("Select fourth Sunday of given month"),
"answer": {"year": 2018, "month": 2, "day": 25}
},
{
"question": qsTr("Select day one week after 13th of given month"),
"answer": {"year": 2018, "month": 2, "day": 20}
},
{
"question": qsTr("Select fifth Thursday of given month"),
"answer": {"year": 2018, "month": 2, "day": 29}
},
{
"question": qsTr("Select third day after 27th of given month"),
"answer": {"year": 2018, "month": 2, "day": 30}
}
]
],
[ // Level 5
[ // Level 5 Configurations
{
"navigationBarVisible" : true,
"minimumDate": "2018-01-01",
"maximumDate": "2018-12-31",
"visibleMonth": 1,
"visibleYear": 2018,
"mode": "findMonthOnly"
}
],
[ // Level 5 Questions
{
"question": qsTr("Find the month starting a Thursday and having 28 days"),
"answer": {"month": [1]}
},
{
"question": qsTr("Find a month starting a Monday and having 31 days"),
"answer": {"month": [0, 9]}
},
{
"question": qsTr("Find the month between June and August"),
"answer": {"month": [6]}
},
{
"question": qsTr("Find a month starting a Saturday"),
"answer": {"month": [8, 11]}
},
{
"question": qsTr("Find a month having 30 days"),
"answer": {"month": [3, 5, 8, 10]}
}
]
],
[ // level 6
[ // Level 6 Configurations
{
"navigationBarVisible" : true,
"minimumDate": "2017-01-01",
"maximumDate": "2019-12-31",
"visibleMonth": 2,
"visibleYear": 2018,
"mode": "findYearMonthDay"
}
],
[ // Level 6 Questions
{
"question": qsTr("Find the first Monday of January month of year 2019"),
"answer": {"year": 2019, "month": 0, "day": 7}
},
{
"question": qsTr("Find the second Wednesday of February month of year 2019"),
"answer": {"year": 2019, "month": 1, "day": 13}
},
{
"question": qsTr("Find the third Friday of March month of year 2019"),
"answer": {"year": 2019, "month": 2, "day": 15}
},
{
"question": qsTr("Find the fifth Sunday of April month of year 2018"),
"answer": {"year": 2018, "month": 3, "day": 29}
},
{
"question": qsTr("Find the fourth Tuesday of July month of year 2018"),
"answer": {"year": 2018, "month": 6, "day": 24}
},
{
"question": qsTr("Find the first Monday of August month of year 2018"),
"answer": {"year": 2018, "month": 7, "day": 6}
},
{
"question": qsTr("Find the third Thursday of September month of year 2017"),
"answer": {"year": 2017, "month": 8, "day": 21}
},
{
"question": qsTr("Find the fifth Sunday of October month of year 2017"),
"answer": {"year": 2017, "month": 9, "day": 29}
},
{
"question": qsTr("Find the second Friday of December month of year 2017"),
"answer": {"year": 2017, "month": 11, "day": 8}
}
]
],
[ // Level 7
[ // Level 7 Configurations
{
"navigationBarVisible" : true,
"minimumDate": "2017-01-01",
"maximumDate": "2019-12-31",
"visibleMonth": 1,
"visibleYear": 2018,
"mode": "findYearMonthDay"
}
],
[ // Level 7 Questions
{
"question": qsTr("Human Rights Day is celebrated five days after December 5.<br> Find the date of Human Rights Day in 2017."),
"answer": {"year": 2017, "month": 11, "day": 10}
},
{
"question": qsTr("Braille Day is celebrated one day before January 5.<br> Find the date of Braille Day in 2018"),
"answer": {"year": 2018, "month": 0, "day": 4}
},
{
"question": qsTr("Mark's birthday is on November 4. In 2017 his party was exactly two weeks later.<br> Find the date of his party in 2017"),
"answer": {"year": 2017, "month": 10, "day": 18}
},
{
"question": qsTr("International Women's Day is celebrated two days before March 10.<br> Find the date of International Women's Day in 2018."),
"answer": {"year": 2018, "month": 2, "day": 8}
},
{
"question": qsTr("Sports competition was held on last Friday of September 2017.<br> Select the date of sports competition on the calendar."),
"answer": {"year": 2017, "month": 8, "day": 29}
}
]
]
]
}
diff --git a/src/activities/canal_lock/ActivityInfo.qml b/src/activities/canal_lock/ActivityInfo.qml
index 282828f94..d5f8dcac6 100644
--- a/src/activities/canal_lock/ActivityInfo.qml
+++ b/src/activities/canal_lock/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "canal_lock/CanalLock.qml"
difficulty: 2
icon: "canal_lock/canal_lock.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
//: Activity title
title: qsTr("Operate a canal lock")
//: Help title
description: qsTr("Tux is in trouble, and needs to take his boat through a lock. Help Tux and find out how a canal lock works.")
//intro: "You are responsible for the lock and you must help Tux pass through. Click on the valves to cause either a drop or an increase in the water level, and click on the gates to open or close a path."
//: Help goal
goal: ""
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("You are in charge of the canal lock. Open the gates and the locks in the right order, so Tux can travel through the gates in both directions.")
credit: qsTr("Drawing by Stephane Cabaraux.")
section: "experiment"
createdInVersion: 0
}
diff --git a/src/activities/canal_lock/CanalLock.qml b/src/activities/canal_lock/CanalLock.qml
index 6b73b4687..08d95d0d2 100644
--- a/src/activities/canal_lock/CanalLock.qml
+++ b/src/activities/canal_lock/CanalLock.qml
@@ -1,471 +1,492 @@
/* GCompris - canal_lock.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "."
ActivityBase {
id: activity
onStart: focus = true
onStop: {}
property string url: "qrc:/gcompris/src/activities/canal_lock/resource/"
pageComponent: Item {
id: background
anchors.fill: parent
property int running: 0
signal start
signal stop
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
+
+ IntroMessage {
+ id: message
+ anchors {
+ top: parent.top
+ topMargin: 10
+ right: parent.right
+ rightMargin: 5
+ left: parent.left
+ leftMargin: 5
+ }
+ z: 100
+ intro: [
+ qsTr("Your goal is to get Tux across the canal lock to get the wooden logs, "
+ +"using the different types of water locks available."),
+ qsTr("The vertical colored bars represent the water locks, which can be operated by clicking them. "
+ +"Two locks of the same type cannot be operated simultaneously.") ,
+ qsTr("The water level inside the lock will change according to the side of the canal it is "
+ +"connected with. Use this property to help Tux get the job done.")
+ ]
+ }
onStart: water.state = 'down'
Image {
id: sky
source: activity.url + "sky.svg"
sourceSize.width: parent.width
anchors.top: parent.top
height: (background.height - canal.paintedHeight) / 2 + canal.paintedHeight * 0.6
}
Image {
source: activity.url + "sun.svg"
sourceSize.width: Math.min(120 * ApplicationInfo.ratio, parent.width * 0.15)
x: 10
y: 10
}
Image {
source: activity.url + "cloud1.svg"
sourceSize.width: Math.min(120 * ApplicationInfo.ratio, parent.width * 0.15)
anchors.top: parent.top
anchors.left: parent.left
anchors.leftMargin: parent.width * 0.18
anchors.topMargin: parent.height * 0.1
}
Image {
source: activity.url + "cloud2.svg"
sourceSize.width: Math.min(130 * ApplicationInfo.ratio, parent.width * 0.2)
anchors.top: parent.top
anchors.left: parent.left
anchors.leftMargin: parent.width * 0.25
anchors.topMargin: parent.height * 0.02
}
Image {
source: activity.url + "ground.svg"
sourceSize.width: parent.width
anchors.bottom: parent.bottom
height: (background.height - canal.paintedHeight) / 2 + canal.paintedHeight * 0.3
}
Image {
id: canal
source: activity.url + "canal_lock.svg"
anchors.fill: parent
sourceSize.width: parent.width
fillMode: Image.PreserveAspectFit
Image {
source: activity.url + "canal_left.svg"
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
width: (background.width - parent.paintedWidth) / 2 + 1
sourceSize.height: parent.paintedHeight
}
Image {
source: activity.url + "canal_right.svg"
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
width: (background.width - parent.paintedWidth) / 2 + 1
sourceSize.height: parent.paintedHeight
}
Rectangle {
id: water
anchors.bottom: parent.bottom
anchors.bottomMargin: (background.height - canal.paintedHeight) / 2 +
canal.paintedHeight * 0.23
anchors.horizontalCenter: parent.horizontalCenter
anchors.horizontalCenterOffset: parent.paintedWidth * 0.035
color: "#4f76d6"
width: parent.paintedWidth * 0.205
height: minHeight
state: "undef"
property int maxHeight: parent.paintedHeight * 0.33
property int minHeight: canal.paintedHeight * 0.15
property int duration: 3500
Behavior on height { NumberAnimation { duration: water.duration } }
onStateChanged: {
if( water.state == "undef")
return
activity.audioEffects.play(activity.url + 'water_fill.wav')
if( water.state == 'up' && boat.state == 'middleDown')
boat.state = 'middleUp'
else if( water.state == 'down' && boat.state == 'middleUp')
boat.state = 'middleDown'
}
states: [
State {
name: "undef"
PropertyChanges { target: water; height: water.minHeight}
},
State {
name: "down"
PropertyChanges { target: water; height: water.minHeight}
},
State {
name: "up"
PropertyChanges { target: water; height: water.maxHeight}
}
]
}
Lock {
id: lock1
color: "#dfb625"
anchors.bottomMargin: (background.height - canal.paintedHeight) / 2 +
canal.paintedHeight * 0.03
anchors.horizontalCenterOffset: - parent.paintedWidth * 0.16
minHeight: canal.paintedHeight * 0.05
maxHeight: parent.paintedHeight * 0.18
duration: 0
MouseArea {
anchors.fill: parent
anchors.margins: -20 * ApplicationInfo.ratio
onClicked: {
if(background.running)
return
lock1.duration = 400
if(lock1.state == 'close' &&
door2.state == 'close' &&
lock2.state == 'close') {
activity.audioEffects.play(activity.url + 'lock.wav')
lock1.state = 'open'
water.state = 'down'
} else if(lock1.state == 'open') {
activity.audioEffects.play(activity.url + 'lock.wav')
lock1.state = 'close'
} else {
activity.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/crash.wav")
}
}
}
}
Lock {
id: lock2
color: "#dfb625"
anchors.bottomMargin: (background.height - canal.paintedHeight) / 2 +
canal.paintedHeight * 0.03
anchors.horizontalCenterOffset: parent.paintedWidth * 0.22
minHeight: canal.paintedHeight * 0.05
maxHeight: parent.paintedHeight * 0.18
duration: 0
MouseArea {
anchors.fill: parent
anchors.margins: -20 * ApplicationInfo.ratio
onClicked: {
if(background.running)
return
lock2.duration = lock1.duration
if(lock2.state == 'close' &&
door1.state == 'close' &&
lock1.state == 'close') {
activity.audioEffects.play(activity.url + 'lock.wav')
lock2.state = 'open'
water.state = 'up'
} else if(lock2.state == 'open') {
activity.audioEffects.play(activity.url + 'lock.wav')
lock2.state = 'close'
} else {
activity.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/crash.wav")
}
}
}
}
Lock {
id: door1
color: "#31cb25"
anchors.bottomMargin: (background.height - canal.paintedHeight) / 2 +
canal.paintedHeight * 0.2
anchors.horizontalCenterOffset: - parent.paintedWidth * 0.07
minHeight: canal.paintedHeight * 0.05
maxHeight: canal.paintedHeight * 0.4
duration: 0
MouseArea {
anchors.fill: parent
anchors.margins: -20 * ApplicationInfo.ratio
onClicked: {
if(background.running)
return
door1.duration = water.duration
if(door1.state == 'close' &&
water.state == 'down') {
door1.state = 'open'
leftLight.state = 'green'
activity.audioEffects.play(activity.url + 'door_open.wav')
} else if(door1.state == 'open') {
door1.state = 'close'
leftLight.state = 'red'
activity.audioEffects.play(activity.url + 'door_close.wav')
} else {
activity.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/crash.wav")
}
}
}
}
Lock {
id: door2
color: "#31cb25"
anchors.bottomMargin: (background.height - canal.paintedHeight) / 2 +
canal.paintedHeight * 0.2
anchors.horizontalCenterOffset: parent.paintedWidth * 0.14
minHeight: canal.paintedHeight * 0.15
maxHeight: canal.paintedHeight * 0.4
duration: 0
MouseArea {
anchors.fill: parent
anchors.margins: -20 * ApplicationInfo.ratio
onClicked: {
if(background.running)
return
door2.duration = water.duration
if(door2.state == 'close' &&
water.state == 'up') {
door2.state = 'open'
rightLight.state = 'green'
activity.audioEffects.play(activity.url + 'door_open.wav')
} else if(door2.state == 'open') {
door2.state = 'close'
rightLight.state = 'red'
activity.audioEffects.play(activity.url + 'door_close.wav')
} else {
activity.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/crash.wav")
}
}
}
}
Image {
id: leftLight
source: activity.url + "light_red.svg"
anchors.bottom: parent.bottom
anchors.bottomMargin: (background.height - canal.paintedHeight) / 2 +
canal.paintedHeight * 0.46
anchors.horizontalCenter: parent.horizontalCenter
anchors.horizontalCenterOffset: - parent.paintedWidth * 0.18
sourceSize.height: parent.paintedHeight * 0.1
states: [
State {
name: "green"
PropertyChanges {
target: leftLight
source: activity.url + "light_green.svg"
}
},
State {
name: "red"
PropertyChanges {
target: leftLight
source: activity.url + "light_red.svg"
}
}
]
}
Image {
id: rightLight
source: activity.url + "light_red.svg"
anchors.bottom: parent.bottom
anchors.bottomMargin: (background.height - canal.paintedHeight) / 2 +
canal.paintedHeight * 0.60
anchors.horizontalCenter: parent.horizontalCenter
anchors.horizontalCenterOffset: parent.paintedWidth * 0.20
sourceSize.height: parent.paintedHeight * 0.1
mirror: true
states: [
State {
name: "green"
PropertyChanges {
target: rightLight
source: activity.url + "light_green.svg"
}
},
State {
name: "red"
PropertyChanges {
target: rightLight
source: activity.url + "light_red.svg"
}
}
]
}
Image {
id: boat
source: activity.url + "boat1.svg"
sourceSize.width: water.width * 0.74
anchors {
bottom: parent.bottom
bottomMargin: leftPositionY
horizontalCenter: parent.horizontalCenter
horizontalCenterOffset: leftPositionX
onHorizontalCenterOffsetChanged: {
if(boat.anchors.horizontalCenterOffset == boat.rightPositionX) {
boat.source = activity.url + "boat2.svg"
bonus.good("flower")
} else if(boat.anchors.horizontalCenterOffset == boat.leftPositionX) {
boat.source = activity.url + "boat1.svg"
}
}
}
state: 'left'
property int leftPositionX: - (parent.paintedWidth / 2) * 0.8
property int leftPositionY: (background.height - canal.paintedHeight) / 2 +
canal.paintedHeight * 0.37
property int middlePositionX: canal.paintedWidth * 0.035
property int rightPositionX: (parent.paintedWidth / 2) * 0.7
property int rightPositionY: (background.height - canal.paintedHeight) / 2 +
canal.paintedHeight * 0.55 // > 0.5 < 0.6
property int duration: 0
Behavior on anchors.horizontalCenterOffset {
NumberAnimation {
duration: boat.duration
onRunningChanged: background.running ? background.running++ : background.running--
}
}
Behavior on anchors.bottomMargin {
NumberAnimation {
duration: boat.duration
onRunningChanged: background.running ? background.running++ : background.running--
}
}
MouseArea {
anchors.fill: parent
onClicked: {
if(background.running)
return
boat.duration = water.duration
var prevState = boat.state
if(boat.state == "left" && door1.state == "open")
boat.state = "middleDown"
else if(boat.state == "middleUp" && door2.state == "open")
boat.state = "right"
else if(boat.state == "right" && door2.state == "open")
boat.state = "middleUp"
else if(boat.state == "middleDown" && door1.state == "open")
boat.state = "left"
if(prevState !== boat.state)
activity.audioEffects.play('qrc:/gcompris/src/core/resource/sounds/water.wav')
}
}
states: [
State {
name: "left"
PropertyChanges {
target: boat
anchors.horizontalCenterOffset: boat.leftPositionX
anchors.bottomMargin: boat.leftPositionY
}
},
State {
name: "middleDown"
PropertyChanges {
target: boat
anchors.horizontalCenterOffset: boat.middlePositionX
anchors.bottomMargin: boat.leftPositionY
}
},
State {
name: "middleUp"
PropertyChanges {
target: boat
anchors.horizontalCenterOffset: boat.middlePositionX
anchors.bottomMargin: boat.rightPositionY
}
},
State {
name: "right"
PropertyChanges {
target: boat
anchors.horizontalCenterOffset: boat.rightPositionX
anchors.bottomMargin: boat.rightPositionY
}
}
]
}
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home }
onHelpClicked: {
displayDialog(dialogHelp)
}
onHomeClicked: activity.home()
}
Bonus {
id: bonus
}
}
}
diff --git a/src/activities/canal_lock/Lock.qml b/src/activities/canal_lock/Lock.qml
index 276c59b38..5ff7a7ae6 100644
--- a/src/activities/canal_lock/Lock.qml
+++ b/src/activities/canal_lock/Lock.qml
@@ -1,52 +1,52 @@
/* GCompris - Lock.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
Rectangle {
id: lock
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
width: parent.paintedWidth * 0.05
height: maxHeight
border.width: 0
state: "close"
property int minHeight
property int maxHeight
property int duration
Behavior on height { NumberAnimation { duration: lock.duration } }
states: [
State {
name: "open"
PropertyChanges { target: lock; height: lock.minHeight}
},
State {
name: "close"
PropertyChanges { target: lock; height: lock.maxHeight}
}
]
}
diff --git a/src/activities/categorization/ActivityInfo.qml b/src/activities/categorization/ActivityInfo.qml
index 62136dccc..500e13c5d 100644
--- a/src/activities/categorization/ActivityInfo.qml
+++ b/src/activities/categorization/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2016 Divyam Madaan <divyam3897@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "categorization/Categorization.qml"
difficulty: 4
icon: "categorization/categorization.svg"
author: "Divyam Madaan &lt;divyam3897@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Categorization")
//: Help title
description: qsTr("Categorize the elements into correct and incorrect groups")
//intro: "Categorize the elements into the correct group"
//: Help goal
goal: qsTr("Build conceptual thinking and enrich knowledge")
//: Help prerequisite
prerequisite: qsTr("Can drag elements using mouse")
//: Help manual
manual: qsTr("Review the instructions and then drag and drop the elements as specified")
credit: ""
section: "fun"
createdInVersion: 8000
}
diff --git a/src/activities/categorization/Categorization.qml b/src/activities/categorization/Categorization.qml
index 992446d98..ceff9d62b 100644
--- a/src/activities/categorization/Categorization.qml
+++ b/src/activities/categorization/Categorization.qml
@@ -1,239 +1,239 @@
/* GCompris - categorization.qml
*
* Copyright (C) 2016 Divyam Madaan <divyam3897@gmail.com>
*
* Authors:
* Divyam Madaan <divyam3897@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import QtQuick.Controls 1.5
import GCompris 1.0
import "../../core"
import "categorization.js" as Activity
import "qrc:/gcompris/src/core/core.js" as Core
import "."
ActivityBase {
id: activity
onStart: focus = true
onStop: {}
property string boardsUrl: ":/gcompris/src/activities/categorization/resource/board/"
- property bool vert: background.width < background.height
+ property bool vert: background.width <= background.height
property var barAtStart
pageComponent: Image {
id: background
source: "qrc:/gcompris/src/activities/guesscount/resource/backgroundW01.svg"
anchors.fill: parent
sourceSize.width: parent.width
signal start
signal stop
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property alias background: background
property alias bar: bar
property alias bonus: bonus
property alias categoryReview: categoryReview
property alias menuScreen: menuScreen
property alias menuModel: menuScreen.menuModel
property alias dialogActivityConfig: dialogActivityConfig
property string mode: "easy"
property bool instructionsVisible: true
property bool categoryImageChecked: (mode === "easy" || mode === "medium")
property bool scoreChecked: (mode === "easy" || mode === "expert")
property bool iAmReadyChecked: (mode === "expert")
property bool displayUpdateDialogAtStart: true
property var details
property bool categoriesFallback
property alias file: file
property var categories: directory.getFiles(boardsUrl)
}
function hideBar() {
barAtStart = ApplicationSettings.isBarHidden;
- if(categoryReview.width > categoryReview.height)
+ if(categoryReview.width >= categoryReview.height)
ApplicationSettings.isBarHidden = false;
else
ApplicationSettings.isBarHidden = true;
}
onStart: {
Activity.init(items, boardsUrl)
dialogActivityConfig.getInitialConfiguration()
Activity.start()
hideBar()
}
onStop: {
dialogActivityConfig.saveDatainConfiguration()
ApplicationSettings.isBarHidden = barAtStart;
}
MenuScreen {
id: menuScreen
File {
id: file
onError: console.error("File error: " + msg);
}
}
Directory {
id: directory
}
CategoryReview {
id: categoryReview
}
ExclusiveGroup {
id: configOptions
}
DialogActivityConfig {
id: dialogActivityConfig
content: Component {
Column {
id: column
spacing: 5
width: dialogActivityConfig.width
height: dialogActivityConfig.height
property alias easyModeBox: easyModeBox
property alias mediumModeBox: mediumModeBox
property alias expertModeBox: expertModeBox
GCDialogCheckBox {
id: easyModeBox
width: column.width - 50
text: qsTr("Put together all the elements from a category (with score)")
checked: (items.mode == "easy") ? true : false
exclusiveGroup: configOptions
onCheckedChanged: {
if(easyModeBox.checked) {
items.mode = "easy"
menuScreen.iAmReady.visible = false
}
}
}
GCDialogCheckBox {
id: mediumModeBox
width: easyModeBox.width
text: qsTr("Put together all the elements from a category (without score)")
checked: (items.mode == "medium") ? true : false
exclusiveGroup: configOptions
onCheckedChanged: {
if(mediumModeBox.checked) {
items.mode = "medium"
menuScreen.iAmReady.visible = false
}
}
}
GCDialogCheckBox {
id: expertModeBox
width: easyModeBox.width
text: qsTr("Discover a category, grouping elements together")
checked: (items.mode == "expert") ? true : false
exclusiveGroup: configOptions
onCheckedChanged: {
if(expertModeBox.checked) {
items.mode = "expert"
menuScreen.iAmReady.visible = true
}
}
}
}
}
onLoadData: {
if(dataToSave && dataToSave["mode"])
items.mode = dataToSave["mode"]
if(dataToSave && dataToSave["displayUpdateDialogAtStart"])
items.displayUpdateDialogAtStart = (dataToSave["displayUpdateDialogAtStart"] == "true") ? true : false
}
onSaveData: {
dataToSave["data"] = Activity.categoriesToSavedProperties(dataToSave)
dataToSave["mode"] = items.mode
dataToSave["displayUpdateDialogAtStart"] = items.displayUpdateDialogAtStart ? "true" : "false"
}
onClose: home()
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: menuScreen.started ? withConfig : withoutConfig
property BarEnumContent withConfig: BarEnumContent { value: help | home | config }
property BarEnumContent withoutConfig: BarEnumContent { value: home | level }
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHelpClicked: {
displayDialog(dialogHelp)
}
onHomeClicked: {
if(items.menuScreen.started)
activity.home()
else if(items.categoryReview.started)
Activity.launchMenuScreen()
}
onConfigClicked: {
dialogActivityConfig.active = true
displayDialog(dialogActivityConfig)
}
}
Bonus {
id: bonus
Component.onCompleted: win.connect(Activity.nextLevel)
}
Loader {
id: categoriesFallbackDialog
sourceComponent: GCDialog {
parent: activity.main
message: qsTr("You don't have all the images for this activity. " +
"Press Update to get the complete dataset. " +
"Press the Cross to play with demo version or 'Never show this dialog later' if you want to never see again this dialog.")
button1Text: qsTr("Update the image set")
button2Text: qsTr("Never show this dialog later")
onClose: items.categoriesFallback = false
onButton1Hit: DownloadManager.downloadResource('data2/words/words.rcc')
onButton2Hit: { items.displayUpdateDialogAtStart = false; dialogActivityConfig.saveDatainConfiguration() }
}
anchors.fill: parent
focus: true
active: items.categoriesFallback && items.displayUpdateDialogAtStart
onStatusChanged: if (status == Loader.Ready) item.start()
}
}
}
diff --git a/src/activities/categorization/CategoryReview.qml b/src/activities/categorization/CategoryReview.qml
index a38c819f1..474433269 100644
--- a/src/activities/categorization/CategoryReview.qml
+++ b/src/activities/categorization/CategoryReview.qml
@@ -1,238 +1,238 @@
/* GCompris - CategoryReview.qml
*
* Copyright (C) 2016 Divyam Madaan <divyam3897@gmail.com>
*
* Authors:
* Divyam Madaan <divyam3897@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "categorization.js" as Activity
Item {
id: rootItem
property alias score: score
property alias categoryDataset: categoryDataset
property alias instructionBox: instructionBox
property alias categoryImage: categoryImage
property bool isDropped: true
property bool leftAreaContainsDrag: false
property bool rightAreaContainsDrag: false
property bool started: rootItem.opacity == 1
- property bool horizontalLayout: categoryBackground.width > categoryBackground.height
+ property bool horizontalLayout: categoryBackground.width >= categoryBackground.height
property alias leftZone: leftZone.model
property alias rightZone: rightZone.model
property alias middleZone: middleZone.model
property alias leftScreen: leftScreen
property alias middleScreen: middleScreen
property alias rightScreen: rightScreen
anchors.fill: parent
Loader {
id: categoryDataset
asynchronous: false
}
Image {
id: categoryBackground
source: "qrc:/gcompris/src/activities/categorization/resource/background.svg"
anchors.fill: parent
sourceSize.width:parent.width
Zone {
- id:leftZone
+ id: leftZone
x: 0.012 * middleScreen.width
z: 2
y: 0.05 * parent.height
spacing: x
}
Rectangle {
id: leftScreen
width: parent.width/3
height: parent.height
x: 0
color: leftAreaContainsDrag ? "#F9F8B4" : "#F9B4B4"
border.width: 5
border.color: "#EC1313"
opacity: 0.5
}
Zone {
id: rightZone
spacing: leftZone.x
x: leftScreen.width + middleScreen.width + spacing
z: 2
anchors.top: categoryBackground.top
anchors.topMargin: items.mode != "expert" ? rootItem.categoryImage.height + 0.027 * rightScreen.height : 0.05 * categoryBackground.height
}
Rectangle {
id: rightScreen
width: parent.width/3
height: parent.height
x: leftScreen.width + middleScreen.width
color: rightAreaContainsDrag ? "#F9F8B4" : "#B4F9C5"
border.width: 5
border.color: "#13EC52"
opacity: 0.5
}
Rectangle {
id: middleScreen
width: parent.width/3
height: parent.height
x: leftScreen.width
color: "#00FFFFFF"
}
Rectangle {
id: instructionBox
anchors.left: categoryBackground.left
anchors.right: categoryImage.left
anchors.leftMargin: 0.32 * parent.width
anchors.rightMargin: 0.03 * parent.width
color: "black"
opacity: items.instructionsVisible ? 0.85 : 0
z: 3
radius: 10
border.width: 2
width: horizontalLayout ? parent.width/5 : parent.width/3
height: horizontalLayout ? parent.height/6 : parent.height * 0.09
gradient: Gradient {
GradientStop { position: 0.0; color: "#000" }
GradientStop { position: 0.9; color: "#666" }
GradientStop { position: 1.0; color: "#AAA" }
}
}
Zone {
id: middleZone
spacing: 0.012 * middleScreen.width
anchors {
left: leftScreen.right
right: rightScreen.left
top: parent.top
topMargin: 0.05 * parent.height
bottom: categoryBackground.bottom
leftMargin: 0.015 * middleScreen.width
}
}
GCText {
id: instructions
text: items.mode !== "expert" && items.details && items.details[bar.level-1] && items.details[bar.level - 1].instructions ? items.details[bar.level - 1].instructions : qsTr("Place the majority category images to the right and other images to the left")
visible: items.instructionsVisible
anchors.fill: instructionBox
anchors.bottom: instructionBox.bottom
fontSizeMode: Text.Fit
wrapMode: Text.Wrap
z: 3
color: "white"
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
}
Image {
id: categoryImage
fillMode: Image.PreserveAspectFit
source: items.details && items.details[bar.level-1] && items.details[bar.level-1].image ? items.details[bar.level-1].image : ""
sourceSize.width: horizontalLayout ? rightZone.width * 0.35 : rightZone.width * 0.35
width: sourceSize.width
height: sourceSize.width
y: 0.015*parent.height
visible: items.categoryImageChecked
anchors {
left: middleScreen.right
leftMargin: 0.15 * rightZone.width
}
}
BarButton {
id: validate
source: "qrc:/gcompris/src/core/resource/bar_ok.svg"
width: horizontalLayout ? rightZone.width * 0.20 : rightZone.width * 0.35
height: width
sourceSize.width: width
sourceSize.height: height
y: parent.height*0.8
z: 2
anchors {
rightMargin: 14 * ApplicationInfo.ratio
right: parent.right
}
MouseArea {
anchors.fill: parent
onClicked: {
Activity.allPlaced();
}
}
}
DropArea {
id: rightArea
anchors.fill: rightZone
}
DropArea {
id: leftArea
anchors.fill: leftZone
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Score {
id: score
- fontSize: 0.013 * parent.width
visible: items.scoreChecked
- height: horizontalLayout ? 0.1 * parent.height : 0.06 * parent.height
- width: horizontalLayout ? 0.015 * parent.width : parent.width
+ width: rightZone.width * 0.4
+ height: width * 0.6
+ margins: 10 * ApplicationInfo.ratio
anchors {
top: parent.top
- right: categoryBackground.right
- left: categoryImage.right
+ right: parent.right
+ left: undefined
bottom: undefined
}
}
}
Keys.onEscapePressed: { Activity.launchMenuScreen(); }
Keys.onReleased: {
if (event.key === Qt.Key_Back) {
event.accepted = true
Activity.launchMenuScreen()
}
}
function stop() {
if(items.mode == "expert")
items.menuScreen.iAmReady.visible = true
focus = false
rootItem.visible = false
}
function start() {
focus = true
rootItem.visible = true
}
}
diff --git a/src/activities/categorization/MenuScreen.qml b/src/activities/categorization/MenuScreen.qml
index b6f1f79b9..c5bc004bd 100644
--- a/src/activities/categorization/MenuScreen.qml
+++ b/src/activities/categorization/MenuScreen.qml
@@ -1,248 +1,248 @@
/* GCompris - MenuScreen.qml
*
* Copyright (C) Divyam Madaan <divyam3897@gmail.com> (Qt Quick port)
*
* Authors:
* Pascal Georges (pascal.georges1@free.fr) (GTK+ version)
* Holger Kaelberer <holger.k@elberer.de> (Qt Quick port of imageid)
* Siddhesh suthar <siddhesh.it@gmail.com> (Qt Quick port)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Integration Lang dataset)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import QtGraphicalEffects 1.0
import QtQuick.Controls 1.5
import "../../core"
import "categorization.js" as Activity
Image {
id: menuScreen
anchors.fill: parent
fillMode: Image.PreserveAspectCrop
source: "qrc:/gcompris/src/activities/guesscount/resource/backgroundW01.svg"
sourceSize.width: Math.max(parent.width, parent.height)
opacity: 0
property alias menuModel: menuModel
property alias iAmReady: iAmReady
property bool keyboardMode: false
property bool started: opacity == 1
Behavior on opacity { PropertyAnimation { duration: 200 } }
visible: opacity != 0
function start() {
focus = true
forceActiveFocus()
menuGrid.currentIndex = 0
opacity = 1
}
function stop() {
focus = false
opacity = 0
}
Keys.onEscapePressed: {
home()
}
- Keys.enabled : (items.mode == "expert") ? false : true
+ Keys.enabled: (items.mode == "expert") ? false : true
Keys.onPressed: {
if(event.key === Qt.Key_Space) {
menuGrid.currentItem.selectCurrentItem()
event.accepted = true
}
if(event.key === Qt.Key_Enter) {
menuGrid.currentItem.selectCurrentItem()
event.accepted = true
}
if(event.key === Qt.Key_Return) {
menuGrid.currentItem.selectCurrentItem()
event.accepted = true
}
if(event.key === Qt.Key_Left) {
menuGrid.moveCurrentIndexLeft()
event.accepted = true
}
if(event.key === Qt.Key_Right) {
menuGrid.moveCurrentIndexRight()
event.accepted = true
}
if(event.key === Qt.Key_Up) {
menuGrid.moveCurrentIndexUp()
event.accepted = true
}
if(event.key === Qt.Key_Down) {
menuGrid.moveCurrentIndexDown()
event.accepted = true
}
}
Keys.onReleased: {
keyboardMode = true
event.accepted = false
}
// sections
property int iconWidth: 180 * ApplicationInfo.ratio
property int iconHeight: 180 * ApplicationInfo.ratio
property int levelCellWidth: background.width / Math.floor(background.width / iconWidth )
property int levelCellHeight: iconHeight * 1.2
ListModel {
id: menuModel
}
GridView {
id: menuGrid
anchors {
fill: parent
bottomMargin: bar.height
}
cellWidth: levelCellWidth
cellHeight: levelCellHeight
clip: true
model: menuModel
keyNavigationWraps: true
property int spacing: 10
ReadyButton {
id: iAmReady
focus: true
visible: items.iAmReadyChecked
onClicked: {
Activity.startCategory()
}
}
delegate: Item {
id: delegateItem
width: levelCellWidth - menuGrid.spacing
height: levelCellHeight - menuGrid.spacing
property string sectionName: name
opacity: (items.mode == "expert") ? 0.25 : 1
Rectangle {
id: activityBackground
width: levelCellWidth - menuGrid.spacing
height: levelCellHeight - menuGrid.spacing
anchors.horizontalCenter: parent.horizontalCenter
color: "white"
opacity: 0.5
}
Image {
id: containerImage
source: image
anchors.top: activityBackground.top
anchors.horizontalCenter: parent.horizontalCenter
height: activityBackground.height*0.8 - 6
width: height
anchors.margins: 5
sourceSize.height: height
fillMode: Image.PreserveAspectCrop
clip: true
}
GCText {
id: categoryName
anchors.top: containerImage.bottom
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
width: activityBackground.width
height: activityBackground.height*0.2 - 6
fontSizeMode: Text.Fit
elide: Text.ElideRight
maximumLineCount: 2
wrapMode: Text.WordWrap
text: name
opacity: (items.mode == "expert") ? 0 : 1
}
ParticleSystemStarLoader {
id: particles
anchors.fill: activityBackground
}
MouseArea {
anchors.fill: activityBackground
enabled: menuScreen.started && items.mode !== "expert"
onClicked: selectCurrentItem()
}
function selectCurrentItem() {
particles.burst(50)
Activity.storeCategoriesLevels(index)
}
Image {
source: "qrc:/gcompris/src/activities/menu/resource/" +
( favorite ? "all.svg" : "all_disabled.svg" );
anchors {
top: parent.top
right: parent.right
rightMargin: 4 * ApplicationInfo.ratio
}
sourceSize.width: iconWidth * 0.25
visible: ApplicationSettings.sectionVisible
MouseArea {
anchors.fill: parent
onClicked: {
for(var i = 0; i < items.menuModel.count; i++) {
var category = items.menuModel.get(i)
var categoryIndex = category.index
if(index == categoryIndex)
menuModel.get(i)['favorite'] = !menuModel.get(i)['favorite']
}
}
}
}
} //delegate close
highlight: Rectangle {
width: levelCellWidth - menuGrid.spacing
height: levelCellHeight - menuGrid.spacing
color: "#AA41AAC4"
border.width: 3
border.color: "black"
visible: (items.mode == "expert") ? false : true
Behavior on x { SpringAnimation { spring: 2; damping: 0.2 } }
Behavior on y { SpringAnimation { spring: 2; damping: 0.2 } }
}
Rectangle {
id: menusMask
visible: false
anchors.fill: menuGrid
gradient: Gradient {
GradientStop { position: 0.0; color: "#FFFFFFFF" }
GradientStop { position: 0.92; color: "#FFFFFFFF" }
GradientStop { position: 0.96; color: "#00FFFFFF" }
}
}
layer.enabled: ApplicationInfo.useOpenGL
layer.effect: OpacityMask {
id: activitiesOpacity
source: menuGrid
maskSource: menusMask
anchors.fill: menuGrid
}
} // grid view close
}
diff --git a/src/activities/categorization/Zone.qml b/src/activities/categorization/Zone.qml
index 2f8d73dea..79dbe3fbd 100644
--- a/src/activities/categorization/Zone.qml
+++ b/src/activities/categorization/Zone.qml
@@ -1,119 +1,119 @@
/* GCompris - Zone.qml
*
* Copyright (C) 2016 Divyam Madaan <divyam3897@gmail.com>
*
* Authors:
* Divyam Madaan <divyam3897@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "categorization.js" as Activity
Flow {
id: zoneFlow
width: parent.width/3
height: parent.height
property alias repeater: repeater
property alias model: zoneModel
ListModel {
id: zoneModel
}
Repeater {
id: repeater
model: zoneModel
Item {
id: item
width: horizontalLayout ? middleZone.width * 0.32 : middleZone.width * 0.48
height: horizontalLayout ? categoryBackground.height * 0.2 : categoryBackground.height * 0.15
opacity: 1
Image {
id: image
fillMode: Image.PreserveAspectFit
sourceSize.width: horizontalLayout ? middleZone.width * 0.32 : middleZone.width * 0.48
width: sourceSize.width
height: sourceSize.width
source: name
MultiPointTouchArea {
id: dragArea
anchors.fill: parent
touchPoints: [ TouchPoint { id: point1 } ]
property real positionX
property real positionY
property real lastX
property real lastY
property bool isRight: isRight
property string currPosition: "middle"
property string imageSource: image.source.toString()
onPressed: {
items.instructionsVisible = false
positionX = point1.x
positionY = point1.y
var imagePos = image.mapToItem(null,0,0)
if(Activity.isDragInLeftArea(leftScreen.width, imagePos.x + parent.width)) {
currPosition = "left"
}
else if(Activity.isDragInRightArea(middleScreen.width + leftScreen.width,imagePos.x)) {
currPosition = "right"
}
else
currPosition = "middle"
}
onUpdated: {
var moveX = point1.x - positionX
var moveY = point1.y - positionY
parent.x = parent.x + moveX
parent.y = parent.y + moveY
var imagePos = image.mapToItem(null,0,0)
leftAreaContainsDrag = Activity.isDragInLeftArea(leftScreen.width, imagePos.x + parent.width)
rightAreaContainsDrag = Activity.isDragInRightArea(middleScreen.width + leftScreen.width,imagePos.x)
lastX = 0, lastY = 0
}
onReleased: {
var droppedPosition = "middle";
if(lastX == point1.x && lastY == point1.y)
return;
else if(leftAreaContainsDrag)
droppedPosition = "left"
else if(rightAreaContainsDrag)
droppedPosition = "right"
// If we drop on same zone, we move it at its initial place
if(currPosition == droppedPosition) {
image.x = 0
image.y = 0
}
else {
Activity.dropControl(currPosition, droppedPosition, imageSource, index)
image.source = ""
}
Activity.setValues()
lastX = point1.x
lastY = point1.y
}
}
}
}
}
}
diff --git a/src/activities/categorization/categorization.js b/src/activities/categorization/categorization.js
index 342b77af2..1d733e538 100644
--- a/src/activities/categorization/categorization.js
+++ b/src/activities/categorization/categorization.js
@@ -1,305 +1,305 @@
/* GCompris - categorization.js
*
* Copyright (C) 2016 Divyam Madaan <divyam3897@gmail.com>
*
* Authors:
* Divyam Madaan <divyam3897@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
.import GCompris 1.0 as GCompris
.import "qrc:/gcompris/src/core/core.js" as Core
var categoryModelIndex = 0;
var currentSubLevel = 0;
var items
var lessons
var categories
var images
var items
var currentLevel = 1
var numberOfLevel
var index
var imagesData = []
var categoriesData = []
var expertCategories = []
var boardsUrl
var answerTable = {}
var totalImages
var fileName = ":/gcompris/data/words/animals/camel.jpg"
function init(items_,boardsUrl_) {
boardsUrl = boardsUrl_
items = items_
items.menuModel.clear()
currentSubLevel = 0
}
function start() {
categoriesData = []
items.categoryReview.stop()
var isEmbeddedMode = items.file.exists(fileName) ? true : false
items.categoriesFallback = !isEmbeddedMode
var categoriesFilename;
var categoryDataset = items.categoryReview.categoryDataset
var categoryLists = items.categories
for(var i = 0; i < categoryLists.length; i++) {
categoriesFilename = "qrc" + boardsUrl + categoryLists[i]
categoryDataset.source = categoriesFilename
if(isEmbeddedMode || categoryDataset.item.isEmbedded) {
categoriesData.push(categoryDataset.item)
}
}
lessons = getAllLessons(categoriesData)
categories = getCategoryModel(categoriesData)
addPropertiesToCategories(categories)
items.menuModel.append(categories)
savedPropertiesToCategories(items.dialogActivityConfig.dataToSave)
sortByFavorites()
items.menuScreen.start()
}
// Inserts specific properties to the categories
function addPropertiesToCategories(categories) {
for (var i = 0; i < categories.length; i++) {
categories[i]['name'] = categories[i].name
categories[i]['image'] = categories[i].image
categories[i]['favorite'] = false
categories[i]['categoryIndex'] = i
}
}
// Return all the properties we have to save
function categoriesToSavedProperties() {
var props = {}
for(var i = 0; i < items.menuModel.count; i++) {
var category = items.menuModel.get(i)
props[category.name] = {
'favorite': category['favorite']
}
}
return props
}
// Update the categories based on a previous saving
function savedPropertiesToCategories(dataToSave) {
var props = dataToSave["data"]
for(var i = 0; i < items.menuModel.count; i++) {
var category = items.menuModel.get(i)
var categoryname = category.name
if(props && props[category.name]) {
category['favorite'] = props[category.name].favorite
}
else {
category['favorite'] = false
}
}
}
function sortByFavorites() {
for(var i = 0; i < items.menuModel.count; i++) {
if(items.menuModel.get(i)['favorite']) {
items.menuModel.move(i, 0, 1);
}
}
}
function launchMenuScreen() {
items.categoryReview.stop()
items.menuScreen.start()
}
function startCategory() {
items.categoryReview.start()
items.menuScreen.stop()
currentLevel = 0
items.bar.level = 0
initLevel()
}
function storeCategoriesLevels(index_) {
index = index_
currentLevel = 0
numberOfLevel = 0
initLevel()
}
function initLevel() {
items.bar.level = currentLevel + 1
items.categoryReview.score.currentSubLevel = 0
items.instructionsVisible = true
getCategoryLevels(index);
numberOfLevel = items.details.length;
items.categoryReview.leftZone.clear();
items.categoryReview.rightZone.clear();
items.categoryReview.start();
items.menuScreen.stop()
}
function nextLevel() {
if(numberOfLevel <= ++currentLevel) {
currentLevel = 0
}
items.categoryReview.score.currentSubLevel = 0
initLevel(index);
getCategoryLevels();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
initLevel(index);
getCategoryLevels();
}
// Checks if all the items are dragged and dropped in the correct or incorrect area.
function allPlaced() {
items.categoryReview.score.currentSubLevel = 0;
for(var i = 0 ; i < items.categoryReview.leftZone.count; ++i) {
for(var answer in answerTable) {
var droppedZoneItem = items.categoryReview.leftZone.get(i)
if(answer === droppedZoneItem.name &&
((droppedZoneItem.droppedZone === "right" && answerTable[answer])
|| (droppedZoneItem.droppedZone === "left" && !answerTable[answer])))
items.categoryReview.score.currentSubLevel ++
}
}
for(var i = 0 ; i < items.categoryReview.rightZone.count; ++i) {
for(var answer in answerTable) {
var droppedZoneItem = items.categoryReview.rightZone.get(i)
if(answer === droppedZoneItem.name &&
((droppedZoneItem.droppedZone === "right" && answerTable[answer])
|| (droppedZoneItem.droppedZone === "left" && !answerTable[answer])))
items.categoryReview.score.currentSubLevel ++
}
}
- if(items.categoryReview.score.currentSubLevel == totalImages)
+ if(items.categoryReview.score.currentSubLevel === totalImages)
items.bonus.good("flower")
else
items.bonus.bad("flower")
}
// Save properties to lessons
function getCategoryLevels() {
var randomGood = 0;
var randomBad = 0;
items.categoryReview.middleZone.clear()
/* If easy or medium mode is selected, store the details of levels of category of that respective index in items.details. */
if(items.mode !== "expert") {
items.details = lessons[index].map(function(ele) {
return { "instructions": ele.instructions, "image": ele.image,
"numberOfGood": ele.maxNumberOfGood, "numberofBad": ele.maxNumberOfBad,
"categoryImages": ele.levelImages ,"good": ele.good,
"bad": ele.bad ,"prefix": ele.prefix }
});
}
// If expert mode is selected, select a random level (selectedLevel) from a random category (selectedCategory)
else if(items.mode === "expert") {
var selectedCategory = Math.floor(Math.random() * expertCategories.length)
var selectedLevel = []
selectedLevel[0] = expertCategories[selectedCategory][Math.floor(Math.random() * expertCategories[selectedCategory].length)]
items.details = selectedLevel.map(function(ele) {
return { "instructions": ele.instructions, "image": ele.image,
"numberOfGood": ele.maxNumberOfGood, "numberofBad": ele.maxNumberOfBad,
"categoryImages": ele.levelImages ,"good": ele.good,
"bad": ele.bad, "prefix": ele.prefix }
});
}
var imagesPrefix = items.details[items.bar.level - 1].prefix
// Good set of images
var goodImages = items.details[items.bar.level - 1].good
var numberOfGood = Math.min(goodImages.length,items.details[items.bar.level-1].numberOfGood);
var goodZoneImages = goodImages.map(function(obj) {
obj = imagesPrefix + obj
return { "name": obj, "isRight": true }
});
goodZoneImages = goodZoneImages.splice(0, numberOfGood);
// Bad set of images
var badImages = items.details[items.bar.level - 1].bad
var badZoneImages = badImages.map(function(obj) {
obj = imagesPrefix + obj
return { "name": obj, "isRight": false }
});
var numberOfBad = Math.min(badImages.length,items.details[items.bar.level-1].numberofBad);
badZoneImages = badZoneImages.splice(0, numberOfBad);
// Concat both set of images(good and bad) in allImages and store in middleZone model
var allImages = goodZoneImages.concat(badZoneImages);
Core.shuffle(allImages);
for(var i = 0; i < allImages.length; i++) {
answerTable[allImages[i].name] = allImages[i].isRight
items.categoryReview.middleZone.append({"isRight": allImages[i].isRight,"name": allImages[i].name})
}
totalImages = allImages.length
items.categoryReview.score.numberOfSubLevels = totalImages
}
// get categories details from the complete dataset
function getCategoryModel(dataset) {
var categories = []
for (var c = 0; c < dataset.length; c++) {
categories.push({
'name': dataset[c].levels[0].name,
'image': dataset[c].levels[0].image,
'index': c
})
}
return categories
}
// get all the content (levels) from the category in dataset
function getAllLessons(dataset) {
var lessons = []
for(var c = 0; c < dataset.length; c++) {
lessons.push(dataset[c].levels[0].content)
if(dataset[c].allowExpertMode) {
expertCategories.push(dataset[c].levels[0].content)
}
}
return lessons
}
function setValues() {
items.categoryReview.leftAreaContainsDrag = false
items.categoryReview.rightAreaContainsDrag = false
}
function isDragInLeftArea(leftAreaRightBorderPos, elementRightPos) {
if(elementRightPos <= leftAreaRightBorderPos)
return true;
else
return false;
}
function isDragInRightArea(rightAreaLeftBorderPos, elementLeftPos) {
if((rightAreaLeftBorderPos <= elementLeftPos))
return true;
else
return false;
}
function dropControl(sourcePosition, destinationPosition, image, index) {
- var destinationZone = destinationPosition == "left" ? items.categoryReview.leftZone : destinationPosition == "right" ? items.categoryReview.rightZone : items.categoryReview.middleZone
- var sourceZone = sourcePosition == "left" ? items.categoryReview.leftZone : sourcePosition == "right" ? items.categoryReview.rightZone : items.categoryReview.middleZone
+ var destinationZone = destinationPosition === "left" ? items.categoryReview.leftZone : destinationPosition === "right" ? items.categoryReview.rightZone : items.categoryReview.middleZone
+ var sourceZone = sourcePosition === "left" ? items.categoryReview.leftZone : sourcePosition === "right" ? items.categoryReview.rightZone : items.categoryReview.middleZone
destinationZone.append({"name": image, "droppedZone": destinationPosition})
sourceZone.remove(index)
}
diff --git a/src/activities/categorization/resource/board/category_alphabets.qml b/src/activities/categorization/resource/board/category_alphabets.qml
index cc2297832..308af7b4f 100644
--- a/src/activities/categorization/resource/board/category_alphabets.qml
+++ b/src/activities/categorization/resource/board/category_alphabets.qml
@@ -1,89 +1,89 @@
/* GCompris
*
* Copyright (C) 2016 Divyam Madaan <divyam3897@gmail.com>
*
* Authors:
* Divyam Madaan <divyam3897@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property bool isEmbedded: true
property bool allowExpertMode: true
property string imagesPrefix: "qrc:/gcompris/src/activities/categorization/resource/images/alphabets/"
property var levels: [
{
"name": qsTr("Alphabets"),
"image": imagesPrefix + "alphabets.jpg",
"content": [
{
"instructions": qsTr("Place the LETTERS to the right and other objects to the left"),
"image": imagesPrefix + "upperA.svg",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/src/activities/",
"good": ["categorization/resource/images/alphabets/upperA.svg","categorization/resource/images/alphabets/lowerP.svg","categorization/resource/images/alphabets/upperR.svg", "categorization/resource/images/alphabets/lowerT.svg","categorization/resource/images/alphabets/lowerD.svg", "categorization/resource/images/alphabets/lowerE.svg"],
"bad": ["categorization/resource/images/numbers/01.svg","categorization/resource/images/numbers/06.svg","categorization/resource/images/numbers/12.svg","lang/resource/words_sample/coconut.png", "lang/resource/words_sample/dolphin.png","lang/resource/words_sample/kiwi.png"]
},
{
"instructions": qsTr("Place the LETTERS to the right and other objects to the left"),
"image": imagesPrefix + "upperA.svg",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/src/activities/",
"good": ["categorization/resource/images/alphabets/lowerB.svg","categorization/resource/images/alphabets/upperV.svg","categorization/resource/images/alphabets/lowerE.svg","categorization/resource/images/alphabets/lowerN.svg","categorization/resource/images/alphabets/upperM.svg", "categorization/resource/images/alphabets/upperO.svg"],
"bad": ["categorization/resource/images/numbers/06.svg","categorization/resource/images/numbers/16.svg","lang/resource/words_sample/mouse.png","lang/resource/words_sample/orange.png","lang/resource/words_sample/raspberry.png","lang/resource/words_sample/tongue.png"]
},
{
"instructions": qsTr("Place the LETTERS to the right and other objects to the left"),
"image": imagesPrefix + "upperA.svg",
"maxNumberOfGood": 5,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/src/activities/",
"good": [ "categorization/resource/images/alphabets/upperF.svg","categorization/resource/images/alphabets/lowerK.svg","categorization/resource/images/alphabets/lowerR.svg","categorization/resource/images/alphabets/upperQ.svg","categorization/resource/images/alphabets/lowerB.svg"],
bad: ["categorization/resource/images/numbers/07.svg","categorization/resource/images/numbers/00.svg","lang/resource/words_sample/turtle.png","lang/resource/words_sample/melon.png"]
},
{
"instructions": qsTr("Place the LETTERS to the right and other objects to the left"),
"image": imagesPrefix + "upperA.svg",
"maxNumberOfGood": 4,
"maxNumberOfBad": 5,
"prefix": "qrc:/gcompris/src/activities/",
"good": ["categorization/resource/images/alphabets/lowerH.svg","categorization/resource/images/alphabets/upperL.svg","categorization/resource/images/alphabets/upperN.svg","categorization/resource/images/alphabets/upperS.svg"],
"bad": ["lang/resource/words_sample/pear.png","lang/resource/words_sample/butterfly.png","categorization/resource/images/numbers/08.svg", "categorization/resource/images/numbers/11.svg","categorization/resource/images/numbers/01.svg"]
},
{
"instructions": qsTr("Place the LETTERS to the right and other objects to the left"),
"image": imagesPrefix + "upperA.svg",
"maxNumberOfGood": 3,
"maxNumberOfBad": 3,
"prefix": "qrc:/gcompris/src/activities/",
"good": ["categorization/resource/images/alphabets/lowerG.svg","categorization/resource/images/alphabets/lowerT.svg","categorization/resource/images/alphabets/lowerK.svg"],
"bad": ["categorization/resource/images/numbers/08.svg","categorization/resource/images/numbers/10.svg", "lang/resource/words_sample/dog.png"]
},
{
"instructions": qsTr("Place the LETTERS to the right and other objects to the left"),
"image": imagesPrefix + "upperA.svg",
"maxNumberOfGood": 2,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/src/activities/",
"good": ["categorization/resource/images/alphabets/upperD.svg","categorization/resource/images/alphabets/upperJ.svg"],
"bad": ["lang/resource/words_sample/green.png","lang/resource/words_sample/plum.png","categorization/resource/images/numbers/09.svg","lang/resource/words_sample/cat.png"]
}
]
}
]
}
diff --git a/src/activities/categorization/resource/board/category_animals.qml b/src/activities/categorization/resource/board/category_animals.qml
index de621a615..293a63a0e 100644
--- a/src/activities/categorization/resource/board/category_animals.qml
+++ b/src/activities/categorization/resource/board/category_animals.qml
@@ -1,117 +1,117 @@
/* GCompris
*
* Copyright (C) 2016 Divyam Madaan <divyam3897@gmail.com>
*
* Authors:
* Divyam Madaan <divyam3897@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject{
property bool isEmbedded: false
property bool allowExpertMode: true
property string imagesPrefix: "qrc:/gcompris/data/words/animals/"
property var levels:[
{
"type": "lesson",
"name": qsTr("Animals"),
"image": imagesPrefix + "animalsherd.jpg",
"content": [
{
"instructions": qsTr("Place the ANIMALS to the right and other objects to the left"),
"image": imagesPrefix + "tiger.jpg",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/data/words/",
"good": ["animals/baboon.jpg","animals/bosmutus.jpg","animals/camel.jpg","animals/cow.jpg","animals/dog.jpg","birds/bird10.jpg"],
"bad": ["nature/nature5.jpg","householdGoods/chair.jpg","food/biryani.jpg","others/electricfan.jpg","others/clock.jpg","nature/nature10.jpg"]
},
{
"instructions": qsTr("Place the ANIMALS to the right and other objects to the left"),
"image": imagesPrefix + "tiger.jpg",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/data/words/",
"good": ["animals/lion.jpg","birds/bird7.jpg","birds/bird8.jpg","animals/mouse1.jpg","animals/opossum.jpg","animals/pig.jpg"],
"bad": ["nature/nature3.jpg","food/milk.jpg","food/butter.jpg","fruits/apple.jpg","transport/rickshaw.jpg","transport/bus.jpg"]
},
{
"instructions": qsTr("Place the ANIMALS to the right and other objects to the left"),
"image": imagesPrefix + "opossum.jpg",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/data/words/",
"good": ["animals/snowcat.jpg","animals/spidermonkey.jpg","animals/squirrel.jpg","animals/squirrel1.jpg","animals/tasmaniandevil.jpg","birds/bird22.jpg"],
"bad": ["transport/helicopter.jpg","nature/nature2.jpg","others/house.jpg","transport/plane2.jpg","plants/plant4.jpg","nature/nature5.jpg"]
},
{
"instructions": qsTr("Place the ANIMALS to the right and other objects to the left"),
"image": imagesPrefix + "tortoise.jpg",
"maxNumberOfGood": 5,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/data/words/",
"good": ["animals/redeyedfrog.jpg","animals/scorpian.jpg","animals/sealion.jpg","animals/sheep.jpg","animals/snake.jpg"],
"bad": ["fruits/grapes.jpg","others/broom1.jpg","transport/car1.jpg","food/icecream.jpg"]
},
{
"instructions": qsTr("Place the ANIMALS to the right and other objects to the left"),
"image": imagesPrefix + "koala.jpg",
"maxNumberOfGood": 5,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/data/words/",
"good": ["animals/donkey.jpg","animals/elephant.jpg","insects/insect20.jpg","animals/tiger.jpg","animals/zebra.jpg"],
"bad": ["vegetables/pumpkin.jpg","vegetables/carrots.jpg","transport/cycle.jpg","plants/tree3.jpg"]
},
{
"instructions": qsTr("Place the ANIMALS to the right and other objects to the left"),
"image": imagesPrefix + "hedgehog.jpg",
"maxNumberOfGood": 4,
"maxNumberOfBad": 5,
"prefix": "qrc:/gcompris/data/words/",
"good": ["animals/giraffe.jpg","birds/bird25.jpg","animals/hedgehog.jpg","insects/insect7.jpg"],
"bad": ["vegetables/potato.jpg","transport/balloon.jpg","food/cheese.jpg","others/mobile.jpg","transport/bus1.jpg"]
},
{
"instructions": qsTr("Place the ANIMALS to the right and other objects to the left"),
"image": imagesPrefix + "lion.jpg",
"maxNumberOfGood": 3 ,
"maxNumberOfBad": 3,
"prefix": "qrc:/gcompris/data/words/",
"good": ["animals/koala.jpg","animals/kodiak-bear.jpg","birds/bird27.jpg"],
"bad": ["nature/nature6.jpg","transport/ferry.jpg","food/eggs.jpg","food/hamburger.jpg"]
},
{
"instructions": qsTr("Place the ANIMALS to the right and other objects to the left"),
"image": imagesPrefix + "pig.jpg",
"maxNumberOfGood": 3,
"maxNumberOfBad": 3,
"prefix": "qrc:/gcompris/data/words/",
"good": ["animals/tiger.jpg","animals/tortoise.jpg","animals/tortoise1.jpg"],
"bad": ["transport/car1.jpg","fruits/papaya.jpg","food/hotdog.jpg"]
},
{
"instructions": qsTr("Place the ANIMALS to the right and other objects to the left"),
"image": imagesPrefix + "snowcat.jpg",
"maxNumberOfGood": 3,
"maxNumberOfBad": 3,
"prefix": "qrc:/gcompris/data/words/",
"good": ["animals/porcupine.jpg","animals/cow.jpg","birds/bird29.jpg"],
"bad": ["nature/nature8.jpg","food/macroni.jpg","others/house.jpg"]
}
]
}
]
}
diff --git a/src/activities/categorization/resource/board/category_birds.qml b/src/activities/categorization/resource/board/category_birds.qml
index 283e58cf0..f51dd7f42 100644
--- a/src/activities/categorization/resource/board/category_birds.qml
+++ b/src/activities/categorization/resource/board/category_birds.qml
@@ -1,117 +1,117 @@
/* GCompris
*
* Copyright (C) 2016 Divyam Madaan <divyam3897@gmail.com>
*
* Authors:
* Divyam Madaan <divyam3897@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject{
property bool isEmbedded: false
property bool allowExpertMode: true
property string imagesPrefix: "qrc:/gcompris/data/words/birds/"
property var levels: [
{
"type": "lesson",
"name": qsTr("Birds"),
"image": imagesPrefix + "bird.jpg",
"content": [
{
"instructions": qsTr("Place the BIRDS to the right and other objects to the left"),
"image": imagesPrefix + "bird.png",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/data/words/",
"good": ["birds/parrot.jpg","birds/bird34.jpg","birds/bird23.jpg","birds/peacock.jpg","birds/rooster.jpg","birds/bird1.jpg"],
"bad": ["animals/baboon.jpg","animals/bosmutus.jpg","animals/camel.jpg","animals/cow.jpg","others/sharpnerandpencil.jpg","transport/cycle.jpg"]
},
{
"instructions": qsTr("Place the BIRDS to the right and other objects to the left"),
"image": imagesPrefix + "bird.png",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/data/words/",
"good": ["birds/bird2.jpg","birds/bird3.jpg","birds/bird4.jpg","birds/bird5.jpg","birds/bird6.jpg","birds/bird7.jpg"],
"bad": ["animals/dog.jpg","animals/dolphin.jpg","animals/donkey.jpg","animals/elephant.jpg","others/mobile.jpg","transport/helicopter1.jpg"]
},
{
"instructions": qsTr("Place the BIRDS to the right and other objects to the left"),
"image": imagesPrefix + "bird.png",
"maxNumberOfGood": 5,
"maxNumberOfBad": 7,
"prefix": "qrc:/gcompris/data/words/",
"good": ["birds/bird8.jpg","birds/bird9.jpg","birds/bird10.jpg","birds/bird11.jpg","birds/bird12.jpg"],
"bad": ["plants/tree1.jpg","transport/train2.jpg","animals/giraffe.jpg","vegetables/spinaches.jpg","fruits/kiwi.jpg","insects/insect12.jpg","food/cereal.jpg"]
},
{
"instructions": qsTr("Place the BIRDS to the right and other objects to the left"),
"image": imagesPrefix + "bird.png",
"maxNumberOfGood": 5,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/data/words/",
"good": ["birds/bird13.jpg","birds/bird14.jpg","birds/bird15.jpg","birds/bird16.jpg","birds/bird17.jpg"],
"bad": ["animals/hare.jpg","animals/hedgehog.jpg","food/cheese.jpg","food/pizza.jpg"]
},
{
"instructions": qsTr("Place the BIRDS to the right and other objects to the left"),
"image": imagesPrefix + "bird.png",
"maxNumberOfGood": 5,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/data/words/",
"good": ["birds/bird18.jpg","birds/bird19.jpg","birds/bird20.jpg","birds/bird21.jpg","birds/bird22.jpg"],
"bad": ["animals/horse.jpg","animals/koala.jpg","food/milk.jpg","insects/insect5.jpg"]
},
{
"instructions": qsTr("Place the BIRDS to the right and other objects to the left"),
"image": imagesPrefix + "bird.png",
"maxNumberOfGood": 4,
"maxNumberOfBad": 5,
"prefix": "qrc:/gcompris/data/words/",
"good": ["birds/bird23.jpg","birds/bird24.jpg","birds/bird25.jpg","birds/bird26.jpg"],
"bad": ["animals/marsupialis.jpg","animals/mouse.jpg","others/pepsi.jpg","insects/insect16.jpg","food/milk.jpg"]
},
{
"instructions": qsTr("Place the BIRDS to the right and other objects to the left"),
"image": imagesPrefix + "bird.png",
"maxNumberOfGood": 3,
"maxNumberOfBad": 3,
"prefix": "qrc:/gcompris/data/words/",
"good": ["birds/bird27.jpg","birds/bird28.jpg","birds/bird29.jpg"],
"bad": ["animals/kodiak-bear.jpg","animals/krotiki.jpg","others/clock.jpg"]
},
{
"instructions": qsTr("Place the BIRDS to the right and other objects to the left"),
"image": imagesPrefix + "bird.png",
"maxNumberOfGood": 3,
"maxNumberOfBad": 3,
"prefix": "qrc:/gcompris/data/words/",
"good": ["birds/bird30.jpg","birds/bird31.jpg","birds/bird32.jpg"],
"bad": ["animals/mouse1.jpg","animals/pig.jpg","nature/nature5.jpg"]
},
{
"instructions": qsTr("Place the BIRDS to the right and other objects to the left"),
"image": imagesPrefix + "bird.png",
"maxNumberOfGood": 2,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/data/words/",
"good": ["birds/bird33.jpg","birds/bird34.jpg"],
"bad": ["animals/lion.jpg","plants/tree3.jpg","transport/balloon.jpg","householdGoods/refrigerator.jpg"]
}
]
}
]
}
diff --git a/src/activities/categorization/resource/board/category_colors.qml b/src/activities/categorization/resource/board/category_colors.qml
index b784aa055..2a95b196d 100644
--- a/src/activities/categorization/resource/board/category_colors.qml
+++ b/src/activities/categorization/resource/board/category_colors.qml
@@ -1,120 +1,120 @@
/* GCompris
*
* Copyright (C) 2016 Divyam Madaan <divyam3897@gmail.com>
*
* Authors:
* Divyam Madaan <divyam3897@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject{
property bool isEmbedded: false
property bool allowExpertMode: true
property string imagesPrefix: "qrc:/gcompris/data/words/"
property var levels: [
{
"type": "lesson",
"name": qsTr("Colors"),
"image": imagesPrefix + "others/color2.png",
"content": [
{
"instructions": "Place the objects matching GREEN color to right and others to the left",
"image": imagesPrefix + "green.png",
"maxNumberOfGood": 5,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/data/words/",
"good": ["artichoke.png","cabbage.png","cucumber.png","cactus.png","clover.png"],
"bad": ["left.png","lobster.png","mail.png","post.png"]
},
{
"instructions": "Place the objects matching WHITE color to right and others to the left",
"image": imagesPrefix + "white.png",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/data/words/",
"good": ["milk.png","paper.png","dove.png","mail.png","egg.png", "bead.png"],
"bad": ["flash.png","plum.png","potato.png","pumpkin.png","rabbit.png","kiwi.png"]
},
{
"instructions": "Place the objects matching PINK color to right and others to the left",
"image": imagesPrefix + "pink.png",
"maxNumberOfGood": 5,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/data/words/",
"good": ["hair_dryer.png","flamingo.png","raspberry.png","pencil.png","flash.png"],
"bad": ["ink.png","kiwi.png","ladybug.png","phone.png"]
},
{
"tags": ["red"],
"instructions": "Place the objects matching RED color to right and others to the left",
"image": imagesPrefix + "red.png",
"maxNumberOfGood": 5,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/data/words/",
"good": ["shapes/dice.svg","lobster.png","pair.png","ladybug.png","post.png"],
"bad": ["shapes/halforange.svg","radio.png","ramp.png","wheat.png"]
},
{
"instructions": "Place the objects matching BROWN color to right and others to the left",
"image": imagesPrefix + "brown.png",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/data/words/",
"good": ["shapes/cookie.svg","date_fruit.png","chocolate.png","board.png","potato.png","kiwi.png"],
"bad": ["cheese.png","bright.png","shapes/conehat.svg","dolphin.png","shapes/cd.svg","drip.png"]
},
{
"instructions": "Place the objects matching PURPLE color to right and others to the left",
"categorise": "PURPLE",
"image": imagesPrefix + "others/purple.png",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/data/words/",
"good": ["grape.png","eggplant.png","shapes/conehat.svg","phone.png","plum.png","ink.png"],
"bad": ["bulb.png","bell.png","blackbird.png","umbrella.png","pumpkin.png","shapes/halfmoon.svg"]
},
{
"instructions": "Place the objects matching GREY color to right and others to the left",
"image": imagesPrefix + "gray.png",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/data/words/",
"good": ["chain.png","rabbit.png","ramp.png","dolphin.png","faucet.png","shapes/halfmoon.svg"],
"bad": ["shapes/backcard.svg","radio.png","clover.png","left.png","flash.png","ink.png"]
},
{
"instructions": "Place the objects matching ORANGE color to right and others to the left",
"image": imagesPrefix + "orange-color.png",
"maxNumberOfGood": 3,
"maxNumberOfBad": 3,
"prefix": "qrc:/gcompris/data/words/",
"good": ["pumpkin.png","shapes/halforange.svg","orange.png"],
"bad": ["plum.png","potato.png","post.png"]
},
{
"instructions": "Place the objects matching YELLOW color to right and others to the left",
"categorise":"YELLOW",
"image": imagesPrefix + "yellow.png",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/data/words/",
"good": ["anchor.png","cheese.png","bright.png","shapes/rectangle_led.svg","bulb.png","bell.png"],
"bad": ["blackbird.png","pair.png","plum.png","potato.png","drip.png","ladybug.png"]
}
]
}
]
}
diff --git a/src/activities/categorization/resource/board/category_fishes.qml b/src/activities/categorization/resource/board/category_fishes.qml
index 56a9315ca..72240a7d1 100644
--- a/src/activities/categorization/resource/board/category_fishes.qml
+++ b/src/activities/categorization/resource/board/category_fishes.qml
@@ -1,91 +1,91 @@
/* GCompris
*
* Copyright (C) 2016 Divyam Madaan <divyam3897@gmail.com>
*
* Authors:
* Divyam Madaan <divyam3897@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property bool isEmbedded: true
property bool allowExpertMode: true
property string imagesPrefix: "qrc:/gcompris/src/activities/categorization/resource/images/fishes/"
property var levels: [
{
"type": "lesson",
- "name": qsTr("fishes"),
+ "name": qsTr("Fishes"),
"image": imagesPrefix + "fish20.jpg",
"content": [
{
"instructions": qsTr("Place the FISHES to the right and other objects to the left"),
"image": imagesPrefix + "fish10.jpg",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/src/activities/categorization/resource/images/",
"good": ["fishes/fish1.jpg","fishes/fish2.png","fishes/fish3.jpg","fishes/fish4.jpg","fishes/fish5.jpg","fishes/fish6.jpg"],
"bad": ["monuments/beandenburgGate.jpg","monuments/burj.jpg","others/bulb.jpg","tools/cutingTool.jpg","others/knife.jpg","tools/multimeter.jpg"]
},
{
"instructions": qsTr("Place the FISHES to the right and other objects to the left"),
"image": imagesPrefix + "fish13.jpg",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/src/activities/categorization/resource/images/",
"good": ["fishes/fish7.jpg","fishes/fish8.jpg","fishes/fish9.jpg","fishes/fish10.jpg","fishes/fish11.jpg","fishes/fish12.jpg"],
"bad": ["renewable/dam2.jpg","renewable/solar5.jpg","others/pillow.jpg","tools/plier2.jpg","tools/nailCutter.jpg","monuments/colosseum.jpg"]
},
{
"instructions": qsTr("Place the FISHES to the right and other objects to the left"),
"image": imagesPrefix + "fish3.jpg",
"maxNumberOfGood": 5,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/src/activities/categorization/resource/images/",
"good": ["fishes/fish13.jpg","fishes/fish14.jpg","fishes/fish15.jpg","fishes/fish16.jpg","fishes/fish17.jpg"],
"bad": ["others/bulb.jpg","others/chair.jpg","renewable/windmill.jpg","monuments/monument2.jpg"]
},
{
"instructions": qsTr("Place the FISHES to the right and other objects to the left"),
"image": imagesPrefix + "fish16.jpg",
"maxNumberOfGood": 5,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/src/activities/categorization/resource/images/",
"good": ["fishes/fish18.jpg","fishes/fish19.jpg","fishes/fish20.jpg","fishes/fish21.jpg",
"fishes/fish22.jpg"],
"bad": ["others/plate.jpg","monuments/operaHouse.jpg","monuments/zimniPalace.jpg","renewable/geothermal.jpg"]
},
{
"instructions": qsTr("Place the FISHES to the right and other objects to the left"),
"image": imagesPrefix + "fish20.jpg",
"maxNumberOfGood": 3,
"maxNumberOfBad": 3,
"prefix": "qrc:/gcompris/src/activities/categorization/resource/images/",
"good": ["fishes/fish23.jpg","fishes/fish24.jpg", "fishes/fish25.jpg"],
"bad": ["monuments/monument3.jpg","others/pan.jpg","others/pencil.jpg"]
},
{
"instructions": qsTr("Place the FISHES to the right and other objects to the left"),
"image": imagesPrefix + "fish25.jpg",
"maxNumberOfGood": 3,
"maxNumberOfBad": 3,
"prefix": "qrc:/gcompris/src/activities/categorization/resource/images/",
"good": ["fishes/fish26.jpg","fishes/fish27.jpg","fishes/fish28.jpg"],
"bad": ["renewable/windmill13.jpg","renewable/geothermal.jpg","tools/scissors.jpg"]
}
]
}
]
}
diff --git a/src/activities/categorization/resource/board/category_flowers.qml b/src/activities/categorization/resource/board/category_flowers.qml
index afb6e8f0c..8193824e6 100644
--- a/src/activities/categorization/resource/board/category_flowers.qml
+++ b/src/activities/categorization/resource/board/category_flowers.qml
@@ -1,116 +1,116 @@
/* GCompris
*
* Copyright (C) 2018 Aman Kumar Gupta <gupta2140@gmail.com>
*
* Authors:
* Aman Kumar Gupta <gupta2140@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property bool isEmbedded: false
property bool allowExpertMode: true
property string imagesPrefix: "qrc:/gcompris/data/words/flowers/"
property var levels: [
{
"name": qsTr("Flowers"),
"image": imagesPrefix + "bunchOfFlowers.jpg",
"content": [
{
"instructions": qsTr("Place the FLOWERS to the right and other objects to the left"),
"image": imagesPrefix + "bunchOfFlowers.jpg",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/data/words/",
"good": ["flowers/allamanda.jpg", "flowers/angiosperms.jpg", "flowers/angiosperms2.jpg", "flowers/aster.jpg", "flowers/aster2.jpg", "flowers/bauhiniaAcuminata.jpg"],
"bad": ["plants/plant2.jpg", "birds/bird1.jpg", "insects/insect10.jpg", "transport/cycle.jpg", "animals/camel.jpg", "householdGoods/iron2.jpg"]
},
{
"instructions": qsTr("Place the FLOWERS to the right and other objects to the left"),
"image": imagesPrefix + "bunchOfFlowers.jpg",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/data/words/",
"good": ["flowers/bossier.jpg", "flowers/bunchOfFlowers.jpg", "flowers/calendulaSuffruticosa.jpg", "flowers/camellia.jpg", "flowers/capullo.jpg", "flowers/crocus.jpg"],
"bad": ["nature/nature5.jpg", "food/biryani.jpg", "food/milk.jpg", "fruits/apple.jpg", "others/house.jpg", "vegetables/carrots.jpg"]
},
{
"instructions": qsTr("Place the FLOWERS to the right and other objects to the left"),
"image": imagesPrefix + "bunchOfFlowers.jpg",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/data/words/",
"good": ["flowers/dahlia.jpg", "flowers/daisy.jpg", "flowers/floora.jpg", "flowers/floreInsectos.jpg", "flowers/galanthusNivalis.jpg", "flowers/hibiscus.jpg"],
"bad": ["animals/cow.jpg", "transport/helicopter1.jpg", "food/cereal.jpg", "animals/elephant.jpg", "others/pepsi.jpg", "plants/tree3.jpg"]
},
{
"instructions": qsTr("Place the FLOWERS to the right and other objects to the left"),
"image": imagesPrefix + "bunchOfFlowers.jpg",
"maxNumberOfGood": 5,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/data/words/",
"good": ["flowers/lily.jpg", "flowers/marigold.jpg", "flowers/orchid.jpg", "flowers/pollen.jpg", "flowers/rose.jpg"],
"bad": ["lobster.png", "potato.png", "pumpkin.png", "radio.png"]
},
{
"instructions": qsTr("Place the FLOWERS to the right and other objects to the left"),
"image": imagesPrefix + "bunchOfFlowers.jpg",
"maxNumberOfGood": 4,
"maxNumberOfBad": 5,
"prefix": "qrc:/gcompris/data/words/",
"good": ["flowers/sunflower.jpg", "flowers/tulip.jpg", "flowers/victoriaAmazonica.jpg", "flowers/wildPetunia.jpg"],
"bad": ["food/hotdog.jpg", "vegetables/onion.jpg", "food/cheese.jpg", "food/water.jpg", "others/street.jpg"]
},
{
"instructions": qsTr("Place the FLOWERS to the right and other objects to the left"),
"image": imagesPrefix + "bunchOfFlowers.jpg",
"maxNumberOfGood": 5,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/data/words/",
"good": ["flowers/lily.jpg", "flowers/marigold.jpg", "flowers/orchid.jpg", "flowers/pollen.jpg", "flowers/rose.jpg"],
"bad": ["food/eggs.jpg", "animals/lion.jpg", "birds/bird17.jpg", "householdGoods/iron.jpg"]
},
{
"instructions": qsTr("Place the FLOWERS to the right and other objects to the left"),
"image": imagesPrefix + "bunchOfFlowers.jpg",
"maxNumberOfGood": 3,
"maxNumberOfBad": 3,
"prefix": "qrc:/gcompris/data/words/",
"good": ["flowers/lotus.jpg", "flowers/jasmine.jpg", "flowers/rhododendron.jpg"],
"bad": ["food/grilledSandwich.jpg", "transport/metro.jpg", "food/frenchFries.jpg"]
},
{
"instructions": qsTr("Place the FLOWERS to the right and other objects to the left"),
"image": imagesPrefix + "bunchOfFlowers.jpg",
"maxNumberOfGood": 2,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/data/words/",
"good": ["flowers/ashoka.jpg", "flowers/acidanthera.jpg"],
"bad": ["others/fork.jpg", "fruits/apple.jpg", "food/skimmedMilk.jpg", "fruits/grapes.jpg"]
},
{
"instructions": qsTr("Place the FLOWERS to the right and other objects to the left"),
"image": imagesPrefix + "bunchOfFlowers.jpg",
"maxNumberOfGood": 4,
"maxNumberOfBad": 2,
"prefix": "qrc:/gcompris/data/words/",
"good": ["flowers/allamanda.jpg", "flowers/camellia.jpg", "flowers/jasmine.jpg", "flowers/marigold.jpg"],
"bad": ["plants/plant6.jpg", "fruits/papaya.jpg"]
}
]
}
]
}
diff --git a/src/activities/categorization/resource/board/category_food.qml b/src/activities/categorization/resource/board/category_food.qml
index c2384e92f..98959b93a 100644
--- a/src/activities/categorization/resource/board/category_food.qml
+++ b/src/activities/categorization/resource/board/category_food.qml
@@ -1,90 +1,90 @@
/* GCompris
*
* Copyright (C) 2016 Divyam Madaan <divyam3897@gmail.com>
*
* Authors:
* Divyam Madaan <divyam3897@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject{
property bool isEmbedded: false
property bool allowExpertMode: true
property string imagesPrefix: "qrc:/gcompris/data/words/food/"
property var levels: [
{
"type": "lesson",
"name": qsTr("Food"),
"image": imagesPrefix + "pizza.jpg",
"content": [
{
"instructions": qsTr("Place the FOOD ITEMS to the right and other objects to the left"),
"image": imagesPrefix + "sweetBread.jpg",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/data/words/",
"good": ["food/applepie.jpg","food/bananaNutBread.jpg","food/biryani.jpg","food/cereal.jpg","food/cheese.jpg","food/eggs.jpg"],
"bad": ["nature/nature28.jpg","plants/plant2.jpg","nature/nature27.jpg","birds/bird1.jpg","nature/nature17.jpg","insects/insect10.jpg"]
},
{
"instructions": qsTr("Place the FOOD ITEMS to the right and other objects to the left"),
"image": imagesPrefix + "pizza1.jpg",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/data/words/",
"good": ["food/fish.jpg","food/frenchFries.jpg","food/friedEggs.jpg","food/grilledSandwich.jpg","food/hamburger.jpg","food/hotdog.jpg"],
"bad": ["nature/nature26.jpg","birds/bird25.jpg","transport/cycle.jpg","insects/insect1.jpg","nature/nature24.jpg","others/fork.jpg"]
},
{
"instructions": qsTr("Place the FOOD ITEMS to the right and other objects to the left"),
"image": imagesPrefix + "hotdog.jpg",
"maxNumberOfGood": 5,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/data/words/",
"good": ["food/icecream.jpg","food/cereal1.jpg","food/cheese1.jpg","food/kathiRoll.jpg","food/macroni.jpg"],
"bad": ["animals/camel.jpg","animals/hare.jpg","insects/insect4.jpg","birds/bird5.jpg"]
},
{
"instructions": qsTr("Place the FOOD ITEMS to the right and other objects to the left"),
"image": imagesPrefix + "frenchFries.jpg",
"maxNumberOfGood": 5,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/data/words/",
"good": ["food/MaozVegetariano.jpg","food/milk.jpg","food/bananaNutBread.jpg","food/pitaBread.jpg","food/pizza.jpg"],
"bad": ["birds/bird6.jpg","others/street.jpg","householdGoods/iron2.jpg","insects/insect8.jpg"]
},
{
"instructions": qsTr("Place the FOOD ITEMS to the right and other objects to the left"),
"image": imagesPrefix + "hamburger.jpg",
"maxNumberOfGood": 3,
"maxNumberOfBad": 3,
"prefix": "qrc:/gcompris/data/words/",
"good": ["food/icecream1.jpg","food/riceBeans.jpg","food/scrambledEggsVeggies.jpg"],
"bad": ["nature/nature21.jpg","plants/tree2.jpg","householdGoods/bed.jpg"]
},
{
"instructions": qsTr("Place the FOOD ITEMS to the right and other objects to the left"),
"image": imagesPrefix + "milk.jpg",
"maxNumberOfGood": 3,
"maxNumberOfBad": 3,
"prefix": "qrc:/gcompris/data/words/",
"good": ["food/skimmedMilk.jpg","food/steak.jpg","food/sweetBread.jpg"],
"bad": ["birds/bird4.jpg","animals/koala.jpg","transport/ferry.jpg"]
}
]
}
]
}
diff --git a/src/activities/categorization/resource/board/category_fruits.qml b/src/activities/categorization/resource/board/category_fruits.qml
index e19f7f6c3..ff3b5eeaf 100644
--- a/src/activities/categorization/resource/board/category_fruits.qml
+++ b/src/activities/categorization/resource/board/category_fruits.qml
@@ -1,108 +1,108 @@
/* GCompris
*
* Copyright (C) 2016 Divyam Madaan <divyam3897@gmail.com>
*
* Authors:
* Divyam Madaan <divyam3897@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject{
property bool isEmbedded: false
property bool allowExpertMode: true
property string imagesPrefix: "qrc:/gcompris/src/activities/lang/resource/words_sample/"
property var levels: [
{
"type": "lesson",
"name": qsTr("Fruits"),
"image": "qrc:/gcompris/data/words/fruits/fruitsalad.jpg",
"content": [
{
"instructions": qsTr("Place the FRUITS to the right and other objects to the left"),
"image": imagesPrefix + "fruit.png",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/data/words/",
"good": ["fruits/apple.jpg","fruits/apricot.jpg","fruits/banana.jpg","fruits/berries.jpg","fruits/billberries.jpg","fruits/cherries.jpg"],
"bad": ["vegetables/batatadoce.jpg","vegetables/bittergourd.jpg","vegetables/blackchillies.jpg","vegetables/aubergine.jpg","others/house.jpg","others/street.jpg"],
},
{
"instructions": qsTr("Place the FRUITS to the right and other objects to the left"),
"image": imagesPrefix + "fruit.png",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/data/words/",
"good": ["fruits/cranberries.jpg","fruits/feiji.jpg","fruits/kiwi.jpg","fruits/lemon.jpg","fruits/litchi.jpg","fruits/mango.jpg"],
"bad": ["vegetables/garlic.jpg","vegetables/carrots.jpg","vegetables/cauliflower.jpg","vegetables/chillies.jpg","others/spoon.jpg","others/fork.jpg"]
},
{
"instructions": qsTr("Place the FRUITS to the right and other objects to the left"),
"image": imagesPrefix + "fruit.png",
"maxNumberOfGood": 5,
"maxNumberOfBad": 7,
"prefix": "qrc:/gcompris/data/words/",
"good": ["fruits/mirabellen.jpg","fruits/nectarine.jpg","fruits/papaya.jpg","fruits/peach.jpg","fruits/pineapple.jpg"],
"bad": ["vegetables/chineseradish.jpg","vegetables/cucumber.jpg","food/cereal.jpg","food/macroni.jpg","food/hamburger.jpg","transport/cycle.jpg","transport/car1.jpg"]
},
{
"instructions": qsTr("Place the FRUITS to the right and other objects to the left"),
"image": imagesPrefix + "fruit.png",
"maxNumberOfGood": 4,
"maxNumberOfBad": 5,
"prefix": "qrc:/gcompris/data/words/",
"good": ["fruits/plum.jpg","fruits/stackelberry.jpg","fruits/tyttberries.jpg","fruits/strwaberry.jpg"],
"bad": ["vegetables/dahuisi.jpg","others/mobile.jpg","vegetables/fid.jpg","food/eggs.jpg","food/icecream.jpg"]
},
{
"instructions": qsTr("Place the FRUITS to the right and other objects to the left"),
"image": imagesPrefix + "fruit.png",
"maxNumberOfGood": 4,
"maxNumberOfBad": 5,
"prefix": "qrc:/gcompris/data/words/",
"good": ["fruits/fruitsalad.jpg","fruits/guava.jpg","fruits/grapes.jpg","fruits/litchi.jpg"],
"bad": ["vegetables/pumpkin.jpg","transport/bus.jpg","food/milk.jpg","food/cheese.jpg","food/butter.jpg"]
},
{
"instructions": qsTr("Place the FRUITS to the right and other objects to the left"),
"image": imagesPrefix + "fruit.png",
"maxNumberOfGood": 3,
"maxNumberOfBad": 3,
"prefix": "qrc:/gcompris/data/words/",
"good": ["fruits/pear.jpg","fruits/pyrusmalus.jpg","fruits/pineapple.jpg"],
"bad": ["vegetables/radish.jpg","food/popcorn.jpg","others/street.jpg"]
},
{
"instructions": qsTr("Place the FRUITS to the right and other objects to the left"),
"image": imagesPrefix + "fruit.png",
"maxNumberOfGood": 3 ,
"maxNumberOfBad": 3,
"prefix": "qrc:/gcompris/data/words/",
"good": ["fruits/peach.jpg","fruits/tyttberries.jpg","fruits/papaya.jpg"],
"bad": ["vegetables/spinach.jpg","food/hotdog.jpg", "food/milk.jpg"]
},
{
"instructions": qsTr("Place the FRUITS to the right and other objects to the left"),
"image": imagesPrefix + "fruit.png",
"maxNumberOfGood": 2,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/data/words/",
"good": ["fruits/mango.jpg","fruits/strwaberry.jpg"],
"bad": ["others/pencil.jpg","vegetables/onion.jpg","food/cheese.jpg","food/water.jpg"]
}
]
}
]
}
diff --git a/src/activities/categorization/resource/board/category_household_goods.qml b/src/activities/categorization/resource/board/category_household_goods.qml
index a2342e225..df6f7e7fb 100644
--- a/src/activities/categorization/resource/board/category_household_goods.qml
+++ b/src/activities/categorization/resource/board/category_household_goods.qml
@@ -1,163 +1,163 @@
/* GCompris
*
* Copyright (C) 2016 Divyam Madaan <divyam3897@gmail.com>
*
* Authors:
* Divyam Madaan <divyam3897@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject{
property bool isEmbedded: false
property bool allowExpertMode: true
property string imagesPrefix: "qrc:/gcompris/data/words/householdGoods/"
property var levels: [
{
"type": "lesson",
"name": qsTr("Household goods"),
"image": imagesPrefix + "utensils.jpg",
"content": [
{
"instructions": qsTr("Place the HOUSEHOLD GOODS to the right and other objects to the left"),
"image":imagesPrefix + "oven.jpg",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/data/words/",
"good": ["householdGoods/bedsheet.jpg","householdGoods/blender.png","householdGoods/breadtoaster.jpg", "householdGoods/canOpener.jpg","householdGoods/bathtub.jpg","householdGoods/bed.jpg"],
"bad": ["food/eggs.jpg","food/milk.jpg","food/riceBeans.jpg","transport/metro.jpg","transport/plane.jpg","fruits/apple.jpg"]
},
{
"instructions": qsTr("Place the HOUSEHOLD GOODS to the right and other objects to the left"),
"image": imagesPrefix + "dressingtable.jpg",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/data/words/",
"good": [ "householdGoods/almirah.jpg","householdGoods/coffeeMaker.jpg","householdGoods/laptop.jpg","householdGoods/bookshelf.jpg","householdGoods/chair.jpg","householdGoods/chest.jpg"],
"bad": ["transport/ship1.jpg","nature/nature5.jpg","fruits/papaya.jpg","food/hamburger.jpg","transport/ship.jpg","others/street.jpg"]
},
{
"instructions": qsTr("Place the HOUSEHOLD GOODS to the right and other objects to the left"),
"image":imagesPrefix + "radio.jpg",
"maxNumberOfGood": 7,
"maxNumberOfBad": 5,
"prefix": "qrc:/gcompris/data/words/",
"good": ["householdGoods/curtains.jpg","householdGoods/heater.jpg","householdGoods/stool.jpg","householdGoods/couch.jpg","householdGoods/crib.jpg","householdGoods/oven.jpg","householdGoods/almirah.jpg"],
"bad": ["others/house.jpg","transport/rocket1.jpg","transport/train4.jpg","insects/insect16.jpg","birds/bird14.jpg"]
},
{
"instructions": qsTr("Place the HOUSEHOLD GOODS to the right and other objects to the left"),
"image":imagesPrefix + "sewingMachine.jpg",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/data/words/",
"good": ["householdGoods/quilt.jpg","householdGoods/iron.jpg","householdGoods/bed2.jpg","householdGoods/couch2.jpg","householdGoods/diningtable.jpg","householdGoods/coffeeMaker1.jpg"],
"bad": ["transport/ferry1.jpg","vegetables/mushroom.jpg","insects/insect22.jpg","birds/bird5.jpg","food/friedEggs.jpg","food/MaozVegetariano.jpg"]
},
{
"instructions": qsTr("Place the HOUSEHOLD GOODS to the right and other objects to the left"),
"image": imagesPrefix + "bed.jpg",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/data/words/",
"good": ["householdGoods/almirah1.jpg","householdGoods/radio.jpg","householdGoods/chair2.jpg","householdGoods/stool2.jpg","householdGoods/electricBlanket.jpg","householdGoods/refrigerator1.jpg"],
"bad": ["birds/bird2.jpg","birds/bird5.jpg","food/macroni.jpg","transport/exchanger.jpg","vegetables/potato.jpg","others/pepsi.jpg"]
},
{
"instructions": qsTr("Place the HOUSEHOLD GOODS to the right and other objects to the left"),
"image":imagesPrefix + "heater.jpg",
"maxNumberOfGood": 5,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/data/words/",
"good": ["householdGoods/television.jpg","householdGoods/toaster.jpg","householdGoods/curtains1.jpg","householdGoods/coffeeMaker2.jpg","householdGoods/iron1.jpg"],
"bad": ["nature/nature14.jpg","food/pizza1.jpg","fruits/mango.jpg","vegetables/spinach.jpg"]
},
{
"instructions": qsTr("Place the HOUSEHOLD GOODS to the right and other objects to the left"),
"image":imagesPrefix + "ac.jpg",
"maxNumberOfGood": 5,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/data/words/",
"good": ["householdGoods/heater1.jpg","householdGoods/oven1.jpg","householdGoods/radio1.jpg","householdGoods/electricBlanket.jpg","householdGoods/bathtub.jpg"],
"bad": ["vegetables/zucchini.jpg","others/street.jpg","transport/helicopter.jpg","plants/tree2.jpg"]
},
{
"instructions": qsTr("Place the HOUSEHOLD GOODS to the right and other objects to the left"),
"image":imagesPrefix + "breadtoaster.jpg",
"maxNumberOfGood": 5,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/data/words/",
"good": ["householdGoods/ac.jpg","householdGoods/iron2.jpg","householdGoods/toaster.jpg", "householdGoods/sewingMachine1.jpg", "householdGoods/vacuumCleaner.jpg"],
"bad": ["food/hotdog.jpg","animals/cow.jpg","birds/bird25.jpg","insects/insect14.jpg"]
},
{
"instructions": qsTr("Place the HOUSEHOLD GOODS to the right and other objects to the left"),
"image": imagesPrefix + "bathtub.jpg",
"maxNumberOfGood": 5,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/data/words/",
"good": ["householdGoods/bed1.jpg","householdGoods/lamp.jpg","householdGoods/chair3.jpg",
"householdGoods/refrigerator2.jpg","householdGoods/towels.jpg"],
"bad": ["transport/bus.jpg","animals/elephant.jpg","insects/insect5.jpg","others/street.jpg"]
},
{
"instructions": qsTr("Place the HOUSEHOLD GOODS to the right and other objects to the left"),
"image": imagesPrefix + "stool.jpg",
"maxNumberOfGood": 4,
"maxNumberOfBad": 5,
"prefix": "qrc:/gcompris/data/words/",
"good": ["householdGoods/chest1.jpg","householdGoods/diningtable1.jpg","householdGoods/laptop.jpg","householdGoods/sewingMachine.jpg"],
"bad": ["animals/kodiak-bear.jpg","animals/sealion.jpg","transport/plane.jpg","food/frenchFries.jpg","others/house.jpg"]
},
{
"instructions": qsTr("Place the HOUSEHOLD GOODS to the right and other objects to the left"),
"image": imagesPrefix + "almirah.jpg",
"maxNumberOfGood": 3,
"maxNumberOfBad": 3,
"prefix": "qrc:/gcompris/data/words/",
"good": ["householdGoods/couch2.jpg","householdGoods/refrigerator.jpg","householdGoods/ac1.jpg"],
"bad": ["insects/insect18.jpg","transport/car1.jpg","animals/dog.jpg"]
},
{
"instructions": qsTr("Place the HOUSEHOLD GOODS to the right and other objects to the left"),
"image":imagesPrefix + "coffeeMaker2.jpg",
"maxNumberOfGood": 3,
"maxNumberOfBad": 3,
"prefix": "qrc:/gcompris/data/words/",
"good": ["householdGoods/heater2.jpg","householdGoods/dressingtable.jpg","householdGoods/stool2.jpg"],
"bad": ["animals/lion.jpg","vegetables/aubergine.jpg","nature/nature12.jpg"]
},
{
"instructions": qsTr("Place the HOUSEHOLD GOODS to the right and other objects to the left"),
"image": imagesPrefix + "chest.jpg",
"maxNumberOfGood": 2,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/data/words/",
"good": ["householdGoods/chair5.jpg","householdGoods/lamp1.JPG"],
"bad": ["vegetables/fid.jpg","animals/koala.jpg","transport/ferry.jpg","others/broom1.jpg"]
},
{
"instructions": qsTr("Place the HOUSEHOLD GOODS to the right and other objects to the left"),
"image":imagesPrefix + "heater1.jpg",
"maxNumberOfGood": 3,
"maxNumberOfBad": 3,
"prefix": "qrc:/gcompris/data/words/",
"good": ["householdGoods/ac2.JPG","householdGoods/vacuumCleaner.jpg","householdGoods/sewingMachine2.jpg"],
"bad": ["insects/insect15.jpg","vegetables/potato.jpg","nature/nature13.jpg"]
}
]
}
]
}
diff --git a/src/activities/categorization/resource/board/category_insects.qml b/src/activities/categorization/resource/board/category_insects.qml
index 4b2656dc2..895a193b2 100644
--- a/src/activities/categorization/resource/board/category_insects.qml
+++ b/src/activities/categorization/resource/board/category_insects.qml
@@ -1,90 +1,90 @@
/* GCompris
*
* Copyright (C) 2016 Divyam Madaan <divyam3897@gmail.com>
*
* Authors:
* Divyam Madaan <divyam3897@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject{
property bool isEmbedded: false
property bool allowExpertMode: true
property string imagesPrefix: "qrc:/gcompris/data/words/insects/"
property var levels: [
{
"type": "lesson",
"name": qsTr("Insects"),
"image": imagesPrefix + "insect6.jpg",
"content": [
{
"instructions": qsTr("Place the INSECTS to the right and other objects to the left"),
"image": imagesPrefix + "insect15.jpg",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/data/words/",
"good": ["insects/insect1.jpg","insects/insect2.jpg","insects/insect3.jpg","insects/insect4.jpg","insects/insect5.jpg","insects/insect6.jpg"],
"bad": ["nature/nature4.jpg","plants/tree2.jpg","birds/bird8.jpg","birds/bird5.jpg","animals/giraffe.jpg","animals/horse.jpg"]
},
{
"instructions": qsTr("Place the INSECTS to the right and other objects to the left"),
"image": imagesPrefix + "insect25.jpg",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/data/words/",
"good": ["insects/insect7.jpg","insects/insect8.jpg","insects/insect9.jpg","insects/insect10.jpg","insects/insect11.jpg","insects/insect12.jpg"],
"bad": ["food/eggs.jpg","birds/bird2.jpg","birds/bird3.jpg","animals/lion.jpg","animals/mouse.jpg","animals/elephant.jpg"]
},
{
"instructions": qsTr("Place the INSECTS to the right and other objects to the left"),
"image": imagesPrefix + "insect6.jpg",
"maxNumberOfGood": 5,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/data/words/",
"good": ["insects/insect13.jpg","insects/insect14.jpg","insects/insect15.jpg","insects/insect16.jpg","insects/insect17.jpg"],
"bad": ["transport/helicopter.jpg","householdGoods/oven.jpg","birds/bird8.jpg","birds/bird9.jpg"]
},
{
"instructions": qsTr("Place the INSECTS to the right and other objects to the left"),
"image": imagesPrefix + "insect8.jpg",
"maxNumberOfGood": 5,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/data/words/",
"good": ["insects/insect18.jpg","insects/insect19.jpg","insects/insect20.jpg","insects/insect21.jpg","insects/insect22.jpg"],
"bad": ["householdGoods/bed.jpg","others/mobile.jpg","birds/bird17.jpg","animals/hare.jpg"]
},
{
"instructions": qsTr("Place the INSECTS to the right and other objects to the left"),
"image": imagesPrefix + "insect19.jpg",
"maxNumberOfGood": 3,
"maxNumberOfBad": 3,
"prefix": "qrc:/gcompris/data/words/",
"good": ["insects/insect23.jpg","insects/insect24.jpg","insects/insect25.jpg"],
"bad": ["plants/tree3.jpg","birds/bird29.jpg","animals/pig.jpg"]
},
{
"instructions": qsTr("Place the INSECTS to the right and other objects to the left"),
"image": imagesPrefix + "insect12.jpg",
"maxNumberOfGood": 3,
"maxNumberOfBad": 3,
"prefix": "qrc:/gcompris/data/words/",
"good": ["insects/insect26.jpg","insects/insect27.jpg","insects/insect12.jpg"],
"bad": ["householdGoods/iron.jpg","birds/bird33.jpg","animals/sheep.jpg"]
}
]
}
]
}
diff --git a/src/activities/categorization/resource/board/category_living_beings.qml b/src/activities/categorization/resource/board/category_living_beings.qml
index 547e3ce3d..72b7c65cb 100644
--- a/src/activities/categorization/resource/board/category_living_beings.qml
+++ b/src/activities/categorization/resource/board/category_living_beings.qml
@@ -1,99 +1,99 @@
/* GCompris
*
* Copyright (C) 2016 Divyam Madaan <divyam3897@gmail.com>
*
* Authors:
* Divyam Madaan <divyam3897@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject{
property bool isEmbedded: false
property bool allowExpertMode: true
property string imagesPrefix: "qrc:/gcompris/data/words/"
property var levels: [
{
"type": "lesson",
"name": qsTr("Living"),
"image": imagesPrefix + "plants" + "/" + "plant1.jpg",
"content": [
{
"instructions": qsTr("Place the living beings to the right and other objects to the left"),
"image":imagesPrefix + "plants" + "/" + "plant5.jpg",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/data/words/",
"good": ["plants/plant2.jpg","plants/tree1.jpg","animals/donkey.jpg","animals/horse.jpg","birds/bird12.jpg","birds/bird13.jpg"],
"bad": ["transport/balloon.jpg","transport/bus.jpg","others/house.jpg","others/clock.jpg","householdGoods/ac.jpg","others/pencil.jpg"]
},
{
"instructions": qsTr("Place the living beings to the right and other objects to the left"),
"image":imagesPrefix + "insects" + "/" + "insect4.jpg",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/data/words/",
"good": ["insects/insect16.jpg","birds/bird17.jpg","insects/insect22.jpg","insects/insect19.jpg","insects/insect23.jpg","birds/bird21.jpg"],
"bad": ["transport/plane.jpg","transport/metro.jpg","householdGoods/refrigerator.jpg","householdGoods/chest1.jpg","food/grilledSandwich.jpg","others/mobile.jpg"]
},
{
"instructions": qsTr("Place the living beings to the right and other objects to the left"),
"image":imagesPrefix + "birds" + "/" + "bird5.jpg",
"maxNumberOfGood": 5,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/data/words/",
"good":["plants/plant1.jpg","plants/tree2.jpg","insects/insect3.jpg","insects/insect4.jpg","birds/bird1.jpg"],
"bad": ["transport/rickshaw.jpg","householdGoods/bed.jpg","others/pepsi.jpg","householdGoods/canOpener.jpg"]
},
{
"instructions": qsTr("Place the living beings to the right and other objects to the left"),
"image":imagesPrefix + "plants" +"/" + "tree2.jpg",
"maxNumberOfGood": 4,
"maxNumberOfBad": 5,
"prefix": "qrc:/gcompris/data/words/",
"good": ["plants/plant3.jpg","plants/tree3.jpg","animals/snowcat.jpg","animals/pig.jpg"],
"bad": ["transport/plane.jpg","food/frenchFries.jpg","food/water.jpg","others/street.jpg","householdGoods/bed.jpg"]
},
{
"instructions": qsTr("Place the living beings to the right and other objects to the left"),
"image":imagesPrefix + "animals" + "/" + "opossum.jpg",
"maxNumberOfGood": 4,
"maxNumberOfBad": 5,
"prefix": "qrc:/gcompris/data/words/",
"good": ["plants/tree4.jpg","animals/giraffe.jpg","insects/insect7.jpg","birds/bird12.jpg","birds/bird15.jpg"],
"bad": ["householdGoods/heater.jpg","householdGoods/couch.jpg","transport/ship.jpg","others/fork.jpg","food/eggs.jpg"]
},
{
"instructions": qsTr("Place the living beings to the right and other objects to the left"),
"image":imagesPrefix + "animals" + "/" + "hare.jpg",
"maxNumberOfGood": 3,
"maxNumberOfBad": 3,
"prefix": "qrc:/gcompris/data/words/",
"good": ["plants/plant4.jpg","animals/lion.jpg","birds/bird24.jpg"],
"bad": ["transport/helicopter.jpg","householdGoods/iron.jpg","others/mobile.jpg"]
},
{
"instructions": qsTr("Place the living beings to the right and other objects to the left"),
"image":imagesPrefix + "insects" + "/" + "insect5.jpg",
"maxNumberOfGood": 3,
"maxNumberOfBad": 3,
"prefix": "qrc:/gcompris/data/words/",
"good": ["plants/plant5.jpg","plants/plant6.jpg","animals/sheep.jpg"],
"bad": ["transport/rocket.jpg","others/pepsi.jpg","food/hotdog.jpg"]
}
]
}
]
}
diff --git a/src/activities/categorization/resource/board/category_monuments.qml b/src/activities/categorization/resource/board/category_monuments.qml
index b6524a1f0..94a90582d 100644
--- a/src/activities/categorization/resource/board/category_monuments.qml
+++ b/src/activities/categorization/resource/board/category_monuments.qml
@@ -1,90 +1,90 @@
/* GCompris
*
* Copyright (C) 2016 Divyam Madaan <divyam3897@gmail.com>
*
* Authors:
* Divyam Madaan <divyam3897@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property bool isEmbedded: true
property bool allowExpertMode: true
property string imagesPrefix: "qrc:/gcompris/src/activities/categorization/resource/images/monuments/"
property var levels: [
{
"type": "lesson",
"name": qsTr("Monuments"),
"image": imagesPrefix + "colosseum.jpg",
"content": [
{
"instructions": qsTr("Place the MONUMENTS to the right and other objects to the left"),
"image": imagesPrefix + "victoriaMemorial.jpg",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/src/activities/categorization/resource/images/",
"good": ["monuments/bayterek.jpg","monuments/burj.jpg","monuments/cathedral.jpg","monuments/colosseum.jpg","monuments/beandenburgGate.jpg","monuments/arcDeTriomphe.jpg"],
"bad": ["renewable/windmill5.jpg","renewable/dam2.jpg","tools/tweezer.jpg","others/bulb.jpg","others/pan.jpg","others/knife.jpg"]
},
{
"instructions": qsTr("Place the MONUMENTS to the right and other objects to the left"),
"image": imagesPrefix + "parthenon.jpg",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/src/activities/categorization/resource/images/",
"good": ["monuments/christTheRedeemer.jpg","monuments/eiffelTower.jpg","monuments/empireState.jpg" ,"monuments/greatPyramid.jpg","monuments/greatWall.jpg","monuments/IndiaGate.jpg"],
"bad": ["fishes/fish3.jpg","fishes/fish5.jpg","renewable/dam2.jpg","others/spoons.jpg","others/igloo.jpg","tools/measuringTape.jpg"]
},
{
"instructions": qsTr("Place the MONUMENTS to the right and other objects to the left"),
"image": imagesPrefix + "monument2.jpg",
"maxNumberOfGood": 5,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/src/activities/categorization/resource/images/",
"good": ["monuments/jucheTower.jpg","monuments/kutubMinar.jpg","monuments/leaningTowerOfPisa.jpg" ,"monuments/leninMuseum.jpg","monuments/monument1.jpg"],
"bad": ["fishes/fish7.jpg","fishes/fish16.jpg","tools/hammer4.jpg","tools/sprinkler.jpg"]
},
{
"instructions": qsTr("Place the MONUMENTS to the right and other objects to the left"),
"image": imagesPrefix + "greatPyramid.jpg",
"maxNumberOfGood": 5,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/src/activities/categorization/resource/images/",
"good": ["monuments/mountRushmore.jpg","monuments/operaHouse.jpg","monuments/parthenon.jpg","monuments/statueOfLiberty.jpg","monuments/tajMahal.jpg"],
"bad": ["renewable/solar2.jpg","renewable/geothermal.jpg","tools/scissor.jpg","tools/stripper1.png"]
},
{
"instructions": qsTr("Place the MONUMENTS to the right and other objects to the left"),
"image": imagesPrefix + "beandenburgGate.jpg",
"maxNumberOfGood": 3,
"maxNumberOfBad": 3,
"prefix": "qrc:/gcompris/src/activities/categorization/resource/images/",
"good": ["monuments/usCapitol.jpg","monuments/victoriaMemorial.jpg","monuments/zimniPalace.jpg"],
"bad": ["tools/plier2.jpg","others/pillow.jpg","renewable/solar5.jpg"]
},
{
"instructions": qsTr("Place the MONUMENTS to the right and other objects to the left"),
"image": imagesPrefix + "IndiaGate.jpg",
"maxNumberOfGood": 2,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/src/activities/categorization/resource/images/",
"good": ["monuments/monument2.jpg","monuments/monument3.jpg"],
"bad": ["others/volleyball.jpg","tools/sickle.jpg","others/chair.jpg","renewable/dam4.jpg"]
}
]
}
]
}
diff --git a/src/activities/categorization/resource/board/category_nature.qml b/src/activities/categorization/resource/board/category_nature.qml
index bd9ccea40..4756dba8b 100644
--- a/src/activities/categorization/resource/board/category_nature.qml
+++ b/src/activities/categorization/resource/board/category_nature.qml
@@ -1,108 +1,108 @@
/* GCompris
*
* Copyright (C) 2016 Divyam Madaan <divyam3897@gmail.com>
*
* Authors:
* Divyam Madaan <divyam3897@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject{
property bool isEmbedded: false
property bool allowExpertMode: true
property string imagesPrefix: "qrc:/gcompris/data/words/nature/"
property var levels: [
{
"type": "lesson",
"name": qsTr("Nature"),
"image": imagesPrefix + "nature7.jpg",
"content": [
{
"instructions": qsTr("Place the NATURE images to the right and other objects to the left"),
"image": imagesPrefix + "nature25.jpg",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/data/words/",
"good": ["nature/nature1.jpg","nature/nature2.jpg","nature/nature3.jpg","nature/nature4.jpg","nature/nature5.jpg","nature/nature6.jpg"],
"bad": ["transport/train3.jpg","others/spoon.jpg","transport/bus.jpg","others/clock.jpg","food/hamburger.jpg","food/macroni.jpg"]
},
{
"instructions": qsTr("Place the NATURE images to the right and other objects to the left"),
"image": imagesPrefix + "nature28.jpg",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/data/words/",
"good": ["nature/nature7.jpg","nature/nature8.jpg","nature/nature9.jpg","nature/nature10.jpg", "nature/nature11.jpg","nature/nature12.jpg"],
"bad": ["fruits/mango.jpg","vegetables/onion.jpg","transport/cycle.jpg","others/fork.jpg","food/riceBeans.jpg","others/pepsi.jpg"]
},
{
"instructions": qsTr("Place the NATURE images to the right and other objects to the left"),
"image": imagesPrefix + "nature22.jpg",
"maxNumberOfGood": 5,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/data/words/",
"good": ["nature/nature13.jpg","nature/nature14.jpg","nature/nature15.jpg","nature/nature16.jpg","nature/nature17.jpg"],
"bad": ["transport/autorickshaw.jpg","transport/bulletTrain.jpg","householdGoods/chest.jpg","others/broom1.jpg"]
},
{
"instructions": qsTr("Place the NATURE images to the right and other objects to the left"),
"image": imagesPrefix + "nature2.jpg",
"maxNumberOfGood": 5,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/data/words/",
"good": ["nature/nature18.jpg","nature/nature19.jpg","nature/nature20.jpg","nature/nature21.jpg","nature/nature22.jpg"],
"bad": ["transport/train5.jpg","transport/tram1.jpg","others/mobile.jpg","others/electricfan.jpg"]
},
{
"instructions": qsTr("Place the NATURE images to the right and other objects to the left"),
"image": imagesPrefix + "nature2.jpg",
"maxNumberOfGood": 5,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/data/words/",
"good": ["nature/nature29.jpg","nature/nature30.jpg","nature/nature31.jpg","nature/nature32.jpg","nature/nature33.jpg"],
"bad": ["fruits/pineapple.jpg","food/pitaBread.jpg","householdGoods/bed.jpg","others/house.jpg"]
},
{
"instructions": qsTr("Place the NATURE images to the right and other objects to the left"),
"image": imagesPrefix + "nature6.jpg",
"maxNumberOfGood": 3,
"maxNumberOfBad": 3,
"prefix": "qrc:/gcompris/data/words/",
"good": ["nature/nature23.jpg","nature/nature24.jpg","nature/nature25.jpg"],
"bad": ["vegetables/zucchini.jpg","others/street.jpg","householdGoods/couch.jpg"]
},
{
"instructions": qsTr("Place the NATURE images to the right and other objects to the left"),
"image": imagesPrefix + "nature14.jpg",
"maxNumberOfGood": 3,
"maxNumberOfBad": 3,
"prefix": "qrc:/gcompris/data/words/",
"good": ["nature/nature26.jpg","nature/nature27.jpg","nature/nature28.jpg"],
"bad": ["food/MaozVegetariano.jpg","transport/rickshaw2.jpg","others/electricfan.jpg"]
},
{
"instructions": qsTr("Place the NATURE images to the right and other objects to the left"),
"image": imagesPrefix + "nature14.jpg",
"maxNumberOfGood": 2,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/data/words/",
"good": ["nature/nature34.jpg","nature/nature35.jpg"],
"bad": ["householdGoods/chair2.jpg","food/milk.jpg","others/weighingmachine.jpg","others/pencil.jpg"]
}
]
}
]
}
diff --git a/src/activities/categorization/resource/board/category_numbers.qml b/src/activities/categorization/resource/board/category_numbers.qml
index 6f387a823..8c052cfa7 100644
--- a/src/activities/categorization/resource/board/category_numbers.qml
+++ b/src/activities/categorization/resource/board/category_numbers.qml
@@ -1,63 +1,63 @@
/* GCompris
*
* Copyright (C) 2016 Divyam Madaan <divyam3897@gmail.com>
*
* Authors:
* Divyam Madaan <divyam3897@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property bool isEmbedded: true
property bool allowExpertMode: true
property string imagesPrefix: "qrc:/gcompris/src/activities/categorization/resource/images/numbers/"
property var levels: [
{
"type": "lesson",
"name": qsTr("Numbers"),
"image": "qrc:/gcompris/src/activities/categorization/resource/images/numbers/numbers.jpg",
"content": [
{
"instructions": qsTr("Place the NUMBERS to the right and other objects to the left"),
"image": imagesPrefix + "00.svg",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/src/activities/",
"good": ["categorization/resource/images/numbers/12.svg","categorization/resource/images/numbers/02.svg","categorization/resource/images/numbers/00.svg","categorization/resource/images/numbers/08.svg","categorization/resource/images/numbers/10.svg","categorization/resource/images/numbers/04.svg"],
"bad": ["categorization/resource/images/alphabets/upperA.svg","categorization/resource/images/alphabets/upperM.svg","categorization/resource/images/alphabets/lowerB.svg","categorization/resource/images/alphabets/upperS.svg","lang/resource/words_sample/fish.png","lang/resource/words_sample/color.png"]
},
{
"instructions": qsTr("Place the NUMBERS to the right and other objects to the left"),
"image": imagesPrefix + "00.svg",
"maxNumberOfGood": 5,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/src/activities/",
"good": ["categorization/resource/images/numbers/05.svg","categorization/resource/images/numbers/11.svg","categorization/resource/images/numbers/09.svg","categorization/resource/images/numbers/03.svg","categorization/resource/images/numbers/07.svg"],
"bad": ["categorization/resource/images/alphabets/upperZ.svg","categorization/resource/images/alphabets/lowerH.svg","lang/resource/words_sample/mosquito.png","lang/resource/words_sample/fruit.png"]
},
{
"instructions": qsTr("Place the NUMBERS to the right and other objects to the left"),
"image": imagesPrefix + "00.svg",
"maxNumberOfGood": 3,
"maxNumberOfBad": 3,
"prefix": "qrc:/gcompris/src/activities/",
"good": ["categorization/resource/images/numbers/01.svg","categorization/resource/images/numbers/06.svg","categorization/resource/images/numbers/16.svg"],
"bad": ["categorization/resource/images/alphabets/upperR.svg","categorization/resource/images/alphabets/lowerQ.svg", "lang/resource/words_sample/strawberry.png"]
}
]
}
]
}
diff --git a/src/activities/categorization/resource/board/category_odd_even.qml b/src/activities/categorization/resource/board/category_odd_even.qml
index d90689237..a252ed4db 100644
--- a/src/activities/categorization/resource/board/category_odd_even.qml
+++ b/src/activities/categorization/resource/board/category_odd_even.qml
@@ -1,91 +1,91 @@
/* GCompris
*
* Copyright (C) 2017 Rudra Nil Basu <rudra.nil.basu.1996@gmail.com>
*
* Authors:
* Rudra Nil Basu <rudra.nil.basu.1996@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property bool isEmbedded: false
property bool allowExpertMode: false
property string imagesPrefix: "qrc:/gcompris/data/words/numbers/"
property var levels: [
{
"type": "lesson",
- "name": qsTr("odd even numbers"),
+ "name": qsTr("Odd even numbers"),
"image": imagesPrefix + "11.svg",
"content": [
{
"instructions": qsTr("Place the EVEN Numbers to the right and ODD Numbers to the left"),
"image": imagesPrefix + "16.svg",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/data/words/numbers/",
"good": ["02.svg","04.svg","06.svg","08.svg", "10.svg","12.svg"],
"bad": ["01.svg","03.svg","05.svg","07.svg","09.svg","11.svg"]
},
{
"instructions": qsTr("Place the EVEN Numbers to the right and ODD Numbers to the left"),
"image": imagesPrefix + "02.svg",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/data/words/numbers/",
"good": ["even72.svg","even22.svg","even96.svg","even92.svg","even88.svg","even192.svg"],
"bad": ["odd47.svg","15.svg","odd35.svg","odd23.svg","odd39.svg","odd111.svg"]
},
{
"instructions": qsTr("Place the EVEN Numbers to the right and ODD Numbers to the left"),
"image": imagesPrefix + "02.svg",
"maxNumberOfGood": 4,
"maxNumberOfBad": 5,
"prefix": "qrc:/gcompris/data/words/numbers/",
"good": ["even786.svg","even276.svg","even192.svg","even92.svg"],
"bad": ["odd111.svg","odd145.svg","odd39.svg","odd353.svg","odd23.svg"]
},
{
"instructions": qsTr("Place the EVEN Numbers to the right and ODD Numbers to the left"),
"image": imagesPrefix + "02.svg",
"maxNumberOfGood": 5,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/data/words/numbers/",
"good": ["even22.svg","even88.svg","even192.svg","even786.svg","even72.svg"],
"bad": ["odd47.svg","odd353.svg","odd35.svg","15.svg"]
},
{
"instructions": qsTr("Place the EVEN Numbers to the right and ODD Numbers to the left"),
"image": imagesPrefix + "02.svg",
"maxNumberOfGood": 3,
"maxNumberOfBad": 3,
"prefix": "qrc:/gcompris/data/words/numbers//",
"good": ["16.svg","10.svg","12.svg"],
"bad": ["01.svg","07.svg","05.svg"]
},
{
"instructions": qsTr("Place the EVEN Numbers to the right and ODD Numbers to the left"),
"image": imagesPrefix + "16.svg",
"maxNumberOfGood": 3,
"maxNumberOfBad": 3,
"prefix": "qrc:/gcompris/data/words/numbers/",
"good": ["02.svg","08.svg","04.svg"],
"bad": ["09.svg","03.svg","11.svg"]
}
]
}
]
}
diff --git a/src/activities/categorization/resource/board/category_renewable.qml b/src/activities/categorization/resource/board/category_renewable.qml
index b0866f66e..015961aa1 100644
--- a/src/activities/categorization/resource/board/category_renewable.qml
+++ b/src/activities/categorization/resource/board/category_renewable.qml
@@ -1,108 +1,108 @@
/* GCompris
*
* Copyright (C) 2016 Divyam Madaan <divyam3897@gmail.com>
*
* Authors:
* Divyam Madaan <divyam3897@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property bool isEmbedded: true
property bool allowExpertMode: true
property string imagesPrefix: "qrc:/gcompris/src/activities/categorization/resource/images/renewable/"
property var levels: [
{
"type": "lesson",
"name": qsTr("Renewable"),
"image": imagesPrefix + "windmill12.jpg",
"content": [
{
"instructions": qsTr("Place the RENEWABLE energy sources to the right and other objects to the left"),
"image": imagesPrefix + "windmill12.jpg",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/src/activities/categorization/resource/images/",
"good": ["renewable/windmill.jpg","renewable/windmill1.jpg","renewable/windmill2.jpg","renewable/windmill3.jpg","renewable/windmill4.jpg","renewable/windmill5.jpg"],
"bad": ["fishes/fish20.jpg","others/volleyball.jpg","monuments/burj.jpg","tools/nosePlier.jpg","others/pillow.jpg","fishes/fish10.jpg"]
},
{
"instructions": qsTr("Place the RENEWABLE energy sources to the right and other objects to the left"),
"image": imagesPrefix + "solar8.jpg",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/src/activities/categorization/resource/images/",
"good": ["renewable/solar1.jpg","renewable/solar2.jpg","renewable/solar3.jpg","renewable/solar4.jpg","renewable/solar5.jpg","renewable/solar6.jpg"],
"bad": ["others/plate.jpg","fishes/fish25.jpg","tools/scissor1.jpg","monuments/christTheRedeemer.jpg","others/bucket.png","monuments/jucheTower.jpg"]
},
{
"instructions": qsTr("Place the RENEWABLE energy sources to the right and other objects to the left"),
"image": imagesPrefix + "dam2.jpg",
"maxNumberOfGood": 4,
"maxNumberOfBad": 5,
"prefix": "qrc:/gcompris/src/activities/categorization/resource/images/",
"good": ["renewable/dam1.jpg","renewable/dam2.jpg","renewable/dam3.jpg","renewable/dam4.jpg"],
"bad": ["fishes/fish14.jpg","tools/wrench.jpg","tools/plier2.jpg","others/baseball.jpg","monuments/arcDeTriomphe.jpg"]
},
{
"instructions": qsTr("Place the RENEWABLE energy sources to the right and other objects to the left"),
"image": imagesPrefix + "dam5.jpg",
"maxNumberOfGood": 4,
"maxNumberOfBad": 5,
"prefix": "qrc:/gcompris/src/activities/categorization/resource/images/",
"good": ["renewable/windmill2.jpg","renewable/windmill13.jpg","renewable/solar7.jpg","renewable/solar3.jpg"],
"bad": ["monuments/greatPyramid.jpg","others/buffetset.jpg","others/weighingMachine.jpg","tools/sprinkler.jpg","monuments/arcDeTriomphe.jpg"]
},
{
"instructions": qsTr("Place the RENEWABLE energy sources to the right and other objects to the left"),
"image": imagesPrefix + "geothermal.jpg",
"maxNumberOfGood": 5,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/src/activities/categorization/resource/images/",
"good": ["renewable/dam5.jpg","renewable/geothermal.jpg","renewable/windmill6.jpg","renewable/windmill7.jpg","renewable/windmill8.jpg"],
"bad": ["fishes/fish6.jpg","fishes/fish3.jpg","others/pan.jpg","others/spoons.jpg"]
},
{
"instructions": qsTr("Place the RENEWABLE energy sources to the right and other objects to the left"),
"image": imagesPrefix + "dam3.jpg",
"maxNumberOfGood": 3,
"maxNumberOfBad": 3,
"prefix": "qrc:/gcompris/src/activities/categorization/resource/images/",
"good": ["renewable/windmill9.jpg","renewable/windmill12.jpg","renewable/solar7.jpg"],
"bad": ["others/blackslate.jpg","monuments/IndiaGate.jpg","tools/multimeter.jpg"]
},
{
"instructions": qsTr("Place the RENEWABLE energy sources to the right and other objects to the left"),
"image": imagesPrefix + "solar2.jpg",
"maxNumberOfGood": 3,
"maxNumberOfBad": 3,
"prefix": "qrc:/gcompris/src/activities/categorization/resource/images/",
"good": ["renewable/solar8.jpg","renewable/dam5.jpg","renewable/windmill11.jpg"],
"bad": ["others/plate.jpg","others/chair.jpg","monuments/eiffelTower.jpg"]
},
{
"instructions": qsTr("Place the RENEWABLE energy sources to the right and other objects to the left"),
"image": imagesPrefix + "solar4.jpg",
"maxNumberOfGood": 3,
"maxNumberOfBad": 3,
"prefix": "qrc:/gcompris/src/activities/categorization/resource/images/",
"good": ["renewable/windmill14.jpg","renewable/windmill15.jpg","renewable/dam5.jpg"],
"bad": ["others/plate.jpg","fishes/fish18.jpg","monuments/leMusee.jpg"]
}
]
}
]
}
diff --git a/src/activities/categorization/resource/board/category_shapes.qml b/src/activities/categorization/resource/board/category_shapes.qml
index 18e5bc198..59e14dd9c 100644
--- a/src/activities/categorization/resource/board/category_shapes.qml
+++ b/src/activities/categorization/resource/board/category_shapes.qml
@@ -1,209 +1,209 @@
/* GCompris
*
* Copyright (C) 2016 Divyam Madaan <divyam3897@gmail.com>
*
* Authors:
* Divyam Madaan <divyam3897@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject{
property bool isEmbedded: false
property bool allowExpertMode: true
property string imagesPrefix: "qrc:/gcompris/data/words/shapes/"
property var levels: [
{
"type": "lesson",
"name": qsTr("Shapes"),
"image": imagesPrefix + "cube.JPG",
"content": [
{
"instructions": qsTr("Place the objects matching a CIRCLE to the right and others to the left"),
"image": imagesPrefix + "circle.svg",
"maxNumberOfGood": 5,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/data/words/shapes/",
"good": ["cd.svg","clock.svg","coin.svg","globe.svg","smile.svg"],
"bad": ["backcard.svg","can.svg","can1.svg","conehat.svg"]
},
{
"instructions": qsTr("Place the objects matching a RECTANGLE to right and others to the left"),
"image": imagesPrefix + "rectangle.svg",
"maxNumberOfGood": 4,
"maxNumberOfBad": 5,
"prefix": "qrc:/gcompris/data/words/shapes/",
"good": ["paper.svg","rectangle_led.svg","stickynote.svg","rainbowsquare.svg"],
"bad": ["cylinder.svg","icecream.svg","trapezium.svg","trash.svg","pizza.svg"]
},
{
"instructions": qsTr("Place the objects matching a SPHERE to right and others to the left"),
"image": imagesPrefix + "sun.svg",
"maxNumberOfGood": 4,
"maxNumberOfBad": 5,
"prefix": "qrc:/gcompris/data/words/",
"good": ["shapes/football.svg","shapes/globe.svg","ball.png","shapes/watermelon.svg"],
"bad": ["shapes/cone.svg","shapes/halforange.svg","shapes/sunrise.svg","shapes/juice2.svg","shapes/icecube.svg"]
},
{
"instructions": qsTr("Place the objects matching a TRAPEZOID to right and others to the left"),
"image": imagesPrefix + "trapezium.svg",
"maxNumberOfGood": 5,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/data/words/shapes/",
"good": ["trapezium2.svg","trapezium4.svg","trapezium3.svg","rectangle.svg","rhombus1.svg"],
"bad": ["cube.svg","dice.svg","rectbin.svg","yellowtriangle.svg"]
},
{
"instructions": qsTr("Place the objects matching a TRIANGLE to right and others to the left"),
"image": imagesPrefix + "triangle.svg",
"maxNumberOfGood": 4,
"maxNumberOfBad": 5,
"prefix": "qrc:/gcompris/data/words/shapes/",
"good": ["yellowtriangle.svg","trianglehat.svg","warning.svg","warning1.svg"],
"bad": ["sun.svg","cookie.svg","rhombus2.svg","trapezium2.svg","semicircle.svg"]
},
{
"instructions": qsTr("Place the objects matching a SEMICIRCLE to right and others to the left"),
"image": imagesPrefix + "semicircle.svg",
"maxNumberOfGood": 4,
"maxNumberOfBad": 5,
"prefix": "qrc:/gcompris/data/words/shapes/",
"good": ["fan.svg","halfmoon.svg","sunrise.svg","rainbow.svg"],
"bad": ["diceface.svg","watermelon.svg","squareclock.svg","trianglehat.svg","circle.svg"]
},
{
"instructions": qsTr("Place the objects matching a PENTAGON to right and others to the left"),
"image": imagesPrefix + "pentagon.svg",
"maxNumberOfGood": 4,
"maxNumberOfBad": 5,
"prefix": "qrc:/gcompris/data/words/",
"good": ["shapes/pentagon1.svg","shapes/pentagon2.svg","shapes/pentagon3.svg","shapes/pentagon4.svg"],
"bad": ["shapes/nonagon1.svg","shapes/trianglehat.svg","shapes/rainbowsquare.svg","shapes/paper.svg","shapes/hexagon1.svg"]
},
{
"instructions": qsTr("Place the objects matching a SQUARE to right and others to the left"),
"image": imagesPrefix + "rhombus.svg",
"maxNumberOfGood": 4,
"maxNumberOfBad": 5,
"prefix": "qrc:/gcompris/data/words/shapes/",
"good": ["rsquare.svg","rainbowsquare.svg","ledsquare.svg","stickynote.svg"],
"bad": ["trapezium.svg","slate.svg","rhombus4.svg","globe.svg","parallelogram.svg"]
},
{
"instructions": qsTr("Place the objects matching a CONE to right and others to the left"),
"image": imagesPrefix + "cone.svg",
"maxNumberOfGood": 4,
"maxNumberOfBad": 5,
"prefix": "qrc:/gcompris/data/words/shapes/",
"good": ["ice_cream.png","icecone.svg","icecream.svg","conehat.svg"],
"bad": ["semicircle.svg","glass.svg","bowl3.svg","halforange.svg","dice.svg"]
},
{
"instructions": qsTr("Place the objects matching a PARALLELOGRAM to right and others to the left"),
"image": imagesPrefix + "parallelogram.svg",
"maxNumberOfGood": 5,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/data/words/shapes/",
"good": ["pgram1.svg","pgram2.svg","pgram3.svg","paper.svg","rectangle_led.svg",],
"bad": ["globe.svg","heptagon.svg","pizza.svg","trapezium4.svg"]
},
{
"instructions": qsTr("Place the objects matching a HEPTAGON to right and others to the left"),
"image": imagesPrefix + "heptagon.svg",
"maxNumberOfGood": 4,
"maxNumberOfBad": 5,
"prefix": "qrc:/gcompris/data/words/shapes/",
"good": ["heptagon1.svg","heptagon2.svg","heptagon3.svg","heptagon4.svg"],
"bad": ["nonagon4.svg","octagon1.svg","decagon2.svg","pentagon1.svg","hexagon4.svg"]
},
{
"instructions": qsTr("Place the objects matching a CUBE to right and others to the left"),
"image": imagesPrefix + "cube.svg",
"maxNumberOfGood": 5,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/data/words/shapes/",
"good": ["icecube.svg","cube1.svg","dice.svg","rubikscube.svg","rubikscube1.svg"],
"bad": ["juice2.svg","cuboid1.svg","stickynote.svg","backcard.svg"]
},
{
"instructions": qsTr("Place the objects matching a RHOMBUS to right and others to the left"),
"image": imagesPrefix + "rhombus1.svg",
"maxNumberOfGood": 4,
"maxNumberOfBad": 5,
"prefix": "qrc:/gcompris/data/words/shapes/",
"good": ["rainbowsquare.svg","rhombus2.svg","ledsquare.svg","rhombus4.svg"],
"bad": ["hexagon.svg","parallelogram.svg","pentagon4.svg","pgram1.svg","trapezium2.svg"]
},
{
"instructions": qsTr("Place the objects matching a NONAGON to right and others to the left"),
"image": imagesPrefix + "nonagon.svg",
"maxNumberOfGood": 4,
"maxNumberOfBad": 5,
"prefix": "qrc:/gcompris/data/words/shapes/",
"good": ["nonagon1.svg","nonagon4.svg","nonagon2.svg","nonagon3.svg"],
"bad": ["pgram2.svg","diceface.svg","octagon2.svg","decagon1.svg","decagon2.svg"],
},
{
"instructions": qsTr("Place the objects matching a CUBOID to right and others to the left"),
"image": imagesPrefix + "cuboid.svg",
"maxNumberOfGood": 5,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/data/words/shapes/",
"good": ["dice.svg","rubikscube.svg","cuboid1.svg","juice2.svg","cube1.svg"],
"bad": ["backcard.svg","cone.svg","pizza.svg","trash.svg"]
},
{
"instructions": qsTr("Place the objects matching a HEXAGON to right and others to the left"),
"image": imagesPrefix + "hexagon.svg",
"maxNumberOfGood": 4,
"maxNumberOfBad": 5,
"prefix": "qrc:/gcompris/data/words/shapes/",
"good": ["hexagon2.svg","hexagon3.svg","hexagon4.svg","hexagon1.svg"],
"bad": ["rhombus1.svg","pgram2.svg","heptagon1.svg","pentagon3.svg","trapezium2.svg"]
},
{
"instructions": qsTr("Place the objects matching an OCTAGON to right and others to the left"),
"image": imagesPrefix + "octagon.svg",
"maxNumberOfGood": 4,
"maxNumberOfBad": 5,
"prefix": "qrc:/gcompris/data/words/shapes/",
"good": ["octagon2.svg","octagon3.svg","octagon4.svg","octagon1.svg"],
"bad": ["rectangle_led.svg","decagon2.svg","hexagon2.svg","heptagon1.svg","nonagon2.svg"]
},
{
"instructions": qsTr("Place the objects matching a CYLINDER to right and others to the left"),
"image": imagesPrefix + "cylinder.svg",
"maxNumberOfGood": 5,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/data/words/shapes/",
"good": ["rolling_pin.png","tin.png","can1.svg","can.svg", "trash.svg"],
"bad": ["halforange.svg","decagon3.svg","wcone.svg","juice2.svg"]
},
{
"instructions": qsTr("Place the objects matching a DECAGON to right and others to the left"),
"image": imagesPrefix + "decagon.svg",
"maxNumberOfGood": 4,
"maxNumberOfBad": 5,
"prefix": "qrc:/gcompris/data/words/shapes/",
"good": ["decagon3.svg","decagon4.svg","decagon1.svg","decagon2.svg"],
"bad": ["hexagon2.svg","nonagon1.svg","nonagon4.svg","octagon2.svg","heptagon1.svg"]
}
]
}
]
}
diff --git a/src/activities/categorization/resource/board/category_tools.qml b/src/activities/categorization/resource/board/category_tools.qml
index 999448a1d..009cbf299 100644
--- a/src/activities/categorization/resource/board/category_tools.qml
+++ b/src/activities/categorization/resource/board/category_tools.qml
@@ -1,126 +1,126 @@
/* GCompris
*
* Copyright (C) 2016 Divyam Madaan <divyam3897@gmail.com>
*
* Authors:
* Divyam Madaan <divyam3897@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property bool isEmbedded: true
property bool allowExpertMode: true
property string imagesPrefix: "qrc:/gcompris/src/activities/categorization/resource/images/tools/"
property var levels: [
{
"type": "lesson",
"name": qsTr("Tools"),
"image": imagesPrefix + "measuringTape.jpg",
"content": [
{
"instructions": qsTr("Place the TOOLS to the right and other objects to the left"),
"image": imagesPrefix + "wrench.jpg",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/src/activities/categorization/resource/images/",
"good": ["tools/clawHammer.jpg", "tools/clawHammer1.jpg","tools/estwingHammer.jpg","tools/framingHammer.jpg","tools/hammer1.jpg","tools/hammer2.jpg"],
"bad": ["monuments/arcDeTriomphe.jpg","others/buffetset.jpg","monuments/cathedral.jpg","others/pillow.jpg","renewable/windmill1.jpg", "renewable/geothermal.jpg"]
},
{
"instructions": qsTr("Place the TOOLS to the right and other objects to the left"),
"image": imagesPrefix + "sideCutter1.jpg",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/src/activities/categorization/resource/images/",
"good": ["tools/measuringTape.jpeg","tools/measuringTape1.jpg","tools/nosePlier.jpg","tools/nosePlier1.jpg","tools/measuringTape3.jpg","tools/measuringTape4.jpg"],
"bad": ["others/pan.jpg","others/blackslate.jpg","monuments/colosseum.jpg","fishes/fish10.jpg","renewable/dam1.jpg","monuments/monument3.jpg"]
},
{
"instructions": qsTr("Place the TOOLS to the right and other objects to the left"),
"image": imagesPrefix + "scissors.jpg",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/src/activities/categorization/resource/images/",
"good": ["tools/scissor1.jpg","tools/scissor2.jpg","tools/scissors.jpg","tools/sprinkler.jpg","tools/tweezer.jpg","tools/wrench1.jpg"],
"bad": ["others/buffetset.jpg","monuments/beandenburgGate.jpg","monuments/parthenon.jpg","fishes/fish12.jpg","fishes/fish16.jpg","others/plate.jpg"]
},
{
"instructions": qsTr("Place the TOOLS to the right and other objects to the left"),
"image": imagesPrefix + "sprinkler.jpg",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/src/activities/categorization/resource/images/",
"good": ["tools/sprinkler.jpg","tools/screwDriver.jpg","tools/screwDriver1.jpg","tools/screwDriver2.jpg","tools/screwDriver3.jpg","tools/plier.jpg"],
"bad": ["others/baseball.jpg","others/igloo.jpg","monuments/mountRushmore.jpg","renewable/dam3.jpg","monuments/greatWall.jpg","renewable/windmill7.jpg"]
},
{
"instructions": qsTr("Place the TOOLS to the right and other objects to the left"),
"image": imagesPrefix + "plier.jpg",
"maxNumberOfGood": 5,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/src/activities/categorization/resource/images/",
"good": ["tools/multimeter.jpg","tools/screwDriver.jpg","tools/hammer3.jpg","tools/measuringTape.jpg","tools/nosePlier.jpg"],
"bad": ["fishes/fish25.jpg","fishes/fish18.jpg","monuments/monument1.jpg","monuments/monument2.jpg"]
},
{
"instructions": qsTr("Place the TOOLS to the right and other objects to the left"),
"image": imagesPrefix + "nosePlier2.jpg",
"maxNumberOfGood": 5,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/src/activities/categorization/resource/images/",
"good": ["tools/wrench.jpg","tools/tweezer1.jpg","tools/sickle.jpg","tools/plier.jpg","tools/sideCutter1.jpg"],
"bad": ["renewable/solar5.jpg","others/bulb.jpg","renewable/dam3.jpg","monuments/leninMuseum.jpg"]
},
{
"instructions": qsTr("Place the TOOLS to the right and other objects to the left"),
"image": imagesPrefix + "multimeter.jpg",
"maxNumberOfGood": 4,
"maxNumberOfBad": 5,
"prefix": "qrc:/gcompris/src/activities/categorization/resource/images/",
"good": ["tools/nosePlier3.jpg","tools/scissor.jpg","tools/plier2.jpg","tools/sideCutter1.jpg"],
"bad": ["fishes/fish3.jpg","others/chair.jpg","monuments/operaHouse.jpg","renewable/windmill12.jpg","monuments/IndiaGate.jpg"]
},
{
"instructions": qsTr("Place the TOOLS to the right and other objects to the left"),
"image": imagesPrefix + "nailCutter.jpg",
"maxNumberOfGood": 3,
"maxNumberOfBad": 3,
"prefix": "qrc:/gcompris/src/activities/categorization/resource/images/",
"good": ["tools/measuringTape2.jpg","tools/hammer5.jpg","tools/plier1.jpg"],
"bad": ["fishes/fish6.jpg","monuments/tajMahal.jpg","renewable/solar3.jpg"]
},
{
"instructions": qsTr("Place the TOOLS to the right and other objects to the left"),
"image": imagesPrefix + "screwDriver.jpg",
"maxNumberOfGood": 3,
"maxNumberOfBad": 3,
"prefix": "qrc:/gcompris/src/activities/categorization/resource/images/",
"good": ["tools/nosePlier2.jpg","tools/multimeter2.jpg","tools/nailCutter.jpg"],
"bad": ["fishes/fish10.jpg","others/pan.jpg","others/igloo.jpg"]
},
{
"instructions": qsTr("Place the TOOLS to the right and other objects to the left"),
"image": imagesPrefix + "scissor.jpg",
"maxNumberOfGood": 3,
"maxNumberOfBad": 3,
"prefix": "qrc:/gcompris/src/activities/categorization/resource/images/",
"good": ["tools/hammer4.jpg","tools/screwDriver.jpg","tools/multimeter1.jpg"],
"bad": ["renewable/dam2.jpg","monuments/leaningTowerOfPisa.jpg", "others/pillow.jpg"]
}
]
}
]
}
diff --git a/src/activities/categorization/resource/board/category_transports.qml b/src/activities/categorization/resource/board/category_transports.qml
index ac42657bf..b5e417cd1 100644
--- a/src/activities/categorization/resource/board/category_transports.qml
+++ b/src/activities/categorization/resource/board/category_transports.qml
@@ -1,127 +1,127 @@
/* GCompris
*
* Copyright (C) 2016 Divyam Madaan <divyam3897@gmail.com>
*
* Authors:
* Divyam Madaan <divyam3897@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject{
property bool isEmbedded: false
property bool allowExpertMode: true
property string imagesPrefix: "qrc:/gcompris/data/words/transport/"
property var levels: [
{
"type": "lesson",
"name": qsTr("Transport"),
"image": imagesPrefix + "balloon.jpg",
"content": [
{
"instructions": qsTr("Place the MEANS OF TRANSPORTATION to the right and other objects to the left"),
"image":imagesPrefix + "tucker.jpg",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/data/words/",
"good": ["transport/autorickshaw.jpg","transport/balloon.jpg","transport/bicycle2.jpg","transport/boat.jpg","transport/bulletTrain.jpg","transport/bullockcart.jpg"],
"bad": ["householdGoods/ac.jpg","householdGoods/heater.jpg","householdGoods/quilt.jpg","food/kathiRoll.jpg","food/icecream.jpg","vegetables/carrots.jpg"]
},
{
"instructions": qsTr("Place the MEANS OF TRANSPORTATION to the right and other objects to the left"),
"image":imagesPrefix + "train1.jpg",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/data/words/",
"good": ["transport/bus.jpg","transport/camel.jpg","transport/car1.jpg","transport/exchanger.jpg","transport/ferry.jpg","transport/flight.jpg"],
"bad": ["householdGoods/coffeeMaker.jpg","householdGoods/curtains.jpg","nature/nature6.jpg","insects/insect10.jpg","householdGoods/lamp.jpg","others/fork.jpg"]
},
{
"instructions": qsTr("Place the MEANS OF TRANSPORTATION to the right and other objects to the left"),
"image":imagesPrefix + "ship.jpg",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/data/words/",
"good": ["transport/helicopter.jpg","transport/metro.jpg","transport/plane.jpg","transport/train5.jpg","transport/rickshaw.jpg","transport/rocket.jpg"],
"bad": ["nature/nature5.jpg","nature/nature8.jpg","food/biryani.jpg","food/skimmedMilk.jpg","fruits/grapes.jpg","fruits/apple.jpg"]
},
{
"instructions": qsTr("Place the MEANS OF TRANSPORTATION to the right and other objects to the left"),
"image":imagesPrefix + "plane.jpg",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/data/words/",
"good": ["transport/bus2.jpg","transport/car2.jpg","transport/ferry1.jpg","transport/ship.jpg","transport/rotorShip.jpg","transport/cycle.jpg"],
"bad": ["vegetables/pumpkin.jpg","householdGoods/oven.jpg","householdGoods/radio1.jpg","food/riceBeans.jpg","fruits/guava.jpg","plants/plant2.jpg","nature/nature14.jpg"]
},
{
"tags": ["transport"],
"instructions": qsTr("Place the MEANS OF TRANSPORTATION to the right and other objects to the left"),
"image":imagesPrefix + "train2.jpg",
"maxNumberOfGood": 5,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/data/words/",
"good": ["transport/tram.jpg","transport/tucker.jpg","transport/bus1.jpg","transport/car1.jpg", "transport/ferry1.jpg"],
"bad": ["insects/insect15.jpg","birds/bird18.jpg","animals/giraffe.jpg","others/street.jpg"]
},
{
"instructions": qsTr("Place the MEANS OF TRANSPORTATION to the right and other objects to the left"),
"image":imagesPrefix + "roadTrain.jpg",
"maxNumberOfGood": 5,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/data/words/",
"good": ["transport/cycle.jpg","transport/helicopter1.jpg","transport/plane1.jpg","transport/train2.jpg","animals/horse.jpg"],
"bad": ["food/hamburger.jpg","householdGoods/electricBlanket.jpg","householdGoods/bed.jpg","vegetables/spinach.jpg"]
},
{
"instructions": qsTr("Place the MEANS OF TRANSPORTATION to the right and other objects to the left"),
"image":imagesPrefix + "car2.jpg",
"maxNumberOfGood": 4,
"maxNumberOfBad": 5,
"prefix": "qrc:/gcompris/data/words/",
"good": ["transport/plane2.jpg","transport/roadTrain.jpg","transport/rocket1.jpg","transport/train4.jpg"],
"bad": ["food/pizza.jpg","householdGoods/toaster.jpg","animals/koala.jpg","birds/bird21.jpg","insects/insect12.jpg"]
},
{
"instructions": qsTr("Place the MEANS OF TRANSPORTATION to the right and other objects to the left"),
"image":imagesPrefix + "ferry.jpg",
"maxNumberOfGood": 3,
"maxNumberOfBad": 3,
"prefix": "qrc:/gcompris/data/words/",
"good": ["transport/car3.jpg","transport/train3.jpg","transport/ship1.jpg"],
"bad": ["householdGoods/almirah.jpg","plants/tree3.jpg","nature/nature17.jpg"]
},
{
"instructions": qsTr("Place the MEANS OF TRANSPORTATION to the right and other objects to the left"),
"image":imagesPrefix + "rocket1.jpg",
"maxNumberOfGood": 2,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/data/words/",
"good": ["transport/car5.jpg","transport/tanker.jpg"],
"bad": ["food/milk.jpg","householdGoods/vacuumCleaner.jpg","insects/insect9.jpg","birds/bird23.jpg"]
},
{
"instructions": qsTr("Place the MEANS OF TRANSPORTATION to the right and other objects to the left"),
"image":imagesPrefix + "cycle.jpg",
"maxNumberOfGood": 3,
"maxNumberOfBad": 3,
"prefix": "qrc:/gcompris/data/words/",
"good": ["transport/plane3.jpg","transport/rickshaw2.jpg","transport/train1.jpg"],
"bad": ["insects/insect18.jpg","vegetables/cauliflower.jpg","nature/nature24.jpg"]
}
]
}
]
}
diff --git a/src/activities/categorization/resource/board/category_vegetables.qml b/src/activities/categorization/resource/board/category_vegetables.qml
index 3ed5ff1db..88daf323b 100644
--- a/src/activities/categorization/resource/board/category_vegetables.qml
+++ b/src/activities/categorization/resource/board/category_vegetables.qml
@@ -1,90 +1,90 @@
/* GCompris
*
* Copyright (C) 2016 Divyam Madaan <divyam3897@gmail.com>
*
* Authors:
* Divyam Madaan <divyam3897@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject{
property bool isEmbedded: false
property bool allowExpertMode: true
property string imagesPrefix: "qrc:/gcompris/data/words/vegetables/"
property var levels: [
{
"type": "lesson",
"name": qsTr("Vegetables"),
"image": imagesPrefix + "vegetablesmix.jpg",
"content": [
{
"instructions": qsTr("Place the VEGETABLES to the right and other objects to the left"),
"image": imagesPrefix + "vegetablesmix.jpg",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/data/words/",
"good": ["vegetables/batatadoce.jpg","vegetables/bittergourd.jpg","vegetables/blackchillies.jpg", "vegetables/aubergine.jpg","vegetables/peas.JPG","vegetables/carrots.jpg"],
"bad": ["fruits/cranberries.jpg","fruits/feiji.jpg","fruits/strwaberry.jpg","fruits/pear.jpg","food/applepie.jpg","food/biryani.jpg","transport/bus.jpg","transport/truck.jpg"]
},
{
"instructions": qsTr("Place the VEGETABLES to the right and other objects to the left"),
"image": imagesPrefix + "vegetablesmix.jpg",
"maxNumberOfGood": 6,
"maxNumberOfBad": 6,
"prefix": "qrc:/gcompris/data/words/",
"good": ["vegetables/cauliflower.jpg","vegetables/chillies.jpg","vegetables/chineseradish.jpg","vegetables/cucumber.jpg","vegetables/dahuisi.jpg","vegetables/garlic.jpg"],
"bad": ["fruits/apple.jpg","fruits/apricot.jpg","fruits/banana.jpg","fruits/berries.jpg","transport/boat.jpg","plants/plant2.jpg","nature/nature6.jpg","householdGoods/quilt.jpg"]
},
{
"instructions": qsTr("Place the VEGETABLES to the right and other objects to the left"),
"image": imagesPrefix + "vegetablesmix.jpg",
"maxNumberOfGood": 4,
"maxNumberOfBad": 5,
"prefix": "qrc:/gcompris/data/words/",
"good": ["vegetables/potato.jpg","vegetables/radish.jpg","vegetables/redchillies.jpg","vegetables/spinach.jpg"],
"bad": ["fruits/billberries.jpg","fruits/cherries.jpg","food/cheese.jpg","birds/bird7.jpg","insects/insect2.jpg"]
},
{
"instructions": qsTr("Place the VEGETABLES to the right and other objects to the left"),
"image": imagesPrefix + "vegetablesmix.jpg",
"maxNumberOfGood": 4,
"maxNumberOfBad": 5,
"prefix": "qrc:/gcompris/data/words/",
"good": ["vegetables/spinaches.jpg","vegetables/taroroot.jpg","vegetables/cauliflower.jpg","vegetables/batatadoce.jpg"],
"bad": ["fruits/kiwi.jpg","householdGoods/vacuumCleaner.jpg","householdGoods/utensils.jpg","food/pizza.jpg","transport/tanker.jpg"]
},
{
"instructions": qsTr("Place the VEGETABLES to the right and other objects to the left"),
"image": imagesPrefix + "vegetablesmix.jpg",
"maxNumberOfGood": 3,
"maxNumberOfBad": 3,
"prefix": "qrc:/gcompris/data/words/",
"good": ["vegetables/mushroom.jpg","vegetables/pumpkin.jpg","vegetables/sweetpotato.jpg"],
"bad": ["fruits/mango.jpg","plants/plant6.jpg","others/electricfan.jpg"]
},
{
"instructions": qsTr("Place the VEGETABLES to the right and other objects to the left"),
"image": imagesPrefix + "vegetablesmix.jpg",
"maxNumberOfGood": 2,
"maxNumberOfBad": 4,
"prefix": "qrc:/gcompris/data/words/",
"good": ["vegetables/zucchini.jpg","vegetables/vegetablesmix.jpg"],
"bad": ["fruits/papaya.jpg","food/sweetBread.jpg","others/clock.jpg","others/pepsi.jpg"]
}
]
}
]
}
diff --git a/src/activities/checkers/ActivityInfo.qml b/src/activities/checkers/ActivityInfo.qml
index be38d195f..2555aaa4d 100644
--- a/src/activities/checkers/ActivityInfo.qml
+++ b/src/activities/checkers/ActivityInfo.qml
@@ -1,43 +1,43 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2017 Johnny Jazeix <jazeix@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "checkers/Checkers.qml"
difficulty: 4
icon: "checkers/checkers.svg"
author: "Johnny Jazeix &lt;jazeix@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Play checkers against the computer")
//: Help title
description: qsTr("The version in GCompris is the international draughts.")
//intro: "play checkers against the computer"
//: Help goal
- goal: qsTr("Capture all the pieces of your opponent before your opponent capture all of yours.")
+ goal: qsTr("Capture all the pieces of your opponent before your opponent captures all of yours.")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("Checkers is played by two opponents, on opposite sides of the gameboard. One player has the dark pieces; the other has the light pieces. Players alternate turns. A player may not move an opponent's piece. A move consists of moving a piece diagonally to an adjacent unoccupied square. If the adjacent square contains an opponent's piece, and the square immediately beyond it is vacant, the piece may be captured (and removed from the game) by jumping over it.
Only the dark squares of the checkered board are used. A piece may move only diagonally into an unoccupied square. Capturing is mandatory. The player without pieces remaining, or who cannot move due to being blocked, loses the game.
When a man reaches the crownhead or kings row (the farthest row forward), it becomes a king, and is marked by placing an additional piece on top of the first man, and acquires additional powers including the ability to move backwards. If there is a piece in a diagonal that a king can capture, he can move any distance along the diagonal, and may capture an opposing man any distance away by jumping to any of the unoccupied squares immediately beyond it.
")
credit: qsTr("The checkers library is draughts.js &lt;https://github.com/shubhendusaurabh/draughts.js&gt;. Manual is from wikipedia &lt;https://en.wikipedia.org/wiki/Draughts&gt;")
section: "strategy"
createdInVersion: 8000
}
diff --git a/src/activities/checkers/Checkers.qml b/src/activities/checkers/Checkers.qml
index 08433aac3..574d796fd 100644
--- a/src/activities/checkers/Checkers.qml
+++ b/src/activities/checkers/Checkers.qml
@@ -1,466 +1,490 @@
/* GCompris - checkers.qml
*
* Copyright (C) 2017 Johnny Jazeix <jazeix@gmail.com>
*
* Authors:
* Johnny Jazeix <jazeix@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import QtQuick.Controls 1.5
import QtQuick.Controls.Styles 1.4
import GCompris 1.0
import "../../core"
import "."
import "checkers.js" as Activity
ActivityBase {
id: activity
property bool acceptClick: true
property bool twoPlayers: false
// difficultyByLevel means that at level 1 computer is bad better at last level
property bool difficultyByLevel: true
onStart: focus = true
onStop: {}
pageComponent: Image {
id: background
anchors.fill: parent
source: Activity.url + 'background-wood.svg'
signal start
signal stop
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property GCSfx audioEffects: activity.audioEffects
property alias background: background
property alias bar: bar
property alias bonus: bonus
property int barHeightAddon: ApplicationSettings.isBarHidden ? 1 : 3
- property bool isPortrait: (background.height > background.width)
+ property bool isPortrait: (background.height >= background.width)
property int cellSize: items.isPortrait ?
Math.min(background.width / (items.numberOfCases + 2),
(background.height - controls.height) / (items.numberOfCases + barHeightAddon)) :
Math.min(background.width / (items.numberOfCases + 2), background.height / (items.numberOfCases + barHeightAddon))
property var fen: activity.fen
property bool twoPlayer: activity.twoPlayers
property bool difficultyByLevel: activity.difficultyByLevel
property var positions
property var pieces: pieces
property var squares: squares
property var history
property var redo_stack
property alias redoTimer: redoTimer
property int from
property bool blackTurn
property bool gameOver
property var movesToDo: []
property string message
property alias trigComputerMove: trigComputerMove
property int numberOfCases: 10
Behavior on cellSize { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 1000 } }
}
onStart: { Activity.start(items) }
onStop: { Activity.stop() }
Grid {
anchors {
top: parent.top
topMargin: items.isPortrait ? 0 : items.cellSize / 2
leftMargin: 10 * ApplicationInfo.ratio
rightMargin: 10 * ApplicationInfo.ratio
}
columns: (items.isPortrait==true) ? 1 : 3
rows: (items.isPortrait==true) ? 2 : 1
width: (items.isPortrait==true) ? undefined : background.width
anchors.horizontalCenter: parent.horizontalCenter
spacing: 10
horizontalItemAlignment: Grid.AlignHCenter
verticalItemAlignment: Grid.AlignVCenter
Column {
id: controls
anchors {
leftMargin: 10
rightMargin: 10
}
width: items.isPortrait ?
parent.width :
Math.max(undo.width * 1.2,
Math.min(
(background.width * 0.9 - undo.width - chessboard.width),
(background.width - chessboard.width) / 2))
GCText {
color: "white"
anchors.horizontalCenter: parent.horizontalCenter
width: parent.width
fontSize: smallSize
text: items.message
horizontalAlignment: Text.AlignHCenter
wrapMode: TextEdit.WordWrap
}
Grid {
- spacing: 10
+ spacing: 60 * ApplicationInfo.ratio
columns: items.isPortrait ? 3 : 1
anchors.horizontalCenter: parent.horizontalCenter
horizontalItemAlignment: Grid.AlignHCenter
verticalItemAlignment: Grid.AlignVCenter
Button {
id: undo
height: 30 * ApplicationInfo.ratio
- text: qsTr("Undo");
+ width: height
+ text: "";
style: GCButtonStyle { theme: "light" }
onClicked: Activity.undo()
enabled: (items.history && items.history.length > 0) ? true : false
opacity: enabled ? 1 : 0
+ Image {
+ source: 'qrc:/gcompris/src/activities/chess/resource/undo.svg'
+ height: parent.height
+ width: height
+ sourceSize.height: height
+ fillMode: Image.PreserveAspectFit
+ }
Behavior on opacity {
PropertyAnimation {
easing.type: Easing.InQuad
duration: 200
}
}
}
Button {
id: redo
- height: 30 * ApplicationInfo.ratio
- text: qsTr("Redo");
+ height: undo.height
+ width: undo.height
+ text: "";
style: GCButtonStyle { theme: "light" }
onClicked: {
Activity.redo()
}
enabled: items.redo_stack.length > 0 && acceptClick ? 1 : 0
opacity: enabled
+ Image {
+ source: 'qrc:/gcompris/src/activities/chess/resource/redo.svg'
+ height: parent.height
+ width: height
+ sourceSize.height: height
+ fillMode: Image.PreserveAspectFit
+ }
Behavior on opacity {
PropertyAnimation {
easing.type: Easing.InQuad
duration: 200
}
}
}
Button {
- height: 30 * ApplicationInfo.ratio
- text: qsTr("Swap");
+ height: undo.height
+ width: undo.height
+ text: "";
style: GCButtonStyle { theme: "light" }
enabled: items.twoPlayer
opacity: enabled
+ Image {
+ source: 'qrc:/gcompris/src/activities/chess/resource/turn.svg'
+ height: parent.height
+ width: height
+ sourceSize.height: height
+ fillMode: Image.PreserveAspectFit
+ }
onClicked: chessboard.swap()
}
}
}
Rectangle {
- id:boardBg
+ id: boardBg
width: items.cellSize * (items.numberOfCases + 0.2)
height: items.cellSize * (items.numberOfCases + 0.2)
z: 09
color: "#2E1B0C"
// The chessboard
GridView {
id: chessboard
cellWidth: items.cellSize
cellHeight: items.cellSize
width: items.cellSize * items.numberOfCases
height: items.cellSize * items.numberOfCases
interactive: false
keyNavigationWraps: true
model: items.numberOfCases*items.numberOfCases
layoutDirection: Qt.RightToLeft
delegate: square
rotation: 180
z: 10
anchors.centerIn: boardBg
Component {
id: square
Image {
source: index % 2 + (Math.floor(index / items.numberOfCases) % 2) == 1 ?
Activity.url + 'checkers-white.svg' : Activity.url + 'checkers-black.svg';
width: items.cellSize
height: items.cellSize
}
}
Behavior on rotation { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 1400 } }
function swap() {
items.audioEffects.play('qrc:/gcompris/src/core/resource/sounds/flip.wav')
if(chessboard.rotation == 180)
chessboard.rotation = 0
else
chessboard.rotation = 180
}
}
}
}
Repeater {
id: squares
model: items.positions
delegate: square
parent: chessboard
DropArea {
id: square
x: items.cellSize * (9 - pos % items.numberOfCases) + spacing / 2
y: items.cellSize * Math.floor(pos / items.numberOfCases) + spacing / 2
width: items.cellSize - spacing
height: items.cellSize - spacing
z: 1
keys: acceptMove ? ['acceptMe'] : ['sorryNo']
property bool acceptMove: false
property bool jumpable: false
property int pos: modelData.pos
property int spacing: 6 * ApplicationInfo.ratio
Rectangle {
id: possibleMove
anchors.fill: parent
color: parent.containsDrag ? '#803ACAFF' : 'transparent'
border.width: parent.acceptMove || parent.jumpable ? 5 : 0
border.color: parent.acceptMove ? '#FF808080' : '#C0808080'
radius: parent.acceptMove ? width*0.5 : 0
z: 1
}
}
function getSquareAt(pos) {
for(var i=0; i < squares.count; i++) {
if(squares.itemAt(i).pos === pos)
return squares.itemAt(i)
}
return undefined
}
}
Repeater {
id: pieces
model: items.positions
delegate: piece
parent: chessboard
Piece {
id: piece
sourceSize.width: items.cellSize
width: items.cellSize - spacing
height: items.cellSize - spacing
source: img ? Activity.url + img + '.svg' : ''
img: modelData.img
x: items.cellSize * (items.numberOfCases - 1 - pos % items.numberOfCases) + spacing / 2
y: items.cellSize * Math.floor(pos / items.numberOfCases) + spacing / 2
z: 1
pos: modelData.pos
newPos: modelData.pos
rotation: - chessboard.rotation
property int spacing: 6 * ApplicationInfo.ratio
Drag.active: dragArea.drag.active
Drag.hotSpot.x: width / 2
Drag.hotSpot.y: height / 2
MouseArea {
id: dragArea
anchors.fill: parent
enabled: !items.gameOver
drag.target: parent
onPressed: {
piece.Drag.keys = ['acceptMe']
parent.z = 100
if(parent.isWhite == 1 && !items.blackTurn ||
parent.isWhite == 0 && items.blackTurn) {
items.from = parent.newPos
Activity.showPossibleMoves(items.from)
} else if(items.from != -1 && squares.getSquareAt(parent.newPos)['acceptMove']) {
Activity.moveTo(items.from, parent.newPos)
}
}
onReleased: {
// If no target or move not possible, we reset the position
if(!piece.Drag.target || (items.from != -1 && !Activity.moveTo(items.from, piece.Drag.target.pos))) {
var pos = parent.pos
// Force recalc of the old x,y position
parent.pos = -1
if(pieces.getPieceAt(pos))
pieces.getPieceAt(pos).move(pos)
}
}
}
}
function moveTo(from, to, moves) {
items.movesToDo.push({"from": from, "to": to, "move": moves});
if(items.movesToDo.length == 1) {
moveInternal();
}
}
function moveInternal() {
var moveToDo = items.movesToDo[0]
var from = moveToDo.from;
var to = moveToDo.to;
var moves = moveToDo.move;
var fromPiece = getPieceAt(from)
var toPiece = getPieceAt(to)
if(moves.jumps.length != 0)
items.audioEffects.play('qrc:/gcompris/src/core/resource/sounds/smudge.wav')
else
items.audioEffects.play('qrc:/gcompris/src/core/resource/sounds/scroll.wav')
toPiece.hide(from)
movingPiece = fromPiece
- if(moves.jumps.length != 0) {
+ if(moves.jumps.length !== 0) {
listJumps = moves.jumps
}
else {
// create the move if needed
listJumps = [Activity.viewPosToEngine(from), Activity.viewPosToEngine(to)]
}
}
function promotion(to) {
var toPiece = getPieceAt(to)
toPiece.promotion()
}
function getPieceAt(pos) {
for(var i=0; i < pieces.count; i++) {
- if(pieces.itemAt(i).newPos == pos)
+ if(pieces.itemAt(i).newPos === pos)
return pieces.itemAt(i)
}
return undefined
}
}
property var movingPiece: undefined
property var listJumps
property bool restartNeeded: false
onListJumpsChanged: {
if(listJumps.length >= 2) {
if(!animationTimer.isRunning)
animationTimer.restart();
else
restartNeeded = true;
}
}
SequentialAnimation {
id: animationTimer
onRunningChanged: {
if(!running && restartNeeded)
start()
}
ScriptAction {
script: {
restartNeeded = false
var to = Activity.engineToViewPos(listJumps[1])
movingPiece.move(to)
}
}
PauseAnimation { duration: 200 }
ScriptAction {
script: {
listJumps.shift()
// only shifting does not trigger the onChanged
var tmp = listJumps
listJumps = tmp
// only change player once all the jumps have been done
- if(listJumps.length == 1) {
+ if(listJumps.length === 1) {
items.movesToDo.shift()
if(items.movesToDo.length > 0) {
pieces.moveInternal()
}
else {
Activity.refresh()
movingPiece = undefined
}
}
}
}
}
Timer {
id: trigComputerMove
repeat: false
interval: 400
onTriggered: Activity.randomMove()
}
// Use to redo the computer move after the user move
Timer {
id: redoTimer
repeat: false
interval: 400
onTriggered: {
acceptClick = true;
Activity.moveByEngine(move)
}
property var move
function moveByEngine(engineMove) {
move = engineMove
redoTimer.start()
}
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | (items.twoPlayer ? 0 : level) |
(items.twoPlayer && !items.gameOver ? 0 : reload) }
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
onReloadClicked: {
trigComputerMove.stop()
Activity.initLevel()
}
}
Bonus {
id: bonus
}
}
}
diff --git a/src/activities/checkers/Piece.qml b/src/activities/checkers/Piece.qml
index cb075f89c..4778ab138 100644
--- a/src/activities/checkers/Piece.qml
+++ b/src/activities/checkers/Piece.qml
@@ -1,113 +1,113 @@
/* GCompris - chess.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
Image {
id: piece
property int pos
Behavior on opacity { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 200 } }
Behavior on x { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 200 } }
Behavior on y { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 200 } }
z: 10
property string img
property bool acceptMove: false
property int newPos
// color = -1 if no piece, 0 is black and 1 is white
property int isWhite: img[0] == 'w' ? 1 : img[0] == 'b' ? 0 : -1
onImgChanged: {
if(img == 'W')
img = 'wk'
else if(img == 'B')
img = 'bk'
}
SequentialAnimation {
id: hideAnim
NumberAnimation {
target: piece
property: "scale"
duration: 200
to: 0
}
PropertyAction {
target: piece
property: 'img'
value: ""
}
PropertyAction {
target: piece
property: 'pos'
value: piece.newPos
}
PropertyAction {
target: piece
property: 'scale'
value: 1
}
PropertyAction {
target: piece
property: 'z'
value: 2
}
}
SequentialAnimation {
id: promotionAnim
PauseAnimation {
duration: 200
}
NumberAnimation {
target: piece
property: 'scale'
to: 0
}
PropertyAction {
target: piece
property: 'img'
value: isWhite ? 'wk' : 'bk'
}
NumberAnimation {
target: piece
property: 'scale'
to: 1
easing.type: Easing.OutElastic
}
}
function hide(newPos) {
piece.newPos = newPos
hideAnim.start()
}
function promotion() {
promotionAnim.start()
}
function move(to) {
piece.newPos = to
piece.pos = to
piece.z = 2
}
}
diff --git a/src/activities/checkers/checkers.js b/src/activities/checkers/checkers.js
index c145a8977..205f46350 100644
--- a/src/activities/checkers/checkers.js
+++ b/src/activities/checkers/checkers.js
@@ -1,364 +1,364 @@
/* GCompris - checkers.js
*
* Copyright (C) 2017 Johnny Jazeix <jazeix@gmail.com>
*
* Authors:
* Johnny Jazeix <jazeix@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
.import "qrc:/gcompris/src/core/core.js" as Core
.import "engine.js" as Engine
var url = "qrc:/gcompris/src/activities/checkers/resource/"
var currentLevel
var numberOfLevel = 5
var items
var state
function start(items_) {
items = items_
currentLevel = 0
initLevel()
}
function stop() {
}
function initLevel() {
items.bar.level = currentLevel + 1
state = new Engine.Draughts('W:W31-50:B1-20')
- state.reset()
+ state.resetGame()
items.from = -1
items.gameOver = false
items.redo_stack = []
refresh()
items.positions = 0 // Force a model reload
items.positions = simplifiedState(state.position())
clearAcceptMove()
}
function nextLevel() {
if(numberOfLevel <= ++currentLevel) {
currentLevel = 0
}
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
initLevel();
}
function simplifiedState(position) {
var newState = new Array()
for(var i = 0; i < position.length; ++i) {
var img = position[i] !== '0' && position[i] !== '?' ? position[i] : ''
newState.push(
{
'pos': engineToViewPos(i),
'img': img
})
}
return newState
}
function updateMessage() {
items.gameOver = false
items.message = items.blackTurn ? qsTr("Black's turn") : qsTr("White's turn")
if(state.gameOver()) {
items.message = items.blackTurn ? qsTr("White wins") : qsTr("Black wins")
items.gameOver = true
if(!items.twoPlayer)
if(items.blackTurn)
items.bonus.good('gnu')
else
items.bonus.good('tux')
else
items.bonus.good('flower')
}
}
function refresh() {
- items.blackTurn = (state.turn() == 'b')
+ items.blackTurn = (state.getTurn() == 'b')
items.history = state.history()
updateMessage()
items.positions = 0 // Force a model reload
items.positions = simplifiedState(state.position())
}
// Convert view position (QML) to the chess engine coordinate
//
// engine view:
// | 01 02 03 04 05|
// |06 07 08 09 10 |
// | 11 12 13 14 15|
// |16 17 18 19 20 |
// | 21 22 23 24 25|
// |26 27 28 29 30 |
// | 31 32 33 34 35|
// |36 37 38 39 40 |
// | 41 42 43 44 45|
// |46 47 48 49 50 |
//
// QML view:
// | 91 93 95 97 99|
// |80 82 84 86 88 |
// | 71 73 75 77 79|
// |60 62 64 66 68 |
// | 51 53 55 57 59|
// |40 42 44 46 48 |
// | 31 33 35 37 39|
// |20 22 24 26 28 |
// | 11 13 15 17 19|
// |00 02 04 06 08 |
//
function viewPosToEngine(pos) {
var casesNumber = items.numberOfCases*items.numberOfCases
var a = 10 * Math.floor((casesNumber - pos) / 10 + 1);
var b = 20;
if(pos % 10 !== 0) {
b = (casesNumber - pos) % 10;
}
var newPos = (a - b + 1)
newPos = Math.floor(newPos / 2 + 0.5)
return newPos
}
// Convert chess engine coordinate to view position (QML)
function engineToViewPos(pos) {
var newPos = 90-10*Math.floor((2*pos-1)/10)+2*((pos-1)%5)+1+((-1+Math.pow(-1, Math.floor((2*pos-1)/10)))/2)
return newPos
}
// move is the result from the engine move
function visibleMove(move, from, to) {
var piece = items.pieces.getPieceAt(from);
items.pieces.moveTo(from, to, move)
// promotion
if (move.to <= 5 && piece.img === 'w')
piece.promotion()
else if (move.to >= 46 && piece.img === 'b')
piece.promotion()
}
function findBestMove(currentState, depth, sign) {
if(depth <= 0) {
return getScore(currentState);
}
var moves = currentState.moves()
- if(moves.length == 0) {
+ if(moves.length === 0) {
return [100, 0];
}
var bestScore = -1000;
var bestScores;
for(var move in moves) {
currentState.move(moves[move]);
var newScore = findBestMove(currentState, depth-1, -1.0*sign)
currentState.undo()
var score = sign*(newScore[0] - newScore[1])
if(score > bestScore) {
bestScore = score;
bestScores = newScore;
}
}
return bestScores
}
function computerMove() {
var moves = state.moves()
var bestScore = -1000
var bestMoves = []
var newState = new Engine.Draughts(state.fen())
// 0 is b, 1 is b -> w, 2 is b -> w -> b guesses
- var depth = currentLevel == 5 ? 2 : 1;
+ var depth = currentLevel === 5 ? 2 : 1;
for(var move in moves) {
newState.move(moves[move]);
var newScore = findBestMove(newState, depth, 1)
newState.undo()
var score = newScore[1] - newScore[0]
if(bestMoves.length == 0 || bestScore < score) {
bestScore = score
bestMoves = []
bestMoves.push(moves[move])
}
else if(bestScore == score) {
bestMoves.push(moves[move])
}
}
bestMoves = Core.shuffle(bestMoves)
var computer = bestMoves[0]
var move = state.move({"from": computer.from, "to": computer.to})
if(move) {
visibleMove(move, engineToViewPos(computer.from), engineToViewPos(computer.to))
}
return move
}
function moveTo(from, to) {
var move = state.move({"from": viewPosToEngine(from), "to": viewPosToEngine(to)})
if(move) {
visibleMove(move, from, to)
clearAcceptMove()
items.redo_stack = []
if(!items.twoPlayer && !state.gameOver())
items.trigComputerMove.start()
items.from = -1;
} else {
// Probably a check makes the move is invalid
updateMessage(move)
}
return move
}
function undo() {
var move = state.undo();
var redo_stack = items.redo_stack
redo_stack.push(move)
// In computer mode, the white always starts, take care
// of undo after a mate which requires us to revert on
// a white play
- if(!items.twoPlayer && state.turn() == 'b') {
+ if(!items.twoPlayer && state.getTurn() === 'b') {
move = state.undo();
redo_stack.push(move)
}
items.redo_stack = redo_stack
refresh()
}
function moveByEngine(engineMove) {
if(!engineMove)
return
var move = state.move(engineMove)
visibleMove(move, engineToViewPos(engineMove.from), engineToViewPos(engineMove.to))
}
function redo() {
var redo_stack = items.redo_stack
var move = redo_stack.pop()
moveByEngine(move)
// In computer mode, the white always starts, take care
// of undo after a mate which requires us to revert on
// a white play
- if(!items.twoPlayer && state.turn() == 'b') {
+ if(!items.twoPlayer && state.getTurn() === 'b') {
move = redo_stack.pop()
moveByEngine(move)
}
// Force refresh
items.redo_stack = []
items.redo_stack = redo_stack
clearAcceptMove()
}
// Random move depending on the level
function randomMove() {
if(!items.difficultyByLevel) {
computerMove()
return
}
// Disable random move if the situation is too bad for the user
// This avoid having the computer playing bad against a user
// with too few pieces making the game last too long
var score = getScore(state)
if(score[0] / score[1] < 0.7) {
computerMove()
return
}
// At level 2 we let the computer play 20% of the time
// and 80% of the time we make a random move.
if(Math.random() < currentLevel / (numberOfLevel - 1)) {
computerMove()
return
}
// Get all possible moves
var moves = state.moves()
moves = Core.shuffle(moves)
var move = state.move(moves[0])
if(move) {
visibleMove(move, engineToViewPos(moves[0].from), engineToViewPos(moves[0].to))
} else {
// Bad move, should not happen
computerMove()
}
}
// Clear all accept move marker from the chessboard
function clearAcceptMove() {
for(var i=0; i < 50; ++i) {
var square = items.squares.getSquareAt(engineToViewPos(i))
if(square) {
square['acceptMove'] = false
square['jumpable'] = false
}
}
}
// Highlight the possible moves for the piece at position 'from'
function showPossibleMoves(from) {
var fromEngine = viewPosToEngine(from)
var result = state.moves();
clearAcceptMove()
for(var i=0; i < result.length; ++i) {
if(fromEngine === result[i].from) {
var pos = engineToViewPos(result[i].to)
items.squares.getSquareAt(pos)['acceptMove'] = true
for(var v = 1; v < result[i].jumps.length; ++ v) {
items.squares.getSquareAt(engineToViewPos(result[i].jumps[v]))['jumpable'] = true
}
}
}
}
// Calculate the score for black and white
// Count the number of pieces with each piece having a given weight
// Piece pawn queen
// Value 1 4
// @return [white, black]
function getScore(board) {
var white = 0
var black = 0
var queenScore = 4
var position = board.position()
for(var i = 0; i < position.length; ++i) {
var img = position[i] !== '0' && position[i] !== '?' ? position[i] : ''
- if(img == '')
+ if(img === '')
continue;
- else if(img == 'w') {
+ else if(img === 'w') {
white ++;
}
- else if(img == 'W') {
+ else if(img === 'W') {
white += queenScore;
}
- if(img == 'b') {
+ if(img === 'b') {
black ++;
}
- else if(img == 'B') {
+ else if(img === 'B') {
black += queenScore;
}
}
return [white, black]
}
diff --git a/src/activities/checkers/engine.js b/src/activities/checkers/engine.js
index b03de9725..f2ccbdbda 100644
--- a/src/activities/checkers/engine.js
+++ b/src/activities/checkers/engine.js
@@ -1,1273 +1,1273 @@
/*
||==================================================================================
|| DESCRIPTION OF IMPLEMENTATION PRINCIPLES
|| A. Position for rules (internal representation): string with length 56.
|| Special numbering for easy applying rules.
|| Valid characters: b B w W 0 -
|| b (black) B (black king) w (white) W (white king) 0 (empty) (- unused)
|| Examples:
|| '-bbbBBB000w-wwWWWwwwww-bbbbbbbbbb-000wwwwwww-00bbbwwWW0-'
|| '-0000000000-0000000000-0000000000-0000000000-0000000000-' (empty position)
|| '-bbbbbbbbbb-bbbbbbbbbb-0000000000-wwwwwwwwww-wwwwwwwwww-' (start position)
|| B. Position (external respresentation): string with length 51.
|| Square numbers are represented by the position of the characters.
|| Position 0 is reserved for the side to move (B or W)
|| Valid characters: b B w W 0
|| b (black) B (black king) w (white) W (white king) 0 (empty)
|| Examples:
|| 'B00000000000000000000000000000000000000000000000000' (empty position)
|| 'Wbbbbbbbbbbbbbbbbbbbb0000000000wwwwwwwwwwwwwwwwwwww' (start position)
|| 'WbbbbbbBbbbbb00bbbbb000000w0W00ww00wwwwww0wwwwwwwww' (random position)
||
|| External numbering Internal Numbering
|| -------------------- --------------------
|| 01 02 03 04 05 01 02 03 04 05
|| 06 07 08 09 10 06 07 08 09 10
|| 11 12 13 14 15 12 13 14 15 16
|| 16 17 18 19 20 17 18 19 20 21
|| 21 22 23 24 25 23 24 25 26 27
|| 26 27 28 29 30 28 29 30 31 32
|| 31 32 33 34 35 34 35 36 37 38
|| 36 37 38 39 40 39 40 41 42 43
|| 41 42 43 44 45 45 46 47 48 49
|| 46 47 48 49 50 50 51 52 53 54
|| -------------------- --------------------
||
|| Internal numbering has fixed direction increments for easy applying rules:
|| NW NE -5 -6
|| \ / \ /
|| sQr >> sQr
|| / \ / \
|| SW SE +5 +6
||
|| DIRECTION-STRINGS
|| Strings of variable length for each of four directions at one square.
|| Each string represents the position in that direction.
|| Directions: NE, SE, SW, NW (wind directions)
|| Example for square 29 (internal number):
|| NE: 29, 24, 19, 14, 09, 04 b00bb0
|| SE: 35, 41, 47, 53 bww0
|| SW: 34, 39 b0
|| NW: 23, 17 bw
|| CONVERSION internal to external representation of numbers.
|| N: external number, values 1..50
|| M: internal number, values 0..55 (invalid 0,11,22,33,44,55)
|| Formulas:
|| M = N + floor((N-1)/10)
|| N = M - floor((M-1)/11)
||
||==================================================================================
*/
var Draughts = function (fen) {
var BLACK = 'B'
var WHITE = 'W'
// var EMPTY = -1
var MAN = 'b'
var KING = 'w'
var SYMBOLS = 'bwBW'
var DEFAULT_FEN = 'W:W31-50:B1-20'
var position
var DEFAULT_POSITION_INTERNAL = '-bbbbbbbbbb-bbbbbbbbbb-0000000000-wwwwwwwwww-wwwwwwwwww-'
var DEFAULT_POSITION_EXTERNAL = 'Wbbbbbbbbbbbbbbbbbbbb0000000000wwwwwwwwwwwwwwwwwwww'
var STEPS = {NE: -5, SE: 6, SW: 5, NW: -6}
var POSSIBLE_RESULTS = ['2-0', '0-2', '1-1', '0-0', '*', '1-0', '0-1']
var FLAGS = {
NORMAL: 'n',
CAPTURE: 'c',
PROMOTION: 'p'
}
var UNICODES = {
'w': '\u26C0',
'b': '\u26C2',
'B': '\u26C3',
'W': '\u26C1',
'0': '\u0020\u0020'
}
var SIGNS = {
n: '-',
c: 'x'
}
var BITS = {
NORMAL: 1,
CAPTURE: 2,
PROMOTION: 4
}
var turn = WHITE
var moveNumber = 1
var history = []
var header = {}
if (!fen) {
position = DEFAULT_POSITION_INTERNAL
load(DEFAULT_FEN)
} else {
position = DEFAULT_POSITION_INTERNAL
load(fen)
}
function clear () {
position = DEFAULT_POSITION_INTERNAL
turn = WHITE
moveNumber = 1
history = []
header = {}
update_setup(generate_fen())
}
function reset () {
load(DEFAULT_FEN)
}
function load (fen) {
// TODO for default fen
if (!fen || fen === DEFAULT_FEN) {
position = DEFAULT_POSITION_INTERNAL
update_setup(generate_fen(position))
return true
}
// fen_constants(dimension) //TODO for empty fens
var checkedFen = validate_fen(fen)
if (!checkedFen.valid) {
console.error('Fen Error', fen, checkedFen)
return false
}
clear()
// remove spaces
fen = fen.replace(/\s+/g, '')
// remove suffixes
fen.replace(/\..*$/, '')
var tokens = fen.split(':')
// which side to move
turn = tokens[0].substr(0, 1)
// var positions = new Array()
var externalPosition = DEFAULT_POSITION_EXTERNAL
for (var i = 1; i <= externalPosition.length; i++) {
externalPosition = setCharAt(externalPosition, i, 0)
}
externalPosition = setCharAt(externalPosition, 0, turn)
// TODO refactor
for (var k = 1; k <= 2; k++) {
// TODO called twice
var color = tokens[k].substr(0, 1)
var sideString = tokens[k].substr(1)
if (sideString.length === 0) continue
var numbers = sideString.split(',')
for (i = 0; i < numbers.length; i++) {
var numSquare = numbers[i]
var isKing = (numSquare.substr(0, 1) === 'K')
numSquare = (isKing === true ? numSquare.substr(1) : numSquare) // strip K
var range = numSquare.split('-')
if (range.length === 2) {
var from = parseInt(range[0], 10)
var to = parseInt(range[1], 10)
for (var j = from; j <= to; j++) {
externalPosition = setCharAt(externalPosition, j, (isKing === true ? color.toUpperCase() : color.toLowerCase()))
}
} else {
numSquare = parseInt(numSquare, 10)
externalPosition = setCharAt(externalPosition, numSquare, (isKing === true ? color.toUpperCase() : color.toLowerCase()))
}
}
}
position = convertPosition(externalPosition, 'internal')
update_setup(generate_fen(position))
return true
}
function validate_fen (fen) {
var errors = [
{
code: 0,
message: 'no errors'
},
{
code: 1,
message: 'fen position not a string'
},
{
code: 2,
message: 'fen position has not colon at second position'
},
{
code: 3,
message: 'fen position has not 2 colons'
},
{
code: 4,
message: 'side to move of fen position not valid'
},
{
code: 5,
message: 'color(s) of sides of fen position not valid'
},
{
code: 6,
message: 'squares of fen position not integer'
},
{
code: 7,
message: 'squares of fen position not valid'
},
{
code: 8,
message: 'empty fen position'
}
]
if (typeof fen !== 'string') {
return {valid: false, error: errors[0], fen: fen}
}
fen = fen.replace(/\s+/g, '')
if (fen === 'B::' || fen === 'W::' || fen === '?::') {
return {valid: true, fen: fen + ':B:W'} // exception allowed i.e. empty fen
}
fen = fen.trim()
fen = fen.replace(/\..*$/, '')
if (fen === '') {
return {valid: false, error: errors[7], fen: fen}
}
if (fen.substr(1, 1) !== ':') {
return {valid: false, error: errors[1], fen: fen}
}
// fen should be 3 sections separated by colons
var parts = fen.split(':')
if (parts.length !== 3) {
return {valid: false, error: errors[2], fen: fen}
}
// which side to move
var turnColor = parts[0]
if (turnColor !== 'B' && turnColor !== 'W' && turnColor !== '?') {
return {valid: false, error: errors[3], fen: fen}
}
// check colors of both sides
var colors = parts[1].substr(0, 1) + parts[2].substr(0, 1)
if (colors !== 'BW' && colors !== 'WB') {
return {valid: false, error: errors[4], fen: fen}
}
// check parts for both sides
for (var k = 1; k <= 2; k += 1) {
var sideString = parts[k].substr(1) // Stripping color
if (sideString.length === 0) {
continue
}
var numbers = sideString.split(',')
for (var i = 0; i < numbers.length; i++) {
var numSquare = numbers[i]
var isKing = (numSquare.substr(0, 1) === 'K')
numSquare = (isKing === true ? numSquare.substr(1) : numSquare)
var range = numSquare.split('-')
if (range.length === 2) {
if (isInteger(range[0]) === false) {
return {valid: false, error: errors[5], fen: fen, range: range[0]}
}
if (!(range[0] >= 1 && range[0] <= 100)) {
return {valid: false, error: errors[6], fen: fen}
}
if (isInteger(range[1]) === false) {
return {valid: false, error: errors[5], fen: fen}
}
if (!(range[1] >= 1 && range[1] <= 100)) {
return {valid: false, error: errors[6], fen: fen}
}
} else {
if (isInteger(numSquare) === false) {
return {valid: false, error: errors[5], fen: fen}
}
if (!(numSquare >= 1 && numSquare <= 100)) {
return {valid: false, error: errors[6], fen: fen}
}
}
}
}
return {valid: true, error_number: 0, error: errors[0]}
}
function generate_fen () {
var black = []
var white = []
var externalPosition = convertPosition(position, 'external')
for (var i = 0; i < externalPosition.length; i++) {
switch (externalPosition[i]) {
case 'w':
white.push(i)
break
case 'W':
white.push('K' + i)
break
case 'b':
black.push(i)
break
case 'B':
black.push('K' + i)
break
default:
break
}
}
return turn.toUpperCase() + ':W' + white.join(',') + ':B' + black.join(',')
}
function generatePDN (options) {
// for html usage {maxWidth: 72, newline_char: "<br />"}
var newline = (typeof options === 'object' && typeof options.newline_char === 'string')
? options.newline_char : '\n'
var maxWidth = (typeof options === 'object' && typeof options.maxWidth === 'number')
? options.maxWidth : 0
var result = []
var headerExists = false
for (var i in header) {
result.push('[' + i + ' "' + header[i] + '"]' + newline)
headerExists = true
}
if (headerExists && history.length) {
result.push(newline)
}
var tempHistory = clone(history)
var moves = []
var moveString = ''
var moveNumber = 1
while (tempHistory.length > 0) {
var move = tempHistory.shift()
if (move.turn === 'W') {
moveString += moveNumber + '. '
}
moveString += move.move.from
if (move.move.flags === 'c') {
moveString += 'x'
} else {
moveString += '-'
}
moveString += move.move.to
moveString += ' '
moveNumber += 1
}
if (moveString.length) {
moves.push(moveString)
}
// TODO result from pdn or header??
if (typeof header.Result !== 'undefined') {
moves.push(header.Result)
}
if (maxWidth === 0) {
return result.join('') + moves.join(' ')
}
var currentWidth = 0
for (i = 0; i < moves.length; i++) {
if (currentWidth + moves[i].length > maxWidth && i !== 0) {
if (result[result.length - 1] === ' ') {
result.pop()
}
result.push(newline)
currentWidth = 0
} else if (i !== 0) {
result.push(' ')
currentWidth++
}
result.push(' ')
currentWidth += moves[i].length
}
return result.join('')
}
function set_header (args) {
for (var i = 0; i < args.length; i += 2) {
if (typeof args[i] === 'string' && typeof args[i + 1] === 'string') {
header[args[i]] = args[i + 1]
}
}
return header
}
/* called when the initial board setup is changed with put() or remove().
* modifies the SetUp and FEN properties of the header object. if the FEN is
* equal to the default position, the SetUp and FEN are deleted
* the setup is only updated if history.length is zero, ie moves haven't been
* made.
*/
function update_setup (fen) {
if (history.length > 0) {
return false
}
if (fen !== DEFAULT_FEN) {
header['SetUp'] = '1'
header['FEN'] = fen
} else {
delete header['SetUp']
delete header['FEN']
}
}
function parsePDN (pdn, options) {
var newline_char = (typeof options === 'object' &&
typeof options.newline_char === 'string')
? options.newline_char : '\r?\n'
var regex = new RegExp('^(\\[(.|' + mask(newline_char) + ')*\\])' +
'(' + mask(newline_char) + ')*' +
'1.(' + mask(newline_char) + '|.)*$', 'g')
function mask (str) {
return str.replace(/\\/g, '\\')
}
function parsePDNHeader (header, options) {
var headerObj = {}
var headers = header.split(new RegExp(mask(newline_char)))
var key = ''
var value = ''
for (var i = 0; i < headers.length; i++) {
key = headers[i].replace(/^\[([A-Z][A-Za-z]*)\s.*\]$/, '$1')
value = headers[i].replace(/^\[[A-Za-z]+\s"(.*)"\]$/, '$1')
if (trim(key).length > 0) {
headerObj[key] = value
}
}
return headerObj
}
var headerString = pdn.replace(regex, '$1')
if (headerString[0] !== '[') {
headerString = ''
}
reset()
var headers = parsePDNHeader(headerString, options)
for (var key in headers) {
set_header([key, headers[key]])
}
if (headers['Setup'] === '1') {
if (!(('FEN' in headers) && load(headers['FEN']))) {
console.error('fen invalid')
return false
}
} else {
position = DEFAULT_POSITION_INTERNAL
}
/* delete header to get the moves */
var ms = pdn.replace(headerString, '').replace(new RegExp(mask(newline_char), 'g'), ' ')
/* delete comments */
ms = ms.replace(/(\{[^}]+\})+?/g, '')
/* delete recursive annotation variations */
var rav_regex = /(\([^\(\)]+\))+?/g
while (rav_regex.test(ms)) {
ms = ms.replace(rav_regex, '')
}
/* delete move numbers */
// TODO not working for move numbers with space
ms = ms.replace(/\d+\./g, '')
/* delete ... indicating black to move */
ms = ms.replace(/\.\.\./g, '')
/* trim and get array of moves */
var moves = trim(ms).split(new RegExp(/\s+/))
/* delete empty entries */
moves = moves.join(',').replace(/,,+/g, ',').split(',')
var move = ''
for (var half_move = 0; half_move < moves.length - 1; half_move += 1) {
move = getMoveObject(moves[half_move])
if (!move) {
return false
} else {
makeMove(move)
}
}
var result = moves[moves.length - 1]
if (POSSIBLE_RESULTS.indexOf(result) > -1) {
if (headers['Result'] === 'undefined') {
set_header(['Result', result])
}
} else {
move = getMoveObject(result)
if (!move) {
return false
} else {
makeMove(move)
}
}
return true
}
function getMoveObject (move) {
// TODO move flags for both capture and promote??
var tempMove = {}
var matches = move.split(/[x|-]/)
tempMove.from = parseInt(matches[0], 10)
tempMove.to = parseInt(matches[1], 10)
var moveType = move.match(/[x|-]/)[0]
if (moveType === '-') {
tempMove.flags = FLAGS.NORMAL
} else {
tempMove.flags = FLAGS.CAPTURE
}
tempMove.piece = position.charAt(convertNumber(tempMove.from, 'internal'))
var moves = getLegalMoves(tempMove.from)
moves = convertMoves(moves, 'external')
// if move legal then make move
for (var i = 0; i < moves.length; i += 1) {
if (tempMove.to === moves[i].to && tempMove.from === moves[i].from) {
if (moves[i].takes.length > 0) {
tempMove.flags = FLAGS.CAPTURE
tempMove.captures = moves[i].takes
tempMove.takes = moves[i].takes
tempMove.piecesCaptured = moves[i].piecesTaken
}
return tempMove
}
}
console.log(moves, tempMove)
return false
}
function makeMove (move) {
move.piece = position.charAt(convertNumber(move.from, 'internal'))
position = setCharAt(position, convertNumber(move.to, 'internal'), move.piece)
position = setCharAt(position, convertNumber(move.from, 'internal'), 0)
move.flags = FLAGS.NORMAL
// TODO refactor to either takes or capture
if (move.takes && move.takes.length) {
move.flags = FLAGS.CAPTURE
move.captures = move.takes
move.piecesCaptured = move.piecesTaken
for (var i = 0; i < move.takes.length; i++) {
position = setCharAt(position, convertNumber(move.takes[i], 'internal'), 0)
}
}
// Promoting piece here
if (move.to <= 5 && move.piece === 'w') {
move.flags = FLAGS.PROMOTION
position = setCharAt(position, convertNumber(move.to, 'internal'), move.piece.toUpperCase())
} else if (move.to >= 46 && move.piece === 'b') {
position = setCharAt(position, convertNumber(move.to, 'internal'), move.piece.toUpperCase())
}
push(move)
if (turn === BLACK) {
moveNumber += 1
}
turn = swap_color(turn)
}
function get (square) {
var piece = position.charAt(convertNumber(square, 'internal'))
return piece
}
function put (piece, square) {
// check for valid piece string
if (SYMBOLS.match(piece) === null) {
return false
}
// check for valid square
if (outsideBoard(convertNumber(square, 'internal')) === true) {
return false
}
position = setCharAt(position, convertNumber(square, 'internal'), piece)
update_setup(generate_fen())
return true
}
function remove (square) {
var piece = get(square)
position = setCharAt(position, convertNumber(square, 'internal'), 0)
update_setup(generate_fen())
return piece
}
function build_move (board, from, to, flags, promotion) {
var move = {
color: turn,
from: from,
to: to,
flags: flags,
piece: board[from].type
}
if (promotion) {
move.flags |= BITS.PROMOTION
}
if (board[to]) {
move.captured = board[to].type
} else if (flags & BITS.CAPTURE) {
move.captured = MAN
}
return move
}
function generate_moves (square) {
var moves = []
if (square) {
moves = getLegalMoves(square.square)
} else {
var tempCaptures = getCaptures()
// TODO change to be applicable to array
if (tempCaptures.length) {
for (var i = 0; i < tempCaptures.length; i++) {
tempCaptures[i].flags = FLAGS.CAPTURE
tempCaptures[i].captures = tempCaptures[i].jumps
tempCaptures[i].piecesCaptured = tempCaptures[i].piecesTaken
}
return tempCaptures
}
moves = getMoves()
}
// TODO returns [] for on hovering for square no
moves = [].concat.apply([], moves)
return moves
}
function getLegalMoves (index) {
var legalMoves
index = parseInt(index, 10)
if (!Number.isNaN(index)) {
index = convertNumber(index, 'internal')
var captures = capturesAtSquare(index, {position: position, dirFrom: ''}, {jumps: [index], takes: [], piecesTaken: []})
captures = longestCapture(captures)
legalMoves = captures
if (captures.length === 0) {
legalMoves = movesAtSquare(index)
}
}
// TODO called on hover ??
return convertMoves(legalMoves, 'external')
}
function getMoves (index) {
var moves = []
var us = turn
for (var i = 1; i < position.length; i++) {
if (position[i] === us || position[i] === us.toLowerCase()) {
var tempMoves = movesAtSquare(i)
if (tempMoves.length) {
moves = moves.concat(convertMoves(tempMoves, 'external'))
}
}
}
return moves
}
function setCharAt (position, idx, chr) {
idx = parseInt(idx, 10)
if (idx > position.length - 1) {
return position.toString()
} else {
return position.substr(0, idx) + chr + position.substr(idx + 1)
}
}
function movesAtSquare (square) {
var moves = []
var posFrom = square
var piece = position.charAt(posFrom)
// console.trace(piece, square, 'movesAtSquare')
switch (piece) {
case 'b':
case 'w':
var dirStrings = directionStrings(position, posFrom, 2)
for (var dir in dirStrings) {
var str = dirStrings[dir]
var matchArray = str.match(/^[bw]0/) // e.g. b0 w0
if (matchArray !== null && validDir(piece, dir) === true) {
var posTo = posFrom + STEPS[dir]
var moveObject = {from: posFrom, to: posTo, takes: [], jumps: []}
moves.push(moveObject)
}
}
break
case 'W':
case 'B':
dirStrings = directionStrings(position, posFrom, 2)
for (dir in dirStrings) {
str = dirStrings[dir]
matchArray = str.match(/^[BW]0+/) // e.g. B000, W0
if (matchArray !== null) {
for (var i = 1; i < matchArray[0].length; i++) {
posTo = posFrom + (i * STEPS[dir])
moveObject = {from: posFrom, to: posTo, takes: [], jumps: []}
moves.push(moveObject)
}
}
}
break
default:
return moves
}
return moves
}
function getCaptures () {
var us = turn
var captures = []
for (var i = 0; i < position.length; i++) {
if (position[i] === us || position[i] === us.toLowerCase()) {
var posFrom = i
var state = {position: position, dirFrom: ''}
var capture = {jumps: [], takes: [], from: posFrom, to: '', piecesTaken: []}
capture.jumps[0] = posFrom
var tempCaptures = capturesAtSquare(posFrom, state, capture)
if (tempCaptures.length) {
captures = captures.concat(convertMoves(tempCaptures, 'external'))
}
}
}
captures = longestCapture(captures)
return captures
}
function capturesAtSquare (posFrom, state, capture) {
var piece = state.position.charAt(posFrom)
if (piece !== 'b' && piece !== 'w' && piece !== 'B' && piece !== 'W') {
return [capture]
}
var dirString
if (piece === 'b' || piece === 'w') {
dirString = directionStrings(state.position, posFrom, 3)
} else {
dirString = directionStrings(state.position, posFrom)
}
var finished = true
var captureArrayForDir = {}
for (var dir in dirString) {
if (dir === state.dirFrom) {
continue
}
var str = dirString[dir]
switch (piece) {
case 'b':
case 'w':
var matchArray = str.match(/^b[wW]0|^w[bB]0/) // matches: bw0, bW0, wB0, wb0
if (matchArray !== null) {
var posTo = posFrom + (2 * STEPS[dir])
var posTake = posFrom + (1 * STEPS[dir])
if (capture.takes.indexOf(posTake) > -1) {
continue // capturing twice forbidden
}
var updateCapture = clone(capture)
updateCapture.to = posTo
updateCapture.jumps.push(posTo)
updateCapture.takes.push(posTake)
updateCapture.piecesTaken.push(position.charAt(posTake))
updateCapture.from = posFrom
var updateState = clone(state)
updateState.dirFrom = oppositeDir(dir)
var pieceCode = updateState.position.charAt(posFrom)
updateState.position = setCharAt(updateState.position, posFrom, 0)
updateState.position = setCharAt(updateState.position, posTo, pieceCode)
finished = false
captureArrayForDir[dir] = capturesAtSquare(posTo, updateState, updateCapture)
}
break
case 'B':
case 'W':
matchArray = str.match(/^B0*[wW]0+|^W0*[bB]0+/) // matches: B00w000, WB00
if (matchArray !== null) {
var matchStr = matchArray[0]
var matchArraySubstr = matchStr.match(/[wW]0+$|[bB]0+$/) // matches: w000, B00
var matchSubstr = matchArraySubstr[0]
var takeIndex = matchStr.length - matchSubstr.length
posTake = posFrom + (takeIndex * STEPS[dir])
if (capture.takes.indexOf(posTake) > -1) {
continue
}
for (var i = 1; i < matchSubstr.length; i++) {
posTo = posFrom + ((takeIndex + i) * STEPS[dir])
updateCapture = clone(capture)
updateCapture.jumps.push(posTo)
updateCapture.to = posTo
updateCapture.takes.push(posTake)
updateCapture.piecesTaken.push(position.charAt(posTake))
updateCapture.posFrom = posFrom
updateState = clone(state)
updateState.dirFrom = oppositeDir(dir)
pieceCode = updateState.position.charAt(posFrom)
updateState.position = setCharAt(updateState.position, posFrom, 0)
updateState.position = setCharAt(updateState.position, posTo, pieceCode)
finished = false
var dirIndex = dir + i.toString()
captureArrayForDir[dirIndex] = capturesAtSquare(posTo, updateState, updateCapture)
}
}
break
default:
captureArrayForDir = []
}
}
var captureArray = []
if (finished === true && capture.takes.length) {
- // fix for mutiple capture
+ // fix for multiple capture
capture.from = capture.jumps[0]
captureArray[0] = capture
} else {
for (dir in captureArrayForDir) {
captureArray = captureArray.concat(captureArrayForDir[dir])
}
}
return captureArray
}
function push (move) {
history.push({
move: move,
turn: turn,
moveNumber: moveNumber
})
}
function undoMove () {
var old = history.pop()
if (!old) {
return null
}
var move = old.move
turn = old.turn
moveNumber = old.moveNumber
position = setCharAt(position, convertNumber(move.from, 'internal'), move.piece)
position = setCharAt(position, convertNumber(move.to, 'internal'), 0)
if (move.flags === 'c') {
for (var i = 0; i < move.captures.length; i += 1) {
position = setCharAt(position, convertNumber(move.captures[i], 'internal'), move.piecesCaptured[i])
}
} else if (move.flags === 'p') {
if(move.captures) {
for (var i = 0; i < move.captures.length; i += 1) {
position = setCharAt(position, convertNumber(move.captures[i], 'internal'), move.piecesCaptured[i])
}
}
position = setCharAt(position, convertNumber(move.from, 'internal'), move.piece.toLowerCase())
}
return move
}
function get_disambiguator (move) {
}
function swap_color (c) {
return c === WHITE ? BLACK : WHITE
}
function isInteger (int) {
var regex = /^\d+$/
if (regex.test(int)) {
return true
} else {
return false
}
}
function longestCapture (captures) {
var maxJumpCount = 0
for (var i = 0; i < captures.length; i++) {
var jumpCount = captures[i].jumps.length
if (jumpCount > maxJumpCount) {
maxJumpCount = jumpCount
}
}
var selectedCaptures = []
if (maxJumpCount < 2) {
return selectedCaptures
}
for (i = 0; i < captures.length; i++) {
if (captures[i].jumps.length === maxJumpCount) {
selectedCaptures.push(captures[i])
}
}
return selectedCaptures
}
function convertMoves (moves, type) {
var tempMoves = []
if (!type || moves.length === 0) {
return tempMoves
}
for (var i = 0; i < moves.length; i++) {
var moveObject = {jumps: [], takes: []}
moveObject.from = convertNumber(moves[i].from, type)
for (var j = 0; j < moves[i].jumps.length; j++) {
moveObject.jumps[j] = convertNumber(moves[i].jumps[j], type)
}
for (j = 0; j < moves[i].takes.length; j++) {
moveObject.takes[j] = convertNumber(moves[i].takes[j], type)
}
moveObject.to = convertNumber(moves[i].to, type)
moveObject.piecesTaken = moves[i].piecesTaken
tempMoves.push(moveObject)
}
return tempMoves
}
function convertNumber (number, notation) {
var num = parseInt(number, 10)
var result
switch (notation) {
case 'internal':
result = num + Math.floor((num - 1) / 10)
break
case 'external':
result = num - Math.floor((num - 1) / 11)
break
default:
result = num
}
return result
}
function convertPosition (position, notation) {
var sub1, sub2, sub3, sub4, sub5, newPosition
switch (notation) {
case 'internal':
sub1 = position.substr(1, 10)
sub2 = position.substr(11, 10)
sub3 = position.substr(21, 10)
sub4 = position.substr(31, 10)
sub5 = position.substr(41, 10)
newPosition = '-' + sub1 + '-' + sub2 + '-' + sub3 + '-' + sub4 + '-' + sub5 + '-'
break
case 'external':
sub1 = position.substr(1, 10)
sub2 = position.substr(12, 10)
sub3 = position.substr(23, 10)
sub4 = position.substr(34, 10)
sub5 = position.substr(45, 10)
newPosition = '?' + sub1 + sub2 + sub3 + sub4 + sub5
break
default:
newPosition = position
}
return newPosition
}
function outsideBoard (square) {
// internal notation only
var n = parseInt(square, 10)
if (n >= 0 && n <= 55 && (n % 11) !== 0) {
return false
} else {
return true
}
}
function directionStrings (tempPosition, square, maxLength) {
// Create direction strings for square at position (internal representation)
// Output object with four directions as properties (four rhumbs).
// Each property has a string as value representing the pieces in that direction.
// Piece of the given square is part of each string.
// Example of output: {NE: 'b0', SE: 'b00wb00', SW: 'bbb00', NW: 'bb'}
// Strings have maximum length of given maxLength.
if (arguments.length === 2) {
maxLength = 100
}
var dirStrings = {}
if (outsideBoard(square) === true) {
return 334
}
for (var dir in STEPS) {
var dirArray = []
var i = 0
var index = square
do {
dirArray[i] = tempPosition.charAt(index)
i++
index = square + i * STEPS[dir]
var outside = outsideBoard(index)
} while (outside === false && i < maxLength)
dirStrings[dir] = dirArray.join('')
}
return dirStrings
}
function oppositeDir (direction) {
var opposite = {NE: 'SW', SE: 'NW', SW: 'NE', NW: 'SE'}
return opposite[direction]
}
function validDir (piece, dir) {
var validDirs = {}
validDirs.w = {NE: true, SE: false, SW: false, NW: true}
validDirs.b = {NE: false, SE: true, SW: true, NW: false}
return validDirs[piece][dir]
}
function ascii (unicode) {
var extPosition = convertPosition(position, 'external')
var s = '\n+-------------------------------+\n'
var i = 1
for (var row = 1; row <= 10; row++) {
s += '|\t'
if (row % 2 !== 0) {
s += ' '
}
for (var col = 1; col <= 10; col++) {
if (col % 2 === 0) {
s += ' '
i++
} else {
if (unicode) {
s += ' ' + UNICODES[extPosition[i]]
} else {
s += ' ' + extPosition[i]
}
}
}
if (row % 2 === 0) {
s += ' '
}
s += '\t|\n'
}
s += '+-------------------------------+\n'
return s
}
function gameOver () {
// First check if any piece left
for (var i = 0; i < position.length; i++) {
if (position[i].toLowerCase() === turn.toLowerCase()) {
// if moves left game not over
return generate_moves().length === 0
}
}
return true
}
function getHistory (options) {
var tempHistory = clone(history)
var moveHistory = []
var verbose = (typeof options !== 'undefined' && 'verbose' in options && options.verbose)
while (tempHistory.length > 0) {
var move = tempHistory.shift()
if (verbose) {
moveHistory.push(makePretty(move))
} else {
moveHistory.push(move.move.from + SIGNS[move.move.flags] + move.move.to)
}
}
return moveHistory
}
function getPosition () {
return convertPosition(position, 'external')
}
function makePretty (uglyMove) {
var move = {}
move.from = uglyMove.move.from
move.to = uglyMove.move.to
move.flags = uglyMove.move.flags
move.moveNumber = uglyMove.moveNumber
move.piece = uglyMove.move.piece
if (move.flags === 'c') {
move.captures = uglyMove.move.captures.join(',')
}
return move
}
function clone (obj) {
var dupe = JSON.parse(JSON.stringify(obj))
return dupe
}
function trim (str) {
return str.replace(/^\s+|\s+$/g, '')
}
// TODO
function perft (depth) {
var moves = generate_moves({legal: false})
var nodes = 0
for (var i = 0; i < moves.length; i++) {
makeMove(moves[i])
if (depth - 1 > 0) {
var child_nodes = perft(depth - 1)
nodes += child_nodes
} else {
nodes++
}
undoMove()
}
return nodes
}
return {
WHITE: WHITE,
BLACK: BLACK,
MAN: MAN,
KING: KING,
FLAGS: FLAGS,
SQUARES: 'A8',
load: function (fen) {
return load(fen)
},
- reset: function () {
+ resetGame: function () {
return reset()
},
moves: generate_moves,
gameOver: gameOver,
inDraw: function () {
return false
},
validate_fen: validate_fen,
fen: generate_fen,
pdn: generatePDN,
load_pdn: function (pdn, options) {},
parsePDN: parsePDN,
header: function () {
return set_header(arguments)
},
ascii: ascii,
- turn: function () {
+ getTurn: function () {
return turn.toLowerCase()
},
move: function move (myMove) {
if (typeof myMove.to === 'undefined' && typeof myMove.from === 'undefined') {
return false
}
myMove.to = parseInt(myMove.to, 10)
myMove.from = parseInt(myMove.from, 10)
var moves = generate_moves()
for (var i = 0; i < moves.length; i++) {
if ((myMove.to === moves[i].to) && (myMove.from === moves[i].from)) {
makeMove(moves[i])
return moves[i]
}
}
return false
},
getMoves: getMoves,
getLegalMoves: getLegalMoves,
undo: function () {
var move = undoMove()
return move || null
},
clear: function () {
return clear()
},
put: function (piece, square) {
return put(piece, square)
},
get: function (square) {
return get(square)
},
remove: function (square) {
return remove(square)
},
perft: function (depth) {
return perft(depth)
},
history: getHistory,
convertMoves: convertMoves,
convertNumber: convertNumber,
convertPosition: convertPosition,
outsideBoard: outsideBoard,
directionStrings: directionStrings,
oppositeDir: oppositeDir,
validDir: validDir,
position: getPosition,
clone: clone,
makePretty: makePretty,
captures: getCaptures
}
}
if (typeof exports !== 'undefined') {
exports.Draughts = Draughts
}
if (typeof define !== 'undefined') {
define(function () {
return Draughts
})
}
diff --git a/src/activities/checkers_2players/ActivityInfo.qml b/src/activities/checkers_2players/ActivityInfo.qml
index 87abd7d80..35ff9b66b 100644
--- a/src/activities/checkers_2players/ActivityInfo.qml
+++ b/src/activities/checkers_2players/ActivityInfo.qml
@@ -1,43 +1,43 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2017 Johnny Jazeix <jazeix@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "checkers_2players/Checkers2Players.qml"
difficulty: 4
icon: "checkers_2players/checkers_2players.svg"
author: "Johnny Jazeix &lt;jazeix@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Play checkers with your friend")
//: Help title
description: qsTr("The version in GCompris is the international draughts.")
//intro: "play checkers with your friend"
//: Help goal
- goal: qsTr("Capture all the pieces of your opponent before your opponent capture all of yours.")
+ goal: qsTr("Capture all the pieces of your opponent before your opponent captures all of yours.")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("Checkers is played by two opponents, on opposite sides of the gameboard. One player has the dark pieces; the other has the light pieces. Players alternate turns. A player may not move an opponent's piece. A move consists of moving a piece diagonally to an adjacent unoccupied square. If the adjacent square contains an opponent's piece, and the square immediately beyond it is vacant, the piece may be captured (and removed from the game) by jumping over it.
Only the dark squares of the checkered board are used. A piece may move only diagonally into an unoccupied square. Capturing is mandatory. The player without pieces remaining, or who cannot move due to being blocked, loses the game.
When a man reaches the crownhead or kings row (the farthest row forward), it becomes a king, and is marked by placing an additional piece on top of the first man, and acquires additional powers including the ability to move backwards. If there is a piece in a diagonal that a king can capture, he can move any distance along the diagonal, and may capture an opposing man any distance away by jumping to any of the unoccupied squares immediately beyond it.
")
credit: qsTr("The checkers library is draughts.js &lt;https://github.com/shubhendusaurabh/draughts.js&gt;. Manual is from wikipedia &lt;https://en.wikipedia.org/wiki/Draughts&gt;")
section: "strategy"
createdInVersion: 8000
}
diff --git a/src/activities/checkers_2players/Checkers2Players.qml b/src/activities/checkers_2players/Checkers2Players.qml
index 2de30afff..1e1ab5cc3 100644
--- a/src/activities/checkers_2players/Checkers2Players.qml
+++ b/src/activities/checkers_2players/Checkers2Players.qml
@@ -1,28 +1,28 @@
/* GCompris - checkers_2players.qml
*
* Copyright (C) 2017 Johnny Jazeix <jazeix@gmail.com>
*
* Authors:
* Johnny Jazeix <jazeix@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
import "../checkers"
Checkers {
twoPlayers: true
}
diff --git a/src/activities/chess/ActivityInfo.qml b/src/activities/chess/ActivityInfo.qml
index e15425df5..e3fce19d1 100644
--- a/src/activities/chess/ActivityInfo.qml
+++ b/src/activities/chess/ActivityInfo.qml
@@ -1,47 +1,47 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "chess/Chess.qml"
difficulty: 6
icon: "chess/chess.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
//: Activity title
title: qsTr("Play chess against Tux")
//: Help title
description: ""
//intro: "play chess against Tux"
//: Help goal
goal: ""
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("In this activity you discover the chess game by playing against the computer. It displays the possible target position for any selected piece which helps the children understand how pieces moves. At first level the computer is fully random to give the most chances to the children. As level increases, better the computer plays.
\nYou can achieve a mate sooner if follow these simple rules:
Trying to drive opponent's King in the corner.
<b>Explanation</b>: this way opponent's piece would have only 3 directions to move instead of 8 from a best position.
'Making a trap'. Use your pawns as baits.
<b>Explanation</b>: this way you can lure the opponent out of his 'comfort zone'.
Be patient enough.
<b>Explanation</b>: don't rush too quick, be patient. Let yourself think a little bit and try to predict your opponent's future moves, so you can catch him on it or secure your pieces from his attacks.")
credit: qsTr("The chess engine is p4wn &lt;https://github.com/douglasbagnall/p4wn&gt;.")
section: "strategy"
createdInVersion: 5000
}
diff --git a/src/activities/chess/Chess.qml b/src/activities/chess/Chess.qml
index 6e8c7ad7b..1840d25fc 100644
--- a/src/activities/chess/Chess.qml
+++ b/src/activities/chess/Chess.qml
@@ -1,462 +1,486 @@
/* GCompris - chess.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import QtQuick.Controls 1.5
import QtQuick.Controls.Styles 1.4
import GCompris 1.0
import "../../core"
import "."
import "chess.js" as Activity
ActivityBase {
id: activity
property bool acceptClick: true
property bool twoPlayers: false
property int coordsOpacity: 1
// difficultyByLevel means that at level 1 computer is bad better at last level
property bool difficultyByLevel: true
property var fen: [
["initial state", "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 1 1"],
["initial state", "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 1 1"],
["initial state", "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 1 1"],
["initial state", "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 1 1"],
["initial state", "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 1 1"]
]
onStart: focus = true
onStop: {}
pageComponent: Image {
id: background
anchors.fill: parent
source: Activity.url + 'background-wood.svg'
signal start
signal stop
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property GCSfx audioEffects: activity.audioEffects
property alias background: background
property alias bar: bar
property alias bonus: bonus
property int barHeightAddon: ApplicationSettings.isBarHidden ? 1 : 3
- property bool isPortrait: (background.height > background.width)
+ property bool isPortrait: (background.height >= background.width)
property int cellSize: items.isPortrait ?
Math.min((background.width - numbers.childrenRect.width) / (8 + 2),
(background.height - controls.height - letters.childrenRect.height) / (8 + barHeightAddon)) :
Math.min((background.width - numbers.childrenRect.width) / (8 + 2), (background.height - letters.childrenRect.height) / (8.5 + barHeightAddon))
property var fen: activity.fen
property bool twoPlayer: activity.twoPlayers
property bool difficultyByLevel: activity.difficultyByLevel
property var positions
property var pieces: pieces
property var squares: squares
property var history
property var redo_stack
property alias redoTimer: redoTimer
property int from
property bool blackTurn
property bool gameOver
property string message
property bool isWarningMessage
property alias trigComputerMove: trigComputerMove
Behavior on cellSize { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 1000 } }
}
onStart: { Activity.start(items) }
onStop: { Activity.stop() }
Grid {
anchors {
top: parent.top
topMargin: items.isPortrait ? 0 : items.cellSize
leftMargin: 10 * ApplicationInfo.ratio
rightMargin: 10 * ApplicationInfo.ratio
}
columns: (items.isPortrait==true)?1:3
rows: (items.isPortrait==true)?2:1
width: (items.isPortrait==true)?undefined:background.width
anchors.horizontalCenter: parent.horizontalCenter
spacing: 10
horizontalItemAlignment: Grid.AlignHCenter
verticalItemAlignment: Grid.AlignVCenter
Column {
id: controls
anchors {
leftMargin: 10
rightMargin: 10
}
z: 20
width: items.isPortrait ?
parent.width :
Math.max(undo.width * 1.2,
Math.min(
(background.width * 0.9 - undo.width - chessboard.width),
(background.width - chessboard.width) / 2))
GCText {
color: items.isWarningMessage ? "red" : "white"
anchors.horizontalCenter: parent.horizontalCenter
width: parent.width
fontSize: smallSize
text: items.message
horizontalAlignment: Text.AlignHCenter
wrapMode: TextEdit.WordWrap
}
Grid {
- spacing: 10
+ spacing: 60 * ApplicationInfo.ratio
columns: items.isPortrait ? 3 : 1
anchors.horizontalCenter: parent.horizontalCenter
horizontalItemAlignment: Grid.AlignHCenter
verticalItemAlignment: Grid.AlignVCenter
Button {
id: undo
height: 30 * ApplicationInfo.ratio
- text: qsTr("Undo");
+ width: height
+ text: "";
style: GCButtonStyle { theme: "light" }
onClicked: Activity.undo()
enabled: items.history.length > 0 ? 1 : 0
opacity: enabled
+ Image {
+ source: Activity.url + 'undo.svg'
+ height: parent.height
+ width: height
+ sourceSize.height: height
+ fillMode: Image.PreserveAspectFit
+ }
Behavior on opacity {
PropertyAnimation {
easing.type: Easing.InQuad
duration: 200
}
}
}
Button {
id: redo
- height: 30 * ApplicationInfo.ratio
- text: qsTr("Redo");
+ height: undo.height
+ width: undo.height
+ text: "";
style: GCButtonStyle { theme: "light" }
onClicked: {
if (!twoPlayers) {
acceptClick = false;
Activity.redo()
} else {
Activity.redo()
}
}
enabled: items.redo_stack.length > 0 && acceptClick ? 1 : 0
opacity: enabled
+ Image {
+ source: Activity.url + 'redo.svg'
+ height: parent.height
+ width: height
+ sourceSize.height: height
+ fillMode: Image.PreserveAspectFit
+ }
Behavior on opacity {
PropertyAnimation {
easing.type: Easing.InQuad
duration: 200
}
}
}
Button {
- height: 30 * ApplicationInfo.ratio
- text: qsTr("Swap");
+ height: undo.height
+ width: undo.height
+ text: "";
style: GCButtonStyle { theme: "light" }
enabled: items.twoPlayer
opacity: enabled
+ Image {
+ source: Activity.url + 'turn.svg'
+ height: parent.height
+ width: height
+ sourceSize.height: height
+ fillMode: Image.PreserveAspectFit
+ }
onClicked: chessboard.swap()
}
}
}
Rectangle {
- id:boardBg
+ id: boardBg
width: items.cellSize * 8.2
height: boardBg.width
z: 08
color: "#452501"
// The chessboard
GridView {
id: chessboard
cellWidth: items.cellSize
cellHeight: items.cellSize
width: items.cellSize * 8
height: chessboard.width
interactive: false
keyNavigationWraps: true
model: 64
layoutDirection: Qt.RightToLeft
delegate: square
rotation: 180
z: 10
anchors.centerIn: boardBg
Component {
id: square
Image {
source: index % 2 + (Math.floor(index / 8) % 2) == 1 ?
Activity.url + 'chess-white.svg' : Activity.url + 'chess-black.svg';
width: items.cellSize
height: items.cellSize
}
}
Behavior on rotation { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 1400 } }
function swap() {
items.audioEffects.play('qrc:/gcompris/src/core/resource/sounds/flip.wav')
coordsOpacity = 0
timerSwap.start()
if(chessboard.rotation == 180)
chessboard.rotation = 0
else
chessboard.rotation = 180
}
}
Timer {
id: timerSwap
interval: 1500
running: false
repeat: false
onTriggered: coordsOpacity = 1
}
Grid {
id: letters
anchors.left: chessboard.left
anchors.top: chessboard.bottom
opacity: coordsOpacity
Behavior on opacity { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 500} }
Repeater {
id: lettersA
model: chessboard.rotation == 0 ? ["F", "G", "F", "E", "D", "C", "B", "A"] : ["A", "B", "C", "D", "E", "F", "G", "H"]
GCText {
x: items.cellSize * (index % 8) + (items.cellSize/2-width/2)
y: items.cellSize * Math.floor(index / 8)
text: modelData
color: "#CBAE7B"
}
}
}
Grid {
id: numbers
anchors.left: chessboard.right
anchors.top: chessboard.top
opacity: coordsOpacity
Behavior on opacity { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 500} }
Repeater {
model: chessboard.rotation == 0 ? ["1", "2", "3", "4", "5", "6", "7", "8"] : ["8", "7", "6", "5", "4", "3", "2", "1"]
GCText {
x: items.cellSize * Math.floor(index / 8) + width
y: items.cellSize * (index % 8) + (items.cellSize/2-height/2)
text: modelData
color: "#CBAE7B"
}
}
}
Rectangle {
id: boardBorder
width: items.cellSize * 10
height: boardBorder.width
anchors.centerIn: boardBg
z: -1
color: "#542D0F"
border.color: "#3A1F0A"
border.width: items.cellSize * 0.1
}
}
}
Repeater {
id: squares
model: items.positions
delegate: square
parent: chessboard
DropArea {
id: square
x: items.cellSize * (7 - pos % 8) + spacing / 2
y: items.cellSize * Math.floor(pos / 8) + spacing / 2
width: items.cellSize - spacing
height: square.width
z: 1
keys: acceptMove ? ['acceptMe'] : ['sorryNo']
property bool acceptMove : false
property int pos: modelData.pos
property int spacing: 6 * ApplicationInfo.ratio
Rectangle {
id: possibleMove
anchors.fill: parent
color: parent.containsDrag ? '#803ACAFF' : 'transparent'
border.width: parent.acceptMove ? 5 : 0
border.color: '#FF808080'
z: 1
}
}
function getSquareAt(pos) {
for(var i=0; i < squares.count; i++) {
if(squares.itemAt(i).pos === pos)
return squares.itemAt(i)
}
return(undefined)
}
}
Repeater {
id: pieces
model: items.positions
delegate: piece
parent: chessboard
Piece {
id: piece
sourceSize.width: items.cellSize
width: items.cellSize - spacing
height: piece.width
source: img ? Activity.url + img + '.svg' : ''
img: modelData.img
x: items.cellSize * (7 - pos % 8) + spacing / 2
y: items.cellSize * Math.floor(pos / 8) + spacing / 2
z: 1
pos: modelData.pos
newPos: modelData.pos
rotation: - chessboard.rotation
property int spacing: 6 * ApplicationInfo.ratio
Drag.active: dragArea.drag.active
Drag.hotSpot.x: width / 2
Drag.hotSpot.y: height / 2
MouseArea {
id: dragArea
anchors.fill: parent
enabled: !items.gameOver
drag.target: parent
onPressed: {
piece.Drag.keys = ['acceptMe']
parent.z = 100
if(parent.isWhite == 1 && !items.blackTurn ||
parent.isWhite == 0 && items.blackTurn) {
items.from = parent.newPos
Activity.showPossibleMoves(items.from)
} else if(items.from != -1 && squares.getSquareAt(parent.newPos)['acceptMove']) {
Activity.moveTo(items.from, parent.newPos)
}
}
onReleased: {
// If no target or move not possible, we reset the position
if(!piece.Drag.target || (items.from != -1 && !Activity.moveTo(items.from, piece.Drag.target.pos))) {
var pos = parent.pos
// Force recalc of the old x,y position
parent.pos = -1
pieces.getPieceAt(pos).move(pos)
}
}
}
}
function moveTo(from, to) {
var fromPiece = getPieceAt(from)
var toPiece = getPieceAt(to)
- if(toPiece.img != '')
+ if(toPiece.img !== '')
items.audioEffects.play('qrc:/gcompris/src/core/resource/sounds/smudge.wav')
else
items.audioEffects.play('qrc:/gcompris/src/core/resource/sounds/scroll.wav')
toPiece.hide(from)
fromPiece.move(to)
}
function promotion(to) {
var toPiece = getPieceAt(to)
toPiece.promotion()
}
function getPieceAt(pos) {
for(var i=0; i < pieces.count; i++) {
- if(pieces.itemAt(i).newPos == pos)
+ if(pieces.itemAt(i).newPos === pos)
return pieces.itemAt(i)
}
return(undefined)
}
}
Timer {
id: trigComputerMove
repeat: false
interval: 400
onTriggered: Activity.randomMove()
}
// Use to redo the computer move after the user move
Timer {
id: redoTimer
repeat: false
interval: 400
onTriggered: {
acceptClick = true;
Activity.moveByEngine(move)
}
property var move
function moveByEngine(engineMove) {
move = engineMove
redoTimer.start()
}
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | (items.twoPlayer ? 0 : level) |
(items.twoPlayer && !items.gameOver ? 0 : reload) }
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
onReloadClicked: {
trigComputerMove.stop()
Activity.initLevel()
}
}
Bonus {
id: bonus
}
}
}
diff --git a/src/activities/chess/Piece.qml b/src/activities/chess/Piece.qml
index b33f1b5a1..86a68914d 100644
--- a/src/activities/chess/Piece.qml
+++ b/src/activities/chess/Piece.qml
@@ -1,107 +1,107 @@
/* GCompris - chess.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
Image {
id: piece
property int pos
Behavior on opacity { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 200 } }
Behavior on x { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 200 } }
Behavior on y { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 200 } }
z: 10
property string img
- property bool acceptMove : false
+ property bool acceptMove: false
property int newPos
// color = -1 if no piece, 0 is black and 1 is white
property int isWhite: img.length != 2 ? -1 : img[0] == 'w' ? 1 : 0
SequentialAnimation {
id: hideAnim
NumberAnimation {
target: piece
property: "scale"
duration: 200
to: 0
}
PropertyAction {
target: piece
property: 'img'
value: ""
}
PropertyAction {
target: piece
property: 'pos'
value: piece.newPos
}
PropertyAction {
target: piece
property: 'scale'
value: 1
}
PropertyAction {
target: piece
property: 'z'
value: 2
}
}
SequentialAnimation {
id: promotionAnim
PauseAnimation {
duration: 200
}
NumberAnimation {
target: piece
property: 'scale'
to: 0
}
PropertyAction {
target: piece
property: 'img'
value: isWhite ? 'wq' : 'bq'
}
NumberAnimation {
target: piece
property: 'scale'
to: 1
easing.type: Easing.OutElastic
}
}
function hide(newPos) {
piece.newPos = newPos
hideAnim.start()
}
function promotion() {
promotionAnim.start()
}
function move(to) {
piece.newPos = to
piece.pos = to
piece.z = 2
}
}
diff --git a/src/activities/chess/chess.js b/src/activities/chess/chess.js
index fa3e2c846..c88c3b073 100644
--- a/src/activities/chess/chess.js
+++ b/src/activities/chess/chess.js
@@ -1,346 +1,346 @@
/* GCompris - chess.js
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
.import "qrc:/gcompris/src/core/core.js" as Core
.import "engine.js" as Engine
var url = "qrc:/gcompris/src/activities/chess/resource/"
var currentLevel
var numberOfLevel
var items
var state
function start(items_) {
items = items_
currentLevel = 0
numberOfLevel = items.fen.length
initLevel()
}
function stop() {
}
function initLevel() {
items.bar.level = currentLevel + 1
state = Engine.p4_fen2state(items.fen[currentLevel][1])
items.from = -1
items.gameOver = false
items.redo_stack = []
refresh()
Engine.p4_prepare(state)
items.positions = 0 // Force a model reload
items.positions = simplifiedState(state['board'])
clearAcceptMove()
}
function nextLevel() {
if(numberOfLevel <= ++currentLevel ) {
currentLevel = 0
}
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
initLevel();
}
function simplifiedState(state) {
var newState = new Array()
for(var i = state.length - 1; i >= 0; --i) {
- if(state[i] != 16) {
+ if(state[i] !== 16) {
var img = ""
switch(state[i]) {
case 2:
img = "wp"
break
case 3:
img = "bp"
break
case 4:
img = "wr"
break
case 5:
img = "br"
break
case 6:
img = "wn"
break
case 7:
img = "bn"
break
case 8:
img = "wb"
break
case 9:
img = "bb"
break
case 10:
img = "wk"
break
case 11:
img = "bk"
break
case 12:
img = "wq"
break
case 13:
img = "bq"
break
default:
break
}
newState.push(
{
'pos': engineToViewPos(i),
'img': img
})
}
}
return newState
}
function updateMessage(move) {
items.isWarningMessage = false
items.gameOver = false
items.message = items.blackTurn ? qsTr("Black's turn") : qsTr("White's turn")
if(!move)
return
if((move.flags & (Engine.P4_MOVE_FLAG_CHECK | Engine.P4_MOVE_FLAG_MATE))
== (Engine.P4_MOVE_FLAG_CHECK | Engine.P4_MOVE_FLAG_MATE)) {
items.message = items.blackTurn ? qsTr("White mates", "white wins") : qsTr("Black mates", "black wins")
items.gameOver = true
if(!items.twoPlayer)
- if(state.to_play != 0)
+ if(state.to_play !== 0)
items.bonus.good('gnu')
else
items.bonus.good('tux')
else
items.bonus.good('flower')
} else if((move.flags & Engine.P4_MOVE_FLAG_MATE) == Engine.P4_MOVE_FLAG_MATE) {
items.message = qsTr("Drawn game")
items.gameOver = true
items.bonus.good('flower')
} else if((move.flags & Engine.P4_MOVE_FLAG_CHECK) == Engine.P4_MOVE_FLAG_CHECK) {
items.message = items.blackTurn ? qsTr("White checks", "black king is under attack") : qsTr("Black checks", "white king is under attack")
- } else if(move.flags == Engine.P4_MOVE_ILLEGAL) {
+ } else if(move.flags === Engine.P4_MOVE_ILLEGAL) {
items.isWarningMessage = true
items.message = qsTr("Invalid, your king may be in check")
}
}
function refresh(move) {
items.blackTurn = state.to_play // 0=w 1=b
items.history = state.history
updateMessage(move)
}
// Convert view position (QML) to the chess engine coordinate
//
// The engine manages coordinate into a 120 element array, which is conceptually
// a 10x12 board, with the 8x8 board placed at the centre, thus:
// + 0123456789
// 0 ##########
// 10 ##########
// 20 #RNBQKBNR#
// 30 #PPPPPPPP#
// 40 #........#
// 50 #........#
// 60 #........#
// 70 #........#
// 80 #pppppppp#
// 90 #rnbqkbnr#
//100 ##########
//110 ##########
//
// In QML each cell is in the regular range [0-63]
//
function viewPosToEngine(pos) {
return (Math.floor(pos / 8) + 2) * 10 + pos % 8 + 1
}
// Convert chess engine coordinate to view position (QML)
function engineToViewPos(pos) {
var newpos = pos - 21 - (Math.floor((pos - 20) / 10) * 2)
return newpos
}
// move is the result from the engine move
function visibleMove(move, from, to) {
items.pieces.moveTo(from, to)
// Castle move
if(move.flags & Engine.P4_MOVE_FLAG_CASTLE_KING)
items.pieces.moveTo(from + 3, to - 1)
else if(move.flags & Engine.P4_MOVE_FLAG_CASTLE_QUEEN)
items.pieces.moveTo(from - 4, to + 1)
- else if(items.pieces.getPieceAt(to).img == 'wp' && to > 55)
+ else if(items.pieces.getPieceAt(to).img === 'wp' && to > 55)
items.pieces.promotion(to)
- else if(items.pieces.getPieceAt(to).img == 'bp' && to < 8)
+ else if(items.pieces.getPieceAt(to).img === 'bp' && to < 8)
items.pieces.promotion(to)
}
function computerMove() {
var computer = state.findmove(3)
var move = state.move(computer[0], computer[1])
if(move.ok) {
visibleMove(move, engineToViewPos(computer[0]), engineToViewPos(computer[1]))
refresh(move)
}
return move
}
function moveTo(from, to) {
var move = state.move(viewPosToEngine(from), viewPosToEngine(to))
if(move.ok) {
visibleMove(move, from, to)
refresh(move)
clearAcceptMove()
items.redo_stack = []
if(!items.twoPlayer)
items.trigComputerMove.start()
items.from = -1;
} else {
// Probably a check makes the move is invalid
updateMessage(move)
}
return move.ok
}
function undo() {
var redo_stack = items.redo_stack
redo_stack.push(state.history[state.moveno - 1])
state.jump_to_moveno(state.moveno - 1)
// In computer mode, the white always starts, take care
// of undo after a mate which requires us to revert on
// a white play
- if(!items.twoPlayer && state.to_play != 0) {
+ if(!items.twoPlayer && state.to_play !== 0) {
redo_stack.push(state.history[state.moveno - 1])
state.jump_to_moveno(state.moveno - 1)
}
// without it, you can't move again the same piece
Engine.p4_prepare(state)
items.redo_stack = redo_stack
refresh()
items.positions = [] // Force a model reload
items.positions = simplifiedState(state['board'])
}
function moveByEngine(engineMove) {
if(!engineMove)
return
var move = state.move(engineMove[0], engineMove[1])
visibleMove(move, engineToViewPos(engineMove[0]), engineToViewPos(engineMove[1]))
refresh(move)
}
function redo() {
var redo_stack = items.redo_stack
moveByEngine(items.redo_stack.pop())
// In computer mode, the white always starts, take care
// of undo after a mate which requires us to revert on
// a white play
- if(!items.twoPlayer && state.to_play != 0) {
+ if(!items.twoPlayer && state.to_play !== 0) {
items.redoTimer.moveByEngine(items.redo_stack.pop())
}
// Force refresh
items.redo_stack = []
items.redo_stack = redo_stack
}
// Random move depending on the level
function randomMove() {
if(!items.difficultyByLevel) {
computerMove()
return
}
// Disable random move if the situation is too bad for the user
// This avoid having the computer playing bad against a user
// with too few pieces making the game last too long
var score = getScore()
if(score[0] / score[1] < 0.7) {
computerMove()
return
}
// At level 2 we let the computer play 20% of the time
// and 80% of the time we make a random move.
if(Math.random() < currentLevel / (numberOfLevel - 1)) {
computerMove()
return
}
// Get all possible moves
var moves = Engine.p4_parse(state, state.to_play, 0, 0)
moves = Core.shuffle(moves)
var move = state.move(moves[0][1], moves[0][2])
if(move.ok) {
visibleMove(move, engineToViewPos(moves[0][1]), engineToViewPos(moves[0][2]))
refresh(move)
} else {
// Bad move, should not happens
computerMove()
}
}
// Clear all accept move marker from the chessboard
function clearAcceptMove() {
for(var i=0; i < items.positions.length; ++i)
items.squares.getSquareAt(i)['acceptMove'] = false
}
// Highlight the possible moves for the piece at position 'from'
function showPossibleMoves(from) {
var result = Engine.p4_parse(state, state.to_play, 0, 0)
clearAcceptMove()
var fromEngine = viewPosToEngine(from)
for(var i=0; i < result.length; ++i) {
- if(fromEngine == result[i][1]) {
+ if(fromEngine === result[i][1]) {
var pos = engineToViewPos(result[i][2])
items.squares.getSquareAt(pos)['acceptMove'] = true
}
}
}
// Calculate the score for black and white
// Count the number of pieces with each piece having a given weight
// Piece pawn knight bishop rook queen
// Value 1 3 3 5 9
// @return [white, black]
function getScore() {
var lut = {2: 1, 4: 5, 6: 3, 8: 3, 12: 9}
var white = 0
var black = 0
for(var i=0; i < state['board'].length; ++i) {
var score = lut[state['board'][i] & 0xFE]
if(score)
if(state['board'][i] & 0x01)
black += score
else
white += score
}
return [white, black]
}
diff --git a/src/activities/chess/engine.js b/src/activities/chess/engine.js
index adcc06630..4ae321bd8 100644
--- a/src/activities/chess/engine.js
+++ b/src/activities/chess/engine.js
@@ -1,1603 +1,1603 @@
/* p4wn, AKA 5k chess - by Douglas Bagnall <douglas@paradise.net.nz>
*
* This code is in the public domain, or as close to it as various
* laws allow. No warranty; no restrictions.
*
* lives at http://p4wn.sf.net/
*/
/*Compatibility tricks:
* backwards for old MSIEs (to 5.5)
* sideways for seed command-line javascript.*/
var p4_log;
if (this.imports !== undefined &&
this.printerr !== undefined){//seed or gjs
p4_log = function(){
var args = Array.prototype.slice.call(arguments);
printerr(args.join(', '));
};
}
else if (this.console === undefined){//MSIE
p4_log = function(){};
}
else {
// disable the console
p4_log = function(){};
//p4_log = function(){console.log.apply(console, arguments);};
}
/*MSIE Date.now backport */
if (Date.now === undefined)
Date.now = function(){return (new Date).getTime();};
/* The pieces are stored as numbers between 2 and 13, inclusive.
* Empty squares are stored as 0, and off-board squares as 16.
* There is some bitwise logic to it:
* piece & 1 -> colour (white: 0, black: 1)
* piece & 2 -> single move piece (including pawn)
* if (piece & 2) == 0:
* piece & 4 -> row and column moves
* piece & 8 -> diagonal moves
*/
var P4_PAWN = 2, P4_ROOK = 4, P4_KNIGHT = 6, P4_BISHOP = 8, P4_QUEEN = 12, P4_KING = 10;
var P4_EDGE = 16;
/* in order, even indices: <nothing>, pawn, rook, knight, bishop, king, queen. Only the
* even indices are used.*/
var P4_MOVES = [[], [],
[], [],
[1,10,-1,-10], [],
[21,19,12,8,-21,-19,-12,-8], [],
[11,9,-11,-9], [],
[1,10,11,9,-1,-10,-11,-9], [],
[1,10,11,9,-1,-10,-11,-9], []
];
/*P4_VALUES defines the relative value of various pieces.
*
* It follows the 1,3,3,5,9 pattern you learn as a kid, multiplied by
* 20 to give sub-pawn resolution to other factors, with bishops given
* a wee boost over knights.
*/
var P4_VALUES=[0, 0, //Piece values
20, 20, //pawns
100, 100, //rooks
60, 60, //knights
61, 61, //bishops
8000, 8000,//kings
180, 180, //queens
0];
/* A score greater than P4_WIN indicates a king has been taken. It is
* less than the value of a king, in case someone finds a way to, say,
* sacrifice two queens in order to checkmate.
*/
var P4_KING_VALUE = P4_VALUES[10];
var P4_WIN = P4_KING_VALUE >> 1;
/* every move, a winning score decreases by this much */
var P4_WIN_DECAY = 300;
var P4_WIN_NOW = P4_KING_VALUE - 250;
/* P4_{MAX,MIN}_SCORE should be beyond any possible evaluated score */
var P4_MAX_SCORE = 9999; // extremes of evaluation range
var P4_MIN_SCORE = -P4_MAX_SCORE;
/*initialised in p4_initialise_state */
var P4_CENTRALISING_WEIGHTS;
var P4_BASE_PAWN_WEIGHTS;
var P4_KNIGHT_WEIGHTS;
/*P4_DEBUG turns on debugging features */
var P4_DEBUG = 0;
var P4_INITIAL_BOARD = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 1 1";
/*use javascript typed arrays rather than plain arrays
* (faster in some browsers, unsupported in others, possibly slower elsewhere) */
var P4_USE_TYPED_ARRAYS = this.Int32Array !== undefined;
var P4_PIECE_LUT = { /*for FEN, PGN interpretation */
P: 2,
p: 3,
R: 4,
r: 5,
N: 6,
n: 7,
B: 8,
b: 9,
K: 10,
k: 11,
Q: 12,
q: 13
};
var P4_ENCODE_LUT = ' PPRRNNBBKKQQ';
function p4_alphabeta_treeclimber(state, count, colour, score, s, e, alpha, beta){
var move = p4_make_move(state, s, e, P4_QUEEN);
var i;
var ncolour = 1 - colour;
var movelist = p4_parse(state, colour, move.ep, -score);
var movecount = movelist.length;
if(count){
//branch nodes
var t;
for(i = 0; i < movecount; i++){
var mv = movelist[i];
var mscore = mv[0];
var ms = mv[1];
var me = mv[2];
if (mscore > P4_WIN){ //we won! Don't look further.
alpha = P4_KING_VALUE;
break;
}
t = -p4_alphabeta_treeclimber(state, count - 1, ncolour, mscore, ms, me,
-beta, -alpha);
if (t > alpha){
alpha = t;
}
if (alpha >= beta){
break;
}
}
if (alpha < -P4_WIN_NOW && ! p4_check_check(state, colour)){
/* Whatever we do, we lose the king.
* But if it is not check then this is stalemate, and the
* score doesn't apply.
*/
alpha = state.stalemate_scores[colour];
}
if (alpha < -P4_WIN){
/*make distant checkmate seem less bad */
alpha += P4_WIN_DECAY;
}
}
else{
//leaf nodes
while(beta > alpha && --movecount != -1){
if(movelist[movecount][0] > alpha){
alpha = movelist[movecount][0];
}
}
}
p4_unmake_move(state, move);
return alpha;
}
/* p4_prepare() works out weightings for assessing various moves,
* favouring centralising moves early, for example.
*
* It is called before each tree search, not for each parse(), so it
* is OK for it to be a little bit slow. But that also means it drifts
* out of sync with the real board state, especially on deep searches.
*/
function p4_prepare(state){
var i, j, x, y, a;
var pieces = state.pieces = [[], []];
/*convert state.moveno half move count to move cycle count */
var moveno = state.moveno >> 1;
var board = state.board;
/* high earliness_weight indicates a low move number. The formula
* should work above moveno == 50, but this is javascript.
*/
var earliness_weight = (moveno > 50) ? 0 : parseInt(6 * Math.exp(moveno * -0.07));
var king_should_hide = moveno < 12;
var early = moveno < 5;
/* find the pieces, kings, and weigh material*/
var kings = [0, 0];
var material = [0, 0];
var best_pieces = [0, 0];
for(i = 20; i < 100; i++){
a = board[i];
var piece = a & 14;
var colour = a & 1;
if(piece){
pieces[colour].push([a, i]);
if (piece == P4_KING){
kings[colour] = i;
}
else{
material[colour] += P4_VALUES[piece];
best_pieces[colour] = Math.max(best_pieces[colour], P4_VALUES[piece]);
}
}
}
/*does a draw seem likely soon?*/
var draw_likely = (state.draw_timeout > 90 || state.current_repetitions >= 2);
if (draw_likely)
p4_log("draw likely", state.current_repetitions, state.draw_timeout);
state.values = [[], []];
var qvalue = P4_VALUES[P4_QUEEN]; /*used as ballast in various ratios*/
var material_sum = material[0] + material[1] + 2 * qvalue;
var wmul = 2 * (material[1] + qvalue) / material_sum;
var bmul = 2 * (material[0] + qvalue) / material_sum;
var multipliers = [wmul, bmul];
var emptiness = 4 * P4_QUEEN / material_sum;
state.stalemate_scores = [parseInt(0.5 + (wmul - 1) * 2 * qvalue),
parseInt(0.5 + (bmul - 1) * 2 * qvalue)];
//p4_log("value multipliers (W, B):", wmul, bmul,
// "stalemate scores", state.stalemate_scores);
for (i = 0; i < P4_VALUES.length; i++){
var v = P4_VALUES[i];
if (v < P4_WIN){//i.e., not king
state.values[0][i] = parseInt(v * wmul + 0.5);
state.values[1][i] = parseInt(v * bmul + 0.5);
}
else {
state.values[0][i] = v;
state.values[1][i] = v;
}
}
/*used for pruning quiescence search */
state.best_pieces = [parseInt(best_pieces[0] * wmul + 0.5),
parseInt(best_pieces[1] * bmul + 0.5)];
var kx = [kings[0] % 10, kings[1] % 10];
var ky = [parseInt(kings[0] / 10), parseInt(kings[1] / 10)];
/* find the frontmost pawns in each file */
var pawn_cols = [[], []];
for (y = 3; y < 9; y++){
for (x = 1; x < 9; x++){
i = y * 10 + x;
a = board[i];
if ((a & 14) != P4_PAWN)
continue;
if ((a & 1) == 0){
pawn_cols[0][x] = y;
}
else if (pawn_cols[1][x] === undefined){
pawn_cols[1][x] = y;
}
}
}
var target_king = (moveno >= 20 || material_sum < 5 * qvalue);
var weights = state.weights;
for (y = 2; y < 10; y++){
for (x = 1; x < 9; x++){
i = y * 10 + x;
var early_centre = P4_CENTRALISING_WEIGHTS[i] * earliness_weight;
var plateau = P4_KNIGHT_WEIGHTS[i];
for (var c = 0; c < 2; c++){
var dx = Math.abs(kx[1 - c] - x);
var dy = Math.abs(ky[1 - c] - y);
var our_dx = Math.abs(kx[c] - x);
var our_dy = Math.abs(ky[c] - y);
var d = Math.max(Math.sqrt(dx * dx + dy * dy), 1) + 1;
var mul = multipliers[c]; /*(mul < 1) <==> we're winning*/
var mul3 = mul * mul * mul;
var at_home = y == 2 + c * 7;
var pawn_home = y == 3 + c * 5;
var row4 = y == 5 + c;
var promotion_row = y == 9 - c * 7;
var get_out = (early && at_home) * -5;
var knight = parseInt(early_centre * 0.3) + 2 * plateau + get_out;
var rook = parseInt(early_centre * 0.3);
var bishop = parseInt(early_centre * 0.6) + plateau + get_out;
if (at_home){
rook += (x == 4 || x == 5) * (earliness_weight + ! target_king);
rook += (x == 1 || x == 8) * (moveno > 10 && moveno < 20) * -3;
rook += (x == 2 || x == 7) * (moveno > 10 && moveno < 20) * -1;
}
/*Queen wants to stay home early, then jump right in*/
/*keep kings back on home row for a while*/
var queen = parseInt(plateau * 0.5 + early_centre * (0.5 - early));
var king = (king_should_hide && at_home) * 2 * earliness_weight;
/*empty board means pawn advancement is more urgent*/
var get_on_with_it = Math.max(emptiness * 2, 1);
var pawn = get_on_with_it * P4_BASE_PAWN_WEIGHTS[c ? 119 - i : i];
if (early){
/* Early pawn weights are slightly randomised, so each game is different.
*/
if (y >= 4 && y <= 7){
var boost = 1 + 3 * (y == 5 || y == 6);
pawn += parseInt((boost + p4_random_int(state, 4)) * 0.1 *
early_centre);
}
if (x == 4 || x == 5){
//discourage middle pawns from waiting at home
pawn -= 3 * pawn_home;
pawn += 3 * row4;
}
}
/*pawn promotion row is weighted as a queen minus a pawn.*/
if (promotion_row)
pawn += state.values[c][P4_QUEEN] - state.values[c][P4_PAWN];
/*pawns in front of a castled king should stay there*/
pawn += 4 * (y == 3 && ky[c] == 2 && Math.abs(our_dx) < 2 &&
kx[c] != 5 && x != 4 && x != 5);
/*passed pawns (having no opposing pawn in front) are encouraged. */
var cols = pawn_cols[1 - c];
if (cols[x] == undefined ||
(c == 0 && cols[x] < y) ||
(c == 1 && cols[x] > y))
pawn += 2;
/* After a while, start going for opposite king. Just
* attract pieces into the area so they can mill about in
* the area, waiting for an opportunity.
*
* As prepare is only called at the beginning of each tree
- * search, the king could wander out of the targetted area
+ * search, the king could wander out of the targeted area
* in deep searches. But that's OK. Heuristics are
* heuristics.
*/
if (target_king){
knight += 2 * parseInt(8 * mul / d);
rook += 2 * ((dx < 2) + (dy < 2));
bishop += 3 * (Math.abs((dx - dy)) < 2);
queen += 2 * parseInt(8 / d) + (dx * dy == 0) + (dx - dy == 0);
/* The losing king wants to stay in the middle, while
the winning king goes in for the kill.*/
var king_centre_wt = 8 * emptiness * P4_CENTRALISING_WEIGHTS[i];
king += parseInt(150 * emptiness / (mul3 * d) + king_centre_wt * mul3);
}
weights[P4_PAWN + c][i] = pawn;
weights[P4_KNIGHT + c][i] = knight;
weights[P4_ROOK + c][i] = rook;
weights[P4_BISHOP + c][i] = bishop;
weights[P4_QUEEN + c][i] = queen;
weights[P4_KING + c][i] = king;
if (draw_likely && mul < 1){
/*The winning side wants to avoid draw, so adds jitter to its weights.*/
var range = 3 / mul3;
for (j = 2 + c; j < 14; j += 2){
weights[j][i] += p4_random_int(state, range);
}
}
}
}
}
state.prepared = true;
}
function p4_maybe_prepare(state){
if (! state.prepared)
p4_prepare(state);
}
function p4_parse(state, colour, ep, score) {
var board = state.board;
var s, e; //start and end position
var E, a; //E=piece at end place, a= piece moving
var i, j;
var other_colour = 1 - colour;
var dir = (10 - 20 * colour); //dir= 10 for white, -10 for black
var movelist = [];
var captures = [];
var weight;
var pieces = state.pieces[colour];
var castle_flags = (state.castles >> (colour * 2)) & 3;
var values = state.values[other_colour];
var all_weights = state.weights;
for (j = pieces.length - 1; j >= 0; j--){
s = pieces[j][1]; // board position
a = board[s]; //piece number
var weight_lut = all_weights[a];
weight = score - weight_lut[s];
a &= 14;
if(a > 2){ //non-pawns
var moves = P4_MOVES[a];
if(a & 2){
for(i = 0; i < 8; i++){
e = s + moves[i];
E = board[e];
if(!E){
movelist.push([weight + values[E] + weight_lut[e], s, e]);
}
else if((E&17)==other_colour){
captures.push([weight + values[E] + weight_lut[e] + all_weights[E][e], s, e]);
}
}
- if(a == P4_KING && castle_flags){
+ if(a === P4_KING && castle_flags){
if((castle_flags & 1) &&
(board[s-1] + board[s-2] + board[s-3] == 0) &&
p4_check_castling(board, s - 2,other_colour,dir,-1)){//Q side
movelist.push([weight + 12, s, s - 2]); //no analysis, just encouragement
}
if((castle_flags & 2) && (board[s+1]+board[s+2] == 0)&&
p4_check_castling(board, s, other_colour, dir, 1)){//K side
movelist.push([weight + 13, s, s + 2]);
}
}
}
else{//rook, bishop, queen
var mlen = moves.length;
for(i=0;i<mlen;){ //goeth thru list of moves
var m = moves[i++];
e=s;
// can't do-while loop: https://bugreports.qt.io/browse/QTBUG-59012
e+=m;
E=board[e];
if(!E){
movelist.push([weight + values[E] + weight_lut[e], s, e]);
}
else if((E&17)==other_colour){
captures.push([weight + values[E] + weight_lut[e] + all_weights[E][e], s, e]);
}
while(!E) {
e+=m;
E=board[e];
if(!E){
movelist.push([weight + values[E] + weight_lut[e], s, e]);
}
else if((E&17)==other_colour){
captures.push([weight + values[E] + weight_lut[e] + all_weights[E][e], s, e]);
}
}
}
}
}
else{ //pawns
e=s+dir;
if(!board[e]){
movelist.push([weight + weight_lut[e], s, e]);
/* s * (120 - s) < 3200 true for outer two rows on either side.*/
var e2 = e + dir;
if(s * (120 - s) < 3200 && (!board[e2])){
movelist.push([weight + weight_lut[e2], s, e2]);
}
}
/* +/-1 for pawn capturing */
E = board[--e];
if(E && (E & 17) == other_colour){
captures.push([weight + values[E] + weight_lut[e] + all_weights[E][e], s, e]);
}
e += 2;
E = board[e];
if(E && (E & 17) == other_colour){
captures.push([weight + values[E] + weight_lut[e] + all_weights[E][e], s, e]);
}
}
}
if(ep){
var pawn = P4_PAWN | colour;
var taken;
/* Some repetitive calculation here could be hoisted out, but that would
probably slow things: the common case is no pawns waiting to capture
enpassant, not 2.
*/
s = ep - dir - 1;
- if (board[s] == pawn){
+ if (board[s] === pawn){
taken = values[P4_PAWN] + all_weights[P4_PAWN | other_colour][ep - dir];
captures.push([score - weight_lut[s] + weight_lut[ep] + taken, s, ep]);
}
s += 2;
- if (board[s] == pawn){
+ if (board[s] === pawn){
taken = values[P4_PAWN] + all_weights[P4_PAWN | other_colour][ep - dir];
captures.push([score - weight_lut[s] + weight_lut[ep] + taken, s, ep]);
}
}
return captures.concat(movelist);
}
/*Explaining the bit tricks used in check_castling and check_check:
*
* in binary: 16 8 4 2 1
* empty
* pawn 1 c
* rook 1 c
* knight 1 1 c
* bishop 1 c
* king 1 1 c
* queen 1 1 c
* wall 1
*
* so:
*
* piece & (16 | 4 | 2 | 1) is:
* 2 + c for kings and pawns
* 4 + c for rooks and queens
* 6 + c for knights
* 0 + c for bishops
* 16 for walls
*
* thus:
* ((piece & 23) == 4 | colour) separates the rooks and queens out
* from the rest.
* ((piece & 27) == 8 | colour) does the same for queens and bishops.
*/
/* check_castling
*
* s - "start" location (either king home square, or king destination)
* the checks are done left to right.
* * dir - direction of travel (White: 10, Black: -10)
* side: -1 means Q side; 1, K side
*/
function p4_check_castling(board, s, colour, dir, side){
var e;
var E;
var m, p;
var knight = colour + P4_KNIGHT;
var diag_slider = P4_BISHOP | colour;
var diag_mask = 27;
var grid_slider = P4_ROOK | colour;
var king_pawn = 2 | colour;
var grid_mask = 23;
/* go through 3 positions, checking for check in each
*/
for(p = s; p < s + 3; p++){
//bishops, rooks, queens
e = p;
// can't do-while loop: https://bugreports.qt.io/browse/QTBUG-59012
e += dir;
E=board[e];
while (! E) {
e += dir;
E=board[e];
}
if((E & grid_mask) == grid_slider)
return 0;
e = p;
var delta = dir - 1;
// can't do-while loop: https://bugreports.qt.io/browse/QTBUG-59012
e += delta;
E=board[e];
while (!E) {
e += delta;
E=board[e];
}
if((E & diag_mask) == diag_slider)
return 0;
e = p;
delta += 2;
// can't do-while loop: https://bugreports.qt.io/browse/QTBUG-59012
e += delta;
E=board[e];
while(! E) {
e += delta;
E=board[e];
}
if((E & diag_mask) == diag_slider)
return 0;
/*knights on row 7. (row 6 is handled below)*/
- if (board[p + dir - 2] == knight ||
- board[p + dir + 2] == knight)
+ if (board[p + dir - 2] === knight ||
+ board[p + dir + 2] === knight)
return 0;
}
/* a pawn or king in any of 5 positions on row 7.
* or a knight on row 6. */
for(p = s + dir - 1; p < s + dir + 4; p++){
E = board[p] & grid_mask;
- if(E == king_pawn || board[p + dir] == knight)
+ if(E === king_pawn || board[p + dir] === knight)
return 0;
}
/* scan back row for rooks, queens on the other side.
* Same side check is impossible, because the castling rook is there
*/
e = (side < 0) ? s + 2 : s;
// can't do-while loop: https://bugreports.qt.io/browse/QTBUG-59012
e -= side;
E=board[e];
while (! E) {
e -= side;
E=board[e];
}
if((E & grid_mask) == grid_slider)
return 0;
return 1;
}
function p4_check_check(state, colour){
var board = state.board;
/*find the king. The pieces list updates from the end,
* so the last-most king is correctly placed.*/
var pieces = state.pieces[colour];
var i = pieces.length;
var king = P4_KING | colour
// can't do-while loop: https://bugreports.qt.io/browse/QTBUG-59012
var val = king-1
while (val !== king) {
var p = pieces[--i];
val = p[0]
};
var s = p[1];
var other_colour = 1 - colour;
var dir = 10 - 20 * colour;
- if (board[s + dir - 1] == (P4_PAWN | other_colour) ||
- board[s + dir + 1] == (P4_PAWN | other_colour))
+ if (board[s + dir - 1] === (P4_PAWN | other_colour) ||
+ board[s + dir + 1] === (P4_PAWN | other_colour))
return true;
var knight_moves = P4_MOVES[P4_KNIGHT];
var king_moves = P4_MOVES[P4_KING];
var knight = P4_KNIGHT | other_colour;
var king = P4_KING | other_colour;
for (i = 0; i < 8; i++){
- if (board[s + knight_moves[i]] == knight ||
- board[s + king_moves[i]] == king)
+ if (board[s + knight_moves[i]] === knight ||
+ board[s + king_moves[i]] === king)
return true;
}
var diagonal_moves = P4_MOVES[P4_BISHOP];
var grid_moves = P4_MOVES[P4_ROOK];
/* diag_mask ignores rook moves of queens,
* grid_mask ignores the bishop moves*/
var diag_slider = P4_BISHOP | other_colour;
var diag_mask = 27;
var grid_slider = P4_ROOK | other_colour;
var grid_mask = 23;
for (i = 0; i < 4; i++){
var m = diagonal_moves[i];
var e = s;
var E;
// can't do-while loop: https://bugreports.qt.io/browse/QTBUG-59012
e += m;
E = board[e];
while (!E) {
e += m;
E = board[e];
}
if((E & diag_mask) == diag_slider)
return true;
m = grid_moves[i];
e = s;
// can't do-while loop: https://bugreports.qt.io/browse/QTBUG-59012
e += m;
E = board[e];
while (!E) {
e += m;
E = board[e];
}
if((E & grid_mask) == grid_slider)
return true;
}
return false;
}
function p4_optimise_piece_list(state){
var i, p, s, e;
var movelists = [
p4_parse(state, 0, 0, 0),
p4_parse(state, 1, 0, 0)
];
var weights = state.weights;
var board = state.board;
for (var colour = 0; colour < 2; colour++){
var our_values = state.values[colour];
var pieces = state.pieces[colour];
var movelist = movelists[colour];
var threats = movelists[1 - colour];
/* sparse array to index by score. */
var scores = [];
for (i = 0; i < pieces.length; i++){
p = pieces[i];
scores[p[1]] = {
score: 0,
piece: p[0],
pos: p[1],
threatened: 0
};
}
/* Find the best score for each piece by pure static weights,
* ignoring captures, which have their own path to the top. */
for(i = movelist.length - 1; i >= 0; i--){
var mv = movelist[i];
var score = mv[0];
s = mv[1];
e = mv[2];
if(! board[e]){
var x = scores[s];
x.score = Math.max(x.score, score);
}
}
/* moving out of a threat is worth considering, especially
* if it is a pawn and you are not.*/
for(i = threats.length - 1; i >= 0; i--){
var mv = threats[i];
var x = scores[mv[2]];
if (x !== undefined){
var S = board[mv[1]];
var r = (1 + x.piece > 3 + S < 4) * 0.01;
if (x.threatened < r)
x.threatened = r;
}
}
var pieces2 = [];
for (i = 20; i < 100; i++){
p = scores[i];
if (p !== undefined){
p.score += p.threatened * our_values[p.piece];
pieces2.push(p);
}
}
pieces2.sort(function(a, b){return a.score - b.score;});
for (i = 0; i < pieces2.length; i++){
p = pieces2[i];
pieces[i] = [p.piece, p.pos];
}
}
}
function p4_findmove(state, level, colour, ep){
p4_prepare(state);
p4_optimise_piece_list(state);
var board = state.board;
if (arguments.length == 2){
colour = state.to_play;
ep = state.enpassant;
}
var movelist = p4_parse(state, colour, ep, 0);
var alpha = P4_MIN_SCORE;
var mv, t, i;
var bs = 0;
var be = 0;
if (level <= 0){
for (i = 0; i < movelist.length; i++){
mv = movelist[i];
if(movelist[i][0] > alpha){
alpha = mv[0];
bs = mv[1];
be = mv[2];
}
}
return [bs, be, alpha];
}
for(i = 0; i < movelist.length; i++){
mv = movelist[i];
var mscore = mv[0];
var ms = mv[1];
var me = mv[2];
if (mscore > P4_WIN){
p4_log("XXX taking king! it should never come to this");
alpha = P4_KING_VALUE;
bs = ms;
be = me;
break;
}
t = -state.treeclimber(state, level - 1, 1 - colour, mscore, ms, me,
P4_MIN_SCORE, -alpha);
if (t > alpha){
alpha = t;
bs = ms;
be = me;
}
}
if (alpha < -P4_WIN_NOW && ! p4_check_check(state, colour)){
alpha = state.stalemate_scores[colour];
}
return [bs, be, alpha];
}
/*p4_make_move changes the state and returns an object containing
- * everything necesary to undo the change.
+ * everything necessary to undo the change.
*
* p4_unmake_move uses the p4_make_move return value to restore the
* previous state.
*/
function p4_make_move(state, s, e, promotion){
var board = state.board;
var S = board[s];
var E = board[e];
board[e] = S;
board[s] = 0;
var piece = S & 14;
var moved_colour = S & 1;
var end_piece = S; /* can differ from S in queening*/
//now some stuff to handle queening, castling
var rs = 0, re, rook;
var ep_taken = 0, ep_position;
var ep = 0;
if(piece == P4_PAWN){
if((60 - e) * (60 - e) > 900){
/*got to end; replace the pawn on board and in pieces cache.*/
promotion |= moved_colour;
board[e] = promotion;
end_piece = promotion;
}
- else if (((s ^ e) & 1) && E == 0){
+ else if (((s ^ e) & 1) && E === 0){
/*this is a diagonal move, but the end spot is empty, so we surmise enpassant */
ep_position = e - 10 + 20 * moved_colour;
ep_taken = board[ep_position];
board[ep_position] = 0;
}
else if ((s - e) * (s - e) == 400){
/*delta is 20 --> two row jump at start*/
ep = (s + e) >> 1;
}
}
else if (piece == P4_KING && ((s - e) * (s - e) == 4)){ //castling - move rook too
rs = s - 4 + (s < e) * 7;
re = (s + e) >> 1; //avg of s,e=rook's spot
rook = moved_colour + P4_ROOK;
board[rs] = 0;
board[re] = rook;
//piece_locations.push([rook, re]);
}
var old_castle_state = state.castles;
if (old_castle_state){
var mask = 0;
var shift = moved_colour * 2;
var side = moved_colour * 70;
var s2 = s - side;
var e2 = e + side;
//wipe both our sides if king moves
if (s2 == 25)
mask |= 3 << shift;
//wipe one side on any move from rook points
else if (s2 == 21)
mask |= 1 << shift;
else if (s2 == 28)
mask |= 2 << shift;
//or on any move *to* opposition corners
if (e2 == 91)
mask |= 4 >> shift;
else if (e2 == 98)
mask |= 8 >> shift;
state.castles &= ~mask;
}
var old_pieces = state.pieces.concat();
var our_pieces = old_pieces[moved_colour];
var dest = state.pieces[moved_colour] = [];
for (var i = 0; i < our_pieces.length; i++){
var x = our_pieces[i];
var pp = x[0];
var ps = x[1];
if (ps != s && ps != rs){
dest.push(x);
}
}
dest.push([end_piece, e]);
if (rook)
dest.push([rook, re]);
if (E || ep_taken){
var their_pieces = old_pieces[1 - moved_colour];
dest = state.pieces[1 - moved_colour] = [];
var gone = ep_taken ? ep_position : e;
for (i = 0; i < their_pieces.length; i++){
var x = their_pieces[i];
if (x[1] != gone){
dest.push(x);
}
}
}
return {
/*some of these (e.g. rook) could be recalculated during
* unmake, possibly more cheaply. */
s: s,
e: e,
S: S,
E: E,
ep: ep,
castles: old_castle_state,
rs: rs,
re: re,
rook: rook,
ep_position: ep_position,
ep_taken: ep_taken,
pieces: old_pieces
};
}
function p4_unmake_move(state, move){
var board = state.board;
if (move.ep_position){
board[move.ep_position] = move.ep_taken;
}
board[move.s] = move.S;
board[move.e] = move.E;
//move.piece_locations.length--;
if(move.rs){
board[move.rs] = move.rook;
board[move.re] = 0;
//move.piece_locations.length--;
}
state.pieces = move.pieces;
state.castles = move.castles;
}
function p4_insufficient_material(state){
var knights = false;
var bishops = undefined;
var i;
var board = state.board;
for(i = 20; i < 100; i++){
var piece = board[i] & 14;
if(piece == 0 || piece == P4_KING){
continue;
}
if (piece == P4_KNIGHT){
/* only allow one knight of either colour, never with a bishop */
if (knights || bishops !== undefined){
return false;
}
knights = true;
}
else if (piece == P4_BISHOP){
/*any number of bishops, but on only one colour square */
var x = i & 1;
var y = parseInt(i / 10) & 1;
var parity = x ^ y;
if (knights){
return false;
}
else if (bishops === undefined){
bishops = parity;
}
else if (bishops != parity){
return false;
}
}
else {
return false;
}
}
return true;
}
/* p4_move(state, s, e, promotion)
* s, e are start and end positions
*
* promotion is the desired pawn promotion if the move gets a pawn to the other
* end.
*
* return value contains bitwise flags
*/
var P4_MOVE_FLAG_OK = 1;
var P4_MOVE_FLAG_CHECK = 2;
var P4_MOVE_FLAG_MATE = 4;
var P4_MOVE_FLAG_CAPTURE = 8;
var P4_MOVE_FLAG_CASTLE_KING = 16;
var P4_MOVE_FLAG_CASTLE_QUEEN = 32;
var P4_MOVE_FLAG_DRAW = 64;
var P4_MOVE_ILLEGAL = 0;
var P4_MOVE_MISSED_MATE = P4_MOVE_FLAG_CHECK | P4_MOVE_FLAG_MATE;
var P4_MOVE_CHECKMATE = P4_MOVE_FLAG_OK | P4_MOVE_FLAG_CHECK | P4_MOVE_FLAG_MATE;
var P4_MOVE_STALEMATE = P4_MOVE_FLAG_OK | P4_MOVE_FLAG_MATE;
function p4_move(state, s, e, promotion){
var board = state.board;
var colour = state.to_play;
var other_colour = 1 - colour;
if (s != parseInt(s)){
if (e === undefined){
var mv = p4_interpret_movestring(state, s);
s = mv[0];
e = mv[1];
if (s == 0)
return {flags: P4_MOVE_ILLEGAL, ok: false};
promotion = mv[2];
}
else {/*assume two point strings: 'e2', 'e4'*/
s = p4_destringify_point(s);
e = p4_destringify_point(e);
}
}
if (promotion === undefined)
promotion = P4_QUEEN;
var E=board[e];
var S=board[s];
/*See if this move is even slightly legal, disregarding check.
*/
var i;
var legal = false;
p4_maybe_prepare(state);
var moves = p4_parse(state, colour, state.enpassant, 0);
for (i = 0; i < moves.length; i++){
- if (e == moves[i][2] && s == moves[i][1]){
+ if (e === moves[i][2] && s === moves[i][1]){
legal = true;
break;
}
}
if (! legal) {
return {flags: P4_MOVE_ILLEGAL, ok: false};
}
/*Try the move, and see what the response is.*/
var changes = p4_make_move(state, s, e, promotion);
/*is it check? */
if (p4_check_check(state, colour)){
p4_unmake_move(state, changes);
p4_log('in check', changes);
return {flags: P4_MOVE_ILLEGAL, ok: false, string: "in check!"};
}
/*The move is known to be legal. We won't be undoing it.*/
var flags = P4_MOVE_FLAG_OK;
state.enpassant = changes.ep;
state.history.push([s, e, promotion]);
/*draw timeout: 50 moves without pawn move or capture is a draw */
if (changes.E || changes.ep_position){
state.draw_timeout = 0;
flags |= P4_MOVE_FLAG_CAPTURE;
}
else if ((S & 14) == P4_PAWN){
state.draw_timeout = 0;
}
else{
state.draw_timeout++;
}
if (changes.rs){
flags |= (s > e) ? P4_MOVE_FLAG_CASTLE_QUEEN : P4_MOVE_FLAG_CASTLE_KING;
}
var shortfen = p4_state2fen(state, true);
var repetitions = (state.position_counts[shortfen] || 0) + 1;
state.position_counts[shortfen] = repetitions;
state.current_repetitions = repetitions;
if (state.draw_timeout > 100 || repetitions >= 3 ||
p4_insufficient_material(state)){
flags |= P4_MOVE_FLAG_DRAW;
}
state.moveno++;
state.to_play = other_colour;
if (p4_check_check(state, other_colour)){
flags |= P4_MOVE_FLAG_CHECK;
}
/* check for (stale|check)mate, by seeing if there is a move for
* the other side that doesn't result in check. (In other words,
* reduce the pseudo-legal-move list down to a legal-move list,
* and check it isn't empty).
*
* We don't need to p4_prepare because other colour pieces can't
* have moved (just disappeared) since previous call. Also,
* setting the promotion piece is unnecessary, because all
* promotions block check equally well.
*/
var is_mate = true;
var replies = p4_parse(state, other_colour, changes.ep, 0);
for (i = 0; i < replies.length; i++){
var m = replies[i];
var change2 = p4_make_move(state, m[1], m[2], P4_QUEEN);
var check = p4_check_check(state, other_colour);
p4_unmake_move(state, change2);
if (!check){
is_mate = false;
break;
}
}
if (is_mate)
flags |= P4_MOVE_FLAG_MATE;
var movestring = p4_move2string(state, s, e, S, promotion, flags, moves);
p4_log("successful move", s, e, movestring, flags);
state.prepared = false;
return {
flags: flags,
string: movestring,
ok: true
};
}
function p4_move2string(state, s, e, S, promotion, flags, moves){
var piece = S & 14;
var src, dest;
var mv, i;
var capture = flags & P4_MOVE_FLAG_CAPTURE;
src = p4_stringify_point(s);
dest = p4_stringify_point(e);
if (piece == P4_PAWN){
if (capture){
mv = src.charAt(0) + 'x' + dest;
}
else
mv = dest;
if (e > 90 || e < 30){ //end row, queening
if (promotion === undefined)
promotion = P4_QUEEN;
mv += '=' + P4_ENCODE_LUT.charAt(promotion);
}
}
else if (piece == P4_KING && (s-e) * (s-e) == 4) {
if (e < s)
mv = 'O-O-O';
else
mv = 'O-O';
}
else {
var row_qualifier = '';
var col_qualifier = '';
var pstr = P4_ENCODE_LUT.charAt(S);
var sx = s % 10;
var sy = parseInt(s / 10);
/* find any other pseudo-legal moves that would put the same
* piece in the same place, for which we'd need
* disambiguation. */
var co_landers = [];
for (i = 0; i < moves.length; i++){
var m = moves[i];
if (e == m[2] && s != m[1] && state.board[m[1]] == S){
co_landers.push(m[1]);
}
}
if (co_landers.length){
for (i = 0; i < co_landers.length; i++){
var c = co_landers[i];
var cx = c % 10;
var cy = parseInt(c / 10);
if (cx == sx)/*same column, so qualify by row*/
row_qualifier = src.charAt(1);
if (cy == sy)
col_qualifier = src.charAt(0);
}
if (row_qualifier == '' && col_qualifier == ''){
/*no co-landers on the same rank or file, so one or the other will do.
* By convention, use the column (a-h) */
col_qualifier = src.charAt(0);
}
}
mv = pstr + col_qualifier + row_qualifier + (capture ? 'x' : '') + dest;
}
if (flags & P4_MOVE_FLAG_CHECK){
if (flags & P4_MOVE_FLAG_MATE)
mv += '#';
else
mv += '+';
}
else if (flags & P4_MOVE_FLAG_MATE)
mv += ' stalemate';
return mv;
}
function p4_jump_to_moveno(state, moveno){
p4_log('jumping to move', moveno);
if (moveno === undefined || moveno > state.moveno)
moveno = state.moveno;
else if (moveno < 0){
moveno = state.moveno + moveno;
}
var state2 = p4_fen2state(state.beginning);
var i = 0;
while (state2.moveno < moveno){
var m = state.history[i++];
p4_move(state2, m[0], m[1], m[2]);
}
/* copy the replayed state across, not all that deeply, but
* enough to cover, eg, held references to board. */
var attr, dest;
for (attr in state2){
var src = state2[attr];
if (attr instanceof Array){
dest = state[attr];
dest.length = 0;
for (i = 0; i < src.length; i++){
dest[i] = src[i];
}
}
else {
state[attr] = src;
}
}
state.prepared = false;
}
/* write a standard FEN notation
* http://en.wikipedia.org/wiki/Forsyth%E2%80%93Edwards_Notation
* */
function p4_state2fen(state, reduced){
var piece_lut = ' PpRrNnBbKkQq';
var board = state.board;
var fen = '';
//fen does Y axis backwards, X axis forwards */
for (var y = 9; y > 1; y--){
var count = 0;
for (var x = 1; x < 9; x++){
var piece = board[y * 10 + x];
- if (piece == 0)
+ if (piece === 0)
count++;
else{
if (count)
fen += count.toString();
fen += piece_lut.charAt(piece);
count = 0;
}
}
if (count)
fen += count;
if (y > 2)
fen += '/';
}
/*white or black */
fen += ' ' + 'wb'.charAt(state.to_play) + ' ';
/*castling */
if (state.castles){
var lut = [2, 'K', 1, 'Q', 8, 'k', 4, 'q'];
for (var i = 0; i < 8; i += 2){
if (state.castles & lut[i]){
fen += lut[i + 1];
}
}
}
else
fen += '-';
/*enpassant */
if (state.enpassant !== 0){
fen += ' ' + p4_stringify_point(state.enpassant);
}
else
fen += ' -';
if (reduced){
/*if the 'reduced' flag is set, the move number and draw
*timeout are not added. This form is used to detect draws by
*3-fold repetition.*/
return fen;
}
fen += ' ' + state.draw_timeout + ' ';
fen += (state.moveno >> 1) + 1;
return fen;
}
function p4_stringify_point(p){
var letters = " abcdefgh";
var x = p % 10;
var y = (p - x) / 10 - 1;
return letters.charAt(x) + y;
}
function p4_destringify_point(p){
var x = parseInt(p.charAt(0), 19) - 9; //a-h <-> 10-18, base 19
var y = parseInt(p.charAt(1)) + 1;
if (y >= 2 && y < 10 && x >= 1 && x < 9)
return y * 10 + x;
return undefined;
}
/* read a standard FEN notation
* http://en.wikipedia.org/wiki/Forsyth%E2%80%93Edwards_Notation
* */
function p4_fen2state(fen, state){
if (state === undefined)
state = p4_initialise_state();
var board = state.board;
var fenbits = fen.split(' ');
var fen_board = fenbits[0];
var fen_toplay = fenbits[1];
var fen_castles = fenbits[2];
var fen_enpassant = fenbits[3];
var fen_timeout = fenbits[4];
var fen_moveno = fenbits[5];
if (fen_timeout === undefined)
fen_timeout = 0;
//fen does Y axis backwards, X axis forwards */
var y = 90;
var x = 1;
var i;
for (var j = 0; j < fen_board.length; j++){
var c = fen_board.charAt(j);
- if (c == '/'){
+ if (c === '/'){
x = 1;
y -= 10;
if (y < 20)
break;
continue;
}
var piece = P4_PIECE_LUT[c];
if (piece && x < 9){
board[y + x] = piece;
x++;
}
else {
var end = Math.min(x + parseInt(c), 9);
for (; x < end; x++){
board[y + x] = 0;
}
}
}
state.to_play = (fen_toplay.toLowerCase() == 'b') ? 1 : 0;
state.castles = 0;
for (i = 0; i < fen_castles.length; i++){
var bit = {k: 8, q: 4, K: 2, Q: 1}[fen_castles.charAt(i)];
state.castles |= (bit || 0);
}
state.enpassant = (fen_enpassant != '-') ? p4_destringify_point(fen_enpassant) : 0;
state.draw_timeout = parseInt(fen_timeout);
if (fen_moveno === undefined){
/*have a guess based on entropy and pieces remaining*/
var pieces = 0;
var mix = 0;
var p, q, r;
for (y = 20; y < 100; y+=10){
for (x = 1; x < 9; x++){
p = board[y + x] & 15;
pieces += (!!p);
if (x < 8){
q = board[y + x + 1];
mix += (!q) != (!p);
}
if (y < 90){
q = board[y + x + 10];
mix += (!q) != (!p);
}
}
}
fen_moveno = Math.max(1, parseInt((32 - pieces) * 1.3 + (4 - fen_castles.length) * 1.5 + ((mix - 16) / 5)));
//p4_log("pieces", pieces, "mix", mix, "estimate", fen_moveno);
}
state.moveno = 2 * (parseInt(fen_moveno) - 1) + state.to_play;
state.history = [];
state.beginning = fen;
state.prepared = false;
state.position_counts = {};
/* Wrap external functions as methods. */
state.move = function(s, e, promotion){
return p4_move(this, s, e, promotion);
};
state.findmove = function(level){
return p4_findmove(this, level);
};
state.jump_to_moveno = function(moveno){
return p4_jump_to_moveno(this, moveno);
};
return state;
}
/*
Weights would all fit within an Int8Array *except* for the last row
for pawns, which is close to the queen value (180, max is 127).
Int8Array seems slightly quicker in Chromium 18, no different in
Firefox 12.
Int16Array is no faster, perhaps slower than Int32Array.
Int32Array is marginally slower than plain arrays with Firefox 12, but
significantly quicker with Chromium.
*/
var P4_ZEROS = [];
function p4_zero_array(){
if (P4_USE_TYPED_ARRAYS)
return new Int32Array(120);
if (P4_ZEROS.length == 0){
for(var i = 0; i < 120; i++){
P4_ZEROS[i] = 0;
}
}
return P4_ZEROS.slice();
}
/* p4_initialise_state() creates the board and initialises weight
* arrays etc. Some of this is really only needs to be done once.
*/
function p4_initialise_state(){
var board = p4_zero_array();
P4_CENTRALISING_WEIGHTS = p4_zero_array();
P4_BASE_PAWN_WEIGHTS = p4_zero_array();
P4_KNIGHT_WEIGHTS = p4_zero_array();
for(var i = 0; i < 120; i++){
var y = parseInt(i / 10);
var x = i % 10;
var dx = Math.abs(x - 4.5);
var dy = Math.abs(y - 5.5);
P4_CENTRALISING_WEIGHTS[i] = parseInt(6 - Math.pow((dx * dx + dy * dy) * 1.5, 0.6));
//knights have a flat topped centre (bishops too, but less so).
P4_KNIGHT_WEIGHTS[i] = parseInt(((dx < 2) + (dy < 2) * 1.5)
+ (dx < 3) + (dy < 3)) - 2;
P4_BASE_PAWN_WEIGHTS[i] = parseInt('000012347000'.charAt(y));
if (y > 9 || y < 2 || x < 1 || x > 8)
board[i] = 16;
}
var weights = [];
for (i = 0; i < 14; i++){
weights[i] = p4_zero_array();
}
var state = {
board: board,
weights: weights,
history: [],
treeclimber: p4_alphabeta_treeclimber
};
p4_random_seed(state, P4_DEBUG ? 1 : Date.now());
return state;
}
function p4_new_game(){
return p4_fen2state(P4_INITIAL_BOARD);
}
/*convert an arbitrary movestring into a pair of integers offsets into
* the board. The string might be in any of these forms:
*
* "d2-d4" "d2d4" "d4" -- moving a pawn
*
* "b1-c3" "b1c3" "Nc3" "N1c3" "Nbc3" "Nb1c3" -- moving a knight
*
* "b1xc3" "b1xc3" "Nxc3" -- moving a knight, also happens to capture.
*
* "O-O" "O-O-O" -- special cases for castling ("e1-c1", etc, also work)
*
* Note that for the "Nc3" (pgn) format, some knowledge of the board
* is necessary, so the state parameter is required. If it is
* undefined, the other forms will still work.
*/
function p4_interpret_movestring(state, str){
/* Ignore any irrelevant characters, then tokenise.
*
*/
var FAIL = [0, 0];
var algebraic_re = /^\s*([RNBQK]?[a-h]?[1-8]?)[ :x-]*([a-h][1-8]?)(=[RNBQ])?[!?+#e.p]*\s*$/;
var castle_re = /^\s*([O0o]-[O0o](-[O0o])?)\s*$/;
var position_re = /^[a-h][1-8]$/;
var m = algebraic_re.exec(str);
if (m == null){
/*check for castling notation (O-O, O-O-O) */
m = castle_re.exec(str);
if (m){
s = 25 + state.to_play * 70;
if (m[2])/*queenside*/
e = s - 2;
else
e = s + 2;
}
else
return FAIL;
}
var src = m[1];
var dest = m[2];
var queen = m[3];
var s, e, q;
var moves, i;
if (src == '' || src == undefined){
/* a single coordinate pawn move */
e = p4_destringify_point(dest);
s = p4_find_source_point(state, e, 'P' + dest.charAt(0));
}
else if (/^[RNBQK]/.test(src)){
/*pgn format*/
e = p4_destringify_point(dest);
s = p4_find_source_point(state, e, src);
}
else if (position_re.test(src) && position_re.test(dest)){
s = p4_destringify_point(src);
e = p4_destringify_point(dest);
}
else if (/^[a-h]$/.test(src)){
e = p4_destringify_point(dest);
s = p4_find_source_point(state, e, 'P' + src);
}
if (s == 0)
return FAIL;
if (queen){
/* the chosen queen piece */
q = P4_PIECE_LUT[queen.charAt(1)];
}
return [s, e, q];
}
function p4_find_source_point(state, e, str){
var colour = state.to_play;
var piece = P4_PIECE_LUT[str.charAt(0)];
piece |= colour;
var s, i;
var row, column;
/* can be specified as Na, Na3, N3, and who knows, N3a? */
for (i = 1; i < str.length; i++){
var c = str.charAt(i);
if (/[a-h]/.test(c)){
column = str.charCodeAt(i) - 96;
}
else if (/[1-8]/.test(c)){
/*row goes 2 - 9 */
row = 1 + parseInt(c);
}
}
var possibilities = [];
p4_prepare(state);
var moves = p4_parse(state, colour,
state.enpassant, 0);
for (i = 0; i < moves.length; i++){
var mv = moves[i];
- if (e == mv[2]){
+ if (e === mv[2]){
s = mv[1];
- if (state.board[s] == piece &&
- (column === undefined || column == s % 10) &&
- (row === undefined || row == parseInt(s / 10))
+ if (state.board[s] === piece &&
+ (column === undefined || column === s % 10) &&
+ (row === undefined || row === parseInt(s / 10))
){
var change = p4_make_move(state, s, e, P4_QUEEN);
if (! p4_check_check(state, colour))
possibilities.push(s);
p4_unmake_move(state, change);
}
}
}
p4_log("finding", str, "that goes to", e, "got", possibilities);
if (possibilities.length == 0){
return 0;
}
else if (possibilities.length > 1){
p4_log("p4_find_source_point seems to have failed",
state, e, str,
possibilities);
}
return possibilities[0];
}
/*random number generator based on
* http://burtleburtle.net/bob/rand/smallprng.html
*/
function p4_random_seed(state, seed){
seed &= 0xffffffff;
state.rng = (P4_USE_TYPED_ARRAYS) ? new Uint32Array(4) : [];
state.rng[0] = 0xf1ea5eed;
state.rng[1] = seed;
state.rng[2] = seed;
state.rng[3] = seed;
for (var i = 0; i < 20; i++)
p4_random31(state);
}
function p4_random31(state){
var rng = state.rng;
var b = rng[1];
var c = rng[2];
/* These shifts amount to rotates.
* Note the three-fold right shift '>>>', meaning an unsigned shift.
* The 0xffffffff masks are needed to keep javascript to 32bit. (supposing
* untyped arrays).
*/
var e = rng[0] - ((b << 27) | (b >>> 5));
rng[0] = b ^ ((c << 17) | (c >>> 15));
rng[1] = (c + rng[3]) & 0xffffffff;
rng[2] = (rng[3] + e) & 0xffffffff;
rng[3] = (e + rng[0]) & 0xffffffff;
return rng[3] & 0x7fffffff;
}
function p4_random_int(state, top){
/* uniform integer in range [0 < n < top), supposing top < 2 ** 31
*
* This method is slightly (probably pointlessly) more accurate
* than converting to 0-1 float, multiplying and truncating, and
* considerably more accurate than a simple modulus.
* Obviously it is a bit slower.
*/
/* mask becomes one less than the next highest power of 2 */
var mask = top;
mask--;
mask |= mask >>> 1;
mask |= mask >>> 2;
mask |= mask >>> 4;
mask |= mask >>> 8;
mask |= mask >>> 16;
// can't do-while loop: https://bugreports.qt.io/browse/QTBUG-59012
var r = top + 1;
while(r >= top)
r = p4_random31(state) & mask;
return r;
}
diff --git a/src/activities/chess/resource/README b/src/activities/chess/resource/README
index 0c9a2129e..fa07bc702 100644
--- a/src/activities/chess/resource/README
+++ b/src/activities/chess/resource/README
@@ -1,18 +1,21 @@
-Copyright: Timothée Giet, 2016
+Copyright: Timothée Giet, 2016 - 2018
License: CC-BY-SA 4.0
Files:
background-wood.svg
bb.svg
bk.svg
bn.svg
bp.svg
bq.svg
br.svg
chess-black.svg
chess-white.svg
+redo.svg
+turn.svg
+undo.svg
wb.svg
wk.svg
wn.svg
wp.svg
wq.svg
wr.svg
diff --git a/src/activities/chess/resource/redo.svg b/src/activities/chess/resource/redo.svg
new file mode 100644
index 000000000..6ed1401ba
--- /dev/null
+++ b/src/activities/chess/resource/redo.svg
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="42"
+ height="42"
+ id="svg3930"
+ sodipodi:docname="redo.svg"
+ inkscape:version="0.92.1 r15371">
+ <sodipodi:namedview
+ pagecolor="#a5a5a5"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ id="namedview10"
+ showgrid="false"
+ inkscape:zoom="4.9166667"
+ inkscape:cx="-48.203389"
+ inkscape:cy="16.677966"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg3930" />
+ <defs
+ id="defs3932" />
+ <metadata
+ id="metadata3935">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ <dc:date>2018</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Timothée Giet</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <rect
+ style="opacity:1;vector-effect:none;fill:#5471af;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect819"
+ width="40"
+ height="40"
+ x="1"
+ y="1"
+ ry="5" />
+ <g
+ transform="matrix(-0.83333333,0,0,0.83333333,42.742409,-835.9685)"
+ id="layer1"
+ style="fill:#eef1f7;fill-opacity:1">
+ <g
+ transform="translate(-792,300.3622)"
+ id="g4784"
+ style="display:inline;fill:#eef1f7;fill-opacity:1">
+ <path
+ d="m 804,718 12,12 h -12 z"
+ id="path4564"
+ style="fill:#eef1f7;fill-opacity:1;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 819.53125,715.3125 c -2.67562,0.0197 -5.34109,1.02859 -7.375,3.0625 l -0.0625,0.0625 -5.3125,5.3125 3.53125,3.5625 5.3125,-5.3125 0.0625,-0.0625 c 2.19996,-2.19996 5.56652,-2.21479 7.6875,-0.0937 L 823.53125,722 c 2.12096,2.12097 2.13749,5.48751 -0.0625,7.6875 l -6.53125,6.5 3.5625,3.5625 6.5,-6.5 c 4.06779,-4.06779 4.14248,-10.73256 0.0937,-14.78125 l -0.1875,-0.15625 c -2.02434,-2.02436 -4.69938,-3.01973 -7.375,-3 z m -3.0625,21.375 -2.1875,2.1875 3.53125,3.5625 L 820,740.25 Z m -3.21875,3.25 -1.09375,1.0625 3.53125,3.5625 1.09375,-1.09375 z"
+ id="path4594"
+ style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#eef1f7;fill-opacity:1;stroke:none;stroke-width:5;marker:none;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+</svg>
diff --git a/src/activities/chess/resource/turn.svg b/src/activities/chess/resource/turn.svg
new file mode 100644
index 000000000..b23650b06
--- /dev/null
+++ b/src/activities/chess/resource/turn.svg
@@ -0,0 +1,182 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="42"
+ height="42"
+ id="svg3930"
+ sodipodi:docname="turn.svg"
+ inkscape:version="0.92.1 r15371">
+ <sodipodi:namedview
+ pagecolor="#a5a5a5"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ id="namedview10"
+ showgrid="true"
+ inkscape:zoom="4.9166667"
+ inkscape:cx="19.420372"
+ inkscape:cy="23.117375"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg3930">
+ <inkscape:grid
+ type="xygrid"
+ id="grid817" />
+ </sodipodi:namedview>
+ <defs
+ id="defs3932" />
+ <metadata
+ id="metadata3935">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ <dc:date>2018</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Timothée Giet</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <rect
+ style="opacity:1;vector-effect:none;fill:#5471af;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect819"
+ width="40"
+ height="40"
+ x="1"
+ y="1"
+ ry="5" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#eef1f7;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect821"
+ width="5"
+ height="5"
+ x="18.686533"
+ y="-2.3134665"
+ ry="0"
+ transform="rotate(30)" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#eef1f7;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect823"
+ width="5"
+ height="5"
+ x="28.686533"
+ y="-2.3134665"
+ transform="rotate(30)" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#eef1f7;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect827"
+ width="5"
+ height="5"
+ x="33.686535"
+ y="2.6865335"
+ transform="rotate(30)" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#eef1f7;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect829"
+ width="5"
+ height="5"
+ x="23.686533"
+ y="2.6865335"
+ transform="rotate(30)" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#eef1f7;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect831"
+ width="5"
+ height="5"
+ x="18.686533"
+ y="7.6865335"
+ transform="rotate(30)" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#eef1f7;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect833"
+ width="5"
+ height="5"
+ x="28.686533"
+ y="7.6865335"
+ transform="rotate(30)" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#eef1f7;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect837"
+ width="5"
+ height="5"
+ x="23.686533"
+ y="12.686534"
+ transform="rotate(30)" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#eef1f7;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect839"
+ width="5"
+ height="5"
+ x="33.686535"
+ y="12.686534"
+ transform="rotate(30)" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;stroke:#eef1f7;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect847"
+ width="20"
+ height="20"
+ x="18.686533"
+ y="-2.3134665"
+ transform="rotate(30)" />
+ <path
+ style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#eef1f7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ d="m 28,39 c 4.450045,-0.261506 8,-3.960766 8,-8.474609 0,-0.168756 -0.01561,-0.333659 -0.02539,-0.5 h -2 C 33.987156,30.191043 34,30.356384 34,30.525391 34,33.958084 31.365174,36.745375 28,37 Z"
+ id="path849"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#eef1f7;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 38,30.025391 h -6 l 3,-5 z"
+ id="path860"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc" />
+ <path
+ style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#eef1f7;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ d="M 14,3.025391 C 9.549955,3.286897 6,6.986157 6,11.5 6,11.668756 6.01561,11.833659 6.02539,12 h 2 C 8.012844,11.834348 8,11.669007 8,11.5 8,8.067307 10.634826,5.280016 14,5.025391 Z"
+ id="path849-3"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#eef1f7;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 4,12 h 6 l -3,5 z"
+ id="path860-6"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc" />
+</svg>
diff --git a/src/activities/chess/resource/undo.svg b/src/activities/chess/resource/undo.svg
new file mode 100644
index 000000000..195efabfe
--- /dev/null
+++ b/src/activities/chess/resource/undo.svg
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="42"
+ height="42"
+ id="svg3930"
+ sodipodi:docname="undo.svg"
+ inkscape:version="0.92.1 r15371">
+ <sodipodi:namedview
+ pagecolor="#a5a5a5"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ id="namedview10"
+ showgrid="false"
+ inkscape:zoom="4.9166667"
+ inkscape:cx="-48.203389"
+ inkscape:cy="16.677966"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg3930" />
+ <defs
+ id="defs3932" />
+ <metadata
+ id="metadata3935">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ <dc:date>2018</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Timothée Giet</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <rect
+ style="opacity:1;vector-effect:none;fill:#df543d;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect819"
+ width="40"
+ height="40"
+ x="1"
+ y="1"
+ ry="5" />
+ <g
+ transform="matrix(0.83333333,0,0,0.83333333,1.0000001,-835.9685)"
+ id="layer1"
+ style="fill:#eef1f7;fill-opacity:1">
+ <g
+ transform="translate(-792,300.3622)"
+ id="g4784"
+ style="display:inline;fill:#eef1f7;fill-opacity:1">
+ <path
+ d="m 804,718 12,12 h -12 z"
+ id="path4564"
+ style="fill:#eef1f7;fill-opacity:1;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 819.53125,715.3125 c -2.67562,0.0197 -5.34109,1.02859 -7.375,3.0625 l -0.0625,0.0625 -5.3125,5.3125 3.53125,3.5625 5.3125,-5.3125 0.0625,-0.0625 c 2.19996,-2.19996 5.56652,-2.21479 7.6875,-0.0937 L 823.53125,722 c 2.12096,2.12097 2.13749,5.48751 -0.0625,7.6875 l -6.53125,6.5 3.5625,3.5625 6.5,-6.5 c 4.06779,-4.06779 4.14248,-10.73256 0.0937,-14.78125 l -0.1875,-0.15625 c -2.02434,-2.02436 -4.69938,-3.01973 -7.375,-3 z m -3.0625,21.375 -2.1875,2.1875 3.53125,3.5625 L 820,740.25 Z m -3.21875,3.25 -1.09375,1.0625 3.53125,3.5625 1.09375,-1.09375 z"
+ id="path4594"
+ style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#eef1f7;fill-opacity:1;stroke:none;stroke-width:5;marker:none;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+</svg>
diff --git a/src/activities/chess_2players/ActivityInfo.qml b/src/activities/chess_2players/ActivityInfo.qml
index 19d7f3141..75c7cde0f 100644
--- a/src/activities/chess_2players/ActivityInfo.qml
+++ b/src/activities/chess_2players/ActivityInfo.qml
@@ -1,47 +1,47 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "chess_2players/Chess2Players.qml"
difficulty: 6
icon: "chess_2players/chess_2players.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
//: Activity title
title: qsTr("Play chess against your friend")
//: Help title
description: ""
//intro: "play chess against your friend"
//: Help goal
goal: ""
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("In this activity you discover the chess game by playing against a friend. It displays the possible target position for any selected piece which helps the children understand how pieces moves.
\nYou can achieve a mate sooner if follow these simple rules:
Trying to drive opponent's King in the corner.
<b>Explanation</b>: this way opponent's piece would have only 3 directions to move instead of 8 from a best position.
'Making a trap'. Use your pawns as baits.
<b>Explanation</b>: this way you can lure the opponent out of his 'comfort zone'.
Be patient enough.
<b>Explanation</b>: don't rush too quick, be patient. Let yourself think a little bit and try to predict your opponent's future moves, so you can catch him on it or secure your pieces from his attacks.")
credit: ""
section: "strategy"
createdInVersion: 5000
}
diff --git a/src/activities/chess_2players/Chess2Players.qml b/src/activities/chess_2players/Chess2Players.qml
index d2020bcaa..8dc9525ef 100644
--- a/src/activities/chess_2players/Chess2Players.qml
+++ b/src/activities/chess_2players/Chess2Players.qml
@@ -1,29 +1,29 @@
/* GCompris - chess_2players.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
import "../chess"
Chess {
twoPlayers: true
}
diff --git a/src/activities/chess_partyend/ActivityInfo.qml b/src/activities/chess_partyend/ActivityInfo.qml
index 21e65e2dc..bf93022e7 100644
--- a/src/activities/chess_partyend/ActivityInfo.qml
+++ b/src/activities/chess_partyend/ActivityInfo.qml
@@ -1,47 +1,47 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "chess_partyend/ChessPartyEnd.qml"
difficulty: 6
icon: "chess_partyend/chess_partyend.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
//: Activity title
title: qsTr("End of chess game")
//: Help title
description: qsTr("Play the end of the chess game against Tux")
//intro: "Click on a white chess piece and green boxes will appear to indicate all the movements that piece can make. Try and get the black king into checkmate."
//: Help goal
goal: ""
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("In this activity you discover the chess game by playing only the end of a game. It displays the possible target position for any selected piece which helps the children understand how pieces moves.
\nYou can achieve a mate sooner if follow these simple rules:
Trying to drive opponent's King in the corner.
<b>Explanation</b>: this way opponent's piece would have only 3 directions to move instead of 8 from a best position.
'Making a trap'. Use your pawns as baits.
<b>Explanation</b>: this way you can lure the opponent out of his 'comfort zone'.
Be patient enough.
<b>Explanation</b>: don't rush too quick, be patient. Let yourself think a little bit and try to predict your opponent's future moves, so you can catch him on it or secure your pieces from his attacks.")
credit: qsTr("The chess engine is p4wn &lt;https://github.com/douglasbagnall/p4wn&gt;.")
section: "strategy"
createdInVersion: 5000
}
diff --git a/src/activities/chess_partyend/ChessPartyEnd.qml b/src/activities/chess_partyend/ChessPartyEnd.qml
index cec65a899..a85fcf9c4 100644
--- a/src/activities/chess_partyend/ChessPartyEnd.qml
+++ b/src/activities/chess_partyend/ChessPartyEnd.qml
@@ -1,46 +1,46 @@
/* GCompris - chess_2players.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
import "../chess"
Chess {
twoPlayers: false
difficultyByLevel: false
fen: [
["", "4k3/8/8/8/8/8/8/K4QQ1 w - -"],
["", "1k6/8/8/8/8/8/8/K4RR1 w - -"],
["", "8/8/8/1B6/1R6/8/8/k3K3 w - -"],
["", "8/8/8/3N4/3N4/3B4/3B4/k3K3 w - -"],
["checkmate in 1", "8/8/8/8/8/6K1/4Q3/6k1 w - - 21 61"],
["mate in 1", "5k2/8/5K2/4Q3/5P2/8/8/8 w - - 3 61"],
["zugzwang", "8/8/p1p5/1p5p/1P5p/8/PPP2K1p/4R1rk w - - 0 1"],
["earlyish", "rnq1nrk1/pp3pbp/6p1/3p4/3P4/5N2/PP2BPPP/R1BQK2R w KQ -"],
["checkmate in 2", "4kb2/3r1p2/2R3p1/6B1/p6P/P3p1P1/P7/5K2 w - - 0 36"],
["leonid's position", "q2k2q1/2nqn2b/1n1P1n1b/2rnr2Q/1NQ1QN1Q/3Q3B/2RQR2B/Q2K2Q1 w - -"],
["sufficient material - opposing bishops", "8/6BK/7B/6b1/7B/8/B7/7k w - - 40 40"],
["checkmate in 1", "rnbqkr2/ppppbp1p/8/3NQ3/8/8/PPPP1nPP/R1B1KBNR w - -"],
["checkmate in 2", "6k1/p4p2/1p4p1/2p4p/4Pnq1/1PQ5/P1P2PPP/3R2K1 w - -"],
["checkmate in 5, sacrifice your queen", "5rk1/1p3p1p/6p1/q2P4/2n5/P6Q/KB2p3/2R5 w - -"]
]
}
diff --git a/src/activities/chronos/ActivityInfo.qml b/src/activities/chronos/ActivityInfo.qml
index 57bedeeba..0f8c7032e 100644
--- a/src/activities/chronos/ActivityInfo.qml
+++ b/src/activities/chronos/ActivityInfo.qml
@@ -1,44 +1,44 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Pulkit Gupta <pulkitgenius@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "chronos/Chronos.qml"
difficulty: 1
icon: "chronos/chronos.svg"
author: "Pulkit Gupta &lt;pulkitgenius@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Chronos")
//: Help title
description: qsTr("Drag and Drop the items to organize the story")
// intro: "Slide the pictures into the order that tells the story"
//: Help goal
goal: qsTr("Sort the pictures into the order that tells the story")
//: Help prerequisite
prerequisite: qsTr("Tell a short story")
//: Help manual
manual: qsTr("Pick from the pictures on the left and put them on the red dots")
credit: qsTr("Moon photo is copyright NASA. The space sounds come from Tuxpaint and Vegastrike which are released under the GPL license. The transportation images are copyright Franck Doucet. Dates of Transportation are based on those found in &lt;http://www.wikipedia.org&gt;.")
section: "discovery"
createdInVersion: 4000
}
diff --git a/src/activities/chronos/Chronos.qml b/src/activities/chronos/Chronos.qml
index 9c76ad2d1..96278d5ca 100644
--- a/src/activities/chronos/Chronos.qml
+++ b/src/activities/chronos/Chronos.qml
@@ -1,34 +1,34 @@
/* GCompris - Chronos.qml
*
* Copyright (C) 2015 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* José Jorge <jjorge@free.fr> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../babymatch"
Babymatch {
id: activity
onStart: focus = true
onStop: {}
boardsUrl: "qrc:/gcompris/src/activities/chronos/resource/"
levelCount: 6
}
diff --git a/src/activities/chronos/resource/board/board1_0.qml b/src/activities/chronos/resource/board/board1_0.qml
index 089f9360b..0a686e9d5 100644
--- a/src/activities/chronos/resource/board/board1_0.qml
+++ b/src/activities/chronos/resource/board/board1_0.qml
@@ -1,84 +1,80 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Moonwalker")
property var levels: [
- {
- "pixmapfile": "images/bg.jpg",
- "type": "SHAPE_BACKGROUND_IMAGE"
- },
{
"pixmapfile": "images/4.png",
"x": "0.7",
"y": "0.7",
"soundFile": "sound/2.$CA"
},
{
"pixmapfile": "images/3.png",
"x": "0.3",
"y": "0.7",
"soundFile": "sound/3.$CA"
},
{
"pixmapfile": "images/2.png",
"x": "0.7",
"y": "0.25",
"soundFile": "sound/2.$CA"
},
{
"pixmapfile": "images/1.png",
"x": "0.3",
"y": "0.25",
"soundFile": "sound/1.$CA"
},
{
"text": qsTr("1"),
"x": "0.3",
"y": 0.25,
"width": "0.2",
"type": "DisplayText"
},
{
"text": qsTr("2"),
"x": "0.7",
"y": 0.25,
"width": "0.2",
"type": "DisplayText"
},
{
"text": qsTr("3"),
"x": "0.3",
"y": 0.7,
"width": "0.2",
"type": "DisplayText"
},
{
"text": qsTr("4"),
"x": "0.7",
"y": 0.7,
"width": "0.2",
"type": "DisplayText"
}
]
}
diff --git a/src/activities/chronos/resource/board/board2_0.qml b/src/activities/chronos/resource/board/board2_0.qml
index 258238e47..66e7888ad 100644
--- a/src/activities/chronos/resource/board/board2_0.qml
+++ b/src/activities/chronos/resource/board/board2_0.qml
@@ -1,84 +1,84 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("The 4 Seasons")
property var levels: [
{
"pixmapfile": "images/autumn.svg",
"x": 0.25,
"y": 0.7,
"width": 0.4,
"height": 0.319
},
{
"pixmapfile": "images/summer.svg",
"x": 0.75,
"y": 0.25,
"width": 0.4,
"height": 0.319
},
{
"pixmapfile": "images/spring.svg",
"x": 0.25,
"y": 0.25,
"width": 0.4,
"height": 0.319
},
{
"pixmapfile": "images/winter.svg",
"x": 0.75,
"y": 0.7,
"width": 0.4,
"height": 0.319
},
{
"text": qsTr("Spring"),
"x": "0.25",
"y": 0.25,
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("Summer"),
"x": "0.75",
"y": 0.25,
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("Autumn"),
"x": "0.25",
"y": 0.7,
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("Winter"),
"x": "0.75",
"y": 0.7,
"width": "0.4",
"type": "DisplayText"
}
]
}
diff --git a/src/activities/chronos/resource/board/board3_0.qml b/src/activities/chronos/resource/board/board3_0.qml
index 12c0254f6..71ed5892d 100644
--- a/src/activities/chronos/resource/board/board3_0.qml
+++ b/src/activities/chronos/resource/board/board3_0.qml
@@ -1,84 +1,84 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Gardening")
property var levels: [
{
"pixmapfile": "images/garden1.svg",
"x": 0.25,
"y": 0.25,
"width": 0.4,
"height": 0.309
},
{
"pixmapfile": "images/garden4.svg",
"x": 0.75,
"y": 0.7,
"width": 0.4,
"height": 0.309
},
{
"pixmapfile": "images/garden3.svg",
"x": 0.25,
"y": 0.7,
"width": 0.4,
"height": 0.309
},
{
"pixmapfile": "images/garden2.svg",
"x": 0.75,
"y": 0.25,
"width": 0.4,
"height": 0.309
},
{
"text": qsTr("1"),
"x": "0.25",
"y": 0.25,
"width": "0.2",
"type": "DisplayText"
},
{
"text": qsTr("2"),
"x": "0.75",
"y": 0.25,
"width": "0.2",
"type": "DisplayText"
},
{
"text": qsTr("3"),
"x": "0.25",
"y": 0.7,
"width": "0.2",
"type": "DisplayText"
},
{
"text": qsTr("4"),
"x": "0.75",
"y": 0.7,
"width": "0.2",
"type": "DisplayText"
}
]
}
diff --git a/src/activities/chronos/resource/board/board4_0.qml b/src/activities/chronos/resource/board/board4_0.qml
index 2a87fb095..743a475c6 100644
--- a/src/activities/chronos/resource/board/board4_0.qml
+++ b/src/activities/chronos/resource/board/board4_0.qml
@@ -1,84 +1,84 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Tux and the apple tree")
property var levels: [
{
"pixmapfile": "images/chronos-tuxtree3.svg",
"x": "0.25",
"y": "0.7",
"width": 0.4,
"height": 0.4
},
{
"pixmapfile": "images/chronos-tuxtree2.svg",
"x": "0.75",
"y": "0.25",
"width": 0.4,
"height": 0.4
},
{
"pixmapfile": "images/chronos-tuxtree4.svg",
"x": "0.75",
"y": "0.7",
"width": 0.4,
"height": 0.4
},
{
"pixmapfile": "images/chronos-tuxtree1.svg",
"x": "0.25",
"y": "0.25",
"width": 0.4,
"height": 0.4
},
{
"text": qsTr("1"),
"x": "0.25",
"y": 0.25,
"width": "0.2",
"type": "DisplayText"
},
{
"text": qsTr("2"),
"x": "0.75",
"y": 0.25,
"width": "0.2",
"type": "DisplayText"
},
{
"text": qsTr("3"),
"x": "0.25",
"y": 0.7,
"width": "0.2",
"type": "DisplayText"
},
{
"text": qsTr("4"),
"x": "0.75",
"y": 0.7,
"width": "0.2",
"type": "DisplayText"
}
]
}
diff --git a/src/activities/chronos/resource/board/board5_0.qml b/src/activities/chronos/resource/board/board5_0.qml
index 2eb9372d3..efdfad016 100644
--- a/src/activities/chronos/resource/board/board5_0.qml
+++ b/src/activities/chronos/resource/board/board5_0.qml
@@ -1,64 +1,64 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property int numberOfSubLevel: 4
property string instruction: qsTr("Place each image in the order and on the date it was invented.")
property var levels: [
{
"pixmapfile": "images/fardier.svg",
"x": 0.7,
"y": 0.8,
"width": 0.4,
"height": 0.14
},
{
"pixmapfile": "images/st_rocket.svg",
"x": 0.25,
"y": 0.55,
"width": 0.4,
"height": 0.308
},
{
"text": qsTr("1829 Stephenson's Rocket Steam locomotive"),
"x": 0.24,
"y": 0.29,
"width": 0.4,
"type": "DisplayText"
},
{
"text": qsTr("1769 Cugnot's fardier"),
"x": 0.75,
"y": 0.59,
"width": 0.4,
"type": "DisplayText"
},
{
"text": qsTr("Transportation"),
"x": 0.8,
"y": 0.3,
"width": 0.3,
"type": "DisplayText"
}
]
}
diff --git a/src/activities/chronos/resource/board/board5_1.qml b/src/activities/chronos/resource/board/board5_1.qml
index 7745c64e3..7abfb9ef2 100644
--- a/src/activities/chronos/resource/board/board5_1.qml
+++ b/src/activities/chronos/resource/board/board5_1.qml
@@ -1,70 +1,70 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Transportation")
property var levels: [
{
"pixmapfile": "images/helico_cornu.svg",
"x": 0.75,
"y": 0.55,
"width": 0.4,
"height": 0.16
},
{
"pixmapfile": "images/Eole.svg",
"x": "0.5",
"y": "0.9",
"width": 0.4,
"height": 0.2
},
{
"pixmapfile": "images/mongolfiere.svg",
"x": 0.2,
"y": 0.55,
"width": 0.4,
"height": 0.522
},
{
"text": qsTr("1783 Montgolfier brothers' hot air balloon"),
"x": "0.25",
"y": 0.2,
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("1880 Clement Ader's Eole"),
"x": "0.5",
"y": 0.75,
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("1906 Paul Cornu First helicopter flight"),
"x": 0.75,
"y": 0.21,
"width": 0.4,
"type": "DisplayText"
}
]
}
diff --git a/src/activities/chronos/resource/board/board5_2.qml b/src/activities/chronos/resource/board/board5_2.qml
index 79df6e34c..d82dd2d13 100644
--- a/src/activities/chronos/resource/board/board5_2.qml
+++ b/src/activities/chronos/resource/board/board5_2.qml
@@ -1,70 +1,70 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Transportation")
property var levels: [
{
"pixmapfile": "images/celerifere.svg",
"x": 0.2,
"y": 0.55,
"width": 0.4,
"height": 0.406
},
{
"pixmapfile": "images/fardier.svg",
"x": 0.5,
"y": 0.9,
"width": 0.4,
"height": 0.14
},
{
"pixmapfile": "images/Eole.svg",
"x": 0.75,
"y": 0.55,
"width": 0.4,
"height": 0.4
},
{
"text": qsTr("1791 Comte de Sivrac's Celerifere"),
"x": "0.25",
"y": 0.2,
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("1769 Cugnot's fardier"),
"x": "0.5",
"y": 0.75,
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("1880 Clement Ader's Eole"),
"x": "0.75",
"y": 0.21,
"width": "0.4",
"type": "DisplayText"
}
]
}
diff --git a/src/activities/chronos/resource/board/board5_3.qml b/src/activities/chronos/resource/board/board5_3.qml
index 4c4fdc3a3..34c728f73 100644
--- a/src/activities/chronos/resource/board/board5_3.qml
+++ b/src/activities/chronos/resource/board/board5_3.qml
@@ -1,70 +1,70 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Transportation")
property var levels: [
{
"pixmapfile": "images/celerifere.svg",
"x": "0.2",
"y": "0.55",
"width": 0.4,
"height": 0.406
},
{
"pixmapfile": "images/mongolfiere.svg",
"x": 0.5,
"y": 0.9,
"width": 0.4,
"height": 0.522
},
{
"pixmapfile": "images/st_rocket.svg",
"x": 0.75,
"y": 0.55,
"width": 0.4,
"height": 0.308
},
{
"text": qsTr("1791 Comte de Sivrac's Celerifere"),
"x": "0.25",
"y": 0.2,
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("1783 Montgolfier brothers' hot air balloon"),
"x": "0.5",
"y": 0.75,
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("1829 Stephenson's Rocket Steam locomotive"),
"x": "0.75",
"y": 0.21,
"width": "0.4",
"type": "DisplayText"
}
]
}
diff --git a/src/activities/chronos/resource/board/board5_4.qml b/src/activities/chronos/resource/board/board5_4.qml
index 137179dc1..c54e890fb 100644
--- a/src/activities/chronos/resource/board/board5_4.qml
+++ b/src/activities/chronos/resource/board/board5_4.qml
@@ -1,70 +1,70 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Transportation")
property var levels: [
{
"pixmapfile": "images/st_rocket.svg",
"x": 0.2,
"y": 0.55,
"width": 0.4,
"height": 0.308
},
{
"pixmapfile": "images/Eole.svg",
"x": "0.5",
"y": "0.9",
"width": 0.4,
"height": 0.2
},
{
"pixmapfile": "images/fardier.svg",
"x": 0.75,
"y": 0.55,
"width": 0.4,
"height": 0.14
},
{
"text": qsTr("1829 Stephenson's Rocket Steam locomotive"),
"x": "0.25",
"y": 0.2,
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("1880 Clement Ader's Eole"),
"x": "0.5",
"y": 0.75,
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("1769 Cugnot's fardier"),
"x": "0.75",
"y": 0.21,
"width": "0.4",
"type": "DisplayText"
}
]
}
diff --git a/src/activities/chronos/resource/board/board6_0.qml b/src/activities/chronos/resource/board/board6_0.qml
index 8db5fa219..138e0dbff 100644
--- a/src/activities/chronos/resource/board/board6_0.qml
+++ b/src/activities/chronos/resource/board/board6_0.qml
@@ -1,71 +1,71 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property int numberOfSubLevel: 3
property string instruction: qsTr("Aviation")
property var levels: [
{
"pixmapfile": "images/Eole.svg",
"x": "0.2",
"y": "0.55",
"width": 0.4,
"height": 0.4
},
{
"pixmapfile": "images/wright_flyer.svg",
"x": 0.5,
"y": 0.9,
"width": 0.4,
"height": 0.216
},
{
"pixmapfile": "images/bleriot.svg",
"x": 0.75,
"y": 0.55,
"width": 0.4,
"height": 0.115
},
{
"text": qsTr("1880 Clement Ader's Eole"),
"x": "0.25",
"y": 0.2,
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("1903 The Wright brothers' Flyer III"),
"x": 0.5,
"y": 0.75,
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("1909 Louis Bleriot crosses the English Channel"),
"x": "0.75",
"y": 0.21,
"width": "0.4",
"type": "DisplayText"
}
]
}
diff --git a/src/activities/chronos/resource/board/board6_1.qml b/src/activities/chronos/resource/board/board6_1.qml
index ceb8ede14..d40b4bd15 100644
--- a/src/activities/chronos/resource/board/board6_1.qml
+++ b/src/activities/chronos/resource/board/board6_1.qml
@@ -1,70 +1,70 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Aviation")
property var levels: [
{
"pixmapfile": "images/bell_X1.svg",
"x": 0.2,
"y": 0.55,
"width": 0.4,
"height": 0.244
},
{
"pixmapfile": "images/lindbergh.svg",
"x": 0.5,
"y": 0.9,
"width": 0.4,
"height": 0.14
},
{
"pixmapfile": "images/rafale.svg",
"x": 0.75,
"y": 0.55,
"width": 0.4,
"height": 0.292
},
{
"text": qsTr("1947 Chuck Yeager breaks the sound-barrier"),
"x": "0.25",
"y": 0.2,
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("1927 Charles Lindbergh crosses the Atlantic Ocean"),
"x": "0.5",
"y": 0.75,
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("1934 Hélène Boucher's speed record of 444km/h"),
"x": "0.75",
"y": 0.21,
"width": "0.4",
"type": "DisplayText"
}
]
}
diff --git a/src/activities/chronos/resource/board/board6_2.qml b/src/activities/chronos/resource/board/board6_2.qml
index 95b6d2369..2a23e8eeb 100644
--- a/src/activities/chronos/resource/board/board6_2.qml
+++ b/src/activities/chronos/resource/board/board6_2.qml
@@ -1,70 +1,70 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Cars")
property var levels: [
{
"pixmapfile": "images/bolle1878.svg",
"x": "0.2",
"y": "0.55",
"width": 0.4,
"height": 0.4
},
{
"pixmapfile": "images/fardier.svg",
"x": 0.5,
"y": 0.9,
"width": 0.4,
"height": 0.14
},
{
"pixmapfile": "images/benz1885.svg",
"x": 0.75,
"y": 0.55,
"width": 0.4,
"height": 0.32
},
{
"text": qsTr("1878 Amédée Bollée's La Mancelle"),
"x": "0.25",
"y": 0.2,
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("1769 Cugnot's fardier"),
"x": "0.5",
"y": 0.75,
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("1885 The first petrol car by Benz"),
"x": "0.75",
"y": 0.21,
"width": "0.4",
"type": "DisplayText"
}
]
}
diff --git a/src/activities/chronos/resource/board/board6_3.qml b/src/activities/chronos/resource/board/board6_3.qml
index 8131b57ff..d9b3d401b 100644
--- a/src/activities/chronos/resource/board/board6_3.qml
+++ b/src/activities/chronos/resource/board/board6_3.qml
@@ -1,70 +1,70 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Cars")
property var levels: [
{
"pixmapfile": "images/renault1899.svg",
"x": 0.2,
"y": 0.55,
"width": 0.4,
"height": 0.305
},
{
"pixmapfile": "images/lancia1923.svg",
"x": 0.5,
"y": 0.9,
"width": 0.4,
"height": 0.16
},
{
"pixmapfile": "images/1955ds19.svg",
"x": 0.75,
"y": 0.55,
"width": 0.4,
"height": 0.19
},
{
"text": qsTr("1899 Renault voiturette"),
"x": "0.25",
"y": 0.2,
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("1923 Lancia Lambda"),
"x": "0.5",
"y": 0.75,
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("1955 Citroën DS 19"),
"x": 0.75,
"y": 0.21,
"width": 0.4,
"type": "DisplayText"
}
]
}
diff --git a/src/activities/chronos/resource/images/README b/src/activities/chronos/resource/images/README
index 37ef0031b..13696a04e 100644
--- a/src/activities/chronos/resource/images/README
+++ b/src/activities/chronos/resource/images/README
@@ -1,36 +1,35 @@
Copyright: Franck Doucet
License: GPLv3
Files:
1.png
2.png
3.png
4.png
1955ds19.svg
autumn.svg
bell_X1.svg
benz1885.svg
-bg.jpg
bleriot.svg
bolle1878.svg
celerifere.svg
chronos-tuxtree1.svg
chronos-tuxtree2.svg
chronos-tuxtree3.svg
chronos-tuxtree4.svg
Eole.svg
fardier.svg
garden1.svg
garden2.svg
garden3.svg
garden4.svg
helico_cornu.svg
lancia1923.svg
lindbergh.svg
mongolfiere.svg
rafale.svg
renault1899.svg
spring.svg
st_rocket.svg
summer.svg
winter.svg
wright_flyer.svg
diff --git a/src/activities/chronos/resource/images/bg.jpg b/src/activities/chronos/resource/images/bg.jpg
deleted file mode 100644
index ece452a22..000000000
Binary files a/src/activities/chronos/resource/images/bg.jpg and /dev/null differ
diff --git a/src/activities/click_on_letter/ActivityInfo.qml b/src/activities/click_on_letter/ActivityInfo.qml
index ab3ea9599..a52967919 100644
--- a/src/activities/click_on_letter/ActivityInfo.qml
+++ b/src/activities/click_on_letter/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Holger Kaelberer <holger.k@elberer.de>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "click_on_letter/ClickOnLetter.qml"
difficulty: 2
icon: "click_on_letter/click_on_letter.svg"
author: "Holger Kaelberer &lt;holger.k@elberer.de&gt;"
demo: true
//: Activity title
title: qsTr("Click on a lowercase letter")
//: Help title
description: qsTr("Listen to a letter and click on the right one")
// intro: "Click on the required letter. You can listen to it again by clicking on the mouth."
//: Help goal
goal: qsTr("Letter-name recognition")
//: Help prerequisite
prerequisite: qsTr("Visual letter-recognition.")
//: Help manual
manual: qsTr("A letter is spoken. Click on the matching letter in the main area. You can listen to the letter again, by clicking on the mouth icon.")
credit: ""
section: "reading"
createdInVersion: 0
}
diff --git a/src/activities/click_on_letter/Carriage.qml b/src/activities/click_on_letter/Carriage.qml
index 255647646..49da2f093 100644
--- a/src/activities/click_on_letter/Carriage.qml
+++ b/src/activities/click_on_letter/Carriage.qml
@@ -1,175 +1,175 @@
/* GCompris - Carriage.qml
*
* Copyright (C) 2014 Holger Kaelberer <holger.k@elberer.de>
*
* Authors:
* Pascal Georges <pascal.georges1@free.fr> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ Mostly full rewrite)
* Holger Kaelberer <holger.k@elberer.de> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import QtGraphicalEffects 1.0
import "../../core"
import "click_on_letter.js" as Activity
Item {
id: carriageItem
property int nbCarriage
property bool isCarriage: index <= nbCarriage
Image {
id: carriageImage
sourceSize.width: carriageItem.width
fillMode: Image.PreserveAspectFit
source: isCarriage ?
Activity.url + "carriage.svg":
Activity.url + "cloud.svg"
z: (state == 'scaled') ? 1 : -1
Rectangle {
id: carriageBg
visible: isCarriage
width: parent.width - 8
height: parent.height / 1.8
anchors.bottom: parent.top
anchors.bottomMargin: - parent.height / 1.5
radius: height / 10
color: "#f0d578"
border.color: "#b98a1c"
border.width: 3
}
GCText {
id: text
anchors.horizontalCenter: isCarriage ?
carriageBg.horizontalCenter :
parent.horizontalCenter
anchors.verticalCenter: isCarriage ?
carriageBg.verticalCenter :
parent.verticalCenter
z: 11
-
text: letter
font.pointSize: NaN // need to clear font.pointSize explicitly
font.pixelSize: parent.width * 0.65
font.bold: true
style: Text.Outline
styleColor: "#2a2a2a"
color: "white"
}
DropShadow {
anchors.fill: text
cached: false
horizontalOffset: 1
verticalOffset: 1
radius: 3
samples: 16
color: "#422a2a2a"
source: text
}
Image {
- id:softFailure
+ id: softFailure
z: 12
source: "qrc:/gcompris/src/activities/tic_tac_toe/resource/cross.svg"
width: parent.width
height: width
anchors.centerIn: text
- opacity:0
+ opacity: 0
visible: ApplicationInfo.useOpenGL ? false : true
}
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: ApplicationInfo.isMobile ? false : true
onClicked: {
if (Activity.checkAnswer(index)) {
successAnimation.restart();
particle.burst(30)
} else {
failureAnimation.restart()
}
}
}
ParticleSystemStarLoader {
id: particle
clip: false
}
states: State {
name: "scaled"; when: mouseArea.containsMouse
PropertyChanges {
target: carriageItem
scale: /*carriageImage.scale * */ 1.2
- z: 2}
+ z: 2
+ }
}
transitions: Transition {
NumberAnimation { properties: "scale"; easing.type: Easing.OutCubic }
}
SequentialAnimation {
id: successAnimation
NumberAnimation {
target: carriageImage
easing.type: Easing.InOutQuad
property: "rotation"
to: 20; duration: 100
}
NumberAnimation {
target: carriageImage
easing.type: Easing.InOutQuad
property: "rotation"; to: -20
duration: 100 }
NumberAnimation {
target: carriageImage
easing.type: Easing.InOutQuad
property: "rotation"
- to: 0
- duration: 50 }
+ to: 0; duration: 50
+ }
}
SequentialAnimation {
id: failureAnimation
NumberAnimation {
target: ApplicationInfo.useOpenGL ? color : softFailure
property: "opacity"
to: 1; duration: 400
}
NumberAnimation {
target: ApplicationInfo.useOpenGL ? color : softFailure
property: "opacity"
to: 0; duration: 200
}
}
}
Colorize {
id: color
z: 5
anchors.fill: carriageImage
source: carriageImage
hue: 0.0
saturation: 1
opacity: 0
}
}
diff --git a/src/activities/click_on_letter/ClickOnLetter.qml b/src/activities/click_on_letter/ClickOnLetter.qml
index edaf6b942..8d7794a71 100644
--- a/src/activities/click_on_letter/ClickOnLetter.qml
+++ b/src/activities/click_on_letter/ClickOnLetter.qml
@@ -1,326 +1,324 @@
/* GCompris - ClickOnLetter.qml
*
* Copyright (C) 2014 Holger Kaelberer <holger.k@elberer.de>
*
* Authors:
* Pascal Georges <pascal.georges1@free.fr> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ Mostly full rewrite)
* Holger Kaelberer <holger.k@elberer.de> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import QtGraphicalEffects 1.0
import GCompris 1.0
import "../../core"
import "click_on_letter.js" as Activity
import "qrc:/gcompris/src/core/core.js" as Core
ActivityBase {
id: activity
focus: true
/* mode of the activity, either "lowercase" (click_on_letter)
* or "uppercase" (click_on_letter_up): */
property string mode: "lowercase"
onStart: focus = true
pageComponent: Image {
id: background
source: Activity.url + "background.svg"
sourceSize.width: Math.max(parent.width, parent.height)
fillMode: Image.PreserveAspectCrop
focus: true
// system locale by default
property string locale: "system"
signal start
signal stop
signal voiceError
Component.onCompleted: {
dialogActivityConfig.getInitialConfiguration()
activity.start.connect(start)
activity.stop.connect(stop)
}
QtObject {
id: items
property Item main: activity.main
property alias bar: bar
property alias trainModel: trainModel
property GCAudio audioVoices: activity.audioVoices
property alias parser: parser
property alias questionItem: questionItem
property alias repeatItem: repeatItem
property alias score: score
property alias bonus: bonus
property alias locale: background.locale
}
onVoiceError: {
questionItem.visible = true
repeatItem.visible = false
}
onStart: {
activity.audioVoices.error.connect(voiceError)
Activity.start(items, mode);
}
onStop: Activity.stop()
DialogActivityConfig {
id: dialogActivityConfig
currentActivity: activity
content: Component {
Item {
property alias localeBox: localeBox
height: column.height
property alias availableLangs: langs.languages
LanguageList {
id: langs
}
Column {
id: column
spacing: 10
width: parent.width
Flow {
spacing: 5
width: dialogActivityConfig.width
GCComboBox {
id: localeBox
model: langs.languages
background: dialogActivityConfig
label: qsTr("Select your locale")
}
}
}
}
}
onClose: home()
onLoadData: {
if(dataToSave && dataToSave["locale"]) {
background.locale = dataToSave["locale"];
}
}
onSaveData: {
var oldLocale = background.locale;
var newLocale =
dialogActivityConfig.configItem.availableLangs[dialogActivityConfig.loader.item.localeBox.currentIndex].locale;
// Remove .UTF-8
if(newLocale.indexOf('.') != -1) {
newLocale = newLocale.substring(0, newLocale.indexOf('.'))
}
dataToSave = {"locale": newLocale }
background.locale = newLocale;
// Restart the activity with new information
if(oldLocale !== newLocale) {
background.stop();
background.start();
}
}
function setDefaultValues() {
var localeUtf8 = background.locale;
if(background.locale != "system") {
localeUtf8 += ".UTF-8";
}
for(var i = 0 ; i < dialogActivityConfig.configItem.availableLangs.length ; i ++) {
if(dialogActivityConfig.configItem.availableLangs[i].locale === localeUtf8) {
dialogActivityConfig.loader.item.localeBox.currentIndex = i;
break;
}
}
}
}
DialogHelp {
id: dialogHelpLeftRight
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level | config }
onHelpClicked: {
displayDialog(dialogHelpLeftRight)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: home()
onConfigClicked: {
dialogActivityConfig.active = true
dialogActivityConfig.setDefaultValues()
displayDialog(dialogActivityConfig)
}
}
Score {
id: score
anchors.top: parent.top
anchors.topMargin: 10 * ApplicationInfo.ratio
anchors.left: parent.left
anchors.leftMargin: 10 * ApplicationInfo.ratio
anchors.bottom: undefined
anchors.right: undefined
}
Bonus {
id: bonus
Component.onCompleted: win.connect(Activity.nextSubLevel)
}
BarButton {
id: repeatItem
source: "qrc:/gcompris/src/core/resource/bar_repeat.svg";
sourceSize.width: 80 * ApplicationInfo.ratio
anchors {
top: parent.top
right: parent.right
margins: 10
}
onClicked: Activity.playLetter(Activity.currentLetter);
}
Image {
id: railway
source: Activity.url + "railway.svg"
fillMode: Image.PreserveAspectCrop
anchors.bottom: bar.top
anchors.left: parent.left
anchors.right: parent.right
height: 15 * ApplicationInfo.ratio
sourceSize.width: Math.max(parent.width, parent.height)
anchors.bottomMargin: 13 * ApplicationInfo.ratio
}
Item {
id: questionItem
anchors.left: parent.left
anchors.top: parent.top
anchors.leftMargin: 10 * ApplicationInfo.ratio
anchors.topMargin: parent.height * 0.25
z: 10
width: questionText.width * 2
height: questionText.height * 1.3
visible: false
property alias text: questionText.text
Rectangle {
id: questionRect
anchors.fill: parent
border.color: "#FFFFFFFF"
border.width: 2
color: "#000065"
opacity: 0.31
radius: 10
}
GCText {
id: questionText
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
opacity: 1.0
z:11
text: ""
fontSize: 44
font.bold: true
style: Text.Outline
styleColor: "#2a2a2a"
color: "white"
}
DropShadow {
anchors.fill: questionText
cached: false
horizontalOffset: 1
verticalOffset: 1
radius: 3
samples: 16
color: "#422a2a2a"
source: questionText
}
}
ListModel {
id: trainModel
}
property int itemWidth: Math.min(parent.width / 7.5, parent.height / 5)
property int itemHeight: itemWidth * 1.11
Image {
id: engine
source: Activity.url + "engine.svg"
-
anchors.bottom: railway.bottom
anchors.left: railway.left
anchors.leftMargin: 10 * ApplicationInfo.ratio
anchors.bottomMargin: 5 * ApplicationInfo.ratio
sourceSize.width: itemWidth
fillMode: Image.PreserveAspectFit
}
Image {
id: smoke
source: Activity.url + "smoke.svg"
-
anchors.bottom: engine.top
anchors.left: railway.left
anchors.leftMargin: 10 * ApplicationInfo.ratio
anchors.bottomMargin: 5 * ApplicationInfo.ratio
sourceSize.width: itemWidth
fillMode: Image.PreserveAspectFit
}
GridView {
id: train
anchors.bottom: railway.bottom
anchors.left: engine.right
anchors.right: parent.right
anchors.top: parent.top
anchors.bottomMargin: 5 * ApplicationInfo.ratio
cellWidth: itemWidth
cellHeight: itemHeight
clip: false
interactive: false
verticalLayoutDirection: GridView.BottomToTop
layoutDirection: Qt.LeftToRight
model: trainModel
delegate: Carriage {
width: background.itemWidth
nbCarriage: (parent.width - engine.width) / background.itemWidth
}
}
JsonParser {
id: parser
onError: console.error("Click_on_letter: Error parsing JSON: " + msg);
}
}
}
diff --git a/src/activities/click_on_letter/click_on_letter.js b/src/activities/click_on_letter/click_on_letter.js
index ddfef0db7..3ff67221e 100644
--- a/src/activities/click_on_letter/click_on_letter.js
+++ b/src/activities/click_on_letter/click_on_letter.js
@@ -1,210 +1,210 @@
/* GCompris - click_on_letter.js
*
* Copyright (C) 2014 Holger Kaelberer
*
* Authors:
* Pascal Georges <pascal.georges1@free.fr> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ Mostly full rewrite)
* Holger Kaelberer <holger.k@elberer.de> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
.import GCompris 1.0 as GCompris //for ApplicationInfo
.import "qrc:/gcompris/src/core/core.js" as Core
var url = "qrc:/gcompris/src/activities/click_on_letter/resource/"
var defaultLevelsFile = ":/gcompris/src/activities/click_on_letter/resource/levels-en.json";
var maxLettersPerLine = 6;
var levels;
var currentLevel;
var maxLevel;
var currentSubLevel;
var currentLetter;
var maxSubLevel;
var level;
var questions;
var answers;
var items;
var mode;
function start(_items, _mode)
{
Core.checkForVoices(_items.main);
items = _items;
mode = _mode;
// register the voices for the locale
var locale = GCompris.ApplicationInfo.getVoicesLocale(items.locale)
GCompris.DownloadManager.updateResource(GCompris.DownloadManager.getVoicesResourceForLocale(locale))
loadLevels();
currentLevel = 0;
currentSubLevel = 0;
maxLevel = levels.length;
initLevel();
}
function validateLevels(levels)
{
var i;
for (i = 0; i < levels.length; i++) {
if (undefined === levels[i].questions
|| typeof levels[i].questions != "string"
|| levels[i].questions.length < 1
|| typeof levels[i].answers != "string"
|| levels[i].answers.length < 1)
return false;
}
if (i < 1)
return false;
return true;
}
function loadLevels()
{
var ret;
var locale = GCompris.ApplicationInfo.getVoicesLocale(items.locale)
var filename = GCompris.ApplicationInfo.getLocaleFilePath(url + "levels-" + locale + ".json");
levels = items.parser.parseFromUrl(filename);
if (levels == null) {
console.warn("Click_on_letter: Invalid levels file " + filename);
// fallback to default Latin (levels-en.json) file:
levels = items.parser.parseFromUrl(defaultLevelsFile);
if (levels == null) {
console.error("Click_on_letter: Invalid default levels file "
+ defaultLevelsFile + ". Can't continue!");
// any way to error-exit here?
return;
}
}
// at this point we have valid levels
for (var i = 0; i < levels.length; i++) {
if (mode === "lowercase") {
levels[i].questions = levels[i].questions.toLocaleLowerCase();
levels[i].answers = levels[i].answers.toLocaleLowerCase();
} else {
levels[i].questions = levels[i].questions.toLocaleUpperCase();
levels[i].answers = levels[i].answers.toLocaleUpperCase();
}
}
}
function stop()
{
}
function shuffleString(s)
{
var a = s.split("");
var n = a.length;
for(var i = n-1; i>0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
return a.join("");
}
function initLevel() {
items.bar.level = currentLevel + 1;
if (currentSubLevel == 0) {
level = levels[currentLevel];
maxSubLevel = level.questions.length;
items.score.numberOfSubLevels = maxSubLevel;
items.score.currentSubLevel = 1;
questions = shuffleString(level.questions);
answers = shuffleString(level.answers);
var answerArr = answers.split("");
items.trainModel.clear();
for (var i = 0; i < answerArr.length; i++) {
items.trainModel.append({
"letter": answerArr[i],
});
}
} else {
items.score.currentSubLevel = currentSubLevel + 1;
}
var locale = GCompris.ApplicationInfo.getVoicesLocale(items.locale);
currentLetter = questions.split("")[currentSubLevel];
if (GCompris.ApplicationSettings.isAudioVoicesEnabled &&
GCompris.DownloadManager.haveLocalResource(
GCompris.DownloadManager.getVoicesResourceForLocale(locale))) {
items.audioVoices.append(GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/"+locale+"/misc/click_on_letter.$CA"))
items.audioVoices.silence(100)
playLetter(currentLetter)
items.questionItem.visible = false
items.repeatItem.visible = true
} else {
// no sound -> show question
items.questionItem.visible = true;
items.repeatItem.visible = false
}
// Maybe we will display it if sound fails
items.questionItem.text = currentLetter;
}
function playLetter(letter) {
var locale = GCompris.ApplicationInfo.getVoicesLocale(items.locale)
items.audioVoices.append(GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/"+locale+"/alphabet/"
+ Core.getSoundFilenamForChar(letter)))
}
function nextLevel() {
items.audioVoices.clearQueue()
if(maxLevel <= ++currentLevel) {
currentLevel = 0
}
currentSubLevel = 0;
initLevel();
}
function previousLevel() {
items.audioVoices.clearQueue()
if(--currentLevel < 0) {
currentLevel = maxLevel - 1
}
currentSubLevel = 0;
initLevel();
}
function nextSubLevel() {
items.audioVoices.clearQueue()
if(++currentSubLevel >= maxSubLevel) {
currentSubLevel = 0
nextLevel()
}
initLevel();
}
function checkAnswer(index)
{
var modelEntry = items.trainModel.get(index);
- if (modelEntry.letter == currentLetter) {
+ if (modelEntry.letter === currentLetter) {
playLetter(modelEntry.letter);
items.bonus.good("flower");
return true
} else {
return false
}
}
diff --git a/src/activities/click_on_letter/resource/levels-el.json b/src/activities/click_on_letter/resource/levels-el.json
new file mode 100644
index 000000000..d654f9240
--- /dev/null
+++ b/src/activities/click_on_letter/resource/levels-el.json
@@ -0,0 +1,13 @@
+[
+ { "level": 1, "questions": "αεηιουω", "answers": "αεηιουω" },
+ { "level": 2, "questions": "αεηιουω", "answers": "αεηιουωβγ" },
+ { "level": 3, "questions": "αεηιουω", "answers": "αεηιουωβγδεζ" },
+ { "level": 4, "questions": "βγδζθκλμν", "answers": "βγδζθκλμν" },
+ { "level": 5, "questions": "ξπρστφχψβγ", "answers": "ξπρστφχψβγ" },
+ { "level": 6, "questions": "αβεζηθικοπω", "answers": "αβεζηθικοπω" },
+ { "level": 7, "questions": "βαγεδηζιθοκω", "answers": "βαγεδηζιθοκω" },
+ { "level": 8, "questions": "αβγδεζηθικλμ", "answers": "αβγδεζηθικλμ" },
+ { "level": 9, "questions": "νξοπρστυφχψω", "answers": "νξοπρστυφχψω" },
+ { "level": 10, "questions": "εκρφλςακδλςδψ", "answers": "εκρφλςακδλςδψ" },
+ { "level": 11, "questions": "βδζθκλμνξπρστφχψ", "answers": "βδζθκλμνξπρστφχψ" }
+]
diff --git a/src/activities/click_on_letter/resource/levels-ro.json b/src/activities/click_on_letter/resource/levels-ro.json
new file mode 100644
index 000000000..42fea5edb
--- /dev/null
+++ b/src/activities/click_on_letter/resource/levels-ro.json
@@ -0,0 +1,13 @@
+[
+ { "level": 1, "questions": "aeioăuy", "answers": "aeliâourăjy" },
+ { "level": 2, "questions": "aeiouyî", "answers": "afediouîycsâ" },
+ { "level": 3, "questions": "aeiăouy", "answers": "âeiouyăcksvxaz" },
+ { "level": 4, "questions": "ckspsvxșwz", "answers": "ckțepglsvxșwzs" },
+ { "level": 5, "questions": "bfțglmnșqt", "answers": "bpfțglâmoinșqt" },
+ { "level": 6, "questions": "bdagqpnmâu", "answers": "bdgqâpnamău" },
+ { "level": 7, "questions": "ilthwîvae", "answers": "iltâhczăwrvîae" },
+ { "level": 8, "questions": "abcdefăgh", "answers": "aubpcâdefăgsh" },
+ { "level": 9, "questions": "ijklmînop", "answers": "ijâkfslmînboyp" },
+ { "level": 10, "questions": "qrstuvwxyțz", "answers": "qrestuvșwxhyțz" },
+ { "level": 11, "questions": "âbcdhjlmnptvwxz", "answers": "âbcdhjaîlmnptvăwxz" }
+]
diff --git a/src/activities/click_on_letter/resource/levels-ru.json b/src/activities/click_on_letter/resource/levels-ru.json
new file mode 100644
index 000000000..521409c34
--- /dev/null
+++ b/src/activities/click_on_letter/resource/levels-ru.json
@@ -0,0 +1,14 @@
+[
+ { "level": 1, "questions": "аеиоую", "answers": "аеиоую" },
+ { "level": 2, "questions": "бвгджзс", "answers": "бвгджзс" },
+ { "level": 3, "questions": "еёийыэя", "answers": "еёийыэя" },
+ { "level": 4, "questions": "клмнпрдт", "answers": "клмнпрдт" },
+ { "level": 5, "questions": "хцчшщфвз", "answers": "хцчшщфвз" },
+ { "level": 6, "questions": "адосфвегк", "answers": "адосфвегк" },
+ { "level": 7, "questions": "инжшявоблг", "answers": "инжшявоблг" },
+ { "level": 8, "questions": "занормуцыъь", "answers": "занормуцыъь" },
+ { "level": 9, "questions": "паштмэзсфйёя", "answers": "паштмэзсфйёя" },
+ { "level": 10, "questions": "никлодщувсюеь", "answers": "никлодщувсоеь" },
+ { "level": 11, "questions": "авдёзйлнпсуфцшъью", "answers": "авдёзйлнпсуфцшъью" },
+ { "level": 12, "questions": "бгежикьортвчщыхэя", "answers": "бгежикьортхчщыхэя" }
+]
diff --git a/src/activities/click_on_letter_up/ActivityInfo.qml b/src/activities/click_on_letter_up/ActivityInfo.qml
index 20b16d2ae..c244cbade 100644
--- a/src/activities/click_on_letter_up/ActivityInfo.qml
+++ b/src/activities/click_on_letter_up/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Holger Kaelberer <holger.k@elberer.de>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "click_on_letter_up/ClickOnLetterUp.qml"
difficulty: 2
icon: "click_on_letter_up/click_on_letter_up.svg"
author: "Holger Kaelberer &lt;holger.k@elberer.de&gt;"
demo: true
//: Activity title
title: qsTr("Click on an uppercase letter")
//: Help title
description: qsTr("Listen to a letter and click on the right one")
// intro: "Click on the required letter. You can listen to it again by clicking on the mouth."
//: Help goal
goal: qsTr("Letter-name recognition")
//: Help prerequisite
prerequisite: qsTr("Visual letter-recognition.")
//: Help manual
manual: qsTr("A letter is spoken. Click on the matching letter in the main area. You can listen to the letter again, by clicking on the mouth icon in the bottom box.")
credit: ""
section: "reading"
createdInVersion: 0
}
diff --git a/src/activities/click_on_letter_up/ClickOnLetterUp.qml b/src/activities/click_on_letter_up/ClickOnLetterUp.qml
index be648802b..e7b676bb7 100644
--- a/src/activities/click_on_letter_up/ClickOnLetterUp.qml
+++ b/src/activities/click_on_letter_up/ClickOnLetterUp.qml
@@ -1,34 +1,34 @@
/* GCompris - ClickOnLetterUp.qml
*
* Copyright (C) 2014 Holger Kaelberer <holger.k@elberer.de>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Holger Kaelberer <holger.k@elberer.de> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "../click_on_letter"
ClickOnLetter {
id: activity
mode: "uppercase"
}
diff --git a/src/activities/clickanddraw/ActivityInfo.qml b/src/activities/clickanddraw/ActivityInfo.qml
index c4e9af983..2910afce7 100644
--- a/src/activities/clickanddraw/ActivityInfo.qml
+++ b/src/activities/clickanddraw/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Emmanuel Charruau <echarruau@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "clickanddraw/Clickanddraw.qml"
difficulty: 1
icon: "clickanddraw/clickanddraw.svg"
author: "Emmanuel Charruau &lt;echarruau@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Click and draw")
//: Help title
description: qsTr("Draw the picture by clicking on the selected points.")
// intro: "Click on the selected points and draw"
//: Help goal
goal: ""
//: Help prerequisite
prerequisite: qsTr("Can move the mouse and click accurately on points.")
//: Help manual
manual: qsTr("Draw the picture by clicking on each point in sequence. Each time a point is selected the next blue one appears.")
credit: ""
section: "computer mouse"
createdInVersion: 0
}
diff --git a/src/activities/clickanddraw/Clickanddraw.qml b/src/activities/clickanddraw/Clickanddraw.qml
index 3148e8e5c..5249193cb 100644
--- a/src/activities/clickanddraw/Clickanddraw.qml
+++ b/src/activities/clickanddraw/Clickanddraw.qml
@@ -1,32 +1,32 @@
/* GCompris - Clickanddraw.qml
*
* Copyright (C) 2014 Emmanuel Charruau <echarruau@gmail.com>
*
* Authors:
* Olivier Ponchaut <opvg@mailoo.org> (GTK+ version)
* Emmanuel Charruau <echarruau@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../number_sequence"
import "../../core" as Core
import "clickanddraw_dataset.js" as Dataset
NumberSequence {
mode: "clickanddraw"
pointImageOpacity: 0
dataset: Dataset
url: "qrc:/gcompris/src/activities/number_sequence/resource/"
}
diff --git a/src/activities/clickanddraw/clickanddraw_dataset.js b/src/activities/clickanddraw/clickanddraw_dataset.js
index 43da2fa8d..1c9891f44 100644
--- a/src/activities/clickanddraw/clickanddraw_dataset.js
+++ b/src/activities/clickanddraw/clickanddraw_dataset.js
@@ -1,69 +1,69 @@
/* GCompris - clickanddraw_dataset.js
* Copyright (C) 2014 Emmanuel Charruau <echarruau@gmail.com>
*
* Authors: Emmanuel Charruau <echarruau@gmail.com> (initial set)
* Timothée Giet <animtim@gmail.com> (update set ratio)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
function get() {
return [
{
"imageName1": "dn_fond1.svg",
"imageName2": "dn_fond2.svg",
"coordinates": [[267,121],[349,369],[139,216],[397,214],[190,369],[267,121]]
},
{
"imageName1": "de1.svg",
"imageName2": "de2.svg",
"coordinates": [[104,275],[106,171],[203,133],[288,178],[288,237],[311,211],[427,220],[428,324],[382,386],[260,374],[260,297],[195,323],[104,275]]
},
{
"imageName1": "house1.svg",
"imageName2": "house2.svg",
"coordinates": [[306,360],[412,360],[413,175],[356,120],[355,70],[330,70],[330,96],[272,40],[119,177],[120,361],[253,361],[252,276],[306,276],[306,360]]
},
{
"imageName1": "sapin1.svg",
"imageName2": "sapin2.svg",
"coordinates": [[104,463],[201,361],[127,373],[221,238],[160,251],[237,127],[189,146],[259,52],[324,144],[276,128],[352,251],[295,239],[387,371],[318,362],[417,466],[282,453],[282,504],[234,504],[234,453],[104,463]]
},
{
"imageName1": "epouvantail1.svg",
"imageName2": "epouvantail2.svg",
"coordinates": [[105,449],[190,340],[190,224],[62,233],[58,168],[245,160],[218,135],[217,77],[190,79],[189,68],[213,65],[209,30],[310,30],[314,56],[338,54],[339,66],[313,68],[312,135],[284,161],[462,163],[457,223],[327,221],[327,337],[411,457],[357,487],[263,377],[159,491],[105,449]]
},
{
"imageName1": "plane1.svg",
"imageName2": "plane2.svg",
"coordinates": [[228,296],[106,299],[85,278],[103,253],[142,237],[133,220],[148,213],[103,159],[108,140],[130,138],[247,223],[332,222],[377,214],[351,197],[352,187],[369,188],[395,198],[428,164],[438,216],[470,236],[472,248],[451,247],[428,240],[378,265],[308,280],[394,352],[392,382],[350,370],[266,316],[228,324],[214,310],[228,296]]
},
{
"imageName1": "fish1.svg",
"imageName2": "fish2.svg",
"coordinates": [[21,320],[50,256],[100,212],[209,203],[244,156],[276,146],[294,156],[302,175],[292,204],[314,215],[342,195],[360,207],[355,225],[365,242],[408,258],[446,246],[462,222],[480,215],[494,226],[498,278],[481,349],[469,373],[440,366],[424,335],[362,328],[318,339],[325,357],[322,378],[299,392],[268,388],[226,352],[202,352],[210,360],[206,380],[188,382],[172,360],[52,360],[35,350],[32,322],[21,320]]
},
{
"imageName1": "carnaval1.svg",
"imageName2": "carnaval2.svg",
"coordinates": [[135,204],[192,143],[224,180],[246,118],[265,188],[269,120],[277,179],[312,154],[364,203],[315,188],[286,224],[286,236],[284,296],[279,315],[320,306],[364,262],[384,184],[404,186],[386,279],[313,366],[304,473],[312,518],[208,518],[220,473],[202,365],[177,402],[200,468],[180,483],[148,407],[180,333],[227,317],[219,295],[214,235],[213,223],[183,189],[135,204]]
},
{
"imageName1": "bear1.svg",
"imageName2": "bear2.svg",
"coordinates": [[154,256],[112,240],[66,206],[42,174],[45,159],[66,154],[107,167],[150,188],[184,220],[202,206],[220,200],[192,185],[171,154],[169,117],[187,90],[170,76],[165,55],[185,38],[210,40],[226,52],[227,66],[250,59],[281,60],[300,66],[301,48],[318,37],[340,36],[357,48],[360,70],[351,82],[336,86],[352,110],[356,136],[349,164],[329,189],[308,200],[330,212],[372,180],[428,158],[461,154],[472,164],[468,184],[442,213],[400,236],[365,251],[379,286],[382,329],[376,364],[398,354],[416,360],[426,384],[421,417],[398,455],[370,470],[343,456],[340,419],[311,440],[264,453],[210,441],[180,422],[181,450],[167,471],[134,467],[105,434],[92,402],[98,366],[121,354],[146,364],[138,326],[142,282],[154,256]]
}
]
}
diff --git a/src/activities/clickgame/ActivityInfo.qml b/src/activities/clickgame/ActivityInfo.qml
index a196478bd..e6255d998 100644
--- a/src/activities/clickgame/ActivityInfo.qml
+++ b/src/activities/clickgame/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "clickgame/Clickgame.qml"
difficulty: 1
icon: "clickgame/clickgame.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
//: Activity title
title: qsTr("Click On Me")
//: Help title
description: qsTr("Catch all the swimming fish before they leave the fish tank")
// intro: "Catch the fish before they leave the aquarium."
//: Help goal
goal: qsTr("Motor coordination: moving the hand precisely.")
//: Help prerequisite
prerequisite: qsTr("Can move mouse and click on the correct place")
//: Help manual
manual: qsTr("Catch all the moving fish by simple clicking or touching them with your finger.")
credit: qsTr("Fish are taken from the Unix utility xfishtank. All image credits belong to Guillaume Rousse.")
section: "computer mouse"
createdInVersion: 0
}
diff --git a/src/activities/clickgame/Clickgame.qml b/src/activities/clickgame/Clickgame.qml
index 6b6c33222..0fb5bc348 100644
--- a/src/activities/clickgame/Clickgame.qml
+++ b/src/activities/clickgame/Clickgame.qml
@@ -1,98 +1,100 @@
/* GCompris - Clickgame.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "clickgame.js" as Activity
ActivityBase {
id: activity
focus: true
onStart: {}
onStop: {}
pageComponent: Image {
id: background
signal start
signal stop
focus: true
fillMode: Image.PreserveAspectCrop
source: "qrc:/gcompris/src/activities/clickgame/resource/sea1.jpg"
sourceSize.width: Math.max(parent.width, parent.height)
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
onStart: { Activity.start(activity, background, bar, bonus, items) }
onStop: {
Activity.stop()
timer.stop()
}
QtObject {
id: items
property alias score: score
property alias killedFishes: score.currentSubLevel
}
Timer {
id: timer
- interval: 5000; running: true; repeat: true
+ interval: 5000
+ running: true
+ repeat: true
onTriggered: activity.audioEffects.play("qrc:/gcompris/src/activities/clickgame/resource/bubble.wav")
}
DialogHelp {
id: dialogHelpLeftRight
onClose: home()
}
Score {
id: score
anchors {
top: parent.top
bottom: undefined
right: parent.right
margins: 10 * ApplicationInfo.ratio
}
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level }
onHelpClicked: {
displayDialog(dialogHelpLeftRight)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: home()
}
Bonus {
id: bonus
Component.onCompleted: win.connect(Activity.nextLevel)
}
}
}
diff --git a/src/activities/clickgame/Fish.qml b/src/activities/clickgame/Fish.qml
index 8194767b8..aa13df087 100644
--- a/src/activities/clickgame/Fish.qml
+++ b/src/activities/clickgame/Fish.qml
@@ -1,144 +1,144 @@
-/* GCompris - Clickgame.qml
+/* GCompris - Fish.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import QtQuick.Particles 2.0
import "clickgame.js" as Activity
import "../../core"
import GCompris 1.0
AnimatedSprite {
id: fish
property Item activity
property Item background
property Item bar
property real targetX // The x target of the fish
property int duration: 5000
frameRate: 2
interpolate: true
Component.onCompleted: {
targetX = background.width - fish.width
x = targetX
}
transform: Rotation {
id: rotate; origin.x: width / 2; origin.y: 0; axis { x: 0; y: 1; z: 0 } angle: 0
}
SequentialAnimation {
id: rotateLeftAnimation
loops: 1
PropertyAnimation {
target: rotate
properties: "angle"
from: 0
to: 180
duration: 500
}
}
SequentialAnimation {
id: rotateRightAnimation
loops: 1
PropertyAnimation {
target: rotate
properties: "angle"
from: 180
to: 0
duration: 500
}
}
onXChanged: {
var minY = Activity.items.score.y + Activity.items.score.height
var maxY = bar.y - fish.height
if( (x > background.width - fish.width && rotate.angle == 0) ||
(x == targetX && rotate.angle == 0) ) {
rotateLeftAnimation.start()
targetX = 0
x = targetX
var barHeight = ApplicationSettings.isBarHidden ? bar.height / 2 : bar.height
y = Activity.currentLevel > 0
? (Math.random() * (maxY - minY + 1)) + minY
: y
} else if(x == 0 && rotate.angle == 180) {
rotateRightAnimation.start()
targetX = background.width - fish.width
x = targetX
}
}
Behavior on x { PropertyAnimation { duration: fish.duration } }
Behavior on y { PropertyAnimation { duration: fish.duration } }
Behavior on opacity { PropertyAnimation { duration: 500 } }
MouseArea {
anchors.fill: parent
onClicked: {
parent.opacity = 0
enabled = false
activity.audioEffects.play("qrc:/gcompris/src/activities/clickgame/resource/drip.wav")
Activity.fishKilled()
particles.burst(40);
}
}
Loader {
id: bubbleEffect
anchors.fill: parent
active: ApplicationInfo.hasShader
sourceComponent: ParticleSystem {
anchors.fill: parent
Emitter {
x: parent.x + parent.width * 0.8
y: parent.y + parent.height / 2
width: 1
height: 1
emitRate: 0.5
lifeSpan: 1000
lifeSpanVariation: 2500
acceleration: PointDirection {
x: -10
xVariation: 10
y: -20
yVariation: 10
}
velocity: PointDirection {
x: -20
xVariation: 10
y: -20
yVariation: 10
}
size: 12
sizeVariation: 8
}
ImageParticle {
source: "qrc:/gcompris/src/activities/clickgame/resource/bubble.png"
}
}
}
ParticleSystemStarLoader {
id: particles
clip: false
}
}
diff --git a/src/activities/clickgame/clickgame.js b/src/activities/clickgame/clickgame.js
index 40a12d450..e6c8f8156 100644
--- a/src/activities/clickgame/clickgame.js
+++ b/src/activities/clickgame/clickgame.js
@@ -1,323 +1,323 @@
/* GCompris - clickgame.js
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
.import GCompris 1.0 as GCompris
var fishes = [
{
"imgName": "blueking2.png",
"nbFrame": 2,
"width": 118,
"height": 76
},
{
"imgName": "butfish.png",
"nbFrame": 2,
"width": 98,
"height": 82
},
{
"imgName": "cichlid1.png",
"nbFrame": 2,
"width": 63,
"height": 37
},
{
"imgName": "cichlid4.png",
"nbFrame": 2,
"width": 73,
"height": 44
},
{
"imgName": "collaris.png",
"nbFrame": 2,
"width": 62,
"height": 50
},
{
"imgName": "discus2.png",
"nbFrame": 2,
"width": 100,
"height": 100
},
{
"imgName": "discus3.png",
"nbFrame": 2,
"width": 63,
"height": 57
},
{
"imgName": "f00.png",
"nbFrame": 2,
"width": 64,
"height": 59
},
{
"imgName": "f01.png",
"nbFrame": 2,
"width": 63,
"height": 50
},
{
"imgName": "f02.png",
"nbFrame": 2,
"width": 71,
"height": 44
},
{
"imgName": "f03.png",
"nbFrame": 2,
"width": 83,
"height": 52
},
{
"imgName": "f04.png",
"nbFrame": 2,
"width": 93,
"height": 62
},
{
"imgName": "f05.png",
"nbFrame": 2,
"width": 90,
"height": 49
},
{
"imgName": "f06.png",
"nbFrame": 2,
"width": 93,
"height": 44
},
{
"imgName": "f07.png",
"nbFrame": 2,
"width": 82,
"height": 75
},
{
"imgName": "f08.png",
"nbFrame": 2,
"width": 91,
"height": 70
},
{
"imgName": "f09.png",
"nbFrame": 2,
"width": 108,
"height": 86
},
{
"imgName": "f10.png",
"nbFrame": 2,
"width": 97,
"height": 60
},
{
"imgName": "f11.png",
"nbFrame": 2,
"width": 116,
"height": 42
},
{
"imgName": "f12.png",
"nbFrame": 2,
"width": 100,
"height": 35
},
{
"imgName": "f13.png",
"nbFrame": 2,
"width": 116,
"height": 73
},
{
"imgName": "manta.png",
"nbFrame": 2,
"width": 266,
"height": 91
},
{
"imgName": "newf1.png",
"nbFrame": 2,
"width": 118,
"height": 81
},
{
"imgName": "QueenAngel.png",
"nbFrame": 2,
"width": 78,
"height": 54
},
{
"imgName": "shark1.png",
"nbFrame": 2,
"width": 187,
"height": 53
},
{
"imgName": "six_barred.png",
"nbFrame": 2,
"width": 76,
"height": 63
},
{
"imgName": "teeth.png",
"nbFrame": 8,
"width": 64,
"height": 64
},
]
var levelProperty = [
{
"nbFish": 5,
"minDuration": 20000
},
{
"nbFish": 7,
"minDuration": 15000
},
{
"nbFish": 10,
"minDuration": 10000
},
{
"nbFish": 12,
"minDuration": 8000
},
{
"nbFish": 15,
"minDuration": 6000
},
{
"nbFish": 18,
"minDuration": 4000
}
]
var currentImageId = 0
var currentLevel = 0
var items
var activity
var background
var bar
var bonus
var isActivityStopped = false
// The array of created fishes object
var createdFishes
var component = Qt.createComponent("qrc:/gcompris/src/activities/clickgame/Fish.qml");
function start(activity_, background_, bar_, bonus_, items_) {
activity = activity_
background = background_
bar = bar_
bonus = bonus_
items = items_
currentLevel = 0
isActivityStopped = false
initLevel()
items.killedFishes = 0
}
function stop() {
isActivityStopped = true
destroyFishes();
}
function initLevel() {
if(isActivityStopped)
return;
destroyFishes();
bar.level = currentLevel + 1
background.source = "qrc:/gcompris/src/activities/clickgame/resource/sea" +
bar.level + ".jpg"
var nbFish = levelProperty[currentLevel].nbFish
createdFishes = new Array(nbFish)
for(var i = 0; i < nbFish; ++i) {
createdFishes[i] = createFish(levelProperty[currentLevel].minDuration)
}
items.score.numberOfSubLevels = nbFish
}
function nextLevel() {
if(levelProperty.length <= ++currentLevel) {
currentLevel = 0
}
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = levelProperty.length - 1
}
initLevel();
}
function createFish(minDuration) {
var fishSource = fishes[Math.floor(Math.random() * fishes.length)]
var minY = items.score.y + items.score.height
- var maxY = bar.y - fishSource.height
+ var maxY = bar.y - fishSource.height - bar.height
var fish = component.createObject(
background,
{
"activity": activity,
"background": background,
"bar": bar,
"y": (Math.random() * (maxY - minY + 1)) + minY,
"width": fishSource.width * 1.1 * GCompris.ApplicationInfo.ratio,
"height": fishSource.height * 1.1 * GCompris.ApplicationInfo.ratio,
"source": "qrc:/gcompris/src/activities/clickgame/resource/" +
fishSource.imgName,
"frameCount": fishSource.nbFrame,
"duration": minDuration + Math.floor(Math.random() * 5000)
});
if (fish === null) {
// Error Handling
console.log("Error creating object");
}
else
fish.restart()
return fish;
}
function destroyFishes() {
if (createdFishes) {
for(var i = 0; i < createdFishes.length; ++i) {
createdFishes[i].destroy()
}
createdFishes.length = 0
}
items.killedFishes = 0
}
function fishKilled() {
if(++items.killedFishes === createdFishes.length) {
bonus.good("flower")
}
items.score.playWinAnimation();
}
diff --git a/src/activities/clockgame/ActivityInfo.qml b/src/activities/clockgame/ActivityInfo.qml
index c5f212545..4b9e3ce32 100644
--- a/src/activities/clockgame/ActivityInfo.qml
+++ b/src/activities/clockgame/ActivityInfo.qml
@@ -1,41 +1,41 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Stephane Mankowski <stephane@mankowski.fr>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "clockgame/Clockgame.qml"
difficulty: 2
icon: "clockgame/clockgame.svg"
author: "Stephane Mankowski &lt;stephane@mankowski.fr&gt;"
demo: true
//: Activity title
title: qsTr("Learning Clock")
//: Help title
description: qsTr("Learn how to tell the time on an analog clock")
// intro: "Drag and drop the needles of the clock to display the required time"
//: Help goal
goal: qsTr("Distinguish between time-units (hour, minute and second). Set and display time on an analog clock.")
//: Help prerequisite
prerequisite: qsTr("The concept of time.")
//: Help manual
manual: qsTr("Set the clock to the given time, in the time-units shown (hours:minutes or hours:minutes:seconds). Drag the different arrows, to make the respective time unit go up or down.")
credit: ""
section: "discovery"
createdInVersion: 0
levels: "1,2"
}
diff --git a/src/activities/clockgame/Clockgame.qml b/src/activities/clockgame/Clockgame.qml
index 885b5a82f..e63ba5889 100644
--- a/src/activities/clockgame/Clockgame.qml
+++ b/src/activities/clockgame/Clockgame.qml
@@ -1,492 +1,492 @@
/* GCompris - Clockgame.qml
*
* Copyright (C) 2014 Stephane Mankowski <stephane@mankowski.fr>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Stephane Mankowski <stephane@mankowski.fr> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import QtGraphicalEffects 1.0
import GCompris 1.0
import "../../core"
import "clockgame.js" as Activity
ActivityBase {
id: activity
onStart: focus = true
onStop: {
}
pageComponent: Image {
id: background
source: "qrc:/gcompris/src/activities/menu/resource/background.svg"
sourceSize.width: Math.max(parent.width, parent.height)
fillMode: Image.PreserveAspectCrop
anchors.fill: parent
signal start
signal stop
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property alias background: background
property alias bar: bar
property alias bonus: bonus
property int targetH: 12
property int targetM: 0
property int targetS: 0
property int currentH: 1
property int currentM: 25
property int currentS: 43
property int numberOfTry: 3
property int currentTry: 0
property var levels: activity.datasetLoader.item.data
property bool minutesHandVisible
property bool secondsHandVisible
property bool zonesVisible
}
onStart: {
Activity.start(items)
}
onStop: {
Activity.stop()
}
Score {
anchors {
bottom: bar.top
bottomMargin: 10 * ApplicationInfo.ratio
right: bar.right
rightMargin: 10 * ApplicationInfo.ratio
left: parent.left
leftMargin: 10 * ApplicationInfo.ratio
top: undefined
}
numberOfSubLevels: items.numberOfTry
currentSubLevel: items.currentTry + 1
}
/* Target text */
Rectangle {
id: questionItemBackground
color: "#c0ceb339"
border.width: 0
radius: 10
z: 10
anchors {
horizontalCenter: parent.horizontalCenter
top: parent.top
margins: 10
}
height: questionItem.height + anchors.margins * 2
width: questionItem.width + anchors.margins * 2
Behavior on height { PropertyAnimation { duration: 100 } }
GCText {
id: questionItem
text: qsTr("Set the watch to:") + " " +
//~ singular %n hour
//~ plural %n hours
addNbsp(qsTr("%n hour(s)", "", items.targetH)) + " " +
//~ singular %n minute
//~ plural %n minutes
addNbsp(qsTr("%n minute(s)", "", items.targetM)) +
//~ singular %n second
//~ plural %n seconds
(s.visible ? " " + addNbsp(qsTr("%n second(s)", "", items.targetS)) : "")
fontSize: mediumSize
textFormat: Text.RichText
font.weight: Font.DemiBold
color: "white"
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.WordWrap
width: background.width
anchors {
horizontalCenter: parent.horizontalCenter
top: parent.top
margins: 10
}
// We don't want the wrapping to happen anywhere, set no break space
function addNbsp(str) {
return str.replace(" ", "&nbsp;");
}
}
}
/* The clock */
Image {
id: clock
source: activity.resourceUrl + "clock_bg.svg"
anchors.centerIn: parent
fillMode: Image.PreserveAspectFit
sourceSize.height: parent.height
property int radius: Math.min(background.width * 1.4, background.height)
/* The yellow zones */
Image {
id: zones
source: activity.resourceUrl + "clock_zones.svg"
anchors.centerIn: parent
fillMode: Image.PreserveAspectFit
sourceSize.height: parent.height * 0.7
visible: items.zonesVisible
z: 2
}
/* The setter */
Image {
id: setter
source: activity.resourceUrl + "clock_setter.svg"
anchors {
verticalCenter: parent.verticalCenter
left: parent.right
leftMargin: -10
}
z: 1
}
/* The minutes */
Repeater {
model: 60
GCText {
text: index + 1
font {
pointSize: NaN // need to clear font.pointSize explicitly
pixelSize: Math.max(
(index + 1) % 5
=== 0 ? clock.radius / 40 : clock.radius / 45,
1)
bold: items.currentM === ((index + 1) % 60) || (items.currentS === ((index + 1) % 60) && s.visible)
underline: items.currentM === ((index + 1) % 60) || (items.currentS === ((index + 1) % 60) && s.visible)
}
anchors {
verticalCenter: clock.verticalCenter
horizontalCenter: clock.horizontalCenter
verticalCenterOffset: -clock.radius * 0.33 * Math.cos(
(index + 1) * 2 * Math.PI / 60)
horizontalCenterOffset: clock.radius * 0.33 * Math.sin(
(index + 1) * 2 * Math.PI / 60)
}
z: 4
color: "#d56a3a"
visible: items.minutesHandVisible
}
}
/* The seconds */
Repeater {
model: 60
Rectangle {
color: "#d56a3a"
width: clock.radius * 0.02
height: 2
rotation: 90 + (index + 1) * 360 / 60
radius: 1
anchors {
verticalCenter: clock.verticalCenter
horizontalCenter: clock.horizontalCenter
verticalCenterOffset: -clock.radius * 0.3 * Math.cos(
(index + 1) * 2 * Math.PI / 60)
horizontalCenterOffset: clock.radius * 0.3 * Math.sin(
(index + 1) * 2 * Math.PI / 60)
}
z: 4
visible: items.secondsHandVisible
}
}
/* The hours */
Repeater {
model: 12
GCText {
text: index + 1
font {
pointSize: NaN // need to clear font.pointSize explicitly
pixelSize: Math.max(clock.radius / 30, 1)
bold: items.currentH === ((index + 1) % 12)
underline: items.currentH === ((index + 1) % 12)
}
anchors {
verticalCenter: clock.verticalCenter
horizontalCenter: clock.horizontalCenter
verticalCenterOffset: -clock.radius * 0.26 * Math.cos(
(index + 1) * 2 * Math.PI / 12)
horizontalCenterOffset: clock.radius * 0.26 * Math.sin(
(index + 1) * 2 * Math.PI / 12)
}
z: 4
color: "#3a81d5"
visible: items.bar.level < 7
}
}
Repeater {
model: 12
Rectangle {
color: "#3a81d5"
width: clock.radius * 0.03
height: 4
rotation: 90 + (index + 1) * 360 / 12
radius: 1
anchors {
verticalCenter: clock.verticalCenter
horizontalCenter: clock.horizontalCenter
verticalCenterOffset: -clock.radius * 0.3 * Math.cos(
(index + 1) * 2 * Math.PI / 12)
horizontalCenterOffset: clock.radius * 0.3 * Math.sin(
(index + 1) * 2 * Math.PI / 12)
}
z: 4
visible: items.bar.level < 9 || (items.bar.level === 9
&& ((index + 1) % 3) === 0)
}
}
/* Help text */
GCText {
id: helper
text: Activity.get2CharValue(
items.currentH) + ":" + Activity.get2CharValue(
items.currentM) + ":" + Activity.get2CharValue(
items.currentS)
font.pointSize: NaN
font.pixelSize: Math.max(clock.radius / 30, 1)
anchors {
verticalCenter: clock.verticalCenter
horizontalCenter: clock.horizontalCenter
verticalCenterOffset: clock.radius * 0.2
}
z: 4
color: "#2a2a2a"
visible: false
}
/* Arrow H */
Rectangle {
id: h
property alias angle: roth.angle
height: clock.radius * 0.2
width: height / 10
radius: width / 2
color: "#3a81d5"
transform: Rotation {
id: roth
origin.x: h.width / 2
origin.y: 0
angle: (180 + 360 * (items.currentH / 12 + items.currentM / 60 / 12)) % 360
Behavior on angle {
RotationAnimation {
duration: 100
direction: RotationAnimation.Shortest
}
}
}
anchors {
verticalCenter: clock.verticalCenter
horizontalCenter: clock.horizontalCenter
verticalCenterOffset: h.height / 2
}
z: 5
}
/* Arrow M */
Rectangle {
id: m
property alias angle: rotm.angle
height: clock.radius * 0.28
width: height / 20
radius: width / 2
color: "#d56a3a"
visible: items.minutesHandVisible
transform: Rotation {
id: rotm
origin.x: m.width / 2
origin.y: 0
angle: (180 + 360 * (items.currentM / 60 + items.currentS / 60 / 60)) % 360
Behavior on angle {
RotationAnimation {
duration: 100
direction: RotationAnimation.Shortest
}
}
}
anchors {
verticalCenter: clock.verticalCenter
horizontalCenter: clock.horizontalCenter
verticalCenterOffset: m.height / 2
}
z: 6
}
/* Arrow S */
Rectangle {
id: s
property alias angle: rots.angle
height: clock.radius * 0.32
width: height / 30
radius: width / 2
color: "#2ccf4b"
visible: items.secondsHandVisible
transform: Rotation {
id: rots
origin.x: s.width / 2
origin.y: 0
angle: (180 + 360 * items.currentS / 60) % 360
Behavior on angle {
RotationAnimation {
duration: 100
direction: RotationAnimation.Shortest
}
}
}
anchors {
verticalCenter: clock.verticalCenter
horizontalCenter: clock.horizontalCenter
verticalCenterOffset: s.height / 2
}
z: 7
}
/* Center */
Rectangle {
id: center
color: "#2a2a2a"
height: clock.radius / 25
width: height
radius: width / 2
anchors.centerIn: clock
z: 8
}
/* Manage the move */
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.LeftButton
onPressed: {
/* Find the closer Arrow */
var a = (270 + 360 + 180 * Math.atan2(
mouseY - (center.y + center.height / 2),
mouseX - (center.x + center.width / 2)) / Math.PI) % 360
var agnh = h.angle
var angm = m.angle
var angs = s.angle
var dh = Math.min(Math.abs(a - agnh),
Math.abs(a - agnh - 360),
Math.abs(a - agnh + 360))
var dm = m.visible ? Math.min(Math.abs(a - angm),
Math.abs(a - angm - 360),
Math.abs(a - angm + 360)) : 9999
var ds = s.visible ? Math.min(
Math.abs(a - angs),
Math.abs(a - angs - 360),
Math.abs(a - angs + 360)) : 9999
var dmin = Math.min(dh, dm, ds)
if (dh === dmin) {
Activity.selectedArrow = h
} else if (dm === dmin) {
Activity.selectedArrow = m
} else {
Activity.selectedArrow = s
}
}
onReleased: {
Activity.selectedArrow = null
//todo replace this with Ok button
if (items.currentH === items.targetH
&& items.currentM === items.targetM
&& items.currentS === items.targetS) {
items.bonus.good("gnu")
}
}
onMouseXChanged: {
/* Move */
if (Activity.selectedArrow !== null) {
var a = (270 + 360 + 180 * Math.atan2(
mouseY - (center.y + center.height / 2),
mouseX - (center.x + center.width / 2)) / Math.PI) % 360
var previousM = items.currentM
var previousS = items.currentS
if (Activity.selectedArrow === h) {
items.currentH = Math.round(
12 * ((a - 180) / 360 - items.currentM / 60 / 12) + 12) % 12
} else if (Activity.selectedArrow === m) {
items.currentM = Math.round(
60 * ((a - 180) / 360 - items.currentS / 60 / 60) + 60) % 60
} else {
items.currentS = Math.round(
60 * (a - 180) / 360 + 60) % 60
}
if (previousS > 45 && items.currentS < 15)
items.currentM = (items.currentM + 1 + 60) % 60
if (previousS < 15 && items.currentS > 45)
items.currentM = (items.currentM - 1 + 60) % 60
if (previousM > 45 && items.currentM < 15)
items.currentH = (items.currentH + 1 + 12) % 12
if (previousM < 15 && items.currentM > 45)
items.currentH = (items.currentH - 1 + 12) % 12
}
}
}
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: BarEnumContent {
value: help | home | level | hint
}
onHelpClicked: {
displayDialog(dialogHelp)
}
onHintClicked: {
helper.visible = !helper.visible
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
}
Bonus {
id: bonus
Component.onCompleted: win.connect(Activity.nextTry)
}
}
}
diff --git a/src/activities/clockgame/clockgame.js b/src/activities/clockgame/clockgame.js
index 3d9740d7b..6a0319879 100644
--- a/src/activities/clockgame/clockgame.js
+++ b/src/activities/clockgame/clockgame.js
@@ -1,107 +1,107 @@
/* GCompris - clockgame.js
*
* Copyright (C) 2014 Stephane Mankowski <stephane@mankowski.fr>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Stephane Mankowski <stephane@mankowski.fr> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
var currentLevel = 0
var numberOfLevel = 10
var items
var selectedArrow
function start(items_) {
items = items_
currentLevel = 0
numberOfLevel = items.levels.length
initLevel()
}
function stop() {}
function initLevel() {
items.bar.level = currentLevel + 1
items.numberOfTry = items.levels[currentLevel].numberOfSubLevels
items.currentH = Math.floor(Math.random() * 12)
items.targetH = Math.floor(Math.random() * 12)
items.minutesHandVisible = items.levels[currentLevel].displayMinutesHand
if(!items.minutesHandVisible) {
items.currentM = 0
items.targetM = 0
}
else if(items.levels[currentLevel].fixedMinutes !== undefined) {
items.currentM = Math.floor(Math.random() * 60)
items.targetM = items.levels[currentLevel].fixedMinutes
}
else {
items.currentM = Math.floor(Math.random() * 60)
items.targetM = Math.floor(Math.random() * 60)
}
items.secondsHandVisible = items.levels[currentLevel].displaySecondsHand
if(!items.secondsHandVisible) {
items.currentS = 0
items.targetS = 0
}
else if(items.levels[currentLevel].fixedSeconds !== undefined) {
items.currentS = Math.floor(Math.random() * 60)
items.targetS = items.levels[currentLevel].fixedSeconds
}
else {
items.currentS = Math.floor(Math.random() * 60)
items.targetS = Math.floor(Math.random() * 60)
}
if(items.levels[currentLevel].zonesVisible !== undefined) {
items.zonesVisible = items.levels[currentLevel].zonesVisible
}
else {
items.zonesVisible = true
}
}
function nextTry() {
if (items.numberOfTry <= ++items.currentTry) {
items.currentTry = 0
nextLevel()
} else {
initLevel()
}
}
function nextLevel() {
if (numberOfLevel <= ++currentLevel) {
currentLevel = 0
}
items.currentTry = 0
initLevel()
}
function previousLevel() {
if (--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
items.currentTry = 0
initLevel()
}
function get2CharValue(i) {
if (String(i).length === 1)
return "0" + i
return i
}
diff --git a/src/activities/color_mix/ActivityInfo.qml b/src/activities/color_mix/ActivityInfo.qml
index f48244f59..33ebc2575 100644
--- a/src/activities/color_mix/ActivityInfo.qml
+++ b/src/activities/color_mix/ActivityInfo.qml
@@ -1,44 +1,44 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Stephane Mankowski <stephane@mankowski.fr>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "color_mix/ColorMix.qml"
difficulty: 4
icon: "color_mix/color_mix.svg"
author: "Stephane Mankowski &lt;stephane@mankowski.fr&gt;"
demo: true
//: Activity title
title: qsTr("Mixing color of paint")
//: Help title
description: qsTr("Discover paint color mixing.")
// intro: "Match the colour by moving the sliders on the tubes of paint"
//: Help goal
goal: qsTr("Mix the primary colors to match to the given color")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("
The activity deals with mixing primary colors of paint (subtractive mixing).
In case of paints the inks absorb different colors of light falling on it, subtracting it from what you see. The more ink you add, the more light is absorbed, and the darker the combined color gets. We can mix just three primary colors to make many new colors. The primary colors for paint/ink are cyan (a special shade of blue), magenta (a special shade of pink), and yellow.
")
credit: qsTr("Images from http://openclipart.org")
section: "experiment color"
createdInVersion: 0
}
diff --git a/src/activities/color_mix/ColorButton.qml b/src/activities/color_mix/ColorButton.qml
index ba5990caf..b0254f01a 100644
--- a/src/activities/color_mix/ColorButton.qml
+++ b/src/activities/color_mix/ColorButton.qml
@@ -1,78 +1,78 @@
/* GCompris - ColorButton.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
Item {
id: button
height: parent.height / 4
width: height
z: 3
property alias source: buttonImage.source
signal clicked
Image {
id: buttonImage
anchors.centerIn: parent
sourceSize.width: parent.width
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
MouseArea {
id: mouseArea
anchors.centerIn: parent
height: 3 * parent.height
width: 3 * parent.width
hoverEnabled: true
}
states: [
State {
name: "notclicked"
PropertyChanges {
target: button
scale: 1.0
}
},
State {
name: "clicked"
when: mouseArea.pressed
PropertyChanges {
target: button
scale: 0.9
}
},
State {
name: "hover"
when: mouseArea.containsMouse
PropertyChanges {
target: button
scale: 1.2
}
}
]
Behavior on scale { NumberAnimation { duration: 70 } }
}
diff --git a/src/activities/color_mix/ColorChooser.qml b/src/activities/color_mix/ColorChooser.qml
index 8d1c10cdf..5583f2bb7 100644
--- a/src/activities/color_mix/ColorChooser.qml
+++ b/src/activities/color_mix/ColorChooser.qml
@@ -1,104 +1,104 @@
/* GCompris - ColorChooser.qml
*
* Copyright (C) 2014 Stephane Mankowski <stephane@mankowski.fr>
*
* Authors:
* Matilda Bernard <serah4291@gmail.com> (GTK+ version)
* Stephane Mankowski <stephane@mankowski.fr> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "colormix.js" as Activity
import "."
Image {
id: chooser
z: 1
property int maxSteps: 10
property int currentStep: 0
property string brushHue
Image {
id: intensityScreen
source: activity.modeRGB ? Activity.url + "flashlight2" + brushHue + ".svg" : "qrc:/gcompris/src/core/resource/empty.svg"
sourceSize.height: parent.sourceSize.height
sourceSize.width: parent.sourceSize.width
z: 2
opacity: currentStep / maxSteps
visible: activity.modeRGB
}
Image {
id: intensityBrush
source: Activity.url + (activity.modeRGB ?
"light" + brushHue + ".svg" : "brush" + brushHue + ".svg")
sourceSize.height: parent.sourceSize.height * 0.25 + currentStep / maxSteps * 15
z: 2
anchors {
left: parent.right
leftMargin: activity.modeRGB ? -20 * ApplicationInfo.ratio : 0
verticalCenter: parent.verticalCenter
}
opacity: activity.modeRGB ? currentStep / maxSteps * 2 : 1
visible: currentStep > 0
fillMode: Image.PreserveAspectFit
}
ColorButton {
source: Activity.url + "plus.svg"
anchors {
verticalCenter: parent.verticalCenter
right: parent.right
- rightMargin: parent.width * 0.2
+ rightMargin: parent.width * 0.25
}
}
ColorButton {
source: Activity.url + "minus.svg"
anchors {
verticalCenter: parent.verticalCenter
left: parent.left
- leftMargin: parent.width * 0.3
+ leftMargin: parent.width * 0.5
}
}
MultiPointTouchArea {
anchors.fill: parent
touchPoints: [ TouchPoint { id: point1 } ]
z: 4
property real startX
property int initialStep: 0
onPressed: {
startX = point1.x
if(startX > parent.width / 2)
currentStep = Math.max(currentStep + 1, 0)
else
currentStep = Math.max(currentStep - 1, 0)
initialStep = currentStep
}
onTouchUpdated: {
currentStep = initialStep + (point1.x - startX) / (20 * ApplicationInfo.ratio)
currentStep = Math.min(currentStep, maxSteps)
currentStep = Math.max(currentStep, 0)
activity.audioEffects.play('qrc:/gcompris/src/activities/redraw/resource/brush.wav')
}
}
}
diff --git a/src/activities/color_mix/ColorMix.qml b/src/activities/color_mix/ColorMix.qml
index 0b7b3e8d3..df731233c 100644
--- a/src/activities/color_mix/ColorMix.qml
+++ b/src/activities/color_mix/ColorMix.qml
@@ -1,268 +1,270 @@
/* GCompris - colormix.qml
*
* Copyright (C) 2014 Stephane Mankowski <stephane@mankowski.fr>
*
* Authors:
* Matilda Bernard <serah4291@gmail.com> (GTK+ version)
* Stephane Mankowski <stephane@mankowski.fr> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "colormix.js" as Activity
ActivityBase {
id: activity
property bool modeRGB: false
onStart: focus = true
onStop: {
}
pageComponent: Image {
id: background
source: Activity.url + (modeRGB ? "background.svg" : "background2.svg")
sourceSize.width: Math.max(parent.width, parent.height)
anchors.fill: parent
fillMode: Image.PreserveAspectCrop
signal start
signal stop
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property alias background: background
property alias bar: bar
property alias bonus: bonus
property alias score: score
property int maxSteps: 1
property int targetColor1: 0
property int targetColor2: 0
property int targetColor3: 0
property alias currentColor1: color1.currentStep
property alias currentColor2: color2.currentStep
property alias currentColor3: color3.currentStep
property int margins: 20
property int chooserHeight: Math.min(background.height * 0.2,
background.width * 0.2)
}
onStart: {
Activity.start(items)
}
onStop: {
Activity.stop()
}
Rectangle {
id: target
- height: width / 2
+ height: width / 2.5
width: parent.width / 5
radius: height / 10
anchors {
top: parent.top
topMargin: items.margins
horizontalCenter: parent.horizontalCenter
}
border.color: "#2a2a2a"
border.width: 0
color: Activity.getColor(items.targetColor1, items.targetColor2,
items.targetColor3)
}
GCText {
text: qsTr("Match the color")
- fontSize: 18
color: "#2a2a2a"
horizontalAlignment: Text.AlignRight
wrapMode: Text.WordWrap
+ fontSizeMode: Text.Fit
anchors {
top: target.top
right: target.left
left: parent.left
rightMargin: items.margins
}
}
GCText {
id: helpMessage
text: ""
- fontSize: mediumSize
+ fontSizeMode: Text.Fit
horizontalAlignment: Text.AlignLeft
wrapMode: Text.WordWrap
anchors {
top: target.top
left: target.right
right: parent.right
leftMargin: items.margins
+ bottom: result.top
}
}
Rectangle {
id: result
height: width
- width: target.width * 0.75
+ width: Math.min(target.width * 0.75, 90 * ApplicationInfo.ratio)
radius: height / 2
+
anchors {
horizontalCenter: parent.horizontalCenter
top: target.bottom
- topMargin: (background.height - items.chooserHeight * 4) / 2
+ topMargin: (background.height - items.chooserHeight * 4) / 3
}
border.color: "#2a2a2a"
border.width: 0
color: Activity.getColor(items.currentColor1, items.currentColor2,
items.currentColor3)
}
ColorChooser {
id: color1
brushHue: activity.modeRGB ? "-r" : "-m" /* red / magenta */
source: Activity.url + (activity.modeRGB ? "flashlight-red.svg" : "tube-magenta.svg")
sourceSize.height: items.chooserHeight
maxSteps: items.maxSteps
anchors {
right: result.left
rightMargin: items.margins
verticalCenter: result.verticalCenter
}
}
ColorChooser {
id: color2
brushHue: activity.modeRGB ? "-g" : "-y" /* green / yellow */
source: Activity.url + (activity.modeRGB ? "flashlight-green.svg" : "tube-yellow.svg")
sourceSize.height: items.chooserHeight
maxSteps: items.maxSteps
anchors {
horizontalCenter: result.horizontalCenter
top: result.bottom
topMargin: items.margins + width / 2 - height / 2
}
rotation: -90
}
ColorChooser {
id: color3
brushHue: activity.modeRGB ? "-b" : "-c" /* blue / cyan */
source: Activity.url + (activity.modeRGB ? "flashlight-blue.svg" : "tube-cyan.svg")
sourceSize.height: items.chooserHeight
maxSteps: items.maxSteps
anchors {
left: result.right
leftMargin: items.margins
verticalCenter: result.verticalCenter
}
rotation: 180
}
Score {
id: score
- x: parent.width * 0.25
y: parent.height * 0.65
+ anchors.left: parent.left
anchors.right: undefined
anchors.bottom: undefined
currentSubLevel: 0
numberOfSubLevels: 10
}
BarButton {
id: validate
source: "qrc:/gcompris/src/core/resource/bar_ok.svg"
sourceSize.width: 66 * bar.barZoom
visible: true
anchors {
right: parent.right
rightMargin: items.margins
top: color3.bottom
topMargin: items.margins
}
onClicked: {
var message = ""
if (activity.modeRGB) {
/* check RGB */
if (items.currentColor1 < items.targetColor1)
message += qsTr("Not enough red") + "\n"
else if (items.currentColor1 > items.targetColor1)
message += qsTr("Too much red") + "\n"
if (items.currentColor2 < items.targetColor2)
message += qsTr("Not enough green") + "\n"
else if (items.currentColor2 > items.targetColor2)
message += qsTr("Too much green") + "\n"
if (items.currentColor3 < items.targetColor3)
message += qsTr("Not enough blue") + "\n"
else if (items.currentColor3 > items.targetColor3)
message += qsTr("Too much blue") + "\n"
} else {
/* check MCY */
if (items.currentColor1 < items.targetColor1)
message += qsTr("Not enough magenta") + "\n"
else if (items.currentColor1 > items.targetColor1)
message += qsTr("Too much magenta") + "\n"
if (items.currentColor2 < items.targetColor2)
message += qsTr("Not enough yellow") + "\n"
else if (items.currentColor2 > items.targetColor2)
message += qsTr("Too much yellow") + "\n"
if (items.currentColor3 < items.targetColor3)
message += qsTr("Not enough cyan") + "\n"
else if (items.currentColor3 > items.targetColor3)
message += qsTr("Too much cyan") + "\n"
}
helpMessage.text = message
if (message === "") {
bonus.good("gnu")
helpMessage.text = ""
}
}
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: BarEnumContent {
value: help | home | level
}
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
}
Bonus {
id: bonus
Component.onCompleted: win.connect(Activity.nextSubLevel)
}
}
}
diff --git a/src/activities/color_mix/colormix.js b/src/activities/color_mix/colormix.js
index a087732cf..692c1e3f7 100644
--- a/src/activities/color_mix/colormix.js
+++ b/src/activities/color_mix/colormix.js
@@ -1,88 +1,88 @@
/* GCompris - colormix.js'
*
* Copyright (C) 2014 Stephane Mankowski <stephane@mankowski.fr>
*
* Authors:
* Matilda Bernard <serah4291@gmail.com> (GTK+ version)
* Stephane Mankowski <stephane@mankowski.fr> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
var url = "qrc:/gcompris/src/activities/color_mix/resource/"
var currentLevel = 0
var numberOfLevel = 6
var items
var maxSteps = 1
function start(items_) {
items = items_
currentLevel = 0
items.score.numberOfSubLevels = 6
items.score.currentSubLevel = 1
initLevel()
}
function stop() {}
function initLevel() {
items.bar.level = currentLevel + 1
/* Set max steps */
maxSteps = items.bar.level
items.maxSteps = maxSteps
/* Compute target color */
items.targetColor1 = Math.floor(Math.random() * (maxSteps + 1))
items.targetColor2 = Math.floor(Math.random() * (maxSteps + 1))
items.targetColor3 = Math.floor(Math.random() * (maxSteps + 1))
/* Reset current color */
items.currentColor1 = 0
items.currentColor2 = 0
items.currentColor3 = 0
}
function getColor(i1, i2, i3) {
return activity.modeRGB ? Qt.rgba(i1 / maxSteps, i2 / maxSteps,
i3 / maxSteps,
1) : Qt.rgba(1 - i3 / maxSteps,
1 - i1 / maxSteps,
1 - i2 / maxSteps, 1)
}
function nextSubLevel() {
if (items.score.numberOfSubLevels >= ++items.score.currentSubLevel) {
initLevel()
} else {
nextLevel()
}
}
function nextLevel() {
items.score.currentSubLevel = 1
if (numberOfLevel <= ++currentLevel) {
currentLevel = 0
}
initLevel()
}
function previousLevel() {
items.score.currentSubLevel = 1
if (--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
initLevel()
}
diff --git a/src/activities/color_mix_light/ActivityInfo.qml b/src/activities/color_mix_light/ActivityInfo.qml
index 8f4170037..8583a0d28 100644
--- a/src/activities/color_mix_light/ActivityInfo.qml
+++ b/src/activities/color_mix_light/ActivityInfo.qml
@@ -1,44 +1,43 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Stephane Mankowski <stephane@mankowski.fr>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "color_mix_light/ColorMixLight.qml"
difficulty: 4
icon: "color_mix_light/color_mix_light.svg"
author: "Stephane Mankowski &lt;stephane@mankowski.fr&gt;"
demo: true
//: Activity title
title: qsTr("Mixing colors of light")
//: Help title
description: qsTr("Discover light color mixing.")
// intro: "Match the colour by moving the sliders on the torches"
//: Help goal
goal: qsTr("Mix the primary colors to match to the given color.")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("
The activity deals with mixing primary colors of light (additive mixing).
-In case of light it is just the opposite of mixing color with paints! The more light you add the lighter the resultant color will get. Primary colors of light are red, green and blue.
- ")
+In case of light it is just the opposite of mixing color with paints! The more light you add the lighter the resultant color will get. Primary colors of light are red, green and blue.")
credit: qsTr("Images from http://openclipart.org")
section: "experiment color"
createdInVersion: 0
}
diff --git a/src/activities/color_mix_light/ColorMixLight.qml b/src/activities/color_mix_light/ColorMixLight.qml
index 423639ff1..b58b74835 100644
--- a/src/activities/color_mix_light/ColorMixLight.qml
+++ b/src/activities/color_mix_light/ColorMixLight.qml
@@ -1,27 +1,27 @@
/* GCompris - colormixlight.qml
*
* Copyright (C) 2014 Stephane Mankowski <stephane@mankowski.fr>
*
* Authors:
* Matilda Bernard <serah4291@gmail.com> (GTK+ version)
* Stephane Mankowski <stephane@mankowski.fr> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../color_mix"
ColorMix {
modeRGB: true
}
diff --git a/src/activities/colors/ActivityInfo.qml b/src/activities/colors/ActivityInfo.qml
index 7db4df665..53b89348f 100644
--- a/src/activities/colors/ActivityInfo.qml
+++ b/src/activities/colors/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "colors/Colors.qml"
difficulty: 1
icon: "colors/colors.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
//: Activity title
title: qsTr("Colors")
//: Help title
description: qsTr("Click on the right color")
// intro: "Click on the right color"
//: Help goal
goal: qsTr("This activity teaches you to recognize different colors. When you hear the name of the color, touch the duck wearing it.")
//: Help prerequisite
prerequisite: qsTr("Identifying colours")
//: Help manual
manual: qsTr("Listen to the color and touch the matching duck.")
credit: ""
section: "discovery color"
createdInVersion: 0
}
diff --git a/src/activities/colors/ColorItem.qml b/src/activities/colors/ColorItem.qml
index 12e7f988f..e5f9a50df 100644
--- a/src/activities/colors/ColorItem.qml
+++ b/src/activities/colors/ColorItem.qml
@@ -1,140 +1,140 @@
/* GCompris - ColorItem.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Pascal Georges <pascal.georges1@free.fr> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "findit.js" as Activity
import "../../core"
import GCompris 1.0
Image {
id: item
property GCAudio audioVoices
property Item bar
property string audioSrc
property string question
property bool playAudioOnError: false
function select() {
mouseArea.enabled = false
if(Activity.hasWon) {
return
}
if(question === Activity.getCurrentTextQuestion()) {
particles.burst(40)
animWin.start()
Activity.nextQuestion()
} else {
if(audioSrc && item.playAudioOnError) {
item.audioVoices.play(audioSrc)
}
crossAnim.start()
}
}
MouseArea {
id: mouseArea
anchors.fill: parent
onClicked: select()
}
SequentialAnimation {
id: anim
running: true
loops: Animation.Infinite
NumberAnimation {
target: item
property: "rotation"
from: -10; to: 10
duration: 400 + Math.floor(Math.random() * 400)
easing.type: Easing.InOutQuad
}
NumberAnimation {
target: item
property: "rotation"
from: 10; to: -10
duration: 400 + Math.floor(Math.random() * 400)
easing.type: Easing.InOutQuad
}
}
SequentialAnimation {
id: animWin
running: false
loops: 1
NumberAnimation {
target: item
property: "rotation"
from: 0; to: 360
duration: 600
easing.type: Easing.InOutQuad
}
onRunningChanged: {
if (running == false) {
mouseArea.enabled = true
}
}
}
ParticleSystemStarLoader {
id: particles
clip: false
}
Image {
id: cross
source: Activity.url + "checkError.svg"
sourceSize.width: 128 * ApplicationInfo.ratio
anchors.centerIn: parent
width: 0
height: width
opacity: 1
property int size: Math.min(parent.width, parent.height)
}
SequentialAnimation {
id: crossAnim
PropertyAnimation {
target: cross
property: "width"
duration: 300
from: 0
to: cross.size
easing.type: Easing.InOutQuad
}
PauseAnimation { duration: 800 }
PropertyAnimation {
target: cross
property: "width"
duration: 300
from: cross.size
to: 0
easing.type: Easing.InOutQuad
}
onRunningChanged: {
if (running == false) {
mouseArea.enabled = true
}
}
}
}
diff --git a/src/activities/colors/Colors.qml b/src/activities/colors/Colors.qml
index d9f8a436d..5ef006d1f 100644
--- a/src/activities/colors/Colors.qml
+++ b/src/activities/colors/Colors.qml
@@ -1,31 +1,31 @@
/* GCompris - Colors.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Original activity in the Gtk+ version of GCompris by
* Pascal Georges <pascal.georges1@free.fr>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "colors.js" as Dataset
FindIt {
mode: "Colors"
dataset: Dataset
backgroundImg: "qrc:/gcompris/src/activities/colors/resource/background.svg"
}
diff --git a/src/activities/colors/FindIt.qml b/src/activities/colors/FindIt.qml
index a2565d4b5..3fa505c0b 100644
--- a/src/activities/colors/FindIt.qml
+++ b/src/activities/colors/FindIt.qml
@@ -1,230 +1,230 @@
/* GCompris - FindIt.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Original activity in the Gtk+ version of GCompris by
* Pascal Georges (pascal.georges1@free.fr)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import QtGraphicalEffects 1.0
import GCompris 1.0
import "../../core"
import "findit.js" as Activity
ActivityBase {
id: activity
focus: true
property var dataset
property string backgroundImg
property string mode: ""
onStart: {
focus = true;
}
pageComponent: Image {
id: background
focus: true
fillMode: Image.PreserveAspectCrop
sourceSize.width: Math.max(parent.width, parent.height)
source: backgroundImg
property bool keyboardMode: false
signal start
signal stop
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
QtObject {
id: items
property alias background: background
property alias bar: bar
property alias bonus: bonus
property alias containerModel: containerModel
property alias questionItem: questionItem
// On startup we want to queue the first sound but not after
property bool firstQuestion: true
property bool audioOk: false
property alias score: score
}
onStart: Activity.start(items, dataset, mode)
onStop: Activity.stop()
Keys.onPressed: {
if(event.key === Qt.Key_Space) {
container.currentItem.select()
}
}
Keys.onReleased: {
keyboardMode = true
event.accepted = false
}
Keys.onEnterPressed: container.currentItem.select();
Keys.onReturnPressed: container.currentItem.select();
Keys.onRightPressed: container.moveCurrentIndexRight();
Keys.onLeftPressed: container.moveCurrentIndexLeft();
Keys.onDownPressed: container.moveCurrentIndexDown();
Keys.onUpPressed: container.moveCurrentIndexUp();
ListModel {
id: containerModel
}
GridView {
id: container
model: containerModel
x: background.width * 0.2
y: background.height * 0.2
width: background.width * 0.7
height: background.height * 0.6
interactive: false
cellWidth: itemHeight + 10
cellHeight: itemWidth + 10
keyNavigationWraps: true
property int itemWidth: Math.min((parent.width * 0.6) / (count / 2),
(parent.height * 0.5) / (count / 3))
property int itemHeight: itemWidth
delegate: ColorItem {
audioVoices: activity.audioVoices
source: model.image
audioSrc: model.audio ? model.audio : ""
question: model.text
sourceSize.height: container.itemHeight
sourceSize.width: container.itemWidth
}
add: Transition {
PathAnimation {
path: Path {
PathCurve { x: background.width / 3}
PathCurve { y: background.height / 3}
PathCurve {}
}
easing.type: Easing.InOutQuad
duration: 2000
}
}
highlight: Rectangle {
width: container.cellWidth - container.spacing
height: container.cellHeight - container.spacing
color: "#AAFFFFFF"
border.width: 3
border.color: "black"
visible: background.keyboardMode
Behavior on x { SpringAnimation { spring: 2; damping: 0.2 } }
Behavior on y { SpringAnimation { spring: 2; damping: 0.2 } }
}
}
GCText {
id: questionItem
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
anchors.topMargin: 10
fontSize: largeSize
width: parent.width * 0.9
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.WordWrap
font.weight: Font.DemiBold
style: Text.Outline
styleColor: "black"
color: "white"
function initQuestion() {
text = Activity.getCurrentTextQuestion()
if(Activity.getCurrentAudioQuestion()) {
if(items.firstQuestion)
items.audioOk = activity.audioVoices.append(Activity.getCurrentAudioQuestion())
else
items.audioOk = activity.audioVoices.play(Activity.getCurrentAudioQuestion())
items.firstQuestion = false
}
opacity = 1.0
}
onOpacityChanged: opacity == 0 ? initQuestion() : ""
Behavior on opacity { PropertyAnimation { duration: 500 } }
}
DropShadow {
anchors.fill: questionItem
cached: false
horizontalOffset: 3
verticalOffset: 3
radius: 8.0
samples: 16
color: "#80000000"
source: questionItem
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level }
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
}
BarButton {
id: repeatItem
source: "qrc:/gcompris/src/core/resource/bar_repeat.svg";
sourceSize.height: visible ? 80 * ApplicationInfo.ratio : 1
z: bar.z + 1
visible: items.audioOk
anchors {
bottom: bar.top
right: parent.right
margins: 10 * ApplicationInfo.ratio
}
onClicked: if (ApplicationSettings.isAudioVoicesEnabled)
questionItem.initQuestion()
}
Score {
id: score
anchors.bottom: bar.top
anchors.right: bar.right
anchors.left: parent.left
anchors.bottomMargin: 10 * ApplicationInfo.ratio
anchors.leftMargin: 10 * ApplicationInfo.ratio
anchors.rightMargin: 0
}
Bonus {
id: bonus
interval: 2000
Component.onCompleted: win.connect(Activity.nextLevel)
}
}
}
diff --git a/src/activities/colors/colors.js b/src/activities/colors/colors.js
index 52954988a..d4a14dfa3 100644
--- a/src/activities/colors/colors.js
+++ b/src/activities/colors/colors.js
@@ -1,138 +1,138 @@
/* GCompris - colors.js
*
* Copyright (C) 2015 Bruno Coudoin
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
function get() {
return [
[ // Level 1
{
"image": "qrc:/gcompris/src/activities/colors/resource/yellow_duck.svg",
"text": qsTr("Find the yellow duck"),
"audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/yellow.$CA")
},
{
"image": "qrc:/gcompris/src/activities/colors/resource/black_duck.svg",
"text": qsTr("Find the black duck"),
"audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/black.$CA")
},
{
"image": "qrc:/gcompris/src/activities/colors/resource/green_duck.svg",
"text": qsTr("Find the green duck"),
"audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/green.$CA")
},
{
"image": "qrc:/gcompris/src/activities/colors/resource/red_duck.svg",
"text": qsTr("Find the red duck"),
"audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/red.$CA")
},
{
"image": "qrc:/gcompris/src/activities/colors/resource/white_duck.svg",
"text": qsTr("Find the white duck"),
"audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/white.$CA")
},
{
"image": "qrc:/gcompris/src/activities/colors/resource/blue_duck.svg",
"text": qsTr("Find the blue duck"),
"audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/blue.$CA")
}
],
[ // Level 2
{
"image": "qrc:/gcompris/src/activities/colors/resource/yellow_duck.svg",
"text": qsTr("Find the yellow duck"),
"audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/yellow.$CA")
},
{
"image": "qrc:/gcompris/src/activities/colors/resource/black_duck.svg",
"text": qsTr("Find the black duck"),
"audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/black.$CA")
},
{
"image": "qrc:/gcompris/src/activities/colors/resource/brown_duck.svg",
"text": qsTr("Find the brown duck"),
"audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/brown.$CA")
},
{
"image": "qrc:/gcompris/src/activities/colors/resource/green_duck.svg",
"text": qsTr("Find the green duck"),
"audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/green.$CA")
},
{
"image": "qrc:/gcompris/src/activities/colors/resource/grey_duck.svg",
"text": qsTr("Find the grey duck"),
"audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/grey.$CA")
},
{
"image": "qrc:/gcompris/src/activities/colors/resource/orange_duck.svg",
"text": qsTr("Find the orange duck"),
"audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/orange.$CA")
},
{
"image": "qrc:/gcompris/src/activities/colors/resource/purple_duck.svg",
"text": qsTr("Find the purple duck"),
"audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/purple.$CA")
},
{
"image": "qrc:/gcompris/src/activities/colors/resource/white_duck.svg",
"text": qsTr("Find the white duck"),
"audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/white.$CA")
}
],
[ // Level 3
{
"image": "qrc:/gcompris/src/activities/colors/resource/yellow_duck.svg",
"text": qsTr("Find the yellow duck"),
"audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/yellow.$CA")
},
{
"image": "qrc:/gcompris/src/activities/colors/resource/brown_duck.svg",
"text": qsTr("Find the brown duck"),
"audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/brown.$CA")
},
{
"image": "qrc:/gcompris/src/activities/colors/resource/green_duck.svg",
"text": qsTr("Find the green duck"),
"audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/green.$CA")
},
{
"image": "qrc:/gcompris/src/activities/colors/resource/grey_duck.svg",
"text": qsTr("Find the grey duck"),
"audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/grey.$CA")
},
{
"image": "qrc:/gcompris/src/activities/colors/resource/orange_duck.svg",
"text": qsTr("Find the orange duck"),
"audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/orange.$CA")
},
{
"image": "qrc:/gcompris/src/activities/colors/resource/purple_duck.svg",
"text": qsTr("Find the purple duck"),
"audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/purple.$CA")
},
{
"image": "qrc:/gcompris/src/activities/colors/resource/pink_duck.svg",
"text": qsTr("Find the pink duck"),
"audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/pink.$CA")
},
{
"image": "qrc:/gcompris/src/activities/colors/resource/blue_duck.svg",
"text": qsTr("Find the blue duck"),
"audio": ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/colors/blue.$CA")
}
]
];
}
diff --git a/src/activities/colors/findit.js b/src/activities/colors/findit.js
index da38b3f59..3a04b650a 100644
--- a/src/activities/colors/findit.js
+++ b/src/activities/colors/findit.js
@@ -1,109 +1,109 @@
/* GCompris - findit.js
*
* Copyright (C) 2015 Bruno Coudoin
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
.import "qrc:/gcompris/src/core/core.js" as Core
var url = "qrc:/gcompris/src/activities/colors/resource/"
var currentLevel
var numberOfLevel
var items
var dataset
var currentQuestion
var hasWon
function start(items_, dataset_, mode_) {
- if (mode_ == "Colors")
+ if (mode_ === "Colors")
Core.checkForVoices(items_.background);
items = items_
dataset = dataset_.get()
currentLevel = 0
numberOfLevel = dataset.length
items.firstQuestion = true
items.audioOk = false
items.score.currentSubLevel = 1
initLevel()
}
function stop() {
}
function initLevel() {
items.bar.level = currentLevel + 1
items.containerModel.clear()
currentQuestion = 0
dataset[currentLevel] = Core.shuffle(dataset[currentLevel])
for(var i = 0; i < dataset[currentLevel].length; ++i) {
items.containerModel.append(dataset[currentLevel][i])
}
items.score.numberOfSubLevels = dataset[currentLevel].length
// Shuffle again not to ask the question in the model order
dataset[currentLevel] = Core.shuffle(dataset[currentLevel])
hasWon = false
initQuestion()
}
function initQuestion() {
// We just set the opacity to 0, the questionItem will then grab
// the new question by itself
// Need to set opacity to 0.1 before in order to be sure it's changed and trigger the questionItem onOpacityChanged
items.questionItem.opacity = 0.1
items.questionItem.opacity = 0
}
function nextQuestion() {
if(dataset[currentLevel].length <= currentQuestion + 1) {
items.bonus.good("flower")
hasWon = true
} else {
currentQuestion++
items.score.currentSubLevel++
initQuestion()
}
}
function nextLevel() {
items.score.currentSubLevel = 1
if(numberOfLevel <= ++currentLevel) {
currentLevel = 0
}
initLevel();
}
function previousLevel() {
items.score.currentSubLevel = 1
if(--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
initLevel();
}
function getCurrentTextQuestion() {
return dataset[currentLevel][currentQuestion].text
}
function getCurrentAudioQuestion() {
return dataset[currentLevel][currentQuestion].audio
}
diff --git a/src/activities/crane/ActivityInfo.qml b/src/activities/crane/ActivityInfo.qml
index c857280e2..a6d587f31 100644
--- a/src/activities/crane/ActivityInfo.qml
+++ b/src/activities/crane/ActivityInfo.qml
@@ -1,45 +1,45 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2016 Stefan Toncu <stefan.toncu29@gmail.com>
*
* Authors:
* <Marc BRUN> (GTK+ version)
* Stefan Toncu <stefan.toncu29@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "crane/Crane.qml"
difficulty: 2
icon: "crane/crane.svg"
author: "Stefan Toncu &lt;stefan.toncu29@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Build the same model")
//: Help title
description: qsTr("Drive the crane and copy the model")
//intro: " Click on each item in turn, in the left frame, and move them to reproduce the pattern from the right frame."
//: Help goal
goal: qsTr("Motor-coordination")
//: Help prerequisite
prerequisite: qsTr("Mouse/keyboard manipulation")
//: Help manual
manual: qsTr("Move the items in the left frame to copy their position in the right model. Next to the crane itself, you will find four arrows that let you move the items. To select the item to move, just click on it. If you prefer, you can use the arrow keys and the space or tab key instead. On a mobile version, you can also swipe up/down/left/right to move the items in the left frame.")
credit: ""
section: "puzzle"
createdInVersion: 7000
}
diff --git a/src/activities/crane/Controls.qml b/src/activities/crane/Controls.qml
index dfcf4fdb7..91d028e9a 100644
--- a/src/activities/crane/Controls.qml
+++ b/src/activities/crane/Controls.qml
@@ -1,43 +1,43 @@
/* GCompris - Controls.qml
*
* Copyright (C) 2016 Stefan Toncu <stefan.toncu29@gmail.com>
*
* Authors:
* <Marc BRUN> (GTK+ version)
* Stefan Toncu <stefan.toncu29@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "crane.js" as Activity
Image {
property string command
sourceSize.width: background.portrait ? parent.width * 0.175 : parent.width * 0.17
sourceSize.height: background.portrait ? parent.height * 0.6 : parent.height * 0.48
width: background.portrait ? parent.width * 0.175 : parent.width * 0.17
height: background.portrait ? parent.height * 0.6 : parent.height * 0.48
anchors {
verticalCenter: parent.verticalCenter
}
MouseArea {
anchors.fill: parent
onPressed: parent.opacity = 0.6
onReleased: parent.opacity = 1
onClicked: {
Activity.move(command)
}
}
}
diff --git a/src/activities/crane/Crane.qml b/src/activities/crane/Crane.qml
index e780d281c..76e87bcc4 100644
--- a/src/activities/crane/Crane.qml
+++ b/src/activities/crane/Crane.qml
@@ -1,486 +1,486 @@
/* GCompris - Crane.qml
*
* Copyright (C) 2016 Stefan Toncu <stefan.toncu29@gmail.com>
*
* Authors:
* <Marc BRUN> (GTK+ version)
* Stefan Toncu <stefan.toncu29@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import QtGraphicalEffects 1.0
import GCompris 1.0
import "../../core"
import "crane.js" as Activity
ActivityBase {
id: activity
// Overload this in your activity to change it
// Put you default-<locale>.json files in it
property string dataSetUrl: "qrc:/gcompris/src/activities/crane/resource/"
onStart: focus = true
onStop: {}
pageComponent: Image {
id: background
source: activity.dataSetUrl+"background.svg"
fillMode: Image.PreserveAspectCrop
anchors.fill: parent
sourceSize.width: Math.max(parent.width, parent.height)
signal start
signal stop
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property alias background: background
property alias bar: bar
property alias bonus: bonus
property alias board: board
property alias grid: grid
property alias repeater: repeater
property alias modelRepeater: modelRepeater
property alias gridRepeater: gridRepeater
property alias showGrid1: showGrid1
property int selected
property int columns
property int rows
property bool ok: true
property int sensivity: 80
property bool gameFinished: false
property bool pieceIsMoving: false
}
onStart: { Activity.start(items) }
onStop: { Activity.stop() }
- property bool portrait: height > width ? true : false
+ property bool portrait: height >= width ? true : false
property bool inLine: true
Keys.onPressed: {
if (event.key === Qt.Key_Left){
Activity.move("left")
left.opacity = 0.6
}
else if (event.key === Qt.Key_Right){
Activity.move("right")
right.opacity = 0.6
}
else if (event.key === Qt.Key_Up){
Activity.move("up")
up.opacity = 0.6
}
else if (event.key === Qt.Key_Down){
Activity.move("down")
down.opacity = 0.6
}
else if (event.key === Qt.Key_Space ||
event.key === Qt.Key_Tab ||
event.key === Qt.Key_Enter ||
event.key === Qt.Key_Return)
Activity.move("next")
}
Keys.onReleased: {
up.opacity = 1
down.opacity = 1
left.opacity = 1
right.opacity = 1
}
//implementation of Swipe effect
MouseArea {
anchors.fill: parent
property int startX;
property int startY;
onPressed: {
startX = mouse.x;
startY = mouse.y;
}
onReleased: Activity.gesture(mouse.x - startX, mouse.y - startY)
}
Rectangle {
id: board
color: "#b9e2f0"
radius: width * 0.03
border.color: "#77c0d9"
border.width: width * 0.02
z: 1
clip: true
anchors {
verticalCenter: crane_vertical.verticalCenter
right: crane_vertical.left
margins: 15
}
width: background.portrait ? parent.width * 0.65 : ((parent.width - anchors.margins * 3 - crane_vertical.width) / 2 ) * 0.9
height: background.portrait ? (parent.height - bar.height * 1.45 - crane_top.height - crane_body.height ) / 2 :
(parent.height - bar.height * 1.45 - crane_top.height - crane_body.height) * 0.9
}
Grid {
id: showGrid1
columns: items.columns
rows: items.rows
z: 1
anchors.fill: board
layer.enabled: ApplicationInfo.useOpenGL
layer.effect: OpacityMask {
maskSource: board
}
Repeater {
id: gridRepeater
Rectangle {
width: board.width/items.columns
height: board.height/items.rows
color: "transparent"
border.width: 2
border.color: "#77c0d9"
}
}
}
Grid {
id: grid
columns: items.columns
rows: items.rows
z: 4
anchors.fill: board
Repeater {
id: repeater
Image {
id: figure
sourceSize.height: board.width/items.columns
sourceSize.width: board.height/items.rows
width: board.width/items.columns
height: board.height/items.rows
property int initialIndex: -1
property alias anim: anim
property int distance
property int indexChange
property int startPoint
property string animationProperty
property int _index: index // make current index accessible from outside
SequentialAnimation {
id: anim
PropertyAction { target: items; property: "ok"; value: "false"}
NumberAnimation { target: figure; property: figure.animationProperty; from: figure.startPoint; to: figure.startPoint + distance; duration: 200 }
PropertyAction { target: figure; property: "opacity"; value: 0 }
NumberAnimation { target: figure; property: figure.animationProperty; from: figure.startPoint + distance; to: figure.startPoint; duration: 0; }
PropertyAction { target: figure; property: "opacity"; value: 1 }
PropertyAction { target: items.repeater.itemAt(items.selected + indexChange); property: "source"; value: figure.source }
PropertyAction { target: items.repeater.itemAt(items.selected + indexChange); property: "initialIndex"; value: figure.initialIndex }
PropertyAction { target: figure; property: "initialIndex"; value: -1 }
PropertyAction { target: figure; property: "source"; value: "" }
PropertyAction { target: items; property: "ok"; value: "true"}
PropertyAction { target: items; property: "pieceIsMoving"; value: "false"}
ScriptAction { script: Activity.checkAnswer() }
}
MouseArea {
anchors.fill: parent
// Swipe effect
property int startX;
property int startY;
onPressed: {
startX = mouse.x;
startY = mouse.y;
}
onReleased:
Activity.gesture(mouse.x - startX, mouse.y - startY)
// Select a figure with mouse/touch
onClicked: {
if (source != "" && !items.pieceIsMoving)
items.selected = index
}
}
}
}
}
Image {
id: selected
source: activity.dataSetUrl+"selected.svg"
sourceSize.width: board.width/items.columns
sourceSize.height: board.height/items.rows
width: board.width/items.columns
height: board.height/items.rows
opacity: 1
property var newCoord: items.selected == 0 ? grid :
items.repeater.mapToItem(background,items.repeater.itemAt(items.selected).x,
items.repeater.itemAt(items.selected).y)
x: newCoord.x
y: newCoord.y
z: 100
Behavior on x { NumberAnimation { duration: 200 } }
Behavior on y { NumberAnimation { duration: 200 } }
}
Rectangle {
id: modelBoard
color: "#f0b9d2"
radius: width * 0.03
border.color: "#e294b7"
border.width: width * 0.02
z: 1
anchors {
left: background.portrait ? board.left : crane_vertical.right
top: background.portrait ? crane_body.bottom : background.inLine ? board.top : parent.top
topMargin: background.portrait ? board.anchors.margins : background.inLine ? 0 : crane_top.height * 1.5
leftMargin: background.portrait ? 0 : board.anchors.margins * 1.2
margins: board.anchors.margins
}
width: board.width
height: board.height
}
Grid {
id: modelGrid
columns: items.columns
rows: items.rows
anchors.fill: modelBoard
z: 4
Repeater {
id: modelRepeater
Image {
id: modelFigure
sourceSize.height: board.height/items.rows
sourceSize.width: board.width/items.columns
width: board.width/items.columns
height: board.height/items.rows
}
}
}
Grid {
id: showGrid2
columns: items.columns
rows: items.rows
z: 1
opacity: showGrid1.opacity
anchors.fill: modelBoard
layer.enabled: ApplicationInfo.useOpenGL
layer.effect: OpacityMask {
maskSource: modelBoard
}
Repeater {
id: gridRepeater2
model: gridRepeater.model
Rectangle {
width: modelBoard.width/items.columns
height: modelBoard.height/items.rows
color: "transparent"
border.width: 2
border.color: showGrid1.opacity == 1 ? "#e294b7" : "transparent"
}
}
}
Image {
id: crane_top
source: activity.dataSetUrl+"crane_up.svg"
sourceSize.width: background.portrait ? background.width * 0.8 : background.width * 0.5
width: background.portrait ? background.width * 0.8 : background.width * 0.5
fillMode: Image.PreserveAspectFit
z: 4
anchors {
top: parent.top
right: crane_vertical.right
rightMargin: 0
margins: board.anchors.margins
}
}
Image {
id: crane_vertical
source: activity.dataSetUrl+"crane_vertical.svg"
sourceSize.height: background.portrait ? background.height * 0.5 : background.height * 0.73
height: background.portrait ? background.height * 0.5 : background.height * 0.73
fillMode: Image.PreserveAspectFit
anchors {
top: crane_top.top
right: background.portrait ? parent.right : parent.horizontalCenter
rightMargin: background.portrait ? width / 2 : - width / 2
topMargin: board.anchors.margins
}
}
Image {
id: crane_body
source: activity.dataSetUrl+"crane_only.svg"
z: 2
sourceSize.width: parent.width / 5
sourceSize.height: parent.height/ 3.6
mirror: background.portrait ? true : false
anchors {
top: crane_vertical.bottom
topMargin: - (height / 1.8)
right: crane_vertical.right
rightMargin: background.portrait ? board.anchors.margins : - crane_body.width + crane_vertical.width
margins: board.anchors.margins
}
}
Image {
id: crane_wire
source: activity.dataSetUrl+"crane-wire.svg"
z: 1
sourceSize.width: parent.width / 22
sourceSize.height: parent.width / 17
anchors {
right: crane_body.left
bottom: crane_command.verticalCenter
rightMargin: -10
bottomMargin: -10
}
}
Image {
id: crane_command
source: activity.dataSetUrl+"command.svg"
sourceSize.width: background.portrait ? parent.width / 2.7 : parent.width / 3.5
sourceSize.height: background.portrait ? parent.height / 3.5 : parent.height / 4
width: background.portrait ? parent.width / 2.7 : parent.width / 3.5
height: background.portrait ? parent.height / 3.5 : parent.height / 4
anchors {
top: crane_body.top
bottom: crane_body.bottom
right: crane_wire.left
rightMargin: 0
topMargin: background.portrait ? 0 : board.anchors.margins * 1.5
bottomMargin: background.portrait ? 0 : board.anchors.margins * 1.5
}
Controls {
id: up
source: activity.dataSetUrl+"arrow_up.svg"
anchors {
left: parent.left
leftMargin: parent.width / 11
}
command: "up"
}
Controls {
id: down
source: activity.dataSetUrl+"arrow_down.svg"
anchors {
left: up.right
leftMargin: parent.width / 30
}
command: "down"
}
Controls {
id: left
source: activity.dataSetUrl+"arrow_left.svg"
anchors {
right: right.left
rightMargin: parent.width / 30
}
command: "left"
}
Controls {
id: right
source: activity.dataSetUrl+"arrow_right.svg"
anchors {
right: parent.right
rightMargin: parent.width / 11
}
command: "right"
}
}
Rectangle {
id: cable
color: "#373737"
width: 5
height: convert.y - crane_top.y
x: convert.x + board.width / items.columns / 2
z: 3
anchors.top: crane_top.top
anchors.topMargin: 10
property var convert: items.selected == 0 ? grid :
items.repeater.mapToItem(background,items.repeater.itemAt(items.selected).x,
items.repeater.itemAt(items.selected).y)
Behavior on x { NumberAnimation { duration: 200 } }
Behavior on height { NumberAnimation { duration: 200 } }
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level }
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
}
Bonus {
id: bonus
Component.onCompleted: win.connect(Activity.nextLevel)
}
}
}
diff --git a/src/activities/crane/crane.js b/src/activities/crane/crane.js
index f93cdc23f..7fe999c0c 100644
--- a/src/activities/crane/crane.js
+++ b/src/activities/crane/crane.js
@@ -1,407 +1,407 @@
/* GCompris - crane.js
*
* Copyright (C) 2016 Stefan Toncu <stefan.toncu29@gmail.com>
*
* Authors:
* <Marc BRUN> (GTK+ version)
* Stefan Toncu <stefan.toncu29@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
.import "qrc:/gcompris/src/core/core.js" as Core
.import GCompris 1.0 as GCompris
var levels = [{showGrid: 1, noOfItems: 2, inLine: true, columns: 4, rows: 3 },
{showGrid: 1, noOfItems: 3, inLine: true, columns: 5, rows: 4 },
{showGrid: 1, noOfItems: 4, inLine: true, columns: 6, rows: 5 },
{showGrid: 0, noOfItems: 5, inLine: false, columns: 7, rows: 6 },
{showGrid: 0, noOfItems: 6, inLine: false, columns: 7, rows: 6 },
{showGrid: 1, noOfItems: 7, inLine: true, columns: 7, rows: 6 },
{showGrid: 1, noOfItems: 8, inLine: true, columns: 7, rows: 6 },
{showGrid: 0, noOfItems: 9, inLine: false, columns: 7, rows: 6 },
{showGrid: 0, noOfItems: 10, inLine: false, columns: 7, rows: 6 },
{showGrid: 0, noOfItems: 11, inLine: false, columns: 7, rows: 6 }]
var currentLevel = 0
var numberLevelsWords = 2
var maxWordLevels = 3 * numberLevelsWords
var maxImageLevels = levels.length
var numberOfLevel = maxWordLevels + maxImageLevels
var items
var url = "qrc:/gcompris/src/activities/crane/resource/"
var allNames = ["bulb.svg","letter-a.svg","letter-b.svg",
"rectangle1.svg","rectangle2.svg","square1.svg",
"square2.svg","triangle1.svg","triangle2.svg",
"tux.svg","water_drop1.svg","water_drop2.svg",
"water_spot1.svg","water_spot2.svg"]
var currentLocale
var words3Letters = []
var words4Letters = []
var words5Letters = []
var alreadyUsed3 = []
var alreadyUsed4 = []
var alreadyUsed5 = []
var names = []
var names2 = []
var good = []
function start(items_) {
items = items_
currentLevel = 0
currentLocale = GCompris.ApplicationInfo.getVoicesLocale(GCompris.ApplicationSettings.locale)
/*: Translators: NOTE: Word list for crane activity.
Translate this into a list of 15–25 simple 3-letter
words separated by semi-colons. The words can only contain
lowercase ASCII letters (a–z). Example: cat;dog;win;red;yes
*/
words3Letters = qsTr("cat;dog;win;red;yes;big;box;air;arm;car;bus;fun;day;eat;hat;leg;ice;old;egg").split(';')
/*: Translators: NOTE: Word list for crane activity.
Translate this into a list of 10–20 simple 4-letter
words separated by semi-colons. The words can only contain
lowercase ASCII letters (a–z). Example: blue;best;good;area
*/
words4Letters = qsTr("blue;best;good;area;bell;coat;easy;farm;food;else;girl;give;hero;help;hour;sand;song").split(';')
/*: Translators: NOTE: Word list for crane activity.
Translate this into a list of 10–20 simple 5-letter
words separated by semi-colons. The words can only contain
lowercase ASCII letters (a–z). Example: happy;child;white;apple
*/
words5Letters = qsTr("happy;child;white;apple;brown;truth;fresh;green;horse;hotel;house;paper;shape;shirt;study").split(';')
alreadyUsed3 = []
alreadyUsed4 = []
alreadyUsed5 = []
initLevel()
}
function stop() {
}
function initLevel() {
items.bar.level = currentLevel + 1
Core.shuffle(words3Letters)
Core.shuffle(words4Letters)
Core.shuffle(words5Letters)
init()
}
function init() {
// reset the arrays
names = []
names2 = []
// set models for repeaters
if (currentLevel >= maxWordLevels)
setRandomModelImage()
else
setRandomModelWord()
items.gameFinished = false
// set "initialIndex" to the position in the repeater
for(var i = 0; i < names.length; i++) {
if (items.repeater.itemAt(i).source != "") {
items.repeater.itemAt(i).initialIndex = i
good[i] = i
}
else {
// set the initialIndex to -1 if there is no item inside (no source)
items.repeater.itemAt(i).initialIndex = -1
good[i] = -1
}
}
// select the first item in the grid
for(i = 0; i < items.repeater.count; i++) {
if (items.repeater.itemAt(i).source != "") {
items.selected = i
break
}
}
}
function getNextUnusedWord(wordsUsed, alreadyUsed) {
var currentIndex = Math.floor(Math.random() * wordsUsed.length)
while(alreadyUsed.indexOf(wordsUsed[currentIndex]) >= 0) {
// there are no more words to use => clear the "alreadyUsed" vector
if (alreadyUsed.length == wordsUsed.length)
alreadyUsed = []
// get another random index
currentIndex = Math.floor(Math.random() * wordsUsed.length)
}
// add the word in the "alreadyUsed" vector
alreadyUsed = alreadyUsed.concat(wordsUsed[currentIndex])
return wordsUsed[currentIndex]
}
// levels with words as items
function setRandomModelWord() {
var numbers = []
var i
var wordsUsed
if (currentLevel < numberLevelsWords) {
wordsUsed = words3Letters
// show or hide the grid
items.showGrid1.opacity = 1
// set the two boards in line or not
items.background.inLine = true
}
else if (currentLevel < numberLevelsWords * 2) {
wordsUsed = words4Letters
// show or hide the grid
items.showGrid1.opacity = 1
// set the two boards in line or not
items.background.inLine = false
}
else {
wordsUsed = words5Letters
// show or hide the grid
items.showGrid1.opacity = 0
// set the two boards in line or not
items.background.inLine = false
}
// take the first word and keep its length
var currentWordsLength = wordsUsed[0].length;
// set the number of columns and rows, be sure we have enough space to display the word
items.columns = currentWordsLength + 1
items.rows = currentWordsLength
for (i = 0; i < items.columns * items.rows; i++) {
names[i] = ""
names2[i] = ""
numbers[i] = i; // generate columns*rows numbers
}
// before: // var currentIndex = currentLevel % numberLevelsWords
// get a random word
var word
// use vectors to store the words already used
if (currentWordsLength == 3) {
word = getNextUnusedWord(wordsUsed, alreadyUsed3);
}
else if (currentWordsLength == 4) {
word = getNextUnusedWord(wordsUsed, alreadyUsed4);
}
else if (currentWordsLength == 5) {
word = getNextUnusedWord(wordsUsed, alreadyUsed5);
}
// place the word at a random position in the grid
var randomRow = Math.floor(Math.random() * items.rows)
var randomCol = Math.floor(Math.random() * items.columns)
// check if the word goes out of the frame and replace to left it if needed
if (items.columns - randomCol - word.length < 0)
randomCol = randomCol - Math.abs(items.columns - randomCol - word.length)
// set full path (url) to the letter image
var index = 0;
for (i = 0; i < word.length; i++) {
index = randomRow * items.columns + randomCol + i
names[index] = url + "letters/" + word.charAt(i) + ".svg"
names2[index] = names[index]
}
Core.shuffle(names)
// set model for repeaters
items.repeater.model = names.length
items.modelRepeater.model = names2.length
items.gridRepeater.model = names.length
// set the source of items inside repeaters to names and names2
for (i = 0; i < names.length; i++) {
items.repeater.itemAt(i).source = names[i]
items.modelRepeater.itemAt(i).source = names2[i]
}
}
// levels with images as items
function setRandomModelImage() {
var numbers = []
var i
// set the number of columns and rows from "levels"
items.columns = levels[currentLevel - maxWordLevels].columns
items.rows = levels[currentLevel - maxWordLevels].rows
for (i = 0; i < items.columns * items.rows; i++) {
names[i] = ""
names2[i] = ""
numbers[i] = i; // generate columns*rows numbers
}
// randomize the names
Core.shuffle(allNames)
//get "levels[currentLevel].noOfItems" random numbers
Core.shuffle(numbers)
for (i = 0; i < levels[currentLevel - maxWordLevels].noOfItems; i++)
names[numbers[i]] = url + allNames[i]
Core.shuffle(numbers)
for (i = 0; i < levels[currentLevel - maxWordLevels].noOfItems; i++)
names2[numbers[i]] = url + allNames[i]
// set model for repeaters
items.repeater.model = names.length
items.modelRepeater.model = names2.length
items.gridRepeater.model = names.length
// set the source of items inside repeaters to names and names2
for (i = 0; i < names.length; i++) {
items.repeater.itemAt(i).source = names[i]
items.modelRepeater.itemAt(i).source = names2[i]
}
// show or hide the grid
items.showGrid1.opacity = levels[currentLevel - maxWordLevels].showGrid
// set the two boards in line or not
items.background.inLine = levels[currentLevel - maxWordLevels].inLine
}
// returns the next index needed for switching to another item
function getNextIndex() {
// get the initialIndex
var index = items.repeater.itemAt(items.selected).initialIndex
var min = 100
var min2 = 100
var biggerIndex = -1
var smallestIndex = -1
for (var i = 0; i < items.repeater.count; i++) {
var currentItemIndex = items.repeater.itemAt(i).initialIndex
// get the immediat bigger index
if (index < currentItemIndex) {
if (min > currentItemIndex) {
// update min and index
min = currentItemIndex
biggerIndex = i
}
}
// in case current index is the biggest, search the smallest index from start
if (currentItemIndex >= 0 && min2 > currentItemIndex) {
min2 = currentItemIndex
smallestIndex = i
}
}
// if a bigger index was found, return it
if (biggerIndex != -1)
return biggerIndex
// this is the biggest index; the next one is the smallest in the array
return smallestIndex
}
//touchscreen gestures
function gesture(deltax, deltay) {
if (Math.abs(deltax) > 40 || Math.abs(deltay) > 40)
if (deltax > 30 && Math.abs(deltay) < items.sensivity)
move("right")
else if (deltax < -30 && Math.abs(deltay) < items.sensivity)
move("left")
else if (Math.abs(deltax) < items.sensivity && deltay > 30)
move("down")
else if (Math.abs(deltax) < items.sensivity && deltay < 30)
move("up")
}
//depending on the command, make a move to left/right/up/down or select next item
function move(command) {
if (items.ok && !items.gameFinished && !items.pieceIsMoving) {
var item = items.repeater.itemAt(items.selected)
if (command === "left") {
if (items.selected % items.columns != 0)
makeMove(item, -item.width, item.x, -1, "x")
} else if (command === "right") {
if ((items.selected+1) % items.columns != 0)
makeMove(item, item.width, item.x, 1, "x")
} else if (command === "up") {
if (items.selected > items.columns-1)
makeMove(item, -item.height, item.y, -items.columns, "y")
} else if (command === "down") {
if (items.selected < (items.repeater.count-items.columns))
makeMove(item, item.height, item.y, items.columns, "y")
} else if (command === "next") {
items.selected = getNextIndex()
}
}
}
//set the environment for making a move and start the animation
function makeMove(item, distance, startPoint, add, animationProperty) {
if (items.repeater.itemAt(items.selected+add).source == "") {
items.pieceIsMoving = true
//setup the animation
item.distance = distance
item.indexChange = add
item.startPoint = startPoint
item.animationProperty = animationProperty
//start the animation
item.anim.start()
//update the selected item
items.selected += add;
}
}
//check the answer; advance to next level if the answer is good
function checkAnswer() {
var hasWon = true
for (var i = 0; i < items.repeater.count && hasWon; i++) {
if (items.repeater.itemAt(i).source != items.modelRepeater.itemAt(i).source) {
hasWon = false
}
}
if (hasWon) {
items.bonus.good("flower")
items.gameFinished = true
}
}
function nextLevel() {
if(numberOfLevel <= ++currentLevel) {
currentLevel = 0
}
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
initLevel();
}
diff --git a/src/activities/details/ActivityInfo.qml b/src/activities/details/ActivityInfo.qml
index 5209b0b27..3e74e1818 100644
--- a/src/activities/details/ActivityInfo.qml
+++ b/src/activities/details/ActivityInfo.qml
@@ -1,43 +1,43 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Pulkit Gupta <pulkitgenius@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "details/Details.qml"
difficulty: 1
icon: "details/details.svg"
author: "Pulkit Gupta &lt;pulkitgenius@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Find the details")
//: Help title
description: qsTr("Drag and Drop the shapes on their respective targets")
// intro: "Slide the images on their respective targets"
//: Help goal
goal: ""
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("Complete the puzzle by dragging each piece from the set of pieces on the left, to the matching space in the puzzle.")
credit: qsTr("The images are from Wikimedia Commons.")
section: "discovery"
createdInVersion: 4000
}
diff --git a/src/activities/details/Details.qml b/src/activities/details/Details.qml
index f8e7f3a98..416e826b9 100644
--- a/src/activities/details/Details.qml
+++ b/src/activities/details/Details.qml
@@ -1,36 +1,36 @@
/* GCompris - Details.qml
*
* Copyright (C) 2015 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Bruno Coudoin (bruno.coudoin@gcompris.net) / Andre Connes (andre.connes@toulouse.iufm.fr) (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../babymatch"
Babymatch {
id: activity
onStart: focus = true
onStop: {}
boardsUrl: "qrc:/gcompris/src/activities/details/resource/"
answerGlow: false
levelCount: 21
displayDropCircle: false
}
diff --git a/src/activities/details/resource/board/board10_0.qml b/src/activities/details/resource/board/board10_0.qml
index b6d927d70..6f4e8018e 100644
--- a/src/activities/details/resource/board/board10_0.qml
+++ b/src/activities/details/resource/board/board10_0.qml
@@ -1,44 +1,44 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Eilean Donan castle")
property var levels: [
{
"pixmapfile" : "image/EilanDonanCastle_background.jpg",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "image/EilanDonanCastle_0.png",
"x" : "0.566",
"y" : "0.327",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/EilanDonanCastle_1.png",
"x" : "0.825",
"y" : "0.174",
"dropAreaSize" : "8"
}
]
}
diff --git a/src/activities/details/resource/board/board11_0.qml b/src/activities/details/resource/board/board11_0.qml
index 92f43a8e7..cc2769d31 100644
--- a/src/activities/details/resource/board/board11_0.qml
+++ b/src/activities/details/resource/board/board11_0.qml
@@ -1,56 +1,56 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Gizah Pyramids, Egypt")
property var levels: [
{
"pixmapfile" : "image/GizahPyramids_background.jpg",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "image/GizahPyramids_0.png",
"x" : "0.754",
"y" : "0.498",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/GizahPyramids_1.png",
"x" : "0.585",
"y" : "0.365",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/GizahPyramids_2.png",
"x" : "0.41",
"y" : "0.604",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/GizahPyramids_3.png",
"x" : "0.891",
"y" : "0.71",
"dropAreaSize" : "8"
}
]
}
diff --git a/src/activities/details/resource/board/board12_0.qml b/src/activities/details/resource/board/board12_0.qml
index 5c6183994..30d0ceff5 100644
--- a/src/activities/details/resource/board/board12_0.qml
+++ b/src/activities/details/resource/board/board12_0.qml
@@ -1,56 +1,56 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Sydney Opera House, Australia")
property var levels: [
{
"pixmapfile" : "image/OperaSidney_background.jpg",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "image/OperaSidney_0.png",
"x" : "0.243",
"y" : "0.543",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/OperaSidney_1.png",
"x" : "0.399",
"y" : "0.596",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/OperaSidney_2.png",
"x" : "0.471",
"y" : "0.375",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/OperaSidney_3.png",
"x" : "0.579",
"y" : "0.58",
"dropAreaSize" : "8"
}
]
}
diff --git a/src/activities/details/resource/board/board13_0.qml b/src/activities/details/resource/board/board13_0.qml
index 53b5cbc14..7e06103d4 100644
--- a/src/activities/details/resource/board/board13_0.qml
+++ b/src/activities/details/resource/board/board13_0.qml
@@ -1,62 +1,62 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Tower Bridge in London")
property var levels: [
{
"pixmapfile" : "image/TowerBridgeLondon_background.jpg",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "image/TowerBridgeLondon_0.png",
"x" : "0.487",
"y" : "0.365",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/TowerBridgeLondon_1.png",
"x" : "0.774",
"y" : "0.206",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/TowerBridgeLondon_2.png",
"x" : "0.382",
"y" : "0.709",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/TowerBridgeLondon_3.png",
"x" : "0.844",
"y" : "0.565",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/TowerBridgeLondon_4.png",
"x" : "0.226",
"y" : "0.668",
"dropAreaSize" : "8"
}
]
}
diff --git a/src/activities/details/resource/board/board14_0.qml b/src/activities/details/resource/board/board14_0.qml
index 9776e6c1e..44ac2364c 100644
--- a/src/activities/details/resource/board/board14_0.qml
+++ b/src/activities/details/resource/board/board14_0.qml
@@ -1,44 +1,44 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Eiffel Tower, seen from the champ de Mars, Paris, France")
property var levels: [
{
"pixmapfile" : "image/TourEiffel_background.jpg",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "image/TourEiffel_0.png",
"x" : "0.493",
"y" : "0.09",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/TourEiffel_1.png",
"x" : "0.489",
"y" : "0.524",
"dropAreaSize" : "8"
}
]
}
diff --git a/src/activities/details/resource/board/board15_0.qml b/src/activities/details/resource/board/board15_0.qml
index 33f2b622e..b73f5034d 100644
--- a/src/activities/details/resource/board/board15_0.qml
+++ b/src/activities/details/resource/board/board15_0.qml
@@ -1,50 +1,50 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Courtyard of the Museum of Louvre, and its pyramid")
property var levels: [
{
"pixmapfile" : "image/Louvre_2007_02_24_c_background.jpg",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "image/Louvre_2007_02_24_c_0.png",
"x" : "0.9",
"y" : "0.495",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/Louvre_2007_02_24_c_1.png",
"x" : "0.494",
"y" : "0.509",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/Louvre_2007_02_24_c_2.png",
"x" : "0.164",
"y" : "0.437",
"dropAreaSize" : "8"
}
]
}
diff --git a/src/activities/details/resource/board/board16_0.qml b/src/activities/details/resource/board/board16_0.qml
index 1e250cdf1..86e8e20d3 100644
--- a/src/activities/details/resource/board/board16_0.qml
+++ b/src/activities/details/resource/board/board16_0.qml
@@ -1,50 +1,50 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Panorama of Château de Chenonceau, Indre-et-Loire, France.")
property var levels: [
{
"pixmapfile" : "image/Chenonceau_background.jpg",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "image/Chenonceau_0.png",
"x" : "0.199",
"y" : "0.459",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/Chenonceau_1.png",
"x" : "0.318",
"y" : "0.421",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/Chenonceau_2.png",
"x" : "0.469",
"y" : "0.579",
"dropAreaSize" : "8"
}
]
}
diff --git a/src/activities/details/resource/board/board17_0.qml b/src/activities/details/resource/board/board17_0.qml
index a44887b66..7288ed9d2 100644
--- a/src/activities/details/resource/board/board17_0.qml
+++ b/src/activities/details/resource/board/board17_0.qml
@@ -1,56 +1,56 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Windmill in Sønderho, Fanø, Denmark")
property var levels: [
{
"pixmapfile" : "image/FanoeWindmill_background.jpg",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "image/FanoeWindmill_0.png",
"x" : "0.679",
"y" : "0.324",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/FanoeWindmill_1.png",
"x" : "0.162",
"y" : "0.612",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/FanoeWindmill_2.png",
"x" : "0.703",
"y" : "0.812",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/FanoeWindmill_3.png",
"x" : "0.372",
"y" : "0.696",
"dropAreaSize" : "8"
}
]
}
diff --git a/src/activities/details/resource/board/board18_0.qml b/src/activities/details/resource/board/board18_0.qml
index 1dc036bce..e3b10a83f 100644
--- a/src/activities/details/resource/board/board18_0.qml
+++ b/src/activities/details/resource/board/board18_0.qml
@@ -1,62 +1,62 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Nagoya Castle, Aichi Prefecture, Japan.")
property var levels: [
{
"pixmapfile" : "image/Nagoya_background.jpg",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "image/Nagoya_0.png",
"x" : "0.731",
"y" : "0.35",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/Nagoya_1.png",
"x" : "0.76",
"y" : "0.721",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/Nagoya_2.png",
"x" : "0.213",
"y" : "0.543",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/Nagoya_3.png",
"x" : "0.669",
"y" : "0.117",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/Nagoya_4.png",
"x" : "0.515",
"y" : "0.522",
"dropAreaSize" : "8"
}
]
}
diff --git a/src/activities/details/resource/board/board19_0.qml b/src/activities/details/resource/board/board19_0.qml
index 76c7a9ff0..cf04b7859 100644
--- a/src/activities/details/resource/board/board19_0.qml
+++ b/src/activities/details/resource/board/board19_0.qml
@@ -1,68 +1,68 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Taj Mahal, Agra, India")
property var levels: [
{
"pixmapfile" : "image/TajMahal_background.jpg",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "image/TajMahal_0.png",
"x" : "0.499",
"y" : "0.1",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/TajMahal_1.png",
"x" : "0.893",
"y" : "0.252",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/TajMahal_2.png",
"x" : "0.507",
"y" : "0.534",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/TajMahal_3.png",
"x" : "0.351",
"y" : "0.33",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/TajMahal_4.png",
"x" : "0.626",
"y" : "0.32",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/TajMahal_5.png",
"x" : "0.501",
"y" : "0.256",
"dropAreaSize" : "8"
}
]
}
diff --git a/src/activities/details/resource/board/board1_0.qml b/src/activities/details/resource/board/board1_0.qml
index 6df947d4a..a61edc50a 100644
--- a/src/activities/details/resource/board/board1_0.qml
+++ b/src/activities/details/resource/board/board1_0.qml
@@ -1,44 +1,44 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Vincent van Gogh, Entrance Hall of Saint-Paul Hospital - 1889")
property var levels: [
{
"pixmapfile" : "image/VincentVanGogh0012_background.jpg",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "image/VincentVanGogh0012_0.png",
"x" : "0.543",
"y" : "0.102",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/VincentVanGogh0012_1.png",
"x" : "0.601",
"y" : "0.468",
"dropAreaSize" : "8"
}
]
}
diff --git a/src/activities/details/resource/board/board20_0.qml b/src/activities/details/resource/board/board20_0.qml
index f84476904..4067c1686 100644
--- a/src/activities/details/resource/board/board20_0.qml
+++ b/src/activities/details/resource/board/board20_0.qml
@@ -1,92 +1,92 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Castle Neuschwanstein at Schwangau, Bavaria, Germany")
property var levels: [
{
"pixmapfile" : "image/Neuschwanstein_background.jpg",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "image/Neuschwanstein_0.png",
"x" : "0.876",
"y" : "0.578",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/Neuschwanstein_1.png",
"x" : "0.759",
"y" : "0.537",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/Neuschwanstein_2.png",
"x" : "0.674",
"y" : "0.348",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/Neuschwanstein_3.png",
"x" : "0.557",
"y" : "0.465",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/Neuschwanstein_4.png",
"x" : "0.553",
"y" : "0.735",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/Neuschwanstein_5.png",
"x" : "0.434",
"y" : "0.537",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/Neuschwanstein_6.png",
"x" : "0.325",
"y" : "0.265",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/Neuschwanstein_7.png",
"x" : "0.254",
"y" : "0.11",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/Neuschwanstein_8.png",
"x" : "0.165",
"y" : "0.535",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/Neuschwanstein_9.png",
"x" : "0.059",
"y" : "0.499",
"dropAreaSize" : "8"
}
]
}
diff --git a/src/activities/details/resource/board/board21_0.qml b/src/activities/details/resource/board/board21_0.qml
index 4b685923a..247084dd3 100644
--- a/src/activities/details/resource/board/board21_0.qml
+++ b/src/activities/details/resource/board/board21_0.qml
@@ -1,80 +1,80 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Egeskov Castle, Denmark")
property var levels: [
{
"pixmapfile" : "image/EgeskovSlotSpejling_background.jpg",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "image/EgeskovSlotSpejling_0.png",
"x" : "0.766",
"y" : "0.197",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/EgeskovSlotSpejling_1.png",
"x" : "0.762",
"y" : "0.816",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/EgeskovSlotSpejling_2.png",
"x" : "0.669",
"y" : "0.209",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/EgeskovSlotSpejling_3.png",
"x" : "0.568",
"y" : "0.452",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/EgeskovSlotSpejling_4.png",
"x" : "0.524",
"y" : "0.101",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/EgeskovSlotSpejling_5.png",
"x" : "0.278",
"y" : "0.161",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/EgeskovSlotSpejling_6.png",
"x" : "0.524",
"y" : "0.81",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/EgeskovSlotSpejling_7.png",
"x" : "0.416",
"y" : "0.412",
"dropAreaSize" : "8"
}
]
}
diff --git a/src/activities/details/resource/board/board2_0.qml b/src/activities/details/resource/board/board2_0.qml
index 7ae66cece..2d6bd8998 100644
--- a/src/activities/details/resource/board/board2_0.qml
+++ b/src/activities/details/resource/board/board2_0.qml
@@ -1,44 +1,44 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Vincent van Gogh, The Bridge of Langlois at Arles with a lady with umbrella - 1888")
property var levels: [
{
"pixmapfile" : "image/VincentVanGoghBridge_background.jpg",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "image/VincentVanGoghBridge_0.png",
"x" : "0.56",
"y" : "0.536",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/VincentVanGoghBridge_1.png",
"x" : "0.943",
"y" : "0.5",
"dropAreaSize" : "8"
}
]
}
diff --git a/src/activities/details/resource/board/board3_0.qml b/src/activities/details/resource/board/board3_0.qml
index 58a8b11f5..1e3bcb979 100644
--- a/src/activities/details/resource/board/board3_0.qml
+++ b/src/activities/details/resource/board/board3_0.qml
@@ -1,50 +1,50 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Vincent van Gogh, The Church at Auvers-sur-Oise - 1890")
property var levels: [
{
"pixmapfile" : "image/Eglise_dAuvers-sur-Oise_background.jpg",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "image/Eglise_dAuvers-sur-Oise_0.png",
"x" : "0.181",
"y" : "0.78",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/Eglise_dAuvers-sur-Oise_1.png",
"x" : "0.577",
"y" : "0.178",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/Eglise_dAuvers-sur-Oise_2.png",
"x" : "0.091",
"y" : "0.56",
"dropAreaSize" : "8"
}
]
}
diff --git a/src/activities/details/resource/board/board4_0.qml b/src/activities/details/resource/board/board4_0.qml
index 85c57e482..ae3beb8ae 100644
--- a/src/activities/details/resource/board/board4_0.qml
+++ b/src/activities/details/resource/board/board4_0.qml
@@ -1,62 +1,62 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Vincent van Gogh, Painter on His Way to Work - 1888")
property var levels: [
{
"pixmapfile" : "image/VincentVanGogh0013_background.jpg",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "image/VincentVanGogh0013_0.png",
"x" : "0.501",
"y" : "0.32",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/VincentVanGogh0013_1.png",
"x" : "0.859",
"y" : "0.828",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/VincentVanGogh0013_2.png",
"x" : "0.67",
"y" : "0.22",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/VincentVanGogh0013_3.png",
"x" : "0.396",
"y" : "0.268",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/VincentVanGogh0013_4.png",
"x" : "0.212",
"y" : "0.44",
"dropAreaSize" : "8"
}
]
}
diff --git a/src/activities/details/resource/board/board5_0.qml b/src/activities/details/resource/board/board5_0.qml
index 2adb3ca42..c10a84cc9 100644
--- a/src/activities/details/resource/board/board5_0.qml
+++ b/src/activities/details/resource/board/board5_0.qml
@@ -1,86 +1,86 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Vincent van Gogh, The Harvest - 1888")
property var levels: [
{
"pixmapfile" : "image/VincentVanGogh0019_background.jpg",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "image/VincentVanGogh0019_0.png",
"x" : "0.393",
"y" : "0.348",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/VincentVanGogh0019_1.png",
"x" : "0.784",
"y" : "0.498",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/VincentVanGogh0019_2.png",
"x" : "0.5",
"y" : "0.464",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/VincentVanGogh0019_3.png",
"x" : "0.13",
"y" : "0.346",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/VincentVanGogh0019_4.png",
"x" : "0.685",
"y" : "0.604",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/VincentVanGogh0019_5.png",
"x" : "0.226",
"y" : "0.212",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/VincentVanGogh0019_6.png",
"x" : "0.908",
"y" : "0.21",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/VincentVanGogh0019_7.png",
"x" : "0.292",
"y" : "0.484",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/VincentVanGogh0019_8.png",
"x" : "0.337",
"y" : "0.27",
"dropAreaSize" : "8"
}
]
}
diff --git a/src/activities/details/resource/board/board6_0.qml b/src/activities/details/resource/board/board6_0.qml
index 890d71551..eaf6dc3b5 100644
--- a/src/activities/details/resource/board/board6_0.qml
+++ b/src/activities/details/resource/board/board6_0.qml
@@ -1,86 +1,86 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Vincent van Gogh, Cafe Terrace at Night - 1888")
property var levels: [
{
"pixmapfile" : "image/Gogh4_background.jpg",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "image/Gogh4_0.png",
"x" : "0.753",
"y" : "0.594",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/Gogh4_1.png",
"x" : "0.234",
"y" : "0.776",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/Gogh4_2.png",
"x" : "0.633",
"y" : "0.618",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/Gogh4_3.png",
"x" : "0.459",
"y" : "0.922",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/Gogh4_4.png",
"x" : "0.511",
"y" : "0.112",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/Gogh4_5.png",
"x" : "0.88",
"y" : "0.532",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/Gogh4_6.png",
"x" : "0.783",
"y" : "0.198",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/Gogh4_7.png",
"x" : "0.229",
"y" : "0.444",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/Gogh4_8.png",
"x" : "0.579",
"y" : "0.794",
"dropAreaSize" : "8"
}
]
}
diff --git a/src/activities/details/resource/board/board7_0.qml b/src/activities/details/resource/board/board7_0.qml
index 14fe13f10..2563c2748 100644
--- a/src/activities/details/resource/board/board7_0.qml
+++ b/src/activities/details/resource/board/board7_0.qml
@@ -1,80 +1,80 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Vincent van Gogh, The Night Café - 1888")
property var levels: [
{
"pixmapfile" : "image/Van_Gogh_The_Night_Cafe_background.jpg",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "image/Van_Gogh_The_Night_Cafe_0.png",
"x" : "0.328",
"y" : "0.124",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/Van_Gogh_The_Night_Cafe_1.png",
"x" : "0.606",
"y" : "0.538",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/Van_Gogh_The_Night_Cafe_2.png",
"x" : "0.675",
"y" : "0.356",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/Van_Gogh_The_Night_Cafe_3.png",
"x" : "0.808",
"y" : "0.29",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/Van_Gogh_The_Night_Cafe_4.png",
"x" : "0.166",
"y" : "0.354",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/Van_Gogh_The_Night_Cafe_5.png",
"x" : "0.278",
"y" : "0.258",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/Van_Gogh_The_Night_Cafe_6.png",
"x" : "0.915",
"y" : "0.944",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/Van_Gogh_The_Night_Cafe_7.png",
"x" : "0.42",
"y" : "0.262",
"dropAreaSize" : "8"
}
]
}
diff --git a/src/activities/details/resource/board/board8_0.qml b/src/activities/details/resource/board/board8_0.qml
index 658231af6..f8d40542a 100644
--- a/src/activities/details/resource/board/board8_0.qml
+++ b/src/activities/details/resource/board/board8_0.qml
@@ -1,86 +1,86 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Vincent van Gogh, Portrait of Pere Tanguy 1887-8")
property var levels: [
{
"pixmapfile" : "image/PortraitOfPereTanguy_background.jpg",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "image/PortraitOfPereTanguy_0.png",
"x" : "0.112",
"y" : "0.364",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/PortraitOfPereTanguy_1.png",
"x" : "0.503",
"y" : "0.252",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/PortraitOfPereTanguy_2.png",
"x" : "0.904",
"y" : "0.544",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/PortraitOfPereTanguy_3.png",
"x" : "0.594",
"y" : "0.466",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/PortraitOfPereTanguy_4.png",
"x" : "0.107",
"y" : "0.91",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/PortraitOfPereTanguy_5.png",
"x" : "0.485",
"y" : "0.814",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/PortraitOfPereTanguy_6.png",
"x" : "0.254",
"y" : "0.212",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/PortraitOfPereTanguy_7.png",
"x" : "0.122",
"y" : "0.08",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/PortraitOfPereTanguy_8.png",
"x" : "0.906",
"y" : "0.824",
"dropAreaSize" : "8"
}
]
}
diff --git a/src/activities/details/resource/board/board9_0.qml b/src/activities/details/resource/board/board9_0.qml
index 34f704234..48b1670a5 100644
--- a/src/activities/details/resource/board/board9_0.qml
+++ b/src/activities/details/resource/board/board9_0.qml
@@ -1,50 +1,50 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Notre Dame de Paris cathedral on the Île de la Cité island in Paris, France.")
property var levels: [
{
"pixmapfile" : "image/NDP_background.jpg",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "image/NDP_0.png",
"x" : "0.508",
"y" : "0.65",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/NDP_1.png",
"x" : "0.499",
"y" : "0.357",
"dropAreaSize" : "8"
},
{
"pixmapfile" : "image/NDP_2.png",
"x" : "0.286",
"y" : "0.888",
"dropAreaSize" : "8"
}
]
}
diff --git a/src/activities/digital_electricity/ActivityInfo.qml b/src/activities/digital_electricity/ActivityInfo.qml
index c7ec7de8f..c684940cf 100644
--- a/src/activities/digital_electricity/ActivityInfo.qml
+++ b/src/activities/digital_electricity/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2016 Pulkit Gupta <pulkitnsit@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "digital_electricity/DigitalElectricity.qml"
difficulty: 6
icon: "digital_electricity/digital_electricity.svg"
author: "Pulkit Gupta &lt;pulkitnsit@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Digital Electricity")
//: Help title
description: qsTr("Create and simulate a digital electric schema")
//intro: "Learn how digital electronics work and create your own circuit."
//: Help goal
goal: qsTr("Freely create a digital electric schema with a real time simulation of it.")
//: Help prerequisite
prerequisite: qsTr("Requires some basic understanding of the concept of digital electronics.")
//: Help manual
manual: qsTr("Drag electrical components from the selector and drop them in the working area. In the working area, you can move the components by dragging them. To delete a component, select the deletion tool on top of the component selector, and select the component. You can click on the component and then on the rotate button to rotate it or info button to get information about it. You can click on the switch to open and close it. To connect two terminals, click on first terminal, then on second terminal. To deselect terminal or delete tool, click on any empty area. The simulation is updated in real time by any user action.")
credit: ""
section: "experimental"
createdInVersion: 9000
}
diff --git a/src/activities/digital_electricity/Dataset.qml b/src/activities/digital_electricity/Dataset.qml
index 95ade243e..5de5ea892 100644
--- a/src/activities/digital_electricity/Dataset.qml
+++ b/src/activities/digital_electricity/Dataset.qml
@@ -1,480 +1,480 @@
/* GCompris - Dataset.qml
*
* Copyright (C) 2017 Rudra Nil Basu <rudra.nil.basu.1996@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Gtk+ version)
* Rudra Nil Basu <rudra.nil.basu.1996@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property var zero: {
'imageName': 'zero.svg',
'componentSource': 'Zero.qml',
'width': 0.2,
'height': 0.2,
'toolTipText': qsTr("Zero input")
}
property var one: {
'imageName': 'one.svg',
'componentSource': 'One.qml',
'width': 0.2,
'height': 0.2,
'toolTipText': qsTr("One input")
}
property var digitalLight: {
'imageName': 'DigitalLightOff.svg',
'componentSource': 'DigitalLight.qml',
'width': 0.2,
'height': 0.2,
'toolTipText': qsTr("Digital light")
}
property var andGate: {
'imageName': 'gateAnd.svg',
'componentSource': 'AndGate.qml',
'width': 0.15,
'height': 0.15,
'toolTipText': qsTr("AND gate")
}
property var orGate: {
'imageName': 'gateOr.svg',
'componentSource': 'OrGate.qml',
'width': 0.15,
'height': 0.15,
'toolTipText': qsTr("OR gate")
}
property var notGate: {
'imageName': 'gateNot.svg',
'componentSource': 'NotGate.qml',
'width': 0.15,
'height': 0.15,
'toolTipText': qsTr("NOT gate")
}
property var xorGate: {
'imageName': 'gateXor.svg',
'componentSource': 'XorGate.qml',
'width': 0.15,
'height': 0.15,
'toolTipText': qsTr("XOR gate")
}
property var nandGate: {
'imageName': 'gateNand.svg',
'componentSource': 'NandGate.qml',
'width': 0.15,
'height': 0.15,
'toolTipText': qsTr("NAND gate")
}
property var norGate: {
'imageName': 'gateNor.svg',
'componentSource': 'NorGate.qml',
'width': 0.15,
'height': 0.15,
'toolTipText': qsTr("NOR gate")
}
property var switchKey: {
'imageName': 'switchOff.svg',
'componentSource': 'Switch.qml',
'width': 0.15,
'height': 0.15,
'toolTipText': qsTr("Switch")
}
property var comparator: {
'imageName': 'comparator.svg',
'componentSource': 'Comparator.qml',
'width': 0.3,
'height': 0.2,
'toolTipText': qsTr("Comparator")
}
property var bcdToSevenSegment: {
'imageName': 'BCDTo7Segment.svg',
'componentSource': 'BCDToSevenSegment.qml',
'width': 0.3,
'height': 0.4,
'toolTipText': qsTr("BCD to 7 segment")
}
property var sevenSegmentDisplay: {
'imageName': 'sevenSegmentDisplay.svg',
'componentSource': 'SevenSegment.qml',
'width': 0.225,
'height': 0.4,
'toolTipText': qsTr("7 segment display")
}
property var signalGenerator: {
'imageName': 'signalGenerator.svg',
'componentSource': 'SignalGenerator.qml',
'width': 0.3,
'height': 0.2,
'toolTipText': qsTr("Signal generator")
}
property var bcdCounter: {
'imageName': 'bcdCounter.svg',
'componentSource': 'BcdCounter.qml',
'width': 0.225,
'height': 0.4,
'toolTipText': qsTr("BCD counter")
}
// List of all components
property var componentList: [zero, one, digitalLight, andGate, orGate,
notGate, xorGate, nandGate, norGate, switchKey,
comparator, bcdToSevenSegment,
sevenSegmentDisplay, signalGenerator, bcdCounter]
property var problemType: {
'lightTheBulb': 1,
'equation1Variable': 2,
'equation2Variables': 3,
'equation3Variables': 4,
'others': 5,
}
// tutorial levels
property var tutorialLevels: [
// level 1
{
inputComponentList: [zero, one],
playAreaComponentList: [digitalLight],
determiningComponentsIndex: [0],
wires: [],
playAreaComponentPositionX: [0.4],
playAreaComponentPositionY: [0.3],
type: [problemType.lightTheBulb],
introMessage: [
qsTr("The digital light will glow when its terminal is connected with an input of 1."),
qsTr("Turn the digital light on using the inputs provided.")
]
},
// level 2
{
inputComponentList: [zero, one],
playAreaComponentList: [andGate, digitalLight],
determiningComponentsIndex: [1],
wires: [ [0, 0, 1, 0] ], // from_component_index, from_terminal_no, to_component_index, to_terminal_no
playAreaComponentPositionX: [0.4, 0.6],
playAreaComponentPositionY: [0.3, 0.3],
type: [problemType.lightTheBulb],
introMessage: [
qsTr("The AND gate produces an output of one when both of its input terminals are of value 1."),
qsTr("Turn the digital light on using an AND gate and the inputs provided.")
]
},
// level 3
{
inputComponentList: [zero, one],
playAreaComponentList: [orGate, digitalLight],
determiningComponentsIndex: [1],
wires: [ [0, 0, 1, 0] ],
playAreaComponentPositionX: [0.4, 0.6],
playAreaComponentPositionY: [0.3, 0.3],
type: [problemType.lightTheBulb],
introMessage: [
qsTr("The OR gate produces an output of 1 when at least one of its input terminals is of value 1."),
qsTr("Turn the digital light on using an OR gate and the inputs provided.")
]
},
// level 4
{
inputComponentList: [zero],
playAreaComponentList: [zero, one, orGate, andGate, digitalLight],
determiningComponentsIndex: [4],
wires: [ [0, 0, 2, 0], [2, 0, 3, 0], [3, 0, 4, 0]],
playAreaComponentPositionX: [0.0, 0.0, 0.2, 0.4, 0.6],
playAreaComponentPositionY: [0.0, 0.4, 0.2, 0.2, 0.3],
type: [problemType.lightTheBulb],
introMessage: [
qsTr("Note: You can draw multiple wires from the output terminal of a component.")
]
},
// level 5
{
inputComponentList: [zero],
playAreaComponentList: [notGate, notGate, orGate, orGate, andGate, digitalLight],
determiningComponentsIndex: [5],
wires: [ [4, 0, 5, 0], [2, 0, 4, 0], [3, 0, 4, 1]],
playAreaComponentPositionX: [0.05, 0.05, 0.3, 0.3, 0.35, 0.58],
playAreaComponentPositionY: [0.1, 0.4, 0.05, 0.45, 0.25, 0.25],
type: [problemType.lightTheBulb],
introMessage: [
qsTr("The NOT gate takes a single binary input and flips the value in the output.")
]
},
// level 6
{
inputComponentList: [zero, one],
playAreaComponentList: [nandGate, digitalLight],
determiningComponentsIndex: [1],
wires: [ [0, 0, 1, 0] ],
playAreaComponentPositionX: [0.25, 0.6],
playAreaComponentPositionY: [0.3, 0.3],
type: [problemType.lightTheBulb],
introMessage: [
qsTr("The NAND gate takes two binary inputs and produces one binary output."),
qsTr("The output of the NAND gate will be zero if both of its inputs are \"1\". Else, the output will be one."),
qsTr("For a more detailed description about the gate, select it and click on the info button."),
qsTr("Light the bulb using the NAND gate provided.")
]
},
// level 7
{
inputComponentList: [zero, one, andGate, orGate, nandGate],
playAreaComponentList: [switchKey, switchKey, switchKey, digitalLight],
determiningComponentsIndex: [0, 1, 2, 3],
wires: [],
playAreaComponentPositionX: [0.1, 0.1, 0.1, 0.5],
playAreaComponentPositionY: [0.0, 0.25, 0.55, 0.25],
type: [problemType.equation3Variables],
result: function (A, B, C) {
return A | (B & C)
},
introMessage: [
qsTr("Light the bulb using the components provided such that the bulb will glow under the following two circumstances:\n" +
"1. The first switch is turned ON, or\n" +
"2. Both of the second and the third switches are turned on.")
]
},
// level 8
{
inputComponentList: [zero, one],
playAreaComponentList: [xorGate, digitalLight],
determiningComponentsIndex: [1],
wires: [ [0, 0, 1, 0] ],
playAreaComponentPositionX: [0.25, 0.6],
playAreaComponentPositionY: [0.3, 0.3],
type: [problemType.lightTheBulb],
introMessage: [
qsTr("The XOR Gate takes two binary inputs and produces one binary output."),
qsTr("The output of the XOR gate will be one if the number of \"1\" in the input is odd. Else, the output will be zero."),
qsTr("Light the bulb using the XOR gate provided.")
]
},
// level 9
{
inputComponentList: [zero, one, xorGate],
playAreaComponentList: [switchKey, switchKey, switchKey, digitalLight],
determiningComponentsIndex: [0, 1, 2, 3],
wires: [],
playAreaComponentPositionX: [0.1, 0.1, 0.1, 0.5],
playAreaComponentPositionY: [0.0, 0.25, 0.55, 0.25],
type: [problemType.equation3Variables],
result: function (A, B, C) {
return A ^ B ^ C
},
introMessage: [
qsTr("Light the bulb using the three switches such that the bulb glows when odd number of the switches are turned on.")
]
},
// level 10
{
inputComponentList: [one, notGate],
playAreaComponentList: [norGate, digitalLight],
determiningComponentsIndex: [1],
wires: [ [0, 0, 1, 0] ],
playAreaComponentPositionX: [0.25, 0.6],
playAreaComponentPositionY: [0.3, 0.3],
type: [problemType.lightTheBulb],
introMessage: [
qsTr("A NOR gate takes 2 binary input and outputs 1 if both of them are 0, otherwise produces an output of 0."),
qsTr("For a more detailed description about the gate, select it and click on the info button."),
qsTr("Light the bulb using the NOR gate provided.")
]
},
// level 11
{
inputComponentList: [nandGate],
playAreaComponentList: [one, switchKey, digitalLight],
determiningComponentsIndex: [1, 2],
wires: [ [0, 0, 1, 0] ],
playAreaComponentPositionX: [0.0, 0.3, 0.6],
playAreaComponentPositionY: [0.25, 0.25, 0.25],
type: [problemType.equation1Variable],
introMessage: [
qsTr("Use the gates such that the bulb will glow only when the switch is turned off and remain off when the switch is turned on.")
]
},
// level 12
{
inputComponentList: [nandGate],
playAreaComponentList: [one, switchKey, switchKey, digitalLight],
determiningComponentsIndex: [1, 2, 3],
wires: [ [0, 0, 1, 0], [0, 0, 2, 0] ],
playAreaComponentPositionX: [0.0, 0.2, 0.2, 0.6],
playAreaComponentPositionY: [0.25, 0.2, 0.35, 0.25],
type: [problemType.equation2Variables],
result: function (A, B) {
return A & B
},
introMessage: [
qsTr("Create a circuit using the components provided such that the bulb glows only when both of the switches are turned on.")
]
},
// level 13
{
inputComponentList: [nandGate],
playAreaComponentList: [one, switchKey, switchKey, digitalLight],
determiningComponentsIndex: [1, 2, 3],
wires: [ [0, 0, 1, 0], [0, 0, 2, 0] ],
playAreaComponentPositionX: [0.0, 0.2, 0.2, 0.6],
playAreaComponentPositionY: [0.25, 0.2, 0.35, 0.25],
type: [problemType.equation2Variables],
result: function (A, B) {
return A | B
},
introMessage: [
qsTr("Create a circuit using the components provided such that the bulb glows when either of the switches are turned on.")
]
},
// level 14
{
inputComponentList: [nandGate],
playAreaComponentList: [one, switchKey, switchKey, digitalLight],
determiningComponentsIndex: [1, 2, 3],
wires: [ [0, 0, 1, 0], [0, 0, 2, 0] ],
playAreaComponentPositionX: [0.0, 0.2, 0.2, 0.6],
playAreaComponentPositionY: [0.25, 0.2, 0.35, 0.25],
type: [problemType.equation2Variables],
result: function (A, B) {
return !(A | B)
},
introMessage: [
qsTr("Create a circuit using the components provided such that the bulb glows only when both of the switches are turned off.")
]
},
// level 15
{
inputComponentList: [norGate],
playAreaComponentList: [one, switchKey, digitalLight],
determiningComponentsIndex: [1, 2],
wires: [ [0, 0, 1, 0] ],
playAreaComponentPositionX: [0.0, 0.3, 0.6],
playAreaComponentPositionY: [0.25, 0.25, 0.25],
type: [problemType.equation1Variable],
introMessage: [
qsTr("Use the gates such that the bulb will glow only when the switch is turned off and remain off when the switch is turned on.")
]
},
// level 16
{
inputComponentList: [norGate],
playAreaComponentList: [one, switchKey, switchKey, digitalLight],
determiningComponentsIndex: [1, 2, 3],
wires: [ [0, 0, 1, 0], [0, 0, 2, 0] ],
playAreaComponentPositionX: [0.0, 0.2, 0.2, 0.6],
playAreaComponentPositionY: [0.25, 0.2, 0.35, 0.25],
type: [problemType.equation2Variables],
result: function (A, B) {
return A & B
},
introMessage: [
qsTr("Create a circuit using the components provided such that the bulb glows only when both of the switches are turned on.")
]
},
// level 17
{
inputComponentList: [norGate],
playAreaComponentList: [one, switchKey, switchKey, digitalLight],
determiningComponentsIndex: [1, 2, 3],
wires: [ [0, 0, 1, 0], [0, 0, 2, 0] ],
playAreaComponentPositionX: [0.0, 0.2, 0.2, 0.6],
playAreaComponentPositionY: [0.25, 0.2, 0.35, 0.25],
type: [problemType.equation2Variables],
result: function (A, B) {
return A | B
},
introMessage: [
qsTr("Create a circuit using the components provided such that the bulb glows when either of the switches are turned on.")
]
},
// level 18
{
inputComponentList: [norGate],
playAreaComponentList: [one, switchKey, switchKey, digitalLight],
determiningComponentsIndex: [1, 2, 3],
wires: [ [0, 0, 1, 0], [0, 0, 2, 0] ],
playAreaComponentPositionX: [0.0, 0.2, 0.2, 0.6],
playAreaComponentPositionY: [0.25, 0.2, 0.35, 0.25],
type: [problemType.equation2Variables],
result: function (A, B) {
return !(A & B)
},
introMessage: [
qsTr("Create a circuit using the components provided such that the bulb will glow when at least one of the switches are turned off.")
]
},
// level 19
{
inputComponentList: [one, andGate, notGate, norGate, xorGate, nandGate, orGate],
playAreaComponentList: [switchKey, switchKey, comparator, digitalLight],
determiningComponentsIndex: [0, 1, 3],
wires: [ ],
playAreaComponentPositionX: [0.02, 0.02, 0.2, 0.6],
playAreaComponentPositionY: [0.05, 0.5, 0.25, 0.25],
type: [problemType.equation2Variables],
result: function (A, B) {
return A <= B
},
introMessage: [
qsTr("A comparator takes two numbers (A and B) as input and produces 3 values as output. First value is 1 if A < B, second value is 1 for A = B and third value is 1 for A > B."),
qsTr("Create a circuit using the components provided such that the bulb will glow when the value of the current flowing through the first switch is less than or equal to that of the second switch.")
]
},
// level 20
{
inputComponentList: [one, switchKey, nandGate, norGate, andGate, orGate, notGate],
playAreaComponentList: [bcdToSevenSegment, sevenSegmentDisplay],
determiningComponentsIndex: [0, 1],
wires: [ [0, 0, 1, 0], [0, 1, 1, 1], [0, 2, 1, 2], [0, 3, 1, 3], [0, 4, 1, 4], [0, 5, 1, 5], [0, 6, 1, 6] ],
playAreaComponentPositionX: [0.2, 0.6],
playAreaComponentPositionY: [0.1, 0.1],
type: [problemType.others],
introMessage: [
qsTr("The component in the middle is a BCD to seven segment converter."),
qsTr("It takes 4 bits as input represented in the binary coded decimal (BCD) format and converts the BCD number into a seven segment code."),
qsTr("The output of the converter is connected to the seven segment display, to view the value of the input provided."),
qsTr("Display the number \"6\" in the seven segment display.")
]
},
// level 21
{
inputComponentList: [one, switchKey, nandGate, norGate, andGate, orGate, notGate],
playAreaComponentList: [signalGenerator, bcdCounter, bcdToSevenSegment, sevenSegmentDisplay],
determiningComponentsIndex: [1, 2],
wires: [ [2, 0, 3, 0], [2, 1, 3, 1], [2, 2, 3, 2], [2, 3, 3, 3], [2, 4, 3, 4], [2, 5, 3, 5], [2, 6, 3, 6] ],
playAreaComponentPositionX: [0.0, 0.0, 0.27, 0.6],
playAreaComponentPositionY: [0.0, 0.3, 0.1, 0.1],
type: [problemType.others],
introMessage: [
qsTr("The signal generator on the left is used to generate alternating signals between 0 and 1 in a given time period taken as input. The time period by default is 1 second, but it can be changed between 0.25 and 2s."),
qsTr("The BCD counter placed under it is a special type of counter which can count from 0 to 9 and back to 0 on application of a clock signal."),
qsTr("Connect the components to make sure that the count of 0 to 9 is visible in the seven segment display provided.")
]
},
// level 22
{
inputComponentList: [zero, notGate, orGate, andGate],
playAreaComponentList: [one, one, switchKey, switchKey, digitalLight],
determiningComponentsIndex: [2, 3, 4],
wires: [ ],
playAreaComponentPositionX: [0.0, 0.0, 0.2, 0.2, 0.6],
playAreaComponentPositionY: [0.0, 0.5, 0.15, 0.4, 0.27],
type: [problemType.equation2Variables],
result: function (A, B) {
return A ^ B
},
introMessage: [
qsTr("Light the bulb using both the switches such that the bulb will glow only when either the first switch is on and the second switch is off or the first switch is off and the second switch is on.")
]
}
]
}
diff --git a/src/activities/digital_electricity/DigitalElectricity.qml b/src/activities/digital_electricity/DigitalElectricity.qml
index c3c6adfa7..07e04730d 100644
--- a/src/activities/digital_electricity/DigitalElectricity.qml
+++ b/src/activities/digital_electricity/DigitalElectricity.qml
@@ -1,529 +1,529 @@
/* GCompris - DigitalElectricity.qml
*
* Copyright (C) 2016 Pulkit Gupta <pulkitnsit@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitnsit@gmail.com> (Qt Quick port)
* Rudra Nil Basu <rudra.nil.basu.1996@gmail.com> (Qt Quick port)
* Timothée Giet <animtim@gmail.com> (mouse drag refactoring)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "digital_electricity.js" as Activity
ActivityBase {
id: activity
onStart: focus = true
onStop: {}
property string mode: "tutorial"
property bool isTutorialMode: mode == "tutorial" ? true : false
pageComponent: Image {
id: background
anchors.fill: parent
source: Activity.url + "texture02.png"
fillMode: Image.Tile
signal start
signal stop
- property bool hori: background.width > background.height
+ property bool hori: background.width >= background.height
Component.onCompleted: {
dialogActivityConfig.getInitialConfiguration()
activity.start.connect(start)
activity.stop.connect(stop)
}
Keys.onPressed: {
- if ((event.key == Qt.Key_Return || event.key == Qt.Key_Enter) && okButton.enabled) {
+ if ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter) && okButton.enabled) {
Activity.checkAnswer()
}
- if (event.key == Qt.Key_Plus) {
+ if (event.key === Qt.Key_Plus) {
Activity.zoomIn()
}
- if (event.key == Qt.Key_Minus) {
+ if (event.key === Qt.Key_Minus) {
Activity.zoomOut()
}
- if (event.key == Qt.Key_Right) {
+ if (event.key === Qt.Key_Right) {
playArea.x -= 200;
}
- if (event.key == Qt.Key_Left) {
+ if (event.key === Qt.Key_Left) {
playArea.x += 200
}
- if (event.key == Qt.Key_Up) {
+ if (event.key === Qt.Key_Up) {
playArea.y += 200
}
- if (event.key == Qt.Key_Down) {
+ if (event.key === Qt.Key_Down) {
playArea.y -= 200
}
if (playArea.x >= mousePan.drag.maximumX) {
playArea.x = mousePan.drag.maximumX
}
if (playArea.y >= mousePan.drag.maximumY) {
playArea.y = mousePan.drag.maximumY
}
if (playArea.x <= mousePan.drag.minimumX) {
playArea.x = mousePan.drag.minimumX
}
if (playArea.y <= mousePan.drag.minimumY) {
playArea.y = mousePan.drag.minimumY
}
}
onHoriChanged: {
if (hori == true) {
playArea.x += items.toolsMargin
playArea.y -= items.toolsMargin
} else {
playArea.x -= items.toolsMargin
playArea.y += items.toolsMargin
}
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property alias playArea: playArea
property alias mousePan: mousePan
property alias bar: bar
property alias bonus: bonus
property alias availablePieces: availablePieces
property alias toolTip: toolTip
property alias infoTxt: infoTxt
property alias truthTablesModel: truthTablesModel
property alias displayTruthTable: inputOutputTxt.displayTruthTable
property alias dataset: dataset
property alias tutorialDataset: tutorialDataset
property alias infoImage: infoImage
property bool isTutorialMode: activity.isTutorialMode
property alias tutorialInstruction: tutorialInstruction
property real toolsMargin: 90 * ApplicationInfo.ratio
property real zoomLvl: 0.25
}
Loader {
id: dataset
asynchronous: false
}
Dataset {
id: tutorialDataset
}
IntroMessage {
id: tutorialInstruction
intro: []
textContainerWidth: background.hori ? parent.width - inputComponentsContainer.width - items.toolsMargin : 0.9 * background.width
textContainerHeight: background.hori ? 0.5 * parent.height : parent.height - inputComponentsContainer.height - (bar.height * 2) - items.toolsMargin
anchors {
fill: undefined
top: background.hori ? parent.top : inputComponentsContainer.bottom
topMargin: 10
right: parent.right
rightMargin: 5
left: background.hori ? inputComponentsContainer.right : parent.left
leftMargin: 5
}
z: 5
}
onStart: { Activity.start(items) }
onStop: { Activity.stop() }
Rectangle {
id: visibleArea
color: "#00000000"
width: background.hori ? background.width - items.toolsMargin - 10 : background.width - 10
height: background.hori ? background.height - bar.height - items.toolsMargin - 10 : background.height - bar.height - 10
anchors {
fill: undefined
top: background.hori ? parent.top : inputComponentsContainer.bottom
topMargin: 5
right: parent.right
rightMargin: 5
left: background.hori ? inputComponentsContainer.right : parent.left
leftMargin: 5
bottom: bar.top
bottomMargin: 20
}
z: 6
GCText {
id: infoTxt
anchors {
horizontalCenter: parent.horizontalCenter
top: parent.top
topMargin: 2
}
fontSizeMode: Text.Fit
minimumPixelSize: 10
font.pixelSize: 150
color: "white"
horizontalAlignment: Text.AlignHLeft
width: Math.min(implicitWidth, 0.90 * parent.width)
height: inputOutputTxt.visible == false ? Math.min(implicitHeight, 0.7 * parent.height) :
Math.min(implicitHeight, (inputOutputTxt.inputs > 2 ? 0.3 : 0.4) * parent.height)
wrapMode: TextEdit.WordWrap
visible: false
z: 4
}
Rectangle {
id: infoTxtContainer
anchors.fill: parent
opacity: 1
radius: 10
color: "#373737"
border.width: 2
border.color: "#F2F2F2"
visible: infoTxt.visible
MouseArea {
anchors.fill: parent
onClicked: infoTxt.visible = false
}
z: 3
}
Image {
id: infoImage
property bool imgVisible: false
height: source == "" ? 0 : parent.height * 0.3 - 10
width: source == "" ? 0 : parent.width - 10
fillMode: Image.PreserveAspectFit
visible: infoTxt.visible && imgVisible
anchors {
top: infoTxt.bottom
horizontalCenter: infoTxtContainer.horizontalCenter
}
z: 5
}
ListModel {
id: truthTablesModel
property int rows
property int columns
property int inputs
property int outputs
}
Row {
id: inputOutputTxt
z: 5
property bool displayTruthTable
visible: infoTxt.visible && displayTruthTable
property int inputs: truthTablesModel.inputs
property int outputs: truthTablesModel.outputs
property int cellSize: (inputs > 2 ? 0.65 : 0.5) * parent.height / (truthTablesModel.rows + 1)
property int maxWidth: Math.min(cellSize, parent.width * 0.95 / truthTablesModel.columns)
property int minSize: 2.5 * cellSize
height: cellSize
anchors {
top: infoTxt.bottom
horizontalCenter: parent.horizontalCenter
}
Rectangle {
color: "#A7D9F9"
width: inputOutputTxt.inputs > 1 ? inputOutputTxt.maxWidth * inputOutputTxt.inputs : inputOutputTxt.minSize
height: inputOutputTxt.cellSize
border.color: "#373737"
border.width: 1
GCText {
anchors.centerIn: parent
fontSizeMode: Text.Fit
minimumPixelSize: 10
color: "#353535"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
height: parent.height
width: parent.width
text: qsTr("Input")
}
}
Rectangle {
color: "#A7F9DD"
width: inputOutputTxt.outputs > 1 ? inputOutputTxt.maxWidth * inputOutputTxt.outputs : inputOutputTxt.minSize
height: inputOutputTxt.cellSize
border.color: "#373737"
border.width: 1
GCText {
anchors.centerIn: parent
fontSizeMode: Text.Fit
minimumPixelSize: 10
color: "#353535"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
height: parent.height
width: parent.width
text: qsTr("Output")
}
}
}
Grid {
id: truthTable
rows: truthTablesModel.rows
columns: truthTablesModel.columns
height: rows * inputOutputTxt.cellSize
z: 5
visible: inputOutputTxt.visible
anchors {
top: inputOutputTxt.bottom
horizontalCenter: parent.horizontalCenter
}
Repeater {
id: repeater
model: truthTablesModel
delegate: blueSquare
Component {
id: blueSquare
Rectangle {
width: ((index % truthTable.columns) / (truthTablesModel.inputs - 1)) <= 1 ?
(inputOutputTxt.inputs > 1 ? inputOutputTxt.maxWidth : inputOutputTxt.minSize) :
(inputOutputTxt.outputs > 1 ? inputOutputTxt.maxWidth : inputOutputTxt.minSize)
height: inputOutputTxt.cellSize
border.color: "#373737"
border.width: 1
color: {
if(truthTablesModel.inputs == 1) {
return index%2 == 0 ? "#A7D9F9" : "#A7F9DD"
}
else {
return ((index % truthTable.columns) / (truthTablesModel.inputs - 1)) <= 1 ? "#A7D9F9" : "#A7F9DD"
}
}
GCText {
id: truthTableValue
anchors.centerIn: parent
fontSizeMode: Text.Fit
minimumPixelSize: 10
color: "#353535"
horizontalAlignment: Text.AlignHCenter
height: parent.height
width: parent.width
text: value
}
}
}
}
}
}
Rectangle {
id: playArea
color: "#10000000"
x: background.hori ? items.toolsMargin : 0
y: background.hori ? 0 : items.toolsMargin
width: background.hori ?
background.width * 4 - items.toolsMargin : background.width * 4
height: background.hori ?
background.height * 4 - (bar.height * 1.1) :
background.height * 4 - (bar.height * 1.1) - items.toolsMargin
PinchArea {
id: pinchZoom
anchors.fill: parent
onPinchFinished: {
if (pinch.scale < 1) {
Activity.zoomOut()
}
if (pinch.scale > 1) {
Activity.zoomIn()
}
}
MouseArea {
id: mousePan
anchors.fill: parent
scrollGestureEnabled: false //needed for pinchZoom
drag.target: playArea
drag.axis: Drag.XandYAxis
drag.minimumX: - playArea.width * items.zoomLvl
drag.maximumX: background.hori ? items.toolsMargin : 0
drag.minimumY: - playArea.height * items.zoomLvl
drag.maximumY: background.hori ? 0 : items.toolsMargin
onClicked: {
Activity.deselect()
availablePieces.hideToolbar()
}
}
}
}
Rectangle {
id: inputComponentsContainer
width: background.hori ?
items.toolsMargin :
background.width
height: background.hori ?
background.height :
items.toolsMargin
color: "#4A3823"
anchors.left: parent.left
Image {
anchors.fill: parent
anchors.rightMargin: background.hori ? 3 * ApplicationInfo.ratio : 0
anchors.bottomMargin: background.hori ? 0 : 3 * ApplicationInfo.ratio
source: Activity.url + "texture01.png"
fillMode: Image.Tile
ListWidget {
id: availablePieces
hori: background.hori
}
}
z: 10
}
Rectangle {
id: toolTip
anchors {
bottom: bar.top
bottomMargin: 10
left: inputComponentsContainer.left
leftMargin: 5
}
width: toolTipTxt.width + 10
height: toolTipTxt.height + 5
color: "#373737"
opacity: 1
radius: 10
z: 100
border.width: 2
border.color: "#F2F2F2"
property alias text: toolTipTxt.text
Behavior on opacity { NumberAnimation { duration: 120 } }
function show(newText) {
if(newText) {
text = newText
opacity = 1
} else {
opacity = 0
}
}
GCText {
id: toolTipTxt
anchors.centerIn: parent
fontSize: regularSize
color: "white"
horizontalAlignment: Text.AlignHCenter
wrapMode: TextEdit.WordWrap
}
}
DialogActivityConfig {
id: dialogActivityConfig
currentActivity: activity
content: Component {
Item {
property alias modesComboBox: modesComboBox
property var availableModes: [
{ "text": qsTr("Tutorial Mode"), "value": "tutorial" },
{ "text": qsTr("Free Mode"), "value": "free" },
]
Flow {
id: flow
spacing: 5
width: dialogActivityConfig.width
GCComboBox {
id: modesComboBox
model: availableModes
background: dialogActivityConfig
label: qsTr("Select your Mode")
}
}
}
}
onClose: home();
onLoadData: {
if(dataToSave && dataToSave["modes"]) {
activity.mode = dataToSave["modes"];
}
}
onSaveData: {
var newMode = dialogActivityConfig.configItem.availableModes[dialogActivityConfig.configItem.modesComboBox.currentIndex].value;
if (newMode !== activity.mode) {
activity.mode = newMode;
dataToSave = {"modes": activity.mode};
Activity.reset()
}
}
function setDefaultValues() {
for(var i = 0 ; i < dialogActivityConfig.configItem.availableModes.length; i ++) {
if(dialogActivityConfig.configItem.availableModes[i].value === activity.mode) {
dialogActivityConfig.configItem.modesComboBox.currentIndex = i;
break;
}
}
}
}
DialogHelp {
id: dialogHelp
onClose: home()
}
BarButton {
id: okButton
visible: activity.isTutorialMode
anchors {
bottom: bar.top
right: parent.right
rightMargin: 10 * ApplicationInfo.ratio
bottomMargin: height * 0.5
}
source: "qrc:/gcompris/src/core/resource/bar_ok.svg"
sourceSize.width: 60 * ApplicationInfo.ratio
enabled: !tutorialInstruction.visible
onClicked: Activity.checkAnswer()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | ( activity.isTutorialMode ? level : 0) | reload | config}
onHelpClicked: {displayDialog(dialogHelp)}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
onReloadClicked: Activity.reset()
onConfigClicked: {
dialogActivityConfig.active = true
dialogActivityConfig.setDefaultValues()
displayDialog(dialogActivityConfig)
}
}
Bonus {
id: bonus
Component.onCompleted: win.connect(Activity.nextLevel)
}
}
}
diff --git a/src/activities/digital_electricity/DragListItem.qml b/src/activities/digital_electricity/DragListItem.qml
index d6bc72139..e34185f12 100644
--- a/src/activities/digital_electricity/DragListItem.qml
+++ b/src/activities/digital_electricity/DragListItem.qml
@@ -1,136 +1,136 @@
/* gcompris - DragListItem.qml
*
* Copyright (C) 2016 Pulkit Gupta <pulkitnsit@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitnsit@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "digital_electricity.js" as Activity
Item {
id: item
width: tile.width
height: tile.height
property string source: componentSrc
property string imageName: imgName
property string toolTipTxt: toolTipText
property double imageWidth: imgWidth
property double imageHeight: imgHeight
property double heightInColumn
property double widthInColumn
property double tileWidth
property double tileHeight
property bool selected: false
signal pressed
Rectangle {
id: tile
width: tileWidth
height: tileHeight
color: (parent.selected && tileImage.parent == tile) ? "#33FF294D" : "transparent"
border.color: (parent.selected && tileImage.parent == tile) ? "white" : "transparent"
border.width: 3
radius: 2
property double xCenter: tile.x + tile.width / 2
property double yCenter: tile.y + tile.height / 2
property bool selected: false
Image {
anchors.centerIn: parent
width: widthInColumn
height: heightInColumn
fillMode: Image.PreserveAspectFit
source: Activity.url + imgName
}
Image {
id: tileImage
anchors.centerIn: parent
width: smallWidth
height: smallHeight
fillMode: Image.PreserveAspectFit
source: Activity.url + imgName
mipmap: true
antialiasing: true
property double smallWidth: widthInColumn
property double smallHeight: heightInColumn
property double fullWidth: imgWidth * playArea.width
property double fullHeight: imgHeight * playArea.height
property QtObject tileImageParent
property bool small: true
function toSmall() {
width = smallWidth
height = smallHeight
small = true
}
function toFull() {
width = fullWidth * Activity.currentZoom
height = fullHeight * Activity.currentZoom
small = false
}
MultiPointTouchArea {
id: mouseArea
touchPoints: [ TouchPoint { id: point1 } ]
property real startX
property real startY
property bool pressedOnce
anchors.fill: parent
onPressed: {
tileImage.anchors.centerIn = undefined
startX = point1.x
startY = point1.y
tileImage.toFull()
toolTip.show(toolTipText)
pressedOnce = true
item.selected = true
}
onUpdated: {
var moveX = point1.x - startX
var moveY = point1.y - startY
parent.x = parent.x + moveX
parent.y = parent.y + moveY
}
onReleased: {
if (pressedOnce) {
pressedOnce = false
item.selected = false
var coord = playArea.mapFromItem(tileImage.parent, parent.x, parent.y)
if(coord.x > 0 && ((playArea.width/Activity.currentZoom) - coord.x > tileImage.fullWidth))
Activity.createComponent(coord.x, coord.y, index)
tileImage.anchors.centerIn = tile
tileImage.toSmall()
toolTip.show("")
}
}
}
}
}
}
diff --git a/src/activities/digital_electricity/ListWidget.qml b/src/activities/digital_electricity/ListWidget.qml
index 2b47b57a8..f45d1a5c8 100644
--- a/src/activities/digital_electricity/ListWidget.qml
+++ b/src/activities/digital_electricity/ListWidget.qml
@@ -1,421 +1,421 @@
/* gcompris - ListWidget.qml
*
* Copyright (C) 2016 Pulkit Gupta <pulkitnsit@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitnsit@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "digital_electricity.js" as Activity
Item {
id: listWidget
anchors.fill: parent
anchors.topMargin: 5 * ApplicationInfo.ratio
anchors.leftMargin: 5 * ApplicationInfo.ratio
z: 10
property bool hori
property alias model: mymodel
property alias view: view
property alias repeater: repeater
property alias toolDelete: toolDelete
property alias rotateLeft: rotateLeft
property alias rotateRight: rotateRight
property alias info: info
property alias zoomInBtn: zoomInBtn
property alias zoomOutBtn: zoomOutBtn
signal hideToolbar
onHideToolbar: toolButton.showToolBar = false
property int minIconWidth: listWidget.hori ? Math.min((background.width - 1.5*view.width) / 6, 100) : Math.min((background.height - 1.5*bar.height - view.height) / 6, 100)
ListModel {
id: mymodel
}
Grid {
id: view
width: listWidget.hori ? inputComponentsContainer.width : 2 * bar.height
height: listWidget.hori ? background.height - 2 * bar.height : bar.height
spacing: 5
z: 20
columns: listWidget.hori ? 1 : nbItemsByGroup + 2
property int currentDisplayedGroup: 0
property int setCurrentDisplayedGroup: 0
property int nbItemsByGroup:
listWidget.hori ?
parent.height / iconSize - 2 :
parent.width / iconSize - 2
property int nbDisplayedGroup: Math.ceil(model.count / nbItemsByGroup)
property int iconSize: 80 * ApplicationInfo.ratio
property int previousNavigation: 1
property int nextNavigation: 1
onNbDisplayedGroupChanged: {
view.setCurrentDisplayedGroup = 0
refreshInputComponentsContainer()
}
add: Transition {
NumberAnimation { property: "opacity"; from: 0; to: 1.0; duration: 400 }
NumberAnimation { property: "scale"; from: 0; to: 1.0; duration: 400 }
}
move: Transition {
NumberAnimation { properties: "x,y"; duration: 400; easing.type: Easing.OutBounce }
}
//For setting navigation buttons
function setNextNavigation() {
nextNavigation = 0
if(currentDisplayedGroup + 1 < nbDisplayedGroup)
nextNavigation = 1
}
function setPreviousNavigation() {
previousNavigation = 0
if(currentDisplayedGroup > 0)
previousNavigation = 1
}
function refreshInputComponentsContainer() {
availablePieces.view.currentDisplayedGroup = availablePieces.view.setCurrentDisplayedGroup
availablePieces.view.setNextNavigation()
availablePieces.view.setPreviousNavigation()
}
Image {
id: toolButton
width: (listWidget.hori ? listWidget.width : listWidget.height) - listWidget.anchors.leftMargin
height: width
sourceSize.width: width
sourceSize.height: height
source: Activity.url + "tools.svg"
fillMode: Image.PreserveAspectFit
property bool showToolBar: false
MouseArea {
anchors.fill: parent
onClicked: toolButton.showToolBar = !toolButton.showToolBar
}
Rectangle {
id: toolsContainer
visible: toolButton.showToolBar
width: listWidget.hori ? (toolDelete.width + tools.spacing) * tools.children.length + tools.spacing * 4 : parent.width
height: listWidget.hori ? parent.width : (toolDelete.height + tools.spacing) * tools.children.length + tools.spacing * 4
anchors.top: listWidget.hori ? parent.top : parent.bottom
anchors.left: listWidget.hori ? parent.right : parent.left
color: "#2a2a2a"
radius: 4 * ApplicationInfo.ratio
Flow {
id: tools
width: parent.width
height: parent.height
property int topMarginAmt: (toolsContainer.height - toolDelete.height) / 2
property int leftMarginAmt: (toolsContainer.width - toolDelete.width) / 2
anchors {
fill: parent
leftMargin: listWidget.hori ? 8 * ApplicationInfo.ratio : tools.leftMarginAmt
topMargin: listWidget.hori ? tools.topMarginAmt : 8 * ApplicationInfo.ratio
}
spacing: 4 * ApplicationInfo.ratio
Image {
id: toolDelete
state: "notSelected"
width: minIconWidth
height: width
sourceSize.width: width
sourceSize.height: height
source: Activity.url + "deleteOn.svg"
fillMode: Image.PreserveAspectFit
MouseArea {
anchors.fill: parent
onClicked: {
toolDelete.state = (toolDelete.state == "selected") ? "notSelected" : "selected"
Activity.toolDelete = !Activity.toolDelete
Activity.toolDeleteSticky = false
}
onDoubleClicked: {
Activity.toolDeleteSticky = true
Activity.toolDelete = true
toolDelete.state = "selected"
}
}
states: [
State {
name: "selected"
PropertyChanges {
target: toolDelete
opacity: 1
}
},
State {
name: "notSelected"
PropertyChanges {
target: toolDelete
opacity: 0.5
}
}
]
}
Image {
id: info
source: Activity.url + "info.svg"
width: minIconWidth
height: width
sourceSize.width: width
sourceSize.height: height
fillMode: Image.PreserveAspectFit
MouseArea {
anchors.fill: parent
onClicked: {
if(!Activity.animationInProgress && parent.state == "canBeSelected") {
Activity.displayInfo()
hideToolbar()
}
}
}
states: [
State {
name: "canBeSelected"
PropertyChanges {
target: info
opacity: 1
}
},
State {
name: "canNotBeSelected"
PropertyChanges {
target: info
opacity: 0.5
}
}
]
}
Image {
id: rotateLeft
width: minIconWidth
height: width
sourceSize.width: width
sourceSize.height: height
source: Activity.url + "rotate.svg"
fillMode: Image.PreserveAspectFit
state: "CanNotBeSelected"
MouseArea {
anchors.fill: parent
onClicked: {
if(!Activity.animationInProgress && parent.state == "canBeSelected") {
Activity.rotateLeft()
}
}
}
states: [
State {
name: "canBeSelected"
PropertyChanges {
target: rotateLeft
opacity: 1
}
},
State {
name: "canNotBeSelected"
PropertyChanges {
target: rotateLeft
opacity: 0.5
}
}
]
}
Image {
id: rotateRight
width: minIconWidth
height: width
sourceSize.width: width
sourceSize.height: height
source: Activity.url + "rotate.svg"
fillMode: Image.PreserveAspectFit
mirror: true
state: "CanNotBeSelected"
MouseArea {
anchors.fill: parent
onClicked: {
if(!Activity.animationInProgress && parent.state == "canBeSelected") {
Activity.rotateRight()
}
}
}
states: [
State {
name: "canBeSelected"
PropertyChanges{
target: rotateRight
opacity: 1
}
},
State {
name: "canNotBeSelected"
PropertyChanges {
target: rotateRight
opacity: 0.5
}
}
]
}
Image {
id: zoomInBtn
width: minIconWidth
height: width
sourceSize.width: width
sourceSize.height: height
source: Activity.url + "zoomIn.svg"
fillMode: Image.PreserveAspectFit
MouseArea {
anchors.fill: parent
onClicked: Activity.zoomIn()
}
states: [
State {
name: "canZoomIn"
PropertyChanges {
target: zoomInBtn
opacity: 1.0
}
},
State {
name: "cannotZoomIn"
PropertyChanges {
target: zoomInBtn
opacity: 0.5
}
}
]
}
Image {
id: zoomOutBtn
width: minIconWidth
height: width
sourceSize.width: width
sourceSize.height: height
source: Activity.url + "zoomOut.svg"
fillMode: Image.PreserveAspectFit
MouseArea {
anchors.fill: parent
onClicked: Activity.zoomOut()
}
states: [
State {
name: "canZoomOut"
PropertyChanges {
target: zoomOutBtn
opacity: 1.0
}
},
State {
name: "cannotZoomOut"
PropertyChanges {
target: zoomOutBtn
opacity: 0.5
}
}
]
}
}
}
}
Repeater {
id: repeater
property int currentIndex
width: 100
DragListItem {
id: contactsDelegate
z: 1
heightInColumn: view.iconSize * 0.75
widthInColumn: view.iconSize * 0.85
tileWidth: view.iconSize
tileHeight: view.iconSize * 0.85
visible: view.currentDisplayedGroup * view.nbItemsByGroup <= index &&
index <= (view.currentDisplayedGroup+1) * view.nbItemsByGroup-1
onPressed: repeater.currentIndex = index
}
clip: true
model: mymodel
onModelChanged: repeater.currentIndex = -1
}
Row {
spacing: view.iconSize * 0.20
Image {
id: previous
opacity: (model.count > view.nbItemsByGroup &&
view.previousNavigation != 0 && view.currentDisplayedGroup != 0) ? 1 : 0
source: "qrc:/gcompris/src/core/resource/bar_previous.svg"
sourceSize.width: view.iconSize * 0.30
fillMode: Image.PreserveAspectFit
MouseArea {
anchors.fill: parent
onClicked: {
repeater.currentIndex = -1
if(previous.opacity == 1) {
view.setCurrentDisplayedGroup = view.currentDisplayedGroup - view.previousNavigation
view.refreshInputComponentsContainer()
}
}
}
}
Image {
id: next
visible: model.count > view.nbItemsByGroup && view.nextNavigation != 0 && view.currentDisplayedGroup <
view.nbDisplayedGroup - 1
source: "qrc:/gcompris/src/core/resource/bar_next.svg"
sourceSize.width: view.iconSize * 0.30
fillMode: Image.PreserveAspectFit
MouseArea {
anchors.fill: parent
onClicked: {
repeater.currentIndex = -1
view.setCurrentDisplayedGroup = view.currentDisplayedGroup + view.nextNavigation
view.refreshInputComponentsContainer()
}
}
}
}
}
}
diff --git a/src/activities/digital_electricity/Wire.qml b/src/activities/digital_electricity/Wire.qml
index c207934e7..aef5859c7 100644
--- a/src/activities/digital_electricity/Wire.qml
+++ b/src/activities/digital_electricity/Wire.qml
@@ -1,51 +1,51 @@
/* GCompris - Wire.qml
*
* Copyright (C) 2016 Pulkit Gupta <pulkitnsit@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitnsit@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "digital_electricity.js" as Activity
Rectangle {
id: wire
property QtObject from
property QtObject to
property bool destructible
height: 5 * ApplicationInfo.ratio
color: from.value == 0 ? "#d21818" : "#6ce76c"
radius: height / 2
transformOrigin: Item.Left
MouseArea {
id: mouseArea
enabled: destructible
width: parent.width
height: parent.height * 3
anchors.centerIn: parent
onPressed: {
if(Activity.toolDelete) {
Activity.removeWire(wire)
}
}
}
}
diff --git a/src/activities/digital_electricity/components/AndGate.qml b/src/activities/digital_electricity/components/AndGate.qml
index 928986344..a9565be35 100644
--- a/src/activities/digital_electricity/components/AndGate.qml
+++ b/src/activities/digital_electricity/components/AndGate.qml
@@ -1,88 +1,88 @@
/* GCompris - AndGate.qml
*
* Copyright (C) 2016 Pulkit Gupta <pulkitnsit@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitnsit@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
ElectricalComponent {
id: andGate
terminalSize: 0.50
noOfInputs: 2
noOfOutputs: 1
property var inputTerminalPosY: [0.2, 0.8]
information: qsTr("AND gate outputs 1 only if all its inputs are equal to 1. " +
"As soon as one input is equal to 0 the result is 0. Output for 2 input AND gate is:")
truthTable: [['A','B',qsTr("A AND B")],
['0','0','0'],
['0','1','0'],
['1','0','0'],
['1','1','1']]
property alias inputTerminals: inputTerminals
property alias outputTerminals: outputTerminals
Repeater {
id: inputTerminals
model: 2
delegate: inputTerminal
Component {
id: inputTerminal
TerminalPoint {
posX: 0.04
posY: inputTerminalPosY[index]
type: "In"
}
}
}
Repeater {
id: outputTerminals
model: 1
delegate: outputTerminal
Component {
id: outputTerminal
TerminalPoint {
posX: 0.96
posY: 0.5
type: "Out"
}
}
}
function updateOutput(wireVisited) {
var terminal = outputTerminals.itemAt(0)
/* Keep the output value == 0 if only one of the input terminals is connected */
terminal.value = (inputTerminals.itemAt(0).wires.length != 0 && inputTerminals.itemAt(1).wires.length != 0) ? (inputTerminals.itemAt(0).value & inputTerminals.itemAt(1).value) : 0
for(var i = 0 ; i < terminal.wires.length ; ++i)
terminal.wires[i].to.value = terminal.value
var componentVisited = []
for(var i = 0 ; i < terminal.wires.length ; ++i) {
var wire = terminal.wires[i]
var component = wire.to.parent
componentVisited[component] = true
wireVisited[wire] = true
component.updateOutput(wireVisited)
}
}
}
diff --git a/src/activities/digital_electricity/components/BCDToSevenSegment.qml b/src/activities/digital_electricity/components/BCDToSevenSegment.qml
index 4844e9ef3..06e584702 100644
--- a/src/activities/digital_electricity/components/BCDToSevenSegment.qml
+++ b/src/activities/digital_electricity/components/BCDToSevenSegment.qml
@@ -1,150 +1,150 @@
/* GCompris - BCDToSevenSegment.qml
*
* Copyright (C) 2016 Pulkit Gupta <pulkitnsit@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitnsit@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../digital_electricity.js" as Activity
import GCompris 1.0
ElectricalComponent {
id: bcdTo7Segment
terminalSize: 0.125
noOfInputs: 4
noOfOutputs: 7
property var inputTerminalPosY: [0.125, 0.375, 0.625, 0.875]
property var outputTerminalPosY: [0.066, 0.211, 0.355, 0.5, 0.645, 0.789, 0.934]
property var redChar: ["BCDTo7SegmentA_on.svg","BCDTo7SegmentB_on.svg","BCDTo7SegmentC_on.svg",
"BCDTo7SegmentD_on.svg","BCDTo7SegmentE_on.svg","BCDTo7SegmentF_on.svg",
"BCDTo7SegmentG_on.svg"]
information: qsTr("BCD to 7 segment converter takes 4 binary inputs in its input terminals " +
"and gives 7 binary outputs which allow to light BCD number segments (binary-coded decimal) " +
"to display numbers between 0 and 9. The output for BCD To 7 Segment converted is:")
truthTable: [['D','C','B','A','a','b','c','d','e','f','g'],
['0','0','0','0','1','1','1','1','1','1','0'],
['0','0','0','1','0','1','1','0','0','0','0'],
['0','0','1','0','1','1','0','1','1','0','1'],
['0','0','1','1','1','1','1','1','0','0','1'],
['0','1','0','0','0','1','1','0','0','1','1'],
['0','1','0','1','1','0','1','1','0','1','1'],
['0','1','1','0','1','0','1','1','1','1','1'],
['0','1','1','1','1','1','1','0','0','0','0'],
['1','0','0','0','1','1','1','1','1','1','1'],
['1','0','0','1','1','1','1','1','0','1','1']]
property alias inputTerminals: inputTerminals
property alias outputTerminals: outputTerminals
Repeater {
id: inputTerminals
model: 4
delegate: inputTerminal
Component {
id: inputTerminal
TerminalPoint {
posX: 0.05
posY: inputTerminalPosY[index]
type: "In"
}
}
}
Repeater {
id: outputTerminals
model: 7
delegate: outputTerminal
Component {
id: outputTerminal
TerminalPoint {
posX: 0.95
posY: outputTerminalPosY[index]
type: "Out"
}
}
}
function updateOutput(wireVisited) {
var i
for(i = 1 ; i < truthTable.length ; ++i) {
var j
for(j = 0 ; j < noOfInputs; ++j) {
if(inputTerminals.itemAt(j).value != truthTable[i][j])
break
}
if(j == noOfInputs)
break
}
if(i == truthTable.length) {
for(var j = 0 ; j < noOfOutputs ; ++j) {
outputTerminals.itemAt(j).value = 0
outputChar.itemAt(j).source = "qrc:/gcompris/src/core/resource/empty.svg"
}
}
else {
for(var j = 0 ; j < noOfOutputs ; ++j) {
var terminal = outputTerminals.itemAt(j)
terminal.value = truthTable[i][j + noOfInputs]
outputChar.itemAt(j).source = (terminal.value == 0 ? "qrc:/gcompris/src/core/resource/empty.svg" : Activity.url + redChar[j])
}
}
for(var i = 0 ; i < noOfOutputs ; ++i) {
var terminal = outputTerminals.itemAt(i)
for(var j = 0 ; j < terminal.wires.length ; ++j)
terminal.wires[j].to.value = terminal.value
}
var componentVisited = []
for(var i = 0 ; i < noOfOutputs ; ++i) {
var terminal = outputTerminals.itemAt(i)
for(var j = 0 ; j < terminal.wires.length ; ++j) {
var wire = terminal.wires[j]
var component = wire.to.parent
if(componentVisited[component] != true && wireVisited[wire] != true) {
componentVisited[component] = true
wireVisited[wire] = true
component.updateOutput(wireVisited)
}
}
}
}
Repeater {
id: outputChar
model: 7
delegate: outputCharImages
Component {
id: outputCharImages
Image {
source: ""
anchors.centerIn: parent
height: parent.height
width: parent.width
fillMode: Image.PreserveAspectFit
mipmap: true
antialiasing: true
}
}
}
}
diff --git a/src/activities/digital_electricity/components/BcdCounter.qml b/src/activities/digital_electricity/components/BcdCounter.qml
index 8ea5c1c9a..a04c31097 100644
--- a/src/activities/digital_electricity/components/BcdCounter.qml
+++ b/src/activities/digital_electricity/components/BcdCounter.qml
@@ -1,109 +1,109 @@
/* GCompris - BcdCounter.qml
*
* Copyright (C) 2016 Pulkit Gupta <pulkitnsit@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitnsit@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../digital_electricity.js" as Activity
ElectricalComponent {
id: bcdTo7Segment
terminalSize: 0.125
noOfInputs: 1
noOfOutputs: 4
property var outputTerminalPosY: [0.125, 0.375, 0.625, 0.875]
property int count: 0
property int previousInput: 0
information: qsTr("BCD counter usually takes a signal generator as input. " +
"The output is a BCD number starting from 0 which is increased by one at each tick.")
truthTable: []
property var outputTable: [['0','0','0','0'],
['0','0','0','1'],
['0','0','1','0'],
['0','0','1','1'],
['0','1','0','0'],
['0','1','0','1'],
['0','1','1','0'],
['0','1','1','1'],
['1','0','0','0'],
['1','0','0','1']]
property alias inputTerminals: inputTerminals
property alias outputTerminals: outputTerminals
Repeater {
id: inputTerminals
model: 1
delegate: inputTerminal
Component {
id: inputTerminal
TerminalPoint {
posX: 0.07
posY: 0.5
type: "In"
}
}
}
Repeater {
id: outputTerminals
model: 4
delegate: outputTerminal
Component {
id: outputTerminal
TerminalPoint {
posX: 0.93
posY: outputTerminalPosY[index]
type: "Out"
}
}
}
function updateOutput(wireVisited) {
for(var i = 0 ; i < noOfOutputs ; ++i) {
var terminal = outputTerminals.itemAt(i)
terminal.value = outputTable[count][i]
for(var j = 0 ; j < terminal.wires.length ; ++j)
terminal.wires[j].to.value = terminal.value
}
if(previousInput != inputTerminals.itemAt(0).value) {
previousInput = inputTerminals.itemAt(0).value
count = (count + 1) % 10;
var componentVisited = []
for(var i = 0 ; i < noOfOutputs ; ++i) {
var terminal = outputTerminals.itemAt(i)
for(var j = 0 ; j < terminal.wires.length ; ++j) {
var wire = terminal.wires[j]
var component = wire.to.parent
if(componentVisited[component] != true && wireVisited[wire] != true) {
componentVisited[component] = true
wireVisited[wire] = true
component.updateOutput(wireVisited)
}
}
}
}
}
}
diff --git a/src/activities/digital_electricity/components/Comparator.qml b/src/activities/digital_electricity/components/Comparator.qml
index fa3faf7fb..a5405c085 100644
--- a/src/activities/digital_electricity/components/Comparator.qml
+++ b/src/activities/digital_electricity/components/Comparator.qml
@@ -1,95 +1,95 @@
/* GCompris - Comparator.qml
*
* Copyright (C) 2016 Pulkit Gupta <pulkitnsit@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitnsit@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
ElectricalComponent {
id: comparator
terminalSize: 0.25
noOfInputs: 2
noOfOutputs: 3
property var inputTerminalPosY: [0.25, 0.75]
property var outputTerminalPosY: [0.13, 0.5, 0.87]
information: qsTr("Comparator takes 2 numbers as input, A and B. It compares them and outputs 3 " +
"values. First output is 1 if A < B, 0 otherwise. Second is 1 " +
"if A = B, 0 otherwise. Third is 1 if A > B, 0 otherwise. ")
truthTable: []
property alias inputTerminals: inputTerminals
property alias outputTerminals: outputTerminals
Repeater {
id: inputTerminals
model: 2
delegate: inputTerminal
Component {
id: inputTerminal
TerminalPoint {
posX: 0.05
posY: inputTerminalPosY[index]
type: "In"
}
}
}
Repeater {
id: outputTerminals
model: 3
delegate: outputTerminal
Component {
id: outputTerminal
TerminalPoint {
posX: 0.95
posY: outputTerminalPosY[index]
type: "Out"
}
}
}
function updateOutput(wireVisited) {
outputTerminals.itemAt(0).value = (inputTerminals.itemAt(0).value < inputTerminals.itemAt(1).value)
outputTerminals.itemAt(1).value = (inputTerminals.itemAt(0).value == inputTerminals.itemAt(1).value)
outputTerminals.itemAt(2).value = (inputTerminals.itemAt(0).value > inputTerminals.itemAt(1).value)
for(var i = 0 ; i < noOfOutputs ; ++i) {
var terminal = outputTerminals.itemAt(i)
for(var j = 0 ; j < terminal.wires.length ; ++j)
terminal.wires[j].to.value = terminal.value
}
var componentVisited = []
for(var i = 0 ; i < noOfOutputs ; ++i) {
var terminal = outputTerminals.itemAt(i)
for(var j = 0 ; j < terminal.wires.length ; ++j) {
var wire = terminal.wires[j]
var component = wire.to.parent
if(componentVisited[component] != true && wireVisited[wire] != true) {
componentVisited[component] = true
wireVisited[wire] = true
component.updateOutput(wireVisited)
}
}
}
}
}
diff --git a/src/activities/digital_electricity/components/DigitalLight.qml b/src/activities/digital_electricity/components/DigitalLight.qml
index 311f72b88..6db0db2a4 100644
--- a/src/activities/digital_electricity/components/DigitalLight.qml
+++ b/src/activities/digital_electricity/components/DigitalLight.qml
@@ -1,59 +1,59 @@
/* GCompris - DigitalLight.qml
*
* Copyright (C) 2016 Pulkit Gupta <pulkitnsit@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitnsit@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../digital_electricity.js" as Activity
ElectricalComponent {
id: digitalLight
terminalSize: 0.25
noOfInputs: 1
noOfOutputs: 0
information: qsTr("Digital light is used to check the output of other digital components. It turns " +
"green if the input is 1, and turns red if the input is 0.")
truthTable: []
property alias inputTerminals: inputTerminals
Repeater {
id: inputTerminals
model: 1
delegate: inputTerminal
Component {
id: inputTerminal
TerminalPoint {
posX: 0.1
posY: 0.5
type: "In"
}
}
}
function updateOutput(wireVisited) {
if(inputTerminals.itemAt(0).value == 1)
imgSrc = "DigitalLightOn.svg"
else
imgSrc = "DigitalLightOff.svg"
}
}
diff --git a/src/activities/digital_electricity/components/ElectricalComponent.qml b/src/activities/digital_electricity/components/ElectricalComponent.qml
index 617d9bd83..a7d6ac5ba 100644
--- a/src/activities/digital_electricity/components/ElectricalComponent.qml
+++ b/src/activities/digital_electricity/components/ElectricalComponent.qml
@@ -1,149 +1,149 @@
/* GCompris - Component.qml
*
* Copyright (C) 2016 Pulkit Gupta <pulkitnsit@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitnsit@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../digital_electricity.js" as Activity
Image {
id: electricalComponent
property double posX
property double posY
property double imgWidth
property double imgHeight
property string imgSrc
property string information
property string toolTipTxt
property var truthTable: []
property int index
property int noOfInputs
property int noOfOutputs
property int rotationAngle: 0
property int initialAngle: 0
property int startingAngle: 0
property double terminalSize
property bool destructible
property alias rotateComponent: rotateComponent
x: posX * parent.width
y: posY * parent.height
width: imgWidth * parent.width
height: imgHeight * parent.height
fillMode: Image.PreserveAspectFit
source: Activity.url + imgSrc
z: 2
mipmap: true
antialiasing: true
onPaintedWidthChanged: {
updateDragConstraints()
Activity.updateWires(index)
}
PropertyAnimation {
id: rotateComponent
target: electricalComponent
property: "rotation"
from: initialAngle; to: initialAngle + rotationAngle
duration: 1
onStarted:{ Activity.animationInProgress = true }
onStopped: {
initialAngle = initialAngle + rotationAngle
Activity.updateWires(index)
if(initialAngle == startingAngle + rotationAngle * 45) {
if(initialAngle == 360 || initialAngle == -360)
initialAngle = 0
startingAngle = initialAngle
Activity.animationInProgress = false
updateDragConstraints()
}
else
rotateComponent.start()
}
easing.type: Easing.InOutQuad
}
function updateDragConstraints() {
if(initialAngle == 0 || initialAngle == 180 || initialAngle == 360 || initialAngle == -360
|| initialAngle == -180) {
mouseArea.drag.minimumX = (electricalComponent.paintedWidth - electricalComponent.width)/2
mouseArea.drag.minimumY = (electricalComponent.paintedHeight - electricalComponent.height)/2
mouseArea.drag.maximumX = electricalComponent.parent.width -
(electricalComponent.width + electricalComponent.paintedWidth)/2
mouseArea.drag.maximumY = electricalComponent.parent.height -
(electricalComponent.height + electricalComponent.paintedHeight)/2
}
else {
mouseArea.drag.minimumX = (electricalComponent.paintedHeight - electricalComponent.width)/2
mouseArea.drag.minimumY = (electricalComponent.paintedWidth - electricalComponent.height)/2
mouseArea.drag.maximumX = electricalComponent.parent.width -
(electricalComponent.width + electricalComponent.paintedHeight)/2
mouseArea.drag.maximumY = electricalComponent.parent.height -
(electricalComponent.height + electricalComponent.paintedWidth)/2
}
}
MouseArea {
id: mouseArea
width: parent.paintedWidth
height: parent.paintedHeight
anchors.centerIn: parent
drag.target: electricalComponent
onPressed: {
Activity.updateToolTip(toolTipTxt)
Activity.componentSelected(index)
}
onClicked: {
if(Activity.toolDelete || Activity.toolDeleteSticky) {
if (destructible) {
Activity.removeComponent(index)
} else {
Activity.deselect()
}
}
else {
if(imgSrc == "switchOff.svg") {
imgSrc = "switchOn.svg"
Activity.updateComponent(index)
}
else if(imgSrc == "switchOn.svg") {
imgSrc = "switchOff.svg"
Activity.updateComponent(index)
}
}
}
onReleased: {
parent.posX = parent.x / parent.parent.width
parent.posY = parent.y / parent.parent.height
Activity.updateToolTip("")
}
onPositionChanged: {
updateDragConstraints()
Activity.updateWires(index)
}
}
}
diff --git a/src/activities/digital_electricity/components/NandGate.qml b/src/activities/digital_electricity/components/NandGate.qml
index b6d0ab4e4..10ccc89da 100644
--- a/src/activities/digital_electricity/components/NandGate.qml
+++ b/src/activities/digital_electricity/components/NandGate.qml
@@ -1,88 +1,88 @@
/* GCompris - NandGate.qml
*
* Copyright (C) 2016 Pulkit Gupta <pulkitnsit@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitnsit@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
ElectricalComponent {
id: nandGate
terminalSize: 0.5
noOfInputs: 2
noOfOutputs: 1
property var inputTerminalPosY: [0.2, 0.8]
information: qsTr("NAND gate outputs the opposite of AND gate. " +
"If all inputs are 1, output is equal to 0 and as soon as one input is equal to 0 it gives a 1:")
truthTable: [['A','B',qsTr("NOT (A AND B)")],
['0','0','1'],
['0','1','1'],
['1','0','1'],
['1','1','0']]
property alias inputTerminals: inputTerminals
property alias outputTerminals: outputTerminals
Repeater {
id: inputTerminals
model: 2
delegate: inputTerminal
Component {
id: inputTerminal
TerminalPoint {
posX: 0.04
posY: inputTerminalPosY[index]
type: "In"
}
}
}
Repeater {
id: outputTerminals
model: 1
delegate: outputTerminal
Component {
id: outputTerminal
TerminalPoint {
posX: 0.96
posY: 0.5
type: "Out"
}
}
}
function updateOutput(wireVisited) {
var terminal = outputTerminals.itemAt(0)
/* Keep the output value == 0 if only one of the input terminals is connected */
terminal.value = (inputTerminals.itemAt(0).wires.length != 0 && inputTerminals.itemAt(1).wires.length != 0) ? !(inputTerminals.itemAt(0).value & inputTerminals.itemAt(1).value) : 0
for(var i = 0 ; i < terminal.wires.length ; ++i)
terminal.wires[i].to.value = terminal.value
var componentVisited = []
for(var i = 0 ; i < terminal.wires.length ; ++i) {
var wire = terminal.wires[i]
var component = wire.to.parent
componentVisited[component] = true
wireVisited[wire] = true
component.updateOutput(wireVisited)
}
}
}
diff --git a/src/activities/digital_electricity/components/NorGate.qml b/src/activities/digital_electricity/components/NorGate.qml
index ea675426d..5c0a65c6c 100644
--- a/src/activities/digital_electricity/components/NorGate.qml
+++ b/src/activities/digital_electricity/components/NorGate.qml
@@ -1,88 +1,88 @@
/* GCompris - NorGate.qml
*
* Copyright (C) 2016 Pulkit Gupta <pulkitnsit@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitnsit@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
ElectricalComponent {
id: norGate
terminalSize: 0.5
noOfInputs: 2
noOfOutputs: 1
property var inputTerminalPosY: [0.2, 0.8]
information: qsTr("NOR gate outputs the opposite of OR gate. As soon as there is a 1 in input the output is equal to 0. " +
"To obtain a 1 all the inputs must be equal to 0:")
truthTable: [['A','B',qsTr("NOT (A OR B)")],
['0','0','1'],
['0','1','0'],
['1','0','0'],
['1','1','0']]
property alias inputTerminals: inputTerminals
property alias outputTerminals: outputTerminals
Repeater {
id: inputTerminals
model: 2
delegate: inputTerminal
Component {
id: inputTerminal
TerminalPoint {
posX: 0.04
posY: inputTerminalPosY[index]
type: "In"
}
}
}
Repeater {
id: outputTerminals
model: 1
delegate: outputTerminal
Component {
id: outputTerminal
TerminalPoint {
posX: 0.96
posY: 0.5
type: "Out"
}
}
}
function updateOutput(wireVisited) {
var terminal = outputTerminals.itemAt(0)
/* Keep the output value == 0 if only one of the input terminals is connected */
terminal.value = (inputTerminals.itemAt(0).wires.length != 0 && inputTerminals.itemAt(1).wires.length != 0) ? !(inputTerminals.itemAt(0).value | inputTerminals.itemAt(1).value) : 0
for(var i = 0 ; i < terminal.wires.length ; ++i)
terminal.wires[i].to.value = terminal.value
var componentVisited = []
for(var i = 0 ; i < terminal.wires.length ; ++i) {
var wire = terminal.wires[i]
var component = wire.to.parent
componentVisited[component] = true
wireVisited[wire] = true
component.updateOutput(wireVisited)
}
}
}
diff --git a/src/activities/digital_electricity/components/NotGate.qml b/src/activities/digital_electricity/components/NotGate.qml
index 7199463ab..47bf1d392 100644
--- a/src/activities/digital_electricity/components/NotGate.qml
+++ b/src/activities/digital_electricity/components/NotGate.qml
@@ -1,87 +1,87 @@
/* GCompris - NotGate.qml
*
* Copyright (C) 2016 Pulkit Gupta <pulkitnsit@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitnsit@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
ElectricalComponent {
id: notGate
terminalSize: 0.5
noOfInputs: 1
noOfOutputs: 1
information: qsTr("Not gate (also known as inverter) outputs the opposite of the input. " +
"Input 0 gives an output 1. Input 1 gives an output 0:")
truthTable: [['A',qsTr("NOT A")],
['0','1'],
['1','0']]
property alias inputTerminals: inputTerminals
property alias outputTerminals: outputTerminals
Repeater {
id: inputTerminals
model: 1
delegate: inputTerminal
Component {
id: inputTerminal
TerminalPoint {
posX: 0.04
posY: 0.5
type: "In"
}
}
}
Repeater {
id: outputTerminals
model: 1
delegate: outputTerminal
Component {
id: outputTerminal
TerminalPoint {
posX: 0.96
posY: 0.5
type: "Out"
}
}
}
function updateOutput(wireVisited) {
var terminal = outputTerminals.itemAt(0)
/* Keep the output value == 0 if only one of the input terminals is connected */
terminal.value = (inputTerminals.itemAt(0).wires.length != 0) ? !inputTerminals.itemAt(0).value : 0
for(var i = 0 ; i < terminal.wires.length ; ++i)
terminal.wires[i].to.value = terminal.value
var componentVisited = []
for(var i = 0 ; i < terminal.wires.length ; ++i) {
var wire = terminal.wires[i]
var component = wire.to.parent
if(componentVisited[component] != true && wireVisited[wire] != true) {
componentVisited[component] = true
wireVisited[wire] = true
component.updateOutput(wireVisited)
}
}
}
}
diff --git a/src/activities/digital_electricity/components/One.qml b/src/activities/digital_electricity/components/One.qml
index 7ef97337c..b4f0f7381 100644
--- a/src/activities/digital_electricity/components/One.qml
+++ b/src/activities/digital_electricity/components/One.qml
@@ -1,69 +1,69 @@
/* GCompris - One.qml
*
* Copyright (C) 2016 Pulkit Gupta <pulkitnsit@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitnsit@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
ElectricalComponent {
id: one
terminalSize: 0.25
noOfInputs: 0
noOfOutputs: 1
information: qsTr("Digital electronics works with only two states: 0 and 1. " +
"This allows to operate mathematical operations such as additions, subtractions... " +
"It is the basics of computer technics. In reality, 0 is often the representation of a voltage nearly equal to ground voltage " +
"and 1 is the representation of the supply voltage of a circuit.")
property alias outputTerminals: outputTerminals
Repeater {
id: outputTerminals
model: 1
delegate: outputTerminal
Component {
id: outputTerminal
TerminalPoint {
posX: 0.9
posY: 0.5
value: 1
type: "Out"
}
}
}
function updateOutput(wireVisited) {
var terminal = outputTerminals.itemAt(0)
for(var i = 0 ; i < terminal.wires.length ; ++i)
terminal.wires[i].to.value = terminal.value
var componentVisited = []
for(var i = 0 ; i < terminal.wires.length ; ++i) {
var wire = terminal.wires[i]
var component = wire.to.parent
if(componentVisited[component] != true && wireVisited[wire] != true) {
componentVisited[component] = true
wireVisited[wire] = true
component.updateOutput(wireVisited)
}
}
}
}
diff --git a/src/activities/digital_electricity/components/OrGate.qml b/src/activities/digital_electricity/components/OrGate.qml
index d5d4dc887..e25c82b4f 100644
--- a/src/activities/digital_electricity/components/OrGate.qml
+++ b/src/activities/digital_electricity/components/OrGate.qml
@@ -1,86 +1,86 @@
/* GCompris - OrGate.qml
*
* Copyright (C) 2016 Pulkit Gupta <pulkitnsit@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitnsit@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
ElectricalComponent {
id: orGate
terminalSize: 0.5
noOfInputs: 2
noOfOutputs: 1
property var inputTerminalPosY: [0.2, 0.8]
information: qsTr("OR gate outputs 1 if any of the inputs is 1, 0 otherwise:")
truthTable: [['A','B',qsTr("A OR B")],
['0','0','0'],
['0','1','1'],
['1','0','1'],
['1','1','1']]
property alias inputTerminals: inputTerminals
property alias outputTerminals: outputTerminals
Repeater {
id: inputTerminals
model: 2
delegate: inputTerminal
Component {
id: inputTerminal
TerminalPoint {
posX: 0.04
posY: inputTerminalPosY[index]
type: "In"
}
}
}
Repeater {
id: outputTerminals
model: 1
delegate: outputTerminal
Component {
id: outputTerminal
TerminalPoint {
posX: 0.96
posY: 0.5
type: "Out"
}
}
}
function updateOutput(wireVisited) {
var terminal = outputTerminals.itemAt(0)
/* Keep the output value == 0 if only one of the input terminals is connected */
terminal.value = (inputTerminals.itemAt(0).wires.length != 0 && inputTerminals.itemAt(1).wires.length != 0) ? (inputTerminals.itemAt(0).value | inputTerminals.itemAt(1).value) : 0
for(var i = 0 ; i < terminal.wires.length ; ++i)
terminal.wires[i].to.value = terminal.value
var componentVisited = []
for(var i = 0 ; i < terminal.wires.length ; ++i) {
var wire = terminal.wires[i]
var component = wire.to.parent
componentVisited[component] = true
wireVisited[wire] = true
component.updateOutput(wireVisited)
}
}
}
diff --git a/src/activities/digital_electricity/components/SevenSegment.qml b/src/activities/digital_electricity/components/SevenSegment.qml
index a02f70b70..909e37275 100644
--- a/src/activities/digital_electricity/components/SevenSegment.qml
+++ b/src/activities/digital_electricity/components/SevenSegment.qml
@@ -1,87 +1,87 @@
/* GCompris - SevenSegment.qml
*
* Copyright (C) 2016 Pulkit Gupta <pulkitnsit@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitnsit@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../digital_electricity.js" as Activity
ElectricalComponent {
id: sevenSegmentDisplay
terminalSize: 0.125
noOfInputs: 7
noOfOutputs: 0
property var inputTerminalPosY: [0.066, 0.211, 0.355, 0.5, 0.645, 0.789, 0.934]
property var redBars: ["sevenSegmentDisplayA.svg","sevenSegmentDisplayB.svg","sevenSegmentDisplayC.svg",
"sevenSegmentDisplayD.svg","sevenSegmentDisplayE.svg","sevenSegmentDisplayF.svg",
"sevenSegmentDisplayG.svg"]
information: qsTr("7 segment display takes 7 binary inputs in its input terminals. The display " +
"consists of 7 segments and each segment gets lighted according to the input. " +
"By generating different combination of binary inputs, the display can be used to " +
"display numbers from 0 to 9 and a few letters. The diagram is:")
property string infoImageSrc: "7SegmentDisplay.svg"
property alias inputTerminals: inputTerminals
Repeater {
id: inputTerminals
model: 7
delegate: inputTerminal
Component {
id: inputTerminal
TerminalPoint {
posX: 0.06
posY: inputTerminalPosY[index]
type: "In"
}
}
}
function updateOutput(wireVisited) {
for(var i = 0 ; i < noOfInputs ; ++i) {
if(inputTerminals.itemAt(i).value == 1)
outputBar.itemAt(i).visible = true;
else
outputBar.itemAt(i).visible = false;
}
}
Repeater {
id: outputBar
model: 7
delegate: outputBarImages
Component {
id: outputBarImages
Image {
source: Activity.url + redBars[index]
visible: false //code[0] == 1
anchors.centerIn: parent
height: parent.height
width: parent.width
fillMode: Image.PreserveAspectFit
mipmap: true
antialiasing: true
}
}
}
}
diff --git a/src/activities/digital_electricity/components/SignalGenerator.qml b/src/activities/digital_electricity/components/SignalGenerator.qml
index 469028f97..ff50f4667 100644
--- a/src/activities/digital_electricity/components/SignalGenerator.qml
+++ b/src/activities/digital_electricity/components/SignalGenerator.qml
@@ -1,166 +1,166 @@
/* GCompris - SignalGenerator.qml
*
* Copyright (C) 2016 Pulkit Gupta <pulkitnsit@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitnsit@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../digital_electricity.js" as Activity
import "../../../core"
ElectricalComponent {
id: signalGenerator
terminalSize: 0.25
noOfInputs: 0
noOfOutputs: 1
information: qsTr("Signal Generator is used to generate alternating signals of 0 and 1. " +
"The time between two changes can be modified by pressing the arrows on the generator.")
property alias outputTerminals: outputTerminals
property double period: 1
property var periodFraction: ["1/4","1/2","1","2"]
property int periodIndex: 2
Repeater {
id: outputTerminals
model: 1
delegate: outputTerminal
Component {
id: outputTerminal
TerminalPoint {
posX: 0.94
posY: 0.5
value: 0
type: "Out"
}
}
}
function updateOutput(wireVisited) {
var terminal = outputTerminals.itemAt(0)
terminal.value = terminal.value == 1 ? 0 : 1
for(var i = 0 ; i < terminal.wires.length ; ++i)
terminal.wires[i].to.value = terminal.value
var componentVisited = []
for(var i = 0 ; i < terminal.wires.length ; ++i) {
var wire = terminal.wires[i]
var component = wire.to.parent
if(componentVisited[component] != true && wireVisited[wire] != true) {
componentVisited[component] = true
wireVisited[wire] = true
component.updateOutput(wireVisited)
}
}
}
Timer {
id: timer
interval: 1000 * signalGenerator.period
running: true
repeat: true
onTriggered: Activity.updateComponent(signalGenerator.index)
}
Image {
source: Activity.url + "arrowUp.svg"
height: 0.437 * parent.height
width: 0.208 * parent.width
sourceSize.height: height
sourceSize.width: width
property double posX: 0.6
property double posY: 0.28
x: (parent.width - parent.paintedWidth) / 2 + posX * parent.paintedWidth - width / 2
y: (parent.height - parent.paintedHeight) / 2 + posY * parent.paintedHeight - height / 2
fillMode: Image.PreserveAspectFit
antialiasing: true
opacity: 0
MouseArea {
anchors.fill: parent
anchors.centerIn: parent
enabled: signalGenerator.period != 2
onPressed: {
parent.opacity = 1
signalGenerator.period *= 2
periodIndex++
timer.restart()
outputTerminals.itemAt(0).value = 1
Activity.updateComponent(signalGenerator.index)
}
onReleased: {
parent.opacity = 0
}
}
}
Image {
source: Activity.url + "arrowDown.svg"
height: 0.437 * parent.height
width: 0.208 * parent.width
sourceSize.height: height
sourceSize.width: width
property double posX: 0.6
property double posY: 0.72
x: (parent.width - parent.paintedWidth) / 2 + posX * parent.paintedWidth - width / 2
y: (parent.height - parent.paintedHeight) / 2 + posY * parent.paintedHeight - height / 2
fillMode: Image.PreserveAspectFit
antialiasing: true
opacity: 0
MouseArea {
anchors.fill: parent
anchors.centerIn: parent
enabled: signalGenerator.period != 0.25
onPressed: {
parent.opacity = 1
signalGenerator.period /= 2
periodIndex--
timer.restart()
outputTerminals.itemAt(0).value = 1
Activity.updateComponent(signalGenerator.index)
}
onReleased: {
parent.opacity = 0
}
}
}
Rectangle {
height: 0.625 * parent.height
width: 0.35 * parent.width
color: "#00000000"
property double posX: 0.25
property double posY: 0.5
x: (parent.width - parent.paintedWidth) / 2 + posX * parent.paintedWidth - width / 2
y: (parent.height - parent.paintedHeight) / 2 + posY * parent.paintedHeight - height / 2
GCText {
id: value
anchors.centerIn: parent
fontSizeMode: Text.Fit
minimumPointSize: 6
font.pointSize: 32
color: "#3f6f71"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
height: parent.height - 10
width: parent.width - 10
text: qsTr("%1 s").arg(signalGenerator.periodFraction[periodIndex])
}
}
}
diff --git a/src/activities/digital_electricity/components/Switch.qml b/src/activities/digital_electricity/components/Switch.qml
index 02413182a..0c030f752 100644
--- a/src/activities/digital_electricity/components/Switch.qml
+++ b/src/activities/digital_electricity/components/Switch.qml
@@ -1,87 +1,87 @@
/* GCompris - Switch.qml
*
* Copyright (C) 2016 Pulkit Gupta <pulkitnsit@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitnsit@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../digital_electricity.js" as Activity
import GCompris 1.0
ElectricalComponent {
id: switchComponent
terminalSize: 0.5
noOfInputs: 1
noOfOutputs: 1
information: qsTr("Switch is used to connect or disconnect two terminals. " +
"If the switch is turned on, current can flow through the switch. " +
"If the switch is turned off, then the connection between terminal is broken and current can not flow through it.")
truthTable: []
property alias inputTerminals: inputTerminals
property alias outputTerminals: outputTerminals
Repeater {
id: inputTerminals
model: 1
delegate: inputTerminal
Component {
id: inputTerminal
TerminalPoint {
posX: 0.04
posY: 0.5
type: "In"
}
}
}
Repeater {
id: outputTerminals
model: 1
delegate: outputTerminal
Component {
id: outputTerminal
TerminalPoint {
posX: 0.96
posY: 0.5
type: "Out"
}
}
}
function updateOutput(wireVisited) {
var terminal = outputTerminals.itemAt(0)
terminal.value = imgSrc == "switchOn.svg" ? inputTerminals.itemAt(0).value : 0
for(var i = 0 ; i < terminal.wires.length ; ++i)
terminal.wires[i].to.value = terminal.value
var componentVisited = []
for(var i = 0 ; i < terminal.wires.length ; ++i) {
var wire = terminal.wires[i]
var component = wire.to.parent
if(componentVisited[component] != true && wireVisited[wire] != true) {
componentVisited[component] = true
wireVisited[wire] = true
component.updateOutput(wireVisited)
}
}
}
}
diff --git a/src/activities/digital_electricity/components/TerminalPoint.qml b/src/activities/digital_electricity/components/TerminalPoint.qml
index 2a9d7af6d..81b9c1624 100644
--- a/src/activities/digital_electricity/components/TerminalPoint.qml
+++ b/src/activities/digital_electricity/components/TerminalPoint.qml
@@ -1,72 +1,72 @@
/* GCompris - TerminalPoint.qml
*
* Copyright (C) 2016 Pulkit Gupta <pulkitnsit@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitnsit@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../digital_electricity.js" as Activity
Image {
id: terminalPoint
property double posX
property double posY
property double size: parent.terminalSize
property bool selected: false
property string type
property int value: 0
property var wires: []
width: size * parent.paintedHeight
height: width
source: Activity.url + "tPoint.svg"
sourceSize.width: width
sourceSize.height: width
antialiasing: true
x: (parent.width - parent.paintedWidth) / 2 + posX * parent.paintedWidth - width / 2
y: (parent.height - parent.paintedHeight) / 2 + posY * parent.paintedHeight - height / 2
property double xCenter: terminalPoint.parent.x + terminalPoint.x + width/2
property double yCenter: terminalPoint.parent.y + terminalPoint.y + height/2
property double xCenterFromComponent: terminalPoint.x + width/2 - terminalPoint.parent.width / 2
property double yCenterFromComponent: terminalPoint.y + height/2 - terminalPoint.parent.height / 2
Rectangle {
id: boundary
anchors.centerIn: terminalPoint
width: terminalPoint.width * 2
height: width
visible: selected
radius: width / 2
color: "#08D050"
z: -1
}
MouseArea {
id: mouseArea
anchors.fill: parent
onPressed: {
selected = true
Activity.terminalPointSelected(terminalPoint)
}
}
}
diff --git a/src/activities/digital_electricity/components/XorGate.qml b/src/activities/digital_electricity/components/XorGate.qml
index 073b0227e..555cd601c 100644
--- a/src/activities/digital_electricity/components/XorGate.qml
+++ b/src/activities/digital_electricity/components/XorGate.qml
@@ -1,86 +1,86 @@
/* GCompris - XorGate.qml
*
* Copyright (C) 2016 Pulkit Gupta <pulkitnsit@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitnsit@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
ElectricalComponent {
id: xorGate
terminalSize: 0.5
noOfInputs: 2
noOfOutputs: 1
property var inputTerminalPosY: [0.2, 0.8]
information: qsTr("XOR gate outputs 1 if the number of '1' in input is odd, and 0 if number of '1' in " +
"input is even. In this activity, a 2 input XOR gate is shown. Output for 2 input XOR gate is:")
truthTable: [['A','B',qsTr("A XOR B")],
['0','0','0'],
['0','1','1'],
['1','0','1'],
['1','1','0']]
property alias inputTerminals: inputTerminals
property alias outputTerminals: outputTerminals
Repeater {
id: inputTerminals
model: 2
delegate: inputTerminal
Component {
id: inputTerminal
TerminalPoint {
posX: 0.04
posY: inputTerminalPosY[index]
type: "In"
}
}
}
Repeater {
id: outputTerminals
model: 1
delegate: outputTerminal
Component {
id: outputTerminal
TerminalPoint {
posX: 0.96
posY: 0.5
type: "Out"
}
}
}
function updateOutput(wireVisited) {
var terminal = outputTerminals.itemAt(0)
terminal.value = inputTerminals.itemAt(0).value ^ inputTerminals.itemAt(1).value
for(var i = 0 ; i < terminal.wires.length ; ++i)
terminal.wires[i].to.value = terminal.value
var componentVisited = []
for(var i = 0 ; i < terminal.wires.length ; ++i) {
var wire = terminal.wires[i]
var component = wire.to.parent
componentVisited[component] = true
wireVisited[wire] = true
component.updateOutput(wireVisited)
}
}
}
diff --git a/src/activities/digital_electricity/components/Zero.qml b/src/activities/digital_electricity/components/Zero.qml
index 2dc77fd28..773a92e64 100644
--- a/src/activities/digital_electricity/components/Zero.qml
+++ b/src/activities/digital_electricity/components/Zero.qml
@@ -1,66 +1,66 @@
/* GCompris - Zero.qml
*
* Copyright (C) 2016 Pulkit Gupta <pulkitnsit@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitnsit@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
ElectricalComponent {
id: zero
terminalSize: 0.25
noOfInputs: 0
noOfOutputs: 1
information: qsTr("Digital electronics works with only two states: 0 and 1. This allows to operate mathematical operations such as additions, subtractions... It is the basics of computer technics. In reality, 0 is often the representation of a voltage nearly equal to ground voltage and 1 is the representation of the supply voltage of a circuit.")
property alias outputTerminals: outputTerminals
Repeater {
id: outputTerminals
model: 1
delegate: outputTerminal
Component {
id: outputTerminal
TerminalPoint {
posX: 0.9
posY: 0.5
value: 0
type: "Out"
}
}
}
function updateOutput(wireVisited) {
var terminal = outputTerminals.itemAt(0)
for(var i = 0 ; i < terminal.wires.length ; ++i)
terminal.wires[i].to.value = terminal.value
var componentVisited = []
for(var i = 0 ; i < terminal.wires.length ; ++i) {
var wire = terminal.wires[i]
var component = wire.to.parent
if(componentVisited[component] != true && wireVisited[wire] != true) {
componentVisited[component] = true
wireVisited[wire] = true
component.updateOutput(wireVisited)
}
}
}
}
diff --git a/src/activities/digital_electricity/digital_electricity.js b/src/activities/digital_electricity/digital_electricity.js
index 935dd5223..73e02b42d 100644
--- a/src/activities/digital_electricity/digital_electricity.js
+++ b/src/activities/digital_electricity/digital_electricity.js
@@ -1,657 +1,657 @@
/* GCompris - digital_electricity.js
*
* Copyright (C) 2016 Pulkit Gupta <pulkitnsit@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitnsit@gmail.com> (Qt Quick port)
* Rudra Nil Basu <rudra.nil.basu.1996@gmail.com> (Qt Quick port)
* Timothée Giet <animtim@gmail.com> (mouse drag refactoring)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
var currentLevel = 1
var numberOfLevel
var items
var url = "qrc:/gcompris/src/activities/digital_electricity/resource/"
var toolDelete
var toolDeleteSticky
var selectedIndex
var animationInProgress
var selectedTerminal
var deletedIndex = []
var components = []
var connected = []
var determiningComponents = []
var processingAnswer
var currentZoom
var maxZoom = 0.375
var minZoom = 0.125
var defaultZoom = 0.25
var zoomStep = 0.0625
var direction = {
LEFT: -1,
RIGHT: 1,
UP: -2,
DOWN: 2
}
var viewPort = {
leftExtreme: 0,
rightExtreme: 1,
topExtreme: 0,
bottomExtreme: 1,
leftEdge: 0,
topEdge: 0
}
function start(items_) {
items = items_
currentLevel = 1
numberOfLevel = items.tutorialDataset.tutorialLevels.length
initLevel()
}
function stop() {
for(var i = 0 ; i < components.length ; ++i) {
var j
for(j = 0 ; j < deletedIndex.length ; ++j) {
if(deletedIndex[j] == i)
break
}
if(j == deletedIndex.length)
removeComponent(i)
}
}
function initLevel() {
items.bar.level = currentLevel
items.availablePieces.view.currentDisplayedGroup = 0
items.availablePieces.view.previousNavigation = 1
items.availablePieces.view.nextNavigation = 1
deletedIndex = []
components = []
connected = []
determiningComponents = []
animationInProgress = false
toolDelete = false
toolDeleteSticky = false
deselect()
updateToolTip("")
items.availablePieces.hideToolbar()
currentZoom = defaultZoom
items.availablePieces.zoomInBtn.state = "canZoomIn"
items.availablePieces.zoomOutBtn.state = "canZoomOut"
viewPort.leftEdge = 0
viewPort.topEdge = 0
items.playArea.x = items.mousePan.drag.maximumX
items.playArea.y = items.mousePan.drag.maximumY
if (!items.isTutorialMode) {
items.tutorialInstruction.index = -1
loadFreeMode()
} else {
// load tutorial levels from dataset
processingAnswer = false
var levelProperties = items.tutorialDataset.tutorialLevels[currentLevel - 1]
for (var i = 0; i < levelProperties.inputComponentList.length; i++) {
var currentInputComponent = levelProperties.inputComponentList[i]
items.availablePieces.model.append( {
"imgName": currentInputComponent.imageName,
"componentSrc": currentInputComponent.componentSource,
"imgWidth": currentInputComponent.width,
"imgHeight": currentInputComponent.height,
"toolTipText": currentInputComponent.toolTipText
})
}
for (var i = 0; i < levelProperties.playAreaComponentList.length; i++) {
var index = components.length
var currentPlayAreaComponent = levelProperties.playAreaComponentList[i]
var staticElectricalComponent = Qt.createComponent("qrc:/gcompris/src/activities/digital_electricity/components/" + currentPlayAreaComponent.componentSource)
components[index] = staticElectricalComponent.createObject(
items.playArea, {
"index": index,
"posX": levelProperties.playAreaComponentPositionX[i] * currentZoom,
"posY": levelProperties.playAreaComponentPositionY[i] * currentZoom,
"imgSrc": currentPlayAreaComponent.imageName,
"toolTipTxt": currentPlayAreaComponent.toolTipText,
"imgWidth": currentPlayAreaComponent.width * currentZoom,
"imgHeight": currentPlayAreaComponent.height * currentZoom,
"destructible": false
});
}
var _determiningComponentsIndex = levelProperties.determiningComponentsIndex
for (var i = 0; i < _determiningComponentsIndex.length; i++) {
determiningComponents[determiningComponents.length] = components[_determiningComponentsIndex[i]]
}
// creating wires
for (i = 0; i < levelProperties.wires.length; i++) {
var terminal_number = levelProperties.wires[i][1]
var outTerminal = components[levelProperties.wires[i][0]].outputTerminals.itemAt(terminal_number)
terminal_number = levelProperties.wires[i][3]
var inTerminal = components[levelProperties.wires[i][2]].inputTerminals.itemAt(terminal_number)
createWire(inTerminal, outTerminal, false)
}
if (levelProperties.introMessage.length != 0) {
items.tutorialInstruction.index = 0
items.tutorialInstruction.intro = levelProperties.introMessage
} else {
items.tutorialInstruction.index = -1
}
}
}
function loadFreeMode() {
var componentList = items.tutorialDataset.componentList
for (var i = 0; i < componentList.length; i++) {
items.availablePieces.model.append( {
"imgName": componentList[i].imageName,
"componentSrc": componentList[i].componentSource,
"imgWidth": componentList[i].width,
"imgHeight": componentList[i].height,
"toolTipText": componentList[i].toolTipText
})
}
}
function checkAnswer() {
if (processingAnswer)
return
processingAnswer = true
var problemType = items.tutorialDataset.tutorialLevels[currentLevel - 1].type
var levelProperties = items.tutorialDataset.tutorialLevels[currentLevel - 1]
if (problemType == items.tutorialDataset.problemType.lightTheBulb) {
if (determiningComponents[0].inputTerminals.itemAt(0).value == 1) {
items.bonus.good('tux')
} else {
items.bonus.bad('tux')
processingAnswer = false
}
} else if (problemType == items.tutorialDataset.problemType.equation1Variable) {
var switch1 = determiningComponents[0]
var digitalLight = determiningComponents[1]
var switch1InitialState = switch1.imgSrc
for (var A = 0; A <= 1; A++) {
switch1.imgSrc = A == 1 ? "switchOn.svg" : "switchOff.svg"
updateComponent(switch1.index)
var operationResult = !A
if (operationResult != digitalLight.inputTerminals.itemAt(0).value) {
switch1.imgSrc = switch1InitialState
updateComponent(switch1.index)
items.bonus.bad('tux')
processingAnswer = false
return
}
}
items.bonus.good('tux')
} else if (problemType == items.tutorialDataset.problemType.equation2Variables) {
var digitalLight = determiningComponents[determiningComponents.length - 1]
var switch1 = determiningComponents[0]
var switch2 = determiningComponents[1]
var switch1InitialState = switch1.imgSrc
var switch2InitialState = switch2.imgSrc
for (var A = 0; A <= 1; A++) {
for (var B = 0; B <= 1; B++) {
switch1.imgSrc = A == 1 ? "switchOn.svg" : "switchOff.svg"
switch2.imgSrc = B == 1 ? "switchOn.svg" : "switchOff.svg"
updateComponent(switch1.index)
updateComponent(switch2.index)
var operationResult = levelProperties.result(A, B)
if (operationResult != digitalLight.inputTerminals.itemAt(0).value) {
switch1.imgSrc = switch1InitialState
switch2.imgSrc = switch2InitialState
updateComponent(switch1.index)
updateComponent(switch2.index)
items.bonus.bad('tux')
processingAnswer = false
return
}
}
}
items.bonus.good('tux')
} else if (problemType == items.tutorialDataset.problemType.equation3Variables) {
var switch1 = determiningComponents[0]
var switch2 = determiningComponents[1]
var switch3 = determiningComponents[2]
var digitalLight = determiningComponents[3]
var switch1InitialState = switch1.imgSrc
var switch2InitialState = switch2.imgSrc
var switch3InitialState = switch3.imgSrc
for (var A = 0; A <= 1; A++) {
for (var B = 0; B <= 1; B++) {
for (var C = 0; C <= 1; C++) {
switch1.imgSrc = A == 1 ? "switchOn.svg" : "switchOff.svg"
switch2.imgSrc = B == 1 ? "switchOn.svg" : "switchOff.svg"
switch3.imgSrc = C == 1 ? "switchOn.svg" : "switchOff.svg"
updateComponent(switch1.index)
updateComponent(switch2.index)
updateComponent(switch3.index)
var operationResult = levelProperties.result(A, B, C)
if (operationResult != digitalLight.inputTerminals.itemAt(0).value) {
switch1.imgSrc = switch1InitialState
switch2.imgSrc = switch2InitialState
switch3.imgSrc = switch3InitialState
updateComponent(switch1.index)
updateComponent(switch2.index)
updateComponent(switch3.index)
processingAnswer = false
items.bonus.bad('tux')
return
}
}
}
}
items.bonus.good('tux')
} else if (problemType == items.tutorialDataset.problemType.others) {
if (currentLevel == 20) {
var bcdToSevenSegment = determiningComponents[0]
var decimalValue =
bcdToSevenSegment.inputTerminals.itemAt(3).value +
(bcdToSevenSegment.inputTerminals.itemAt(2).value * 2) +
(bcdToSevenSegment.inputTerminals.itemAt(1).value * 4) +
(bcdToSevenSegment.inputTerminals.itemAt(0).value * 8)
if (decimalValue == 6) {
items.bonus.good('tux')
return
}
items.bonus.bad('tux')
processingAnswer = false
return
} else if (currentLevel == 21) {
var bcdCounter = determiningComponents[0]
var bcdOutput =
bcdCounter.outputTerminals.itemAt(3).value +
bcdCounter.outputTerminals.itemAt(2).value * 2 +
bcdCounter.outputTerminals.itemAt(1).value * 4 +
bcdCounter.outputTerminals.itemAt(0).value * 8
var bcdToSevenSegment = determiningComponents[1]
var decimalValue =
bcdToSevenSegment.inputTerminals.itemAt(3).value +
(bcdToSevenSegment.inputTerminals.itemAt(2).value * 2) +
(bcdToSevenSegment.inputTerminals.itemAt(1).value * 4) +
(bcdToSevenSegment.inputTerminals.itemAt(0).value * 8)
if (bcdCounter.inputTerminals.itemAt(0).wires.length == 0 ||
bcdCounter.outputTerminals.itemAt(0).wires.length == 0 ||
bcdCounter.outputTerminals.itemAt(1).wires.length == 0 ||
bcdCounter.outputTerminals.itemAt(2).wires.length == 0 ||
bcdCounter.outputTerminals.itemAt(3).wires.length == 0) {
items.bonus.bad('tux')
processingAnswer = false
return
}
if ((bcdOutput == decimalValue) && (bcdCounter.inputTerminals.itemAt(0).wires.length != 0) ) {
items.bonus.good('tux')
return
}
items.bonus.bad('tux')
processingAnswer = false
}
}
}
function zoomIn() {
var previousZoom = currentZoom
currentZoom += zoomStep
if (currentZoom > maxZoom)
currentZoom = maxZoom
var zoomRatio = currentZoom / previousZoom
updateComponentDimension(zoomRatio)
if (currentZoom == maxZoom) {
items.availablePieces.zoomInBtn.state = "cannotZoomIn"
} else {
items.availablePieces.zoomInBtn.state = "canZoomIn"
}
items.availablePieces.zoomOutBtn.state = "canZoomOut"
if (items.zoomLvl < 0.5) {
items.zoomLvl += 0.125
}
}
function zoomOut() {
var previousZoom = currentZoom
currentZoom -= zoomStep
if (currentZoom < minZoom)
currentZoom = minZoom
var zoomRatio = currentZoom / previousZoom
updateComponentDimension(zoomRatio)
if (currentZoom == minZoom) {
items.availablePieces.zoomOutBtn.state = "cannotZoomOut"
} else {
items.availablePieces.zoomOutBtn.state = "canZoomOut"
}
items.availablePieces.zoomInBtn.state = "canZoomIn"
if (items.zoomLvl > 0) {
items.zoomLvl -= 0.125
}
}
function updateComponentDimension(zoomRatio) {
for (var i = 0; i < components.length; i++) {
components[i].posX *= zoomRatio
components[i].posY *= zoomRatio
components[i].imgWidth *= zoomRatio
components[i].imgHeight *= zoomRatio
}
}
function nextLevel() {
if(numberOfLevel < ++currentLevel) {
currentLevel = 1
}
reset();
}
function previousLevel() {
if(--currentLevel < 1) {
currentLevel = numberOfLevel
}
reset();
}
function reset() {
stop()
items.availablePieces.model.clear()
initLevel()
}
// Creates component from ListWidget to the drawing board area
function createComponent(x, y, componentIndex) {
x = x / items.playArea.width
y = y / items.playArea.height
var index
if(deletedIndex.length > 0) {
index = deletedIndex[deletedIndex.length - 1]
deletedIndex.pop()
}
else
index = components.length
var component = items.availablePieces.repeater.itemAt(componentIndex)
var electricComponent = Qt.createComponent("qrc:/gcompris/src/activities/digital_electricity/components/" +
component.source)
//console.log("Error loading component:", electricComponent.errorString())
components[index] = electricComponent.createObject(
items.playArea, {
"index": index,
"posX": x,
"posY": y,
"imgSrc": component.imageName,
"toolTipTxt": component.toolTipTxt,
"imgWidth": component.imageWidth * currentZoom,
"imgHeight": component.imageHeight * currentZoom,
"destructible": true
});
toolDeleteSticky = false
deselect()
componentSelected(index)
updateComponent(index)
}
/* Creates wire between two terminals. Condition for creation of wire is that an input terminal
* can only be connected to 1 wire, output terminals can be connected by any number of wires, and
* an input terminal can be connected with an output terminal only. 'connected' variable is used
* to make sure that an input is connected by only 1 wire.
*/
function terminalPointSelected(terminal) {
if(selectedTerminal == -1 || selectedTerminal == terminal)
selectedTerminal = terminal
else if((selectedTerminal.type != terminal.type) && (selectedTerminal.parent != terminal.parent)) {
var inTerminal = terminal.type == "In" ? terminal : selectedTerminal
var outTerminal = terminal.type == "Out" ? terminal : selectedTerminal
if(connected[inTerminal] == undefined || connected[inTerminal] == -1) {
createWire(inTerminal, outTerminal, true)
}
deselect()
}
else {
deselect()
selectedTerminal = terminal
terminal.selected = true
}
}
function createWire(inTerminal, outTerminal, destructible) {
var wireComponent = Qt.createComponent("qrc:/gcompris/src/activities/digital_electricity/Wire.qml")
var wire = wireComponent.createObject(
items.playArea, {
"from": outTerminal,
"to": inTerminal,
"destructible": destructible
});
inTerminal.value = outTerminal.value
inTerminal.wires.push(wire)
outTerminal.wires.push(wire)
updateWires(inTerminal.parent.index)
updateWires(outTerminal.parent.index)
updateComponent(inTerminal.parent.index)
connected[inTerminal] = outTerminal
}
/* Updates the output of the component. 'wireVisited' is used to update the value of
* each wire once which will avoid updating the outputs of components in an infinite loop.
*/
function updateComponent(index) {
var wireVisited = []
components[index].updateOutput(wireVisited)
}
/* Updates the orientation of the wire. It is called whenever a new wire is created or
* an object is rotated.
*/
function updateWires(index) {
var component = components[index]
if(component == undefined || component.noOfInputs == undefined || component.noOfOutputs == undefined)
return
var rotatedAngle = component.initialAngle * Math.PI / 180
for(var i = 0 ; i < component.noOfInputs ; ++i) {
var terminal = component.inputTerminals.itemAt(i)
if(terminal.wires.length != 0) {
var wire = terminal.wires[0]
var otherAngle = wire.from.parent.initialAngle * Math.PI / 180
var x = wire.from.xCenterFromComponent
var y = wire.from.yCenterFromComponent
var x1 = wire.from.xCenter - x + x * Math.cos(otherAngle) - y * Math.sin(otherAngle)
var y1 = wire.from.yCenter - y + x * Math.sin(otherAngle) + y * Math.cos(otherAngle)
x = terminal.xCenterFromComponent
y = terminal.yCenterFromComponent
var x2 = terminal.xCenter - x + x * Math.cos(rotatedAngle) - y * Math.sin(rotatedAngle)
var y2 = terminal.yCenter - y + x * Math.sin(rotatedAngle) + y * Math.cos(rotatedAngle)
var width = Math.pow((Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2)),0.5) + 2
var angle = (180/Math.PI)*Math.atan((y2-y1)/(x2-x1))
if(x2 - x1 < 0) angle = angle - 180
wire.x = x1
wire.y = y1 - wire.height / 2
wire.width = width
wire.rotation = angle
}
}
for(var i = 0 ; i < component.noOfOutputs ; ++i) {
var terminal = component.outputTerminals.itemAt(i)
for(var j = 0 ; j < terminal.wires.length ; ++j) {
var x = terminal.xCenterFromComponent
var y = terminal.yCenterFromComponent
var x1 = terminal.xCenter - x + x * Math.cos(rotatedAngle) - y * Math.sin(rotatedAngle)
var y1 = terminal.yCenter - y + x * Math.sin(rotatedAngle) + y * Math.cos(rotatedAngle)
var wire = terminal.wires[j]
var otherAngle = wire.to.parent.initialAngle * Math.PI / 180
x = wire.to.xCenterFromComponent
y = wire.to.yCenterFromComponent
var x2 = wire.to.xCenter - x + x * Math.cos(otherAngle) - y * Math.sin(otherAngle)
var y2 = wire.to.yCenter - y + x * Math.sin(otherAngle) + y * Math.cos(otherAngle)
var width = Math.pow((Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2)),0.5) + 2
var angle = (180/Math.PI)*Math.atan((y2-y1)/(x2-x1))
if(x2 - x1 < 0)
angle = angle - 180
wire.x = x1
wire.y = y1
wire.width = width
wire.rotation = angle
}
}
}
function deselect() {
if(toolDeleteSticky == false) {
toolDelete = false
items.availablePieces.toolDelete.state = "notSelected"
}
items.availablePieces.rotateLeft.state = "canNotBeSelected"
items.availablePieces.rotateRight.state = "canNotBeSelected"
items.availablePieces.info.state = "canNotBeSelected"
items.infoTxt.visible = false
selectedIndex = -1
selectedTerminal = -1
for(var i = 0 ; i < components.length ; ++i) {
var component = components[i]
for(var j = 0 ; j < component.noOfInputs ; ++j)
component.inputTerminals.itemAt(j).selected = false
for(var j = 0 ; j < component.noOfOutputs ; ++j)
component.outputTerminals.itemAt(j).selected = false
}
}
function removeComponent(index) {
var component = components[index]
for(var i = 0 ; i < component.noOfInputs ; ++i) {
var terminal = component.inputTerminals.itemAt(i)
if(terminal.wires.length != 0) // Input Terminal can have only 1 wire
removeWire(terminal.wires[0])
}
for(var i = 0 ; i < component.noOfOutputs ; ++i) {
var terminal = component.outputTerminals.itemAt(i)
while (terminal.wires.length != 0) {
removeWire(terminal.wires[0]) // Output Terminal can have more than 1 wire
}
}
components[index].destroy()
deletedIndex.push(index)
deselect()
}
function removeWire(wire) {
var inTerminal = wire.to
var outTerminal = wire.from
var removeIndex = inTerminal.wires.indexOf(wire)
inTerminal.wires.splice(removeIndex, 1)
removeIndex = outTerminal.wires.indexOf(wire)
outTerminal.wires.splice(removeIndex, 1)
connected[wire.to] = -1
inTerminal.value = 0
wire.destroy()
updateComponent(inTerminal.parent.index)
deselect()
}
function componentSelected(index) {
selectedIndex = index
items.availablePieces.rotateLeft.state = "canBeSelected"
items.availablePieces.rotateRight.state = "canBeSelected"
items.availablePieces.info.state = "canBeSelected"
}
function rotateLeft() {
components[selectedIndex].rotationAngle = -2
components[selectedIndex].rotateComponent.start()
}
function rotateRight() {
components[selectedIndex].rotationAngle = 2
components[selectedIndex].rotateComponent.start()
}
function displayInfo() {
var component = components[selectedIndex]
var componentTruthTable = component.truthTable
deselect()
items.infoTxt.visible = true
items.infoTxt.text = component.information
if(component.infoImageSrc != undefined) {
items.infoImage.imgVisible = true
items.infoImage.source = url + component.infoImageSrc
}
else {
items.infoImage.imgVisible = false
items.infoImage.source = ""
}
if(componentTruthTable.length == 0)
items.displayTruthTable = false
else {
items.displayTruthTable = true
var truthTable = items.truthTablesModel
truthTable.clear()
truthTable.rows = componentTruthTable.length
truthTable.columns = componentTruthTable[0].length
truthTable.inputs = component.noOfInputs
truthTable.outputs = component.noOfOutputs
for(var i = 0 ; i < componentTruthTable.length ; ++i)
for(var j = 0 ; j < componentTruthTable[i].length ; ++j)
truthTable.append({'value': componentTruthTable[i][j]})
}
}
function updateToolTip(toolTipTxt) {
items.toolTip.show(toolTipTxt)
}
diff --git a/src/activities/drawletters/ActivityInfo.qml b/src/activities/drawletters/ActivityInfo.qml
index da6c398a5..92a5a7029 100644
--- a/src/activities/drawletters/ActivityInfo.qml
+++ b/src/activities/drawletters/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2016 Nitish Chauhan <nitish.nc18@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "drawletters/Drawletters.qml"
difficulty: 1
icon: "drawletters/drawletters.svg"
author: "Nitish Chauhan &lt;nitish.nc18@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Draw Letters")
//: Help title
description: qsTr("Connect the dots to draw letters")
// intro: "Click on the selected points and draw the letter"
//: Help goal
goal: qsTr("Learning how to draw the letters in a funny way.")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("Draw the letter by connecting the dots in the correct order")
credit: ""
section: "reading"
createdInVersion: 7000
}
diff --git a/src/activities/drawletters/Drawletters.qml b/src/activities/drawletters/Drawletters.qml
index cdceec4b7..4a3d382f5 100644
--- a/src/activities/drawletters/Drawletters.qml
+++ b/src/activities/drawletters/Drawletters.qml
@@ -1,33 +1,33 @@
/* GCompris - drawletters.qml
*
* Copyright (C) 2016 NITISH CHAUHAN <nitish.nc18@gmail.com>
*
* Authors:
*
* Nitish Chauhan <nitish.nc18@gmail.com> (Qt Quick port)
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../number_sequence"
import "../../core" as Core
import "drawletters_dataset.js" as Dataset
NumberSequence {
mode: "drawletters"
dataset: Dataset
pointImageOpacity: 0
url: "qrc:/gcompris/src/activities/drawletters/resource/"
}
diff --git a/src/activities/drawletters/drawletters_dataset.js b/src/activities/drawletters/drawletters_dataset.js
index af49b95a9..5b70a3fee 100644
--- a/src/activities/drawletters/drawletters_dataset.js
+++ b/src/activities/drawletters/drawletters_dataset.js
@@ -1,193 +1,193 @@
/* GCompris - drawletters_dataset.js
* Copyright (C) 2016 Nitish Chauhan <nitish.nc18@gmail.com>
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.import GCompris 1.0 as GCompris //for ApplicationInfo
.import "qrc:/gcompris/src/core/core.js" as Core
function get() {
return [
{
"imageName1": "paper.svg",
"imageName2": "A1.svg",
"coordinates": [[136,402],[154,359],[171,316],[189,276],[207,230],[225,187],[242,144],[260,101],[278,58],[296,101],[314,144],[332,187],[350,230],[368,276],[386,316],[403,359],[420,402],[187,286],[235,286],[282,286],[330,286],[378,286]],
"coordinates2": [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2],
"sound": GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/"+ Core.getSoundFilenamForChar("a"))
},
{
"imageName1": "paper.svg",
"imageName2": "B1.svg",
"coordinates": [[190,59],[190,93],[190,126],[190,165],[190,212],[190,263],[190,308],[190,342],[190,375],[190,409],[223,77],[262,77],[300,78],[340,80],[384,91],[417,114],[433,154],[427,194],[388,226],[360,235],[328,242],[291,240],[262,235],[234,234],[223,234],[251,246],[288,248],[322,248],[358,249],[394,263],[427,291],[440,322],[441,357],[417,390],[375,406],[346,411],[307,413],[267,413],[244,413],[215,409]],
"coordinates2": [1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2],
"sound": GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/"+ Core.getSoundFilenamForChar("b"))
},
{
"imageName1": "paper.svg",
"imageName2": "C1.svg",
"coordinates": [[435,160],[420,135],[391,110],[353,91],[318,86],[289,86],[255,93],[220,108],[184,136],[162,166],[147,211],[148,249],[157,282],[175,314],[198,340],[233,360],[278,372],[318,372],[361,362],[406,342],[427,315],[442,284]],
"sound": GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/"+ Core.getSoundFilenamForChar("c"))
},
{
"imageName1": "paper.svg",
"imageName2": "D1.svg",
"coordinates": [[110,67],[110,98],[110,132],[110,173],[110,220],[110,267],[110,305],[110,347],[110,383],[110,410],[146,73],[184,78],[219,80],[255,81],[292,85],[328,90],[373,100],[408,118],[434,144],[456,174],[471,220],[475,268],[467,315],[437,356],[398,385],[346,401],[307,406],[260,409],[219,409],[190,409],[157,407]],
"coordinates2": [1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2],
"sound": GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/"+ Core.getSoundFilenamForChar("d"))
},
{
"imageName1": "paper.svg",
"imageName2": "E1.svg",
"coordinates": [[161,62],[161,95],[161,133],[161,175],[161,216],[161,256],[161,296],[161,336],[161,377],[186,78],[212,78],[242,78],[274,78],[304,78],[335,78],[368,78],[405,78],[186,220],[217,220],[253,220],[289,220],[322,220],[353,220],[390,220],[193,366],[222,366],[252,366],[285,366],[313,366],[346,366],[377,366],[408,366]],
"coordinates2": [1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4],
"sound": GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/"+ Core.getSoundFilenamForChar("e"))
},
{
"imageName1": "paper.svg",
"imageName2": "F1.svg",
"coordinates": [[176,81],[176,107],[176,140],[176,180],[176,215],[176,256],[176,304],[176,339],[176,379],[176,415],[201,96],[230,96],[257,96],[291,96],[318,96],[343,96],[373,96],[411,96],[204,249],[227,249],[256,249],[292,249],[324,249],[357,249],[391,249]],
"coordinates2": [1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3],
"sound": GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/"+ Core.getSoundFilenamForChar("f"))
},
{
"imageName1": "paper.svg",
"imageName2": "G1.svg",
"coordinates": [[446,147],[434,124],[411,97],[383,82],[347,70],[317,66],[275,73],[242,86],[208,107],[183,136],[164,172],[161,206],[165,256],[179,297],[206,328],[238,350],[282,366],[320,369],[362,366],[397,355],[428,344],[456,315],[455,288],[455,262],[455,234],[423,235],[395,235],[369,235],[339,235]],
"sound": GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/"+ Core.getSoundFilenamForChar("g"))
},
{
"imageName1": "paper.svg",
"imageName2": "H1.svg",
"coordinates": [[165,71],[165,107],[165,160],[165,194],[165,235],[165,267],[165,310],[165,344],[165,379],[165,400],[182,228],[206,230],[240,230],[268,230],[296,230],[325,230],[350,230],[379,230],[404,230],[416,75],[416,104],[416,136],[416,169],[416,213],[416,262],[416,299],[416,340],[416,368],[416,393]],
"coordinates2": [1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3],
"sound": GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/"+ Core.getSoundFilenamForChar("h"))
},
{
"imageName1": "paper.svg",
"imageName2": "I1.svg",
"coordinates": [[248,78],[248,106],[248,148],[248,184],[248,220],[248,251],[248,282],[248,320],[248,357],[248,391],[248,409]],
"sound": GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/"+ Core.getSoundFilenamForChar("i"))
},
{
"imageName1": "paper.svg",
"imageName2": "J1.svg",
"coordinates": [[369,71],[369,102],[369,136],[369,179],[369,224],[369,270],[369,306],[368,346],[348,375],[311,391],[277,394],[241,384],[213,348],[205,321]],
"sound": GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/"+ Core.getSoundFilenamForChar("j"))
},
{
"imageName1": "paper.svg",
"imageName2": "K1.svg",
"coordinates": [[160,64],[160,102],[160,146],[160,190],[160,240],[160,281],[160,325],[160,366],[160,402],[160,402],[160,437],[186,273],[224,246],[257,219],[285,195],[315,169],[346,144],[375,124],[411,95],[444,68],[286,224],[310,257],[333,289],[366,318],[387,348],[411,373],[434,406],[459,434]],
"coordinates2": [1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3],
"sound": GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/"+ Core.getSoundFilenamForChar("k"))
},
{
"imageName1": "paper.svg",
"imageName2": "L1.svg",
"coordinates": [[177,64],[177,110],[177,158],[177,206],[177,264],[177,315],[177,365],[177,406],[177,420],[211,420],[245,420],[286,420],[326,420],[361,420],[404,420]],
"sound": GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/"+ Core.getSoundFilenamForChar("l"))
},
{
"imageName1": "paper.svg",
"imageName2": "M1.svg",
"coordinates": [[144,413],[144,377],[144,337],[144,297],[144,263],[144,227],[144,194],[144,148],[144,106],[144,73],[186,103],[198,137],[211,175],[222,204],[234,234],[249,263],[259,291],[274,325],[286,360],[302,393],[311,413],[325,379],[339,344],[354,311],[364,280],[376,246],[387,217],[401,184],[413,150],[426,115],[446,82],[462,114],[462,142],[462,171],[462,201],[462,233],[462,266],[462,306],[462,340],[462,372],[462,405]],
"sound": GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/"+ Core.getSoundFilenamForChar("m"))
},
{
"imageName1": "paper.svg",
"imageName2": "N1.svg",
"coordinates": [[186,376],[186,349],[186,324],[186,302],[186,279],[186,255],[186,226],[186,195],[186,172],[186,146],[186,127],[186,96],[206,118],[219,130],[234,150],[250,168],[265,185],[280,201],[295,223],[313,243],[327,260],[345,287],[368,312],[390,334],[410,349],[431,368],[431,343],[431,328],[431,296],[431,267],[431,245],[431,220],[431,194],[431,163],[431,137],[431,111],[431,96]],
"sound": GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/"+ Core.getSoundFilenamForChar("n"))
},
{
"imageName1": "paper.svg",
"imageName2": "O1.svg",
"coordinates": [[291,71],[326,77],[360,89],[393,108],[417,132],[440,168],[452,209],[457,251],[453,302],[441,335],[426,369],[394,394],[357,415],[322,430],[284,430],[246,424],[215,411],[184,394],[160,364],[140,331],[125,292],[118,246],[131,195],[144,155],[165,122],[193,96],[228,78],[270,66]],
"sound": GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/"+ Core.getSoundFilenamForChar("o"))
},
{
"imageName1": "paper.svg",
"imageName2": "P1.svg",
"coordinates": [[154,56],[154,99],[154,132],[154,172],[154,212],[154,273],[154,324],[154,361],[154,400],[154,435],[169,73],[212,73],[248,74],[286,74],[324,78],[371,81],[420,96],[457,121],[477,161],[480,209],[455,249],[412,267],[380,273],[344,277],[308,277],[271,278],[235,275],[208,277],[184,277]],
"coordinates2": [1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2],
"sound": GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/"+ Core.getSoundFilenamForChar("p"))
},
{
"imageName1": "paper.svg",
"imageName2": "Q1.svg",
"coordinates": [[321,107],[358,108],[393,122],[430,153],[456,193],[464,233],[466,270],[455,308],[423,347],[390,368],[346,382],[297,382],[260,376],[222,360],[193,332],[175,303],[161,270],[160,226],[172,188],[195,148],[233,120],[271,107],[299,99],[329,324],[360,337],[390,350],[413,366],[444,383],[473,397],[492,406]],
"coordinates2": [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2],
"sound": GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/"+ Core.getSoundFilenamForChar("q"))
},
{
"imageName1": "paper.svg",
"imageName2": "R1.svg",
"coordinates": [[143,86],[146,120],[146,160],[146,202],[146,246],[146,300],[146,344],[146,391],[146,428],[177,99],[212,100],[246,100],[286,100],[329,100],[377,118],[415,147],[428,191],[412,238],[364,256],[311,266],[268,266],[228,263],[202,259],[177,260],[202,277],[234,275],[273,280],[308,292],[339,322],[368,351],[387,379],[415,405],[437,428]],
"coordinates2": [1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2],
"sound": GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/"+ Core.getSoundFilenamForChar("r"))
},
{
"imageName1": "paper.svg",
"imageName2": "S1.svg",
"coordinates": [[448,175],[434,148],[404,125],[366,110],[320,103],[277,104],[245,117],[202,132],[179,162],[176,200],[204,223],[248,237],[281,246],[325,253],[382,264],[423,277],[452,304],[456,343],[423,371],[382,388],[329,394],[284,390],[240,383],[205,368],[171,346],[148,307]],
"sound": GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/"+ Core.getSoundFilenamForChar("s"))
},
{
"imageName1": "paper.svg",
"imageName2": "T1.svg",
"coordinates": [[150,85],[194,85],[233,85],[271,85],[313,85],[350,85],[394,85],[434,85],[304,111],[304,153],[304,186],[304,222],[304,262],[304,303],[304,344],[304,384],[304,424]],
"coordinates2": [1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2],
"sound": GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/"+ Core.getSoundFilenamForChar("t"))
},
{
"imageName1": "paper.svg",
"imageName2": "U1.svg",
"coordinates": [[151,77],[151,118],[151,160],[151,195],[151,234],[151,275],[151,311],[171,351],[198,380],[242,400],[278,404],[320,402],[360,388],[395,369],[423,329],[430,284],[430,237],[430,201],[430,168],[430,136],[430,104],[430,78]],
"sound": GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/"+ Core.getSoundFilenamForChar("u"))
},
{
"imageName1": "paper.svg",
"imageName2": "V1.svg",
"coordinates": [[188,110],[198,134],[205,156],[214,183],[224,207],[230,228],[239,254],[249,277],[260,303],[272,335],[284,359],[298,387],[315,352],[325,321],[341,280],[356,242],[367,212],[382,173],[395,143],[405,111]],
"sound": GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/"+ Core.getSoundFilenamForChar("v"))
},
{
"imageName1": "paper.svg",
"imageName2": "W1.svg",
"coordinates": [[124,110],[134,142],[144,175],[154,207],[164,240],[174,272],[184,305],[194,337],[204,370],[214,337],[224,305],[234,272],[244,240],[254,207],[264,175],[274,142],[284,110],[294,142],[304,175],[314,207],[324,240],[334,272],[344,305],[354,337],[364,370],[374,337],[384,305],[394,272],[404,240],[414,207],[424,175],[434,142],[444,110]],
"sound": GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/"+ Core.getSoundFilenamForChar("w"))
},
{
"imageName1": "paper.svg",
"imageName2": "X1.svg",
"coordinates": [[173,93],[191,115],[206,140],[224,161],[244,184],[267,212],[295,240],[313,267],[333,295],[355,321],[379,348],[400,373],[423,400],[424,92],[404,125],[380,153],[357,180],[332,211],[311,235],[277,275],[252,303],[226,333],[204,358],[186,379],[161,408]],
"coordinates2": [1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2],
"sound": GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/"+ Core.getSoundFilenamForChar("x"))
},
{
"imageName1": "paper.svg",
"imageName2": "Y1.svg",
"coordinates": [[165,91],[180,122],[200,154],[219,183],[235,213],[260,253],[285,292],[308,267],[331,234],[343,211],[360,186],[375,158],[388,136],[411,99],[289,303],[289,339],[289,371],[289,395],[289,420],[289,446]],
"coordinates2": [1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2],
"sound": GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/"+ Core.getSoundFilenamForChar("y"))
},
{
"imageName1": "paper.svg",
"imageName2": "Z1.svg",
"coordinates": [[180,146],[219,146],[252,146],[289,146],[328,146],[368,146],[413,146],[455,146],[427,179],[398,206],[375,228],[350,251],[321,274],[286,303],[256,332],[217,358],[177,384],[217,382],[253,384],[289,384],[320,384],[357,384],[394,384],[431,384],[475,384]],
"sound": GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/"+ Core.getSoundFilenamForChar("z"))
}
]
}
diff --git a/src/activities/drawnumbers/ActivityInfo.qml b/src/activities/drawnumbers/ActivityInfo.qml
index 21dd2efa9..e8fb9f829 100644
--- a/src/activities/drawnumbers/ActivityInfo.qml
+++ b/src/activities/drawnumbers/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2016 Nitish Chauhan <nitish.nc18@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "drawnumbers/Drawnumbers.qml"
difficulty: 1
icon: "drawnumbers/drawnumbers.svg"
author: "Nitish Chauhan &lt;nitish.nc18@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Draw Numbers")
//: Help title
description: qsTr("Connect the dots to draw numbers from 0 to 9")
// intro: "Draw the numbers by connecting the dots in the correct order."
//: Help goal
goal: qsTr("Learning how to draw the numbers in a funny way.")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("Draw the numbers by connecting the dots in the correct order")
credit: ""
section: "math numeration"
createdInVersion: 7000
}
diff --git a/src/activities/drawnumbers/Drawnumbers.qml b/src/activities/drawnumbers/Drawnumbers.qml
index 7b2ce4ea3..a25f8629f 100644
--- a/src/activities/drawnumbers/Drawnumbers.qml
+++ b/src/activities/drawnumbers/Drawnumbers.qml
@@ -1,32 +1,32 @@
/* GCompris - drawnumbers.qml
*
* Copyright (C) 2016 NITISH CHAUHAN <nitish.nc18@gmail.com>
*
* Authors:
*
* Nitish Chauhan <nitish.nc18@gmail.com> (Qt Quick port)
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../number_sequence"
import "../../core" as Core
import "drawnumbers_dataset.js" as Dataset
NumberSequence {
mode: "drawnumbers"
dataset: Dataset
pointImageOpacity: 0
url: "qrc:/gcompris/src/activities/drawnumbers/resource/"
}
diff --git a/src/activities/drawnumbers/drawnumbers_dataset.js b/src/activities/drawnumbers/drawnumbers_dataset.js
index 5c36b229e..fdf287969 100644
--- a/src/activities/drawnumbers/drawnumbers_dataset.js
+++ b/src/activities/drawnumbers/drawnumbers_dataset.js
@@ -1,89 +1,89 @@
/* GCompris - drawnumbers_dataset.js
* Copyright (C) 2016 Nitish Chauhan <nitish.nc18@gmail.com>
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.import GCompris 1.0 as GCompris //for ApplicationInfo
.import "qrc:/gcompris/src/core/core.js" as Core
function get() {
return [
{
"imageName1": "paper.svg",
"imageName2": "zero.svg",
"coordinates": [[341,62],[300,50],[279,52],[251,59],[207,88],[181,121],[164,169],[159,209],[157,259],[168,307],[186,355],[222,388],[266,406],[316,408],[357,402],[402,375],[432,331],[446,289],[450,246],[444,205],[435,160],[414,111],[385,80]],
"sound": GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/"+ Core.getSoundFilenamForChar("0"))
},
{
"imageName1": "paper.svg",
"imageName2": "one.svg",
"coordinates": [[156,175],[189,157],[224,144],[261,124],[293,103],[320,80],[320,115],[320,151],[320,200],[320,246],[320,295],[320,337],[320,376],[320,412],[320,446]],
"sound": GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/"+ Core.getSoundFilenamForChar("1"))
},
{
"imageName1": "paper.svg",
"imageName2": "two.svg",
"coordinates": [[177,132],[189,96],[214,70],[254,49],[304,44],[352,49],[395,70],[425,108],[433,153],[403,198],[359,231],[320,264],[275,295],[237,315],[204,340],[168,372],[210,372],[239,372],[272,372],[301,372],[338,372],[373,372],[408,372],[446,372]],
"sound": GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/"+ Core.getSoundFilenamForChar("2"))
},
{
"imageName1": "paper.svg",
"imageName2": "three.svg",
"coordinates": [[166,128],[185,96],[217,70],[254,59],[295,53],[342,57],[380,75],[410,111],[407,157],[380,183],[344,194],[312,197],[269,212],[313,216],[348,220],[384,231],[414,256],[437,291],[433,329],[414,355],[382,373],[348,384],[305,383],[253,377],[208,357],[177,329],[155,295]],
"sound": GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/"+ Core.getSoundFilenamForChar("3"))
},
{
"imageName1": "paper.svg",
"imageName2": "four.svg",
"coordinates":[[340,31], [312,66],[287,97],[255,132],[231,166],[200,201],[168,240],[122,288],[173,288],[225,288],[262,288],[306,288],[345,288],[386,288],[417,288],
[340,31],[340,86],[340,151],[340,212],[340,262],[340,310],[340,364],[340,401]],
"coordinates2":[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2],
"sound": GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/"+ Core.getSoundFilenamForChar("4"))
},
{
"imageName1": "paper.svg",
"imageName2": "five.svg",
"coordinates": [[428,55],[380,55],[328,55],[283,55],[251,55],[215,55],[208,93],[202,122],[193,160],[185,188],[178,223],[202,226],[225,202],[258,184],[294,179],[335,190],[377,208],[411,234],[428,268],[425,313],[410,347],[381,377],[341,394],[301,402],[254,394],[211,372],[184,347],[167,308]],
"sound": GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/"+ Core.getSoundFilenamForChar("5"))
},
{
"imageName1": "paper.svg",
"imageName2": "six.svg",
"coordinates": [[422,125],[406,86],[380,66],[331,52],[288,51],[253,63],[218,88],[191,129],[177,172],[173,208],[175,251],[181,292],[195,333],[217,368],[251,387],[298,401],[346,395],[393,369],[418,315],[411,255],[382,215],[342,197],[300,193],[266,201],[237,219],[208,246]],
"sound": GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/"+ Core.getSoundFilenamForChar("6"))
},
{
"imageName1": "paper.svg",
"imageName2": "seven.svg",
"coordinates": [[164,57],[207,57],[258,57],[306,57],[344,57],[391,57],[426,57],[461,57],[426,93],[397,125],[370,160],[348,188],[324,222],[297,273],[282,304],[266,346],[254,390]],
"sound": GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/"+ Core.getSoundFilenamForChar("7"))
},
{
"imageName1": "paper.svg",
"imageName2": "eight.svg",
"coordinates": [[279,200],[231,172],[206,135],[210,91],[242,59],[277,42],[319,41],[363,52],[395,78],[413,121],[399,168],[371,198],[317,216],[271,223],[225,246],[197,281],[195,336],[203,364],[224,386],[253,400],[295,411],[345,408],[388,390],[421,354],[432,310],[426,267],[402,240],[374,226],[311,219]],
"sound": GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/"+ Core.getSoundFilenamForChar("8"))
},
{
"imageName1": "paper.svg",
"imageName2": "nine.svg",
"coordinates": [[413,157],[389,106],[351,74],[305,62],[254,67],[218,89],[193,120],[175,172],[193,222],[226,252],[279,266],[331,259],[371,237],[388,205],[413,157],[421,198],[420,262],[411,304],[395,342],[362,375],[313,388],[262,386],[222,369],[202,348],[191,321]],
"sound": GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/"+ Core.getSoundFilenamForChar("9"))
}
]
}
diff --git a/src/activities/enumerate/ActivityInfo.qml b/src/activities/enumerate/ActivityInfo.qml
index 4aa95a6d9..c6bec1f6d 100644
--- a/src/activities/enumerate/ActivityInfo.qml
+++ b/src/activities/enumerate/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Thib ROMAIN <thibrom@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "enumerate/Enumerate.qml"
difficulty: 2
icon: "enumerate/enumerate.svg"
author: "Thib ROMAIN &lt;thibrom@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Count the items")
//: Help title
description: qsTr("Place the items in the best way to count them")
// intro: "Count the elements by organising them then type the answer on your keyboard."
//: Help goal
goal: qsTr("Numeration training")
//: Help prerequisite
prerequisite: qsTr("Basic enumeration")
//: Help manual
manual: qsTr("First, properly organize the items so that you can count them. Then, select the item you want to answer in the bottom right area. Enter the answer with the keyboard.")
credit: ""
section: "math numeration"
createdInVersion: 0
}
diff --git a/src/activities/enumerate/AnswerArea.qml b/src/activities/enumerate/AnswerArea.qml
index 10cce88e6..968453589 100644
--- a/src/activities/enumerate/AnswerArea.qml
+++ b/src/activities/enumerate/AnswerArea.qml
@@ -1,153 +1,153 @@
/* GCompris - AnswerArea.qml
*
* Copyright (C) 2014 Thib ROMAIN <thibrom@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Thib ROMAIN <thibrom@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "enumerate.js" as Activity
import "../../core"
Rectangle {
id: answerBackground
- width: 140 * ApplicationInfo.ratio
- height: 70 * ApplicationInfo.ratio
+ width: Math.min(140 * ApplicationInfo.ratio, background.width / 4)
+ height: width / 2
color: activeFocus ? "#ff07fff2" : "#cccccccc"
radius: 10
border {
width: activeFocus ? 3 : 1
color: "black"
}
property string imgPath
// The backspace code coming from the virtual keyboard
property string backspaceCode
// True when the value is entered correctly
property bool valid: false
property GCSfx audioEffects
Component.onCompleted: Activity.registerAnswerItem(answerBackground)
onValidChanged: valid ? audioEffects.play("qrc:/gcompris/src/core/resource/sounds/win.wav") : null
// A top gradient
Rectangle {
anchors.fill: parent
anchors.margins: activeFocus ? 3 : 1
radius: 10
gradient: Gradient {
GradientStop { position: 0.0; color: valid ? "#CC00FF00" : "#CCFFFFFF" }
GradientStop { position: 0.5; color: valid ? "#8000FF00" : "#80FFFFFF" }
GradientStop { position: 1.0; color: valid ? "#8000F000" : "#00000000" }
}
}
// The OK feedback
Image {
source: "qrc:/gcompris/src/core/resource/apply.svg";
fillMode: Image.PreserveAspectFit
anchors {
right: parent.left
verticalCenter: parent.verticalCenter
}
sourceSize.height: parent.height * 0.8
anchors.margins: 10
opacity: valid ? 1.0 : 0.0
Behavior on opacity { NumberAnimation { duration: 200 } }
}
MouseArea {
id: mouseArea
anchors.fill: parent
onClicked: Activity.registerAnswerItem(answerBackground)
}
Image {
id: img
anchors {
left: parent.left
leftMargin: 10
verticalCenter: parent.verticalCenter
}
height: parent.height * 0.75
width: height
source: imgPath
fillMode: Image.PreserveAspectFit
}
Keys.onPressed: {
if(event.key === Qt.Key_Backspace) {
backspace()
}
appendText(event.text)
}
function backspace() {
userEntry.text = userEntry.text.slice(0, -1)
if(userEntry.text.length === 0) {
userEntry.text = "?"
valid = Activity.setUserAnswer(imgPath, -1)
return
} else {
valid = Activity.setUserAnswer(imgPath, parseInt(userEntry.text))
return
}
}
function appendText(text) {
if(text === answerBackground.backspaceCode) {
backspace()
return
}
var number = parseInt(text)
if(isNaN(number))
return
if(userEntry.text === "?") {
userEntry.text = ""
}
if(userEntry.text.length >= 2) {
valid = false
return
}
userEntry.text += text
valid = Activity.setUserAnswer(imgPath, parseInt(userEntry.text))
}
GCText {
id: userEntry
anchors {
left: img.right
verticalCenter: img.verticalCenter
leftMargin: 10
}
text: "?"
color: "black"
fontSize: 28
style: Text.Outline
styleColor: "white"
}
}
diff --git a/src/activities/enumerate/Enumerate.qml b/src/activities/enumerate/Enumerate.qml
index 82ce5da45..e8b90e586 100644
--- a/src/activities/enumerate/Enumerate.qml
+++ b/src/activities/enumerate/Enumerate.qml
@@ -1,184 +1,182 @@
/* GCompris - Enumerate.qml
*
* Copyright (C) 2014 Thib ROMAIN <thibrom@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Thib ROMAIN <thibrom@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "."
import "../../core"
import "enumerate.js" as Activity
ActivityBase {
id: activity
focus: true
onStart: {}
onStop: {}
pageComponent: Image {
id: background
anchors.fill: parent
signal start
signal stop
fillMode: Image.PreserveAspectCrop
source: Activity.url + "background.svg"
sourceSize.width: Math.max(parent.width, parent.height)
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
onStart: { Activity.start(items); keyboard.populate(); }
onStop: { Activity.stop() }
Keys.onDownPressed: {
if(++answerColumn.currentIndex >= answerColumn.count)
answerColumn.currentIndex = 0
Activity.registerAnswerItem(answerColumn.itemAt(answerColumn.currentIndex))
}
Keys.onUpPressed: {
if(--answerColumn.currentIndex < 0)
answerColumn.currentIndex = answerColumn.count - 1
Activity.registerAnswerItem(answerColumn.itemAt(answerColumn.currentIndex))
}
QtObject {
id: items
property alias background: background
property alias bar: bar
property alias bonus: bonus
property alias answerColumnModel: answerColumn.model
property alias itemListModel: itemList.model
}
DropArea {
id: dropableArea
anchors.left: background.left
anchors.bottom: background.bottom
width: background.width
height: background.height
}
Image {
source: Activity.url + 'turtle.svg'
anchors.fill: parent
fillMode: Image.PreserveAspectFit
sourceSize.width: Math.max(parent.width, parent.height)
}
Column {
id: answer
anchors {
- right: parent.right
- bottom: keyboard.top
+ left: parent.left
+ top: parent.top
margins: 10
}
spacing: 5
- Repeater
- {
+ Repeater {
id: answerColumn
property int currentIndex
onModelChanged: currentIndex = count - 1
AnswerArea {
imgPath: modelData
focus: true
backspaceCode: keyboard.backspace
audioEffects: activity.audioEffects
}
}
add: Transition {
NumberAnimation { properties: "x,y"; duration: 200 }
}
}
// Reposition the items to find when whidh or height changes
onWidthChanged: {
for(var i in itemList.model)
itemList.itemAt(i).positionMe()
}
onHeightChanged: {
for(var i in itemList.model)
itemList.itemAt(i).positionMe()
}
- Repeater
- {
+ Repeater {
id: itemList
ItemToEnumerate {
source: modelData
main: background
}
}
VirtualKeyboard {
id: keyboard
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
function populate() {
layout = [ [
{ label: "0" },
{ label: "1" },
{ label: "2" },
{ label: "3" },
{ label: "4" },
{ label: "5" },
{ label: "6" },
{ label: "7" },
{ label: "8" },
{ label: "9" },
{ label: keyboard.backspace }
] ]
}
onKeypress: Activity.currentAnswerItem.appendText(text)
onError: console.log("VirtualKeyboard error: " + msg);
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
anchors.bottom: keyboard.top
content: BarEnumContent { value: help | home | level }
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
}
Bonus {
id: bonus
Component.onCompleted: win.connect(Activity.nextLevel)
}
}
}
diff --git a/src/activities/enumerate/ItemToEnumerate.qml b/src/activities/enumerate/ItemToEnumerate.qml
index 8c38eb15f..48e35b444 100644
--- a/src/activities/enumerate/ItemToEnumerate.qml
+++ b/src/activities/enumerate/ItemToEnumerate.qml
@@ -1,77 +1,77 @@
/* GCompris - ItemToEnumerate.qml
*
* Copyright (C) 2014 Thib ROMAIN <thibrom@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Thib ROMAIN <thibrom@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "enumerate.js" as Activity
Image {
- sourceSize.width: 90 * ApplicationInfo.ratio
- fillMode : Image.PreserveAspectFit
+ sourceSize.width: Math.min(90 * ApplicationInfo.ratio, main.width / 5)
+ fillMode: Image.PreserveAspectFit
z: 0
// Let the items comes from random side of the screen
- x: Math.random() > 0.5 ? - width : main.width
- y: Math.random() > 0.5 ? - height : main.height
+ x: Math.random() > 0.5 ? -width : main.width
+ y: Math.random() > 0.5 ? -height : main.height
property real xRatio
property real yRatio
property Item main
Component.onCompleted: {
xRatio = Activity.getRandomInt(10, main.width - 220 * ApplicationInfo.ratio) /
(main.width - 220 * ApplicationInfo.ratio)
yRatio = Activity.getRandomInt(10, main.height - 180 * ApplicationInfo.ratio) /
(main.height - 180 * ApplicationInfo.ratio)
positionMe()
}
function positionMe() {
x = (main.width - 220 * ApplicationInfo.ratio) * xRatio
y = (main.height- 180 * ApplicationInfo.ratio) * yRatio
}
Drag.active: dragArea.drag.active
- Drag.hotSpot.x : width / 2
- Drag.hotSpot.y : height / 2
+ Drag.hotSpot.x: width / 2
+ Drag.hotSpot.y: height / 2
MouseArea {
id: dragArea
anchors.fill: parent
drag.target: parent
onPressed: {
parent.z = ++Activity.globalZ
}
onReleased: parent.Drag.drop()
}
Behavior on x {
- PropertyAnimation {
+ PropertyAnimation {
duration: 2000
easing.type: Easing.InOutQuad
}
}
Behavior on y {
- PropertyAnimation {
+ PropertyAnimation {
duration: 2000
easing.type: Easing.InOutQuad
}
}
}
diff --git a/src/activities/enumerate/enumerate.js b/src/activities/enumerate/enumerate.js
index 9dacde615..22cace216 100644
--- a/src/activities/enumerate/enumerate.js
+++ b/src/activities/enumerate/enumerate.js
@@ -1,172 +1,172 @@
-/* GCompris - enumarate.js
+/* GCompris - enumerate.js
*
* Copyright (C) 2014 Thib ROMAIN <thibrom@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Thib ROMAIN <thibrom@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
.import "qrc:/gcompris/src/core/core.js" as Core
var url = "qrc:/gcompris/src/activities/enumerate/resource/"
var url2 = "qrc:/gcompris/src/activities/algorithm/resource/"
var items
var currentLevel = 0
var numberOfLevel = 9
var itemIcons = [
url2 + "apple.svg",
url2 + "banana.svg",
url2 + "cherries.svg",
url + "grapes.svg",
url2 + "lemon.svg",
url2 + "orange.svg",
url + "peach.svg",
url2 + "pear.svg",
url2 + "plum.svg",
url + "strawberry.svg",
url + "watermelon.svg",
]
var numberOfTypes = itemIcons.length
var userAnswers = new Array()
var answerToFind = new Array()
// We keep a globalZ across all items. It is increased on each
// item selection to put it on top
var globalZ = 0
function start(items_) {
items = items_
currentLevel = 0
initLevel()
}
function stop() {
cleanUp()
}
function initLevel() {
items.bar.level = currentLevel + 1
cleanUp()
var numberOfItemType
var numberOfItemMax
switch(currentLevel)
{
case 0:
numberOfItemType = 1;
numberOfItemMax = 5;
break;
case 1:
numberOfItemType = 2;
numberOfItemMax = 5;
break;
case 2:
numberOfItemType = 3;
numberOfItemMax = 4;
break;
case 3:
numberOfItemType = 3;
numberOfItemMax = 5;
break;
case 4:
numberOfItemType = 4;
numberOfItemMax = 5;
break;
case 5:
numberOfItemType = 4;
numberOfItemMax = 6;
break;
case 6:
numberOfItemType = 5;
numberOfItemMax = 5;
break;
case 7:
numberOfItemType = 4;
numberOfItemMax = 6;
break;
case 8:
numberOfItemType = 3;
numberOfItemMax = 8;
break;
default:
numberOfItemType = 2;
numberOfItemMax = 9;
}
itemIcons = Core.shuffle(itemIcons)
var enumItems = new Array()
var types = new Array()
for(var type = 0; type < numberOfItemType; type++) {
var nbItems = getRandomInt(1, numberOfItemMax)
for(var j = 0; j < nbItems; j++) {
enumItems.push(itemIcons[type])
}
answerToFind[itemIcons[type]] = nbItems
types.push(itemIcons[type])
}
items.answerColumnModel = types
items.itemListModel = enumItems
}
function nextLevel() {
if(numberOfLevel <= ++currentLevel ) {
currentLevel = 0
}
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
initLevel();
}
function cleanUp() {
userAnswers = new Array()
answerToFind = new Array()
}
function setUserAnswer(imgPath, userValue) {
userAnswers[imgPath] = userValue
checkAnswers()
return userAnswers[imgPath] === answerToFind[imgPath]
}
function checkAnswers() {
for (var key in answerToFind) {
if(userAnswers[key] !== answerToFind[key]) {
return;
}
}
items.bonus.good("smiley")
}
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
var currentAnswerItem
function registerAnswerItem(item) {
currentAnswerItem = item
item.forceActiveFocus()
}
diff --git a/src/activities/erase/ActivityInfo.qml b/src/activities/erase/ActivityInfo.qml
index 9468e9c16..ee7a6d35e 100644
--- a/src/activities/erase/ActivityInfo.qml
+++ b/src/activities/erase/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "erase/Erase.qml"
difficulty: 1
icon: "erase/erase.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
//: Activity title
title: qsTr("Move the mouse or touch the screen")
//: Help title
description: qsTr("Move the mouse or touch the screen to erase the area and discover the background")
// intro: " Clear the window with your sponge and discover the hidden picture."
//: Help goal
goal: qsTr("Motor-coordination")
//: Help prerequisite
prerequisite: qsTr("Mouse-manipulation")
//: Help manual
manual: qsTr("Move the mouse or touch the screen until all the blocks disappear.")
credit: ""
section: "computer mouse"
createdInVersion: 0
}
diff --git a/src/activities/erase/Block.qml b/src/activities/erase/Block.qml
index 349a30da3..d050c2348 100644
--- a/src/activities/erase/Block.qml
+++ b/src/activities/erase/Block.qml
@@ -1,105 +1,110 @@
/* GCompris - Block.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "erase.js" as Activity
import "../../core"
import GCompris 1.0
Image {
id: block
property Item main
property Item bar
+ property Item background
property double ix
property double iy
property int nbx
property int nby
x: ix * main.width / nbx
- y: iy * (main.height - bar.height / 2) / nby
+ y: iy * (main.height - bar.height) / (nby + getMultipleOfRatioToAdjustHeight() * ApplicationInfo.ratio)
width: main.width / nbx
- height: (main.height - bar.height / 2) / nby
+ height: (main.height - bar.height) / (nby + getMultipleOfRatioToAdjustHeight() * ApplicationInfo.ratio)
signal enter
signal leave
property string type
property int counter: 0
+ function getMultipleOfRatioToAdjustHeight() {
+ return (background.width >= background.height + 40 * ApplicationInfo.ratio) ? 0.125 : 0.625
+ }
+
onEnter: {
if(opacity == 1.0) {
playSound()
block.opacity = 0
}
}
onLeave: {
if(opacity != 0) {
block.opacity = 1.0
}
}
Behavior on opacity { PropertyAnimation { duration: 200 } }
onOpacityChanged: {
if (opacity == 0) {
mouseArea.enabled = false
mouseArea.hoverEnabled = false
Activity.blockKilled()
}
}
MouseArea {
id: mouseArea
anchors.fill: parent
enabled: block.type !== "erase" || !ApplicationInfo.isMobile
hoverEnabled: block.type === "erase" && !ApplicationInfo.isMobile
onClicked: {
if(block.type === "click") {
enabled = false
block.enter()
}
}
onDoubleClicked: {
if(block.type === "double_click") {
enabled = false
block.enter()
}
}
onEntered: {
if(block.type === "erase") {
block.enter()
}
}
onExited: {
if(block.type === "erase") {
block.leave()
}
}
}
function playSound()
{
activity.audioEffects.play(
ix % 2 ? "qrc:/gcompris/src/activities/erase/resource/eraser1.wav" :
"qrc:/gcompris/src/activities/erase/resource/eraser2.wav")
}
}
diff --git a/src/activities/erase/Erase.qml b/src/activities/erase/Erase.qml
index f90b0ae8b..7e1b633c8 100644
--- a/src/activities/erase/Erase.qml
+++ b/src/activities/erase/Erase.qml
@@ -1,139 +1,141 @@
/* GCompris - Erase.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "erase.js" as Activity
ActivityBase {
id: activity
focus: true
property string type: "erase"
onStart: {}
onStop: {}
pageComponent: Image {
id: background
signal start
signal stop
focus: true
fillMode: Image.PreserveAspectCrop
source: Activity.url + Activity.getFirstImage()
sourceSize.width: Math.max(parent.width, parent.height)
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
QtObject {
id: items
property alias background: background
property alias blocks: blocks
property alias bar: bar
property alias bonus: bonus
property int nbSubLevel: 6
property int currentSubLevel: 0
}
onStart: Activity.start(main, items, type)
onStop: { Activity.stop() }
MultiPointTouchArea {
anchors.fill: parent
onTouchUpdated: {
for(var i in touchPoints) {
var touch = touchPoints[i]
var newBlock = rootItem.childAt(touch.x, touch.y)
if(newBlock)
newBlock.enter()
var previousBlock = rootItem.childAt(touch.previousX, touch.previousY)
if(previousBlock !== newBlock && previousBlock != repeater)
previousBlock.leave()
}
}
}
Item {
id: rootItem
}
ListModel {
id: blocks
}
Repeater {
id: repeater
model: blocks
parent: rootItem
Block {
id: modelData
nbx: nx
nby: ny
ix: a
iy: b
opacity: op
source: img
type: activity.type
main: MAIN
bar: BAR
+ background: items.background
}
}
DialogHelp {
id: dialogHelpLeftRight
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level }
onHelpClicked: {
displayDialog(dialogHelpLeftRight)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: home()
}
Bonus {
id: bonus
Component.onCompleted: win.connect(Activity.nextSubLevel)
}
Score {
+ id: score
anchors {
- bottom: parent.bottom
+ bottom: (background.width >= background.height + 40 * ApplicationInfo.ratio) ? background.bottom : bar.top
bottomMargin: 10 * ApplicationInfo.ratio
right: parent.right
rightMargin: 10 * ApplicationInfo.ratio
top: undefined
left: undefined
}
numberOfSubLevels: items.nbSubLevel
currentSubLevel: items.currentSubLevel + 1
}
}
}
diff --git a/src/activities/erase/erase.js b/src/activities/erase/erase.js
index 7f2535bd6..e3aa41f83 100644
--- a/src/activities/erase/erase.js
+++ b/src/activities/erase/erase.js
@@ -1,184 +1,181 @@
/* GCompris - erase.js
*
* Copyright (C) 2014 Bruno Coudoin
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
+.import GCompris 1.0 as GCompris //for ApplicationInfo
.import "qrc:/gcompris/src/core/core.js" as Core
var url = "qrc:/gcompris/src/activities/erase/resource/"
var backgroundImages = [
"Adelie_Penguin2.jpg",
"Adelie_Penguin.jpg",
"Asian_Elephant_and_Baby.jpg",
"bear001.jpg",
"black-headed-gull.jpg",
"butterfly.jpg",
"cape_petrel.jpg",
"cat1.jpg",
"cat2.jpg",
"cow.jpg",
"donkey.jpg",
"earless_seal2.jpg",
"earless_seal.jpg",
"elephanteauxgc.jpg",
"emperor_penguin.jpg",
"flamentrosegc.jpg",
"fulmar_antarctic.jpg",
"gazelle.jpg",
"giant_panda.jpg",
"girafegc.jpg",
"golden_toad.jpg",
"Helioconius_sp_Richard_Bartz.jpg",
"honey_bee.jpg",
"horses2.jpg",
"horses.jpg",
"hypogc.jpg",
"joybear002.jpg",
"jumentmulassieregc.jpg",
"maki1.jpg",
"maki2.jpg",
"maki3.jpg",
"maki4.jpg",
"maki5.jpg",
"maki6.jpg",
"malaybear002.jpg",
"papilio_demodocus.jpg",
"polabear011.jpg",
"polarbear001.jpg",
"poolbears001.jpg",
"Pteroglossus-torquatus-001.jpg",
"rhinogc.jpg",
"sheep_irish2.jpg",
"sheep_irish.jpg",
"singegc.jpg",
"skua.jpg",
"snow_petrels.jpg",
"spectbear001.jpg",
"Spider_vdg.jpg",
"squirrel.jpg",
"tetegorillegc.jpg",
"tiger1_by_Ralf_Schmode.jpg",
"tigercub003.jpg",
"tigerdrink001.jpg",
"tigerplay001.jpg",
"White_shark.jpg"
]
var blockImages = [
url + "transparent_square.svg",
url + "transparent_square_yellow.svg",
url + "transparent_square_green.svg"
]
var currentLevel
var currentImage
var main
var items
var type
// The counter of created blocks object
var createdBlocks
var killedBlocks
var nbLevel = 6
var imgIndex
function start(main_, items_, type_) {
main = main_
items = items_
type = type_
currentLevel = 0
items_.currentSubLevel = 0
currentImage = 0
imgIndex = 0
initLevel()
}
function stop() {
}
-var nbx = (currentLevel % 2 * 3) + 5;
-var nby = (currentLevel % 2 * 3) + 5;
+
function initLevel() {
items.blocks.clear()
imgIndex++
items.bar.level = currentLevel + 1
items.background.source = url + backgroundImages[currentImage++]
if(currentImage >= backgroundImages.length) {
currentImage = 0
}
createdBlocks = 0
killedBlocks = 0
- var nbx = (currentLevel % 2 * 3) + 5;
- var nby = (currentLevel % 2 * 3) + 5;
- var w = main.width / nbx
- var h = (main.height - items.bar.height) / nby
- var i = 0
+ var nbx = Math.min((currentLevel % 2 * 3) + 5, main.width / (10 * GCompris.ApplicationInfo.ratio));
+ var nby = Math.min((currentLevel % 2 * 3) + 5, main.height / (10 * GCompris.ApplicationInfo.ratio));
var data
for(var x = 0; x < nbx; ++x) {
for(var y = 0; y < nby; ++y) {
data = {
'nx': nbx, 'ny': nby, 'a': x, 'b': y,
'op': 1.0, 'MAIN': main, 'BAR': items.bar,
'img': blockImages[imgIndex % blockImages.length]
}
items.blocks.append(data)
createdBlocks++
}
}
}
function nextLevel() {
if( ++currentLevel >= nbLevel ) {
currentLevel = 0
}
items.currentSubLevel = 0;
initLevel();
}
function nextSubLevel() {
if( ++items.currentSubLevel >= items.nbSubLevel) {
items.currentSubLevel = 0
nextLevel()
}
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = nbLevel - 1
}
items.currentSubLevel = 0;
initLevel();
}
function blockKilled() {
if(++killedBlocks === createdBlocks) {
items.bonus.good("flower")
}
}
function getFirstImage() {
backgroundImages = Core.shuffle(backgroundImages)
return backgroundImages[0]
}
diff --git a/src/activities/erase_2clic/ActivityInfo.qml b/src/activities/erase_2clic/ActivityInfo.qml
index c3ef2644e..de308d6c9 100644
--- a/src/activities/erase_2clic/ActivityInfo.qml
+++ b/src/activities/erase_2clic/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "erase_2clic/Erase2clic.qml"
difficulty: 2
icon: "erase_2clic/erase_2clic.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
//: Activity title
title: qsTr("Double tap or double click")
//: Help title
description: qsTr("Double tap or double click to erase the area and discover the background image")
// intro: "Double tap or double click on the bricks to discover the hidden picture"
//: Help goal
goal: qsTr("Motor-coordination")
//: Help prerequisite
prerequisite: qsTr("Mouse-manipulation")
//: Help manual
manual: qsTr("Double tap or double click the mouse on rectangles until all the blocks disappear.")
credit: ""
section: "computer mouse"
createdInVersion: 0
}
diff --git a/src/activities/erase_2clic/Erase2clic.qml b/src/activities/erase_2clic/Erase2clic.qml
index 18705f752..403218eb8 100644
--- a/src/activities/erase_2clic/Erase2clic.qml
+++ b/src/activities/erase_2clic/Erase2clic.qml
@@ -1,29 +1,29 @@
/* GCompris - Erase2clic.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
import "../erase"
Erase {
type: "double_click"
}
diff --git a/src/activities/erase_clic/ActivityInfo.qml b/src/activities/erase_clic/ActivityInfo.qml
index a57b1e82b..d9c7cbfd5 100644
--- a/src/activities/erase_clic/ActivityInfo.qml
+++ b/src/activities/erase_clic/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "erase_clic/EraseClic.qml"
difficulty: 1
icon: "erase_clic/erase_clic.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
//: Activity title
title: qsTr("Click or tap")
//: Help title
description: qsTr("Click or tap to erase the area and discover the background")
// intro: "Click or tap on the transparent bricks and discover the hidden picture."
//: Help goal
goal: qsTr("Motor-coordination")
//: Help prerequisite
prerequisite: qsTr("Mouse-manipulation")
//: Help manual
manual: qsTr("Click or tap on the blocks all of them disappear.")
credit: ""
section: "computer mouse"
createdInVersion: 0
}
diff --git a/src/activities/erase_clic/EraseClic.qml b/src/activities/erase_clic/EraseClic.qml
index 08a006fab..ae5e4c5f6 100644
--- a/src/activities/erase_clic/EraseClic.qml
+++ b/src/activities/erase_clic/EraseClic.qml
@@ -1,29 +1,29 @@
/* GCompris - EraseClic.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
import "../erase"
Erase {
type: "click"
}
diff --git a/src/activities/explore_farm_animals/ActivityInfo.qml b/src/activities/explore_farm_animals/ActivityInfo.qml
index bacace5ab..f73438cce 100644
--- a/src/activities/explore_farm_animals/ActivityInfo.qml
+++ b/src/activities/explore_farm_animals/ActivityInfo.qml
@@ -1,47 +1,47 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Djalil Mesli <djalilmesli@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "explore_farm_animals/ExploreFarmAnimals.qml"
difficulty: 2
icon: "explore_farm_animals/explore_farm_animals.svg"
author: "Djalil Mesli &lt;djalilmesli@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Explore Farm Animals")
//: Help title
description: qsTr("Learn about farm animals, what sounds they make, and interesting facts.")
// intro: "Learn about farmyard animals and the noises that they make."
//: Help goal
goal: qsTr("Learn to associate animal sounds with the animal name and what the animal looks like.")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("There are three levels in this game.
-In level one, players enjoy exploring each animal on the screen. Click on the question mark, and learn about the animal, what it's name is, what sound it makes, and what it looks like. Study well this information, because you will be tested in level 2 and 3!
+In level one, players enjoy exploring each animal on the screen. Click on an animal and learn about it, what its name is, what sound it makes, and what it looks like. Study well this information, because you will be tested in level 2 and 3!
-In level two, a random animal sound is played and you must choose which animal makes that sound. Click on the question mark that corresponds to the animal you hear. If you'd like to hear the animal sound repeated, click on the play button. When you have matched all animals correctly, you win!
+In level two, a random animal sound is played and you must find which animal makes this sound. Click on the corresponding animal. If you'd like to hear the animal sound repeated, click on the play button. When you have matched all animals correctly, you win!
In level three, a random text prompt is displayed and you must click on the animal that matches the text. When you have matched all texts correctly, you win!
")
credit: ""
section: "discovery sound_group"
createdInVersion: 0
}
diff --git a/src/activities/explore_farm_animals/AnimalDescriptionLevels.qml b/src/activities/explore_farm_animals/AnimalDescriptionLevels.qml
index b46bbed74..7320e0365 100644
--- a/src/activities/explore_farm_animals/AnimalDescriptionLevels.qml
+++ b/src/activities/explore_farm_animals/AnimalDescriptionLevels.qml
@@ -1,248 +1,248 @@
/* GCompris - AnimalDescriptionLevels.qml
*
* Copyright (C) 2015 Ayush Agrawal <ayushagrawal288@gmail.com>
*
* Authors:
* Beth Hadley <bethmhadley@gmail.com> (GTK+ version)
* Ayush Agrawal <ayushagrawal288@gmail.com> (Qt Quick port)
* Djalil MESLI <djalilmesli@gmail.com> (Qt Quick port)
* Johnny Jazeix <jazeix@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "explore-level.js" as Activity
Rectangle {
id: rectangleDesc
radius: 30
border.width: 5
border.color: "black"
width: parent.width
height: parent.height
MouseArea {
anchors.fill: parent
onPressed: parent.closeDescriptionPanel()
}
property alias title: heading.text
property alias description: descriptionText.text
property alias imageSource: animalImage.source
- property bool horizontalLayout: background.width > background.height
+ property bool horizontalLayout: background.width >= background.height
signal showDescriptionPanel
signal closeDescriptionPanel
onShowDescriptionPanel: {
descriptionPanelCloseAnimation.stop()
descriptionPanelAppearAnimation.start()
}
onCloseDescriptionPanel: {
descriptionPanelAppearAnimation.stop()
close()
}
// animation for appearance of the description panel
NumberAnimation {
id: descriptionPanelAppearAnimation
target: descriptionPanel
property: horizontalLayout ? "x" : "y"
from: horizontalLayout ? -width : -height
to: 0
duration: 1200
easing.type: Easing.OutBack
}
GCText {
id: heading
fontSize: largeSize
horizontalAlignment: Text.AlignHCenter
font.weight: Font.DemiBold
anchors.top: parent.top
color: "#2a2a2a"
width: parent.width - cancelButton.width
wrapMode: Text.WordWrap
}
Image {
id: animalImage
width: rectangleDesc.horizontalLayout ? parent.width / 2 : parent.width * 0.9
height: rectangleDesc.horizontalLayout ?
parent.height * 0.8 :
(parent.height - heading.height - descriptionText.height) * 0.9
fillMode: Image.PreserveAspectFit
anchors {
top: rectangleDesc.horizontalLayout ? heading.bottom : descriptionText.bottom
horizontalCenter: rectangleDesc.horizontalLayout ? undefined : parent.horizontalCenter
left: rectangleDesc.horizontalLayout ? parent.left : undefined
leftMargin: rectangleDesc.horizontalLayout ? 30 * ApplicationInfo.ratio : 0
}
MouseArea {
anchors.fill: parent
onClicked: parent.switchImageWithTextOrAlone()
}
state: "zoomedOut"
// Relative width and height of the image is changed on zooming-in and zooming-out keeping original binding intact
states: [
State {
name: "zoomedIn"
PropertyChanges {
target: animalImage
width: rectangleDesc.width / 1.2
height: rectangleDesc.height / 1.2
}
PropertyChanges {
target: descriptionText
visible: false
}
AnchorChanges {
target: animalImage
anchors.top: heading.bottom
}
},
State {
name: "zoomedOut"
PropertyChanges {
target: animalImage
width: rectangleDesc.horizontalLayout ? parent.width / 2 : parent.width * 0.9
height: rectangleDesc.horizontalLayout ?
parent.height * 0.8 :
(parent.height - heading.height - descriptionText.height) * 0.9
}
PropertyChanges {
target: descriptionText
visible: true
}
AnchorChanges {
target: animalImage
anchors.top: rectangleDesc.horizontalLayout ? heading.bottom : descriptionText.bottom
}
}
]
// Transition to animate zoom-in and zoom-out
transitions: [
Transition {
from: "zoomedOut"
to: "zoomedIn"
NumberAnimation {
target: animalImage
properties: "width, height"
easing.type: Easing.OutBack
duration: 500
}
AnchorAnimation { duration: 250 }
},
Transition {
from: "zoomedIn"
to: "zoomedOut"
NumberAnimation {
target: animalImage
properties: "width, height"
duration: 250
}
PropertyAnimation {
target: descriptionText
property: "visible"
}
AnchorAnimation { duration: 250 }
}
]
// Changes the state of the image
function switchImageWithTextOrAlone() {
if(state === "zoomedOut") {
state = "zoomedIn";
}
else {
state = "zoomedOut";
}
}
}
GCText {
id: descriptionText
font.weight: Font.DemiBold
fontSizeMode: Text.Fit
horizontalAlignment: Text.AlignJustify
anchors {
top: (heading.height > cancelButton.height) ? heading.bottom : cancelButton.bottom
right: parent.right
rightMargin: 30 * ApplicationInfo.ratio
left: rectangleDesc.horizontalLayout ? animalImage.right : parent.left
leftMargin: 30 * ApplicationInfo.ratio
}
color: "#2a2a2a"
width: rectangleDesc.horizontalLayout ? parent.width * 0.45 : parent.width
height: rectangleDesc.horizontalLayout ? parent.height * 0.5 : parent.height * 0.3
wrapMode: Text.WordWrap
}
// The close panel button
GCButtonCancel {
id: cancelButton
onClose: parent.closeDescriptionPanel()
}
function close() {
if(animalImage.state === "zoomedIn") {
animalImage.state = "zoomedOut";
}
descriptionPanelCloseAnimation.start();
if (Activity.isComplete()) {
Activity.items.bonus.good("flower");
Activity.nextLevel();
}
}
SequentialAnimation {
id: descriptionPanelCloseAnimation
NumberAnimation {
id: slideBackDescriptionPanel
target: descriptionPanel
property: horizontalLayout ? "x" : "y"
to: horizontalLayout ? -width : -height
duration: 1200
easing.type: Easing.InSine
}
PropertyAnimation {
id: switchDescriptionPanelInvisible
target: descriptionPanel
property: "visible"
to: false
}
}
}
diff --git a/src/activities/explore_farm_animals/AnimalLevels.qml b/src/activities/explore_farm_animals/AnimalLevels.qml
index 567bbd3eb..aa8554168 100644
--- a/src/activities/explore_farm_animals/AnimalLevels.qml
+++ b/src/activities/explore_farm_animals/AnimalLevels.qml
@@ -1,117 +1,117 @@
/* GCompris - AnimalLevels.qml
*
* Copyright (C) 2015 Ayush Agrawal <ayushagrawal288@gmail.com>
*
* Authors:
* Beth Hadley <bethmhadley@gmail.com> (GTK+ version)
* Ayush Agrawal <ayushagrawal288@gmail.com> (Qt Quick port)
* Djalil MESLI <djalilmesli@gmail.com> (Qt Quick port)
* Johnny Jazeix <jazeix@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "explore-level.js" as Activity
Image {
id: animalImg
width: animalWidth
height: animalHeight
sourceSize.width: width
sourceSize.height: height
fillMode: Image.PreserveAspectFit
property string name: name
property alias starVisible: star.visible
property int questionId
property string title
property string description
property string imageSource
property string question
property string audio
signal displayDescription(var animal)
SequentialAnimation {
id: anim
running: true
loops: 1
NumberAnimation {
target: animalImg
property: "rotation"
from: 0; to: 360
duration: 400 + Math.floor(Math.random() * 400)
easing.type: Easing.InOutQuad
}
}
Image {
id: star
-
x: animalImg.width / 2.5
y: animalImg.height * 0.8
visible: false
-
source:"qrc:/gcompris/src/core/resource/star.png"
}
MultiPointTouchArea {
id: touchArea
anchors.centerIn: parent
// Make the item big enough to be clicked easily
width: Math.max(parent.width, 55 * ApplicationInfo.ratio)
height: Math.max(parent.height, 55 * ApplicationInfo.ratio)
touchPoints: [ TouchPoint { id: point1 } ]
mouseEnabled: progressbar.value != progressbar.maximumValue && !items.bonus.isPlaying
onPressed: {
if(items.progressbar.value >= progressbar.maximumValue) {
return
}
var questionTargetId = items.questionOrder[Activity.items.progressbar.value]
Activity.items.instruction.visible = false
- if (Activity.items.score.currentSubLevel == 1) {
- audioVoices.play(animalImg.audio);
+ if (Activity.items.score.currentSubLevel === 1) {
+ if(animalImg.audio) {
+ audioVoices.play(animalImg.audio);
+ }
displayDescription(animalImg)
star.visible = true;
} else {
if (questionId === questionTargetId) {
animWin.start();
items.progressbar.value ++;
items.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/completetask.wav");
Activity.nextSubSubLevel();
} else {
items.bonus.bad("smiley")
}
}
}
}
SequentialAnimation {
id: animWin
running: false
loops: 1
NumberAnimation {
target: animalImg
property: "rotation"
from: 0; to: 360
duration: 600
easing.type: Easing.InOutQuad
}
}
}
diff --git a/src/activities/explore_farm_animals/ExploreFarmAnimals.qml b/src/activities/explore_farm_animals/ExploreFarmAnimals.qml
index aedc29546..cef03f4e1 100644
--- a/src/activities/explore_farm_animals/ExploreFarmAnimals.qml
+++ b/src/activities/explore_farm_animals/ExploreFarmAnimals.qml
@@ -1,32 +1,32 @@
/* GCompris - ExploreFarmAnimals.qml
*
* Copyright (C) 2015 Djalil MESLI <djalilmesli@gmail.com>
*
* Authors:
* Beth Hadley <bethmhadley@gmail.com> (GTK+ version)
* Djalil MESLI <djalilmesli@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
ExploreLevels {
id: activity
numberOfLevels: 1
url: "qrc:/gcompris/src/activities/explore_farm_animals/resource/"
hasAudioQuestions: true
}
diff --git a/src/activities/explore_farm_animals/ExploreLevels.qml b/src/activities/explore_farm_animals/ExploreLevels.qml
index 6226f8006..4ac1991e5 100644
--- a/src/activities/explore_farm_animals/ExploreLevels.qml
+++ b/src/activities/explore_farm_animals/ExploreLevels.qml
@@ -1,305 +1,305 @@
/* GCompris - ExploreLevels.qml
*
* Copyright (C) 2015 Ayush Agrawal <ayushagrawal288@gmail.com>
*
* Authors:
* Beth Hadley <bethmhadley@gmail.com> (GTK+ version)
* Ayush Agrawal <ayushagrawal288@gmail.com> (Qt Quick port)
* Djalil MESLI <djalilmesli@gmail.com> (Qt Quick port)
* Johnny Jazeix <jazeix@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import QtQuick.Controls 1.5
import "../../core"
import "explore-level.js" as Activity
ActivityBase {
id: activity
property int numberOfLevels
property string url
property bool hasAudioQuestions
onStart: focus = true
onStop: {}
pageComponent: Item {
id: background
/* In order to accept any screen ratio the play area is always a 1000x1000
* square and is centered in a big background image that is 2000x2000
*/
Image {
id: bg
source: dataset.item.backgroundImage
sourceSize.width: 2000 * ApplicationInfo.ratio
sourceSize.height: 2000 * ApplicationInfo.ratio
width: 2000 * background.playRatio
height: width
anchors.centerIn: parent
}
- property bool horizontalLayout: background.width > background.height
+ property bool horizontalLayout: background.width >= background.height
property int playX: (activity.width - playWidth) / 2
property int playY: (activity.height - playHeight) / 2
property int playWidth: horizontalLayout ? activity.height : activity.width
property int playHeight: playWidth
property double playRatio: playWidth / 1000
focus: true
signal start
signal stop
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property GCAudio audioVoices: activity.audioVoices
property GCSfx audioEffects: activity.audioEffects
property Item main: activity.main
property alias background: background
property alias bar: bar
property alias bonus: bonus
property alias score: score
property alias progressbar: progressbar
property alias ok: ok
property alias dataModel: dataModel
property alias dataset: dataset
property alias instruction: instruction
property alias instructionText: instructionText
property alias descriptionPanel: descriptionPanel
property alias nextQuestion: nextQuestion
property bool hasAudioQuestions: activity.hasAudioQuestions
property string currentAudio
property var questionOrder
property var currentQuestion: items.dataset ? items.dataset.item.tab[items.questionOrder[progressbar.value]] : ""
}
Timer {
id: nextQuestion
repeat: false
interval: 2000
onTriggered: {
Activity.repeat();
}
}
Loader{
id: dataset
asynchronous: false
onStatusChanged: {
if (status == Loader.Ready) {
// create table of size N filled with numbers from 0 to N
items.questionOrder = Array.apply(null, {length: items.dataModel.count}).map(Number.call, Number)
}
}
}
onStart: { Activity.start(items, url, numberOfLevels) }
onStop: { Activity.stop() }
Keys.onEscapePressed: {
descriptionPanel.visible ? descriptionPanel.closeDescriptionPanel() : home()
}
Repeater {
id: dataModel
model: dataset && dataset.item && dataset.item.tab ? dataset.item.tab.length : 0
AnimalLevels {
questionId: index
source: dataset.item.tab[index].image
x: background.playX + background.playWidth * dataset.item.tab[index].x - width / 2
y: background.playY + background.playHeight * dataset.item.tab[index].y - height / 2
width: background.playWidth * dataset.item.tab[index].width
height: background.playHeight * dataset.item.tab[index].height
title: dataset.item.tab[index].title
description: dataset.item.tab[index].text
imageSource: dataset.item.tab[index].image2
question: dataset.item.tab[index].text2
audio: dataset.item.tab[index].audio !== undefined ? dataset.item.tab[index].audio : ""
Component.onCompleted: {
displayDescription.connect(displayDescriptionItem)
}
}
}
function displayDescriptionItem(animal) {
descriptionPanel.title = animal.title
descriptionPanel.description = animal.description
descriptionPanel.imageSource = animal.imageSource
descriptionPanel.visible = true
descriptionPanel.showDescriptionPanel()
}
AnimalDescriptionLevels {
id: descriptionPanel
width: parent.width
height: parent.height
z: instruction.z + 1
}
Column {
id: progress
visible: items.score.currentSubLevel != 1
anchors.bottom: bar.top
anchors.right: parent.right
anchors.margins: 10 * ApplicationInfo.ratio
ProgressBar {
id: progressbar
height: progressbarText.height
width: bar.width
property string message
onValueChanged: message = value + "/" + maximumValue
onMaximumValueChanged: message = value + "/" + maximumValue
GCText {
id: progressbarText
anchors.centerIn: parent
fontSize: mediumSize
font.bold: true
color: "black"
text: progressbar.message
}
}
}
Image {
id: ok
visible: progressbar.value === progressbar.maximumValue
source:"qrc:/gcompris/src/core/resource/bar_ok.svg"
sourceSize.width: questionText.height * 2
fillMode: Image.PreserveAspectFit
anchors.right: progress.left
anchors.bottom: bar.top
anchors.margins: 10 * ApplicationInfo.ratio
MouseArea {
anchors.fill: parent
onClicked: Activity.nextLevel()
}
}
Row {
id: row
spacing: 10 * ApplicationInfo.ratio
anchors.fill: parent
anchors.margins: 10 * ApplicationInfo.ratio
layoutDirection: leftCol.width === 0 ? Qt.RightToLeft : Qt.LeftToRight
Column {
id: leftCol
spacing: 10 * ApplicationInfo.ratio
Rectangle {
id: instruction
width: row.width - rightCol.width - 10 * ApplicationInfo.ratio
height: instructionText.height
color: "#CCCCCCCC"
radius: 10
border.width: 3
border.color: "black"
GCText {
id: instructionText
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
anchors.centerIn: parent.Center
color: "black"
width: parent.width
wrapMode: Text.Wrap
text: (dataset.item && items.score.currentSubLevel - 1 != items.score.numberOfSubLevels && items.score.currentSubLevel != 0) ? dataset.item.instructions[items.score.currentSubLevel - 1].text : ""
}
MouseArea {
anchors.fill: parent
onClicked: instruction.visible = false
enabled: instruction.visible
}
}
Rectangle {
id: question
width: row.width - rightCol.width - 10 * ApplicationInfo.ratio
height: questionText.height
color: '#CCCCCCCC'
radius: 10
border.width: 3
border.color: "black"
visible: items.score.currentSubLevel == 3 || (items.score.currentSubLevel == 2 && !items.hasAudioQuestions)
GCText {
id: questionText
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
anchors.centerIn: parent.Center
color: "black"
width: parent.width
wrapMode: Text.Wrap
text: items.currentQuestion ? items.currentQuestion.text2 : ""
}
}
}
Column {
id: rightCol
spacing: 10 * ApplicationInfo.ratio
Score {
id: score
anchors {
bottom: undefined
right: undefined
}
}
BarButton {
id: repeatItem
source: "qrc:/gcompris/src/core/resource/bar_repeat.svg";
sourceSize.width: 60 * ApplicationInfo.ratio
anchors.right: parent.right
visible: items.score.currentSubLevel == 2 && activity.hasAudioQuestions //&& ApplicationSettings.isAudioVoicesEnabled
onClicked: Activity.repeat();
}
}
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level | reload }
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
onReloadClicked: Activity.start(items, url, numberOfLevels)
}
Bonus {
id: bonus
}
}
}
diff --git a/src/activities/explore_farm_animals/explore-level.js b/src/activities/explore_farm_animals/explore-level.js
index ca5897b42..02b23c64f 100644
--- a/src/activities/explore_farm_animals/explore-level.js
+++ b/src/activities/explore_farm_animals/explore-level.js
@@ -1,144 +1,144 @@
/* GCompris - explore-level.js
*
* Copyright (C) 2015 Ayush Agrawal <ayushagrawal288@gmail.com>
*
* Authors:
* Beth Hadley <bethmhadley@gmail.com> (GTK+ version)
* Ayush Agrawal <ayushagrawal288@gmail.com> (Qt Quick port)
* Djalil MESLI <djalilmesli@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import GCompris 1.0 as GCompris
.import "qrc:/gcompris/src/core/core.js" as Core
var numberOfLevels
var items
var url
var currentLevel
function start(items_,url_,levelCount_) {
items = items_
url = url_
numberOfLevels = levelCount_
currentLevel = 1
items.score.currentSubLevel = 1
initLevel()
}
function stop() {
items.audioVoices.stop()
}
function initLevel() {
items.bar.level = currentLevel
var filename = url + "board" + "/" + "board" + currentLevel + ".qml"
items.dataset.source = filename
items.progressbar.value = 0
items.progressbar.maximumValue = items.dataModel.count
items.score.numberOfSubLevels = items.hasAudioQuestions ? 3 : 2;
// randomize the questions for level 2 and 3
Core.shuffle(items.questionOrder);
// Change the currentSubLevel value to 1 to be sure to update the question value
// else if you are sublevel 0 and go to last level, the question is not the good one
items.progressbar.value = 1
items.progressbar.value = 0
items.descriptionPanel.visible = false
items.instruction.visible = true
reload();
}
function nextLevel() {
++items.score.currentSubLevel
if(numberOfLevels <= currentLevel && items.score.numberOfSubLevels < items.score.currentSubLevel)
{
currentLevel = 0
}
if (items.score.numberOfSubLevels < items.score.currentSubLevel) {
currentLevel++
items.score.currentSubLevel = 1
}
initLevel();
// Stop audio if necessary (switch from level 2 at beginning to a new level for example)
items.audioVoices.stop()
if (items.score.currentSubLevel == 2) {
items.progressbar.value = 0;
initSubSubLevel();
}
}
function previousLevel() {
--items.score.currentSubLevel
if(currentLevel <= 1 && items.score.currentSubLevel < 1)
{
currentLevel = numberOfLevels
items.score.currentSubLevel = items.score.numberOfSubLevels
}
else if(items.score.currentSubLevel < 1) {
currentLevel--
items.score.currentSubLevel = items.score.numberOfSubLevels
}
initLevel();
// Stop audio if necessary (switch from level 2 at beginning to a new level for example)
items.audioVoices.stop()
if(items.score.currentSubLevel == 2 && items.hasAudioQuestions) {
repeat();
}
}
function isComplete() {
for(var i = 0 ; i < items.dataModel.count ; ++ i) {
if(!items.dataModel.itemAt(i).starVisible)
return false;
}
return true;
}
function initSubSubLevel(IsNext) {
if(items.progressbar.value == items.dataModel.count) {
items.bonus.good("smiley");
}
if(items.score.currentSubLevel == 2 && items.hasAudioQuestions && getCurrentQuestion()) {
repeat();
}
}
function nextSubSubLevel() {
items.audioVoices.silence(2000)
initSubSubLevel(true)
}
function reload() {
for(var i = 0 ; i < items.dataModel.count ; ++ i) {
items.dataModel.itemAt(i).starVisible = false;
}
}
function repeat() {
items.audioVoices.stop()
items.audioVoices.clearQueue()
items.audioVoices.append(getCurrentQuestion().audio);
}
function getCurrentQuestion() {
return items.dataset.item.tab[items.questionOrder[items.progressbar.value]];
}
diff --git a/src/activities/explore_farm_animals/resource/board/board1.qml b/src/activities/explore_farm_animals/resource/board/board1.qml
index 873864da6..4643076b6 100644
--- a/src/activities/explore_farm_animals/resource/board/board1.qml
+++ b/src/activities/explore_farm_animals/resource/board/board1.qml
@@ -1,162 +1,162 @@
/* GCompris
*
* Copyright (C) 2015 Johnny Jazeix <jazeix@gmail.com>
*
* Authors:
* Beth Hadley <bethmhadley@gmail.com> (GTK+ version)
* Johnny Jazeix <jazeix@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0 as GCompris
QtObject {
property string backgroundImage: "qrc:/gcompris/src/activities/explore_farm_animals/resource/animals/farm-animals.svg"
property var tab : [
{
"image": "qrc:/gcompris/src/activities/explore_farm_animals/resource/animals/horse.svg",
"title": qsTr("Horse"),
"text": qsTr("The horse goes 'neigh! neigh!'. Horses usually sleep standing up."),
"audio": GCompris.ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/explore_farm_animals/resource/animals/horse.$CA"),
"image2": "qrc:/gcompris/src/activities/explore_farm_animals/resource/animals/horse.jpg",
"text2": qsTr("You can ride on the back of this animal!"),
"x": 0.304,
"y": 0.480,
"width": 0.156,
"height": 0.166
},
{
"image": "qrc:/gcompris/src/activities/explore_farm_animals/resource/animals/chicken.svg",
"title": qsTr("Chicken"),
"text": qsTr("The chicken goes 'luck, cackle, cluck'. Chickens have over 200 different noises they can use to communicate."),
"audio": GCompris.ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/explore_farm_animals/resource/animals/chickens.$CA"),
"image2": "qrc:/gcompris/src/activities/explore_farm_animals/resource/animals/chicken.jpg",
"text2": qsTr("This animal lays eggs."),
"x": 0.66,
"y": 0.67,
"width": 0.190,
"height": 0.119
},
{
"image": "qrc:/gcompris/src/activities/explore_farm_animals/resource/animals/cow.svg",
"title": qsTr("Cow"),
"text": qsTr("The cow goes 'moo! moo!'. Cows are herbivorous mammals. They graze all day in the meadow."),
"audio": GCompris.ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/explore_farm_animals/resource/animals/cow.$CA"),
"image2": "qrc:/gcompris/src/activities/explore_farm_animals/resource/animals/cow.jpg",
"text2": qsTr("You can drink the milk this animal produces."),
"x": 0.364,
"y": 0.620,
"width": 0.305,
"height": 0.172
},
{
"image": "qrc:/gcompris/src/activities/explore_farm_animals/resource/animals/cat.svg",
"title": qsTr("Cat"),
"text": qsTr("The cat goes 'meow, meow'. Cats usually hate water because their fur doesn't stay warm when it is wet."),
"audio": GCompris.ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/explore_farm_animals/resource/animals/cat.$CA"),
"image2": "qrc:/gcompris/src/activities/explore_farm_animals/resource/animals/cat.jpg",
"text2": qsTr("This pet likes chasing mice."),
"x": 0.880,
"y": 0.550,
"width": 0.114,
"height": 0.110
},
{
"image": "qrc:/gcompris/src/activities/explore_farm_animals/resource/animals/pig.svg",
"title": qsTr("Pig"),
"text": qsTr("The pig goes 'oink, oink'. Pigs are the 4th most intelligent animal."),
"audio": GCompris.ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/explore_farm_animals/resource/animals/pig.$CA"),
"image2": "qrc:/gcompris/src/activities/explore_farm_animals/resource/animals/pig.jpg",
"text2": qsTr("This animal likes to lie in the mud."),
"x": 0.42,
"y": 0.75,
"width": 0.185,
"height": 0.153
},
{
"image": "qrc:/gcompris/src/activities/explore_farm_animals/resource/animals/duck.svg",
"title": qsTr("Duck"),
"text": qsTr("The duck goes 'quack, quack'. Ducks have special features like webbed feet and produce an oil to make their feathers 'waterproof'."),
"audio": GCompris.ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/explore_farm_animals/resource/animals/duck.$CA"),
"image2": "qrc:/gcompris/src/activities/explore_farm_animals/resource/animals/duck.jpg",
"text2": qsTr("This animal has webbed feet so it can swim in the water."),
"x": 0.163,
"y": 0.76,
"width": 0.210,
"height": 0.134
},
{
"image": "qrc:/gcompris/src/activities/explore_farm_animals/resource/animals/owl.svg",
"title": qsTr("Owl"),
"text": qsTr("The owl goes 'hoo. hoo.' The owl has excellent vision and hearing at night."),
"audio": GCompris.ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/explore_farm_animals/resource/animals/owl.$CA"),
"image2": "qrc:/gcompris/src/activities/explore_farm_animals/resource/animals/owl.jpg",
"text2": qsTr("This animal likes to come out at night."),
"x": 0.71,
"y": 0.29,
"width": 0.042,
"height": 0.056
},
{
"image": "qrc:/gcompris/src/activities/explore_farm_animals/resource/animals/dog.svg",
"title": qsTr("Dog"),
"text": qsTr("The dog goes 'bark! bark!'. Dogs are great human companions and usually enjoy love and attention."),
"audio": GCompris.ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/explore_farm_animals/resource/animals/dog.$CA"),
"image2": "qrc:/gcompris/src/activities/explore_farm_animals/resource/animals/dog.jpg",
"text2": qsTr("This animal's ancestors were wolves."),
"x": 0.120,
"y": 0.600,
"width": 0.126,
"height": 0.101
},
{
"image": "qrc:/gcompris/src/activities/explore_farm_animals/resource/animals/rooster.svg",
"title": qsTr("Rooster"),
"text": qsTr("The rooster goes 'coc-a-doodle-doo!'. Roosters have been on farms for about 5,000 years. Every morning it wakes the farm up with its noises."),
"audio": GCompris.ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/explore_farm_animals/resource/animals/rooster.$CA"),
"image2": "qrc:/gcompris/src/activities/explore_farm_animals/resource/animals/rooster.jpg",
"text2": qsTr("This animal wakes the farm up in the morning."),
"x": 0.66,
"y": 0.78,
"width": 0.122,
"height": 0.127
},
{
"image": "qrc:/gcompris/src/activities/explore_farm_animals/resource/animals/sheep.svg",
"title": qsTr("Sheep"),
"text": qsTr("The sheep is a mammal that bears a fleece of wool. It is a grazing herbivore, bred for its wool, its meat, and its milk. The fleece can be removed and used to produce articles of clothing and blankets, among other things."),
"audio": GCompris.ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/explore_farm_animals/resource/animals/sheep.$CA"),
"image2": "qrc:/gcompris/src/activities/explore_farm_animals/resource/animals/sheep.jpg",
"text2": qsTr("This animal is a close relative to the goat."),
"x": 0.66,
"y": 0.548,
"width": 0.20,
"height": 0.13
}
]
property var instructions : [
{
"text": qsTr("Click on each farm animal to discover them.")
},
{
"text": qsTr("Click on the farm animal that makes the sound you hear.")
},
{
"text": qsTr("Click the animal that matches the description.")
}
]
}
diff --git a/src/activities/explore_monuments/ActivityInfo.qml b/src/activities/explore_monuments/ActivityInfo.qml
index c3dbb484c..41972d3ab 100644
--- a/src/activities/explore_monuments/ActivityInfo.qml
+++ b/src/activities/explore_monuments/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Ayush Agrawal <ayushagrawal288@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "explore_monuments/Explore_monuments.qml"
difficulty: 3
icon: "explore_monuments/explore_monuments.svg"
author: "Ayush Agrawal &lt;ayushagrawal288@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Explore Monuments")
//: Help title
description: qsTr("Explore Monuments around the world.")
//intro: "Explore Monuments around the world."
//: Help goal
goal: qsTr("To learn about different monuments on the basis of their location.")
//: Help prerequisite
prerequisite: qsTr("Knowledge of different monuments.")
//: Help manual
manual: qsTr("Click on the given keys to learn more of the monuments and then identify where the monuments is on the map by its name.")
credit: qsTr("Photos taken from Wikipedia.")
section: "discovery"
createdInVersion: 6000
}
diff --git a/src/activities/explore_monuments/CMakeLists.txt b/src/activities/explore_monuments/CMakeLists.txt
index 3580d150b..d1c66aadd 100644
--- a/src/activities/explore_monuments/CMakeLists.txt
+++ b/src/activities/explore_monuments/CMakeLists.txt
@@ -1 +1 @@
-GCOMPRIS_ADD_RCC(activities/explore_monuments *.qml *.svg resource/*.txt resource/*/*)
+GCOMPRIS_ADD_RCC(activities/explore_monuments *.qml *.svg resource/*.* resource/README resource/*/*)
diff --git a/src/activities/explore_monuments/Explore_monuments.qml b/src/activities/explore_monuments/Explore_monuments.qml
index 7937d3c7c..063e2f21e 100644
--- a/src/activities/explore_monuments/Explore_monuments.qml
+++ b/src/activities/explore_monuments/Explore_monuments.qml
@@ -1,35 +1,33 @@
/* GCompris - Explore_monuments.qml
*
* Copyright (C) 2015 Ayush Agrawal <ayushagrawal288@gmail.com>
*
* Authors:
* Ayush Agrawal <ayushagrawal288@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../explore_farm_animals"
ExploreLevels {
id: activity
numberOfLevels: 6
- url : "qrc:/gcompris/src/activities/explore_monuments/resource/"
+ url: "qrc:/gcompris/src/activities/explore_monuments/resource/"
hasAudioQuestions: false
}
-
-
diff --git a/src/activities/explore_monuments/resource/README.txt b/src/activities/explore_monuments/resource/README.txt
index 55e933ab3..b1c12a276 100644
--- a/src/activities/explore_monuments/resource/README.txt
+++ b/src/activities/explore_monuments/resource/README.txt
@@ -1,25 +1,30 @@
#Information Regarding source of Images used
Level 1
Background http://www.clker.com/clipart-9207.html
All monuments: Wikipedia
Level 2
Background https://openclipart.org/detail/194681/map-of-india-and-sri-lanka-in-cylindrical-equal-area-projection
All monuments: Wikipedia
Level 3
Background http://www.clipartbest.com/clipart-4cbMK6dcg
All monuments: Wikipedia
Level 4
Background http://cliparts.co/cliparts/zTX/oBj/zTXoBj5Lc.jpg
All monuments: Wikipedia
Level 5
Background http://www.cloudclipart.com/clipart/countries-clipart/usa-clipart/usa-map-silhouette-2-detail
All monuments: Wikipedia
Level 6
Background http://www.clipartbest.com/clipart-dcrMeMMc9
-All pyramids: Wikipedia
\ No newline at end of file
+All pyramids: Wikipedia
+
+Copyright: Timothee Giet, 2018
+License: CC-BY-SA 4.0
+Files:
+key.svg
diff --git a/src/activities/explore_monuments/resource/board/board1.qml b/src/activities/explore_monuments/resource/board/board1.qml
index b092c55c5..18a1ccb31 100644
--- a/src/activities/explore_monuments/resource/board/board1.qml
+++ b/src/activities/explore_monuments/resource/board/board1.qml
@@ -1,115 +1,115 @@
/* GCompris
*
* Copyright (C) 2015 Ayush Agrawal <ayushagrawal288@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Ayush Agrawal <ayushagrawal288@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string backgroundImage: "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/worldbg.jpg"
- property var tab : [
+ property var tab: [
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Chichén Itzá"),
"text": qsTr("Chichen Itza, meaning “at the mouth of the Itza well”, is a Mayan City on the Yucatan Peninsula in Mexico, between Valladolid and Merida. It was established before the period of Christopher Colombus and probably served as the religion center of Yucatan for a while."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/chichenItza.jpg",
"text2": qsTr("Chichén Itzá"),
"x": "0.206",
"y": "0.498",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Colosseum"),
"text": qsTr("The Colosseum or Coliseum is today the most recognizable of Rome's Classical buildings. Even 2,000 years after it was built, and despite centuries when the abandoned building was pillaged for building materials, it is instantly recognizable as a classical template for the stadia of today. It was the first permanent amphitheatre to be raised in Rome, and the most impressive arena the Classical world had yet seen."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/colosseum.jpg",
"text2": qsTr("Colosseum"),
"x": "0.514",
"y": "0.406",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Christ the Redeemer"),
"text": qsTr("Christ the Redeemer is an Art Deco statue of Jesus Christ in Rio de Janeiro, Brazil. A symbol of Christianity across the world, the statue has also become a cultural icon of both Rio de Janeiro and Brazil."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/christTheRedeemer.jpg",
"text2": qsTr("Christ the Redeemer"),
"x": "0.351",
"y": "0.628",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("The Great Wall of China"),
"text": qsTr("The Great Wall, was listed as a World Heritage by UNESCO in 1987. Just like a gigantic dragon, it winds up and down across deserts, grasslands, mountains and plateaus, stretching approximately 13,170 miles (21,196 kilometers) from east to west of China."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/greatWallofChina.jpg",
"text2": qsTr("The Great Wall of China"),
"x": "0.765",
"y": "0.445",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Machu Picchu"),
"text": qsTr("Machu Picchu stands 2,430 m above sea-level, in the middle of a tropical mountain forest, in an extraordinarily beautiful setting. It was probably the most amazing urban creation of the Inca Empire at its height; its giant walls, terraces and ramps seem as if they have been cut naturally in the continuous rock escarpments. The natural setting, on the eastern slopes of the Andes, encompasses the upper Amazon basin with its rich diversity of flora and fauna."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/machuPicchu.jpg",
"text2": qsTr("Machu Picchu"),
"x": "0.267",
"y": "0.598",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Petra"),
"text": qsTr("Petra is a historical and archaeological city in the southern Jordanian governorate of Ma'an that is famous for its rock-cut architecture and water conduit system. Established possibly as early as 312 BC as the capital city of the Arab Nabataeans, it is a symbol of Jordan, as well as Jordan's most-visited tourist attraction."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/petra.jpg",
"text2": qsTr("Petra"),
"x": "0.586",
"y": "0.462",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Taj Mahal, India"),
"text": qsTr("The Taj Mahal is a white marble mausoleum located on the southern bank of the Yamuna River in the Indian city of Agra. It was commissioned in 1632 by the Mughal emperor Shah Jahan reigned to house the tomb of his favorite wife of three, Mumtaz Mahal."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/tajMahal.jpg",
"text2": qsTr("Taj Mahal"),
"x": "0.692",
"y": "0.471",
"height": "0.07",
"width": "0.07"
}
]
- property var instructions : [
+ property var instructions: [
{
"text": qsTr("The 7 New Wonders of World.")
},
{
"text": qsTr("Click on location where the given monument is located.")
}
]
}
diff --git a/src/activities/explore_monuments/resource/board/board2.qml b/src/activities/explore_monuments/resource/board/board2.qml
index 467d3eb44..d072858c3 100644
--- a/src/activities/explore_monuments/resource/board/board2.qml
+++ b/src/activities/explore_monuments/resource/board/board2.qml
@@ -1,169 +1,169 @@
/* GCompris
*
* Copyright (C) 2015 Ayush Agrawal <ayushagrawal288@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Ayush Agrawal <ayushagrawal288@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string backgroundImage: "qrc:/gcompris/src/activities/explore_monuments/resource/india/indiabg.jpg"
- property var tab : [
+ property var tab: [
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Golden Temple"),
"text": qsTr("Sri Harimandir Sahib, known as the Golden Temple in Amritsar, is one of the most revered spiritual sites of Sikhism. The construction was intended to build a place of worship for men and women from all walks of life and all religions to worship God equally."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/india/goldenTemple.jpg",
- "text2" : qsTr("Golden Temple"),
+ "text2": qsTr("Golden Temple"),
"x": "0.256",
"y": "0.206",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Hawa Mahal"),
"text": qsTr("Hawa Mahal, is a palace in Jaipur, India, so named because it was essentially a high screen wall built so the women of the royal household could observe street festivals while unseen from the outside. Constructed of red and pink sandstone, the palace sits on the edge of the City Palace, and extends to the zenana, or women's chambers."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/india/hawaMahal.jpg",
- "text2" : qsTr("Hawa Mahal"),
+ "text2": qsTr("Hawa Mahal"),
"x": "0.230",
"y": "0.290",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Taj Mahal"),
"text": qsTr("The Taj Mahal is a white marble mausoleum located on the southern bank of the Yamuna River in the Indian city of Agra. It was commissioned in 1632 by the Mughal emperor Shah Jahan reigned to house the tomb of his favorite wife of three, Mumtaz Mahal."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/india/tajMahal.jpg",
- "text2" : qsTr("Taj Mahal"),
+ "text2": qsTr("Taj Mahal"),
"x": "0.416",
"y": "0.298",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Gateway of India"),
"text": qsTr("The Gateway of India is one of India's most unique landmarks situated in the city of Mumbai. The colossal structure was constructed in 1924. Located at the tip of Apollo Bunder, the gateway overlooks the Mumbai harbor, bordered by the Arabian Sea in the Colaba district. The Gateway of India is a monument that marks India's chief ports and is a major tourist attraction for visitors who arrive in India for the first time."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/india/gatewayofIndia.jpg",
- "text2" : qsTr("Gateway of India"),
+ "text2": qsTr("Gateway of India"),
"x": "0.179",
"y": "0.540",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Great Stupa"),
"text": qsTr("The Great Stupa at Sanchi is the oldest stone structure in India and was originally commissioned by the emperor Ashoka the Great in the 3rd century BCE. Its nucleus was a simple hemispherical brick structure built over the relics of the Buddha. It was crowned by the chatra, a parasol-like structure symbolizing high rank, which was intended to honor and shelter the relics."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/india/greatStupa.jpg",
- "text2" : qsTr("Great Stupa"),
+ "text2": qsTr("Great Stupa"),
"x": "0.329",
"y": "0.396",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Ajanta Caves"),
"text": qsTr("The Ajanta Caves are about 29 rock-cut Buddhist cave monuments which date from the 2nd century BCE to about 480 CE in Aurangabad district of Maharashtra state of India. The caves include paintings and rock cut sculptures described as among the finest surviving examples of ancient Indian art, particularly expressive paintings that present emotion through gesture, pose and form. Since 1983, the caves have been a UNESCO World Heritage Site"),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/india/ajantaCave.jpg",
- "text2" : qsTr("Ajanta Caves"),
+ "text2": qsTr("Ajanta Caves"),
"x": "0.304",
"y": "0.502",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Konark Sun Temple"),
"text": qsTr("The Konark Sun Temple (also spelled Konarak) is a 13th-century Hindu temple dedicated to the Sun god. Shaped like a giant chariot, the temple is known for the exquisite stone carvings that cover the entire structure."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/india/konarkSunTemple.jpg",
- "text2" : qsTr("Konark Sun Temple"),
+ "text2": qsTr("Konark Sun Temple"),
"x": "0.506",
"y": "0.538",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Mysore Palace"),
"text": qsTr("Mysore Palace or Mysore Maharaja Palace is one of the largest and most spectacular monuments in India. Also known as Amba Vilas, it is located in the heart of the city of Mysore. The palace was initially built by the Wodeyar kings in the 14th century."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/india/mysorePalace.jpg",
- "text2" : qsTr("Mysore Palace"),
+ "text2": qsTr("Mysore Palace"),
"x": "0.295",
"y": "0.748",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Charminar"),
"text": qsTr("The Charminar in Hyderabad was constructed in 1591 by Mohammed Quli Qutab Shah. He built the Charminar to mark the end of plague in the Hyderabad city. Since the construction of the Charminar, the Hyderabad city has almost become synonymous with the monument. The Charminar is a massive and impressive structure with four minarets."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/india/charminar.jpg",
- "text2" : qsTr("Charminar"),
+ "text2": qsTr("Charminar"),
"x": "0.360",
"y": "0.588",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Victoria Memorial"),
"text": qsTr("The Victoria Memorial was built to commemorate the peak of the British Empire in India. It represents the architectural climax of Kolkata city, and blends the best of the British and Mughal architecture. The Victoria Memorial hall was built with white Makrana marbles."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/india/victoriaMemorials.jpg",
- "text2" : qsTr("Victoria Memorial"),
+ "text2": qsTr("Victoria Memorial"),
"x": "0.670",
"y": "0.414",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Rang Ghar"),
"text": qsTr("The Rang Ghar is a two-storied building which once served as the royal sports-pavilion where Ahom kings and nobles were spectators at games like buffalo fights and other sports at Rupahi Pathar - particularly during the Rongali Bihu festival in the Ahom capital of Rangpur."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/india/rangGhar.jpg",
- "text2" : qsTr("Rang Ghar"),
+ "text2": qsTr("Rang Ghar"),
"x": "0.860",
"y": "0.306",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Qutub Minar"),
"text": qsTr("Qutub Minar at 74 meters, is the tallest brick minaret in the world, and the second tallest minar in India after Fateh Burj at Mohali. Along with the ancient and medieval monuments surrounding it, they form the Qutb Complex, which is a UNESCO World Heritage Site. The tower, located in the Mehrauli area of Delhi, is made of red sandstone and marble."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/india/qutubMinar.jpg",
- "text2" : qsTr("Qutub Minar"),
+ "text2": qsTr("Qutub Minar"),
"x": "0.328",
"y": "0.254",
"height": "0.07",
"width": "0.07"
}
]
- property var instructions : [
+ property var instructions: [
{
"text": qsTr("Monuments of India")
},
{
"text": qsTr("Click on location where the given monument is located.")
}
]
}
diff --git a/src/activities/explore_monuments/resource/board/board3.qml b/src/activities/explore_monuments/resource/board/board3.qml
index a39a4095d..4a40e39ec 100644
--- a/src/activities/explore_monuments/resource/board/board3.qml
+++ b/src/activities/explore_monuments/resource/board/board3.qml
@@ -1,147 +1,147 @@
/* GCompris
*
* Copyright (C) 2015 Ayush Agrawal <ayushagrawal288@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Ayush Agrawal <ayushagrawal288@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string backgroundImage: "qrc:/gcompris/src/activities/explore_monuments/resource/france/francebg.jpg"
- property var tab : [
+ property var tab: [
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Mont-Saint-Michel"),
"text": qsTr("Mont Saint-Michel is a rocky tidal island located in Normandy, at the mouth of the Couesnon River, near the city of Avranches. The highest point of the island is the spire at the top of the Abbey’s bell tower, 170 metres above sea level. They are currently less than 50 people living on the island. The unique feature of Mont Saint-Michel is that it is completely surrounded by water and can only be accessed at low tide."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/france/montStMichel.jpg",
- "text2" : qsTr("Mont-Saint-Michel"),
+ "text2": qsTr("Mont-Saint-Michel"),
"x": "0.278",
"y": "0.268",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Cité de Carcassonne"),
"text": qsTr("With more than 4 million visitors each year, Carcassonne is among the most prestigious tourist destinations in France, on a par with Mont Saint Michel and Paris’ Notre-Dame. A UNESCO World Heritage Site since 1997, Carcassonne is a dramatic representation of medieval architecture perched on a rocky spur that towers above the River Aude, southeast of the new town."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/france/citedeCarcassonne.jpg",
- "text2" : qsTr("Cité de Carcassonne"),
+ "text2": qsTr("Cité de Carcassonne"),
"x": "0.588",
"y": "0.875",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Reims Cathedral"),
"text": qsTr("By size, Reims Cathedral is quite an extraordinary construction: designed to accommodate huge crowds, its gigantic dimensions include a surface area of 6,650 m2 and a length of 122m. A Gothic art masterpiece and the coronation site of the Kings of France, it has been listed as a UNESCO World Heritage Site since 1991. The Mecca for tourists in the Champagne region welcomes 1,500,000 visitors every year."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/france/reimsCathedral.jpg",
- "text2" : qsTr("Reims Cathedral"),
+ "text2": qsTr("Reims Cathedral"),
"x": "0.687",
"y": "0.196",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Pont du Gard"),
"text": qsTr("The Pont du Gard was built shortly before the Christian era to allow the aqueduct of Nîmes (which is almost 50 km long) to cross the Gardon river. The Roman architects and hydraulic engineers who designed this bridge, which stands almost 50 m high and is on three levels – the longest measuring 275 m – created a technical as well as an artistic masterpiece."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/france/pontduGard.jpg",
- "text2" : qsTr("Pont du Gard"),
+ "text2": qsTr("Pont du Gard"),
"x": "0.691",
"y": "0.757",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Arles Amphitheatre"),
"text": qsTr("This Roman amphitheatre dates back to the first century BC and was originally the setting for gladiator battles and chariot races during Antiquity. Modified many times, it was finally renovated during the 19th century."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/france/arlesAmphitheater.jpg",
- "text2" : qsTr("Arles Amphitheatre"),
+ "text2": qsTr("Arles Amphitheatre"),
"x": "0.730",
"y": "0.831",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Château de Chambord"),
"text": qsTr("Prestigious, majestic, colossal, extravagant are these adjectives enough to fully describe the splendour of Chambord? The largest chateau of the Loire Valley is indeed full of surprises for those who are lucky enough to explore its domain. This remarkable piece of architecture is certainly more than just a castle: it is the dream of a King, transformed into reality."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/france/chateaudeChambord.jpg",
- "text2" : qsTr("Château de Chambord"),
+ "text2": qsTr("Château de Chambord"),
"x": "0.456",
"y": "0.388",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Rocamadour"),
"text": qsTr("When coming from Cahors by road, Rocamadour suddenly appears clinging precariously against the cliff above the Alzou canyon. One of the most famous villages of Europe, Rocamadour seemingly defies the laws of gravity. The vertiginous Citadel of Faith is best summed up by an old local saying: “houses on the river, churches on the houses, rocks on the churches, castle on the rock”."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/france/rocamadour.jpg",
- "text2" : qsTr("Rocamadour"),
+ "text2": qsTr("Rocamadour"),
"x": "0.538",
"y": "0.658",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Palais des Papes"),
"text": qsTr("The star attraction of Avignon is the Palais des Papes (Palace of the Popes), a vast castle of significant historic, religious and architectural importance. It is one of the largest and most important medieval Gothic buildings in Europe."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/france/palaisdesPapes.jpg",
- "text2" : qsTr("Palais des Papes"),
+ "text2": qsTr("Palais des Papes"),
"x": "0.771",
"y": "0.768",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Château de Chenonceau"),
"text": qsTr("Chateau de Chenonceau is among many of Loire Valley Chateaux that boast amazing architecture and historical significance drawing thousands of tourists from all over the world. Chateau de Chenonceau is sometimes called the Ladies Castle by some historians due to feminine figures having greatly influenced the construction and development of this French Chateau over the centuries."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/france/chateaudeChenonceau.jpg",
- "text2" : qsTr("Château de Chenonceau"),
+ "text2": qsTr("Château de Chenonceau"),
"x": "0.449",
"y": "0.464",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Eiffel Tower"),
"text": qsTr("The world-famous metallic tower was built for the Paris International Exhibition in 1889 for the centenary of the French Revolution. At the time of its inauguration, it was the world’s tallest monument."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/france/eiffelTower.jpg",
- "text2" : qsTr("Eiffel Tower"),
+ "text2": qsTr("Eiffel Tower"),
"x": "0.538",
"y": "0.304",
"height": "0.07",
"width": "0.07"
},
]
- property var instructions : [
+ property var instructions: [
{
"text": qsTr("Monuments of France")
},
{
"text": qsTr("Click on location where the given monument is located.")
}
]
}
diff --git a/src/activities/explore_monuments/resource/board/board4.qml b/src/activities/explore_monuments/resource/board/board4.qml
index 63aae8348..d4dd5d62a 100644
--- a/src/activities/explore_monuments/resource/board/board4.qml
+++ b/src/activities/explore_monuments/resource/board/board4.qml
@@ -1,114 +1,114 @@
/* GCompris
*
* Copyright (C) 2015 Ayush Agrawal <ayushagrawal288@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Ayush Agrawal <ayushagrawal288@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string backgroundImage: "qrc:/gcompris/src/activities/explore_monuments/resource/germany/germanybg.jpg"
- property var tab : [
+ property var tab: [
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Neuschwanstein Castle"),
"text": qsTr("The ultimate fairytale castle, Neuschwanstein is situated on a rugged hill near Füssen in southwest Bavaria. It was the inspiration for the Sleeping Beauty castles in the Disneyland parks. The castle was commissioned by King Ludwig II of Bavaria who was declared insane when the castle was almost completed in 1886 and found dead a few days later. Neuschwanstein is the most photographed building in the country and one of the most popular tourist attractions in Germany."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/germany/neuschwansteinCastle.jpg",
- "text2" : qsTr("Neuschwanstein Castle"),
+ "text2": qsTr("Neuschwanstein Castle"),
"x": "0.525",
"y": "0.938",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Trier Imperial Baths"),
"text": qsTr("The Trier Imperial Baths are a large Roman bath complex in Trier, Germany. It is designated as part of the Roman Monuments, Cathedral of St. Peter and Church of Our Lady in Trier UNESCO World Heritage Site."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/germany/trierImperialBaths.jpg",
- "text2" : qsTr("Trier Imperial Baths"),
+ "text2": qsTr("Trier Imperial Baths"),
"x": "0.205",
"y": "0.721",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Brandenburg Gate"),
"text": qsTr("The Brandenburg Gate is the only surviving city gate of Berlin and symbolizes the reunification of East and West Berlin. Built in the 18th century, the Brandenburg Gate is the entry to Unter den Linden, the prominent boulevard of linden trees which once led directly to the palace of the Prussian monarchs. It is regarded as one of the most famous landmarks in Europe."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/germany/brandenburgGate.jpg",
- "text2" : qsTr("Brandenburg Gate"),
+ "text2": qsTr("Brandenburg Gate"),
"x": "0.753",
"y": "0.331",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Berlin Cathedral"),
"text": qsTr("The Cathedral of Berlin is the largest church in the city, and it serves as a vital center for the Protestant church of Germany. Reaching out well beyond the borders of the parish and of Berlin, the cathedral attracts thousands of visitors, year after year, from Germany and abroad."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/germany/berlinCathedral.jpg",
- "text2" : qsTr("Berlin Cathedral"),
+ "text2": qsTr("Berlin Cathedral"),
"x": "0.736",
"y": "0.255",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Schwerin Palace"),
"text": qsTr("This romantic fairytale fortress, with all its many towers, domes and wings, is reflected in the waters of Lake Schwerin. It was completed in 1857 and symbolized the powerful dynasty of its founder, Friedrich Franz II."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/germany/schwerinPalace.jpg",
- "text2" : qsTr("Schwerin Palace"),
+ "text2": qsTr("Schwerin Palace"),
"x": "0.585",
"y": "0.206",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Aula Palatina"),
"text": qsTr("The long, high-ceilinged brick structure was the throne hall of the Roman emperor until the destruction of the city by Germanic tribes. The invaders built a settlement inside the roofless ruin. In the 12th century, the apse was converted into a tower to accommodate the Archbishop of Trier."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/germany/aulaPalatina.jpg",
- "text2" : qsTr("Aula Palatina"),
+ "text2": qsTr("Aula Palatina"),
"x": "0.245",
"y": "0.655",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Worms Cathedral"),
"text": qsTr("Worms Cathedral (Wormser Dom) also known as the Cathedral of St Peter is a Romanesque cathedral in the German city of Worms. A sandstone structure with distinctive conical towers, Worms Cathedral was constructed in phases throughout the twelfth century and mostly completed by 1181."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/germany/wormsCathedral.jpg",
- "text2" : qsTr("Worms Cathedral"),
+ "text2": qsTr("Worms Cathedral"),
"x": "0.332",
"y": "0.697",
"height": "0.07",
"width": "0.07"
},
]
- property var instructions : [
+ property var instructions: [
{
"text": qsTr("Monuments of Germany")
},
{
"text": qsTr("Click on location where the given monument is located.")
}
]
}
diff --git a/src/activities/explore_monuments/resource/board/board5.qml b/src/activities/explore_monuments/resource/board/board5.qml
index ee227d0a1..3b97aafcc 100644
--- a/src/activities/explore_monuments/resource/board/board5.qml
+++ b/src/activities/explore_monuments/resource/board/board5.qml
@@ -1,147 +1,147 @@
/* GCompris
*
* Copyright (C) 2015 Ayush Agrawal <ayushagrawal288@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Ayush Agrawal <ayushagrawal288@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string backgroundImage: "qrc:/gcompris/src/activities/explore_monuments/resource/usa/usbg.jpg"
- property var tab : [
+ property var tab: [
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Cabrillo"),
"text": qsTr("Situated on Point Loma in San Diego, California, Cabrillo National Monument commemorates the first European to land on the West Coast of the United States, Juan Rodriguez Cabrillo. Portuguese by birth, Cabrillo carried the Spanish flag in his conquests of the New World. He arrived at San Diego Bay in September 1542, three months after departing from Barra de Navidad on the west coast of Mexico."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/usa/cabrillo.jpg",
- "text2" : qsTr("Cabrillo"),
+ "text2": qsTr("Cabrillo"),
"x": "0.182",
"y": "0.586",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Canyon de Chelly"),
"text": qsTr("The stoic red ruins of Canyon de Chelly in northeastern Arizona are at once part of the National Park Service and the Navajo Nation, having been established as a national monument in 1931. A number of important early Native American sites are preserved in the nearly 84,000 acres of parkland, and Canyon de Chelly also offers an array of Southwestern geological formations, including Spider Rock, an 800-foot-tall sandstone spire that rises eerily from the bottom of the canyon floor."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/usa/canyondeChelly.jpg",
- "text2" : qsTr("Canyon de Chelly"),
+ "text2": qsTr("Canyon de Chelly"),
"x": "0.277",
"y": "0.569",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Castillo de San Marcos"),
"text": qsTr("Set on more than 20 acres in St. Augustine, Florida, the Castillo de San Marcos was completed as the city's defensive fort in 1695, when Florida was still a Spanish territory. Constructed out of the rare coquina limestone, the star-shaped Castillo also is the oldest masonry fort in the country."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/usa/castillodeSanMarcos.jpg",
- "text2" : qsTr("Castillo de San Marcos"),
+ "text2": qsTr("Castillo de San Marcos"),
"x": "0.759",
"y": "0.668",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Castle Clinton"),
"text": qsTr("This round, sandstone fort sitting at the bottom of Manhattan Island predates Ellis Island by about 50 years as the first U.S. immigration checkpoint. Castle Clinton (nps.gov/cacl) was originally built as a fort to protect New York from a British invasion during the War of 1812, and was dedicated as a national monument in 1946."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/usa/castleClinton.jpg",
- "text2" : qsTr("Castle Clinton"),
+ "text2": qsTr("Castle Clinton"),
"x": "0.841",
"y": "0.390",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("George Washington Birthplace"),
"text": qsTr("The George Washington Birthplace National Monument is in Westmoreland County, Virginia, United States. Originally settled by John Washington, George Washington's great-grandfather, George Washington was born here on February 22, 1732. He lived here until age three, returning later as a teenager."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/usa/georgeWashingtonBirthplace.jpg",
- "text2" : qsTr("George Washington Birthplace"),
+ "text2": qsTr("George Washington Birthplace"),
"x": "0.836",
"y": "0.532",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Lincoln Memorial"),
"text": qsTr("Built in white stone with 36 iconic columns, The Lincoln Memorial is one of the most recognized structures in the United States. The memorial is at the west end of the National Mall, in West Potomac Park, and is an example in Neoclassical architecture. It features a solitary, 19-foot-tall statue of Abraham Lincoln sitting in contemplation, which is flanked on both side chambers with inscriptions of Lincoln’s Second Inaugural Address and arguably his most famous speech, the Gettysburg Address."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/usa/lincolnMemorial.jpg",
- "text2" : qsTr("Lincoln Memorial"),
+ "text2": qsTr("Lincoln Memorial"),
"x": "0.791",
"y": "0.456",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Mount Rushmore"),
"text": qsTr("Mt. Rushmore stands as a shrine of democracy, a monument and memorial to George Washington, this country's birth, growth and ideals. Mount Rushmore symbolizes the greatness of this nation through the greatness of its leaders. The epic sculpture of Mount Rushmore depicts the faces of four exalted American presidents that symbolize this nation's rich history, rugged determination and lasting achievements."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/usa/mountRushmore.jpg",
- "text2" : qsTr("Mount Rushmore"),
+ "text2": qsTr("Mount Rushmore"),
"x": "0.492",
"y": "0.399",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Navajo"),
"text": qsTr("Navajo National Monument is a National Monument located within the northwest portion of the Navajo Nation territory in northern Arizona, which was established to preserve three-well preserved cliff dwellings of the Ancestral Puebloan People: Keet Seel (Kitsʼiil), Betatakin (Bitátʼahkin), and Inscription House (Tsʼah Biiʼ Kin). The monument is high on the Shonto plateau, overlooking the Tsegi Canyon system, west of Kayenta, Arizona. It features a visitor center with a museum, two short self-guided mesa top trails, two small campgrounds, and a picnic area. Rangers guide visitors on free tours of the Keet Seel and Betatakin cliff dwellings. The Inscription House site, further west, is currently closed to public access."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/usa/navajo.jpg",
- "text2" : qsTr("Navajo"),
+ "text2": qsTr("Navajo"),
"x": "0.300",
"y": "0.498",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Statue of Liberty"),
"text": qsTr("Perhaps the best-known monument and symbol of the United States is the Statue of Liberty, which sits on its own tiny island in New York City. The statue was a gift from the people of France and was dedicated in October 1886."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/usa/statueofLiberty.jpg",
- "text2" : qsTr("Statue of Liberty"),
+ "text2": qsTr("Statue of Liberty"),
"x": "0.860",
"y": "0.309",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Fort Sumter"),
"text": qsTr("Originally built as a defensive structure following the War of 1812, it was at this oceanfront fortification in Charleston Harbor, South Carolina, that the first shots of the Civil War were fired. Inside Fort Sumter, a number of exhibits offer perspectives on U.S. history, particularly the divisions between North and South that eventually resulted in the war."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/usa/fortSumter.jpg",
- "text2" : qsTr("Fort Sumter"),
+ "text2": qsTr("Fort Sumter"),
"x": "0.769",
"y": "0.589",
"height": "0.07",
"width": "0.07"
},
]
- property var instructions : [
+ property var instructions: [
{
"text": qsTr("Monuments of US")
},
{
"text": qsTr("Click on location where the given monument is located.")
}
]
}
diff --git a/src/activities/explore_monuments/resource/board/board6.qml b/src/activities/explore_monuments/resource/board/board6.qml
index 721902795..cd26fb161 100644
--- a/src/activities/explore_monuments/resource/board/board6.qml
+++ b/src/activities/explore_monuments/resource/board/board6.qml
@@ -1,80 +1,80 @@
/* GCompris
*
* Copyright (C) 2016 Ayush Agrawal <ayushagrawal288@gmail.com>
*
* Authors:
* Ayush Agrawal <ayushagrawal288@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string backgroundImage: "qrc:/gcompris/src/activities/explore_monuments/resource/egypt/egyptbg.jpg"
- property var tab : [
+ property var tab: [
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Great Pyramid of Giza"),
"text": qsTr("The Great Pyramid of Giza is also known as the Pyramid of Khufu or the Pyramid of Cheops. It is considered to be the oldest of all the Seven Wonders of the Ancient World. It is also the largest of all the three pyramids in the Giza. It is situated in Giza Necropolis of Egypt. The initial construction has been started by Egyptian Pharaoh Khufu then it was continued by his son Khafre and finally completed by Menkaure. It took almost 20 years to build the pyramid and approximately 2 million blocks of stone has been used in the construction. The height of the pyramid is approximately 139 meters making it the highest pyramid of Egypt."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/egypt/greatPyramidOfGiza.jpg",
- "text2" : qsTr("Great Pyramid of Giza"),
+ "text2": qsTr("Great Pyramid of Giza"),
"x": "0.627",
"y": "0.141",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Bent Pyramid"),
"text": qsTr("The Bent Pyramid located at Dahshur was the second pyramid built by pharaoh Sneferu. Mysteriously, this true pyramid rises from the desert at an angle of 55 degrees and then suddenly changes to a more gradual angle of 43 degrees. One theory holds that due to the steepness of the original angle the weight to be added above the inner chambers and passageways became too large, forcing the builders to adopt a shallower angle. Today, the Bent Pyramid is the only pyramid in Egypt of which the outer casing of polished limestone is still largely intact."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/egypt/bentPyramid.jpg",
- "text2" : qsTr("Bent Pyramid"),
+ "text2": qsTr("Bent Pyramid"),
"x": "0.596",
"y": "0.200",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Pyramid of Meidum"),
"text": qsTr("Five miles south of Saqqara in Egypt stands the mysterious tower-like pyramid of Meidum, which today scarcely resembles a typical pyramid at all. The pyramid was probably built during the reign of the 4th Dynasty pharaoh Sneferu, although it is believed by some that the pyramid may have been started by Sneferu’s predecessor, Huni. At some point during its construction the steps of the pyramid were filled with limestone encasing marking the first attempt by the ancient Egyptians at the construction of a true pyramid."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/egypt/meidumPyramid.jpg",
- "text2" : qsTr("Pyramid of Meidum"),
+ "text2": qsTr("Pyramid of Meidum"),
"x": "0.609",
"y": "0.260",
"height": "0.07",
"width": "0.07"
},
{
- "image": "qrc:/gcompris/src/activities/explore_monuments/resource/wonders/key.png",
+ "image": "qrc:/gcompris/src/activities/explore_monuments/resource/key.svg",
"title": qsTr("Red Pyramid"),
"text": qsTr("Red Pyramid was one of the finest and successful attempts by Pharaoh Sneferu in building world’s first ever smooth sided pyramid during the Ancient Egypt period. The height of the pyramid is 104 meters making it the world’s 4th largest pyramid in Egypt. The pyramid has been built with red limestone stones and hence the name. The local people of Egypt called it as el-heram el-watwaat meaning the Bat Pyramid."),
"image2": "qrc:/gcompris/src/activities/explore_monuments/resource/egypt/redPyramid.jpg",
- "text2" : qsTr("Red Pyramid"),
+ "text2": qsTr("Red Pyramid"),
"x": "0.535",
"y": "0.240",
"height": "0.07",
"width": "0.07"
}
]
- property var instructions : [
+ property var instructions: [
{
"text": qsTr("Egyptian pyramids")
},
{
"text": qsTr("Click on location where the given pyramid is located.")
}
]
}
diff --git a/src/activities/explore_monuments/resource/key.svg b/src/activities/explore_monuments/resource/key.svg
new file mode 100644
index 000000000..65770b0ad
--- /dev/null
+++ b/src/activities/explore_monuments/resource/key.svg
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="150"
+ height="200"
+ viewBox="0 0 39.687499 52.916668"
+ version="1.1"
+ id="svg849"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="key.svg">
+ <defs
+ id="defs843" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="2.8"
+ inkscape:cx="11.428571"
+ inkscape:cy="67.857142"
+ inkscape:document-units="mm"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ units="px"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata846">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ <dc:date>2018</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Timothée Giet</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Calque 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-244.08332)">
+ <path
+ style="opacity:1;vector-effect:none;fill:#704917;fill-opacity:1;stroke:none;stroke-width:9.04892159;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ d="M 75 1 A 42.189929 42.189929 0 0 0 32.810547 43.189453 A 42.189929 42.189929 0 0 0 58.306641 81.884766 L 58.306641 181.36914 C 58.306641 191.13639 65.646493 199 74.765625 199 C 83.519757 199 90.616265 191.74816 91.171875 182.52734 L 109.31445 182.52734 L 109.31445 154.52148 L 91.226562 154.52148 L 91.226562 151.08398 L 102.06836 151.08398 L 102.06836 131.14648 L 91.226562 131.14648 L 91.226562 82.125 A 42.189929 42.189929 0 0 0 117.18945 43.189453 A 42.189929 42.189929 0 0 0 75 1 z M 75 29.955078 A 13.234927 13.234927 0 0 1 88.234375 43.189453 A 13.234927 13.234927 0 0 1 75 56.423828 A 13.234927 13.234927 0 0 1 61.765625 43.189453 A 13.234927 13.234927 0 0 1 75 29.955078 z "
+ transform="matrix(0.26458333,0,0,0.26458333,0,244.08332)"
+ id="rect845-3" />
+ <path
+ style="opacity:1;vector-effect:none;fill:#f49b32;fill-opacity:1;stroke:none;stroke-width:10.09026051;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ d="M 75 8.5957031 A 34.595176 34.595176 0 0 0 40.40625 43.189453 A 34.595176 34.595176 0 0 0 66.697266 76.736328 L 66.697266 183.08984 C 66.697266 187.50011 70.247938 191.05078 74.658203 191.05078 L 74.875 191.05078 C 79.285265 191.05078 82.835938 187.50011 82.835938 183.08984 L 82.835938 177.30469 L 102.29688 177.30469 L 102.29688 159.74219 L 82.835938 159.74219 L 82.835938 145.86133 L 95.689453 145.86133 L 95.689453 136.36914 L 82.835938 136.36914 L 82.835938 76.849609 A 34.595176 34.595176 0 0 0 109.59375 43.189453 A 34.595176 34.595176 0 0 0 75 8.5957031 z M 75 24.259766 A 18.930994 18.930994 0 0 1 93.931641 43.189453 A 18.930994 18.930994 0 0 1 75 62.121094 A 18.930994 18.930994 0 0 1 56.068359 43.189453 A 18.930994 18.930994 0 0 1 75 24.259766 z "
+ transform="matrix(0.26458333,0,0,0.26458333,0,244.08332)"
+ id="path841" />
+ </g>
+</svg>
diff --git a/src/activities/explore_monuments/resource/wonders/key.png b/src/activities/explore_monuments/resource/wonders/key.png
deleted file mode 100644
index 834d8c740..000000000
Binary files a/src/activities/explore_monuments/resource/wonders/key.png and /dev/null differ
diff --git a/src/activities/explore_world_animals/ActivityInfo.qml b/src/activities/explore_world_animals/ActivityInfo.qml
index 4dde93fa9..87bca7ce7 100644
--- a/src/activities/explore_world_animals/ActivityInfo.qml
+++ b/src/activities/explore_world_animals/ActivityInfo.qml
@@ -1,49 +1,49 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Johnny Jazeix <jazeix@gmail.com>
*
* Authors:
* Beth Hadley <bethmhadley@gmail.com> (GTK+ version)
* Johnny Jazeix <jazeix@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "explore_world_animals/ExploreWorldAnimals.qml"
difficulty: 4
icon: "explore_world_animals/explore_world_animals.svg"
author: "Johnny Jazeix &lt;jazeix@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Explore World Animals")
//: Help title
description: qsTr("Learn about world animals, interesting facts and their location on a map.")
// intro: "Learn about world animals and locate them on a map."
//: Help goal
goal: ""
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("There are two levels in this game.
In level one, players enjoy exploring each animal on the screen. Click on the question mark, and learn about the animal, what it's name is, and what it looks like. Study well this information, because you will be tested in level 2!
In level two, a random text prompt is displayed and you must click on the animal that matches the text. When you have matched all texts correctly, you win!
")
credit: ""
section: "discovery miscellaneous"
createdInVersion: 0
}
diff --git a/src/activities/explore_world_animals/ExploreWorldAnimals.qml b/src/activities/explore_world_animals/ExploreWorldAnimals.qml
index dc74fde27..f0e78ace2 100644
--- a/src/activities/explore_world_animals/ExploreWorldAnimals.qml
+++ b/src/activities/explore_world_animals/ExploreWorldAnimals.qml
@@ -1,34 +1,34 @@
/* GCompris - explore_world_animals.qml
*
* Copyright (C) 2015 Johnny Jazeix <jazeix@gmail.com>
*
* Authors:
* Beth Hadley <bethmhadley@gmail.com> (GTK+ version)
* Johnny Jazeix <jazeix@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../explore_farm_animals"
ExploreLevels {
id: activity
numberOfLevels: 3
url: "qrc:/gcompris/src/activities/explore_world_animals/resource/"
hasAudioQuestions: false
}
diff --git a/src/activities/explore_world_animals/resource/animals/README b/src/activities/explore_world_animals/resource/animals/README
index 679e1eacb..50812eaea 100644
--- a/src/activities/explore_world_animals/resource/animals/README
+++ b/src/activities/explore_world_animals/resource/animals/README
@@ -1,12 +1,17 @@
This file explains where were some images in this directory taken from
kangaroo.jpg: https://commons.wikimedia.org/wiki/File:Kangaroo_and_joey02.jpg by fir0002/Flagstaffotos / GFDL 1.2
chameleon.jpg: https://commons.wikimedia.org/wiki/File:Chameleon_(16139192778).jpg by Laika ac / CC BY-SA 2.0
polar_bear.jpg: https://commons.wikimedia.org/wiki/File:Polar_Bear_AdF.jpg by Arturo de Frias Marques / CC BY-SA 4.0
moose.jpg: https://commons.wikimedia.org/wiki/File:Male_Moose.jpg by Ryan Hagerty / Public domain
scarlet_macaw.jpg: https://commons.wikimedia.org/wiki/File:Ara_macao_-Diergaarde_Blijdorp_-flying-8a.jpg by Jar0d / CC BY-SA 2.0
crocodile.jpg: https://commons.wikimedia.org/wiki/File:Marsh_Crocodiles_basking_in_the_sun.JPG by Kmanoj / CC BY 3.0
dragon.jpg: https://commons.wikimedia.org/wiki/File:Varanus_komodoensis4.jpg by Raul654 / CC BY-SA 3.0
koala.jpg: https://commons.wikimedia.org/wiki/File:Koala_climbing_tree.jpg by David Iliff / CC BY-SA 3.0
lemur.jpg: https://commons.wikimedia.org/wiki/File:Ring_tailed_lemur_and_twins.jpg by Sannse / CC BY-SA 3.0
panda.jpg: https://commons.wikimedia.org/wiki/File:Lightmatter_panda.jpg by Aaron Logan / CC BY 1.0
+
+Copyright: Timothee Giet, 2018
+License: CC-BY-SA 4.0
+Files:
+question.svg
diff --git a/src/activities/explore_world_animals/resource/animals/question.svg b/src/activities/explore_world_animals/resource/animals/question.svg
new file mode 100644
index 000000000..340a5400b
--- /dev/null
+++ b/src/activities/explore_world_animals/resource/animals/question.svg
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="150"
+ height="200"
+ viewBox="0 0 39.687499 52.916668"
+ version="1.1"
+ id="svg849"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="question.svg">
+ <defs
+ id="defs843" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="0.7"
+ inkscape:cx="120"
+ inkscape:cy="-64.285715"
+ inkscape:document-units="mm"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ units="px"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata846">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ <dc:date>2018</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Timothée Giet</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Calque 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-244.08332)">
+ <path
+ style="fill:#f49b32;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.5574795px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 3.1666378,255.28298 13.2069892,-8.3604 14.407605,1.5482 6.303317,8.9798 -2.401245,13.31501 -9.304923,6.50281 -2.401269,5.8834 2.101101,5.88341 -6.303317,6.50281 -9.605078,-1.5482 v -6.50281 l 1.200635,-2.47699 -1.5007968,-5.26463 2.7014318,-14.2438 -6.0031807,2.78701 z"
+ id="path36501-7-2"
+ inkscape:connector-curvature="0" />
+ <path
+ sodipodi:nodetypes="ccccsccccccccccccscccccccccccccc"
+ inkscape:connector-curvature="0"
+ id="path4188-9"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:100%;font-family:'Indigo Joker';text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#704917;fill-opacity:1;stroke:none;stroke-width:1.64068317px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 39.422245,258.06619 c -0.879005,13.83635 -6.415075,13.55417 -13.193873,19.84249 0.0367,1.2907 -0.325204,2.55165 -0.635856,3.66266 0,0.0696 0.229604,0.45554 0.688838,1.1477 2.787249,4.33711 -1.484923,10.56154 -5.563675,12.13567 -5.050314,1.9487 -13.3507239,1.3837 -13.458813,-4.8654 0.090095,-1.88985 0.8842127,-3.46399 1.5366323,-5.08368 -0.2826236,-0.14552 -0.6711662,-0.43656 -1.1657165,-0.87438 -0.2472561,-0.329 -0.3708842,-1.32992 -0.3708842,-3.00656 -0.5709415,-5.00143 1.9756765,-12.46846 2.2759016,-14.03691 -1.5289388,0.86489 -3.1595196,1.8095 -4.8722808,2.77626 C 2.8845835,264.27796 2.251885,259.54289 0.74144607,255.16909 0.42351821,254.40353 0.26458591,253.96634 0.26458591,253.85689 16.192576,241.44663 39.561273,242.07616 39.422302,258.06619 Z m -4.874843,-0.38594 c -1.377668,-6.04981 -6.19953,-9.07408 -14.46556,-9.07408 -4.864562,0.51881 -10.1489781,1.73991 -13.4058185,5.68474 -0.459208,0.54412 -0.6888437,1.0566 -0.6888437,1.53049 0,0.98383 0.33558,3.31657 1.0067653,6.99694 0.035431,0.25308 0.2472561,0.54412 0.6358494,0.87501 4.1444065,-3.06096 13.8442685,-6.17317 13.9356985,1.25716 -1.198635,3.56902 -5.122808,2.58202 -8.266042,2.40487 -1.757031,3.53042 -1.854566,7.65557 -1.854566,12.08062 0,0.25308 0.07067,0.54412 0.211951,0.87502 0.211952,0.47452 0.459208,0.71051 0.741826,0.71051 3.348093,-1.00282 6.169135,-0.689 9.537734,-2.02272 0.141154,-1.05659 0.33558,-2.58708 0.582836,-4.59144 8.888238,-1.4824 12.288004,-8.50655 12.028151,-16.72712 z M 22.254331,283.6453 c -3.640202,-2.25807 -11.019159,1.285 -11.127374,5.1381 1.597168,4.06252 9.173114,2.30363 10.968391,-0.38594 1.351721,-1.88543 1.287193,-3.19826 0.158995,-4.75532 z" />
+ </g>
+</svg>
diff --git a/src/activities/explore_world_animals/resource/animals/tux.svg b/src/activities/explore_world_animals/resource/animals/tux.svg
deleted file mode 100644
index 5aa44ea12..000000000
--- a/src/activities/explore_world_animals/resource/animals/tux.svg
+++ /dev/null
@@ -1,162 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- id="svg5845"
- viewBox="0 0 157.16 201"
- version="1.1"
- inkscape:version="0.91 r13725"
- sodipodi:docname="tux.svg">
- <defs
- id="defs24" />
- <sodipodi:namedview
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1"
- objecttolerance="10"
- gridtolerance="10"
- guidetolerance="10"
- inkscape:pageopacity="0"
- inkscape:pageshadow="2"
- inkscape:window-width="640"
- inkscape:window-height="480"
- id="namedview22" />
- <g
- id="layer1"
- transform="translate(-764.28 -326.15)">
- <path
- id="path5345"
- d="m878.37 396.2c-8.5139 5.5867-9.5012 23.06-2.2137 39.177 12.957 28.761 35.51 52.833 41.916 48.63 6.4058-4.2034 4.1697-34.851-11.18-68.799-7.2875-16.117-20.009-24.595-28.522-19.008z" />
- <path
- id="rect5342"
- d="m807.34 396.2c8.5139 5.5867 9.5012 23.06 2.2137 39.177-12.957 28.761-35.51 52.833-41.916 48.63-6.4058-4.2034-4.1697-34.851 11.18-68.799 7.2875-16.117 20.009-24.595 28.522-19.008z" />
- <path
- id="rect5259"
- d="m842.49 326.15c-26.503 0-43.955 20.116-44.875 45.438 0 0-0.0303-0.0104-0.0312 0-1.3736 15.903-7.7903 26.783-10.406 42.062-13.557 79.186-0.1875 79.073 10.812 102 29.333-5.3662 58.667-6.1266 88 0 0 0 37.198-27.469 11-101.5-5.7857-10.923-6.4927-28.358-9.625-42.562-5.2203-23.673-18.372-45.438-44.875-45.438z" />
- <path
- id="rect5265"
- d="m890.61 451.64c0 30.47-10.927 39-24.5 39h-46c-13.573 0-24.5-8.53-24.5-39s10.927-55 24.5-55h46c13.573 0 24.5 24.53 24.5 55z"
- fill="#fff" />
- <g
- id="g5267"
- transform="matrix(.99309 0 0 .95723 458.16 1158.4)"
- fill="#fff">
- <rect
- id="rect5269"
- rx="10"
- ry="18"
- height="36"
- width="20"
- y="-841.64"
- x="392" />
- <rect
- id="rect5271"
- rx="10"
- ry="18"
- height="36"
- width="20"
- y="-841.64"
- x="362" />
- </g>
- <path
- id="path5273"
- fill="#ecb63a"
- d="m875.26 386.7c0 8.723-14.673 19.623-32.772 19.623-18.1 0-32.772-10.9-32.772-19.623 0-8.7229 14.673-11.965 32.772-11.965 18.1 0 32.772 3.2424 32.772 11.965z" />
- <path
- id="path5275"
- fill="#876108"
- d="m815.74 387.29c3.5583 6.1603 13.97 12.15 26.255 12.15 12.284 0 22.697-5.99 26.255-12.15-5.3045 4.8654-15.073 8.9303-26.255 8.9303s-20.95-4.0649-26.255-8.9303z" />
- <rect
- id="rect5277"
- rx="6.6206"
- ry="7.6578"
- height="15.316"
- width="13.241"
- y="363.25"
- x="850.77" />
- <rect
- id="rect5279"
- rx="6.6206"
- ry="7.6578"
- height="15.316"
- width="13.241"
- y="363.25"
- x="820.97" />
- <g
- id="g5416"
- transform="translate(272.99 1153.8)">
- <path
- id="path5347"
- fill="#ecb63a"
- d="m574.39-641.24c0-7.865-14.723-17.693-32.886-17.693-18.162 0-32.886 9.8281-32.886 17.693s14.723 10.788 32.886 10.788c18.162 0 32.886-2.9235 32.886-10.788z" />
- <path
- id="path5352"
- fill="#926a0d"
- d="m569.27-644.62c-1.1416 2.9443-4.5466 6.1732-8.9783 7.1076-3.5502 0.7485-6.9044-0.17246-9.0983-1.7342-1.9547 1.773-4.931 3.1273-8.2581 3.1273-3.0204 0-5.7424-1.1138-7.682-2.644-2.0884 1.8756-5.5924 3.135-9.3864 2.5871-4.5417-0.65587-8.1424-3.7249-9.3624-6.6242-0.22081 0.36638-0.38332 0.77713-0.43211 1.2509-0.34341 3.3352 3.951 8.1685 9.7945 9.0124 3.794 0.5479 7.2981-0.71155 9.3864-2.5872 1.9395 1.5302 4.6615 2.644 7.682 2.644 3.3272 0 6.3034-1.3543 8.2581-3.1273 2.194 1.5618 5.5482 2.4828 9.0983 1.7342 5.7956-1.222 9.8597-6.3584 9.3624-9.6663-0.0604-0.40239-0.20095-0.76671-0.38409-1.0804z" />
- <path
- id="path5408"
- fill="#ecb63a"
- d="m632.39-641.24c0-7.865-14.723-17.693-32.886-17.693-18.162 0-32.886 9.8281-32.886 17.693s14.723 10.788 32.886 10.788c18.162 0 32.886-2.9235 32.886-10.788z" />
- <path
- id="path5410"
- d="m627.27-644.62c-1.1416 2.9443-4.5466 6.1732-8.9783 7.1076-3.5502 0.7485-6.9044-0.17246-9.0983-1.7342-1.9547 1.773-4.931 3.1273-8.2581 3.1273-3.0204 0-5.7424-1.1138-7.682-2.644-2.0884 1.8756-5.5924 3.135-9.3864 2.5871-4.5417-0.65587-8.1424-3.7249-9.3624-6.6242-0.22081 0.36638-0.38332 0.77713-0.43211 1.2509-0.34341 3.3352 3.951 8.1685 9.7945 9.0124 3.794 0.5479 7.2981-0.71155 9.3864-2.5872 1.9395 1.5302 4.6615 2.644 7.682 2.644 3.3272 0 6.3034-1.3543 8.2581-3.1273 2.194 1.5618 5.5482 2.4828 9.0983 1.7342 5.7956-1.222 9.8597-6.3584 9.3624-9.6663-0.0604-0.40239-0.20095-0.76671-0.38409-1.0804z"
- fill="#926a0d" />
- </g>
- </g>
- <metadata
- id="metadata20">
- <rdf:RDF>
- <cc:Work>
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <cc:license
- rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
- <dc:publisher>
- <cc:Agent
- rdf:about="http://openclipart.org/">
- <dc:title>Openclipart</dc:title>
- </cc:Agent>
- </dc:publisher>
- <dc:title>Tux the Penguin</dc:title>
- <dc:date>2011-01-06T20:30:29</dc:date>
- <dc:description>A little stylized drawing of Tux the Linux penguin.</dc:description>
- <dc:source>http://openclipart.org/detail/103855/tux-the-penguin-by-mairin</dc:source>
- <dc:creator>
- <cc:Agent>
- <dc:title>mairin</dc:title>
- </cc:Agent>
- </dc:creator>
- <dc:subject>
- <rdf:Bag>
- <rdf:li>OS</rdf:li>
- <rdf:li>animal</rdf:li>
- <rdf:li>cartoon</rdf:li>
- <rdf:li>character</rdf:li>
- <rdf:li>clip art</rdf:li>
- <rdf:li>clipart</rdf:li>
- <rdf:li>cute</rdf:li>
- <rdf:li>free</rdf:li>
- <rdf:li>linux</rdf:li>
- <rdf:li>penguin</rdf:li>
- <rdf:li>tux</rdf:li>
- </rdf:Bag>
- </dc:subject>
- </cc:Work>
- <cc:License
- rdf:about="http://creativecommons.org/licenses/publicdomain/">
- <cc:permits
- rdf:resource="http://creativecommons.org/ns#Reproduction" />
- <cc:permits
- rdf:resource="http://creativecommons.org/ns#Distribution" />
- <cc:permits
- rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
- </cc:License>
- </rdf:RDF>
- </metadata>
-</svg>
diff --git a/src/activities/explore_world_animals/resource/board/board1.qml b/src/activities/explore_world_animals/resource/board/board1.qml
index 27f54959d..105b1f30b 100644
--- a/src/activities/explore_world_animals/resource/board/board1.qml
+++ b/src/activities/explore_world_animals/resource/board/board1.qml
@@ -1,93 +1,93 @@
/* GCompris
*
* Copyright (C) 2015 Johnny Jazeix <jazeix@gmail.com>
*
* Authors:
* Beth Hadley <bethmhadley@gmail.com> (GTK+ version)
* Johnny Jazeix <jazeix@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string backgroundImage: "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/content.svg"
property var tab : [
{
- "image": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/tux.svg",
+ "image": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/question.svg",
"title": qsTr("Jaguar"),
- "text": qsTr("Jaguars are named after the Native American word meaning 'he who kills with one leap' because they like to climb trees to attack their prey."),
+ "text": qsTr("The jaguar's jaw is well developed. Because of this, it has the strongest bite of all the felines, being able to break even a tortoise shell!"),
"image2": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/jaggy.jpg",
"text2": qsTr("Jaguar"),
"x": 0.36,
"y": 0.56,
"width": 0.0785,
"height": 0.1005
},
{
- "image": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/tux.svg",
+ "image": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/question.svg",
"title": qsTr("Hedgehog"),
"text": qsTr("Hedgehogs eat small animals, like frogs and insects, so many people keep them as useful pets. When in danger, they will curl up into a ball and stick up their coat of sharp spines."),
"image2": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/hedgy.jpg",
"text2": qsTr("Hedgehog"),
"x": 0.53,
"y": 0.24,
"width": 0.0785,
"height": 0.1005
},
{
- "image": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/tux.svg",
+ "image": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/question.svg",
"title": qsTr("Giraffe"),
"text": qsTr("The giraffe lives in Africa and is the tallest mammal in the world. Just their legs, which are usually 1.8 meters long, are taller than most humans!"),
"image2": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/giraffe.jpg",
"text2": qsTr("Giraffe"),
"x": 0.58,
"y": 0.48,
"width": 0.0785,
"height": 0.1005
},
{
- "image": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/tux.svg",
+ "image": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/question.svg",
"title": qsTr("Bison"),
"text": qsTr("Bison live on the plains of North America and were hunted by the Native Americans for food."),
"image2": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/bison.jpg",
"text2": qsTr("Bison"),
"x": 0.27,
"y": 0.29,
"width": 0.0785,
"height": 0.1005
},
{
- "image": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/tux.svg",
+ "image": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/question.svg",
"title": qsTr("Narwhal"),
"text": qsTr("Narwhals are whales that live in the Arctic Ocean and have long tusks. These tusks remind many people of the mythical unicorn's horn."),
"image2": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/narwhal.jpg",
"text2": qsTr("Narwhal"),
"x": 0.50,
"y": 0.06,
"width": 0.0785,
"height": 0.1005
}
]
property var instructions : [
{
"text": qsTr("Explore exotic animals from around the world.")
},
{
"text": qsTr("Click on location where the given animal lives.")
}
]
}
diff --git a/src/activities/explore_world_animals/resource/board/board2.qml b/src/activities/explore_world_animals/resource/board/board2.qml
index 5414e47c3..61d3eb293 100644
--- a/src/activities/explore_world_animals/resource/board/board2.qml
+++ b/src/activities/explore_world_animals/resource/board/board2.qml
@@ -1,93 +1,93 @@
/* GCompris
*
* Copyright (C) 2017 Sergey Popov <sergobot@protonmail.com>
*
* Authors:
* Beth Hadley <bethmhadley@gmail.com> (GTK+ version)
* Johnny Jazeix <jazeix@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string backgroundImage: "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/content.svg"
property var tab : [
{
- "image": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/tux.svg",
+ "image": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/question.svg",
"title": qsTr("Chameleon"),
"text": qsTr("Chameleon lives in Africa and Madagascar and is well-known for its ability to change its skin color in a couple of seconds."),
"image2": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/chameleon.jpg",
"text2": qsTr("Chameleon"),
"x": 0.63,
"y": 0.56,
"width": 0.0785,
"height": 0.1005
},
{
- "image": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/tux.svg",
+ "image": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/question.svg",
"title": qsTr("Polar bear"),
"text": qsTr("Polar bear is one of the world's largest predatory mammals. It weights up to a ton and can be as long as 3 meters!"),
"image2": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/polar_bear.jpg",
"text2": qsTr("Polar bear"),
"x": 0.75,
"y": 0.10,
"width": 0.0785,
"height": 0.1005
},
{
- "image": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/tux.svg",
+ "image": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/question.svg",
"title": qsTr("Kangaroo"),
"text": qsTr("Kangaroo lives in Australia and is well-known for pouch on its belly used to cradle baby kangaroos."),
"image2": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/kangaroo.jpg",
"text2": qsTr("Kangaroo"),
"x": 0.87,
"y": 0.61,
"width": 0.0785,
"height": 0.1005
},
{
- "image": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/tux.svg",
+ "image": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/question.svg",
"title": qsTr("Scarlet macaw"),
"text": qsTr("Scarlet macaw lives in South America and is a big and bright colored parrot, able to learn up to 100 words!"),
"image2": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/scarlet_macaw.jpg",
"text2": qsTr("Scarlet macaw"),
"x": 0.33,
"y": 0.48,
"width": 0.0785,
"height": 0.1005
},
{
- "image": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/tux.svg",
+ "image": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/question.svg",
"title": qsTr("Moose"),
"text": qsTr("Being the largest of all the deers, moose eats as much as 25 kg a day. However, it's not easy, so sometimes moose has to stand on its hind legs to reach branches up to 4 meters!"),
"image2": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/moose.jpg",
"text2": qsTr("Moose"),
"x": 0.25,
"y": 0.15,
"width": 0.0785,
"height": 0.1005
}
]
property var instructions : [
{
"text": qsTr("Explore exotic animals from around the world.")
},
{
"text": qsTr("Click on location where the given animal lives.")
}
]
}
diff --git a/src/activities/explore_world_animals/resource/board/board3.qml b/src/activities/explore_world_animals/resource/board/board3.qml
index e48b1082d..12bb02b7c 100644
--- a/src/activities/explore_world_animals/resource/board/board3.qml
+++ b/src/activities/explore_world_animals/resource/board/board3.qml
@@ -1,93 +1,93 @@
/* GCompris
*
* Copyright (C) 2017 Ilya Bizyaev <bizyaev@zoho.com>
*
* Authors:
* Beth Hadley <bethmhadley@gmail.com> (GTK+ version)
* Johnny Jazeix <jazeix@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string backgroundImage: "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/content.svg"
property var tab : [
{
- "image": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/tux.svg",
+ "image": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/question.svg",
"title": qsTr("Crocodile"),
"text": qsTr("A crocodile is a large amphibious reptile. It lives mostly in large tropical rivers, where it is an ambush predator."),
"image2": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/crocodile.jpg",
"text2": qsTr("Crocodile"),
"x": 0.50,
"y": 0.40,
"width": 0.0785,
"height": 0.1005
},
{
- "image": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/tux.svg",
+ "image": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/question.svg",
"title": qsTr("Komodo dragon"),
"text": qsTr("The Komodo dragon is the largest living lizard (up to 3 meters). It inhabits the Indonesian islands."),
"image2": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/dragon.jpg",
"text2": qsTr("Komodo dragon"),
"x": 0.80,
"y": 0.49,
"width": 0.0785,
"height": 0.1005
},
{
- "image": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/tux.svg",
+ "image": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/question.svg",
"title": qsTr("Koala"),
"text": qsTr("Koalas are herbivore marsupials that live in the eucalyptus forests of eastern Australia."),
"image2": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/koala.jpg",
"text2": qsTr("Koala"),
"x": 0.87,
"y": 0.61,
"width": 0.0785,
"height": 0.1005
},
{
- "image": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/tux.svg",
+ "image": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/question.svg",
"title": qsTr("Ring-tailed lemur"),
"text": qsTr("Lemur is a primate that lives in the dry regions of southwest Madagascar. The striped tail makes it easy to recognize."),
"image2": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/lemur.jpg",
"text2": qsTr("Ring-tailed lemur"),
"x": 0.65,
"y": 0.60,
"width": 0.0785,
"height": 0.1005
},
{
- "image": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/tux.svg",
+ "image": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/question.svg",
"title": qsTr("Panda"),
"text": qsTr("Panda is a bear with black and white fur that lives in a few mountain ranges in central China. Pandas mostly eat bamboo."),
"image2": "qrc:/gcompris/src/activities/explore_world_animals/resource/animals/panda.jpg",
"text2": qsTr("Panda"),
"x": 0.80,
"y": 0.30,
"width": 0.0785,
"height": 0.1005
}
]
property var instructions : [
{
"text": qsTr("Explore exotic animals from around the world.")
},
{
"text": qsTr("Click on location where the given animal lives.")
}
]
}
diff --git a/src/activities/explore_world_music/ActivityInfo.qml b/src/activities/explore_world_music/ActivityInfo.qml
index bb4814bfe..68451ae08 100644
--- a/src/activities/explore_world_music/ActivityInfo.qml
+++ b/src/activities/explore_world_music/ActivityInfo.qml
@@ -1,47 +1,47 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Johnny Jazeix <jazeix@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "explore_world_music/ExploreWorldMusic.qml"
difficulty: 4
icon: "explore_world_music/explore_world_music.svg"
author: "Johnny Jazeix &lt;jazeix@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Explore World Music")
//: Help title
description: qsTr("Learn about the music of the world.")
// intro: "Click on the suitcases to learn about music from around the world."
//: Help goal
goal: qsTr("Develop a better understanding of the variety of music present in the world")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("There are three levels in this activity.
In the first level, enjoy exploring music from around the world. Click on each suitcase to learn about the music from that area, and listen to a short sample. Study well, because there will be two games related to this information next!
The second level is a matching game. You will hear a clip of music, and you must select the location that corresponds to that music. Click the play button if you'd like to hear the music again. You win the level when you have correctly matched all sound clips.
The third level is also a matching game. You must select the location that matches the text description on the screen. You win the level when you have correctly matched all text prompts.
")
credit: qsTr("Images from http://commons.wikimedia.org/wiki, http://archive.org")
section: "discovery sound_group"
createdInVersion: 0
}
diff --git a/src/activities/explore_world_music/ExploreWorldMusic.qml b/src/activities/explore_world_music/ExploreWorldMusic.qml
index c426098c0..bf839b897 100644
--- a/src/activities/explore_world_music/ExploreWorldMusic.qml
+++ b/src/activities/explore_world_music/ExploreWorldMusic.qml
@@ -1,34 +1,34 @@
/* GCompris - explore_world_music.qml
*
* Copyright (C) 2015 Johnny Jazeix <jazeix@gmail.com>
*
* Authors:
* Beth Hadley <bethmhadley@gmail.com> (GTK+ version)
* Johnny Jazeix <jazeix@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../explore_farm_animals"
ExploreLevels {
id: activity
numberOfLevels: 1
url: "qrc:/gcompris/src/activities/explore_world_music/resource/"
hasAudioQuestions: true
}
diff --git a/src/activities/explore_world_music/resource/board/board1.qml b/src/activities/explore_world_music/resource/board/board1.qml
index de0d19e88..e6f1740f6 100644
--- a/src/activities/explore_world_music/resource/board/board1.qml
+++ b/src/activities/explore_world_music/resource/board/board1.qml
@@ -1,150 +1,150 @@
/* GCompris
*
* Copyright (C) 2015 Johnny Jazeix <jazeix@gmail.com>
*
* Authors:
* Beth Hadley <bethmhadley@gmail.com> (GTK+ version)
* Johnny Jazeix <jazeix@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0 as GCompris
QtObject {
property string backgroundImage: "qrc:/gcompris/src/activities/explore_world_music/resource/music/content.svg"
property var tab : [
{
"image": "qrc:/gcompris/src/activities/explore_world_music/resource/music/suitcase.svg",
"title": qsTr("Australia"),
"text": qsTr("Aboriginals were the first people to live in Australia. They sing and play instruments, like the didgeridoo. It is made from a log and can be up to five meters long!"),
"audio": GCompris.ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/explore_world_music/resource/music/australia.$CA"),
"image2": "qrc:/gcompris/src/activities/explore_world_music/resource/music/australia.jpg",
"text2": qsTr("Australia"),
"x": 0.87,
"y": 0.65,
"width": 0.05,
"height": 0.05
},
{
"image": "qrc:/gcompris/src/activities/explore_world_music/resource/music/suitcase.svg",
"title": qsTr("Africa"),
"text": qsTr("Music is a part of everyday life in Africa. African music features a great variety of drums, and they believe it is a sacred and magical instrument."),
"audio": GCompris.ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/explore_world_music/resource/music/africa.$CA"),
"image2": "qrc:/gcompris/src/activities/explore_world_music/resource/music/africa.jpg",
"text2": qsTr("Africa"),
"x": 0.57,
"y": 0.47,
"width": 0.05,
"height": 0.05
},
{
"image": "qrc:/gcompris/src/activities/explore_world_music/resource/music/suitcase.svg",
"title": qsTr("Middle East"),
"text": qsTr("Music is a very important part of middle eastern culture. Specific songs are played to call worshipers to prayer. The lute is an instrument invented thousands of years ago and still in use today."),
"audio": GCompris.ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/explore_world_music/resource/music/middleeast.$CA"),
"image2": "qrc:/gcompris/src/activities/explore_world_music/resource/music/middleeast.jpg",
"text2": qsTr("Middle East"),
"x": 0.62,
"y": 0.32,
"width": 0.05,
"height": 0.05
},
{
"image": "qrc:/gcompris/src/activities/explore_world_music/resource/music/suitcase.svg",
"title": qsTr("Japan"),
"text": qsTr("Taiko drumming comes from Japan. This type of drumming was originally used to scare enemies in battle. It is very loud, and performances are very exciting with crowds cheering and performers yelling!"),
"audio": GCompris.ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/explore_world_music/resource/music/japan.$CA"),
"image2": "qrc:/gcompris/src/activities/explore_world_music/resource/music/japan.jpg",
"text2": qsTr("Japan"),
"x": 0.87,
"y": 0.22,
"width": 0.05,
"height": 0.05
},
{
"image": "qrc:/gcompris/src/activities/explore_world_music/resource/music/suitcase.svg",
"title": qsTr("Scotland and Ireland"),
"text": qsTr("Folk music of this region is called celtic music, often incorporates a narrative poem or story. Typical instruments include bagpipes, fiddles, flutes, harps, and accordions."),
"audio": GCompris.ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/explore_world_music/resource/music/ireland.$CA"),
"image2": "qrc:/gcompris/src/activities/explore_world_music/resource/music/ireland.jpg",
"text2": qsTr("Scotland and Ireland"),
"x": 0.50,
"y": 0.14,
"width": 0.05,
"height": 0.05
},
{
"image": "qrc:/gcompris/src/activities/explore_world_music/resource/music/suitcase.svg",
"title": qsTr("Italy"),
"text": qsTr("Italy is famous for its Opera. Opera is a musical theater where actors tell a story by acting and singing. Opera singers, both male and female, learn special techniques to sing operas."),
"audio": GCompris.ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/explore_world_music/resource/music/italy.$CA"),
"image2": "qrc:/gcompris/src/activities/explore_world_music/resource/music/italy.jpg",
"text2": qsTr("Italy"),
"x": 0.54,
"y": 0.22,
"width": 0.05,
"height": 0.05
},
{
"image": "qrc:/gcompris/src/activities/explore_world_music/resource/music/suitcase.svg",
"title": qsTr("European Classical Music"),
"text": qsTr("Europe is the home of classical music. Famous composers like Bach, Beethoven, and Mozart forever changed music history."),
"audio": GCompris.ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/explore_world_music/resource/music/beethoven.$CA"),
"image2": "qrc:/gcompris/src/activities/explore_world_music/resource/music/orchestra.jpg",
"text2": qsTr("European Classical Music"),
"x": 0.57,
"y": 0.17,
"width": 0.05,
"height": 0.05
},
{
"image": "qrc:/gcompris/src/activities/explore_world_music/resource/music/suitcase.svg",
"title": qsTr("Mexico"),
"text": qsTr("Mariachi is a famous type of Mexican music. It features guitars, trumpets, and violins. These bands play for many occasions, including weddings and parties."),
"audio": GCompris.ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/explore_world_music/resource/music/mexico.$CA"),
"image2": "qrc:/gcompris/src/activities/explore_world_music/resource/music/mexico.jpg",
"text2": qsTr("Mexico"),
"x": 0.24,
"y": 0.37,
"width": 0.05,
"height": 0.05
},
{
"image": "qrc:/gcompris/src/activities/explore_world_music/resource/music/suitcase.svg",
"title": qsTr("United States of America"),
"text": qsTr("USA also has a wide variety of musical genres, but perhaps it is most famous for rock n' roll music. This music features vocalists, guitars, and drums."),
"audio": GCompris.ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/explore_world_music/resource/music/america.$CA"),
"image2": "qrc:/gcompris/src/activities/explore_world_music/resource/music/america.jpg",
"text2": qsTr("United States of America"),
"x": 0.25,
"y": 0.22,
"width": 0.05,
"height": 0.05
}
]
property var instructions : [
{
"text": qsTr("Explore world music! Click on the suitcases.")
},
{
"text": qsTr("Click on the location that matches the music you hear.")
},
{
"text": qsTr("Click on the location that matches the text.")
}
]
}
diff --git a/src/activities/family/ActivityInfo.qml b/src/activities/family/ActivityInfo.qml
index af6b9ee8b..10055e3b0 100644
--- a/src/activities/family/ActivityInfo.qml
+++ b/src/activities/family/ActivityInfo.qml
@@ -1,42 +1,42 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2016 Rajdeep Kaur <rajdeep.kaur@kde.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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "family/Family.qml"
difficulty: 2
icon: "family/family.svg"
author: "Rajdeep Kaur &lt;rajdeep.kaur@kde.org&gt;"
demo: true
//: Activity title
title: qsTr("Family")
//: Help title
description: qsTr("Select the name you should call this family member")
//intro: "Let us understand what to call our relatives"
//: Help goal
goal: qsTr("Learn the relationships in a family, according to the lineal system used in most Western societies")
//: Help prerequisite
prerequisite: qsTr("Reading skills")
//: Help manual
manual: qsTr("A family tree is shown.\n" +
"The circles are linked with lines to mark the relations. Married couples are marked with a ring on the link.\n" +
"You are the person in the white circle. Select the name you should call the person in the orange circle.\n")
credit: ""
section: "discovery"
createdInVersion: 9000
}
diff --git a/src/activities/family/Dataset.qml b/src/activities/family/Dataset.qml
index 3bb5d1476..da37328db 100644
--- a/src/activities/family/Dataset.qml
+++ b/src/activities/family/Dataset.qml
@@ -1,619 +1,619 @@
/* GCompris - Dataset.qml
*
* Copyright (C) 2017 Rudra Nil Basu <rudra.nil.basu.1996@gmail.com>
*
* Authors:
*
* Rajdeep Kaur <rajdeep.kaur@kde.org>
* Rudra Nil Basu <rudra.nil.basu.1996@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property real nodeWidth: background.nodeWidthRatio
property real nodeHeight: background.nodeHeightRatio
property int numberOfGenerations: 3
/*
* Vertically, the screen is divided into three parts:
* gen1: stands for Generation 1
* gen2: stands for Generation 2
* gen3: stands for Generation 3
*/
readonly property real gen1: numberOfGenerations == 3 ? 0.10 : 0.20
readonly property real gen2: numberOfGenerations == 3 ? 0.40 : 0.60
readonly property real gen3: 0.70
/*
* Horizontally, the screen is divided into left, center
* and right
*/
readonly property real left: 0.2
readonly property real center: 0.4
readonly property real right: 0.6
/*
* ext: exterior
* int: interior
*/
readonly property real leftExt: 0.1
readonly property real leftInt: 0.3
readonly property real rightInt: 0.5
readonly property real rightExt: 0.7
/*
* pairs are used to determine the correct
* pair for a given relation in the family_find_relative
* activity
* A correct pair is formed by selecting a node of type
* "pair1" and "pair2" only
*/
readonly property int pair1: -1
readonly property int pair2: 1
readonly property int noPair: 0
/*
* Returns the x coordinate of the
* right edge of a node
*/
function rightXEdge(xPosition) {
return xPosition + nodeWidth
}
/*
* Returns the y coordinate of the
* midpoint of a node
*/
function nodeMidPointY(yPosition) {
return yPosition + nodeHeight / 2
}
/*
* Returns the x coordinate of the
* midpoint of two nodes
*/
function nodeMidPointX(xLeftPosition, xRightPosition) {
return ((xLeftPosition + nodeWidth) + xRightPosition) / 2
}
// Note:
// To add any new levels in the activities doesn't really require coding skills, it can be done by adding the calculated coordinates
// to the following database (with trial-and-error...)
// { edgeList: [
// [],
// []
// ],
// nodePositions: [
// [],
// [],
// []
// ],
// captions: [ [],
// []
// ],
// nodeleave: [],
// currentstate: [],
// edgeState:[],
// answer: [],
-// optionss: []
+// options: []
//
// },
property var levelElements: [
// level 1
{
numberOfGenerations: 2,
edgeList: [
[left + nodeWidth, gen1 + nodeHeight / 2, right, gen1 + nodeHeight / 2],
[((left + nodeWidth) + right) / 2, gen1 + nodeHeight / 2, ((left + nodeWidth) + right) / 2, gen2]
],
nodePositions: [
[left, gen1],
[right, gen1],
[center, gen2]
],
captions: [
[center - (nodeWidth * 3 / 4), gen2 + nodeHeight / 2],
[left - nodeWidth / 2, gen1]
],
nodeValue: ["man1.svg", "woman2.svg", "boy1.svg"],
nodeWeights: [pair1, noPair, pair2],
currentState: ["activeTo", "deactivate", "active"],
edgeState:["married","others"],
answer: [qsTr("Father")],
options: [qsTr("Father"), qsTr("Grandfather"), qsTr("Uncle")]
},
// level 2
{
numberOfGenerations: 2,
edgeList: [
[left + nodeWidth, gen1 + nodeHeight / 2, right, gen1 + nodeHeight / 2],
[((left + nodeWidth) + right) / 2, gen1 + nodeHeight / 2, ((left + nodeWidth) + right) / 2, gen2]
],
nodePositions: [
[left, gen1],
[right, gen1],
[center, gen2]
],
captions: [
[center - (nodeWidth * 3 / 4), gen2 + nodeHeight / 2],
[right + nodeWidth, gen1]
],
nodeValue: ["man1.svg", "woman2.svg", "boy1.svg"],
nodeWeights: [noPair, pair1, pair2],
currentState: ["deactivate", "activeTo", "active"],
edgeState:["married","others"],
answer: [qsTr("Mother")],
options: [qsTr("Mother"), qsTr("Grandmother"), qsTr("Aunt")]
},
// level 3
{
numberOfGenerations: 2,
edgeList: [
[rightXEdge(left), nodeMidPointY(gen1), right, nodeMidPointY(gen1)],
[nodeMidPointX(left, right), nodeMidPointY(gen1), nodeMidPointX(left, right), gen2 - nodeHeight / 4],
[left + nodeWidth / 2, gen2 - nodeHeight / 4, right + nodeWidth / 2, gen2 - nodeHeight / 4],
[left + nodeWidth / 2, gen2 - nodeHeight / 4, left + nodeWidth / 2, gen2],
[right + nodeWidth / 2, gen2 - nodeHeight / 4, right + nodeWidth / 2, gen2]
],
nodePositions: [
[left, gen1],
[right, gen1],
[left, gen2],
[right, gen2]
],
captions:[
[left - (nodeWidth * 3 / 4), gen2 + nodeHeight / 2],
[right + nodeWidth, gen2]
],
nodeValue: ["man1.svg", "woman2.svg", "boy1.svg", "boy2.svg"],
nodeWeights: [noPair, noPair, pair1, pair2],
currentState: ["deactivate", "deactivate", "active", "activeTo"],
edgeState:["married","others","others","others"],
answer: [qsTr("Brother")],
options: [qsTr("Cousin"), qsTr("Brother"), qsTr("Sister")]
},
// level 4
{
numberOfGenerations: 2,
edgeList: [
[rightXEdge(left), nodeMidPointY(gen1), right, nodeMidPointY(gen1)],
[nodeMidPointX(left, right), nodeMidPointY(gen1), nodeMidPointX(left, right), gen2 - nodeHeight / 4],
[left + nodeWidth / 2, gen2 - nodeHeight / 4, right + nodeWidth / 2, gen2 - nodeHeight / 4],
[left + nodeWidth / 2, gen2 - nodeHeight / 4, left + nodeWidth / 2, gen2],
[center + nodeWidth / 2, gen2 - nodeHeight / 4, center + nodeWidth / 2, gen2],
[right + nodeWidth / 2, gen2 - nodeHeight / 4, right + nodeWidth / 2, gen2]
],
nodePositions: [
[left, gen1],
[right, gen1],
[left, gen2],
[center, gen2],
[right, gen2]
],
captions: [
[left - (nodeWidth * 3 / 4), gen2 + nodeHeight / 2],
[center + nodeWidth / 2, (gen2 + nodeHeight)]
],
nodeValue: ["man1.svg", "woman2.svg", "boy1.svg", "girl1.svg", "boy2.svg"],
nodeWeights: [noPair, noPair, pair1, pair2, pair1],
currentState: ["deactivate", "deactivate", "active", "activeTo", "deactivate"],
edgeState:["married", "others", "others", "others", "others", "others"],
answer: [qsTr("Sister")],
options: [qsTr("Cousin"), qsTr("Brother"), qsTr("Sister")]
},
// level 5
{
numberOfGenerations: 3,
edgeList: [
[leftExt + nodeWidth, gen1 + nodeHeight / 2, rightInt, gen1 + nodeHeight / 2],
[((leftExt + nodeWidth) + rightInt) / 2, gen1 + nodeHeight / 2, ((leftExt + nodeWidth) + rightInt) / 2, gen2],
[leftInt + nodeWidth, gen2 + nodeHeight / 2, right, gen2 + nodeHeight / 2],
[((leftInt + nodeWidth) + right) / 2, gen2 + nodeHeight / 2, ((leftInt + nodeWidth) + right) / 2, gen3 - nodeWidth / 4],
[left + nodeWidth / 2, gen3 - nodeWidth / 4, right + nodeWidth / 2, gen3 - nodeWidth / 4],
[left + nodeWidth / 2, gen3 - nodeWidth / 4, left + nodeWidth / 2, gen3],
[center + nodeWidth / 2, gen3 - nodeWidth / 4, center + nodeWidth / 2, gen3],
[right + nodeWidth / 2, gen3 - nodeWidth / 4, right + nodeWidth / 2, gen3]
],
nodePositions: [
[leftExt, gen1],
[rightInt, gen1],
[leftInt, gen2],
[right, gen2],
[left, gen3],
[center, gen3],
[right, gen3]
],
captions: [
[leftExt, gen3 + nodeHeight / 4],
[leftExt, gen1 + nodeHeight]
],
nodeValue: ["oldMan1.svg", "oldWoman1.svg", "man2.svg", "woman1.svg", "girl1.svg", "boy1.svg", "boy2.svg"],
nodeWeights: [pair1, noPair, noPair, noPair, pair2, pair2, pair2],
currentState: ["activeTo", "deactivate", "deactivate", "deactivate", "active", "deactivate", "deactivate"],
edgeState:["married","others","married","others","others","others","others","others" ],
answer: [qsTr("Grandfather")],
options: [qsTr("Granddaughter"), qsTr("Grandson"), qsTr("Grandfather"), qsTr("Grandmother")]
},
// level 6
{
numberOfGenerations: 3,
edgeList: [
[leftExt + nodeWidth, gen1 + nodeHeight / 2, rightInt, gen1 + nodeHeight / 2],
[((leftExt + nodeWidth) + rightInt) / 2, gen1 + nodeHeight / 2, ((leftExt + nodeWidth) + rightInt) / 2, gen2],
[leftInt + nodeWidth, gen2 + nodeHeight / 2, right, gen2 + nodeHeight / 2],
[((leftInt + nodeWidth) + right) / 2, gen2 + nodeHeight / 2, ((leftInt + nodeWidth) + right) / 2, gen3 - nodeWidth / 4],
[left + nodeWidth / 2, gen3 - nodeWidth / 4, right + nodeWidth / 2, gen3 - nodeWidth / 4],
[left + nodeWidth / 2, gen3 - nodeWidth / 4, left + nodeWidth / 2, gen3],
[center + nodeWidth / 2, gen3 - nodeWidth / 4, center + nodeWidth / 2, gen3],
[right + nodeWidth / 2, gen3 - nodeWidth / 4, right + nodeWidth / 2, gen3]
],
nodePositions: [
[leftExt, gen1],
[rightInt, gen1],
[leftInt, gen2],
[right, gen2],
[left, gen3],
[center, gen3],
[right, gen3]
],
captions: [
[right + nodeWidth, gen3 + (nodeHeight * 3 / 4)],
[rightInt, gen1 + nodeHeight]
],
nodeValue: ["oldMan1.svg", "oldWoman1.svg", "man2.svg", "woman1.svg", "boy1.svg", "girl1.svg", "boy2.svg"],
nodeWeights: [noPair, pair1, noPair, noPair, pair2, pair2, pair2],
currentState: ["deactivate", "activeTo", "deactivate", "deactivate", "deactivate", "deactivate", "active", "active"],
edgeState:["married","others","married","others","others","others","others","others" ],
answer: [qsTr("Grandmother")],
options: [qsTr("Granddaughter"), qsTr("Grandson"), qsTr("Grandfather"), qsTr("Grandmother")],
},
// level 7
{
numberOfGenerations: 3,
edgeList: [
[leftExt + nodeWidth, gen1 + nodeHeight / 2, rightInt, gen1 + nodeHeight / 2],
[((leftExt + nodeWidth) + rightInt) / 2, gen1 + nodeHeight / 2, ((leftExt + nodeWidth) + rightInt) / 2, gen2],
[leftInt + nodeWidth, gen2 + nodeHeight / 2, right, gen2 + nodeHeight / 2],
[((leftInt + nodeWidth) + right) / 2, gen2 + nodeHeight / 2, ((leftInt + nodeWidth) + right) / 2, gen3 - nodeWidth / 4],
[left + nodeWidth / 2, gen3 - nodeWidth / 4, right + nodeWidth / 2, gen3 - nodeWidth / 4],
[left + nodeWidth / 2, gen3 - nodeWidth / 4, left + nodeWidth / 2, gen3],
[center + nodeWidth / 2, gen3 - nodeWidth / 4, center + nodeWidth / 2, gen3],
[right + nodeWidth / 2, gen3 - nodeWidth / 4, right + nodeWidth / 2, gen3]
],
nodePositions: [
[leftExt, gen1],
[rightInt, gen1],
[leftInt, gen2],
[right, gen2],
[left, gen3],
[center, gen3],
[right, gen3]
],
captions: [
[leftExt + nodeWidth, gen1],
[right + nodeWidth, gen3]
],
nodeValue: ["oldMan1.svg", "oldWoman1.svg", "man2.svg", "woman1.svg", "boy1.svg", "boy2.svg","girl1.svg" ],
nodeWeights: [pair1, pair1, noPair, noPair, noPair, noPair, pair2],
currentState: ["active", "deactivate", "deactivate", "deactivate", "deactivate", "deactivate", "activeTo"],
edgeState:["married","others","married","others","others","others","others","others" ],
answer: [qsTr("Granddaughter")],
options: [qsTr("Granddaughter"), qsTr("Grandson"), qsTr("Grandfather"), qsTr("Grandmother")]
},
// level 8
{
numberOfGenerations: 3,
edgeList: [
[leftExt + nodeWidth, gen1 + nodeHeight / 2, rightInt, gen1 + nodeHeight / 2],
[((leftExt + nodeWidth) + rightInt) / 2, gen1 + nodeHeight / 2, ((leftExt + nodeWidth) + rightInt) / 2, gen2],
[leftInt + nodeWidth, gen2 + nodeHeight / 2, right, gen2 + nodeHeight / 2],
[((leftInt + nodeWidth) + right) / 2, gen2 + nodeHeight / 2, ((leftInt + nodeWidth) + right) / 2, gen3 - nodeWidth / 4],
[left + nodeWidth / 2, gen3 - nodeWidth / 4, right + nodeWidth / 2, gen3 - nodeWidth / 4],
[left + nodeWidth / 2, gen3 - nodeWidth / 4, left + nodeWidth / 2, gen3],
[center + nodeWidth / 2, gen3 - nodeWidth / 4, center + nodeWidth / 2, gen3],
[right + nodeWidth / 2, gen3 - nodeWidth / 4, right + nodeWidth / 2, gen3]
],
nodePositions: [
[leftExt, gen1],
[rightInt, gen1],
[leftInt, gen2],
[right, gen2],
[left, gen3],
[center, gen3],
[right, gen3]
],
captions: [
[rightInt + nodeWidth, gen1],
[right + nodeWidth, gen3]
],
nodeValue: ["oldMan1.svg", "oldWoman1.svg", "man2.svg", "woman1.svg", "boy1.svg", "girl1.svg", "boy2.svg"],
nodeWeights: [pair1, pair1, noPair, noPair, pair2, noPair, pair2],
currentState: ["deactivate", "active", "deactivate", "deactivate", "deactivate", "deactivate", "activeTo", "active"],
edgeState:["married","others","married","others","others","others","others","others" ],
answer: [qsTr("Grandson")],
options: [qsTr("Granddaughter"), qsTr("Grandson"), qsTr("Grandfather"), qsTr("Grandmother")]
},
// level 9
{
numberOfGenerations: 3,
edgeList: [
[center + nodeWidth / 2, gen1 + nodeHeight, center + nodeWidth / 2, gen2 + nodeHeight / 2],
[rightXEdge(left), nodeMidPointY(gen2), right, nodeMidPointY(gen2)],
[left + nodeWidth / 2, gen2 + nodeHeight, left + nodeWidth / 2, gen3],
[right + nodeWidth / 2, gen2 + nodeHeight, right + nodeWidth / 2, gen3]
],
nodePositions: [
[center, gen1],
[left, gen2],
[right, gen2],
[left, gen3],
[right, gen3]
],
captions: [
[(right + nodeWidth * 1.1), gen3 + nodeHeight / 4],
[left - nodeWidth / 2, gen3 + nodeHeight / 4]
],
nodeValue: ["oldMan1.svg", "man3.svg", "man2.svg", "boy1.svg","boy2.svg"],
nodeWeights: [noPair, noPair, noPair, pair2, pair1],
currentState: ["deactivate", "deactivate", "deactivate", "activeTo","active"],
edgeState:["others","others","others","others"],
answer: [qsTr("Cousin")],
options: [qsTr("Brother"), qsTr("Sister"), qsTr("Cousin")]
},
// level 10
{
numberOfGenerations: 3,
edgeList: [
[center + nodeWidth / 2, gen1 + nodeHeight, center + nodeWidth / 2, gen2 + nodeHeight / 2],
[rightXEdge(left), nodeMidPointY(gen2), right, nodeMidPointY(gen2)],
[left + nodeWidth / 2, gen2 + nodeHeight, left + nodeWidth / 2, gen3]
],
nodePositions: [
[center, gen1],
[left, gen2],
[right, gen2],
[left, gen3]
],
captions: [
[left - nodeWidth * 3 / 4, gen3 + nodeHeight / 4],
[right + nodeWidth * 1.1, gen2 + nodeHeight / 4]
],
nodeValue: ["oldMan1.svg", "man3.svg", "man2.svg", "boy1.svg"],
nodeWeights: [noPair, noPair, pair1, pair2],
currentState: ["deactivate", "deactivate", "activeTo", "active"],
edgeState:["others","others","others"],
answer: [qsTr("Uncle")],
options: [qsTr("Uncle"), qsTr("Aunt"), qsTr("Nephew"), qsTr("Niece")]
},
// level 11
{
numberOfGenerations: 3,
edgeList: [
[center + nodeWidth / 2, gen1 + nodeHeight, center + nodeWidth / 2, gen2 + nodeHeight / 2],
[rightXEdge(left), nodeMidPointY(gen2), right, nodeMidPointY(gen2)],
[left + nodeWidth / 2, gen2 + nodeHeight, left + nodeWidth / 2, gen3]
],
nodePositions: [
[center, gen1],
[left, gen2],
[right, gen2],
[left, gen3]
],
captions: [
[right + nodeWidth * 1.1, gen2 + nodeHeight / 4],
[left - nodeWidth * 3 / 4, gen3 + nodeHeight / 4]
],
nodeValue: ["oldMan1.svg", "man3.svg", "man2.svg", "boy1.svg"],
nodeWeights: [noPair, noPair, pair2, pair1],
currentState: ["deactivate", "deactivate", "active", "activeTo"],
edgeState:["others","others","others"],
answer: [qsTr("Nephew")],
options: [qsTr("Uncle"), qsTr("Aunt"), qsTr("Nephew"), qsTr("Niece")]
},
// level 12
{
numberOfGenerations: 3,
edgeList: [
[rightXEdge(left), gen1 + nodeHeight / 2, right, gen1 + nodeHeight / 2],
[nodeMidPointX(left, right), nodeMidPointY(gen1), nodeMidPointX(left, right), nodeMidPointY(gen2)],
[rightXEdge(left), nodeMidPointY(gen2), right, nodeMidPointY(gen2)],
[left + nodeWidth / 2, gen2 + nodeHeight, left + nodeWidth / 2, gen3]
],
nodePositions: [
[left, gen1],
[right, gen1],
[left, gen2],
[right, gen2],
[left, gen3]
],
captions: [
[left - nodeWidth * 3 / 4, gen3 + nodeHeight / 4],
[right + nodeWidth * 1.1, gen2 + nodeHeight / 4]
],
nodeValue: ["oldMan1.svg", "oldWoman1.svg", "man3.svg", "woman1.svg", "babyBoy.svg"],
nodeWeights: [noPair, noPair, noPair, pair1, pair2],
currentState: ["deactivate", "deactivate", "deactivate", "activeTo", "active"],
edgeState:["married","others","siblings","others","others","others"],
answer: [qsTr("Aunt")],
options: [qsTr("Uncle"), qsTr("Aunt"), qsTr("Nephew"), qsTr("Niece")]
},
// level 13
{
numberOfGenerations: 3,
edgeList: [
[rightXEdge(left), gen1 + nodeHeight / 2, right, gen1 + nodeHeight / 2],
[nodeMidPointX(left, right), nodeMidPointY(gen1), nodeMidPointX(left, right), nodeMidPointY(gen2)],
[rightXEdge(left), nodeMidPointY(gen2), right, nodeMidPointY(gen2)],
[left + nodeWidth / 2, gen2 + nodeHeight, left + nodeWidth / 2, gen3]
],
nodePositions: [
[left, gen1],
[right, gen1],
[left, gen2],
[right, gen2],
[left, gen3]
],
captions: [
[right + nodeWidth * 1.1, gen2 + nodeHeight / 4],
[left - nodeWidth / 2, gen3 + nodeHeight / 4]
],
nodeValue: ["oldMan1.svg", "oldWoman1.svg", "man3.svg", "woman1.svg", "babyGirl.svg"],
nodeWeights: [noPair, noPair, noPair, pair2, pair1],
currentState: ["deactivate", "deactivate", "deactivate", "active", "activeTo"],
edgeState:["married","others","siblings","others","others","others"],
answer: [qsTr("Niece")],
options: [qsTr("Uncle"), qsTr("Aunt"), qsTr("Nephew"), qsTr("Niece")]
},
// level 14
{
numberOfGenerations: 2,
edgeList: [
[rightXEdge(center), nodeMidPointY(gen1), rightExt, nodeMidPointY(gen1)],
[nodeMidPointX(center, rightExt), nodeMidPointY(gen1), nodeMidPointX(center, rightExt), nodeMidPointY(gen2)],
[rightXEdge(center), nodeMidPointY(gen2), rightExt, nodeMidPointY(gen2)],
[rightXEdge(leftExt), nodeMidPointY(gen2), center, nodeMidPointY(gen2)]
],
nodePositions: [
[center, gen1],
[rightExt, gen1],
[center, gen2],
[rightExt, gen2],
[leftExt, gen2]
],
captions: [
[leftExt - nodeWidth / 2, gen2 + nodeHeight * 3 / 4],
[center - nodeWidth * 3 / 4, gen1 + nodeHeight / 4]
],
nodeValue: ["oldMan1.svg", "oldWoman1.svg", "man3.svg", "man1.svg", "woman2.svg"],
nodeWeights: [pair1, noPair, noPair, noPair, pair2],
currentState: ["activeTo", "deactivate", "deactivate", "deactivate", "active"],
edgeState:["married","others","others","married"],
answer: [qsTr("Father-in-law")],
options: [qsTr("Father-in-law"), qsTr("Mother-in-law"), qsTr("Sister-in-law"), qsTr("Brother-in-law"), qsTr("Daughter-in-law")]
},
// level 15
{
numberOfGenerations: 2,
edgeList: [
[rightXEdge(center), nodeMidPointY(gen1), rightExt, nodeMidPointY(gen1)],
[nodeMidPointX(center, rightExt), nodeMidPointY(gen1), nodeMidPointX(center, rightExt), nodeMidPointY(gen2)],
[rightXEdge(center), nodeMidPointY(gen2), rightExt, nodeMidPointY(gen2)],
[rightXEdge(leftExt), nodeMidPointY(gen2), center, nodeMidPointY(gen2)]
],
nodePositions: [
[center, gen1],
[rightExt, gen1],
[center, gen2],
[rightExt, gen2],
[leftExt, gen2]
],
captions: [
[leftExt - nodeWidth / 2, gen2 + nodeHeight * 3 / 4],
[rightExt + nodeWidth * 1.1, gen1 + nodeHeight / 4]
],
nodeValue: ["oldMan1.svg", "oldWoman1.svg", "man3.svg", "man1.svg", "woman2.svg"],
nodeWeights: [noPair, pair1, noPair, noPair, pair2],
currentState: ["deactivate", "activeTo", "deactivate", "deactivate", "active"],
edgeState:["married","others","others","married","others"],
answer: [qsTr("Mother-in-law")],
options: [qsTr("Father-in-law"), qsTr("Mother-in-law"), qsTr("Sister-in-law"), qsTr("Brother-in-law"), qsTr("Daughter-in-law")]
},
// level 16
{
numberOfGenerations: 2,
edgeList: [
[rightXEdge(center), nodeMidPointY(gen1), rightExt, nodeMidPointY(gen1)],
[nodeMidPointX(center, rightExt), nodeMidPointY(gen1), nodeMidPointX(center, rightExt), nodeMidPointY(gen2)],
[rightXEdge(center), nodeMidPointY(gen2), rightExt, nodeMidPointY(gen2)],
[rightXEdge(leftExt), nodeMidPointY(gen2), center, nodeMidPointY(gen2)]
],
nodePositions: [
[center, gen1],
[rightExt, gen1],
[center, gen2],
[rightExt, gen2],
[leftExt, gen2]
],
captions: [
[leftExt - nodeWidth / 2, gen2 + nodeHeight * 3 / 4],
[rightExt + nodeWidth * 1.1, gen2 + nodeHeight / 4]
],
nodeValue: ["oldMan1.svg", "oldWoman1.svg", "man3.svg", "man1.svg", "woman2.svg"],
nodeWeights: [noPair, noPair, noPair, pair1, pair2],
currentState: ["deactivate", "deactivate", "deactivate", "activeTo", "active"],
edgeState:["married","others","others","married","others"],
answer: [qsTr("Brother-in-law")],
options: [qsTr("Father-in-law"), qsTr("Mother-in-law"), qsTr("Sister-in-law"), qsTr("Brother-in-law"), qsTr("Daughter-in-law")]
},
// level 17
{
numberOfGenerations: 2,
edgeList: [
[rightXEdge(leftInt), nodeMidPointY(gen1), rightInt, nodeMidPointY(gen1)],
[nodeMidPointX(leftInt, rightInt), nodeMidPointY(gen1), nodeMidPointX(leftInt, rightInt), nodeMidPointY(gen2)],
[rightXEdge(leftInt), nodeMidPointY(gen2), rightInt, nodeMidPointY(gen2)],
[rightXEdge(leftExt), nodeMidPointY(gen2), leftInt, nodeMidPointY(gen2)],
[rightXEdge(rightInt), nodeMidPointY(gen2), rightExt, nodeMidPointY(gen2)]
],
nodePositions: [
[leftInt, gen1],
[rightInt, gen1],
[leftInt, gen2],
[leftExt, gen2],
[rightInt, gen2],
[rightExt, gen2]
],
captions: [
[leftExt - nodeWidth / 2, gen2],
[rightInt + nodeWidth * 0.8, gen2 - nodeHeight / 4]
],
nodeValue: ["oldMan1.svg", "oldWoman1.svg", "man3.svg", "woman2.svg", "woman1.svg", "man1.svg"],
nodeWeights: [noPair, noPair, noPair, pair1, pair2, noPair],
currentState: ["dective", "deactivate", "deactivate", "active", "activeTo", "deactivate"],
edgeState:["married","others","others","married","married"],
answer: [qsTr("Sister-in-law")],
options: [qsTr("Father-in-law"), qsTr("Mother-in-law"), qsTr("Sister-in-law"), qsTr("Brother-in-law"), qsTr("Daughter-in-law")]
},
// level 18
{
numberOfGenerations: 2,
edgeList: [
[rightXEdge(center), nodeMidPointY(gen1), rightExt, nodeMidPointY(gen1)],
[nodeMidPointX(center, rightExt), nodeMidPointY(gen1), nodeMidPointX(center, rightExt), nodeMidPointY(gen2)],
[rightXEdge(center), nodeMidPointY(gen2), rightExt, nodeMidPointY(gen2)],
[rightXEdge(leftExt), nodeMidPointY(gen2), center, nodeMidPointY(gen2)]
],
nodePositions: [
[center, gen1],
[rightExt, gen1],
[center, gen2],
[leftExt, gen2],
[rightExt, gen2]
],
captions: [
[center - (nodeWidth * 3/ 4), gen1 + nodeHeight / 4],
[leftExt - nodeWidth / 2, gen2 + nodeHeight / 2]
],
nodeValue: ["oldMan1.svg", "oldWoman1.svg", "woman2.svg", "man3.svg", "man1.svg"],
nodeWeights: [pair1, pair1, noPair, pair2, noPair],
currentState: ["active", "deactivate", "deactivate", "activeTo", "deactivate", "deactivate"],
edgeState:["married","others","others","married","others"],
answer: [qsTr("Son-in-law")],
options: [qsTr("Son-in-law"), qsTr("Mother-in-law"), qsTr("Sister-in-law"), qsTr("Brother-in-law"), qsTr("Daughter-in-law")]
}
]
}
diff --git a/src/activities/family/Family.qml b/src/activities/family/Family.qml
index 9face026c..651a957bf 100644
--- a/src/activities/family/Family.qml
+++ b/src/activities/family/Family.qml
@@ -1,413 +1,413 @@
/* GCompris - family.qml
*
* Copyright (C) 2016 Rajdeep Kaur <rajdeep.kaur@kde.org>
*
* Authors:
*
* Rajdeep Kaur <rajdeep.kaur@kde.org>
* Rudra Nil Basu <rudra.nil.basu.1996@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import QtGraphicalEffects 1.0
import "../../core"
import "family.js" as Activity
ActivityBase {
id: activity
property string mode: "family"
onStart: focus = true
onStop: {}
pageComponent: Image {
id: background
anchors.fill: parent
source: Activity.url + "background.svg"
width: parent.width
height: parent.height
fillMode: Image.PreserveAspectCrop
- property bool horizontalLayout: background.width > background.height
+ property bool horizontalLayout: background.width >= background.height
signal start
signal stop
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
property real treeAreaWidth: background.horizontalLayout ? background.width * 0.65 : background.width
property real treeAreaHeight: background.horizontalLayout ? background.height : background.height * 0.65
property real nodeWidth: (0.8 * treeAreaWidth) / 5
property real nodeHeight: (0.8 * treeAreaWidth) / 5
property real nodeWidthRatio: nodeWidth / treeAreaWidth
property real nodeHeightRatio: nodeHeight / treeAreaHeight
onWidthChanged: loadDatasetDelay.start()
onHeightChanged: if (!loadDatasetDelay.running) {
loadDatasetDelay.start()
}
/*
* Adding a delay before reloading the datasets
* needed for fast width / height changes
*/
Timer {
id: loadDatasetDelay
running: false
repeat: false
interval: 100
onTriggered: Activity.loadDatasets()
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property alias background: background
property alias bar: bar
property alias bonus: bonus
property alias nodeRepeater: nodeRepeater
property alias answersChoice: answersChoice
property alias edgeRepeater: edgeRepeater
property alias ringRepeator: ringRepeator
property alias dataset: dataset
property string mode: activity.mode
property alias questionTopic: question.questionTopic
property alias selectedPairs: selectedPairs
property alias loadDatasetDelay: loadDatasetDelay
property bool buttonsBlocked: false
property point questionMarkPosition: questionMarkPosition
property point meLabelPosition: meLabelPosition
}
onStart: { Activity.start(items) }
onStop: { Activity.stop() }
Dataset {
id: dataset
}
// handling pair matching for family_find_relative
Item {
id: selectedPairs
property var firstNodePointer: undefined
property var secondNodePointer: undefined
function reset() {
firstNodePointer = undefined
secondNodePointer = undefined
}
function deactivatePairs() {
if (firstNodePointer && secondNodePointer) {
firstNodePointer.changeState("deactivate")
secondNodePointer.changeState("deactivate")
reset()
}
}
function checkResult() {
if (firstNodePointer.weight == (secondNodePointer.weight * -1) && firstNodePointer.weight != 0) {
return true
} else {
return false
}
}
function selectNode(node_) {
if (firstNodePointer && secondNodePointer)
return
if(firstNodePointer == undefined) {
firstNodePointer = node_
firstNodePointer.changeState("activeTo")
} else {
secondNodePointer = node_
if (firstNodePointer == secondNodePointer) {
deactivatePairs()
return
}
secondNodePointer.changeState("activeTo")
// checking results
if (checkResult()) {
bonus.good("lion")
} else {
bonus.bad("lion")
deactivatePairs()
}
}
}
}
Item {
id: board
width: background.width
height: background.height
Rectangle {
id: treeArea
color: "transparent"
width: background.treeAreaWidth
height: background.treeAreaHeight
anchors.horizontalCenter: activity.mode == "find_relative" ? board.horizontalCenter : undefined
anchors.verticalCenter: activity.mode == "find_relative" ? board.verticalCenter : undefined
border.width: 0
Item {
id: treeItem
Repeater {
id: nodeRepeater
model: ListModel {}
delegate:
Node {
id: currentPointer
x: xPosition * treeArea.width
y: yPosition * treeArea.height
z: 30
width: treeArea.width / 5
height: treeArea.width / 5
nodeWidth: currentPointer.width
nodeHeight: currentPointer.height
nodeImageSource: Activity.url + nodeValue
borderColor: "#373737"
borderWidth: 8
color: "transparent"
radius: nodeWidth / 2
state: currentState
weight: nodeWeight
states: [
State {
name: "active"
PropertyChanges {
target: currentPointer
borderColor: "#e1e1e1"
}
},
State {
name: "deactivate"
PropertyChanges {
target: currentPointer
}
},
State {
name: "activeTo"
PropertyChanges {
target: currentPointer
borderColor: "#e77936"
color: "#80f2f2f2"
}
}
]
}
}
Rectangle {
id: me
visible: dataset.levelElements[bar.level-1].captions[0] !== undefined && activity.mode == "family"
x: items.meLabelPosition.x * treeArea.width
y: items.meLabelPosition.y * treeArea.height
width: treeArea.width / 12
height: treeArea.height / 14
radius: 5
color: "#f2f2f2"
border.color: "#e1e1e1"
GCText {
id: meLabel
text: qsTr("Me")
color: "#555555"
anchors {
horizontalCenter: parent.horizontalCenter
verticalCenter: parent.verticalCenter
}
}
}
Rectangle {
id: questionmark
visible: dataset.levelElements[bar.level-1].captions[1] !== undefined && activity.mode == "family"
x: items.questionMarkPosition.x * treeArea.width
y: items.questionMarkPosition.y * treeArea.height
width: treeArea.width / 14
height: width
radius: width/2
color: "#f2f2f2"
border.color: "#e77936"
GCText {
id: qLabel
text: qsTr("?")
color: "#555555"
anchors {
horizontalCenter: parent.horizontalCenter
verticalCenter: parent.verticalCenter
}
}
}
Repeater {
id: edgeRepeater
model: ListModel {}
delegate: Rectangle {
id: edge
z: 20
opacity: 1
antialiasing: true
transformOrigin: Item.TopLeft
x: _x1 * treeArea.width
y: _y1 * treeArea.height
property var x2: _x2 * treeArea.width
property var y2: _y2 * treeArea.height
width: Math.sqrt(Math.pow(x - x2, 2) + Math.pow(y- y2, 2))
height: 4 * ApplicationInfo.ratio
rotation: (Math.atan((y2 - y)/(x2-x)) * 180 / Math.PI) + (((y2-y) < 0 && (x2-x) < 0) * 180) + (((y2-y) >= 0 && (x2-x) < 0) * 180)
color: "#373737"
}
}
Repeater {
id: ringRepeator
model: ListModel {}
delegate: Image {
id: ring
source: Activity.url + "rings.svg"
width: treeArea.width * 0.05
sourceSize.width: width
fillMode: Image.PreserveAspectCrop
x: ringx * treeArea.width
y: ringy * treeArea.height
z: 40
}
}
}
}
Rectangle {
id: answers
color: "transparent"
width: background.horizontalLayout ? background.width*0.35 : background.width
height: background.horizontalLayout ? background.height : background.height*0.35
anchors.left: background.horizontalLayout ? treeArea.right : board.left
anchors.top: background.horizontalLayout ? board.top: treeArea.bottom
border.width: 0
Rectangle {
width: parent.width * 0.99
height: parent.height * 0.99
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
color: "transparent"
Grid {
id: answersGrid
visible: activity.mode == "family" ? true : false
columns: 1
rowSpacing: 10*ApplicationInfo.ratio
states: [
State {
name: "anchorCenter"; when: background.horizontalLayout
AnchorChanges {
target: answersGrid
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
}
},
State {
name: "anchorTop"; when: !background.horizontalLayout
AnchorChanges {
target: answersGrid
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
}
}
]
Repeater {
id: answersChoice
model: ListModel {}
delegate:
AnswerButton {
id: options
width: answers.width*0.75
height: answers.height*Activity.answerButtonRatio
textLabel: optionn
isCorrectAnswer: textLabel === answer
onCorrectlyPressed: bonus.good("lion")
onIncorrectlyPressed: bonus.bad("lion")
onPressed: items.buttonsBlocked = true
blockAllButtonClicks: items.buttonsBlocked
}
}
}
}
}
}
GCText {
id: question
property string questionTopic
visible: activity.mode == "find_relative" ? true : false
width: background.width
anchors.horizontalCenter: background.horizontalCenter
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.WordWrap
fontSize: smallSize
text: qsTr("Select one of the pairs denoting: %1").arg(questionTopic)
Rectangle {
width: parent.width
height: parent.height
anchors.horizontalCenter: parent.horizontalCenter
z: parent.z - 1
radius: 10
border.width: 1
color: "white"
opacity: 0.8
}
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level }
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
}
Bonus {
id: bonus
onStop: items.buttonsBlocked = false
Component.onCompleted: win.connect(Activity.nextLevel)
}
}
}
diff --git a/src/activities/family/Node.qml b/src/activities/family/Node.qml
index 80cf39556..9638add2a 100644
--- a/src/activities/family/Node.qml
+++ b/src/activities/family/Node.qml
@@ -1,98 +1,98 @@
/* GCompris - Node.qml
*
* Copyright (C) 2016 Rajdeep Kaur <rajdeep.kaur@kde.org>
*
* Authors:
*
* Rajdeep Kaur <rajdeep.kaur@kde.org>
* Rudra Nil Basu <rudra.nil.basu.1996@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "family.js" as Activity
Item {
id: node
property int nodeWidth
property int nodeHeight
property string nodeImageSource
property string borderColor
property real borderWidth
property string color
property real radius
property int weight
function changeState(state_) {
currentPointer.state = state_
}
Rectangle {
id: content
color: node.color
width: 0.8 * nodeWidth
height: 0.8 * nodeHeight
border.color: borderColor
border.width: borderWidth
radius: node.radius
Image {
id: nodeImage
source: nodeImageSource
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
width: parent.width * 0.8
height: parent.height * 0.8
sourceSize.width: width
sourceSize.height: height
SequentialAnimation {
id: activeAnimation
running: currentPointer.state === "active" || currentPointer.state === "activeTo"
loops: Animation.Infinite
alwaysRunToEnd: true
NumberAnimation {
target: nodeImage
property: "rotation"
from: 0; to: 10
duration: 200
easing.type: Easing.OutQuad
}
NumberAnimation {
target: nodeImage
property: "rotation"
from: 10; to: -10
duration: 400
easing.type: Easing.InOutQuad
}
NumberAnimation {
target: nodeImage
property: "rotation"
from: -10; to: 0
duration: 200
easing.type: Easing.InQuad
}
}
}
MouseArea {
visible: activity.mode == "find_relative" ? true : false
anchors.fill: parent
onClicked: selectedPairs.selectNode(currentPointer)
}
}
}
diff --git a/src/activities/family/family.js b/src/activities/family/family.js
index ca25d5d1e..0e17b4426 100644
--- a/src/activities/family/family.js
+++ b/src/activities/family/family.js
@@ -1,153 +1,153 @@
/* GCompris - family.js
*
* Copyright (C) 2016 Rajdeep Kaur <rajdeep.kaur@kde.org>
*
* Authors:
*
* Rajdeep Kaur <rajdeep.kaur@kde.org>
* Rudra Nil Basu <rudra.nil.basu.1996@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
.import GCompris 1.0 as GCompris
.import "qrc:/gcompris/src/core/core.js" as Core
var currentLevel = 0
var items;
var barAtStart;
var url = "qrc:/gcompris/src/activities/family/resource/"
var numberOfLevel
var shuffledLevelIndex = []
var levelToLoad
var answerButtonRatio = 0;
function start(items_) {
items = items_
currentLevel = 0
numberOfLevel = items.dataset.levelElements.length
barAtStart = GCompris.ApplicationSettings.isBarHidden;
GCompris.ApplicationSettings.isBarHidden = true;
shuffle()
initLevel()
}
function stop() {
GCompris.ApplicationSettings.isBarHidden = barAtStart;
}
function initLevel() {
items.bar.level = currentLevel + 1
items.selectedPairs.reset()
levelToLoad = getCurrentLevelIndex()
var levelTree = items.dataset.levelElements[levelToLoad]
items.dataset.numberOfGenerations = levelTree.numberOfGenerations
// Need to delay in order of the number of generation change to be taken in account
items.loadDatasetDelay.start()
}
function loadDatasets() {
if (!items) {
return
}
var levelTree = items.dataset.levelElements[levelToLoad]
answerButtonRatio = 1 / (levelTree.options.length + 4);
items.nodeRepeater.model.clear();
items.answersChoice.model.clear();
items.edgeRepeater.model.clear();
items.ringRepeator.model.clear();
for(var i = 0 ; i < levelTree.nodePositions.length ; i++) {
items.nodeRepeater.model.append({
"xPosition": levelTree.nodePositions[i][0],
"yPosition": levelTree.nodePositions[i][1],
"nodeValue": levelTree.nodeValue[i],
"currentState": items.mode == "family" ? levelTree.currentState[i] : "deactive",
"nodeWeight": levelTree.nodeWeights[i]
});
}
for(var i = 0 ; i <levelTree.options.length ; i++) {
items.answersChoice.model.append({
"optionn": levelTree.options[i],
"answer": levelTree.answer[0]
});
}
for(var i = 0 ; i < levelTree.edgeList.length ; i++) {
items.edgeRepeater.model.append({
"_x1": levelTree.edgeList[i][0],
"_y1": levelTree.edgeList[i][1],
"_x2": levelTree.edgeList[i][2],
"_y2": levelTree.edgeList[i][3],
"edgeState": levelTree.edgeState[i]
});
}
for(var i = 0 ; i < levelTree.edgeState.length ; i++) {
if(levelTree.edgeState[i] === "married") {
var xcor = (levelTree.edgeList[i][0]+levelTree.edgeList[i][2]-0.04)/2;
var ycor = levelTree.edgeList[i][3] - 0.02
items.ringRepeator.model.append({
"ringx": xcor,
"ringy": ycor
});
}
}
items.questionTopic = levelTree.answer[0]
items.questionMarkPosition.x = levelTree.captions[1][0]
items.questionMarkPosition.y = levelTree.captions[1][1]
items.meLabelPosition.x = levelTree.captions[0][0]
items.meLabelPosition.y = levelTree.captions[0][1]
}
function shuffle() {
for (var i = 0;i < numberOfLevel;i++) {
shuffledLevelIndex[i] = i
}
Core.shuffle(shuffledLevelIndex);
}
function getCurrentLevelIndex() {
if (!items) {
return
}
return shuffledLevelIndex[currentLevel]
}
function nextLevel() {
if(numberOfLevel <= ++currentLevel) {
currentLevel = 0
}
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
initLevel();
}
diff --git a/src/activities/family/family.svg b/src/activities/family/family.svg
index b785a1549..057f66e9e 100644
--- a/src/activities/family/family.svg
+++ b/src/activities/family/family.svg
@@ -1,1093 +1,1093 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="100"
height="100"
id="svg9131"
sodipodi:version="0.32"
inkscape:version="0.92.1 r15371"
version="1.0"
sodipodi:docname="family.svg">
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
- inkscape:zoom="1.5763927"
- inkscape:cx="-103.33771"
- inkscape:cy="43.707451"
+ inkscape:zoom="6.3055708"
+ inkscape:cx="1.4109351"
+ inkscape:cy="20.870502"
inkscape:document-units="px"
- inkscape:current-layer="layer1"
+ inkscape:current-layer="g984"
height="100px"
width="100px"
inkscape:window-width="1884"
inkscape:window-height="1051"
inkscape:window-x="0"
inkscape:window-y="0"
showgrid="false"
inkscape:snap-global="false"
inkscape:window-maximized="1" />
<defs
id="defs9133">
<linearGradient
id="linearGradient2903"
inkscape:collect="always">
<stop
id="stop2899"
offset="0"
style="stop-color:#2e67a5;stop-opacity:1" />
<stop
id="stop2901"
offset="1"
style="stop-color:#8eccd3;stop-opacity:1" />
</linearGradient>
<linearGradient
gradientTransform="translate(-0.10609271,1.7143672e-5)"
gradientUnits="userSpaceOnUse"
y2="271.88818"
x2="-42.304996"
y1="262.9585"
x1="-42.493988"
id="linearGradient1449"
xlink:href="#linearGradient1447"
inkscape:collect="always" />
<linearGradient
id="linearGradient1447"
inkscape:collect="always">
<stop
id="stop1443"
offset="0"
style="stop-color:#ffffff;stop-opacity:1;" />
<stop
id="stop1445"
offset="1"
style="stop-color:#ffffff;stop-opacity:0;" />
</linearGradient>
<linearGradient
gradientTransform="translate(0.01159271,1.7143672e-5)"
gradientUnits="userSpaceOnUse"
y2="271.60468"
x2="25.418896"
y1="263.1947"
x1="25.371651"
id="linearGradient1457"
xlink:href="#linearGradient1447"
inkscape:collect="always" />
<linearGradient
gradientTransform="matrix(-1,0,0,1,67.803763,-0.02360486)"
gradientUnits="userSpaceOnUse"
y2="267.67691"
x2="28.142437"
y1="263.06653"
x1="28.15424"
id="linearGradient1317-9"
xlink:href="#linearGradient2903"
inkscape:collect="always" />
<linearGradient
gradientTransform="translate(0.01159271,-0.02359956)"
gradientUnits="userSpaceOnUse"
y2="268.34509"
x2="27.674715"
y1="263.4006"
x1="27.753334"
id="linearGradient1317"
xlink:href="#linearGradient2903"
inkscape:collect="always" />
<linearGradient
gradientTransform="matrix(-0.26458333,0,0,0.26458333,67.684171,232.30801)"
gradientUnits="userSpaceOnUse"
y2="133.98727"
x2="91.167053"
y1="116.81467"
x1="91.167053"
id="linearGradient1834-8"
xlink:href="#linearGradient1498"
inkscape:collect="always" />
<linearGradient
inkscape:collect="always"
id="linearGradient1498">
<stop
style="stop-color:#ad7932;stop-opacity:1"
offset="0"
id="stop1494" />
<stop
style="stop-color:#d3b48e;stop-opacity:1"
offset="1"
id="stop1496" />
</linearGradient>
<linearGradient
gradientTransform="matrix(0.26458333,0,0,0.26458333,-2.4918076e-8,232.30801)"
gradientUnits="userSpaceOnUse"
y2="133.98727"
x2="91.167053"
y1="116.81467"
x1="91.167053"
id="linearGradient1834"
xlink:href="#linearGradient1498"
inkscape:collect="always" />
<linearGradient
gradientTransform="matrix(-0.26458333,0,0,0.26458333,67.341987,229.74857)"
gradientUnits="userSpaceOnUse"
y2="150.12811"
x2="90.72126"
y1="127.98526"
x1="90.72126"
id="linearGradient1537-8-0"
xlink:href="#linearGradient1498"
inkscape:collect="always" />
<linearGradient
gradientTransform="matrix(0.26458333,0,0,0.26458333,0.52916708,229.74857)"
gradientUnits="userSpaceOnUse"
y2="150.12811"
x2="90.72126"
y1="127.98526"
x1="90.72126"
id="linearGradient1537-8"
xlink:href="#linearGradient1498"
inkscape:collect="always" />
<linearGradient
gradientTransform="matrix(-0.26458333,0,0,0.26458333,67.273098,229.2194)"
gradientUnits="userSpaceOnUse"
y2="150.12811"
x2="90.72126"
y1="120.17857"
x1="86.260529"
id="linearGradient1537-8-0-1"
xlink:href="#linearGradient2903"
inkscape:collect="always" />
<linearGradient
gradientTransform="matrix(0.26458333,0,0,0.26458333,0.46023677,229.2194)"
gradientUnits="userSpaceOnUse"
y2="150.12811"
x2="90.72126"
y1="120.17857"
x1="86.260521"
id="linearGradient1537-8-8"
xlink:href="#linearGradient2903"
inkscape:collect="always" />
</defs>
<metadata
id="metadata9136">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
<dc:date>2018</dc:date>
<dc:creator>
<cc:Agent>
<dc:title>Timothée Giet</dc:title>
</cc:Agent>
</dc:creator>
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Notice" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
<g
style="display:inline"
id="layer1"
inkscape:groupmode="layer"
inkscape:label="Calque 1">
<g
transform="matrix(0.69218746,0.18547107,-0.18547107,0.69218746,98.459475,-150.24133)"
id="layer1-2"
inkscape:label="Calque 1">
<path
sodipodi:nodetypes="cccscsc"
inkscape:connector-curvature="0"
id="path2195"
d="m 23.653353,280.83017 c -4.543582,2.40543 -7.082642,2.6727 -10.824416,-1.06907 -2.138156,0.8018 -6.548103,-2.40543 -7.216277,-6.1472 -3.2072342,-0.40091 -4.4099471,-6.41447 -4.2763123,-7.75082 0.1336347,-1.33635 3.0735996,-2.27179 6.4144684,-1.60362 0.668174,-0.66817 6.5481039,-8.55262 9.6217029,-4.94448 3.0736,3.60813 6.280834,21.51519 6.280834,21.51519 z"
style="display:inline;fill:#96421d;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="cccscsc"
inkscape:connector-curvature="0"
id="path2195-8"
d="m 23.653353,279.57617 c -4.326022,2.11365 -6.743505,2.34849 -10.306112,-0.93939 -2.035775,0.70454 -6.234561,-2.11365 -6.870741,-5.40153 -3.0536625,-0.35228 -4.1987862,-5.63638 -4.0715502,-6.81063 0.1272359,-1.17425 2.9264269,-1.99622 6.1073255,-1.4091 0.6361798,-0.58712 6.2345617,-7.51517 9.1609877,-4.34471 2.926428,3.17047 5.98009,18.90536 5.98009,18.90536 z"
style="display:inline;fill:#d16335;fill-opacity:1;stroke:none;stroke-width:0.24200673px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
style="display:inline;fill:#8c6a3e;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 16.251632,265.15549 c -1.039434,-0.75596 -2.929315,-2.45685 -3.685268,-1.98438 -1.614495,0.12905 -2.447802,3.7485 -2.173363,5.19717 0.492425,2.59935 3.088937,5.91737 4.819197,7.37054 0.47247,1.32292 2.078869,2.92932 3.023809,0.94494 0.944941,-1.98437 -1.984375,-11.52827 -1.984375,-11.52827 z"
id="path2031"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccscsc" />
<path
style="display:inline;fill:#d7bc99;fill-opacity:1;stroke:none;stroke-width:0.23015694px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 16.316595,266.5607 c -0.91791,-0.64776 -2.681333,-2.67219 -3.348905,-2.26734 -1.425738,0.11059 -1.878138,3.11752 -1.635785,4.35886 0.434854,2.22733 2.727798,5.07047 4.255768,6.31566 0.417231,1.13358 1.835821,2.51008 2.670284,0.80971 0.834465,-1.70037 -1.941362,-9.21689 -1.941362,-9.21689 z"
id="path2033"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccscsc" />
<path
style="display:inline;opacity:1;fill:#b0936e;fill-opacity:1;stroke:none;stroke-width:0.16146536;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 15.869265,273.55595 c -0.8618,-0.39885 -1.887328,-1.61362 -2.152198,-2.78722 -0.25819,-1.14397 -0.152341,-2.21028 0.448059,-2.86602 l 0.666824,-0.09 0.541985,0.42573 c 0.22459,0.12389 0.797496,0.77348 1.060246,1.0096 l 0.147011,0.80725 0.542645,1.18692 c 1.174,2.56786 -0.541792,2.64364 -1.254572,2.31374 z"
id="path2035"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccsc" />
<path
sodipodi:nodetypes="cccscsc"
inkscape:connector-curvature="0"
id="path2195-7"
d="m 44.055271,280.83017 c 4.543584,2.40543 7.082645,2.6727 10.824417,-1.06907 2.138156,0.8018 6.548104,-2.40543 7.216277,-6.1472 3.207234,-0.40091 4.409948,-6.41447 4.276312,-7.75082 -0.133633,-1.33635 -3.073598,-2.27179 -6.414468,-1.60362 -0.668173,-0.66817 -6.548104,-8.55262 -9.621702,-4.94448 -3.073602,3.60813 -6.280836,21.51519 -6.280836,21.51519 z"
style="display:inline;fill:#96421d;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="cccscsc"
inkscape:connector-curvature="0"
id="path2195-8-1"
d="m 44.055271,279.57617 c 4.326022,2.11365 6.743507,2.34849 10.306114,-0.93939 2.035775,0.70454 6.234559,-2.11365 6.870739,-5.40153 3.053665,-0.35228 4.198787,-5.63638 4.071552,-6.81063 -0.127236,-1.17425 -2.926427,-1.99622 -6.107325,-1.4091 -0.63618,-0.58712 -6.234562,-7.51517 -9.160988,-4.34471 -2.92643,3.17047 -5.980092,18.90536 -5.980092,18.90536 z"
style="display:inline;fill:#d16335;fill-opacity:1;stroke:none;stroke-width:0.24200673px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
style="display:inline;fill:#8c6a3e;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 51.671832,265.15549 c 1.039434,-0.75596 2.929313,-2.45685 3.685267,-1.98438 1.614496,0.12905 2.447801,3.7485 2.173362,5.19717 -0.492424,2.59935 -3.088937,5.91737 -4.819195,7.37054 -0.472472,1.32292 -2.078871,2.92932 -3.023809,0.94494 -0.944941,-1.98437 1.984375,-11.52827 1.984375,-11.52827 z"
id="path2039"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccscsc" />
<path
style="display:inline;fill:#d7bc99;fill-opacity:1;stroke:none;stroke-width:0.23015694px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 51.606869,266.5607 c 0.917908,-0.64776 2.681332,-2.67219 3.348905,-2.26734 1.425736,0.11059 1.878137,3.11752 1.635784,4.35886 -0.434854,2.22733 -2.727799,5.07047 -4.255768,6.31566 -0.417232,1.13359 -1.835822,2.51008 -2.670283,0.80971 -0.834467,-1.70037 1.941362,-9.21689 1.941362,-9.21689 z"
id="path2041"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccscsc" />
<path
style="display:inline;opacity:1;fill:#b0936e;fill-opacity:1;stroke:none;stroke-width:0.16146536;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 52.054197,273.55595 c 0.861801,-0.39885 1.887328,-1.61362 2.152197,-2.78722 0.258191,-1.14397 0.152342,-2.21028 -0.448058,-2.86602 l -0.600006,-0.15682 -0.742437,0.62617 c -0.224589,0.12389 -0.663861,0.63986 -0.926611,0.87597 l -0.14701,0.80725 -0.609465,1.52101 c -1.0502,2.62093 0.60861,2.30955 1.32139,1.97966 z"
id="path2043"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccsc" />
<path
style="display:inline;fill:#8f7049;fill-opacity:1;stroke:none;stroke-width:0.23146558px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 55.480149,268.68479 c -0.371062,-4.52144 -7.17133,3.85123 -4.476771,4.61393 2.338609,0.53454 4.407008,-3.7289 2.201619,-5.44769 2.480773,-0.0764 1.139978,7.24602 -2.354821,5.97064 -3.528957,-1.28784 4.96158,-11.22051 4.629973,-5.13689 z"
id="path2045"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccscc" />
<path
style="display:inline;fill:#8f7049;fill-opacity:1;stroke:none;stroke-width:0.23146558px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 12.443315,268.68479 c 0.371061,-4.52144 7.17133,3.85123 4.47677,4.61393 -2.33861,0.53454 -4.407009,-3.7289 -2.201619,-5.4477 -2.480773,-0.0764 -1.139978,7.24603 2.354822,5.97065 3.528955,-1.28784 -4.961581,-11.22051 -4.629973,-5.13689 z"
id="path2051"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccscc" />
<path
style="display:inline;fill:#8c6a3e;fill-opacity:1;stroke:none;stroke-width:0.27737862px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 33.937149,290.67488 c -6.62841,0 -14.673792,-10.40213 -15.36401,-12.52081 -1.693392,-5.19801 -2.311749,-7.5554 -3.370083,-11.80082 -0.538989,-2.16211 -7.7795466,-28.97219 18.734093,-28.97219 26.51364,0 19.855905,24.6591 18.734093,28.97219 -1.058333,4.06903 -1.046591,5.89912 -3.704169,12.2071 -0.602427,1.42991 -8.401513,12.11453 -15.029924,12.11453 z"
id="path2057"
inkscape:connector-curvature="0"
sodipodi:nodetypes="sssssss" />
<path
style="display:inline;fill:#d7bc99;fill-opacity:1;stroke:none;stroke-width:0.26528287px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 33.937149,289.4658 c -6.35,0 -13.528942,-9.00134 -14.527096,-11.34931 -1.615061,-3.79913 -2.406243,-7.78651 -3.464577,-11.864 -0.534495,-2.05927 -7.4083367,-27.66236 17.991673,-27.66236 25.400022,0 19.105767,23.55576 17.991683,27.66236 0,0 -1.892795,8.08978 -3.704169,11.70331 -1.124006,2.24229 -7.937503,11.51 -14.287514,11.51 z"
id="path2059"
inkscape:connector-curvature="0"
sodipodi:nodetypes="sssssss" />
<path
style="display:inline;opacity:1;fill:#b86f4f;fill-opacity:1;stroke:none;stroke-width:0.50866431;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 40.439052,279.87496 c -2.728751,5.34474 -10.290148,5.34659 -13.229831,0 1.417487,1.0952 2.439694,1.7928 6.614912,1.7928 4.175225,0 5.19744,-0.6976 6.614919,-1.7928 z"
id="path2069"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccsc" />
<path
style="display:inline;fill:#84643a;fill-opacity:1;stroke:none;stroke-width:0.23705293px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 30.601412,275.43778 c 0.65917,0.22053 1.841956,1.22031 3.223419,1.22031 1.381467,0 2.532687,-0.97625 3.235759,-1.17673 0.448151,0.68861 -1.854292,2.39705 -3.235759,2.39705 -1.381463,0 -3.683902,-1.70844 -3.223419,-2.44063 z"
id="path2073"
inkscape:connector-curvature="0"
sodipodi:nodetypes="czczc" />
<path
style="display:inline;opacity:1;fill:#a05e41;fill-opacity:1;stroke:none;stroke-width:0.53702116;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 40.77583,279.63197 c -2.072378,1.5441 -5.136754,0.7322 -6.952838,0.7322 -1.816086,0 -3.92566,0.9486 -6.950547,-0.7322 1.489653,1.16158 2.563904,2.58808 6.951688,2.58808 4.387792,0 5.46205,-1.4265 6.951697,-2.58808 z"
id="path2075"
inkscape:connector-curvature="0"
sodipodi:nodetypes="czcsc" />
<path
style="display:inline;opacity:1;fill:#6f3116;fill-opacity:1;stroke:none;stroke-width:0.52250832;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 29.860119,266.23977 c 0.118549,1.59621 -1.661846,3.32125 -4.299481,3.63918 -2.563769,0.30903 -4.23741,-1.79431 -4.142916,-3.89976 0.102666,-2.28753 1.559629,-3.88531 4.142916,-3.88531 2.583287,0 4.129867,1.86216 4.299481,4.14589 z"
id="path2081"
inkscape:connector-curvature="0"
sodipodi:nodetypes="sssss" />
<path
inkscape:connector-curvature="0"
style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.46194309;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 29.812872,266.29886 c -3e-6,1.27229 -1.4849,2.65323 -4.015999,2.97656 -2.510697,0.32073 -4.526524,-1.56906 -4.21784,-3.36936 0.313188,-1.82656 2.004596,-2.77275 3.981605,-2.77275 2.531101,0 4.252234,1.33899 4.252234,3.16555 z"
id="path2083"
sodipodi:nodetypes="sssss" />
<path
style="display:inline;opacity:1;fill:url(#linearGradient1834);fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 25.560713,262.99968 c -0.880287,0 -1.822298,0.2944 -2.625162,0.78135 a 2.8063298,2.7395128 0 0 0 -0.08423,0.65215 2.8063298,2.7395128 0 0 0 2.806547,2.73937 2.8063298,2.7395128 0 0 0 2.806547,-2.73937 2.8063298,2.7395128 0 0 0 -0.09922,-0.71985 c -0.723893,-0.45065 -1.684392,-0.71365 -2.804482,-0.71365 z"
id="path2085"
inkscape:connector-curvature="0" />
<ellipse
style="display:inline;opacity:1;fill:#2a2a2a;fill-opacity:1;stroke:none;stroke-width:0.27103657;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="ellipse2087"
cx="25.657875"
cy="264.36624"
rx="1.4373885"
ry="1.403165" />
<ellipse
style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="ellipse2089"
cx="26.760359"
cy="265.46335"
rx="0.63476509"
ry="0.56794775" />
<ellipse
style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="ellipse2091"
cx="25.991959"
cy="266.43219"
rx="0.33408689"
ry="0.26726952" />
<path
style="display:inline;fill:#b38a54;fill-opacity:0.99215686;stroke:none;stroke-width:0.26835129px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 26.169268,280.33123 c 0,-0.52917 -0.276047,-1.5875 1.088693,-1.5875 0.544353,0 -1.088693,0.52917 -1.088693,1.5875 z"
id="path2117"
inkscape:connector-curvature="0"
sodipodi:nodetypes="csc" />
<path
style="display:inline;fill:#b38a54;fill-opacity:0.99215686;stroke:none;stroke-width:0.26835129px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 41.479015,280.33123 c 0,-0.52917 0.276048,-1.5875 -1.088691,-1.5875 -0.544343,0 1.088691,0.52917 1.088691,1.5875 z"
id="path2119"
inkscape:connector-curvature="0"
sodipodi:nodetypes="csc" />
<path
style="display:inline;opacity:1;fill:#6f3116;fill-opacity:1;stroke:none;stroke-width:0.52250832;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 37.824053,266.23977 c -0.118552,1.59621 1.661846,3.32125 4.299479,3.63918 2.563771,0.30903 4.170593,-1.79431 4.076097,-3.89976 -0.102663,-2.28753 -1.492811,-3.88531 -4.076097,-3.88531 -2.583285,0 -4.129868,1.86216 -4.299479,4.14589 z"
id="path2081-6"
inkscape:connector-curvature="0"
sodipodi:nodetypes="sssss" />
<path
inkscape:connector-curvature="0"
style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.46194309;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 37.8713,266.29886 c 0,1.27229 1.484897,2.65323 4.015997,2.97656 2.510697,0.32073 4.526526,-1.56906 4.217842,-3.36936 -0.31319,-1.82656 -2.004598,-2.77275 -3.981607,-2.77275 -2.531099,0 -4.252235,1.33899 -4.252232,3.16555 z"
id="path2083-6"
sodipodi:nodetypes="sssss" />
<path
style="display:inline;opacity:1;fill:url(#linearGradient1834-8);fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 42.123458,262.99968 c 0.880288,0 1.822297,0.2944 2.625162,0.78135 a 2.8063298,2.7395128 0 0 1 0.08423,0.65215 2.8063298,2.7395128 0 0 1 -2.806547,2.73937 2.8063298,2.7395128 0 0 1 -2.806549,-2.73937 2.8063298,2.7395128 0 0 1 0.09922,-0.71985 c 0.723892,-0.45065 1.684387,-0.71365 2.80448,-0.71365 z"
id="path2085-4"
inkscape:connector-curvature="0" />
<ellipse
transform="scale(-1,1)"
style="display:inline;opacity:1;fill:#2a2a2a;fill-opacity:1;stroke:none;stroke-width:0.27103657;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="ellipse2087-9"
cx="-42.026302"
cy="264.36624"
rx="1.4373885"
ry="1.403165" />
<ellipse
transform="scale(-1,1)"
style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="ellipse2089-5"
cx="-43.040485"
cy="265.46335"
rx="0.63476509"
ry="0.56794775" />
<ellipse
transform="scale(-1,1)"
style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="ellipse2091-0"
cx="-42.221386"
cy="266.43219"
rx="0.33408689"
ry="0.26726952" />
<path
sodipodi:nodetypes="cssc"
inkscape:connector-curvature="0"
id="path2178"
d="m 19.377041,259.84414 c 3.741773,-4.40994 8.808263,0.2675 9.220798,-0.33408 0.541049,-0.78899 -4.07586,-3.47451 -6.347651,-2.40543 -2.271791,1.06908 -2.873147,2.73951 -2.873147,2.73951 z"
style="display:inline;fill:#96421d;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="cssc"
inkscape:connector-curvature="0"
id="path2178-4"
d="m 48.087087,259.84414 c -3.741774,-4.40994 -8.808262,0.2675 -9.220798,-0.33408 -0.541049,-0.78899 4.075859,-3.47451 6.347651,-2.40543 2.271789,1.06908 2.873147,2.73951 2.873147,2.73951 z"
style="display:inline;fill:#96421d;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="ccscccscscsscccc"
inkscape:connector-curvature="0"
id="path2230"
d="m 43.297663,244.88242 c 0.610251,5.29607 1.572422,10.2501 7.216275,11.89349 0.801809,5.3454 4.67722,13.63075 9.888974,11.4926 5.211758,-2.13816 6.949009,-13.63075 -2.672694,-16.97162 -0.133635,-5.74629 -4.677216,-13.35273 -11.22532,-13.35273 -2.138157,-3.4745 -14.432553,-11.75986 -28.063301,0.93544 -3.608138,3.87541 -5.61266,5.46828 -7.483546,5.60192 -1.8708869,0.13363 1.336347,3.87541 1.870886,4.27631 -2.271791,1.33635 -7.6171811,2.40543 -9.3544332,2.40543 -1.7372519,0 0.4009043,4.67721 2.1381565,5.61266 -2.0045217,0.26726 -4.0090431,-2.2718 -4.1426779,-0.80181 -0.1336348,1.46998 -0.53453908,8.01808 5.8799297,10.0226 6.4144679,2.00453 12.4280329,-4.14267 10.8244159,-9.22079 1.202713,-2.13816 1.870886,-3.74178 1.870886,-3.74178 2.138157,0.40091 8.552625,-0.80181 9.755339,-5.74629 0.847405,-1.19068 3.135477,2.6388 13.49711,-2.40543 z"
style="display:inline;fill:#96421d;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="ccscccscscsscccc"
inkscape:connector-curvature="0"
id="path2230-7"
d="m 43.82683,243.53116 c 0.610254,5.03651 2.235224,10.47721 7.879077,12.04006 0.467993,5.08341 3.721569,14.32493 8.301474,13.11296 5.805295,-1.53624 5.70502,-14.70666 -3.335496,-16.808 -0.133636,-5.46466 -4.677217,-13.4076 -11.225321,-13.4076 -2.138156,-3.30422 -13.374219,-10.65433 -27.004967,1.41876 -3.608138,3.68548 -4.554327,5.25215 -6.425213,5.37923 -1.870887,0.12709 1.865514,3.15631 2.400053,3.53757 -2.271791,1.27085 -8.1463477,3.34586 -9.8835998,3.34586 -1.737252,0 1.4592377,4.97715 3.1964897,5.86675 -2.0045217,0.25417 -5.0673764,-1.63128 -5.2010112,-0.23335 -0.1336348,1.39794 1.2134578,7.36859 4.8215964,8.47306 6.3986669,1.95867 11.3696999,-4.99797 9.7660829,-9.82721 1.202713,-2.03336 2.400052,-4.61672 2.400052,-4.61672 2.138157,0.38126 8.552623,-1.29168 9.755339,-5.99383 0.847408,-1.13233 4.193813,2.50948 14.555444,-2.28754 z"
style="display:inline;fill:#d16335;fill-opacity:1;stroke:none;stroke-width:0.25801817px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<g
transform="matrix(0.77087516,-0.20655538,0.20655538,0.77087516,-53.289331,-160.17342)"
id="layer1-5"
inkscape:label="Calque 1">
<path
sodipodi:nodetypes="ccscc"
inkscape:connector-curvature="0"
id="path895-6"
d="m 18.384043,263.7008 c -2.53493,-3.14146 -2.53493,-3.14146 -5.46423,-4.05617 -2.9293203,-0.91469 -3.7784003,6.83458 -1.24347,9.97602 2.53492,3.14143 1.80645,4.29909 4.73576,5.2138 2.92932,0.91469 1.97194,-11.13365 1.97194,-11.13365 z"
style="display:inline;fill:#8f7049;fill-opacity:1;stroke:none;stroke-width:0.32795629px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path895"
d="m 16.944943,263.13332 c -2.11667,-2.11668 -2.11667,-2.11668 -4.23334,-2.11668 -2.11667,0 -2.11667,6.35 0,8.46668 2.11667,2.11666 2.11667,4.23332 4.23334,4.23332 2.11667,0 0,-10.58332 0,-10.58332 z"
style="display:inline;fill:#d0b18b;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path914"
d="m 15.798773,270.38094 c -0.8618,-0.39884 -1.69834,-1.56637 -1.96322,-2.73996 -0.25819,-1.14398 -0.0106,-2.44652 0.58981,-3.10227 l 0.26592,-0.29044 0.40834,0.22526 c 0.22459,0.1239 0.62333,0.41845 0.88609,0.65455 l 0.47774,0.42929 v 2.49837 c 0,2.82351 0.0481,2.6551 -0.66468,2.3252 z"
style="display:inline;opacity:1;fill:#b99871;fill-opacity:1;stroke:none;stroke-width:0.16146536;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="cccscc"
inkscape:connector-curvature="0"
id="path912"
d="m 12.372823,265.50979 c 2.38195,-3.6074 7.17132,3.85123 4.47677,4.61392 -2.33861,0.53454 -4.07628,-3.91788 -1.87089,-5.63667 -2.6727,-0.46024 -1.46998,7.33579 2.07134,6.15963 3.54132,-1.17615 -3.54132,-10.71085 -4.67722,-5.13689 z"
style="display:inline;fill:#8f7049;fill-opacity:1;stroke:none;stroke-width:0.23146558px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="ccscc"
inkscape:connector-curvature="0"
id="path895-6-7"
d="m 49.349283,263.7008 c 2.53493,-3.14146 2.53493,-3.14146 5.46424,-4.05617 2.92932,-0.91469 3.7784,6.83458 1.24346,9.97602 -2.53492,3.14143 -1.80644,4.29909 -4.73575,5.2138 -2.92932,0.91469 -1.97195,-11.13365 -1.97195,-11.13365 z"
style="display:inline;fill:#8f7049;fill-opacity:1;stroke:none;stroke-width:0.32795629px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path895-5"
d="m 50.788383,263.13332 c 2.11667,-2.11668 2.11667,-2.11668 4.23334,-2.11668 2.11667,0 2.11667,6.35 0,8.46668 -2.11667,2.11666 -2.11667,4.23332 -4.23334,4.23332 -2.11666,0 0,-10.58332 0,-10.58332 z"
style="display:inline;fill:#d0b18b;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path914-3"
d="m 51.934563,270.38094 c 0.86179,-0.39884 1.69834,-1.56637 1.96321,-2.73996 0.25819,-1.14398 0.0106,-2.44652 -0.58981,-3.10227 l -0.26591,-0.29044 -0.40835,0.22526 c -0.22459,0.1239 -0.62333,0.41845 -0.88608,0.65455 l -0.47774,0.42929 v 2.49837 c 0,2.82351 -0.0481,2.6551 0.66468,2.3252 z"
style="display:inline;opacity:1;fill:#b99871;fill-opacity:1;stroke:none;stroke-width:0.16146536;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="sssssss"
inkscape:connector-curvature="0"
id="path874-3"
d="m 33.878283,289.73603 c -6.62841,0 -17.67576,-11.08447 -17.67576,-13.30136 V 265.3502 c 0,-2.21688 -8.8378803,-28.81959 17.67576,-28.81959 26.51366,0 17.67578,24.38579 17.67578,28.81959 v 11.08447 c 0,2.2169 -11.04735,13.30136 -17.67578,13.30136 z"
style="display:inline;fill:#8f7049;fill-opacity:1;stroke:none;stroke-width:0.27664718px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="cccscc"
inkscape:connector-curvature="0"
id="path912-5"
d="m 55.360503,265.50979 c -2.38194,-3.6074 -7.17132,3.85123 -4.47676,4.61392 2.33861,0.53454 4.07627,-3.91788 1.87089,-5.63667 2.67269,-0.46024 1.46998,7.33579 -2.07135,6.15963 -3.54132,-1.17615 3.54133,-10.71085 4.67722,-5.13689 z"
style="display:inline;fill:#8f7049;fill-opacity:1;stroke:none;stroke-width:0.23146558px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="sssssss"
inkscape:connector-curvature="0"
id="path874"
d="m 33.878283,288.53332 c -6.35,0 -16.93334,-10.58334 -16.93334,-12.7 v -10.58334 c 0,-2.11666 -8.4666703,-27.51666 16.93334,-27.51666 25.40003,0 16.93336,23.28331 16.93336,27.51666 v 10.58334 c 0,2.11667 -10.58333,12.7 -16.93336,12.7 z"
style="display:inline;fill:#d0b18b;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="ccsc"
inkscape:connector-curvature="0"
id="path974"
d="m 41.780523,276.89164 c -3.25979,5.1648 -12.2927,5.16658 -15.80447,0 1.69334,1.05834 2.91448,2.64584 7.90223,2.64584 4.98776,0 6.20891,-1.5875 7.90224,-2.64584 z"
style="display:inline;opacity:1;fill:#7a603e;fill-opacity:1;stroke:none;stroke-width:0.54652095;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="csc"
inkscape:connector-curvature="0"
id="path977"
d="m 25.940783,278.21457 c 0,-0.52918 -0.28624,-1.5875 1.12889,-1.5875 0.56445,0 -1.12889,0.52917 -1.12889,1.5875 z"
style="display:inline;fill:#7a603e;fill-opacity:1;stroke:none;stroke-width:0.27326047px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="csc"
inkscape:connector-curvature="0"
id="path977-9"
d="m 41.815803,278.21457 c 0,-0.52918 0.28624,-1.5875 -1.12889,-1.5875 -0.56444,0 1.12889,0.52917 1.12889,1.5875 z"
style="display:inline;fill:#7a603e;fill-opacity:1;stroke:none;stroke-width:0.27326047px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="ccccssssssssscccccccssscccssssscccss"
inkscape:connector-curvature="0"
id="path994"
d="m 40.636553,231.54041 c -9.48626,-0.0677 -13.18089,2.07994 -19.51047,8.29097 -0.67028,-0.4891 -0.15247,-1.57224 0.13333,-2.53938 -4.21841,3.17909 -5.42738,6.12668 -6.42959,9.05836 -0.52689,3.42798 -0.17969,9.68831 -0.002,12.54962 0.21989,3.53192 1.0189,5.27213 1.05833,8.46666 0.0394,3.19454 -1.6023,6.09464 0,10.58334 1.60231,4.4887 8.14635,9.48143 11.64168,11.64166 3.49532,2.16024 4.11884,2.11668 6.35,2.11668 2.23117,0 2.85468,0.0436 6.35003,-2.11668 3.49532,-2.16023 10.03936,-7.15296 11.64167,-11.64166 1.6023,-4.4887 -0.0394,-7.3888 0,-10.58334 0.0394,-3.19453 0.83844,-4.93474 1.05833,-8.46666 0.18431,-2.9605 0.54614,-9.40756 -0.063,-12.9005 -0.64175,-2.31972 -2.32452,-3.33817 -3.94343,-4.43642 -0.43544,-0.90244 0.55845,-1.32843 1.60352,-1.73736 -3.22623,-2.2632 -5.33567,-1.54831 -7.88428,-2.00453 -0.10407,-0.92061 1.01163,-1.59726 2.13837,-2.2717 h -6.28076 c -0.70584,-0.54832 0.61173,-2.22076 2.13787,-4.00906 z m -16.32565,14.51798 c 2.40779,0.0173 5.14283,2.25826 9.56738,2.25826 5.05665,0 7.90673,-2.92709 10.58336,-2.11667 2.67663,0.81042 4.23333,4.23334 4.23333,4.23334 v 2.11666 l 2.11667,10.58334 c 0,0 -0.2216,9.01753 -2.11667,12.7 -1.89506,3.68245 -4.38037,7.75185 -7.40833,8.46666 -3.02799,0.7148 -3.17502,-2.11666 -7.40836,-2.11666 -4.23333,0 -4.38037,2.83146 -7.40834,2.11666 -3.02796,-0.71481 -5.51327,-4.78421 -7.40833,-8.46666 -1.89507,-3.68247 -2.11667,-12.7 -2.11667,-12.7 l 2.11667,-10.58334 v -2.11666 c 0,0 1.5567,-3.42292 4.23333,-4.23334 0.33458,-0.1013 0.67199,-0.14407 1.01596,-0.14159 z"
style="display:inline;fill:#413527;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="cscsc"
inkscape:connector-curvature="0"
id="path1016"
d="m 30.446933,265.39533 c -0.14878,2.03022 -2.09575,3.54592 -4.66051,3.54134 -2.57393,-0.005 -4.49348,-1.94764 -4.49348,-3.90346 0.37288,-1.21006 1.94153,-2.14037 4.49348,-2.17694 2.5677,-0.0368 4.42543,0.8967 4.66051,2.53906"
style="display:inline;opacity:1;fill:#50422f;fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="cscsc"
inkscape:connector-curvature="0"
id="path1016-2"
d="m 30.279893,265.46792 c -0.14336,1.77793 -2.01926,3.10528 -4.49043,3.10126 -2.47999,-0.004 -4.32948,-1.77138 -4.32947,-3.48415 0.35927,-1.05969 1.87066,-1.66235 4.32947,-1.69437 2.47399,-0.0322 4.26392,0.63898 4.49043,2.07726"
style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.48607698;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path1307"
d="m 25.789363,263.36704 c -1.123,0.0146 -2.04559,0.14984 -2.75383,0.39171 a 3.4017855,3.4017855 0 0 0 -0.0145,0.28629 3.4017855,3.4017855 0 0 0 3.40186,3.40186 3.4017855,3.4017855 0 0 0 3.37137,-2.97347 c -0.72682,-0.76888 -2.17815,-1.13017 -4.00493,-1.10639 z"
style="display:inline;opacity:1;fill:url(#linearGradient1317);fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path1335"
d="m 25.789363,263.34341 c -0.2884,0.004 -0.56223,0.0164 -0.82423,0.0357 a 1.5591518,1.5591518 0 0 0 -0.10181,0.54777 1.5591518,1.5591518 0 0 0 1.5596,1.5596 1.5591518,1.5591518 0 0 0 1.55908,-1.5596 1.5591518,1.5591518 0 0 0 -0.0517,-0.39378 c -0.62414,-0.13675 -1.34673,-0.19998 -2.14096,-0.18964 z"
style="display:inline;opacity:1;fill:#3a3a3a;fill-opacity:1;stroke:none;stroke-width:0.47195944;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<ellipse
ry="0.56696427"
rx="0.62602305"
cy="265.41534"
cx="27.629911"
id="path1262"
style="display:inline;opacity:1;fill:#fdfcfa;fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<ellipse
ry="0.23623511"
rx="0.2952939"
cy="266.4548"
cx="27.058241"
id="path1264"
style="display:inline;opacity:1;fill:#fdfcfa;fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="cscsc"
inkscape:connector-curvature="0"
id="path1016-89"
d="m 37.368413,265.39533 c 0.14878,2.03022 2.09576,3.54592 4.66053,3.54134 2.57393,-0.005 4.49348,-1.94764 4.49347,-3.90346 -0.37288,-1.21006 -1.94152,-2.14037 -4.49347,-2.17694 -2.56771,-0.0368 -4.42545,0.8967 -4.66053,2.53906"
style="display:inline;opacity:1;fill:#50422f;fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="cscsc"
inkscape:connector-curvature="0"
id="path1016-2-73"
d="m 37.535453,265.46792 c 0.14336,1.77793 2.01928,3.10528 4.49044,3.10126 2.47999,-0.004 4.32948,-1.77138 4.32948,-3.48415 -0.35927,-1.05969 -1.87067,-1.66235 -4.32948,-1.69437 -2.47399,-0.0322 -4.26393,0.63898 -4.49044,2.07726"
style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.48607698;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path1307-6"
d="m 42.025993,263.36704 c 1.12301,0.0146 2.0456,0.14984 2.75384,0.39171 a 3.4017855,3.4017855 0 0 1 0.0145,0.28629 3.4017855,3.4017855 0 0 1 -3.40186,3.40186 3.4017855,3.4017855 0 0 1 -3.37139,-2.97347 c 0.72683,-0.76888 2.17817,-1.13017 4.00494,-1.10639 z"
style="display:inline;opacity:1;fill:url(#linearGradient1317-9);fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<ellipse
transform="scale(-1,1)"
ry="0.23623511"
rx="0.2952939"
cy="266.4548"
cx="-41.804092"
id="path1264-2"
style="display:inline;opacity:1;fill:#fdfcfa;fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path1335-1"
d="m 42.025993,263.34341 c 0.2884,0.004 0.56224,0.0164 0.82424,0.0357 a 1.5591518,1.5591518 0 0 1 0.1018,0.54777 1.5591518,1.5591518 0 0 1 -1.55959,1.5596 1.5591518,1.5591518 0 0 1 -1.55909,-1.5596 1.5591518,1.5591518 0 0 1 0.0517,-0.39378 c 0.62415,-0.13675 1.34674,-0.19998 2.14097,-0.18964 z"
style="display:inline;opacity:1;fill:#3a3a3a;fill-opacity:1;stroke:none;stroke-width:0.47195947;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<ellipse
transform="scale(-1,1)"
ry="0.56696427"
rx="0.62602305"
cy="265.41534"
cx="-42.290756"
id="path1262-0"
style="display:inline;opacity:1;fill:#fdfcfa;fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path1392"
d="m 25.312393,261.13964 a 6.3547249,4.8428201 0 0 0 -6.35465,4.8426 6.3547249,4.8428201 0 0 0 6.35465,4.8431 6.3547249,4.8428201 0 0 0 6.35466,-4.8431 6.3547249,4.8428201 0 0 0 -6.35466,-4.8426 z m 0,0.73794 a 5.5987725,4.1520295 0 0 1 5.59863,4.1522 5.5987725,4.1520295 0 0 1 -5.59863,4.15167 5.5987725,4.1520295 0 0 1 -5.59863,-4.15167 5.5987725,4.1520295 0 0 1 5.59863,-4.1522 z"
style="display:inline;opacity:1;fill:#474a50;fill-opacity:1;stroke:none;stroke-width:0.52527565;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<ellipse
ry="4.1520295"
rx="5.5987725"
cy="266.02957"
cx="25.312422"
id="path1392-3"
style="display:inline;opacity:0.42000002;fill:url(#linearGradient1457);fill-opacity:1;stroke:none;stroke-width:0.45652688;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
id="path1392-9"
d="m 42.529233,261.13964 a 6.3547249,4.8428201 0 0 1 6.35466,4.8426 6.3547249,4.8428201 0 0 1 -6.35466,4.84311 6.3547249,4.8428201 0 0 1 -6.35467,-4.84311 6.3547249,4.8428201 0 0 1 6.35467,-4.8426 z m 0,0.73794 a 5.5987725,4.1520295 0 0 0 -5.59864,4.1522 5.5987725,4.1520295 0 0 0 5.59864,4.15168 5.5987725,4.1520295 0 0 0 5.59863,-4.15168 5.5987725,4.1520295 0 0 0 -5.59863,-4.1522 z"
style="display:inline;opacity:1;fill:#474a50;fill-opacity:1;stroke:none;stroke-width:0.52527565;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
inkscape:connector-curvature="0" />
<ellipse
transform="scale(-1,1)"
ry="4.1520295"
rx="5.5987725"
cy="266.02957"
cx="-42.529282"
id="path1392-3-4"
style="display:inline;opacity:0.42000002;fill:url(#linearGradient1449);fill-opacity:1;stroke:none;stroke-width:0.45652688;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="ccccccc"
inkscape:connector-curvature="0"
id="path1459"
d="m 33.911363,262.2357 c -1.70928,-9e-5 -3.09497,0.9008 -3.09491,1.71513 0.001,0.17839 0.0321,0.35605 0.0915,0.52917 0.33633,-1.00541 1.57683,-1.7138 3.00344,-1.71514 1.4264,10e-4 2.66682,0.70943 3.00343,1.71463 0.0593,-0.17297 0.09,-0.35044 0.0915,-0.52866 6e-5,-1.00331 -1.38563,-1.71522 -3.0949,-1.71513 z"
style="display:inline;opacity:1;fill:#474a50;fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="zcccz"
inkscape:connector-curvature="0"
id="path1477"
d="m 14.610933,259.48584 c 0.54704,-0.14611 5.66965,4.20499 5.66965,4.20499 l -0.7087,0.99219 -5.19718,-4.39397 c 0,0 -0.3108,-0.65708 0.23623,-0.80321 z"
style="display:inline;fill:#474a50;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="zcccz"
inkscape:connector-curvature="0"
id="path1477-8"
d="m 53.293953,259.48584 c -0.54703,-0.14611 -5.66964,4.20499 -5.66964,4.20499 l 0.7087,0.99219 5.19718,-4.39397 c 0,0 0.3108,-0.65708 -0.23624,-0.80321 z"
style="display:inline;fill:#474a50;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="czczc"
inkscape:connector-curvature="0"
id="path940"
d="m 30.174113,273.18749 c 0.75748,0.23907 2.11667,1.3229 3.70417,1.3229 1.5875,0 2.91042,-1.05832 3.71835,-1.27567 0.51499,0.74652 -2.13085,2.5986 -3.71835,2.5986 -1.5875,0 -4.23333,-1.85208 -3.70417,-2.64583 z"
style="display:inline;fill:#7b613f;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="ccc"
inkscape:connector-curvature="0"
id="path942"
d="m 19.326193,261.81039 c 0,-4.76249 9.19866,-4.27638 11.37709,-0.79375 -4.31807,-0.99755 -7.93753,-1.83744 -11.37709,0.79375 z"
style="display:inline;fill:#413527;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="ccc"
inkscape:connector-curvature="0"
id="path942-2"
d="m 48.430393,261.81039 c 0,-4.76249 -9.19867,-4.27638 -11.37711,-0.79375 4.31809,-0.99755 7.93755,-1.83744 11.37711,0.79375 z"
style="display:inline;fill:#413527;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="cccssssssssscccccccccscccssssscccssc"
inkscape:connector-curvature="0"
id="path994-3"
d="m 21.126083,240.8897 c -0.67028,-0.4891 -0.15247,-2.63057 0.13332,-3.59771 -4.2184,3.17909 -4.8982,6.12668 -5.90041,9.05837 -0.52689,3.42797 -0.17969,9.6883 -10e-4,12.54962 0.21989,3.53192 1.0189,5.27213 1.05833,8.46665 0.0394,3.19455 -1.07313,6.09465 0.52917,10.58335 1.6023,4.48869 7.08801,8.4231 10.58334,10.58333 3.49532,2.16024 4.11884,2.11667 6.35,2.11667 2.23117,0 2.85468,0.0436 6.35003,-2.11667 3.49532,-2.16023 8.98103,-6.09464 10.58333,-10.58333 1.6023,-4.4887 0.48974,-7.3888 0.52917,-10.58335 0.0394,-3.19452 0.83844,-4.93473 1.05833,-8.46665 0.18432,-2.96051 0.54614,-9.40757 -0.063,-12.90051 -0.64174,-2.31972 -2.85368,-3.33816 -4.4726,-4.43642 -0.43544,-0.90244 0.55845,-1.32843 1.60352,-1.73736 -3.22622,-2.2632 -5.33567,-0.48998 -7.88427,-0.9462 -0.10407,-0.9206 0.63366,-2.18311 1.76039,-2.85756 l -5.90279,0.58586 c -0.70583,-0.54832 1.9421,-4.55121 1.9421,-4.55121 -7.7863,0.14491 -11.76142,1.95278 -18.25641,8.83312 z m 3.18482,5.16868 c 2.40779,0.0174 5.14283,2.25826 9.56738,2.25826 5.05665,0 7.90673,-2.92708 10.58336,-2.11666 2.67663,0.81042 4.23333,4.23333 4.23333,4.23333 v 2.11667 l 2.11667,10.58333 c 0,0 -0.2216,9.01754 -2.11667,12.7 -1.89506,3.68246 -4.38037,7.75186 -7.40833,8.46667 -3.02799,0.7148 -3.17502,-2.11667 -7.40836,-2.11667 -4.23333,0 -4.38037,2.83147 -7.40834,2.11667 -3.02796,-0.71481 -5.51327,-4.78421 -7.40833,-8.46667 -1.89507,-3.68246 -2.11667,-12.7 -2.11667,-12.7 l 2.11667,-10.58333 v -2.11667 c 0,0 1.5567,-3.42291 4.23333,-4.23333 0.33458,-0.10131 0.67199,-0.14407 1.01596,-0.1416 z"
style="display:inline;fill:#51412e;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="ccc"
inkscape:connector-curvature="0"
id="path942-6"
d="m 19.642753,261.27177 c 1.08668,-3.81755 7.82789,-2.98727 10.53136,-0.65199 -4.31807,-0.99756 -7.4934,-1.48311 -10.53136,0.65199 z"
style="display:inline;fill:#51412e;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="ccc"
inkscape:connector-curvature="0"
id="path942-6-5"
d="m 48.128013,261.2954 c -1.08668,-3.81756 -7.82789,-2.98728 -10.53138,-0.65201 4.31808,-0.99754 7.49342,-1.48309 10.53138,0.65201 z"
style="display:inline;fill:#51412e;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<g
transform="matrix(0.70229636,0.18817974,-0.18817974,0.70229636,48.833301,-112.35669)"
id="layer1-7"
inkscape:label="Calque 1">
<path
sodipodi:nodetypes="csc"
inkscape:connector-curvature="0"
id="path1490-68"
d="m 17.172067,264.99983 c -7.2482718,-9.3385 -6.088271,10.96659 1.336348,10.89123 4.899788,-0.0497 -1.336348,-10.89123 -1.336348,-10.89123 z"
style="display:inline;fill:#8f7049;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="csc"
inkscape:connector-curvature="0"
id="path1490-0-8"
d="m 17.303978,265.77381 c -6.649489,-8.21655 -5.451681,9.38177 1.359586,9.31547 4.495014,-0.0437 -1.359586,-9.31547 -1.359586,-9.31547 z"
style="display:inline;fill:#d0b18b;fill-opacity:1;stroke:none;stroke-width:0.23770896px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path1509-4"
d="m 17.78329,273.3764 c -0.288666,-0.052 -0.382024,-0.0864 -0.551234,-0.20291 -0.784195,-0.54009 -1.69582,-2.13965 -1.986746,-3.48599 -0.08995,-0.4163 -0.08973,-1.2232 4.23e-4,-1.52036 0.09224,-0.30405 0.255565,-0.59669 0.441085,-0.7903 0.163563,-0.17071 0.565937,-0.45168 0.646834,-0.45168 0.06489,0 0.326425,0.31848 0.604282,0.73587 0.585827,0.88001 1.483803,2.90435 1.820951,4.10504 0.256526,0.91357 0.21728,1.43547 -0.120144,1.59773 -0.158485,0.0762 -0.47638,0.0809 -0.855441,0.0126 z"
style="display:inline;opacity:1;fill:#b9976b;fill-opacity:1;stroke:none;stroke-width:0.07199875;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="cscccsccc"
inkscape:connector-curvature="0"
id="path1507-3"
d="m 13.898015,268.7416 c -0.467722,-2.73951 1.80407,-3.94222 3.808591,0.46773 2.004521,4.40994 0.868626,4.10927 -0.200452,3.90881 -1.069078,-0.20045 -3.775183,-4.94449 -1.03567,-6.01356 -0.06682,-0.20045 -0.133637,-0.33409 -0.367495,-0.50113 -0.567948,0.20045 -3.108308,3.84041 1.135896,7.04923 3.669162,2.77406 1.399229,-4.79404 -0.300681,-6.71515 -1.737252,-1.9377 -4.042452,-1.87088 -3.040191,1.80407 z"
style="display:inline;fill:#8f7049;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="csc"
inkscape:connector-curvature="0"
id="path1490-68-7"
d="m 50.69909,264.99983 c 7.248271,-9.3385 6.088271,10.96659 -1.33635,10.89123 -4.899787,-0.0497 1.33635,-10.89123 1.33635,-10.89123 z"
style="display:inline;fill:#8f7049;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="csc"
inkscape:connector-curvature="0"
id="path1490-0-8-7"
d="m 50.567179,265.77381 c 6.649487,-8.21655 5.451679,9.38177 -1.359588,9.31547 -4.495014,-0.0437 1.359588,-9.31547 1.359588,-9.31547 z"
style="display:inline;fill:#d0b18b;fill-opacity:1;stroke:none;stroke-width:0.23770896px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path1509-4-1"
d="m 50.087865,273.3764 c 0.288666,-0.052 0.382024,-0.0864 0.551236,-0.20291 0.784193,-0.54009 1.69582,-2.13965 1.986745,-3.48599 0.08995,-0.4163 0.08973,-1.2232 -5.29e-4,-1.52036 -0.09224,-0.30405 -0.255566,-0.59669 -0.441087,-0.7903 -0.16356,-0.17071 -0.565935,-0.45168 -0.646832,-0.45168 -0.06489,0 -0.326424,0.31848 -0.604282,0.73587 -0.585827,0.88001 -1.483802,2.90435 -1.820952,4.10504 -0.256527,0.91357 -0.217279,1.43547 0.120145,1.59773 0.158485,0.0762 0.476379,0.0809 0.855442,0.0126 z"
style="display:inline;opacity:1;fill:#b9976b;fill-opacity:1;stroke:none;stroke-width:0.07199875;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="szszszs"
inkscape:connector-curvature="0"
id="path874-3-2-2"
d="m 33.878283,290.26521 c -6.62841,0 -13.347912,-8.05484 -14.500761,-10.65552 -1.152849,-2.60067 -3.175,-12.1428 -3.175,-12.1428 -0.415819,-2.17754 -6.192056,-27.2321 17.675761,-27.2321 23.867817,0 18.507422,22.87699 17.675781,27.2321 0,0 -2.211138,9.82561 -3.269496,12.1428 -1.058354,2.3172 -7.777855,10.65552 -14.406285,10.65552 z"
style="display:inline;fill:#8f7049;fill-opacity:1;stroke:none;stroke-width:0.27664718px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="cscccsccc"
inkscape:connector-curvature="0"
id="path1507-3-1"
d="m 53.973142,268.7416 c 0.467722,-2.73951 -1.804072,-3.94222 -3.808593,0.46773 -2.00452,4.40994 -0.868624,4.10927 0.200454,3.90881 1.069078,-0.20045 3.775181,-4.94449 1.035669,-6.01356 0.06682,-0.20045 0.133636,-0.33409 0.367496,-0.50113 0.567946,0.20045 3.108306,3.84041 -1.135896,7.04923 -3.669162,2.77406 -1.399231,-4.79404 0.30068,-6.71515 1.737252,-1.9377 4.042453,-1.87088 3.04019,1.80407 z"
style="display:inline;fill:#8f7049;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="szszszs"
inkscape:connector-curvature="0"
id="path874-8-6"
d="m 33.878283,289.0625 c -6.35,0 -12.889328,-8.07145 -13.758341,-10.05416 -0.869013,-1.98272 -3.175,-11.64168 -3.175,-11.64168 -0.41511,-2.07555 -6.009834,-25.92916 16.933341,-25.92916 22.943175,0 17.763586,21.77803 16.93336,25.92916 0,0 -2.305986,9.46996 -3.175,11.64168 -0.869016,2.17171 -7.40833,10.05416 -13.75836,10.05416 z"
style="display:inline;fill:#d0b18b;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="cczc"
inkscape:connector-curvature="0"
id="path974-79-8"
d="m 40.552099,279.00833 c -2.753045,3.79054 -10.381767,3.6907 -13.347623,0 1.430106,1.05833 4.154325,1.52068 6.673808,1.52068 2.519481,0 5.243719,-0.46235 6.673815,-1.52068 z"
style="display:inline;opacity:1;fill:#7a603e;fill-opacity:1;stroke:none;stroke-width:0.5022487;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="czcsc"
inkscape:connector-curvature="0"
id="path1016-3-6"
d="m 30.361889,266.15131 c -0.14878,2.03022 -1.051481,4.59966 -4.66051,4.59966 -3.609029,0 -4.49348,-3.00597 -4.49348,-4.96179 0.37288,-1.21006 1.94153,-2.66953 4.49348,-2.7061 2.5677,-0.0368 4.42543,1.42586 4.66051,3.06823"
style="display:inline;opacity:1;fill:#5c5035;fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="czcsc"
inkscape:connector-curvature="0"
id="path1016-2-7-6"
d="m 30.194849,266.22389 c -0.14336,1.77793 -0.975418,4.16529 -4.49043,4.15959 -3.515012,-0.006 -4.32948,-2.82971 -4.32947,-4.54248 0.35927,-1.05969 1.87066,-2.19152 4.32947,-2.22354 2.47399,-0.0322 4.26392,1.16815 4.49043,2.60643"
style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.48607698;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path1513-49"
d="m 25.704374,263.57028 c -1.316739,0.0171 -2.358688,0.3511 -3.100586,0.81907 a 3.7797618,3.7797618 0 0 0 -0.01034,0.20877 3.7797618,3.7797618 0 0 0 3.779614,3.77962 3.7797618,3.7797618 0 0 0 3.640089,-2.77606 c -0.551114,-1.16866 -2.173981,-2.05919 -4.308782,-2.0314 z"
style="display:inline;opacity:1;fill:url(#linearGradient1537-8);fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<ellipse
ry="0.23623511"
rx="0.2952939"
cy="267.21078"
cx="26.973675"
id="path1264-28-50"
style="display:inline;opacity:1;fill:#fdfcfa;fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="czczc"
inkscape:connector-curvature="0"
id="path940-03-4"
d="m 31.101841,274.8695 c 0.568041,0.29244 1.587309,0.97092 2.777789,0.97092 1.190481,0 2.18255,-0.64728 2.788423,-0.91314 0.386196,0.91315 -1.597942,2.53135 -2.788423,2.53135 -1.19048,0 -3.174611,-1.6182 -2.777789,-2.58913 z"
style="display:inline;fill:#7b613f;fill-opacity:1;stroke:none;stroke-width:0.25340664px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="ccc"
inkscape:connector-curvature="0"
id="path942-61-8"
d="m 18.889505,260.35334 c 0,-3.34403 9.12226,-3.0027 11.282597,-0.55734 -4.282206,-0.70044 -7.871605,-1.29018 -11.282597,0.55734 z"
style="display:inline;fill:#8c7439;fill-opacity:1;stroke:none;stroke-width:0.22078453px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="cccc"
inkscape:connector-curvature="0"
id="path1916-6"
d="m 20.888789,249.46948 c -2.36235,2.36235 -3.685268,14.83556 -2.834823,16.63095 -5.324877,-1.71025 -9.6683311,-20.57974 -0.09449,-20.50521 1.255301,0.7914 2.965393,3.44497 2.929313,3.87426 z"
style="display:inline;fill:#9e813e;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="ccc"
inkscape:connector-curvature="0"
id="path942-6-3-7"
d="m 19.203436,259.97514 c 1.077655,-2.68053 7.762875,-2.09754 10.443891,-0.45781 -4.282206,-0.70044 -7.431164,-1.04137 -10.443891,0.45781 z"
style="display:inline;fill:#b08f42;fill-opacity:1;stroke:none;stroke-width:0.22078453px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="cccc"
inkscape:connector-curvature="0"
id="path1916-5-3"
d="m 20.321824,248.52454 c -2.83482,3.1183 -3.779761,14.07961 -2.929316,15.875 -3.812974,-1.52126 -8.9123796,-17.46144 0.661462,-17.38691 1.100129,-0.13321 2.984074,0.59018 2.267854,1.51191 z"
style="display:inline;fill:#b08f42;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path1511-1"
d="m 25.704374,263.52303 c -0.13937,0.002 -0.274482,0.008 -0.407727,0.017 a 1.5119048,1.5119048 0 0 0 -0.482658,1.10536 1.5119048,1.5119048 0 0 0 1.512053,1.51154 1.5119048,1.5119048 0 0 0 1.512051,-1.51154 1.5119048,1.5119048 0 0 0 -0.295587,-0.89555 c -0.551768,-0.15202 -1.168817,-0.23557 -1.838132,-0.22686 z"
style="display:inline;opacity:1;fill:#3a3a3a;fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<ellipse
ry="0.56696427"
rx="0.62602305"
cy="266.17133"
cx="27.54533"
id="path1262-2-72"
style="display:inline;opacity:1;fill:#fdfcfa;fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="czcsc"
inkscape:connector-curvature="0"
id="path1016-3-6-5"
d="m 37.509267,266.15131 c 0.14878,2.03022 1.05148,4.59966 4.660511,4.59966 3.609027,0 4.493479,-3.00597 4.493479,-4.96179 -0.37288,-1.21006 -1.941531,-2.66953 -4.493479,-2.7061 -2.567702,-0.0368 -4.425432,1.42586 -4.660511,3.06823"
style="display:inline;opacity:1;fill:#5c5035;fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="czcsc"
inkscape:connector-curvature="0"
id="path1016-2-7-6-9"
d="m 37.676306,266.22389 c 0.143359,1.77793 0.975418,4.16529 4.490429,4.15959 3.515013,-0.006 4.329483,-2.82971 4.329472,-4.54248 -0.359269,-1.05969 -1.870662,-2.19152 -4.329472,-2.22354 -2.473989,-0.0322 -4.263919,1.16815 -4.490429,2.60643"
style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.48607698;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path1513-49-7"
d="m 42.16678,263.57028 c 1.316741,0.0171 2.358689,0.3511 3.100586,0.81907 a 3.7797618,3.7797618 0 0 1 0.01035,0.20877 3.7797618,3.7797618 0 0 1 -3.779613,3.77962 3.7797618,3.7797618 0 0 1 -3.640089,-2.77606 c 0.551113,-1.16866 2.17398,-2.05919 4.308782,-2.0314 z"
style="display:inline;opacity:1;fill:url(#linearGradient1537-8-0);fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<ellipse
transform="scale(-1,1)"
ry="0.23623511"
rx="0.2952939"
cy="267.21078"
cx="-41.955811"
id="path1264-28-50-7"
style="display:inline;opacity:1;fill:#fdfcfa;fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="ccc"
inkscape:connector-curvature="0"
id="path942-61-8-6"
d="m 48.98165,260.35334 c 0,-3.34403 -9.122259,-3.0027 -11.282598,-0.55734 4.282207,-0.70044 7.871606,-1.29018 11.282598,0.55734 z"
style="display:inline;fill:#8c7439;fill-opacity:1;stroke:none;stroke-width:0.22078453px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="ccc"
inkscape:connector-curvature="0"
id="path942-6-3-7-7"
d="m 48.667719,259.97514 c -1.077653,-2.68053 -7.762875,-2.09754 -10.443892,-0.45781 4.282207,-0.70044 7.431167,-1.04137 10.443892,0.45781 z"
style="display:inline;fill:#b08f42;fill-opacity:1;stroke:none;stroke-width:0.22078453px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path1511-1-3"
d="m 42.16678,263.52303 c 0.139372,0.002 0.274484,0.008 0.407728,0.017 a 1.5119048,1.5119048 0 0 1 0.482658,1.10536 1.5119048,1.5119048 0 0 1 -1.512051,1.51154 1.5119048,1.5119048 0 0 1 -1.512054,-1.51154 1.5119048,1.5119048 0 0 1 0.295587,-0.89555 c 0.55177,-0.15202 1.168818,-0.23557 1.838132,-0.22686 z"
style="display:inline;opacity:1;fill:#3a3a3a;fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<ellipse
transform="scale(-1,1)"
ry="0.56696427"
rx="0.62602305"
cy="266.17133"
cx="-42.442493"
id="path1262-2-72-6"
style="display:inline;opacity:1;fill:#fdfcfa;fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="ccccccsc"
inkscape:connector-curvature="0"
id="path1916"
d="m 46.585565,249.46948 c 2.83482,3.1183 3.685268,14.83556 2.834823,16.63095 5.324877,-1.71025 9.66833,-20.57974 0.09449,-20.50521 C 49.325892,235.95683 6.6145831,230.00371 9.8273807,262.88763 15.875,260.61978 28.44271,249.84745 33.923363,247.01263 c -2.929316,3.68527 -12.37872,10.11087 -12.37872,10.11087 0,0 22.014689,-5.37288 21.922617,-9.35491 -0.04884,-2.11239 3.118305,1.70089 3.118305,1.70089 z"
style="display:inline;fill:#9e813e;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="ccccccsc"
inkscape:connector-curvature="0"
id="path1916-5"
d="m 46.774554,248.43004 c 2.83482,3.11831 4.157737,14.17411 3.307292,15.9695 3.812974,-1.52126 7.967438,-18.1229 -1.606402,-18.04837 0.0097,-9.39717 -37.704327,-15.15425 -37.419641,14.17411 6.04762,-2.26785 18.709824,-12.47321 24.757441,-15.21354 -2.929316,3.68527 -10.583333,10.01637 -10.583333,10.01637 0,0 17.951445,-4.33344 17.859373,-8.31548 -0.04884,-2.11238 3.68527,1.41741 3.68527,1.41741 z"
style="display:inline;fill:#b08f42;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<g
transform="matrix(0.69364118,-0.1858606,0.1858606,0.69364118,2.00487,-95.470759)"
id="layer1-60"
inkscape:label="Calque 1">
<path
sodipodi:nodetypes="ccsssc"
inkscape:connector-curvature="0"
id="path2262"
d="m 8.4666667,280.59582 c 4.1581663,8.43066 46.4906443,8.5026 50.8000003,0 C 57.074406,274.34031 57.15,269.48332 57.15,267.36665 c 0,-2.11667 2.116667,-31.75 -23.283333,-31.75 -25.4000003,0 -23.283334,29.63333 -23.283334,31.75 0,2.11667 0,8.99583 -2.1166663,13.22917 z"
style="display:inline;fill:#44341e;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="ccsssc"
inkscape:connector-curvature="0"
id="path2262-6"
d="m 9.6640073,280.38999 c 4.0487817,8.16453 44.2093267,8.2342 48.4053197,0 -2.134592,-6.05804 -1.531819,-11.24076 -1.531819,-13.29061 0,-2.04985 2.060986,-30.74774 -22.67084,-30.74774 -24.7318274,0 -22.670842,28.69789 -22.670842,30.74774 0,2.04985 0.529167,9.19091 -1.5318187,13.29061 z"
style="display:inline;fill:#644e2d;fill-opacity:1;stroke:none;stroke-width:0.25692621px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="csc"
inkscape:connector-curvature="0"
id="path1490-68-9"
d="m 17.10315,264.99983 c -7.2482795,-9.3385 -6.08828,10.96659 1.33635,10.89123 4.899791,-0.0497 -1.33635,-10.89123 -1.33635,-10.89123 z"
style="display:inline;fill:#8f7249;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="csc"
inkscape:connector-curvature="0"
id="path1490-0-8-0"
d="m 17.23506,265.77381 c -6.6495,-8.21655 -5.45168,9.38177 1.359591,9.31547 4.49501,-0.0437 -1.359591,-9.31547 -1.359591,-9.31547 z"
style="display:inline;fill:#cbb697;fill-opacity:1;stroke:none;stroke-width:0.23770896px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path1509-4-8"
d="m 17.71437,273.3764 c -0.28866,-0.052 -0.38202,-0.0864 -0.55123,-0.20291 -0.7842,-0.54009 -1.69583,-2.13965 -1.98675,-3.48599 -0.0899,-0.4163 -0.0897,-1.2232 4.24e-4,-1.52036 0.0922,-0.30405 0.25557,-0.59669 0.44109,-0.79031 0.16356,-0.1707 0.56593,-0.45167 0.64683,-0.45167 0.0649,0 0.32643,0.31848 0.60429,0.73587 0.585819,0.88001 1.4838,2.90435 1.82095,4.10504 0.25652,0.91357 0.21728,1.43547 -0.12015,1.59773 -0.15848,0.0762 -0.47638,0.0809 -0.85544,0.0126 z"
style="display:inline;opacity:1;fill:#b59c78;fill-opacity:1;stroke:none;stroke-width:0.07199875;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="cscccsccc"
inkscape:connector-curvature="0"
id="path1507-3-8"
d="m 13.82909,268.7416 c -0.46772,-2.73951 1.80407,-3.94222 3.8086,0.46772 2.004521,4.40995 0.86862,4.10927 -0.20045,3.90882 -1.06908,-0.20045 -3.77519,-4.94449 -1.03567,-6.01357 -0.0668,-0.20045 -0.13365,-0.33408 -0.3675,-0.50112 -0.56795,0.20045 -3.10831,3.84041 1.1359,7.04923 3.669161,2.77406 1.399231,-4.79404 -0.30068,-6.71515 -1.73726,-1.9377 -4.04246,-1.87088 -3.0402,1.80407 z"
style="display:inline;fill:#8f7249;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="csc"
inkscape:connector-curvature="0"
id="path1490-68-7-5"
d="m 50.630191,264.99983 c 7.248271,-9.3385 6.088269,10.96659 -1.33635,10.89123 -4.899789,-0.0497 1.33635,-10.89123 1.33635,-10.89123 z"
style="display:inline;fill:#8f7249;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="csc"
inkscape:connector-curvature="0"
id="path1490-0-8-7-0"
d="m 50.49828,265.77381 c 6.64949,-8.21655 5.451681,9.38177 -1.35959,9.31547 -4.49502,-0.0437 1.35959,-9.31547 1.35959,-9.31547 z"
style="display:inline;fill:#cbb697;fill-opacity:1;stroke:none;stroke-width:0.23770896px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path1509-4-1-9"
d="m 50.018971,273.3764 c 0.288661,-0.052 0.382019,-0.0864 0.551231,-0.20291 0.784188,-0.54009 1.69582,-2.13965 1.98674,-3.48599 0.09,-0.4163 0.0897,-1.2232 -5.29e-4,-1.52036 -0.0922,-0.30405 -0.255558,-0.59669 -0.441079,-0.79031 -0.163571,-0.1707 -0.565941,-0.45167 -0.64684,-0.45167 -0.0649,0 -0.326422,0.31848 -0.604279,0.73587 -0.585833,0.88001 -1.483802,2.90435 -1.820953,4.10504 -0.256529,0.91357 -0.217278,1.43547 0.120142,1.59773 0.158488,0.0762 0.47638,0.0809 0.855448,0.0126 z"
style="display:inline;opacity:1;fill:#b59c78;fill-opacity:1;stroke:none;stroke-width:0.07199875;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="cscccsccc"
inkscape:connector-curvature="0"
id="path1507-3-1-6"
d="m 53.90424,268.7416 c 0.467731,-2.73951 -1.804069,-3.94222 -3.80859,0.46772 -2.004528,4.40995 -0.868629,4.10927 0.200451,3.90882 1.069081,-0.20045 3.775189,-4.94449 1.035669,-6.01357 0.0668,-0.20045 0.133642,-0.33408 0.367501,-0.50112 0.567939,0.20045 3.10831,3.84041 -1.135901,7.04923 -3.669159,2.77406 -1.39923,-4.79404 0.300681,-6.71515 1.737251,-1.9377 4.04246,-1.87088 3.0402,1.80407 z"
style="display:inline;fill:#8f7249;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path2003"
d="m 33.866667,237.73332 c -5.746295,0 -13.371698,3.08736 -16.895093,10.8908 -3.704735,8.20508 0.778839,26.21717 2.138371,29.5336 0.956383,2.333 5.612478,6.28076 6.547921,6.94893 0.935445,0.66818 3.975468,3.42667 8.208801,3.42667 4.233333,0 7.273356,-2.75849 8.208801,-3.42667 0.935442,-0.66817 5.591538,-4.61593 6.547922,-6.94893 1.359532,-3.31643 5.843106,-21.32852 2.13837,-29.5336 -3.523395,-7.80344 -11.148798,-10.8908 -16.895093,-10.8908 z"
style="display:inline;opacity:1;fill:#8f7249;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
id="path2003-3"
d="m 33.866667,238.77275 c -5.538927,0 -12.889152,2.95528 -16.285399,10.42487 -3.571042,7.85404 0.750732,25.09552 2.061203,28.27007 0.92187,2.23319 5.409941,6.01205 6.311627,6.65164 0.901687,0.63958 3.832005,3.28006 7.912569,3.28006 4.080566,0 7.010882,-2.64048 7.912568,-3.28006 0.901687,-0.63959 5.389756,-4.41845 6.311628,-6.65164 1.31047,-3.17455 5.632246,-20.41603 2.061202,-28.27007 -3.396247,-7.46959 -10.74647,-10.42487 -16.285398,-10.42487 z"
style="display:inline;opacity:1;fill:#cbb697;fill-opacity:1;stroke:none;stroke-width:0.25414798px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0" />
<path
sodipodi:nodetypes="czcsc"
inkscape:connector-curvature="0"
id="path1016-3-6-1"
d="m 30.292978,265.62214 c -0.14878,2.03022 -1.05148,4.66648 -4.66052,4.66648 -3.60903,0 -4.49348,-3.60196 -4.49348,-5.55778 0.372879,-1.21006 1.94153,-2.46907 4.49348,-2.50564 2.56771,-0.0368 4.42544,1.75457 4.66052,3.39694"
style="display:inline;opacity:1;fill:#574427;fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="czcsc"
inkscape:connector-curvature="0"
id="path1016-2-7-6-5"
d="m 30.125938,265.69472 c -0.14336,1.77793 -0.97542,4.16529 -4.490441,4.15959 -3.515009,-0.006 -4.32948,-2.82971 -4.329469,-4.54248 0.35927,-1.05969 1.87066,-2.19152 4.329469,-2.22354 2.474001,-0.0322 4.263931,1.16815 4.490441,2.60643"
style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.48607698;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path1513-49-9"
d="m 25.635458,263.04111 c -1.31674,0.0172 -2.35869,0.3511 -3.10059,0.81907 a 3.7797618,3.7797618 0 0 0 -0.0103,0.20877 3.7797618,3.7797618 0 0 0 3.77962,3.77962 3.7797618,3.7797618 0 0 0 3.64009,-2.77606 c -0.55112,-1.16866 -2.17398,-2.05918 -4.30879,-2.0314 z"
style="display:inline;opacity:1;fill:url(#linearGradient1537-8-8);fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<ellipse
ry="0.23623511"
rx="0.2952939"
cy="266.68161"
cx="26.904797"
id="path1264-28-50-8"
style="display:inline;opacity:1;fill:#fdfcfa;fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="ccc"
inkscape:connector-curvature="0"
id="path942-61-8-4"
d="m 19.889666,259.82417 c 0,-3.34403 7.393508,-3.0027 9.144444,-0.55734 -3.470692,-0.70044 -6.379868,-1.29018 -9.144444,0.55734 z"
style="display:inline;fill:#644e2d;fill-opacity:1;stroke:none;stroke-width:0.19876628px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path1511-1-1"
d="m 25.635458,262.99387 c -0.139371,0.002 -0.274481,0.008 -0.407731,0.017 a 1.5119048,1.5119048 0 0 0 -0.482659,1.10536 1.5119048,1.5119048 0 0 0 1.51206,1.51154 1.5119048,1.5119048 0 0 0 1.51205,-1.51154 1.5119048,1.5119048 0 0 0 -0.29559,-0.89555 c -0.55177,-0.15202 -1.16882,-0.23557 -1.83813,-0.22686 z"
style="display:inline;opacity:1;fill:#3a3a3a;fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<ellipse
ry="0.56696427"
rx="0.62602305"
cy="265.64215"
cx="27.47645"
id="path1262-2-72-0"
style="display:inline;opacity:1;fill:#fdfcfa;fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="czcsc"
inkscape:connector-curvature="0"
id="path1016-3-6-5-3"
d="m 37.440357,265.62214 c 0.148781,2.03022 1.051481,4.66648 4.660511,4.66648 3.609031,0 4.49348,-3.07279 4.49348,-5.02861 -0.37288,-1.21006 -1.941531,-2.99824 -4.49348,-3.03481 -2.567699,-0.0368 -4.425431,1.75457 -4.660511,3.39694"
style="display:inline;opacity:1;fill:#574427;fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="czcsc"
inkscape:connector-curvature="0"
id="path1016-2-7-6-9-0"
d="m 37.607396,265.69472 c 0.143362,1.77793 0.975421,4.16529 4.490432,4.15959 3.515019,-0.006 4.32948,-2.82971 4.32947,-4.54248 -0.35927,-1.05969 -1.87066,-2.19152 -4.32947,-2.22354 -2.473989,-0.0322 -4.263919,1.16815 -4.490432,2.60643"
style="display:inline;opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.48607698;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path1513-49-7-4"
d="m 42.097868,263.04111 c 1.316749,0.0172 2.358699,0.3511 3.100591,0.81907 a 3.7797618,3.7797618 0 0 1 0.01029,0.20877 3.7797618,3.7797618 0 0 1 -3.77961,3.77962 3.7797618,3.7797618 0 0 1 -3.64009,-2.77606 c 0.551112,-1.16866 2.173981,-2.05918 4.308782,-2.0314 z"
style="display:inline;opacity:1;fill:url(#linearGradient1537-8-0-1);fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<ellipse
transform="scale(-1,1)"
ry="0.23623511"
rx="0.2952939"
cy="266.68161"
cx="-41.886944"
id="path1264-28-50-7-4"
style="display:inline;opacity:1;fill:#fdfcfa;fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="path1511-1-3-7"
d="m 42.097868,262.99387 c 0.139369,0.002 0.274489,0.008 0.407731,0.017 a 1.5119048,1.5119048 0 0 1 0.482658,1.10536 1.5119048,1.5119048 0 0 1 -1.512049,1.51154 1.5119048,1.5119048 0 0 1 -1.512051,-1.51154 1.5119048,1.5119048 0 0 1 0.295582,-0.89555 c 0.55177,-0.15202 1.168818,-0.23557 1.838129,-0.22686 z"
style="display:inline;opacity:1;fill:#3a3a3a;fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<ellipse
transform="scale(-1,1)"
ry="0.56696427"
rx="0.62602305"
cy="265.64215"
cx="-42.373638"
id="path1262-2-72-6-6"
style="display:inline;opacity:1;fill:#fdfcfa;fill-opacity:1;stroke:none;stroke-width:0.52916664;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="cssscsc"
inkscape:connector-curvature="0"
id="path2240"
d="m 15.902537,263.45766 c 0.801808,-8.55263 3.115981,-15.11768 9.354434,-16.23663 3.225965,-0.57861 4.142678,1.20272 8.485808,1.20272 4.34313,0 5.901544,-1.87533 8.686257,-1.33635 6.21402,1.20271 8.686263,5.21175 9.354436,16.77116 3.474503,-16.37026 -5.078121,-26.0027 -17.639789,-25.93589 -12.561669,0.0668 -19.777946,8.96428 -18.241146,25.53499 z"
style="display:inline;fill:#44341e;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="cssscsc"
inkscape:connector-curvature="0"
id="path2240-2"
d="m 15.707457,263.25721 c 0.801808,-8.55263 3.311061,-15.4464 9.549514,-16.56534 3.225965,-0.57862 4.142679,1.20271 8.485808,1.20271 4.34313,0 5.901544,-1.87532 8.68626,-1.33635 6.214017,1.20271 8.881343,5.20639 9.549513,16.76579 7.015827,-14.56619 -5.273198,-26.5265 -17.834869,-26.45968 -12.561669,0.0668 -25.3852335,8.88671 -18.436226,26.39287 z"
style="display:inline;fill:#644e2d;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="cscsc"
inkscape:connector-curvature="0"
id="path2242"
d="m 15.875,254.66665 c 1.058333,-4.23333 5.291668,-12.7 17.991667,-12.7 12.7,0 16.933333,8.46667 17.991667,12.7 0,0 -1.058334,-16.93333 -17.991667,-16.93333 -16.933334,0 -17.991667,16.93333 -17.991667,16.93333 z"
style="display:inline;fill:#7a3a34;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="ccc"
inkscape:connector-curvature="0"
id="path942-61-8-4-3"
d="m 47.688577,259.82417 c 0,-3.34403 -7.393509,-3.0027 -9.144444,-0.55734 3.470693,-0.70044 6.379868,-1.29018 9.144444,0.55734 z"
style="display:inline;fill:#644e2d;fill-opacity:1;stroke:none;stroke-width:0.19876628px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="cczc"
inkscape:connector-curvature="0"
id="path974-79-8-7"
d="m 40.540483,279.5375 c -2.851796,3.49426 -10.460727,3.45382 -13.34763,0 1.43011,1.05832 4.15433,1.45386 6.67381,1.45386 2.519491,0 5.243731,-0.39554 6.67382,-1.45386 z"
style="display:inline;opacity:1;fill:#b59c78;fill-opacity:1;stroke:none;stroke-width:0.5022487;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="czczc"
inkscape:connector-curvature="0"
id="path940-03-4-5"
d="m 31.61939,275.39867 c 0.56804,0.29243 1.058143,0.44175 2.248623,0.44175 1.19048,0 1.653382,-0.11811 2.259254,-0.38397 0.386199,0.91314 -1.068774,2.00218 -2.259254,2.00218 -1.19048,0 -2.645443,-1.08904 -2.248623,-2.05996 z"
style="display:inline;fill:#846a43;fill-opacity:1;stroke:none;stroke-width:0.25340664px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="cczc"
inkscape:connector-curvature="0"
id="path974-79-8-7-9"
d="m 40.540483,279.5375 c -3.317143,1.15807 -10.886053,1.33738 -13.347631,0 1.43011,1.05832 4.15433,1.52068 6.67381,1.52068 2.519489,0 5.243729,-0.46236 6.673821,-1.52068 z"
style="display:inline;opacity:1;fill:#a28153;fill-opacity:1;stroke:none;stroke-width:0.5022487;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
sodipodi:nodetypes="cscsc"
inkscape:connector-curvature="0"
id="path2242-1"
d="m 16.309673,253.07915 c 1.058333,-4.23333 4.856995,-11.64167 17.556994,-11.64167 12.7,0 16.49866,7.40834 17.556993,11.64167 0,0 -2.740326,-14.81667 -17.556993,-14.81667 -14.816666,0 -17.556994,14.81667 -17.556994,14.81667 z"
style="display:inline;fill:#bb685f;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
<g
id="g984"
transform="translate(0,6)">
<path
inkscape:connector-curvature="0"
id="path1992"
d="m 39.894707,50.552436 5.712629,-4.536499 8.400923,0.336037 5.376591,3.192351 1.176129,5.712628 -2.016221,4.536498 -3.024332,3.192352 -2.016222,1.344148 -1.008111,2.856313 1.176129,2.856314 -2.520277,3.192351 -5.040554,1.344148 -2.352258,-1.848204 0.168018,-2.352258 0.672074,-2.016221 -0.840092,-1.512167 0.672074,-5.208572 0.168018,-4.872535 -3.528388,1.176129 z"
- style="display:inline;fill:#f8931d;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:0.81778818px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ style="display:inline;fill:#faae55;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.81778818px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
id="text1953"
d="m 62.041897,53.219932 c -2.4e-5,1.504745 -0.316235,2.965858 -0.948634,4.383345 -0.04364,0.239895 -0.130868,0.567011 -0.261693,0.981345 -0.567021,1.810047 -1.711924,3.303872 -3.43471,4.48148 -0.54521,0.392544 -1.297575,0.774177 -2.257095,1.144903 -0.654247,0.261697 -1.068593,0.556101 -1.243038,0.883211 -1.6e-5,0.239889 -0.02182,0.5561 -0.06542,0.948634 -1.6e-5,0.13085 -0.05453,0.348926 -0.163558,0.654231 -0.109054,0.30531 -0.163572,0.501579 -0.163558,0.588807 -1.4e-5,0.04362 0.141735,0.272599 0.42525,0.686943 0.305292,0.414347 0.501561,0.719654 0.588808,0.915922 0.02179,0.06542 0.03269,0.294404 0.03271,0.686942 -1.6e-5,0.457961 -0.250804,1.199422 -0.752365,2.224384 -0.02182,0.174459 -0.07634,0.40344 -0.163557,0.686942 -0.348938,0.741458 -0.817803,1.37388 -1.406596,1.897269 -0.239898,0.239879 -0.817801,0.523378 -1.733711,0.850499 -1.373895,0.479763 -2.595124,0.719648 -3.663691,0.719654 -1.112199,-6e-6 -2.104448,-0.272602 -2.976749,-0.817788 -1.112196,-0.676044 -1.668292,-1.613773 -1.668288,-2.813191 -4e-6,-0.501579 0.119939,-1.046771 0.359827,-1.635577 0.196265,-0.457962 0.392534,-0.926827 0.588808,-1.406595 -0.174467,-0.08723 -0.414351,-0.261693 -0.719654,-0.523385 -0.152657,-0.196268 -0.228985,-0.795979 -0.228981,-1.799134 -4e-6,-1.766418 0.479765,-4.50328 1.439307,-8.210593 -0.109043,-0.08722 -0.18537,-0.130835 -0.22898,-0.130846 -0.04362,1.1e-5 -0.403447,0.207183 -1.079481,0.621519 -0.806887,0.479779 -1.38479,0.806893 -1.733711,0.981346 -0.218078,-0.174453 -0.348924,-0.33801 -0.392538,-0.490673 -0.348924,-1.635565 -0.915923,-4.06712 -1.700999,-7.294671 -0.04362,-0.174444 -0.152654,-0.490655 -0.327116,-0.948634 -0.196268,-0.457943 -0.294402,-0.719635 -0.294403,-0.785077 1e-6,-0.327096 0.588807,-1.046749 1.766422,-2.15896 1.046767,-0.937709 1.679189,-1.471997 1.897269,-1.602865 0.741457,-0.414324 1.493821,-0.817765 2.257095,-1.210327 1.003147,-0.545168 1.7228,-0.861378 2.158961,-0.948634 0.479761,-0.196245 1.221222,-0.436129 2.224384,-0.719654 1.482911,-0.21805 2.61691,-0.327089 3.401998,-0.327115 1.37387,2.6e-5 2.507869,0.04364 3.401999,0.130846 0.348906,0.130872 0.87229,0.305333 1.570153,0.523385 1.635557,0.436178 2.911305,1.341196 3.827249,2.715056 0.501554,0.785098 0.9159,1.75554 1.243038,2.911326 0.283477,1.003172 0.425226,2.071748 0.42525,3.20573 m -2.976749,1.308461 c -2e-5,-0.915907 -0.01092,-1.428387 -0.03271,-1.537442 -0.85052,-3.620055 -3.827265,-5.430091 -8.930247,-5.430113 -1.177626,2.2e-5 -2.5297,0.283521 -4.05623,0.8505 -0.152661,2.1e-5 -0.348929,0.02183 -0.588807,0.06542 -1.679197,0.763289 -2.889522,1.59198 -3.63098,2.486076 -0.283502,0.327133 -0.425253,0.63244 -0.425249,0.915922 -4e-6,0.588825 0.20717,1.984515 0.621519,4.187076 0.0218,0.152667 0.15265,0.327128 0.392538,0.523384 2.595108,-1.4611 4.350625,-2.191657 5.266556,-2.191672 0.981336,1.5e-5 1.777315,0.250803 2.387941,0.752365 0.63241,0.50159 0.948622,1.232148 0.948634,2.191672 -1.2e-5,0.109051 -0.109051,0.338031 -0.327115,0.686942 -0.196281,0.348934 -0.338031,0.5343 -0.42525,0.556096 -0.174473,0.08724 -0.425261,0.185377 -0.752365,0.294404 -0.109049,1.1e-5 -0.534298,1.1e-5 -1.275749,0 -0.08724,1.1e-5 -0.479779,-0.01089 -1.177615,-0.03271 -0.676046,-0.0436 -1.057681,-0.06541 -1.144904,-0.06542 -0.261699,1e-5 -0.457968,0.501587 -0.588807,1.50473 -0.109046,0.676046 -0.239891,1.591968 -0.392539,2.747768 -0.109044,0.174468 -0.163564,0.283506 -0.163557,0.327115 v 2.649634 c -7e-6,0.152657 0.04361,0.327118 0.130846,0.523384 0.13084,0.283503 0.283493,0.425253 0.457961,0.42525 0.06542,3e-6 0.78507,-0.152651 2.158961,-0.457961 0.04361,3e-6 0.719644,-0.08723 2.028115,-0.261692 0.872295,-0.109035 1.439295,-0.272593 1.700999,-0.490673 0.08722,-0.632419 0.20716,-1.548341 0.359827,-2.747769 0.08722,-0.08722 0.57789,-0.185359 1.472019,-0.294403 1.090368,-0.152647 2.191655,-0.752358 3.303864,-1.799134 1.112173,-1.046759 1.864537,-2.148047 2.257095,-3.303864 0.28348,-0.82868 0.42523,-1.85364 0.42525,-3.074884 m -7.00027,15.145436 c -1.4e-5,-0.436154 -0.207186,-0.817787 -0.621519,-1.144904 -0.39255,-0.348921 -0.828704,-0.523382 -1.308461,-0.523384 -0.894125,2e-6 -1.973605,0.305309 -3.238441,0.915923 -1.548353,0.763268 -2.322524,1.657382 -2.322518,2.682345 -6e-6,0.370728 0.07632,0.599709 0.22898,0.686942 0.436147,0.283497 0.915916,0.479766 1.439308,0.588808 0.414338,0.06542 0.785068,0.09813 1.112191,0.09813 0.654221,-3e-6 1.439297,-0.09814 2.35523,-0.294404 0.588796,-0.130849 1.133988,-0.567002 1.635577,-1.308461 0.479755,-0.654232 0.719639,-1.221231 0.719653,-1.700999"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;line-height:100%;font-family:'Indigo Joker';text-align:start;writing-mode:lr-tb;text-anchor:start;display:inline;fill:#4b4136;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
</g>
</g>
</svg>
diff --git a/src/activities/family_find_relative/ActivityInfo.qml b/src/activities/family_find_relative/ActivityInfo.qml
index 328a58cba..2e73c4217 100644
--- a/src/activities/family_find_relative/ActivityInfo.qml
+++ b/src/activities/family_find_relative/ActivityInfo.qml
@@ -1,42 +1,42 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2017 Rudra Nil Basu <rudra.nil.basu.1996@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "family_find_relative/Family_find_relative.qml"
difficulty: 2
icon: "family_find_relative/family_find_relative.svg"
author: "Rudra Nil Basu &lt;rudra.nil.basu.1996@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Point the relatives")
//: Help title
description: "Click on a pair corresponding to the given relation"
//intro: "Click on a pair that defines the given relation"
//: Help goal
goal: qsTr("Learn the relationships in a family, according to the lineal system used in most Western societies")
//: Help prerequisite
prerequisite: qsTr("Reading, moving and clicking with the mouse")
//: Help manual
manual: qsTr("A family tree is shown, with some instructions.\n" +
"The circles are linked with lines to mark the relations. Married couples are marked with a ring on the link.\n" +
"Click on a pair of family members which corresponds to the given relation.")
credit: ""
section: "discovery"
createdInVersion: 9000
}
diff --git a/src/activities/family_find_relative/Family_find_relative.qml b/src/activities/family_find_relative/Family_find_relative.qml
index 5c904dab2..e62f47235 100644
--- a/src/activities/family_find_relative/Family_find_relative.qml
+++ b/src/activities/family_find_relative/Family_find_relative.qml
@@ -1,30 +1,30 @@
/* GCompris - family_find_relative.qml
*
* Copyright (C) 2017 RUDRA NIL BASU <rudra.nil.basu.1996@gmail.com>
*
* Authors:
* RUDRA NIL BASU <rudra.nil.basu.1996@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
import "../family"
Family {
id: activity
property string mode: "find_relative"
}
diff --git a/src/activities/fifteen/ActivityInfo.qml b/src/activities/fifteen/ActivityInfo.qml
index f19ada75e..48c37daee 100644
--- a/src/activities/fifteen/ActivityInfo.qml
+++ b/src/activities/fifteen/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "fifteen/Fifteen.qml"
difficulty: 5
icon: "fifteen/fifteen.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
//: Activity title
title: qsTr("The fifteen game")
//: Help title
description: qsTr("Move each item to recreate the image.")
//intro: "Click or drag an element next to a free space, the element will move and release its space. You must put all the pieces in the correct order. The numbers on the pieces can help you."
//: Help goal
goal: ""
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("Click or drag on any pieces that has a free block beside it, and it will be swapped with the empty one.")
credit: ""
section: "puzzle"
createdInVersion: 0
}
diff --git a/src/activities/fifteen/Fifteen.qml b/src/activities/fifteen/Fifteen.qml
index f4b83d472..715c2bd31 100644
--- a/src/activities/fifteen/Fifteen.qml
+++ b/src/activities/fifteen/Fifteen.qml
@@ -1,187 +1,190 @@
/* GCompris - fifteen.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import QtGraphicalEffects 1.0
import "../../core"
import "fifteen.js" as Activity
ActivityBase {
id: activity
onStart: focus = true
onStop: {}
pageComponent: Image {
id: background
anchors.fill: parent
source: Activity.url + "background.svg"
sourceSize.width: Math.max(parent.width, parent.height)
fillMode: Image.PreserveAspectCrop
signal start
signal stop
Keys.onPressed: Activity.processPressedKey(event)
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property GCSfx audioEffects: activity.audioEffects
property alias background: background
property alias bar: bar
property alias bonus: bonus
property alias model: fifteenModel
property string scene: bar.level < 5 ? Activity.url + "Fishing_Boat_Scene.svg" :
Activity.url + "Coastal_Path.svg"
}
onStart: { Activity.start(items) }
onStop: { Activity.stop() }
+
+ property int pieceSize: Math.round(blueFrame.width * 0.222)
Image {
+ id: blueFrame
source: Activity.url + "blueframe.svg"
- sourceSize.width: Math.min(background.width * 0.9,
- background.height * 0.9)
+ sourceSize.width: Math.min(background.width,
+ background.height - bar.height) * 0.95
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
+ anchors.verticalCenterOffset: -bar.height * 0.55
}
Grid {
id: puzzleArea
- anchors.horizontalCenter: parent.horizontalCenter
- anchors.verticalCenter: parent.verticalCenter
+ anchors.horizontalCenter: blueFrame.horizontalCenter
+ anchors.verticalCenter: blueFrame.verticalCenter
columns: 4
spacing: 0
property alias trans: trans
ListModel {
id: fifteenModel
}
move: Transition {
id: trans
NumberAnimation {
properties: "x, y"
easing.type: Easing.InOutQuad
}
}
Repeater {
id: repeater
model: fifteenModel
delegate: Item {
- width: Math.min(background.width * 0.2,
- background.height * 0.2)
- height: width
+ width: pieceSize
+ height: pieceSize
clip: true
property int val: value
Image {
id: image
source: value ? items.scene : ""
- sourceSize.width: parent.width * 4
+ sourceSize.width: pieceSize * 4
fillMode: Image.Pad
transform: Translate {
- x: - image.width / 4 * ((value - 1) % 4)
- y: - image.width / 4 * Math.floor((value - 1) / 4)
+ x: - pieceSize * ((value - 1) % 4)
+ y: - pieceSize * Math.floor((value - 1) / 4)
}
}
GCText {
id: text
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
text: value && bar.level % 2 == 1 ? value : ""
fontSize: mediumSize
color: "#ffe9f0fb"
style: Text.Outline
styleColor: "#ff1c4788"
}
DropShadow {
anchors.fill: text
cached: false
horizontalOffset: 3
verticalOffset: 3
radius: 1
samples: 16
color: "#ff1c4788"
source: text
}
}
}
}
MultiPointTouchArea {
x: puzzleArea.x
y: puzzleArea.y
width: puzzleArea.width
height: puzzleArea.height
onPressed: checkTouchPoint(touchPoints)
function checkTouchPoint(touchPoints) {
for(var i in touchPoints) {
var touch = touchPoints[i]
var block = puzzleArea.childAt(touch.x, touch.y)
if(!puzzleArea.trans.running && block) {
Activity.onClick(block.val)
if(Activity.checkAnswer())
bonus.good('flower')
else
activity.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/flip.wav")
}
}
}
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level }
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
}
Bonus {
id: bonus
Component.onCompleted: win.connect(Activity.nextLevel)
}
}
}
diff --git a/src/activities/fifteen/fifteen.js b/src/activities/fifteen/fifteen.js
index ae1b6f5c3..bbbc6c629 100644
--- a/src/activities/fifteen/fifteen.js
+++ b/src/activities/fifteen/fifteen.js
@@ -1,219 +1,219 @@
/* GCompris - fifteen.js
*
* Copyright (C) 2014 Bruno Coudoin
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
.import "qrc:/gcompris/src/core/core.js" as Core
var url = "qrc:/gcompris/src/activities/fifteen/resource/"
var currentLevel = 0
var numberOfLevel = 13
var items
var palette = [
"#D40000",
"#FF0000",
"#FF5555",
"#FFAAAA",
"#FFD5D5",
"#FF6600",
"#FFB380",
"#D4AA00",
"#FFCC00",
"#FFE680",
"#88AA00",
"#AAD400",
"#CCFF00",
"#66FF00",
"#7FFF2A",
"#55FFDD"
]
function start(items_) {
items = items_
currentLevel = 0
initLevel()
}
function stop() {
}
function initLevel() {
items.bar.level = currentLevel + 1
// Create the initial array that holds the model data sorted
var model = []
for(var i = 1; i < 16; i++)
model.push(i)
model.push(0)
scramble(model, [3, 3], (currentLevel + 2))
items.model.clear()
for(i = 0; i < 16; i++)
items.model.append(
{"value": model[i],
"fcolor": palette[model[i]]}
)
}
function countBadPlaced(model) {
var badPlaced = 0
for(var i = 0; i < 15; i++) {
if(model[i] !== i + 1)
badPlaced++
}
return badPlaced
}
function swap(model, spot1, spot2) {
var old = model[spot1[0] + spot1[1] * 4]
model[spot1[0] + spot1[1] * 4] = model[spot2[0] + spot2[1] * 4]
model[spot2[0] + spot2[1] * 4] = old
}
function getRandomMove(model, emptySpot) {
var possibleMoves = []
if(emptySpot[0] > 0)
possibleMoves.push([emptySpot[0] - 1, emptySpot[1]])
if(emptySpot[0] < 3)
possibleMoves.push([emptySpot[0] + 1, emptySpot[1]])
if(emptySpot[1] > 0)
possibleMoves.push([emptySpot[0], emptySpot[1] - 1])
if(emptySpot[1] < 3)
possibleMoves.push([emptySpot[0], emptySpot[1] + 1])
return Core.shuffle(possibleMoves)[0]
}
function scrambleOne(model, emptySpot) {
var nextSpot = getRandomMove(model, emptySpot)
swap(model, emptySpot, nextSpot)
return nextSpot
}
// We loop until the scramble created the requested
// numberOfExpectedBadPlaced items
function scramble(model, emptySpot, numberOfExpectedBadPlaced) {
do {
emptySpot = scrambleOne(model, emptySpot)
} while(countBadPlaced(model) < numberOfExpectedBadPlaced)
}
function checkAnswer() {
for(var i = 0; i < 15; i++)
if(items.model.get(i).value !== i + 1) {
return false
}
return true
}
function onClick(value) {
// Find the value in the model
var done = false
for(var x = 0; x < 4 && !done; x++)
for(var y = 0; y < 4 && !done; y++)
if(items.model.get(x + y * 4).value === value) {
// Find a free spot
if(x > 0 && items.model.get((x - 1) + y * 4).value === 0) {
items.model.move(x + y * 4, (x - 1) + y * 4, 1)
done = true
} else if(x < 3 && items.model.get((x + 1) + y * 4).value === 0) {
items.model.move(x + y * 4, (x + 1) + y * 4, 1)
done = true
} else if(y > 0 && items.model.get(x + (y - 1) * 4).value === 0) {
items.model.move(x + y * 4, x + (y - 1) * 4, 1)
items.model.move(x + 1 + (y - 1) * 4, x + y * 4, 1)
done = true
} else if(y < 3 && items.model.get(x + (y + 1) * 4).value === 0) {
items.model.move(x + (y + 1) * 4, x + y * 4, 1)
items.model.move(x + 1 + y * 4, x + (y + 1) * 4, 1)
done = true
}
}
}
// Return the index in the model of the empty spot
function getEmptySpot()
{
for(var i=0; i < items.model.count; i++) {
if(items.model.get(i).value === 0)
return i
}
}
function processPressedKey(event) {
var emptySpot = getEmptySpot()
/* Move the player */
switch (event.key) {
case Qt.Key_Right:
if(emptySpot % 4 != 0) {
items.model.move(emptySpot - 1, emptySpot, 1)
event.accepted = true
}
break
case Qt.Key_Left:
if(emptySpot % 4 != 3) {
items.model.move(emptySpot + 1, emptySpot, 1)
event.accepted = true
}
break
case Qt.Key_Up:
if(emptySpot < items.model.count - 4) {
items.model.move(emptySpot + 4, emptySpot, 1)
items.model.move(emptySpot + 1, emptySpot + 4, 1)
event.accepted = true
}
break
case Qt.Key_Down:
if(emptySpot >= 4) {
items.model.move(emptySpot, emptySpot - 4, 1)
items.model.move(emptySpot - 3, emptySpot, 1)
event.accepted = true
}
break
}
/* Check if success */
if(checkAnswer())
items.bonus.good('flower')
else if(event.accepted)
items.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/flip.wav")
}
function nextLevel() {
if(numberOfLevel <= ++currentLevel ) {
currentLevel = 0
}
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
initLevel();
}
diff --git a/src/activities/find_the_day/ActivityInfo.qml b/src/activities/find_the_day/ActivityInfo.qml
index fc5597f95..5f1ae1e07 100644
--- a/src/activities/find_the_day/ActivityInfo.qml
+++ b/src/activities/find_the_day/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2018 Amit Sagtani <asagtani06@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "find_the_day/FindTheDay.qml"
difficulty: 6
icon: "find_the_day/find_the_day.svg"
author: "Amit Sagtani &lt;asagtani06@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Find the day")
//: Help title
description: qsTr("Find the correct date and select it on the calendar.")
//intro: "Select the required day."
//: Help goal
goal: qsTr("Learn how to count days and find a date on a calendar.")
//: Help prerequisite
prerequisite: qsTr("Basics of calendar")
//: Help manual
manual: qsTr("Read the instructions and perform the requested calculation to find a date. Then select this date on the calendar.")
credit: ""
section: "discovery"
createdInVersion: 9000
}
diff --git a/src/activities/find_the_day/FindTheDay.qml b/src/activities/find_the_day/FindTheDay.qml
index 62f0bb3c6..b0e3a526b 100644
--- a/src/activities/find_the_day/FindTheDay.qml
+++ b/src/activities/find_the_day/FindTheDay.qml
@@ -1,29 +1,29 @@
/* GCompris - find_the_day.qml
*
* Copyright (C) 2018 Amit Sagtani <asagtani06@gmail.com>
*
* Authors:
* Amit Sagtani <asagtani06@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../calendar"
import "find_the_day_dataset.js" as Dataset
Calendar {
dataset: Dataset
}
diff --git a/src/activities/find_the_day/find_the_day_dataset.js b/src/activities/find_the_day/find_the_day_dataset.js
index f9fcd6899..439f36164 100644
--- a/src/activities/find_the_day/find_the_day_dataset.js
+++ b/src/activities/find_the_day/find_the_day_dataset.js
@@ -1,216 +1,216 @@
/* GCompris - find_the_day_dataset.js
*
* Copyright (C) 2018 Amit Sagtani <asagtani06@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
// Contains the questions, answers and calendar configurations of every level.
// Add more levels by inserting questions and answers below.
// Days of weeks are indexed from 0 i.e (Sunday = 0, Monday = 1, Tuesday = 2, .... ..... .... , Saturday = 6)
// Months of year are indexed from 0 i.e (January = 0, February = 1, March = 2, .... ..... ...., December = 11)
//MODES
// findMonthOnly --> For questions based on finding month only.
// findYearMonthDay --> For questions based on finding year, month and day.
// findDayOfWeek --> For questions based on finding day of week only.
// findDay --> For questions based on finding day of a given month and year.
function get() {
return [
[ // Level 1
[ // Level 1 Configurations
{
"navigationBarVisible" : true,
"minimumDate": "2018-01-01",
"maximumDate": "2018-12-31",
"visibleMonth": 7,
"visibleYear": 2018,
"mode": "findYearMonthDay"
}
],
[ // Level 1 Questions
{
- "question": qsTr("Find the date 13 days after 3 May."),
+ "question": qsTr("Find the date 13 days after May 3."),
"answer": {"year": 2018, "month": 4, "day": 16}
},
{
- "question": qsTr("Find the date 7 days after 1 October."),
+ "question": qsTr("Find the date 7 days after October 1."),
"answer": {"year": 2018, "month": 9, "day": 8}
},
{
- "question": qsTr("Find the date 31 days after 12 July."),
+ "question": qsTr("Find the date 31 days after July 12."),
"answer": {"year": 2018, "month": 7, "day": 12}
},
{
- "question": qsTr("Find the date two weeks after 27 November."),
+ "question": qsTr("Find the date two weeks after November 27."),
"answer": {"year": 2018, "month": 11, "day": 11}
},
{
- "question": qsTr("Find the date 19 days before 1 September."),
+ "question": qsTr("Find the date 19 days before September 1."),
"answer": {"year": 2018, "month": 7, "day": 13}
},
{
- "question": qsTr("Find the date 5 days before 8 December."),
+ "question": qsTr("Find the date 5 days before December 8."),
"answer": {"year": 2018, "month": 11, "day": 3}
}
]
],
[ // Level 2
[ // Level 2 Configurations
{
"navigationBarVisible" : true,
"minimumDate": "2018-01-01",
"maximumDate": "2018-12-31",
"visibleMonth": 7,
"visibleYear": 2018,
"mode": "findDayOfWeek"
}
],
[ // Level 2 Questions
{
- "question": qsTr("Find day of week 3 days after 5 December."),
+ "question": qsTr("Find day of week 3 days after December 5."),
"answer": {"dayOfWeek": 6}
},
{
- "question": qsTr("Find day of week 12 days before 12 November."),
+ "question": qsTr("Find day of week 12 days before November 12."),
"answer": {"dayOfWeek": 3}
},
{
- "question": qsTr("Find day of week 32 days after 5 January."),
+ "question": qsTr("Find day of week 32 days after January 5."),
"answer": {"dayOfWeek": 2}
},
{
- "question": qsTr("Find day of week 5 days after 23 February."),
+ "question": qsTr("Find day of week 5 days after February 23."),
"answer": {"dayOfWeek": 3}
},
{
- "question": qsTr("Find day of week 17 days before 16 August."),
+ "question": qsTr("Find day of week 17 days before August 16."),
"answer": {"dayOfWeek": 1}
}
]
],
[ // Level 3
[ // Level 3 configurations
{
"navigationBarVisible": true,
"minimumDate": "2018-01-01",
"maximumDate": "2018-12-31",
"visibleMonth": 7,
"visibleYear": 2018,
"mode": "findYearMonthDay"
}
],
[ // Level 3 Questions
{
- "question": qsTr("Find the date 2 weeks and 3 days after 12 January."),
+ "question": qsTr("Find the date 2 weeks and 3 days after January 12."),
"answer": {"year": 2018, "month": 0, "day": 29}
},
{
- "question": qsTr("Find the date 3 weeks and 2 days after 22 March."),
+ "question": qsTr("Find the date 3 weeks and 2 days after March 22."),
"answer": {"year": 2018, "month": 3, "day": 14}
},
{
- "question": qsTr("Find the date 5 weeks and 6 days after 5 October."),
+ "question": qsTr("Find the date 5 weeks and 6 days after October 5."),
"answer": {"year": 2018, "month": 10, "day": 15}
},
{
- "question": qsTr("Find the date 1 week and 1 day before 8 August."),
+ "question": qsTr("Find the date 1 week and 1 day before August 8."),
"answer": {"year": 2018, "month": 6, "day": 31}
},
{
- "question": qsTr("Find the date 2 weeks and 5 days before 2 July."),
+ "question": qsTr("Find the date 2 weeks and 5 days before July 2."),
"answer": {"year": 2018, "month": 5, "day": 13}
}
]
],
[ // level 4
[ // Level 4 Configurations
{
"navigationBarVisible" : true,
"minimumDate": "2018-01-01",
"maximumDate": "2018-12-31",
"visibleMonth": 7,
"visibleYear": 2018,
"mode": "findDayOfWeek"
}
],
[ // Level 4 Questions
{
- "question": qsTr("Find day of week 5 months and 2 days after 3 July."),
+ "question": qsTr("Find day of week 5 months and 2 days after July 3."),
"answer": {"dayOfWeek": 3}
},
{
- "question": qsTr("Find day of week 2 months and 4 days after 8 October."),
+ "question": qsTr("Find day of week 2 months and 4 days after October 8."),
"answer": {"dayOfWeek": 3}
},
{
- "question": qsTr("Find day of week 1 month and 3 days before 28 December."),
+ "question": qsTr("Find day of week 1 month and 3 days before December 28."),
"answer": {"dayOfWeek": 0}
},
{
- "question": qsTr("Find day of week 8 months and 7 days after 28 February."),
+ "question": qsTr("Find day of week 8 months and 7 days after February 28."),
"answer": {"dayOfWeek": 0}
},
{
- "question": qsTr("Find day of week 3 months and 3 days before 15 September."),
+ "question": qsTr("Find day of week 3 months and 3 days before September 15."),
"answer": {"dayOfWeek": 2}
}
]
],
[ // level 5
[ // Level 5 Configurations
{
"navigationBarVisible" : true,
"minimumDate": "2018-01-01",
"maximumDate": "2018-12-31",
"visibleMonth": 7,
"visibleYear": 2018,
"mode": "findYearMonthDay"
}
],
[ // Level 5 Questions
{
- "question": qsTr("Find the date 2 months, 1 week and 5 days after 12 January."),
+ "question": qsTr("Find the date 2 months, 1 week and 5 days after January 12."),
"answer": {"year": 2018, "month": 2, "day": 24}
},
{
- "question": qsTr("Find the date 3 months, 2 weeks and 1 day after 23 August."),
+ "question": qsTr("Find the date 3 months, 2 weeks and 1 day after August 23."),
"answer": {"year": 2018, "month": 11, "day": 8}
},
{
- "question": qsTr("Find the date 5 months, 3 weeks and 2 days after 20 March."),
+ "question": qsTr("Find the date 5 months, 3 weeks and 2 days after March 20."),
"answer": {"year": 2018, "month": 8, "day": 12}
},
{
- "question": qsTr("Find the date 1 month 1 week and 1 day before 10 September."),
+ "question": qsTr("Find the date 1 month 1 week and 1 day before September 10."),
"answer": {"year": 2018, "month": 7, "day": 2}
},
{
- "question": qsTr("Find the date 2 months, 1 week and 8 days before 7 April."),
+ "question": qsTr("Find the date 2 months, 1 week and 8 days before April 7."),
"answer": {"year": 2018, "month": 0, "day": 23}
}
]
]
]
}
diff --git a/src/activities/followline/ActivityInfo.qml b/src/activities/followline/ActivityInfo.qml
index a6f59e3b5..e558be6da 100644
--- a/src/activities/followline/ActivityInfo.qml
+++ b/src/activities/followline/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "followline/Followline.qml"
difficulty: 1
icon: "followline/followline.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
//: Activity title
title: qsTr("Control the hose-pipe")
//: Help title
description: qsTr("The fireman needs to stop the fire, but the hose is blocked.")
// intro: " Move the mouse or your finger along the pipe to stop the fire."
//: Help goal
goal: qsTr("Fine motor coordination")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("Move the mouse or your finger over the lock which is represented as a red part in the hose-pipe. This will move it, bringing it, part by part, up to the fire. Be careful, if you move off the hose, the lock will go backward.")
credit: ""
section: "computer mouse"
createdInVersion: 0
}
diff --git a/src/activities/followline/Followline.qml b/src/activities/followline/Followline.qml
index c4b44a9b8..665f91937 100644
--- a/src/activities/followline/Followline.qml
+++ b/src/activities/followline/Followline.qml
@@ -1,173 +1,173 @@
/* GCompris - FollowLine.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "followline.js" as Activity
ActivityBase {
id: activity
onStart: focus = true
onStop: {}
pageComponent: Image {
id: background
source: Activity.url + "background.svg"
fillMode: Image.PreserveAspectCrop
sourceSize.width: Math.max(parent.width, parent.height)
signal start
signal stop
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property alias background: background
property GCSfx audioEffects: activity.audioEffects
property alias fireman: fireman
property alias fire: fire
property alias bar: bar
property alias bonus: bonus
property int currentLock: 0
property int lastLock: 0
}
onHeightChanged: Activity.initLevel()
onStart: { Activity.start(items) }
onStop: { Activity.stop() }
Image {
id: fireman
source: Activity.url + "fireman.svg"
sourceSize.width: 182 * ApplicationInfo.ratio
anchors {
left: parent.left
verticalCenter: parent.verticalCenter
verticalCenterOffset: - height / 10
}
}
Image {
id: fire
source: Activity.url + "fire.svg"
sourceSize.width: 90 * ApplicationInfo.ratio
anchors {
right: parent.right
bottom: bar.top
}
Image {
id: fireflame
source: Activity.url + "fire_flame.svg"
sourceSize.width: 90 * ApplicationInfo.ratio
anchors {
fill: parent
}
Behavior on opacity { NumberAnimation { duration: 2000 } }
onOpacityChanged: if(opacity == 0) Activity.nextLevel()
}
}
Image {
id: water
source: Activity.url + "water_spot.svg"
sourceSize.width: 148 * ApplicationInfo.ratio
z: 200
opacity: 0
anchors {
right: parent.right
bottom: fire.top
bottomMargin: - fire.height / 2
}
Behavior on opacity { NumberAnimation { duration: 500 } }
}
DialogHelp {
id: dialogHelp
onClose: home()
}
function win() {
fireflame.opacity = 0
water.opacity = 1
}
MultiPointTouchArea {
anchors.fill: parent
maximumTouchPoints: 1
z: 1000
onTouchUpdated: {
for(var i in touchPoints) {
var touch = touchPoints[i]
var part = background.childAt(touch.x, touch.y)
if(part) {
if(items.currentLock == part.index) {
items.currentLock++
if(items.currentLock == items.lastLock) {
background.win()
activity.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/water.wav")
} else {
activity.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/darken.wav")
}
}
}
}
}
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level }
onHelpClicked: displayDialog(dialogHelp)
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
onLevelChanged: {
fireflame.opacity = 1
water.opacity = 0
}
}
Bonus {
id: bonus
Component.onCompleted: win.connect(Activity.nextLevel)
}
MouseArea {
anchors.fill: parent
enabled: !ApplicationInfo.isMobile
hoverEnabled: true
onPositionChanged: items.currentLock > 0 && fireflame.opacity == 1 ?
items.currentLock-- : false
}
}
}
diff --git a/src/activities/followline/LinePart.qml b/src/activities/followline/LinePart.qml
index d57014a0b..9f143d640 100644
--- a/src/activities/followline/LinePart.qml
+++ b/src/activities/followline/LinePart.qml
@@ -1,83 +1,83 @@
/* GCompris - LinePart.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
Item {
id: part
property QtObject items
property int index
property GCSfx audioEffects
Rectangle {
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenterOffset: - parent.height / 2
width: parent.width
height: parent.height * 0.2
radius: height / 8
color: "#30354e"
z: 10
}
Rectangle {
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenterOffset: - parent.width * 0.1
anchors.verticalCenterOffset: 0
width: parent.width * 1.2
height: parent.height * 0.9
radius: height / 4
z: 5
color: index < part.items.currentLock
? "#3ca7e0"
: index === part.items.currentLock
? "#dd3128"
: "#7A7F8E"
MouseArea {
anchors.fill: parent
hoverEnabled: true
onEntered: {
if(part.items.currentLock == part.index) {
part.items.currentLock++
if(part.items.currentLock >= part.items.lastLock) {
audioEffects.play("qrc:/gcompris/src/core/resource/sounds/water.wav")
items.background.win()
} else {
audioEffects.play("qrc:/gcompris/src/core/resource/sounds/darken.wav")
}
}
}
}
}
Rectangle {
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
anchors.verticalCenterOffset: parent.height / 2
width: parent.width
height: parent.height * 0.2
radius: height / 8
color: "#30354e"
z: 10
}
}
diff --git a/src/activities/followline/followline.js b/src/activities/followline/followline.js
index f3a7d8c9b..c099f79db 100644
--- a/src/activities/followline/followline.js
+++ b/src/activities/followline/followline.js
@@ -1,138 +1,138 @@
/* GCompris - followline.js
*
* Copyright (C) 2014 Bruno Coudoin
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
.import GCompris 1.0 as GCompris
var url = "qrc:/gcompris/src/activities/followline/resource/"
var currentLevel = 0
var numberOfLevel = 8
var items
var createdLineParts
function start(items_) {
items = items_
currentLevel = 0
initLevel()
}
function stop() {
destroyLineParts()
}
function initLevel() {
/* Check items.bar because when starting followline at least twice,
it is undefined (called by FollowLine.qml:onHeightChanged())
*/
if(!items || !items.bar)
return
items.bar.level = currentLevel + 1
items.currentLock = 0
destroyLineParts()
createdLineParts = new Array()
var width = 40 * GCompris.ApplicationInfo.ratio
var height = 60 * GCompris.ApplicationInfo.ratio
var index = 0
var y = items.fireman.y
var x = items.fireman.x + items.fireman.width
var angle = 0
var directionStep = 0.01 * (currentLevel + 1)
var direction = directionStep
do {
var newy = y + Math.sin(angle) * width * 0.5
var newx = x + Math.cos(angle) * width * 0.5
angle += direction
if(angle > Math.PI / 4)
direction = - directionStep
else if(angle < - Math.PI / 4)
direction = directionStep
if(y > items.fire.y-items.fire.height/2)
direction = - directionStep
else if(y < items.background.height * 0.3)
direction = directionStep
createdLineParts[index] =
createLinePart(index, x, y, width, height,
getAngleOfLineBetweenTwoPoints(x, y, newx, newy) * (180 / Math.PI))
x = newx
y = newy
index++
} while(x < (items.fire.x - 10))
items.lastLock = index - 1
}
function nextLevel() {
if(numberOfLevel <= ++currentLevel) {
currentLevel = 0
}
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
initLevel();
}
function createLinePart(index, x, y, width, height, rotation) {
var component = Qt.createComponent("qrc:/gcompris/src/activities/followline/LinePart.qml");
var part = component.createObject(
items.background,
{
"audioEffects": items.audioEffects,
"x": x,
"y": y,
"width": width,
"height": height,
"rotation": rotation,
"z": index,
"items": items,
"index": index
});
if (part === null) {
// Error Handling
console.log("Error creating LinePart object");
}
return part;
}
// Determines the angle of a straight line drawn between point one and two.
// The number returned, which is a float in radian,
// tells us how much we have to rotate a horizontal line clockwise
// for it to match the line between the two points.
function getAngleOfLineBetweenTwoPoints(x1, y1, x2, y2) {
var xDiff = x2 - x1;
var yDiff = y2 - y1;
return Math.atan2(yDiff, xDiff);
}
function destroyLineParts() {
if (createdLineParts) {
for(var i = 0; i < createdLineParts.length; ++i) {
createdLineParts[i].destroy()
}
createdLineParts.length = 0
}
}
diff --git a/src/activities/football/ActivityInfo.qml b/src/activities/football/ActivityInfo.qml
index 80fc24bde..b3e9c8c2d 100644
--- a/src/activities/football/ActivityInfo.qml
+++ b/src/activities/football/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "football/Football.qml"
difficulty: 1
icon: "football/football.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
//: Activity title
title: qsTr("The football game")
//: Help title
description: qsTr("Kick the ball into the goal")
// intro: "Drag a line from the ball to set the speed and direction of your kick."
//: Help goal
goal: qsTr("Kick the ball behind the goal keeper on the right")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("Drag a line from the ball, to set its speed and direction.")
credit: ""
section: "fun"
createdInVersion: 0
}
diff --git a/src/activities/football/Football.qml b/src/activities/football/Football.qml
index 436ea5b12..e5aaf1a4a 100644
--- a/src/activities/football/Football.qml
+++ b/src/activities/football/Football.qml
@@ -1,176 +1,176 @@
/* GCompris - football.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
* Bharath M S <brat.197@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
import "football.js" as Activity
import GCompris 1.0
ActivityBase {
id: activity
onStart: focus = true
onStop: {}
pageComponent: Rectangle {
id: background
anchors.fill: parent
signal start
signal stop
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property alias background: background
property alias field: field
property alias border: border
property alias ball: ball
property alias line: line
property alias tux: tux
property alias moveTux: moveTux
property alias moveUp: moveUp
property alias moveDown: moveDown
property alias bar: bar
property alias bonus: bonus
property alias timer: timer
property GCSfx audioEffects: activity.audioEffects
}
onStart: { Activity.start(items) }
onStop: { Activity.stop() }
/* To modify when screen size changes */
onHeightChanged: {
moveUp.to = 0
moveDown.to = background.height * 0.75 - tux.height
moveTux.restart()
}
Image {
id: field
source: Activity.url + "background.svg"
anchors.fill: parent
Rectangle {
id: border
height: parent.height * 0.75
width: parent.width * 0.856
x: parent.width * 0.075
y: parent.height * 0.125
color: "transparent"
Rectangle {
id: line
opacity: 0.0
color: "#ee4b4b"
transformOrigin: Item.TopLeft
}
Image {
id: ball
source: Activity.url + "ball.svg"
sourceSize.height: 50 * ApplicationInfo.ratio
property real change
z: 10
MultiPointTouchArea {
anchors.fill: parent
touchPoints: [ TouchPoint { id: point1 }]
onReleased: {
line.opacity = 0
Activity.startMotion(point1.x - ball.width / 2,
point1.y - ball.height / 2)
activity.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/brick.wav")
}
onPressed: line.opacity = 1
onTouchUpdated: {
var point = ball.mapToItem(border, point1.x, point1.y)
Activity.drawLine(point.x, point.y, ball.x + ball.width/2, ball.y + ball.height/2)
}
}
}
Image {
id: tux
source: Activity.url+"tux_top.svg"
sourceSize.height: 80 * ApplicationInfo.ratio
x: border.width - tux.width
y: border.height / 2
SequentialAnimation on y {
id: moveTux
loops: Animation.Infinite
running: true
PropertyAnimation {
id: moveUp
duration: 800
easing.type: Easing.InOutQuad
}
PropertyAnimation {
id: moveDown
duration: 800
easing.type: Easing.InOutQuad
}
}
}
}
Rectangle {
width: parent.width * 0.1
height: parent.height * 0.75
color: "blue"
anchors.top: border.top
anchors.left: border.right
- z:10
+ z: 10
opacity: 0.3
}
}
Timer {
id: timer
interval: 16;
running: false;
repeat: true
onTriggered: Activity.ballMotion()
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level }
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
}
Bonus {
id: bonus
Component.onCompleted: win.connect(Activity.nextLevel)
}
}
}
diff --git a/src/activities/football/football.js b/src/activities/football/football.js
index 3bbaed72f..4d01b2c35 100644
--- a/src/activities/football/football.js
+++ b/src/activities/football/football.js
@@ -1,173 +1,173 @@
/* GCompris - football.js
*
* Copyright (C) 2014 Bruno Coudoin
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
* Bharath M S <brat.197@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
.import GCompris 1.0 as GCompris
.import "qrc:/gcompris/src/core/core.js" as Core
var url = "qrc:/gcompris/src/activities/football/resource/"
var currentLevel = 0
var numberOfLevel = 8
var items
var flag = 0
var friction = 0.995
var velocityX
var velocityY
var tuxCollision
function start(items_) {
items = items_
currentLevel = 0
initLevel()
}
function stop() {
}
function initLevel() {
items.bar.level = currentLevel + 1
items.ball.x = items.border.width * 0.2
items.ball.y = items.border.height / 2 - items.ball.height / 2
velocityX = 0
velocityY = 0
tuxCollision = false
/* Increase size of TUX for each level */
items.tux.sourceSize.height = 10 * (5 + 2 * items.bar.level) * GCompris.ApplicationInfo.ratio
moveTux(items.background.height)
}
function nextLevel() {
if(numberOfLevel <= ++currentLevel ) {
currentLevel = 0
}
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
initLevel();
}
function startMotion(x1, y1) {
var velocity = Math.sqrt(Math.pow(x1, 2) +
Math.pow(y1, 2))
velocity = Math.min(10, velocity * 0.5)
/* Modify speed of ball here */
velocityX = velocity * x1 * 0.01 * -1 / 5
velocityY = velocity * y1 * 0.01 * -1 / 5
tuxCollision = false
items.timer.start()
}
-/* Calcualtes the angle between the two points */
+/* Calculates the angle between the two points */
function getAngle(sx1, sy1, sx2, sy2)
{
var dy, slope, angle;
var dx = sx2 - sx1;
if (dx === 0)
return 0;
dy = sy2 - sy1;
slope = dy / dx;
angle = Math.atan(slope) * 180 / Math.PI;
if (dy < 0 && dx < 0){
return angle;
}
else if (dy >= 0 && dx >= 0){
return angle + 180;
}
else if (dy < 0 && dx >= 0){
return angle + 180;
}
else if (dy >= 0 && dx < 0){
return angle;
}
else
return 0;
}
/* Draw a line dynamically to display the drag */
function drawLine(x1, y1, x2, y2){
items.line.height = 5
items.line.rotation = getAngle(x1, y1, x2, y2);
items.line.width = Math.sqrt(Math.pow((x1 - x2), 2) + Math.pow((y1- y2), 2));
items.line.x = x2
items.line.y = y2
}
/* Tux moves up and down, called in initlevel() */
function moveTux(height){
items.moveUp.to = 0
items.moveDown.to = items.background.height * 0.75 - items.tux.height
items.moveTux.restart()
}
function ballMotion() {
items.ball.x += velocityX
items.ball.y += velocityY
if(items.ball.y > (items.border.height - items.ball.height)) { //bottom
velocityY *= -1
items.ball.y = items.border.height - items.ball.height
tuxCollision = false
} else if(items.ball.x > (items.border.width)) { //right ---- GOAL!
velocityX *= 0
velocityY *= 0
items.ball.x = items.border.width// - items.ball.width
items.bonus.good("tux")
} else if(items.ball.x < 0) { // left
velocityX *= -1
items.ball.x = 0
tuxCollision = false
} else if(items.ball.y < 0) { //top
velocityY *= -1
items.ball.y = 0
tuxCollision = false
}
/* Collision with TUX */
else if(items.ball.y > items.tux.y &&
items.ball.y <= items.tux.y + items.tux.height/2 &&
items.ball.x > items.tux.x &&
items.ball.x <= items.tux.x + items.tux.width/2 &&
!tuxCollision) {
velocityY *= -2
velocityX *= -2
tuxCollision = true
items.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/brick.wav")
}
// Friction
velocityX *= friction
velocityY *= friction
// Ball stop
if(Math.abs(velocityX) < 0.2 && Math.abs(velocityY) < 0.2) {
velocityX = 0
velocityY = 0
items.timer.stop()
}
}
diff --git a/src/activities/geo-country/ActivityInfo.qml b/src/activities/geo-country/ActivityInfo.qml
index 0ad256819..fcfcbab6a 100644
--- a/src/activities/geo-country/ActivityInfo.qml
+++ b/src/activities/geo-country/ActivityInfo.qml
@@ -1,44 +1,44 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Pulkit Gupta <pulkitgenius@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "geo-country/GeoCountry.qml"
difficulty: 2
icon: "geo-country/geo-country.svg"
author: "Pulkit Gupta &lt;pulkitgenius@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Locate the region")
//: Help title
description: qsTr("Drag and Drop the regions to redraw the whole country")
// intro: "Drag and drop the regions to complete the country maps."
//: Help goal
goal: ""
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("Drag and drop different regions of the country to correct locations to redraw the whole country.")
credit: ""
section: "discovery"
createdInVersion: 4000
}
diff --git a/src/activities/geo-country/GeoCountry.qml b/src/activities/geo-country/GeoCountry.qml
index 01a73f943..94a91a3c0 100644
--- a/src/activities/geo-country/GeoCountry.qml
+++ b/src/activities/geo-country/GeoCountry.qml
@@ -1,35 +1,35 @@
/* GCompris - GeoCountry.qml
*
* Copyright (C) 2015 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Jean-Philippe Ayanides <jp.ayanides@free.fr> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../babymatch"
Babymatch {
id: activity
onStart: focus = true
onStop: {}
boardsUrl: "qrc:/gcompris/src/activities/geo-country/resource/"
levelCount: 16
answerGlow: false
}
diff --git a/src/activities/geo-country/resource/board/board10_0.qml b/src/activities/geo-country/resource/board/board10_0.qml
index 14c207d1a..bb1dda030 100644
--- a/src/activities/geo-country/resource/board/board10_0.qml
+++ b/src/activities/geo-country/resource/board/board10_0.qml
@@ -1,340 +1,340 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property int numberOfSubLevel: 1
property string instruction: qsTr("United States of America")
property var levels: [
{
"pixmapfile" : "usa/background.png",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "usa/washington.png",
"toolTipText" : "Washington",
"x" : "0.13",
"y" : "0.083"
},
{
"pixmapfile" : "usa/oregon.png",
"toolTipText" : "Oregon",
"x" : "0.11",
"y" : "0.199"
},
{
"pixmapfile" : "usa/idaho.png",
"toolTipText" : "Idaho",
"x" : "0.209",
"y" : "0.187"
},
{
"pixmapfile" : "usa/montana.png",
"toolTipText" : "Montana",
"x" : "0.293",
"y" : "0.147"
},
{
"pixmapfile" : "usa/north_dakota.png",
"toolTipText" : "North Dakota",
"x" : "0.436",
"y" : "0.156"
},
{
"pixmapfile" : "usa/south_dakota.png",
"toolTipText" : "South Dakota",
"x" : "0.435",
"y" : "0.273"
},
{
"pixmapfile" : "usa/nebraska.png",
"toolTipText" : "Nebraska",
"x" : "0.441",
"y" : "0.376"
},
{
"pixmapfile" : "usa/kansas.png",
"toolTipText" : "Kansas",
"x" : "0.463",
"y" : "0.49"
},
{
"pixmapfile" : "usa/colorado.png",
"toolTipText" : "Colorado",
"x" : "0.336",
"y" : "0.458"
},
{
"pixmapfile" : "usa/new_mexico.png",
"toolTipText" : "New Mexico",
"x" : "0.316",
"y" : "0.625"
},
{
"pixmapfile" : "usa/arizona.png",
"toolTipText" : "Arizona",
"x" : "0.209",
"y" : "0.613"
},
{
"pixmapfile" : "usa/alaska.png",
"toolTipText" : "Alaska",
"x" : "0.115",
"y" : "0.861"
},
{
"pixmapfile" : "usa/hawaii.png",
"toolTipText" : "Hawaii",
"x" : "0.302",
"y" : "0.921"
},
{
"pixmapfile" : "usa/texas.png",
"toolTipText" : "Texas",
"x" : "0.427",
"y" : "0.754"
},
{
"pixmapfile" : "usa/oklahoma.png",
"toolTipText" : "Oklahoma",
"x" : "0.456",
"y" : "0.605"
},
{
"pixmapfile" : "usa/minnesota.png",
"toolTipText" : "Minnesota",
"x" : "0.544",
"y" : "0.197"
},
{
"pixmapfile" : "usa/iowa.png",
"toolTipText" : "Iowa",
"x" : "0.549",
"y" : "0.36"
},
{
"pixmapfile" : "usa/missouri.png",
"toolTipText" : "Missouri",
"x" : "0.569",
"y" : "0.494"
},
{
"pixmapfile" : "usa/arkansas.png",
"toolTipText" : "Arkansas",
"x" : "0.574",
"y" : "0.622"
},
{
"pixmapfile" : "usa/louisiana.png",
"toolTipText" : "Louisiana",
"x" : "0.596",
"y" : "0.758"
},
{
"pixmapfile" : "usa/mississippi.png",
"toolTipText" : "Mississippi",
"x" : "0.626",
"y" : "0.694"
},
{
"pixmapfile" : "usa/tennessee.png",
"toolTipText" : "Tennessee",
"x" : "0.69",
"y" : "0.569"
},
{
"pixmapfile" : "usa/kentucky.png",
"toolTipText" : "Kentucky",
"x" : "0.69",
"y" : "0.503"
},
{
"pixmapfile" : "usa/indiana.png",
"toolTipText" : "Indiana",
"x" : "0.673",
"y" : "0.428"
},
{
"pixmapfile" : "usa/illinois.png",
"toolTipText" : "Illinois",
"x" : "0.618",
"y" : "0.436"
},
{
"pixmapfile" : "usa/wisconsin.png",
"toolTipText" : "Wisconsin",
"x" : "0.6",
"y" : "0.256"
},
{
"pixmapfile" : "usa/michigan.png",
"toolTipText" : "Michigan",
"x" : "0.66",
"y" : "0.254"
},
{
"pixmapfile" : "usa/ohio.png",
"toolTipText" : "Ohio",
"x" : "0.733",
"y" : "0.397"
},
{
"pixmapfile" : "usa/west_virginia.png",
"toolTipText" : "West Virginia",
"x" : "0.785",
"y" : "0.443"
},
{
"pixmapfile" : "usa/virginia.png",
"toolTipText" : "Virginia",
"x" : "0.806",
"y" : "0.47"
},
{
"pixmapfile" : "usa/north_carolina.png",
"toolTipText" : "North Carolina",
"x" : "0.801",
"y" : "0.553"
},
{
"pixmapfile" : "usa/south_carolina.png",
"toolTipText" : "South Carolina",
"x" : "0.788",
"y" : "0.634"
},
{
"pixmapfile" : "usa/georgia.png",
//: Translators: Strip USA| and translate only Georgia
"toolTipText" : "USA|Georgia",
"x" : "0.75",
"y" : "0.673"
},
{
"pixmapfile" : "usa/florida.png",
"toolTipText" : "Florida",
"x" : "0.754",
"y" : "0.841"
},
{
"pixmapfile" : "usa/alabama.png",
"toolTipText" : "Alabama",
"x" : "0.688",
"y" : "0.689"
},
{
"pixmapfile" : "usa/maryland.png",
"toolTipText" : "Maryland",
"x" : "0.841",
"y" : "0.415"
},
{
"pixmapfile" : "usa/new_jersey.png",
"toolTipText" : "New Jersey",
"x" : "0.872",
"y" : "0.361"
},
{
"pixmapfile" : "usa/delaware.png",
"toolTipText" : "Delaware",
"x" : "0.867",
"y" : "0.41"
},
{
"pixmapfile" : "usa/pennsylvania.png",
"toolTipText" : "Pennsylvania",
"x" : "0.819",
"y" : "0.352"
},
{
"pixmapfile" : "usa/new_york.png",
"toolTipText" : "New York",
"x" : "0.844",
"y" : "0.261"
},
{
"pixmapfile" : "usa/vermont.png",
"toolTipText" : "Vermont",
"x" : "0.884",
"y" : "0.215"
},
{
"pixmapfile" : "usa/new_hampshire.png",
"toolTipText" : "New Hampshire",
"x" : "0.906",
"y" : "0.207"
},
{
"pixmapfile" : "usa/maine.png",
"toolTipText" : "Maine",
"x" : "0.934",
"y" : "0.149"
},
{
"pixmapfile" : "usa/washington_dc.png",
"toolTipText" : "Washington D.C.",
"x" : "0.943",
"y" : "0.575"
},
{
"pixmapfile" : "usa/california.png",
"toolTipText" : "California",
"x" : "0.096",
"y" : "0.448"
},
{
"pixmapfile" : "usa/nevada.png",
"toolTipText" : "Nevada",
"x" : "0.146",
"y" : "0.424"
},
{
"pixmapfile" : "usa/utah.png",
"toolTipText" : "Utah",
"x" : "0.233",
"y" : "0.418"
},
{
"pixmapfile" : "usa/wyoming.png",
"toolTipText" : "Wyoming",
"x" : "0.313",
"y" : "0.305"
},
{
"pixmapfile" : "usa/massachusetts.png",
"toolTipText" : "Massachusetts",
"x" : "0.909",
"y" : "0.266"
},
{
"pixmapfile" : "usa/rhode_island.png",
"toolTipText" : "Rhode Island",
"x" : "0.915",
"y" : "0.288"
},
{
"pixmapfile" : "usa/connecticut.png",
"toolTipText" : "Connecticut",
"x" : "0.896",
"y" : "0.301"
}
]
}
diff --git a/src/activities/geo-country/resource/board/board10_1.qml b/src/activities/geo-country/resource/board/board10_1.qml
index 3c0295418..2883bb54a 100644
--- a/src/activities/geo-country/resource/board/board10_1.qml
+++ b/src/activities/geo-country/resource/board/board10_1.qml
@@ -1,339 +1,339 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("United States of America")
property var levels: [
{
"pixmapfile" : "usa/background1.png",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "usa/washington.png",
"toolTipText" : "Washington",
"x" : "0.13",
"y" : "0.083"
},
{
"pixmapfile" : "usa/oregon.png",
"toolTipText" : "Oregon",
"x" : "0.11",
"y" : "0.199"
},
{
"pixmapfile" : "usa/idaho.png",
"toolTipText" : "Idaho",
"x" : "0.209",
"y" : "0.187"
},
{
"pixmapfile" : "usa/montana.png",
"toolTipText" : "Montana",
"x" : "0.293",
"y" : "0.147"
},
{
"pixmapfile" : "usa/north_dakota.png",
"toolTipText" : "North Dakota",
"x" : "0.436",
"y" : "0.156"
},
{
"pixmapfile" : "usa/south_dakota.png",
"toolTipText" : "South Dakota",
"x" : "0.435",
"y" : "0.273"
},
{
"pixmapfile" : "usa/nebraska.png",
"toolTipText" : "Nebraska",
"x" : "0.441",
"y" : "0.376"
},
{
"pixmapfile" : "usa/kansas.png",
"toolTipText" : "Kansas",
"x" : "0.463",
"y" : "0.49"
},
{
"pixmapfile" : "usa/colorado.png",
"toolTipText" : "Colorado",
"x" : "0.336",
"y" : "0.458"
},
{
"pixmapfile" : "usa/new_mexico.png",
"toolTipText" : "New Mexico",
"x" : "0.316",
"y" : "0.625"
},
{
"pixmapfile" : "usa/arizona.png",
"toolTipText" : "Arizona",
"x" : "0.209",
"y" : "0.613"
},
{
"pixmapfile" : "usa/alaska.png",
"toolTipText" : "Alaska",
"x" : "0.115",
"y" : "0.861"
},
{
"pixmapfile" : "usa/hawaii.png",
"toolTipText" : "Hawaii",
"x" : "0.302",
"y" : "0.921"
},
{
"pixmapfile" : "usa/texas.png",
"toolTipText" : "Texas",
"x" : "0.427",
"y" : "0.754"
},
{
"pixmapfile" : "usa/oklahoma.png",
"toolTipText" : "Oklahoma",
"x" : "0.456",
"y" : "0.605"
},
{
"pixmapfile" : "usa/minnesota.png",
"toolTipText" : "Minnesota",
"x" : "0.544",
"y" : "0.197"
},
{
"pixmapfile" : "usa/iowa.png",
"toolTipText" : "Iowa",
"x" : "0.549",
"y" : "0.36"
},
{
"pixmapfile" : "usa/missouri.png",
"toolTipText" : "Missouri",
"x" : "0.569",
"y" : "0.494"
},
{
"pixmapfile" : "usa/arkansas.png",
"toolTipText" : "Arkansas",
"x" : "0.574",
"y" : "0.622"
},
{
"pixmapfile" : "usa/louisiana.png",
"toolTipText" : "Louisiana",
"x" : "0.596",
"y" : "0.758"
},
{
"pixmapfile" : "usa/mississippi.png",
"toolTipText" : "Mississippi",
"x" : "0.626",
"y" : "0.694"
},
{
"pixmapfile" : "usa/tennessee.png",
"toolTipText" : "Tennessee",
"x" : "0.69",
"y" : "0.569"
},
{
"pixmapfile" : "usa/kentucky.png",
"toolTipText" : "Kentucky",
"x" : "0.69",
"y" : "0.503"
},
{
"pixmapfile" : "usa/indiana.png",
"toolTipText" : "Indiana",
"x" : "0.673",
"y" : "0.428"
},
{
"pixmapfile" : "usa/illinois.png",
"toolTipText" : "Illinois",
"x" : "0.618",
"y" : "0.436"
},
{
"pixmapfile" : "usa/wisconsin.png",
"toolTipText" : "Wisconsin",
"x" : "0.6",
"y" : "0.256"
},
{
"pixmapfile" : "usa/michigan.png",
"toolTipText" : "Michigan",
"x" : "0.66",
"y" : "0.254"
},
{
"pixmapfile" : "usa/ohio.png",
"toolTipText" : "Ohio",
"x" : "0.733",
"y" : "0.397"
},
{
"pixmapfile" : "usa/west_virginia.png",
"toolTipText" : "West Virginia",
"x" : "0.785",
"y" : "0.443"
},
{
"pixmapfile" : "usa/virginia.png",
"toolTipText" : "Virginia",
"x" : "0.806",
"y" : "0.47"
},
{
"pixmapfile" : "usa/north_carolina.png",
"toolTipText" : "North Carolina",
"x" : "0.801",
"y" : "0.553"
},
{
"pixmapfile" : "usa/south_carolina.png",
"toolTipText" : "South Carolina",
"x" : "0.788",
"y" : "0.634"
},
{
"pixmapfile" : "usa/georgia.png",
//: Translators: Strip USA| and translate only Georgia
"toolTipText" : "USA|Georgia",
"x" : "0.75",
"y" : "0.673"
},
{
"pixmapfile" : "usa/florida.png",
"toolTipText" : "Florida",
"x" : "0.754",
"y" : "0.841"
},
{
"pixmapfile" : "usa/alabama.png",
"toolTipText" : "Alabama",
"x" : "0.688",
"y" : "0.689"
},
{
"pixmapfile" : "usa/maryland.png",
"toolTipText" : "Maryland",
"x" : "0.841",
"y" : "0.415"
},
{
"pixmapfile" : "usa/new_jersey.png",
"toolTipText" : "New Jersey",
"x" : "0.872",
"y" : "0.361"
},
{
"pixmapfile" : "usa/delaware.png",
"toolTipText" : "Delaware",
"x" : "0.867",
"y" : "0.41"
},
{
"pixmapfile" : "usa/pennsylvania.png",
"toolTipText" : "Pennsylvania",
"x" : "0.819",
"y" : "0.352"
},
{
"pixmapfile" : "usa/new_york.png",
"toolTipText" : "New York",
"x" : "0.844",
"y" : "0.261"
},
{
"pixmapfile" : "usa/vermont.png",
"toolTipText" : "Vermont",
"x" : "0.884",
"y" : "0.215"
},
{
"pixmapfile" : "usa/new_hampshire.png",
"toolTipText" : "New Hampshire",
"x" : "0.906",
"y" : "0.207"
},
{
"pixmapfile" : "usa/maine.png",
"toolTipText" : "Maine",
"x" : "0.934",
"y" : "0.149"
},
{
"pixmapfile" : "usa/washington_dc.png",
"toolTipText" : "Washington D.C.",
"x" : "0.943",
"y" : "0.575"
},
{
"pixmapfile" : "usa/california.png",
"toolTipText" : "California",
"x" : "0.096",
"y" : "0.448"
},
{
"pixmapfile" : "usa/nevada.png",
"toolTipText" : "Nevada",
"x" : "0.146",
"y" : "0.424"
},
{
"pixmapfile" : "usa/utah.png",
"toolTipText" : "Utah",
"x" : "0.233",
"y" : "0.418"
},
{
"pixmapfile" : "usa/wyoming.png",
"toolTipText" : "Wyoming",
"x" : "0.313",
"y" : "0.305"
},
{
"pixmapfile" : "usa/massachusetts.png",
"toolTipText" : "Massachusetts",
"x" : "0.909",
"y" : "0.266"
},
{
"pixmapfile" : "usa/rhode_island.png",
"toolTipText" : "Rhode Island",
"x" : "0.915",
"y" : "0.288"
},
{
"pixmapfile" : "usa/connecticut.png",
"toolTipText" : "Connecticut",
"x" : "0.896",
"y" : "0.301"
}
]
}
diff --git a/src/activities/geo-country/resource/board/board11_0.qml b/src/activities/geo-country/resource/board/board11_0.qml
index 8d4bbc2c0..a03d6a62f 100644
--- a/src/activities/geo-country/resource/board/board11_0.qml
+++ b/src/activities/geo-country/resource/board/board11_0.qml
@@ -1,153 +1,153 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property int numberOfSubLevel: 3
property string instruction: qsTr("Districts of Italy")
property var levels: [
{
"pixmapfile" : "italy/backgrounditaly.png",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "italy/liguria.png",
"toolTipText" : "Liguria",
"x" : "0.181",
"y" : "0.267"
},
{
"pixmapfile" : "italy/piemonte.png",
"toolTipText" : "Piemonte",
"x" : "0.108",
"y" : "0.169"
},
{
"pixmapfile" : "italy/valle_d_aosta.png",
"toolTipText" : "Valle d'Aosta",
"x" : "0.063",
"y" : "0.13"
},
{
"pixmapfile" : "italy/lombardia.png",
"toolTipText" : "Lombardia",
"x" : "0.276",
"y" : "0.134"
},
{
"pixmapfile" : "italy/trentino_alto_adige.png",
"toolTipText" : "Trentino Alto Adige",
"x" : "0.401",
"y" : "0.07"
},
{
"pixmapfile" : "italy/veneto.png",
"toolTipText" : "Veneto",
"x" : "0.438",
"y" : "0.127"
},
{
"pixmapfile" : "italy/friuli_venezia_giulia.png",
"toolTipText" : "Friuli Venezia Giulia",
"x" : "0.547",
"y" : "0.093"
},
{
"pixmapfile" : "italy/emilia_romagna.png",
"toolTipText" : "Emilia Romagna",
"x" : "0.366",
"y" : "0.247"
},
{
"pixmapfile" : "italy/toscana.png",
"toolTipText" : "Toscana",
"x" : "0.371",
"y" : "0.341"
},
{
"pixmapfile" : "italy/umbria.png",
"toolTipText" : "Umbria",
"x" : "0.5",
"y" : "0.378"
},
{
"pixmapfile" : "italy/marche.png",
"toolTipText" : "Marche",
"x" : "0.539",
"y" : "0.346"
},
{
"pixmapfile" : "italy/lazio.png",
"toolTipText" : "Lazio",
"x" : "0.513",
"y" : "0.461"
},
{
"pixmapfile" : "italy/abruzzo.png",
"toolTipText" : "Abruzzo",
"x" : "0.612",
"y" : "0.437"
},
{
"pixmapfile" : "italy/molise.png",
"toolTipText" : "Molise",
"x" : "0.668",
"y" : "0.487"
},
{
"pixmapfile" : "italy/campania.png",
"toolTipText" : "Campania",
"x" : "0.688",
"y" : "0.569"
},
{
"pixmapfile" : "italy/puglia.png",
"toolTipText" : "Puglia",
"x" : "0.849",
"y" : "0.558"
},
{
"pixmapfile" : "italy/basilicata.png",
"toolTipText" : "Basilicata",
"x" : "0.797",
"y" : "0.589"
},
{
"pixmapfile" : "italy/calabria.png",
"toolTipText" : "Calabria",
"x" : "0.822",
"y" : "0.713"
},
{
"pixmapfile" : "italy/sicilia.png",
"toolTipText" : "Sicilia",
"x" : "0.598",
"y" : "0.819"
},
{
"pixmapfile" : "italy/sardegna.png",
"toolTipText" : "Sardegna",
"x" : "0.198",
"y" : "0.625"
}
]
}
diff --git a/src/activities/geo-country/resource/board/board11_1.qml b/src/activities/geo-country/resource/board/board11_1.qml
index 0d8abea19..9363f9f8c 100644
--- a/src/activities/geo-country/resource/board/board11_1.qml
+++ b/src/activities/geo-country/resource/board/board11_1.qml
@@ -1,308 +1,308 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Districts of Northern Italy")
property var levels: [
{
"pixmapfile" : "italy/north/background.png",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "italy/north/aosta.png",
"toolTipText" : "Aosta",
"x" : "0.126",
"y" : "0.425"
},
{
"pixmapfile" : "italy/north/imperia.png",
"toolTipText" : "Imperia",
"x" : "0.182",
"y" : "0.895"
},
{
"pixmapfile" : "italy/north/savona.png",
"toolTipText" : "Savona",
"x" : "0.244",
"y" : "0.826"
},
{
"pixmapfile" : "italy/north/genova.png",
"toolTipText" : "Genova",
"x" : "0.344",
"y" : "0.768"
},
{
"pixmapfile" : "italy/north/la_spezia.png",
"toolTipText" : "La_Spezia",
"x" : "0.43",
"y" : "0.82"
},
{
"pixmapfile" : "italy/north/verbania.png",
"toolTipText" : "Verbania",
"x" : "0.245",
"y" : "0.32"
},
{
"pixmapfile" : "italy/north/vercelli.png",
"toolTipText" : "Vercelli",
"x" : "0.23",
"y" : "0.469"
},
{
"pixmapfile" : "italy/north/biella.png",
"toolTipText" : "Biella",
"x" : "0.218",
"y" : "0.467"
},
{
"pixmapfile" : "italy/north/novara.png",
"toolTipText" : "Novara",
"x" : "0.28",
"y" : "0.463"
},
{
"pixmapfile" : "italy/north/torino.png",
"toolTipText" : "Torino",
"x" : "0.131",
"y" : "0.58"
},
{
"pixmapfile" : "italy/north/cuneo.png",
"toolTipText" : "Cuneo",
"x" : "0.154",
"y" : "0.756"
},
{
"pixmapfile" : "italy/north/asti.png",
"toolTipText" : "Asti",
"x" : "0.231",
"y" : "0.663"
},
{
"pixmapfile" : "italy/north/alessandria.png",
"toolTipText" : "Alessandria",
"x" : "0.289",
"y" : "0.663"
},
{
"pixmapfile" : "italy/north/piacenza.png",
"toolTipText" : "Piacenza",
"x" : "0.413",
"y" : "0.662"
},
{
"pixmapfile" : "italy/north/parma.png",
"toolTipText" : "Parma",
"x" : "0.457",
"y" : "0.698"
},
{
"pixmapfile" : "italy/north/reggio_emilia.png",
"toolTipText" : "Reggio_Emilia",
"x" : "0.527",
"y" : "0.721"
},
{
"pixmapfile" : "italy/north/modena.png",
"toolTipText" : "Modena",
"x" : "0.577",
"y" : "0.741"
},
{
"pixmapfile" : "italy/north/bologna.png",
"toolTipText" : "Bologna",
"x" : "0.63",
"y" : "0.763"
},
{
"pixmapfile" : "italy/north/ferrara.png",
"toolTipText" : "Ferrara",
"x" : "0.687",
"y" : "0.688"
},
{
"pixmapfile" : "italy/north/ravenna.png",
"toolTipText" : "Ravenna",
"x" : "0.711",
"y" : "0.783"
},
{
"pixmapfile" : "italy/north/forli-cesena.png",
"toolTipText" : "Forli-Cesena",
"x" : "0.723",
"y" : "0.87"
},
{
"pixmapfile" : "italy/north/rimini.png",
"toolTipText" : "Rimini",
"x" : "0.77",
"y" : "0.89"
},
{
"pixmapfile" : "italy/north/varese.png",
"toolTipText" : "Varese",
"x" : "0.307",
"y" : "0.396"
},
{
"pixmapfile" : "italy/north/milano.png",
"toolTipText" : "Milano",
"x" : "0.352",
"y" : "0.482"
},
{
"pixmapfile" : "italy/north/pavia.png",
"toolTipText" : "Pavia",
"x" : "0.335",
"y" : "0.609"
},
{
"pixmapfile" : "italy/north/como.png",
"toolTipText" : "Como",
"x" : "0.358",
"y" : "0.368"
},
{
"pixmapfile" : "italy/north/lecco.png",
"toolTipText" : "Lecco",
"x" : "0.386",
"y" : "0.377"
},
{
"pixmapfile" : "italy/north/sondrio.png",
"toolTipText" : "Sondrio",
"x" : "0.456",
"y" : "0.267"
},
{
"pixmapfile" : "italy/north/bergamo.png",
"toolTipText" : "Bergamo",
"x" : "0.442",
"y" : "0.414"
},
{
"pixmapfile" : "italy/north/brescia.png",
"toolTipText" : "Brescia",
"x" : "0.502",
"y" : "0.412"
},
{
"pixmapfile" : "italy/north/lodi.png",
"toolTipText" : "Lodi",
"x" : "0.409",
"y" : "0.546"
},
{
"pixmapfile" : "italy/north/cremona.png",
"toolTipText" : "Cremona",
"x" : "0.465",
"y" : "0.559"
},
{
"pixmapfile" : "italy/north/mantova.png",
"toolTipText" : "Mantova",
"x" : "0.566",
"y" : "0.573"
},
{
"pixmapfile" : "italy/north/bolzano.png",
"toolTipText" : "Bolzano",
"x" : "0.643",
"y" : "0.171"
},
{
"pixmapfile" : "italy/north/trento.png",
"toolTipText" : "Trento",
"x" : "0.613",
"y" : "0.325"
},
{
"pixmapfile" : "italy/north/verona.png",
"toolTipText" : "Verona",
"x" : "0.596",
"y" : "0.502"
},
{
"pixmapfile" : "italy/north/vicenza.png",
"toolTipText" : "Vicenza",
"x" : "0.651",
"y" : "0.448"
},
{
"pixmapfile" : "italy/north/padova.png",
"toolTipText" : "Padova",
"x" : "0.691",
"y" : "0.51"
},
{
"pixmapfile" : "italy/north/rovigo.png",
"toolTipText" : "Rovigo",
"x" : "0.7",
"y" : "0.622"
},
{
"pixmapfile" : "italy/north/venezia.png",
"toolTipText" : "Venezia",
"x" : "0.782",
"y" : "0.497"
},
{
"pixmapfile" : "italy/north/treviso.png",
"toolTipText" : "Treviso",
"x" : "0.749",
"y" : "0.396"
},
{
"pixmapfile" : "italy/north/belluno.png",
"toolTipText" : "Belluno",
"x" : "0.745",
"y" : "0.276"
},
{
"pixmapfile" : "italy/north/pordenone.png",
"toolTipText" : "Pordenone",
"x" : "0.805",
"y" : "0.315"
},
{
"pixmapfile" : "italy/north/udine.png",
"toolTipText" : "Udine",
"x" : "0.859",
"y" : "0.311"
},
{
"pixmapfile" : "italy/north/gorizia.png",
"toolTipText" : "Gorizia",
"x" : "0.905",
"y" : "0.392"
},
{
"pixmapfile" : "italy/north/trieste.png",
"toolTipText" : "Trieste",
"x" : "0.941",
"y" : "0.434"
}
]
}
diff --git a/src/activities/geo-country/resource/board/board11_2.qml b/src/activities/geo-country/resource/board/board11_2.qml
index 2af220282..e57c653a8 100644
--- a/src/activities/geo-country/resource/board/board11_2.qml
+++ b/src/activities/geo-country/resource/board/board11_2.qml
@@ -1,188 +1,188 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Districts of Central Italy")
property var levels: [
{
"pixmapfile" : "italy/central/background.png",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "italy/central/massa-carrara.png",
"toolTipText" : "Massa-Carrara",
"x" : "0.199",
"y" : "0.159"
},
{
"pixmapfile" : "italy/central/lucca.png",
"toolTipText" : "Lucca",
"x" : "0.259",
"y" : "0.213"
},
{
"pixmapfile" : "italy/central/pistoia.png",
"toolTipText" : "Pistoia",
"x" : "0.313",
"y" : "0.225"
},
{
"pixmapfile" : "italy/central/prato.png",
"toolTipText" : "Prato",
"x" : "0.343",
"y" : "0.239"
},
{
"pixmapfile" : "italy/central/firenze.png",
"toolTipText" : "Firenze",
"x" : "0.358",
"y" : "0.262"
},
{
"pixmapfile" : "italy/central/pisa.png",
"toolTipText" : "Pisa",
"x" : "0.283",
"y" : "0.355"
},
{
"pixmapfile" : "italy/central/livorno.png",
"toolTipText" : "Livorno",
"x" : "0.235",
"y" : "0.48"
},
{
"pixmapfile" : "italy/central/arezzo.png",
"toolTipText" : "Arezzo",
"x" : "0.447",
"y" : "0.334"
},
{
"pixmapfile" : "italy/central/siena.png",
"toolTipText" : "Siena",
"x" : "0.389",
"y" : "0.43"
},
{
"pixmapfile" : "italy/central/grosseto.png",
"toolTipText" : "Grosseto",
"x" : "0.36",
"y" : "0.539"
},
{
"pixmapfile" : "italy/central/terni.png",
"toolTipText" : "Terni",
"x" : "0.512",
"y" : "0.561"
},
{
"pixmapfile" : "italy/central/perugia.png",
"toolTipText" : "Perugia",
"x" : "0.537",
"y" : "0.446"
},
{
"pixmapfile" : "italy/central/pesaro-urbino.png",
"toolTipText" : "Pesaro-Urbino",
"x" : "0.55",
"y" : "0.296"
},
{
"pixmapfile" : "italy/central/ancona.png",
"toolTipText" : "Ancona",
"x" : "0.617",
"y" : "0.35"
},
{
"pixmapfile" : "italy/central/macerata.png",
"toolTipText" : "Macerata",
"x" : "0.63",
"y" : "0.426"
},
{
"pixmapfile" : "italy/central/fermo.png",
"toolTipText" : "Fermo",
"x" : "0.663",
"y" : "0.447"
},
{
"pixmapfile" : "italy/central/ascoli_piceno.png",
"toolTipText" : "Ascoli_Piceno",
"x" : "0.665",
"y" : "0.499"
},
{
"pixmapfile" : "italy/central/viterbo.png",
"toolTipText" : "Viterbo",
"x" : "0.459",
"y" : "0.6"
},
{
"pixmapfile" : "italy/central/rieti.png",
"toolTipText" : "Rieti",
"x" : "0.583",
"y" : "0.621"
},
{
"pixmapfile" : "italy/central/roma.png",
"toolTipText" : "Roma",
"x" : "0.528",
"y" : "0.756"
},
{
"pixmapfile" : "italy/central/frosinone.png",
"toolTipText" : "Frosinone",
"x" : "0.658",
"y" : "0.82"
},
{
"pixmapfile" : "italy/central/latina.png",
"toolTipText" : "Latina",
"x" : "0.62",
"y" : "0.858"
},
{
"pixmapfile" : "italy/central/teramo.png",
"toolTipText" : "Teramo",
"x" : "0.689",
"y" : "0.556"
},
{
"pixmapfile" : "italy/central/pescara.png",
"toolTipText" : "Pescara",
"x" : "0.723",
"y" : "0.643"
},
{
"pixmapfile" : "italy/central/chieti.png",
"toolTipText" : "Chieti",
"x" : "0.777",
"y" : "0.696"
},
{
"pixmapfile" : "italy/central/l_aquila.png",
"toolTipText" : "L_Aquila",
"x" : "0.676",
"y" : "0.685"
}
]
}
diff --git a/src/activities/geo-country/resource/board/board11_3.qml b/src/activities/geo-country/resource/board/board11_3.qml
index dfa9d8bea..9c509d119 100644
--- a/src/activities/geo-country/resource/board/board11_3.qml
+++ b/src/activities/geo-country/resource/board/board11_3.qml
@@ -1,254 +1,254 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Districts of Southern Italy")
property var levels: [
{
"pixmapfile" : "italy/south/background.png",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "italy/south/sassari.png",
"toolTipText" : "Sassari",
"x" : "0.12",
"y" : "0.328"
},
{
"pixmapfile" : "italy/south/olbia-tempio.png",
"toolTipText" : "Olbia-Tempio",
"x" : "0.171",
"y" : "0.299"
},
{
"pixmapfile" : "italy/south/nuoro.png",
"toolTipText" : "Nuoro",
"x" : "0.164",
"y" : "0.393"
},
{
"pixmapfile" : "italy/south/oristano.png",
"toolTipText" : "Oristano",
"x" : "0.125",
"y" : "0.433"
},
{
"pixmapfile" : "italy/south/ogliastra.png",
"toolTipText" : "Ogliastra",
"x" : "0.19",
"y" : "0.453"
},
{
"pixmapfile" : "italy/south/cagliari.png",
"toolTipText" : "Cagliari",
"x" : "0.156",
"y" : "0.53"
},
{
"pixmapfile" : "italy/south/medio_campidano.png",
"toolTipText" : "Medio_Campidano",
"x" : "0.124",
"y" : "0.502"
},
{
"pixmapfile" : "italy/south/carbonia-iglesias.png",
"toolTipText" : "Carbonia-Iglesias",
"x" : "0.105",
"y" : "0.557"
},
{
"pixmapfile" : "italy/south/trapani.png",
"toolTipText" : "Trapani",
"x" : "0.452",
"y" : "0.763"
},
{
"pixmapfile" : "italy/south/palermo.png",
"toolTipText" : "Palermo",
"x" : "0.542",
"y" : "0.761"
},
{
"pixmapfile" : "italy/south/agrigento.png",
"toolTipText" : "Agrigento",
"x" : "0.488",
"y" : "0.859"
},
{
"pixmapfile" : "italy/south/caltanissetta.png",
"toolTipText" : "Caltanissetta",
"x" : "0.581",
"y" : "0.837"
},
{
"pixmapfile" : "italy/south/enna.png",
"toolTipText" : "Enna",
"x" : "0.616",
"y" : "0.808"
},
{
"pixmapfile" : "italy/south/catania.png",
"toolTipText" : "Catania",
"x" : "0.646",
"y" : "0.819"
},
{
"pixmapfile" : "italy/south/siracusa.png",
"toolTipText" : "Siracusa",
"x" : "0.666",
"y" : "0.887"
},
{
"pixmapfile" : "italy/south/ragusa.png",
"toolTipText" : "Ragusa",
"x" : "0.635",
"y" : "0.907"
},
{
"pixmapfile" : "italy/south/messina.png",
"toolTipText" : "Messina",
"x" : "0.656",
"y" : "0.709"
},
{
"pixmapfile" : "italy/south/reggio_calabria.png",
"toolTipText" : "Reggio_Calabria",
"x" : "0.76",
"y" : "0.706"
},
{
"pixmapfile" : "italy/south/vibo_valentia.png",
"toolTipText" : "Vibo_Valentia",
"x" : "0.761",
"y" : "0.646"
},
{
"pixmapfile" : "italy/south/catanzaro.png",
"toolTipText" : "Catanzaro",
"x" : "0.796",
"y" : "0.617"
},
{
"pixmapfile" : "italy/south/crotone.png",
"toolTipText" : "Crotone",
"x" : "0.83",
"y" : "0.563"
},
{
"pixmapfile" : "italy/south/cosenza.png",
"toolTipText" : "Cosenza",
"x" : "0.785",
"y" : "0.499"
},
{
"pixmapfile" : "italy/south/potenza.png",
"toolTipText" : "Potenza",
"x" : "0.74",
"y" : "0.357"
},
{
"pixmapfile" : "italy/south/matera.png",
"toolTipText" : "Matera",
"x" : "0.79",
"y" : "0.366"
},
{
"pixmapfile" : "italy/south/foggia.png",
"toolTipText" : "Foggia",
"x" : "0.714",
"y" : "0.202"
},
{
"pixmapfile" : "italy/south/barlettaandriatrani.png",
"toolTipText" : "Barletta-Andria-Trani",
"x" : "0.77",
"y" : "0.254"
},
{
"pixmapfile" : "italy/south/bari.png",
"toolTipText" : "Bari",
"x" : "0.815",
"y" : "0.29"
},
{
"pixmapfile" : "italy/south/taranto.png",
"toolTipText" : "Taranto",
"x" : "0.859",
"y" : "0.354"
},
{
"pixmapfile" : "italy/south/brindisi.png",
"toolTipText" : "Brindisi",
"x" : "0.898",
"y" : "0.338"
},
{
"pixmapfile" : "italy/south/lecce.png",
"toolTipText" : "Lecce",
"x" : "0.935",
"y" : "0.413"
},
{
"pixmapfile" : "italy/south/isernia.png",
"toolTipText" : "Isernia",
"x" : "0.6",
"y" : "0.182"
},
{
"pixmapfile" : "italy/south/campobasso.png",
"toolTipText" : "Campobasso",
"x" : "0.644",
"y" : "0.169"
},
{
"pixmapfile" : "italy/south/caserta.png",
"toolTipText" : "Caserta",
"x" : "0.593",
"y" : "0.249"
},
{
"pixmapfile" : "italy/south/benevento.png",
"toolTipText" : "Benevento",
"x" : "0.641",
"y" : "0.248"
},
{
"pixmapfile" : "italy/south/avellino.png",
"toolTipText" : "Avellino",
"x" : "0.67",
"y" : "0.285"
},
{
"pixmapfile" : "italy/south/napoli.png",
"toolTipText" : "Napoli",
"x" : "0.6",
"y" : "0.32"
},
{
"pixmapfile" : "italy/south/salerno.png",
"toolTipText" : "Salerno",
"x" : "0.678",
"y" : "0.373"
}
]
}
diff --git a/src/activities/geo-country/resource/board/board12_0.qml b/src/activities/geo-country/resource/board/board12_0.qml
index f09983e06..e697988a7 100644
--- a/src/activities/geo-country/resource/board/board12_0.qml
+++ b/src/activities/geo-country/resource/board/board12_0.qml
@@ -1,225 +1,225 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("States of India")
property var levels: [
{
"pixmapfile" : "india/background.png",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "india/jammu_and_kashmir.png",
"toolTipText" : "Jammu and Kashmir",
"x" : "0.313",
"y" : "0.111"
},
{
"pixmapfile" : "india/himachal_pradesh.png",
"toolTipText" : "Himachal Pradesh",
"x" : "0.337",
"y" : "0.205"
},
{
"pixmapfile" : "india/punjab.png",
"toolTipText" : "Punjab",
"x" : "0.278",
"y" : "0.228"
},
{
"pixmapfile" : "india/harayana.png",
"toolTipText" : "Harayana",
"x" : "0.296",
"y" : "0.294"
},
{
"pixmapfile" : "india/uttarakhand.png",
"toolTipText" : "Uttarakhand",
"x" : "0.403",
"y" : "0.267"
},
{
"pixmapfile" : "india/rajasthan.png",
"toolTipText" : "Rajasthan",
"x" : "0.216",
"y" : "0.377"
},
{
"pixmapfile" : "india/uttar_pradesh.png",
"toolTipText" : "Uttar Pradesh",
"x" : "0.459",
"y" : "0.36"
},
{
"pixmapfile" : "india/bihar.png",
"toolTipText" : "Bihar",
"x" : "0.623",
"y" : "0.4"
},
{
"pixmapfile" : "india/gujarat.png",
"toolTipText" : "Gujarat",
"x" : "0.124",
"y" : "0.507"
},
{
"pixmapfile" : "india/madhya_pradesh.png",
"toolTipText" : "Madhya Pradesh",
"x" : "0.375",
"y" : "0.461"
},
{
"pixmapfile" : "india/jharkhand.png",
"toolTipText" : "Jharkhand",
"x" : "0.621",
"y" : "0.471"
},
{
"pixmapfile" : "india/maharashtra.png",
"toolTipText" : "Maharashtra",
"x" : "0.314",
"y" : "0.624"
},
{
"pixmapfile" : "india/chhattisgarh.png",
"toolTipText" : "Chhattisgarh",
"x" : "0.511",
"y" : "0.559"
},
{
"pixmapfile" : "india/orrisa.png",
"toolTipText" : "Orrisa",
"x" : "0.591",
"y" : "0.584"
},
{
"pixmapfile" : "india/goa.png",
"toolTipText" : "Goa",
"x" : "0.208",
"y" : "0.733"
},
{
"pixmapfile" : "india/karnataka.png",
"toolTipText" : "Karnataka",
"x" : "0.295",
"y" : "0.748"
},
{
"pixmapfile" : "india/telangana.png",
"toolTipText" : "Telangana",
"x" : "0.405",
"y" : "0.66"
},
{
"pixmapfile" : "india/andhra_pradesh.png",
"toolTipText" : "Andhra Pradesh",
"x" : "0.454",
"y" : "0.71"
},
{
"pixmapfile" : "india/kerala.png",
"toolTipText" : "Kerala",
"x" : "0.286",
"y" : "0.885"
},
{
"pixmapfile" : "india/tamil_nadu.png",
"toolTipText" : "Tamil Nadu",
"x" : "0.371",
"y" : "0.875"
},
{
"pixmapfile" : "india/west_bengal.png",
"toolTipText" : "West Bengal",
"x" : "0.689",
"y" : "0.445"
},
{
"pixmapfile" : "india/sikkim.png",
"toolTipText" : "Sikkim",
"x" : "0.702",
"y" : "0.344"
},
{
"pixmapfile" : "india/assam.png",
"toolTipText" : "Assam",
"x" : "0.842",
"y" : "0.37"
},
{
"pixmapfile" : "india/arunachal_pradesh.png",
"toolTipText" : "Arunachal Pradesh",
"x" : "0.891",
"y" : "0.305"
},
{
"pixmapfile" : "india/nagaland.png",
"toolTipText" : "Nagaland",
"x" : "0.891",
"y" : "0.37"
},
{
"pixmapfile" : "india/manipur.png",
"toolTipText" : "Manipur",
"x" : "0.884",
"y" : "0.416"
},
{
"pixmapfile" : "india/mizoram.png",
"toolTipText" : "Mizoram",
"x" : "0.854",
"y" : "0.473"
},
{
"pixmapfile" : "india/tripura.png",
"toolTipText" : "Tripura",
"x" : "0.819",
"y" : "0.457"
},
{
"pixmapfile" : "india/meghalaya.png",
"toolTipText" : "Meghalaya",
"x" : "0.796",
"y" : "0.395"
},
{
"pixmapfile" : "india/lakshadweep_islands.png",
"toolTipText" : "Lakshadweep Islands",
"x" : "0.153",
"y" : "0.888"
},
{
"pixmapfile" : "india/andaman_and_nicobar_islands.png",
"toolTipText" : "Andaman and Nicobar Islands",
"x" : "0.909",
"y" : "0.876"
},
{
"pixmapfile" : "india/delhi.png",
"toolTipText" : "Delhi",
"x" : "0.336",
"y" : "0.31"
}
]
}
diff --git a/src/activities/geo-country/resource/board/board13_0.qml b/src/activities/geo-country/resource/board/board13_0.qml
index 4b279da75..636e18dfb 100644
--- a/src/activities/geo-country/resource/board/board13_0.qml
+++ b/src/activities/geo-country/resource/board/board13_0.qml
@@ -1,74 +1,74 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Districts of Australia")
property var levels: [
{
"pixmapfile" : "australia/background.png",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "australia/western_australia.png",
"toolTipText" : "Western Australia",
"x" : "0.217",
"y" : "0.402"
},
{
"pixmapfile" : "australia/northern_territory.png",
"toolTipText" : "Northern Territory",
"x" : "0.496",
"y" : "0.246"
},
{
"pixmapfile" : "australia/south_australia.png",
"toolTipText" : "South Australia",
"x" : "0.533",
"y" : "0.622"
},
{
"pixmapfile" : "australia/queensland.png",
"toolTipText" : "Queensland",
"x" : "0.779",
"y" : "0.275"
},
{
"pixmapfile" : "australia/new_south_wales.png",
"toolTipText" : "New South Wales",
"x" : "0.817",
"y" : "0.637"
},
{
"pixmapfile" : "australia/victoria.png",
"toolTipText" : "Victoria",
"x" : "0.772",
"y" : "0.753"
},
{
"pixmapfile" : "australia/tasmania.png",
"toolTipText" : "Tasmania",
"x" : "0.798",
"y" : "0.933"
}
]
}
diff --git a/src/activities/geo-country/resource/board/board14_0.qml b/src/activities/geo-country/resource/board/board14_0.qml
index 82e317b25..c12b9467e 100644
--- a/src/activities/geo-country/resource/board/board14_0.qml
+++ b/src/activities/geo-country/resource/board/board14_0.qml
@@ -1,218 +1,218 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Districts of China")
property var levels: [
{
"pixmapfile" : "china/background.png",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "china/xinjiang.png",
"toolTipText" : "Xinjiang",
"x" : "0.201",
"y" : "0.275"
},
{
"pixmapfile" : "china/gansu.png",
"toolTipText" : "Gansu",
"x" : "0.459",
"y" : "0.445"
},
{
"pixmapfile" : "china/inner_mongolia.png",
"toolTipText" : "Inner Mangolia",
"x" : "0.631",
"y" : "0.237"
},
{
"pixmapfile" : "china/ningxia.png",
"toolTipText" : "Ningxia",
"x" : "0.552",
"y" : "0.464"
},
{
"pixmapfile" : "china/heilongjiang.png",
"toolTipText" : "Heilongjiang",
"x" : "0.886",
"y" : "0.132"
},
{
"pixmapfile" : "china/jilin.png",
"toolTipText" : "Jilin",
"x" : "0.883",
"y" : "0.274"
},
{
"pixmapfile" : "china/liaoning.png",
"toolTipText" : "Liaoning",
"x" : "0.828",
"y" : "0.34"
},
{
"pixmapfile" : "china/tianjin.png",
"toolTipText" : "Tianjin",
"x" : "0.746",
"y" : "0.402"
},
{
"pixmapfile" : "china/beijing.png",
"toolTipText" : "Beijing",
"x" : "0.729",
"y" : "0.381"
},
{
"pixmapfile" : "china/shandong.png",
"toolTipText" : "Shandong",
"x" : "0.776",
"y" : "0.485"
},
{
"pixmapfile" : "china/shanxi.png",
"toolTipText" : "Shanxi",
"x" : "0.662",
"y" : "0.456"
},
{
"pixmapfile" : "china/shaanxi.png",
"toolTipText" : "Shaanxi",
"x" : "0.591",
"y" : "0.511"
},
{
"pixmapfile" : "china/qinghai.png",
"toolTipText" : "Qinghai",
"x" : "0.372",
"y" : "0.492"
},
{
"pixmapfile" : "china/xizang.png",
"toolTipText" : "Xizang",
"x" : "0.223",
"y" : "0.558"
},
{
"pixmapfile" : "china/sichuan.png",
"toolTipText" : "Sichuan",
"x" : "0.489",
"y" : "0.652"
},
{
"pixmapfile" : "china/chongqing.png",
"toolTipText" : "Chongqing",
"x" : "0.576",
"y" : "0.659"
},
{
"pixmapfile" : "china/henan.png",
"toolTipText" : "Henan",
"x" : "0.685",
"y" : "0.556"
},
{
"pixmapfile" : "china/jiangsu.png",
"toolTipText" : "Jiangsu",
"x" : "0.792",
"y" : "0.573"
},
{
"pixmapfile" : "china/anhui.png",
"toolTipText" : "Anhui",
"x" : "0.757",
"y" : "0.603"
},
{
"pixmapfile" : "china/hubei.png",
"toolTipText" : "Hubei",
"x" : "0.665",
"y" : "0.632"
},
{
"pixmapfile" : "china/shanghai.png",
"toolTipText" : "Shanghai",
"x" : "0.838",
"y" : "0.618"
},
{
"pixmapfile" : "china/zhejiang.png",
"toolTipText" : "Zhejiang",
"x" : "0.815",
"y" : "0.673"
},
{
"pixmapfile" : "china/fujian.png",
"toolTipText" : "Fujian",
"x" : "0.785",
"y" : "0.769"
},
{
"pixmapfile" : "china/jiangxi.png",
"toolTipText" : "Jiangxi",
"x" : "0.74",
"y" : "0.735"
},
{
"pixmapfile" : "china/hunan.png",
"toolTipText" : "Hunan",
"x" : "0.651",
"y" : "0.737"
},
{
"pixmapfile" : "china/guizhou.png",
"toolTipText" : "Guizhou",
"x" : "0.552",
"y" : "0.747"
},
{
"pixmapfile" : "china/yunnan.png",
"toolTipText" : "Yunnan",
"x" : "0.453",
"y" : "0.786"
},
{
"pixmapfile" : "china/guangxi.png",
"toolTipText" : "Guangxi",
"x" : "0.586",
"y" : "0.833"
},
{
"pixmapfile" : "china/guangdong.png",
"toolTipText" : "Guangdong",
"x" : "0.691",
"y" : "0.861"
},
{
"pixmapfile" : "china/hainan.png",
"toolTipText" : "Hainan",
"x" : "0.617",
"y" : "0.966"
},
{
"pixmapfile" : "china/hebei.png",
"toolTipText" : "Hebei",
"x" : "0.735",
"y" : "0.405"
}
]
}
diff --git a/src/activities/geo-country/resource/board/board15_0.qml b/src/activities/geo-country/resource/board/board15_0.qml
index a9d5e4d46..544d68a2e 100644
--- a/src/activities/geo-country/resource/board/board15_0.qml
+++ b/src/activities/geo-country/resource/board/board15_0.qml
@@ -1,111 +1,111 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property int numberOfSubLevel: 3
property string instruction: qsTr("Northern Scotland")
property var levels: [
{
"pixmapfile" : "scotland/bg_north.png",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "scotland/n_aberdeenshire.png",
"toolTipText" : "Aberdeenshire",
"x" : "0.688",
"y" : "0.804"
},
{
"pixmapfile" : "scotland/n_aberdeen.png",
"toolTipText" : "Aberdeen",
"x" : "0.756",
"y" : "0.818"
},
{
"pixmapfile" : "scotland/n_moray.png",
"toolTipText" : "Moray",
"x" : "0.638",
"y" : "0.768"
},
{
"pixmapfile" : "scotland/n_eileanan_siar.png",
"toolTipText" : "Na h-Eileanan Siar",
"x" : "0.162",
"y" : "0.722"
},
{
"pixmapfile" : "scotland/n_orkney.png",
"toolTipText" : "Orkney",
"x" : "0.674",
"y" : "0.448"
},
{
"pixmapfile" : "scotland/n_shetland.png",
"toolTipText" : "Shetland",
"x" : "0.842",
"y" : "0.23"
},
{
"pixmapfile" : "scotland/n_hl_caithness.png",
"toolTipText" : "Caithness",
"x" : "0.612",
"y" : "0.574"
},
{
"pixmapfile" : "scotland/n_hl_sutherland.png",
"toolTipText" : "Sutherland",
"x" : "0.49",
"y" : "0.61"
},
{
"pixmapfile" : "scotland/n_hl_ross.png",
"toolTipText" : "Ross",
"x" : "0.456",
"y" : "0.704"
},
{
"pixmapfile" : "scotland/n_hl_inverness_nairn.png",
"toolTipText" : "Inverness and Nairn",
"x" : "0.564",
"y" : "0.78"
},
{
"pixmapfile" : "scotland/n_hl_lochalsh_badenoch_stra.png",
"toolTipText" : "Lochalsh, Badenoch, Cromarty and Strathspey",
"x" : "0.472",
"y" : "0.802"
},
{
"pixmapfile" : "scotland/n_hl_lochaber.png",
"toolTipText" : "Lochaber",
"x" : "0.372",
"y" : "0.888"
},
{
"pixmapfile" : "scotland/n_hl_skye.png",
"toolTipText" : "Skye",
"x" : "0.296",
"y" : "0.776"
}
]
}
diff --git a/src/activities/geo-country/resource/board/board15_1.qml b/src/activities/geo-country/resource/board/board15_1.qml
index 97c3c9e88..6a68d8411 100644
--- a/src/activities/geo-country/resource/board/board15_1.qml
+++ b/src/activities/geo-country/resource/board/board15_1.qml
@@ -1,182 +1,182 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Southern Scotland")
property var levels: [
{
"pixmapfile" : "scotland/bg_south.png",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "scotland/s_borders.png",
"toolTipText" : "Scottish Borders",
"x" : "0.803",
"y" : "0.564"
},
{
"pixmapfile" : "scotland/s_east_lothian.png",
"toolTipText" : "East Lothian",
"x" : "0.813",
"y" : "0.413"
},
{
"pixmapfile" : "scotland/s_midlothian.png",
"toolTipText" : "Midlothian",
"x" : "0.749",
"y" : "0.458"
},
{
"pixmapfile" : "scotland/s_west_lothian.png",
"toolTipText" : "West Lothian",
"x" : "0.666",
"y" : "0.433"
},
{
"pixmapfile" : "scotland/s_edinburgh.png",
"toolTipText" : "Edinburgh",
"x" : "0.723",
"y" : "0.424"
},
{
"pixmapfile" : "scotland/s_falkirk.png",
"toolTipText" : "Falkirk",
"x" : "0.638",
"y" : "0.391"
},
{
"pixmapfile" : "scotland/s_south_lanarkshire.png",
"toolTipText" : "South Lanarkshire",
"x" : "0.626",
"y" : "0.551"
},
{
"pixmapfile" : "scotland/s_north_lanarkshire.png",
"toolTipText" : "North Lanarkshire",
"x" : "0.607",
"y" : "0.433"
},
{
"pixmapfile" : "scotland/s_dumfries_galloway.png",
"toolTipText" : "Dumfries and Galloway",
"x" : "0.597",
"y" : "0.74"
},
{
"pixmapfile" : "scotland/s_south_ayrshire.png",
"toolTipText" : "South Ayrshire",
"x" : "0.476",
"y" : "0.649"
},
{
"pixmapfile" : "scotland/s_east_ayrshire.png",
"toolTipText" : "East Ayrshire",
"x" : "0.55",
"y" : "0.593"
},
{
"pixmapfile" : "scotland/s_glasgow.png",
"toolTipText" : "Glasgow",
"x" : "0.561",
"y" : "0.444"
},
{
"pixmapfile" : "scotland/s_east_dunbartonshire.png",
"toolTipText" : "East Dunbartonshire",
"x" : "0.561",
"y" : "0.407"
},
{
"pixmapfile" : "scotland/s_west_dunbartonshire.png",
"toolTipText" : "West Dunbartonshire",
"x" : "0.512",
"y" : "0.398"
},
{
"pixmapfile" : "scotland/s_east_renfrewshire.png",
"toolTipText" : "East Renfrewshire",
"x" : "0.536",
"y" : "0.484"
},
{
"pixmapfile" : "scotland/s_renfrewshire.png",
"toolTipText" : "Renfrewshire",
"x" : "0.505",
"y" : "0.449"
},
{
"pixmapfile" : "scotland/s_inverclyde.png",
"toolTipText" : "Inverclyde",
"x" : "0.474",
"y" : "0.429"
},
{
"pixmapfile" : "scotland/s_north_ayrshire.png",
"toolTipText" : "North Ayrshire",
"x" : "0.441",
"y" : "0.516"
},
{
"pixmapfile" : "scotland/s_clackmannanshire.png",
"toolTipText" : "Clackmannanshire",
"x" : "0.644",
"y" : "0.34"
},
{
"pixmapfile" : "scotland/s_fife.png",
"toolTipText" : "Fife",
"x" : "0.739",
"y" : "0.307"
},
{
"pixmapfile" : "scotland/s_dundee.png",
"toolTipText" : "Dundee",
"x" : "0.772",
"y" : "0.218"
},
{
"pixmapfile" : "scotland/s_angus.png",
"toolTipText" : "Angus",
"x" : "0.782",
"y" : "0.127"
},
{
"pixmapfile" : "scotland/s_perth_kinross.png",
"toolTipText" : "Perth and Kinross",
"x" : "0.618",
"y" : "0.193"
},
{
"pixmapfile" : "scotland/s_stirling.png",
"toolTipText" : "Stirling",
"x" : "0.545",
"y" : "0.3"
},
{
"pixmapfile" : "scotland/s_argyll_bute.png",
"toolTipText" : "Argyll and Bute",
"x" : "0.301",
"y" : "0.396"
}
]
}
diff --git a/src/activities/geo-country/resource/board/board15_2.qml b/src/activities/geo-country/resource/board/board15_2.qml
index 2cd4d920f..ea5da4900 100644
--- a/src/activities/geo-country/resource/board/board15_2.qml
+++ b/src/activities/geo-country/resource/board/board15_2.qml
@@ -1,110 +1,110 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Northern Scotland")
property var levels: [
{
"pixmapfile" : "scotland/bg_north_blank.png",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "scotland/n_aberdeenshire.png",
"toolTipText" : "Aberdeenshire",
"x" : "0.688",
"y" : "0.804"
},
{
"pixmapfile" : "scotland/n_aberdeen.png",
"toolTipText" : "Aberdeen",
"x" : "0.756",
"y" : "0.818"
},
{
"pixmapfile" : "scotland/n_moray.png",
"toolTipText" : "Moray",
"x" : "0.638",
"y" : "0.768"
},
{
"pixmapfile" : "scotland/n_eileanan_siar.png",
"toolTipText" : "Na h-Eileanan Siar",
"x" : "0.162",
"y" : "0.722"
},
{
"pixmapfile" : "scotland/n_orkney.png",
"toolTipText" : "Orkney",
"x" : "0.674",
"y" : "0.448"
},
{
"pixmapfile" : "scotland/n_shetland.png",
"toolTipText" : "Shetland",
"x" : "0.842",
"y" : "0.23"
},
{
"pixmapfile" : "scotland/n_hl_caithness.png",
"toolTipText" : "Caithness",
"x" : "0.612",
"y" : "0.574"
},
{
"pixmapfile" : "scotland/n_hl_sutherland.png",
"toolTipText" : "Sutherland",
"x" : "0.49",
"y" : "0.61"
},
{
"pixmapfile" : "scotland/n_hl_ross.png",
"toolTipText" : "Ross",
"x" : "0.456",
"y" : "0.704"
},
{
"pixmapfile" : "scotland/n_hl_inverness_nairn.png",
"toolTipText" : "Inverness and Nairn",
"x" : "0.564",
"y" : "0.78"
},
{
"pixmapfile" : "scotland/n_hl_lochalsh_badenoch_stra.png",
"toolTipText" : "Lochalsh, Badenoch, Cromarty and Strathspey",
"x" : "0.472",
"y" : "0.802"
},
{
"pixmapfile" : "scotland/n_hl_lochaber.png",
"toolTipText" : "Lochaber",
"x" : "0.372",
"y" : "0.888"
},
{
"pixmapfile" : "scotland/n_hl_skye.png",
"toolTipText" : "Skye",
"x" : "0.296",
"y" : "0.776"
}
]
}
diff --git a/src/activities/geo-country/resource/board/board15_3.qml b/src/activities/geo-country/resource/board/board15_3.qml
index 80ebf9f97..5875d6936 100644
--- a/src/activities/geo-country/resource/board/board15_3.qml
+++ b/src/activities/geo-country/resource/board/board15_3.qml
@@ -1,182 +1,182 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Southern Scotland")
property var levels: [
{
"pixmapfile" : "scotland/bg_south_blank.png",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "scotland/s_borders.png",
"toolTipText" : "Scottish Borders",
"x" : "0.803",
"y" : "0.564"
},
{
"pixmapfile" : "scotland/s_east_lothian.png",
"toolTipText" : "East Lothian",
"x" : "0.813",
"y" : "0.413"
},
{
"pixmapfile" : "scotland/s_midlothian.png",
"toolTipText" : "Midlothian",
"x" : "0.749",
"y" : "0.458"
},
{
"pixmapfile" : "scotland/s_west_lothian.png",
"toolTipText" : "West Lothian",
"x" : "0.666",
"y" : "0.433"
},
{
"pixmapfile" : "scotland/s_edinburgh.png",
"toolTipText" : "Edinburgh",
"x" : "0.723",
"y" : "0.424"
},
{
"pixmapfile" : "scotland/s_falkirk.png",
"toolTipText" : "Falkirk",
"x" : "0.638",
"y" : "0.391"
},
{
"pixmapfile" : "scotland/s_south_lanarkshire.png",
"toolTipText" : "South Lanarkshire",
"x" : "0.626",
"y" : "0.551"
},
{
"pixmapfile" : "scotland/s_north_lanarkshire.png",
"toolTipText" : "North Lanarkshire",
"x" : "0.607",
"y" : "0.433"
},
{
"pixmapfile" : "scotland/s_dumfries_galloway.png",
"toolTipText" : "Dumfries and Galloway",
"x" : "0.597",
"y" : "0.74"
},
{
"pixmapfile" : "scotland/s_south_ayrshire.png",
"toolTipText" : "South Ayrshire",
"x" : "0.476",
"y" : "0.649"
},
{
"pixmapfile" : "scotland/s_east_ayrshire.png",
"toolTipText" : "East Ayrshire",
"x" : "0.55",
"y" : "0.593"
},
{
"pixmapfile" : "scotland/s_glasgow.png",
"toolTipText" : "Glasgow",
"x" : "0.561",
"y" : "0.444"
},
{
"pixmapfile" : "scotland/s_east_dunbartonshire.png",
"toolTipText" : "East Dunbartonshire",
"x" : "0.561",
"y" : "0.407"
},
{
"pixmapfile" : "scotland/s_west_dunbartonshire.png",
"toolTipText" : "West Dunbartonshire",
"x" : "0.512",
"y" : "0.398"
},
{
"pixmapfile" : "scotland/s_east_renfrewshire.png",
"toolTipText" : "East Renfrewshire",
"x" : "0.536",
"y" : "0.484"
},
{
"pixmapfile" : "scotland/s_renfrewshire.png",
"toolTipText" : "Renfrewshire",
"x" : "0.505",
"y" : "0.449"
},
{
"pixmapfile" : "scotland/s_inverclyde.png",
"toolTipText" : "Inverclyde",
"x" : "0.474",
"y" : "0.429"
},
{
"pixmapfile" : "scotland/s_north_ayrshire.png",
"toolTipText" : "North Ayrshire",
"x" : "0.441",
"y" : "0.516"
},
{
"pixmapfile" : "scotland/s_clackmannanshire.png",
"toolTipText" : "Clackmannanshire",
"x" : "0.644",
"y" : "0.34"
},
{
"pixmapfile" : "scotland/s_fife.png",
"toolTipText" : "Fife",
"x" : "0.739",
"y" : "0.307"
},
{
"pixmapfile" : "scotland/s_dundee.png",
"toolTipText" : "Dundee",
"x" : "0.772",
"y" : "0.218"
},
{
"pixmapfile" : "scotland/s_angus.png",
"toolTipText" : "Angus",
"x" : "0.782",
"y" : "0.127"
},
{
"pixmapfile" : "scotland/s_perth_kinross.png",
"toolTipText" : "Perth and Kinross",
"x" : "0.618",
"y" : "0.193"
},
{
"pixmapfile" : "scotland/s_stirling.png",
"toolTipText" : "Stirling",
"x" : "0.545",
"y" : "0.3"
},
{
"pixmapfile" : "scotland/s_argyll_bute.png",
"toolTipText" : "Argyll and Bute",
"x" : "0.301",
"y" : "0.396"
}
]
}
diff --git a/src/activities/geo-country/resource/board/board16_0.qml b/src/activities/geo-country/resource/board/board16_0.qml
index 3266b9959..f73f73bb5 100644
--- a/src/activities/geo-country/resource/board/board16_0.qml
+++ b/src/activities/geo-country/resource/board/board16_0.qml
@@ -1,86 +1,86 @@
/* GCompris
*
* Copyright (C) 2016 Johnny Jazeix <jazeix@gmail.com>
*
* Authors:
* Johnny Jazeix <jazeix@gmail.com>
* Horia PELLE <horricane@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Historical provinces of Romania")
property var levels: [
{
"pixmapfile" : "romania/background.png",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "romania/oltenia.png",
"toolTipText" : "Oltenia",
"x" : "0.346",
"y" : "0.787"
},
{
"pixmapfile" : "romania/muntenia.png",
"toolTipText" : "Muntenia",
"x" : "0.629",
"y" : "0.768"
},
{
"pixmapfile" : "romania/dobrogea.png",
"toolTipText" : "Dobrogea",
"x" : "0.873",
"y" : "0.776"
},
{
"pixmapfile" : "romania/moldova.png",
"toolTipText" : "Moldova",
"x" : "0.693",
"y" : "0.307"
},
{
"pixmapfile" : "romania/bucovina.png",
"toolTipText" : "Bucovina",
"x" : "0.567",
"y" : "0.155"
},
{
"pixmapfile" : "romania/transilvania.png",
"toolTipText" : "Transilvania",
"x" : "0.443",
"y" : "0.396"
},
{
"pixmapfile" : "romania/maramures.png",
"toolTipText" : "Maramureș",
"x" : "0.386",
"y" : "0.111"
},
{
"pixmapfile" : "romania/crisana.png",
"toolTipText" : "Crișana",
"x" : "0.193",
"y" : "0.290"
},
{
"pixmapfile" : "romania/banat.png",
"toolTipText" : "Banat",
"x" : "0.128",
"y" : "0.617"
}
]
}
diff --git a/src/activities/geo-country/resource/board/board1_0.qml b/src/activities/geo-country/resource/board/board1_0.qml
index 92894db50..f03479920 100644
--- a/src/activities/geo-country/resource/board/board1_0.qml
+++ b/src/activities/geo-country/resource/board/board1_0.qml
@@ -1,123 +1,123 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Districts of France")
property var levels: [
{
"pixmapfile" : "france/france-regions.png",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "france/corse.png",
"sound" : "voices-$CA/$LOCALE/france/corse.$CA",
"x" : "0.836",
"y" : "0.905",
"toolTipText" : "Corse"
},
{
"pixmapfile" : "france/nouvelle-aquitaine.png",
"sound" : "voices-$CA/$LOCALE/france/nouvelle-aquitaine.$CA",
"x" : "0.37",
"y" : "0.64",
"toolTipText" : "Nouvelle-Aquitaine"
},
{
"pixmapfile" : "france/occitanie.png",
"sound" : "voices-$CA/$LOCALE/france/occitanie.$CA",
"x" : "0.47",
"y" : "0.776",
"toolTipText" : "Occitanie"
},
{
"pixmapfile" : "france/paca.png",
"sound" : "voices-$CA/$LOCALE/france/paca.$CA",
"x" : "0.672",
"y" : "0.728",
"toolTipText" : "Provence-Alpes-Côte d'Azur"
},
{
"pixmapfile" : "france/auvergne-rhone-alpes.png",
"sound" : "voices-$CA/$LOCALE/france/auvergne-rhone-alpes.$CA",
"x" : "0.597",
"y" : "0.586",
"toolTipText" : "Auvergne-Rhône-Alpes"
},
{
"pixmapfile" : "france/centre-val-de-loire.png",
"sound" : "voices-$CA/$LOCALE/france/centre-val-de-loire.$CA",
"x" : "0.439",
"y" : "0.360",
"toolTipText" : "Centre-Val de Loire"
},
{
"pixmapfile" : "france/pays-de-la-loire.png",
"sound" : "voices-$CA/$LOCALE/france/pays-de-la-loire.$CA",
"x" : "0.316",
"y" : "0.378",
"toolTipText" : "Pays de la Loire"
},
{
"pixmapfile" : "france/ile-de-france.png",
"sound" : "voices-$CA/$LOCALE/france/ile-de-france.$CA",
"x" : "0.486",
"y" : "0.253",
"toolTipText" : "Île-de-france"
},
{
"pixmapfile" : "france/bretagne.png",
"sound" : "voices-$CA/$LOCALE/france/bretagne.$CA",
"x" : "0.216",
"y" : "0.291",
"toolTipText" : "Bretagne"
},
{
"pixmapfile" : "france/normandie.png",
"sound" : "voices-$CA/$LOCALE/france/normandie.$CA",
"x" : "0.366",
"y" : "0.199",
"toolTipText" : "Normandie"
},
{
"pixmapfile" : "france/haut-de-france.png",
"sound" : "voices-$CA/$LOCALE/france/haut-de-france.$CA",
"x" : "0.503",
"y" : "0.117",
"toolTipText" : "Haut de France"
},
{
"pixmapfile" : "france/grand-est.png",
"sound" : "voices-$CA/$LOCALE/france/grand-est.$CA",
"x" : "0.649",
"y" : "0.233",
"toolTipText" : "Grand est"
},
{
"pixmapfile" : "france/bourgogne-franche-comte.png",
"sound" : "voices-$CA/$LOCALE/france/bourgogne-franche-comte.$CA",
"x" : "0.613",
"y" : "0.398",
"toolTipText" : "Bourgogne-Franche-Comté"
}
]
}
diff --git a/src/activities/geo-country/resource/board/board2_0.qml b/src/activities/geo-country/resource/board/board2_0.qml
index 1f66bc775..33e77c5d5 100644
--- a/src/activities/geo-country/resource/board/board2_0.qml
+++ b/src/activities/geo-country/resource/board/board2_0.qml
@@ -1,128 +1,128 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Districts of Germany")
property var levels: [
{
"pixmapfile" : "germany/back.png",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "germany/thueringen.png",
"toolTipText" : "Thüringen",
"x" : "0.584",
"y" : "0.536"
},
{
"pixmapfile" : "germany/schleswig_holstein.png",
"toolTipText" : "Schleswig-Holstein",
"x" : "0.436",
"y" : "0.14"
},
{
"pixmapfile" : "germany/sachsen.png",
"toolTipText" : "Sachsen",
"x" : "0.805",
"y" : "0.536"
},
{
"pixmapfile" : "germany/sachsen-anhalt.png",
"toolTipText" : "Sachsen-Anhalt",
"x" : "0.645",
"y" : "0.409"
},
{
"pixmapfile" : "germany/saarland.png",
"toolTipText" : "Saarland",
"x" : "0.13",
"y" : "0.729"
},
{
"pixmapfile" : "germany/rheinland-pfalz.png",
"toolTipText" : "Rheinland-Pfalz",
"x" : "0.178",
"y" : "0.656"
},
{
"pixmapfile" : "germany/nordrhein-westfalen.png",
"toolTipText" : "Nordrhein-Westfalen",
"x" : "0.221",
"y" : "0.473"
},
{
"pixmapfile" : "germany/niedersachsen.png",
"toolTipText" : "Niedersachsen",
"x" : "0.371",
"y" : "0.292"
},
{
"pixmapfile" : "germany/mecklenburg-vorpommern.png",
"toolTipText" : "Mecklenburg-Vorpommern",
"x" : "0.699",
"y" : "0.176"
},
{
"pixmapfile" : "germany/hessen.png",
"toolTipText" : "Hessen",
"x" : "0.356",
"y" : "0.587"
},
{
"pixmapfile" : "germany/hamburg.png",
"toolTipText" : "Hamburg",
"x" : "0.463",
"y" : "0.235"
},
{
"pixmapfile" : "germany/bremen.png",
"toolTipText" : "Bremen",
"x" : "0.289",
"y" : "0.252"
},
{
"pixmapfile" : "germany/brandenburg.png",
"toolTipText" : "Brandenburg",
"x" : "0.758",
"y" : "0.344"
},
{
"pixmapfile" : "germany/berlin.png",
"toolTipText" : "Berlin",
"x" : "0.823",
"y" : "0.339"
},
{
"pixmapfile" : "germany/bayern.png",
"toolTipText" : "Bayern",
"x" : "0.605",
"y" : "0.786"
},
{
"pixmapfile" : "germany/baden-wuerttemberg.png",
"toolTipText" : "Baden-Württemberg",
"x" : "0.351",
"y" : "0.817"
}
]
}
diff --git a/src/activities/geo-country/resource/board/board3_0.qml b/src/activities/geo-country/resource/board/board3_0.qml
index 4eec9d054..eac7228e0 100644
--- a/src/activities/geo-country/resource/board/board3_0.qml
+++ b/src/activities/geo-country/resource/board/board3_0.qml
@@ -1,170 +1,170 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Districts of Argentina")
property var levels: [
{
"pixmapfile" : "argentina/argentina.png",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "argentina/tucuman.png",
"toolTipText" : "Tucuman",
"x" : "0.434",
"y" : "0.178"
},
{
"pixmapfile" : "argentina/tierra_del_fuego.png",
"toolTipText" : "Tierra del Fuego",
"x" : "0.437",
"y" : "0.881"
},
{
"pixmapfile" : "argentina/santiago_del_estero.png",
"toolTipText" : "Santiago del Estero",
"x" : "0.489",
"y" : "0.192"
},
{
"pixmapfile" : "argentina/santa_fe.png",
"toolTipText" : "Santa Fe",
"x" : "0.56",
"y" : "0.283"
},
{
"pixmapfile" : "argentina/santa_cruz.png",
"toolTipText" : "Santa Cruz",
"x" : "0.363",
"y" : "0.752"
},
{
"pixmapfile" : "argentina/san_luis.png",
"toolTipText" : "San Luis",
"x" : "0.415",
"y" : "0.355"
},
{
"pixmapfile" : "argentina/san_juan.png",
"toolTipText" : "San Juan",
"x" : "0.346",
"y" : "0.269"
},
{
"pixmapfile" : "argentina/salta.png",
"toolTipText" : "Salta",
"x" : "0.432",
"y" : "0.103"
},
{
"pixmapfile" : "argentina/rio_negro.png",
"toolTipText" : "Rio Negro",
"x" : "0.4",
"y" : "0.507"
},
{
"pixmapfile" : "argentina/neuquen.png",
"toolTipText" : "Neuquen",
"x" : "0.332",
"y" : "0.481"
},
{
"pixmapfile" : "argentina/misiones.png",
"toolTipText" : "Misiones",
"x" : "0.734",
"y" : "0.178"
},
{
"pixmapfile" : "argentina/mendoza.png",
"toolTipText" : "Mendoza",
"x" : "0.36",
"y" : "0.379"
},
{
"pixmapfile" : "argentina/la_rioja.png",
"toolTipText" : "La Rioja",
"x" : "0.377",
"y" : "0.25"
},
{
"pixmapfile" : "argentina/la_pampa.png",
"toolTipText" : "La Pampa",
"x" : "0.432",
"y" : "0.437"
},
{
"pixmapfile" : "argentina/jujuy.png",
"toolTipText" : "Jujuy",
"x" : "0.42",
"y" : "0.075"
},
{
"pixmapfile" : "argentina/formosa.png",
"toolTipText" : "Formosa",
"x" : "0.588",
"y" : "0.117"
},
{
"pixmapfile" : "argentina/entre_rios.png",
"toolTipText" : "Entre Rios",
"x" : "0.6",
"y" : "0.308"
},
{
"pixmapfile" : "argentina/corrientes.png",
"toolTipText" : "Corrientes",
"x" : "0.648",
"y" : "0.227"
},
{
"pixmapfile" : "argentina/cordoba.png",
"toolTipText" : "Cordoba",
"x" : "0.477",
"y" : "0.311"
},
{
"pixmapfile" : "argentina/chubut.png",
"toolTipText" : "Chubut",
"x" : "0.389",
"y" : "0.617"
},
{
"pixmapfile" : "argentina/chaco.png",
"toolTipText" : "Chaco",
"x" : "0.563",
"y" : "0.152"
},
{
"pixmapfile" : "argentina/catamarca.png",
"toolTipText" : "Catamarca",
"x" : "0.389",
"y" : "0.189"
},
{
"pixmapfile" : "argentina/buenos_aires.png",
"toolTipText" : "Buenos Aires",
"x" : "0.577",
"y" : "0.439"
}
]
}
diff --git a/src/activities/geo-country/resource/board/board4_0.qml b/src/activities/geo-country/resource/board/board4_0.qml
index 25ccc03ee..0d9b3d07b 100644
--- a/src/activities/geo-country/resource/board/board4_0.qml
+++ b/src/activities/geo-country/resource/board/board4_0.qml
@@ -1,128 +1,128 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Districts of Poland")
property var levels: [
{
"pixmapfile" : "poland/poland.png",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "poland/dolnoslaskie.png",
"toolTipText" : "Dolnoslaskie",
"x" : "0.202",
"y" : "0.664"
},
{
"pixmapfile" : "poland/zachodnio-pomorskie.png",
"toolTipText" : "Zachodnio Pomorskie",
"x" : "0.14",
"y" : "0.203"
},
{
"pixmapfile" : "poland/wielkopolskie.png",
"toolTipText" : "Wielkopolskie",
"x" : "0.32",
"y" : "0.422"
},
{
"pixmapfile" : "poland/warminsko-mazurskie.png",
"toolTipText" : "Warminsko-Mazurskie",
"x" : "0.66",
"y" : "0.18"
},
{
"pixmapfile" : "poland/swietokrzyskie.png",
"toolTipText" : "Swietokrzyskie",
"x" : "0.656",
"y" : "0.702"
},
{
"pixmapfile" : "poland/slaskie.png",
"toolTipText" : "Slaskie",
"x" : "0.47",
"y" : "0.795"
},
{
"pixmapfile" : "poland/pomorskie.png",
"toolTipText" : "Pomorskie",
"x" : "0.396",
"y" : "0.113"
},
{
"pixmapfile" : "poland/podlaskie.png",
"toolTipText" : "Podlaskie",
"x" : "0.842",
"y" : "0.247"
},
{
"pixmapfile" : "poland/podkarpackie.png",
"toolTipText" : "Podkarpackie",
"x" : "0.818",
"y" : "0.841"
},
{
"pixmapfile" : "poland/opolskie.png",
"toolTipText" : "Opolskie",
"x" : "0.35",
"y" : "0.734"
},
{
"pixmapfile" : "poland/mazowieckie.png",
"toolTipText" : "Mazowieckie",
"x" : "0.692",
"y" : "0.447"
},
{
"pixmapfile" : "poland/malopolskie.png",
"toolTipText" : "Malopolskie",
"x" : "0.604",
"y" : "0.862"
},
{
"pixmapfile" : "poland/lodzkie.png",
"toolTipText" : "Lódzkie",
"x" : "0.512",
"y" : "0.557"
},
{
"pixmapfile" : "poland/lubuskie.png",
"toolTipText" : "Lubuskie",
"x" : "0.124",
"y" : "0.437"
},
{
"pixmapfile" : "poland/lubelskie.png",
"toolTipText" : "Lubelskie",
"x" : "0.868",
"y" : "0.605"
},
{
"pixmapfile" : "poland/kujawsko-pomorskie.png",
"toolTipText" : "Kujawsko-Pomorskie",
"x" : "0.426",
"y" : "0.308"
}
]
}
diff --git a/src/activities/geo-country/resource/board/board5_0.qml b/src/activities/geo-country/resource/board/board5_0.qml
index 6e01cb8e3..e92b8358d 100644
--- a/src/activities/geo-country/resource/board/board5_0.qml
+++ b/src/activities/geo-country/resource/board/board5_0.qml
@@ -1,321 +1,321 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property int numberOfSubLevel: 2
property string instruction: qsTr("Districts of Turkey")
property var levels: [
{
"pixmapfile" : "turkey/turkey-west.png",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "turkey/zonguldak.png",
"toolTipText" : "Zonguldak",
"x" : "0.533",
"y" : "0.15"
},
{
"pixmapfile" : "turkey/yozgat.png",
"toolTipText" : "Yozgat",
"x" : "0.806",
"y" : "0.398"
},
{
"pixmapfile" : "turkey/yalova.png",
"toolTipText" : "Yalova",
"x" : "0.296",
"y" : "0.239"
},
{
"pixmapfile" : "turkey/usak.png",
"toolTipText" : "Usak",
"x" : "0.3",
"y" : "0.515"
},
{
"pixmapfile" : "turkey/tekirdag.png",
"toolTipText" : "Tekirdag",
"x" : "0.167",
"y" : "0.155"
},
{
"pixmapfile" : "turkey/sinop.png",
"toolTipText" : "Sinop",
"x" : "0.794",
"y" : "0.114"
},
{
"pixmapfile" : "turkey/samsun.png",
"toolTipText" : "Samsun",
"x" : "0.886",
"y" : "0.162"
},
{
"pixmapfile" : "turkey/sakarya.png",
"toolTipText" : "Sakarya",
"x" : "0.414",
"y" : "0.221"
},
{
"pixmapfile" : "turkey/osmaniye.png",
"toolTipText" : "Osmaniye",
"x" : "0.91",
"y" : "0.692"
},
{
"pixmapfile" : "turkey/nigde.png",
"toolTipText" : "Nigde",
"x" : "0.765",
"y" : "0.638"
},
{
"pixmapfile" : "turkey/nevsehir.png",
"toolTipText" : "Nevsehir",
"x" : "0.765",
"y" : "0.5"
},
{
"pixmapfile" : "turkey/mugla.png",
"toolTipText" : "Mugla",
"x" : "0.206",
"y" : "0.733"
},
{
"pixmapfile" : "turkey/mersin.png",
"toolTipText" : "Mersin",
"x" : "0.688",
"y" : "0.794"
},
{
"pixmapfile" : "turkey/manisa.png",
"toolTipText" : "Manisa",
"x" : "0.196",
"y" : "0.477"
},
{
"pixmapfile" : "turkey/kutahya.png",
"toolTipText" : "Kütahya",
"x" : "0.32",
"y" : "0.413"
},
{
"pixmapfile" : "turkey/konya.png",
"toolTipText" : "Konya",
"x" : "0.602",
"y" : "0.62"
},
{
"pixmapfile" : "turkey/kocaeli.png",
"toolTipText" : "Kocaeli",
"x" : "0.367",
"y" : "0.198"
},
{
"pixmapfile" : "turkey/kirsehir.png",
"toolTipText" : "Kirsehir",
"x" : "0.718",
"y" : "0.431"
},
{
"pixmapfile" : "turkey/kirklareli.png",
"toolTipText" : "Kirklareli",
"x" : "0.178",
"y" : "0.07"
},
{
"pixmapfile" : "turkey/kirikkale.png",
"toolTipText" : "Kirikkale",
"x" : "0.686",
"y" : "0.362"
},
{
"pixmapfile" : "turkey/kayseri.png",
"toolTipText" : "Kayseri",
"x" : "0.869",
"y" : "0.543"
},
{
"pixmapfile" : "turkey/kastamonu.png",
"toolTipText" : "Kastamonu",
"x" : "0.69",
"y" : "0.142"
},
{
"pixmapfile" : "turkey/karaman.png",
"toolTipText" : "Karaman",
"x" : "0.627",
"y" : "0.748"
},
{
"pixmapfile" : "turkey/karabuk.png",
"toolTipText" : "Karabük",
"x" : "0.59",
"y" : "0.188"
},
{
"pixmapfile" : "turkey/izmir.png",
"toolTipText" : "Izmir",
"x" : "0.129",
"y" : "0.485"
},
{
"pixmapfile" : "turkey/istanbul.png",
"toolTipText" : "Istanbul",
"x" : "0.292",
"y" : "0.157"
},
{
"pixmapfile" : "turkey/isparta.png",
"toolTipText" : "Isparta",
"x" : "0.42",
"y" : "0.618"
},
{
"pixmapfile" : "turkey/hatay.png",
"toolTipText" : "Hatay",
"x" : "0.916",
"y" : "0.835"
},
{
"pixmapfile" : "turkey/eskisehir.png",
"toolTipText" : "Eskisehir",
"x" : "0.457",
"y" : "0.38"
},
{
"pixmapfile" : "turkey/edirne.png",
"toolTipText" : "Edirne",
"x" : "0.096",
"y" : "0.104"
},
{
"pixmapfile" : "turkey/duzce.png",
"toolTipText" : "Düzce",
"x" : "0.476",
"y" : "0.201"
},
{
"pixmapfile" : "turkey/denizli.png",
"toolTipText" : "Denizli",
"x" : "0.29",
"y" : "0.633"
},
{
"pixmapfile" : "turkey/corum.png",
"toolTipText" : "Çorum",
"x" : "0.78",
"y" : "0.265"
},
{
"pixmapfile" : "turkey/cankiri.png",
"toolTipText" : "Çankiri",
"x" : "0.665",
"y" : "0.244"
},
{
"pixmapfile" : "turkey/canakkale.png",
"toolTipText" : "Çanakkale",
"x" : "0.084",
"y" : "0.27"
},
{
"pixmapfile" : "turkey/bursa.png",
"toolTipText" : "Bursa",
"x" : "0.296",
"y" : "0.306"
},
{
"pixmapfile" : "turkey/burdur.png",
"toolTipText" : "Burdur",
"x" : "0.355",
"y" : "0.682"
},
{
"pixmapfile" : "turkey/bolu.png",
"toolTipText" : "Bolu",
"x" : "0.5",
"y" : "0.242"
},
{
"pixmapfile" : "turkey/bilecik.png",
"toolTipText" : "Bilecik",
"x" : "0.382",
"y" : "0.311"
},
{
"pixmapfile" : "turkey/bartin.png",
"toolTipText" : "Bartin",
"x" : "0.594",
"y" : "0.114"
},
{
"pixmapfile" : "turkey/balikesir.png",
"toolTipText" : "Balikesir",
"x" : "0.18",
"y" : "0.321"
},
{
"pixmapfile" : "turkey/aydin.png",
"toolTipText" : "Aydin",
"x" : "0.171",
"y" : "0.61"
},
{
"pixmapfile" : "turkey/antalya.png",
"toolTipText" : "Antalya",
"x" : "0.424",
"y" : "0.779"
},
{
"pixmapfile" : "turkey/ankara.png",
"toolTipText" : "Ankara",
"x" : "0.571",
"y" : "0.382"
},
{
"pixmapfile" : "turkey/amasya.png",
"toolTipText" : "Amasya",
"x" : "0.863",
"y" : "0.252"
},
{
"pixmapfile" : "turkey/aksaray.png",
"toolTipText" : "Aksaray",
"x" : "0.694",
"y" : "0.551"
},
{
"pixmapfile" : "turkey/afyon.png",
"toolTipText" : "Afyon",
"x" : "0.412",
"y" : "0.536"
},
{
"pixmapfile" : "turkey/adana.png",
"toolTipText" : "Adana",
"x" : "0.841",
"y" : "0.687"
}
]
}
diff --git a/src/activities/geo-country/resource/board/board5_1.qml b/src/activities/geo-country/resource/board/board5_1.qml
index ed9acc437..3ef81b4f8 100644
--- a/src/activities/geo-country/resource/board/board5_1.qml
+++ b/src/activities/geo-country/resource/board/board5_1.qml
@@ -1,242 +1,242 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Eastern Districts of Turkey")
property var levels: [
{
"pixmapfile" : "turkey/turkey-east.png",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "turkey/van.png",
"toolTipText" : "Van",
"x" : "0.85",
"y" : "0.492"
},
{
"pixmapfile" : "turkey/tunceli.png",
"toolTipText" : "Tunceli",
"x" : "0.413",
"y" : "0.433"
},
{
"pixmapfile" : "turkey/trabzon.png",
"toolTipText" : "Trabzon",
"x" : "0.435",
"y" : "0.21"
},
{
"pixmapfile" : "turkey/tokat.png",
"toolTipText" : "Tokat",
"x" : "0.098",
"y" : "0.287"
},
{
"pixmapfile" : "turkey/sivas.png",
"toolTipText" : "Sivas",
"x" : "0.163",
"y" : "0.405"
},
{
"pixmapfile" : "turkey/sirnak.png",
"toolTipText" : "Sirnak",
"x" : "0.733",
"y" : "0.662"
},
{
"pixmapfile" : "turkey/siirt.png",
"toolTipText" : "Siirt",
"x" : "0.7",
"y" : "0.597"
},
{
"pixmapfile" : "turkey/sanliurfa.png",
"toolTipText" : "Sanliurfa",
"x" : "0.368",
"y" : "0.69"
},
{
"pixmapfile" : "turkey/rize.png",
"toolTipText" : "Rize",
"x" : "0.543",
"y" : "0.177"
},
{
"pixmapfile" : "turkey/osmaniye.png",
"toolTipText" : "Osmaniye",
"x" : "0.065",
"y" : "0.695"
},
{
"pixmapfile" : "turkey/ordu.png",
"toolTipText" : "Ordu",
"x" : "0.188",
"y" : "0.231"
},
{
"pixmapfile" : "turkey/mus.png",
"toolTipText" : "Mus",
"x" : "0.67",
"y" : "0.444"
},
{
"pixmapfile" : "turkey/mardin.png",
"toolTipText" : "Mardin",
"x" : "0.565",
"y" : "0.685"
},
{
"pixmapfile" : "turkey/malatya.png",
"toolTipText" : "Malatya",
"x" : "0.27",
"y" : "0.528"
},
{
"pixmapfile" : "turkey/kilis.png",
"toolTipText" : "Kilis",
"x" : "0.158",
"y" : "0.774"
},
{
"pixmapfile" : "turkey/kars.png",
"toolTipText" : "Kars",
"x" : "0.76",
"y" : "0.223"
},
{
"pixmapfile" : "turkey/kahramanmaras.png",
"toolTipText" : "Kahramanmaras",
"x" : "0.14",
"y" : "0.621"
},
{
"pixmapfile" : "turkey/igdir.png",
"toolTipText" : "Igdir",
"x" : "0.875",
"y" : "0.297"
},
{
"pixmapfile" : "turkey/hatay.png",
"toolTipText" : "Hatay",
"x" : "0.073",
"y" : "0.836"
},
{
"pixmapfile" : "turkey/hakkari.png",
"toolTipText" : "Hakkari",
"x" : "0.903",
"y" : "0.633"
},
{
"pixmapfile" : "turkey/gumushane.png",
"toolTipText" : "Gümüshane",
"x" : "0.38",
"y" : "0.277"
},
{
"pixmapfile" : "turkey/giresun.png",
"toolTipText" : "Giresun",
"x" : "0.298",
"y" : "0.251"
},
{
"pixmapfile" : "turkey/gaziantep.png",
"toolTipText" : "Gaziantep",
"x" : "0.173",
"y" : "0.744"
},
{
"pixmapfile" : "turkey/erzurum.png",
"toolTipText" : "Erzurum",
"x" : "0.605",
"y" : "0.29"
},
{
"pixmapfile" : "turkey/erzincan.png",
"toolTipText" : "Erzincan",
"x" : "0.395",
"y" : "0.382"
},
{
"pixmapfile" : "turkey/elazig.png",
"toolTipText" : "Elazig",
"x" : "0.39",
"y" : "0.49"
},
{
"pixmapfile" : "turkey/diyarbakir.png",
"toolTipText" : "Diyarbakir",
"x" : "0.493",
"y" : "0.577"
},
{
"pixmapfile" : "turkey/bitlis.png",
"toolTipText" : "Bitlis",
"x" : "0.715",
"y" : "0.505"
},
{
"pixmapfile" : "turkey/bingol.png",
"toolTipText" : "Bingöl",
"x" : "0.525",
"y" : "0.449"
},
{
"pixmapfile" : "turkey/bayburt.png",
"toolTipText" : "Bayburt",
"x" : "0.478",
"y" : "0.279"
},
{
"pixmapfile" : "turkey/batman.png",
"toolTipText" : "Batman",
"x" : "0.618",
"y" : "0.579"
},
{
"pixmapfile" : "turkey/artvin.png",
"toolTipText" : "Artvin",
"x" : "0.635",
"y" : "0.162"
},
{
"pixmapfile" : "turkey/ardahan.png",
"toolTipText" : "Ardahan",
"x" : "0.74",
"y" : "0.138"
},
{
"pixmapfile" : "turkey/agri.png",
"toolTipText" : "Agri",
"x" : "0.818",
"y" : "0.369"
},
{
"pixmapfile" : "turkey/adiyaman.png",
"toolTipText" : "Adiyaman",
"x" : "0.288",
"y" : "0.626"
}
]
}
diff --git a/src/activities/geo-country/resource/board/board5_2.qml b/src/activities/geo-country/resource/board/board5_2.qml
index 1a013b8b7..cc4b1a18a 100644
--- a/src/activities/geo-country/resource/board/board5_2.qml
+++ b/src/activities/geo-country/resource/board/board5_2.qml
@@ -1,518 +1,518 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Districts of Turkey")
property var levels: [
{
"pixmapfile" : "turkey/turkey.png",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "turkey/van.png",
"toolTipText" : "Van",
"x" : "0.85",
"y" : "0.495"
},
{
"pixmapfile" : "turkey/tunceli.png",
"toolTipText" : "Tunceli",
"x" : "0.677",
"y" : "0.449"
},
{
"pixmapfile" : "turkey/trabzon.png",
"toolTipText" : "Trabzon",
"x" : "0.686",
"y" : "0.269"
},
{
"pixmapfile" : "turkey/tokat.png",
"toolTipText" : "Tokat",
"x" : "0.553",
"y" : "0.331"
},
{
"pixmapfile" : "turkey/sivas.png",
"toolTipText" : "Sivas",
"x" : "0.579",
"y" : "0.426"
},
{
"pixmapfile" : "turkey/sirnak.png",
"toolTipText" : "Sirnak",
"x" : "0.803",
"y" : "0.631"
},
{
"pixmapfile" : "turkey/siirt.png",
"toolTipText" : "Siirt",
"x" : "0.791",
"y" : "0.579"
},
{
"pixmapfile" : "turkey/sanliurfa.png",
"toolTipText" : "Sanliurfa",
"x" : "0.659",
"y" : "0.654"
},
{
"pixmapfile" : "turkey/rize.png",
"toolTipText" : "Rize",
"x" : "0.728",
"y" : "0.244"
},
{
"pixmapfile" : "turkey/ordu.png",
"toolTipText" : "Ordu",
"x" : "0.589",
"y" : "0.287"
},
{
"pixmapfile" : "turkey/mus.png",
"toolTipText" : "Mus",
"x" : "0.778",
"y" : "0.456"
},
{
"pixmapfile" : "turkey/mardin.png",
"toolTipText" : "Mardin",
"x" : "0.736",
"y" : "0.649"
},
{
"pixmapfile" : "turkey/malatya.png",
"toolTipText" : "Malatya",
"x" : "0.621",
"y" : "0.523"
},
{
"pixmapfile" : "turkey/kilis.png",
"toolTipText" : "Kilis",
"x" : "0.576",
"y" : "0.721"
},
{
"pixmapfile" : "turkey/kars.png",
"toolTipText" : "Kars",
"x" : "0.814",
"y" : "0.279"
},
{
"pixmapfile" : "turkey/kahramanmaras.png",
"toolTipText" : "Kahramanmaras",
"x" : "0.569",
"y" : "0.597"
},
{
"pixmapfile" : "turkey/igdir.png",
"toolTipText" : "Igdir",
"x" : "0.86",
"y" : "0.338"
},
{
"pixmapfile" : "turkey/hatay.png",
"toolTipText" : "Hatay",
"x" : "0.543",
"y" : "0.769"
},
{
"pixmapfile" : "turkey/hakkari.png",
"toolTipText" : "Hakkari",
"x" : "0.869",
"y" : "0.608"
},
{
"pixmapfile" : "turkey/gumushane.png",
"toolTipText" : "gümüshane",
"x" : "0.664",
"y" : "0.323"
},
{
"pixmapfile" : "turkey/giresun.png",
"toolTipText" : "Giresun",
"x" : "0.632",
"y" : "0.303"
},
{
"pixmapfile" : "turkey/gaziantep.png",
"toolTipText" : "Gaziantep",
"x" : "0.583",
"y" : "0.697"
},
{
"pixmapfile" : "turkey/erzurum.png",
"toolTipText" : "Erzurum",
"x" : "0.752",
"y" : "0.333"
},
{
"pixmapfile" : "turkey/erzincan.png",
"toolTipText" : "Erzincan",
"x" : "0.67",
"y" : "0.408"
},
{
"pixmapfile" : "turkey/elazig.png",
"toolTipText" : "Elazig",
"x" : "0.667",
"y" : "0.492"
},
{
"pixmapfile" : "turkey/diyarbakir.png",
"toolTipText" : "Diyarbakir",
"x" : "0.708",
"y" : "0.564"
},
{
"pixmapfile" : "turkey/bitlis.png",
"toolTipText" : "Bitlis",
"x" : "0.796",
"y" : "0.505"
},
{
"pixmapfile" : "turkey/bingol.png",
"toolTipText" : "Bingöl",
"x" : "0.722",
"y" : "0.462"
},
{
"pixmapfile" : "turkey/bayburt.png",
"toolTipText" : "Bayburt",
"x" : "0.702",
"y" : "0.326"
},
{
"pixmapfile" : "turkey/batman.png",
"toolTipText" : "Batman",
"x" : "0.757",
"y" : "0.564"
},
{
"pixmapfile" : "turkey/artvin.png",
"toolTipText" : "Artvin",
"x" : "0.765",
"y" : "0.231"
},
{
"pixmapfile" : "turkey/ardahan.png",
"toolTipText" : "Ardahan",
"x" : "0.805",
"y" : "0.213"
},
{
"pixmapfile" : "turkey/agri.png",
"toolTipText" : "Agri",
"x" : "0.836",
"y" : "0.397"
},
{
"pixmapfile" : "turkey/adiyaman.png",
"toolTipText" : "Adiyaman",
"x" : "0.628",
"y" : "0.603"
},
{
"pixmapfile" : "turkey/zonguldak.png",
"toolTipText" : "Zonguldak",
"x" : "0.356",
"y" : "0.221"
},
{
"pixmapfile" : "turkey/yozgat.png",
"toolTipText" : "Yozgat",
"x" : "0.489",
"y" : "0.421"
},
{
"pixmapfile" : "turkey/yalova.png",
"toolTipText" : "Yalova",
"x" : "0.243",
"y" : "0.292"
},
{
"pixmapfile" : "turkey/usak.png",
"toolTipText" : "Usak",
"x" : "0.244",
"y" : "0.513"
},
{
"pixmapfile" : "turkey/tekirdag.png",
"toolTipText" : "Tekirdag",
"x" : "0.18",
"y" : "0.226"
},
{
"pixmapfile" : "turkey/sinop.png",
"toolTipText" : "Sinop",
"x" : "0.483",
"y" : "0.192"
},
{
"pixmapfile" : "turkey/samsun.png",
"toolTipText" : "Samsun",
"x" : "0.527",
"y" : "0.231"
},
{
"pixmapfile" : "turkey/sakarya.png",
"toolTipText" : "Sakarya",
"x" : "0.299",
"y" : "0.277"
},
{
"pixmapfile" : "turkey/osmaniye.png",
"toolTipText" : "Osmaniye",
"x" : "0.538",
"y" : "0.656"
},
{
"pixmapfile" : "turkey/nigde.png",
"toolTipText" : "Nigde",
"x" : "0.469",
"y" : "0.613"
},
{
"pixmapfile" : "turkey/nevsehir.png",
"toolTipText" : "Nevsehir",
"x" : "0.469",
"y" : "0.503"
},
{
"pixmapfile" : "turkey/mugla.png",
"toolTipText" : "Mugla",
"x" : "0.198",
"y" : "0.687"
},
{
"pixmapfile" : "turkey/mersin.png",
"toolTipText" : "Mersin",
"x" : "0.431",
"y" : "0.738"
},
{
"pixmapfile" : "turkey/manisa.png",
"toolTipText" : "Manisa",
"x" : "0.193",
"y" : "0.482"
},
{
"pixmapfile" : "turkey/kutahya.png",
"toolTipText" : "Kütahya",
"x" : "0.254",
"y" : "0.431"
},
{
"pixmapfile" : "turkey/konya.png",
"toolTipText" : "Konya",
"x" : "0.39",
"y" : "0.597"
},
{
"pixmapfile" : "turkey/kocaeli.png",
"toolTipText" : "Kocaeli",
"x" : "0.277",
"y" : "0.259"
},
{
"pixmapfile" : "turkey/kirsehir.png",
"toolTipText" : "Kirsehir",
"x" : "0.446",
"y" : "0.446"
},
{
"pixmapfile" : "turkey/kirklareli.png",
"toolTipText" : "Kirklareli",
"x" : "0.185",
"y" : "0.156"
},
{
"pixmapfile" : "turkey/kirikkale.png",
"toolTipText" : "Kirikkale",
"x" : "0.43",
"y" : "0.39"
},
{
"pixmapfile" : "turkey/kayseri.png",
"toolTipText" : "Kayseri",
"x" : "0.518",
"y" : "0.536"
},
{
"pixmapfile" : "turkey/kastamonu.png",
"toolTipText" : "Kastamonu",
"x" : "0.432",
"y" : "0.215"
},
{
"pixmapfile" : "turkey/karaman.png",
"toolTipText" : "Karaman",
"x" : "0.401",
"y" : "0.7"
},
{
"pixmapfile" : "turkey/karabuk.png",
"toolTipText" : "Karabuk",
"x" : "0.384",
"y" : "0.251"
},
{
"pixmapfile" : "turkey/izmir.png",
"toolTipText" : "Izmir",
"x" : "0.161",
"y" : "0.49"
},
{
"pixmapfile" : "turkey/istanbul.png",
"toolTipText" : "Istanbul",
"x" : "0.24",
"y" : "0.226"
},
{
"pixmapfile" : "turkey/isparta.png",
"toolTipText" : "Isparta",
"x" : "0.302",
"y" : "0.595"
},
{
"pixmapfile" : "turkey/eskisehir.png",
"toolTipText" : "Eskisehir",
"x" : "0.32",
"y" : "0.405"
},
{
"pixmapfile" : "turkey/edirne.png",
"toolTipText" : "Edirne",
"x" : "0.145",
"y" : "0.185"
},
{
"pixmapfile" : "turkey/duzce.png",
"toolTipText" : "Düzce",
"x" : "0.329",
"y" : "0.262"
},
{
"pixmapfile" : "turkey/denizli.png",
"toolTipText" : "Denizli",
"x" : "0.239",
"y" : "0.608"
},
{
"pixmapfile" : "turkey/corum.png",
"toolTipText" : "Çorum",
"x" : "0.475",
"y" : "0.313"
},
{
"pixmapfile" : "turkey/cankiri.png",
"toolTipText" : "Çankiri",
"x" : "0.42",
"y" : "0.297"
},
{
"pixmapfile" : "turkey/canakkale.png",
"toolTipText" : "Çanakkale",
"x" : "0.139",
"y" : "0.318"
},
{
"pixmapfile" : "turkey/bursa.png",
"toolTipText" : "Bursa",
"x" : "0.243",
"y" : "0.346"
},
{
"pixmapfile" : "turkey/burdur.png",
"toolTipText" : "Burdur",
"x" : "0.271",
"y" : "0.646"
},
{
"pixmapfile" : "turkey/bolu.png",
"toolTipText" : "Bolu",
"x" : "0.341",
"y" : "0.295"
},
{
"pixmapfile" : "turkey/bilecik.png",
"toolTipText" : "Bilecik",
"x" : "0.283",
"y" : "0.349"
},
{
"pixmapfile" : "turkey/bartin.png",
"toolTipText" : "Bartin",
"x" : "0.385",
"y" : "0.192"
},
{
"pixmapfile" : "turkey/balikesir.png",
"toolTipText" : "Balikesir",
"x" : "0.186",
"y" : "0.359"
},
{
"pixmapfile" : "turkey/aydin.png",
"toolTipText" : "Aydin",
"x" : "0.182",
"y" : "0.59"
},
{
"pixmapfile" : "turkey/antalya.png",
"toolTipText" : "Antalya",
"x" : "0.304",
"y" : "0.726"
},
{
"pixmapfile" : "turkey/ankara.png",
"toolTipText" : "Ankara",
"x" : "0.376",
"y" : "0.408"
},
{
"pixmapfile" : "turkey/amasya.png",
"toolTipText" : "Amasya",
"x" : "0.516",
"y" : "0.303"
},
{
"pixmapfile" : "turkey/aksaray.png",
"toolTipText" : "Aksaray",
"x" : "0.435",
"y" : "0.544"
},
{
"pixmapfile" : "turkey/afyon.png",
"toolTipText" : "Afyon",
"x" : "0.298",
"y" : "0.531"
},
{
"pixmapfile" : "turkey/adana.png",
"toolTipText" : "Adana",
"x" : "0.505",
"y" : "0.651"
}
]
}
diff --git a/src/activities/geo-country/resource/board/board6_0.qml b/src/activities/geo-country/resource/board/board6_0.qml
index 820f4c5b7..e3f1e3e2c 100644
--- a/src/activities/geo-country/resource/board/board6_0.qml
+++ b/src/activities/geo-country/resource/board/board6_0.qml
@@ -1,140 +1,140 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Counties of Norway")
property var levels: [
{
"pixmapfile" : "norway/norway.png",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "norway/telemark.png",
"toolTipText" : "Telemark",
"x" : "0.208",
"y" : "0.849"
},
{
"pixmapfile" : "norway/ostfold.png",
"toolTipText" : "Østfold",
"x" : "0.319",
"y" : "0.871"
},
{
"pixmapfile" : "norway/nordland.png",
"toolTipText" : "Nordland",
"x" : "0.469",
"y" : "0.352"
},
{
"pixmapfile" : "norway/finnmark.png",
"toolTipText" : "Finnmark",
"x" : "0.787",
"y" : "0.152"
},
{
"pixmapfile" : "norway/vestfold.png",
"toolTipText" : "Vestfold",
"x" : "0.275",
"y" : "0.862"
},
{
"pixmapfile" : "norway/trondelag.png",
"toolTipText" : "Trøndelag",
"x" : "0.338",
"y" : "0.58"
},
{
"pixmapfile" : "norway/oslo.png",
"toolTipText" : "Oslo",
"x" : "0.304",
"y" : "0.838"
},
{
"pixmapfile" : "norway/more-og-romsdal.png",
"toolTipText" : "Møre og Romsdal",
"x" : "0.196",
"y" : "0.632"
},
{
"pixmapfile" : "norway/buskerud.png",
"toolTipText" : "Buskerud",
"x" : "0.234",
"y" : "0.799"
},
{
"pixmapfile" : "norway/vest-agder.png",
"toolTipText" : "Vest-Agder",
"x" : "0.15",
"y" : "0.901"
},
{
"pixmapfile" : "norway/sogn-og-fjordane.png",
"toolTipText" : "Sogn og Fjordane",
"x" : "0.15",
"y" : "0.712"
},
{
"pixmapfile" : "norway/oppland.png",
"toolTipText" : "Oppland",
"x" : "0.251",
"y" : "0.734"
},
{
"pixmapfile" : "norway/hordaland.png",
"toolTipText" : "Hordaland",
"x" : "0.13",
"y" : "0.786"
},
{
"pixmapfile" : "norway/aust-agder.png",
"toolTipText" : "Aust-Agder",
"x" : "0.186",
"y" : "0.881"
},
{
"pixmapfile" : "norway/troms.png",
"toolTipText" : "Troms",
"x" : "0.594",
"y" : "0.201"
},
{
"pixmapfile" : "norway/rogaland.png",
"toolTipText" : "Rogaland",
"x" : "0.114",
"y" : "0.868"
},
{
"pixmapfile" : "norway/hedmark.png",
"toolTipText" : "Hedmark",
"x" : "0.329",
"y" : "0.737"
},
{
"pixmapfile" : "norway/akershus.png",
"toolTipText" : "Akershus",
"x" : "0.319",
"y" : "0.817"
}
]
}
diff --git a/src/activities/geo-country/resource/board/board7_0.qml b/src/activities/geo-country/resource/board/board7_0.qml
index 418ae4bfd..148b0ccff 100644
--- a/src/activities/geo-country/resource/board/board7_0.qml
+++ b/src/activities/geo-country/resource/board/board7_0.qml
@@ -1,194 +1,194 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Counties of Brazil")
property var levels: [
{
"pixmapfile" : "brazil/background.png",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "brazil/Amazonas.png",
"toolTipText" : "Amazonas",
"x" : "0.269",
"y" : "0.266"
},
{
"pixmapfile" : "brazil/Para.png",
"toolTipText" : "Pará",
"x" : "0.538",
"y" : "0.259"
},
{
"pixmapfile" : "brazil/Mato_Grosso.png",
"toolTipText" : "Mato Grosso",
"x" : "0.467",
"y" : "0.466"
},
{
"pixmapfile" : "brazil/Minas_Gerais.png",
"toolTipText" : "Minas Gerais",
"x" : "0.692",
"y" : "0.597"
},
{
"pixmapfile" : "brazil/Bahia.png",
"toolTipText" : "Bahia",
"x" : "0.764",
"y" : "0.481"
},
{
"pixmapfile" : "brazil/Mato_Grosso_do_Sul.png",
"toolTipText" : "Mato Grosso do Sul",
"x" : "0.497",
"y" : "0.642"
},
{
"pixmapfile" : "brazil/Goias.png",
"toolTipText" : "Goiás",
"x" : "0.601",
"y" : "0.539"
},
{
"pixmapfile" : "brazil/Maranhao.png",
"toolTipText" : "Maranhão",
"x" : "0.698",
"y" : "0.305"
},
{
"pixmapfile" : "brazil/Rio_Grande_do_Sul.png",
"toolTipText" : "Rio Grande do Sul",
"x" : "0.519",
"y" : "0.865"
},
{
"pixmapfile" : "brazil/Tocantins.png",
"toolTipText" : "Tocantins",
"x" : "0.63",
"y" : "0.387"
},
{
"pixmapfile" : "brazil/Piaui.png",
"toolTipText" : "Piauí",
"x" : "0.74",
"y" : "0.331"
},
{
"pixmapfile" : "brazil/Sao_Paulo.png",
"toolTipText" : "São Paulo",
"x" : "0.627",
"y" : "0.685"
},
{
"pixmapfile" : "brazil/Rondonia.png",
"toolTipText" : "Rondônia",
"x" : "0.322",
"y" : "0.422"
},
{
"pixmapfile" : "brazil/Roraima.png",
"toolTipText" : "Roraima",
"x" : "0.345",
"y" : "0.133"
},
{
"pixmapfile" : "brazil/Parana.png",
"toolTipText" : "Paraná",
"x" : "0.565",
"y" : "0.733"
},
{
"pixmapfile" : "brazil/Acre.png",
"toolTipText" : "Acre",
"x" : "0.159",
"y" : "0.386"
},
{
"pixmapfile" : "brazil/Ceara.png",
"toolTipText" : "Ceará",
"x" : "0.82",
"y" : "0.296"
},
{
"pixmapfile" : "brazil/Amapa.png",
"toolTipText" : "Amapá",
"x" : "0.546",
"y" : "0.14"
},
{
"pixmapfile" : "brazil/Pernambuco.png",
"toolTipText" : "Pernambuco",
"x" : "0.853",
"y" : "0.368"
},
{
"pixmapfile" : "brazil/Santa_Catarina.png",
"toolTipText" : "Santa Catarina",
"x" : "0.57",
"y" : "0.8"
},
{
"pixmapfile" : "brazil/Paraiba.png",
"toolTipText" : "Paraíba",
"x" : "0.878",
"y" : "0.34"
},
{
"pixmapfile" : "brazil/Rio_Grande_do_Norte.png",
"toolTipText" : "Rio Grande do Norte",
"x" : "0.883",
"y" : "0.308"
},
{
"pixmapfile" : "brazil/Espirito_Santo.png",
"toolTipText" : "Espírito Santo",
"x" : "0.794",
"y" : "0.619"
},
{
"pixmapfile" : "brazil/Rio_de_Janeiro.png",
"toolTipText" : "Rio de Janeiro",
"x" : "0.752",
"y" : "0.673"
},
{
"pixmapfile" : "brazil/Alagoas.png",
"toolTipText" : "Alagoas",
"x" : "0.879",
"y" : "0.395"
},
{
"pixmapfile" : "brazil/Sergipe.png",
"toolTipText" : "Sergipe",
"x" : "0.866",
"y" : "0.418"
},
{
"pixmapfile" : "brazil/Distrito_Federal.png",
"toolTipText" : "Distrito Federal",
"x" : "0.641",
"y" : "0.533"
}
]
}
diff --git a/src/activities/geo-country/resource/board/board8_0.qml b/src/activities/geo-country/resource/board/board8_0.qml
index a4d934c63..60079d8bb 100644
--- a/src/activities/geo-country/resource/board/board8_0.qml
+++ b/src/activities/geo-country/resource/board/board8_0.qml
@@ -1,110 +1,110 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Districts of Canada")
property var levels: [
{
"pixmapfile" : "canada/background.png",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "canada/yukon.png",
"toolTipText" : "Yukon",
"x" : "0.074",
"y" : "0.372"
},
{
"pixmapfile" : "canada/british_columbia.png",
"toolTipText" : "British Columbia",
"x" : "0.083",
"y" : "0.597"
},
{
"pixmapfile" : "canada/northwest_territories.png",
"toolTipText" : "Northwest Territories",
"x" : "0.243",
"y" : "0.365"
},
{
"pixmapfile" : "canada/nunavut.png",
"toolTipText" : "Nunavut",
"x" : "0.469",
"y" : "0.306"
},
{
"pixmapfile" : "canada/alberta.png",
"toolTipText" : "Alberta",
"x" : "0.204",
"y" : "0.661"
},
{
"pixmapfile" : "canada/saskatchewan.png",
"toolTipText" : "Saskatchewan",
"x" : "0.291",
"y" : "0.688"
},
{
"pixmapfile" : "canada/manitoba.png",
"toolTipText" : "Manitoba",
"x" : "0.417",
"y" : "0.698"
},
{
"pixmapfile" : "canada/ontario.png",
"toolTipText" : "Ontario",
"x" : "0.582",
"y" : "0.805"
},
{
"pixmapfile" : "canada/quebec.png",
"toolTipText" : "Quebec",
"x" : "0.742",
"y" : "0.673"
},
{
"pixmapfile" : "canada/newfoundland_labrador.png",
"toolTipText" : "Newfoundland and Labrador",
"x" : "0.87",
"y" : "0.603"
},
{
"pixmapfile" : "canada/new_brunswick.png",
"toolTipText" : "New Brunswick",
"x" : "0.834",
"y" : "0.779"
},
{
"pixmapfile" : "canada/nova_scotia.png",
"toolTipText" : "Nova Scotia",
"x" : "0.894",
"y" : "0.782"
},
{
"pixmapfile" : "canada/prince_edward_island.png",
"toolTipText" : "Prince Edward Island",
"x" : "0.878",
"y" : "0.757"
}
]
}
diff --git a/src/activities/geo-country/resource/board/board9_0.qml b/src/activities/geo-country/resource/board/board9_0.qml
index ca4d6ff88..7e826c692 100644
--- a/src/activities/geo-country/resource/board/board9_0.qml
+++ b/src/activities/geo-country/resource/board/board9_0.qml
@@ -1,224 +1,224 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Districts of Mexico")
property var levels: [
{
"pixmapfile" : "mexico/background.png",
"type" : "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile" : "mexico/zacatecas.png",
"toolTipText" : "Zacatecas",
"x" : "0.451",
"y" : "0.554"
},
{
"pixmapfile" : "mexico/yucatan.png",
"toolTipText" : "Yucatan",
"x" : "0.923",
"y" : "0.662"
},
{
"pixmapfile" : "mexico/veracruz.png",
"toolTipText" : "Veracruz",
"x" : "0.68",
"y" : "0.73"
},
{
"pixmapfile" : "mexico/tlaxcala.png",
"toolTipText" : "Tlaxcala",
"x" : "0.604",
"y" : "0.752"
},
{
"pixmapfile" : "mexico/tamaulipas.png",
"toolTipText" : "Tamaulipas",
"x" : "0.585",
"y" : "0.459"
},
{
"pixmapfile" : "mexico/tabasco.png",
"toolTipText" : "Tabasco",
"x" : "0.807",
"y" : "0.817"
},
{
"pixmapfile" : "mexico/sonora.png",
"toolTipText" : "Sonora",
"x" : "0.167",
"y" : "0.194"
},
{
"pixmapfile" : "mexico/sinaloa.png",
"toolTipText" : "Sinaloa",
"x" : "0.288",
"y" : "0.461"
},
{
"pixmapfile" : "mexico/san_luis_potosi.png",
"toolTipText" : "San Luis Potosi",
"x" : "0.528",
"y" : "0.57"
},
{
"pixmapfile" : "mexico/quintana_roo.png",
"toolTipText" : "Quintana Roo",
"x" : "0.955",
"y" : "0.712"
},
{
"pixmapfile" : "mexico/queretaro.png",
"toolTipText" : "Queretaro",
"x" : "0.547",
"y" : "0.677"
},
{
"pixmapfile" : "mexico/puebla.png",
"toolTipText" : "Puebla",
"x" : "0.615",
"y" : "0.756"
},
{
"pixmapfile" : "mexico/oaxaca.png",
"toolTipText" : "Oaxaca",
"x" : "0.677",
"y" : "0.871"
},
{
"pixmapfile" : "mexico/nuevo_leon.png",
"toolTipText" : "Nuevo Leon",
"x" : "0.545",
"y" : "0.431"
},
{
"pixmapfile" : "mexico/nayarit.png",
"toolTipText" : "Nayarit",
"x" : "0.369",
"y" : "0.617"
},
{
"pixmapfile" : "mexico/morelos.png",
"toolTipText" : "Morelos",
"x" : "0.573",
"y" : "0.792"
},
{
"pixmapfile" : "mexico/michoacan.png",
"toolTipText" : "Michoacan",
"x" : "0.472",
"y" : "0.768"
},
{
"pixmapfile" : "mexico/jalisco.png",
"toolTipText" : "Jalisco",
"x" : "0.413",
"y" : "0.674"
},
{
"pixmapfile" : "mexico/hidalgo.png",
"toolTipText" : "Hidalgo",
"x" : "0.58",
"y" : "0.693"
},
{
"pixmapfile" : "mexico/guerrero.png",
"toolTipText" : "Guerrero",
"x" : "0.538",
"y" : "0.854"
},
{
"pixmapfile" : "mexico/guanajuato.png",
"toolTipText" : "Guanajuato",
"x" : "0.507",
"y" : "0.675"
},
{
"pixmapfile" : "mexico/estado_de_mexico.png",
"toolTipText" : "Estado de Mexico",
"x" : "0.558",
"y" : "0.758"
},
{
"pixmapfile" : "mexico/durango.png",
"toolTipText" : "Durango",
"x" : "0.377",
"y" : "0.471"
},
{
"pixmapfile" : "mexico/distrito_federal.png",
"toolTipText" : "Distrito Federal",
"x" : "0.572",
"y" : "0.763"
},
{
"pixmapfile" : "mexico/coahuila.png",
"toolTipText" : "Coahuila",
"x" : "0.477",
"y" : "0.34"
},
{
"pixmapfile" : "mexico/chiapas.png",
"toolTipText" : "Chiapas",
"x" : "0.822",
"y" : "0.91"
},
{
"pixmapfile" : "mexico/chihuahua.png",
"toolTipText" : "Chihuahua",
"x" : "0.338",
"y" : "0.247"
},
{
"pixmapfile" : "mexico/campeche.png",
"toolTipText" : "Campeche",
"x" : "0.862",
"y" : "0.749"
},
{
"pixmapfile" : "mexico/baja_california_norte.png",
"toolTipText" : "Baja California Norte",
"x" : "0.06",
"y" : "0.133"
},
{
"pixmapfile" : "mexico/baja_california_sur.png",
"toolTipText" : "Baja California Sur",
"x" : "0.129",
"y" : "0.403"
},
{
"pixmapfile" : "mexico/colima.png",
"toolTipText" : "Colima",
"x" : "0.394",
"y" : "0.771"
},
{
"pixmapfile" : "mexico/aguascalientes.png",
"toolTipText" : "Aguascalientes",
"x" : "0.455",
"y" : "0.614"
}
]
}
diff --git a/src/activities/geography/ActivityInfo.qml b/src/activities/geography/ActivityInfo.qml
index bc3a72f46..8f58637a9 100644
--- a/src/activities/geography/ActivityInfo.qml
+++ b/src/activities/geography/ActivityInfo.qml
@@ -1,44 +1,44 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Pulkit Gupta <pulkitgenius@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "geography/Geography.qml"
difficulty: 2
icon: "geography/geography.svg"
author: "Pulkit Gupta &lt;pulkitgenius@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Locate the countries")
//: Help title
description: qsTr("Drag and Drop the items to redraw the whole map")
// intro: "Drag and drop the objects to complete the map."
//: Help goal
goal: ""
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("Drag and drop the map pieces to correct locations to redraw the whole map.")
credit: ""
section: "discovery"
createdInVersion: 4000
}
diff --git a/src/activities/geography/Geography.qml b/src/activities/geography/Geography.qml
index 2a9b7fe43..a6e978367 100644
--- a/src/activities/geography/Geography.qml
+++ b/src/activities/geography/Geography.qml
@@ -1,36 +1,36 @@
/* GCompris - Geography.qml
*
* Copyright (C) 2015 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Jean-Philippe Ayanides <jp.ayanides@free.fr> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../babymatch"
Babymatch {
id: activity
onStart: focus = true
onStop: {}
soundsUrl: ""
boardsUrl: "qrc:/gcompris/src/activities/geography/resource/"
levelCount: 10
answerGlow: false
}
diff --git a/src/activities/geography/resource/board/board10_0.qml b/src/activities/geography/resource/board/board10_0.qml
index fd567157f..00add06da 100644
--- a/src/activities/geography/resource/board/board10_0.qml
+++ b/src/activities/geography/resource/board/board10_0.qml
@@ -1,186 +1,186 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Oceania")
property var levels: [
{
"pixmapfile": "oceania/bg_oceania.png",
"type": "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile": "oceania/pitcairn_islands.png",
"soundFile": "voices-$CA/$LOCALE/geography/pitcairn_islands.$CA",
"toolTipText": qsTr("Pitcairn Islands"),
"x": "0.967",
"y": "0.722"
},
{
"pixmapfile": "oceania/french_polynesia.png",
"soundFile": "voices-$CA/$LOCALE/geography/french_polynesia.$CA",
"toolTipText": qsTr("French Polynesia"),
"x": "0.875",
"y": "0.622"
},
{
"pixmapfile": "oceania/papua_new_guinea.png",
"soundFile": "voices-$CA/$LOCALE/geography/papua_new_guinea.$CA",
"toolTipText": qsTr("Papua New Guinea"),
"x": "0.314",
"y": "0.476"
},
{
"pixmapfile": "oceania/east_timor.png",
"soundFile": "voices-$CA/$LOCALE/geography/east_timor.$CA",
"toolTipText": qsTr("East Timor"),
"x": "0.131",
"y": "0.516"
},
{
"pixmapfile": "oceania/indonesia.png",
"soundFile": "voices-$CA/$LOCALE/geography/indonesia.$CA",
"toolTipText": qsTr("Indonesia"),
"x": "0.128",
"y": "0.456"
},
{
"pixmapfile": "oceania/palau.png",
"soundFile": "voices-$CA/$LOCALE/geography/palau.$CA",
"toolTipText": qsTr("Palau"),
"x": "0.179",
"y": "0.35"
},
{
"pixmapfile": "oceania/northern_mariana_islands.png",
"soundFile": "voices-$CA/$LOCALE/geography/northern_mariana_islands.$CA",
"toolTipText": qsTr("Northern Mariana Islands"),
"x": "0.288",
"y": "0.222"
},
{
"pixmapfile": "oceania/micronesia.png",
"soundFile": "voices-$CA/$LOCALE/geography/micronesia.$CA",
"toolTipText": qsTr("Micronesia"),
"x": "0.334",
"y": "0.324"
},
{
"pixmapfile": "oceania/vanuatu.png",
"soundFile": "voices-$CA/$LOCALE/geography/vanuatu.$CA",
"toolTipText": qsTr("Vanuatu"),
"x": "0.487",
"y": "0.582"
},
{
"pixmapfile": "oceania/tuvalu.png",
"soundFile": "voices-$CA/$LOCALE/geography/tuvalu.$CA",
"toolTipText": qsTr("Tuvalu"),
"x": "0.572",
"y": "0.484"
},
{
"pixmapfile": "oceania/tonga.png",
"soundFile": "voices-$CA/$LOCALE/geography/tonga.$CA",
"toolTipText": qsTr("Tonga"),
"x": "0.626",
"y": "0.608"
},
{
"pixmapfile": "oceania/new_caledonia.png",
"soundFile": "voices-$CA/$LOCALE/geography/new_caledonia.$CA",
"toolTipText": qsTr("New Caledonia"),
"x": "0.451",
"y": "0.628"
},
{
"pixmapfile": "oceania/marshall_islands.png",
"soundFile": "voices-$CA/$LOCALE/geography/marshall_islands.$CA",
"toolTipText": qsTr("Marshall Islands"),
"x": "0.49",
"y": "0.344"
},
{
"pixmapfile": "oceania/kiribati.png",
"soundFile": "voices-$CA/$LOCALE/geography/kiribati.$CA",
"toolTipText": qsTr("Kiribati"),
"x": "0.676",
"y": "0.448"
},
{
"pixmapfile": "oceania/fiji.png",
"soundFile": "voices-$CA/$LOCALE/geography/fiji.$CA",
"toolTipText": qsTr("Fiji"),
"x": "0.569",
"y": "0.586"
},
{
"pixmapfile": "oceania/solomon_islands.png",
"soundFile": "voices-$CA/$LOCALE/geography/solomon_islands.$CA",
"toolTipText": qsTr("Solomon Islands"),
"x": "0.438",
"y": "0.506"
},
{
"pixmapfile": "oceania/new_zealand.png",
"soundFile": "voices-$CA/$LOCALE/geography/new_zealand.$CA",
"toolTipText": qsTr("New Zealand"),
"x": "0.572",
"y": "0.726"
},
{
"pixmapfile": "oceania/cook_islands.png",
"soundFile": "voices-$CA/$LOCALE/geography/cook_islands.$CA",
"toolTipText": qsTr("Cook Islands"),
"x": "0.745",
"y": "0.582"
},
{
"pixmapfile": "oceania/american_samoa.png",
"soundFile": "voices-$CA/$LOCALE/geography/american_samoa.$CA",
"toolTipText": qsTr("American Samoa"),
"x": "0.662",
"y": "0.544"
},
{
"pixmapfile": "oceania/australia.png",
"soundFile": "voices-$CA/$LOCALE/geography/australia.$CA",
"toolTipText": qsTr("Australia"),
"x": "0.273",
"y": "0.748"
},
{
"pixmapfile": "oceania/us_minor.png",
"soundFile": "voices-$CA/$LOCALE/geography/us_minor.$CA",
"toolTipText": qsTr("United States Minor Outlying Islands"),
"x": "0.617",
"y": "0.258"
},
{
"pixmapfile": "oceania/hawaii.png",
"soundFile": "voices-$CA/$LOCALE/geography/hawaii.$CA",
"toolTipText": qsTr("Hawaii"),
"x": "0.722",
"y": "0.164"
}
]
}
diff --git a/src/activities/geography/resource/board/board1_0.qml b/src/activities/geography/resource/board/board1_0.qml
index 9f2585d71..90ffd84e4 100644
--- a/src/activities/geography/resource/board/board1_0.qml
+++ b/src/activities/geography/resource/board/board1_0.qml
@@ -1,74 +1,74 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Continents")
property var levels: [
{
"pixmapfile": "continents/back.png",
"type": "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile": "continents/oceania.png",
"soundFile": "voices-$CA/$LOCALE/geography/oceania.$CA",
"toolTipText": qsTr("Oceania"),
"x": "0.892",
"y": "0.822"
},
{
"pixmapfile": "continents/europa.png",
"soundFile": "voices-$CA/$LOCALE/geography/europe.$CA",
"toolTipText": qsTr("Europe"),
"x": "0.507",
"y": "0.257"
},
{
"pixmapfile": "continents/asia.png",
"soundFile": "voices-$CA/$LOCALE/geography/asia.$CA",
"toolTipText": qsTr("Asia"),
"x": "0.747",
"y": "0.386"
},
{
"pixmapfile": "continents/antarctica.png",
"soundFile": "voices-$CA/$LOCALE/geography/antarctica.$CA",
"toolTipText": qsTr("Antarctica"),
"x": "0.42",
"y": "0.979"
},
{
"pixmapfile": "continents/america.png",
"soundFile": "voices-$CA/$LOCALE/geography/america.$CA",
"toolTipText": qsTr("America"),
"x": "0.22",
"y": "0.479"
},
{
"pixmapfile": "continents/africa.png",
"soundFile": "voices-$CA/$LOCALE/geography/africa.$CA",
"toolTipText": qsTr("Africa"),
"x": "0.512",
"y": "0.636"
}
]
}
diff --git a/src/activities/geography/resource/board/board2_0.qml b/src/activities/geography/resource/board/board2_0.qml
index d86e9d1f3..d591ee647 100644
--- a/src/activities/geography/resource/board/board2_0.qml
+++ b/src/activities/geography/resource/board/board2_0.qml
@@ -1,74 +1,74 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("North America")
property var levels: [
{
"pixmapfile": "northamerica/north_america.png",
"type": "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile": "northamerica/alaska.png",
"soundFile": "voices-$CA/$LOCALE/geography/alaska.$CA",
"toolTipText": qsTr("Alaska"),
"x": "0.126",
"y": "0.177"
},
{
"pixmapfile": "northamerica/usa.png",
"soundFile": "voices-$CA/$LOCALE/geography/usa.$CA",
"toolTipText": qsTr("United States of America"),
"x": "0.358",
"y": "0.704"
},
{
"pixmapfile": "northamerica/mexico.png",
"soundFile": "voices-$CA/$LOCALE/geography/mexico.$CA",
"toolTipText": qsTr("Mexico"),
"x": "0.264",
"y": "0.835"
},
{
"pixmapfile": "northamerica/iceland.png",
"soundFile": "voices-$CA/$LOCALE/geography/iceland.$CA",
"toolTipText": qsTr("Iceland"),
"x": "0.643",
"y": "0.092"
},
{
"pixmapfile": "northamerica/greenland.png",
"soundFile": "voices-$CA/$LOCALE/geography/greenland.$CA",
"toolTipText": qsTr("Greenland"),
"x": "0.524",
"y": "0.152"
},
{
"pixmapfile": "northamerica/canada.png",
"soundFile": "voices-$CA/$LOCALE/geography/canada.$CA",
"toolTipText": qsTr("Canada"),
"x": "0.394",
"y": "0.35"
}
]
}
diff --git a/src/activities/geography/resource/board/board3_0.qml b/src/activities/geography/resource/board/board3_0.qml
index ce62cd24e..ce2c7e00e 100644
--- a/src/activities/geography/resource/board/board3_0.qml
+++ b/src/activities/geography/resource/board/board3_0.qml
@@ -1,131 +1,131 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property int numberOfSubLevel: 1
property string instruction: qsTr("Central America")
property var levels: [
{
"pixmapfile": "centralamerica/bg_central_america.png",
"type": "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile": "centralamerica/puerto_rico.png",
"soundFile": "voices-$CA/$LOCALE/geography/puerto_rico.$CA",
"toolTipText": qsTr("Puerto Rico"),
"x": "0.828",
"y": "0.498"
},
{
"pixmapfile": "centralamerica/panama.png",
"soundFile": "voices-$CA/$LOCALE/geography/panama.$CA",
"toolTipText": qsTr("Panama"),
"x": "0.453",
"y": "0.929"
},
{
"pixmapfile": "centralamerica/nicaragua.png",
"soundFile": "voices-$CA/$LOCALE/geography/nicaragua.$CA",
"toolTipText": qsTr("Nicaragua"),
"x": "0.33",
"y": "0.736"
},
{
"pixmapfile": "centralamerica/mexico.png",
"soundFile": "voices-$CA/$LOCALE/geography/mexico.$CA",
"toolTipText": qsTr("Mexico"),
"x": "0.161",
"y": "0.329"
},
{
"pixmapfile": "centralamerica/jamaica.png",
"soundFile": "voices-$CA/$LOCALE/geography/jamaica.$CA",
"toolTipText": qsTr("Jamaica"),
"x": "0.552",
"y": "0.502"
},
{
"pixmapfile": "centralamerica/honduras.png",
"soundFile": "voices-$CA/$LOCALE/geography/honduras.$CA",
"toolTipText": qsTr("Honduras"),
"x": "0.31",
"y": "0.665"
},
{
"pixmapfile": "centralamerica/haiti.png",
"soundFile": "voices-$CA/$LOCALE/geography/haiti.$CA",
"toolTipText": qsTr("Haiti"),
"x": "0.662",
"y": "0.461"
},
{
"pixmapfile": "centralamerica/guatemala.png",
"soundFile": "voices-$CA/$LOCALE/geography/guatemala.$CA",
"toolTipText": qsTr("Guatemala"),
"x": "0.211",
"y": "0.604"
},
{
"pixmapfile": "centralamerica/el_salvador.png",
"soundFile": "voices-$CA/$LOCALE/geography/salvador.$CA",
"toolTipText": qsTr("El Salvador"),
"x": "0.242",
"y": "0.695"
},
{
"pixmapfile": "centralamerica/dominican_republic.png",
"soundFile": "voices-$CA/$LOCALE/geography/dominican_republic.$CA",
"toolTipText": qsTr("Dominican Republic"),
"x": "0.733",
"y": "0.474"
},
{
"pixmapfile": "centralamerica/cuba.png",
"soundFile": "voices-$CA/$LOCALE/geography/cuba.$CA",
"toolTipText": qsTr("Cuba"),
"x": "0.507",
"y": "0.353"
},
{
"pixmapfile": "centralamerica/costa_rica.png",
"soundFile": "voices-$CA/$LOCALE/geography/costa_rica.$CA",
"toolTipText": qsTr("Costa Rica"),
"x": "0.353",
"y": "0.872"
},
{
"pixmapfile": "centralamerica/belize.png",
"soundFile": "voices-$CA/$LOCALE/geography/belize.$CA",
"toolTipText": qsTr("Belize"),
"x": "0.26",
"y": "0.543"
},
{
"pixmapfile": "centralamerica/bahamas.png",
"soundFile": "voices-$CA/$LOCALE/geography/bahamas.$CA",
"toolTipText": qsTr("Bahamas"),
"x": "0.629",
"y": "0.245"
}
]
}
diff --git a/src/activities/geography/resource/board/board3_1.qml b/src/activities/geography/resource/board/board3_1.qml
index 224d7cd89..ffd771a8e 100644
--- a/src/activities/geography/resource/board/board3_1.qml
+++ b/src/activities/geography/resource/board/board3_1.qml
@@ -1,130 +1,130 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Central America")
property var levels: [
{
"pixmapfile": "centralamerica/bg_central_america_blank.png",
"type": "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile": "centralamerica/puerto_rico.png",
"soundFile": "voices-$CA/$LOCALE/geography/puerto_rico.$CA",
"toolTipText": qsTr("Puerto Rico"),
"x": "0.828",
"y": "0.498"
},
{
"pixmapfile": "centralamerica/panama.png",
"soundFile": "voices-$CA/$LOCALE/geography/panama.$CA",
"toolTipText": qsTr("Panama"),
"x": "0.453",
"y": "0.929"
},
{
"pixmapfile": "centralamerica/nicaragua.png",
"soundFile": "voices-$CA/$LOCALE/geography/nicaragua.$CA",
"toolTipText": qsTr("Nicaragua"),
"x": "0.33",
"y": "0.736"
},
{
"pixmapfile": "centralamerica/mexico.png",
"soundFile": "voices-$CA/$LOCALE/geography/mexico.$CA",
"toolTipText": qsTr("Mexico"),
"x": "0.161",
"y": "0.329"
},
{
"pixmapfile": "centralamerica/jamaica.png",
"soundFile": "voices-$CA/$LOCALE/geography/jamaica.$CA",
"toolTipText": qsTr("Jamaica"),
"x": "0.552",
"y": "0.502"
},
{
"pixmapfile": "centralamerica/honduras.png",
"soundFile": "voices-$CA/$LOCALE/geography/honduras.$CA",
"toolTipText": qsTr("Honduras"),
"x": "0.31",
"y": "0.665"
},
{
"pixmapfile": "centralamerica/haiti.png",
"soundFile": "voices-$CA/$LOCALE/geography/haiti.$CA",
"toolTipText": qsTr("Haiti"),
"x": "0.662",
"y": "0.461"
},
{
"pixmapfile": "centralamerica/guatemala.png",
"soundFile": "voices-$CA/$LOCALE/geography/guatemala.$CA",
"toolTipText": qsTr("Guatemala"),
"x": "0.211",
"y": "0.604"
},
{
"pixmapfile": "centralamerica/el_salvador.png",
"soundFile": "voices-$CA/$LOCALE/geography/salvador.$CA",
"toolTipText": qsTr("El Salvador"),
"x": "0.242",
"y": "0.695"
},
{
"pixmapfile": "centralamerica/dominican_republic.png",
"soundFile": "voices-$CA/$LOCALE/geography/dominican_republic.$CA",
"toolTipText": qsTr("Dominican Republic"),
"x": "0.733",
"y": "0.474"
},
{
"pixmapfile": "centralamerica/cuba.png",
"soundFile": "voices-$CA/$LOCALE/geography/cuba.$CA",
"toolTipText": qsTr("Cuba"),
"x": "0.507",
"y": "0.353"
},
{
"pixmapfile": "centralamerica/costa_rica.png",
"soundFile": "voices-$CA/$LOCALE/geography/costa_rica.$CA",
"toolTipText": qsTr("Costa Rica"),
"x": "0.353",
"y": "0.872"
},
{
"pixmapfile": "centralamerica/belize.png",
"soundFile": "voices-$CA/$LOCALE/geography/belize.$CA",
"toolTipText": qsTr("Belize"),
"x": "0.26",
"y": "0.543"
},
{
"pixmapfile": "centralamerica/bahamas.png",
"soundFile": "voices-$CA/$LOCALE/geography/bahamas.$CA",
"toolTipText": qsTr("Bahamas"),
"x": "0.629",
"y": "0.245"
}
]
}
diff --git a/src/activities/geography/resource/board/board4_0.qml b/src/activities/geography/resource/board/board4_0.qml
index bafc0dba5..2e5946f99 100644
--- a/src/activities/geography/resource/board/board4_0.qml
+++ b/src/activities/geography/resource/board/board4_0.qml
@@ -1,130 +1,130 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("South America")
property var levels: [
{
"pixmapfile": "southamerica/south_america.png",
"type": "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile": "southamerica/venezuela.png",
"soundFile": "voices-$CA/$LOCALE/geography/venezuela.$CA",
"toolTipText": qsTr("Venezuela"),
"x": "0.411",
"y": "0.127"
},
{
"pixmapfile": "southamerica/uruguay.png",
"soundFile": "voices-$CA/$LOCALE/geography/uruguay.$CA",
"toolTipText": qsTr("Uruguay"),
"x": "0.545",
"y": "0.64"
},
{
"pixmapfile": "southamerica/suriname.png",
"soundFile": "voices-$CA/$LOCALE/geography/suriname.$CA",
"toolTipText": qsTr("Suriname"),
"x": "0.52",
"y": "0.148"
},
{
"pixmapfile": "southamerica/peru.png",
"soundFile": "voices-$CA/$LOCALE/geography/peru.$CA",
"toolTipText": qsTr("Peru"),
"x": "0.338",
"y": "0.342"
},
{
"pixmapfile": "southamerica/paraguay.png",
"soundFile": "voices-$CA/$LOCALE/geography/paraguay.$CA",
"toolTipText": qsTr("Paraguay"),
"x": "0.511",
"y": "0.519"
},
{
"pixmapfile": "southamerica/panama.png",
"soundFile": "voices-$CA/$LOCALE/geography/panama.$CA",
"toolTipText": qsTr("Panama"),
"x": "0.279",
"y": "0.104"
},
{
"pixmapfile": "southamerica/guyana.png",
"soundFile": "voices-$CA/$LOCALE/geography/guyana.$CA",
"toolTipText": qsTr("Guyana"),
"x": "0.49",
"y": "0.138"
},
{
"pixmapfile": "southamerica/french_guiana.png",
"soundFile": "voices-$CA/$LOCALE/geography/french_guiana.$CA",
"toolTipText": qsTr("French Guiana"),
"x": "0.548",
"y": "0.148"
},
{
"pixmapfile": "southamerica/ecuador.png",
"soundFile": "voices-$CA/$LOCALE/geography/ecuador.$CA",
"toolTipText": qsTr("Ecuador"),
"x": "0.301",
"y": "0.246"
},
{
"pixmapfile": "southamerica/colombia.png",
"soundFile": "voices-$CA/$LOCALE/geography/colombia.$CA",
"toolTipText": qsTr("Colombia"),
"x": "0.351",
"y": "0.156"
},
{
"pixmapfile": "southamerica/chile.png",
"soundFile": "voices-$CA/$LOCALE/geography/chile.$CA",
"toolTipText": qsTr("Chile"),
"x": "0.437",
"y": "0.71"
},
{
"pixmapfile": "southamerica/brazil.png",
"soundFile": "voices-$CA/$LOCALE/geography/brazil.$CA",
"toolTipText": qsTr("Brazil"),
"x": "0.546",
"y": "0.39"
},
{
"pixmapfile": "southamerica/bolivia.png",
"soundFile": "voices-$CA/$LOCALE/geography/bolivia.$CA",
"toolTipText": qsTr("Bolivia"),
"x": "0.458",
"y": "0.431"
},
{
"pixmapfile": "southamerica/argentina.png",
"soundFile": "voices-$CA/$LOCALE/geography/argentina.$CA",
"toolTipText": qsTr("Argentina"),
"x": "0.486",
"y": "0.731"
}
]
}
diff --git a/src/activities/geography/resource/board/board5_0.qml b/src/activities/geography/resource/board/board5_0.qml
index 23b1d9447..e8ba6f4de 100644
--- a/src/activities/geography/resource/board/board5_0.qml
+++ b/src/activities/geography/resource/board/board5_0.qml
@@ -1,151 +1,151 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Western Europe")
property var levels: [
{
"pixmapfile": "europe/europe.png",
"type": "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile": "europe/united_kingdom.png",
"soundFile": "voices-$CA/$LOCALE/geography/united_kingdom.$CA",
"toolTipText": qsTr("United Kingdom"),
"x": "0.215",
"y": "0.439"
},
{
"pixmapfile": "europe/switz.png",
"soundFile": "voices-$CA/$LOCALE/geography/switz.$CA",
"toolTipText": qsTr("Switzerland"),
"x": "0.409",
"y": "0.644"
},
{
"pixmapfile": "europe/sweden.png",
"soundFile": "voices-$CA/$LOCALE/geography/sweden.$CA",
"toolTipText": qsTr("Sweden"),
"x": "0.523",
"y": "0.247"
},
{
"pixmapfile": "europe/spain.png",
"soundFile": "voices-$CA/$LOCALE/geography/spain.$CA",
"toolTipText": qsTr("Spain"),
"x": "0.23",
"y": "0.835"
},
{
"pixmapfile": "europe/portugal.png",
"soundFile": "voices-$CA/$LOCALE/geography/portugal.$CA",
"toolTipText": qsTr("Portugal"),
"x": "0.134",
"y": "0.844"
},
{
"pixmapfile": "europe/norway.png",
"soundFile": "voices-$CA/$LOCALE/geography/norway.$CA",
"toolTipText": qsTr("Norway"),
"x": "0.516",
"y": "0.188"
},
{
"pixmapfile": "europe/netherland.png",
"soundFile": "voices-$CA/$LOCALE/geography/netherland.$CA",
"toolTipText": qsTr("The Netherlands"),
"x": "0.353",
"y": "0.502"
},
{
"pixmapfile": "europe/luxembourg.png",
"soundFile": "voices-$CA/$LOCALE/geography/luxembourg.$CA",
"type": "SHAPE_BACKGROUND",
"x": "0.369",
"y": "0.568"
},
{
"pixmapfile": "europe/italy.png",
"soundFile": "voices-$CA/$LOCALE/geography/italy.$CA",
"toolTipText": qsTr("Italy"),
"x": "0.485",
"y": "0.78"
},
{
"pixmapfile": "europe/ireland.png",
"soundFile": "voices-$CA/$LOCALE/geography/ireland.$CA",
"toolTipText": qsTr("Ireland"),
"x": "0.14",
"y": "0.47"
},
{
"pixmapfile": "europe/iceland.png",
"soundFile": "voices-$CA/$LOCALE/geography/iceland.$CA",
"toolTipText": qsTr("Iceland"),
"x": "0.078",
"y": "0.133"
},
{
"pixmapfile": "europe/germany.png",
"soundFile": "voices-$CA/$LOCALE/geography/germany.$CA",
"toolTipText": qsTr("Germany"),
"x": "0.439",
"y": "0.53"
},
{
"pixmapfile": "europe/france.png",
"soundFile": "voices-$CA/$LOCALE/geography/france.$CA",
"toolTipText": qsTr("France"),
"x": "0.312",
"y": "0.662"
},
{
"pixmapfile": "europe/finland.png",
"soundFile": "voices-$CA/$LOCALE/geography/finland.$CA",
"toolTipText": qsTr("Finland"),
"x": "0.642",
"y": "0.17"
},
{
"pixmapfile": "europe/denmark.png",
"soundFile": "voices-$CA/$LOCALE/geography/denmark.$CA",
"toolTipText": qsTr("Denmark"),
"x": "0.43",
"y": "0.398"
},
{
"pixmapfile": "europe/belgium.png",
"soundFile": "voices-$CA/$LOCALE/geography/belgium.$CA",
"toolTipText": qsTr("Belgium"),
"x": "0.343",
"y": "0.546"
},
{
"pixmapfile": "europe/austria.png",
"soundFile": "voices-$CA/$LOCALE/geography/austria.$CA",
"toolTipText": qsTr("Austria"),
"x": "0.49",
"y": "0.621"
}
]
}
diff --git a/src/activities/geography/resource/board/board6_0.qml b/src/activities/geography/resource/board/board6_0.qml
index d83506cd5..2344860bf 100644
--- a/src/activities/geography/resource/board/board6_0.qml
+++ b/src/activities/geography/resource/board/board6_0.qml
@@ -1,196 +1,196 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Eastern Europe")
property var levels: [
{
"pixmapfile": "europe/europe.png",
"type": "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile": "europe/cyprus.png",
"soundFile": "voices-$CA/$LOCALE/geography/cyprus.$CA",
"type": "SHAPE_BACKGROUND",
"x": "0.859",
"y": "0.965"
},
{
"pixmapfile": "europe/greece.png",
"soundFile": "voices-$CA/$LOCALE/geography/greece.$CA",
"toolTipText": qsTr("Greece"),
"x": "0.692",
"y": "0.878"
},
{
"pixmapfile": "europe/ukraine.png",
"soundFile": "voices-$CA/$LOCALE/geography/ukraine.$CA",
"toolTipText": qsTr("Ukraine"),
"x": "0.781",
"y": "0.603"
},
{
"pixmapfile": "europe/turkey.png",
"soundFile": "voices-$CA/$LOCALE/geography/turkey.$CA",
"toolTipText": qsTr("Turkey"),
"x": "0.851",
"y": "0.867"
},
{
"pixmapfile": "europe/slovenia.png",
"soundFile": "voices-$CA/$LOCALE/geography/slovenia.$CA",
"type": "SHAPE_BACKGROUND",
"toolTipText": qsTr("Slovenia"),
"x": "0.516",
"y": "0.662"
},
{
"pixmapfile": "europe/slovakia.png",
"soundFile": "voices-$CA/$LOCALE/geography/slovakia.$CA",
"toolTipText": qsTr("Slovak Republic"),
"x": "0.593",
"y": "0.596"
},
{
"pixmapfile": "europe/montenegro.png",
"soundFile": "voices-$CA/$LOCALE/geography/montenegro.$CA",
"toolTipText": qsTr("Montenegro"),
"type": "SHAPE_BACKGROUND",
"x": "0.601",
"y": "0.755"
},
{
"pixmapfile": "europe/serbia.png",
"soundFile": "voices-$CA/$LOCALE/geography/serbia.$CA",
"toolTipText": qsTr("Serbia"),
"x": "0.623",
"y": "0.723"
},
{
"pixmapfile": "europe/russia.png",
"soundFile": "voices-$CA/$LOCALE/geography/russia.$CA",
"toolTipText": qsTr("Russia"),
"x": "0.788",
"y": "0.373"
},
{
"pixmapfile": "europe/romania.png",
"soundFile": "voices-$CA/$LOCALE/geography/romania.$CA",
"toolTipText": qsTr("Romania"),
"x": "0.688",
"y": "0.669"
},
{
"pixmapfile": "europe/poland.png",
"soundFile": "voices-$CA/$LOCALE/geography/poland.$CA",
"toolTipText": qsTr("Poland"),
"x": "0.574",
"y": "0.507"
},
{
"pixmapfile": "europe/moldova.png",
"soundFile": "voices-$CA/$LOCALE/geography/moldova.$CA",
"toolTipText": qsTr("Moldova"),
"x": "0.74",
"y": "0.641"
},
{
"pixmapfile": "europe/macedonia.png",
"soundFile": "voices-$CA/$LOCALE/geography/macedonia.$CA",
"toolTipText": qsTr("Macedonia"),
"type": "SHAPE_BACKGROUND",
"x": "0.642",
"y": "0.787"
},
{
"pixmapfile": "europe/lithuania.png",
"soundFile": "voices-$CA/$LOCALE/geography/lithuania.$CA",
"toolTipText": qsTr("Lithuania"),
"x": "0.642",
"y": "0.425"
},
{
"pixmapfile": "europe/latvia.png",
"soundFile": "voices-$CA/$LOCALE/geography/latvia.$CA",
"toolTipText": qsTr("Latvia"),
"x": "0.651",
"y": "0.381"
},
{
"pixmapfile": "europe/hungary.png",
"soundFile": "voices-$CA/$LOCALE/geography/hungary.$CA",
"toolTipText": qsTr("Hungary"),
"x": "0.591",
"y": "0.635"
},
{
"pixmapfile": "europe/estonia.png",
"soundFile": "voices-$CA/$LOCALE/geography/estonia.$CA",
"toolTipText": qsTr("Estonia"),
"x": "0.647",
"y": "0.334"
},
{
"pixmapfile": "europe/czechia.png",
"soundFile": "voices-$CA/$LOCALE/geography/czechia.$CA",
"toolTipText": qsTr("Czechia"),
"x": "0.525",
"y": "0.561"
},
{
"pixmapfile": "europe/croatia.png",
"soundFile": "voices-$CA/$LOCALE/geography/croatia.$CA",
"toolTipText": qsTr("Croatia"),
"x": "0.546",
"y": "0.705"
},
{
"pixmapfile": "europe/bulgaria.png",
"soundFile": "voices-$CA/$LOCALE/geography/bulgaria.$CA",
"toolTipText": qsTr("Bulgaria"),
"x": "0.701",
"y": "0.757"
},
{
"pixmapfile": "europe/bosnia_herzegovina.png",
"soundFile": "voices-$CA/$LOCALE/geography/bosnia_herzegovina.$CA",
"toolTipText": qsTr("Bosnia Herzegovina"),
"x": "0.568",
"y": "0.728"
},
{
"pixmapfile": "europe/belarus.png",
"soundFile": "voices-$CA/$LOCALE/geography/belarus.$CA",
"toolTipText": qsTr("Belarus"),
"x": "0.714",
"y": "0.463"
},
{
"pixmapfile": "europe/albania.png",
"soundFile": "voices-$CA/$LOCALE/geography/albania.$CA",
"toolTipText": qsTr("Albania"),
"x": "0.616",
"y": "0.805"
}
]
}
diff --git a/src/activities/geography/resource/board/board7_0.qml b/src/activities/geography/resource/board/board7_0.qml
index 65b0f7fe4..a9ccc886f 100644
--- a/src/activities/geography/resource/board/board7_0.qml
+++ b/src/activities/geography/resource/board/board7_0.qml
@@ -1,263 +1,263 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Northern Africa")
property var levels: [
{
"pixmapfile": "africa/north_africa.png",
"type": "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile": "africa/western_sahara.png",
"soundFile": "voices-$CA/$LOCALE/geography/western_sahara.$CA",
"toolTipText": qsTr("Western Sahara"),
"x": "0.114",
"y": "0.307"
},
{
"pixmapfile": "africa/uganda.png",
"soundFile": "voices-$CA/$LOCALE/geography/uganda.$CA",
"toolTipText": qsTr("Uganda"),
"x": "0.737",
"y": "0.878"
},
{
"pixmapfile": "africa/tunisia.png",
"soundFile": "voices-$CA/$LOCALE/geography/tunisia.$CA",
"toolTipText": qsTr("Tunisia"),
"x": "0.425",
"y": "0.139"
},
{
"pixmapfile": "africa/togo.png",
"soundFile": "voices-$CA/$LOCALE/geography/togo.$CA",
"toolTipText": qsTr("Togo"),
"x": "0.27",
"y": "0.689"
},
{
"pixmapfile": "africa/sudan.png",
"soundFile": "voices-$CA/$LOCALE/geography/sudan.$CA",
"toolTipText": qsTr("Sudan"),
"x": "0.694",
"y": "0.599"
},
{
"pixmapfile": "africa/somalia.png",
"soundFile": "voices-$CA/$LOCALE/geography/somalia.$CA",
"toolTipText": qsTr("Somalia"),
"x": "0.926",
"y": "0.792"
},
{
"pixmapfile": "africa/sierra_leone.png",
"soundFile": "voices-$CA/$LOCALE/geography/sierra_leone.$CA",
"toolTipText": qsTr("Sierra Leone"),
"x": "0.093",
"y": "0.672"
},
{
"pixmapfile": "africa/senegal.png",
"soundFile": "voices-$CA/$LOCALE/geography/senegal.$CA",
"toolTipText": qsTr("Senegal"),
"x": "0.055",
"y": "0.536"
},
{
"pixmapfile": "africa/rwanda.png",
"soundFile": "voices-$CA/$LOCALE/geography/rwanda.$CA",
"toolTipText": qsTr("Rwanda"),
"x": "0.706",
"y": "0.959"
},
{
"pixmapfile": "africa/niger.png",
"soundFile": "voices-$CA/$LOCALE/geography/niger.$CA",
"toolTipText": qsTr("Niger"),
"x": "0.384",
"y": "0.491"
},
{
"pixmapfile": "africa/nigeria.png",
"soundFile": "voices-$CA/$LOCALE/geography/nigeria.$CA",
"toolTipText": qsTr("Nigeria"),
"x": "0.388",
"y": "0.68"
},
{
"pixmapfile": "africa/moroco.png",
"soundFile": "voices-$CA/$LOCALE/geography/moroco.$CA",
"toolTipText": qsTr("Morocco"),
"x": "0.205",
"y": "0.159"
},
{
"pixmapfile": "africa/mauritania.png",
"soundFile": "voices-$CA/$LOCALE/geography/mauritania.$CA",
"toolTipText": qsTr("Mauritania"),
"x": "0.133",
"y": "0.395"
},
{
"pixmapfile": "africa/mali.png",
"soundFile": "voices-$CA/$LOCALE/geography/mali.$CA",
"toolTipText": qsTr("Mali"),
"x": "0.215",
"y": "0.479"
},
{
"pixmapfile": "africa/libya.png",
"soundFile": "voices-$CA/$LOCALE/geography/libya.$CA",
"toolTipText": qsTr("Libya"),
"x": "0.517",
"y": "0.313"
},
{
"pixmapfile": "africa/liberia.png",
"soundFile": "voices-$CA/$LOCALE/geography/liberia.$CA",
"toolTipText": qsTr("Liberia"),
"x": "0.12",
"y": "0.727"
},
{
"pixmapfile": "africa/ivory_coast.png",
"soundFile": "voices-$CA/$LOCALE/geography/ivory_coast.$CA",
"toolTipText": qsTr("Ivory Coast"),
"x": "0.177",
"y": "0.706"
},
{
"pixmapfile": "africa/guinea.png",
"soundFile": "voices-$CA/$LOCALE/geography/guinea.$CA",
"toolTipText": qsTr("Guinea"),
"x": "0.099",
"y": "0.639"
},
{
"pixmapfile": "africa/guinea_bissau.png",
"soundFile": "voices-$CA/$LOCALE/geography/guinea_bissau.$CA",
"toolTipText": qsTr("Guinea Bissau"),
"x": "0.05",
"y": "0.599"
},
{
"pixmapfile": "africa/ghana.png",
"soundFile": "voices-$CA/$LOCALE/geography/ghana.$CA",
"toolTipText": qsTr("Ghana"),
"x": "0.24",
"y": "0.704"
},
{
"pixmapfile": "africa/gambia.png",
"soundFile": "voices-$CA/$LOCALE/geography/gambia.$CA",
"toolTipText": qsTr("Gambia"),
"x": "0.048",
"y": "0.564"
},
{
"pixmapfile": "africa/gabon.png",
"soundFile": "voices-$CA/$LOCALE/geography/gabon.$CA",
"toolTipText": qsTr("Gabon"),
"x": "0.455",
"y": "0.933"
},
{
"pixmapfile": "africa/eritrea.png",
"soundFile": "voices-$CA/$LOCALE/geography/eritrea.$CA",
"toolTipText": qsTr("Eritrea"),
"x": "0.833",
"y": "0.571"
},
{
"pixmapfile": "africa/ethiopia.png",
"soundFile": "voices-$CA/$LOCALE/geography/ethiopia.$CA",
"toolTipText": qsTr("Ethiopia"),
"x": "0.843",
"y": "0.706"
},
{
"pixmapfile": "africa/equatorial_guinea.png",
"soundFile": "voices-$CA/$LOCALE/geography/equatorial_guinea.$CA",
"toolTipText": qsTr("Equatorial Guinea"),
"x": "0.433",
"y": "0.878"
},
{
"pixmapfile": "africa/egypt.png",
"soundFile": "voices-$CA/$LOCALE/geography/egypt.$CA",
"toolTipText": qsTr("Egypt"),
"x": "0.697",
"y": "0.294"
},
{
"pixmapfile": "africa/djibouti.png",
"soundFile": "voices-$CA/$LOCALE/geography/djibouti.$CA",
"toolTipText": qsTr("Djibouti"),
"x": "0.874",
"y": "0.637"
},
{
"pixmapfile": "africa/chad.png",
"soundFile": "voices-$CA/$LOCALE/geography/chad.$CA",
"toolTipText": qsTr("Chad"),
"x": "0.537",
"y": "0.545"
},
{
"pixmapfile": "africa/central_african_republic.png",
"soundFile": "voices-$CA/$LOCALE/geography/central_african_republic.$CA",
"toolTipText": qsTr("Central African Republic"),
"x": "0.564",
"y": "0.736"
},
{
"pixmapfile": "africa/cameroon.png",
"soundFile": "voices-$CA/$LOCALE/geography/cameroon.$CA",
"toolTipText": qsTr("Cameroon"),
"x": "0.448",
"y": "0.751"
},
{
"pixmapfile": "africa/burkina_faso.png",
"soundFile": "voices-$CA/$LOCALE/geography/burkina_faso.$CA",
"toolTipText": qsTr("Burkina Faso"),
"x": "0.239",
"y": "0.607"
},
{
"pixmapfile": "africa/benin.png",
"soundFile": "voices-$CA/$LOCALE/geography/benin.$CA",
"toolTipText": qsTr("Benin"),
"x": "0.294",
"y": "0.674"
},
{
"pixmapfile": "africa/algeria.png",
"soundFile": "voices-$CA/$LOCALE/geography/algeria.$CA",
"toolTipText": qsTr("Algeria"),
"x": "0.31",
"y": "0.264"
}
]
}
diff --git a/src/activities/geography/resource/board/board8_0.qml b/src/activities/geography/resource/board/board8_0.qml
index c87671d84..e3399fad9 100644
--- a/src/activities/geography/resource/board/board8_0.qml
+++ b/src/activities/geography/resource/board/board8_0.qml
@@ -1,172 +1,172 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Southern Africa")
property var levels: [
{
"pixmapfile": "africa/all_south_africa.png",
"type": "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile": "africa/zimbabwe.png",
"soundFile": "voices-$CA/$LOCALE/geography/zimbabwe.$CA",
"toolTipText": qsTr("Zimbabwe"),
"x": "0.515",
"y": "0.554"
},
{
"pixmapfile": "africa/zambia.png",
"soundFile": "voices-$CA/$LOCALE/geography/zambia.$CA",
"toolTipText": qsTr("Zambia"),
"x": "0.5",
"y": "0.426"
},
{
"pixmapfile": "africa/uganda.png",
"soundFile": "voices-$CA/$LOCALE/geography/uganda.$CA",
"toolTipText": qsTr("Uganda"),
"x": "0.599",
"y": "0.105"
},
{
"pixmapfile": "africa/tanzania.png",
"soundFile": "voices-$CA/$LOCALE/geography/tanzania.$CA",
"toolTipText": qsTr("Tanzania"),
"x": "0.658",
"y": "0.279"
},
{
"pixmapfile": "africa/swaziland.png",
"soundFile": "voices-$CA/$LOCALE/geography/swaziland.$CA",
"toolTipText": qsTr("Swaziland"),
"x": "0.559",
"y": "0.717"
},
{
"pixmapfile": "africa/south_africa.png",
"soundFile": "voices-$CA/$LOCALE/geography/south_africa.$CA",
"toolTipText": qsTr("South Africa"),
"x": "0.436",
"y": "0.757"
},
{
"pixmapfile": "africa/rwanda.png",
"soundFile": "voices-$CA/$LOCALE/geography/rwanda.$CA",
"toolTipText": qsTr("Rwanda"),
"x": "0.555",
"y": "0.188"
},
{
"pixmapfile": "africa/republic_of_congo.png",
"soundFile": "voices-$CA/$LOCALE/geography/republic_of_congo.$CA",
"toolTipText": qsTr("Republic of Congo"),
"x": "0.228",
"y": "0.143"
},
{
"pixmapfile": "africa/namibia.png",
"soundFile": "voices-$CA/$LOCALE/geography/namibia.$CA",
"toolTipText": qsTr("Namibia"),
"x": "0.298",
"y": "0.632"
},
{
"pixmapfile": "africa/mozambique.png",
"soundFile": "voices-$CA/$LOCALE/geography/mozambique.$CA",
"toolTipText": qsTr("Mozambique"),
"x": "0.66",
"y": "0.551"
},
{
"pixmapfile": "africa/malawi.png",
"soundFile": "voices-$CA/$LOCALE/geography/malawi.$CA",
"toolTipText": qsTr("Malawi"),
"x": "0.636",
"y": "0.435"
},
{
"pixmapfile": "africa/madagascar.png",
"soundFile": "voices-$CA/$LOCALE/geography/madagascar.$CA",
"toolTipText": qsTr("Madagascar"),
"x": "0.886",
"y": "0.56"
},
{
"pixmapfile": "africa/lesotho.png",
"soundFile": "voices-$CA/$LOCALE/geography/lesotho.$CA",
"toolTipText": qsTr("Lesotho"),
"x": "0.509",
"y": "0.779"
},
{
"pixmapfile": "africa/kenya.png",
"soundFile": "voices-$CA/$LOCALE/geography/kenya.$CA",
"toolTipText": qsTr("Kenya"),
"x": "0.721",
"y": "0.127"
},
{
"pixmapfile": "africa/gabon.png",
"soundFile": "voices-$CA/$LOCALE/geography/gabon.$CA",
"toolTipText": qsTr("Gabon"),
"x": "0.162",
"y": "0.161"
},
{
"pixmapfile": "africa/equatorial_guinea.png",
"soundFile": "voices-$CA/$LOCALE/geography/equatorial_guinea.$CA",
"toolTipText": qsTr("Equatorial Guinea"),
"x": "0.134",
"y": "0.103"
},
{
"pixmapfile": "africa/democratic_republic_of_congo.png",
"soundFile": "voices-$CA/$LOCALE/geography/democratic_republic_of_congo.$CA",
"toolTipText": qsTr("Democratic Republic of Congo"),
"x": "0.377",
"y": "0.223"
},
{
"pixmapfile": "africa/burundi.png",
"soundFile": "voices-$CA/$LOCALE/geography/burundi.$CA",
"toolTipText": qsTr("Burundi"),
"x": "0.553",
"y": "0.225"
},
{
"pixmapfile": "africa/botswana.png",
"soundFile": "voices-$CA/$LOCALE/geography/botswana.$CA",
"toolTipText": qsTr("Botswana"),
"x": "0.43",
"y": "0.627"
},
{
"pixmapfile": "africa/angola.png",
"soundFile": "voices-$CA/$LOCALE/geography/angola.$CA",
"toolTipText": qsTr("Angola"),
"x": "0.296",
"y": "0.388"
}
]
}
diff --git a/src/activities/geography/resource/board/board9_0.qml b/src/activities/geography/resource/board/board9_0.qml
index cb88de1a0..2c13ffb68 100644
--- a/src/activities/geography/resource/board/board9_0.qml
+++ b/src/activities/geography/resource/board/board9_0.qml
@@ -1,411 +1,411 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Asia")
property var levels: [
{
"pixmapfile": "asia/background.png",
"type": "SHAPE_BACKGROUND_IMAGE"
},
{
"pixmapfile": "asia/russia.png",
"soundFile": "voices-$CA/$LOCALE/geography/russia.$CA",
"toolTipText": qsTr("Russia"),
"x": "0.497",
"y": "0.215"
},
{
"pixmapfile": "asia/mongolia.png",
"soundFile": "voices-$CA/$LOCALE/geography/mongolia.$CA",
"toolTipText": qsTr("Mongolia"),
"x": "0.562",
"y": "0.341"
},
{
"pixmapfile": "asia/japan.png",
"soundFile": "voices-$CA/$LOCALE/geography/japan.$CA",
"toolTipText": qsTr("Japan"),
"x": "0.855",
"y": "0.437"
},
{
"pixmapfile": "asia/north_korea.png",
"soundFile": "voices-$CA/$LOCALE/geography/north_korea.$CA",
"toolTipText": qsTr("North Korea"),
"x": "0.768",
"y": "0.415"
},
{
"pixmapfile": "asia/south_korea.png",
"soundFile": "voices-$CA/$LOCALE/geography/south_korea.$CA",
"toolTipText": qsTr("South Korea"),
"x": "0.79",
"y": "0.459"
},
{
"pixmapfile": "asia/kazakhstan.png",
"soundFile": "voices-$CA/$LOCALE/geography/kazakhstan.$CA",
"toolTipText": qsTr("Kazakhstan"),
"x": "0.293",
"y": "0.328"
},
{
"pixmapfile": "asia/uzbekistan.png",
"soundFile": "voices-$CA/$LOCALE/geography/uzbekistan.$CA",
"toolTipText": qsTr("Uzbekistan"),
"x": "0.289",
"y": "0.403"
},
{
"pixmapfile": "asia/taiwan.png",
"soundFile": "voices-$CA/$LOCALE/geography/taiwan.$CA",
"toolTipText": qsTr("Taiwan"),
"x": "0.772",
"y": "0.603"
},
{
"pixmapfile": "asia/vietnam.png",
"soundFile": "voices-$CA/$LOCALE/geography/vietnam.$CA",
"toolTipText": qsTr("Vietnam"),
"x": "0.661",
"y": "0.691"
},
{
"pixmapfile": "asia/cambodia.png",
"soundFile": "voices-$CA/$LOCALE/geography/cambodia.$CA",
"toolTipText": qsTr("Cambodia"),
"x": "0.658",
"y": "0.732"
},
{
"pixmapfile": "asia/laos.png",
"soundFile": "voices-$CA/$LOCALE/geography/laos.$CA",
"toolTipText": qsTr("Laos"),
"x": "0.644",
"y": "0.664"
},
{
"pixmapfile": "asia/thailand.png",
"soundFile": "voices-$CA/$LOCALE/geography/thailand.$CA",
"toolTipText": qsTr("Thailand"),
"x": "0.627",
"y": "0.723"
},
{
"pixmapfile": "asia/sri_lanka.png",
"soundFile": "voices-$CA/$LOCALE/geography/sri_lanka.$CA",
"toolTipText": qsTr("Sri Lanka"),
"x": "0.465",
"y": "0.785"
},
{
"pixmapfile": "asia/china.png",
"soundFile": "voices-$CA/$LOCALE/geography/china.$CA",
"toolTipText": qsTr("China"),
"x": "0.577",
"y": "0.466"
},
{
"pixmapfile": "asia/india.png",
"soundFile": "voices-$CA/$LOCALE/geography/india.$CA",
"toolTipText": qsTr("India"),
"x": "0.465",
"y": "0.624"
},
{
"pixmapfile": "asia/bangladesh.png",
"soundFile": "voices-$CA/$LOCALE/geography/bangladesh.$CA",
"toolTipText": qsTr("Bangladesh"),
"x": "0.532",
"y": "0.602"
},
{
"pixmapfile": "asia/bhutan.png",
"soundFile": "voices-$CA/$LOCALE/geography/bhutan.$CA",
"toolTipText": qsTr("Bhutan"),
"x": "0.523",
"y": "0.561"
},
{
"pixmapfile": "asia/nepal.png",
"soundFile": "voices-$CA/$LOCALE/geography/nepal.$CA",
"toolTipText": qsTr("Nepal"),
"x": "0.472",
"y": "0.55"
},
{
"pixmapfile": "asia/pakistan.png",
"soundFile": "voices-$CA/$LOCALE/geography/pakistan.$CA",
"toolTipText": qsTr("Pakistan"),
"x": "0.344",
"y": "0.527"
},
{
"pixmapfile": "asia/myanmar.png",
"soundFile": "voices-$CA/$LOCALE/geography/myanmar.$CA",
"toolTipText": qsTr("Myanmar"),
"x": "0.579",
"y": "0.65"
},
{
"pixmapfile": "asia/philippines.png",
"soundFile": "voices-$CA/$LOCALE/geography/philippines.$CA",
"toolTipText": qsTr("Philippines"),
"x": "0.8",
"y": "0.736"
},
{
"pixmapfile": "asia/indonesia.png",
"soundFile": "voices-$CA/$LOCALE/geography/indonesia.$CA",
"toolTipText": qsTr("Indonesia"),
"x": "0.727",
"y": "0.9"
},
{
"pixmapfile": "asia/malaysia.png",
"soundFile": "voices-$CA/$LOCALE/geography/malaysia.$CA",
"toolTipText": qsTr("Malaysia"),
"x": "0.699",
"y": "0.831"
},
{
"pixmapfile": "asia/afghanistan.png",
"soundFile": "voices-$CA/$LOCALE/geography/afghanistan.$CA",
"toolTipText": qsTr("Afghanistan"),
"x": "0.328",
"y": "0.487"
},
{
"pixmapfile": "asia/tajikistan.png",
"soundFile": "voices-$CA/$LOCALE/geography/tajikistan.$CA",
"toolTipText": qsTr("Tajikistan"),
"x": "0.35",
"y": "0.429"
},
{
"pixmapfile": "asia/kyrgyzstan.png",
"soundFile": "voices-$CA/$LOCALE/geography/kyrgyzstan.$CA",
"toolTipText": qsTr("Kyrgyzstan"),
"x": "0.371",
"y": "0.404"
},
{
"pixmapfile": "asia/turkmenistan.png",
"soundFile": "voices-$CA/$LOCALE/geography/turkmenistan.$CA",
"toolTipText": qsTr("Turkmenistan"),
"x": "0.26",
"y": "0.428"
},
{
"pixmapfile": "asia/iran.png",
"soundFile": "voices-$CA/$LOCALE/geography/iran.$CA",
"toolTipText": qsTr("Iran"),
"x": "0.224",
"y": "0.505"
},
{
"pixmapfile": "asia/azerbaijan.png",
"soundFile": "voices-$CA/$LOCALE/geography/azerbaijan.$CA",
"toolTipText": qsTr("Azerbaijan"),
"x": "0.163",
"y": "0.414"
},
{
"pixmapfile": "asia/georgia.png",
"soundFile": "voices-$CA/$LOCALE/geography/georgia.$CA",
//: Translators: Strip Asia| and translate only Georgia
"toolTipText": qsTr("Asia|Georgia"),
"x": "0.133",
"y": "0.389"
},
{
"pixmapfile": "asia/turkey.png",
"soundFile": "voices-$CA/$LOCALE/geography/turkey.$CA",
"toolTipText": qsTr("Turkey"),
"x": "0.077",
"y": "0.428"
},
{
"pixmapfile": "asia/syria.png",
"soundFile": "voices-$CA/$LOCALE/geography/syria.$CA",
"toolTipText": qsTr("Syria"),
"x": "0.108",
"y": "0.478"
},
{
"pixmapfile": "asia/iraq.png",
"soundFile": "voices-$CA/$LOCALE/geography/iraq.$CA",
"toolTipText": qsTr("Iraq"),
"x": "0.15",
"y": "0.492"
},
{
"pixmapfile": "asia/jordan.png",
"soundFile": "voices-$CA/$LOCALE/geography/jordan.$CA",
"toolTipText": qsTr("Jordan"),
"x": "0.1",
"y": "0.517"
},
{
"pixmapfile": "asia/saudi_arabia.png",
"soundFile": "voices-$CA/$LOCALE/geography/saudi_arabia.$CA",
"toolTipText": qsTr("Saudi Arabia"),
"x": "0.167",
"y": "0.592"
},
{
"pixmapfile": "asia/yemen.png",
"soundFile": "voices-$CA/$LOCALE/geography/yemen.$CA",
"toolTipText": qsTr("Yemen"),
"x": "0.192",
"y": "0.692"
},
{
"pixmapfile": "asia/united_arab_emirates.png",
"soundFile": "voices-$CA/$LOCALE/geography/united_arab_emirates.$CA",
"toolTipText": qsTr("United Arab Emirates"),
"x": "0.236",
"y": "0.598"
},
{
"pixmapfile": "asia/oman.png",
"soundFile": "voices-$CA/$LOCALE/geography/oman.$CA",
"toolTipText": qsTr("Oman"),
"x": "0.255",
"y": "0.628"
},
{
"pixmapfile": "asia/armenia.png",
"soundFile": "voices-$CA/$LOCALE/geography/armenia.$CA",
"type": "SHAPE_BACKGROUND",
"x": "0.15",
"y": "0.415"
},
{
"pixmapfile": "asia/kuwait.png",
"soundFile": "voices-$CA/$LOCALE/geography/kuwait.$CA",
"type": "SHAPE_BACKGROUND",
"x": "0.18",
"y": "0.538"
},
{
"pixmapfile": "asia/cyprus.png",
"soundFile": "voices-$CA/$LOCALE/geography/cyprus.$CA",
"type": "SHAPE_BACKGROUND",
"x": "0.065",
"y": "0.472"
},
{
"pixmapfile": "asia/lebanon.png",
"soundFile": "voices-$CA/$LOCALE/geography/lebanon.$CA",
"type": "SHAPE_BACKGROUND",
"x": "0.086",
"y": "0.487"
},
{
"pixmapfile": "asia/bahrain.png",
"soundFile": "voices-$CA/$LOCALE/geography/bahrain.$CA",
"type": "SHAPE_BACKGROUND",
"x": "0.208",
"y": "0.575"
},
{
"pixmapfile": "asia/qatar.png",
"soundFile": "voices-$CA/$LOCALE/geography/qatar.$CA",
"type": "SHAPE_BACKGROUND",
"x": "0.214",
"y": "0.586"
},
{
"pixmapfile": "asia/brunei.png",
"soundFile": "voices-$CA/$LOCALE/geography/brunei.$CA",
"type": "SHAPE_BACKGROUND",
"x": "0.744",
"y": "0.821"
},
{
"pixmapfile": "asia/israel.png",
"soundFile": "voices-$CA/$LOCALE/geography/israel.$CA",
"type": "SHAPE_BACKGROUND",
"x": "0.08",
"y": "0.517"
},
{
"pixmapfile": "asia/palestine.png",
"soundFile": "voices-$CA/$LOCALE/geography/palestine.$CA",
"type": "SHAPE_BACKGROUND",
"x": "0.081",
"y": "0.516"
},
{
"pixmapfile": "asia/red_sea.png",
"soundFile": "voices-$CA/$LOCALE/geography/red_sea.$CA",
"type": "SHAPE_BACKGROUND",
"x": "0.128",
"y": "0.662"
},
{
"pixmapfile": "asia/africa2.png",
"soundFile": "voices-$CA/$LOCALE/geography/africa2.$CA",
"type": "SHAPE_BACKGROUND",
"x": "0.176",
"y": "0.808"
},
{
"pixmapfile": "asia/africa.png",
"soundFile": "voices-$CA/$LOCALE/geography/africa.$CA",
"type": "SHAPE_BACKGROUND",
"x": "0.054",
"y": "0.769"
},
{
"pixmapfile": "asia/persian_gulf.png",
"soundFile": "voices-$CA/$LOCALE/geography/persian_gulf.$CA",
"type": "SHAPE_BACKGROUND",
"x": "0.223",
"y": "0.563"
},
{
"pixmapfile": "asia/mediteranean_sea.png",
"soundFile": "voices-$CA/$LOCALE/geography/mediteranean_sea.$CA",
"type": "SHAPE_BACKGROUND",
"x": "0.042",
"y": "0.485"
},
{
"pixmapfile": "asia/black_sea.png",
"soundFile": "voices-$CA/$LOCALE/geography/black_sea.$CA",
"type": "SHAPE_BACKGROUND",
"x": "0.059",
"y": "0.344"
},
{
"pixmapfile": "asia/caspian_sea.png",
"soundFile": "voices-$CA/$LOCALE/geography/caspian_sea.$CA",
"type": "SHAPE_BACKGROUND",
"x": "0.189",
"y": "0.398"
}
]
}
diff --git a/src/activities/gletters/ActivityInfo.qml b/src/activities/gletters/ActivityInfo.qml
index 5bb99846f..408210e4c 100644
--- a/src/activities/gletters/ActivityInfo.qml
+++ b/src/activities/gletters/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Holger Kaelberer <holger.k@elberer.de>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "gletters/Gletters.qml"
difficulty: 2
icon: "gletters/gletters.svg"
author: "Holger Kaelberer &lt;holger.k@elberer.de&gt;"
demo: true
//: Activity title
title: qsTr("Simple Letters")
//: Help title
description: qsTr("Type the falling letters before they reach the ground")
// intro: "Type the letters on your keyboard before they reach the ground."
//: Help goal
goal: qsTr("Letter association between the screen and the keyboard")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("Type the falling letters before they reach the ground")
credit: ""
section: "computer keyboard reading"
createdInVersion: 0
}
diff --git a/src/activities/gletters/FallingDomino.qml b/src/activities/gletters/FallingDomino.qml
index c2bdacbdd..0b0ff7a06 100644
--- a/src/activities/gletters/FallingDomino.qml
+++ b/src/activities/gletters/FallingDomino.qml
@@ -1,121 +1,123 @@
/* GCompris - FallingDomino.qml
*
* Copyright (C) 2014 Holger Kaelberer <holger.k@elberer.de>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Holger Kaelberer <holger.k@elberer.de> (Qt Quick port)
*
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import QtGraphicalEffects 1.0
import GCompris 1.0
import "../../core"
import "gletters.js" as Activity
Item {
id: word
width: domino.width
height: domino.height
/// index into text.split("") where next typed match should occur
property int unmatchedIndex: 0;
property string text
property var dominoValues
property bool wonState: false
+ property string mode: "dot"
signal won
onWon: {
wonState = true
particle.burst(30)
fadeout.restart();
}
Component.onCompleted: {
// make sure our word is completely visible
- if (x + width > parent.width)
+ if (x + width >= parent.width)
x = parent.width - width;
}
PropertyAnimation {
id: fadeout
target: word;
property: "opacity"
to: 0
duration: 1000
onStopped: Activity.deleteWord(word);
}
function checkMatch(c)
{
// We are in the ending animation
if (wonState)
return
var chars = text.split("");
- if (chars[unmatchedIndex] == c) {
+ if (chars[unmatchedIndex] === c) {
unmatchedIndex++;
return true;
} else {
unmatchedIndex = 0;
return false;
}
}
function startMoving(dur)
{
down.duration = dur;
down.restart();
}
function isCompleted()
{
return (unmatchedIndex === text.length);
}
Domino {
id: domino
width: 120 * ApplicationInfo.ratio
height: width / 2
+ mode: word.mode
visible: dominoValues.length != 0
value1: dominoValues[0]
value2: dominoValues[1]
isClickable: false
ParticleSystemStarLoader {
id: particle
clip: false
}
}
NumberAnimation {
id: down
target: word
property: "y"
to: parent.height
duration: 10000
onStopped: {
Activity.audioCrashPlay();
Activity.appendRandomWord(word.text)
Activity.deleteWord(word);
}
}
}
diff --git a/src/activities/gletters/FallingImage.qml b/src/activities/gletters/FallingImage.qml
index c8773a607..e8aeec7c2 100644
--- a/src/activities/gletters/FallingImage.qml
+++ b/src/activities/gletters/FallingImage.qml
@@ -1,130 +1,129 @@
/* GCompris - Word.qml
*
* Copyright (C) 2014 Holger Kaelberer <holger.k@elberer.de>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Holger Kaelberer <holger.k@elberer.de> (Qt Quick port)
*
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import QtGraphicalEffects 1.0
import GCompris 1.0
import "../../core"
import "gletters.js" as Activity
Item {
id: word
width: image.width
height: image.height
/// index into text.split("") where next typed match should occur
property int unmatchedIndex: 0;
property string text
property alias image: image.source;
property bool wonState: false
signal won
onWon: {
wonState = true
particle.burst(30)
dropShadow.opacity = 0
fadeout.restart();
}
Component.onCompleted: {
// make sure our word is completely visible
- if (x + width > parent.width)
+ if (x + width >= parent.width)
x = parent.width - width;
}
PropertyAnimation {
id: fadeout
target: word;
property: "opacity"
to: 0
duration: 1000
-
onStopped: Activity.deleteWord(word);
}
function checkMatch(c)
{
// We are in the ending animation
if (wonState)
return
var chars = text.split("");
- if (chars[unmatchedIndex] == c) {
+ if (chars[unmatchedIndex] === c) {
unmatchedIndex++;
return true;
} else {
unmatchedIndex = 0;
return false;
}
}
function startMoving(dur)
{
down.duration = dur;
down.restart();
}
function isCompleted()
{
return (unmatchedIndex === text.length);
}
Image {
id: image
// FIXME, the size should be passed from the caller
sourceSize.height: 106 * ApplicationInfo.ratio
ParticleSystemStarLoader {
id: particle
clip: false
}
}
DropShadow {
id: dropShadow
anchors.fill: image
cached: false
horizontalOffset: 1
verticalOffset: 1
radius: 3.0
samples: 16
color: "#422a2a2a"
source: image
}
NumberAnimation {
id: down
target: word
property: "y"
to: parent.height
duration: 10000
onStopped: {
Activity.audioCrashPlay();
Activity.appendRandomWord(word.text)
Activity.deleteWord(word);
}
}
}
diff --git a/src/activities/gletters/FallingWord.qml b/src/activities/gletters/FallingWord.qml
index 34844ed05..5d85a3082 100644
--- a/src/activities/gletters/FallingWord.qml
+++ b/src/activities/gletters/FallingWord.qml
@@ -1,169 +1,165 @@
/* GCompris - Word.qml
*
* Copyright (C) 2014 Holger Kaelberer <holger.k@elberer.de>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Holger Kaelberer <holger.k@elberer.de> (Qt Quick port)
*
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import QtGraphicalEffects 1.0
import GCompris 1.0
import "../../core"
import "gletters.js" as Activity
Item {
id: word
width: wordText.width
height: wordText.height
/// index into text.split("") where next typed match should occur
property int unmatchedIndex: 0;
property alias text: wordText.text;
property bool wonState: false
property string mode
signal won
onWon: {
wonState = true
particle.burst(30)
dropShadow.opacity = 0
fadeout.restart();
}
Component.onCompleted: {
// make sure our word is completely visible
- if (x + width > parent.width)
+ if (x + width >= parent.width)
x = parent.width - width;
}
onUnmatchedIndexChanged: {
if (unmatchedIndex <= 0)
highlightedWordText.text = "";
else if (wordText.text.length > 0 && wordText.text.length >= unmatchedIndex) {
highlightedWordText.text = wordText.text.substring(0, unmatchedIndex);
/* Need to add the ZERO WIDTH JOINER to force joined char in Arabic and
* Hangul: http://en.wikipedia.org/wiki/Zero-width_joiner
*
* FIXME: this works only on desktop systems, on android this
* shifts the typed word a few pixels down. */
if (!ApplicationInfo.isMobile)
highlightedWordText.text += "\u200C";
}
}
PropertyAnimation {
id: fadeout
target: word;
property: "opacity"
to: 0
duration: 1000
-
onStopped: Activity.deleteWord(word);
}
function checkMatch(c)
{
// We are in the ending animation
if (wonState)
return
if(word.mode === 'letter') {
// Only highlight letter if it is the good one
unmatchedIndex = text === c ? c.length : 0
return (text === c)
} else {
var chars = text.split("");
- if (chars[unmatchedIndex] == c) {
+ if (chars[unmatchedIndex] === c) {
unmatchedIndex++;
return true;
} else {
unmatchedIndex = 0;
return false;
}
}
}
function startMoving(dur)
{
down.duration = dur;
down.restart();
}
function isCompleted()
{
return (unmatchedIndex === text.length);
}
GCText {
id: wordText
-
text: ""
fontSize: 35
font.bold: true
color: "navy"
style: Text.Outline
styleColor: "white"
ParticleSystemStarLoader {
id: particle
clip: false
}
GCText {
id: highlightedWordText
-
anchors.fill: parent
-
text: ""
fontSize: parent.fontSize
font.bold: parent.font.bold
color: "red"
style: Text.Outline
styleColor: "white"
}
}
DropShadow {
id: dropShadow
anchors.fill: wordText
cached: false
horizontalOffset: 1
verticalOffset: 1
radius: 3.0
samples: 16
color: "#422a2a2a"
source: wordText
}
NumberAnimation {
id: down
target: word
property: "y"
to: parent.height
duration: 10000
onStopped: {
Activity.audioCrashPlay();
Activity.appendRandomWord(word.text)
Activity.deleteWord(word);
}
}
}
diff --git a/src/activities/gletters/Gletters.qml b/src/activities/gletters/Gletters.qml
index 226aa9bcf..2490f79fa 100644
--- a/src/activities/gletters/Gletters.qml
+++ b/src/activities/gletters/Gletters.qml
@@ -1,274 +1,316 @@
/* GCompris - gletters.qml
*
* Copyright (C) 2014 Holger Kaelberer <holger.k@elberer.de>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Holger Kaelberer <holger.k@elberer.de> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "gletters.js" as Activity
ActivityBase {
id: activity
// Overload this in your activity to change it
// Put you default-<locale>.json files in it
property string dataSetUrl: "qrc:/gcompris/src/activities/gletters/resource/"
/* no need to display the configuration button for smallnumbers */
property bool configurationButtonVisible: true
property bool uppercaseOnly: false
+ property string activityName: "gletters"
+
/* mode of the activity, "letter" (gletters) or "word" (wordsgame):*/
property string mode: "letter"
// Override if you want to replace texts by your image
function getImage(key) {
return ""
}
// Override if you want to replace texts by the domino
function getDominoValues(key) {
return []
}
onStart: focus = true
onStop: {}
// When going on configuration, it steals the focus and re set it to the activity.
// We need to set it back to the textinput item in order to have key events.
onFocusChanged: {
if(focus) {
Activity.focusTextInput()
}
}
pageComponent: Image {
id: background
source: activity.dataSetUrl + "background.svg"
fillMode: Image.PreserveAspectCrop
sourceSize.height: parent.height
signal start
signal stop
// system locale by default
property string locale: "system"
Component.onCompleted: {
dialogActivityConfig.getInitialConfiguration()
activity.start.connect(start)
activity.stop.connect(stop)
}
QtObject {
id: items
property Item main: activity.main
property Item ourActivity: activity
property GCAudio audioVoices: activity.audioVoices
property alias background: background
property alias bar: bar
property alias bonus: bonus
property alias wordlist: wordlist
property alias score: score
property alias keyboard: keyboard
property alias wordDropTimer: wordDropTimer
property GCSfx audioEffects: activity.audioEffects
property alias locale: background.locale
property alias textinput: textinput
}
onStart: {
Activity.start(items, uppercaseOnly, mode);
Activity.focusTextInput()
}
onStop: { Activity.stop() }
TextInput {
// Helper element to capture composed key events like french ô which
// are not available via Keys.onPressed() on linux. Must be
// disabled on mobile!
id: textinput
anchors.centerIn: background
enabled: !ApplicationInfo.isMobile
focus: true
visible: false
onTextChanged: {
if (text != "") {
Activity.processKeyPress(text);
text = "";
}
}
}
+ //created to retrieve available menu modes for domino configurations
+ Domino {
+ id: invisibleDomino
+ visible: false
+ }
+
DialogActivityConfig {
id: dialogActivityConfig
currentActivity: activity
content: Component {
Item {
property alias localeBox: localeBox
+ property alias dominoModeBox: dominoModeBox
property alias uppercaseBox: uppercaseBox
height: column.height
property alias availableLangs: langs.languages
LanguageList {
id: langs
}
+ property var availableModes: invisibleDomino.menuModes
Column {
id: column
spacing: 10
width: parent.width
-
Flow {
spacing: 5
width: dialogActivityConfig.width
GCComboBox {
id: localeBox
+ visible: (activity.activityName == "gletters")
model: langs.languages
background: dialogActivityConfig
label: qsTr("Select your locale")
}
+ GCComboBox {
+ id: dominoModeBox
+ visible: (activity.activityName == "smallnumbers2")
+ model: availableModes
+ background: dialogActivityConfig
+ label: qsTr("Select Domino mode")
+ }
}
GCDialogCheckBox {
id: uppercaseBox
+ visible: (activity.activityName == "gletters")
width: dialogActivityConfig.width
text: qsTr("Uppercase only mode")
checked: activity.uppercaseOnly
}
}
}
}
onClose: home()
onLoadData: {
- if(dataToSave && dataToSave["locale"]) {
- background.locale = dataToSave["locale"];
- activity.uppercaseOnly = dataToSave["uppercaseMode"] === "true" ? true : false;
+ if (activity.activityName == "gletters") {
+ if(dataToSave && dataToSave["locale"]) {
+ background.locale = dataToSave["locale"];
+ activity.uppercaseOnly = dataToSave["uppercaseMode"] === "true" ? true : false;
+ }
+ } else if (activity.activityName == "smallnumbers2") {
+ if(dataToSave && dataToSave["mode"]) {
+ activity.dominoMode = dataToSave["mode"];
+ }
}
}
onSaveData: {
- var oldLocale = background.locale;
- var newLocale = dialogActivityConfig.configItem.availableLangs[dialogActivityConfig.loader.item.localeBox.currentIndex].locale;
- // Remove .UTF-8
- if(newLocale.indexOf('.') != -1) {
- newLocale = newLocale.substring(0, newLocale.indexOf('.'))
- }
+ var configHasChanged = false
+ if (activity.activityName == "gletters") {
+ var oldLocale = background.locale;
+ var newLocale = dialogActivityConfig.configItem.availableLangs[dialogActivityConfig.loader.item.localeBox.currentIndex].locale;
+ // Remove .UTF-8
+ if(newLocale.indexOf('.') != -1) {
+ newLocale = newLocale.substring(0, newLocale.indexOf('.'))
+ }
- var oldUppercaseMode = activity.uppercaseOnly
- activity.uppercaseOnly = dialogActivityConfig.configItem.uppercaseBox.checked
- dataToSave = {"locale": newLocale, "uppercaseMode": ""+activity.uppercaseOnly}
+ var oldUppercaseMode = activity.uppercaseOnly
+ activity.uppercaseOnly = dialogActivityConfig.configItem.uppercaseBox.checked
+ dataToSave = {"locale": newLocale, "uppercaseMode": ""+activity.uppercaseOnly}
- background.locale = newLocale;
+ background.locale = newLocale;
+ if(oldLocale !== newLocale || oldUppercaseMode !== activity.uppercaseOnly) {
+ configHasChanged = true;
+ }
+ } else if (activity.activityName == "smallnumbers2") {
+ var newMode = dialogActivityConfig.configItem.availableModes[dialogActivityConfig.configItem.dominoModeBox.currentIndex].value;
+ if (newMode !== activity.dominoMode) {
+ activity.dominoMode = newMode;
+ dataToSave = {"mode": activity.dominoMode};
+ configHasChanged = true;
+ }
+ }
+
// Restart the activity with new information
- if(oldLocale !== newLocale || oldUppercaseMode !== activity.uppercaseOnly) {
+ if(configHasChanged) {
background.stop();
background.start();
}
}
-
function setDefaultValues() {
- var localeUtf8 = background.locale;
- if(background.locale != "system") {
- localeUtf8 += ".UTF-8";
- }
+ if (activity.activityName == "gletters") {
+ var localeUtf8 = background.locale;
+ if(background.locale != "system") {
+ localeUtf8 += ".UTF-8";
+ }
- for(var i = 0 ; i < dialogActivityConfig.configItem.availableLangs.length ; i ++) {
- if(dialogActivityConfig.configItem.availableLangs[i].locale === localeUtf8) {
- dialogActivityConfig.loader.item.localeBox.currentIndex = i;
- break;
+ for(var i = 0 ; i < dialogActivityConfig.configItem.availableLangs.length ; i ++) {
+ if(dialogActivityConfig.configItem.availableLangs[i].locale === localeUtf8) {
+ dialogActivityConfig.configItem.localeBox.currentIndex = i;
+ break;
+ }
+ }
+ } else if (activity.activityName == "smallnumbers2") {
+ for(var i = 0 ; i < dialogActivityConfig.configItem.availableModes.length ; i++) {
+ if(dialogActivityConfig.configItem.availableModes[i].value === activity.dominoMode) {
+ dialogActivityConfig.configItem.dominoModeBox.currentIndex = i;
+ break;
+ }
}
}
}
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
anchors.bottom: keyboard.top
content: BarEnumContent { value: configurationButtonVisible ? (help | home | level | config) : (help | home | level)}
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
onConfigClicked: {
dialogActivityConfig.active = true
dialogActivityConfig.setDefaultValues()
displayDialog(dialogActivityConfig)
}
}
Bonus {
id: bonus
interval: 2000
Component.onCompleted: win.connect(Activity.nextLevel)
}
Score {
id: score
-
anchors.top: undefined
anchors.topMargin: 10 * ApplicationInfo.ratio
anchors.right: parent.right
anchors.rightMargin: 10 * ApplicationInfo.ratio
anchors.bottom: keyboard.top
}
VirtualKeyboard {
id: keyboard
-
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
width: parent.width
-
onKeypress: Activity.processKeyPress(text)
-
onError: console.log("VirtualKeyboard error: " + msg);
}
Wordlist {
id: wordlist
defaultFilename: activity.dataSetUrl + "default-en.json"
// To switch between locales: xx_XX stored in configuration and
// possibly correct xx if available (ie fr_FR for french but dataset is fr.)
useDefault: false
filename: ""
onError: console.log("Gletters: Wordlist error: " + msg);
}
Timer {
id: wordDropTimer
repeat: false
onTriggered: Activity.dropWord();
}
}
}
diff --git a/src/activities/gletters/gletters.js b/src/activities/gletters/gletters.js
index c45ff65f6..5fe02004d 100644
--- a/src/activities/gletters/gletters.js
+++ b/src/activities/gletters/gletters.js
@@ -1,417 +1,418 @@
/* GCompris - gletters.js
*
* Copyright (C) 2014-2016 Holger Kaelberer
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Holger Kaelberer <holger.k@elberer.de> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
/* ToDo / open issues:
* - adjust wordlist filenames once we have an ApplicationInfo.dataPath() or so
*/
.pragma library
.import QtQuick 2.6 as Quick
.import GCompris 1.0 as GCompris //for ApplicationInfo
.import "qrc:/gcompris/src/core/core.js" as Core
var currentLevel = 0;
var currentSubLevel = 0;
var level = null;
var maxLevel = 0;
var maxSubLevel = 0;
var items;
var uppercaseOnly;
var mode;
//speed calculations, common:
var speed = 0; // how fast letters fall
var fallSpeed = 0; // how often new letters are dropped
var incFallSpeed = 1000; // how much drop rate increases per sublevel
var incSpeed = 10; // how much speed increases per sublevel
// gletters:
var fallRateBase = 40; // default for how fast letters fall (smaller is faster)
var fallRateMult = 80; // default for how much falling speed increases per level (smaller is faster)
var dropRateBase = 5000; // default for how often new letters are dropped
var dropRateMult = 100; // default for how much drop rate increases per level
// wordsgame:
var wgMaxFallSpeed = 7000;
var wgMaxSpeed = 150;
var wgMinFallSpeed = 3000;
var wgMinSpeed = 50;
var wgDefaultFallSpeed = 8000;
var wgDefaultSpeed = 170;
var wgAddSpeed = 20;
var wgAddFallSpeed = 1000;
var wgMaxFallingItems;
var droppedWords;
var currentWord = null; // reference to the word currently typing, null if n/a
var wordComponent = null;
var successRate // Falling speed depends on it
function start(items_, uppercaseOnly_, _mode) {
items = items_;
uppercaseOnly = uppercaseOnly_;
mode = _mode;
currentLevel = 0;
currentSubLevel = 0;
var locale = items.locale == "system" ? "$LOCALE" : items.locale
// register the voices for the locale
GCompris.DownloadManager.updateResource(GCompris.DownloadManager.getVoicesResourceForLocale(GCompris.ApplicationInfo.getVoicesLocale(items.locale)));
items.wordlist.loadFromFile(GCompris.ApplicationInfo.getLocaleFilePath(
items.ourActivity.dataSetUrl + "default-"+locale+".json"));
// If wordlist is empty, we try to load from short locale and if not present again, we switch to default one
var localeUnderscoreIndex = locale.indexOf('_')
// probably exist a better way to see if the list is empty
if(items.wordlist.maxLevel == 0) {
var localeShort;
// We will first look again for locale xx (without _XX if exist)
if(localeUnderscoreIndex > 0) {
localeShort = locale.substring(0, localeUnderscoreIndex)
}
else {
localeShort = locale;
}
// If not found, we will use the default file
items.wordlist.useDefault = true
items.wordlist.loadFromFile(GCompris.ApplicationInfo.getLocaleFilePath(
items.ourActivity.dataSetUrl + "default-"+localeShort+".json"));
// We remove the using of default file for next time we enter this function
items.wordlist.useDefault = false
}
maxLevel = items.wordlist.maxLevel;
droppedWords = new Array();
initLevel();
}
function stop() {
deleteWords();
wordComponent = null
items.wordDropTimer.stop();
}
function initLevel() {
items.audioVoices.clearQueue()
items.bar.level = currentLevel + 1;
wgMaxFallingItems = 3
successRate = 1.0
// initialize level
deleteWords();
level = items.wordlist.getLevelWordList(currentLevel + 1);
maxSubLevel = items.wordlist.getMaxSubLevel(currentLevel + 1);
if (maxSubLevel == 0) {
// If "sublevels" length is not set in wordlist, use the words length
maxSubLevel = level.words.length
}
items.score.numberOfSubLevels = maxSubLevel;
setSpeed();
/*console.log("Gletters: initializing level " + (currentLevel + 1)
+ " maxSubLvl=" + maxSubLevel
+ " wordCount=" + level.words.length
+ " speed=" + speed + " fallspeed=" + fallSpeed);*/
{
/* populate VirtualKeyboard for mobile:
* 1. for < 10 letters print them all in the same row
* 2. for > 10 letters create 3 rows with equal amount of keys per row
* if possible, otherwise more keys in the upper rows
* 3. if we have both upper- and lowercase letters activate the shift
* key*/
// first generate a map of needed letters
var letters = new Array();
items.keyboard.shiftKey = false;
for (var i = 0; i < level.words.length; i++) {
if(mode ==='letter') {
// The word is a letter, even if it has several chars (digraph)
var letter = level.words[i];
var isUpper = (letter == letter.toLocaleUpperCase());
if (isUpper && letters.indexOf(letter.toLocaleLowerCase()) !== -1)
items.keyboard.shiftKey = true;
else if (!isUpper && letters.indexOf(letter.toLocaleUpperCase()) !== -1)
items.keyboard.shiftKey = true;
else if (letters.indexOf(letter) === -1)
letters.push(level.words[i]);
} else {
// We split each word in char to create the keyboard
for (var j = 0; j < level.words[i].length; j++) {
var letter = level.words[i].charAt(j);
var isUpper = (letter == letter.toLocaleUpperCase());
if (isUpper && letters.indexOf(letter.toLocaleLowerCase()) !== -1)
items.keyboard.shiftKey = true;
else if (!isUpper && letters.indexOf(letter.toLocaleUpperCase()) !== -1)
items.keyboard.shiftKey = true;
else if (letters.indexOf(letter) === -1)
letters.push(level.words[i].charAt(j));
}
}
}
letters = GCompris.ApplicationInfo.localeSort(letters, items.locale);
// generate layout from letter map
var layout = new Array();
var row = 0;
var offset = 0;
while (offset < letters.length-1) {
var cols = letters.length <= 10 ? letters.length : (Math.ceil((letters.length-offset) / (3 - row)));
layout[row] = new Array();
for (var j = 0; j < cols; j++)
layout[row][j] = { label: letters[j+offset] };
offset += j;
row++;
}
items.keyboard.layout = layout;
}
items.wordlist.initRandomWord(currentLevel + 1)
initSubLevel()
}
function initSubLevel() {
currentWord = null;
if (currentSubLevel != 0) {
// increase speed
speed = Math.max(speed - incSpeed, wgMinSpeed);
items.wordDropTimer.interval = fallSpeed = Math.max(fallSpeed - incFallSpeed, wgMinFallSpeed);
}
items.score.currentSubLevel = currentSubLevel + 1;
if (currentSubLevel == 0 || droppedWords.length <= 1) // note, last word is still fading out
dropWord();
//console.log("Gletters: initializing subLevel " + (currentSubLevel + 1) + " words=" + JSON.stringify(level.words));
}
function processKeyPress(text) {
var typedText = uppercaseOnly ? text.toLocaleUpperCase() : text;
if (currentWord !== null) {
// check against a currently typed word
if (!currentWord.checkMatch(typedText)) {
currentWord = null;
audioCrashPlay()
} else {
playLetter(text)
}
} else {
// no current word, check against all available words
var found = false
for (var i = 0; i< droppedWords.length; i++) {
if (droppedWords[i].checkMatch(typedText)) {
// typed correctly
currentWord = droppedWords[i];
playLetter(text)
found = true
break;
}
}
if(!found) {
audioCrashPlay()
}
}
if (currentWord !== null && currentWord.isCompleted()) {
// win!
currentWord.won(); // note: deleteWord() is triggered after fadeout
successRate += 0.1
currentWord = null
nextSubLevel();
}
}
function setSpeed()
{
- if (mode == "letter") {
+ if (mode === "letter") {
speed = (level.speed !== undefined) ? level.speed : (fallRateBase + Math.floor(fallRateMult / (currentLevel + 1)));
fallSpeed = (level.fallspeed !== undefined) ? level.fallspeed : Math.floor((dropRateBase + (dropRateMult * (currentLevel + 1))));
} else { // wordsgame
speed = (level.speed !== undefined) ? level.speed : wgDefaultSpeed - (currentLevel+1)*wgAddSpeed;
fallSpeed = (level.fallspeed !== undefined) ? level.fallspeed : wgDefaultFallSpeed - (currentLevel+1)*wgAddFallSpeed
if(speed < wgMinSpeed ) speed = wgMinSpeed;
if(speed > wgMaxSpeed ) speed = wgMaxSpeed;
if(fallSpeed < wgMinFallSpeed ) fallSpeed = wgMinFallSpeed;
if(fallSpeed > wgMaxFallSpeed ) fallSpeed = wgMaxFallSpeed;
}
items.wordDropTimer.interval = fallSpeed;
}
function deleteWords()
{
if (droppedWords === undefined || droppedWords.length < 1)
return;
for (var i = 0; i< droppedWords.length; i++)
droppedWords[i].destroy();
droppedWords.length = 0;
}
function deleteWord(w)
{
if (droppedWords === undefined || droppedWords.length < 1)
return;
if (w == currentWord)
currentWord = null;
for (var i = 0; i< droppedWords.length; i++)
if (droppedWords[i] == w) {
droppedWords[i].destroy();
droppedWords.splice(i, 1);
break;
}
}
function createWord()
{
if (wordComponent.status == 1 /* Component.Ready */) {
var text = items.wordlist.getRandomWord();
if(!text) {
items.wordDropTimer.restart();
return
}
// if uppercaseOnly case does not matter otherwise it does
if (uppercaseOnly)
text = text.toLocaleUpperCase();
var word
if(items.ourActivity.getImage(text)) {
word = wordComponent.createObject( items.background,
{
"text": text,
"image": items.ourActivity.getImage(text),
// assume x=width-25px for now, Word auto-adjusts onCompleted():
"x": Math.random() * (items.main.width - 25),
"y": -25,
});
} else if(items.ourActivity.getDominoValues(text).length) {
word = wordComponent.createObject( items.background,
{
"text": text,
+ "mode": items.ourActivity.getMode(),
"dominoValues": items.ourActivity.getDominoValues(text),
// assume x=width-25px for now, Word auto-adjusts onCompleted():
"x": Math.random() * (items.main.width - 25),
"y": -25,
});
} else {
word = wordComponent.createObject( items.background,
{
"text": text,
// assume x=width-25px for now, Word auto-adjusts onCompleted():
"x": Math.random() * (items.main.width - 25),
"y": -25,
"mode": mode,
});
}
if (word === null)
console.log("Gletters: Error creating word object");
else {
droppedWords[droppedWords.length] = word;
// speed to duration:
var duration = (items.main.height / 2) * speed / successRate;
/* console.debug("Gletters: dropping new word " + word.text
+ " duration=" + duration + " (speed=" + speed + ")"
+ " num=" + droppedWords.length);*/
word.startMoving(duration);
}
items.wordDropTimer.restart();
} else if (wordComponent.status == 3 /* Component.Error */) {
console.log("Gletters: error creating word component: " + wordComponent.errorString());
}
}
function dropWord()
{
// Do not create too many falling items
if(droppedWords.length > wgMaxFallingItems) {
items.wordDropTimer.restart();
return
}
if (wordComponent !== null)
createWord();
else {
var text = items.wordlist.getRandomWord();
items.wordlist.appendRandomWord(text)
var fallingItem
if(items.ourActivity.getImage(text))
fallingItem = "FallingImage.qml"
else if(items.ourActivity.getDominoValues(text).length)
fallingItem = "FallingDomino.qml"
else
fallingItem = "FallingWord.qml"
wordComponent = Qt.createComponent("qrc:/gcompris/src/activities/gletters/" + fallingItem);
if (wordComponent.status == 1 /* Component.Ready */)
createWord();
else if (wordComponent.status == 3 /* Component.Error */) {
console.log("Gletters: error creating word component: " + wordComponent.errorString());
} else
wordComponent.statusChanged.connect(createWord);
}
}
function appendRandomWord(word) {
items.wordlist.appendRandomWord(word)
}
function audioCrashPlay() {
if(successRate > 0.5)
successRate -= 0.1
items.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/crash.wav")
}
function nextLevel() {
if(maxLevel <= ++currentLevel ) {
currentLevel = 0
}
currentSubLevel = 0;
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = maxLevel - 1
}
currentSubLevel = 0;
initLevel();
}
function nextSubLevel() {
if( ++currentSubLevel >= maxSubLevel) {
currentSubLevel = 0
items.bonus.good("lion")
} else
items.score.playWinAnimation();
initSubLevel();
}
function playLetter(letter) {
var locale = GCompris.ApplicationInfo.getVoicesLocale(items.locale)
items.audioVoices.append(GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/"+locale+"/alphabet/"
+ Core.getSoundFilenamForChar(letter)))
}
function focusTextInput() {
if (!GCompris.ApplicationInfo.isMobile && items && items.textinput)
items.textinput.forceActiveFocus();
}
diff --git a/src/activities/gnumch-equality/ActivityInfo.qml b/src/activities/gnumch-equality/ActivityInfo.qml
index d6c4f76d5..13a8bc73c 100644
--- a/src/activities/gnumch-equality/ActivityInfo.qml
+++ b/src/activities/gnumch-equality/ActivityInfo.qml
@@ -1,44 +1,44 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Manuel Tondeur <manueltondeur@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "gnumch-equality/GnumchEquality.qml"
difficulty: 3
icon: "gnumch-equality/gnumch-equality.svg"
author: "Manuel Tondeur &lt;manueltondeur@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Gnumch Equality")
//: Help title
description: qsTr("Guide the Number Muncher to the expressions that equal the number at the bottom of the screen.")
// intro: "Guide the number eater with the arrow keys to the required numbers and press the space bar to swallow them."
//: Help goal
goal: qsTr("Practice addition, multiplication, division and subtraction.")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("Guide the Number Muncher to the expressions that equal the number at the bottom of the screen.") +
"<br><br>" +
qsTr("If you have a keyboard you can use the arrow keys to move and hit space to swallow a number. With a mouse you can click on the block next to your position to move and click again to swallow the number. With a touch screen you can do like with a mouse or swipe anywhere in the direction you want to move and tap to swallow the number.") +
"<br><br>" +
qsTr("Take care to avoid the Troggles.")
credit: ""
section: "math"
createdInVersion: 0
}
diff --git a/src/activities/gnumch-equality/CellDelegate.qml b/src/activities/gnumch-equality/CellDelegate.qml
index 1b4cde1eb..e9fe87bec 100644
--- a/src/activities/gnumch-equality/CellDelegate.qml
+++ b/src/activities/gnumch-equality/CellDelegate.qml
@@ -1,80 +1,80 @@
/* GCompris - CellDelegate.qml
*
* Copyright (C) 2014 Manuel Tondeur <manueltondeur@gmail.com>
*
* Authors:
* Joe Neeman (spuzzzzzzz@gmail.com) (GTK+ version)
* Manuel Tondeur <manueltondeur@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
Item {
property Component delegate: cellDelegate
Component {
id: cellDelegate
Rectangle {
id: cellRectangle
property string num1: number1
property string num2: number2
property string operator: activity.operator
function setText() {
if (activity.type == "equality" || activity.type == "inequality") {
} else if (activity.type == "primes" ||
activity.type == "factors"||
activity.type == "multiples") {
num2 = ""
operator = ""
}
}
width: grid.cellWidth
height: grid.cellHeight
border.color: "black"
border.width: 2
radius: 5
color: "transparent"
focus: false
Component.onCompleted: setText()
GCText {
id: numberText
anchors.fill: parent
anchors.margins: ApplicationInfo.ratio * 5
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
style: Text.Outline
styleColor: "white"
visible: show
fontSizeMode: Text.Fit
minimumPointSize: 7
fontSize: 28
maximumLineCount: 1
text: num1 + operator + num2
}
}
}
}
diff --git a/src/activities/gnumch-equality/Creature.qml b/src/activities/gnumch-equality/Creature.qml
index 3fe963e2d..ec090997d 100644
--- a/src/activities/gnumch-equality/Creature.qml
+++ b/src/activities/gnumch-equality/Creature.qml
@@ -1,169 +1,169 @@
/* GCompris - Creature.qml
*
* Copyright (C) 2014 Manuel Tondeur <manueltondeur@gmail.com>
*
* Authors:
* Joe Neeman (spuzzzzzzz@gmail.com) (GTK+ version)
* Manuel Tondeur <manueltondeur@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
Item {
id: creature
property int index
property string monsterType
property bool movable
property bool movingOn: false
property bool eating: false
property int frames
property int frameW
property real widthRatio
property GCSfx audioEffects
function moveTo(direction) {
if (!movable)
return true
if (!hasReachLimit(direction)) {
movementOn(direction)
return true
} else {
return false
}
}
function init() {
index = 0
x = 0
y = 0
}
function hasReachLimit(direction) {
switch (direction) {
case 0:
if ((index + 1) % 6 > 0)
return false
break
case 1:
if ((index % 6) > 0)
return false
break
case 2:
if (index < 30)
return false
break
case 3:
if (index > 5)
return false
break
}
return true
}
function movementOn(direction) {
// Compute if the direction is vertical (1) or not (0)
var vertical = Math.floor(direction / 2)
var sign = Math.pow(-1, (direction))
index += sign * (1 + 5 * vertical)
var restIndex = index % 6
y = ((index - restIndex) / 6) * grid.cellHeight
x = restIndex * grid.cellWidth
}
function updatePosition() {
var restIndex = index % 6
y = ((index - restIndex) / 6) * grid.cellHeight
x = restIndex * grid.cellWidth
}
index: 0
z: 0
movable: true
width: grid.cellWidth
height: grid.cellHeight
onEatingChanged: {
if (eating == true) {
creatureImage.restart()
creatureImage.resume()
creature.audioEffects.play("qrc:/gcompris/src/activities/gnumch-equality/resource/eat.wav")
}
}
AnimatedSprite {
id: creatureImage
property int turn: 0
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
- width: parent.width / parent.height < widthRatio ? parent.width * 0.85 : parent.height * 0.85 * widthRatio
+ width: parent.width / parent.height <= widthRatio ? parent.width * 0.85 : parent.height * 0.85 * widthRatio
height: width * (1/widthRatio)
source: "qrc:/gcompris/src/activities/gnumch-equality/resource/"
+ monsterType + ".png"
frameCount: frames
frameWidth: frameW
frameDuration: 50
currentFrame: 0
running: false
onCurrentFrameChanged: {
if (currentFrame == frames - 1) {
turn++
}
}
onTurnChanged: {
if (turn == 2) {
eating = false
turn = 0
currentFrame = 0
pause()
}
}
}
Behavior on x {
NumberAnimation {
id: xAnim
duration: 300
onRunningChanged: {
movingOn = !movingOn
}
}
}
Behavior on y {
NumberAnimation {
id: yAnim
duration: 300
onRunningChanged: {
movingOn = !movingOn
}
}
}
Behavior on opacity {
NumberAnimation {
duration: 500
}
}
}
diff --git a/src/activities/gnumch-equality/Diaper.qml b/src/activities/gnumch-equality/Diaper.qml
index f2faf9910..5b2dc1018 100644
--- a/src/activities/gnumch-equality/Diaper.qml
+++ b/src/activities/gnumch-equality/Diaper.qml
@@ -1,40 +1,40 @@
/* GCompris - Diaper.qml
*
* Copyright (C) 2014 Manuel Tondeur <manueltondeur@gmail.com>
*
* Authors:
* Joe Neeman (spuzzzzzzz@gmail.com) (GTK+ version)
* Manuel Tondeur <manueltondeur@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
Monster {
id: diaper
monsterType: "diaper"
frames: 3
frameW: 54
widthRatio: 0.81
onMovingOnChanged: {
if (movingOn == false && opacity == 1) {
if (Math.random() > 0.5) {
direction = Math.floor(Math.random()*4)
}
modelCells.regenCell(index)
}
}
}
diff --git a/src/activities/gnumch-equality/Eater.qml b/src/activities/gnumch-equality/Eater.qml
index 974b3c292..5fc837d1b 100644
--- a/src/activities/gnumch-equality/Eater.qml
+++ b/src/activities/gnumch-equality/Eater.qml
@@ -1,40 +1,40 @@
/* GCompris - Eater.qml
*
* Copyright (C) 2014 Manuel Tondeur <manueltondeur@gmail.com>
*
* Authors:
* Joe Neeman (spuzzzzzzz@gmail.com) (GTK+ version)
* Manuel Tondeur <manueltondeur@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
Monster {
id: eater
monsterType: "eater"
frames: 3
frameW: 64
widthRatio: 0.9
onMovingOnChanged: {
if (movingOn == false) {
if (Math.random() > 0.666) {
modelCells.get(index).show = false
gridPart.isLevelDone()
}
}
}
}
diff --git a/src/activities/gnumch-equality/Fraidy.qml b/src/activities/gnumch-equality/Fraidy.qml
index b4f6e75a7..596eb36f4 100644
--- a/src/activities/gnumch-equality/Fraidy.qml
+++ b/src/activities/gnumch-equality/Fraidy.qml
@@ -1,65 +1,65 @@
/* GCompris - Fraidy.qml
*
* Copyright (C) 2014 Manuel Tondeur <manueltondeur@gmail.com>
*
* Authors:
* Joe Neeman (spuzzzzzzz@gmail.com) (GTK+ version)
* Manuel Tondeur <manueltondeur@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
// Fraidy is an afraid monster. He won't go in the center but he'll
// stay close to the border.
Monster {
id: fraidy
property int firstDirection
function setFirstDirection() {
var firstDir = direction
firstDirection = firstDir
}
monsterType: "fraidy"
frames: 3
frameW: 53
widthRatio: 0.74
onMovingOnChanged: {
// He will either follow the border or go outside.
if (movingOn == false) {
if (Math.random() > 0.5) {
// He will go outside in this case.
if (firstDirection % 2 == 0) {
direction = firstDirection + 1
} else {
direction = firstDirection - 1
}
}
}
}
onOpacityChanged: {
// When fraidy appear, he will not go straight but follow the border or go outside.
if (opacity == 1) {
direction = (direction + Math.pow(-1, Math.floor(Math.random()*2))) % 4
if (direction < 0)
direction = 3
}
}
Component.onCompleted: setFirstDirection()
}
diff --git a/src/activities/gnumch-equality/Gnumch.qml b/src/activities/gnumch-equality/Gnumch.qml
index 8dbb26bea..8adcdf92a 100644
--- a/src/activities/gnumch-equality/Gnumch.qml
+++ b/src/activities/gnumch-equality/Gnumch.qml
@@ -1,398 +1,398 @@
/* GCompris - Gnumch.qml
*
* Copyright (C) 2014 Manuel Tondeur <manueltondeur@gmail.com>
*
* Authors:
* Joe Neeman (spuzzzzzzz@gmail.com) (GTK+ version)
* Manuel Tondeur <manueltondeur@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "gnumch-equality.js" as Activity
ActivityBase {
id: activity
property string type
property string operator
focus: true
operator: " + "
onStart: {}
onStop: {}
pageComponent: Rectangle {
id: background
function checkAnswer() {
if (!muncher.movable)
return
muncher.eating = true
// Set the cell invisible if it's the correct answer.
if (Activity.isAnswerCorrect(muncher.index)) {
modelCells.get(muncher.index).show = false
var levelDone = gridPart.isLevelDone()
if (levelDone) {
nextLevel()
}
} else {
modelCells.get(muncher.index).show = false
muncher.getCaught(muncher.index)
}
}
function nextLevel() {
Activity.nextLevel()
if (Activity._currentLevel == 7) {
operator = " - "
Activity._operator = operator
}
if (Activity._currentLevel == 0) {
operator = " + "
}
topPanel.goal = Activity.getGoal()
monsters.destroyAll()
Activity.fillAllGrid()
topPanel.life.opacity = 1
spawningMonsters.stop()
timerActivateWarn.stop()
if (Activity._currentLevel != 7) {
spawningMonsters.start()
timerActivateWarn.start()
}
}
anchors.fill: parent
color: "#ABCDEF"
signal start
signal stop
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
onStart: {
Activity.start(modelCells, topPanel.bar, bonus, type, operator)
topPanel.life.opacity = 1
forceActiveFocus()
operator = " + "
Activity._operator = operator
Activity.fillAllGrid()
topPanel.goal = Activity.getGoal()
if (Activity._currentLevel % 6 == 1) {
spawningMonsters.restart()
} else {
spawningMonsters.stop()
timerActivateWarn.stop()
}
}
onStop: {
monsters.destroyAll()
muncher.init()
Activity.stop()
}
Keys.onRightPressed: muncher.moveTo(0)
Keys.onLeftPressed: muncher.moveTo(1)
Keys.onDownPressed: muncher.moveTo(2)
Keys.onUpPressed: muncher.moveTo(3)
Keys.onSpacePressed: {
checkAnswer()
}
Keys.onReturnPressed: {
warningRect.hideWarning()
}
// Debug utility.
// Keys.onAsteriskPressed: {
// nextLevel()
// }
onWidthChanged: {
positionTimer.restart()
}
Timer {
id: positionTimer
interval: 100
onTriggered: {
muncher.updatePosition()
var children = monsters.children
for (var it = 0; it < children.length; it++) {
children[it].updatePosition()
}
}
}
Connections {
target: warningRect.mArea
onClicked: warningRect.hideWarning()
}
Rectangle {
id: gridPart
width: background.width
height: background.height / 7 * 6
border.color: "black"
border.width: 2
anchors.right: parent.right
anchors.top: parent.top
anchors.bottom: topPanel.top
radius: 5
function isLevelDone() {
for (var it = 0; it < modelCells.count; it++) {
if (Activity.isAnswerCorrect(it) && modelCells.get(it).show) {
return false
}
}
bonus.good("gnu")
return true
}
MultiPointTouchArea {
anchors.fill: parent
touchPoints: [ TouchPoint { id: point1 } ]
property real startX
property real startY
// Workaround to avoid having 2 times the onReleased event
property bool started
onPressed: {
startX = point1.x
startY = point1.y
started = true
}
onReleased: {
if(!started)
return false
var moveX = point1.x - startX
var moveY = point1.y - startY
// Find the direction with the most move
if(Math.abs(moveX) * ApplicationInfo.ratio > 10 &&
Math.abs(moveX) > Math.abs(moveY)) {
if(moveX > 10 * ApplicationInfo.ratio)
muncher.moveTo(0)
else if(moveX < -10 * ApplicationInfo.ratio)
muncher.moveTo(1)
else
background.checkAnswer()
} else if(Math.abs(moveY) * ApplicationInfo.ratio > 10 &&
Math.abs(moveX) < Math.abs(moveY)) {
if(moveY > 10 * ApplicationInfo.ratio)
muncher.moveTo(2)
else if(moveY < -10 * ApplicationInfo.ratio)
muncher.moveTo(3)
else
background.checkAnswer()
} else {
// No move, just a tap or mouse click
if(point1.x > muncher.x + muncher.width)
muncher.moveTo(0)
else if(point1.x < muncher.x)
muncher.moveTo(1)
else if(point1.y < muncher.y)
muncher.moveTo(3)
else if(point1.y > muncher.y + muncher.height)
muncher.moveTo(2)
else
background.checkAnswer()
}
started = false
}
}
Muncher {
id: muncher
audioEffects: activity.audioEffects
}
Item {
id: monsters
function setMovable(movable) {
var children = monsters.children
for (var it = 0; it < children.length; it++) {
children[it].movable = movable
}
}
function destroyAll() {
var children = monsters.children
for (var it = 0; it < children.length; it++) {
children[it].destroy()
}
}
function isThereAMonster(position) {
var children = monsters.children
for (var it = 0; it < children.length; it++) {
if (children[it].index == position) {
children[it].eating = true
return true
}
}
return false
}
function checkOtherMonster(position) {
var children = monsters.children
var count = 0
for (var it = 0; it < children.length; it++) {
if (children[it].index == position
&& !children[it].movingOn) {
count++
if (count > 1) {
children[it].opacity = 0
}
}
}
}
}
// Show an hint to show that can move by swiping anywhere
Image {
anchors {
right: parent.right
bottom: parent.bottom
margins: 12
}
source: "qrc:/gcompris/src/core/resource/arrows_move.svg"
sourceSize.width: 140
opacity: topPanel.bar.level == 1 && ApplicationInfo.isMobile ? 0.8 : 0
}
Timer {
id: spawningMonsters
interval: Activity.genTime()
running: false
repeat: true
onTriggered: {
interval = Activity.genTime()
timerActivateWarn.start()
var comp = Qt.createComponent("qrc:/gcompris/src/activities/gnumch-equality/" +
Activity.genMonster(
) + ".qml")
if (comp.status === Component.Ready) {
var direction = Math.floor(Math.random() * 4)
var result = Activity.genPosition(direction,
grid.cellWidth,
grid.cellHeight)
var reggie = comp.createObject(monsters, {
audioEffects: activity.audioEffects,
direction: direction,
player: muncher,
index: result[0],
x: result[1],
y: result[2]
})
reggie.opacity = 1
}
}
}
Timer {
id: timerActivateWarn
interval: spawningMonsters.interval - 2000
running: spawningMonsters.running
onTriggered: {
warnMonsters.opacity = 1
}
}
GridView {
id: grid
anchors.fill: parent
cellHeight: (parent.height - 2) / 6
cellWidth: (parent.width - 2) / 6
interactive: false
focus: false
model: modelCells
delegate: gridDelegate.delegate
}
CellDelegate {
id: gridDelegate
}
ListModel {
id: modelCells
function regenCell(position) {
if (type == "equality" || type == "inequality") {
var terms
if (operator == " + ") {
terms = Activity.splitPlusNumber(
Activity.genNumber())
} else {
terms = Activity.splitMinusNumber(
Activity.genNumber())
}
modelCells.setProperty(position, "number1", terms[0])
modelCells.setProperty(position, "number2", terms[1])
} else if (type == "multiples") {
modelCells.setProperty(position, "number1", Activity.genMultiple())
} else if (type == "factors") {
modelCells.setProperty(position, "number1", Activity.genFactor())
}
modelCells.setProperty(position, "show", true)
gridPart.isLevelDone()
}
}
}
TopPanel {
id: topPanel
goal: Activity.getGoal() ? Activity.getGoal() : 0
}
WarnMonster {
id: warnMonsters
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Warning {
id: warningRect
}
Bonus {
id: bonus
}
}
}
diff --git a/src/activities/gnumch-equality/GnumchEquality.qml b/src/activities/gnumch-equality/GnumchEquality.qml
index ba6219d65..0339cd1f1 100644
--- a/src/activities/gnumch-equality/GnumchEquality.qml
+++ b/src/activities/gnumch-equality/GnumchEquality.qml
@@ -1,26 +1,26 @@
/* GCompris - GnumchEquality.qml
*
* Copyright (C) 2014 Manuel Tondeur <manueltondeur@gmail.com>
*
* Authors:
* Joe Neeman (spuzzzzzzz@gmail.com) (GTK+ version)
* Manuel Tondeur <manueltondeur@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
Gnumch {
type: "equality"
}
diff --git a/src/activities/gnumch-equality/Monster.qml b/src/activities/gnumch-equality/Monster.qml
index c5a10afd7..37ef80d4d 100644
--- a/src/activities/gnumch-equality/Monster.qml
+++ b/src/activities/gnumch-equality/Monster.qml
@@ -1,87 +1,87 @@
/* GCompris - Monster.qml
*
* Copyright (C) 2014 Manuel Tondeur <manueltondeur@gmail.com>
*
* Authors:
* Joe Neeman (spuzzzzzzz@gmail.com) (GTK+ version)
* Manuel Tondeur <manueltondeur@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "gnumch-equality.js" as Activity
Creature {
id: monster
property int direction
property var player
function checkCell() {
- if (index == player.index) {
+ if (index === player.index) {
player.getCaught(-1)
eating = true
}
if (monsters.checkOtherMonster(index)) {
eating = true
}
}
opacity: 0
onMovingOnChanged: {
if (movingOn == false) {
checkCell()
}
}
onOpacityChanged: {
if (opacity == 1) {
checkCell()
}
}
Timer {
id: timerMove
interval: 2000
running: true
repeat: true
onTriggered: {
if (!moveTo(direction)) {
var vertical = Math.floor(direction/2)
var sign = Math.pow(-1,(direction))
y = y + sign * grid.cellHeight * vertical
x = x - sign * grid.cellWidth * (vertical - 1)
opacity = 0
}
}
}
Behavior on opacity {
NumberAnimation {
id: animationEnd
duration: 500
onRunningChanged: {
if (!animationEnd.running && monster.opacity == 0) {
monster.destroy()
}
}
}
}
}
diff --git a/src/activities/gnumch-equality/Muncher.qml b/src/activities/gnumch-equality/Muncher.qml
index b6fe1818d..3dc44ad76 100644
--- a/src/activities/gnumch-equality/Muncher.qml
+++ b/src/activities/gnumch-equality/Muncher.qml
@@ -1,81 +1,81 @@
/* GCompris - Muncher.qml
*
* Copyright (C) 2014 Manuel Tondeur <manueltondeur@gmail.com>
*
* Authors:
* Joe Neeman (spuzzzzzzz@gmail.com) (GTK+ version)
* Manuel Tondeur <manueltondeur@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
Creature {
function getCaught(index) {
if (!movable) {
return
}
caughted = true
opacity = 0
warningRect.setFault(index)
warningRect.opacity = 0.95
if (topPanel.life.opacity == 1) {
topPanel.life.opacity = 0
spawningMonsters.stop()
movable = false
monsters.setMovable(false)
} else {
bonus.bad("tux")
monsters.destroyAll()
spawningMonsters.restart()
start()
}
}
property bool caughted: false
monsterType: "muncher"
frames: 4
frameW: 80
widthRatio: 1.35
Drag.active: ApplicationInfo.isMobile ? muncherArea.drag.active : false
Drag.hotSpot.x: width / 2
Drag.hotSpot.y: height / 2
onMovingOnChanged: {
if (movingOn == false && caughted) {
init()
caughted = false
}
}
onIndexChanged: {
audioEffects.stop()
audioEffects.play("qrc:/gcompris/src/core/resource/sounds/smudge.wav")
if (monsters.isThereAMonster(index)) {
getCaught(-1)
}
}
onOpacityChanged: {
if (opacity == 0) {
init()
}
}
}
diff --git a/src/activities/gnumch-equality/Reggie.qml b/src/activities/gnumch-equality/Reggie.qml
index d8d562d4d..032510b54 100644
--- a/src/activities/gnumch-equality/Reggie.qml
+++ b/src/activities/gnumch-equality/Reggie.qml
@@ -1,30 +1,30 @@
/* GCompris - Reggie.qml
*
* Copyright (C) 2014 Manuel Tondeur <manueltondeur@gmail.com>
*
* Authors:
* Joe Neeman (spuzzzzzzz@gmail.com) (GTK+ version)
* Manuel Tondeur <manueltondeur@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
Monster {
id: reggie
monsterType: "reggie"
frames: 3
frameW: 54
widthRatio: 0.81
}
diff --git a/src/activities/gnumch-equality/Smarty.qml b/src/activities/gnumch-equality/Smarty.qml
index 2a36162db..f92e335dd 100644
--- a/src/activities/gnumch-equality/Smarty.qml
+++ b/src/activities/gnumch-equality/Smarty.qml
@@ -1,54 +1,54 @@
/* GCompris - Smarty.qml
*
* Copyright (C) 2014 Manuel Tondeur <manueltondeur@gmail.com>
*
* Authors:
* Joe Neeman (spuzzzzzzz@gmail.com) (GTK+ version)
* Manuel Tondeur <manueltondeur@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
// Smarty is smart enough to follow the muncher. So he will go after him.
Monster {
id: smarty
frames: 3
frameW: 66
widthRatio: 0.93
function goAfterMuncher() {
// Number of cells between muncher and smarty.
var horizontalCells = muncher.index % 6 - index % 6
var verticalCells = ((muncher.index - muncher.index % 6) / 6) - ((index - index % 6) / 6)
if (horizontalCells == 0 && verticalCells == 0)
return
if ( Math.abs(horizontalCells) >= Math.abs(verticalCells)) {
direction = 0.5 - (horizontalCells / Math.abs(horizontalCells))/2
} else {
direction = 2.5 - (verticalCells / Math.abs(verticalCells))/2
}
}
monsterType: "smarty"
onMovingOnChanged: {
if (movingOn == false) {
goAfterMuncher()
}
}
}
diff --git a/src/activities/gnumch-equality/TopPanel.qml b/src/activities/gnumch-equality/TopPanel.qml
index 87407870c..a0601bd9d 100644
--- a/src/activities/gnumch-equality/TopPanel.qml
+++ b/src/activities/gnumch-equality/TopPanel.qml
@@ -1,114 +1,109 @@
/* GCompris - TopPanel.qml
*
* Copyright (C) 2014 Manuel Tondeur <manueltondeur@gmail.com>
*
* Authors:
* Joe Neeman (spuzzzzzzz@gmail.com) (GTK+ version)
* Manuel Tondeur <manueltondeur@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
Rectangle {
property int goal
- property var muncherLife : muncherLife
- property var life : life
- property var bar : bar
+ property var muncherLife: muncherLife
+ property var life: life
+ property var bar: bar
width: gridPart.width
- height: background.height / 7 - 4
+ height: background.height / 3
anchors.right: parent.right
anchors.bottom: parent.bottom
border.color: "black"
border.width: 2
radius: 5
onGoalChanged: {
goalText.text = goalText.setTextGoal(goal)
}
GCText {
id: goalText
+ height: parent.height - bar.height
+ width: parent.width - parent.height*1.8
function setTextGoal(goal) {
if (activity.type === "equality") {
return qsTr("Equal to %1").arg(goal)
} else if (activity.type === "inequality") {
return qsTr("Not equal to %1").arg(goal)
} else if (activity.type === "factors") {
return qsTr("Factor of %1").arg(goal)
} else if (activity.type === "multiples") {
return qsTr("Multiple of %1").arg(goal)
} else if (activity.type === "primes") {
return qsTr("Primes less than %1").arg(goal)
}
}
fontSizeMode: Text.Fit
minimumPointSize: 7
fontSize: hugeSize
font.weight: Font.DemiBold
maximumLineCount: 1
- verticalAlignment: Text.AlignVCenter
+ verticalAlignment: Text.AlignTop
horizontalAlignment: Text.AlignHCenter
- anchors {
- right: muncherLife.left
- rightMargin: ApplicationInfo.ratio*5
- left: bar.right
- leftMargin: ApplicationInfo.ratio*5
- top: parent.top
- bottom: parent.bottom
- }
+ anchors.horizontalCenter: parent.horizontalCenter
}
Rectangle {
id: muncherLife
width: height
- height: parent.height * 0.9
+ height: parent.height * 0.5
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
- anchors.rightMargin: ApplicationInfo.ratio*5
+ anchors.rightMargin: 5 * ApplicationInfo.ratio
border.width: 2
radius: 5
Creature {
id: life
monsterType: "muncher"
width: parent.width
height: parent.width
frames: 1
frameW: 80
widthRatio: 1.35
}
}
Bar {
id: bar
content: BarEnumContent {
value: help | home
}
onHelpClicked: displayDialog(dialogHelp)
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
}
}
diff --git a/src/activities/gnumch-equality/WarnMonster.qml b/src/activities/gnumch-equality/WarnMonster.qml
index 5ada278d6..0ef367e45 100644
--- a/src/activities/gnumch-equality/WarnMonster.qml
+++ b/src/activities/gnumch-equality/WarnMonster.qml
@@ -1,63 +1,63 @@
/* GCompris - WarnMonster.qml
*
* Copyright (C) 2014 Manuel Tondeur <manueltondeur@gmail.com>
*
* Authors:
* Joe Neeman (spuzzzzzzz@gmail.com) (GTK+ version)
* Manuel Tondeur <manueltondeur@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
Rectangle {
- property var text : warningText
+ property alias text: warningText
width: warningText.contentWidth * 1.1
height: warningText.height * 1.1
opacity: 0
border.width: 2
radius: 5
anchors.horizontalCenter: topPanel.horizontalCenter
anchors.verticalCenter: topPanel.verticalCenter
GCText {
id: warningText
- text: qsTr("Be careful, a troggle !")
+ text: qsTr("Be careful, a troggle!")
fontSize: largeSize
wrapMode: Text.WordWrap
horizontalAlignment: Text.AlignHCenter
anchors.horizontalCenter: parent.horizontalCenter
color: "red"
}
onOpacityChanged: timerWarn.start()
Timer {
id: timerWarn
interval: 2500
onTriggered: parent.opacity = 0
}
Behavior on opacity {
NumberAnimation {
duration: 500
}
}
}
diff --git a/src/activities/gnumch-equality/Warning.qml b/src/activities/gnumch-equality/Warning.qml
index 7fc1700e8..2b2bfb8a4 100644
--- a/src/activities/gnumch-equality/Warning.qml
+++ b/src/activities/gnumch-equality/Warning.qml
@@ -1,152 +1,152 @@
/* GCompris - Warning.qml
*
* Copyright (C) 2014 Manuel Tondeur <manueltondeur@gmail.com>
*
* Authors:
* Joe Neeman (spuzzzzzzz@gmail.com) (GTK+ version)
* Manuel Tondeur <manueltondeur@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "gnumch-equality.js" as Activity
Rectangle {
function hideWarning() {
if (opacity > 0) {
opacity = 0
if (Activity._currentLevel % 6 != 0) {
spawningMonsters.start()
timerActivateWarn.start()
}
muncher.movable = true
monsters.setMovable(true)
}
}
property string warningText: warning.text
property string fault
property var mArea: area
function setFault(index) {
- if (index == -1) {
+ if (index === -1) {
fault = qsTr("You were eaten by a Troggle.") + "<br>"
return
}
fault = qsTr("You ate a wrong number.") +"<br>"
var num1 = modelCells.get(index).number1
var num2 = modelCells.get(index).number2
if (activity.type == "equality" || activity.type == "inequality") {
if (activity.operator == " + ") {
fault += num1 + " + " + num2 + " = " + (num1 + num2)
} else {
fault += num1 + " - " + num2 + " = " + (num1 - num2)
}
} else if (activity.type == "primes") {
- if (num1 == 1) {
+ if (num1 === 1) {
fault += qsTr("1 is not a prime number.")
return
}
var divisors = []
for (var div = 2; div < num1; ++div) {
if ((num1 / div) % 1 == 0)
divisors.push(div)
}
fault += qsTr("%1 is divisible by %2").arg(num1).arg(divisors[0])
if (divisors.length > 2) {
for (var div = 1; div < divisors.length - 1; ++div) {
fault += ", " + divisors[div]
}
}
fault += " " + qsTr("and") + " " + divisors[divisors.length - 1] + "."
} else if (activity.type == "factors") {
// First we find the multiples of the wrong number.
var multiples = "" + num1*2 + ", " + num1*3 + ", " + num1*4
fault += qsTr("Multiples of %1 include %2, ").arg(num1).arg(multiples)
fault += qsTr("but %1 is not a multiple of %2.").arg(Activity.getGoal()).arg(num1)
} else if (activity.type == "multiples") {
// First we find divisors of the wrong number.
var divisors = []
for (var div = 1; div < Activity.getGoal() * 6; ++div) {
if ((num1 / div) % 1 == 0)
divisors.push(div)
}
fault += divisors[0]
if (divisors.length > 2) {
for (var div = 1; div < divisors.length - 1; ++div) {
fault += ", " + divisors[div]
}
}
fault += " " + qsTr("and %1 are the divisors of %2.").arg(divisors[divisors.length - 1]).arg(num1)
}
}
width: 400 * ApplicationInfo.ratio
height: 150 * ApplicationInfo.ratio
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
z: 3
border.width: 2
radius: 5
opacity: 0
color: "#00d635"
onOpacityChanged: {
if (opacity == 0) {
muncher.opacity = 1
area.enabled = false
} else {
area.enabled = true
}
}
GCText {
id: warning
anchors.fill: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
text: fault + "<br>" + qsTr("Press \"Return\" or click on me to continue.")
fontSizeMode: Text.Fit
minimumPointSize: 10
fontSize: 28
wrapMode: Text.WordWrap
}
Behavior on opacity {
NumberAnimation {
duration: 200
}
}
MouseArea {
id: area
anchors.fill: parent
enabled: false
}
}
diff --git a/src/activities/gnumch-equality/gnumch-equality.js b/src/activities/gnumch-equality/gnumch-equality.js
index 2a38af727..19d1a77f0 100644
--- a/src/activities/gnumch-equality/gnumch-equality.js
+++ b/src/activities/gnumch-equality/gnumch-equality.js
@@ -1,296 +1,296 @@
/* GCompris - GnumchEquality.qml
*
* Copyright (C) 2014 Manuel Tondeur <manueltondeur@gmail.com>
*
* Authors:
* Joe Neeman (spuzzzzzzz@gmail.com) (GTK+ version)
* Manuel Tondeur <manueltondeur@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
var _currentLevel = 0
var _numberOfLevel = 14
var _main
var _bar
var _bonus
var _type
var _operator
var _modelCells
function start(modelCells, bar, bonus, type, operator) {
_bar = bar
_bonus = bonus
_currentLevel = 0
_type = type
_operator = operator
_modelCells = modelCells
if (type != "equality" && type != "inequality") {
_numberOfLevel = 8
}
}
function stop() {
}
function nextLevel() {
if(_numberOfLevel <= ++_currentLevel ) {
_currentLevel = 0
}
}
function previousLevel() {
if(--_currentLevel < 0) {
_currentLevel = _numberOfLevel - 1
}
}
function getGoal() {
var goal
if (_type == "equality" || _type == "inequality") {
goal = _currentLevel + 6
if (_currentLevel > 6) {
goal = _currentLevel - 1
}
} else if (_type == "multiples") {
goal = _currentLevel + 2
} else if (_type == "factors") {
var goalsFactor = [4, 6, 8, 10, 12, 15, 18, 20]
goal = goalsFactor[_currentLevel]
} else if (_type == "primes") {
var primenumbers = [2, 3, 5, 7, 11, 13, 17, 19, 23]
goal = primenumbers[_currentLevel + 1] + 1
}
return goal
}
function genNumber() {
if (Math.random() < 0.5) {
// Choose a good number
return (getGoal())
} else {
// Choose a bad number
var sign = Math.random() - 0.5
sign = sign / Math.abs(sign)
var number = getGoal() + (sign * Math.floor(((Math.random() * (getGoal() - 1)) + 1)))
return number
}
}
function genMultiple() {
var number = getGoal() * Math.floor(Math.random() * 6 + 1)
if (Math.random() < 0.5) {
// Choose a good number
return number
} else {
// Choose a bad number
return number - 1
}
}
function genFactor() {
var goodOnes = []
var badOnes = []
for (var div = 1; div < getGoal() + 1; ++div) {
if (getGoal() % div == 0) {
goodOnes.push(div)
} else {
badOnes.push(div)
}
}
if (Math.random() < 0.5) {
// Choose a good number
return goodOnes[Math.floor(Math.random() * goodOnes.length)]
} else {
// Choose a bad number
return badOnes[Math.floor(Math.random() * badOnes.length)]
}
}
function genPrime() {
var primenumbers = [2, 3, 5, 7, 11, 13, 17, 19, 23]
var badNumbers = [1, 4, 6, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 22]
if (Math.random() < 0.5) {
// Choose a good number
var goodOnes = []
for (var it = 0; it < primenumbers.length; ++it) {
if (getGoal() < primenumbers[it])
break
goodOnes.push(primenumbers[it])
}
return goodOnes[Math.floor(Math.random() * goodOnes.length)]
} else {
// Choose a bad number
var badOnes = []
for (var it = 0; it < badNumbers.length; ++it) {
if (getGoal() < badNumbers[it])
break
badOnes.push(badNumbers[it])
}
return badOnes[Math.floor(Math.random() * badOnes.length)]
}
}
function genTime() {
// generate a time in millisecond between 3,000 and 10,000
var time = Math.floor(((Math.random() * 10) + 3)) * 1000
return time
}
function splitPlusNumber(term) {
// Check if the term is odd
var odd = term % 2
var term1 = Math.floor(term / 2)
var term2 = term1 + odd
// Shift randomly the terms
var shift = Math.floor((Math.random() * term1))
term1 += shift
term2 -= shift
// Switch randomly the terms
if (Math.random() < 0.5) {
return [term1, term2]
} else {
return [term2, term1]
}
}
function splitMinusNumber(term) {
var term1 = term
var term2 = 0
// Shift randomly the terms
var shift = Math.floor((Math.random() * (term + 1)))
term1 += shift
term2 += shift
return [term1, term2]
}
function genPosition(direction, cellWidth, cellHeight) {
var randomNumber = Math.floor(Math.random() * 5)
if (direction == 0) {
return [6 * randomNumber, 0, cellHeight * randomNumber]
} else if (direction == 2) {
return [randomNumber, cellWidth * randomNumber, 0]
} else if (direction == 1) {
return [6 * randomNumber + 5, cellWidth * 5, cellHeight * randomNumber]
} else if (direction == 3) {
return [30 + randomNumber, cellWidth * randomNumber, cellHeight * 5]
}
}
function genMonster() {
var monsters = ["Reggie", "Diaper", "Eater", "Fraidy", "Smarty", "Reggie"]
var allowedMonsters = _currentLevel % 7
return monsters[Math.floor(Math.random()*allowedMonsters)]
}
function fillAllGrid() {
_modelCells.clear()
if (_type == "equality" || _type == "inequality") {
for (var it = 0; it < 36; it++) {
var terms
if (_operator == " + ") {
terms = splitPlusNumber(
genNumber())
} else {
terms = splitMinusNumber(
genNumber())
}
_modelCells.append({
number1: terms[0],
number2: terms[1],
show: true
})
}
} else if (_type == "primes") {
for (var it = 0; it < 36; it++) {
_modelCells.append({"number1": genPrime(), "number2": -1, "show": true});
}
} else if (_type == "factors") {
for (var it = 0; it < 36; it++) {
_modelCells.append({"number1": genFactor(), "number2": -1, "show": true});
}
} else if (_type == "multiples") {
for (var it = 0; it < 36; it++) {
_modelCells.append({"number1": genMultiple(), "number2": -1, "show": true});
}
}
}
function isAnswerCorrect(position) {
if (_type == "equality") {
if (_operator == " + ") {
if ((_modelCells.get(position).number1 + _modelCells.get(
position).number2) == (getGoal())) {
return true
} else {
return false
}
} else {
if ((_modelCells.get(position).number1 - _modelCells.get(
position).number2) == (getGoal())) {
return true
} else {
return false
}
}
} else if (_type == "inequality") {
if (_operator == " + ") {
if ((_modelCells.get(position).number1 + _modelCells.get(
position).number2) != (getGoal())) {
return true
} else {
return false
}
} else {
if ((_modelCells.get(position).number1 - _modelCells.get(
position).number2) != (getGoal())) {
return true
} else {
return false
}
}
} else if (_type == "multiples") {
if ((_modelCells.get(position).number1 / getGoal()) % 1 == 0) {
return true
} else {
return false
}
} else if (_type == "factors") {
if ((getGoal() / _modelCells.get(position).number1) % 1 == 0) {
return true
} else {
return false
}
} else if (_type == "primes") {
var primenumbers = [2, 3, 5, 7, 11, 13, 17, 19]
for (var it = 0; it < 8; ++it) {
if (primenumbers[it] == _modelCells.get(position).number1)
return true
}
return false
}
}
diff --git a/src/activities/gnumch-factors/ActivityInfo.qml b/src/activities/gnumch-factors/ActivityInfo.qml
index 37820504a..a6ce7a53c 100644
--- a/src/activities/gnumch-factors/ActivityInfo.qml
+++ b/src/activities/gnumch-factors/ActivityInfo.qml
@@ -1,45 +1,45 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Manuel Tondeur <manueltondeur@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
// Must be updated once GnumchEquality is reviewed
ActivityInfo {
name: "gnumch-factors/GnumchFactors.qml"
difficulty: 5
icon: "gnumch-factors/gnumch-factors.svg"
author: "Manuel Tondeur &lt;manueltondeur@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Gnumch Factors")
//: Help title
- description: qsTr("Guide the Number Muncher to all the factors of the number at the top of the screen.")
+ description: qsTr("Guide the Number Muncher to all the factors of the number at the bottom of the screen.")
// intro: "Guide the number eater with the arrow keys to the factors of the displayed number and press space to swallow them."
//: Help goal
goal: qsTr("Learn about multiples and factors.")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("The factors of a number are all the numbers that divide that number evenly. For example, the factors of 6 are 1, 2, 3 and 6. 4 is not a factor of 6 because 6 cannot be divided into 4 equal pieces. If one number is a multiple of a second number, then the second number is a factor of the first number. You can think of multiples as families, and factors are the people in those families. So 1, 2, 3 and 6 all fit into the 6 family, but 4 belongs to another family.") +
"<br><br>" +
qsTr("If you have a keyboard you can use the arrow keys to move and hit space to swallow a number. With a mouse you can click on the block next to your position to move and click again to swallow the number. With a touch screen you can do like with a mouse or swipe anywhere in the direction you want to move and tap to swallow the number.") +
"<br><br>" +
qsTr("Take care to avoid the Troggles.")
credit: ""
section: "math"
createdInVersion: 0
}
diff --git a/src/activities/gnumch-factors/GnumchFactors.qml b/src/activities/gnumch-factors/GnumchFactors.qml
index 180d42a76..c487b349f 100644
--- a/src/activities/gnumch-factors/GnumchFactors.qml
+++ b/src/activities/gnumch-factors/GnumchFactors.qml
@@ -1,29 +1,29 @@
/* GCompris - gnumch-factors.qml
*
* Copyright (C) 2014 Manuel Tondeur <manueltondeur@gmail.com>
*
* Authors:
* Joe Neeman <spuzzzzzzz@gmail.com> (GTK+ version)
* Manuel Tondeur <manueltondeur@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
import "../gnumch-equality/"
Gnumch {
type: "factors"
}
diff --git a/src/activities/gnumch-inequality/ActivityInfo.qml b/src/activities/gnumch-inequality/ActivityInfo.qml
index 09a4f5914..8f68b9331 100644
--- a/src/activities/gnumch-inequality/ActivityInfo.qml
+++ b/src/activities/gnumch-inequality/ActivityInfo.qml
@@ -1,45 +1,43 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Manuel Tondeur <manueltondeur@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
// Must be updated once GnumchEquality is reviewed
ActivityInfo {
name: "gnumch-inequality/GnumchInequality.qml"
difficulty: 3
icon: "gnumch-inequality/gnumch-inequality.svg"
author: "Manuel Tondeur &lt;manueltondeur@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Gnumch Inequality")
//: Help title
- description: qsTr("Guide the Number Muncher to the all the expressions that do not equal the number at the top of the screen.")
+ description: qsTr("Guide the Number Muncher to all the expressions that do not equal the number at the bottom of the screen.")
// intro: "Guide the number eater with the arrow keys to the numbers that are different from the ones displayed and press the space bar to swallow them."
//: Help goal
goal: qsTr("Practice addition, subtraction, multiplication and division.")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("If you have a keyboard you can use the arrow keys to move and hit space to swallow a number. With a mouse you can click on the block next to your position to move and click again to swallow the number. With a touch screen you can do like with a mouse or swipe anywhere in the direction you want to move and tap to swallow the number.") +
- "<br><br>" +
- qsTr("If you have a keyboard you can use the arrow keys to move and hit space to swallow a number. With a mouse you can click on the block next to your position to move and click again to swallow the number. With a touch screen you can do like with a mouse or swipe anywhere in the direction you want to move and tap to swallow the number.") +
"<br><br>" +
qsTr("Take care to avoid the Troggles.")
credit: ""
section: "math"
createdInVersion: 0
}
diff --git a/src/activities/gnumch-inequality/GnumchInequality.qml b/src/activities/gnumch-inequality/GnumchInequality.qml
index 41fc41c22..0a26a0cbc 100644
--- a/src/activities/gnumch-inequality/GnumchInequality.qml
+++ b/src/activities/gnumch-inequality/GnumchInequality.qml
@@ -1,29 +1,29 @@
/* GCompris - gnumch-inequality.qml
*
* Copyright (C) 2014 Manuel Tondeur <manueltondeur@gmail.com>
*
* Authors:
* Joe Neeman <spuzzzzzzz@gmail.com> (GTK+ version)
* Manuel Tondeur <manueltondeur@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
import "../gnumch-equality/"
Gnumch {
type: "inequality"
}
diff --git a/src/activities/gnumch-multiples/ActivityInfo.qml b/src/activities/gnumch-multiples/ActivityInfo.qml
index 3f09136f3..d13bb17b5 100644
--- a/src/activities/gnumch-multiples/ActivityInfo.qml
+++ b/src/activities/gnumch-multiples/ActivityInfo.qml
@@ -1,45 +1,44 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Manuel Tondeur <manueltondeur@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
-// Must be updated once GnumchEquality is reviewed
ActivityInfo {
name: "gnumch-multiples/GnumchMultiples.qml"
difficulty: 3
icon: "gnumch-multiples/gnumch-multiples.svg"
author: "Manuel Tondeur &lt;manueltondeur@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Gnumch Multiples")
//: Help title
- description: qsTr("Guide the Number Muncher to all the multiples of the number at the top of the screen.")
+ description: qsTr("Guide the Number Muncher to all the multiples of the number at the bottom of the screen.")
// intro: "Guide the number eater with the arrow keys to the multiples of the displayed number and press space to swallow them."
//: Help goal
goal: qsTr("Learn about multiples and factors.")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("The multiples of a number are all the numbers that are equal to the original number times another number. For example, 24, 36, 48 and 60 are all multiples of 12. 25 is not a multiple of 12 because there isn't any number that can be multiplied by 12 to get 25. If one number is a factor of a second number, then the second number is a multiple of the first number. Again, you can think of multiples as families, and factors are the people who belong to those families. The factor 5, has parents 10, grandparents 15, great-grandparents 20, great-great-grandparents 25, and every extra step of 5 is another great- in front! But the number 5 does not belong in the 8 or 23 families. You can't fit any number of 5s into 8 or 23 with nothing left over. So 8 isn't a multiple of 5, nor is 23. Only 5, 10, 15, 20, 25 ... are multiples (or families or steps) of 5.") +
"<br><br>" +
qsTr("If you have a keyboard you can use the arrow keys to move and hit space to swallow a number. With a mouse you can click on the block next to your position to move and click again to swallow the number. With a touch screen you can do like with a mouse or swipe anywhere in the direction you want to move and tap to swallow the number.") +
"<br><br>" +
qsTr("Take care to avoid the Troggles.")
credit: ""
section: "math"
createdInVersion: 0
}
diff --git a/src/activities/gnumch-multiples/GnumchMultiples.qml b/src/activities/gnumch-multiples/GnumchMultiples.qml
index dcb85ee3c..92e471b12 100644
--- a/src/activities/gnumch-multiples/GnumchMultiples.qml
+++ b/src/activities/gnumch-multiples/GnumchMultiples.qml
@@ -1,29 +1,29 @@
/* GCompris - gnumch-multiples.qml
*
* Copyright (C) 2014 Manuel Tondeur <manueltondeur@gmail.com>
*
* Authors:
* Joe Neeman <spuzzzzzzz@gmail.com> (GTK+ version)
* Manuel Tondeur <manueltondeur@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
import "../gnumch-equality/"
Gnumch {
type: "multiples"
}
diff --git a/src/activities/gnumch-primes/ActivityInfo.qml b/src/activities/gnumch-primes/ActivityInfo.qml
index 7856b6663..417053150 100644
--- a/src/activities/gnumch-primes/ActivityInfo.qml
+++ b/src/activities/gnumch-primes/ActivityInfo.qml
@@ -1,45 +1,45 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Manuel Tondeur <manueltondeur@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
// Must be updated once GnumchEquality is reviewed
ActivityInfo {
name: "gnumch-primes/GnumchPrimes.qml"
difficulty: 6
icon: "gnumch-primes/gnumch-primes.svg"
author: "Manuel Tondeur &lt;manueltondeur@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Gnumch Primes")
//: Help title
description: qsTr("Guide the Number Muncher to all the prime numbers.")
// intro: "Guide the number eater with the arrow keys to the prime numbers and press space to swallow them."
//: Help goal
goal: qsTr("Learn about prime numbers.")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("Prime numbers are numbers that are only divisible by themselves and 1. For example, 3 is a prime number, but 4 isn't (because 4 is divisible by 2). You can think of prime numbers as very small families: they only ever have two people in them! Only themselves and 1. You can't fit any other numbers into them with nothing left over. 5 is one of these lonely numbers (only 5 × 1 = 5), but you can see that 6 has 2 and 3 in its family as well (6 × 1 = 6, 2 × 3 = 6). So 6 is not a prime number.") +
"<br><br>" +
qsTr("If you have a keyboard you can use the arrow keys to move and hit space to swallow a number. With a mouse you can click on the block next to your position to move and click again to swallow the number. With a touch screen you can do like with a mouse or swipe anywhere in the direction you want to move and tap to swallow the number.") +
"<br><br>" +
qsTr("Take care to avoid the Troggles.")
credit: ""
section: "math"
createdInVersion: 0
}
diff --git a/src/activities/gnumch-primes/GnumchPrimes.qml b/src/activities/gnumch-primes/GnumchPrimes.qml
index 33623c093..4cc763fe3 100644
--- a/src/activities/gnumch-primes/GnumchPrimes.qml
+++ b/src/activities/gnumch-primes/GnumchPrimes.qml
@@ -1,29 +1,29 @@
/* GCompris - gnumch-primes.qml
*
* Copyright (C) 2014 Manuel Tondeur <manueltondeur@gmail.com>
*
* Authors:
* Joe Neeman <spuzzzzzzz@gmail.com> (GTK+ version)
* Manuel Tondeur <manueltondeur@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
import "../gnumch-equality/"
Gnumch {
type: "primes"
}
diff --git a/src/activities/graph-coloring/ActivityInfo.qml b/src/activities/graph-coloring/ActivityInfo.qml
index 45440f751..5dbe1ed18 100644
--- a/src/activities/graph-coloring/ActivityInfo.qml
+++ b/src/activities/graph-coloring/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Akshat Tandon <akshat.tandon@research.iiit.ac.in>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "graph-coloring/GraphColoring.qml"
difficulty: 1
icon: "graph-coloring/graph-coloring.svg"
author: "Akshat Tandon &lt;akshat.tandon@research.iiit.ac.in&gt;"
demo: true
//: Activity title
title: qsTr("Graph Coloring")
//: Help title
description: qsTr("Color the graph so that no two adjacent nodes have the same color.")
//intro: "Color the graph so that no two adjacent nodes have the same color."
//: Help goal
goal: qsTr("Learn to distinguish between different colors/shapes and learn about relative positions.")
//: Help prerequisite
prerequisite: qsTr("Ability to distinguish different colors/shapes, sense of positions")
//: Help manual
manual: ""
credit: ""
section: "math"
createdInVersion: 6000
}
diff --git a/src/activities/graph-coloring/GraphColoring.qml b/src/activities/graph-coloring/GraphColoring.qml
index ffa645802..2ec9f7e38 100644
--- a/src/activities/graph-coloring/GraphColoring.qml
+++ b/src/activities/graph-coloring/GraphColoring.qml
@@ -1,395 +1,395 @@
/* GCompris - graph-coloring.qml
*
* Copyright (C) 2015 Akshat Tandon <akshat.tandon@research.iiit.ac.in>
*
* Authors:
*
* Akshat Tandon <akshat.tandon@research.iiit.ac.in> (Qt Quick version)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
import "graph-coloring.js" as Activity
import GCompris 1.0
ActivityBase {
id: activity
onStart: focus = true
onStop: {}
pageComponent: Image {
id: background
anchors.fill: parent
source: "qrc:/gcompris/src/activities/tic_tac_toe/resource/background.svg"
sourceSize.width: parent.width
fillMode: Image.PreserveAspectCrop
focus: true
signal start
signal stop
Component.onCompleted: {
dialogActivityConfig.getInitialConfiguration()
activity.start.connect(start)
activity.stop.connect(stop)
}
MouseArea {
anchors.fill: parent
onClicked: showChooser(false);
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property alias background: background
property alias bar: bar
property alias bonus: bonus
property alias colorsRepeater: colorsRepeater
property alias nodesRepeater: nodesRepeater
property alias edgesRepeater: edgesRepeater
property alias chooserGrid: chooserGrid
}
onStart: { Activity.start(items) }
onStop: { Activity.stop() }
Column {
id: colorsColumn
anchors.left: parent.left
anchors.leftMargin: 5 * ApplicationInfo.ratio
anchors.top: parent.top
anchors.topMargin: 5 * ApplicationInfo.ratio
spacing: 3 * ApplicationInfo.ratio
add: Transition {
NumberAnimation { properties: "y"; duration: 1000; easing.type: Easing.OutBounce }
}
Repeater {
id: colorsRepeater
model: ListModel {}
delegate:
Node {
width: 40 * ApplicationInfo.ratio
height: 40 * ApplicationInfo.ratio
border.width: 2
border.color: "white"
searchItemIndex: itemIndex
}
}
}
Item {
id: graphRect
anchors.left: parent.left
anchors.leftMargin: 100 * ApplicationInfo.ratio
anchors.bottom: parent.bottom
anchors.bottomMargin: 50 * ApplicationInfo.ratio
anchors.top: parent.top
anchors.topMargin: 50 * ApplicationInfo.ratio
height: background.height - 100 * ApplicationInfo.ratio
width: background.width - 150 * ApplicationInfo.ratio
property int diameter: graphRect.width/11
property int minDiameter: 40 * ApplicationInfo.ratio
property int maxDiameter: 80 * ApplicationInfo.ratio
property int optDiameter: diameter < minDiameter ? minDiameter : ( diameter > maxDiameter ? maxDiameter : diameter)
Repeater {
id: edgesRepeater
model: ListModel {}
delegate: Rectangle {
id: line
opacity: 1
antialiasing: true
color: highlight == true ? "red" : "black"
transformOrigin: Item.TopLeft
x: xp * graphRect.width
y: yp * graphRect.height
property var x2: xpp * graphRect.width
property var y2: ypp * graphRect.height
width: Math.sqrt(Math.pow(x - x2, 2) + Math.pow(y- y2, 2))
height: highlight == true ? 7 * ApplicationInfo.ratio : 3 * ApplicationInfo.ratio
rotation: (Math.atan((y2 - y)/(x2-x)) * 180 / Math.PI) + (((y2-y) < 0 && (x2-x) < 0) * 180) + (((y2-y) >= 0 && (x2-x) < 0) * 180)
Behavior on color {
ColorAnimation {
duration: 2000
easing.type: Easing.OutExpo
}
}
Behavior on height {
NumberAnimation {
duration: 2000
easing.type: Easing.OutExpo
}
}
}
}
Repeater{
id: nodesRepeater
model: ListModel {}
delegate:
Node{
id: currentNode
x: posX * graphRect.width - width/2
y: posY * graphRect.height - height/2
width: graphRect.optDiameter
height: width
radius: width/2
border.color: highlight ? "red" : "black"
border.width: highlight ? 7 : 4
symbolRotation: highlight
searchItemIndex: colIndex
Behavior on border.color {
ColorAnimation {
duration: 2000
easing.type: Easing.OutExpo
}
}
Behavior on border.width {
NumberAnimation {
duration: 2000
easing.type: Easing.OutExpo
}
}
MouseArea {
id: mouseArea
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton
enabled: true
z: 3
hoverEnabled: ApplicationInfo.isMobile ? false : true
onClicked:{
var obj = items.nodesRepeater.model.get(index);
showChooser(true, index, parent);
}
}
states: State {
name: "scaled"; when: mouseArea.containsMouse
PropertyChanges {
target: currentNode
scale: 1.1
}
}
transitions: Transition {
NumberAnimation { properties: "scale"; easing.type: Easing.OutCubic }
}
}
}
}
function showChooser(visible, guessIndex, item)
{
if (!visible) {
chooserTimer.stop();
chooser.scale = 0;
return;
}
var modelObj = items.nodesRepeater.model.get(guessIndex);
var absolute = graphRect.mapToItem(background, item.x, item.y);
chooserGrid.colIndex = modelObj.colIndex;
chooserGrid.guessIndex = guessIndex;
var targetX = absolute.x + item.width;
var targetY = absolute.y - item.height/2;
if (targetX < 0) {
targetX = 0;
}
if (targetX + chooser.width > background.width) {
targetX = background.width - chooser.width - 10;
}
if (targetY < 0) {
targetY = 0;
}
if (targetY + chooser.height > background.height) {
targetY = background.height - chooser.height - 10;
}
chooser.x = targetX;
chooser.y = targetY;
chooser.scale = 1;
chooser.visible = true;
chooserTimer.restart();
//console.log(" item.x = " + item.x + " item.y" + item.y+" absolute.x" + absolute.x +" absolute.y" + absolute.y)
}
Rectangle {
id: chooser
width: chooserGrid.width + 5
height: chooserGrid.height + 5
color: "darkgray"
border.width: 0
border.color: "white"
opacity: 1
scale: 0
visible: false
z: 10
GridView {
id: chooserGrid
cellWidth: graphRect.optDiameter - 2
cellHeight: cellWidth
width: Math.ceil(count / 2) * cellWidth
height: 2 * cellHeight
anchors.centerIn: parent
z: 11
clip: false
interactive: false
verticalLayoutDirection: GridView.TopToBottom
layoutDirection: Qt.LeftToRight
flow: GridView.FlowLeftToRight
property int gridCount : count
property int colIndex: 0
property int guessIndex: 0
Timer {
id: chooserTimer
interval: 5000
onTriggered: showChooser(false);
}
model: new Array()
delegate: Node {
id: chooserItem
width: graphRect.optDiameter - 5
height: width
border.width: index == chooserGrid.colIndex ? 3 : 1
border.color: index == chooserGrid.colIndex ? "white" : "darkgray"
searchItemIndex: modelData
highlightSymbol: index == chooserGrid.colIndex
radius: 5
MouseArea {
id: chooserMouseArea
anchors.fill: parent
acceptedButtons: Qt.LeftButton
z: 11
hoverEnabled: ApplicationInfo.isMobile ? false : true
onClicked: {
chooserGrid.colIndex = chooserItem.searchItemIndex;
var obj = items.nodesRepeater.model;
obj.setProperty(chooserGrid.guessIndex, "colIndex", chooserGrid.colIndex);
showChooser(false);
Activity.checkAdjacent()
Activity.checkGuess()
}
}
}
}
}
DialogHelp {
id: dialogHelp
onClose: home()
}
DialogActivityConfig {
id: dialogActivityConfig
currentActivity: activity
content: Component {
Item {
property alias modeBox: modeBox
property var availableModes: [
{ "text": qsTr("Colors"), "value": "color" },
{ "text": qsTr("Shapes"), "value": "symbol" }
]
Flow {
id: flow
spacing: 5
width: dialogActivityConfig.width
GCComboBox {
id: modeBox
model: availableModes
background: dialogActivityConfig
label: qsTr("Select your mode")
}
}
}
}
onClose: home()
onLoadData: {
if(dataToSave && dataToSave["mode"]) {
Activity.mode = dataToSave["mode"];
}
}
onSaveData: {
var newMode = dialogActivityConfig.configItem.availableModes[dialogActivityConfig.configItem.modeBox.currentIndex].value;
if (newMode !== Activity.mode) {
chooserGrid.model = new Array();
Activity.mode = newMode;
dataToSave = {"mode": Activity.mode};
Activity.initLevel();
}
}
function setDefaultValues() {
for(var i = 0 ; i < dialogActivityConfig.configItem.availableModes.length ; i ++) {
if(dialogActivityConfig.configItem.availableModes[i].value === Activity.mode) {
dialogActivityConfig.configItem.modeBox.currentIndex = i;
break;
}
}
}
}
Bar {
id: bar
content: BarEnumContent { value: config | help | home | level }
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
onConfigClicked: {
dialogActivityConfig.active = true
// Set default values
dialogActivityConfig.setDefaultValues();
displayDialog(dialogActivityConfig)
}
}
Bonus {
id: bonus
Component.onCompleted: win.connect(Activity.nextLevel)
}
}
}
diff --git a/src/activities/graph-coloring/Node.qml b/src/activities/graph-coloring/Node.qml
index e113dd1a3..6a27a96fc 100644
--- a/src/activities/graph-coloring/Node.qml
+++ b/src/activities/graph-coloring/Node.qml
@@ -1,96 +1,96 @@
/* GCompris - SearchItem.qml
*
* Copyright (C) Holger Kaelberer <holger.k@elberer.de>
*
* Authors:
* Holger Kaelberer <holger.k@elberer.de>
* Akshat Tandon <akshat.tandon@research.iiit.ac.in>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
//import QtGraphicalEffects 1.0
import "graph-coloring.js" as Activity
Item {
id: root
property int searchItemIndex: -1
property alias border: color.border
property alias radius: color.radius
property bool highlightSymbol: false
property bool symbolRotation: false
Image {
id: symbol
visible: Activity.mode === "symbol"
fillMode: Image.PreserveAspectFit
source: searchItemIndex == -1 ? Activity.url + "shapes/" + "circle_node.svg" : Activity.symbols[root.searchItemIndex]
anchors.left: parent.left
anchors.top: parent.top
anchors.margins: 3
width: parent.width - 6
height: parent.height - 6
SequentialAnimation {
id: anim
running: root.symbolRotation
loops: Animation.Infinite
NumberAnimation {
target: symbol
property: "rotation"
from: -10; to: 10
duration: 500
easing.type: Easing.InOutQuad
}
NumberAnimation {
target: symbol
property: "rotation"
from: 10; to: -10
duration: 500
easing.type: Easing.InOutQuad }
}
NumberAnimation {
id: rotationStop
running: !root.symbolRotation
target: symbol
property: "rotation"
to: 0
duration: 500
easing.type: Easing.InOutQuad
}
}
Rectangle {
id: symbolHighlighter
visible: (Activity.mode === "symbol") && root.highlightSymbol
anchors.fill: parent
width: parent.width
height: parent.height
border.width: 3
border.color: "white"
color: "transparent"
}
Rectangle {
id: color
visible: Activity.mode === "color"
color: root.searchItemIndex == -1 ? "white" : Activity.colors[root.searchItemIndex]
anchors.fill: parent
width: parent.width
height: parent.height
radius: width / 2
}
}
diff --git a/src/activities/graph-coloring/graph-coloring.js b/src/activities/graph-coloring/graph-coloring.js
index 18094deee..06dc3846f 100644
--- a/src/activities/graph-coloring/graph-coloring.js
+++ b/src/activities/graph-coloring/graph-coloring.js
@@ -1,355 +1,355 @@
/* GCompris - graph-coloring.js
*
* Copyright (C) Akshat Tandon <akshat.tandon@research.iiit.ac.in>
*
* Authors:
*
* Akshat Tandon <akshat.tandon@research.iiit.ac.in> (Qt Quick version)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
var currentLevel = 0
var items
var url = "qrc:/gcompris/src/activities/graph-coloring/resource/"
var coloringLeft
var colors = [
"#FF0000FF", // dark blue
"#FF00FF00", // light green
"#FFFF0000", // red
"#FF00FFFF", // light blue
"#FFFF00FF", // magenta
"#FFFFFF00", // yellow
"#FF8e7016", // brown
"#FF04611a", // dark green
"#FFa0174b" // dark magenta
];
var symbols = [
url + "shapes/" + "star.svg",
url + "shapes/" + "triangle.svg",
url + "shapes/" + "heart.svg",
url + "shapes/" + "cloud.svg",
url + "shapes/" + "diamond.svg",
url + "shapes/" + "star_simple.svg",
url + "shapes/" + "cross.svg",
url + "shapes/" + "ring.svg",
url + "shapes/" + "circle.svg",
];
var graphs = [
{
minColor:3,
edgeList:[
[0, 1], [0, 4], [1, 4], [1, 2], [1, 3], [2, 3]
],
nodePositions : [
[0, 0], [0.5, 0.4], [1, 0], [1, 0.7], [0, 0.7]
]
},
{
minColor: 3,
edgeList:[
[0, 1], [0, 3], [1, 2], [1, 3], [2, 3]
],
nodePositions : [
[0, 0.4], [0.5, 0], [1, 0.4], [0.5, 0.8]
]
},
{
minColor: 4,
edgeList:[
[0, 1], [0, 2], [0, 3],
[1, 2], [1, 3],
[2, 3]
],
nodePositions : [
[0.628, 0.401],
[0.083, 0.401],
[0.900, 0.030],
[0.900, 0.773]
]
},
{
minColor: 3,
edgeList:[
[0,1], [1,2], [2,3], [3,4], [4,0], [5,7],
[7,9], [9,6], [6,8], [8,5], [0,5], [1,6],
[2,7], [3,8], [4,9]
],
nodePositions : [
[0.5,0], [0.90,0.35], [0.80,0.80],
[0.20, 0.80], [0.10, 0.35], [0.5,0.20],
[0.75,0.45], [0.65, 0.65], [0.35, 0.65], [0.25, 0.45]
]
},
{
minColor: 5,
edgeList: [
[5, 1],
[5, 0],
[0, 3],
[0, 1],
[0, 2],
[2, 4],
[2, 1],
[3, 4],
[3, 2],
[4, 1],
[5, 4],
[5, 3]
],
nodePositions : [
[0.75, 0.00],
[0.75, 0.80],
[1.00, 0.40],
[0.25, 0.00],
[0.25, 0.80],
[0.00, 0.40]
]
},
{
minColor: 3,
edgeList: [
[5, 4],
[2, 0],
[0, 1],
[1, 5],
[4, 3],
[3, 2],
[0, 11],
[1, 6],
[7, 5],
[3, 9],
[8, 4],
[2, 10],
[11, 9],
[7, 9],
[11, 7],
[6, 8],
[10, 8],
[6, 10]
],
nodePositions : [
[0.26, 0.00],
[0.74, 0.00],
[0.00, 0.40],
[0.26, 0.80],
[0.74, 0.80],
[1.00, 0.40],
[0.62, 0.26],
[0.74, 0.40],
[0.62, 0.64],
[0.38, 0.64],
[0.26, 0.40],
[0.38, 0.26]
]
},
{
minColor: 4,
edgeList: [
[0, 8],
[0, 4],
[3, 6],
[10, 3],
[2, 11],
[7, 2],
[9, 1],
[5, 1],
[0, 1],
[1, 2],
[4, 6],
[8, 9],
[10, 11],
[0, 3],
[3, 2],
[8, 11],
[10, 9],
[4, 7],
[5, 7],
[6, 5],
[6, 9],
[10, 5],
[4, 11],
[8, 7]
],
nodePositions : [
[0.00, 0.00],
[1.00, 0.00],
[1.00, 0.80],
[0.00, 0.80],
[0.32, 0.32],
[0.74, 0.32],
[0.32, 0.53],
[0.74, 0.53],
[0.42, 0.22],
[0.63, 0.22],
[0.42, 0.64],
[0.63, 0.64]
]
}
]
var levels = [
{extraColor:1, graph:graphs[0]},
{extraColor:0, graph:graphs[0]},
{extraColor:1, graph:graphs[1]},
{extraColor:0, graph:graphs[1]},
{extraColor:1, graph:graphs[2]},
{extraColor:0, graph:graphs[2]},
{extraColor:1, graph:graphs[3]},
{extraColor:0, graph:graphs[3]},
{extraColor:1, graph:graphs[4]},
{extraColor:0, graph:graphs[4]},
{extraColor:1, graph:graphs[5]},
{extraColor:0, graph:graphs[5]},
{extraColor:1, graph:graphs[6]},
{extraColor:0, graph:graphs[6]}
];
var numberOfLevel = levels.length
var mode = "symbol";
function start(items_) {
items = items_
currentLevel = 0
initLevel()
}
function stop() {
}
function initLevel() {
coloringLeft = true
items.bar.level = currentLevel + 1
var currentIndeces = new Array();
var levelData = levels[currentLevel].graph
items.colorsRepeater.model.clear();
items.nodesRepeater.model.clear();
items.edgesRepeater.model.clear();
var numColors = levelData.minColor + levels[currentLevel].extraColor;
for (var i = 0; i < numColors; ++i) {
currentIndeces[i] = i;
items.colorsRepeater.model.append({"itemIndex": i});
}
items.chooserGrid.model = currentIndeces
for (var i = 0; i < levelData.nodePositions.length; ++i){
items.nodesRepeater.model.append({
"posX":levelData.nodePositions[i][0],
"posY":levelData.nodePositions[i][1],
"colIndex": -1,
"highlight": false
});
}
for (var i = 0; i < levelData.edgeList.length; ++i){
var node1 = levelData.edgeList[i][0]
var node2 = levelData.edgeList[i][1]
items.edgesRepeater.model.append({
"xp": levelData.nodePositions[node1][0],
"yp": levelData.nodePositions[node1][1],
"xpp": levelData.nodePositions[node2][0],
"ypp": levelData.nodePositions[node2][1],
"highlight": false
});
}
}
function checkGuess() {
var flag = false;
var levelData = levels[currentLevel].graph
- //Check wether all the nodes have been colored or not
+ //Check whether all the nodes have been colored or not
for (var i = 0; i < levelData.nodePositions.length; i++){
var node1 = items.nodesRepeater.model.get(i)
if (node1.colIndex == -1){
flag = true;
break;
}
}
- //Check wether the adjacent nodes do not have the same color
+ //Check whether the adjacent nodes do not have the same color
for (var i = 0; i < levelData.edgeList.length; i++){
var node1 = items.nodesRepeater.model.get(levelData.edgeList[i][0])
var node2 = items.nodesRepeater.model.get(levelData.edgeList[i][1])
//console.log("node1 " + levelData.edgeList[i][0] + " node2 "+ levelData.edgeList[i][1]+" node1 color "+ node1.colIndex+ " node2 color " + node2.colIndex);
if (node1.colIndex == node2.colIndex) {
//console.log("node1 " + levelData.edgeList[i][0] + " node2 "+ levelData.edgeList[i][1]+" node1 color "+ node1.colIndex+ " node2 color " + node2.colIndex);
flag = true;
break;
}
}
//console.log("flag is " + flag);
if (flag == false) {
items.bonus.good("lion");
}
}
function checkAdjacent() {
var levelData = levels[currentLevel].graph
var flagNodes = new Array(levelData.nodePositions.length)
for (var i = 0; i < levelData.nodePositions.length; i++){
flagNodes[i] = false
}
for (var i = 0; i < levelData.edgeList.length; i++){
var node1 = items.nodesRepeater.model.get(levelData.edgeList[i][0])
var node1Num = levelData.edgeList[i][0]
var node2 = items.nodesRepeater.model.get(levelData.edgeList[i][1])
var node2Num = levelData.edgeList[i][1]
if (node1.colIndex == node2.colIndex && node2.colIndex != -1) {
items.nodesRepeater.model.setProperty(node1Num, "highlight", true)
items.nodesRepeater.model.setProperty(node2Num, "highlight", true)
items.edgesRepeater.model.setProperty(i, "highlight", true)
flagNodes[node1Num] = true
flagNodes[node2Num] = true
}
else {
if(!flagNodes[node1Num]) {
items.nodesRepeater.model.setProperty(node1Num, "highlight", false)
}
if(!flagNodes[node2Num]) {
items.nodesRepeater.model.setProperty(node2Num, "highlight", false)
}
items.edgesRepeater.model.setProperty(i, "highlight", false)
}
}
}
function nextLevel() {
if(numberOfLevel <= ++currentLevel ) {
currentLevel = 0
}
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
initLevel();
}
diff --git a/src/activities/guesscount/ActivityInfo.qml b/src/activities/guesscount/ActivityInfo.qml
index b62133b5f..79796ce57 100644
--- a/src/activities/guesscount/ActivityInfo.qml
+++ b/src/activities/guesscount/ActivityInfo.qml
@@ -1,45 +1,44 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2016 Rahul Yadav <rahulyadav170923@gmail.com>
*
* Authors:
* Pascal Georges <pascal.georges1@free.fr> (GTK+ version)
* RAHUL YADAV <rahulyadav170923@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "guesscount/Guesscount.qml"
difficulty: 3
icon: "guesscount/guesscount.svg"
author: "Rahul Yadav &lt;rahulyadav170923@gmail.com&gt;"
demo: true
- //: activity title
//: Activity title
title: qsTr("Guesscount")
//: Help title
description:qsTr("Guess the algebraic expression and drag the tiles to get a result equal to the Guesscount.")
//intro: "Use the numbers and operations suggested to find the results proposed above."
//: Help goal
goal: qsTr("Intuition and practice of algebraic-like calculations.")
//: Help prerequisite
prerequisite: qsTr("knowledge of arithmetic operations")
//: Help manual
- manual: ""
+ manual: qsTr("Drag the appropriate numbers and the operators to the boxes to obtain the number to guess in the instruction.")
credit: ""
section: "math"
createdInVersion: 8000
}
diff --git a/src/activities/guesscount/Admin.qml b/src/activities/guesscount/Admin.qml
index 0eaf33c89..84bba38fa 100644
--- a/src/activities/guesscount/Admin.qml
+++ b/src/activities/guesscount/Admin.qml
@@ -1,102 +1,102 @@
/* GCompris - Admin.qml
*
* Copyright (C) 2016 RAHUL YADAV <rahulyadav170923@gmail.com>
*
* Authors:
* Pascal Georges <pascal.georges1@free.fr> (GTK+ version)
* RAHUL YADAV <rahulyadav170923@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
import "guesscount.js" as Activity
Row {
id: admin
spacing: 20
property int level
property var levelOperators
Rectangle {
id: operator
width: parent.width*0.23
height: parent.height
radius: 10.0;
color: "red"
state: "selected"
GCText {
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
fontSize: smallSize
text: qsTr("Level %1").arg(level+1)
}
}
Repeater {
model: ['+','-','*','/']
delegate: Rectangle {
id: tile
width: parent.width*0.1
height: parent.height
radius: 20
opacity: 0.7
state: Activity.check(modelData, levelOperators[level]) ? "selected" : "notselected"
GCText {
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
text: modelData
fontSize: smallSize
}
MouseArea {
anchors.fill: parent
onClicked: {
if(tile.state == "selected") {
tile.state = "notselected"
levelOperators[level].splice(levelOperators[level].indexOf(modelData), 1)
Activity.sync(levelOperators, level)
}
else{
tile.state = "selected"
levelOperators[level].push(modelData)
Activity.sync(levelOperators, level)
}
}
}
states: [
State {
name: "selected"
PropertyChanges { target: tile; color: "green" }
},
State {
name: "notselected"
PropertyChanges { target: tile; color: "red" }
}
]
}
}
Rectangle {
id: warning
visible: levelOperators[level].length == 0 ? true : false
width: parent.width*0.15
height: parent.height
radius: 20.0
color: "gray"
GCText {
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
fontSize: smallSize
text: qsTr("empty")
}
}
}
diff --git a/src/activities/guesscount/DragTile.qml b/src/activities/guesscount/DragTile.qml
index 9a98b466f..05de5698b 100644
--- a/src/activities/guesscount/DragTile.qml
+++ b/src/activities/guesscount/DragTile.qml
@@ -1,50 +1,50 @@
/* GCompris - DragTile.qml
*
* Copyright (C) 2016 RAHUL YADAV <rahulyadav170923@gmail.com>
*
* Authors:
* Pascal Georges <pascal.georges1@free.fr> (GTK+ version)
* RAHUL YADAV <rahulyadav170923@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
Item {
id: root
property string type
property int length: root.children.length
function createDynamicObject() {
var component = Qt.createComponent('Tile.qml')
component.createObject(root)
}
Loader {
active: type == "operands" ? true : false
sourceComponent: Tile {
id: tile
}
}
Component.onCompleted: {
if(type == "operators")
createDynamicObject()
}
onChildrenChanged: {
if(type == "operators") {
if(root.children.length-1 == 0)
createDynamicObject()
}
}
}
diff --git a/src/activities/guesscount/DropTile.qml b/src/activities/guesscount/DropTile.qml
index ebb73bcee..5f76fa0a0 100644
--- a/src/activities/guesscount/DropTile.qml
+++ b/src/activities/guesscount/DropTile.qml
@@ -1,52 +1,52 @@
/* GCompris - DropTile.qml
*
* Copyright (C) 2016 RAHUL YADAV <rahulyadav170923@gmail.com>
*
* Authors:
* Pascal Georges <pascal.georges1@free.fr> (GTK+ version)
* RAHUL YADAV <rahulyadav170923@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
import "guesscount.js" as Activity
DropArea {
id: dragTarget
property string type
property var droppedItem
keys: [ type ]
Rectangle {
id: dropRectangle
width: parent.width
height: parent.height
anchors.fill: parent
color: type == "operators" ? "#80F16F6F" : "#8075D21B" // red or green
border.width: 5
border.color: type == "operators" ? "#FFF16F6F" : "#FF75D21B" // red or green
radius: 10
states: [
State {
when: dragTarget.containsDrag
PropertyChanges {
target: dropRectangle
color: "transparent"
border.color: "#80FFFFFF"
}
}
]
}
}
diff --git a/src/activities/guesscount/Guesscount.qml b/src/activities/guesscount/Guesscount.qml
index 136e68840..b4635710c 100644
--- a/src/activities/guesscount/Guesscount.qml
+++ b/src/activities/guesscount/Guesscount.qml
@@ -1,420 +1,420 @@
/* GCompris - guesscount.qml
*
* Copyright (C) 2016 RAHUL YADAV <rahulyadav170923@gmail.com>
*
* Authors:
* Pascal Georges <pascal.georges1@free.fr> (GTK+ version)
* RAHUL YADAV <rahulyadav170923@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
import "guesscount.js" as Activity
ActivityBase {
id: activity
onStart: focus = true
onStop: {}
property bool needRestart: true
pageComponent: Image {
id: background
anchors.fill: parent
source: Activity.baseUrl + "/backgroundW01.svg"
signal start
signal stop
Component.onCompleted: {
dialogActivityConfig.getInitialConfiguration()
activity.start.connect(start)
activity.stop.connect(stop)
}
MouseArea {
anchors.fill: parent
onClicked: {
if(warningDialog.visible)
warningDialog.visible = false
}
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property alias background: background
property alias bar: bar
property alias bonus: bonus
property int sublevel: 0
property alias operandRow: operandRow
property var data
property int result: data[sublevel-1][1]
property alias timer: timer
property alias warningDialog: warningDialog
property GCSfx audioEffects: activity.audioEffects
property bool solved
property bool levelchanged: false
property var levelArr
property string mode
property int currentlevel
}
onStart: if (activity.needRestart) {
Activity.start(items);
activity.needRestart = false;
}
else
Activity.initLevel();
onStop: { Activity.stop() }
JsonParser {
id: parser
onError: console.error("Guesscount: Error parsing JSON: " + msg);
}
Loader {
id: admin
active: false
sourceComponent: Column {
spacing: 10
width: parent.width
height: parent.height
Repeater {
id:levels
model: Activity.numberOfLevel
Admin {
id:level
level: modelData+1
width: parent.width
height: parent.height
data: items.data
}
}
}
}
Rectangle {
id: top
width: parent.width
height: parent.height/10
anchors {
top: parent.top
topMargin: 20
}
color: "transparent"
Rectangle {
id: questionNo
width: parent.width*0.2
height: parent.height
radius: 20
color: "steelblue"
anchors {
right: guessLabel.left
rightMargin: 20
}
GCText {
color: "#E8E8E8"
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
fontSize: mediumSize
text: qsTr("%1/%2").arg(items.sublevel).arg(items.data.length)
}
}
Rectangle {
id: guessLabel
width: parent.width*0.4
height: parent.height
radius: 20
color: "orange"
anchors {
horizontalCenter: parent.horizontalCenter
}
Rectangle {
id: insideFill
width: parent.width - anchors.margins
height: parent.height - anchors.margins
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: parent.height/4
radius: 10
color: "#E8E8E8"
}
GCText {
id: guess
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
fontSize: smallSize
text: qsTr("Guesscount: %1").arg(items.result)
}
}
}
Column {
id: col
spacing: 10
anchors.top: top.bottom
anchors.topMargin: 20
anchors.left: parent.left
anchors.leftMargin: 5
width: parent.width
height: parent.height-top.height-background.height/5
OperatorRow {
id: operatorRow
width: parent.width
height: parent.height/7
mode: items.mode
operators: items.levelArr
level: items.currentlevel
}
OperandRow {
id: operandRow
width: parent.width
height: parent.height/7
}
Repeater {
id: repeat
model: operatorRow.repeater.model.length
delegate: OperationRow {
id: operationRow
width: col.width
height: col.height/7
property alias operationRow: operationRow
noOfRows: operatorRow.repeater.model.length
rowNo: modelData
guesscount: items.result
prevText: modelData ? repeat.itemAt(modelData-1).text : ''
prevComplete: modelData ? repeat.itemAt(modelData-1).complete : false
reparent: items.solved || items.levelchanged
}
}
}
DialogHelp {
id: dialogHelp
onClose: home()
}
DialogActivityConfig {
id: dialogActivityConfig
currentActivity: activity
content: Component {
Item {
property alias modeBox: modeBox
property var availableModes: [
{ "text": qsTr("Admin"), "value": "admin" },
{ "text": qsTr("BuiltIn"), "value": "builtin" }
]
Rectangle {
id: flow
width: dialogActivityConfig.width
height: background.height
GCComboBox {
id: modeBox
anchors {
top: parent.top
topMargin: 5
}
model: availableModes
background: dialogActivityConfig
label: qsTr("Select your mode")
}
Row {
id: labels
spacing: 20
anchors {
top: modeBox.bottom
topMargin: 5
}
visible: modeBox.currentIndex == 0
Repeater {
model: 2
Row {
spacing: 10
Rectangle {
id: label
width: background.width*0.3
height: background.height/15
radius: 20.0;
color: modelData ? "green" : "red"
GCText {
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
fontSize: smallSize
text: modelData ? qsTr("Selected") : qsTr("Not Selected")
}
}
}
}
}
Rectangle {
width: parent.width
color: "transparent"
height: parent.height/1.25-labels.height-modeBox.height
anchors {
top: labels.bottom
topMargin: 5
}
ListView {
anchors.fill: parent
visible: modeBox.currentIndex == 0
spacing: 5
model: Activity.numberOfLevel
clip: true
delegate: Admin {
id: level
level: modelData
levelOperators: items.levelArr
width: background.width
height: background.height/10
}
}
}
}
}
}
onClose: {
if(Activity.configDone(items.levelArr)){
Activity.initLevel()
home()
}
}
onLoadData: {
if(dataToSave && dataToSave["mode"] ) {
items.mode = dataToSave["mode"]
if(dataToSave["levelArr"] == undefined)
dataToSave["levelArr"] = Activity.defaultOperators
if(dataToSave["levelArr"].length != Activity.numberOfLevel)
items.levelArr = Activity.defaultOperators
else
items.levelArr = dataToSave["levelArr"]
}
else{
items.mode='builtin'
items.levelArr = Activity.defaultOperators
}
}
onSaveData: {
items.mode = dialogActivityConfig.configItem.availableModes[dialogActivityConfig.configItem.modeBox.currentIndex].value
dataToSave = {"mode": items.mode, "levelArr":items.levelArr}
activity.needRestart = true
}
function setDefaultValues() {
for(var i = 0 ; i < dialogActivityConfig.configItem.availableModes.length ; i ++) {
if(dialogActivityConfig.configItem.availableModes[i].value === items.mode) {
dialogActivityConfig.configItem.modeBox.currentIndex = i;
break;
}
}
}
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level | config}
onConfigClicked: {
dialogActivityConfig.active = true
dialogActivityConfig.setDefaultValues();
displayDialog(dialogActivityConfig)
}
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: {
items.levelchanged = true
Activity.previousLevel()
}
onNextLevelClicked: {
items.levelchanged = true
Activity.nextLevel()
}
onHomeClicked: activity.home()
}
Bonus {
id: bonus
Component.onCompleted: win.connect(Activity.nextSublevel)
}
Timer {
id: timer
interval: 1500
repeat: false
onTriggered: {
items.solved = true
}
}
Rectangle {
id: warningDialog
width: parent.width*0.49
height: parent.height/6
visible: false
color: "steelblue"
gradient: Gradient {
GradientStop { position: 0.0; color: "#000" }
GradientStop { position: 0.9; color: "#666" }
GradientStop { position: 1.0; color: "#AAA" }
}
radius: 30
property alias dialogText: dialogText
anchors.centerIn: parent
GCText {
id: dialogText
anchors.centerIn: parent
anchors {
centerIn: warningDialog
}
opacity: warningDialog.opacity
z: warningDialog.z
fontSize: background.vert ? regularSize : smallSize
color: "white"
style: Text.Outline
styleColor: "black"
horizontalAlignment: Text.AlignHCenter
width: parent.width
wrapMode: TextEdit.WordWrap
}
states: [
State {
when: warningDialog.visible
PropertyChanges {
target: top
opacity: 0.5
}
PropertyChanges {
target: col
opacity: 0.5
}
},
State {
when: !warningDialog.visible
PropertyChanges {
target: top
opacity: 1
}
PropertyChanges {
target: col
opacity: 1
}
}
]
}
}
}
diff --git a/src/activities/guesscount/OperandRow.qml b/src/activities/guesscount/OperandRow.qml
index 415d98651..f43794c1e 100644
--- a/src/activities/guesscount/OperandRow.qml
+++ b/src/activities/guesscount/OperandRow.qml
@@ -1,63 +1,63 @@
/* GCompris - OperandRow.qml
*
* Copyright (C) 2016 RAHUL YADAV <rahulyadav170923@gmail.com>
*
* Authors:
* Pascal Georges <pascal.georges1@free.fr> (GTK+ version)
* RAHUL YADAV <rahulyadav170923@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
Row {
id: operandRow
property alias repeater: repeater
property int rowSum
spacing: 20
Rectangle {
id: operands
width: parent.width*0.328
height: parent.height
radius: 10
color: "#75D21B" //green
Rectangle {
id: insideFill
width: parent.width - anchors.margins
height: parent.height - anchors.margins
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: parent.height/4
radius: 10
color: "#E8E8E8" //paper white
}
GCText {
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
fontSize: mediumSize
text: qsTr("Numbers")
}
}
Repeater {
id: repeater
delegate: DragTile {
id: root
type: "operands"
width: operandRow.width*0.1
height: operandRow.height
}
}
}
diff --git a/src/activities/guesscount/OperationRow.qml b/src/activities/guesscount/OperationRow.qml
index 3e714b258..363251a41 100644
--- a/src/activities/guesscount/OperationRow.qml
+++ b/src/activities/guesscount/OperationRow.qml
@@ -1,217 +1,217 @@
/* GCompris - OperationRow.qml
*
* Copyright (C) 2016 RAHUL YADAV <rahulyadav170923@gmail.com>
*
* Authors:
* Pascal Georges <pascal.georges1@free.fr> (GTK+ version)
* RAHUL YADAV <rahulyadav170923@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
import "guesscount.js" as Activity
Row {
id: operandRow
spacing: 20
property alias endResult: endResult
property int rowResult
property int noOfRows
property int rowNo
property int guesscount
property bool complete
property bool prevComplete
property bool reparent
property var prevText
property string text: endResult.text
Component {
id: component1
DropTile {
id: operand1
type: "operands"
width: operandRow.width*0.1
height: operandRow.height
droppedItem: operand1.children[count]
property int count: 0
onChildrenChanged: {
Activity.childrenChange(operand1, operandRow)
if(operand1.count == 1 && operator.count == 1 && operand2.count == 1) {
Activity.calculate(operand1.droppedItem.datavalue, operator.droppedItem.datavalue, operand2.droppedItem.datavalue, operandRow)
if(operandRow.rowNo == operandRow.noOfRows-1 && operandRow.rowResult == operandRow.guesscount) {
Activity.checkAnswer(operandRow)
}
}
}
}
}
Component {
id:component2
Rectangle {
id: prevResult
width: operandRow.width*0.1
height: operandRow.height
color: "orange" //orange
radius: 10
Rectangle {
width: parent.width - anchors.margins
height: parent.height - anchors.margins
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: parent.height/4
radius: 10
color: "#E8E8E8" //paper white
}
property alias droppedItem: tile
property int count: operandRow.prevComplete ? 1 : 0
GCText {
id: tile
property int datavalue: Number(tile.text)
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
fontSize: mediumSize
text: prevText
}
}
}
Loader {
id: loader
sourceComponent: rowNo ? component2 : component1
}
DropTile {
id: operator
type : "operators"
width: operandRow.width*0.1
height: operandRow.height
property int count: 0
droppedItem: operator.children[count]
onChildrenChanged: {
Activity.childrenChange(operator, operandRow)
if(loader.children[0].count == 1 && operator.count == 1 && operand2.count == 1)
{
Activity.calculate(loader.children[0].droppedItem.datavalue, operator.droppedItem.datavalue, operand2.droppedItem.datavalue, operandRow)
if(operandRow.rowNo == operandRow.noOfRows-1 && operandRow.rowResult == operandRow.guesscount)
{
Activity.checkAnswer(operandRow)
}
}
}
}
DropTile {
id: operand2
type: "operands"
width: operandRow.width*0.1
height: operandRow.height
property int count: 0
droppedItem: operand2.children[count]
onChildrenChanged: {
Activity.childrenChange(operand2, operandRow)
if(loader.children[0].count == 1 && operator.count == 1 && operand2.count == 1) {
Activity.calculate(loader.children[0].droppedItem.datavalue, operator.droppedItem.datavalue, operand2.droppedItem.datavalue, operandRow)
operandRow.complete = true
if(operandRow.rowNo == operandRow.noOfRows-1 && operandRow.rowResult == operandRow.guesscount) {
Activity.checkAnswer(operandRow)
}
}
}
}
Rectangle {
width: operandRow.width*0.1
height: operandRow.height
color: "transparent"
radius: 10
Rectangle {
width: parent.width * 0.8
height: parent.height * 0.8
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
radius: 10
color: "#1B8BD2" //blue
Rectangle {
width: parent.width - anchors.margins
height: parent.height - anchors.margins
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: parent.height/4
radius: 10
color: "#E8E8E8" //paper white
}
}
GCText {
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
text: "="
fontSize: mediumSize
}
}
Rectangle {
width: operandRow.width*0.1
height: operandRow.height
color: "orange" //orange
radius: 10
Rectangle {
width: parent.width - anchors.margins
height: parent.height - anchors.margins
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: parent.height/4
radius: 10
color: "#E8E8E8" //paper white
}
GCText {
id: endResult
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
fontSize: mediumSize
text: ""
}
}
onPrevCompleteChanged: {
if(!prevComplete) {
endResult.text = ""
operandRow.complete = false
}
else {
if(operator.count == 1 && operand2.count == 1) {
Activity.calculate(loader.children[0].droppedItem.datavalue, operator.droppedItem.datavalue, operand2.droppedItem.datavalue, operandRow)
operandRow.complete = true
if(operandRow.rowNo == operandRow.noOfRows-1 && operandRow.rowResult == operandRow.guesscount) {
Activity.checkAnswer(operandRow)
}
}
}
}
onReparentChanged: {
if(operandRow.reparent) {
if(loader.children[0]) {
if(loader.children[0].count != 0 && rowNo == 0) {
loader.children[0].droppedItem.parent = loader.children[0].droppedItem.reparent
}
}
if(operator.count != 0) {
operator.droppedItem.destroy()
}
if(operand2.count != 0) {
operand2.droppedItem.parent = operand2.droppedItem.reparent
}
}
}
}
diff --git a/src/activities/guesscount/OperatorRow.qml b/src/activities/guesscount/OperatorRow.qml
index 83ce228b1..a5d562124 100644
--- a/src/activities/guesscount/OperatorRow.qml
+++ b/src/activities/guesscount/OperatorRow.qml
@@ -1,68 +1,68 @@
/* GCompris - OperatorRow.qml
*
* Copyright (C) 2016 RAHUL YADAV <rahulyadav170923@gmail.com>
*
* Authors:
* Pascal Georges <pascal.georges1@free.fr> (GTK+ version)
* RAHUL YADAV <rahulyadav170923@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
import "guesscount.js" as Activity
Row {
id: operatorRow
spacing: 20
property string mode
property var operators
property int level
property alias repeater: repeater
Rectangle {
id: operator
width: parent.width*0.328
height: parent.height
radius: 20.0;
color: "#E16F6F" //red
Rectangle {
id: insideFill
width: parent.width - anchors.margins
height: parent.height - anchors.margins
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: parent.height/4
radius: 10
color: "#E8E8E8"
}
GCText {
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
fontSize: mediumSize
text: qsTr("Operators")
}
}
Repeater {
id: repeater
model: mode == "builtin" ? Activity.defaultOperators[level] : operators[level]
delegate: DragTile {
id: root
type: "operators"
width: operatorRow.width * 0.1
height: operatorRow.height
}
}
}
diff --git a/src/activities/guesscount/Tile.qml b/src/activities/guesscount/Tile.qml
index de1151719..d3493f92b 100644
--- a/src/activities/guesscount/Tile.qml
+++ b/src/activities/guesscount/Tile.qml
@@ -1,108 +1,108 @@
/* GCompris - Tile.qml
*
* Copyright (C) 2016 RAHUL YADAV <rahulyadav170923@gmail.com>
*
* Authors:
* Pascal Georges <pascal.georges1@free.fr> (GTK+ version)
* RAHUL YADAV <rahulyadav170923@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "guesscount.js" as Activity
import "../../core"
MouseArea {
id: mouseArea
property alias tile: tile
property alias datavalue: tile.datavalue
property var reparent: root
width: root.width
height: root.height
anchors.centerIn: parent
drag.target: tile
onReleased: {
parent = tile.Drag.target != null ? tile.Drag.target : root
tile.Drag.drop()
}
onParentChanged: {
if(parent.children.length>2 && root.type == "operators")
mouseArea.destroy()
}
onClicked: {
if(Activity.items.warningDialog.visible)
Activity.items.warningDialog.visible = false
}
Rectangle {
id: tile
width: parent.width
height: parent.height
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
property var datavalue: modelData
radius: 10
//opacity: 0.7
//color: root.type == "operators" ? "red" : "green"
color: "#E8E8E8"
Drag.keys: [ type ]
Drag.active: mouseArea.drag.active
Drag.hotSpot.x: parent.width/2
Drag.hotSpot.y: parent.height/2
Rectangle {
id: typeLine
width: parent.width - anchors.margins
height: parent.height - anchors.margins
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: parent.height/8
radius: 10
color: root.type == "operators" ? "#E16F6F" : "#75D21B" // red or green
}
Rectangle {
id: insideFill
width: parent.width - anchors.margins
height: parent.height - anchors.margins
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: parent.height/4
radius: 10
color: "#E8E8E8" //paper white
}
GCText {
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
text: modelData
fontSize: mediumSize
}
states: [
State {
when: mouseArea.drag.active
ParentChange { target: tile; parent: root }
AnchorChanges { target: tile; anchors.verticalCenter: undefined; anchors.horizontalCenter: undefined }
},
State {
when: Activity.items.warningDialog.visible
PropertyChanges {
target: mouseArea
enabled: false
}
}
]
}
}
diff --git a/src/activities/guesscount/dataset.js b/src/activities/guesscount/dataset.js
index e7156095e..330420bd3 100644
--- a/src/activities/guesscount/dataset.js
+++ b/src/activities/guesscount/dataset.js
@@ -1,71 +1,71 @@
/* GCompris - dataset.js
*
* Copyright (C) 2016 Rahul Yadav <rahulyadav170923@gmail.com>
*
* Authors:
* Pascal Georges <pascal.georges1@free.fr> (GTK+ version)
* RAHUL YADAV <rahulyadav170923@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
// questions according to operators
/*
format of the dataset
outermost array contains four arrays according to number of operator used in the Questions array.
Question array = [[operators used],[Questions]]
Question = [[operands],result]
*/
var dataset = [
[
[['+'],[ [[1,2,4],3] , [[3,4,5],7] ,[[6,2,7],8] ,[[5,2,4],7] ,[[9,2,4],11] ,[[4,6,2],6],[[1,6],7] ,[[3,2],5] ,[[13,1],14] ,[[5,8],13] ]],
[['-'],[ [[2,1,3],1] , [[3,1,0],2] ,[[7,2,3],5] ,[[6,2,2],4] ,[[9,2,4],7] ,[[8,5,5],3],[[9,5,3],4],[[18,9,8],9],[[5,1,2],4],[[6,3,7],3],[[5,4,1],1] ] ],
[['*'],[ [[2,1,3],2] , [[3,1,4],3] ,[[7,2,5],14] ,[[6,2,1],12] ,[[9,2,3],18] ,[[8,5,5],40],[[9,5,6],45],[[1,9,2],9],[[5,1,4],5] ]],
[['/'],[ [[2,1,4],2] , [[3,1,2],3] ,[[8,2,1],4] ,[[6,2,7],3] ,[[9,3,2],3] ,[[8,4,2 ],2],[[9,3,4],3],[[18,9,3],2] ]]
],
[
[['+','-'],[ [[1,2,4,5],5] , [[1,2,4,6],5] ,[[3,4,5,7],2] ,[[8,7,9,7],6] ,[[9,4,6,7],7] ,[[3,4,5,7],6] ,[[6,4,5,7],5] ]],
[['+','*'],[ [[1,2,4,6],12] , [[1,2,4,7],9] ,[[3,4,5,8],35] ,[[2,7,9,3],23] ,[[1,4,6,5],30] ,[[2,4,5,6],13] ,[[3,6,5,3],23] ]],
[['+','/'],[ [[1,2,4,2],6] , [[1,2,4,1],6] ,[[3,6,5,5],7] ,[[9,3,3,4],3] ,[[1,4,2,2],2] ,[[5,10,15,7],13] ]],
[['-','*'],[ [[1,2,4,3],4] , [[1,2,4,9],2] ,[[3,4,5,1],8] ,[[8,7,9,3],9] ,[[9,4,6,2],30] ]],
[['-','/'],[ [[1,2,4,7],2] , [[1,2,5,2],3] ,[[1,10,5,3],1] ,[[1,3,9,5],2] ,[[12,2,5,1],1] ]],
[['*','/'],[ [[1,2,4,3],8] , [[1,2,4,2],2] ,[[3,3,6,2],6] ,[[15,5,4,6],18] ,[[14,7,3,0],6] ]],
],
[
[['+','-','*'],[ [[1,4,3,5],10] , [[1,3,3,5],5] ,[[5,4,3,5],30] ,[[1,2,6,5],25] ]],
[['-','*','/'],[ [[1,4,3,3],3] ,[[3,4,3,3],1] ,[[7,4,2,1],6] ,[[8,4,2,4],2] ,[[9,4,5,3],3] ]],
[['*','/','+'],[ [[1,8,4,3],5] , [[10,8,9,3],5] ,[[9,1,3,3],6] ,[[5,8,4,3],13] ]],
[['/','+','-'],[ [[2,8,2,3],3] , [[10,2,9,3],11] ,[[9,3,3,2],4] ,[[5,5,4,3],6] ]]
],
[
[['+','-','*','/'],[ [[1,7,2,3,2],13] ,[[8,1,5,2,3],6] ,[[1,7,2,4,2],5] ,[[9,7,8,2,4],4]]]
]
]
// no of Question at each level ( total sublevels)
var levelSchema = [4,4,4,4,3,3,4,5]
// default operators at each level ( in case Built-in mode is activated )
var defaultOperators = [["+"],["-"],["/"],["*"],["+","-"],["/","*"],["/","*",'+'],['-',"*","+","/"]]
diff --git a/src/activities/guesscount/guesscount.js b/src/activities/guesscount/guesscount.js
index c825f79f4..10f8be345 100644
--- a/src/activities/guesscount/guesscount.js
+++ b/src/activities/guesscount/guesscount.js
@@ -1,208 +1,208 @@
/* GCompris - guesscount.js
*
* Copyright (C) 2016 Rahul Yadav <rahulyadav170923@gmail.com>
*
* Authors:
* Pascal Georges <pascal.georges1@free.fr> (GTK+ version)
* RAHUL YADAV <rahulyadav170923@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
.import GCompris 1.0 as GCompris
.import "dataset.js" as Data
.import "qrc:/gcompris/src/core/core.js" as Core
var url = "qrc:/gcompris/src/activities/guesscount/resource/"
var defaultOperators = Data.defaultOperators
var baseUrl = "qrc:/gcompris/src/activities/guesscount/resource";
var builtinFile = baseUrl + "/levels-default.json";
var dataset = []
var currentLevel
var numberOfLevel = Data.levelSchema.length
var items
function start(items_) {
items = items_
currentLevel = 0
initLevel()
}
function stop() {
}
function initLevel() {
items.bar.level = currentLevel + 1
items.currentlevel = currentLevel
items.sublevel = 1
items.data = buildDataset(Data.dataset, Data.levelSchema)
items.operandRow.repeater.model = items.data[items.sublevel-1][0]
items.levelchanged = false
items.solved = false
if(items.warningDialog.visible)
items.warningDialog.visible = false
}
function initSublevel(){
items.sublevel += 1
items.operandRow.repeater.model = items.data[items.sublevel-1][0]
items.solved = false
}
function nextSublevel() {
if(items.sublevel < items.data.length) {
initSublevel()
}
else {
nextLevel()
}
}
function nextLevel() {
if(numberOfLevel <= ++currentLevel) {
currentLevel = 0
}
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
initLevel();
}
function calculate(operand1, operator, operand2, operationRow)
{
var repeat = operationRow.rowResult
var result
switch (operator) {
case "+":
result = operand1+operand2
break;
case "-":
result = operand1-operand2
break;
case "/":
result = operand1/operand2
break;
case "*":
result = operand1*operand2
}
// result is positive integer
if(Math.round(result)-result === 0 && result >= 0) {
operationRow.rowResult = result
operationRow.endResult.text = operationRow.rowResult.toString()
operationRow.complete = true
}
else {
if(result != repeat) {
operationRow.endResult.text = ""
operationRow.complete = false
if(result < 0)
items.warningDialog.dialogText.text = qsTr("result is not positive integer")
else
items.warningDialog.dialogText.text = qsTr("result is not an integer")
items.warningDialog.visible = true
}
}
}
function childrenChange(item, operationRow)
{
if(item.children.length == 2 && item.count == 0) {
item.count += 1
}
else if(item.children.length == 3) {
item.droppedItem.parent = item.droppedItem.reparent
operationRow.complete=false
if(items.warningDialog.visible)
items.warningDialog.visible = false
}
else if(item.children.length == 1) {
item.count -= 1
operationRow.complete = false
operationRow.endResult.text = ""
}
}
function checkAnswer(row) {
if(items.sublevel < items.data.length) {
items.bonus.good("flower")
items.timer.start()
}
else {
items.timer.start()
items.bonus.good("smiley")
}
}
function sync(array, level) {
items.levelArr = array
}
function check(operator, array) {
for (var i in array) {
if(array[i] == operator) {
return true
}
}
return false
}
function configDone(array) {
for(var i in array) {
if(array[i].length == 0) {
return false
}
}
return true
}
function equal(levelOperators, array) {
for(var i in levelOperators) {
var found = false
for(var j in array) {
if(levelOperators[i] == array[j])
found = true
}
if(!found)
return false
}
return true
}
function buildDataset(data, levelSchema) {
var level = []
var levelArr = items.mode == 'builtin' ? defaultOperators : items.levelArr
var noOfOperators = levelArr[currentLevel].length
var questions
for(var j in data[noOfOperators-1]) {
if(equal(levelArr[currentLevel], data[noOfOperators-1][j][0])) {
questions = data[noOfOperators-1][j][1]
break
}
}
var questions = Core.shuffle(questions)
for(var m = 0 ; m < levelSchema[currentLevel] ; ++ m) {
level.push(questions[m])
}
return level
}
diff --git a/src/activities/guessnumber/ActivityInfo.qml b/src/activities/guessnumber/ActivityInfo.qml
index 54b7ef110..97f37fbe2 100644
--- a/src/activities/guessnumber/ActivityInfo.qml
+++ b/src/activities/guessnumber/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Thib ROMAIN <thibrom@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "guessnumber/Guessnumber.qml"
difficulty: 3
icon: "guessnumber/guessnumber.svg"
author: "Thib ROMAIN &lt;thibrom@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Guess a number")
//: Help title
description: qsTr("Help Tux escape the cave. Tux hides a number for you to find.")
// intro: "Find out the number by typing a number from the range proposed."
//: Help goal
goal: ""
//: Help prerequisite
prerequisite: qsTr("Numbers from 1 to 1000 for the last level.")
//: Help manual
manual: qsTr("Read the instructions that give you the range of the number to find. Enter a number in the top right entry box. You will be told if your number is higher or lower. Then enter another number. The distance between Tux and the escape area on the right represents how far you are from the correct number. If Tux is over or under the escape area, it means your number is over or under the correct number.")
credit: ""
section: "math numeration"
createdInVersion: 0
}
diff --git a/src/activities/guessnumber/AnswerArea.qml b/src/activities/guessnumber/AnswerArea.qml
index d382267d9..a51621ce0 100644
--- a/src/activities/guessnumber/AnswerArea.qml
+++ b/src/activities/guessnumber/AnswerArea.qml
@@ -1,75 +1,75 @@
/* GCompris - AnswerArea.qml
*
* Copyright (C) 2014 Thib ROMAIN <thibrom@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Thib ROMAIN <thibrom@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "guessnumber.js" as Activity
Rectangle {
id: answerBackground
width: hiddentext.width * 1.2
height: 60 * ApplicationInfo.ratio
color: activeFocus ? "#ff07fff2" : "#cccccccc"
radius: 10
border {
width: activeFocus ? 3 : 1
color: "black"
}
property string userEntry
// A top gradient
Rectangle {
anchors.fill: parent
anchors.margins: activeFocus ? 3 : 1
radius: 10
gradient: Gradient {
GradientStop { position: 0.0; color: "#CCFFFFFF" }
GradientStop { position: 0.5; color: "#80FFFFFF" }
GradientStop { position: 1.0; color: "#00000000" }
}
}
GCText {
id: userEntryText
anchors.fill: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
text: answerBackground.userEntry
color: "black"
fontSize: largeSize
style: Text.Outline
styleColor: "white"
}
GCText {
id: hiddentext
opacity: 0
fontSize: userEntryText.fontSize
text: items.currentMax
}
onUserEntryChanged: {
if(userEntry != "")
Activity.setUserAnswer(parseInt(userEntry))
}
}
diff --git a/src/activities/guessnumber/Guessnumber.qml b/src/activities/guessnumber/Guessnumber.qml
index 6e9b2b359..d4e757fdb 100644
--- a/src/activities/guessnumber/Guessnumber.qml
+++ b/src/activities/guessnumber/Guessnumber.qml
@@ -1,159 +1,159 @@
/* GCompris - guessnumber.qml
*
* Copyright (C) 2014 Thib ROMAIN <thibrom@gmail.com>
*
* Authors:
* Clement Coudoin <clement.coudoin@free.fr> (GTK+ version)
* Thib ROMAIN <thibrom@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "guessnumber.js" as Activity
ActivityBase {
id: activity
onStart: focus = true
onStop: {}
pageComponent: Image {
id: background
- fillMode : Image.PreserveAspectCrop
+ fillMode: Image.PreserveAspectCrop
source: "resource/cave.svg"
anchors.fill: parent
signal start
signal stop
onWidthChanged: helico.init()
onHeightChanged: helico.init()
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property alias background: background
property alias bar: bar
property alias bonus: bonus
property alias helico: helico
property alias textArea: textArea
property alias infoText: userInfo
property alias answerArea: answerArea
property alias numpad: numpad
property int currentMax: 0
property int maxSize: 120
property int minSize: 80
property int barHeightAddon: ApplicationSettings.isBarHidden ? 1 : 3
property int size: Math.min(background.width / 9, background.height / (8 + barHeightAddon))
}
onStart: { Activity.start(items) }
onStop: { Activity.stop() }
Helico {
id: helico
fillMode: "PreserveAspectFit"
sourceSize.height: items.maxSize * ApplicationInfo.ratio
height: (items.size>items.minSize) ?
(items.size<items.maxSize) ? items.size * ApplicationInfo.ratio :
items.maxSize * ApplicationInfo.ratio :
items.minSize * ApplicationInfo.ratio
}
GCText {
id: textArea
anchors.top: parent.top
anchors.topMargin: 10
anchors.left: parent.left
anchors.leftMargin: numpad.columnWidth + 10
anchors.right: answerArea.left
horizontalAlignment: Text.AlignHCenter
width: parent.width - answerArea.width - 10
wrapMode: TextEdit.WordWrap
color: "white"
font.bold: true
fontSize: mediumSize
}
AnswerArea {
id: answerArea
anchors.right: parent.right
anchors.rightMargin: numpad.visible ?
numpad.columnWidth + 10 * ApplicationInfo.ratio :
10 * ApplicationInfo.ratio
anchors.top: parent.top
anchors.topMargin: 10
}
GCText {
id: userInfo
anchors.top: textArea.top
anchors.topMargin: 15 + textArea.contentHeight
anchors.horizontalCenter: textArea.horizontalCenter
color: "white"
font.bold: true
fontSize: regularSize
}
NumPad {
id: numpad
onAnswerChanged: {
if(answer && answerArea.userEntry != answer)
activity.audioEffects.play('qrc:/gcompris/src/activities/guessnumber/resource/helicopter.wav')
answerArea.userEntry = answer
}
maxDigit: ("" + items.currentMax).length
columnWidth: 60 * ApplicationInfo.ratio
}
Keys.onPressed: {
numpad.updateAnswer(event.key, true);
}
Keys.onReleased: {
numpad.updateAnswer(event.key, false);
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level }
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
}
Bonus {
id: bonus
Component.onCompleted: win.connect(Activity.nextLevel)
}
}
}
diff --git a/src/activities/guessnumber/Helico.qml b/src/activities/guessnumber/Helico.qml
index f305dccad..d770af98a 100644
--- a/src/activities/guessnumber/Helico.qml
+++ b/src/activities/guessnumber/Helico.qml
@@ -1,83 +1,83 @@
/* GCompris - guessnumber.qml
*
* Copyright (C) 2014 Thib ROMAIN <thibrom@gmail.com>
*
* Authors:
* Thib ROMAIN <thibrom@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
Image {
id: helico
source: "resource/tuxhelico.svg"
sourceSize.height: 120 * ApplicationInfo.ratio
function init() {
x = 2
y = parent.height / 2 - height / 2
}
Behavior on x {
PropertyAnimation {
id: xAnim
easing.type: Easing.OutQuad
duration: 1000
}
}
Behavior on y {
PropertyAnimation {easing.type: Easing.OutQuad; duration: 1000}
}
transform: Rotation {
id: helicoRotation;
origin.x: helico.width / 2;
origin.y: helico.height / 2;
axis { x: 0; y: 0; z: 1 }
Behavior on angle {
animation: rotAnim
}
}
states: [
State {
name: "horizontal"
PropertyChanges {
target: helicoRotation
angle: 0
}
},
State {
name: "advancing"
PropertyChanges {
target: helicoRotation
angle: 25
}
}
]
RotationAnimation {
id: rotAnim
direction: helico.state == "horizontal" ?
RotationAnimation.Counterclockwise :
RotationAnimation.Clockwise
duration: 500
onRunningChanged: if(!rotAnim.running && helico.state == "advancing")
helico.state = "horizontal"
}
}
diff --git a/src/activities/guessnumber/guessnumber.js b/src/activities/guessnumber/guessnumber.js
index d7a09f3ef..783f03e9b 100644
--- a/src/activities/guessnumber/guessnumber.js
+++ b/src/activities/guessnumber/guessnumber.js
@@ -1,120 +1,120 @@
/* GCompris - guessnumber.js
*
* Copyright (C) 2014 Thib ROMAIN <thibrom@gmail.com>
*
* Authors:
* Clement Coudoin <clement.coudoin@free.fr> (GTK+ version)
* Thib ROMAIN <thibrom@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
var currentLevel = 0
var numberOfLevel = 9
var items
var numberToGuess = 0
function start(items_) {
items = items_
currentLevel = 0
initLevel()
}
function stop() {
}
function initLevel() {
items.bar.level = currentLevel + 1
items.helico.init()
items.helico.state = "horizontal"
items.infoText.text = ""
items.numpad.resetText()
switch(currentLevel) {
case 0: items.currentMax = 20
numberToGuess = getRandomInt(1,items.currentMax)
break;
case 1: items.currentMax = 40
numberToGuess = getRandomInt(1,items.currentMax)
break;
case 2: items.currentMax = 60
numberToGuess = getRandomInt(1,items.currentMax)
break;
case 3: items.currentMax = 100
numberToGuess = getRandomInt(1,items.currentMax)
break;
case 4: items.currentMax = 500
numberToGuess = getRandomInt(1,items.currentMax)
break;
case 5: items.currentMax = 1000
numberToGuess = getRandomInt(1,items.currentMax)
break;
case 6: items.currentMax = 5000
numberToGuess = getRandomInt(1,items.currentMax)
break;
case 7: items.currentMax = 10000
numberToGuess = getRandomInt(1,items.currentMax)
break;
case 8: items.currentMax = 50000
numberToGuess = getRandomInt(1,items.currentMax)
break;
}
items.textArea.text = qsTr("Guess a number between 1 and %1").arg(items.currentMax);
}
function nextLevel() {
if(numberOfLevel <= ++currentLevel ) {
currentLevel = 0
}
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
initLevel();
}
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
function setUserAnswer(value){
if(value === 0)
return;
if(value > items.currentMax){
items.infoText.text = qsTr("Number too high")
return;
}
if(value > numberToGuess){
items.infoText.text = qsTr("Number too high")
}
if(value < numberToGuess){
items.infoText.text = qsTr("Number too low")
}
items.helico.state = "advancing"
if(value === numberToGuess) {
items.infoText.text = qsTr("Number found!")
items.bonus.good("tux")
items.helico.x = items.background.width
items.helico.y = items.background.height / 2 - items.helico.height / 2
} else {
var diff = Math.abs(numberToGuess-value)/items.currentMax
items.helico.x = (items.background.width-items.helico.width) - diff * items.background.width
items.helico.y = items.background.height / 2 +
((numberToGuess-value) / items.currentMax) * (items.background.height/2) - items.helico.height / 2
}
}
diff --git a/src/activities/hangman/ActivityInfo.qml b/src/activities/hangman/ActivityInfo.qml
index ba5dbf071..14e0cea61 100644
--- a/src/activities/hangman/ActivityInfo.qml
+++ b/src/activities/hangman/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Rajdeep Kaur <rajdeep1994@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "hangman/Hangman.qml"
difficulty: 5
icon: "hangman/hangman.svg"
author: "Rajdeep kaur &lt;rajdeep1994@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("The classic hangman game")
//: Help title
description: qsTr("Guess the letters of the given word. To help you, on every wrong try, a part of the image representing the word will be revealed.")
//: Help goal
goal: qsTr("This is a good exercise to improve reading and spelling skills.")
//: Help prerequisite
prerequisite: ""
// intro: "A word is hidden, you must discover it letter by letter."
//: Help manual
manual: qsTr("You can enter the letters using the virtual keyboard on the screen or with the real keyboard.")
credit: ""
section: "keyboard reading"
createdInVersion: 5000
}
diff --git a/src/activities/hangman/Hangman.qml b/src/activities/hangman/Hangman.qml
index d965375e5..a550f687d 100644
--- a/src/activities/hangman/Hangman.qml
+++ b/src/activities/hangman/Hangman.qml
@@ -1,455 +1,457 @@
/* GCompris - hangman.qml
*
* Copyright (C) 2015 Rajdeep Kaur <rajdeep51994@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Rajdeep kaur<rajdeep51994@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import QtGraphicalEffects 1.0
import "../../core"
import "hangman.js" as Activity
import "qrc:/gcompris/src/core/core.js" as Core
ActivityBase {
id: activity
// Overload this in your activity to change it
// Put you default-<locale>.json files in it
property string dataSetUrl: "qrc:/gcompris/src/activities/hangman/resource/"
onStart: focus = true
onStop: { }
// When going on configuration, it steals the focus and re set it to the activity.
// We need to set it back to the textinput item in order to have key events.
onFocusChanged: {
if(focus) {
Activity.focusTextInput()
}
}
pageComponent: Image {
id: background
source: activity.dataSetUrl + "background.svg"
fillMode: Image.PreserveAspectCrop
anchors.fill: parent
sourceSize.width: Math.max(parent.width, parent.height)
// system locale by default
property string locale: "system"
property bool englishFallback: false
signal start
signal stop
Component.onCompleted: {
dialogActivityConfig.getInitialConfiguration()
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property alias background: background
property Item ourActivity: activity
property alias bar: bar
property alias bonus: bonus
property alias keyboard: keyboard
property alias hidden: hidden
property alias guessedText: guessedText
property alias textinput: textinput
property alias wordImage: wordImage
property alias score: score
property alias parser: parser
property alias locale: background.locale
property alias ok: ok
property int remainingLife
+ property double maskThreshold
property var goodWord
property int goodWordIndex
property bool easyMode: false
property alias englishFallbackDialog: englishFallbackDialog
function playWord() {
var locale = ApplicationInfo.getVoicesLocale(items.locale)
if(activity.audioVoices.append(
ApplicationInfo.getAudioFilePathForLocale(goodWord.voice, locale)))
bonus.interval = 2500
else
bonus.interval = 500
}
onRemainingLifeChanged: {
+ maskThreshold = 0.15 * remainingLife
if(remainingLife == 3) {
playWord();
}
}
}
onStart: {
focus = true
Activity.start(items)
Activity.focusTextInput()
}
onStop: {
Activity.stop();
}
GCText {
id: hidden
fontSize: largeSize
color: "#4d4d4d"
font.letterSpacing: 0.5
width: parent.width * 0.90 - score.width
fontSizeMode: Text.Fit
horizontalAlignment: Text.AlignHCenter
anchors {
right: score.left
bottom: bar.top
bottomMargin: 10 * ApplicationInfo.ratio
}
z: 11
}
GCText {
id: guessedText
fontSize: smallSize
color: "#FFFFFF"
wrapMode: Text.WordWrap
horizontalAlignment: Text.AlignHCenter
width: parent.width - 2.1 * clock.width
anchors {
horizontalCenter: parent.horizontalCenter
}
z: 12
}
Rectangle {
width: guessedText.width
height: guessedText.height
radius: 10
border.width: 1
gradient: Gradient {
GradientStop { position: 0.0; color: "#000" }
GradientStop { position: 0.9; color: "#666" }
GradientStop { position: 1.0; color: "#AAA" }
}
anchors {
horizontalCenter: parent.horizontalCenter
}
z: 11
}
TextInput {
// Helper element to capture composed key events like french ô which
// are not available via Keys.onPressed() on linux. Must be
// disabled on mobile!
id: textinput
enabled: !ApplicationInfo.isMobile
visible: false
focus: true
onTextChanged: {
if (text != "") {
Activity.processKeyPress(text);
text = "";
}
}
onAccepted: if(items.remainingLife === 0) Activity.nextSubLevel()
}
Item {
id: imageframe
width: Math.min(300 * ApplicationInfo.ratio,
background.width * 0.8,
hidden.y) - guessedText.height
height: width
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: guessedText.bottom
y: 5 * ApplicationInfo.ratio
z: 10
opacity: items.easyMode ? 1 : 0
Image {
id: wordImage
smooth: true
visible: false
anchors.fill: parent
property string nextSource
function changeSource(nextSource_) {
nextSource = nextSource_
animImage.start()
}
SequentialAnimation {
id: animImage
PropertyAnimation {
target: wordImage
property: "opacity"
to: 0
duration: 100
}
PropertyAction {
target: wordImage
property: "source"
value: wordImage.nextSource
}
PropertyAnimation {
target: wordImage
property: "opacity"
to: 1
duration: 100
}
}
}
Image {
id: threshmask
smooth: true
visible: false
width: 1.3*parent.width
height: 1.2*parent.height
source: dataSetUrl + "fog.png"
}
ThresholdMask {
id: thresh
anchors.fill: wordImage
source: wordImage
maskSource: threshmask
spread: 0.4
// remainingLife between 0 and 6 => threshold between 0 and 0.9
- threshold: 0.15 * items.remainingLife
+ threshold: items.maskThreshold
}
}
DialogActivityConfig {
id: dialogActivityConfig
currentActivity: activity
content: Component {
Item {
property alias localeBox: localeBox
height: column.height
property alias availableLangs: langs.languages
LanguageList {
id: langs
}
Column {
id: column
spacing: 10
width: parent.width
Flow {
spacing: 5
width: dialogActivityConfig.width
GCComboBox {
id: localeBox
model: langs.languages
background: dialogActivityConfig
label: qsTr("Select your locale")
}
GCDialogCheckBox {
id: easyModeBox
width: parent.width
text: qsTr("Display image to find as hint")
checked: items.easyMode
onCheckedChanged: {
items.easyMode = checked
}
}
}
}
}
}
onClose: home()
onLoadData: {
if(dataToSave && dataToSave["locale"]) {
background.locale = dataToSave["locale"];
}
if(dataToSave && dataToSave["easyMode"]) {
items.easyMode = (dataToSave["easyMode"] === "true");
}
}
onSaveData: {
var oldLocale = background.locale;
var newLocale =
dialogActivityConfig.configItem.availableLangs[dialogActivityConfig.loader.item.localeBox.currentIndex].locale;
// Remove .UTF-8
if(newLocale.indexOf('.') != -1) {
newLocale = newLocale.substring(0, newLocale.indexOf('.'))
}
dataToSave = {"locale": newLocale,
"easyMode": "" + items.easyMode }
background.locale = newLocale;
// Restart the activity with new information
if(oldLocale !== newLocale) {
background.stop();
background.start();
}
}
function setDefaultValues() {
var localeUtf8 = background.locale;
if(background.locale != "system") {
localeUtf8 += ".UTF-8";
}
for(var i = 0 ; i < dialogActivityConfig.configItem.availableLangs.length ; i ++) {
if(dialogActivityConfig.configItem.availableLangs[i].locale === localeUtf8) {
dialogActivityConfig.loader.item.localeBox.currentIndex = i;
break;
}
}
}
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
anchors.bottom: keyboard.top
content: BarEnumContent { value: help | home | level | config }
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
onConfigClicked: {
dialogActivityConfig.active = true
dialogActivityConfig.setDefaultValues()
displayDialog(dialogActivityConfig)
}
}
Score {
id: score
height: 1.2 * internalTextComponent.height
width: 1.3 * internalTextComponent.width
anchors {
bottom: keyboard.enabled ? keyboard.top : parent.bottom
bottomMargin: keyboard.enabled ? 1.2 * bar.height : 0.55 * parent.height
right: parent.right
rightMargin: 0.025 * parent.width
}
}
BarButton {
id: ok
source: "qrc:/gcompris/src/core/resource/bar_ok.svg";
sourceSize.width: Math.min(score.width, clock.width)
visible: false
anchors {
bottom: score.top
horizontalCenter: score.horizontalCenter
bottomMargin: 5 * ApplicationInfo.ratio
}
onClicked: Activity.nextSubLevel()
}
JsonParser {
id: parser
onError: console.error("Hangman: Error parsing json: " + msg);
}
Image {
id: clock
anchors {
left: parent.left
top: parent.top
margins: 10
}
sourceSize.width: 66 * bar.barZoom
property int remainingLife: items.remainingLife
onRemainingLifeChanged: if(remainingLife >= 0) clockAnim.restart()
SequentialAnimation {
id: clockAnim
alwaysRunToEnd: true
ParallelAnimation {
NumberAnimation {
target: clock; properties: "opacity";
to: 0; duration: 800; easing.type: Easing.OutCubic
}
NumberAnimation {
target: clock; properties: "rotation"; from: 0; to: 180;
duration: 800; easing.type: Easing.OutCubic
}
}
PropertyAction {
target: clock; property: 'source';
value: "qrc:/gcompris/src/activities/reversecount/resource/" +
"flower" + items.remainingLife + ".svg"
}
ParallelAnimation {
NumberAnimation {
target: clock; properties: "opacity";
to: 1; duration: 800; easing.type: Easing.OutCubic
}
NumberAnimation {
target: clock; properties: "rotation"; from: 180; to: 0;
duration: 800; easing.type: Easing.OutCubic
}
}
}
}
VirtualKeyboard {
id: keyboard
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
width: parent.width
onKeypress: Activity.processKeyPress(text);
onError: console.log("VirtualKeyboard error: " + msg);
}
Bonus {
id: bonus
interval: 2000
onLoose: ok.visible = true
onWin: Activity.nextSubLevel()
}
Loader {
id: englishFallbackDialog
sourceComponent: GCDialog {
parent: activity.main
message: qsTr("We are sorry, we don't have yet a translation for your language.") + " " +
- qsTr("GCompris is developed by the KDE community, you can translate GCompris by joining a translation team on <a href=\"%2\">%2</a>").arg("http://l10n.kde.org/") +
+ qsTr("GCompris is developed by the KDE community, you can translate GCompris by joining a translation team on <a href=\"%2\">%2</a>").arg("https://l10n.kde.org/") +
"<br /> <br />" +
qsTr("We switched to English for this activity but you can select another language in the configuration dialog.")
onClose: background.englishFallback = false
}
anchors.fill: parent
focus: true
active: background.englishFallback
onStatusChanged: if (status == Loader.Ready) item.start()
}
}
}
diff --git a/src/activities/hangman/hangman.js b/src/activities/hangman/hangman.js
index e7194c06a..bb5afb4e1 100644
--- a/src/activities/hangman/hangman.js
+++ b/src/activities/hangman/hangman.js
@@ -1,230 +1,231 @@
/* GCompris - hangman.js
*
* Copyright (C) 2015 Rajdeep Kaur <rajdeep1994@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Rajdeep kaur <rajdeep51994@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
.import GCompris 1.0 as GCompris
.import "qrc:/gcompris/src/core/core.js" as Core
.import "qrc:/gcompris/src/activities/lang/lang_api.js" as Lang
var currentLevel
var currentSubLevel
var maxLevel
var maxSubLevel
var items
var currentWord
var sp ="_ "
var dataset = null
var lessons
var wordList
var subLevelsLeft
var alreadyTypedLetters
// js strings are immutable, can't replace letter like that...
// http://stackoverflow.com/questions/1431094/how-do-i-replace-a-character-at-a-particular-index-in-javascript
String.prototype.replaceAt = function(index, character) {
return this.substr(0, index) + character + this.substr(index+character.length);
}
function start(items_) {
items = items_
currentLevel = 0;
currentSubLevel = 0;
items.remainingLife = 6;
var locale = GCompris.ApplicationInfo.getVoicesLocale(items.locale)
var resourceUrl = "qrc:/gcompris/src/activities/lang/resource/"
// register the voices for the locale
GCompris.DownloadManager.updateResource(
GCompris.DownloadManager.getVoicesResourceForLocale(locale))
var data = Lang.loadDataset(items.parser, resourceUrl, locale);
dataset = data["dataset"];
items.background.englishFallback = data["englishFallback"];
lessons = Lang.getAllLessons(dataset)
maxLevel = lessons.length
initLevel();
}
function stop() {
}
function initLevel() {
items.bar.level = currentLevel + 1;
var currentLesson = lessons[currentLevel];
wordList = Lang.getLessonWords(dataset, currentLesson);
Core.shuffle(wordList);
maxSubLevel = wordList.length;
items.score.numberOfSubLevels = maxSubLevel;
items.score.visible = true;
subLevelsLeft = []
for(var i in wordList)
subLevelsLeft.push(i)
initSubLevel();
//to set the layout...populate
var letters = new Array();
for (var i = 0; i < wordList.length; i++) {
var word = wordList[i].translatedTxt;
for (var j = 0; j < word.length; j++) {
var letter = word.charAt(j).toLocaleLowerCase();
if (letters.indexOf(letter) === -1)
letters.push(letter);
}
}
letters = GCompris.ApplicationInfo.localeSort(letters, items.locale);
// Remove space character if in list
var indexOfSpace = letters.indexOf(' ')
if(indexOfSpace > -1)
letters.splice(indexOfSpace, 1)
// generate layout from letter map
var layout = new Array();
var row = 0;
var offset = 0;
while (offset < letters.length-1) {
var cols = letters.length <= 10
? letters.length : (Math.ceil((letters.length-offset) / (3 - row)));
layout[row] = new Array();
for (var j = 0; j < cols; j++)
layout[row][j] = { label: letters[j+offset] };
offset += j;
row++;
}
items.keyboard.layout = layout;
}
function processKeyPress(text) {
if(items.remainingLife === 0 || items.bonus.isPlaying)
return
text = text.toLocaleLowerCase()
// Check if the character has already been typed
if(alreadyTypedLetters.indexOf(text) !== -1) {
// Character already typed, do nothing
return;
}
// Add the character to the already typed characters
alreadyTypedLetters.push(text);
// add the typed character in the "Attempted characters" text field
createAttemptedText()
// Get all the indices of this letter in the word
var indices = [];
for(var i = 0 ; i < currentWord.length ; i ++) {
if (currentWord[i].toLocaleLowerCase() === text) {
indices.push(i);
}
}
if(indices.length == 0) {
// The letter is not in the word to find
// If no more life, we display the good word and show the bonus
if(--items.remainingLife == 0) {
items.hidden.text = items.goodWord.translatedTxt;
items.playWord()
items.bonus.bad("lion");
return;
}
} else {
// For all the indices found, we replace the "_" by the letter
for(var index = 0 ; index < indices.length ; index ++) {
// Characters in the word displayed are separated by spaces, this is why we do 2*index
items.hidden.text = items.hidden.text.replaceAt(2*indices[index],
currentWord[indices[index]]);
}
}
// If no more '_' in the word to find, we have found all letters, show bonus
if(items.hidden.text.indexOf("_") === -1) {
+ items.maskThreshold = 0;
items.playWord()
items.bonus.good("lion");
}
}
function nextLevel() {
if(maxLevel <= ++currentLevel) {
currentLevel = 0
}
currentSubLevel = 0;
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = maxLevel - 1
}
currentSubLevel = 0;
initLevel();
}
function initSubLevel() {
// initialize sublevel
if(items.score.currentSubLevel < items.score.numberOfSubLevels)
items.score.currentSubLevel = currentSubLevel + 1;
else
items.score.visible = false
items.goodWordIndex = subLevelsLeft.pop()
items.ok.visible = false
items.goodWord = wordList[items.goodWordIndex]
items.wordImage.changeSource(items.goodWord.image);
items.remainingLife = 6;
alreadyTypedLetters = new Array();
currentWord = items.goodWord.translatedTxt;
items.hidden.text = ""
createAttemptedText()
for(var i = 0; i < currentWord.length ; ++ i) {
if(currentWord[i] == " ") {
items.hidden.text = items.hidden.text + " " + " "
} else {
items.hidden.text = items.hidden.text + sp;
}
}
}
function createAttemptedText() {
alreadyTypedLetters.sort()
items.guessedText.text = qsTr("Attempted: %1").arg(alreadyTypedLetters.join(", "))
}
function nextSubLevel() {
if( ++currentSubLevel >= maxSubLevel) {
currentSubLevel = 0;
nextLevel();
} else {
initSubLevel();
}
}
function focusTextInput() {
if (!GCompris.ApplicationInfo.isMobile && items && items.textinput)
items.textinput.forceActiveFocus();
}
diff --git a/src/activities/hanoi/ActivityInfo.qml b/src/activities/hanoi/ActivityInfo.qml
index 679ebc7ee..9c4e9924b 100644
--- a/src/activities/hanoi/ActivityInfo.qml
+++ b/src/activities/hanoi/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Johnny Jazeix <jazeix@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "hanoi/Hanoi.qml"
difficulty: 2
icon: "hanoi/hanoi.svg"
author: "Johnny Jazeix &lt;jazeix@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Simplified Tower of Hanoi")
//: Help title
description: qsTr("Reproduce the given tower")
//intro: "Rebuild the same tower in the empty area as the one you see on the right hand side."
//: Help goal
goal: qsTr("Reproduce the tower on the right in the empty space on the left")
//: Help prerequisite
prerequisite: qsTr("Mouse-manipulation")
//: Help manual
manual: qsTr("Drag and Drop one top piece at a time, from one peg to another, to reproduce the tower on the right in the empty space on the left.")
credit: qsTr("Concept taken from EPI games.")
section: "puzzle"
createdInVersion: 4000
}
diff --git a/src/activities/hanoi/Hanoi.qml b/src/activities/hanoi/Hanoi.qml
index ae19e2846..2adfac6f1 100644
--- a/src/activities/hanoi/Hanoi.qml
+++ b/src/activities/hanoi/Hanoi.qml
@@ -1,29 +1,29 @@
/* GCompris - Hanoi.qml
*
* Copyright (C) 2015 Johnny Jazeix <jazeix@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Johnny Jazeix <jazeix@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../hanoi_real"
HanoiReal {
id: activity
activityMode: "simplified"
}
diff --git a/src/activities/hanoi_real/ActivityInfo.qml b/src/activities/hanoi_real/ActivityInfo.qml
index 860fecdf5..b20b00f1d 100644
--- a/src/activities/hanoi_real/ActivityInfo.qml
+++ b/src/activities/hanoi_real/ActivityInfo.qml
@@ -1,43 +1,43 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Amit Tomar <a.tomar@outlook.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "hanoi_real/HanoiReal.qml"
difficulty: 5
icon: "hanoi_real/hanoi_real.svg"
author: "Amit Tomar &lt;a.tomar@outlook.com&gt;"
demo: true
//: Activity title
title: qsTr("The Tower of Hanoi")
//: Help title
description: qsTr("Reproduce the tower on the right side")
//intro: "Rebuild the model tower on the right support. Take care, no disc may be placed atop a smaller disc."
//: Help goal
goal: qsTr("The object of the game is to move the entire stack to another peg, obeying the following rules:
only one disc may be moved at a time
no disc may be placed atop a smaller disc
")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("Drag and drop the top pieces only from one peg to another, to reproduce the initial left side tower on the right peg.")
credit: qsTr("The puzzle was invented by the French mathematician Edouard Lucas in 1883. There is a legend about a Hindu temple whose priests were constantly engaged in moving a set of 64 discs according to the rules of the Tower of Hanoi puzzle. According to the legend, the world would end when the priests finished their work. The puzzle is therefore also known as the Tower of Brahma puzzle. It is not clear whether Lucas invented this legend or was inspired by it. (source Wikipedia: http://en.wikipedia.org/wiki/Tower_of_hanoi)")
section: "puzzle"
createdInVersion: 4000
}
diff --git a/src/activities/hanoi_real/HanoiReal.qml b/src/activities/hanoi_real/HanoiReal.qml
index ed815a3ab..7ea517b62 100644
--- a/src/activities/hanoi_real/HanoiReal.qml
+++ b/src/activities/hanoi_real/HanoiReal.qml
@@ -1,244 +1,242 @@
/* GCompris - hanoi_real.qml
*
* Copyright (C) 2015 Amit Tomar <a.tomar@outlook.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Amit Tomar <a.tomar@outlook.com> (Qt Quick port)
* Timothée Giet <animtim@gmail.com> (Graphics refactoring)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "hanoi_real.js" as Activity
ActivityBase {
id: activity
onStart: focus = true
onStop: {}
property string activityMode: "real"
pageComponent: Image {
id: background
source: Activity.url + "background.svg"
sourceSize.width: Math.max(parent.width, parent.height)
fillMode: Image.PreserveAspectCrop
signal start
signal stop
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property alias background: background
property alias bar: bar
property alias bonus: bonus
property alias discRepeater: discRepeater
property alias towerModel: towerModel
property bool hasWon: false
property int numberOfDisc
}
onStart: { Activity.start(items, activityMode) }
- onStop : { Activity.stop() }
+ onStop: { Activity.stop() }
onWidthChanged: Activity.sceneSizeChanged()
onHeightChanged: Activity.sceneSizeChanged()
Rectangle {
id: instruction
width: parent.width
height: description.height + 5 * ApplicationInfo.ratio
color: "#FFF"
opacity: 0.8
anchors {
bottom: bar.top
bottomMargin: 15 * ApplicationInfo.ratio
}
visible: bar.level == 1
}
GCText {
id: description
text: activityMode == "real" ? qsTr("Move the entire stack to the right peg, one disc at a time.") :
qsTr("Build the same tower in the empty area as the one you see on the right-hand side")
width: instruction.width
- fontSize: largeSize
+ fontSize: mediumSize
color: "#373737"
wrapMode: Text.WordWrap
anchors.centerIn: instruction
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
visible: bar.level == 1
}
Repeater {
id: discRepeater
Rectangle {
id: disc
- parent: towerModel.itemAt(0)
z: 4
width: Activity.getDiscWidth(index)
height: activityMode == "real"? towerModel.itemAt(0).height * 0.15: towerModel.itemAt(0).height / (Activity.nbMaxItemsByTower+1)
-
+
opacity: index < items.numberOfDisc ? 1 : 0
onHeightChanged: Activity.sceneSizeChanged()
property alias color: disc.color
radius: height * 0.5
- property bool mouseEnabled : true
+ property bool mouseEnabled: true
property alias discMouseArea: discMouseArea
property Item towerImage
property int position // The position index on the tower
property alias text: textSimplified.text
- anchors.horizontalCenter: if(parent) parent.horizontalCenter
-
-
+ anchors.horizontalCenter: parent.horizontalCenter
+
Behavior on y {
NumberAnimation {
id: bouncebehavior
easing {
type: Easing.OutElastic
amplitude: 1.0
period: 0.75
}
}
}
Rectangle {
id: inDisc
width: parent.width - 10 * ApplicationInfo.ratio
height: parent.height - 6 * ApplicationInfo.ratio
radius: width * 0.5
color: "#2AFFFFFF"
anchors.centerIn: parent
GCText {
id: textSimplified
visible: activityMode == "simplified"
color: "#b4000000"
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: 10 * ApplicationInfo.ratio
anchors.right: parent.right
}
}
MouseArea {
id: discMouseArea
enabled: disc.mouseEnabled && !items.hasWon
anchors.centerIn: parent
width: Activity.getDiscWidth(0)
height: background.height
drag.target: parent
drag.axis: Drag.XandYAxis
hoverEnabled: true
onPressed: {
disc.anchors.horizontalCenter = undefined
// Need to higher the z tower for the disc to be above all other towers and disc
disc.towerImage.z ++
disc.z ++
}
onReleased: {
// Restore previous z before releasing the disc
disc.towerImage.z --
disc.z --
Activity.discReleased(index)
disc.anchors.horizontalCenter = disc.parent.horizontalCenter
}
}
}
}
Grid {
// do columns if mobile?
rows: 1
columnSpacing: (background.width - towerModel.model * towerModel.itemAt(0).width) / (items.towerModel.model+1)
anchors {
bottom: instruction.top
horizontalCenter: parent.horizontalCenter
bottomMargin: 10 * ApplicationInfo.ratio
}
Repeater {
id: towerModel
model: 1 // will be dynamically set in js
delegate: Item {
id: towerImage
width: image.width
height: image.height
onHeightChanged: Activity.sceneSizeChanged()
Image {
id: image
source:
if(activityMode == "simplified" && (modelData == towerModel.model-2))
//in simplified mode, the target tower
Activity.url + "disc_support-green.svg"
else if(activityMode == "simplified" && (modelData == towerModel.model-1))
// in simplified mode, the reference tower
Activity.url + "disc_support-red.svg"
else if(activityMode == "real" && (modelData == towerModel.model-1))
// in real mode, the target tower
Activity.url + "disc_support-green.svg"
else
Activity.url + "disc_support.svg"
sourceSize.width: background.width / (towerModel.model + 2.5)
fillMode: Image.Stretch
height: background.height - instruction.height - 2 * bar.height
}
z: 3
}
}
}
DialogHelp {
id: dialogHelpLeftRight
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level | reload }
onHelpClicked: {
displayDialog(dialogHelpLeftRight)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: home()
onReloadClicked: Activity.initLevel()
}
Bonus {
id: bonus
Component.onCompleted: win.connect(Activity.nextLevel)
}
}
}
diff --git a/src/activities/hanoi_real/hanoi_real.js b/src/activities/hanoi_real/hanoi_real.js
index f6684e60f..55dab96e1 100644
--- a/src/activities/hanoi_real/hanoi_real.js
+++ b/src/activities/hanoi_real/hanoi_real.js
@@ -1,370 +1,369 @@
/* GCompris - hanoi_real.js
*
* Copyright (C) 2015 <Amit Tomar>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Amit Tomar <a.tomar@outlook.com> (Qt Quick hanoi tower port)
* Johnny Jazeix <jazeix@gmail.com> (Qt Quick hanoi simplified port)
* Timothée Giet <animtim@gmail.com> (Graphics refactoring)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
.import "qrc:/gcompris/src/core/core.js" as Core
var url = "qrc:/gcompris/src/activities/hanoi_real/resource/"
var currentLevel = 0
var numberOfLevel
var items
var activityMode
// Specific data for simplified mode
var symbols = [
"!", "/", "<",
">", "&", "~",
"#", "{", "%",
"|", "?", "}",
"=", "+", "*"
]
var colors = [
"#e4230b", // red
"#2cd60a", // green
"#0b62e4", // blue
"#ddb20b", // yellow
"#e40bb6", // magenta
"#0bb1e4", // cyan
"#e4900b", // orange
"#bc0be4", // purple
"#e43e0b", // red2
"#0ad618", // green2
"#2749f5", // blue2
"#ddc70b", // yellow2
"#e40b80", // magenta2
"#0b80e4", // cyan2
"#e4710b" // orange2
]
var nbTowersLessExpectedAndResultOnes
var nbMaxItemsByTower
function start(items_, activityMode_) {
items = items_
activityMode = activityMode_
currentLevel = 0
numberOfLevel = (activityMode == "real") ? 3 : 6
initLevel()
}
function stop() {
}
function initSpecificInfoForSimplified() {
Core.shuffle(symbols);
switch(items.bar.level) {
case 1:
nbTowersLessExpectedAndResultOnes = 3;
nbMaxItemsByTower = 5;
break;
case 2:
nbTowersLessExpectedAndResultOnes = 4;
nbMaxItemsByTower = 5;
break;
case 3:
nbTowersLessExpectedAndResultOnes = 5;
nbMaxItemsByTower = 6;
break;
case 4:
nbTowersLessExpectedAndResultOnes = 6;
nbMaxItemsByTower = 7;
break;
case 5:
nbTowersLessExpectedAndResultOnes = 6;
nbMaxItemsByTower = 8;
break;
case 6:
nbTowersLessExpectedAndResultOnes = 5;
nbMaxItemsByTower = 9;
}
}
function initLevel() {
items.bar.level = currentLevel + 1
items.hasWon = false
if(activityMode == "real") {
items.numberOfDisc = currentLevel + 3
items.discRepeater.model = items.numberOfDisc
items.towerModel.model = 3
}
else {
initSpecificInfoForSimplified();
items.towerModel.model = nbTowersLessExpectedAndResultOnes + 2
items.numberOfDisc = nbTowersLessExpectedAndResultOnes * (nbMaxItemsByTower-1) + nbMaxItemsByTower
items.discRepeater.model = items.numberOfDisc
}
placeDiscsAtOrigin()
if(activityMode != "real") {
for(var i = 0 ; i < (items.numberOfDisc-nbMaxItemsByTower); ++i) {
var index = Math.floor(Math.random() * symbols.length);
items.discRepeater.itemAt(i).text = symbols[index];
items.discRepeater.itemAt(i).color = colors[index];
}
// Fill the text discs avoiding duplicates
var currentAnswerId = items.numberOfDisc-nbMaxItemsByTower;
var goodAnswerIndices = [];
do {
var id = Math.floor(Math.random() * (items.numberOfDisc-nbMaxItemsByTower));
if(goodAnswerIndices.indexOf(id) == -1) {
items.discRepeater.itemAt(currentAnswerId).text = items.discRepeater.itemAt(id).text;
items.discRepeater.itemAt(currentAnswerId).color = items.discRepeater.itemAt(id).color;
goodAnswerIndices.push(id);
currentAnswerId ++;
}
}
while(currentAnswerId < items.numberOfDisc);
}
disableNonDraggablediscs()
}
function nextLevel()
{
if(numberOfLevel <= ++currentLevel) {
currentLevel = 0
}
initLevel();
}
function previousLevel()
{
if(--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
initLevel();
}
function placeDisc(disc, towerImage)
{
disc.towerImage = towerImage
disc.position = getNumberOfDiscOnTower(towerImage)
disc.parent = towerImage
setDiscY(disc, towerImage);
}
function setDiscY(disc, towerImage)
{
// -(towerImage.height * 0.12) because we need to remove the base of the tower
- // dependant of the image!
+ // dependent of the image!
disc.y = towerImage.y + towerImage.height - disc.position * disc.height - (towerImage.height * 0.12)
}
function placeDiscsAtOrigin() {
// Reset the model to get the initial animation
if(items.discRepeater.model === items.numberOfDisc)
items.discRepeater.model = 0
items.discRepeater.model = items.numberOfDisc
if(activityMode == "real") {
for(var i = 0 ; i < items.numberOfDisc ; ++i) {
placeDisc(items.discRepeater.itemAt(i), items.towerModel.itemAt(0))
items.discRepeater.itemAt(i).color = colors[i];
}
}
else {
// First fill the first towers
for(var i = 0 ; i < (items.numberOfDisc-nbMaxItemsByTower); ++i) {
placeDisc(items.discRepeater.itemAt(i), items.towerModel.itemAt(i%nbTowersLessExpectedAndResultOnes))
}
// Fill last tower
for(var i = items.numberOfDisc-nbMaxItemsByTower ; i < items.numberOfDisc ; ++i) {
placeDisc(items.discRepeater.itemAt(i), items.towerModel.itemAt(nbTowersLessExpectedAndResultOnes+1))
}
}
}
function discReleased(index)
{
var disc = items.discRepeater.itemAt(index)
var isCorrect = false;
-
if(activityMode == "real") {
for(var i = 0 ; i < items.towerModel.model ; ++ i) {
var towerItem = items.towerModel.itemAt(i);
if(checkIfDiscOnTowerImage(disc, towerItem) &&
getNumberOfDiscOnTower(towerItem) < items.numberOfDisc &&
getHigherfDiscOnTower(towerItem) <= index) {
placeDisc(disc, towerItem)
isCorrect = true
break;
}
}
}
else {
for(var i = 0 ; i < items.towerModel.model ; ++ i) {
var towerItem = items.towerModel.itemAt(i);
if(checkIfDiscOnTowerImage(disc, towerItem) &&
getNumberOfDiscOnTower(towerItem) < nbMaxItemsByTower) {
placeDisc(disc, towerItem)
isCorrect = true
break;
}
}
}
if(!isCorrect) {
// Cancel the drop
setDiscY(disc, disc.towerImage)
}
disableNonDraggablediscs()
checkSolved()
}
function sceneSizeChanged()
{
if(!items)
return
for(var i = 0 ; i < items.numberOfDisc ; ++i) {
var disc = items.discRepeater.itemAt(i)
if(!disc || !disc.towerImage)
continue
setDiscY(disc, disc.towerImage)
}
disableNonDraggablediscs()
}
function disableNonDraggablediscs()
{
if(activityMode == "real") {
// Only the highest (index) one is enabled
for(var i = 0 ; i < items.numberOfDisc ; ++i) {
var disc = items.discRepeater.itemAt(i)
if(disc)
disc.mouseEnabled = (getHigherfDiscOnTower(disc.towerImage) <= i)
}
}
else {
// In simplified, all the last tower discs are disabled
// We disable all except the highest (in position) ones of each tower
var highestOnes = [];
for(var i = 0 ; i < items.numberOfDisc ; ++i) {
var disc = items.discRepeater.itemAt(i)
if(!disc)
continue
disc.mouseEnabled = false
if(disc.towerImage == items.towerModel.itemAt(items.towerModel.model-1)) {
continue;
}
else if(highestOnes[disc.towerImage] == undefined) {
highestOnes[disc.towerImage] = {"pos": disc.position, "id": i}
}
else if(highestOnes[disc.towerImage].pos < disc.position) {
highestOnes[disc.towerImage].pos = disc.position
highestOnes[disc.towerImage].id = i
}
}
for(var i in highestOnes) {
items.discRepeater.itemAt(highestOnes[i].id).mouseEnabled = true
}
}
}
function checkIfDiscOnTowerImage(disc, towerImage)
{
var discPosition = items.background.mapFromItem(disc, 0, 0)
var towerPosition = items.background.mapFromItem(towerImage, 0, 0)
return ((discPosition.x + disc.width / 2) > towerPosition.x &&
(discPosition.x + disc.width / 2) < towerPosition.x + towerImage.width)
}
function getHigherfDiscOnTower(towerImage) {
var higher = 0
for(var i = 0 ; i < items.numberOfDisc ; ++i)
{
if(items.discRepeater.itemAt(i) && items.discRepeater.itemAt(i).towerImage === towerImage)
higher = i
}
return higher
}
function getNumberOfDiscOnTower(towerImage) {
var count = 0
for(var i = 0 ; i < items.numberOfDisc ; ++i)
{
if(items.discRepeater.itemAt(i).towerImage === towerImage)
count++
}
return count
}
function checkSolved() {
if(activityMode == "real") {
if(getNumberOfDiscOnTower(items.towerModel.itemAt(items.towerModel.model-1)) === items.numberOfDisc) {
items.hasWon = true
items.bonus.good("flower")
}
}
else {
// Recreate both last towers text
var expectedTower = [];
var actualTower = [];
for(var i = 0 ; i < items.numberOfDisc ; ++i) {
var disc = items.discRepeater.itemAt(i);
if(disc.towerImage == items.towerModel.itemAt(items.towerModel.model-1)) {
actualTower[disc.position] = disc.text
}
else if(disc.towerImage == items.towerModel.itemAt(items.towerModel.model-2)) {
expectedTower[disc.position] = disc.text
}
}
// Don't check if not the same length
var hasWon = (expectedTower.length == actualTower.length)
for (var i = 0; hasWon && i < actualTower.length; ++i) {
if (expectedTower[i] !== actualTower[i]) hasWon = false
}
if(hasWon) {
items.hasWon = true
items.bonus.good("flower")
}
}
}
function getDiscWidth(index)
{
if(activityMode == "real") {
if( 0 === index ) return items.towerModel.itemAt(0).width * 1.6
else if ( 1 === index ) return items.towerModel.itemAt(0).width * 1.3
else if ( 2 === index ) return items.towerModel.itemAt(0).width * 1
else if ( 3 === index ) return items.towerModel.itemAt(0).width * 0.7
else return items.towerModel.itemAt(0).width * 0.5
}
else {
return items.towerModel.itemAt(0).width
}
}
diff --git a/src/activities/hexagon/ActivityInfo.qml b/src/activities/hexagon/ActivityInfo.qml
index 8eb092a0e..5340d94ae 100644
--- a/src/activities/hexagon/ActivityInfo.qml
+++ b/src/activities/hexagon/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "hexagon/Hexagon.qml"
difficulty: 2
icon: "hexagon/hexagon.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
//: Activity title
title: qsTr("Hexagon")
//: Help title
description: qsTr("Find the strawberry by clicking on the blue fields")
// intro: "Click on the hexagons to find the hidden object, the red zone indicates that you're close to it!"
//: Help goal
goal: qsTr("Logic-training activity")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("Try to find the strawberry under the blue fields. The fields become redder as you get closer.")
credit: ""
section: "fun"
createdInVersion: 0
}
diff --git a/src/activities/hexagon/Hexagon.qml b/src/activities/hexagon/Hexagon.qml
index 038e917df..ab0ff6314 100644
--- a/src/activities/hexagon/Hexagon.qml
+++ b/src/activities/hexagon/Hexagon.qml
@@ -1,119 +1,119 @@
/* GCompris - Hexagon.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Christof Petig and Ingo Konrad (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "hexagon.js" as Activity
ActivityBase {
id: activity
onStart: focus = true
pageComponent: Image {
id: background
source: "qrc:/gcompris/src/activities/menu/resource/background.svg"
sourceSize.width: Math.max(parent.width, parent.height)
fillMode: Image.PreserveAspectCrop
signal start
signal stop
focus: true
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
QtObject {
id: items
property alias background: background
property alias bar: bar
property alias bonus: bonus
property alias hexagonModel: hexagonModel
}
onStart: Activity.start(main, items)
onStop: Activity.stop()
function checkTouchPoint(touchPoints) {
for(var i in touchPoints) {
var touch = touchPoints[i]
var block = rootItem.childAt(touch.x, touch.y)
if(block)
block.touched()
}
}
MultiPointTouchArea {
anchors.fill: parent
onPressed: checkTouchPoint(touchPoints)
}
Item {
id: rootItem
anchors.fill: parent
}
ListModel {
id: hexagonModel
}
Repeater {
model: hexagonModel
parent: rootItem
HexagonItem {
audioEffects: activity.audioEffects
ix: m_ix
iy: m_iy
nbx: m_nbx
nby: m_nby
hasStrawberry: m_hasStrawberry
color: "#0099FF"
}
}
DialogHelp {
id: dialogHelpLeftRight
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level }
onHelpClicked: {
displayDialog(dialogHelpLeftRight)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: home()
}
Bonus {
id: bonus
interval: 2000
Component.onCompleted: win.connect(Activity.nextLevel)
}
}
}
diff --git a/src/activities/hexagon/HexagonItem.qml b/src/activities/hexagon/HexagonItem.qml
index a0cdd5904..9ae2e05e6 100644
--- a/src/activities/hexagon/HexagonItem.qml
+++ b/src/activities/hexagon/HexagonItem.qml
@@ -1,122 +1,122 @@
/* GCompris - Hexagon.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Christof Petig and Ingo Konrad (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
* Timothée Giet <animtim@gmail.com> (add mode without OpenGL)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import QtGraphicalEffects 1.0
import "hexagon.js" as Activity
import "../../core"
import GCompris 1.0
Item {
id: hexagon
property GCSfx audioEffects
property ParticleSystemStar particles
property alias color: softCanvas.color
property bool hasStrawberry: false
property double ix
property double iy
property int nbx
property int nby
// Warning testing parent here, just to avoid an error at deletion time
property double r: parent ? Math.min(parent.width / nbx / 2, (parent.height - 10) / nby / 2) : 0
property double offsetX: parent ? (parent.width % (width * nbx)) / 2 : 0
property double offsetY: parent ? (parent.height % (height * nby)) / 2 : 0
x: (iy % 2 ? width * ix + width / 2 : width * ix) + offsetX
y: height * iy - (Math.sin((Math.PI * 2) / 12) * r * 2 * iy) / 2 + offsetY
width: Math.cos((Math.PI * 2) / 12) * r * 2
height: r * 2
Image {
id: strawberry
anchors.fill: parent
opacity: 0
onSourceChanged: opacity = 1
Behavior on opacity { PropertyAnimation { duration: 2000; easing.type: Easing.OutQuad } }
}
Image {
id: border
anchors.fill: parent
source: Activity.url + "hexagon_border.svg"
Behavior on opacity { PropertyAnimation { duration: 500 } }
}
Image {
id: canvas
anchors.fill: parent
source: Activity.url + "hexagon.svg"
visible: false
}
Rectangle {
id:softCanvas
width: parent.width * 0.8
height: width
radius: width * 0.5
anchors.centerIn: parent
opacity: strawberry.opacity == 0 ? 0.65 : 0
visible: ApplicationInfo.useOpenGL ? false : true
}
ColorOverlay {
id: colorOverlay
anchors.fill: canvas
source: canvas
onOpacityChanged: if(opacity == 0) Activity.strawberryFound()
color: softCanvas.color
opacity: 0.65
Behavior on opacity { PropertyAnimation { duration: 500 } }
}
// Create a particle only for the strawberry
Loader {
id: particleLoader
anchors.fill: parent
active: hasStrawberry
sourceComponent: particle
}
Component {
id: particle
ParticleSystemStarLoader
{
id: particles
clip: false
}
}
property bool isTouched: false
function touched() {
if(hasStrawberry && !isTouched) {
colorOverlay.opacity = 0
border.opacity = 0
isTouched = true
strawberry.source = Activity.url + "strawberry.svg"
audioEffects.play("qrc:/gcompris/src/core/resource/sounds/win.wav")
Activity.strawberryFound()
particleLoader.item.burst(40)
} else {
hexagon.color =
Activity.getColor(Activity.getDistance(hexagon.ix, hexagon.iy))
}
}
}
diff --git a/src/activities/hexagon/hexagon.js b/src/activities/hexagon/hexagon.js
index 416bfdc1a..bea171e3c 100644
--- a/src/activities/hexagon/hexagon.js
+++ b/src/activities/hexagon/hexagon.js
@@ -1,112 +1,112 @@
/* GCompris - Hexagon.qml
*
* Copyright (C) 2014 Bruno Coudoin
*
* Authors:
* Christof Petig and Ingo Konrad (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
var url = "qrc:/gcompris/src/activities/hexagon/resource/"
var maxNumberOfLevel = 12;
var currentLevel = 0
var main
var items
// The size of the array
var nbx
var nby
// The strawberry position
var strawBerryX
var strawBerryY
function start(main_, items_) {
main = main_
items = items_
currentLevel = 0
initLevel()
}
function stop() {
}
function initLevel() {
items.hexagonModel.clear()
items.bar.level = currentLevel + 1
nbx = 10 + currentLevel
nby = Math.floor(nbx * (main.height / main.width))
// Select a random place for the strawberry
strawBerryX = Math.floor(Math.random() * (nbx -1))
strawBerryY = Math.floor(Math.random() * nby)
var model = []
for(var ix = 0; ix < nbx; ++ix) {
for(var iy = 0; iy < nby; ++iy) {
if( (iy % 2 && ix < nbx - 1) || iy % 2 == 0)
items.hexagonModel.append( {
"m_ix": ix, "m_iy": iy, "m_nbx": nbx, "m_nby": nby,
"m_hasStrawberry": (strawBerryX === ix && strawBerryY === iy) ? true : false
} )
}
}
}
function nextLevel() {
if(maxNumberOfLevel <= ++currentLevel ) {
currentLevel = 0
}
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = maxNumberOfLevel - 1
}
initLevel();
}
function strawberryFound() {
items.bonus.good("flower")
}
function getDistance(ix, iy) {
return Math.sqrt(Math.pow((ix - strawBerryX), 2) + Math.pow((iy - strawBerryY), 2))
}
function getColor(dist) {
var r = 0
var b = 0
var g = 0
if (dist < 5) {
r = 0xFF
g = 0xFF * (dist / 5)
} else if(dist < 10) {
g = 0xFF
r = 0xFF - 0xFF * ((dist - 5) / 5)
} else if (dist < 15) {
g = 0xFF - 0xFF * ((dist - 10) / 5)
b = 0xFF * ((dist - 10) / 5)
} else {
// Calc the max size
var maxSize = Math.sqrt(Math.pow(nbx, 2) + Math.pow(nby, 2))
b = 0xFF
r = 0xFF * ((dist - 15) / maxSize)
}
return Qt.rgba(r/255, g/255, b/255, 1)
}
diff --git a/src/activities/imagename/ActivityInfo.qml b/src/activities/imagename/ActivityInfo.qml
index 17c49932b..98a661e79 100644
--- a/src/activities/imagename/ActivityInfo.qml
+++ b/src/activities/imagename/ActivityInfo.qml
@@ -1,42 +1,42 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Pulkit Gupta <pulkitgenius@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "imagename/Imagename.qml"
difficulty: 3
icon: "imagename/imagename.svg"
author: "Pulkit Gupta &lt;pulkitgenius@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Image Name")
//: Help title
description: qsTr("Drag and Drop each item above its name")
// intro: "Drag and drop each item above its name."
//: Help goal
goal: qsTr("Vocabulary and reading")
//: Help prerequisite
prerequisite: qsTr("Reading")
//: Help manual
manual: qsTr("Drag each image from the (vertical) box on the left to its (corresponding) name on the right. Click the OK button to check your answer.")
section: "reading"
createdInVersion: 4000
}
diff --git a/src/activities/imagename/Imagename.qml b/src/activities/imagename/Imagename.qml
index dd4d1f2cc..2fd53dced 100644
--- a/src/activities/imagename/Imagename.qml
+++ b/src/activities/imagename/Imagename.qml
@@ -1,35 +1,35 @@
/* GCompris - Imagename.qml
*
* Copyright (C) 2015 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Bruno Coudoin (bruno.coudoin@gcompris.net) / Andre Connes (andre.connes@toulouse.iufm.fr) (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../babymatch"
Babymatch {
id: activity
onStart: focus = true
onStop: {}
imagesUrl: "qrc:/gcompris/src/activities/babymatch/resource/"
boardsUrl: "qrc:/gcompris/src/activities/imagename/resource/"
levelCount: 7
}
diff --git a/src/activities/imagename/resource/board/board1_0.qml b/src/activities/imagename/resource/board/board1_0.qml
index 011bb4d26..91a391bc0 100644
--- a/src/activities/imagename/resource/board/board1_0.qml
+++ b/src/activities/imagename/resource/board/board1_0.qml
@@ -1,113 +1,113 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Drag and Drop each item onto its name")
property var levels: [
{
"pixmapfile": "images/postpoint.svg",
"x": "0.2",
"y": "0.25",
"height": 0.25,
"width": 0.25
},
{
"pixmapfile": "images/sailingboat.svg",
"x": "0.5",
"y": "0.25",
"height": 0.25,
"width": 0.25
},
{
"pixmapfile": "images/lamp.svg",
"x": "0.8",
"y": "0.25",
"height": 0.25,
"width": 0.25
},
{
"pixmapfile": "images/postcard.svg",
"x": "0.2",
"y": "0.7",
"height": 0.25,
"width": 0.25
},
{
"pixmapfile": "images/fishingboat.svg",
"x": "0.5",
"y": "0.7",
"height": 0.25,
"width": 0.25
},
{
"pixmapfile": "images/light.svg",
"x": "0.8",
"y": "0.7",
"height": 0.25,
"width": 0.25
},
{
"text": qsTr("mail box"),
"x": "0.2",
"y": "0.4",
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("sailing boat"),
"x": "0.5",
"y": "0.4",
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("lamp"),
"x": "0.8",
"y": "0.4",
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("postcard"),
"x": "0.2",
"y": "0.85",
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("fishing boat"),
"x": "0.5",
"y": "0.85",
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("bulb"),
"x": "0.8",
"y": "0.85",
"width": "0.4",
"type": "DisplayText"
}
]
}
diff --git a/src/activities/imagename/resource/board/board2_0.qml b/src/activities/imagename/resource/board/board2_0.qml
index 164734302..474db0f7e 100644
--- a/src/activities/imagename/resource/board/board2_0.qml
+++ b/src/activities/imagename/resource/board/board2_0.qml
@@ -1,112 +1,112 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property var levels: [
{
"pixmapfile": "images/bottle.svg",
"x": "0.2",
"y": "0.25",
"height": 0.25,
"width": 0.25
},
{
"pixmapfile": "images/glass.svg",
"x": "0.5",
"y": "0.25",
"height": 0.25,
"width": 0.25
},
{
"pixmapfile": "images/egg.svg",
"x": "0.8",
"y": "0.25",
"height": 0.25,
"width": 0.25
},
{
"pixmapfile": "images/eggpot.svg",
"x": "0.2",
"y": "0.7",
"height": 0.25,
"width": 0.25
},
{
"pixmapfile": "images/flower.svg",
"x": "0.5",
"y": "0.7",
"height": 0.25,
"width": 0.25
},
{
"pixmapfile": "images/flowerpot.svg",
"x": "0.8",
"y": "0.7",
"height": 0.25,
"width": 0.25
},
{
"text": qsTr("bottle"),
"x": "0.2",
"y": "0.4",
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("glass"),
"x": "0.5",
"y": "0.4",
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("egg"),
"x": "0.8",
"y": "0.4",
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("eggcup"),
"x": "0.2",
"y": "0.85",
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("flower"),
"x": "0.5",
"y": "0.85",
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("vase"),
"x": "0.8",
"y": "0.85",
"width": "0.4",
"type": "DisplayText"
}
]
}
diff --git a/src/activities/imagename/resource/board/board3_0.qml b/src/activities/imagename/resource/board/board3_0.qml
index dce9992bb..4b122138e 100644
--- a/src/activities/imagename/resource/board/board3_0.qml
+++ b/src/activities/imagename/resource/board/board3_0.qml
@@ -1,112 +1,112 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property var levels: [
{
"pixmapfile": "images/fusee.svg",
"x": "0.2",
"y": "0.25",
"height": 0.25,
"width": 0.25
},
{
"pixmapfile": "images/star.svg",
"x": "0.5",
"y": "0.25",
"height": 0.25,
"width": 0.25
},
{
"pixmapfile": "images/sofa.svg",
"x": "0.8",
"y": "0.25",
"height": 0.25,
"width": 0.25
},
{
"pixmapfile": "images/house.svg",
"x": "0.2",
"y": "0.7",
"height": 0.25,
"width": 0.25
},
{
"pixmapfile": "images/lighthouse.svg",
"x": "0.5",
"y": "0.7",
"height": 0.25,
"width": 0.25
},
{
"pixmapfile": "images/sailingboat.svg",
"x": "0.8",
"y": "0.7",
"height": 0.25,
"width": 0.25
},
{
"text": qsTr("rocket"),
"x": "0.2",
"y": "0.4",
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("star"),
"x": "0.5",
"y": "0.4",
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("sofa"),
"x": "0.8",
"y": "0.4",
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("house"),
"x": "0.2",
"y": "0.85",
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("light house"),
"x": "0.5",
"y": "0.85",
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("sailing boat"),
"x": "0.8",
"y": "0.85",
"width": "0.4",
"type": "DisplayText"
}
]
}
diff --git a/src/activities/imagename/resource/board/board4_0.qml b/src/activities/imagename/resource/board/board4_0.qml
index ddcc5e782..de72dcabb 100644
--- a/src/activities/imagename/resource/board/board4_0.qml
+++ b/src/activities/imagename/resource/board/board4_0.qml
@@ -1,112 +1,112 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property var levels: [
{
"pixmapfile": "images/apple.svg",
"x": "0.2",
"y": "0.25",
"height": 0.25,
"width": 0.25
},
{
"pixmapfile": "images/tree.svg",
"x": "0.5",
"y": "0.25",
"height": 0.25,
"width": 0.25
},
{
"pixmapfile": "images/bicycle.svg",
"x": "0.8",
"y": "0.25",
"height": 0.25,
"width": 0.25
},
{
"pixmapfile": "images/car.svg",
"x": "0.2",
"y": "0.7",
"height": 0.25,
"width": 0.25
},
{
"pixmapfile": "images/carrot.svg",
"x": "0.5",
"y": "0.7",
"height": 0.25,
"width": 0.25
},
{
"pixmapfile": "images/rape.svg",
"x": "0.8",
"y": "0.7",
"height": 0.25,
"width": 0.25
},
{
"text": qsTr("apple"),
"x": "0.2",
"y": "0.4",
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("tree"),
"x": "0.5",
"y": "0.4",
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("bicycle"),
"x": "0.8",
"y": "0.4",
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("car"),
"x": "0.2",
"y": "0.85",
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("carrot"),
"x": "0.5",
"y": "0.85",
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("grater"),
"x": "0.8",
"y": "0.85",
"width": "0.4",
"type": "DisplayText"
}
]
}
diff --git a/src/activities/imagename/resource/board/board5_0.qml b/src/activities/imagename/resource/board/board5_0.qml
index 63c9eca95..0e582e3f2 100644
--- a/src/activities/imagename/resource/board/board5_0.qml
+++ b/src/activities/imagename/resource/board/board5_0.qml
@@ -1,112 +1,112 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property var levels: [
{
"pixmapfile": "images/pencil.svg",
"x": "0.2",
"y": "0.25",
"height": 0.25,
"width": 0.25
},
{
"pixmapfile": "images/postcard.svg",
"x": "0.5",
"y": "0.25",
"height": 0.25,
"width": 0.25
},
{
"pixmapfile": "images/tree.svg",
"x": "0.8",
"y": "0.25",
"height": 0.25,
"width": 0.25
},
{
"pixmapfile": "images/star.svg",
"x": "0.2",
"y": "0.7",
"height": 0.25,
"width": 0.25
},
{
"pixmapfile": "images/truck.svg",
"x": "0.5",
"y": "0.7",
"height": 0.25,
"width": 0.25
},
{
"pixmapfile": "images/minivan.svg",
"x": "0.8",
"y": "0.7",
"height": 0.25,
"width": 0.25
},
{
"text": qsTr("pencil"),
"x": "0.2",
"y": "0.4",
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("postcard"),
"x": "0.5",
"y": "0.4",
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("tree"),
"x": "0.8",
"y": "0.4",
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("star"),
"x": "0.2",
"y": "0.85",
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("truck"),
"x": "0.5",
"y": "0.85",
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("van"),
"x": "0.8",
"y": "0.85",
"width": "0.4",
"type": "DisplayText"
}
]
}
diff --git a/src/activities/imagename/resource/board/board6_0.qml b/src/activities/imagename/resource/board/board6_0.qml
index a17e9c6b0..4a1ee979d 100644
--- a/src/activities/imagename/resource/board/board6_0.qml
+++ b/src/activities/imagename/resource/board/board6_0.qml
@@ -1,112 +1,112 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property var levels: [
{
"pixmapfile": "images/castle.svg",
"x": "0.2",
"y": "0.25",
"height": 0.25,
"width": 0.25
},
{
"pixmapfile": "images/crown.svg",
"x": "0.5",
"y": "0.25",
"height": 0.25,
"width": 0.25
},
{
"pixmapfile": "images/sailingboat.svg",
"x": "0.8",
"y": "0.25",
"height": 0.25,
"width": 0.25
},
{
"pixmapfile": "images/windflag5.svg",
"x": "0.2",
"y": "0.7",
"height": 0.25,
"width": 0.25
},
{
"pixmapfile": "images/raquette.svg",
"x": "0.5",
"y": "0.7",
"height": 0.25,
"width": 0.25
},
{
"pixmapfile": "images/football.svg",
"x": "0.8",
"y": "0.7",
"height": 0.25,
"width": 0.25
},
{
"text": qsTr("castle"),
"x": "0.2",
"y": "0.4",
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("crown"),
"x": "0.5",
"y": "0.4",
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("sailing boat"),
"x": "0.8",
"y": "0.4",
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("flag"),
"x": "0.2",
"y": "0.85",
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("racket"),
"x": "0.5",
"y": "0.85",
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("ball"),
"x": "0.8",
"y": "0.85",
"width": "0.4",
"type": "DisplayText"
}
]
}
diff --git a/src/activities/imagename/resource/board/board7_0.qml b/src/activities/imagename/resource/board/board7_0.qml
index 093c2e9c0..34a9196ce 100644
--- a/src/activities/imagename/resource/board/board7_0.qml
+++ b/src/activities/imagename/resource/board/board7_0.qml
@@ -1,112 +1,112 @@
/* GCompris
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property var levels: [
{
"pixmapfile": "images/tree.svg",
"x": "0.2",
"y": "0.25",
"height": 0.25,
"width": 0.25
},
{
"pixmapfile": "images/postpoint.svg",
"x": "0.5",
"y": "0.25",
"height": 0.25,
"width": 0.25
},
{
"pixmapfile": "images/sailingboat.svg",
"x": "0.8",
"y": "0.25",
"height": 0.25,
"width": 0.25
},
{
"pixmapfile": "images/light.svg",
"x": "0.2",
"y": "0.7",
"height": 0.25,
"width": 0.25
},
{
"pixmapfile": "images/bottle.svg",
"x": "0.5",
"y": "0.7",
"height": 0.25,
"width": 0.25
},
{
"pixmapfile": "images/flower.svg",
"x": "0.8",
"y": "0.7",
"height": 0.25,
"width": 0.25
},
{
"text": qsTr("tree"),
"x": "0.2",
"y": "0.4",
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("mail box"),
"x": "0.5",
"y": "0.4",
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("sailing boat"),
"x": "0.8",
"y": "0.4",
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("bulb"),
"x": "0.2",
"y": "0.85",
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("bottle"),
"x": "0.5",
"y": "0.85",
"width": "0.4",
"type": "DisplayText"
},
{
"text": qsTr("flower"),
"x": "0.8",
"y": "0.85",
"width": "0.4",
"type": "DisplayText"
}
]
}
diff --git a/src/activities/instruments/ActivityInfo.qml b/src/activities/instruments/ActivityInfo.qml
index 39e80c892..ed13ccada 100644
--- a/src/activities/instruments/ActivityInfo.qml
+++ b/src/activities/instruments/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "instruments/Instruments.qml"
difficulty: 4
icon: "instruments/instruments.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
//: Activity title
title: qsTr("Music instruments")
//: Help title
description: qsTr("Click on the correct musical instruments")
// intro: "Click on the correct musical instrument."
//: Help goal
goal: qsTr("Learn to recognize musical instruments.")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("Click on the correct instrument.")
credit: ""
section: "discovery music"
createdInVersion: 0
}
diff --git a/src/activities/instruments/Instruments.qml b/src/activities/instruments/Instruments.qml
index 5e651e018..f06aeb17e 100644
--- a/src/activities/instruments/Instruments.qml
+++ b/src/activities/instruments/Instruments.qml
@@ -1,32 +1,32 @@
/* GCompris - Instruments.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Original activity in the Gtk+ version of GCompris by
* Sylvain Dechy <syl.1@free.fr>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../colors"
import "instruments.js" as Dataset
FindIt {
mode: "Instruments"
dataset: Dataset
backgroundImg: "qrc:/gcompris/src/activities/instruments/resource/background.svg"
}
diff --git a/src/activities/instruments/instruments.js b/src/activities/instruments/instruments.js
index 05b34d6fd..c488bf331 100644
--- a/src/activities/instruments/instruments.js
+++ b/src/activities/instruments/instruments.js
@@ -1,311 +1,311 @@
/* GCompris - instruments.js
*
* Copyright (C) 2015 Bruno Coudoin
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
var colors =
[
[ // Level 1
{
"image": "qrc:/gcompris/src/activities/instruments/resource/clarinet.svg",
"text": qsTr("Find the clarinet"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/clarinet.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/flute_traversiere.svg",
"text": qsTr("Find the transverse flute"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/flute_traversiere.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/guitar.svg",
"text": qsTr("Find the guitar"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/guitar.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/harp.svg",
"text": qsTr("Find the harp"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/harp.$CA")
}
],
[ // Level 2
{
"image": "qrc:/gcompris/src/activities/instruments/resource/piano.svg",
"text": qsTr("Find the piano"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/piano.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/saxophone.svg",
"text": qsTr("Find the saxophone"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/saxophone.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/trombone.svg",
"text": qsTr("Find the trombone"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/trombone.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/trumpet.svg",
"text": qsTr("Find the trumpet"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/trumpet.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/violin.svg",
"text": qsTr("Find the violin"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/violin.$CA")
}
],
[ // Level
{
"image": "qrc:/gcompris/src/activities/instruments/resource/clarinet.svg",
"text": qsTr("Find the clarinet"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/clarinet.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/flute_traversiere.svg",
"text": qsTr("Find the transverse flute"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/flute_traversiere.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/guitar.svg",
"text": qsTr("Find the guitar"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/guitar.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/harp.svg",
"text": qsTr("Find the harp"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/harp.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/piano.svg",
"text": qsTr("Find the piano"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/piano.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/saxophone.svg",
"text": qsTr("Find the saxophone"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/saxophone.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/trombone.svg",
"text": qsTr("Find the trombone"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/trombone.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/trumpet.svg",
"text": qsTr("Find the trumpet"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/trumpet.$CA")
}
],
[ // Level 4
{
"image": "qrc:/gcompris/src/activities/instruments/resource/violin.svg",
"text": qsTr("Find the violin"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/violin.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/flute_traversiere.svg",
"text": qsTr("Find the transverse flute"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/flute_traversiere.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/guitar.svg",
"text": qsTr("Find the guitar"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/guitar.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/harp.svg",
"text": qsTr("Find the harp"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/harp.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/piano.svg",
"text": qsTr("Find the piano"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/piano.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/saxophone.svg",
"text": qsTr("Find the saxophone"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/saxophone.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/trombone.svg",
"text": qsTr("Find the trombone"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/trombone.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/trumpet.svg",
"text": qsTr("Find the trumpet"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/trumpet.$CA")
}
],
[ // Level 5
{
"image": "qrc:/gcompris/src/activities/instruments/resource/drum_kit.svg",
"text": qsTr("Find the drum kit"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/drum_kit.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/accordion.svg",
"text": qsTr("Find the accordion"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/accordion.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/banjo.svg",
"text": qsTr("Find the banjo"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/banjo.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/bongo.svg",
"text": qsTr("Find the bongo"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/bongo.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/electric_guitar.svg",
"text": qsTr("Find the electric guitar"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/electric_guitar.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/castanets.svg",
"text": qsTr("Find the castanets"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/castanets.$CA")
}
],
[ // Level 6
{
"image": "qrc:/gcompris/src/activities/instruments/resource/drum_kit.svg",
"text": qsTr("Find the drum kit"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/drum_kit.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/accordion.svg",
"text": qsTr("Find the accordion"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/accordion.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/banjo.svg",
"text": qsTr("Find the banjo"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/banjo.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/cymbal.svg",
"text": qsTr("Find the cymbal"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/cymbal.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/cello.svg",
"text": qsTr("Find the cello"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/cello.$CA")
}
],
[ // Level 7
{
"image": "qrc:/gcompris/src/activities/instruments/resource/bongo.svg",
"text": qsTr("Find the bongo"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/bongo.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/electric_guitar.svg",
"text": qsTr("Find the electric guitar"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/electric_guitar.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/harmonica.svg",
"text": qsTr("Find the harmonica"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/harmonica.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/horn.svg",
"text": qsTr("Find the horn"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/horn.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/maracas.svg",
"text": qsTr("Find the maracas"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/maracas.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/organ.svg",
"text": qsTr("Find the organ"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/organ.$CA")
}
],
[ // Level 8
{
"image": "qrc:/gcompris/src/activities/instruments/resource/snare_drum.svg",
"text": qsTr("Find the snare drum"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/snare_drum.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/timpani.svg",
"text": qsTr("Find the timpani"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/timpani.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/triangle.svg",
"text": qsTr("Find the triangle"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/triangle.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/horn.svg",
"text": qsTr("Find the horn"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/horn.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/maracas.svg",
"text": qsTr("Find the maracas"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/maracas.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/organ.svg",
"text": qsTr("Find the organ"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/organ.$CA")
}
],
[ // Level 9
{
"image": "qrc:/gcompris/src/activities/instruments/resource/snare_drum.svg",
"text": qsTr("Find the snare drum"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/snare_drum.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/timpani.svg",
"text": qsTr("Find the timpani"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/timpani.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/triangle.svg",
"text": qsTr("Find the triangle"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/triangle.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/tambourine.svg",
"text": qsTr("Find the tambourine"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/tambourine.$CA")
},
{
"image": "qrc:/gcompris/src/activities/instruments/resource/tuba.svg",
"text": qsTr("Find the tuba"),
"audio": ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/activities/instruments/resource/tuba.$CA")
}
]
]
function get() {
return colors
}
diff --git a/src/activities/intro_gravity/ActivityInfo.qml b/src/activities/intro_gravity/ActivityInfo.qml
index 3539e8957..41c566492 100644
--- a/src/activities/intro_gravity/ActivityInfo.qml
+++ b/src/activities/intro_gravity/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Siddhesh suthar<siddhesh.it@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "intro_gravity/IntroGravity.qml"
difficulty: 4
icon: "intro_gravity/intro_gravity.svg"
author: "Siddhesh suthar &lt;siddhesh.it@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Intro gravity")
//: Help title
description: qsTr("Introduction to the concept of gravity")
//intro: "Change the planets' gravitational force by moving the sliders up and down. Be careful not to crash Tux's spaceship."
//: Help goal
goal: qsTr("Maintain the spaceship in the middle without crashing into the planets or the asteroids")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("Follow the instructions when you run the activity.")
credit: ""
section: "experiment"
createdInVersion: 4000
}
diff --git a/src/activities/intro_gravity/Asteroid.qml b/src/activities/intro_gravity/Asteroid.qml
index e2f7c3f29..9816c7738 100644
--- a/src/activities/intro_gravity/Asteroid.qml
+++ b/src/activities/intro_gravity/Asteroid.qml
@@ -1,46 +1,46 @@
/*GCompris :- intro_gravity.qml
*
* Copyright (C) 2015 Siddhesh suthar <siddhesh.it@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> and Matilda Bernard (GTK+ version)
* Siddhesh suthar <siddhesh.it@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "intro_gravity.js" as Activity
import "../../core"
import GCompris 1.0
Image {
id: asteroid
sourceSize.height: 100 * ApplicationInfo.ratio
z: 5
property alias fallDuration: down.duration
function startMoving() {
down.restart()
}
NumberAnimation {
id: down
target: asteroid
property: "y"
to: parent.height
}
}
diff --git a/src/activities/intro_gravity/IntroGravity.qml b/src/activities/intro_gravity/IntroGravity.qml
index 09d7c6735..1ee46a3cf 100644
--- a/src/activities/intro_gravity/IntroGravity.qml
+++ b/src/activities/intro_gravity/IntroGravity.qml
@@ -1,238 +1,238 @@
/* GCompris - intro_gravity.qml
*
* Copyright (C) 2015 Siddhesh suthar <siddhesh.it@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> and Matilda Bernard (GTK+ version)
* Siddhesh suthar <siddhesh.it@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "intro_gravity.js" as Activity
ActivityBase {
id: activity
onStart: focus = true
onStop: {}
property int oldWidth: width
onWidthChanged: {
// Reposition planets and asteroids, same for height
Activity.repositionObjectsOnWidthChanged(width / oldWidth)
oldWidth = width
}
property int oldHeight: height
onHeightChanged: {
// Reposition planets and asteroids, same for height
Activity.repositionObjectsOnHeightChanged(height / oldHeight)
oldHeight = height
}
pageComponent: Image {
id: background
anchors.fill: parent
source: Activity.url+"background.svg"
sourceSize.width: Math.max(parent.width, parent.height)
fillMode: Image.PreserveAspectCrop
signal start
signal stop
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property alias background: background
property alias bar: bar
property alias bonus: bonus
property alias planetLeft: planetLeft
property alias planetRight: planetRight
property alias scaleLeft: planetLeft.value
property alias scaleRight: planetRight.value
property alias spaceship: spaceship
property alias shuttle: shuttle
property alias shuttleMotion: shuttleMotion
property alias timer: timer
property alias arrow: arrow
property alias asteroidCreation: asteroidCreation
property GCSfx audioEffects: activity.audioEffects
property double distLeft: Math.abs(spaceshipX / ApplicationInfo.ratio)
property double distRight: Math.abs((background.width - spaceshipX) / ApplicationInfo.ratio)
property double forceLeft: (Math.pow(scaleLeft, 2) / Math.pow(distLeft, 2)) * Math.pow(10, 6)
property double forceRight: (Math.pow(scaleRight, 2) / Math.pow(distRight, 2)) * Math.pow(10, 6)
// the center value for the spaceship
property double spaceshipX
property double spaceshipY: parent.height / 2
}
onStart: Activity.start(items,message)
onStop: Activity.stop()
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level | reload }
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
onReloadClicked: Activity.initLevel()
}
Bonus {
id: bonus
Component.onCompleted: win.connect(Activity.nextLevel)
}
IntroMessage {
id: message
onIntroDone: {
items.timer.start()
items.asteroidCreation.start()
items.shuttleMotion.restart()
}
intro: [
qsTr("Gravity is universal and Newton's law of universal gravitation extends gravity"
+" beyond earth. This force of gravitational attraction is directly dependent"
+" upon the masses of both objects and inversely proportional to"
+" the square of the distance that separates their centers."),
qsTr("Since the gravitational force is directly proportional to the mass of both interacting "
+"objects, more massive objects will attract each other with a greater gravitational "
+"force. So as the mass of either object increases, the force of gravitational "
+"attraction between them also increases"),
qsTr("But this force is inversely proportional to the square of the separation distance "
+"between the two interacting objects, more separation distance will "
+"result in weaker gravitational forces."),
qsTr("Your goal is to let Tux's spaceship move by changing the mass "
+"of its surrounding planets. Don't get too close to the planets "
+"or you will crash on them. "
+"The arrow indicates the direction of the force on your ship."),
qsTr("Avoid the asteroid and join the space "
+"shuttle to win.")
]
z: 20
anchors {
top: parent.top
topMargin: 10
right: parent.right
rightMargin: 5
left: parent.left
leftMargin: 5
}
}
Planet {
id: planetLeft
x: 0
width: parent.width * 0.5
height: parent.height
planetSource: Activity.url + "saturn.svg"
planetWidth: 240 * ApplicationInfo.ratio
isLeft: true
}
Planet {
id: planetRight
x: parent.width / 2
width: parent.width * 0.5
height: parent.height
planetSource: Activity.url + "neptune.svg"
planetWidth: 184 * ApplicationInfo.ratio
isLeft: false
}
Image {
id: spaceship
source: Activity.url + "tux_spaceship.svg"
sourceSize.width: 120 * ApplicationInfo.ratio
x: items.spaceshipX - width / 2
y: items.spaceshipY - height / 2
}
// line to show force magnitude and direction
Image {
id: arrow
visible: !message.displayed && width > 6 && timer.running
x: items.forceLeft < items.forceRight ?
items.spaceshipX : items.spaceshipX - width
y: spaceship.y - 80
z: 11
sourceSize.width: 120 * 10 * ApplicationInfo.ratio
width: Math.min(background.width / 4, Math.abs(items.forceLeft - items.forceRight) * 6)
height: 40 * ApplicationInfo.ratio
source: Activity.url +"arrow.svg"
rotation: items.forceLeft > items.forceRight ? 0 : 180
Behavior on rotation {
NumberAnimation{ duration: 100 }
}
Behavior on width {
NumberAnimation{ duration: 100 }
}
}
Image {
id: shuttle
source: Activity.url + "space_shuttle.svg"
sourceSize.width: 80 * ApplicationInfo.ratio
z: 10
NumberAnimation {
id: shuttleMotion
target: shuttle
property: "y"
to: 0 - shuttle.height
duration: 40000 / (Activity.currentLevel+1)
}
}
Timer {
id: timer
interval: 16
running: false
repeat: true
onTriggered: {
Activity.moveSpaceship()
Activity.handleCollisionWithAsteroid()
}
}
Timer {
id: asteroidCreation
running: false
repeat: true
interval: 10200 - (bar.level * 200)
onTriggered: Activity.createAsteroid()
}
}
}
diff --git a/src/activities/intro_gravity/Planet.qml b/src/activities/intro_gravity/Planet.qml
index 341f8eeb5..70fcef276 100644
--- a/src/activities/intro_gravity/Planet.qml
+++ b/src/activities/intro_gravity/Planet.qml
@@ -1,123 +1,123 @@
/* GCompris - intro_gravity.qml
*
* Copyright (C) 2015 Siddhesh suthar <siddhesh.it@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> and Matilda Bernard (GTK+ version)
* Siddhesh suthar <siddhesh.it@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "intro_gravity.js" as Activity
Item {
id: planet
y: 0
property string planetSource
property int planetWidth
property alias value: planetImg.scale
property double minimumValue: 0.5
property double maximumValue: 2.2
property bool isLeft
Image {
id: planetImg
source: parent.planetSource
sourceSize.width: parent.planetWidth
x: parent.isLeft ? slider.x
: slider.x + slider.width - planet.planetWidth
y: background.height / 2 - height / 2
Behavior on scale {
NumberAnimation{ duration: 10 }
}
}
Image {
id: slider
source: Activity.url + "updown.svg"
sourceSize.width: 40 * ApplicationInfo.ratio
x: parent.isLeft ? 20 * ApplicationInfo.ratio :
parent.width - slider.width - 20 * ApplicationInfo.ratio
y: background.height / 2 - height / 2
}
MultiPointTouchArea {
id: touchArea
anchors.fill: parent
touchPoints: [ TouchPoint { id: point1 } ]
property real startX
property real startY
property bool started
property int direction: 0
onStartedChanged: started ? retouch.start() : retouch.stop()
onPressed: {
startX = point1.x
startY = point1.y
if(startY < parent.height / 2)
direction = 1
else
direction = -1
move()
started = true
}
function move() {
if(direction < 0 && planet.value > planet.minimumValue)
planet.value -= 0.1
else if(direction > 0 && planet.value < planet.maximumValue)
planet.value += 0.1
}
onUpdated: {
if(!started)
return false
var moveX = point1.x - startX
var moveY = point1.y - startY
// Find the direction with the most move
if(Math.abs(moveX) * ApplicationInfo.ratio > 10 &&
Math.abs(moveX) > Math.abs(moveY)) {
if(moveX > 10 * ApplicationInfo.ratio)
direction = 1
else if(moveX < -10 * ApplicationInfo.ratio)
direction = -1
} else if(Math.abs(moveY) * ApplicationInfo.ratio > 10 &&
Math.abs(moveX) < Math.abs(moveY)) {
if(moveY > 10 * ApplicationInfo.ratio)
direction = -1
else if(moveY < -10 * ApplicationInfo.ratio)
direction = 1
}
move()
}
onReleased: started = false
}
Timer {
id: retouch
interval: 10
repeat: true
onTriggered: touchArea.started ? touchArea.move() : touchArea.move()
}
}
diff --git a/src/activities/intro_gravity/intro_gravity.js b/src/activities/intro_gravity/intro_gravity.js
index a8d692cd1..2304011ec 100644
--- a/src/activities/intro_gravity/intro_gravity.js
+++ b/src/activities/intro_gravity/intro_gravity.js
@@ -1,218 +1,218 @@
/* GCompris - intro_gravity.js
*
* Copyright (C) 2015 Siddhesh suthar <siddhesh.it@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> and Matilda Bernard (GTK+ version)
* Siddhesh suthar <siddhesh.it@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
.import GCompris 1.0 as GCompris //for ApplicationInfo
.import "qrc:/gcompris/src/core/core.js" as Core
var url = "qrc:/gcompris/src/activities/intro_gravity/resource/"
var currentLevel = 0;
var numberOfLevel = 4;
// delta move
var move
//array of created asteroids
var asteroids = new Array;
var asteroidsErased = new Array;
var minDuration = 20000
var asteroidCounter
var items;
var message;
function start(items_,message_) {
items = items_
currentLevel = 0
message = message_
initLevel()
}
function stop() {
items.timer.stop()
items.asteroidCreation.stop()
items.shuttleMotion.stop()
destroyAsteroids(asteroids)
destroyAsteroids(asteroidsErased)
asteroidCounter = 0
}
function initLevel() {
items.bar.level = currentLevel + 1
stop()
items.scaleLeft = items.planetLeft.minimumValue + 0.2 * currentLevel
items.scaleRight = items.planetRight.minimumValue + 0.2 * currentLevel
items.spaceship.source = url + "tux_spaceship.svg"
items.spaceshipX = items.background.width / 2
move = 0
items.shuttle.x = Math.random() > 0.5 ?
items.background.width * 0.2 : items.background.width * 0.7
items.shuttle.y = items.background.height + items.shuttle.height
if(items.bar.level != 1) {
items.timer.start()
items.asteroidCreation.start()
items.shuttleMotion.restart()
message.index = -1
} else {
message.index = 0
}
}
function nextLevel() {
if(numberOfLevel <= ++currentLevel ) {
currentLevel = 0
}
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
initLevel();
}
function repositionObjectsOnWidthChanged(factor) {
if(items) {
initLevel()
}
for(var i = asteroids.length - 1; i >= 0 ; --i) {
var asteroid = asteroids[i];
}
}
function repositionObjectsOnHeightChanged(factor) {
if(items ) {
initLevel()
}
for(var i = asteroids.length - 1; i >= 0 ; --i) {
var asteroid = asteroids[i];
}
}
// functions to create and handle asteroids
function createAsteroid() {
var asteroidComponent = Qt.createComponent("qrc:/gcompris/src/activities/intro_gravity/Asteroid.qml");
var ImageUrl = url + "asteroid" + Math.floor( Math.random() * 5 ) + ".png"
var randomX = items.background.width * 0.2 +
Math.random() * (items.background.width - items.background.width * 0.4)
var fallDuration = minDuration - Math.floor(Math.random()* 1000 *(currentLevel+1))
var asteroid = asteroidComponent.createObject(
items.background,
{
"source" : ImageUrl,
"x": randomX,
"y": 50,
"fallDuration": fallDuration,
"scale": GCompris.ApplicationInfo.ratio
});
if(asteroid === null) {
console.log("error in creating the asteroid object")
}
asteroids.push(asteroid);
asteroid.startMoving()
asteroidCounter++
}
function destroyAsteroids(asteroids) {
for(var i = asteroids.length - 1; i >= 0 ; --i) {
var asteroid = asteroids[i];
// Remove the asteroid
asteroid.destroy()
// Remove the element from list
asteroids.splice(i,1)
}
}
function moveSpaceship() {
move += (items.forceRight - items.forceLeft) / 10000 * items.bar.level
items.spaceshipX += move
// Manage the crash case
if(items.spaceshipX < 200 * GCompris.ApplicationInfo.ratio)
crash()
else if(items.spaceshipX > items.background.width - 200 * GCompris.ApplicationInfo.ratio)
crash()
// Manage to get into shuttle
var shuttleY = items.shuttle.y + items.shuttle.height / 2
var shuttleX = items.shuttle.x + items.shuttle.width / 2
if(shuttleY > items.spaceshipY - items.spaceship.height / 2 &&
shuttleY < items.spaceshipY + items.spaceship.height / 2 &&
shuttleX > items.spaceshipX -items.spaceship.width / 2 &&
shuttleX < items.spaceshipX + items.spaceship.width / 2) {
items.bonus.good("flower")
items.spaceship.source = ""
stop()
}
}
function handleCollisionWithAsteroid() {
if(asteroids !== undefined) {
for(var i = asteroids.length -1 ; i >= 0 ; --i) {
var asteroid = asteroids[i];
var x = asteroid.x + asteroid.width / 2
var y = asteroid.y + asteroid.height / 2
if(y > items.background.height) {
asteroid.destroy()
asteroids.splice(i,1)
} else if(y > items.spaceshipY - items.spaceship.height / 2 &&
y < items.spaceshipY + items.spaceship.height / 2 &&
x > items.spaceshipX - items.spaceship.width / 2 &&
x < items.spaceshipX + items.spaceship.width / 2 ) {
asteroid.destroy()
asteroids.splice(i,1)
crash()
return
}
if(asteroidCounter == 4) {
items.bonus.good("flower")
stop()
return
}
}
}
}
function crash() {
items.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/crash.wav")
items.spaceship.source = url + "crash.svg"
stop()
}
diff --git a/src/activities/land_safe/Accelerometer.qml b/src/activities/land_safe/Accelerometer.qml
index d43781a64..58bf58a83 100644
--- a/src/activities/land_safe/Accelerometer.qml
+++ b/src/activities/land_safe/Accelerometer.qml
@@ -1,76 +1,76 @@
/* GCompris - Accelerometer.qml
*
* Copyright (C) 2016 Holger Kaelberer <holger.k@elberer.de>
*
* Authors:
* Holger Kaelberer <holger.k@elberer.de>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
Item {
id: root
property double max: 1
property double min: -1
property double current: min
property alias currentRect: currentRect.anchors
Rectangle {
id: rect
width: parent.width
height: parent.height
anchors.fill: parent
border.width: root.width / 10
border.color: "lightgray"
radius: root.width / 3
gradient: Gradient {
GradientStop { position: 0.0; color: "green" }
GradientStop { position: 1-(-root.min/(root.max-root.min)); color: "yellow" }
GradientStop { position: 1.0; color: "red" }
}
Rectangle {
id: baseline
height: 2
width: rect.width
anchors.left: rect.left
anchors.leftMargin: 0
anchors.bottom: rect.bottom
anchors.bottomMargin: -root.min/(root.max-root.min) * rect.height
color: "steelblue"
}
Rectangle {
id: currentRect
width: rect.width * 1.1
height: root.width / 10
anchors.left: rect.left
anchors.leftMargin: -rect.width * 0.05
anchors.bottom: rect.bottom
anchors.bottomMargin: Math.max(0, (-root.min + root.current)/(root.max-root.min) * rect.height - height)
color: "white"
Behavior on anchors.bottomMargin {
PropertyAnimation {
duration: 100
easing.type: Easing.InOutQuad
}
}
}
}
}
diff --git a/src/activities/land_safe/ActivityInfo.qml b/src/activities/land_safe/ActivityInfo.qml
index 4e86ba80a..79566b2c7 100644
--- a/src/activities/land_safe/ActivityInfo.qml
+++ b/src/activities/land_safe/ActivityInfo.qml
@@ -1,49 +1,49 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2016 Holger Kaelberer <holger.k@elberer.de>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "land_safe/LandSafe.qml"
difficulty: 4
icon: "land_safe/land_safe.svg"
author: "Matilda Bernard &lt;serah4291@gmail.com&gt; (Gtk+), Holger Kaelberer &lt;holger.k@elberer.de&gt; (Qt Quick)"
demo: true
//: Activity title
title: qsTr("Land Safe")
//: Help title
description: qsTr("Understanding acceleration due to gravity.")
// intro: "Use the arrow keys to pilot your spaceship safely onto the landing pad."
//: Help goal
goal: qsTr("Pilot the spaceship towards the green landing area.")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("Acceleration due to gravity experienced by the spaceship is directly proportional to the mass of the planet and inversely proportional to the square of the distance from the center of the planet. Thus, with every planet the acceleration will differ and as the spaceship comes closer and closer to the planet the acceleration increases.
Use the up/down keys to control the thrust and the right/left keys to control direction. On touch screens you can control the rocket through the corresponding on-screen buttons.
The accelerometer on the right border shows your rocket's overall vertical acceleration including gravitational force. In the upper green area of the accelerometer your acceleration is higher than the gravitational force, in the lower red area it's lower, and on the blue baseline in the yellow middle area the two forces cancel each other out.
In higher levels, you can use the right/left keys to rotate the spaceship. By rotating the spaceship you can trigger an acceleration in non-vertical direction using the up/down keys.
The landing platform is green if your speed is fine for a safe landing.")
credit: ""
section: "experiment"
- enabled: true //ApplicationInfo.hasShader
+ enabled: ApplicationInfo.isBox2DInstalled //ApplicationInfo.hasShader
createdInVersion: 6000
}
diff --git a/src/activities/land_safe/ControlButton.qml b/src/activities/land_safe/ControlButton.qml
index 68e7ed68e..f73d6c9bd 100644
--- a/src/activities/land_safe/ControlButton.qml
+++ b/src/activities/land_safe/ControlButton.qml
@@ -1,79 +1,79 @@
/* GCompris - ControlButton.qml
*
* Copyright (C) 2016 Holger Kaelberer <holger.k@elberer.de>
*
* Authors:
* Holger Kaelberer <holger.k@elberer.de>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
Image {
id: root
state: "notclicked"
sourceSize.width: 54 * ApplicationInfo.ratio
signal clicked
signal pressed
signal released
/** How much the mousearea should exceed the visible item on each border */
property double exceed: 0
MouseArea {
id: mouseArea
anchors.left: parent.left
anchors.leftMargin: -root.exceed
anchors.top: parent.top
anchors.topMargin: -root.exceed
width: root.width + 2*root.exceed
height: root.height + 2*root.exceed
hoverEnabled: !ApplicationInfo.isMobile
onClicked: root.clicked()
onPressed: root.pressed()
onReleased: root.released()
}
states: [
State {
name: "notclicked"
PropertyChanges {
target: root
scale: 1.0
}
},
State {
name: "clicked"
when: mouseArea.pressed
PropertyChanges {
target: root
scale: 0.9
}
},
State {
name: "hover"
when: mouseArea.containsMouse
PropertyChanges {
target: root
scale: 1.1
}
}
]
Behavior on scale { NumberAnimation { duration: 70 } }
// Behavior on opacity { PropertyAnimation { duration: 200 } }
}
diff --git a/src/activities/land_safe/LandSafe.qml b/src/activities/land_safe/LandSafe.qml
index f8670acb6..db6659ddf 100644
--- a/src/activities/land_safe/LandSafe.qml
+++ b/src/activities/land_safe/LandSafe.qml
@@ -1,770 +1,770 @@
/* GCompris - LandSafe.qml
*
* Copyright (C) 2016 Holger Kaelberer <holger.k@elberer.de>
*
* Authors:
* Matilda Bernard <serah4291@gmail.com> (GTK+ version)
* Holger Kaelberer <holger.k@elberer.de> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import Box2D 2.0
import QtQuick.Particles 2.0
import GCompris 1.0
import "../../core"
import "land_safe.js" as Activity
ActivityBase {
id: activity
property bool inForeground: false // to avoid unneeded reconfigurations
onStart: {
inForeground = true;
focus = true;
}
onStop: inForeground = false;
Keys.onPressed: Activity.processKeyPress(event)
Keys.onReleased: Activity.processKeyRelease(event)
onWidthChanged: if (inForeground)
Activity.initLevel();
onHeightChanged: if (inForeground)
Activity.initLevel();
pageComponent: Image {
id: background
source: Activity.baseUrl + "/background.svg";
anchors.centerIn: parent
anchors.fill: parent
fillMode: Image.PreserveAspectCrop
sourceSize.height: height
signal start
signal stop
function changeZoom(newZoom)
{
var dZoom = newZoom / items.zoom;
var curAltReal = Activity.getAltitudeReal();
items.world.pixelsPerMeter *= dZoom;
var altPx = curAltReal * items.world.pixelsPerMeter;
var rdy;
var rdx;
var ldx;
if (dZoom < 1) {
rdy = items.rocket.height*dZoom;
rdx = items.rocket.width*dZoom/2;
ldx = items.landing.width*dZoom/2;
} else {
rdy = -items.rocket.height/dZoom*2;
rdx = -items.rocket.width/dZoom;
ldx = -items.landing.width/dZoom;
}
items.rocket.y = Activity.pxAltitudeToY(altPx) + rdy;
items.rocket.x += rdx
items.landing.anchors.leftMargin += ldx;
items.zoom = newZoom;
if (dZoom < 1)
Activity.zoomStack.unshift(curAltReal);
else
Activity.zoomStack.shift();
}
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property alias background: background
property alias bar: bar
property alias bonus: bonus
property alias rocket: rocket
property alias explosion: explosion
property alias world: physicsWorld
property alias landing: landing
property alias ground: ground
property alias intro: intro
property alias ok: ok
property alias leftRightControl: leftRightControl
property alias upDownControl: upDownControl
property alias accelerometer: accelerometer
property var rocketCategory: Fixture.Category1
property var groundCategory: Fixture.Category2
property var landingCategory: Fixture.Category3
property string mode: "rotate" // "simple"
property double velocity: 0.0
property double altitude: 0.0
property double fuel: 100
property double lastVelocity: 0.0
property double gravity: 0.0
property double scale: background.height / 400
property double zoom: 1.0
property bool onScreenControls: /* items.world.running && */ ApplicationInfo.isMobile
}
onStart: { Activity.start(items) }
onStop: { Activity.stop() }
World {
id: physicsWorld
running: false;
gravity: Qt.point(0, items.gravity)
autoClearForces: false
//timeStep: 1.0/60.0 // default: 60Hz
onStepped: {
if (Math.abs(rocket.body.linearVelocity.y) > 0.01) // need to store velocity before it is aaaalmost 0 because of ground/landing contact
items.lastVelocity = items.velocity;
items.velocity = rocket.body.linearVelocity.y;
if (rocket.body.linearVelocity.y > Activity.maxLandingVelocity)
landing.overlayColor = "-r" // redish
else if (explosion.visible == true)
landing.overlayColor = "-r"
else if (rocket.body.linearVelocity.y > Activity.maxLandingVelocity - 2)
landing.overlayColor = "-y" // yellowish
else
landing.overlayColor = "-g" // greenish
items.altitude = Math.max(0, Math.round(Activity.getAltitudeReal()));
if (Activity.maxFuel != -1) {
// update fuel:
var dt = timeStep;
var dFuel = -(dt * (items.rocket.accel + items.rocket.leftAccel
+ items.rocket.rightAccel));
Activity.currentFuel = Math.max(0, Activity.currentFuel + dFuel);
items.fuel = Math.round(Activity.currentFuel / Activity.maxFuel * 100);
if (Activity.currentFuel === 0) // fuel consumed
items.rocket.accel = items.rocket.leftAccel = items.rocket.rightAccel = 0;
} else
items.fuel = 100;
if (items.rocket.x > background.width)
items.rocket.x = -items.rocket.width;
if (items.rocket.x < -items.rocket.width)
items.rocket.x = background.width;
if (items.rocket.y < 0)
background.changeZoom(items.zoom / 2);
else if (Activity.zoomStack.length > 0 && items.altitude < Activity.zoomStack[0]-1)
background.changeZoom(items.zoom * 2);
}
}
MouseArea {
id: mouse
anchors.fill: parent
onClicked: debugDraw.visible = !debugDraw.visible;
enabled: Activity.debugDraw
}
Item {
id: rocket
property double accel: 0.0
property double leftAccel: 0.0
property double rightAccel: 0.0
property alias body: rocketBody
function show() {
opacity = 100;
}
function hide() {
opacity = 0;
}
Behavior on opacity {
NumberAnimation {
duration: 500
easing.type: Easing.InExpo
}
}
//property float rotate
rotation: 0
width: items.scale * 28 * items.zoom// * ApplicationInfo.ratio
height: width / 232 * 385
x: 300
y: 50
z: 4
// Component.onCompleted: rocket.body.applyForceToCenter(Qt.point(0, 5));
onAccelChanged: applyForces();
onLeftAccelChanged: applyForces();
onRightAccelChanged: applyForces();
onRotationChanged: if (accel > 0) // should only happen in
applyForces(); // "rotation" mode
// decompose a force/acceleration vector v using angle into x/y components
function decomposeVector(v, angle) {
return Qt.point(v * Math.sin(Activity.degToRad(angle)), // x-component
v * Math.cos(Activity.degToRad(items.rocket.rotation))); // y-component
}
// map acceleration to box2d forces applying appropriate factors:
function applyForces()
{
var totForce = (accel / 0.5 * 5)
var v;
if (items.mode === "simple")
v = Qt.point((leftAccel-rightAccel)
* 10 /* base of 10 m/s^2 */
* 5, /* factor to make movement smooth */
-totForce
);
else { // "rotation"
v = decomposeVector(totForce, rotation);
v.y = -v.y;
}
v.x *= items.rocket.body.getMass();
v.y *= items.rocket.body.getMass();
physicsWorld.clearForces();
items.rocket.body.applyForceToCenter(v);
// console.log("XXX rocket.acc=" + rocket.accel + " acc.current=" + items.accelerometer.current + " bottomMargin=" + items.accelerometer.currentRect.bottomMargin);
}
Image {
id: rocketImage
sourceSize.width: 1024
source: Activity.baseUrl + "/rocket.svg"
anchors.centerIn: parent
anchors.fill: parent
z: 4
mipmap: true
}
Body {
id: rocketBody
target: rocket
bodyType: Body.Dynamic
sleepingAllowed: false
fixedRotation: true
linearDamping: 0
property double rotation: Activity.degToRad(rocket.rotation % 360)
fixtures: Box {
id: rocketFixture
categories: items.rocketCategory
collidesWith: items.groundCategory | items.landingCategory
density: 1
friction: 0
restitution: 0
width: rocket.width
height: rocket.height
rotation: rocketBody.rotation
onBeginContact: {
//console.log("XXX beginning contact with " + other.getBody().target.collisionName + " abs v=" + Math.abs(items.lastVelocity) + + " maxV=" + Activity.maxLandingVelocity);
if (other.getBody().target === landing &&
Math.abs(items.lastVelocity) <= Activity.maxLandingVelocity &&
(items.mode === "simple" || rocket.rotation%360 === 0))
Activity.finishLevel(true);
else // ground
Activity.finishLevel(false); // crash
}
// onEndContact: console.log("XXX ending contact with " + other.getBody().target.collisionName);
}
}
Image {
id: softLeftEngine
source: Activity.baseUrl + "/engine.svg"
rotation: 90
anchors.right: parent.left
anchors.verticalCenter: parent.verticalCenter
width: rocket.leftAccel > 0 ?
rocket.width * 0.2 + rocket.width * rocket.leftAccel : 0
height: width * 2 + width * rocket.leftAccel
sourceSize.width: width
sourceSize.height: height
visible: ApplicationInfo.useOpenGL ? false : true
}
ParticleSystem {
id: leftEngine
anchors.left: parent.left
anchors.leftMargin: 10
anchors.verticalCenter: parent.verticalCenter
height: 30
ImageParticle {
groups: ["flameLeft"]
source: "qrc:///particleresources/glowdot.png"
color: "#11ff400f"
colorVariation: 0.1
}
Emitter {
anchors.centerIn: parent
group: "flameLeft"
emitRate: (rocket.leftAccel > 0 ? 50 * items.scale / 1.9 : 0) * items.zoom // 50
lifeSpan: (rocket.leftAccel > 0 ? 600 * items.scale / 1.9 : 0) * items.zoom // 600
size: rocket.leftAccel > 0 ? leftEngine.height : 0
endSize: 5
sizeVariation: 3
acceleration: PointDirection { x: -40 }
velocity: PointDirection { x: -40 }
}
}
Image {
id: softRightEngine
source: Activity.baseUrl + "/engine.svg"
rotation: -90
anchors.left: parent.right
anchors.verticalCenter: parent.verticalCenter
width: rocket.rightAccel > 0 ?
rocket.width * 0.2 + rocket.width * rocket.rightAccel : 0
height: width * 2 + width * rocket.rightAccel
sourceSize.width: width
sourceSize.height: height
visible: ApplicationInfo.useOpenGL ? false : true
}
ParticleSystem {
id: rightEngine
anchors.right: parent.right
anchors.rightMargin: 10
anchors.verticalCenter: parent.verticalCenter
height: 30
ImageParticle {
groups: ["flameRight"]
source: "qrc:///particleresources/glowdot.png"
color: "#11ff400f"
colorVariation: 0.1
}
Emitter {
anchors.centerIn: parent
group: "flameRight"
emitRate: (rocket.rightAccel > 0 ? 50 * items.scale / 1.9 : 0) * items.zoom // 50
lifeSpan: (rocket.rightAccel > 0 ? 600 * items.scale / 1.9 : 0) * items.zoom // 600
size: rocket.rightAccel > 0 ? rightEngine.height : 0
endSize: 5
sizeVariation: 3
acceleration: PointDirection { x: 40 }
velocity: PointDirection { x: 40 }
}
}
Image {
id: softBottomEngine
source: Activity.baseUrl + "/engine.svg"
anchors.top: parent.bottom
anchors.topMargin: -5 * ApplicationInfo.ratio
anchors.horizontalCenter: parent.horizontalCenter
width: rocket.width * 0.5 + rocket.width * rocket.accel
height: rocket.accel > 0 ? width * 2 : 0
sourceSize.width: width
sourceSize.height: height
visible: ApplicationInfo.useOpenGL ? false : true
}
ParticleSystem {
id: bottomEngine
anchors.top: parent.bottom
anchors.topMargin: 5
anchors.horizontalCenter: parent.horizontalCenter
width: rocket.width
ImageParticle {
groups: ["flame"]
source: "qrc:///particleresources/glowdot.png"
color: "#11ff400f"
colorVariation: 0.1
}
Emitter {
anchors.centerIn: parent
group: "flame"
emitRate: (rocket.accel > 0 ? (80 + 60 * rocket.accel) : 0) * items.zoom // 75-150
lifeSpan: ((700 + 450 * rocket.accel) * items.scale / 2.5) * items.zoom // 500 - 1000
size: rocket.width/1.8 + rocket.width/2*rocket.accel // width*-0.5 - width
endSize: size/1.85
sizeVariation: 5
acceleration: PointDirection { y: 80 }
velocity: PointDirection { y: 80 }
}
}
}
ParticleSystem {
id: explosion
anchors.centerIn: rocket
width: rocket.width
z: 5
ImageParticle {
groups: ["flame"]
source: "qrc:///particleresources/glowdot.png"
color: "#11ff400f"
colorVariation: 0.1
}
Emitter {
anchors.centerIn: parent
group: "flame"
emitRate: 75 // 75-150
lifeSpan: 300 // 500 - 1000
size: rocket.width * 3 // width*-0.5 - width
endSize: 0
sizeVariation: 5
acceleration: PointDirection { x: 0 }
velocity: PointDirection { x: 0 }
}
Timer {
id: timer0
interval: 600; running: false; repeat: false
onTriggered: explosion.opacity = 0
}
function show() {
visible = true;
opacity = 100
scale = 1;
timer0.running = true
}
function hide() {
visible = false;
scale = 0;
timer0.running = false
}
Behavior on opacity {
NumberAnimation {
duration: 300
easing.type: Easing.InExpo
}
}
}
Image {
id: ground
z: 1
width: parent.width
height: parent.height/7
sourceSize.width: width
sourceSize.height: height
source: Activity.baseUrl + "/ground.svg"
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
readonly property string collisionName: "ground"
property int surfaceOffset: height/2
Body {
id: groundBody
target: ground
bodyType: Body.Static
sleepingAllowed: true
fixedRotation: true
linearDamping: 0
fixtures: Box {
id: groundFixture
categories: items.groundCategory
collidesWith: items.rocketCategory
density: 1
friction: 0
restitution: 0
width: ground.width
height: ground.height - ground.surfaceOffset
x: 0
y: ground.surfaceOffset
}
}
}
Image {
id: landing
readonly property string collisionName: "landing"
property int surfaceOffset: landing.height * 0.8
property string overlayColor: "-g"
z: 2
source: Activity.baseUrl + "/landing" + overlayColor + ".svg";
anchors.left: ground.left
anchors.leftMargin: 270
anchors.top: ground.top
anchors.topMargin: ground.surfaceOffset - height
width: 66 * items.scale * items.zoom
height: width / 7 * 2
Body {
id: landingBody
target: landing
bodyType: Body.Static
sleepingAllowed: true
fixedRotation: true
linearDamping: 0
fixtures: Box {
id: landingFixture
categories: items.landingCategory
collidesWith: items.rocketCategory
density: 1
friction: 0
restitution: 0
width: landing.width
height: landing.height - landing.surfaceOffset
y: landing.surfaceOffset
}
}
}
Item {
id: osdWrapper
anchors.right: background.right
anchors.rightMargin: 10 * ApplicationInfo.ratio
anchors.bottom: upDownControl.bottom
anchors.bottomMargin: -(planetText.height + gravityText.height + 20 * ApplicationInfo.ratio)
width: 200
height: background.height
z: 2
GCText {
id: fuelText
anchors.right: parent.right
anchors.bottom: altitudeText.top
anchors.bottomMargin: 10
color: "white"
fontSize: tinySize
horizontalAlignment: Text.AlignRight
text: qsTr("Fuel: %1").arg(items.fuel)
}
GCText {
id: altitudeText
anchors.right: parent.right
anchors.bottom: velocityText.top
anchors.bottomMargin: 10
color: "white"
fontSize: tinySize
horizontalAlignment: Text.AlignRight
text: qsTr("Altitude: %1").arg(items.altitude)
}
GCText {
id: velocityText
anchors.right: parent.right
// anchors.rightMargin: 10 * ApplicationInfo.ratio
anchors.bottom: accelText.top
anchors.bottomMargin: 10
color: "white"
fontSize: tinySize
horizontalAlignment: Text.AlignRight
text: qsTr("Velocity: %1").arg(Math.round(items.velocity * 10) / 10)
}
GCText {
id: accelText
anchors.bottom: accelerometer.top
anchors.bottomMargin: 10 * ApplicationInfo.ratio
anchors.right: parent.right
fontSize: tinySize
// width: 50
// height: 50
color: "white"
horizontalAlignment: Text.AlignRight
text: qsTr("Acceleration: %1").arg(Math.round(accelerometer.current * 100) / 100)
}
Accelerometer {
id: accelerometer
current: rocket.decomposeVector(rocket.accel, rocket.rotation).y * 10 - items.gravity
anchors.right: parent.right
anchors.bottom: gravityText.top
anchors.bottomMargin: 10 * ApplicationInfo.ratio
// anchors.bottom: upDownControl.bottom
// anchors.bottomMargin: upDownControl.bottomMargin
width: 15 + 3 * items.scale * ApplicationInfo.ratio
height: background.height / 2.5
z: 2 // on top of rocket and ground
opacity: 1
}
GCText {
id: gravityText
anchors.bottom: planetText.top
anchors.bottomMargin: 10 * ApplicationInfo.ratio
anchors.right: parent.right
horizontalAlignment: Text.AlignRight
fontSize: tinySize
color: "white"
text: qsTr("Gravity: %1").arg(Math.round(items.gravity * 100) / 100);
}
GCText {
id: planetText
anchors.right: parent.right
anchors.bottom: parent.bottom
color: "white"
fontSize: tinySize
horizontalAlignment: Text.AlignRight
text: Activity.levels[bar.level-1].planet
}
}
Column {
id: upDownControl
anchors.right: background.right
anchors.rightMargin: accelerometer.width
anchors.bottom: bar.top
anchors.bottomMargin: 10 * ApplicationInfo.ratio
width: upButton.width + 20 * ApplicationInfo.ratio
height: upButton.height + downButton.height + 20 * ApplicationInfo.ratio
visible: items.onScreenControls
z: 19 // below intro, above the rest
opacity: 0.4
spacing: 20 * ApplicationInfo.ratio
ControlButton {
id: upButton
source: Activity.baseUrl + "/arrow_up.svg"
onPressed: Activity.processKeyPress({key: Qt.Key_Up});
exceed: upDownControl.spacing / 2
}
ControlButton {
id: downButton
source: Activity.baseUrl + "/arrow_down.svg"
onPressed: Activity.processKeyPress({key: Qt.Key_Down});
exceed: upDownControl.spacing / 2
}
}
Row {
id: leftRightControl
anchors.left: parent.left
anchors.leftMargin: 10 * ApplicationInfo.ratio
anchors.bottom: bar.top
anchors.bottomMargin: 10 * ApplicationInfo.ratio
width: leftButton.width + rightButton.width + 20 * ApplicationInfo.ratio
height: leftButton.height + 10 * ApplicationInfo.ratio
visible: items.onScreenControls
z: 19 // below intro, on top of the rest
opacity: 0.4
spacing: 20 * ApplicationInfo.ratio
ControlButton {
id: leftButton
source: Activity.baseUrl + "/arrow_left.svg"
onPressed: Activity.processKeyPress({key: Qt.Key_Left});
onReleased: Activity.processKeyRelease({key: Qt.Key_Left});
exceed: leftRightControl.spacing / 2
}
ControlButton {
id: rightButton
source: Activity.baseUrl + "/arrow_right.svg"
onPressed: Activity.processKeyPress({key: Qt.Key_Right});
onReleased: Activity.processKeyRelease({key: Qt.Key_Right});
exceed: leftRightControl.spacing / 2
}
}
DebugDraw {
id: debugDraw
world: physicsWorld
visible: false
z: 1
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
z: 21
content: BarEnumContent { value: help | home | level }
onHelpClicked: {
Activity.initLevel();
displayDialog(dialogHelp);
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
}
Bonus {
id: bonus
Component.onCompleted: {
loose.connect(Activity.initLevel);
win.connect(Activity.nextLevel)
}
}
IntroMessage {
id: intro
onIntroDone: {
items.world.running = true;
}
z: 20
anchors {
top: parent.top
topMargin: 10
right: parent.right
rightMargin: 5
left: parent.left
leftMargin: 5
}
}
BarButton {
id: ok
source: "qrc:/gcompris/src/core/resource/bar_ok.svg";
sourceSize.width: 75 * ApplicationInfo.ratio
visible: false
anchors.centerIn: background
onClicked: {
visible = false;
items.world.running = true;
}
}
}
}
diff --git a/src/activities/land_safe/land_safe.js b/src/activities/land_safe/land_safe.js
index ca6055745..43cffb010 100644
--- a/src/activities/land_safe/land_safe.js
+++ b/src/activities/land_safe/land_safe.js
@@ -1,314 +1,314 @@
/* GCompris - land_safe.js
*
* Copyright (C) 2016 Holger Kaelberer <holger.k@elberer.de>
*
* Authors:
* Matilda Bernard <serah4291@gmail.com> (GTK+ version)
* Holger Kaelberer <holger.k@elberer.de> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
/* ToDo:
* - check for shader availability
* - test more generic on-screen controls
* (- use polygon fixture for rocket)
*
* Some gravitational forces:
* !- Ceres 0,27
* !- Pluto: 0,62 m/s²
* !- Titan: 1,352 m/s²
* - Ganymed: 1,428
* !- Moon: 1,622 m/s²
* - Io: 1,796 m/s²
* !- Mars: 3,711 m/s²
* - Merkur: 3,7 m/s²
* !- Venus: 8,87 m/s²
* !- Earth: 9,807 m/s²
* - Jupiter: 24,79 m/s²
*/
.pragma library
.import QtQuick 2.6 as Quick
.import GCompris 1.0 as GCompris
var levels = [
/** simple **/
{ "planet": qsTr("Ceres"), "gravity": 0.27, "maxAccel": 0.054,
"accelSteps": 2, "alt": 75.0 , "mode": "simple",
"fuel" : -1 },
{ "planet": qsTr("Pluto"), "gravity": 0.62, "maxAccel": 0.186,
"accelSteps": 3, "alt": 100.0, "mode": "simple",
"fuel" : -1 },
{ "planet": qsTr("Titan"), "gravity": 1.352, "maxAccel": 0.406,
"accelSteps": 3, "alt": 100.0, "mode": "simple",
"fuel" : -1 },
{ "planet": qsTr("Moon"), "gravity": 1.622, "maxAccel": 0.324,
"accelSteps": 4, "alt": 150.0, "mode": "simple",
"fuel" : 10 },
{ "planet": qsTr("Mars"), "gravity": 3.711, "maxAccel": 0.619,
"accelSteps": 5, "alt": 200.0, "mode": "simple",
"fuel" : 20 },
{ "planet": qsTr("Venus"), "gravity": 8.87, "maxAccel": 1.331,
"accelSteps": 6, "alt": 300.0, "mode": "simple",
"fuel" : 70 },
{ "planet": qsTr("Earth"), "gravity": 9.807, "maxAccel": 1.373,
"accelSteps": 7, "alt": 350.0, "mode": "simple",
"fuel" : 70 },
/** rotation **/
{ "planet": qsTr("Ceres"), "gravity": 0.27, "maxAccel": 0.054,
"accelSteps": 2, "alt": 75.0 , "mode": "rotation",
"fuel" : -1 },
{ "planet": qsTr("Pluto"), "gravity": 0.62, "maxAccel": 0.186,
"accelSteps": 3, "alt": 100.0, "mode": "rotation",
"fuel" : -1 },
{ "planet": qsTr("Titan"), "gravity": 1.352, "maxAccel": 0.406,
"accelSteps": 3, "alt": 100.0, "mode": "rotation",
"fuel" : -1 },
{ "planet": qsTr("Moon"), "gravity": 1.62, "maxAccel": 0.324,
"accelSteps": 4, "alt": 150.0, "mode": "rotation",
"fuel" : 10 },
{ "planet": qsTr("Mars"), "gravity": 3.71, "maxAccel": 0.619,
"accelSteps": 5, "alt": 200.0, "mode": "rotation",
"fuel" : 20 },
{ "planet": qsTr("Venus"), "gravity": 8.87, "maxAccel": 1.331,
"accelSteps": 5, "alt": 300.0, "mode": "rotation",
"fuel" : 70 },
{ "planet": qsTr("Earth"), "gravity": 9.807, "maxAccel": 1.373,
"accelSteps": 7, "alt": 350.0, "mode": "rotation",
"fuel" : 70 }
];
var introTextSimple = qsTr("Use the up and down keys to control the thrust."
+ "<br/>Use the right and left keys to control direction."
+ "<br/>You must drive Tux's ship towards the landing platform."
+ "<br/>The landing platform turns green when the velocity is safe to land.")
var introTextRotate = qsTr("The up and down keys control the thrust of the rear engine."
+ "<br/>The right and left keys now control the rotation of the ship."
+ "<br/>To move the ship in horizontal direction you must first rotate and then accelerate it.")
var currentLevel = 0;
var numberOfLevel;
var items = null;
var baseUrl = "qrc:/gcompris/src/activities/land_safe/resource";
var startingAltitudeReal = 100.0;
var startingOffsetPx = 10; // y-value for setting rocket initially
var maxLandingVelocity = 10;
var leftRightAccel = 0.1; // accel force set on horizontal accel
//var minAccel = 0.1;
var maxAccel = 0.15;
var accelSteps = 3;
var dAccel = maxAccel / accelSteps;//- minAccel;
var barAtStart;
var maxFuel = 100.0;
var currentFuel = 0.0;
var lastLevel = -1;
var debugDraw = false;
var zoomStack = new Array;
function start(items_) {
items = items_;
currentLevel = 0;
lastLevel = -1;
numberOfLevel = levels.length;
barAtStart = GCompris.ApplicationSettings.isBarHidden;
GCompris.ApplicationSettings.isBarHidden = true;
initLevel()
}
function stop() {
GCompris.ApplicationSettings.isBarHidden = barAtStart;
}
function initLevel() {
if (items === null)
return;
items.bar.level = currentLevel + 1
items.zoom = 1;
zoomStack = [];
// init level:
items.accelerometer.min = -levels[currentLevel].gravity;
items.accelerometer.max = levels[currentLevel].maxAccel*10-levels[currentLevel].gravity;
maxAccel = levels[currentLevel].maxAccel;
accelSteps = levels[currentLevel].accelSteps;
dAccel = maxAccel / accelSteps;//- minAccel;
startingAltitudeReal = levels[currentLevel].alt;
items.gravity = levels[currentLevel].gravity;
items.mode = levels[currentLevel].mode;
maxFuel = levels[currentLevel].fuel;
currentFuel = (maxFuel == -1 ? 1 : maxFuel); // -1 means unlimited fuel
// reset everything:
items.explosion.hide();
items.rocket.show();
// place rocket randomly:
var max = items.background.width - items.accelerometer.width - items.landing.width - items.rocket.width;
var min = 20;
items.rocket.x = Math.random() * (max- min) + min;
items.rocket.y = startingOffsetPx;
items.rocket.rotation = 0;
items.rocket.accel = 0;
items.rocket.leftAccel = 0;
items.rocket.rightAccel = 0;
items.rocket.body.linearVelocity = Qt.point(0,0)
// for landing random placement shall not intersect with bar -- or osd
// controls on mobile:
min = items.onScreenControls ? items.leftRightControl.width : items.bar.fullButton * items.bar.barZoom;
max = items.onScreenControls ? items.background.width - items.upDownControl.width - items.landing.width : max;
items.landing.anchors.leftMargin = Math.random() * (max- min) + min;
items.landing.overlayColor = "-g";
// initialize world:
items.world.pixelsPerMeter = pxYToAltitude(items.rocket.y) / startingAltitudeReal;
items.world.gravity = Qt.point(0, items.gravity)
items.world.running = false;
// console.log("Starting level (surfaceOff=" + items.ground.surfaceOffset + ", ppm=" + items.world.pixelsPerMeter + ")");
if (currentLevel === 0 && lastLevel !== 0) {
items.ok.visible = false;
items.intro.intro = [introTextSimple];
items.intro.index = 0;
} else if (currentLevel === levels.length / 2 && lastLevel !== 0) {
items.ok.visible = false;
items.intro.intro = [introTextRotate];
items.intro.index = 0;
} else {
// go
items.intro.index = -1;
items.ok.visible = true;
}
lastLevel = currentLevel;
}
function pxAltitudeToY(alt)
{
var y = items.background.height - items.ground.height + items.ground.surfaceOffset
- items.rocket.height - 1 - alt;
return y;
}
function pxYToAltitude(y)
{
var altPx = items.background.height - items.ground.height + items.ground.surfaceOffset
- y - items.rocket.height
- 1; // landing is 1 pixel above ground surface
return altPx;
}
// calc real height of rocket in meters above surface
function getAltitudeReal()
{
var altPx = pxYToAltitude(items.rocket.y);
var altReal = altPx / items.world.pixelsPerMeter;
return altReal;
}
function nextLevel() {
if(numberOfLevel <= ++currentLevel ) {
currentLevel = 0
}
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
initLevel();
}
function processKeyPress(event)
{
var key = event.key;
event.accepted = true;
if (!items.world.running) {
return;
}
var newAccel = 0;
if (key === Qt.Key_Up || key === Qt.Key_Down) {
if (key === Qt.Key_Up) {
if (items.rocket.accel === 0)
newAccel = dAccel;
else
newAccel = items.rocket.accel + dAccel;
} else if (key === Qt.Key_Down)
newAccel = items.rocket.accel - dAccel;
if (newAccel < 0)
newAccel = 0;
if (newAccel > maxAccel)
newAccel = maxAccel;
if (newAccel !== items.rocket.accel && currentFuel > 0)
items.rocket.accel = newAccel;
} else if (key === Qt.Key_Right || key === Qt.Key_Left) {
if (items.mode === "simple") {
if (key === Qt.Key_Right && !event.isAutoRepeat && currentFuel > 0) {
items.rocket.leftAccel = leftRightAccel;
items.rocket.rightAccel = 0.0;
} else if (key === Qt.Key_Left && !event.isAutoRepeat && currentFuel > 0) {
items.rocket.rightAccel = leftRightAccel;
items.rocket.leftAccel = 0.0;
}
} else { // "rotation"
if (key === Qt.Key_Right)
items.rocket.rotation += 10;
else if (key === Qt.Key_Left)
items.rocket.rotation -= 10;
//console.log("XXX rotation=" + items.rocket.rotation + " bodyRot=" + items.rocket.body.rotation);
}
}
}
function processKeyRelease(event)
{
if (!items.world.running) {
event.accepted = false;
return;
}
var key = event.key;
event.accepted = true;
//console.log("XXX release " + key + " = " + event.isAutoRepeat + " = " + Qt.Key_Right);
if (key === Qt.Key_Right && !event.isAutoRepeat) {
items.rocket.leftAccel = 0;
} else if (key === Qt.Key_Left && !event.isAutoRepeat) {
items.rocket.rightAccel = 0;
} else
event.accepted = false;
}
function finishLevel(success)
{
items.rocket.accel = 0;
items.rocket.leftAccel = 0;
items.rocket.rightAccel = 0;
items.rocket.body.linearVelocity = Qt.point(0,0)
if (success)
items.bonus.good("lion");
else {
items.explosion.show();
items.rocket.hide();
items.bonus.bad("lion");
}
}
function degToRad(degrees) {
return degrees * Math.PI / 180;
}
diff --git a/src/activities/lang/ActivityInfo.qml b/src/activities/lang/ActivityInfo.qml
index 942d78d6b..dd3be82c5 100644
--- a/src/activities/lang/ActivityInfo.qml
+++ b/src/activities/lang/ActivityInfo.qml
@@ -1,49 +1,48 @@
/* GCompris - lang.qml
*
* Copyright (C) Siddhesh suthar <siddhesh.it@gmail.com> (Qt Quick port)
*
* Authors:
* Pascal Georges (pascal.georges1@free.fr) (GTK+ version)
* Holger Kaelberer <holger.k@elberer.de> (Qt Quick port of imageid)
* Siddhesh suthar <siddhesh.it@gmail.com> (Qt Quick port)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Integration Lang dataset)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "lang/Lang.qml"
difficulty: 4
icon: "lang/lang.svg"
author: "siddhesh suthar &lt;siddhesh.it@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Enrich your vocabulary")
//: Help title
description: qsTr("Complete language learning activities.")
// intro: "Select the language you want to learn then review the words before doing the exercises."
//: Help goal
goal: qsTr("Enrich your vocabulary in your native language or in a foreign one.")
//: Help prerequisite
prerequisite: qsTr("Reading")
//: Help manual
manual: qsTr("Review a set of words. Each word is shown with a voice, a text and an image.<br/>"
+ "When done, you are suggested an exercise in which, given the voice, "
+ "you must find the right word. In the configuration, you can select the language you want to learn.")
- credit: qsTr("The images and voices come from the Art4Apps project: http://www.art4apps.org/.<br>"
- + "You can also access this activity online on http://gcompris.net/activity/lang.")
+ credit: qsTr("The images and voices come from the Art4Apps project: http://www.art4apps.org/.")
section: "reading"
createdInVersion: 5000
}
diff --git a/src/activities/lang/ImageReview.qml b/src/activities/lang/ImageReview.qml
index c59e7836d..4272b4780 100644
--- a/src/activities/lang/ImageReview.qml
+++ b/src/activities/lang/ImageReview.qml
@@ -1,421 +1,416 @@
/* GCompris - lang.qml
*
* Copyright (C) Siddhesh suthar <siddhesh.it@gmail.com> (Qt Quick port)
*
* Authors:
* Pascal Georges (pascal.georges1@free.fr) (GTK+ version)
* Holger Kaelberer <holger.k@elberer.de> (Qt Quick port of imageid)
* Siddhesh suthar <siddhesh.it@gmail.com> (Qt Quick port)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Integration Lang dataset)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import QtGraphicalEffects 1.0
import "../../core"
import "lang.js" as Activity
import "qrc:/gcompris/src/core/core.js" as Core
Item {
id: imageReview
anchors.fill: parent
property alias category: categoryText.text
property int wordListIndex // This is the current sub list of words
property var word: rootItem.opacity == 1 ? items.wordList[wordListIndex][score.currentSubLevel - 1] : undefined
// miniGames is list of miniGames
// first element is Activity name,
// second element is mode of miniGame
// third element is the qml to load
property var miniGames: [
["QuizActivity", 1, "Quiz.qml"],
["QuizActivity", 2, "Quiz.qml"],
["QuizActivity", 3, "Quiz.qml"],
["SpellActivity", 1, "SpellIt.qml"]
]
property var currentMiniGame
property var loadedItems
property bool started: rootItem.opacity == 1
// Start at last wordListIndex
function start() {
initLevel(wordListIndex)
}
// Start the image review at wordList sublesson
function initLevel(wordListIndex_) {
wordListIndex = wordListIndex_
score.currentSubLevel = 1
score.numberOfSubLevels = items.wordList[wordListIndex].length
focus = true
forceActiveFocus()
miniGameLoader.source = ""
currentMiniGame = -1
rootItem.opacity = 1
}
function stop() {
focus = false
rootItem.opacity = 0
wordImage.changeSource('')
wordText.changeText('')
repeatItem.visible = false
}
onWordChanged: {
if(word) {
if (Activity.playWord(word.voice)) {
word['hasVoice'] = true
repeatItem.visible = true
} else {
word['hasVoice'] = false
repeatItem.visible = false
}
wordImage.changeSource(word.image)
wordText.changeText(word.translatedTxt)
}
}
// Cheat codes to access mini games directly
Keys.onPressed: {
if((event.modifiers & Qt.ControlModifier) && (event.key === Qt.Key_1)) {
initLevel(wordListIndex)
event.accepted = true
}
if((event.modifiers & Qt.ControlModifier) && (event.key === Qt.Key_2)) {
startMiniGame(0)
event.accepted = true
}
if((event.modifiers & Qt.ControlModifier) && (event.key === Qt.Key_3)) {
startMiniGame(1)
event.accepted = true
}
if((event.modifiers & Qt.ControlModifier) && (event.key === Qt.Key_4)) {
startMiniGame(2)
event.accepted = true
}
if((event.modifiers & Qt.ControlModifier) && (event.key === Qt.Key_5)) {
startMiniGame(3)
event.accepted = true
}
}
Keys.onEscapePressed: {
Activity.launchMenuScreen()
}
Keys.onLeftPressed: {
if( score.currentSubLevel > 1 ) {
imageReview.prevWord()
event.accepted = true
}
}
Keys.onRightPressed: {
imageReview.nextWord()
event.accepted = true
}
Keys.onSpacePressed: {
imageReview.nextWord()
event.accepted = true
}
Keys.onEnterPressed: {
imageReview.nextWord()
event.accepted = true
}
Keys.onReturnPressed: {
imageReview.nextWord()
event.accepted = true
}
Keys.onReleased: {
if (event.key === Qt.Key_Back) {
event.accepted = true
Activity.launchMenuScreen()
}
}
Item {
id: rootItem
anchors.fill: parent
opacity: 0
Behavior on opacity { PropertyAnimation { duration: 200 } }
Rectangle {
id: categoryTextbg
parent: rootItem
x: categoryText.x - 4
y: categoryText.y - 4
width: imageFrame.width + 8
height: categoryText.height + 8
color: "#5090ff"
border.color: "#000000"
border.width: 2
radius: 16
anchors {
horizontalCenter: parent.horizontalCenter
top: rootItem.top
topMargin: 4 * ApplicationInfo.ratio
}
GCText {
id: categoryText
fontSize: mediumSize
font.weight: Font.DemiBold
width: parent.width - 8
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
color: "white"
wrapMode: Text.WordWrap
}
}
Image {
id: imageFrame
parent: rootItem
source: "qrc:/gcompris/src/activities/lang/resource/imageid_frame.svg"
sourceSize.width: Math.min((parent.width - previousWordButton.width * 2) * 0.8,
(parent.height - categoryTextbg.height
- wordTextbg.height - bar.height) * 1.1)
anchors {
horizontalCenter: parent.horizontalCenter
top: categoryTextbg.bottom
margins: 10 * ApplicationInfo.ratio
}
z: 11
Image {
id: wordImage
// Images are not svg
width: Math.min(parent.width, parent.height) * 0.9
height: width
anchors.centerIn: parent
property string nextSource
function changeSource(nextSource_) {
nextSource = nextSource_
animImage.start()
}
SequentialAnimation {
id: animImage
PropertyAnimation {
target: wordImage
property: "opacity"
to: 0
duration: 100
}
PropertyAction {
target: wordImage
property: "source"
value: wordImage.nextSource
}
PropertyAnimation {
target: wordImage
property: "opacity"
to: 1
duration: 100
}
}
MouseArea {
anchors.fill: parent
enabled: rootItem.opacity == 1
onClicked: Activity.playWord(word.voice)
}
}
Image {
id: previousWordButton
source: "qrc:/gcompris/src/core/resource/bar_previous.svg";
sourceSize.width: 30 * 1.2 * ApplicationInfo.ratio
visible: score.currentSubLevel > 1 ? true : false
anchors {
right: parent.left
rightMargin: 30
top: parent.top
topMargin: parent.height/2 - previousWordButton.height/2
}
MouseArea {
id: previousWordButtonArea
anchors.fill: parent
onClicked: imageReview.prevWord()
}
}
Image {
id: nextWordButton
source: "qrc:/gcompris/src/core/resource/bar_next.svg";
sourceSize.width: 30 * 1.2 * ApplicationInfo.ratio
anchors {
left: parent.right
leftMargin: 30
top: parent.top
topMargin: parent.height/2 - previousWordButton.height/2
}
MouseArea {
id: nextWordButtonArea
anchors.fill: parent
onClicked: imageReview.nextWord();
}
}
}
Rectangle {
id: wordTextbg
parent: rootItem
x: wordText.x - 4
y: wordText.y - 4
width: imageFrame.width
height: wordText.height + 4
color: "#5090ff"
border.color: "#000000"
border.width: 2
radius: 16
anchors {
top: imageFrame.bottom
left: imageFrame.left
margins: 10 * ApplicationInfo.ratio
}
GCText {
id: wordText
text: ""
fontSize: largeSize
font.weight: Font.DemiBold
width: parent.width
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
color: "white"
wrapMode: Text.WordWrap
property string nextWord
function changeText(nextWord_) {
nextWord = nextWord_
animWord.start()
}
SequentialAnimation {
id: animWord
PropertyAnimation {
target: wordText
property: "opacity"
to: 0
duration: 100
}
PropertyAction {
target: wordText
property: "text"
value: wordText.nextWord
}
PropertyAnimation {
target: wordText
property: "opacity"
to: 1
duration: 100
}
}
}
}
BarButton {
id: repeatItem
parent: rootItem
source: "qrc:/gcompris/src/core/resource/bar_repeat.svg";
- sourceSize.width: 80 * ApplicationInfo.ratio
+ sourceSize.width: Math.min(imageFrame.x, 100 * ApplicationInfo.ratio) - 2 * anchors.margins
z: 12
anchors {
top: parent.top
left: parent.left
margins: 10 * ApplicationInfo.ratio
}
onClicked: Activity.playWord(imageReview.word.voice)
Behavior on opacity { PropertyAnimation { duration: 200 } }
}
Score {
id: score
parent: rootItem
- anchors.bottom: undefined
- anchors.bottomMargin: 10 * ApplicationInfo.ratio
- anchors.right: parent.right
- anchors.rightMargin: 10 * ApplicationInfo.ratio
- anchors.top: parent.top
}
}
Loader {
id: miniGameLoader
width: parent.width
height: parent.height
anchors.fill: parent
asynchronous: false
}
function nextPressed() {
- if(currentMiniGame == 0) {
+ if(currentMiniGame === 0) {
nextSubLevel()
}
}
function nextWord() {
++score.currentSubLevel;
if(score.currentSubLevel == score.numberOfSubLevels + 1) {
nextMiniGame()
}
}
function prevWord() {
--score.currentSubLevel
}
function startMiniGame(miniGameIndex) {
currentMiniGame = miniGameIndex
var mode = miniGames[miniGameIndex][1];
var itemToLoad = miniGames[miniGameIndex][2];
- // Starting a minigame we don't wan't pending voices to play
+ // Starting a minigame we don't want pending voices to play
Activity.clearVoiceQueue()
// preparing the wordList
var wordList = Core.shuffle(items.wordList[wordListIndex]).slice()
miniGameLoader.source = itemToLoad;
var loadedItems = miniGameLoader.item
rootItem.opacity = 0
focus = false
// Initiate the loaded item mini game
// Some Mini Games may not start because they miss voices
// In this case we try the next one
if(!loadedItems.init(loadedItems, wordList, mode))
nextMiniGame()
}
//called by a miniGame when it is won
function nextMiniGame() {
if(currentMiniGame < miniGames.length - 1) {
startMiniGame(++currentMiniGame)
} else {
Activity.markProgress()
if(wordListIndex < items.wordList.length - 1) {
initLevel(wordListIndex + 1)
} else {
Activity.launchMenuScreen()
}
}
}
}
diff --git a/src/activities/lang/Lang.qml b/src/activities/lang/Lang.qml
index 34e5b94aa..fd83d41dd 100644
--- a/src/activities/lang/Lang.qml
+++ b/src/activities/lang/Lang.qml
@@ -1,254 +1,255 @@
/* GCompris - lang.qml
*
* Copyright (C) Siddhesh suthar <siddhesh.it@gmail.com> (Qt Quick port)
*
* Authors:
* Pascal Georges (pascal.georges1@free.fr) (GTK+ version)
* Holger Kaelberer <holger.k@elberer.de> (Qt Quick port of imageid)
* Siddhesh suthar <siddhesh.it@gmail.com> (Qt Quick port)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Integration Lang dataset)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import QtGraphicalEffects 1.0
import "../../core"
import "lang.js" as Activity
import "spell_it.js" as SpellActivity
import "qrc:/gcompris/src/core/core.js" as Core
ActivityBase {
id: activity
onStart: focus = true
onStop: {}
pageComponent: Image {
id: background
source: "qrc:/gcompris/src/activities/lang/resource/imageid-bg.svg"
fillMode: Image.PreserveAspectCrop
sourceSize.width: Math.max(parent.width, parent.height)
property bool englishFallback: false
signal start
signal stop
signal voiceError
signal voiceDone
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property GCAudio audioVoices: activity.audioVoices
property alias background: background
property alias bar: bar
property alias imageReview: imageReview
property alias parser: parser
property alias menuModel: menuScreen.menuModel
property var wordList
property alias menuScreen: menuScreen
property alias englishFallbackDialog: englishFallbackDialog
property string locale: 'system'
property alias dialogActivityConfig: dialogActivityConfig
property var categoriesTranslations: activity.categoriesTranslations
}
onStart: {
Activity.init(items)
dialogActivityConfig.getInitialConfiguration()
activity.audioVoices.error.connect(voiceError)
activity.audioVoices.done.connect(voiceDone)
Activity.start()
}
onStop: {
dialogActivityConfig.saveDatainConfiguration()
Activity.stop()
}
JsonParser {
id: parser
onError: console.error("lang: Error parsing json: " + msg);
}
MenuScreen {
id: menuScreen
}
ImageReview {
id: imageReview
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
anchors.bottom: keyboardArea.top
content: menuScreen.started ? withConfig : withoutConfig
property BarEnumContent withConfig: BarEnumContent { value: help | home | config }
property BarEnumContent withoutConfig: BarEnumContent { value: help | home }
onHelpClicked: {
displayDialog(dialogHelp)
}
onHomeClicked: {
if(!items.menuScreen.started && !items.imageReview.started)
// We're in a mini game, start imageReview
items.imageReview.start()
else if(items.imageReview.started)
// Leave imageReview
Activity.launchMenuScreen()
else
home()
}
onConfigClicked: {
dialogActivityConfig.active = true
dialogActivityConfig.setDefaultValues()
displayDialog(dialogActivityConfig)
}
}
// This is a stop to hold the virtual keyboard from a mini game
Row {
id: keyboardArea
anchors.bottom: parent.bottom
width: parent.width
}
Loader {
id: englishFallbackDialog
sourceComponent: GCDialog {
parent: activity.main
message: qsTr("We are sorry, we don't have yet a translation for your language.") + " " +
- qsTr("GCompris is developed by the KDE community, you can translate GCompris by joining a translation team on <a href=\"%2\">%2</a>").arg("http://l10n.kde.org/") +
+ qsTr("GCompris is developed by the KDE community, you can translate GCompris by joining a translation team on <a href=\"%2\">%2</a>").arg("https://l10n.kde.org/") +
"<br /> <br />" +
qsTr("We switched to English for this activity but you can select another language in the configuration dialog.")
onClose: background.englishFallback = false
}
anchors.fill: parent
focus: true
active: background.englishFallback
onStatusChanged: if (status == Loader.Ready) item.start()
}
DialogActivityConfig {
id: dialogActivityConfig
currentActivity: activity
content: Component {
Item {
property alias localeBox: localeBox
height: column.height
property alias availableLangs: langs.languages
LanguageList {
id: langs
}
Column {
id: column
spacing: 10
width: parent.width
Flow {
spacing: 5
width: dialogActivityConfig.width
GCComboBox {
id: localeBox
model: langs.languages
background: dialogActivityConfig
width: dialogActivityConfig.width
label: qsTr("Select your locale")
}
}
}
}
}
onLoadData: {
if(!dataToSave)
return
if(dataToSave['locale']) {
items.locale = dataToSave["locale"];
}
}
onSaveData: {
// Save the lessons status on the current locale
var oldLocale = items.locale
dataToSave[ApplicationInfo.getVoicesLocale(items.locale)] =
Activity.lessonsToSavedProperties(dataToSave)
if(!dialogActivityConfig.loader.item)
return
var newLocale =
dialogActivityConfig.configItem.availableLangs[
dialogActivityConfig.loader.item.localeBox.currentIndex].locale;
// Remove .UTF-8
if(newLocale.indexOf('.') != -1) {
newLocale = newLocale.substring(0, newLocale.indexOf('.'))
}
dataToSave['locale'] = newLocale
items.locale = newLocale;
// Restart the activity with new information
if(oldLocale !== newLocale) {
Activity.stop()
Activity.start();
}
}
function setDefaultValues() {
var localeUtf8 = items.locale;
if(items.locale != "system") {
localeUtf8 += ".UTF-8";
}
for(var i = 0 ; i < dialogActivityConfig.configItem.availableLangs.length ; i ++) {
if(dialogActivityConfig.configItem.availableLangs[i].locale === localeUtf8) {
dialogActivityConfig.loader.item.localeBox.currentIndex = i;
break;
}
}
}
onClose: home()
}
}
property var categoriesTranslations: {"otherChapter": qsTr("other"),
"otherLesson": qsTr("other"),
"action": qsTr("action"), "adjective": qsTr("adjective"),
"color": qsTr("color"), "number": qsTr("number"),
"people": qsTr("people"), "bodyparts": qsTr("bodyparts"),
"clothes": qsTr("clothes"), "emotion": qsTr("emotion"),
"job": qsTr("job"), "sport": qsTr("sport"),
"nature": qsTr("nature"), "animal": qsTr("animal"),
"fruit": qsTr("fruit"), "plant": qsTr("plant"),
"vegetables": qsTr("vegetables"), "object": qsTr("object"),
"construction": qsTr("construction"),
"furniture": qsTr("furniture"), "houseware": qsTr("houseware"),
- "tool": qsTr("tool"), "food": qsTr("food")}
+ "tool": qsTr("tool"), "food": qsTr("food"),
+ "transport": qsTr("transport")}
}
diff --git a/src/activities/lang/MenuScreen.qml b/src/activities/lang/MenuScreen.qml
index 7a3021e77..e41259726 100644
--- a/src/activities/lang/MenuScreen.qml
+++ b/src/activities/lang/MenuScreen.qml
@@ -1,243 +1,243 @@
/* GCompris - MenuScreen.qml
*
* Copyright (C) Siddhesh suthar <siddhesh.it@gmail.com> (Qt Quick port)
*
* Authors:
* Pascal Georges (pascal.georges1@free.fr) (GTK+ version)
* Holger Kaelberer <holger.k@elberer.de> (Qt Quick port of imageid)
* Siddhesh suthar <siddhesh.it@gmail.com> (Qt Quick port)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Integration Lang dataset)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import QtGraphicalEffects 1.0
import QtQuick.Controls 1.5
import "../../core"
import "lang.js" as Activity
Image {
id: menuScreen
anchors.fill: parent
fillMode: Image.PreserveAspectCrop
source: Activity.baseUrl + "imageid-bg.svg"
sourceSize.width: Math.max(parent.width, parent.height)
opacity: 0
property alias menuModel: menuModel
property bool keyboardMode: false
property bool started: opacity == 1
Behavior on opacity { PropertyAnimation { duration: 200 } }
function start() {
focus = true
forceActiveFocus()
menuGrid.currentIndex = 0
opacity = 1
}
function stop() {
focus = false
opacity = 0
}
Keys.onEscapePressed: {
home()
}
Keys.onPressed: {
if(event.key === Qt.Key_Space) {
menuGrid.currentItem.selectCurrentItem()
event.accepted = true
}
if(event.key === Qt.Key_Enter) {
menuGrid.currentItem.selectCurrentItem()
event.accepted = true
}
if(event.key === Qt.Key_Return) {
menuGrid.currentItem.selectCurrentItem()
event.accepted = true
}
if(event.key === Qt.Key_Left) {
menuGrid.moveCurrentIndexLeft()
event.accepted = true
}
if(event.key === Qt.Key_Right) {
menuGrid.moveCurrentIndexRight()
event.accepted = true
}
if(event.key === Qt.Key_Up) {
menuGrid.moveCurrentIndexUp()
event.accepted = true
}
if(event.key === Qt.Key_Down) {
menuGrid.moveCurrentIndexDown()
event.accepted = true
}
}
Keys.onReleased: {
keyboardMode = true
event.accepted = false
}
// Activities
property int iconWidth: 180 * ApplicationInfo.ratio
property int iconHeight: 180 * ApplicationInfo.ratio
property int levelCellWidth: background.width / Math.floor(background.width / iconWidth )
property int levelCellHeight: iconHeight * 1.4
ListModel {
id: menuModel
}
GridView {
id: menuGrid
anchors {
fill: parent
bottomMargin: bar.height
}
cellWidth: levelCellWidth
cellHeight: levelCellHeight
clip: true
model: menuModel
keyNavigationWraps: true
property int spacing: 10
delegate: Item {
id: delegateItem
width: levelCellWidth - menuGrid.spacing
height: levelCellHeight - menuGrid.spacing
property string sectionName: name
Rectangle {
id: activityBackground
width: levelCellWidth - menuGrid.spacing
height: levelCellHeight - menuGrid.spacing
anchors.horizontalCenter: parent.horizontalCenter
color: "white"
opacity: 0.5
}
Image {
id: containerImage
source: image;
anchors.top: activityBackground.top
anchors.horizontalCenter: parent.horizontalCenter
width: iconWidth
height: iconHeight
anchors.margins: 5
GCText {
id: title
anchors.top: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
horizontalAlignment: Text.AlignHCenter
width: activityBackground.width
fontSizeMode: Text.Fit
minimumPointSize: 7
fontSize: regularSize
elide: Text.ElideRight
maximumLineCount: 2
wrapMode: Text.WordWrap
text: Activity.items.categoriesTranslations[name]
}
ProgressBar {
id: progressLang
anchors.top: title.bottom
anchors.topMargin: ApplicationInfo.ratio * 4
anchors.horizontalCenter: parent.horizontalCenter
width: activityBackground.width
height: 14 * ApplicationInfo.ratio
maximumValue: wordCount
minimumValue: 0
value: progress
orientation: Qt.Horizontal
}
}
ParticleSystemStarLoader {
id: particles
anchors.fill: activityBackground
}
MouseArea {
anchors.fill: activityBackground
enabled: menuScreen.started
onClicked: selectCurrentItem()
}
function selectCurrentItem() {
particles.burst(50)
Activity.initLevel(index)
}
Image {
source: "qrc:/gcompris/src/activities/menu/resource/" +
( favorite ? "all.svg" : "all_disabled.svg" );
anchors {
top: parent.top
right: parent.right
rightMargin: 4 * ApplicationInfo.ratio
}
sourceSize.width: iconWidth * 0.25
visible: ApplicationSettings.sectionVisible
MouseArea {
anchors.fill: parent
onClicked: {
menuModel.get(index)['favorite'] = !menuModel.get(index)['favorite']
}
}
}
} //delegate close
highlight: Rectangle {
width: levelCellWidth - menuGrid.spacing
height: levelCellHeight - menuGrid.spacing
color: "#AA41AAC4"
border.width: 3
border.color: "black"
visible: menuScreen.keyboardMode
Behavior on x { SpringAnimation { spring: 2; damping: 0.2 } }
Behavior on y { SpringAnimation { spring: 2; damping: 0.2 } }
}
Rectangle{
id: menusMask
visible: false
anchors.fill: menuGrid
gradient: Gradient {
GradientStop { position: 0.0; color: "#FFFFFFFF" }
GradientStop { position: 0.92; color: "#FFFFFFFF" }
GradientStop { position: 0.96; color: "#00FFFFFF"}
}
}
layer.enabled: ApplicationInfo.useOpenGL
layer.effect: OpacityMask {
id: activitiesOpacity
source: menuGrid
maskSource: menusMask
anchors.fill: menuGrid
}
} // grid view close
}
diff --git a/src/activities/lang/Quiz.qml b/src/activities/lang/Quiz.qml
index 9cd87c01a..8370d015d 100644
--- a/src/activities/lang/Quiz.qml
+++ b/src/activities/lang/Quiz.qml
@@ -1,293 +1,289 @@
/* GCompris - Quiz.qml
*
* Copyright (C) Siddhesh suthar <siddhesh.it@gmail.com> (Qt Quick port)
*
* Authors:
* Pascal Georges (pascal.georges1@free.fr) (GTK+ version)
* Holger Kaelberer <holger.k@elberer.de> (Qt Quick port of imageid)
* Siddhesh suthar <siddhesh.it@gmail.com> (Qt Quick port)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Integration Lang dataset)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import QtGraphicalEffects 1.0
import "../../core"
import "lang.js" as Activity
import "quiz.js" as QuizActivity
Item {
id: quiz
opacity: 0
property alias background: background
property alias bonus: bonus
property alias score: score
property alias wordImage: wordImage
property alias imageFrame: imageFrame
property alias wordListModel: wordListModel
property alias wordListView: wordListView
property alias parser: parser
property var goodWord
- property bool horizontalLayout: background.width > background.height
+ property bool horizontalLayout: background.width >= background.height
property bool buttonsBlocked: false
function init(loadedItems_, wordList_, mode_) {
opacity = 1
loadedItems_.forceActiveFocus()
return QuizActivity.init(loadedItems_, wordList_, mode_)
}
onGoodWordChanged: Activity.playWord(goodWord.voice)
Behavior on opacity { PropertyAnimation { duration: 200 } }
Image {
id: background
source: "qrc:/gcompris/src/activities/lang/resource/imageid-bg.svg"
fillMode: Image.PreserveAspectCrop
sourceSize.width: Math.max(parent.width, parent.height)
height: parent.height
anchors.fill: parent
property bool keyNavigation: false
Keys.enabled: !quiz.buttonsBlocked
Keys.onEscapePressed: {
imageReview.start()
}
Keys.onRightPressed: {
keyNavigation = true
wordListView.incrementCurrentIndex()
}
Keys.onLeftPressed: {
keyNavigation = true
wordListView.decrementCurrentIndex()
}
Keys.onDownPressed: {
keyNavigation = true
wordListView.incrementCurrentIndex()
}
Keys.onUpPressed: {
keyNavigation = true
wordListView.decrementCurrentIndex()
}
Keys.onSpacePressed: {
keyNavigation = true
wordListView.currentItem.children[1].pressed()
}
Keys.onEnterPressed: {
keyNavigation = true
wordListView.currentItem.children[1].pressed()
}
Keys.onReturnPressed: {
keyNavigation = true
wordListView.currentItem.children[1].pressed()
}
Keys.onReleased: {
if (event.key === Qt.Key_Back) {
event.accepted = true
imageReview.start()
}
}
JsonParser {
id: parser
onError: console.error("Lang: Error parsing json: " + msg);
}
ListModel {
id: wordListModel
}
Grid {
id: gridId
columns: quiz.horizontalLayout ? 2 : 1
- spacing: 10 * ApplicationInfo.ratio
+ spacing: 0.5 * ApplicationInfo.ratio
anchors.fill: parent
anchors.margins: 10 * ApplicationInfo.ratio
Item {
width: quiz.horizontalLayout
? background.width * 0.40
: background.width - gridId.anchors.margins * 2
height: quiz.horizontalLayout
? background.height - bar.height
: (background.height - bar.height) * 0.4
Image {
id: imageFrame
anchors {
horizontalCenter: parent.horizontalCenter
verticalCenter: parent.verticalCenter
}
source: "qrc:/gcompris/src/activities/lang/resource/imageid_frame.svg"
sourceSize.width: quiz.horizontalLayout ? parent.width * 0.7 : quiz.width - repeatItem.width - score.width - 50 * ApplicationInfo.ratio
z: 11
visible: QuizActivity.mode !== 3
Image {
id: wordImage
// Images are not svg
width: Math.min(parent.width, parent.height) * 0.9
height: width
anchors.centerIn: parent
property string nextSource
function changeSource(nextSource_) {
nextSource = nextSource_
animImage.start()
}
SequentialAnimation {
id: animImage
PropertyAnimation {
target: wordImage
property: "opacity"
to: 0
duration: 100
}
PropertyAction {
target: wordImage
property: "source"
value: wordImage.nextSource
}
PropertyAnimation {
target: wordImage
property: "opacity"
to: 1
duration: 100
}
}
MouseArea {
anchors.fill: parent
onClicked: Activity.playWord(goodWord.voice)
}
}
}
}
ListView {
id: wordListView
width: quiz.horizontalLayout
? background.width * 0.55
: background.width - gridId.anchors.margins * 2
height: quiz.horizontalLayout
? background.height - bar.height
: (background.height - bar.height) * 0.60
- spacing: 10 * ApplicationInfo.ratio
+ spacing: 2 * ApplicationInfo.ratio
orientation: Qt.Vertical
verticalLayoutDirection: ListView.TopToBottom
interactive: false
model: wordListModel
highlight: Rectangle {
width: wordListView.width
height: wordListView.buttonHeight
color: "lightsteelblue"
radius: 5
visible: background.keyNavigation
- y: wordListView.currentItem.y
+ y: wordListView.currentItem ? wordListView.currentItem.y : 0
Behavior on y {
SpringAnimation {
spring: 3
damping: 0.2
}
}
}
highlightFollowsCurrentItem: false
focus: true
keyNavigationWraps: true
property int buttonHeight: height / wordListModel.count * 0.9
delegate: Item {
id: wordListViewDelegate
width: wordListView.width
height: wordListView.buttonHeight
anchors.right: parent.right
anchors.left: parent.left
Image {
id: wordImageQuiz
width: height
height: wordListView.buttonHeight
+ mipmap: true
source: image
z: 7
fillMode: Image.PreserveAspectFit
anchors.leftMargin: 5 * ApplicationInfo.ratio
visible: (QuizActivity.mode == 1) ? true : false // hide images after first mini game
}
AnswerButton {
id: wordRectangle
width: parent.width * 0.6
height: wordListView.buttonHeight
textLabel: translatedTxt
anchors.left: wordImageQuiz.left
anchors.right: parent.right
blockAllButtonClicks: quiz.buttonsBlocked
onPressed: quiz.buttonsBlocked = true
isCorrectAnswer: translatedTxt === quiz.goodWord.translatedTxt
onIncorrectlyPressed: {
// push the error to have it asked again
QuizActivity.remainingWords.unshift(quiz.goodWord);
QuizActivity.nextSubLevelQuiz();
}
onCorrectlyPressed: {
QuizActivity.nextSubLevelQuiz();
}
}
}
}
}
BarButton {
id: repeatItem
source: "qrc:/gcompris/src/core/resource/bar_repeat.svg";
sourceSize.width: 80 * ApplicationInfo.ratio
z: 12
anchors {
top: parent.top
left: parent.left
margins: 10 * ApplicationInfo.ratio
}
onClicked: Activity.playWord(goodWord.voice)
Behavior on opacity { PropertyAnimation { duration: 200 } }
}
Score {
id: score
parent: quiz
- anchors.bottom: undefined
- anchors.bottomMargin: 10 * ApplicationInfo.ratio
- anchors.right: parent.right
- anchors.rightMargin: 10 * ApplicationInfo.ratio
- anchors.top: parent.top
}
Bonus {
id: bonus
onWin: imageReview.nextMiniGame()
}
}
}
diff --git a/src/activities/lang/SpellIt.qml b/src/activities/lang/SpellIt.qml
index fe94fe8d2..2ab8f2917 100644
--- a/src/activities/lang/SpellIt.qml
+++ b/src/activities/lang/SpellIt.qml
@@ -1,302 +1,297 @@
/* GCompris - SpellIt.qml
*
* Copyright (C) Siddhesh suthar <siddhesh.it@gmail.com> (Qt Quick port)
*
* Authors:
* Pascal Georges (pascal.georges1@free.fr) (GTK+ version)
* Holger Kaelberer <holger.k@elberer.de> (Qt Quick port of imageid)
* Siddhesh suthar <siddhesh.it@gmail.com> (Qt Quick port)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Integration Lang dataset)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import QtGraphicalEffects 1.0
import "../../core"
import "lang.js" as Activity
import "spell_it.js" as SpellActivity
Item {
id: spellIt
opacity: 0
property alias background: background
property alias wordImage: wordImage
property alias imageFrame: imageFrame
property alias hintTextbg: hintTextbg
property alias hintText: hintText
property alias parser: parser
property alias answerbg: answerbg
property alias answer: answer
property alias ok: ok
property alias okMouseArea: okMouseArea
property alias bonus: bonus
property alias keyboard: keyboard
property alias score: score
property var goodWord
property int goodWordIndex
property int maximumLengthAnswer
function init(loadedItems_, wordList_, mode_) {
opacity = 1
return SpellActivity.init(loadedItems_, wordList_, mode_);
}
onGoodWordChanged: Activity.playWord(goodWord.voice)
Behavior on opacity { PropertyAnimation { duration: 200 } }
Keys.onEscapePressed: {
imageReview.start()
}
Image {
id: background
source: "qrc:/gcompris/src/activities/lang/resource/imageid-bg.svg"
fillMode: Image.PreserveAspectCrop
sourceSize.width: Math.max(parent.width, parent.height)
height: parent.height
- property bool horizontalLayout: background.width > background.height
+ property bool horizontalLayout: background.width >= background.height
JsonParser {
id: parser
onError: console.error("Lang: Error parsing json: " + msg);
}
Rectangle {
id: hintTextbg
x: hintText.x -4
y: hintText.y -4
width: imageFrame.width
height: hintText.height +4
color: "#5090ff"
border.color: "#000000"
border.width: 2
radius: 16
anchors.top: parent.top
anchors.bottom: imageFrame.top
anchors.left: imageFrame.left
anchors.bottomMargin: 5
GCText {
id: hintText
text: ""
fontSize: largeSize
font.weight: Font.DemiBold
width: parent.width
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
color: "white"
wrapMode: Text.WordWrap
property string nextHint
function changeHint(nextHint_) {
nextHint = nextHint_
animHint.start()
}
SequentialAnimation {
id: animHint
PropertyAnimation {
target: hintText
property: "opacity"
to: 0
duration: 100
}
PropertyAction {
target: hintText
property: "text"
value: ""+ hintText.nextHint
}
PropertyAnimation {
target: hintText
property: "opacity"
to: 1
duration: 100
}
}
}
}
Image {
id: imageFrame
source: "qrc:/gcompris/src/activities/lang/resource/imageid_frame.svg"
sourceSize.width: background.horizontalLayout ? parent.width * 0.9 : parent.height * 1.2
width: background.width * 0.55
height: (background.height - hintTextbg.height - answerbg.height
- keyboard.height - bar.height) * 0.8
anchors {
horizontalCenter: background.horizontalCenter
top: background.top
topMargin: (background.height) * 0.15
}
z: 11
Image {
id: wordImage
// Images are not svg
width: Math.min(parent.width, parent.height) * 0.9
height: width
anchors.centerIn: parent
property string nextSource
function changeSource(nextSource_) {
nextSource = nextSource_
animImage.start()
}
SequentialAnimation {
id: animImage
PropertyAnimation {
target: wordImage
property: "opacity"
to: 0
duration: 100
}
PropertyAction {
target: wordImage
property: "source"
value: wordImage.nextSource
}
PropertyAnimation {
target: wordImage
property: "opacity"
to: 1
duration: 100
}
}
MouseArea {
anchors.fill: parent
onClicked: {
Activity.playWord(goodWord.voice)
}
}
}
}
Rectangle {
id: answerbg
x: answer.x -4
y: answer.y -4
width: imageFrame.width
height: answer.height +4
color: "#5090ff"
border.color: "#000000"
border.width: 2
radius: 16
anchors {
top: imageFrame.bottom
left: imageFrame.left
topMargin: 20* ApplicationInfo.ratio
}
TextInput {
id: answer
width: hintTextbg.width
height: hintTextbg.height
color: "white"
cursorVisible: true
focus: false
activeFocusOnPress: !ApplicationInfo.isMobile
visible: true
horizontalAlignment: TextInput.AlignHCenter
verticalAlignment: TextInput.AlignVCenter
font.pointSize: hintText.pointSize
font.weight: Font.DemiBold
font.family: GCSingletonFontLoader.fontLoader.name
font.capitalization: ApplicationSettings.fontCapitalization
font.letterSpacing: ApplicationSettings.fontLetterSpacing
maximumLength: maximumLengthAnswer
onAccepted: {
okMouseArea.clicked(okMouseArea)
}
}
}
Image {
id: ok
source:"qrc:/gcompris/src/core/resource/bar_ok.svg"
sourceSize.width: 70 * ApplicationInfo.ratio
fillMode: Image.PreserveAspectFit
anchors {
top: imageFrame.bottom
- topMargin: 10* ApplicationInfo.ratio
- left: imageFrame.right
- leftMargin: 10* ApplicationInfo.ratio
- right: parent.right
+ topMargin: 10
+ right: imageFrame.left
+ rightMargin: parent.width * 0.06
+
}
MouseArea {
id: okMouseArea
anchors.fill: parent
hoverEnabled: true
onEntered: ok.scale = 1.1
onClicked: {
SpellActivity.checkAnswer(answer.text)
}
onExited: ok.scale = 1
}
}
Bonus {
id: bonus
onWin: imageReview.nextMiniGame()
}
}
BarButton {
id: repeatItem
source: "qrc:/gcompris/src/core/resource/bar_repeat.svg";
sourceSize.width: 80 * ApplicationInfo.ratio
z: 12
anchors {
top: parent.top
left: parent.left
margins: 10 * ApplicationInfo.ratio
}
onClicked: Activity.playWord(goodWord.voice)
Behavior on opacity { PropertyAnimation { duration: 200 } }
}
Score {
id: score
- anchors.bottom: undefined
- anchors.bottomMargin: 10 * ApplicationInfo.ratio
- anchors.right: parent.right
- anchors.rightMargin: 10 * ApplicationInfo.ratio
- anchors.top: parent.top
}
VirtualKeyboard {
id: keyboard
parent: keyboardArea
anchors.bottom: undefined
anchors.horizontalCenter: undefined
width: parent.width
visible: ApplicationSettings.isVirtualKeyboard
onKeypress: SpellActivity.processKeyPress(text)
onError: console.log("VirtualKeyboard error: " + msg);
}
}
diff --git a/src/activities/lang/lang.js b/src/activities/lang/lang.js
index 8adec8653..9838a7c3d 100644
--- a/src/activities/lang/lang.js
+++ b/src/activities/lang/lang.js
@@ -1,175 +1,175 @@
/* GCompris - lang.js
*
* Copyright (C) Siddhesh suthar <siddhesh.it@gmail.com> (Qt Quick port)
*
* Authors:
* Pascal Georges (pascal.georges1@free.fr) (GTK+ version)
* Holger Kaelberer <holger.k@elberer.de> (Qt Quick port of imageid)
* Siddhesh suthar <siddhesh.it@gmail.com> (Qt Quick port)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Integration Lang dataset)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
.import GCompris 1.0 as GCompris
.import "qrc:/gcompris/src/core/core.js" as Core
.import "qrc:/gcompris/src/activities/lang/lang_api.js" as Lang
var lessonModelIndex = 0;
var currentSubLevel = 0;
var items;
var baseUrl = "qrc:/gcompris/src/activities/lang/resource/";
var dataset
var lessons
var maxWordInLesson = 12
function init(items_) {
items = items_
lessonModelIndex = 0
currentSubLevel = 0
}
function start() {
lessonModelIndex = 0;
currentSubLevel = 0;
items.imageReview.stop()
var locale = GCompris.ApplicationInfo.getVoicesLocale(items.locale)
// register the voices for the locale
GCompris.DownloadManager.updateResource(GCompris.DownloadManager.getVoicesResourceForLocale(locale))
var data = Lang.loadDataset(items.parser, baseUrl, locale);
dataset = data["dataset"];
items.background.englishFallback = data["englishFallback"];
// We have to keep it because we can't access content from the model
lessons = Lang.getAllLessons(dataset)
addPropertiesToLessons(lessons)
items.menuModel.clear()
items.menuModel.append(lessons)
savedPropertiesToLessons(items.dialogActivityConfig.dataToSave)
sortByFavorites();
items.menuScreen.start()
}
// Insert our specific properties in the lessons
function addPropertiesToLessons(lessons) {
for (var i in lessons) {
// Ceil the wordCount to a maxWordInLesson count
lessons[i]['wordCount'] =
Math.ceil(Lang.getLessonWords(dataset, lessons[i]).length / maxWordInLesson)
* maxWordInLesson
lessons[i]['image'] = lessons[i].content[0].image
lessons[i]['progress'] = 0
lessons[i]['favorite'] = false
// We need to keep a back reference from the model to the lessons array
lessons[i]['lessonIndex'] = i
}
}
// Return a new json that contains all the properties we have to save
function lessonsToSavedProperties() {
var locale = GCompris.ApplicationInfo.getVoicesLocale(items.locale)
var props = {}
for(var i = 0; i < items.menuModel.count; i++) {
var lesson = items.menuModel.get(i)
props[lesson.name] = {
'favorite': lesson['favorite'],
'progress': lesson['progress']
}
}
return props
}
// Update the lessons based on a previous saving
function savedPropertiesToLessons(dataToSave) {
var locale = GCompris.ApplicationInfo.getVoicesLocale(items.locale)
var props = dataToSave[locale]
for(var i = 0; i < items.menuModel.count; i++) {
var lesson = items.menuModel.get(i)
if(props && props[lesson.name]) {
lesson['favorite'] = props[lesson.name].favorite
lesson['progress'] = props[lesson.name].progress
} else {
lesson['favorite'] = false
lesson['progress'] = 0
}
}
}
function stop() {
}
function initLevel(lessonModelIndex_) {
lessonModelIndex = lessonModelIndex_
var lessonIndex = items.menuModel.get(lessonModelIndex).lessonIndex
var flatWordList = Lang.getLessonWords(dataset, lessons[lessonIndex]);
// We have to split the works in chunks of maxWordInLesson
items.wordList = []
var i = 0
while(flatWordList.length > 0) {
items.wordList[i++] = Core.shuffle(flatWordList.splice(0, maxWordInLesson));
}
// If needed complete the last set to have maxWordInLesson items in it
// We pick extra items from the head of the list
if(items.wordList[i-1].length != maxWordInLesson) {
var flatWordList = Lang.getLessonWords(dataset, lessons[lessonIndex]);
var lastLength = items.wordList[i-1].length
items.wordList[i-1] =
items.wordList[i-1].concat(flatWordList.splice(0, maxWordInLesson - lastLength))
}
items.imageReview.category = items.categoriesTranslations[lessons[lessonIndex].name] //lessons[lessonIndex].name
// Calc the sublevel to start with
var subLevel = Math.floor(items.menuModel.get(lessonModelIndex)['progress'] / maxWordInLesson)
if(subLevel >= items.wordList.length)
// Level done, start again at level 0
subLevel = 0
items.menuScreen.stop()
items.imageReview.initLevel(subLevel)
}
function launchMenuScreen() {
items.imageReview.stop()
items.menuScreen.start()
}
function sortByFavorites() {
for(var i = 0; i < items.menuModel.count; i++) {
if(items.menuModel.get(i)['favorite'])
items.menuModel.move(i, 0, 1);
}
}
function markProgress() {
// We count progress as a number of image learnt from the lesson start
items.menuModel.get(lessonModelIndex)['progress'] += maxWordInLesson
}
function playWord(word) {
var locale = GCompris.ApplicationInfo.getVoicesLocale(items.locale)
return items.audioVoices.append(
GCompris.ApplicationInfo.getAudioFilePathForLocale(word, locale))
}
function clearVoiceQueue() {
items.audioVoices.clearQueue()
}
diff --git a/src/activities/lang/lang_api.js b/src/activities/lang/lang_api.js
index 5e46e0ab8..48a49c0e1 100644
--- a/src/activities/lang/lang_api.js
+++ b/src/activities/lang/lang_api.js
@@ -1,162 +1,162 @@
/* GCompris - lang_api.js
*
* Copyright (C) 2014 Bruno Coudoin
*
* Authors:
* Bruno Coudoin (bruno.coudoin@gcompris.net)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import GCompris 1.0 as GCompris
.import "qrc:/gcompris/src/core/core.js" as Core
var contentText
function validateDataset(levels)
{
return true;
}
function load(parser, baseUrl, datasetFilename, translationFilename) {
var datasetUrl = baseUrl + "/" + datasetFilename;
var dataset = parser.parseFromUrl(datasetUrl, validateDataset);
if (dataset === null) {
console.error("Lang: Invalid dataset, can't continue: "
+ datasetUrl);
return;
}
dataset['contentText'] = loadContent(parser,
GCompris.ApplicationInfo.getLocaleFilePath(baseUrl + "/" + translationFilename))
if(!dataset['contentText']) {
return null
}
applyImgPrefix(dataset)
return dataset
}
function loadContent(parser, datasetUrl) {
var dataset = parser.parseFromUrl(datasetUrl, validateDataset);
if (dataset === null) {
console.error("Lang: Invalid dataset, can't continue: "
+ datasetUrl);
return;
}
return dataset
}
function getChapter(dataset, chapter) {
return dataset[chapter]
}
// Return a datamodel for the chapter suitable for creating a chapter selector
function getChapterModel(dataset) {
var chapters = []
for (var c = 0; c < dataset.length; c++) {
chapters.push(
{'name': dataset[c].name,
'image': dataset[c].content[0].content[0].image,
'index': c
})
}
return chapters
}
function getLesson(dataset, chapter, lesson) {
return chapter.content[lesson]
}
function getAllLessons(dataset) {
var lessons = []
for (var c in dataset) {
for (var l in dataset[c].content) {
var lesson = getLesson(dataset, dataset[c], l)
lessons.push(lesson)
}
}
return lessons
}
/* return a list of words in the lesson. Each words is formatted like:
* 'description' => "splatter"
* 'image' => "words/splatter.png"
* 'voice' => "voices-$CA/$LOCALE/words/splatter.$CA"
* 'translatedTxt' => "splatter"
*/
function getLessonWords(dataset, lesson) {
var wordList = lesson.content
// Fill up the lesson with the translated text
var allWords = []
for (var k in wordList) {
var word = wordList[k]
word['translatedTxt'] = dataset.contentText[
word.voice.substr(word.voice.lastIndexOf("/")+1).replace("$CA", "ogg")];
if(word['translatedTxt'])
allWords.push(word)
}
return allWords
}
/* Apply the imgPrefix of the chapter to the whole image set
*/
function applyImgPrefix(dataset) {
for (var c = 0; c < dataset.length; c++) {
if(!dataset[c].imgPrefix)
break
for (var l in dataset[c].content) {
for (var k in dataset[c].content[l].content) {
dataset[c].content[l].content[k].image = dataset[c].imgPrefix + dataset[c].content[l].content[k].image
}
}
}
}
/**
* Helper to load a dataset
*/
function loadDataset(parser, resourceUrl, locale) {
var wordset = GCompris.ApplicationSettings.useExternalWordset() ? "words.json" : "words_sample.json";
var dataset = load(parser, resourceUrl, wordset,
"content-"+ locale +".json")
var englishFallback = false
// If dataset is empty, we try to load from short locale
// and if not present again, we switch to default one
var localeUnderscoreIndex = locale.indexOf('_')
if(!dataset) {
var localeShort;
// We will first look again for locale xx (without _XX if exist)
if(localeUnderscoreIndex > 0) {
localeShort = locale.substring(0, localeUnderscoreIndex)
} else {
localeShort = locale;
}
dataset = load(parser, resourceUrl, wordset,
"content-"+localeShort+ ".json")
}
// If still dataset is empty then fallback to english
if(!dataset) {
// English fallback
englishFallback = true
dataset = load(parser, resourceUrl, wordset, "content-en.json")
}
return {"dataset": dataset, "englishFallback": englishFallback};
}
diff --git a/src/activities/lang/quiz.js b/src/activities/lang/quiz.js
index 24f219e28..74a4477da 100644
--- a/src/activities/lang/quiz.js
+++ b/src/activities/lang/quiz.js
@@ -1,100 +1,100 @@
/* GCompris - quiz.js
*
* Copyright (C) Siddhesh suthar <siddhesh.it@gmail.com> (Qt Quick port)
*
* Authors:
* Pascal Georges (pascal.georges1@free.fr) (GTK+ version)
* Holger Kaelberer <holger.k@elberer.de> (Qt Quick port of imageid)
* Siddhesh suthar <siddhesh.it@gmail.com> (Qt Quick port)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Integration Lang dataset)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
.import GCompris 1.0 as GCompris
.import "qrc:/gcompris/src/core/core.js" as Core
.import "qrc:/gcompris/src/activities/lang/lang_api.js" as Lang
var quizItems
var wordList
var remainingWords
var mode
// @return true if the quiz was ran
function init(loadedItems_, wordList_, mode_) {
quizItems = loadedItems_
wordList = wordList_
mode = mode_
quizItems.score.numberOfSubLevels = wordList.length
if(mode == 3) {
quizItems.imageFrame.visible = false
// Remove words for which we don't have voice
for (var j = 0; j < wordList.length ; j++) {
if(!wordList[j].hasVoice) {
wordList.splice(j, 1)
j--;
}
}
} else {
quizItems.imageFrame.visible = true
}
// Bails out if we don't have enough words to play
if(wordList.length < 2) {
return false
}
quizItems.wordListView.forceActiveFocus()
remainingWords = Core.shuffle(wordList).slice()
nextQuiz();
return true
}
function nextQuiz() {
quizItems.score.currentSubLevel = quizItems.score.numberOfSubLevels - remainingWords.length + 1
quizItems.goodWord = remainingWords.pop()
var selectedWords = []
selectedWords.push(quizItems.goodWord)
// Pick 3 wrong words to complete the quiz
for (var i = 0; i < wordList.length; i++) {
if(wordList[i] !== quizItems.goodWord) {
selectedWords.push(wordList[i])
}
if(selectedWords.length > 4)
break
}
// Push the result in the model
selectedWords = Core.shuffle(selectedWords);
quizItems.wordListModel.clear();
quizItems.wordListModel.append(selectedWords)
quizItems.wordImage.changeSource(quizItems.goodWord.image)
quizItems.buttonsBlocked = false
}
function nextSubLevelQuiz() {
if(remainingWords.length === 0) {
quizItems.bonus.good("smiley")
} else {
nextQuiz();
}
}
diff --git a/src/activities/lang/resource/content-be.json b/src/activities/lang/resource/content-be.json
index a5988440e..f06c712aa 100644
--- a/src/activities/lang/resource/content-be.json
+++ b/src/activities/lang/resource/content-be.json
@@ -1,1108 +1,467 @@
{
"10.ogg": "дзесяць",
"11.ogg": "адзінаццаць",
"12.ogg": "дванаццаць",
"16.ogg": "шаснаццаць",
"U0030.ogg": "нуль",
"U0031.ogg": "адзін",
"U0032.ogg": "два",
"U0033.ogg": "тры",
"U0034.ogg": "чатыры",
"U0035.ogg": "пяць",
"U0036.ogg": "шэсць",
"U0037.ogg": "сем",
"U0038.ogg": "восем",
"U0039.ogg": "дзевяць",
- "accountant.ogg": "",
- "ache.ogg": "",
- "acorn.ogg": "",
- "actor.ogg": "",
- "air_horn.ogg": "",
- "alarmclock.ogg": "",
"alligator.ogg": "алігатар",
- "alphabet.ogg": "",
"anchor.ogg": "якар",
"angel.ogg": "анёл",
- "angry.ogg": "",
"animal.ogg": "жывёла",
- "ankle.ogg": "",
- "ant.ogg": "",
- "anteater.ogg": "",
- "antelope.ogg": "",
- "apple.ogg": "",
- "apple_tree.ogg": "",
- "appliance.ogg": "",
- "apricot.ogg": "",
- "arm.ogg": "",
- "armchair.ogg": "",
- "artichoke.ogg": "",
- "artist.ogg": "",
- "asparagus.ogg": "",
- "astronaut.ogg": "",
- "ate.ogg": "ежа",
"athlete.ogg": "атлет",
- "avocado.ogg": "",
- "ax.ogg": "",
- "baby_bottle.ogg": "",
"back.ogg": "спіна",
"badge.ogg": "значок",
"bag.ogg": "торба",
"bait.ogg": "прынада",
- "bake.ogg": "пячы",
"balance.ogg": "баланс",
- "bald.ogg": "",
"ball.ogg": "шпуляк",
- "ball_of_yarn.ogg": "",
- "ball_soccer.ogg": "",
"ballet.ogg": "балет",
"bank.ogg": "банк",
"bark.ogg": "брахаць",
"barn.ogg": "хлеў",
"bat.ogg": "кажан",
"bath.ogg": "ванная",
- "bathing_suit.ogg": "",
"bay.ogg": "затока",
"beach.ogg": "пляж",
- "bead.ogg": "шарык",
- "bean.ogg": "",
- "bear.ogg": "",
- "beard.ogg": "",
- "beat.ogg": "",
- "beaver.ogg": "",
"bed.ogg": "ложак",
- "bedroom.ogg": "",
"bee.ogg": "пчала",
- "beef.ogg": "",
"beetle.ogg": "жук",
"beg.ogg": "маліць",
- "behind.ogg": "",
- "bell.ogg": "",
- "belly.ogg": "",
"bench.ogg": "зэдлік",
"bib.ogg": "нагруднік",
"big.ogg": "вялікі",
- "big_top.ogg": "",
"bike.ogg": "ровар",
"bird.ogg": "птушка",
"bit.ogg": "кавалак",
"bite.ogg": "кусаць",
"black.ogg": "чорны",
- "blackberry.ogg": "",
- "blackbird.ogg": "",
- "blade.ogg": "",
"blind.ogg": "невідушчы",
"blink.ogg": "мігацець",
"block.ogg": "блок",
"blond.ogg": "светлы",
"blue.ogg": "блакітны",
- "blueberry.ogg": "",
- "blush.ogg": "",
"board.ogg": "дошка",
"boat.ogg": "лодка",
"boil.ogg": "кіпець",
- "bolt.ogg": "",
"bomb.ogg": "бомба",
"bone.ogg": "костка",
"book.ogg": "кніга",
- "bookcase.ogg": "",
- "bottom.ogg": "",
"box.ogg": "скрыня",
- "boxer.ogg": "",
"boy.ogg": "хлопец",
"braid.ogg": "каса",
"brain.ogg": "мазгі",
"branch.ogg": "галіна",
"bread.ogg": "хлеб",
"break.ogg": "перапынак",
- "breast.ogg": "",
"brick.ogg": "цэгла",
- "bricklayer.ogg": "",
"bride.ogg": "нявеста",
"bridge.ogg": "мост",
"bright.ogg": "бліскучы",
- "broccoli.ogg": "",
"brother.ogg": "брат",
"brown.ogg": "муры",
"brush.ogg": "пэндзаль",
- "bubble.ogg": "",
- "bucket.ogg": "",
"bud.ogg": "бутон",
- "buffalo.ogg": "",
"bug.ogg": "казурка",
- "bulb.ogg": "",
- "bull.ogg": "",
"bump.ogg": "шышка",
"bun.ogg": "булка",
- "bus.ogg": "",
"bush.ogg": "куст",
- "butcher.ogg": "",
- "butter.ogg": "",
- "butterfly.ogg": "",
- "button.ogg": "",
- "cabbage.ogg": "",
"cabin.ogg": "кабіна",
- "cacao.ogg": "",
- "cactus.ogg": "",
"cage.ogg": "краты",
"cake.ogg": "каравай",
"call.ogg": "вокліч",
"camel.ogg": "верблюд",
- "camera.ogg": "",
"camp.ogg": "лагер",
"can.ogg": "бляшанка",
- "canary.ogg": "",
"candle.ogg": "свечка",
"candy.ogg": "цукерка",
"cane.ogg": "кій",
"canoe.ogg": "каноэ",
- "canon.ogg": "",
- "canyon.ogg": "",
"cap.ogg": "шапка",
"cape.ogg": "капюшон",
"car.ogg": "аўтамабіль",
- "carafe.ogg": "",
"card.ogg": "картка",
- "carnival.ogg": "",
- "carpenter.ogg": "",
- "carpet.ogg": "",
"carrot.ogg": "морква",
"cart.ogg": "воз",
"cash.ogg": "гатоўка",
"castle.ogg": "замак",
"cat.ogg": "котка",
- "cat_female.ogg": "",
"catch.ogg": "лавіць",
- "caterpillar.ogg": "",
- "cauldron.ogg": "",
- "cauliflower.ogg": "",
"cave.ogg": "пячора",
- "cavern.ogg": "",
- "celery.ogg": "",
"centipede.ogg": "мнаганожка",
- "cereal.ogg": "",
- "chain.ogg": "",
"chair.ogg": "крэсла",
"chalk.ogg": "крэйда",
- "chameleon.ogg": "",
- "chandelier.ogg": "",
"chat.ogg": "гутарыць",
- "cheek.ogg": "",
"cheer.ogg": "падбадзёрваць",
"cheese.ogg": "сыр",
- "chef.ogg": "",
"cherry.ogg": "вішня",
"chest.ogg": "грудзі",
"chick.ogg": "птушаня",
"chicken.ogg": "кураня",
- "chief.ogg": "кіраўнік",
"child.ogg": "дзіця",
- "chimney.ogg": "",
"chimp.ogg": "шымпанзэ",
"chin.ogg": "падбародак",
"chocolate.ogg": "шакалад",
"chop.ogg": "наразаць",
- "chore.ogg": "",
- "christmas.ogg": "",
- "cigar.ogg": "",
- "circus.ogg": "",
- "city.ogg": "",
"clam.ogg": "малюск",
"clap.ogg": "пляск",
"class.ogg": "клас",
"claw.ogg": "кіпцюр",
"clay.ogg": "гліна",
"clean.ogg": "чысты",
- "cleaning_lady.ogg": "",
"cliff.ogg": "скала",
"climb.ogg": "лезьці",
"clock.ogg": "гадзіннік",
"cloth.ogg": "тканіна",
- "clothes_hanger.ogg": "",
"cloud.ogg": "воблака",
- "cloudy.ogg": "",
- "clover.ogg": "",
"clown.ogg": "клоун",
"coach.ogg": "трэнер",
- "coast.ogg": "",
"coat.ogg": "кажух",
- "cobra.ogg": "",
- "coconut.ogg": "",
- "cod.ogg": "",
- "coffee.ogg": "",
"coin.ogg": "манета",
"cold.ogg": "халодны",
"color.ogg": "колер",
- "colt.ogg": "",
"comb.ogg": "грабянец",
"cone.ogg": "конус",
"cookie.ogg": "печыва",
- "cork.ogg": "",
"corn.ogg": "кукуруза",
"couch.ogg": "канапа",
- "cough.ogg": "",
- "couple.ogg": "",
"cow.ogg": "карова",
"cowboy.ogg": "пастух",
"crab.ogg": "краб",
- "cradle.ogg": "",
- "craft.ogg": "",
"crawl.ogg": "поўзаць",
"crazy.ogg": "шалёны",
- "creek.ogg": "",
- "crepe.ogg": "",
"crib.ogg": "калыска",
- "criminal.ogg": "",
"croak.ogg": "крумкаць",
"crocodile.ogg": "кракадзіл",
- "cross.ogg": "",
"crow.ogg": "крумкач",
"crown.ogg": "карона",
"crumb.ogg": "крошка",
"crust.ogg": "скарынка",
"cry.ogg": "крык",
- "crystal.ogg": "",
"cube.ogg": "куб",
"cucumber.ogg": "агурок",
- "curtain.ogg": "",
"cut.ogg": "адрэзаць",
"cute.ogg": "мілы",
"dad.ogg": "бацька",
- "daffodil.ogg": "",
- "daisy.ogg": "",
- "dam.ogg": "",
"dance.ogg": "танец",
- "dandelion.ogg": "",
- "danger.ogg": "небяспека",
- "dark.ogg": "",
- "dart_board.ogg": "",
- "date_fruit.ogg": "",
- "deer.ogg": "",
"den.ogg": "логва",
- "desert.ogg": "",
"desk.ogg": "стол",
- "dessert.ogg": "",
- "diamond.ogg": "",
"dig.ogg": "капаць",
"dirt.ogg": "бруд",
"dirty.ogg": "брудны",
"dish.ogg": "талерка",
- "dishcloth.ogg": "",
"dive.ogg": "апусканне",
- "doctor.ogg": "",
- "doe.ogg": "",
"dog.ogg": "сабака",
- "doll.ogg": "",
- "dolphin.ogg": "",
- "domino.ogg": "",
"door.ogg": "дзверы",
- "doormat.ogg": "",
"dot.ogg": "кропка",
- "doughnut.ogg": "",
- "dove.ogg": "",
"dragon.ogg": "цмок",
- "dragonfly.ogg": "",
- "drank.ogg": "трунак",
"draw.ogg": "маляваць",
- "drawer.ogg": "",
"dream.ogg": "мара",
"dress.ogg": "сукенка",
"drink.ogg": "піць",
- "drinking.ogg": "",
- "drip.ogg": "",
"drive.ogg": "везці",
- "drool.ogg": "",
"drum.ogg": "бубен",
- "dry.ogg": "",
"duck.ogg": "вутка",
- "duck_mother.ogg": "",
"dune.ogg": "выдма",
- "dwarf.ogg": "",
- "eagle.ogg": "",
"ear.ogg": "вуха",
"earth.ogg": "зямля",
"eat.ogg": "есці",
- "egg.ogg": "",
- "eggplant.ogg": "",
- "elbow.ogg": "",
- "electrician.ogg": "",
- "elk.ogg": "",
"empty.ogg": "пусты",
- "engine.ogg": "",
- "engineer.ogg": "",
- "eraser.ogg": "",
"explore.ogg": "даследаваць",
- "eyelash.ogg": "",
- "eyes.ogg": "",
"face.ogg": "твар",
"fair.ogg": "кірмаш",
- "fairy.ogg": "",
- "fall_down.ogg": "",
- "fall_season.ogg": "",
- "family.ogg": "",
+ "fall.ogg": "упасці",
"fan.ogg": "аматар",
"farm.ogg": "ферма",
- "farmer.ogg": "",
"fat.ogg": "тлушч",
- "faucet.ogg": "",
- "fawn.ogg": "",
"feast.ogg": "feast",
- "feather.ogg": "",
- "feed.ogg": "",
- "feet.ogg": "ступні",
- "fell.ogg": "упасці",
- "femur.ogg": "",
"fetch.ogg": "атрымліваць",
- "fig.ogg": "",
"fin.ogg": "плаўнік",
"find.ogg": "шукаць",
- "finger.ogg": "",
"fire.ogg": "aгонь",
- "fire_extinguisher.ogg": "",
- "fireman.ogg": "",
"fish.ogg": "рыба",
- "fisherman.ogg": "",
"fist.ogg": "кулак",
- "flacon.ogg": "",
"flag.ogg": "сцяг",
"flame.ogg": "полымя",
- "flamingo.ogg": "",
"flash.ogg": "успышка",
"flat.ogg": "пляскаты",
"flies.ogg": "жамяра",
- "flight.ogg": "",
"float.ogg": "паплавок",
"flour.ogg": "падлога",
"flower.ogg": "кветка",
- "fluff.ogg": "",
"flute.ogg": "флейта",
"fly.ogg": "муха",
- "foam.ogg": "",
- "food.ogg": "ежа",
"foot.ogg": "ступня",
- "forest.ogg": "",
"fork.ogg": "відэлец",
"fountain.ogg": "фантан",
"fox.ogg": "лісіца",
"freeze.ogg": "здранцвець",
"friend.ogg": "сябар",
- "fries.ogg": "",
"frog.ogg": "жаба",
"front.ogg": "пярэдні",
- "frown.ogg": "пануры",
"fruit.ogg": "садавіна",
"fudge.ogg": "памадка",
"full.ogg": "поўны",
- "fun.ogg": "весялосць",
"fur.ogg": "футра",
"game.ogg": "гульня",
- "garage.ogg": "",
"garden.ogg": "сад",
- "garlic.ogg": "",
"gem.ogg": "пацерка",
"giant.ogg": "волат",
"gift.ogg": "падарунак",
"giraffe.ogg": "жыраф",
"girl.ogg": "дзяўчына",
"glass.ogg": "шкло",
- "glasses.ogg": "",
"glove.ogg": "пальчатка",
"glue.ogg": "клей",
"gnome.ogg": "гном",
"goat.ogg": "каза",
- "golden.ogg": "",
- "golf.ogg": "",
- "goose.ogg": "",
- "gorilla.ogg": "",
- "grain.ogg": "",
- "grandmother.ogg": "",
- "grape.ogg": "",
- "grapefruit.ogg": "",
"grass.ogg": "трава",
"grave.ogg": "магіла",
"gray.ogg": "шэры",
"green.ogg": "зялёны",
- "grill.ogg": "",
"grin.ogg": "усмешка",
"ground.ogg": "грунт",
"growl.ogg": "рык",
- "guignol.ogg": "",
- "guinea_pig.ogg": "",
"gum.ogg": "жуйка",
"hair.ogg": "валасы",
- "hair_dryer.ogg": "",
- "half.ogg": "",
- "ham.ogg": "",
- "hammer.ogg": "",
"hand.ogg": "рука",
- "handlebar.ogg": "",
"happy.ogg": "шчаслівы",
- "harp.ogg": "",
"hat.ogg": "капялюш",
"hatch.ogg": "прахон",
"hay.ogg": "сена",
"head.ogg": "галава",
"hear.ogg": "чуць",
"heat.ogg": "спёка",
- "hedge.ogg": "",
- "hedgehog.ogg": "",
- "heel.ogg": "",
- "helmet.ogg": "",
"hen.ogg": "курка",
"herd.ogg": "статак",
"high.ogg": "высокі",
"hike.ogg": "паход",
- "hill.ogg": "",
"hip.ogg": "бядро",
- "hippopotamus.ogg": "",
"hit.ogg": "удар",
- "hive.ogg": "",
- "hockey.ogg": "",
"hole.ogg": "дзірка",
"home.ogg": "дом",
"hook.ogg": "крук",
"hop.ogg": "скок",
- "horse.ogg": "",
"hose.ogg": "панчохі",
- "hospital.ogg": "",
"hot.ogg": "гарачы",
- "hot_dog.ogg": "",
"hound.ogg": "гончая",
- "house.ogg": "",
"howl.ogg": "выццё",
"hug.ogg": "абдымаць",
"huge.ogg": "велізарны",
- "hummingbird.ogg": "",
- "hunchback.ogg": "",
"hunter.ogg": "паляўнічы",
- "husband.ogg": "",
"hut.ogg": "хаціна",
- "hyena.ogg": "",
"ice.ogg": "лёд",
- "iceberg.ogg": "",
- "iguana.ogg": "",
- "ill.ogg": "",
"ink.ogg": "атрамант",
- "island.ogg": "",
- "jacket.ogg": "",
- "jaguar.ogg": "",
- "jam.ogg": "",
- "jay.ogg": "",
- "jelly.ogg": "",
- "jellyfish.ogg": "",
"jewel.ogg": "каштоўнасць",
- "job.ogg": "",
- "jockey.ogg": "",
"jog.ogg": "бег",
"judge.ogg": "cудзіць",
- "judo.ogg": "",
- "juggler.ogg": "",
"juice.ogg": "сок",
"jump.ogg": "скакаць",
- "kangaroo.ogg": "",
- "keel.ogg": "",
- "kernel.ogg": "",
- "keyboard.ogg": "",
- "kimono.ogg": "",
- "king.ogg": "",
- "kiss.ogg": "",
- "kitchen.ogg": "",
- "kite.ogg": "",
- "kitten.ogg": "",
- "kiwi.ogg": "",
"knee.ogg": "калена",
"kneel.ogg": "кленчыць",
"knife.ogg": "нож",
"knight.ogg": "рыцар",
"knit.ogg": "вязаць",
"knot.ogg": "вузел",
- "koala.ogg": "",
"lad.ogg": "драбіны",
- "lady.ogg": "",
- "ladybug.ogg": "",
"lake.ogg": "возера",
- "lama.ogg": "",
"lamb.ogg": "ягня",
"lamp.ogg": "лямпа",
"land.ogg": "надзел",
"lane.ogg": "сцежка",
"lap.ogg": "каленькі",
- "lasso.ogg": "",
- "laugh.ogg": "",
- "lava.ogg": "",
"lawn.ogg": "газон",
- "lawyer.ogg": "",
- "leaf.ogg": "",
"ledge.ogg": "падваконне",
- "leek.ogg": "",
"left.ogg": "левы",
- "leg.ogg": "",
- "leg_animal.ogg": "",
- "lemon.ogg": "",
- "lemonade.ogg": "",
- "lemur.ogg": "",
- "leopard.ogg": "",
- "lettuce.ogg": "",
- "librarian.ogg": "",
"lick.ogg": "лізаць",
"lid.ogg": "накрыўка",
"lift.ogg": "ліфт",
"light.ogg": "святло",
- "lighthouse.ogg": "",
- "lightning.ogg": "",
- "lilac.ogg": "",
"lime.ogg": "вапна",
"line.ogg": "радок",
"link.ogg": "спасылка",
- "lion.ogg": "",
- "lion_cub.ogg": "",
"lip.ogg": "губа",
"liquid.ogg": "вадкасць",
- "lizard.ogg": "",
- "lobster.ogg": "",
"log.ogg": "бервяно",
"look.ogg": "выгляд",
"lunch.ogg": "падабед",
"mad.ogg": "вар'ят",
"magic.ogg": "чараўніцтва",
- "magnet.ogg": "",
- "magnifying_glass.ogg": "",
- "magpie.ogg": "",
- "mail.ogg": "",
- "man.ogg": "",
"mane.ogg": "грыва",
- "mango.ogg": "",
"map.ogg": "мапа",
- "maple.ogg": "",
- "marble.ogg": "",
- "mashed_potatoes.ogg": "",
"mask.ogg": "маска",
- "mast.ogg": "",
"mat.ogg": "дыванок",
"match.ogg": "запалка",
- "mate.ogg": "",
- "mattress.ogg": "",
- "mauve.ogg": "",
- "meal.ogg": "",
- "meat.ogg": "",
- "mechanic.ogg": "",
- "medal.ogg": "",
"meet.ogg": "знаёміцца",
- "melon.ogg": "",
- "men.ogg": "мужчыны",
- "merry-go-round.ogg": "",
"mice.ogg": "мышы",
- "microphone.ogg": "",
- "milk.ogg": "",
- "mill.ogg": "",
- "mimosa.ogg": "",
- "mirror.ogg": "",
- "mixer.ogg": "",
"mole.ogg": "крот",
- "mom.ogg": "",
- "moon.ogg": "",
- "moose.ogg": "",
"mop.ogg": "швабра",
- "mosque.ogg": "",
"mosquito.ogg": "камар",
- "mother.ogg": "",
- "motorcycle.ogg": "",
- "mountain.ogg": "",
- "mouse.ogg": "",
"mouth.ogg": "рот",
- "movie.ogg": "",
- "mower.ogg": "",
"mud.ogg": "жужала",
- "mug.ogg": "",
"mule.ogg": "мул",
- "muscle.ogg": "",
"mushroom.ogg": "грыб",
- "music.ogg": "",
- "musician.ogg": "",
- "naked.ogg": "",
- "nap.ogg": "",
- "navel.ogg": "",
"neck.ogg": "шыя",
- "necklace.ogg": "",
- "needle.ogg": "",
"nest.ogg": "гняздо",
"net.ogg": "сетка",
- "newspaper.ogg": "",
"night.ogg": "ноч",
- "nightgown.ogg": "",
"nose.ogg": "нос",
- "nostril.ogg": "",
- "notebook.ogg": "",
- "number.ogg": "",
- "nun.ogg": "",
- "nurse.ogg": "",
- "nurse_male.ogg": "",
"nut.ogg": "арэх",
"oar.ogg": "вясло",
"ocean.ogg": "акіян",
- "office.ogg": "",
- "olive.ogg": "",
"on.ogg": "на",
- "onion.ogg": "",
- "open.ogg": "",
- "opossum.ogg": "",
"orange-color.ogg": "памаранчавы",
"orange.ogg": "апельсін",
- "orchid.ogg": "",
- "ostrich.ogg": "",
- "otter.ogg": "",
"owl.ogg": "сава",
"ox.ogg": "вол",
- "oyster.ogg": "",
- "pacifier.ogg": "",
"page.ogg": "старонка",
"pair.ogg": "пара",
- "pajamas.ogg": "",
- "pal.ogg": "",
- "palm_tree.ogg": "",
"pan.ogg": "патэльня",
- "panda.ogg": "",
- "panther.ogg": "",
- "panties.ogg": "",
- "pants.ogg": "",
- "papaya.ogg": "",
- "paper.ogg": "",
- "parachute.ogg": "",
- "parakeet.ogg": "",
- "parrot.ogg": "",
- "patch.ogg": "",
"path.ogg": "шлях",
"paw.ogg": "лапа",
- "pea.ogg": "",
"peach.ogg": "персік",
- "peacock.ogg": "",
- "peak.ogg": "",
- "pear.ogg": "",
- "pearl.ogg": "",
- "peck.ogg": "",
- "pedal.ogg": "",
- "pelican.ogg": "",
"pen.ogg": "асадка",
"pencil.ogg": "аловак",
- "peony.ogg": "",
- "people.ogg": "",
- "pepper.ogg": "",
- "peppers.ogg": "",
- "pet.ogg": "",
- "petal.ogg": "",
- "petite.ogg": "",
- "phone.ogg": "",
- "piano.ogg": "",
"picture.ogg": "малюнак",
- "pie.ogg": "",
"pig.ogg": "свіння",
- "pigeon.ogg": "",
- "pill.ogg": "",
- "pillow.ogg": "",
- "pilot.ogg": "",
- "pine.ogg": "",
- "pine_cone.ogg": "",
"pink.ogg": "ружовы",
- "pip.ogg": "",
- "pipe.ogg": "",
- "piranha.ogg": "",
- "pirate.ogg": "",
- "pizza.ogg": "",
"plane.ogg": "лятак",
- "planet.ogg": "",
"plant.ogg": "расліна",
"plate.ogg": "талерка",
"play.ogg": "п'еса",
- "pliers.ogg": "",
- "plow.ogg": "",
"plum.ogg": "сліва",
- "plumber.ogg": "",
- "pocket.ogg": "",
- "pod.ogg": "",
- "pole.ogg": "",
- "police.ogg": "",
- "pompon.ogg": "",
- "pond.ogg": "",
- "pony.ogg": "",
- "pool.ogg": "",
- "pop.ogg": "",
- "pope.ogg": "",
- "porthole.ogg": "",
- "post.ogg": "",
- "pot.ogg": "",
- "potato.ogg": "",
- "pounce.ogg": "",
- "president.ogg": "",
"pretty.ogg": "прыгожы",
"price.ogg": "цана",
- "priest.ogg": "",
"prince.ogg": "князь",
"princess.ogg": "княжна",
- "prison.ogg": "",
- "prisoner.ogg": "",
- "prize.ogg": "",
- "pug.ogg": "",
- "pull.ogg": "",
- "pullover.ogg": "",
- "pumpkin.ogg": "",
"puppy.ogg": "шчаня",
- "pyramid.ogg": "",
- "quarrel.ogg": "",
"queen.ogg": "каралева",
"question.ogg": "пытанне",
- "quilt.ogg": "",
- "quiz.ogg": "",
- "rabbit.ogg": "",
- "rabbit_baby.ogg": "",
- "race.ogg": "",
- "radio.ogg": "",
- "radish.ogg": "",
- "raft.ogg": "",
- "rag.ogg": "",
- "rage.ogg": "",
- "rain.ogg": "",
- "raincoat.ogg": "",
- "rake.ogg": "",
- "ramp.ogg": "",
- "ran.ogg": "",
- "raspberry.ogg": "",
"rat.ogg": "пацук",
- "razor.ogg": "",
"read.ogg": "чытаць",
"red.ogg": "чырвоны",
- "reptile.ogg": "",
- "rhinoceros.ogg": "",
"rice.ogg": "рыс",
- "ride.ogg": "",
- "rifle.ogg": "",
"right.ogg": "правы",
- "rip.ogg": "",
- "rise.ogg": "",
- "river.ogg": "",
- "road.ogg": "",
- "roast.ogg": "",
- "robe.ogg": "",
- "robot.ogg": "",
- "rock.ogg": "",
- "rocket.ogg": "",
- "rolling_pin.ogg": "",
"roof.ogg": "дах",
- "room.ogg": "",
- "root.ogg": "",
"rope.ogg": "вяроўка",
"rose.ogg": "ружа",
"round.ogg": "круглы",
- "rowing.ogg": "",
"royal.ogg": "каралеўскі",
- "rug.ogg": "",
"run.ogg": "бегчы",
"sad.ogg": "сумны",
- "saddle.ogg": "",
- "sail.ogg": "",
- "sailor.ogg": "",
- "salamander.ogg": "",
- "salmon.ogg": "",
"sand.ogg": "пясок",
- "sandals.ogg": "",
"sandwich.ogg": "бутэрброд",
- "sash.ogg": "",
- "sat.ogg": "",
"sauce.ogg": "поліўка",
- "sausage.ogg": "",
- "scale.ogg": "",
- "scar.ogg": "",
- "scared.ogg": "",
"scarf.ogg": "шалік",
"school.ogg": "школа",
- "school_bag.ogg": "",
"science.ogg": "навука",
- "scissors.ogg": "",
- "scorpion.ogg": "",
- "scratch.ogg": "",
- "scream.ogg": "",
- "screw.ogg": "",
- "screwdriver.ogg": "",
- "scribble.ogg": "",
- "sea.ogg": "",
- "seat.ogg": "",
"see.ogg": "бачыць",
"seed.ogg": "насенне",
- "shadow.ogg": "",
- "shake.ogg": "",
"shark.ogg": "акула",
- "shave.ogg": "",
- "shed.ogg": "",
- "sheep.ogg": "",
"shelf.ogg": "паліца",
- "shell.ogg": "",
"ship.ogg": "карабель",
"shirt.ogg": "кашуля",
"shoe.ogg": "абутак",
- "shoelace.ogg": "",
"shop.ogg": "крама",
- "shore.ogg": "",
"short.ogg": "кароткі",
- "shovel.ogg": "",
"shower.ogg": "душ",
- "shrimp.ogg": "",
- "shrub.ogg": "",
- "shut.ogg": "",
- "shutter.ogg": "",
"sick.ogg": "хворы",
- "sidewalk.ogg": "",
"sign.ogg": "пазнака",
"sing.ogg": "спяваць",
- "sink.ogg": "",
- "sip.ogg": "",
- "sister.ogg": "",
"sit.ogg": "сядзець",
- "skate.ogg": "",
- "skeleton.ogg": "",
"ski.ogg": "лыжы",
- "skimmer.ogg": "",
"skin.ogg": "скура",
- "skirt.ogg": "",
- "skunk.ogg": "",
"sky.ogg": "нябёсы",
- "slam.ogg": "",
- "sled.ogg": "",
"sleep.ogg": "спаць",
"sleeve.ogg": "рукаў",
- "sleigh.ogg": "",
"slide.ogg": "коўзаць",
- "slim.ogg": "",
- "slime.ogg": "",
- "slippers.ogg": "",
- "slope.ogg": "",
- "sloppy.ogg": "",
- "slot.ogg": "",
- "sloth.ogg": "",
- "slug.ogg": "",
"small.ogg": "малы",
"smell.ogg": "пах",
"smile.ogg": "усмешка",
- "smock.ogg": "",
"smoke.ogg": "дым",
- "smooch.ogg": "",
- "snack.ogg": "",
- "snail.ogg": "",
"snake.ogg": "змяя",
- "sneaker.ogg": "",
- "sniff.ogg": "",
"snow.ogg": "снег",
- "soap.ogg": "",
- "sob.ogg": "",
- "sock.ogg": "",
- "soldier.ogg": "",
- "sole.ogg": "",
- "sole_shoe.ogg": "",
- "son.ogg": "",
- "soup.ogg": "",
- "spade.ogg": "",
- "spaghetti.ogg": "",
- "spark.ogg": "",
- "sparrow.ogg": "",
- "spatula.ogg": "",
- "speak.ogg": "",
"spear.ogg": "дзіда",
- "spice.ogg": "",
"spider.ogg": "павук",
- "spider_web.ogg": "",
"spike.ogg": "пік",
- "spill.ogg": "",
- "spinach.ogg": "",
- "spine.ogg": "",
- "spinning_top.ogg": "",
- "splash.ogg": "",
- "splatter.ogg": "",
- "sponge.ogg": "",
- "spool.ogg": "",
"spoon.ogg": "лыжка",
"sport.ogg": "спорт",
"spot.ogg": "пляма",
- "spray.ogg": "",
- "spread.ogg": "",
"spring.ogg": "вясна",
- "spring_season.ogg": "",
- "sprinkle.ogg": "",
"square.ogg": "квадрат",
- "squash.ogg": "",
- "squat.ogg": "",
- "squid.ogg": "",
"squirrel.ogg": "вавёрка",
- "squirt.ogg": "",
- "stack.ogg": "",
"stage.ogg": "сцэна",
- "staircase.ogg": "",
- "stamp.ogg": "",
"stand.ogg": "стаяць",
"star.ogg": "зорка",
"stare.ogg": "утаропіцца",
- "starfish.ogg": "",
- "steak.ogg": "",
- "steam.ogg": "",
- "steep.ogg": "",
- "steeple.ogg": "",
- "stem.ogg": "",
- "step.ogg": "",
- "stew.ogg": "",
"stick.ogg": "кіёк",
- "sting.ogg": "",
- "stinky.ogg": "",
- "stitch.ogg": "",
- "stomach.ogg": "",
"stone.ogg": "камень",
"stop.ogg": "спыніцца",
"store.ogg": "сховішча",
- "stove.ogg": "",
"straight.ogg": "просты",
- "strainer.ogg": "",
- "straw.ogg": "",
"strawberry.ogg": "трускаўка",
"stream.ogg": "цячэнне",
"street.ogg": "вуліца",
- "stretch.ogg": "",
"string.ogg": "струна",
"stripe.ogg": "палоска",
"strong.ogg": "дужы",
- "student.ogg": "",
"study.ogg": "вучыцца",
- "stump.ogg": "",
- "sugar.ogg": "",
"suit.ogg": "касцюм",
- "suitcase.ogg": "",
"summer.ogg": "лета",
- "summit.ogg": "",
"sun.ogg": "сонца",
"swan.ogg": "галубок",
"sweat.ogg": "салодкі",
- "sweatshirt.ogg": "",
"swim.ogg": "плаваць",
- "table.ogg": "",
- "tablecloth.ogg": "",
- "tadpole.ogg": "",
- "tag.ogg": "",
- "tail.ogg": "",
"tall.ogg": "высокі",
- "tape_measure.ogg": "",
- "taxi.ogg": "",
"teach.ogg": "вучыць",
"teacher.ogg": "настаўнік",
"tear.ogg": "сляза",
- "teddy.ogg": "",
"teeth.ogg": "зубы",
- "television.ogg": "",
- "temple.ogg": "",
- "tennis.ogg": "",
- "tent.ogg": "",
- "text.ogg": "",
"thick.ogg": "тоўсты",
- "thief.ogg": "",
- "thigh.ogg": "",
"think.ogg": "думаць",
"thread.ogg": "нітка",
"throat.ogg": "горла",
"throw.ogg": "кідаць",
- "thumb.ogg": "",
- "tick.ogg": "",
- "ticket.ogg": "",
- "tiger.ogg": "",
"time.ogg": "час",
- "tin.ogg": "",
- "tire.ogg": "",
"tired.ogg": "стомлены",
- "tissue.ogg": "",
- "toad.ogg": "",
- "toaster.ogg": "",
- "toe.ogg": "",
"toilet.ogg": "прыбіральня",
- "tomatoe.ogg": "",
- "tongs.ogg": "",
- "tongue.ogg": "",
"tool.ogg": "прылада",
"top.ogg": "верх",
"torch.ogg": "ліхтар",
"touch.ogg": "дотык",
"towel.ogg": "рушнік",
"toy.ogg": "цацка",
- "trail.ogg": "",
"train.ogg": "цягнік",
- "train_station.ogg": "",
"trap.ogg": "пастка",
"trash.ogg": "смецце",
- "tray.ogg": "",
"treat.ogg": "лячэнне",
"tree.ogg": "дрэва",
- "triangle.ogg": "",
- "tribe.ogg": "",
- "trip.ogg": "",
"truck.ogg": "грузавік",
"tube.ogg": "лямпачка",
- "tulip.ogg": "",
"tune.ogg": "мелодыя",
- "turkey.ogg": "",
- "turnip.ogg": "",
- "turtle.ogg": "",
- "tusk.ogg": "",
- "twin_boys.ogg": "",
- "twin_girls.ogg": "",
- "umbrella.ogg": "",
"under.ogg": "пад",
- "uniform.ogg": "",
"van.ogg": "фургон",
- "vapor.ogg": "",
- "vase.ogg": "",
- "vegetable.ogg": "",
- "vein.ogg": "",
- "verdure.ogg": "",
- "vest.ogg": "",
- "vet.ogg": "",
- "viper.ogg": "",
- "vowel.ogg": "",
- "vulture.ogg": "",
- "wag.ogg": "",
"walk.ogg": "хадзіць",
- "wall.ogg": "",
- "walnut.ogg": "",
- "wart.ogg": "",
"wash.ogg": "мыць",
- "wasp.ogg": "",
"watch.ogg": "назіраць",
"water.ogg": "вада",
- "wave.ogg": "",
- "wedding.ogg": "",
- "wedge.ogg": "",
- "weight.ogg": "",
"wet.ogg": "мокры",
- "whale.ogg": "",
- "wheat.ogg": "",
"wheel.ogg": "кола",
- "whisk.ogg": "",
"whisper.ogg": "шаптаць",
"white.ogg": "белы",
- "wide.ogg": "",
- "wife.ogg": "",
- "wig.ogg": "",
"win.ogg": "перамагаць",
"wind.ogg": "вецер",
- "window.ogg": "",
- "window_glass.ogg": "",
"wing.ogg": "крыло",
- "winter.ogg": "",
- "wolf.ogg": "",
- "woman.ogg": "",
"wood.ogg": "лес",
- "word.ogg": "",
- "worker.ogg": "",
- "world.ogg": "",
- "wreath.ogg": "",
- "wrench.ogg": "",
"wrist.ogg": "запясце",
"write.ogg": "пісаць",
- "yarn.ogg": "",
- "yellow.ogg": "",
- "yogurt.ogg": "",
- "yum.ogg": "",
- "zebra.ogg": "",
- "zipper.ogg": "",
"zoo.ogg": "заапарк"
-}
+}
\ No newline at end of file
diff --git a/src/activities/lang/resource/content-br.json b/src/activities/lang/resource/content-br.json
new file mode 100644
index 000000000..ca26fc38b
--- /dev/null
+++ b/src/activities/lang/resource/content-br.json
@@ -0,0 +1,1092 @@
+{
+ "10.ogg": "dek",
+ "11.ogg": "unnek",
+ "12.ogg": "daouzek",
+ "16.ogg": "c'hwezek",
+ "U0030.ogg": "zero",
+ "U0031.ogg": "unan",
+ "U0032.ogg": "daou",
+ "U0033.ogg": "tri",
+ "U0034.ogg": "pevar",
+ "U0035.ogg": "pemp",
+ "U0036.ogg": "c'hwec'h",
+ "U0037.ogg": "seizh",
+ "U0038.ogg": "eizh",
+ "U0039.ogg": "nav",
+ "accountant.ogg": "ur c'hoñcher",
+ "ache.ogg": "un taol-poan",
+ "acorn.ogg": "ur vezenn",
+ "actor.ogg": "un aktour",
+ "air_horn.ogg": "ur c'horn",
+ "alarmclock.ogg": "ur munuter",
+ "alligator.ogg": "un aligator",
+ "alphabet.ogg": "ul lizherenneg",
+ "anchor.ogg": "un eor",
+ "angel.ogg": "un ael",
+ "angry.ogg": "kounnaret",
+ "animal.ogg": "ul loen",
+ "ankle.ogg": "an ibil-troad",
+ "ant.ogg": "ur verienenn",
+ "anteater.ogg": "ur merionaer",
+ "antelope.ogg": "un antilopenn",
+ "apple.ogg": "un aval",
+ "apple_tree.ogg": "ur wezenn avaloù",
+ "appliance.ogg": "un ardivink",
+ "apricot.ogg": "un abrikezenn",
+ "arm.ogg": "ar vrec'h",
+ "armchair.ogg": "ur gador-vrec'h",
+ "artichoke.ogg": "un artichaodenn",
+ "artist.ogg": "un arzour",
+ "asparagus.ogg": "un asperjezenn",
+ "astronaut.ogg": "un egoraer",
+ "athlete.ogg": "ur sportour",
+ "avocado.ogg": "un avoukezenn",
+ "ax.ogg": "ur vouc'hal",
+ "baby_bottle.ogg": "ur vured",
+ "back.ogg": "ar c'hein",
+ "badge.ogg": "ur badj",
+ "bag.ogg": "ur sac'h",
+ "bait.ogg": "ur vouedenn",
+ "balance.ogg": "ur valañs",
+ "bald.ogg": "moal",
+ "ball.ogg": "ur vell",
+ "ball_of_yarn.ogg": "ur bellenn neud",
+ "ball_soccer.ogg": "ur vell-droad",
+ "ballet.ogg": "dañs",
+ "bank.ogg": "ur bank",
+ "banker_female.ogg": "ur plac'h ti-bank",
+ "bark.ogg": "harzhal",
+ "barn.ogg": "ur c'hrañch",
+ "bat.ogg": "un askell-groc'hen",
+ "bath.ogg": "ur gibell",
+ "bathing_suit.ogg": "ur sae gouronkañ",
+ "bay.ogg": "un hugenn",
+ "beach.ogg": "un draezhenn",
+ "bean.ogg": "ur favenn",
+ "bear.ogg": "un arzh",
+ "beard.ogg": "ar barv",
+ "beat.ogg": "skeiñ",
+ "beaver.ogg": "un avank",
+ "bed.ogg": "ur gwele",
+ "bedroom.ogg": "ur gambr",
+ "bee.ogg": "ur wenanenn",
+ "beetle.ogg": "ur c'hwil",
+ "beg.ogg": "chipañ",
+ "behind.ogg": "a-dreñv",
+ "bell.ogg": "ur c'hloc'h",
+ "belly.ogg": "ar c'hof",
+ "bench.ogg": "ur bank",
+ "bib.ogg": "un divabouzouer",
+ "big.ogg": "bras",
+ "big_top.ogg": "un uhelenn",
+ "bike.ogg": "ur velo",
+ "bird.ogg": "un evn",
+ "bit.ogg": "un tamm",
+ "bite.ogg": "dantañ",
+ "black.ogg": "du",
+ "blackberry.ogg": "mouar",
+ "blackbird.ogg": "ur voualc'h",
+ "blade.ogg": "ul lavnenn",
+ "blind.ogg": "dall",
+ "blink.ogg": "gwignal",
+ "block.ogg": "ur blok",
+ "blond.ogg": "melegan",
+ "blue.ogg": "glas",
+ "blueberry.ogg": "lus",
+ "blush.ogg": "ur ruziañ",
+ "board.ogg": "ur plankenn",
+ "boat.ogg": "ur vag",
+ "boil.ogg": "birviñ",
+ "bolt.ogg": "ur prenn",
+ "bomb.ogg": "ur vombezenn",
+ "bone.ogg": "un askorn",
+ "book.ogg": "ul levr",
+ "bookcase.ogg": "un armel-levrioù",
+ "bottom.ogg": "feskennoù",
+ "box.ogg": "ur vouest",
+ "boxer.ogg": "ur bokser",
+ "boy.ogg": "ur paotr",
+ "braid.ogg": "ur blezhenn",
+ "brain.ogg": "an empenn",
+ "branch.ogg": "ur skourr",
+ "bread.ogg": "bara",
+ "break.ogg": "terriñ",
+ "breast.ogg": "ar bruched",
+ "brick.ogg": "brikennoù",
+ "bricklayer.ogg": "ur masoner",
+ "bride.ogg": "ur bried",
+ "bridge.ogg": "ur pont",
+ "bright.ogg": "sklaer",
+ "broccoli.ogg": "ur penn-brikoli",
+ "brother.ogg": "ur breur",
+ "brown.ogg": "gell",
+ "brush.ogg": "ur broust",
+ "bubble.ogg": "ur glogorenn",
+ "bucket.ogg": "ur c'helorn",
+ "bud.ogg": "ur vroñsenn",
+ "buffalo.ogg": "ur bizon",
+ "bug.ogg": "un amprevan",
+ "bulb.ogg": "ur glogorenn",
+ "bull.ogg": "un tarv",
+ "bump.ogg": "ur bos",
+ "bun.ogg": "bara dous",
+ "bus.ogg": "ur c'harr-boutin",
+ "bush.ogg": "ur vodenn",
+ "butcher.ogg": "ur c'higer",
+ "butter.ogg": "amann",
+ "butterfly.ogg": "ur valafenn",
+ "button.ogg": "ur bouton",
+ "cabbage.ogg": "ur gaolenn",
+ "cabin.ogg": "ur gabinenn",
+ "cacao.ogg": "kakao",
+ "cactus.ogg": "ur gaktuzenn",
+ "cage.ogg": "ur gaoued",
+ "cake.ogg": "ur wastell",
+ "call.ogg": "gervel",
+ "camel.ogg": "ur c'hañval",
+ "camera.ogg": "ur c'hamera",
+ "camp.ogg": "ar c'hampiñ",
+ "can.ogg": "ur boubellenn",
+ "canary.ogg": "ur c'hanari",
+ "candle.ogg": "ur c'houlaouenn",
+ "candy.ogg": "ur madig",
+ "cane.ogg": "ur vazh-kamm",
+ "canoe.ogg": "ur c'hanoe",
+ "canon.ogg": "ur c'hanol",
+ "canyon.ogg": "ur c'hanion",
+ "cap.ogg": "ur boned",
+ "cape.ogg": "ur c'habell",
+ "car.ogg": "ur c'harr",
+ "carafe.ogg": "ur garafenn",
+ "card.ogg": "ur gartenn",
+ "carnival.ogg": "ar Meurlarjez",
+ "carpenter.ogg": "ur c'halvez",
+ "carpet.ogg": "un tapis",
+ "carrot.ogg": "ur garotezenn",
+ "cart.ogg": "ur garrigell",
+ "cash.ogg": "pezhioù moneiz",
+ "castle.ogg": "ur c'hastell",
+ "cat.ogg": "ur c'hazh",
+ "cat_female.ogg": "ur gazhez",
+ "catch.ogg": "tapout",
+ "caterpillar.ogg": "ur viskoulenn",
+ "cauldron.ogg": "ur chaodouron",
+ "cauliflower.ogg": "ur gaolenn-fleur",
+ "cave.ogg": "ur c'hav",
+ "cavern.ogg": "ur vougev",
+ "celery.ogg": "un achenn",
+ "centipede.ogg": "ur mil-kraban",
+ "cereal.ogg": "edaj",
+ "chain.ogg": "ur chadenn",
+ "chair.ogg": "ur gador",
+ "chalk.ogg": "krei",
+ "chameleon.ogg": "ur c'hameleon",
+ "chandelier.ogg": "ur c'hantoller",
+ "chat.ogg": "flapiñ",
+ "cheek.ogg": "ur jod",
+ "cheer.ogg": "strakal an daouarn",
+ "cheese.ogg": "fourmaj",
+ "chef.ogg": "ur chef",
+ "cherry.ogg": "kerez",
+ "chest.ogg": "ur c'hofr",
+ "chick.ogg": "ur pousin",
+ "chicken.ogg": "ur yarig",
+ "child.ogg": "ur bugel",
+ "chimney.ogg": "ur siminal",
+ "chimp.ogg": "ur chimpanze",
+ "chin.ogg": "un elgezh",
+ "chocolate.ogg": "chokolad",
+ "chop.ogg": "troc'hañ",
+ "chores.ogg": "labourioù an ti",
+ "christmas.ogg": "an Nedeleg",
+ "cigar.ogg": "ur segalenn",
+ "circus.ogg": "ur sirk",
+ "city.ogg": "ur gêr",
+ "clam.ogg": "ur bilorenn",
+ "clap.ogg": "stlakal",
+ "class.ogg": "ur c'hlas",
+ "claw.ogg": "skilf",
+ "clay.ogg": "pri",
+ "clean.ogg": "naetaat",
+ "cleaning_lady.ogg": "ur plac'h-ti",
+ "cliff.ogg": "un tornaod",
+ "climb.ogg": "pignat",
+ "clock.ogg": "un horolaj",
+ "cloth.ogg": "dilhad",
+ "clothes_hanger.ogg": "ur doug-dilhad",
+ "cloud.ogg": "ur goumoulenn",
+ "cloudy.ogg": "koumoulek",
+ "clover.ogg": "ur velchonenn",
+ "clown.ogg": "furlukin",
+ "coach.ogg": "ur gourdoner",
+ "coast.ogg": "un aod",
+ "coat.ogg": "ur vantell",
+ "cobra.ogg": "ur c'hobra",
+ "coconut.ogg": "ur graonenn-goko",
+ "cod.ogg": "ur voruenn",
+ "coffee.ogg": "kafe",
+ "coin.ogg": "ur pezh moneiz",
+ "cold.ogg": "yen",
+ "color.ogg": "liv",
+ "colt.ogg": "un ebeul",
+ "comb.ogg": "ur skribl",
+ "cone.ogg": "ur gernenn",
+ "cook.ogg": "keginañ",
+ "cookie.ogg": "kouign",
+ "cork.ogg": "ur stouv",
+ "corn.ogg": "ed",
+ "couch.ogg": "ur gourvezvank",
+ "cough.ogg": "pasaat",
+ "couple.ogg": "ur c'houblad",
+ "cow.ogg": "ur vuoc'h",
+ "cowboy.ogg": "ur c'howboy",
+ "crab.ogg": "ur c'hrank",
+ "cradle.ogg": "ur gwele-babig",
+ "craft.ogg": "ur vicher",
+ "crawl.ogg": "skrampañ",
+ "crazy.ogg": "foll",
+ "creek.ogg": "un ouf",
+ "crepe.ogg": "ur grampouezhenn",
+ "crib.ogg": "ur c'havell",
+ "croak.ogg": "koagal",
+ "crocodile.ogg": "ur c'hrokodil",
+ "cross.ogg": "ur groaz",
+ "crow.ogg": "ur vran",
+ "crown.ogg": "ur gurunenn",
+ "crumb.ogg": "bruzun",
+ "crust.ogg": "kreun",
+ "cry.ogg": "leñvañ",
+ "crystal.ogg": "ur strinkenn",
+ "cube.ogg": "ur c'hub",
+ "cucumber.ogg": "ur gokombrezenn",
+ "curtain.ogg": "ur rideoz",
+ "cut.ogg": "troc'hañ",
+ "cute.ogg": "moutig",
+ "dad.ogg": "un tad",
+ "daffodil.ogg": "ur foeonenn",
+ "daisy.ogg": "un tommheolig",
+ "dam.ogg": "ur stankell",
+ "dance.ogg": "dañsal",
+ "dandelion.ogg": "ur c'hwervizon",
+ "dart_board.ogg": "ur c'hoari biroùigoù",
+ "date_fruit.ogg": "un datezenn",
+ "deer.ogg": "ur c'harv",
+ "den.ogg": "un douarenn",
+ "desert.ogg": "un dezerzh",
+ "desk.ogg": "ur burev",
+ "dessert.ogg": "un dibenn-pred",
+ "diamond.ogg": "un diamant",
+ "dig.ogg": "kleuziañ",
+ "dirt.ogg": "loustoni",
+ "dirty.ogg": "lous",
+ "dish.ogg": "ur plad",
+ "dishcloth.ogg": "un torch",
+ "dive.ogg": "splujañ",
+ "doctor.ogg": "ur mezeg",
+ "doe.ogg": "un heizez",
+ "dog.ogg": "ur c'hi",
+ "doll.ogg": "ur boupinell",
+ "dolphin.ogg": "un delfin",
+ "domino.ogg": "dominoioù",
+ "door.ogg": "un nor",
+ "doormat.ogg": "un torch-treid",
+ "dot.ogg": "ur pik",
+ "doughnut.ogg": "ur bignezenn",
+ "dove.ogg": "ur goulm",
+ "dragon.ogg": "un aerouant",
+ "dragonfly.ogg": "un nadoz-aer",
+ "draw.ogg": "tresañ",
+ "drawer.ogg": "un diretenn",
+ "dream.ogg": "huñvreal",
+ "dress.ogg": "ur sae",
+ "drink.ogg": "un evaj",
+ "drip.ogg": "un dakenn",
+ "drive.ogg": "bleniañ",
+ "drool.ogg": "babouzat",
+ "drum.ogg": "un taboulin",
+ "dry.ogg": "sec'hañ",
+ "duck.ogg": "un houad",
+ "duck_mother.ogg": "un houadez",
+ "dune.ogg": "un tevenn",
+ "dwarf.ogg": "ur c'horr",
+ "eagle.ogg": "un erer",
+ "ear.ogg": "ur skouarn",
+ "earth.ogg": "douar",
+ "eat.ogg": "debriñ",
+ "egg.ogg": "ur vi",
+ "eggplant.ogg": "ur verjinezenn",
+ "elbow.ogg": "un ilin",
+ "electrician.ogg": "un tredaner",
+ "elk.ogg": "un elan",
+ "empty.ogg": "goullo",
+ "engine.ogg": "ur c'heflusker",
+ "engineer.ogg": "un ijinour",
+ "eraser.ogg": "ur c'homenn",
+ "explore.ogg": "ergerzhout",
+ "eyelash.ogg": "ur valvenn",
+ "eyes.ogg": "daoulagad",
+ "face.ogg": "un dremm",
+ "fair.ogg": "ur foar",
+ "fairy.ogg": "ur voudig",
+ "fall.ogg": "kouezhañ",
+ "fall_season.ogg": "an diskar-amzer",
+ "family.ogg": "ur familh",
+ "fan.ogg": "ur wenterez",
+ "farm.ogg": "un atant",
+ "farmer.ogg": "ur peizant",
+ "fat.ogg": "tev",
+ "faucet.ogg": "ur c'hog-dour",
+ "fawn.ogg": "ur menn-karv",
+ "fear.ogg": "un aon",
+ "feast.ogg": "ur fest",
+ "feather.ogg": "ur bluñvenn",
+ "feed.ogg": "magañ",
+ "femur.ogg": "gwerzhid ur vorzhed",
+ "fetch.ogg": "mont da gerc'hat",
+ "fig.ogg": "ur figezenn",
+ "fin.ogg": "un angell",
+ "find.ogg": "kavout",
+ "finger.ogg": "ur biz",
+ "fire.ogg": "tan",
+ "fire_extinguisher.ogg": "ur mouger-tan",
+ "fireman.ogg": "ur pomper",
+ "fish.ogg": "ur pesk",
+ "fisherman.ogg": "ur pesketaer",
+ "fist.ogg": "un dorn",
+ "flacon.ogg": "ur flask",
+ "flag.ogg": "ur banniel",
+ "flame.ogg": "flammenn",
+ "flamingo.ogg": "ur flammeg",
+ "flash.ogg": "ur gouloù godell",
+ "flat.ogg": "ranntiez",
+ "flies.ogg": "kelien",
+ "float.ogg": "flotañ",
+ "flour.ogg": "bleud",
+ "flower.ogg": "ur vleuñvenn",
+ "fluff.ogg": "un dumedenn",
+ "flute.ogg": "ur fleüt",
+ "fly.ogg": "nijal",
+ "foam.ogg": "spoum",
+ "foot.ogg": "un troad",
+ "forest.ogg": "koadeg",
+ "fork.ogg": "ur fourchetezenn",
+ "fountain.ogg": "ur feunteun",
+ "fox.ogg": "ul louarn",
+ "freeze.ogg": "skornañ",
+ "friend.ogg": "ur mignon",
+ "fries.ogg": "fritez",
+ "frog.ogg": "ur ran",
+ "front.ogg": "dirak",
+ "fruit.ogg": "ur frouezhenn",
+ "fudge.ogg": "ur garamellenn",
+ "full.ogg": "leun",
+ "fur.ogg": "ur feur",
+ "game.ogg": "ur c'hoari",
+ "garage.ogg": "ur c'harrdi",
+ "garden.ogg": "liorzh",
+ "garlic.ogg": "ur penn-kignen",
+ "gem.ogg": "ur maen-sked",
+ "giant.ogg": "ur ramz",
+ "gift.ogg": "ur prof",
+ "giraffe.ogg": "ur jirafenn",
+ "girl.ogg": "ur plac'h",
+ "glass.ogg": "ur werenn",
+ "glasses.ogg": "ur re lunedoù",
+ "glove.ogg": "ur vanegenn",
+ "glue.ogg": "peg",
+ "gnome.ogg": "ur c'horrigan",
+ "goat.ogg": "ur c'havr",
+ "golden.ogg": "alaouret",
+ "golf.ogg": "ar golf",
+ "goose.ogg": "ur waz",
+ "gorilla.ogg": "ur gorilh",
+ "grain.ogg": "greun",
+ "grandmother.ogg": "ur vamm-gozh",
+ "grape.ogg": "rezin",
+ "grapefruit.ogg": "ur bampelenn",
+ "grass.ogg": "geot",
+ "grave.ogg": "ur bez",
+ "gray.ogg": "griz",
+ "green.ogg": "gwer",
+ "grill.ogg": "ur c'hrilh",
+ "grin.ogg": "ur mousc'hoarzh",
+ "ground.ogg": "ul leur",
+ "growl.ogg": "krozal",
+ "guignol.ogg": "ur meurlarjez",
+ "guinea_pig.ogg": "ur razh-indez",
+ "gum.ogg": "gom-chaokat",
+ "hair.ogg": "blev",
+ "hair_dryer.ogg": "ur sec'her-blev",
+ "half.ogg": "hanter",
+ "ham.ogg": "morzhed-hoc'h",
+ "hamburger.ogg": "un hamburger",
+ "hammer.ogg": "ur morzhol",
+ "hand.ogg": "un dorn",
+ "handlebar.ogg": "ur varrenn-stur",
+ "happy.ogg": "laouen",
+ "harp.ogg": "un delenn",
+ "hat.ogg": "un tok",
+ "hatch.ogg": "dinodiñ",
+ "hay.ogg": "foenn",
+ "head.ogg": "ur penn",
+ "hear.ogg": "klevout",
+ "heat.ogg": "ur wrez",
+ "hedge.ogg": "ur c'harzh",
+ "hedgehog.ogg": "un avalaouer",
+ "heel.ogg": "ur seul",
+ "helmet.ogg": "un tokarn",
+ "hen.ogg": "ur yar",
+ "herd.ogg": "un tropell",
+ "high.ogg": "uhel",
+ "hike.ogg": "bale",
+ "hill.ogg": "ur run",
+ "hip.ogg": "ul lez",
+ "hippopotamus.ogg": "un dourvarc'h",
+ "hit.ogg": "touchañ",
+ "hive.ogg": "ur ruskenn",
+ "hockey.ogg": "hoke",
+ "hole.ogg": "un toull",
+ "home.ogg": "ar gêr",
+ "hook.ogg": "ur c'hrog",
+ "hop.ogg": "lammig",
+ "horse.ogg": "ul loen-kezeg",
+ "hose.ogg": "ur gorzenn",
+ "hospital.ogg": "un ospital",
+ "hot.ogg": "tomm",
+ "hot_dog.ogg": "un hot-dog",
+ "hound.ogg": "ur mell ki",
+ "house.ogg": "un ti",
+ "howl.ogg": "yudal",
+ "hug.ogg": "briata",
+ "huge.ogg": "bras tre",
+ "hummingbird.ogg": "ur c'holibri",
+ "hunchbacked.ogg": "tort",
+ "hunter.ogg": "ur chaseour",
+ "husband.ogg": "ur gwazh",
+ "hut.ogg": "ul loch",
+ "hyena.ogg": "ur bleiz-broc'h",
+ "ice.ogg": "skorn",
+ "iceberg.ogg": "ur skorngrec'h",
+ "iguana.ogg": "un igwan",
+ "ill.ogg": "klañv",
+ "ink.ogg": "ankr",
+ "island.ogg": "un enezenn",
+ "jacket.ogg": "ur porpant",
+ "jaguar.ogg": "jagoar",
+ "jam.ogg": "koñfitur",
+ "jay.ogg": "ur gegin",
+ "jelly.ogg": "kaotigell",
+ "jellyfish.ogg": "ur vorglaouenn",
+ "jewel.ogg": "ur bravig",
+ "job.ogg": "ur vicher",
+ "jockey.ogg": "ur joke",
+ "jog.ogg": "trotadenn",
+ "joy.ogg": "ur joa",
+ "judge.ogg": "ur barner",
+ "judo.ogg": "judo",
+ "juggler.ogg": "ur jangler",
+ "juice.ogg": "jug",
+ "jump.ogg": "lammat",
+ "kangaroo.ogg": "ur c'hangourou",
+ "keel.ogg": "ur c'hein",
+ "kernel.ogg": "un alamandezenn",
+ "keyboard.ogg": "ur c'hlavier",
+ "kimono.ogg": "ur c'himono",
+ "king.ogg": "ur roue",
+ "kiss.ogg": "pokat",
+ "kitchen.ogg": "ur gegin",
+ "kite.ogg": "ur sarpant-nij",
+ "kitten.ogg": "ur c'hazhig",
+ "kiwi.ogg": "ur giwienn",
+ "knee.ogg": "ur glin",
+ "kneel.ogg": "daoulinañ",
+ "knife.ogg": "ur gountell",
+ "knight.ogg": "ur marc'heg",
+ "knit.ogg": "stammañ",
+ "knot.ogg": "ur skoulm",
+ "koala.ogg": "ur c'hoala",
+ "lad.ogg": "ur paotr",
+ "lady.ogg": "un itron",
+ "ladybug.ogg": "ur viwig",
+ "lake.ogg": "ul lenn",
+ "lama.ogg": "ul lama",
+ "lamb.ogg": "un oan",
+ "lamp.ogg": "ul lamp",
+ "land.ogg": "an douar",
+ "lane.ogg": "un alez",
+ "lap.ogg": "ur varlenn",
+ "lasso.ogg": "ul lasso",
+ "laugh.ogg": "c'hoarzhin",
+ "lava.ogg": "maen teuz",
+ "lawn.ogg": "ul letonenn",
+ "lawyer.ogg": "un avokad",
+ "leaf.ogg": "un delienn",
+ "ledge.ogg": "ur rizenn",
+ "leek.ogg": "ur bourenn",
+ "left.ogg": "kleiz",
+ "leg.ogg": "ur c'har",
+ "lemon.ogg": "ur sitroñs",
+ "lemonade.ogg": "dour pik-pik",
+ "lemur.ogg": "ul lemur",
+ "leopard.ogg": "ul loupard",
+ "lettuce.ogg": "ur saladenn",
+ "librarian.ogg": "ul levraoueger",
+ "lick.ogg": "lipat",
+ "lid.ogg": "ur golo",
+ "lift.ogg": "sevel",
+ "light.ogg": "ar gouloù",
+ "lighthouse.ogg": "un tour-tan",
+ "lightning.ogg": "ar c'hurun",
+ "lilac.ogg": "ul lireuenn",
+ "lime.ogg": "ur sitroñs glas",
+ "line.ogg": "ul linenn",
+ "link.ogg": "ul liamm",
+ "lion.ogg": "ul leon",
+ "lion_cub.ogg": "ul leonig",
+ "lip.ogg": "ur vuzell",
+ "liquid.ogg": "dourennek",
+ "lizard.ogg": "ur glazard",
+ "lobster.ogg": "ur legestr",
+ "log.ogg": "ur geuneudenn",
+ "look.ogg": "sellout",
+ "lunch.ogg": "merenn",
+ "mad.ogg": "ur foll",
+ "magic.ogg": "hud",
+ "magnet.ogg": "ur maen-touch",
+ "magnifying_glass.ogg": "ur werenn-greskiñ",
+ "magpie.ogg": "ur big",
+ "mail.ogg": "ul lizher",
+ "man.ogg": "tud",
+ "mane.ogg": "ur moue",
+ "mango.ogg": "ur vangezenn",
+ "map.ogg": "ur gartenn",
+ "maple.ogg": "ur skavenn-wrac'h",
+ "marble.ogg": "ur ganetenn",
+ "mashed_potatoes.ogg": "yod patatez",
+ "mask.ogg": "ur maskl",
+ "mast.ogg": "ur wern",
+ "mat.ogg": "un tamm tapis",
+ "match.ogg": "ur c'hrogad",
+ "mate.ogg": "ur c'hamalad",
+ "mattress.ogg": "ur vatarasenn",
+ "mauve.ogg": "limestra",
+ "meal.ogg": "pred",
+ "meat.ogg": "kig",
+ "mechanic.ogg": "ur mekaniker",
+ "medal.ogg": "ur vedalenn",
+ "meet.ogg": "kejañ",
+ "melon.ogg": "ur meloñs",
+ "merry-go-round.ogg": "ur manej",
+ "mice.ogg": "logod",
+ "microphone.ogg": "ur mikrofon",
+ "milk.ogg": "laezh",
+ "mill.ogg": "ur vilin",
+ "mimosa.ogg": "ur wezenn-vimoza",
+ "mirror.ogg": "ur melezour",
+ "mixer.ogg": "ur frikerez",
+ "mole.ogg": "ur c'hoz",
+ "mom.ogg": "ur vammig",
+ "moon.ogg": "al loar",
+ "moose.ogg": "un orignal",
+ "mop.ogg": "ur skubellenn",
+ "mosque.ogg": "ur voskeenn",
+ "mosquito.ogg": "ur moustik",
+ "mother.ogg": "ur vamm",
+ "motorcycle.ogg": "ur marc'h-tan",
+ "mountain.ogg": "ur menez",
+ "mouse.ogg": "ul logodenn",
+ "mouth.ogg": "ur genoù",
+ "movie.ogg": "ur film",
+ "mower.ogg": "un douzerez",
+ "mud.ogg": "fank",
+ "mug.ogg": "un tas bras",
+ "mule.ogg": "ur vulez",
+ "muscle.ogg": "ur c'higenn",
+ "mushroom.ogg": "ur c'habell-touseg",
+ "music.ogg": "ur sonerezh",
+ "musician.ogg": "ur soner",
+ "naked.ogg": "noazh",
+ "nap.ogg": "morgousket",
+ "navel.ogg": "ur begel",
+ "neck.ogg": "ur gouzoug",
+ "necklace.ogg": "ur c'holier",
+ "needle.ogg": "ur spilhenn",
+ "nest.ogg": "un neizh",
+ "net.ogg": "ur roued",
+ "newspaper.ogg": "ur gazetenn",
+ "night.ogg": "an noz",
+ "nightgown.ogg": "un hiviz-noz",
+ "nose.ogg": "ur fri",
+ "nostril.ogg": "ur fronell",
+ "notebook.ogg": "ur c'harned",
+ "number.ogg": "un niver",
+ "nun.ogg": "ur seurez",
+ "nurse.ogg": "ur glañvdiourez",
+ "nurse_male.ogg": "ur c'hlañvdiour",
+ "nut.ogg": "ur graoñenn",
+ "oar.ogg": "ur roeñv",
+ "ocean.ogg": "ur meurvor",
+ "office.ogg": "un ofis",
+ "olive.ogg": "un olivezenn",
+ "on.ogg": "war",
+ "onion.ogg": "ur penn-ognon",
+ "open.ogg": "digor",
+ "opossum.ogg": "un oposom",
+ "orange-color.ogg": "orañjez",
+ "orange.ogg": "ur orañjezenn",
+ "orchid.ogg": "un orkideenn",
+ "ostrich.ogg": "ur struskañval",
+ "otter.ogg": "un dourgi",
+ "owl.ogg": "ur gaouenn",
+ "ox.ogg": "un ejen",
+ "oyster.ogg": "un istrenn",
+ "pacifier.ogg": "ur chutenn",
+ "page.ogg": "ur bajenn",
+ "pair.ogg": "ur c'houblad",
+ "pajamas.ogg": "ur pijama",
+ "pal.ogg": "ur c'homper",
+ "palm_tree.ogg": "ur wezenn-balm",
+ "pan.ogg": "ur baelon",
+ "panda.ogg": "ur panda",
+ "panther.ogg": "ur banterenn",
+ "panties.ogg": "ur slip",
+ "pants.ogg": "ur re vragoù",
+ "papaya.ogg": "ur bapaiezenn",
+ "paper.ogg": "paper",
+ "parachute.ogg": "un harz-lamm",
+ "parakeet.ogg": "ur c'hrakperoked",
+ "parrot.ogg": "ur peroked",
+ "patch.ogg": "un dres",
+ "path.ogg": "ur wenojenn",
+ "paw.ogg": "ur pav",
+ "pea.ogg": "ur bizenn",
+ "peach.ogg": "ur bechenn",
+ "peacock.ogg": "ur paun",
+ "peak.ogg": "ur c'hrec'h",
+ "pear.ogg": "ur berenn",
+ "pearl.ogg": "ur berlezenn",
+ "peck.ogg": "beketa",
+ "pedal.ogg": "ur bedalenn",
+ "pelican.ogg": "ur pelikant",
+ "pen.ogg": "ur stilo",
+ "pencil.ogg": "ur c'hreion",
+ "peony.ogg": "ur pivoena",
+ "people.ogg": "tud",
+ "pepper.ogg": "pepr",
+ "peppers.ogg": "pebr-Spagn",
+ "pet.ogg": "ul loen-ti",
+ "petal.ogg": "ur betalenn",
+ "phone.ogg": "ur pellgomzer",
+ "piano.ogg": "ur piano",
+ "picture.ogg": "ur skeudenn",
+ "pie.ogg": "un dartezenn",
+ "pig.ogg": "ur pemoc'h",
+ "pigeon.ogg": "ur pichon",
+ "pill.ogg": "ur bilulenn",
+ "pillow.ogg": "ur goubenner",
+ "pilot.ogg": "un nijer",
+ "pine.ogg": "ur wezenn-bin",
+ "pine_cone.ogg": "un aval-pin",
+ "pink.ogg": "roz",
+ "pip.ogg": "ur splusenn",
+ "pipe.ogg": "ur c'horn-butun",
+ "piranha.ogg": "ur pirania",
+ "pirate.ogg": "ur mor-laer",
+ "pizza.ogg": "ur pizza",
+ "plane.ogg": "ur c'harr-nij",
+ "planet.ogg": "ur blanedenn",
+ "plant.ogg": "ur blantenn",
+ "plate.ogg": "un asied",
+ "play.ogg": "c'hoari",
+ "pliers.ogg": "piñsetoù",
+ "plow.ogg": "arat",
+ "plum.ogg": "ur brunenn",
+ "plumber.ogg": "ur plomer",
+ "pocket.ogg": "ur c'hodell",
+ "pod.ogg": "ur glorenn",
+ "pole.ogg": "ur peul",
+ "police.ogg": "un archer",
+ "pompon.ogg": "ur bichourell",
+ "pond.ogg": "ur poull-dour",
+ "pony.ogg": "ur pone",
+ "pool.ogg": "ur poull",
+ "popcorn.ogg": "popkorn",
+ "pope.ogg": "ur pab",
+ "porthole.ogg": "ul lomber",
+ "post.ogg": "un ti-post",
+ "pot.ogg": "ur pod",
+ "potato.ogg": "ur batatezenn",
+ "pounce.ogg": "lammat",
+ "president.ogg": "ur prezidant",
+ "pretty.ogg": "koant",
+ "price.ogg": "ur priz",
+ "priest.ogg": "ur beleg",
+ "prince.ogg": "ur priñs",
+ "princess.ogg": "ur briñsez",
+ "prison.ogg": "un toull-bac'h",
+ "prisoner.ogg": "ur prizoniad",
+ "prize.ogg": "ur priz",
+ "pug.ogg": "un dogezig fri-du",
+ "pull.ogg": "sachañ",
+ "pullover.ogg": "ur stammenn",
+ "pumpkin.ogg": "ur sitrouilhezenn",
+ "puppy.ogg": "ur c'holen ki",
+ "pyramid.ogg": "ur biramidenn",
+ "quarrel.ogg": "tabutal",
+ "queen.ogg": "ur rouanez",
+ "question.ogg": "ur goulenn",
+ "quilt.ogg": "ur c'holc'hed",
+ "quiz.ogg": "ur c'houlennaoueg",
+ "rabbit.ogg": "ul lapin",
+ "rabbit_baby.ogg": "ul lapinig",
+ "race.ogg": "redadeg",
+ "radio.ogg": "ur skingomz",
+ "radish.ogg": "un irvinenn ruz",
+ "raft.ogg": "ur radell",
+ "rag.ogg": "ur bilhenn",
+ "rage.ogg": "ur gounnar",
+ "rain.ogg": "glav",
+ "raincoat.ogg": "ur vantell c'hlav",
+ "rake.ogg": "ur rastell",
+ "ramp.ogg": "ur savenn",
+ "ran.ogg": "redek",
+ "raspberry.ogg": "ur flamboezenn",
+ "rat.ogg": "ur razh",
+ "razor.ogg": "un aotenn",
+ "read.ogg": "lenn",
+ "red.ogg": "ruz",
+ "reptile.ogg": "ur stlejvil",
+ "rhinoceros.ogg": "ur frikorneg",
+ "rice.ogg": "riz",
+ "ride.ogg": "mont war varc'h",
+ "rifle.ogg": "ur fuzuilh",
+ "right.ogg": "dehoù",
+ "rip.ogg": "regiñ",
+ "rise.ogg": "sevel",
+ "river.ogg": "ur stêr",
+ "road.ogg": "un hent",
+ "roast.ogg": "kig roastet",
+ "robe.ogg": "ur sae",
+ "robot.ogg": "ur robot",
+ "rock.ogg": "ur roc'h",
+ "rocket.ogg": "ur fuzeenn",
+ "rolling_pin.ogg": "ur ruilhenn",
+ "roof.ogg": "un doenn",
+ "room.ogg": "ur pezh",
+ "root.ogg": "ur wrizienn",
+ "rope.ogg": "ur gordenn",
+ "rose.ogg": "ur rozenn",
+ "round.ogg": "ront",
+ "rowing.ogg": "roeñvat",
+ "royal.ogg": "rouantel",
+ "rug.ogg": "un tapisig",
+ "run.ogg": "redek",
+ "sad.ogg": "trist",
+ "saddle.ogg": "un dibr",
+ "sail.ogg": "ur ouel",
+ "sailor.ogg": "ur martolod",
+ "salamander.ogg": "ur sourd",
+ "salmon.ogg": "un eog",
+ "sand.ogg": "traezh",
+ "sandals.ogg": "sandalennoù",
+ "sandwich.ogg": "ur sandwich",
+ "sash.ogg": "ur seizenn",
+ "sauce.ogg": "chaous",
+ "sausage.ogg": "chaousis",
+ "scale.ogg": "ur ventel",
+ "scar.ogg": "ur gleizhenn",
+ "scare.ogg": "spontañ",
+ "scarf.ogg": "ur skerb",
+ "school.ogg": "ur skol",
+ "school_bag.ogg": "ur sac'h-skol",
+ "science.ogg": "ar skiant",
+ "scissors.ogg": "sizailhoù",
+ "scorpion.ogg": "ur c'hrug",
+ "scratch.ogg": "skrabañ",
+ "scream.ogg": "krial",
+ "screw.ogg": "ur viñs",
+ "screwdriver.ogg": "un tro-viñs",
+ "scribble.ogg": "skribouilhiñ",
+ "sea.ogg": "ar mor",
+ "seat.ogg": "ur sez",
+ "see.ogg": "gwelout",
+ "seed.ogg": "un hadenn",
+ "shadow.ogg": "ur skeud",
+ "shake.ogg": "krenañ",
+ "shark.ogg": "ur rinkin",
+ "shave.ogg": "aotennañ",
+ "shed.ogg": "ur c'houdorenn",
+ "sheep.ogg": "un dañvad",
+ "shelf.ogg": "un estajerenn",
+ "shell.ogg": "ur grogenn",
+ "ship.ogg": "ul lestr",
+ "shirt.ogg": "ur roched",
+ "shoe.ogg": "ur votez",
+ "shoelace.ogg": "ul las",
+ "shop.ogg": "ur stal",
+ "shore.ogg": "un aod",
+ "short.ogg": "ur re vragoù berr",
+ "shovel.ogg": "ur bal",
+ "shower.ogg": "ur strinkerez",
+ "shrimp.ogg": "ur chevrenn",
+ "shrub.ogg": "ur vrousgwezenn",
+ "shut.ogg": "serret",
+ "shutter.ogg": "ur stalaf",
+ "sick.ogg": "klañv",
+ "sidewalk.ogg": "ur riblenn",
+ "sign.ogg": "ur skritell",
+ "sing.ogg": "kanañ",
+ "sink.ogg": "un dar",
+ "sip.ogg": "lapat",
+ "sister.ogg": "ur c'hoar",
+ "sit.ogg": "azezañ",
+ "skate.ogg": "plankenn-ruilh",
+ "skeleton.ogg": "un eskeled",
+ "ski.ogg": "ski",
+ "skimmer.ogg": "ul loa-sil",
+ "skin.ogg": "ur c'hroc'hen",
+ "skirt.ogg": "ur vrozh",
+ "skunk.ogg": "ur pudask",
+ "sky.ogg": "an oabl",
+ "slam.ogg": "stlakal",
+ "sled.ogg": "ul luj",
+ "sleep.ogg": "kousket",
+ "sleeve.ogg": "ur milgin",
+ "sleigh.ogg": "ur stlejell",
+ "slide.ogg": "un diapozitiv",
+ "slim.ogg": "moan",
+ "slime.ogg": "ul lec'hid",
+ "slippers.ogg": "kofignonoù",
+ "slope.ogg": "un diribin",
+ "sloppy.ogg": "digempenn ",
+ "slot.ogg": "ur faout",
+ "sloth.ogg": "ur gorreg",
+ "slug.ogg": "ur velc'hwedenn",
+ "small.ogg": "bihan",
+ "smell.ogg": "c'hwesha",
+ "smile.ogg": "ur mousc'hoarzh",
+ "smock.ogg": "ur saro",
+ "smoke.ogg": "moged",
+ "smooch.ogg": "poketal",
+ "snack.ogg": "un torr-naon",
+ "snail.ogg": "ur maligorn",
+ "snake.ogg": "un naer",
+ "sneaker.ogg": "botoù sport",
+ "sniff.ogg": "ruflañ",
+ "snow.ogg": "erc'h",
+ "soap.ogg": "soavon",
+ "sob.ogg": "un difronk",
+ "sock.ogg": "ul loer",
+ "soldier.ogg": "ur soudard",
+ "sole.ogg": "ul leizenn",
+ "sole_shoe.ogg": "ur sol-votez",
+ "son.ogg": "ur mab",
+ "soup.ogg": "soubenn",
+ "spade.ogg": "ur rañv",
+ "spaghetti.ogg": "spageti",
+ "spark.ogg": "ur fulenn",
+ "sparrow.ogg": "ur golvan",
+ "spatula.ogg": "ur spanell",
+ "speak.ogg": "komz",
+ "spear.ogg": "ur goaf",
+ "spice.ogg": "spis",
+ "spider.ogg": "ur gevnidenn",
+ "spider_web.ogg": "ur gwiad-kevnid",
+ "spike.ogg": "un draen",
+ "spill.ogg": "fuilhañ",
+ "spinach.ogg": "ur binochezenn",
+ "spine.ogg": "ul livenn-gein",
+ "spinning_top.ogg": "un toumpi",
+ "splash.ogg": "strinkañ",
+ "splatter.ogg": "strinkañ",
+ "sponge.ogg": "ur spoueenn",
+ "spool.ogg": "ur ganell",
+ "spoon.ogg": "ul loa",
+ "sport.ogg": "sport",
+ "spot.ogg": "ur saotr",
+ "spray.ogg": "glizhenniñ",
+ "spread.ogg": "skignañ",
+ "spring.ogg": "lammat",
+ "spring_season.ogg": "an nevez-amzer",
+ "sprinkle.ogg": "poultrenniñ",
+ "square.ogg": "ur c'harrez",
+ "squash.ogg": "ur potiron",
+ "squat.ogg": "kluchañ",
+ "squid.ogg": "ur stivelleg",
+ "squirrel.ogg": "ur razh-koad",
+ "squirt.ogg": "ur flistradenn",
+ "stack.ogg": "ur bern",
+ "stage.ogg": "ul leurenn",
+ "staircase.ogg": "derezioù",
+ "stamp.ogg": "un timbr",
+ "stand.ogg": "ur stand",
+ "star.ogg": "ur steredenn",
+ "stare.ogg": "parañ e selloù",
+ "starfish.ogg": "ur steredenn-vor",
+ "steam.ogg": "ur c'hlizhenn",
+ "steep.ogg": "sonn",
+ "steeple.ogg": "ur c'hloc'hdi",
+ "stem.ogg": "ur c'hef ",
+ "step.ogg": "un derez",
+ "stew.ogg": "ragoud",
+ "stick.ogg": "ur vriñsenn",
+ "sting.ogg": "flemmañ",
+ "stinky.ogg": "flaerius",
+ "stitch.ogg": "gwriat",
+ "stomach.ogg": "ur stomok",
+ "stone.ogg": "ur maen",
+ "stop.ogg": "paouez",
+ "store.ogg": "ur stal",
+ "stove.ogg": "ur geginerez",
+ "straight.ogg": "eeun",
+ "strainer.ogg": "ur sil",
+ "straw.ogg": "plouz",
+ "strawberry.ogg": "ur sivienn",
+ "stream.ogg": "ur red-dour",
+ "street.ogg": "ur straed",
+ "stretch.ogg": "astenn",
+ "string.ogg": "un neudenn",
+ "stripe.ogg": "ur roudenn",
+ "strong.ogg": "kreñv",
+ "student.ogg": "ur studier",
+ "study.ogg": "studiañ",
+ "stump.ogg": "ur penngos",
+ "sugar.ogg": "sukr",
+ "suit.ogg": "un abid",
+ "suitcase.ogg": "ur valizenn",
+ "summer.ogg": "an hañv",
+ "summit.ogg": "ur barr",
+ "sun.ogg": "an heol",
+ "swan.ogg": "un alarc'h",
+ "sweat.ogg": "c'hwezh",
+ "sweatshirt.ogg": "ur sweat-shirt",
+ "swim.ogg": "neuial",
+ "table.ogg": "un daol",
+ "tablecloth.ogg": "ul lienn-daol",
+ "tadpole.ogg": "ur penndolog",
+ "tag.ogg": "un diketenn",
+ "tail.ogg": "ul lost",
+ "tall.ogg": "bras",
+ "tape_measure.ogg": "ur metr-seizenn",
+ "taxi.ogg": "un taksi",
+ "teach.ogg": "kelenn",
+ "teacher.ogg": "ur c'helenner",
+ "tear.ogg": "drailhañ",
+ "teddy.ogg": "un nanarzh",
+ "teeth.ogg": "an dent",
+ "television.ogg": "ur skinwel",
+ "temple.ogg": "un templ",
+ "tennis.ogg": "tennis",
+ "tent.ogg": "un deltenn",
+ "text.ogg": "un destenn",
+ "thick.ogg": "tev",
+ "thief.ogg": "ul laer",
+ "thigh.ogg": "ur vorzhed",
+ "think.ogg": "prederiañ",
+ "thread.ogg": "un neudenn",
+ "throat.ogg": "ur gorzailhenn",
+ "throw.ogg": "bannañ",
+ "thumb.ogg": "ur biz-meud",
+ "tick.ogg": "un deureugenn",
+ "ticket.ogg": "un tiked",
+ "tiger.ogg": "un tigr",
+ "time.ogg": "an amzer",
+ "tin.ogg": "ur vouest-mir",
+ "tire.ogg": "ur pneu",
+ "tired.ogg": "skuizh",
+ "tissue.ogg": "paper-torch",
+ "to_drink.ogg": "evañ",
+ "toad.ogg": "un touseg",
+ "toaster.ogg": "ur grazerez-vara",
+ "toe.ogg": "ur biz-troad",
+ "toilet.ogg": "ar privezioù",
+ "tomatoe.ogg": "un domatezenn",
+ "tongs.ogg": "ur wask",
+ "tongue.ogg": "un teod",
+ "tool.ogg": "ur beñveg",
+ "top.ogg": "al lein",
+ "torch.ogg": "un flammerenn",
+ "touch.ogg": "touchañ",
+ "towel.ogg": "ur serviedenn",
+ "toy.ogg": "ur c'hoariell",
+ "trail.ogg": "ur riboul",
+ "train.ogg": "un tren",
+ "train_station.ogg": "ur porzh-houarn",
+ "trap.ogg": "un trap",
+ "trash.ogg": "al lastez",
+ "tray.ogg": "ur pladenn",
+ "treat.ogg": "chervad",
+ "tree.ogg": "ur wezenn",
+ "triangle.ogg": "un tric'horn",
+ "tribe.ogg": "ur meuriad",
+ "trip.ogg": "ur veaj",
+ "truck.ogg": "ur c'harr-samm",
+ "tube.ogg": "un duellenn",
+ "tulip.ogg": "un dulipezenn",
+ "tune.ogg": "un ton",
+ "turkey.ogg": "ur yar indez",
+ "turnip.ogg": "un irvinenn",
+ "turtle.ogg": "ur vaot",
+ "tusk.ogg": "ur skilf",
+ "twin_boys.ogg": "gevelled",
+ "twin_girls.ogg": "gevellezed",
+ "umbrella.ogg": "un disglavier",
+ "under.ogg": "dindan",
+ "uniform.ogg": "ul lifre",
+ "van.ogg": "ur sammorell",
+ "vapor.ogg": "un aezhenn",
+ "vase.ogg": "ul lestr",
+ "vegetable.ogg": "legumaj",
+ "vein.ogg": "ur wazhienn",
+ "verdure.ogg": "glasvez",
+ "vest.ogg": "ur chupenn",
+ "vet.ogg": "ur mezeg loened",
+ "viper.ogg": "ur wiber",
+ "vowel.ogg": "ur vogalenn",
+ "vulture.ogg": "ur gup",
+ "wag.ogg": "meskañ",
+ "walk.ogg": "bale",
+ "wall.ogg": "ur voger",
+ "walnut.ogg": "ur graonenn",
+ "wart.ogg": "ur wenaenn",
+ "wash.ogg": "gwalc'hiñ",
+ "wasp.ogg": "ur wespedenn",
+ "watch.ogg": "ur montr",
+ "water.ogg": "dour",
+ "wave.ogg": "ur wagenn",
+ "wedding.ogg": "un eured",
+ "wedge.ogg": "ur genn",
+ "weight.ogg": "ur pouez",
+ "wet.ogg": "gleb",
+ "whale.ogg": "ur valum",
+ "wheat.ogg": "gwinizh",
+ "wheel.ogg": "ur rod",
+ "whisk.ogg": "ur baser",
+ "whisper.ogg": "mouskomz ",
+ "white.ogg": "gwenn",
+ "wide.ogg": "ledan",
+ "wife.ogg": "ur wreg",
+ "wig.ogg": "ur berukenn",
+ "win.ogg": "gounit",
+ "wind.ogg": "an avel",
+ "window.ogg": "ur prenestr",
+ "window_glass.ogg": "ur werenn-brenestr",
+ "wing.ogg": "un askell",
+ "winter.ogg": "ar goañv",
+ "wolf.ogg": "ur bleiz",
+ "woman.ogg": "ur vaouez",
+ "wood.ogg": "koad",
+ "word.ogg": "ur ger",
+ "worker.ogg": "ul labourer",
+ "world.ogg": "ar bed",
+ "wreath.ogg": "ur garlantezenn",
+ "wrench.ogg": "ur gwask",
+ "wrist.ogg": "un arzorn",
+ "write.ogg": "skrivañ",
+ "yellow.ogg": "melen",
+ "yogurt.ogg": "ur yaourt",
+ "yum.ogg": "nenam",
+ "zebra.ogg": "ur roudenneg",
+ "zipper.ogg": "ur serr-prim",
+ "zoo.ogg": "ur zoo"
+}
\ No newline at end of file
diff --git a/src/activities/lang/resource/content-ca.json b/src/activities/lang/resource/content-ca.json
index e6ce4bdc8..6c1e14759 100644
--- a/src/activities/lang/resource/content-ca.json
+++ b/src/activities/lang/resource/content-ca.json
@@ -1,1107 +1,1092 @@
{
"10.ogg": "deu",
"11.ogg": "onze",
"12.ogg": "dotze",
"16.ogg": "setze",
"U0030.ogg": "zero",
"U0031.ogg": "un",
"U0032.ogg": "dos",
"U0033.ogg": "tres",
"U0034.ogg": "quatre",
"U0035.ogg": "cinc",
"U0036.ogg": "sis",
"U0037.ogg": "set",
"U0038.ogg": "vuit",
"U0039.ogg": "nou",
"accountant.ogg": "comptable",
"ache.ogg": "dolor",
"acorn.ogg": "gla",
"actor.ogg": "actor",
"air_horn.ogg": "botzina",
"alarmclock.ogg": "despertador",
"alligator.ogg": "caiman",
"alphabet.ogg": "alfabet",
"anchor.ogg": "àncora",
"angel.ogg": "àngel",
"angry.ogg": "enfadat",
"animal.ogg": "animal",
"ankle.ogg": "turmell",
"ant.ogg": "formiga",
"anteater.ogg": "ós formiguer",
"antelope.ogg": "antílop",
"apple.ogg": "poma",
"apple_tree.ogg": "pomera",
"appliance.ogg": "aparell",
"apricot.ogg": "albercoc",
"arm.ogg": "braç",
"armchair.ogg": "butaca",
"artichoke.ogg": "carxofa",
"artist.ogg": "artista",
"asparagus.ogg": "espàrrec",
"astronaut.ogg": "astronauta",
- "ate.ogg": "menjar",
"athlete.ogg": "atleta",
"avocado.ogg": "alvocat",
"ax.ogg": "destral",
"baby_bottle.ogg": "biberó",
"back.ogg": "esquena",
"badge.ogg": "insígnia",
"bag.ogg": "bossa",
"bait.ogg": "esquer",
- "bake.ogg": "cuinar",
"balance.ogg": "balança",
"bald.ogg": "calba",
"ball.ogg": "bola",
"ball_of_yarn.ogg": "cabdell de llana",
"ball_soccer.ogg": "pilota de futbol",
"ballet.ogg": "ballet",
"bank.ogg": "banc",
+ "banker_female.ogg": "banquera",
"bark.ogg": "bordar",
"barn.ogg": "graner",
"bat.ogg": "ratpenat",
"bath.ogg": "banyera",
"bathing_suit.ogg": "banyador",
"bay.ogg": "badia",
"beach.ogg": "platja",
- "bead.ogg": "bombolla",
"bean.ogg": "fesol",
"bear.ogg": "ós",
"beard.ogg": "barba",
"beat.ogg": "batre",
"beaver.ogg": "castor",
"bed.ogg": "llit",
"bedroom.ogg": "dormitori",
"bee.ogg": "abella",
- "beef.ogg": "carn de boví",
"beetle.ogg": "escarabat",
"beg.ogg": "demanar",
"behind.ogg": "darrere",
"bell.ogg": "campana",
"belly.ogg": "panxa",
"bench.ogg": "banc",
"bib.ogg": "pitet",
"big.ogg": "gran",
"big_top.ogg": "carpa de circ",
"bike.ogg": "bicicleta",
"bird.ogg": "ocell",
"bit.ogg": "mica",
"bite.ogg": "mossegar",
"black.ogg": "negre",
"blackberry.ogg": "móra",
"blackbird.ogg": "merla",
"blade.ogg": "tall",
"blind.ogg": "cec",
"blink.ogg": "picada d'ullet",
"block.ogg": "bloc",
"blond.ogg": "rossa",
"blue.ogg": "blau",
"blueberry.ogg": "nabiu",
"blush.ogg": "rubor",
"board.ogg": "tauló",
"boat.ogg": "barca",
"boil.ogg": "bullir",
"bolt.ogg": "femella",
"bomb.ogg": "bomba",
"bone.ogg": "os",
"book.ogg": "llibre",
"bookcase.ogg": "llibreria",
"bottom.ogg": "natges",
"box.ogg": "caixa",
"boxer.ogg": "boxejador",
"boy.ogg": "noi",
"braid.ogg": "trena",
"brain.ogg": "cervell",
"branch.ogg": "branca",
"bread.ogg": "pa",
"break.ogg": "trencar",
"breast.ogg": "pit",
"brick.ogg": "maó",
"bricklayer.ogg": "paleta",
"bride.ogg": "núvia",
"bridge.ogg": "pont",
"bright.ogg": "brillant",
"broccoli.ogg": "bròquil",
"brother.ogg": "germà",
"brown.ogg": "marró",
"brush.ogg": "brotxa",
"bubble.ogg": "bombolla",
"bucket.ogg": "galleda",
"bud.ogg": "brot",
"buffalo.ogg": "búfal",
"bug.ogg": "insecte",
"bulb.ogg": "bombeta",
"bull.ogg": "toro",
"bump.ogg": "bony",
"bun.ogg": "brioix",
"bus.ogg": "autobús",
"bush.ogg": "arbust",
"butcher.ogg": "carnisser",
"butter.ogg": "mantega",
"butterfly.ogg": "papallona",
"button.ogg": "botó",
"cabbage.ogg": "col",
"cabin.ogg": "cabana",
"cacao.ogg": "cacau",
"cactus.ogg": "cactus",
"cage.ogg": "gàbia",
"cake.ogg": "pastís",
"call.ogg": "trucada",
"camel.ogg": "camell",
"camera.ogg": "càmera",
"camp.ogg": "acampar",
"can.ogg": "llauna",
"canary.ogg": "canari",
"candle.ogg": "espelma",
"candy.ogg": "caramel",
"cane.ogg": "bastó",
"canoe.ogg": "canoa",
"canon.ogg": "canó",
"canyon.ogg": "canó",
"cap.ogg": "gorra",
"cape.ogg": "capa",
"car.ogg": "cotxe",
"carafe.ogg": "gerra",
"card.ogg": "tarjeta",
"carnival.ogg": "carnaval",
"carpenter.ogg": "fuster",
"carpet.ogg": "catifa",
"carrot.ogg": "pastanaga",
"cart.ogg": "carro",
"cash.ogg": "diner",
"castle.ogg": "castell",
"cat.ogg": "gat",
"cat_female.ogg": "gata",
"catch.ogg": "pescar",
"caterpillar.ogg": "eruga",
"cauldron.ogg": "caldera",
"cauliflower.ogg": "coliflor",
"cave.ogg": "cova",
"cavern.ogg": "caverna",
"celery.ogg": "api",
"centipede.ogg": "centpeus",
"cereal.ogg": "cereal",
"chain.ogg": "cadena",
"chair.ogg": "cadira",
"chalk.ogg": "guix",
"chameleon.ogg": "camaleó",
"chandelier.ogg": "aranya",
"chat.ogg": "parlar",
"cheek.ogg": "galta",
"cheer.ogg": "animar",
"cheese.ogg": "formatge",
"chef.ogg": "cuiner",
"cherry.ogg": "cirera",
"chest.ogg": "bagul",
"chick.ogg": "pollet",
"chicken.ogg": "pollastre",
- "chief.ogg": "indi",
- "child.ogg": "nen",
+ "child.ogg": "infant",
"chimney.ogg": "xemeneia",
"chimp.ogg": "ximpanzé",
"chin.ogg": "barbeta",
"chocolate.ogg": "xocolata",
"chop.ogg": "tallar",
- "chore.ogg": "tasca de la llar",
+ "chores.ogg": "tasques",
"christmas.ogg": "nadal",
"cigar.ogg": "puro",
"circus.ogg": "circ",
"city.ogg": "ciutat",
"clam.ogg": "cloïssa",
"clap.ogg": "picar de mans",
"class.ogg": "classe",
"claw.ogg": "urpa",
"clay.ogg": "argila",
"clean.ogg": "rentar",
"cleaning_lady.ogg": "senyora de la neteja",
"cliff.ogg": "penya-segat",
"climb.ogg": "escalada",
"clock.ogg": "rellotge",
"cloth.ogg": "drap",
"clothes_hanger.ogg": "penjador",
"cloud.ogg": "núvol",
"cloudy.ogg": "ennuvolat",
"clover.ogg": "trèvol",
"clown.ogg": "pallasso",
"coach.ogg": "entrenador",
"coast.ogg": "costa",
"coat.ogg": "abric",
"cobra.ogg": "cobra",
"coconut.ogg": "coco",
"cod.ogg": "bacallà",
"coffee.ogg": "cafè",
"coin.ogg": "moneda",
"cold.ogg": "fred",
"color.ogg": "color",
"colt.ogg": "poltre",
"comb.ogg": "pinta",
"cone.ogg": "con",
+ "cook.ogg": "cuinar",
"cookie.ogg": "galeta",
"cork.ogg": "suro",
"corn.ogg": "blat de moro",
"couch.ogg": "sofà",
"cough.ogg": "tossir",
"couple.ogg": "parella",
"cow.ogg": "vaca",
"cowboy.ogg": "vaquer",
"crab.ogg": "cranc",
"cradle.ogg": "bressol",
"craft.ogg": "manualitat",
"crawl.ogg": "gatejar",
"crazy.ogg": "ximple",
"creek.ogg": "rierol",
"crepe.ogg": "crep",
"crib.ogg": "bressol",
- "criminal.ogg": "criminal",
"croak.ogg": "raucar",
"crocodile.ogg": "cocodril",
"cross.ogg": "creu",
"crow.ogg": "corb",
"crown.ogg": "corona",
"crumb.ogg": "engrunes",
"crust.ogg": "crosta",
"cry.ogg": "plorar",
"crystal.ogg": "vidre",
"cube.ogg": "cub",
"cucumber.ogg": "cogombre",
"curtain.ogg": "cortina",
"cut.ogg": "tallar",
"cute.ogg": "bufona",
"dad.ogg": "pare",
"daffodil.ogg": "narcís",
"daisy.ogg": "margarida",
"dam.ogg": "presa",
"dance.ogg": "ballar",
"dandelion.ogg": "dent de lleó",
- "danger.ogg": "perill",
- "dark.ogg": "negra",
"dart_board.ogg": "tauler de dards",
"date_fruit.ogg": "dàtil",
"deer.ogg": "cérvol",
"den.ogg": "cau",
"desert.ogg": "desert",
"desk.ogg": "escriptori",
"dessert.ogg": "postre",
"diamond.ogg": "diamant",
"dig.ogg": "cavar",
"dirt.ogg": "sòl",
"dirty.ogg": "brut",
"dish.ogg": "font",
"dishcloth.ogg": "drap de cuina",
"dive.ogg": "immersió",
"doctor.ogg": "metge",
"doe.ogg": "cérvola",
"dog.ogg": "gos",
"doll.ogg": "nina",
"dolphin.ogg": "dofí",
"domino.ogg": "dominó",
"door.ogg": "porta",
"doormat.ogg": "estora",
"dot.ogg": "punt",
"doughnut.ogg": "bunyol",
"dove.ogg": "colom",
"dragon.ogg": "drac",
"dragonfly.ogg": "libèl·lula",
- "drank.ogg": "beure",
"draw.ogg": "dibuixar",
"drawer.ogg": "calaix",
"dream.ogg": "somiar",
"dress.ogg": "vestit",
"drink.ogg": "beguda",
- "drinking.ogg": "beure",
"drip.ogg": "gota",
"drive.ogg": "conduir",
"drool.ogg": "bavejar",
"drum.ogg": "tambor",
"dry.ogg": "assecar",
"duck.ogg": "ànec",
"duck_mother.ogg": "ànega",
"dune.ogg": "duna",
"dwarf.ogg": "nan",
"eagle.ogg": "àguila",
"ear.ogg": "orella",
"earth.ogg": "la Terra",
"eat.ogg": "menjar",
"egg.ogg": "ou",
"eggplant.ogg": "albergínia",
"elbow.ogg": "colze",
"electrician.ogg": "electricista",
"elk.ogg": "uapití",
"empty.ogg": "buida",
"engine.ogg": "motor",
"engineer.ogg": "enginyer",
"eraser.ogg": "goma d'esborrar",
"explore.ogg": "explorar",
"eyelash.ogg": "pestanya",
"eyes.ogg": "ull",
"face.ogg": "cara",
"fair.ogg": "atracció",
"fairy.ogg": "fada",
- "fall_down.ogg": "caure",
+ "fall.ogg": "caure",
"fall_season.ogg": "tardor",
"family.ogg": "família",
"fan.ogg": "ventilador",
"farm.ogg": "granja",
"farmer.ogg": "granger",
"fat.ogg": "gras",
"faucet.ogg": "aixeta",
"fawn.ogg": "cervatell",
+ "fear.ogg": "por",
"feast.ogg": "banquet",
"feather.ogg": "ploma",
"feed.ogg": "donar de menjar",
- "feet.ogg": "peu",
- "fell.ogg": "caure",
"femur.ogg": "fèmur",
"fetch.ogg": "informar",
"fig.ogg": "figa",
"fin.ogg": "aleta",
"find.ogg": "trobar",
"finger.ogg": "dit",
"fire.ogg": "foc",
"fire_extinguisher.ogg": "extintor",
"fireman.ogg": "bomber",
"fish.ogg": "peix",
"fisherman.ogg": "pescador",
"fist.ogg": "puny",
"flacon.ogg": "dosificador",
"flag.ogg": "bandera",
"flame.ogg": "flama",
"flamingo.ogg": "flamenc",
"flash.ogg": "llanterna",
"flat.ogg": "pis",
"flies.ogg": "mosca",
- "flight.ogg": "vol",
"float.ogg": "flotar",
"flour.ogg": "farina",
"flower.ogg": "flor",
"fluff.ogg": "borrissol",
"flute.ogg": "flauta",
"fly.ogg": "volar",
"foam.ogg": "escuma",
- "food.ogg": "hamburguesa",
"foot.ogg": "peu",
"forest.ogg": "bosc",
"fork.ogg": "forquilla",
"fountain.ogg": "font",
"fox.ogg": "guineu",
"freeze.ogg": "congelar",
"friend.ogg": "amic",
"fries.ogg": "patata fregida",
"frog.ogg": "granota",
"front.ogg": "davant",
- "frown.ogg": "posar mala cara",
"fruit.ogg": "fruita",
"fudge.ogg": "dolç de xocolata",
"full.ogg": "ple",
- "fun.ogg": "diversió",
"fur.ogg": "pell",
"game.ogg": "joc",
"garage.ogg": "garatge",
"garden.ogg": "jardi",
"garlic.ogg": "all",
"gem.ogg": "gemma",
"giant.ogg": "gegant",
"gift.ogg": "regal",
"giraffe.ogg": "girafa",
"girl.ogg": "noia",
"glass.ogg": "got",
"glasses.ogg": "ulleres",
"glove.ogg": "guant",
"glue.ogg": "cola",
"gnome.ogg": "gnom",
"goat.ogg": "cabra",
"golden.ogg": "daurada",
"golf.ogg": "golf",
"goose.ogg": "oca",
"gorilla.ogg": "goril·la",
"grain.ogg": "gra",
"grandmother.ogg": "àvia",
"grape.ogg": "raïm",
"grapefruit.ogg": "pomelo",
"grass.ogg": "herba",
"grave.ogg": "tomba",
"gray.ogg": "gris",
"green.ogg": "verd",
"grill.ogg": "graella",
"grin.ogg": "somriure",
"ground.ogg": "el terra",
"growl.ogg": "grunyir",
"guignol.ogg": "putxinel·li",
"guinea_pig.ogg": "conillet d'Índies",
"gum.ogg": "xiclet",
"hair.ogg": "cabell",
"hair_dryer.ogg": "assecador de cabell",
"half.ogg": "meitat",
"ham.ogg": "pernil",
+ "hamburger.ogg": "hamburguesa",
"hammer.ogg": "martell",
"hand.ogg": "mà",
"handlebar.ogg": "manillar",
"happy.ogg": "feliç",
"harp.ogg": "arpa",
"hat.ogg": "barret",
"hatch.ogg": "sortir de l'ou",
"hay.ogg": "farratge",
"head.ogg": "cap",
"hear.ogg": "sentir",
"heat.ogg": "calor",
"hedge.ogg": "tanca",
"hedgehog.ogg": "eriçó",
"heel.ogg": "taló",
"helmet.ogg": "casc",
"hen.ogg": "gallina",
"herd.ogg": "ramat",
"high.ogg": "a gran alçada",
"hike.ogg": "caminar",
"hill.ogg": "turó",
"hip.ogg": "maluc",
"hippopotamus.ogg": "hipopòtam",
"hit.ogg": "colpejar",
"hive.ogg": "rusc",
"hockey.ogg": "hoquei",
"hole.ogg": "forat",
"home.ogg": "casa",
"hook.ogg": "ham",
"hop.ogg": "saltar",
"horse.ogg": "cavall",
"hose.ogg": "mànega",
"hospital.ogg": "hospital",
"hot.ogg": "calent",
"hot_dog.ogg": "frankfurt",
"hound.ogg": "gos de caça",
"house.ogg": "casa",
"howl.ogg": "udolar",
"hug.ogg": "abraçar",
"huge.ogg": "enorme",
"hummingbird.ogg": "colibrí",
- "hunchback.ogg": "geperut",
+ "hunchbacked.ogg": "geperut",
"hunter.ogg": "caçador",
"husband.ogg": "marit",
"hut.ogg": "cabana",
"hyena.ogg": "hiena",
"ice.ogg": "glaçó",
"iceberg.ogg": "iceberg",
"iguana.ogg": "iguana",
"ill.ogg": "malalt",
"ink.ogg": "tinta",
"island.ogg": "illa",
"jacket.ogg": "jaqueta",
"jaguar.ogg": "jaguar",
"jam.ogg": "melmelada",
"jay.ogg": "gaig",
"jelly.ogg": "gelatina",
"jellyfish.ogg": "medusa",
"jewel.ogg": "joia",
"job.ogg": "treball",
"jockey.ogg": "joquei",
"jog.ogg": "fúting",
+ "joy.ogg": "goig",
"judge.ogg": "jutge",
"judo.ogg": "judo",
"juggler.ogg": "malabarista",
"juice.ogg": "suc",
"jump.ogg": "saltar",
"kangaroo.ogg": "cangur",
"keel.ogg": "equilibri",
"kernel.ogg": "nucli",
"keyboard.ogg": "teclat",
"kimono.ogg": "quimono",
"king.ogg": "rei",
"kiss.ogg": "petó",
"kitchen.ogg": "cuina",
"kite.ogg": "estel",
"kitten.ogg": "gatet",
"kiwi.ogg": "kiwi",
"knee.ogg": "genoll",
"kneel.ogg": "agenollar",
"knife.ogg": "ganivet",
"knight.ogg": "cavaller",
"knit.ogg": "teixir",
"knot.ogg": "nus",
"koala.ogg": "coala",
"lad.ogg": "mosso",
"lady.ogg": "dama",
"ladybug.ogg": "marieta",
"lake.ogg": "llac",
"lama.ogg": "llama",
"lamb.ogg": "xai",
"lamp.ogg": "el llum",
"land.ogg": "terreny",
"lane.ogg": "carril",
"lap.ogg": "a la falda",
"lasso.ogg": "llaç",
"laugh.ogg": "riure",
"lava.ogg": "lava",
"lawn.ogg": "gespa",
"lawyer.ogg": "advocat",
"leaf.ogg": "fulla",
"ledge.ogg": "sortint",
"leek.ogg": "porro",
"left.ogg": "esquerra",
"leg.ogg": "cama",
- "leg_animal.ogg": "pota",
"lemon.ogg": "llimona",
"lemonade.ogg": "llimonada",
"lemur.ogg": "lèmur",
"leopard.ogg": "lleopard",
"lettuce.ogg": "enciam",
"librarian.ogg": "bibliotecària",
"lick.ogg": "llepar",
"lid.ogg": "tapa",
"lift.ogg": "aixecar",
"light.ogg": "el llum",
"lighthouse.ogg": "far",
"lightning.ogg": "llamp",
"lilac.ogg": "lilà",
"lime.ogg": "llima",
"line.ogg": "codi de barres",
"link.ogg": "enllaç",
"lion.ogg": "lleó",
"lion_cub.ogg": "cadell de lleó",
"lip.ogg": "llavi",
"liquid.ogg": "líquid",
"lizard.ogg": "llangardaix",
"lobster.ogg": "llagosta",
"log.ogg": "tronc",
"look.ogg": "mirar-se",
"lunch.ogg": "dinar",
"mad.ogg": "ira",
"magic.ogg": "màgic",
"magnet.ogg": "imant",
"magnifying_glass.ogg": "lupa",
"magpie.ogg": "garsa",
"mail.ogg": "correu",
"man.ogg": "home",
"mane.ogg": "cabellera",
"mango.ogg": "mango",
"map.ogg": "mapa",
"maple.ogg": "auró",
"marble.ogg": "bala",
"mashed_potatoes.ogg": "puré de patates",
"mask.ogg": "màscara",
"mast.ogg": "màstil",
"mat.ogg": "estora",
"match.ogg": "llumí",
"mate.ogg": "company",
"mattress.ogg": "matalàs",
"mauve.ogg": "malva",
"meal.ogg": "àpat",
"meat.ogg": "carn",
"mechanic.ogg": "mecànic",
"medal.ogg": "medalla",
"meet.ogg": "trobar-se",
"melon.ogg": "meló",
- "men.ogg": "multitud",
"merry-go-round.ogg": "cavallet",
"mice.ogg": "ratolins",
"microphone.ogg": "micròfon",
"milk.ogg": "llet",
"mill.ogg": "molí",
"mimosa.ogg": "mimosa",
"mirror.ogg": "mirall",
"mixer.ogg": "mesclador",
"mole.ogg": "talp",
"mom.ogg": "mama",
"moon.ogg": "Lluna",
"moose.ogg": "ant",
"mop.ogg": "fregona",
"mosque.ogg": "mesquita",
"mosquito.ogg": "mosquit",
"mother.ogg": "mare",
"motorcycle.ogg": "moto",
"mountain.ogg": "muntanya",
"mouse.ogg": "ratolí",
"mouth.ogg": "boca",
"movie.ogg": "pel·lícula",
"mower.ogg": "tallagespa",
"mud.ogg": "fang",
"mug.ogg": "tassa",
"mule.ogg": "mula",
"muscle.ogg": "múscul",
"mushroom.ogg": "bolet",
"music.ogg": "música",
"musician.ogg": "músic",
"naked.ogg": "nu",
"nap.ogg": "migdiada",
"navel.ogg": "melic",
"neck.ogg": "coll",
"necklace.ogg": "collaret",
"needle.ogg": "agulla",
"nest.ogg": "niu",
"net.ogg": "xarxa",
"newspaper.ogg": "diari",
"night.ogg": "nit",
"nightgown.ogg": "camisa de dormir",
"nose.ogg": "nas",
"nostril.ogg": "nariu",
"notebook.ogg": "quadern",
"number.ogg": "número",
"nun.ogg": "monja",
"nurse.ogg": "infermera",
"nurse_male.ogg": "infermer",
"nut.ogg": "cacauet",
"oar.ogg": "rem",
"ocean.ogg": "oceà",
"office.ogg": "oficina",
"olive.ogg": "oliva",
"on.ogg": "sobre",
"onion.ogg": "ceba",
"open.ogg": "oberta",
"opossum.ogg": "opòssum",
"orange-color.ogg": "taronja",
"orange.ogg": "taronja",
"orchid.ogg": "orquídia",
"ostrich.ogg": "estruç",
"otter.ogg": "llúdriga",
"owl.ogg": "òliba",
"ox.ogg": "bou",
"oyster.ogg": "ostra",
"pacifier.ogg": "xumet",
"page.ogg": "pàgina",
"pair.ogg": "parell",
"pajamas.ogg": "pijama",
"pal.ogg": "col·legues",
"palm_tree.ogg": "palmera",
"pan.ogg": "paella",
"panda.ogg": "ós panda",
"panther.ogg": "pantera",
"panties.ogg": "calces",
"pants.ogg": "pantalons",
"papaya.ogg": "papaia",
"paper.ogg": "paper",
"parachute.ogg": "paracaigudes",
"parakeet.ogg": "periquito",
"parrot.ogg": "lloro",
"patch.ogg": "pedaç",
"path.ogg": "camí",
"paw.ogg": "pota",
"pea.ogg": "pèsol",
"peach.ogg": "préssec",
"peacock.ogg": "paó",
"peak.ogg": "pic",
"pear.ogg": "pera",
"pearl.ogg": "perla",
"peck.ogg": "picotejar",
"pedal.ogg": "pedal",
"pelican.ogg": "pelicà",
"pen.ogg": "bolígraf",
"pencil.ogg": "llapis",
"peony.ogg": "peònia",
"people.ogg": "gent",
"pepper.ogg": "pebre",
"peppers.ogg": "pebrot",
"pet.ogg": "mascota",
"petal.ogg": "pètal",
- "petite.ogg": "petita",
"phone.ogg": "telèfon",
"piano.ogg": "piano",
"picture.ogg": "pintura",
"pie.ogg": "pastís",
"pig.ogg": "porc",
"pigeon.ogg": "tórtora",
"pill.ogg": "píndola",
"pillow.ogg": "coixí",
"pilot.ogg": "pilot",
"pine.ogg": "pi",
"pine_cone.ogg": "pinya",
"pink.ogg": "rosa",
"pip.ogg": "pinyol",
"pipe.ogg": "pipa",
"piranha.ogg": "piranya",
"pirate.ogg": "pirata",
"pizza.ogg": "pizza",
"plane.ogg": "avió",
"planet.ogg": "planeta",
"plant.ogg": "planta",
"plate.ogg": "plat",
"play.ogg": "jugar",
"pliers.ogg": "alicates",
"plow.ogg": "llaurar",
"plum.ogg": "pruna",
"plumber.ogg": "fontaner",
"pocket.ogg": "butxaca",
"pod.ogg": "beina",
"pole.ogg": "pal",
"police.ogg": "policia",
"pompon.ogg": "pompó",
"pond.ogg": "estany",
"pony.ogg": "poni",
"pool.ogg": "piscina",
- "pop.ogg": "crispetes",
+ "popcorn.ogg": "crispetes",
"pope.ogg": "papa",
"porthole.ogg": "ull de bou",
"post.ogg": "bústia",
"pot.ogg": "olla",
"potato.ogg": "patata",
"pounce.ogg": "saltar",
"president.ogg": "president",
"pretty.ogg": "bella",
"price.ogg": "preu",
"priest.ogg": "sacerdot",
"prince.ogg": "princep",
"princess.ogg": "princesa",
"prison.ogg": "presó",
"prisoner.ogg": "pres",
"prize.ogg": "trofeu",
"pug.ogg": "carlí",
"pull.ogg": "estirar",
"pullover.ogg": "jersei",
"pumpkin.ogg": "carbassa",
"puppy.ogg": "cadell",
"pyramid.ogg": "piràmide",
"quarrel.ogg": "baralla",
"queen.ogg": "reina",
"question.ogg": "pregunta",
"quilt.ogg": "edredó",
"quiz.ogg": "examen",
"rabbit.ogg": "conill",
"rabbit_baby.ogg": "conill jove",
"race.ogg": "cursa",
"radio.ogg": "ràdio",
"radish.ogg": "rave",
"raft.ogg": "barca solera",
"rag.ogg": "drap",
"rage.ogg": "ràbia",
"rain.ogg": "pluja",
"raincoat.ogg": "impermeable",
"rake.ogg": "rasclet",
"ramp.ogg": "rampa",
"ran.ogg": "córrer",
"raspberry.ogg": "gerd",
"rat.ogg": "rata",
"razor.ogg": "maquineta d'afaitar",
"read.ogg": "llegir",
"red.ogg": "vermell",
"reptile.ogg": "rèptil",
"rhinoceros.ogg": "rinoceront",
"rice.ogg": "arròs",
"ride.ogg": "ciclista",
"rifle.ogg": "rifle",
"right.ogg": "dreta",
"rip.ogg": "estripar",
"rise.ogg": "pujar",
"river.ogg": "riu",
"road.ogg": "carretera",
"roast.ogg": "rostit",
"robe.ogg": "mantell",
"robot.ogg": "robot",
"rock.ogg": "roca",
"rocket.ogg": "coet",
"rolling_pin.ogg": "corró",
"roof.ogg": "teulada",
"room.ogg": "habitació",
"root.ogg": "arrel",
"rope.ogg": "corda",
"rose.ogg": "rosa",
"round.ogg": "circular",
"rowing.ogg": "rem",
"royal.ogg": "reial",
"rug.ogg": "catifa",
"run.ogg": "córrer",
"sad.ogg": "trist",
"saddle.ogg": "cadira de muntar",
"sail.ogg": "veler",
"sailor.ogg": "mariner",
"salamander.ogg": "salamandra",
"salmon.ogg": "salmó",
"sand.ogg": "sorra",
"sandals.ogg": "sandàlia",
"sandwich.ogg": "sandvitx",
"sash.ogg": "faixa",
- "sat.ogg": "seure",
"sauce.ogg": "salsa",
"sausage.ogg": "salsitxa",
"scale.ogg": "balança",
"scar.ogg": "cicatriu",
- "scared.ogg": "espantar",
+ "scare.ogg": "espantar",
"scarf.ogg": "bufanda",
"school.ogg": "escola",
"school_bag.ogg": "motxilla",
"science.ogg": "ciència",
"scissors.ogg": "tisores",
"scorpion.ogg": "escorpí",
"scratch.ogg": "esgarrapar",
"scream.ogg": "cridar",
"screw.ogg": "vis",
"screwdriver.ogg": "tornavís",
"scribble.ogg": "fer un gargot",
"sea.ogg": "mar",
"seat.ogg": "seient",
"see.ogg": "mirar",
"seed.ogg": "llavor",
"shadow.ogg": "ombra",
"shake.ogg": "sacsejar",
"shark.ogg": "tauró",
"shave.ogg": "esquilar",
"shed.ogg": "cobert",
"sheep.ogg": "ovella",
"shelf.ogg": "prestatge",
"shell.ogg": "closca",
"ship.ogg": "vaixell",
"shirt.ogg": "camisa",
"shoe.ogg": "sabata",
"shoelace.ogg": "cordó",
"shop.ogg": "botiga",
"shore.ogg": "riba",
"short.ogg": "pantalons curts",
"shovel.ogg": "recollidor",
"shower.ogg": "dutxa",
"shrimp.ogg": "gamba",
"shrub.ogg": "arbust",
"shut.ogg": "tancada",
"shutter.ogg": "finestró",
"sick.ogg": "malalt",
"sidewalk.ogg": "vorera",
"sign.ogg": "el senyal",
"sing.ogg": "cantar",
"sink.ogg": "pica",
"sip.ogg": "xarrupar",
"sister.ogg": "germana",
"sit.ogg": "seure",
"skate.ogg": "patinar",
"skeleton.ogg": "esquelet",
"ski.ogg": "esquiar",
"skimmer.ogg": "escumadora",
"skin.ogg": "pell",
"skirt.ogg": "faldilla",
"skunk.ogg": "mofeta",
"sky.ogg": "cel",
"slam.ogg": "esmaixada",
"sled.ogg": "trineu",
"sleep.ogg": "dormir",
"sleeve.ogg": "màniga",
"sleigh.ogg": "trineu",
"slide.ogg": "tobogan",
"slim.ogg": "prima",
"slime.ogg": "bava",
"slippers.ogg": "sabatilla",
"slope.ogg": "pendent",
"sloppy.ogg": "descuidat",
"slot.ogg": "ranura",
"sloth.ogg": "peresós",
"slug.ogg": "llimac",
"small.ogg": "petit",
"smell.ogg": "olorar",
"smile.ogg": "riure",
"smock.ogg": "bata",
"smoke.ogg": "fum",
"smooch.ogg": "bessar",
"snack.ogg": "mos",
"snail.ogg": "cargol",
"snake.ogg": "serp",
"sneaker.ogg": "sabatilla deportiva",
"sniff.ogg": "ensumar",
"snow.ogg": "neu",
"soap.ogg": "sabó",
"sob.ogg": "sanglotar",
"sock.ogg": "mitjó",
"soldier.ogg": "soldat",
"sole.ogg": "llenguado",
"sole_shoe.ogg": "sola de la sabata",
"son.ogg": "fill",
"soup.ogg": "sopa",
"spade.ogg": "pala",
"spaghetti.ogg": "espagueti",
"spark.ogg": "guspira",
"sparrow.ogg": "pardal",
"spatula.ogg": "espàtula",
"speak.ogg": "parlar",
"spear.ogg": "llança",
"spice.ogg": "espècia",
"spider.ogg": "aranya",
"spider_web.ogg": "teranyina",
"spike.ogg": "eriçó",
"spill.ogg": "vessar",
"spinach.ogg": "espinac",
"spine.ogg": "espina",
"spinning_top.ogg": "baldufa",
"splash.ogg": "esquitxar",
"splatter.ogg": "esquitxada",
"sponge.ogg": "esponja",
"spool.ogg": "rodet",
"spoon.ogg": "cullera",
"sport.ogg": "esport",
"spot.ogg": "taca",
"spray.ogg": "ruixar",
"spread.ogg": "untar",
"spring.ogg": "botar",
"spring_season.ogg": "primavera",
"sprinkle.ogg": "espurnes",
"square.ogg": "quadrat",
"squash.ogg": "carbassó",
"squat.ogg": "ajupir",
"squid.ogg": "calamar",
"squirrel.ogg": "esquirol",
"squirt.ogg": "pulveritzador",
"stack.ogg": "pila",
"stage.ogg": "escenari",
"staircase.ogg": "escala",
"stamp.ogg": "segell",
"stand.ogg": "dret",
"star.ogg": "estel",
"stare.ogg": "mirar fixament",
"starfish.ogg": "estrella de mar",
- "steak.ogg": "filet",
"steam.ogg": "vapor",
"steep.ogg": "empinat",
"steeple.ogg": "campanar",
"stem.ogg": "tija",
"step.ogg": "esglaó",
"stew.ogg": "guisat",
"stick.ogg": "branca",
"sting.ogg": "fibló",
"stinky.ogg": "pudor",
"stitch.ogg": "puntada",
"stomach.ogg": "estómac",
"stone.ogg": "pedra",
"stop.ogg": "aturar",
"store.ogg": "botiga",
"stove.ogg": "cuina",
"straight.ogg": "recte",
"strainer.ogg": "colador",
"straw.ogg": "palla",
"strawberry.ogg": "maduixa",
"stream.ogg": "corrent",
"street.ogg": "carrer",
"stretch.ogg": "estirar",
"string.ogg": "cordill",
"stripe.ogg": "ratlla",
"strong.ogg": "fort",
"student.ogg": "estudiant",
"study.ogg": "estudiar",
"stump.ogg": "tronc",
"sugar.ogg": "sucre",
"suit.ogg": "mudada",
"suitcase.ogg": "maleta",
"summer.ogg": "estiu",
"summit.ogg": "cim",
"sun.ogg": "el Sol",
"swan.ogg": "cigne",
"sweat.ogg": "suor",
"sweatshirt.ogg": "dessuadora",
"swim.ogg": "nedar",
"table.ogg": "taula",
"tablecloth.ogg": "estovalles",
"tadpole.ogg": "capgròs",
"tag.ogg": "etiqueta",
"tail.ogg": "cua",
"tall.ogg": "alt",
"tape_measure.ogg": "cinta mètrica",
"taxi.ogg": "taxi",
"teach.ogg": "ensenyar",
"teacher.ogg": "professora",
"tear.ogg": "esquinçar",
"teddy.ogg": "peluix",
"teeth.ogg": "dentadura",
"television.ogg": "televisió",
"temple.ogg": "temple",
"tennis.ogg": "tennis",
"tent.ogg": "tenda",
"text.ogg": "text",
"thick.ogg": "gruixut",
"thief.ogg": "lladre",
"thigh.ogg": "cuixa",
"think.ogg": "pensar",
"thread.ogg": "bobina",
"throat.ogg": "gola",
"throw.ogg": "llançar",
"thumb.ogg": "polze",
"tick.ogg": "paparra",
"ticket.ogg": "bitllet",
"tiger.ogg": "tigre",
"time.ogg": "temps",
"tin.ogg": "llauna",
"tire.ogg": "pneumàtic",
"tired.ogg": "cansat",
"tissue.ogg": "mocador",
+ "to_drink.ogg": "beure",
"toad.ogg": "gripau",
"toaster.ogg": "torradora",
"toe.ogg": "dit del peu",
"toilet.ogg": "vàter",
"tomatoe.ogg": "tomàquet",
"tongs.ogg": "pinces",
"tongue.ogg": "llengua",
"tool.ogg": "eina",
"top.ogg": "cim",
"torch.ogg": "torxa",
"touch.ogg": "tocar",
"towel.ogg": "tovallola",
"toy.ogg": "joguina",
"trail.ogg": "sender",
"train.ogg": "tren",
"train_station.ogg": "estació de tren",
"trap.ogg": "parany",
"trash.ogg": "escombraries",
"tray.ogg": "safata",
"treat.ogg": "dolç",
"tree.ogg": "arbre",
"triangle.ogg": "triangle",
"tribe.ogg": "tribu",
"trip.ogg": "viatge",
"truck.ogg": "camió",
"tube.ogg": "llapis de llavis",
"tulip.ogg": "tulipa",
"tune.ogg": "melodia",
"turkey.ogg": "gall dindi",
"turnip.ogg": "nap",
"turtle.ogg": "tortuga",
"tusk.ogg": "ullal",
"twin_boys.ogg": "bessons",
"twin_girls.ogg": "bessones",
"umbrella.ogg": "paraigua",
"under.ogg": "sota",
"uniform.ogg": "uniforme",
"van.ogg": "furgoneta",
"vapor.ogg": "vapor",
"vase.ogg": "gerro",
"vegetable.ogg": "vegetal",
"vein.ogg": "vena",
"verdure.ogg": "verdura",
"vest.ogg": "armilla",
"vet.ogg": "veterinari",
"viper.ogg": "escurçó",
"vowel.ogg": "vocal",
"vulture.ogg": "voltor",
"wag.ogg": "moure la cua",
"walk.ogg": "caminar",
"wall.ogg": "mur",
"walnut.ogg": "nou",
"wart.ogg": "berruga",
"wash.ogg": "banyar",
"wasp.ogg": "vespa",
"watch.ogg": "rellotge",
"water.ogg": "aigua",
"wave.ogg": "onada",
"wedding.ogg": "casament",
"wedge.ogg": "falca",
"weight.ogg": "pesa",
"wet.ogg": "mullat",
"whale.ogg": "balena",
"wheat.ogg": "blat",
"wheel.ogg": "roda",
"whisk.ogg": "batedora",
"whisper.ogg": "xiuxiuejar",
"white.ogg": "blanc",
"wide.ogg": "ample",
"wife.ogg": "muller",
"wig.ogg": "perruca",
"win.ogg": "guanyar",
"wind.ogg": "vent",
"window.ogg": "finestra",
"window_glass.ogg": "vidre de la finestra",
"wing.ogg": "ala",
"winter.ogg": "hivern",
"wolf.ogg": "llop",
"woman.ogg": "dona",
"wood.ogg": "fusta",
"word.ogg": "paraula",
"worker.ogg": "treballador",
"world.ogg": "món",
"wreath.ogg": "garlanda",
"wrench.ogg": "clau anglesa",
"wrist.ogg": "canell",
"write.ogg": "escriure",
"yellow.ogg": "groc",
"yogurt.ogg": "iogurt",
"yum.ogg": "deliciós",
"zebra.ogg": "zebra",
"zipper.ogg": "cremallera",
"zoo.ogg": "zoològic"
-}
+}
\ No newline at end of file
diff --git a/src/activities/lang/resource/content-ca.json b/src/activities/lang/resource/content-ca@valencia.json
similarity index 97%
copy from src/activities/lang/resource/content-ca.json
copy to src/activities/lang/resource/content-ca@valencia.json
index e6ce4bdc8..545692b00 100644
--- a/src/activities/lang/resource/content-ca.json
+++ b/src/activities/lang/resource/content-ca@valencia.json
@@ -1,1107 +1,1092 @@
{
"10.ogg": "deu",
"11.ogg": "onze",
"12.ogg": "dotze",
"16.ogg": "setze",
"U0030.ogg": "zero",
"U0031.ogg": "un",
"U0032.ogg": "dos",
"U0033.ogg": "tres",
"U0034.ogg": "quatre",
"U0035.ogg": "cinc",
"U0036.ogg": "sis",
"U0037.ogg": "set",
"U0038.ogg": "vuit",
"U0039.ogg": "nou",
"accountant.ogg": "comptable",
"ache.ogg": "dolor",
"acorn.ogg": "gla",
"actor.ogg": "actor",
"air_horn.ogg": "botzina",
"alarmclock.ogg": "despertador",
"alligator.ogg": "caiman",
"alphabet.ogg": "alfabet",
"anchor.ogg": "àncora",
"angel.ogg": "àngel",
"angry.ogg": "enfadat",
"animal.ogg": "animal",
"ankle.ogg": "turmell",
"ant.ogg": "formiga",
"anteater.ogg": "ós formiguer",
"antelope.ogg": "antílop",
"apple.ogg": "poma",
"apple_tree.ogg": "pomera",
"appliance.ogg": "aparell",
"apricot.ogg": "albercoc",
"arm.ogg": "braç",
"armchair.ogg": "butaca",
"artichoke.ogg": "carxofa",
"artist.ogg": "artista",
"asparagus.ogg": "espàrrec",
"astronaut.ogg": "astronauta",
- "ate.ogg": "menjar",
"athlete.ogg": "atleta",
"avocado.ogg": "alvocat",
"ax.ogg": "destral",
"baby_bottle.ogg": "biberó",
"back.ogg": "esquena",
"badge.ogg": "insígnia",
"bag.ogg": "bossa",
"bait.ogg": "esquer",
- "bake.ogg": "cuinar",
"balance.ogg": "balança",
"bald.ogg": "calba",
"ball.ogg": "bola",
"ball_of_yarn.ogg": "cabdell de llana",
"ball_soccer.ogg": "pilota de futbol",
"ballet.ogg": "ballet",
"bank.ogg": "banc",
+ "banker_female.ogg": "banquera",
"bark.ogg": "bordar",
"barn.ogg": "graner",
"bat.ogg": "ratpenat",
"bath.ogg": "banyera",
"bathing_suit.ogg": "banyador",
"bay.ogg": "badia",
"beach.ogg": "platja",
- "bead.ogg": "bombolla",
"bean.ogg": "fesol",
"bear.ogg": "ós",
"beard.ogg": "barba",
"beat.ogg": "batre",
"beaver.ogg": "castor",
"bed.ogg": "llit",
"bedroom.ogg": "dormitori",
"bee.ogg": "abella",
- "beef.ogg": "carn de boví",
"beetle.ogg": "escarabat",
"beg.ogg": "demanar",
"behind.ogg": "darrere",
"bell.ogg": "campana",
"belly.ogg": "panxa",
"bench.ogg": "banc",
"bib.ogg": "pitet",
"big.ogg": "gran",
"big_top.ogg": "carpa de circ",
"bike.ogg": "bicicleta",
"bird.ogg": "ocell",
"bit.ogg": "mica",
"bite.ogg": "mossegar",
"black.ogg": "negre",
"blackberry.ogg": "móra",
"blackbird.ogg": "merla",
"blade.ogg": "tall",
"blind.ogg": "cec",
"blink.ogg": "picada d'ullet",
"block.ogg": "bloc",
"blond.ogg": "rossa",
"blue.ogg": "blau",
"blueberry.ogg": "nabiu",
"blush.ogg": "rubor",
"board.ogg": "tauló",
"boat.ogg": "barca",
"boil.ogg": "bullir",
"bolt.ogg": "femella",
"bomb.ogg": "bomba",
"bone.ogg": "os",
"book.ogg": "llibre",
"bookcase.ogg": "llibreria",
"bottom.ogg": "natges",
"box.ogg": "caixa",
"boxer.ogg": "boxejador",
"boy.ogg": "noi",
"braid.ogg": "trena",
"brain.ogg": "cervell",
"branch.ogg": "branca",
"bread.ogg": "pa",
"break.ogg": "trencar",
"breast.ogg": "pit",
"brick.ogg": "maó",
"bricklayer.ogg": "paleta",
"bride.ogg": "núvia",
"bridge.ogg": "pont",
"bright.ogg": "brillant",
"broccoli.ogg": "bròquil",
"brother.ogg": "germà",
"brown.ogg": "marró",
"brush.ogg": "brotxa",
"bubble.ogg": "bombolla",
"bucket.ogg": "galleda",
"bud.ogg": "brot",
"buffalo.ogg": "búfal",
"bug.ogg": "insecte",
"bulb.ogg": "bombeta",
"bull.ogg": "toro",
"bump.ogg": "bony",
"bun.ogg": "brioix",
"bus.ogg": "autobús",
"bush.ogg": "arbust",
"butcher.ogg": "carnisser",
"butter.ogg": "mantega",
"butterfly.ogg": "papallona",
"button.ogg": "botó",
"cabbage.ogg": "col",
"cabin.ogg": "cabana",
"cacao.ogg": "cacau",
"cactus.ogg": "cactus",
"cage.ogg": "gàbia",
"cake.ogg": "pastís",
"call.ogg": "trucada",
"camel.ogg": "camell",
"camera.ogg": "càmera",
"camp.ogg": "acampar",
"can.ogg": "llauna",
"canary.ogg": "canari",
"candle.ogg": "espelma",
"candy.ogg": "caramel",
"cane.ogg": "bastó",
"canoe.ogg": "canoa",
"canon.ogg": "canó",
"canyon.ogg": "canó",
"cap.ogg": "gorra",
"cape.ogg": "capa",
"car.ogg": "cotxe",
"carafe.ogg": "gerra",
"card.ogg": "tarjeta",
"carnival.ogg": "carnaval",
"carpenter.ogg": "fuster",
"carpet.ogg": "catifa",
"carrot.ogg": "pastanaga",
"cart.ogg": "carro",
"cash.ogg": "diner",
"castle.ogg": "castell",
"cat.ogg": "gat",
"cat_female.ogg": "gata",
"catch.ogg": "pescar",
"caterpillar.ogg": "eruga",
"cauldron.ogg": "caldera",
"cauliflower.ogg": "coliflor",
"cave.ogg": "cova",
"cavern.ogg": "caverna",
"celery.ogg": "api",
"centipede.ogg": "centpeus",
"cereal.ogg": "cereal",
"chain.ogg": "cadena",
"chair.ogg": "cadira",
"chalk.ogg": "guix",
"chameleon.ogg": "camaleó",
"chandelier.ogg": "aranya",
"chat.ogg": "parlar",
"cheek.ogg": "galta",
"cheer.ogg": "animar",
"cheese.ogg": "formatge",
"chef.ogg": "cuiner",
"cherry.ogg": "cirera",
"chest.ogg": "bagul",
"chick.ogg": "pollet",
"chicken.ogg": "pollastre",
- "chief.ogg": "indi",
- "child.ogg": "nen",
+ "child.ogg": "infant",
"chimney.ogg": "xemeneia",
"chimp.ogg": "ximpanzé",
"chin.ogg": "barbeta",
"chocolate.ogg": "xocolata",
"chop.ogg": "tallar",
- "chore.ogg": "tasca de la llar",
+ "chores.ogg": "tasques",
"christmas.ogg": "nadal",
"cigar.ogg": "puro",
"circus.ogg": "circ",
"city.ogg": "ciutat",
"clam.ogg": "cloïssa",
"clap.ogg": "picar de mans",
"class.ogg": "classe",
"claw.ogg": "urpa",
"clay.ogg": "argila",
"clean.ogg": "rentar",
"cleaning_lady.ogg": "senyora de la neteja",
"cliff.ogg": "penya-segat",
"climb.ogg": "escalada",
"clock.ogg": "rellotge",
"cloth.ogg": "drap",
"clothes_hanger.ogg": "penjador",
"cloud.ogg": "núvol",
"cloudy.ogg": "ennuvolat",
"clover.ogg": "trèvol",
"clown.ogg": "pallasso",
"coach.ogg": "entrenador",
"coast.ogg": "costa",
"coat.ogg": "abric",
"cobra.ogg": "cobra",
"coconut.ogg": "coco",
"cod.ogg": "bacallà",
"coffee.ogg": "cafè",
"coin.ogg": "moneda",
"cold.ogg": "fred",
"color.ogg": "color",
"colt.ogg": "poltre",
"comb.ogg": "pinta",
"cone.ogg": "con",
+ "cook.ogg": "cuinar",
"cookie.ogg": "galeta",
"cork.ogg": "suro",
"corn.ogg": "blat de moro",
"couch.ogg": "sofà",
"cough.ogg": "tossir",
"couple.ogg": "parella",
"cow.ogg": "vaca",
"cowboy.ogg": "vaquer",
"crab.ogg": "cranc",
"cradle.ogg": "bressol",
"craft.ogg": "manualitat",
"crawl.ogg": "gatejar",
"crazy.ogg": "ximple",
"creek.ogg": "rierol",
"crepe.ogg": "crep",
"crib.ogg": "bressol",
- "criminal.ogg": "criminal",
"croak.ogg": "raucar",
"crocodile.ogg": "cocodril",
"cross.ogg": "creu",
"crow.ogg": "corb",
"crown.ogg": "corona",
"crumb.ogg": "engrunes",
"crust.ogg": "crosta",
"cry.ogg": "plorar",
"crystal.ogg": "vidre",
"cube.ogg": "cub",
"cucumber.ogg": "cogombre",
"curtain.ogg": "cortina",
"cut.ogg": "tallar",
"cute.ogg": "bufona",
"dad.ogg": "pare",
"daffodil.ogg": "narcís",
"daisy.ogg": "margarida",
"dam.ogg": "presa",
"dance.ogg": "ballar",
"dandelion.ogg": "dent de lleó",
- "danger.ogg": "perill",
- "dark.ogg": "negra",
"dart_board.ogg": "tauler de dards",
"date_fruit.ogg": "dàtil",
"deer.ogg": "cérvol",
"den.ogg": "cau",
"desert.ogg": "desert",
"desk.ogg": "escriptori",
"dessert.ogg": "postre",
"diamond.ogg": "diamant",
"dig.ogg": "cavar",
"dirt.ogg": "sòl",
"dirty.ogg": "brut",
"dish.ogg": "font",
"dishcloth.ogg": "drap de cuina",
"dive.ogg": "immersió",
"doctor.ogg": "metge",
"doe.ogg": "cérvola",
"dog.ogg": "gos",
"doll.ogg": "nina",
"dolphin.ogg": "dofí",
"domino.ogg": "dominó",
"door.ogg": "porta",
"doormat.ogg": "estora",
"dot.ogg": "punt",
"doughnut.ogg": "bunyol",
"dove.ogg": "colom",
"dragon.ogg": "drac",
"dragonfly.ogg": "libèl·lula",
- "drank.ogg": "beure",
"draw.ogg": "dibuixar",
"drawer.ogg": "calaix",
"dream.ogg": "somiar",
"dress.ogg": "vestit",
"drink.ogg": "beguda",
- "drinking.ogg": "beure",
"drip.ogg": "gota",
"drive.ogg": "conduir",
"drool.ogg": "bavejar",
"drum.ogg": "tambor",
"dry.ogg": "assecar",
"duck.ogg": "ànec",
"duck_mother.ogg": "ànega",
"dune.ogg": "duna",
"dwarf.ogg": "nan",
"eagle.ogg": "àguila",
"ear.ogg": "orella",
"earth.ogg": "la Terra",
"eat.ogg": "menjar",
"egg.ogg": "ou",
"eggplant.ogg": "albergínia",
"elbow.ogg": "colze",
"electrician.ogg": "electricista",
"elk.ogg": "uapití",
"empty.ogg": "buida",
"engine.ogg": "motor",
"engineer.ogg": "enginyer",
"eraser.ogg": "goma d'esborrar",
"explore.ogg": "explorar",
"eyelash.ogg": "pestanya",
"eyes.ogg": "ull",
"face.ogg": "cara",
"fair.ogg": "atracció",
"fairy.ogg": "fada",
- "fall_down.ogg": "caure",
+ "fall.ogg": "caure",
"fall_season.ogg": "tardor",
"family.ogg": "família",
"fan.ogg": "ventilador",
"farm.ogg": "granja",
"farmer.ogg": "granger",
"fat.ogg": "gras",
"faucet.ogg": "aixeta",
"fawn.ogg": "cervatell",
+ "fear.ogg": "por",
"feast.ogg": "banquet",
"feather.ogg": "ploma",
"feed.ogg": "donar de menjar",
- "feet.ogg": "peu",
- "fell.ogg": "caure",
"femur.ogg": "fèmur",
"fetch.ogg": "informar",
"fig.ogg": "figa",
"fin.ogg": "aleta",
"find.ogg": "trobar",
"finger.ogg": "dit",
"fire.ogg": "foc",
"fire_extinguisher.ogg": "extintor",
"fireman.ogg": "bomber",
"fish.ogg": "peix",
"fisherman.ogg": "pescador",
"fist.ogg": "puny",
"flacon.ogg": "dosificador",
"flag.ogg": "bandera",
"flame.ogg": "flama",
"flamingo.ogg": "flamenc",
"flash.ogg": "llanterna",
"flat.ogg": "pis",
"flies.ogg": "mosca",
- "flight.ogg": "vol",
"float.ogg": "flotar",
"flour.ogg": "farina",
"flower.ogg": "flor",
"fluff.ogg": "borrissol",
"flute.ogg": "flauta",
"fly.ogg": "volar",
"foam.ogg": "escuma",
- "food.ogg": "hamburguesa",
"foot.ogg": "peu",
"forest.ogg": "bosc",
"fork.ogg": "forquilla",
"fountain.ogg": "font",
"fox.ogg": "guineu",
"freeze.ogg": "congelar",
"friend.ogg": "amic",
"fries.ogg": "patata fregida",
"frog.ogg": "granota",
"front.ogg": "davant",
- "frown.ogg": "posar mala cara",
"fruit.ogg": "fruita",
"fudge.ogg": "dolç de xocolata",
"full.ogg": "ple",
- "fun.ogg": "diversió",
"fur.ogg": "pell",
"game.ogg": "joc",
"garage.ogg": "garatge",
"garden.ogg": "jardi",
"garlic.ogg": "all",
"gem.ogg": "gemma",
"giant.ogg": "gegant",
"gift.ogg": "regal",
"giraffe.ogg": "girafa",
"girl.ogg": "noia",
"glass.ogg": "got",
"glasses.ogg": "ulleres",
"glove.ogg": "guant",
"glue.ogg": "cola",
"gnome.ogg": "gnom",
"goat.ogg": "cabra",
"golden.ogg": "daurada",
"golf.ogg": "golf",
"goose.ogg": "oca",
"gorilla.ogg": "goril·la",
"grain.ogg": "gra",
"grandmother.ogg": "àvia",
"grape.ogg": "raïm",
"grapefruit.ogg": "pomelo",
"grass.ogg": "herba",
"grave.ogg": "tomba",
"gray.ogg": "gris",
"green.ogg": "verd",
"grill.ogg": "graella",
"grin.ogg": "somriure",
"ground.ogg": "el terra",
"growl.ogg": "grunyir",
"guignol.ogg": "putxinel·li",
"guinea_pig.ogg": "conillet d'Índies",
"gum.ogg": "xiclet",
"hair.ogg": "cabell",
"hair_dryer.ogg": "assecador de cabell",
"half.ogg": "meitat",
"ham.ogg": "pernil",
+ "hamburger.ogg": "hamburguesa",
"hammer.ogg": "martell",
"hand.ogg": "mà",
"handlebar.ogg": "manillar",
"happy.ogg": "feliç",
"harp.ogg": "arpa",
"hat.ogg": "barret",
- "hatch.ogg": "sortir de l'ou",
+ "hatch.ogg": "eixir de l'ou",
"hay.ogg": "farratge",
"head.ogg": "cap",
"hear.ogg": "sentir",
"heat.ogg": "calor",
"hedge.ogg": "tanca",
"hedgehog.ogg": "eriçó",
"heel.ogg": "taló",
"helmet.ogg": "casc",
"hen.ogg": "gallina",
"herd.ogg": "ramat",
- "high.ogg": "a gran alçada",
+ "high.ogg": "a gran alçària",
"hike.ogg": "caminar",
"hill.ogg": "turó",
"hip.ogg": "maluc",
"hippopotamus.ogg": "hipopòtam",
"hit.ogg": "colpejar",
"hive.ogg": "rusc",
"hockey.ogg": "hoquei",
"hole.ogg": "forat",
"home.ogg": "casa",
"hook.ogg": "ham",
"hop.ogg": "saltar",
"horse.ogg": "cavall",
"hose.ogg": "mànega",
"hospital.ogg": "hospital",
"hot.ogg": "calent",
"hot_dog.ogg": "frankfurt",
"hound.ogg": "gos de caça",
"house.ogg": "casa",
"howl.ogg": "udolar",
"hug.ogg": "abraçar",
"huge.ogg": "enorme",
"hummingbird.ogg": "colibrí",
- "hunchback.ogg": "geperut",
+ "hunchbacked.ogg": "geperut",
"hunter.ogg": "caçador",
"husband.ogg": "marit",
"hut.ogg": "cabana",
"hyena.ogg": "hiena",
"ice.ogg": "glaçó",
"iceberg.ogg": "iceberg",
"iguana.ogg": "iguana",
"ill.ogg": "malalt",
"ink.ogg": "tinta",
"island.ogg": "illa",
"jacket.ogg": "jaqueta",
"jaguar.ogg": "jaguar",
"jam.ogg": "melmelada",
"jay.ogg": "gaig",
"jelly.ogg": "gelatina",
"jellyfish.ogg": "medusa",
"jewel.ogg": "joia",
"job.ogg": "treball",
"jockey.ogg": "joquei",
"jog.ogg": "fúting",
+ "joy.ogg": "goig",
"judge.ogg": "jutge",
"judo.ogg": "judo",
"juggler.ogg": "malabarista",
"juice.ogg": "suc",
"jump.ogg": "saltar",
"kangaroo.ogg": "cangur",
"keel.ogg": "equilibri",
"kernel.ogg": "nucli",
"keyboard.ogg": "teclat",
"kimono.ogg": "quimono",
"king.ogg": "rei",
"kiss.ogg": "petó",
"kitchen.ogg": "cuina",
"kite.ogg": "estel",
"kitten.ogg": "gatet",
"kiwi.ogg": "kiwi",
"knee.ogg": "genoll",
"kneel.ogg": "agenollar",
"knife.ogg": "ganivet",
"knight.ogg": "cavaller",
"knit.ogg": "teixir",
"knot.ogg": "nus",
"koala.ogg": "coala",
"lad.ogg": "mosso",
"lady.ogg": "dama",
"ladybug.ogg": "marieta",
"lake.ogg": "llac",
"lama.ogg": "llama",
"lamb.ogg": "xai",
"lamp.ogg": "el llum",
"land.ogg": "terreny",
"lane.ogg": "carril",
"lap.ogg": "a la falda",
"lasso.ogg": "llaç",
"laugh.ogg": "riure",
"lava.ogg": "lava",
"lawn.ogg": "gespa",
"lawyer.ogg": "advocat",
"leaf.ogg": "fulla",
- "ledge.ogg": "sortint",
+ "ledge.ogg": "eixint",
"leek.ogg": "porro",
"left.ogg": "esquerra",
"leg.ogg": "cama",
- "leg_animal.ogg": "pota",
"lemon.ogg": "llimona",
"lemonade.ogg": "llimonada",
"lemur.ogg": "lèmur",
"leopard.ogg": "lleopard",
"lettuce.ogg": "enciam",
"librarian.ogg": "bibliotecària",
"lick.ogg": "llepar",
"lid.ogg": "tapa",
"lift.ogg": "aixecar",
"light.ogg": "el llum",
"lighthouse.ogg": "far",
"lightning.ogg": "llamp",
"lilac.ogg": "lilà",
"lime.ogg": "llima",
"line.ogg": "codi de barres",
"link.ogg": "enllaç",
"lion.ogg": "lleó",
"lion_cub.ogg": "cadell de lleó",
"lip.ogg": "llavi",
"liquid.ogg": "líquid",
"lizard.ogg": "llangardaix",
"lobster.ogg": "llagosta",
"log.ogg": "tronc",
"look.ogg": "mirar-se",
"lunch.ogg": "dinar",
"mad.ogg": "ira",
"magic.ogg": "màgic",
"magnet.ogg": "imant",
"magnifying_glass.ogg": "lupa",
"magpie.ogg": "garsa",
"mail.ogg": "correu",
"man.ogg": "home",
"mane.ogg": "cabellera",
"mango.ogg": "mango",
"map.ogg": "mapa",
"maple.ogg": "auró",
"marble.ogg": "bala",
"mashed_potatoes.ogg": "puré de patates",
"mask.ogg": "màscara",
"mast.ogg": "màstil",
"mat.ogg": "estora",
"match.ogg": "llumí",
"mate.ogg": "company",
"mattress.ogg": "matalàs",
"mauve.ogg": "malva",
"meal.ogg": "àpat",
"meat.ogg": "carn",
"mechanic.ogg": "mecànic",
"medal.ogg": "medalla",
"meet.ogg": "trobar-se",
"melon.ogg": "meló",
- "men.ogg": "multitud",
"merry-go-round.ogg": "cavallet",
"mice.ogg": "ratolins",
"microphone.ogg": "micròfon",
"milk.ogg": "llet",
"mill.ogg": "molí",
"mimosa.ogg": "mimosa",
"mirror.ogg": "mirall",
"mixer.ogg": "mesclador",
"mole.ogg": "talp",
"mom.ogg": "mama",
"moon.ogg": "Lluna",
"moose.ogg": "ant",
"mop.ogg": "fregona",
"mosque.ogg": "mesquita",
"mosquito.ogg": "mosquit",
"mother.ogg": "mare",
"motorcycle.ogg": "moto",
"mountain.ogg": "muntanya",
"mouse.ogg": "ratolí",
"mouth.ogg": "boca",
"movie.ogg": "pel·lícula",
"mower.ogg": "tallagespa",
"mud.ogg": "fang",
"mug.ogg": "tassa",
"mule.ogg": "mula",
"muscle.ogg": "múscul",
"mushroom.ogg": "bolet",
"music.ogg": "música",
"musician.ogg": "músic",
"naked.ogg": "nu",
"nap.ogg": "migdiada",
"navel.ogg": "melic",
"neck.ogg": "coll",
"necklace.ogg": "collaret",
"needle.ogg": "agulla",
"nest.ogg": "niu",
"net.ogg": "xarxa",
"newspaper.ogg": "diari",
"night.ogg": "nit",
"nightgown.ogg": "camisa de dormir",
"nose.ogg": "nas",
"nostril.ogg": "nariu",
"notebook.ogg": "quadern",
"number.ogg": "número",
"nun.ogg": "monja",
"nurse.ogg": "infermera",
"nurse_male.ogg": "infermer",
"nut.ogg": "cacauet",
"oar.ogg": "rem",
"ocean.ogg": "oceà",
"office.ogg": "oficina",
"olive.ogg": "oliva",
"on.ogg": "sobre",
"onion.ogg": "ceba",
"open.ogg": "oberta",
"opossum.ogg": "opòssum",
"orange-color.ogg": "taronja",
"orange.ogg": "taronja",
"orchid.ogg": "orquídia",
"ostrich.ogg": "estruç",
"otter.ogg": "llúdriga",
"owl.ogg": "òliba",
"ox.ogg": "bou",
"oyster.ogg": "ostra",
"pacifier.ogg": "xumet",
"page.ogg": "pàgina",
"pair.ogg": "parell",
"pajamas.ogg": "pijama",
"pal.ogg": "col·legues",
"palm_tree.ogg": "palmera",
"pan.ogg": "paella",
"panda.ogg": "ós panda",
"panther.ogg": "pantera",
"panties.ogg": "calces",
"pants.ogg": "pantalons",
"papaya.ogg": "papaia",
"paper.ogg": "paper",
"parachute.ogg": "paracaigudes",
"parakeet.ogg": "periquito",
"parrot.ogg": "lloro",
"patch.ogg": "pedaç",
"path.ogg": "camí",
"paw.ogg": "pota",
"pea.ogg": "pèsol",
- "peach.ogg": "préssec",
+ "peach.ogg": "bresquilla",
"peacock.ogg": "paó",
"peak.ogg": "pic",
"pear.ogg": "pera",
"pearl.ogg": "perla",
"peck.ogg": "picotejar",
"pedal.ogg": "pedal",
"pelican.ogg": "pelicà",
"pen.ogg": "bolígraf",
"pencil.ogg": "llapis",
"peony.ogg": "peònia",
"people.ogg": "gent",
"pepper.ogg": "pebre",
"peppers.ogg": "pebrot",
"pet.ogg": "mascota",
"petal.ogg": "pètal",
- "petite.ogg": "petita",
"phone.ogg": "telèfon",
"piano.ogg": "piano",
"picture.ogg": "pintura",
"pie.ogg": "pastís",
"pig.ogg": "porc",
"pigeon.ogg": "tórtora",
"pill.ogg": "píndola",
"pillow.ogg": "coixí",
"pilot.ogg": "pilot",
"pine.ogg": "pi",
"pine_cone.ogg": "pinya",
"pink.ogg": "rosa",
"pip.ogg": "pinyol",
"pipe.ogg": "pipa",
"piranha.ogg": "piranya",
"pirate.ogg": "pirata",
"pizza.ogg": "pizza",
"plane.ogg": "avió",
"planet.ogg": "planeta",
"plant.ogg": "planta",
"plate.ogg": "plat",
"play.ogg": "jugar",
"pliers.ogg": "alicates",
"plow.ogg": "llaurar",
"plum.ogg": "pruna",
"plumber.ogg": "fontaner",
"pocket.ogg": "butxaca",
"pod.ogg": "beina",
"pole.ogg": "pal",
"police.ogg": "policia",
"pompon.ogg": "pompó",
"pond.ogg": "estany",
"pony.ogg": "poni",
"pool.ogg": "piscina",
- "pop.ogg": "crispetes",
+ "popcorn.ogg": "crispetes",
"pope.ogg": "papa",
"porthole.ogg": "ull de bou",
"post.ogg": "bústia",
"pot.ogg": "olla",
"potato.ogg": "patata",
"pounce.ogg": "saltar",
"president.ogg": "president",
"pretty.ogg": "bella",
"price.ogg": "preu",
"priest.ogg": "sacerdot",
"prince.ogg": "princep",
"princess.ogg": "princesa",
"prison.ogg": "presó",
"prisoner.ogg": "pres",
"prize.ogg": "trofeu",
"pug.ogg": "carlí",
"pull.ogg": "estirar",
"pullover.ogg": "jersei",
"pumpkin.ogg": "carbassa",
"puppy.ogg": "cadell",
"pyramid.ogg": "piràmide",
"quarrel.ogg": "baralla",
"queen.ogg": "reina",
"question.ogg": "pregunta",
"quilt.ogg": "edredó",
"quiz.ogg": "examen",
"rabbit.ogg": "conill",
"rabbit_baby.ogg": "conill jove",
"race.ogg": "cursa",
"radio.ogg": "ràdio",
"radish.ogg": "rave",
"raft.ogg": "barca solera",
"rag.ogg": "drap",
"rage.ogg": "ràbia",
"rain.ogg": "pluja",
"raincoat.ogg": "impermeable",
"rake.ogg": "rasclet",
"ramp.ogg": "rampa",
"ran.ogg": "córrer",
"raspberry.ogg": "gerd",
"rat.ogg": "rata",
"razor.ogg": "maquineta d'afaitar",
"read.ogg": "llegir",
- "red.ogg": "vermell",
+ "red.ogg": "roig",
"reptile.ogg": "rèptil",
"rhinoceros.ogg": "rinoceront",
"rice.ogg": "arròs",
"ride.ogg": "ciclista",
"rifle.ogg": "rifle",
"right.ogg": "dreta",
"rip.ogg": "estripar",
"rise.ogg": "pujar",
"river.ogg": "riu",
"road.ogg": "carretera",
"roast.ogg": "rostit",
"robe.ogg": "mantell",
"robot.ogg": "robot",
"rock.ogg": "roca",
"rocket.ogg": "coet",
"rolling_pin.ogg": "corró",
"roof.ogg": "teulada",
"room.ogg": "habitació",
"root.ogg": "arrel",
"rope.ogg": "corda",
"rose.ogg": "rosa",
"round.ogg": "circular",
"rowing.ogg": "rem",
"royal.ogg": "reial",
"rug.ogg": "catifa",
"run.ogg": "córrer",
"sad.ogg": "trist",
"saddle.ogg": "cadira de muntar",
"sail.ogg": "veler",
"sailor.ogg": "mariner",
"salamander.ogg": "salamandra",
"salmon.ogg": "salmó",
"sand.ogg": "sorra",
"sandals.ogg": "sandàlia",
"sandwich.ogg": "sandvitx",
"sash.ogg": "faixa",
- "sat.ogg": "seure",
"sauce.ogg": "salsa",
"sausage.ogg": "salsitxa",
"scale.ogg": "balança",
"scar.ogg": "cicatriu",
- "scared.ogg": "espantar",
+ "scare.ogg": "espantar",
"scarf.ogg": "bufanda",
"school.ogg": "escola",
"school_bag.ogg": "motxilla",
"science.ogg": "ciència",
"scissors.ogg": "tisores",
"scorpion.ogg": "escorpí",
"scratch.ogg": "esgarrapar",
"scream.ogg": "cridar",
"screw.ogg": "vis",
"screwdriver.ogg": "tornavís",
"scribble.ogg": "fer un gargot",
"sea.ogg": "mar",
"seat.ogg": "seient",
"see.ogg": "mirar",
"seed.ogg": "llavor",
"shadow.ogg": "ombra",
"shake.ogg": "sacsejar",
"shark.ogg": "tauró",
"shave.ogg": "esquilar",
"shed.ogg": "cobert",
"sheep.ogg": "ovella",
"shelf.ogg": "prestatge",
"shell.ogg": "closca",
"ship.ogg": "vaixell",
"shirt.ogg": "camisa",
"shoe.ogg": "sabata",
"shoelace.ogg": "cordó",
"shop.ogg": "botiga",
"shore.ogg": "riba",
"short.ogg": "pantalons curts",
"shovel.ogg": "recollidor",
"shower.ogg": "dutxa",
"shrimp.ogg": "gamba",
"shrub.ogg": "arbust",
"shut.ogg": "tancada",
"shutter.ogg": "finestró",
"sick.ogg": "malalt",
"sidewalk.ogg": "vorera",
"sign.ogg": "el senyal",
"sing.ogg": "cantar",
"sink.ogg": "pica",
"sip.ogg": "xarrupar",
"sister.ogg": "germana",
"sit.ogg": "seure",
"skate.ogg": "patinar",
"skeleton.ogg": "esquelet",
"ski.ogg": "esquiar",
"skimmer.ogg": "escumadora",
"skin.ogg": "pell",
"skirt.ogg": "faldilla",
"skunk.ogg": "mofeta",
"sky.ogg": "cel",
"slam.ogg": "esmaixada",
"sled.ogg": "trineu",
"sleep.ogg": "dormir",
"sleeve.ogg": "màniga",
"sleigh.ogg": "trineu",
"slide.ogg": "tobogan",
"slim.ogg": "prima",
"slime.ogg": "bava",
"slippers.ogg": "sabatilla",
"slope.ogg": "pendent",
"sloppy.ogg": "descuidat",
"slot.ogg": "ranura",
"sloth.ogg": "peresós",
"slug.ogg": "llimac",
"small.ogg": "petit",
"smell.ogg": "olorar",
"smile.ogg": "riure",
"smock.ogg": "bata",
"smoke.ogg": "fum",
"smooch.ogg": "bessar",
"snack.ogg": "mos",
"snail.ogg": "cargol",
"snake.ogg": "serp",
"sneaker.ogg": "sabatilla deportiva",
"sniff.ogg": "ensumar",
"snow.ogg": "neu",
"soap.ogg": "sabó",
"sob.ogg": "sanglotar",
"sock.ogg": "mitjó",
"soldier.ogg": "soldat",
"sole.ogg": "llenguado",
"sole_shoe.ogg": "sola de la sabata",
"son.ogg": "fill",
"soup.ogg": "sopa",
"spade.ogg": "pala",
"spaghetti.ogg": "espagueti",
"spark.ogg": "guspira",
"sparrow.ogg": "pardal",
"spatula.ogg": "espàtula",
"speak.ogg": "parlar",
"spear.ogg": "llança",
"spice.ogg": "espècia",
"spider.ogg": "aranya",
"spider_web.ogg": "teranyina",
"spike.ogg": "eriçó",
"spill.ogg": "vessar",
"spinach.ogg": "espinac",
"spine.ogg": "espina",
"spinning_top.ogg": "baldufa",
"splash.ogg": "esquitxar",
"splatter.ogg": "esquitxada",
"sponge.ogg": "esponja",
"spool.ogg": "rodet",
"spoon.ogg": "cullera",
"sport.ogg": "esport",
"spot.ogg": "taca",
"spray.ogg": "ruixar",
"spread.ogg": "untar",
"spring.ogg": "botar",
"spring_season.ogg": "primavera",
"sprinkle.ogg": "espurnes",
"square.ogg": "quadrat",
"squash.ogg": "carbassó",
"squat.ogg": "ajupir",
"squid.ogg": "calamar",
"squirrel.ogg": "esquirol",
"squirt.ogg": "pulveritzador",
"stack.ogg": "pila",
"stage.ogg": "escenari",
"staircase.ogg": "escala",
"stamp.ogg": "segell",
"stand.ogg": "dret",
"star.ogg": "estel",
"stare.ogg": "mirar fixament",
"starfish.ogg": "estrella de mar",
- "steak.ogg": "filet",
"steam.ogg": "vapor",
"steep.ogg": "empinat",
"steeple.ogg": "campanar",
"stem.ogg": "tija",
"step.ogg": "esglaó",
"stew.ogg": "guisat",
"stick.ogg": "branca",
"sting.ogg": "fibló",
"stinky.ogg": "pudor",
"stitch.ogg": "puntada",
"stomach.ogg": "estómac",
"stone.ogg": "pedra",
"stop.ogg": "aturar",
"store.ogg": "botiga",
"stove.ogg": "cuina",
"straight.ogg": "recte",
"strainer.ogg": "colador",
"straw.ogg": "palla",
"strawberry.ogg": "maduixa",
"stream.ogg": "corrent",
"street.ogg": "carrer",
"stretch.ogg": "estirar",
"string.ogg": "cordill",
"stripe.ogg": "ratlla",
"strong.ogg": "fort",
"student.ogg": "estudiant",
"study.ogg": "estudiar",
"stump.ogg": "tronc",
"sugar.ogg": "sucre",
"suit.ogg": "mudada",
"suitcase.ogg": "maleta",
"summer.ogg": "estiu",
"summit.ogg": "cim",
"sun.ogg": "el Sol",
"swan.ogg": "cigne",
"sweat.ogg": "suor",
"sweatshirt.ogg": "dessuadora",
"swim.ogg": "nedar",
"table.ogg": "taula",
"tablecloth.ogg": "estovalles",
"tadpole.ogg": "capgròs",
"tag.ogg": "etiqueta",
"tail.ogg": "cua",
"tall.ogg": "alt",
"tape_measure.ogg": "cinta mètrica",
"taxi.ogg": "taxi",
"teach.ogg": "ensenyar",
"teacher.ogg": "professora",
"tear.ogg": "esquinçar",
"teddy.ogg": "peluix",
"teeth.ogg": "dentadura",
"television.ogg": "televisió",
"temple.ogg": "temple",
"tennis.ogg": "tennis",
"tent.ogg": "tenda",
"text.ogg": "text",
"thick.ogg": "gruixut",
"thief.ogg": "lladre",
"thigh.ogg": "cuixa",
"think.ogg": "pensar",
"thread.ogg": "bobina",
"throat.ogg": "gola",
"throw.ogg": "llançar",
"thumb.ogg": "polze",
"tick.ogg": "paparra",
"ticket.ogg": "bitllet",
"tiger.ogg": "tigre",
"time.ogg": "temps",
"tin.ogg": "llauna",
"tire.ogg": "pneumàtic",
"tired.ogg": "cansat",
"tissue.ogg": "mocador",
+ "to_drink.ogg": "beure",
"toad.ogg": "gripau",
"toaster.ogg": "torradora",
"toe.ogg": "dit del peu",
"toilet.ogg": "vàter",
"tomatoe.ogg": "tomàquet",
"tongs.ogg": "pinces",
"tongue.ogg": "llengua",
"tool.ogg": "eina",
"top.ogg": "cim",
"torch.ogg": "torxa",
"touch.ogg": "tocar",
"towel.ogg": "tovallola",
"toy.ogg": "joguina",
"trail.ogg": "sender",
"train.ogg": "tren",
"train_station.ogg": "estació de tren",
"trap.ogg": "parany",
"trash.ogg": "escombraries",
"tray.ogg": "safata",
"treat.ogg": "dolç",
"tree.ogg": "arbre",
"triangle.ogg": "triangle",
"tribe.ogg": "tribu",
"trip.ogg": "viatge",
"truck.ogg": "camió",
"tube.ogg": "llapis de llavis",
"tulip.ogg": "tulipa",
"tune.ogg": "melodia",
"turkey.ogg": "gall dindi",
"turnip.ogg": "nap",
"turtle.ogg": "tortuga",
"tusk.ogg": "ullal",
"twin_boys.ogg": "bessons",
"twin_girls.ogg": "bessones",
"umbrella.ogg": "paraigua",
"under.ogg": "sota",
"uniform.ogg": "uniforme",
"van.ogg": "furgoneta",
"vapor.ogg": "vapor",
"vase.ogg": "gerro",
"vegetable.ogg": "vegetal",
"vein.ogg": "vena",
"verdure.ogg": "verdura",
"vest.ogg": "armilla",
"vet.ogg": "veterinari",
"viper.ogg": "escurçó",
"vowel.ogg": "vocal",
"vulture.ogg": "voltor",
"wag.ogg": "moure la cua",
"walk.ogg": "caminar",
"wall.ogg": "mur",
"walnut.ogg": "nou",
"wart.ogg": "berruga",
"wash.ogg": "banyar",
"wasp.ogg": "vespa",
"watch.ogg": "rellotge",
"water.ogg": "aigua",
"wave.ogg": "onada",
"wedding.ogg": "casament",
"wedge.ogg": "falca",
"weight.ogg": "pesa",
"wet.ogg": "mullat",
"whale.ogg": "balena",
"wheat.ogg": "blat",
"wheel.ogg": "roda",
"whisk.ogg": "batedora",
"whisper.ogg": "xiuxiuejar",
"white.ogg": "blanc",
"wide.ogg": "ample",
"wife.ogg": "muller",
"wig.ogg": "perruca",
"win.ogg": "guanyar",
"wind.ogg": "vent",
"window.ogg": "finestra",
"window_glass.ogg": "vidre de la finestra",
"wing.ogg": "ala",
"winter.ogg": "hivern",
"wolf.ogg": "llop",
"woman.ogg": "dona",
"wood.ogg": "fusta",
"word.ogg": "paraula",
"worker.ogg": "treballador",
"world.ogg": "món",
"wreath.ogg": "garlanda",
"wrench.ogg": "clau anglesa",
"wrist.ogg": "canell",
"write.ogg": "escriure",
"yellow.ogg": "groc",
"yogurt.ogg": "iogurt",
"yum.ogg": "deliciós",
"zebra.ogg": "zebra",
"zipper.ogg": "cremallera",
"zoo.ogg": "zoològic"
-}
+}
\ No newline at end of file
diff --git a/src/activities/lang/resource/content-cs.json b/src/activities/lang/resource/content-cs.json
new file mode 100644
index 000000000..13e02ed54
--- /dev/null
+++ b/src/activities/lang/resource/content-cs.json
@@ -0,0 +1,4 @@
+{
+ "alphabet.ogg": "abeceda",
+ "angel.ogg": "anděl"
+}
\ No newline at end of file
diff --git a/src/activities/lang/resource/content-de.json b/src/activities/lang/resource/content-de.json
index fb7f4d4a7..395201aec 100644
--- a/src/activities/lang/resource/content-de.json
+++ b/src/activities/lang/resource/content-de.json
@@ -1,1111 +1,1076 @@
{
"10.ogg": "zehn",
"11.ogg": "elf",
"12.ogg": "zwölf",
"16.ogg": "sechzehn",
"U0030.ogg": "null",
"U0031.ogg": "eins",
"U0032.ogg": "zwei",
"U0033.ogg": "drei",
"U0034.ogg": "vier",
"U0035.ogg": "fünf",
"U0036.ogg": "sechs",
"U0037.ogg": "sieben",
"U0038.ogg": "acht",
"U0039.ogg": "neun",
"accountant.ogg": "der Buchhalter",
"ache.ogg": "der Schmerz",
"acorn.ogg": "die Eichel",
"actor.ogg": "der Schauspieler",
"air_horn.ogg": "die Hupe",
"alarmclock.ogg": "der Wecker",
"alligator.ogg": "der Alligator",
"alphabet.ogg": "das Alphabet",
"anchor.ogg": "der Anker",
"angel.ogg": "der Engle",
"angry.ogg": "wütend",
"animal.ogg": "die Tiere",
"ankle.ogg": "der Knöchel",
"ant.ogg": "die Ameise",
"anteater.ogg": "der Ameisenbär",
"antelope.ogg": "die Antilope",
"apple.ogg": "der Apfel",
"apple_tree.ogg": "der Apfelbaum",
"appliance.ogg": "das Gerät",
"apricot.ogg": "die Aprikose",
"arm.ogg": "der Arm",
"armchair.ogg": "der Sessel",
"artichoke.ogg": "die Artischocke",
"artist.ogg": "der Künstler",
"asparagus.ogg": "der Spargel",
"astronaut.ogg": "der Astronaut",
- "ate.ogg": "",
"athlete.ogg": "der Athlet",
"avocado.ogg": "die Avocado",
"ax.ogg": "die Axt",
"baby_bottle.ogg": "die Babyflasche",
"back.ogg": "der Rücken",
"badge.ogg": "das Abzeichen",
"bag.ogg": "der Rucksack",
"bait.ogg": "der Köder",
- "bake.ogg": "kochen",
"balance.ogg": "die Waage",
"bald.ogg": "glatzköpfig",
"ball.ogg": "der Ball",
"ball_of_yarn.ogg": "der Wollknäuel",
"ball_soccer.ogg": "der Fußball",
"ballet.ogg": "das Ballet",
"bank.ogg": "die Bank",
"banker_female.ogg": "die Bankangestellte",
"bark.ogg": "bellen",
"barn.ogg": "die Scheune",
"bat.ogg": "die Fledermaus",
"bath.ogg": "das Bad",
"bathing_suit.ogg": "der Badeanzug",
"bay.ogg": "die Bucht",
"beach.ogg": "der Strand",
- "bead.ogg": "die Blase",
"bean.ogg": "die Bohne",
"bear.ogg": "der Bär",
"beard.ogg": "der Bart",
"beat.ogg": "schlagen",
"beaver.ogg": "der Biber",
"bed.ogg": "das Bett",
"bedroom.ogg": "das Schlafzimmer",
"bee.ogg": "die Biene",
- "beef.ogg": "das Rindfleisch",
"beetle.ogg": "der Käfer",
"beg.ogg": "betteln",
"behind.ogg": "dahinter",
"bell.ogg": "die Glocke",
"belly.ogg": "der Bauch",
"bench.ogg": "die Bank",
"bib.ogg": "der Latz",
"big.ogg": "groß",
"big_top.ogg": "das Zirkuszelt",
"bike.ogg": "das Fahrrad",
"bird.ogg": "der Vogel",
"bit.ogg": "der Bissen",
"bite.ogg": "abbeißen",
"black.ogg": "schwarz",
"blackberry.ogg": "die Brombeere",
"blackbird.ogg": "die Amsel",
"blade.ogg": "die Klinge",
"blind.ogg": "blind",
"blink.ogg": "blinzeln",
"block.ogg": "der Block",
"blond.ogg": "blond",
"blue.ogg": "blau",
"blueberry.ogg": "die Heidelbeere",
"blush.ogg": "erröten",
"board.ogg": "das Brett",
"boat.ogg": "das Boot",
"boil.ogg": "kochen",
"bolt.ogg": "die Mutter",
"bomb.ogg": "die Bombe",
"bone.ogg": "der Knochen",
"book.ogg": "das Buch",
"bookcase.ogg": "das Bücherregal",
"bottom.ogg": "das Gesäß",
"box.ogg": "die Schachtel",
"boxer.ogg": "der Boxer",
"boy.ogg": "der Junge",
"braid.ogg": "der Zopf",
"brain.ogg": "das Gehirn",
"branch.ogg": "der Ast",
"bread.ogg": "das Brot",
"break.ogg": "brechen",
"breast.ogg": "die Brust",
"brick.ogg": "der Ziegelstein",
"bricklayer.ogg": "der Maurer",
"bride.ogg": "die Braut",
"bridge.ogg": "die Brücke",
"bright.ogg": "leuchtend",
"broccoli.ogg": "der Brokkoli",
"brother.ogg": "der Bruder",
"brown.ogg": "braun",
"brush.ogg": "der Pinsel",
"bubble.ogg": "die Blase",
"bucket.ogg": "der Eimer",
"bud.ogg": "die Knospe",
"buffalo.ogg": "der Büffel",
"bug.ogg": "das Insekt",
"bulb.ogg": "die Glühbirne",
"bull.ogg": "der Stier",
"bump.ogg": "die Beule",
"bun.ogg": "das Brötchen",
"bus.ogg": "der Bus",
"bush.ogg": "der Busch",
"butcher.ogg": "der Metzger",
"butter.ogg": "die Butter",
"butterfly.ogg": "der Schmetterling",
"button.ogg": "der Knopf",
"cabbage.ogg": "der Kohl",
"cabin.ogg": "die Hütte",
"cacao.ogg": "der Kakao",
"cactus.ogg": "der Kaktus",
"cage.ogg": "der Käfig",
"cake.ogg": "die Torte",
"call.ogg": "anrufen",
"camel.ogg": "das Kamel",
"camera.ogg": "der Fotoapparat",
"camp.ogg": "zelten",
"can.ogg": "die Dose",
"canary.ogg": "der Kanarienvogel",
"candle.ogg": "die Kerze",
"candy.ogg": "das Bonbon",
"cane.ogg": "der Stock",
"canoe.ogg": "das Kanu",
"canon.ogg": "die Kanone",
"canyon.ogg": "der Canyon",
"cap.ogg": "die Mütze",
"cape.ogg": "der Umhang",
"car.ogg": "das Auto",
"carafe.ogg": "die Karaffe",
"card.ogg": "die Karte",
"carnival.ogg": "der Karneval",
"carpenter.ogg": "der Zimmermann",
"carpet.ogg": "der Teppich",
"carrot.ogg": "die Karotte",
"cart.ogg": "der Einkaufswagen",
"cash.ogg": "das Geld",
"castle.ogg": "das Schloss",
"cat.ogg": "der Kater",
"cat_female.ogg": "die Katze",
"catch.ogg": "fangen",
"caterpillar.ogg": "die Raupe",
"cauldron.ogg": "der Kessel",
"cauliflower.ogg": "der Blumenkohl",
- "cave.ogg": "",
"cavern.ogg": "die Höhle",
"celery.ogg": "der Sellerie",
"centipede.ogg": "der Tausendfüßler",
"cereal.ogg": "das Getreide",
"chain.ogg": "die Kette",
"chair.ogg": "der Stuhl",
"chalk.ogg": "die Kreide",
"chameleon.ogg": "das Chamäleon",
"chandelier.ogg": "der Kronleuchter",
"chat.ogg": "plaudern",
"cheek.ogg": "die Wange",
"cheer.ogg": "jubeln",
"cheese.ogg": "der Käse",
"chef.ogg": "die Köchin",
"cherry.ogg": "die Kirsche",
"chest.ogg": "die Truhe",
"chick.ogg": "das Küken",
"chicken.ogg": "das Huhn",
- "chief.ogg": "der Indianer",
"child.ogg": "das Kind",
"chimney.ogg": "der Schornstein",
"chimp.ogg": "der Schimpanse",
"chin.ogg": "das Kinn",
"chocolate.ogg": "die Schokolade",
"chop.ogg": "zerschneiden",
- "chore.ogg": "",
"chores.ogg": "die Hausarbeit",
"christmas.ogg": "das Weihnachten",
"cigar.ogg": "die Zigarre",
"circus.ogg": "der Zirkus",
"city.ogg": "die Stadt",
"clam.ogg": "die Muschel",
"clap.ogg": "klatschen",
"class.ogg": "die Klasse",
"claw.ogg": "die Tatze",
"clay.ogg": "der Ton",
"clean.ogg": "sich waschen",
"cleaning_lady.ogg": "die Putzfrau",
"cliff.ogg": "das Kliff",
"climb.ogg": "klettern",
"clock.ogg": "der Wecker",
"cloth.ogg": "der Stoff",
"clothes_hanger.ogg": "der Kleiderbügel",
"cloud.ogg": "die Wolke",
"cloudy.ogg": "wolkig",
"clover.ogg": "der Klee",
"clown.ogg": "der Clown",
"coach.ogg": "die Trainerin",
"coast.ogg": "die Küste",
"coat.ogg": "der Mantel",
"cobra.ogg": "die Kobra",
"coconut.ogg": "die Kokosnuss",
"cod.ogg": "der Dorsch",
"coffee.ogg": "der Kaffee",
"coin.ogg": "das Geldstück",
"cold.ogg": "die Kälte",
- "color.ogg": "dir Farbe",
+ "color.ogg": "die Farbe",
"colt.ogg": "das Fohlen",
"comb.ogg": "der Kamm",
"cone.ogg": "der Kegel",
+ "cook.ogg": "kochen",
"cookie.ogg": "der Keks",
"cork.ogg": "der Korken",
"corn.ogg": "der Mais",
"couch.ogg": "das Sofa",
"cough.ogg": "husten",
"couple.ogg": "das Paar",
"cow.ogg": "die Kuh",
"cowboy.ogg": "der Cowboy",
"crab.ogg": "der Krebs",
"cradle.ogg": "die Wiege",
"craft.ogg": "das Handwerk",
"crawl.ogg": "krabbeln",
"crazy.ogg": "verrückt",
"creek.ogg": "der Bach",
"crepe.ogg": "der Pfannkuchen",
"crib.ogg": "das Kinderbett",
- "criminal.ogg": "der Verbrecher",
"croak.ogg": "quaken",
"crocodile.ogg": "das Krokodil",
"cross.ogg": "das Kreuz",
"crow.ogg": "die Krähe",
"crown.ogg": "die Krone",
"crumb.ogg": "der Krümel",
"crust.ogg": "die Kruste",
"cry.ogg": "weinen",
"crystal.ogg": "der Kristall",
"cube.ogg": "der Würfel",
"cucumber.ogg": "die Gurke",
"curtain.ogg": "der Vorhang",
"cut.ogg": "schneiden",
"cute.ogg": "reizend",
"dad.ogg": "der Vater",
"daffodil.ogg": "die Osterglocke",
"daisy.ogg": "die Margerite",
"dam.ogg": "der Staudamm ",
"dance.ogg": "tanzen",
"dandelion.ogg": "der Löwenzahn",
- "danger.ogg": "die Gefahr",
- "dark.ogg": "",
"dart_board.ogg": "die Zielscheibe",
"date_fruit.ogg": "die Dattel",
"deer.ogg": "der Hirsch",
"den.ogg": "der Bau",
"desert.ogg": "die Wüste",
"desk.ogg": "der Schreibtisch",
"dessert.ogg": "der Nachtisch",
"diamond.ogg": "der Diamant",
"dig.ogg": "graben",
"dirt.ogg": "der Schmutz",
"dirty.ogg": "schmutzig",
"dish.ogg": "das Gericht",
"dishcloth.ogg": "der Spüllappen",
"dive.ogg": "tauchen",
"doctor.ogg": "die Ärztin",
"doe.ogg": "die Hirschkuh",
"dog.ogg": "der Hund",
"doll.ogg": "die Puppe",
"dolphin.ogg": "der Delphin",
"domino.ogg": "der Domino",
"door.ogg": "die Tür",
"doormat.ogg": "die Fußmatte",
"dot.ogg": "der Punkt",
"doughnut.ogg": "der Donut",
"dove.ogg": "die Taube",
"dragon.ogg": "der Drache",
"dragonfly.ogg": "die Libelle",
- "drank.ogg": "trinken",
"draw.ogg": "die Zeichnung",
"drawer.ogg": "die Schublade",
"dream.ogg": "träumen",
"dress.ogg": "das Kleid",
"drink.ogg": "das Getränk",
- "drinking.ogg": "trinken",
"drip.ogg": "der Tropfen",
"drive.ogg": "fahren",
"drool.ogg": "sabbern",
"drum.ogg": "die Trommel",
"dry.ogg": "trocknen",
"duck.ogg": "der Erpel",
"duck_mother.ogg": "die Ente",
"dune.ogg": "die Düne",
"dwarf.ogg": "der Zwerg",
"eagle.ogg": "der Adler",
"ear.ogg": "das Ohr",
"earth.ogg": "die Erde",
"eat.ogg": "essen",
"egg.ogg": "das Ei",
"eggplant.ogg": "die Aubergine",
"elbow.ogg": "der Ellbogen",
"electrician.ogg": "der Elektriker",
"elk.ogg": "der Elch",
"empty.ogg": "leer",
"engine.ogg": "der Motor",
"engineer.ogg": "der Ingenieur",
"eraser.ogg": "der Radiergummi",
"explore.ogg": "die Erforscher",
"eyelash.ogg": "die Wimper",
"eyes.ogg": "die Augen",
"face.ogg": "das Gesicht",
"fair.ogg": "die Kirmes",
"fairy.ogg": "die Fee",
- "fall_down.ogg": "fallen",
"fall_season.ogg": "der Herbst",
"family.ogg": "die Familie",
"fan.ogg": "der Ventilator",
"farm.ogg": "der Bauernhof",
"farmer.ogg": "der Bauer",
"fat.ogg": "dick",
"faucet.ogg": "der Wasserhahn",
"fawn.ogg": "das Rehkitz",
"feast.ogg": "das Hähnchen",
"feather.ogg": "die Feder",
"feed.ogg": "füttern",
- "feet.ogg": "Füße",
- "fell.ogg": "fallen",
"femur.ogg": "der Oberschenkelknochen",
"fetch.ogg": "bringen",
"fig.ogg": "die Feige",
"fin.ogg": "die Flosse",
"find.ogg": "finden",
"finger.ogg": "der Finger",
"fire.ogg": "das Feuer",
"fire_extinguisher.ogg": "der Feuerlöscher",
"fireman.ogg": "der Feuerwehrmann",
"fish.ogg": "der Fisch",
"fisherman.ogg": "der Fischer",
"fist.ogg": "die Faust",
"flacon.ogg": "der Flakon",
"flag.ogg": "die Flagge",
"flame.ogg": "die Flamme",
"flamingo.ogg": "der Flamingo",
"flash.ogg": "die Taschenlampe",
"flat.ogg": "die Wohnungen",
"flies.ogg": "die Fliege",
- "flight.ogg": "der Flug",
"float.ogg": "treiben",
"flour.ogg": "das Mehl",
"flower.ogg": "die Blume",
"fluff.ogg": "die Fluse",
"flute.ogg": "die Flöte",
"fly.ogg": "fliegen",
"foam.ogg": "der Schaum",
- "food.ogg": "der Hamburger",
"foot.ogg": "der Fuß",
"forest.ogg": "der Wald",
"fork.ogg": "die Gabel",
"fountain.ogg": "der Brunnen",
"fox.ogg": "der Fuchs",
"freeze.ogg": "friehren",
"friend.ogg": "der Freund",
"fries.ogg": "die Pommes Frites",
"frog.ogg": "der Frosch",
"front.ogg": "davor",
- "frown.ogg": "murren",
"fruit.ogg": "die Früchte",
"fudge.ogg": "das Sahnebonbon",
"full.ogg": "voll",
- "fun.ogg": "der Spaß",
"fur.ogg": "der Pelz",
"game.ogg": "die Freude",
"garage.ogg": "die Garage",
"garden.ogg": "der Garten",
"garlic.ogg": "der Knoblauch",
"gem.ogg": "der Edelstein",
"giant.ogg": "riesig",
"gift.ogg": "das Geschenk",
"giraffe.ogg": "die Giraffe",
"girl.ogg": "das Mädchen",
"glass.ogg": "das Glas",
"glasses.ogg": "die Brille",
"glove.ogg": "die Handschuhe",
"glue.ogg": "der Kleber",
"gnome.ogg": "der Gnom",
"goat.ogg": "die Ziege",
"golden.ogg": "golden",
"golf.ogg": "das Golf",
"goose.ogg": "die Gans",
"gorilla.ogg": "der Gorilla",
"grain.ogg": "das Getreide",
"grandmother.ogg": "die Großmutter",
"grape.ogg": "die Traube",
"grapefruit.ogg": "die Pampelmuse",
"grass.ogg": "das Gras",
"grave.ogg": "das Grab",
"gray.ogg": "grau",
"green.ogg": "grün",
"grill.ogg": "der Grill",
"grin.ogg": "lächeln",
"ground.ogg": "die Erde",
"growl.ogg": "knurren",
"guignol.ogg": "der Kasper",
"guinea_pig.ogg": "das Meerschweinchen",
"gum.ogg": "der Kaugummi",
"hair.ogg": "die Haare",
"hair_dryer.ogg": "der Föhn",
"half.ogg": "halb",
"ham.ogg": "der Schinken",
+ "hamburger.ogg": "der Hamburger",
"hammer.ogg": "der Hammer",
"hand.ogg": "die Hand",
"handlebar.ogg": "der Lenker",
"happy.ogg": "glücklich",
"harp.ogg": "die Harfe",
"hat.ogg": "der Hut",
"hatch.ogg": "ausschlüpfen",
"hay.ogg": "das Heu",
"head.ogg": "der Kopf",
"hear.ogg": "hören",
"heat.ogg": "die Hitze ",
"hedge.ogg": "die Hecke",
"hedgehog.ogg": "der Igel",
"heel.ogg": "der Absatz",
"helmet.ogg": "der Helm",
"hen.ogg": "die Henne",
"herd.ogg": "die Herde",
"high.ogg": "hoch",
"hike.ogg": "wandern",
"hill.ogg": "der Hügel",
"hip.ogg": "die Hüfte",
"hippopotamus.ogg": "das Nilpferd",
"hit.ogg": "schlagen",
"hive.ogg": "der Bienenstock",
"hockey.ogg": "das Eishockey",
"hole.ogg": "das Loch",
"home.ogg": "das Zuhause",
"hook.ogg": "der Angelhaken",
- "hop.ogg": "",
"horse.ogg": "das Pferd",
"hose.ogg": "der Schlauch",
"hospital.ogg": "das Krankenhaus",
"hot.ogg": "heiß",
"hot_dog.ogg": "der Hotdog",
"hound.ogg": "der Jagdhund",
"house.ogg": "das Haus",
"howl.ogg": "heulen",
- "hug.ogg": "",
"huge.ogg": "riesig",
"hummingbird.ogg": "der Kolibri",
- "hunchback.ogg": "der Buckel",
"hunter.ogg": "der Jäger",
"husband.ogg": "der Ehemann",
"hut.ogg": "die Hütte",
"hyena.ogg": "die Hyäne",
"ice.ogg": "der Eiswürfel",
"iceberg.ogg": "der Eisberg",
"iguana.ogg": "der Leguan",
"ill.ogg": "krank",
"ink.ogg": "die Tinte",
"island.ogg": "die Insel",
"jacket.ogg": "das Jackett",
"jaguar.ogg": "der Jaguar",
"jam.ogg": "die Marmelade",
"jay.ogg": "der Eichelhäher",
"jelly.ogg": "das Gelee",
"jellyfish.ogg": "die Qualle",
"jewel.ogg": "das Juwel",
"job.ogg": "die Arbeit",
"jockey.ogg": "der Jockey",
"jog.ogg": "das Jogging",
+ "joy.ogg": "joy",
"judge.ogg": "der Richter",
"judo.ogg": "das Judo",
"juggler.ogg": "Jongleur",
"juice.ogg": "der Saft",
"jump.ogg": "springen",
"kangaroo.ogg": "das Känguru",
"keel.ogg": "der Kegel",
"kernel.ogg": "der Kern",
"keyboard.ogg": "die Tastatur",
"kimono.ogg": "der Kimono",
"king.ogg": "der König",
"kiss.ogg": "küssen",
"kitchen.ogg": "die Küche",
"kite.ogg": "der Drachen",
"kitten.ogg": "das Kätzchen",
"kiwi.ogg": "die Kiwi",
"knee.ogg": "das Knie",
"kneel.ogg": "sich hinknien",
"knife.ogg": "das Messer",
"knight.ogg": "der Ritter",
"knit.ogg": "stricken",
"knot.ogg": "der Knoten",
"koala.ogg": "der Koala",
- "lad.ogg": "",
"lady.ogg": "die Dame",
"ladybug.ogg": "der Marienkäfer",
"lake.ogg": "der See",
"lama.ogg": "das Lama",
"lamb.ogg": "das Lamm",
"lamp.ogg": "die Lampe",
"land.ogg": "das Gelände",
"lane.ogg": "die Fahrbahn",
"lap.ogg": "der Schoß",
"lasso.ogg": "das Lasso",
"laugh.ogg": "lachen",
"lava.ogg": "die Lava",
"lawn.ogg": "der Rasen",
"lawyer.ogg": "der Rechtsanwalt",
"leaf.ogg": "das Blatt",
"ledge.ogg": "der Felsvorsprung",
"leek.ogg": "der Lauch",
"left.ogg": "links",
"leg.ogg": "das Bein",
- "leg_animal.ogg": "das Käferbein",
"lemon.ogg": "die Zitrone",
"lemonade.ogg": "die Limonade",
"lemur.ogg": "der Lemur",
"leopard.ogg": "der Leopard",
"lettuce.ogg": "der Blattsalat",
"librarian.ogg": "die Bibliothekarin",
"lick.ogg": "ablecken",
"lid.ogg": "der Deckel",
"lift.ogg": "hochheben",
"light.ogg": "das Licht",
"lighthouse.ogg": "der Leuchtturm",
"lightning.ogg": "der Blitz",
"lilac.ogg": "der Flieder",
"lime.ogg": "die Limone",
"line.ogg": "der Strich",
"link.ogg": "das Kettenglied",
"lion.ogg": "der Löwe",
"lion_cub.ogg": "das Löwenjunge",
"lip.ogg": "die Lippe",
"liquid.ogg": "flüssig",
"lizard.ogg": "die Eidechse",
"lobster.ogg": "der Hummer",
"log.ogg": "das Holzscheit",
"look.ogg": "das Aussehen",
"lunch.ogg": "der Imbiss",
"mad.ogg": "der Zorn",
"magic.ogg": "magisch",
"magnet.ogg": "der Magnet",
"magnifying_glass.ogg": "die Lupe",
"magpie.ogg": "die Elster",
"mail.ogg": "der Briefumschlag",
"man.ogg": "der Mann",
"mane.ogg": "die Mähne",
"mango.ogg": "die Mango",
"map.ogg": "die Landkarte",
"maple.ogg": "der Ahorn",
"marble.ogg": "die Murmel",
"mashed_potatoes.ogg": "der Kartoffelbrei",
"mask.ogg": "die Taucherbrille",
"mast.ogg": "der Mast",
"mat.ogg": "die Matte",
"match.ogg": "die Streichhölzer",
- "mate.ogg": "",
- "mate_female.ogg": "die Freundin",
- "mate_male.ogg": "der Freund",
"mattress.ogg": "die Matratze",
"mauve.ogg": "lila",
"meal.ogg": "die Mahlzeit",
"meat.ogg": "das Fleisch",
"mechanic.ogg": "der Mechaniker",
"medal.ogg": "die Medaille",
"meet.ogg": "treffen",
"melon.ogg": "die Melone",
- "men.ogg": "die Menschenmenge",
"merry-go-round.ogg": "das Karussell",
"mice.ogg": "die Mäuse",
"microphone.ogg": "das Mikrophon",
"milk.ogg": "die Milch",
"mill.ogg": "die Windmühle",
"mimosa.ogg": "die Mimose",
"mirror.ogg": "der Spiegel",
"mixer.ogg": "der Mixer",
"mole.ogg": "der Maulwurf",
"mom.ogg": "die Mama",
"moon.ogg": "der Mond",
"moose.ogg": "der Elch",
"mop.ogg": "der Mopp",
"mosque.ogg": "die Moschee",
"mosquito.ogg": "die Mücke",
"mother.ogg": "die Mutter",
"motorcycle.ogg": "das Motorrad",
"mountain.ogg": "der Berg",
"mouse.ogg": "die Maus",
"mouth.ogg": "der Mund",
"movie.ogg": "der Film",
"mower.ogg": "der Rasenmäher",
"mud.ogg": "der Schlamm",
"mug.ogg": "die Tasse",
"mule.ogg": "der Esel",
"muscle.ogg": "der Muskel",
"mushroom.ogg": "der Fliegenpilz",
"music.ogg": "die Musik",
"musician.ogg": "der Musiker",
"naked.ogg": "nackt",
"nap.ogg": "schlummern",
"navel.ogg": "der Bauchnabel",
"neck.ogg": "der Nacken",
"necklace.ogg": "die Halskette",
"needle.ogg": "die Nadel",
"nest.ogg": "das Nest",
"net.ogg": "der Kescher",
"newspaper.ogg": "die Zeitung",
"night.ogg": "die Nacht",
"nightgown.ogg": "das Nachthemd",
"nose.ogg": "die Nase",
"nostril.ogg": "das Nasenloch",
"notebook.ogg": "das Notizbuch",
"number.ogg": "die Zahl",
"nun.ogg": "die Nonne",
"nurse.ogg": "die Krankenschwester",
"nurse_male.ogg": "der Krankenpfleger",
"nut.ogg": "die Erdnuss",
"oar.ogg": "das Ruder",
"ocean.ogg": "der Ozean",
"office.ogg": "das Büro",
"olive.ogg": "die Olive",
"on.ogg": "darauf",
"onion.ogg": "die Zwiebel",
"open.ogg": "offen",
"opossum.ogg": "das Opossum",
"orange-color.ogg": "orange",
"orange.ogg": "die Orange",
"orchid.ogg": "die Orchidee",
"ostrich.ogg": "der Strauß",
"otter.ogg": "der Otter",
"owl.ogg": "die Eule",
"ox.ogg": "der Ochse",
"oyster.ogg": "die Auster",
"pacifier.ogg": "der Schnuller",
"page.ogg": "die Seite",
"pair.ogg": "das Paar",
"pajamas.ogg": "der Pyjama",
- "pal.ogg": "",
"palm_tree.ogg": "die Palme",
"pan.ogg": "die Pfanne",
"panda.ogg": "der Panda",
"panther.ogg": "der Panther",
"panties.ogg": "die Unterhose",
"pants.ogg": "die Hose",
"papaya.ogg": "die Papaya",
"paper.ogg": "das Papier",
"parachute.ogg": "der Fallschirm",
"parakeet.ogg": "der Sittich",
"parrot.ogg": "der Papagei",
"patch.ogg": "der Flicken",
"path.ogg": "der Weg",
"paw.ogg": "die Pfote",
"pea.ogg": "die Erbse",
"peach.ogg": "der Pfirsich",
"peacock.ogg": "der Pfau",
"peak.ogg": "der Gipfel",
"pear.ogg": "die Birne",
"pearl.ogg": "die Perle",
"peck.ogg": "picken",
"pedal.ogg": "das Pedal",
"pelican.ogg": "der Pelikan",
"pen.ogg": "der Füller",
"pencil.ogg": "der Bleistift",
"peony.ogg": "die Päonie",
"people.ogg": "die Leute",
"pepper.ogg": "der Pfeffer",
"peppers.ogg": "die Peperoni",
- "pet.ogg": "",
"petal.ogg": "das Blütenblatt",
- "petite.ogg": "klein",
"phone.ogg": "das Telefon",
"piano.ogg": "das Klavier",
"picture.ogg": "das Bild",
"pie.ogg": "der Kuchen",
"pig.ogg": "das Schwein",
"pigeon.ogg": "die Taube",
"pill.ogg": "die Tablette",
"pillow.ogg": "das Kissen",
"pilot.ogg": "der Pilot",
"pine.ogg": "die Pinie",
"pine_cone.ogg": "der Tannenzapfen",
"pink.ogg": "rosa",
"pip.ogg": "der Kern",
"pipe.ogg": "die Pfeife",
"piranha.ogg": "der Piranha",
"pirate.ogg": "der Pirat",
"pizza.ogg": "die Pizza",
"plane.ogg": "das Flugzeug",
"planet.ogg": "der Planet",
"plant.ogg": "die Pflanze",
"plate.ogg": "der Teller",
"play.ogg": "spielen",
"pliers.ogg": "die Zange",
"plow.ogg": "pflügen",
"plum.ogg": "die Pflaume",
"plumber.ogg": "der Klempner",
"pocket.ogg": "die Hosentasche",
"pod.ogg": "die Schote",
"pole.ogg": "der Pfosten",
"police.ogg": "der Polizist",
"pompon.ogg": "der Pompon",
"pond.ogg": "der Teich",
"pony.ogg": "das Ponny",
"pool.ogg": "das Schwimmbad",
- "pop.ogg": "das Popcorn",
+ "popcorn.ogg": "das Popcorn",
"pope.ogg": "der Papst",
"porthole.ogg": "das Bullauge",
"post.ogg": "der Briefkasten",
"pot.ogg": "der Topf",
"potato.ogg": "die Kartoffel",
"pounce.ogg": "anspringen",
"president.ogg": "der Präsident",
"pretty.ogg": "schön",
"price.ogg": "der Preis",
"priest.ogg": "der Pfarrer",
"prince.ogg": "der Prinz",
"princess.ogg": "die Prinzession",
"prison.ogg": "das Gefängnis",
"prisoner.ogg": "der Häftling",
"prize.ogg": "der Pokal",
"pug.ogg": "der Mops",
"pull.ogg": "ziehen",
"pullover.ogg": "der Pullover",
"pumpkin.ogg": "der Kürbis",
"puppy.ogg": "der Welpe",
"pyramid.ogg": "die Pyramide",
"quarrel.ogg": "sich streiten",
"queen.ogg": "die Königin",
"question.ogg": "die Frage",
"quilt.ogg": "die Steppdecke",
"quiz.ogg": "das Quiz",
"rabbit.ogg": "das Kaninchen",
"rabbit_baby.ogg": "das Kaninchenjunge",
"race.ogg": "das Wettrennen",
"radio.ogg": "das Radio",
"radish.ogg": "der Rettich",
"raft.ogg": "das Floß",
"rag.ogg": "der Lappen",
"rage.ogg": "die Wut",
"rain.ogg": "der Regen",
"raincoat.ogg": "der Regenmantel",
"rake.ogg": "die Harke",
"ramp.ogg": "die Rampe",
- "ran.ogg": "",
"raspberry.ogg": "die Himbeere",
"rat.ogg": "die Ratte",
"razor.ogg": "der Rasierer",
"read.ogg": "lesen",
"red.ogg": "rot",
"reptile.ogg": "das Reptil",
"rhinoceros.ogg": "das Nashorn",
"rice.ogg": "der Reis",
"ride.ogg": "Fahrrad fahren",
"rifle.ogg": "das Gewehr",
"right.ogg": "rechts",
"rip.ogg": "das Grab",
"rise.ogg": "ansteigen",
"river.ogg": "der Fluss",
"road.ogg": "die Straße",
"roast.ogg": "der Braten",
"robe.ogg": "die Robe",
"robot.ogg": "der Roboter",
"rock.ogg": "der Stein",
"rocket.ogg": "die Rakete",
"rolling_pin.ogg": "das Nudelholz",
"roof.ogg": "das Dach",
"room.ogg": "das Zimmer",
"root.ogg": "die Wurzel",
"rope.ogg": "das Seil",
"rose.ogg": "die Rose",
"round.ogg": "rund",
"rowing.ogg": "das Rudern",
"royal.ogg": "königlich",
"rug.ogg": "der Vorleger",
"run.ogg": "rennen",
"sad.ogg": "traurig",
"saddle.ogg": "der Sattel",
"sail.ogg": "das Segelboot",
"sailor.ogg": "der Matrose",
"salamander.ogg": "der Salamander",
"salmon.ogg": "der Lachs",
"sand.ogg": "der Sand",
"sandals.ogg": "die Sandalen",
"sandwich.ogg": "das Sandwich",
"sash.ogg": "die Schärpe",
- "sat.ogg": "sich hinsetzen",
"sauce.ogg": "die Sauce",
"sausage.ogg": "die Wurst",
"scale.ogg": "die Waage",
"scar.ogg": "die Narbe",
- "scared.ogg": "erschrecken",
"scarf.ogg": "der Schal",
"school.ogg": "die Schule",
"school_bag.ogg": "die Schultasche",
"science.ogg": "die Wissenschaft",
"scissors.ogg": "die Schere",
"scorpion.ogg": "der Skorpion",
"scratch.ogg": "kratzen",
"scream.ogg": "schreien",
"screw.ogg": "die Schraube",
"screwdriver.ogg": "der Schraubenzieher",
"scribble.ogg": "kritzeln",
"sea.ogg": "das Meer",
"seat.ogg": "der Stuhl",
"see.ogg": "sehen",
"seed.ogg": "der Samen",
"shadow.ogg": "der Schatten",
"shake.ogg": "schütteln",
"shark.ogg": "der Hai",
"shave.ogg": "scheren",
"shed.ogg": "der Schuppen",
"sheep.ogg": "das Schaf",
"shelf.ogg": "das Regal",
"shell.ogg": "die Muschel",
"ship.ogg": "das Schiff",
"shirt.ogg": "das Hemd",
"shoe.ogg": "der Schuh",
"shoelace.ogg": "der Schnürsenkel",
"shop.ogg": "der Laden",
"shore.ogg": "das Ufer",
"short.ogg": "die Shorts",
"shovel.ogg": "die Schippe",
"shower.ogg": "die Dusche",
"shrimp.ogg": "die Garnele",
"shrub.ogg": "der Strauch",
"shut.ogg": "geschlossen",
"shutter.ogg": "der Fensterladen",
"sick.ogg": "krank",
"sidewalk.ogg": "der Gehweg",
"sign.ogg": "das Schild",
"sing.ogg": "singen",
"sink.ogg": "die Spüle",
"sip.ogg": "nippen",
"sister.ogg": "die Schwester",
"sit.ogg": "sich hinsetzen",
"skate.ogg": "das Skateboardfahren",
"skeleton.ogg": "das Skelett",
"ski.ogg": "das Skifahren",
"skimmer.ogg": "der Schaumlöffel",
"skin.ogg": "die Haut",
"skirt.ogg": "der Rock",
"skunk.ogg": "das Stinktier",
"sky.ogg": "der Himmel",
- "slam.ogg": "",
"sled.ogg": "der Schlitten",
"sleep.ogg": "schlafen",
"sleeve.ogg": "der Ärmel",
"sleigh.ogg": "der Pferdeschlitten",
"slide.ogg": "die Rutsche",
"slim.ogg": "schlank",
"slime.ogg": "der Schleim",
"slippers.ogg": "der Hausschuh",
"slope.ogg": "der Abhang",
"sloppy.ogg": "durchnässt",
"slot.ogg": "der Schlitz",
"sloth.ogg": "das Faultier",
"slug.ogg": "die Nacktschnecke",
"small.ogg": "klein",
"smell.ogg": "riechen",
"smile.ogg": "lächeln",
"smock.ogg": "der Kittel",
"smoke.ogg": "der Rauch",
"smooch.ogg": "küssen",
"snack.ogg": "der Imbiss",
"snail.ogg": "die Schnecke",
"snake.ogg": "die Schlange",
"sneaker.ogg": "der Turnschuh",
"sniff.ogg": "schnüffeln",
"snow.ogg": "der Schnee",
"soap.ogg": "die Seife",
"sob.ogg": "schluchzen",
"sock.ogg": "die Socke",
"soldier.ogg": "die Soldatin",
"sole.ogg": "die Seezunge",
"sole_shoe.ogg": "die Schuhsohle",
"son.ogg": "der Sohn",
"soup.ogg": "die Suppe",
"spade.ogg": "der Spaten",
"spaghetti.ogg": "die Spaghetti",
"spark.ogg": "der Funke",
"sparrow.ogg": "der Spatz",
"spatula.ogg": "der Pfannenwender",
"speak.ogg": "sprechen",
"spear.ogg": "der Speer",
"spice.ogg": "das Gewürz",
"spider.ogg": "die Spinne",
"spider_web.ogg": "das Spinnennetz",
"spike.ogg": "der Stachel",
"spill.ogg": "ausschütten",
"spinach.ogg": "der Spinat",
"spine.ogg": "die Wirbelsäule",
"spinning_top.ogg": "der Kreisel",
"splash.ogg": "spritzen",
"splatter.ogg": "der Spritzer",
"sponge.ogg": "der Schwamm",
"spool.ogg": "die Spule",
"spoon.ogg": "der Löffel",
"sport.ogg": "der Sport",
"spot.ogg": "fleckig",
"spray.ogg": "sprühen",
"spread.ogg": "verteilen",
"spring.ogg": "federn",
"spring_season.ogg": "der Frühling",
"sprinkle.ogg": "der Streusel",
"square.ogg": "das Quadrat",
"squash.ogg": "der Kürbis",
"squat.ogg": "die Hocke",
"squid.ogg": "der Tintenfisch",
"squirrel.ogg": "das Eichhörnchen",
- "squirt.ogg": "",
"stack.ogg": "der Stapel",
"stage.ogg": "die Bühne",
"staircase.ogg": "die Treppe",
"stamp.ogg": "die Briefmarke",
"stand.ogg": "stehend",
"star.ogg": "der Stern",
"stare.ogg": "der Blick",
"starfish.ogg": "der Seestern",
- "steak.ogg": "das Steak",
"steam.ogg": "der Dampf",
"steep.ogg": "steil",
"steeple.ogg": "der Kirchturm",
"stem.ogg": "der Stiel",
"step.ogg": "die Stufe",
"stew.ogg": "der Eintopf",
"stick.ogg": "der Ast",
"sting.ogg": "stechen",
"stinky.ogg": "stinkend",
"stitch.ogg": "nähen",
"stomach.ogg": "der Magen",
"stone.ogg": "der Stein",
"stop.ogg": "anhalten",
"store.ogg": "das Geschäft",
"stove.ogg": "der Herd",
"straight.ogg": "gerade",
"strainer.ogg": "das Sieb",
"straw.ogg": "der Strohhalm",
"strawberry.ogg": "die Erdbeere",
"stream.ogg": "der Strom",
"street.ogg": "die Straße",
"stretch.ogg": "sich strecken",
"string.ogg": "die Schnur",
"stripe.ogg": "gestreift",
"strong.ogg": "stark",
"student.ogg": "der Student",
"study.ogg": "lernen",
"stump.ogg": "der Baumstumpf",
"sugar.ogg": "der Zucker",
"suit.ogg": "der Anzug",
"suitcase.ogg": "der Koffer",
"summer.ogg": "der Sommer",
"summit.ogg": "der Gipfel",
"sun.ogg": "die Sonne",
"swan.ogg": "der Schwan",
"sweat.ogg": "schwitzen",
"sweatshirt.ogg": "das Sweatshirt",
"swim.ogg": "schwimmen",
"table.ogg": "der Tisch",
"tablecloth.ogg": "die Tischdecke",
"tadpole.ogg": "die Kaulquappe",
"tag.ogg": "das Etikett",
"tail.ogg": "der Schwanz",
"tall.ogg": "groß",
"tape_measure.ogg": "das Metermaß",
"taxi.ogg": "das Taxi",
"teach.ogg": "unterrichten",
"teacher.ogg": "die Lehrerin",
"tear.ogg": "zerreißen",
"teddy.ogg": "der Teddybär",
"teeth.ogg": "die Zähne",
"television.ogg": "das Fernsehen",
"temple.ogg": "der Tempel",
"tennis.ogg": "das Tennis",
"tent.ogg": "das Zelt",
"text.ogg": "der Text",
"thick.ogg": "dick",
"thief.ogg": "der Dieb",
"thigh.ogg": "der Oberschenkel",
"think.ogg": "denken",
"thread.ogg": "die Spule",
"throat.ogg": "der Rachen",
"throw.ogg": "werfen",
"thumb.ogg": "der Daumen",
- "tick.ogg": "",
"ticket.ogg": "die Eintrittskarte",
"tiger.ogg": "der Tiger",
"time.ogg": "die Zeit",
"tin.ogg": "die Dose",
"tire.ogg": "der Reifen",
"tired.ogg": "müde",
"tissue.ogg": "das Papiertaschentuch",
+ "to_drink.ogg": "trinken",
"toad.ogg": "die Kröte",
"toaster.ogg": "der Toaster",
"toe.ogg": "der Zeh",
"toilet.ogg": "die Toilette",
"tomatoe.ogg": "die Tomate",
"tongs.ogg": "die Zange",
"tongue.ogg": "die Zunge",
"tool.ogg": "das Werkzeug",
"top.ogg": "darauf",
"torch.ogg": "die Fackel",
"touch.ogg": "berühren",
"towel.ogg": "das Handtuch",
"toy.ogg": "das Spielzeug",
"trail.ogg": "der Pfad",
"train.ogg": "der Zug",
"train_station.ogg": "der Bahnhof",
"trap.ogg": "die Falle",
"trash.ogg": "der Schmutz",
"tray.ogg": "das Tablett",
"treat.ogg": "die Süßigkeit",
"tree.ogg": "der Baum",
"triangle.ogg": "dreieckig",
"tribe.ogg": "der Stamm",
"trip.ogg": "die Reise",
"truck.ogg": "der Lastwagen",
"tube.ogg": "der Lippenstift",
"tulip.ogg": "die Tulpe",
"tune.ogg": "die Melodie",
"turkey.ogg": "der Truthahn",
"turnip.ogg": "die Rübe",
"turtle.ogg": "die Schildkröte",
"tusk.ogg": "der Stoßzahn",
"twin_boys.ogg": "der Zwillingsbruder",
"twin_girls.ogg": "die Zwillingsschwester",
"umbrella.ogg": "der Regenschirm",
"under.ogg": "darunter",
"uniform.ogg": "die Uniform",
"van.ogg": "der Kleinbus",
- "vapor.ogg": "",
"vase.ogg": "die Vase",
"vegetable.ogg": "das Gemüse",
"vein.ogg": "die Ader",
"verdure.ogg": "das Grün",
"vest.ogg": "die Veste",
"vet.ogg": "der Tierarzt",
"viper.ogg": "die Viper",
"vowel.ogg": "der Vokal",
"vulture.ogg": "der Geier",
"wag.ogg": "schwänzeln",
"walk.ogg": "gehen",
"wall.ogg": "die Mauer",
"walnut.ogg": "die Walnuss",
"wart.ogg": "die Warze",
"wash.ogg": "baden",
"wasp.ogg": "die Wespe",
"watch.ogg": "die Armbanduhr",
"water.ogg": "das Wasser",
"wave.ogg": "die Welle",
"wedding.ogg": "die Hochzeit",
"wedge.ogg": "der Keil",
"weight.ogg": "das Gewicht",
"wet.ogg": "nass",
"whale.ogg": "der Wal",
"wheat.ogg": "der Weizen",
"wheel.ogg": "das Rad",
"whisk.ogg": "der Schneebesen",
"whisper.ogg": "flüstern",
"white.ogg": "weiß",
"wide.ogg": "breit",
"wife.ogg": "die Ehefrau",
"wig.ogg": "die Perücke",
"win.ogg": "gewinnen",
"wind.ogg": "der Wind",
"window.ogg": "das Fenster",
"window_glass.ogg": "die Fensterscheibe",
"wing.ogg": "der Flügel",
"winter.ogg": "der Winter",
"wolf.ogg": "der Wolf",
"woman.ogg": "die Frau",
"wood.ogg": "das Holz",
"word.ogg": "das Wort",
"worker.ogg": "der Arbeiter",
"world.ogg": "die Welt",
"wreath.ogg": "der Kranz",
"wrench.ogg": "der Schraubenschlüssel",
"wrist.ogg": "das Handgelenk",
"write.ogg": "schreiben",
"yellow.ogg": "gelb",
"yogurt.ogg": "der Joghurt",
"yum.ogg": "lecker",
"zebra.ogg": "das Zebra",
"zipper.ogg": "der Reißverschluss",
"zoo.ogg": "der Zoo"
-}
+}
\ No newline at end of file
diff --git a/src/activities/lang/resource/content-el.json b/src/activities/lang/resource/content-el.json
new file mode 100644
index 000000000..9235a1f2b
--- /dev/null
+++ b/src/activities/lang/resource/content-el.json
@@ -0,0 +1,1092 @@
+{
+ "10.ogg": "δέκα",
+ "11.ogg": "έντεκα",
+ "12.ogg": "δώδεκα",
+ "16.ogg": "δεκαέξι",
+ "U0030.ogg": "μηδέν",
+ "U0031.ogg": "ένα",
+ "U0032.ogg": "δύο",
+ "U0033.ogg": "τρία",
+ "U0034.ogg": "τέσσερα",
+ "U0035.ogg": "πέντε",
+ "U0036.ogg": "έξι",
+ "U0037.ogg": "επτά",
+ "U0038.ogg": "οκτώ",
+ "U0039.ogg": "εννέα",
+ "accountant.ogg": "λογιστής",
+ "ache.ogg": "πόνος",
+ "acorn.ogg": "βελανίδι",
+ "actor.ogg": "ηθοποιός",
+ "air_horn.ogg": "κόρνα γηπέδου",
+ "alarmclock.ogg": "ξυπνητήρι",
+ "alligator.ogg": "αλιγάτορας",
+ "alphabet.ogg": "αλφάβητο",
+ "anchor.ogg": "άγκυρα",
+ "angel.ogg": "άγγελος",
+ "angry.ogg": "θυμός",
+ "animal.ogg": "ζώα",
+ "ankle.ogg": "αστράγαλος",
+ "ant.ogg": "μυρμήγκι",
+ "anteater.ogg": "μυρμηγκοφάγος",
+ "antelope.ogg": "αντιλόπη",
+ "apple.ogg": "μήλο",
+ "apple_tree.ogg": "μηλιά",
+ "appliance.ogg": "συσκευές",
+ "apricot.ogg": "βερίκοκο",
+ "arm.ogg": "βραχίονας",
+ "armchair.ogg": "πολυθρόνα",
+ "artichoke.ogg": "αγκινάρα",
+ "artist.ogg": "ζωγράφος",
+ "asparagus.ogg": "σπαράγγι",
+ "astronaut.ogg": "αστροναύτης",
+ "athlete.ogg": "άθληση",
+ "avocado.ogg": "αβοκάντο",
+ "ax.ogg": "τσεκούρι",
+ "baby_bottle.ogg": "μπιμπερό",
+ "back.ogg": "πλάτη",
+ "badge.ogg": "παράσημο",
+ "bag.ogg": "τσάντα",
+ "bait.ogg": "δόλωμα",
+ "balance.ogg": "ζυγαριά",
+ "bald.ogg": "φαλακρός",
+ "ball.ogg": "αερόμπαλα",
+ "ball_of_yarn.ogg": "κούκλα μαλλιού",
+ "ball_soccer.ogg": "μπάλα",
+ "ballet.ogg": "μπαλέτο",
+ "bank.ogg": "τράπεζα",
+ "banker_female.ogg": "τραπεζίτης",
+ "bark.ogg": "γάβγισμα",
+ "barn.ogg": "αχυρώνας",
+ "bat.ogg": "νυχτερίδα",
+ "bath.ogg": "μπανιέρα",
+ "bathing_suit.ogg": "μαγιό",
+ "bay.ogg": "κόλπος",
+ "beach.ogg": "παραλία",
+ "bean.ogg": "φασόλι",
+ "bear.ogg": "αρκούδα",
+ "beard.ogg": "γενειάδα",
+ "beat.ogg": "χτύπημα",
+ "beaver.ogg": "κάστορας",
+ "bed.ogg": "κρεβάτι",
+ "bedroom.ogg": "υπνοδωμάτιο",
+ "bee.ogg": "μέλισσα",
+ "beetle.ogg": "σκαθάρι",
+ "beg.ogg": "ικεσία",
+ "behind.ogg": "πίσω",
+ "bell.ogg": "καμπάνα",
+ "belly.ogg": "κοιλιά",
+ "bench.ogg": "παγκάκι",
+ "bib.ogg": "σαλιάρα",
+ "big.ogg": "μεγάλος",
+ "big_top.ogg": "σκηνή τσίρκου",
+ "bike.ogg": "ποδήλατο",
+ "bird.ogg": "πουλί",
+ "bit.ogg": "κομμάτι",
+ "bite.ogg": "δάγκωμα",
+ "black.ogg": "μαύρο",
+ "blackberry.ogg": "βατόμουρο",
+ "blackbird.ogg": "κοτσύφι",
+ "blade.ogg": "λεπίδι",
+ "blind.ogg": "τυφλός",
+ "blink.ogg": "βλεφάρισμα",
+ "block.ogg": "κύβος",
+ "blond.ogg": "ξανθιά",
+ "blue.ogg": "μπλε",
+ "blueberry.ogg": "μύρτιλο",
+ "blush.ogg": "κοκκινίζω",
+ "board.ogg": "πινακίδα",
+ "boat.ogg": "βάρκα",
+ "boil.ogg": "βράσιμο",
+ "bolt.ogg": "βίδα",
+ "bomb.ogg": "βόμβα",
+ "bone.ogg": "κόκαλο",
+ "book.ogg": "βιβλίο",
+ "bookcase.ogg": "βιβλιοθήκη",
+ "bottom.ogg": "πισινός",
+ "box.ogg": "κουτί",
+ "boxer.ogg": "πυγμάχος",
+ "boy.ogg": "αγόρι",
+ "braid.ogg": "πλεξούδα",
+ "brain.ogg": "εγκέφαλος",
+ "branch.ogg": "κλαδί",
+ "bread.ogg": "ψωμί",
+ "break.ogg": "σπάσιμο",
+ "breast.ogg": "στήθος",
+ "brick.ogg": "τούβλο",
+ "bricklayer.ogg": "χτίστης",
+ "bride.ogg": "νύφη",
+ "bridge.ogg": "γέφυρα",
+ "bright.ogg": "φωτεινός",
+ "broccoli.ogg": "μπρόκολο",
+ "brother.ogg": "αδερφός",
+ "brown.ogg": "καφέ",
+ "brush.ogg": "βούρτσα",
+ "bubble.ogg": "φυσαλίδα",
+ "bucket.ogg": "κουβάς",
+ "bud.ogg": "μπουμπούκι",
+ "buffalo.ogg": "βουβάλι",
+ "bug.ogg": "έντομο",
+ "bulb.ogg": "λάμπα",
+ "bull.ogg": "ταύρος",
+ "bump.ogg": "καρούμπαλο",
+ "bun.ogg": "γλυκόψωμο",
+ "bus.ogg": "λεωφορείο",
+ "bush.ogg": "θάμνος",
+ "butcher.ogg": "κρεοπώλης",
+ "butter.ogg": "βούτυρο",
+ "butterfly.ogg": "πεταλούδα",
+ "button.ogg": "κουμπί",
+ "cabbage.ogg": "λάχανο",
+ "cabin.ogg": "σπιτάκι",
+ "cacao.ogg": "κακάο",
+ "cactus.ogg": "κάκτος",
+ "cage.ogg": "κλουβί",
+ "cake.ogg": "τούρτα",
+ "call.ogg": "τηλεφώνημα",
+ "camel.ogg": "καμήλα",
+ "camera.ogg": "φωτογραφική μηχανή",
+ "camp.ogg": "κατασκήνωση",
+ "can.ogg": "δοχείο",
+ "canary.ogg": "καναρίνι",
+ "candle.ogg": "κερί",
+ "candy.ogg": "καραμέλα",
+ "cane.ogg": "μπαστούνι",
+ "canoe.ogg": "κανό",
+ "canon.ogg": "κανόνι",
+ "canyon.ogg": "φαράγγι",
+ "cap.ogg": "καπέλο",
+ "cape.ogg": "κάπα",
+ "car.ogg": "αυτοκίνητο",
+ "carafe.ogg": "καράφα",
+ "card.ogg": "κάρτα",
+ "carnival.ogg": "καρναβάλι",
+ "carpenter.ogg": "ξυλουργός",
+ "carpet.ogg": "χαλί",
+ "carrot.ogg": "καρότο",
+ "cart.ogg": "καροτσάκι",
+ "cash.ogg": "μετρητά",
+ "castle.ogg": "κάστρο",
+ "cat.ogg": "γάτος",
+ "cat_female.ogg": "γάτα",
+ "catch.ogg": "ψάρεμα",
+ "caterpillar.ogg": "κάμπια",
+ "cauldron.ogg": "καζάνι",
+ "cauliflower.ogg": "κουνουπίδι",
+ "cave.ogg": "σπηλιά",
+ "cavern.ogg": "σπήλαιο",
+ "celery.ogg": "σέλινο",
+ "centipede.ogg": "σαρανταποδαρούσα",
+ "cereal.ogg": "δημητριακά",
+ "chain.ogg": "αλυσίδα",
+ "chair.ogg": "καρέκλα",
+ "chalk.ogg": "κιμωλία",
+ "chameleon.ogg": "χαμαιλέων",
+ "chandelier.ogg": "πολυέλαιος",
+ "chat.ogg": "συνομιλία",
+ "cheek.ogg": "μάγουλο",
+ "cheer.ogg": "μαζορέτα",
+ "cheese.ogg": "τυρί",
+ "chef.ogg": "μάγειρας",
+ "cherry.ogg": "κεράσι",
+ "chest.ogg": "σεντούκι",
+ "chick.ogg": "κοτοπουλάκι",
+ "chicken.ogg": "κοτόπουλο",
+ "child.ogg": "παιδί",
+ "chimney.ogg": "καμινάδα",
+ "chimp.ogg": "χιμπαντζής",
+ "chin.ogg": "πηγούνι",
+ "chocolate.ogg": "σοκολάτα",
+ "chop.ogg": "κόψιμο",
+ "chores.ogg": "μικροδουλειές",
+ "christmas.ogg": "Χριστούγεννα",
+ "cigar.ogg": "πούρο",
+ "circus.ogg": "τσίρκο",
+ "city.ogg": "πόλη",
+ "clam.ogg": "κοχύλι",
+ "clap.ogg": "χειραψία",
+ "class.ogg": "αίθουσα διδασκαλίας",
+ "claw.ogg": "νύχι",
+ "clay.ogg": "πηλός",
+ "clean.ogg": "καθαρός",
+ "cleaning_lady.ogg": "καθαρίστρια",
+ "cliff.ogg": "γκρεμός",
+ "climb.ogg": "αναρρίχηση",
+ "clock.ogg": "ρολόι",
+ "cloth.ogg": "ύφασμα",
+ "clothes_hanger.ogg": "κρεμάστρα",
+ "cloud.ogg": "σύννεφο",
+ "cloudy.ogg": "συννεφιά",
+ "clover.ogg": "τριφύλλι",
+ "clown.ogg": "κλόουν",
+ "coach.ogg": "προπονητής",
+ "coast.ogg": "ακτή",
+ "coat.ogg": "παλτό",
+ "cobra.ogg": "κόμπρα",
+ "coconut.ogg": "καρύδα",
+ "cod.ogg": "μπακαλιάρος",
+ "coffee.ogg": "καφές",
+ "coin.ogg": "κέρματα",
+ "cold.ogg": "κρύο",
+ "color.ogg": "χρώματα",
+ "colt.ogg": "πουλάρι",
+ "comb.ogg": "χτένα",
+ "cone.ogg": "κώνος",
+ "cook.ogg": "μαγειρεύω",
+ "cookie.ogg": "μπισκότα",
+ "cork.ogg": "φελλός",
+ "corn.ogg": "καλαμπόκι",
+ "couch.ogg": "καναπές",
+ "cough.ogg": "βήχας",
+ "couple.ogg": "ζευγάρι",
+ "cow.ogg": "αγελάδα",
+ "cowboy.ogg": "αγελαδάρης",
+ "crab.ogg": "κάβουρας",
+ "cradle.ogg": "κούνια",
+ "craft.ogg": "τέχνη",
+ "crawl.ogg": "μπουσουλάω",
+ "crazy.ogg": "τρέλα",
+ "creek.ogg": "ρυάκι",
+ "crepe.ogg": "κρέπα",
+ "crib.ogg": "κούνια",
+ "croak.ogg": "κοάζω",
+ "crocodile.ogg": "κροκόδειλος",
+ "cross.ogg": "σταυρός",
+ "crow.ogg": "κοράκι",
+ "crown.ogg": "στέμμα",
+ "crumb.ogg": "ψίχουλο",
+ "crust.ogg": "κόρα",
+ "cry.ogg": "κλαίω",
+ "crystal.ogg": "κρύσταλλο",
+ "cube.ogg": "κύβος",
+ "cucumber.ogg": "αγγούρι",
+ "curtain.ogg": "κουρτίνα",
+ "cut.ogg": "κόβω",
+ "cute.ogg": "χαριτωμένη",
+ "dad.ogg": "πατέρας",
+ "daffodil.ogg": "νάρκισσος",
+ "daisy.ogg": "μαργαρίτα",
+ "dam.ogg": "φράγμα",
+ "dance.ogg": "χορός",
+ "dandelion.ogg": "ραδίκι",
+ "dart_board.ogg": "βελάκια",
+ "date_fruit.ogg": "χουρμάδες",
+ "deer.ogg": "ελάφι",
+ "den.ogg": "φωλιά",
+ "desert.ogg": "έρημος",
+ "desk.ogg": "γραφείο",
+ "dessert.ogg": "γλυκό",
+ "diamond.ogg": "διαμάντι",
+ "dig.ogg": "σκάβω",
+ "dirt.ogg": "χώμα",
+ "dirty.ogg": "βρόμικος",
+ "dish.ogg": "πιάτο",
+ "dishcloth.ogg": "πανί για πιάτα",
+ "dive.ogg": "κατάδυση",
+ "doctor.ogg": "γιατρός",
+ "doe.ogg": "θηλυκό ελάφι",
+ "dog.ogg": "σκύλος",
+ "doll.ogg": "κούκλα",
+ "dolphin.ogg": "δελφίνι",
+ "domino.ogg": "ντόμινο",
+ "door.ogg": "πόρτα",
+ "doormat.ogg": "χαλάκι",
+ "dot.ogg": "κουκκίδα",
+ "doughnut.ogg": "ντόνατ",
+ "dove.ogg": "περιστέρι",
+ "dragon.ogg": "δράκος",
+ "dragonfly.ogg": "λιβελούλα",
+ "draw.ogg": "σχεδιάζω",
+ "drawer.ogg": "συρτάρι",
+ "dream.ogg": "όνειρο",
+ "dress.ogg": "φουστάνι",
+ "drink.ogg": "ρόφημα",
+ "drip.ogg": "σταγόνα",
+ "drive.ogg": "οδηγώ",
+ "drool.ogg": "τρέχουν τα σάλια",
+ "drum.ogg": "τύμπανο",
+ "dry.ogg": "στεγνώνω",
+ "duck.ogg": "πάπια",
+ "duck_mother.ogg": "πάπια μητέρα",
+ "dune.ogg": "αμμόλοφος",
+ "dwarf.ogg": "νάνος",
+ "eagle.ogg": "αετός",
+ "ear.ogg": "αυτί",
+ "earth.ogg": "Γη",
+ "eat.ogg": "τρώω",
+ "egg.ogg": "αυγό",
+ "eggplant.ogg": "μελιτζάνα",
+ "elbow.ogg": "αγκώνας",
+ "electrician.ogg": "ηλεκτρολόγος",
+ "elk.ogg": "τάρανδος",
+ "empty.ogg": "άδειο",
+ "engine.ogg": "μηχανή",
+ "engineer.ogg": "μηχανικός",
+ "eraser.ogg": "σβήστρα",
+ "explore.ogg": "εξερεύνηση",
+ "eyelash.ogg": "βλεφαρίδα",
+ "eyes.ogg": "μάτι",
+ "face.ogg": "πρόσωπο",
+ "fair.ogg": "λούνα παρκ",
+ "fairy.ogg": "νεράιδα",
+ "fall.ogg": "πτώση",
+ "fall_season.ogg": "φθινόπωρο",
+ "family.ogg": "οικογένεια",
+ "fan.ogg": "ανεμιστήρας",
+ "farm.ogg": "αγρόκτημα",
+ "farmer.ogg": "αγρότης",
+ "fat.ogg": "χοντρός",
+ "faucet.ogg": "βρύση",
+ "fawn.ogg": "ελαφάκι",
+ "fear.ogg": "φόβος",
+ "feast.ogg": "πανδαισία",
+ "feather.ogg": "φτερό",
+ "feed.ogg": "ταΐζω",
+ "femur.ogg": "μηριαίο οστό",
+ "fetch.ogg": "φέρνω",
+ "fig.ogg": "σύκο",
+ "fin.ogg": "πτερύγιο",
+ "find.ogg": "βρίσκω",
+ "finger.ogg": "δάχτυλο",
+ "fire.ogg": "φωτιά",
+ "fire_extinguisher.ogg": "πυροσβεστήρας",
+ "fireman.ogg": "πυροσβέστης",
+ "fish.ogg": "ψάρι",
+ "fisherman.ogg": "ψαράς",
+ "fist.ogg": "γροθιά",
+ "flacon.ogg": "μπουκαλάκι",
+ "flag.ogg": "σημαία",
+ "flame.ogg": "φλόγα",
+ "flamingo.ogg": "φλαμίνγκο",
+ "flash.ogg": "φακός",
+ "flat.ogg": "επίπεδο",
+ "flies.ogg": "μύγα",
+ "float.ogg": "επιπλέω",
+ "flour.ogg": "αλεύρι",
+ "flower.ogg": "λουλούδι",
+ "fluff.ogg": "χνούδι",
+ "flute.ogg": "φλάουτο",
+ "fly.ogg": "πετάω",
+ "foam.ogg": "αφρός",
+ "foot.ogg": "πατούσα",
+ "forest.ogg": "δάσος",
+ "fork.ogg": "πηρούνι",
+ "fountain.ogg": "σιντριβάνι",
+ "fox.ogg": "αλεπού",
+ "freeze.ogg": "παγώνω",
+ "friend.ogg": "φίλος",
+ "fries.ogg": "τηγανητές πατάτες ",
+ "frog.ogg": "βάτραχος",
+ "front.ogg": "μπροστά",
+ "fruit.ogg": "φρούτα",
+ "fudge.ogg": "είδος γλυκίσματος",
+ "full.ogg": "γεμάτο",
+ "fur.ogg": "γούνα",
+ "game.ogg": "παιχνίδι",
+ "garage.ogg": "χώρος στάθμευσης",
+ "garden.ogg": "κήπος",
+ "garlic.ogg": "σκόρδο",
+ "gem.ogg": "πολύτιμος λίθος",
+ "giant.ogg": "γιγάντιος",
+ "gift.ogg": "δώρο",
+ "giraffe.ogg": "καμηλοπάρδαλη",
+ "girl.ogg": "κορίτσι",
+ "glass.ogg": "ποτήρι",
+ "glasses.ogg": "γυαλιά",
+ "glove.ogg": "γάντια",
+ "glue.ogg": "κόλλα",
+ "gnome.ogg": "νάνος",
+ "goat.ogg": "κατσίκα",
+ "golden.ogg": "χρυσαφένιο",
+ "golf.ogg": "γκολφ",
+ "goose.ogg": "χήνα",
+ "gorilla.ogg": "γορίλλας",
+ "grain.ogg": "σιτηρά",
+ "grandmother.ogg": "γιαγιά",
+ "grape.ogg": "σταφύλια",
+ "grapefruit.ogg": "γκρέιπφρουτ",
+ "grass.ogg": "χόρτα",
+ "grave.ogg": "τάφος",
+ "gray.ogg": "γκρι",
+ "green.ogg": "πράσινο",
+ "grill.ogg": "ψησταριά",
+ "grin.ogg": "χαμόγελο",
+ "ground.ogg": "έδαφος",
+ "growl.ogg": "γρυλίζω",
+ "guignol.ogg": "Γκινιόλ",
+ "guinea_pig.ogg": "ινδικό χοιρίδιο",
+ "gum.ogg": "τσίχλα",
+ "hair.ogg": "μαλλιά",
+ "hair_dryer.ogg": "πιστολάκι",
+ "half.ogg": "μισό",
+ "ham.ogg": "χοιρομέρι",
+ "hamburger.ogg": "χάμπουργκερ",
+ "hammer.ogg": "σφυρί",
+ "hand.ogg": "χέρι",
+ "handlebar.ogg": "handlebar",
+ "happy.ogg": "χαρούμενος",
+ "harp.ogg": "άρπα",
+ "hat.ogg": "καπέλο",
+ "hatch.ogg": "εκκόλαψη",
+ "hay.ogg": "σανός",
+ "head.ogg": "κεφάλι",
+ "hear.ogg": "ακούω",
+ "heat.ogg": "θερμότητα",
+ "hedge.ogg": "φράχτης",
+ "hedgehog.ogg": "σκαντζόχοιρος",
+ "heel.ogg": "τακούνι",
+ "helmet.ogg": "κράνος",
+ "hen.ogg": "κότα",
+ "herd.ogg": "κοπάδι",
+ "high.ogg": "ψηλά",
+ "hike.ogg": "πεζοπορώ",
+ "hill.ogg": "λόφος",
+ "hip.ogg": "γοφός",
+ "hippopotamus.ogg": "ιπποπόταμος",
+ "hit.ogg": "πυγμαχία",
+ "hive.ogg": "κυψέλη",
+ "hockey.ogg": "χόκεϊ",
+ "hole.ogg": "τρύπα",
+ "home.ogg": "σπίτι",
+ "hook.ogg": "αγκίστρι",
+ "hop.ogg": "χοροπηδάω",
+ "horse.ogg": "άλογο",
+ "hose.ogg": "μάνικα",
+ "hospital.ogg": "νοσοκομείο",
+ "hot.ogg": "καυτό",
+ "hot_dog.ogg": "χοτ ντογκ",
+ "hound.ogg": "κυνηγόσκυλο",
+ "house.ogg": "σπίτι",
+ "howl.ogg": "ουρλιάζω",
+ "hug.ogg": "αγκαλιά",
+ "huge.ogg": "πελώριος",
+ "hummingbird.ogg": "κολιμπρί",
+ "hunchbacked.ogg": "καμπούρης ",
+ "hunter.ogg": "κυνηγός",
+ "husband.ogg": "σύζυγος",
+ "hut.ogg": "καλύβα",
+ "hyena.ogg": "ύαινα",
+ "ice.ogg": "πάγος",
+ "iceberg.ogg": "παγόβουνο",
+ "iguana.ogg": "ιγκουάνα",
+ "ill.ogg": "άρρωστος",
+ "ink.ogg": "μελάνι",
+ "island.ogg": "νησί",
+ "jacket.ogg": "μπουφάν",
+ "jaguar.ogg": "τζάγκουαρ",
+ "jam.ogg": "μαρμελάδα",
+ "jay.ogg": "κίσσα",
+ "jelly.ogg": "ζελές",
+ "jellyfish.ogg": "μέδουσα",
+ "jewel.ogg": "πετράδι",
+ "job.ogg": "δουλειά",
+ "jockey.ogg": "αναβάτης",
+ "jog.ogg": "τζόκινγκ",
+ "joy.ogg": "χαρά",
+ "judge.ogg": "δικαστής",
+ "judo.ogg": "τζούντο",
+ "juggler.ogg": "ζογκλέρ",
+ "juice.ogg": "χυμός",
+ "jump.ogg": "πηδώ",
+ "kangaroo.ogg": "καγκουρό",
+ "keel.ogg": "αναποδογυρίζω",
+ "kernel.ogg": "κουκούτσι",
+ "keyboard.ogg": "πληκτρολόγιο",
+ "kimono.ogg": "κιμονό",
+ "king.ogg": "βασιλιάς",
+ "kiss.ogg": "φιλί",
+ "kitchen.ogg": "κουζίνα",
+ "kite.ogg": "χαρταετός",
+ "kitten.ogg": "γατάκι",
+ "kiwi.ogg": "ακτινίδιο",
+ "knee.ogg": "γόνατο",
+ "kneel.ogg": "γονατίζω",
+ "knife.ogg": "μαχαίρι",
+ "knight.ogg": "ιππότης",
+ "knit.ogg": "πλέκω",
+ "knot.ogg": "κόμπος",
+ "koala.ogg": "κοάλα",
+ "lad.ogg": "νεαρός",
+ "lady.ogg": "κυρία",
+ "ladybug.ogg": "πασχαλίτσα",
+ "lake.ogg": "λίμνη",
+ "lama.ogg": "λάμα",
+ "lamb.ogg": "πρόβατο",
+ "lamp.ogg": "φωτιστικό",
+ "land.ogg": "γη",
+ "lane.ogg": "λωρίδα",
+ "lap.ogg": "αγκαλιά",
+ "lasso.ogg": "λάσο",
+ "laugh.ogg": "γέλιο",
+ "lava.ogg": "λάβα",
+ "lawn.ogg": "χορτάρι",
+ "lawyer.ogg": "δικηγόρος",
+ "leaf.ogg": "φύλλο",
+ "ledge.ogg": "προεξοχή",
+ "leek.ogg": "πράσο",
+ "left.ogg": "αριστερά",
+ "leg.ogg": "πόδι",
+ "lemon.ogg": "λεμόνι",
+ "lemonade.ogg": "λεμονάδα",
+ "lemur.ogg": "λεμούριος",
+ "leopard.ogg": "λεοπάρδαλη",
+ "lettuce.ogg": "μαρουλι",
+ "librarian.ogg": "βιβλιοθηκάριος",
+ "lick.ogg": "γλείψιμο",
+ "lid.ogg": "καπάκι",
+ "lift.ogg": "σηκώνω",
+ "light.ogg": "φως",
+ "lighthouse.ogg": "φάρος",
+ "lightning.ogg": "αστραπή",
+ "lilac.ogg": "πασχαλιά",
+ "lime.ogg": "μοσχολέμονο",
+ "line.ogg": "γραμμή",
+ "link.ogg": "κρίκος",
+ "lion.ogg": "λιοντάρι",
+ "lion_cub.ogg": "λιονταράκι",
+ "lip.ogg": "χείλος",
+ "liquid.ogg": "υγρό",
+ "lizard.ogg": "σαύρα",
+ "lobster.ogg": "αστακός",
+ "log.ogg": "κούτσουρο",
+ "look.ogg": "κοιτάζω",
+ "lunch.ogg": "πρόγευμα",
+ "mad.ogg": "τρελός",
+ "magic.ogg": "μαγεία",
+ "magnet.ogg": "μαγνήτης",
+ "magnifying_glass.ogg": "μεγεθυντικός φακός",
+ "magpie.ogg": "καρακάξα",
+ "mail.ogg": "αλληλογραφία",
+ "man.ogg": "άντρας",
+ "mane.ogg": "χαίτη",
+ "mango.ogg": "μάνγκο",
+ "map.ogg": "χάρτης",
+ "maple.ogg": "σφενδάμι",
+ "marble.ogg": "μπίλια",
+ "mashed_potatoes.ogg": "πουρές",
+ "mask.ogg": "μάσκα",
+ "mast.ogg": "κατάρτι",
+ "mat.ogg": "χαλάκι",
+ "match.ogg": "σπίρτο",
+ "mate.ogg": "φίλος",
+ "mattress.ogg": "στρώμα",
+ "mauve.ogg": "μενεξεδί",
+ "meal.ogg": "γεύμα",
+ "meat.ogg": "κρέας",
+ "mechanic.ogg": "μηχανικός",
+ "medal.ogg": "μετάλλιο",
+ "meet.ogg": "συνάντηση",
+ "melon.ogg": "πεπόνι",
+ "merry-go-round.ogg": "καρουζέλ",
+ "mice.ogg": "ποντίκια",
+ "microphone.ogg": "μικρόφωνο",
+ "milk.ogg": "γάλα",
+ "mill.ogg": "μύλος",
+ "mimosa.ogg": "μιμόζα",
+ "mirror.ogg": "καθρέφτης",
+ "mixer.ogg": "μίξερ",
+ "mole.ogg": "τυφλοπόντικας",
+ "mom.ogg": "μαμά",
+ "moon.ogg": "φεγγάρι",
+ "moose.ogg": "άλκη",
+ "mop.ogg": "σφουγγαρίστρα",
+ "mosque.ogg": "τζαμί",
+ "mosquito.ogg": "κουνούπι",
+ "mother.ogg": "μητέρα",
+ "motorcycle.ogg": "μηχανάκι",
+ "mountain.ogg": "βουνό",
+ "mouse.ogg": "ποντίκι",
+ "mouth.ogg": "στόμα",
+ "movie.ogg": "κινηματογράφος",
+ "mower.ogg": "χορτοθεριστικό",
+ "mud.ogg": "λάσπη",
+ "mug.ogg": "κούπα",
+ "mule.ogg": "μουλάρι",
+ "muscle.ogg": "μπράτσο",
+ "mushroom.ogg": "μανιτάρι",
+ "music.ogg": "μουσική",
+ "musician.ogg": "μουσικός",
+ "naked.ogg": "γυμνός",
+ "nap.ogg": "υπνάκος",
+ "navel.ogg": "ομφαλός",
+ "neck.ogg": "λαιμός",
+ "necklace.ogg": "κολιέ",
+ "needle.ogg": "βελόνα",
+ "nest.ogg": "φωλιά",
+ "net.ogg": "δίχτυ",
+ "newspaper.ogg": "εφημερίδα",
+ "night.ogg": "νύχτα",
+ "nightgown.ogg": "νυχτικιά",
+ "nose.ogg": "μύτη",
+ "nostril.ogg": "ρουθούνι",
+ "notebook.ogg": "τετράδιο",
+ "number.ogg": "αριθμοί",
+ "nun.ogg": "καλόγρια",
+ "nurse.ogg": "νοσοκόμα",
+ "nurse_male.ogg": "νοσοκόμος",
+ "nut.ogg": "καρπός",
+ "oar.ogg": "κουπί",
+ "ocean.ogg": "ωκεανός",
+ "office.ogg": "γραφείο",
+ "olive.ogg": "ελιά",
+ "on.ogg": "επάνω",
+ "onion.ogg": "κρεμμύδι",
+ "open.ogg": "ανοιχτή",
+ "opossum.ogg": "οπόσουμ",
+ "orange-color.ogg": "πορτοκαλί",
+ "orange.ogg": "πορτοκάλι",
+ "orchid.ogg": "ορχιδέα",
+ "ostrich.ogg": "στρουθοκάμηλος",
+ "otter.ogg": "βίδρα",
+ "owl.ogg": "κουκουβάγια",
+ "ox.ogg": "βόδι",
+ "oyster.ogg": "στρείδι",
+ "pacifier.ogg": "πιπίλα",
+ "page.ogg": "σελίδα",
+ "pair.ogg": "ζευγάρι",
+ "pajamas.ogg": "πιτζάμες",
+ "pal.ogg": "φιλαράκος",
+ "palm_tree.ogg": "φοίνικας",
+ "pan.ogg": "τηγάνι",
+ "panda.ogg": "πάντα",
+ "panther.ogg": "πάνθηρας",
+ "panties.ogg": "εσώρουχα",
+ "pants.ogg": "παντελόνι",
+ "papaya.ogg": "παπάγια",
+ "paper.ogg": "χαρτί",
+ "parachute.ogg": "αλεξίπτωτο",
+ "parakeet.ogg": "παπαγάλος",
+ "parrot.ogg": "παπαγάλος",
+ "patch.ogg": "μπάλωμα",
+ "path.ogg": "μονοπάτι",
+ "paw.ogg": "πατημασιά",
+ "pea.ogg": "αρακάς",
+ "peach.ogg": "ροδάκινο",
+ "peacock.ogg": "παγόνι",
+ "peak.ogg": "κορυφή",
+ "pear.ogg": "αχλάδι",
+ "pearl.ogg": "μαργαριτάρι",
+ "peck.ogg": "τσιμπάω",
+ "pedal.ogg": "πηδάλι",
+ "pelican.ogg": "πελεκάνος",
+ "pen.ogg": "στιλό",
+ "pencil.ogg": "μολύβι",
+ "peony.ogg": "παιωνία",
+ "people.ogg": "κόσμος",
+ "pepper.ogg": "πιπέρι",
+ "peppers.ogg": "πιπεριές",
+ "pet.ogg": "κατοικίδιο",
+ "petal.ogg": "πέταλο",
+ "phone.ogg": "τηλέφωνο",
+ "piano.ogg": "πιάνο",
+ "picture.ogg": "εικόνα",
+ "pie.ogg": "μηλόπιτα",
+ "pig.ogg": "γουρούνι",
+ "pigeon.ogg": "περιστέρι",
+ "pill.ogg": "χάπι",
+ "pillow.ogg": "μαξιλάρι",
+ "pilot.ogg": "πιλότος",
+ "pine.ogg": "πεύκο",
+ "pine_cone.ogg": "κουκουνάρι",
+ "pink.ogg": "ροζ",
+ "pip.ogg": "κουκούτσι",
+ "pipe.ogg": "πίπα",
+ "piranha.ogg": "πιράνχας",
+ "pirate.ogg": "πειρατής",
+ "pizza.ogg": "πίτσα",
+ "plane.ogg": "αεροπλάνο",
+ "planet.ogg": "πλανήτης",
+ "plant.ogg": "φυτό",
+ "plate.ogg": "πιάτο",
+ "play.ogg": "παίζω",
+ "pliers.ogg": "πένσα",
+ "plow.ogg": "οργώνω",
+ "plum.ogg": "δαμάσκηνο",
+ "plumber.ogg": "υδραυλικός",
+ "pocket.ogg": "τσέπη",
+ "pod.ogg": "αρακάς",
+ "pole.ogg": "πάσσαλος",
+ "police.ogg": "αστυνομικός",
+ "pompon.ogg": "φούντα",
+ "pond.ogg": "λιμνούλα",
+ "pony.ogg": "πόνι",
+ "pool.ogg": "πισίνα",
+ "popcorn.ogg": "ποπκόρν",
+ "pope.ogg": "πάπας",
+ "porthole.ogg": "φινιστρίνι",
+ "post.ogg": "ταχυδρομείο",
+ "pot.ogg": "πιθάρι",
+ "potato.ogg": "πατάτα",
+ "pounce.ogg": "ορμάω",
+ "president.ogg": "πρόεδρος",
+ "pretty.ogg": "χαριτωμένη",
+ "price.ogg": "τιμή",
+ "priest.ogg": "παπάς",
+ "prince.ogg": "πρίγκηπας",
+ "princess.ogg": "πριγκήπισσα",
+ "prison.ogg": "φυλακή",
+ "prisoner.ogg": "φυλακισμένος",
+ "prize.ogg": "βραβείο",
+ "pug.ogg": "μπουλντόγκ",
+ "pull.ogg": "τραβάω",
+ "pullover.ogg": "πουλόβερ",
+ "pumpkin.ogg": "κολοκύθι",
+ "puppy.ogg": "κουτάβι",
+ "pyramid.ogg": "πυραμίδα",
+ "quarrel.ogg": "μαλώνω",
+ "queen.ogg": "βασίλισσα",
+ "question.ogg": "αναρωτιέμαι",
+ "quilt.ogg": "πάπλωμα",
+ "quiz.ogg": "διαγώνισμα",
+ "rabbit.ogg": "κουνέλι",
+ "rabbit_baby.ogg": "κουνελάκι",
+ "race.ogg": "αγώνας",
+ "radio.ogg": "ραδιόφωνο",
+ "radish.ogg": "ραπανάκι",
+ "raft.ogg": "σχεδία",
+ "rag.ogg": "ξεσκονόπανο",
+ "rage.ogg": "οργή",
+ "rain.ogg": "βροχή",
+ "raincoat.ogg": "αδιάβροχο",
+ "rake.ogg": "τσουγκράνα",
+ "ramp.ogg": "ράμπα",
+ "ran.ogg": "τρέχω",
+ "raspberry.ogg": "σμέουρο",
+ "rat.ogg": "αρουραίος",
+ "razor.ogg": "ξυράφι",
+ "read.ogg": "διαβάζω",
+ "red.ogg": "κόκκινο",
+ "reptile.ogg": "ερπετό",
+ "rhinoceros.ogg": "ρινόκερος",
+ "rice.ogg": "ρύζι",
+ "ride.ogg": "καβαλάω",
+ "rifle.ogg": "τουφέκι",
+ "right.ogg": "δεξιά",
+ "rip.ogg": "σκίζω",
+ "rise.ogg": "αυξάνω",
+ "river.ogg": "ποτάμι",
+ "road.ogg": "δρόμος",
+ "roast.ogg": "ψητό",
+ "robe.ogg": "τήβεννος",
+ "robot.ogg": "ρομπότ",
+ "rock.ogg": "βράχος",
+ "rocket.ogg": "πύραυλος",
+ "rolling_pin.ogg": "πλάστης",
+ "roof.ogg": "σκεπή",
+ "room.ogg": "δωμάτιο",
+ "root.ogg": "ρίζα",
+ "rope.ogg": "σκοινί",
+ "rose.ogg": "τριαντάφυλλο",
+ "round.ogg": "κύκλος",
+ "rowing.ogg": "κωπηλασία",
+ "royal.ogg": "βασιλιάς",
+ "rug.ogg": "πατάκι",
+ "run.ogg": "τρέχω",
+ "sad.ogg": "λύπη",
+ "saddle.ogg": "σέλα",
+ "sail.ogg": "καραβάκι",
+ "sailor.ogg": "ναύτης",
+ "salamander.ogg": "σαλαμάνδρα",
+ "salmon.ogg": "σολωμός",
+ "sand.ogg": "άμμος",
+ "sandals.ogg": "σανδάλια",
+ "sandwich.ogg": "σάντουιτς",
+ "sash.ogg": "κορδέλα",
+ "sauce.ogg": "σάλτσα",
+ "sausage.ogg": "λουκάνικο",
+ "scale.ogg": "ζυγαριά",
+ "scar.ogg": "ουλή",
+ "scare.ogg": "τρομάζω",
+ "scarf.ogg": "κασκόλ",
+ "school.ogg": "σχολείο",
+ "school_bag.ogg": "σχολική τσάντα",
+ "science.ogg": "επιστήμη",
+ "scissors.ogg": "ψαλίδι",
+ "scorpion.ogg": "σκορπιός",
+ "scratch.ogg": "γρατζουνιά",
+ "scream.ogg": "ουρλιάζω",
+ "screw.ogg": "βίδα",
+ "screwdriver.ogg": "κατσαβίδι",
+ "scribble.ogg": "κακογραφία",
+ "sea.ogg": "θάλασσα",
+ "seat.ogg": "κάθισμα",
+ "see.ogg": "βλέπω",
+ "seed.ogg": "σπόροι",
+ "shadow.ogg": "σκιά",
+ "shake.ogg": "κουνάω",
+ "shark.ogg": "καρχαρίας",
+ "shave.ogg": "κουρεμένος",
+ "shed.ogg": "αποθήκη",
+ "sheep.ogg": "πρόβατο",
+ "shelf.ogg": "ράφι",
+ "shell.ogg": "όστρακο",
+ "ship.ogg": "πλοιαράκι",
+ "shirt.ogg": "πουκάμισο",
+ "shoe.ogg": "παπούτσι",
+ "shoelace.ogg": "κορδόνι",
+ "shop.ogg": "μαγαζί",
+ "shore.ogg": "ακτή",
+ "short.ogg": "κοντό",
+ "shovel.ogg": "φαράσι",
+ "shower.ogg": "ντουζιέρα",
+ "shrimp.ogg": "γαρίδα",
+ "shrub.ogg": "πόα",
+ "shut.ogg": "κλειστή",
+ "shutter.ogg": "παραθυρόφυλλο",
+ "sick.ogg": "άρρωστος",
+ "sidewalk.ogg": "πεζοδρόμιο",
+ "sign.ogg": "σήμα",
+ "sing.ogg": "τραγουδάω",
+ "sink.ogg": "νεροχύτης",
+ "sip.ogg": "ρουφηξιά",
+ "sister.ogg": "αδερφή",
+ "sit.ogg": "κάθομαι",
+ "skate.ogg": "πατίνι",
+ "skeleton.ogg": "σκελετός",
+ "ski.ogg": "σκι",
+ "skimmer.ogg": "τρυπητή κουτάλα",
+ "skin.ogg": "δέρμα",
+ "skirt.ogg": "φούστα",
+ "skunk.ogg": "νυφίτσα",
+ "sky.ogg": "ουρανός",
+ "slam.ogg": "καρφώνω",
+ "sled.ogg": "έλκυθρο",
+ "sleep.ogg": "κοιμάμαι",
+ "sleeve.ogg": "μανίκι",
+ "sleigh.ogg": "έλκυθρο",
+ "slide.ogg": "τσουλάω",
+ "slim.ogg": "λεπτή",
+ "slime.ogg": "γλίτσα",
+ "slippers.ogg": "παντόφλες",
+ "slope.ogg": "πλαγιά",
+ "sloppy.ogg": "τσαπατσούλης",
+ "slot.ogg": "σχισμή",
+ "sloth.ogg": "βραδύπους",
+ "slug.ogg": "γυμνοσάλιαγκας",
+ "small.ogg": "μικρός",
+ "smell.ogg": "μυρίζω",
+ "smile.ogg": "χαμογελάω",
+ "smock.ogg": "ποδιά",
+ "smoke.ogg": "καπνός",
+ "smooch.ogg": "φιλί",
+ "snack.ogg": "σνακ",
+ "snail.ogg": "σαλιγκάρι",
+ "snake.ogg": "φίδι",
+ "sneaker.ogg": "αθλητικό παπούτσι",
+ "sniff.ogg": "μυρίζω",
+ "snow.ogg": "χιόνι",
+ "soap.ogg": "σαπούνι",
+ "sob.ogg": "κλάμα",
+ "sock.ogg": "κάλτσα",
+ "soldier.ogg": "στρατιώτης",
+ "sole.ogg": "γλώσσα",
+ "sole_shoe.ogg": "σόλα",
+ "son.ogg": "γιος",
+ "soup.ogg": "σούπα",
+ "spade.ogg": "φτυάρι",
+ "spaghetti.ogg": "μακαρονάδα",
+ "spark.ogg": "σπίθα",
+ "sparrow.ogg": "σπουργίτης",
+ "spatula.ogg": "σπάτουλα",
+ "speak.ogg": "μιλάω",
+ "spear.ogg": "ακόντιο",
+ "spice.ogg": "μπαχαρικά",
+ "spider.ogg": "αράχνη",
+ "spider_web.ogg": "ιστός αράχνης",
+ "spike.ogg": "ακίδα",
+ "spill.ogg": "χύνω",
+ "spinach.ogg": "σπανάκι",
+ "spine.ogg": "σπονδυλική στήλη",
+ "spinning_top.ogg": "σβούρα",
+ "splash.ogg": "πιτσιλάω",
+ "splatter.ogg": "πιτσιλιά",
+ "sponge.ogg": "σφουγγάρι",
+ "spool.ogg": "καρούλι",
+ "spoon.ogg": "κουτάλι",
+ "sport.ogg": "άθλημα",
+ "spot.ogg": "λεκέδες",
+ "spray.ogg": "σπρέι",
+ "spread.ogg": "αλείφω",
+ "spring.ogg": "ελατήριο",
+ "spring_season.ogg": "άνοιξη",
+ "sprinkle.ogg": "πασπαλίζω",
+ "square.ogg": "τετράγωνο",
+ "squash.ogg": "κολοκύθα",
+ "squat.ogg": "γονατίζω",
+ "squid.ogg": "καλαμάρι",
+ "squirrel.ogg": "σκίουρος",
+ "squirt.ogg": "ψεκαστήρα",
+ "stack.ogg": "στοίβα",
+ "stage.ogg": "σκηνή",
+ "staircase.ogg": "σκάλα",
+ "stamp.ogg": "γραμματόσημο",
+ "stand.ogg": "στέκομαι",
+ "star.ogg": "αστέρι",
+ "stare.ogg": "κοιτάζω επίμονα",
+ "starfish.ogg": "αστερίας",
+ "steam.ogg": "ατμός",
+ "steep.ogg": "απότομος",
+ "steeple.ogg": "καμπαναριό",
+ "stem.ogg": "βλαστός",
+ "step.ogg": "σκαλοπάτι",
+ "stew.ogg": "βραστό",
+ "stick.ogg": "κλαδί",
+ "sting.ogg": "κεντρί",
+ "stinky.ogg": "βρομερός",
+ "stitch.ogg": "βελονιά",
+ "stomach.ogg": "στομάχι",
+ "stone.ogg": "πέτρες",
+ "stop.ogg": "σταματάω",
+ "store.ogg": "κατάστημα",
+ "stove.ogg": "ηλεκτρική κουζίνα",
+ "straight.ogg": "ίσιος",
+ "strainer.ogg": "σουρωτήρι",
+ "straw.ogg": "καλαμάκι",
+ "strawberry.ogg": "φράουλα",
+ "stream.ogg": "ρέμα",
+ "street.ogg": "δρόμος",
+ "stretch.ogg": "τεντώνομαι",
+ "string.ogg": "σπάγγος",
+ "stripe.ogg": "ρίγα",
+ "strong.ogg": "δυνατός",
+ "student.ogg": "μαθητής",
+ "study.ogg": "μελετάω",
+ "stump.ogg": "κομμένος κορμός",
+ "sugar.ogg": "ζάχαρη",
+ "suit.ogg": "κοστούμι",
+ "suitcase.ogg": "βαλίτσα",
+ "summer.ogg": "καλοκαίρι",
+ "summit.ogg": "κορυφή",
+ "sun.ogg": "ήλιος",
+ "swan.ogg": "κύκνος",
+ "sweat.ogg": "ιδρώνω",
+ "sweatshirt.ogg": "φούτερ",
+ "swim.ogg": "κολυμπώ",
+ "table.ogg": "τραπέζι",
+ "tablecloth.ogg": "τραπεζομάντιλο",
+ "tadpole.ogg": "γυρίνος",
+ "tag.ogg": "ετικέτα",
+ "tail.ogg": "ουρά",
+ "tall.ogg": "ψηλός",
+ "tape_measure.ogg": "μετροταινία",
+ "taxi.ogg": "ταξί",
+ "teach.ogg": "διδάσκω",
+ "teacher.ogg": "δασκάλα",
+ "tear.ogg": "σκίζω",
+ "teddy.ogg": "αρκουδάκι",
+ "teeth.ogg": "δόντια",
+ "television.ogg": "τηλεόραση",
+ "temple.ogg": "ναός",
+ "tennis.ogg": "τένις",
+ "tent.ogg": "σκηνή",
+ "text.ogg": "κείμενο",
+ "thick.ogg": "χοντρός",
+ "thief.ogg": "κλέφτης",
+ "thigh.ogg": "μηρός",
+ "think.ogg": "σκέφτομαι",
+ "thread.ogg": "νήμα",
+ "throat.ogg": "λάρυγγας",
+ "throw.ogg": "πετάω",
+ "thumb.ogg": "αντίχειρας",
+ "tick.ogg": "τσιμπούρι",
+ "ticket.ogg": "εισιτήριο",
+ "tiger.ogg": "τίγρης",
+ "time.ogg": "ώρα",
+ "tin.ogg": "μεταλλικό κουτί",
+ "tire.ogg": "λάστιχο",
+ "tired.ogg": "κουρασμένος",
+ "tissue.ogg": "χαρτομάντιλο",
+ "to_drink.ogg": "πίνω",
+ "toad.ogg": "φρύνος",
+ "toaster.ogg": "τοστιέρα",
+ "toe.ogg": "δάχτυλο ποδιού",
+ "toilet.ogg": "τουαλέτα",
+ "tomatoe.ogg": "ντομάτα",
+ "tongs.ogg": "λαβίδα",
+ "tongue.ogg": "γλώσσα",
+ "tool.ogg": "εργαλεία",
+ "top.ogg": "κορυφή",
+ "torch.ogg": "δαυλός",
+ "touch.ogg": "αγγίζω",
+ "towel.ogg": "πετσέτα",
+ "toy.ogg": "παιχνίδι",
+ "trail.ogg": "διαδρομή",
+ "train.ogg": "τρένο",
+ "train_station.ogg": "σιδηροδρομικός σταθμός",
+ "trap.ogg": "παγίδα",
+ "trash.ogg": "σκουπίδια",
+ "tray.ogg": "δίσκος",
+ "treat.ogg": "λιχουδιές",
+ "tree.ogg": "δέντρο",
+ "triangle.ogg": "τρίγωνο",
+ "tribe.ogg": "φυλή",
+ "trip.ogg": "ταξίδι",
+ "truck.ogg": "φορτηγό",
+ "tube.ogg": "κραγιόν",
+ "tulip.ogg": "τουλίπα",
+ "tune.ogg": "μελωδία",
+ "turkey.ogg": "γαλοπούλα",
+ "turnip.ogg": "γογγύλι",
+ "turtle.ogg": "χελώνα",
+ "tusk.ogg": "ελεφαντόδοντο",
+ "twin_boys.ogg": "δίδυμα αγόρια",
+ "twin_girls.ogg": "δίδυμα κορίτσια",
+ "umbrella.ogg": "ομπρέλα",
+ "under.ogg": "κάτω",
+ "uniform.ogg": "στολή",
+ "van.ogg": "φορτηγάκι",
+ "vapor.ogg": "ατμός",
+ "vase.ogg": "βάζο",
+ "vegetable.ogg": "λαχανικά",
+ "vein.ogg": "φλέβα",
+ "verdure.ogg": "πρασινάδα",
+ "vest.ogg": "αμάνικο",
+ "vet.ogg": "κτηνίατρος",
+ "viper.ogg": "οχιά",
+ "vowel.ogg": "φωνήεντα",
+ "vulture.ogg": "γύπας",
+ "wag.ogg": "κουνάω",
+ "walk.ogg": "περπατάω",
+ "wall.ogg": "τοίχος",
+ "walnut.ogg": "καρύδι",
+ "wart.ogg": "ρόζος",
+ "wash.ogg": "πλένομαι",
+ "wasp.ogg": "σφήκα",
+ "watch.ogg": "ρολόι",
+ "water.ogg": "νερό",
+ "wave.ogg": "κύμα",
+ "wedding.ogg": "παντρεμένοι",
+ "wedge.ogg": "σφηνώνω",
+ "weight.ogg": "βάρος",
+ "wet.ogg": "βρεγμένος",
+ "whale.ogg": "φάλαινα",
+ "wheat.ogg": "σιτάρι",
+ "wheel.ogg": "ρόδα",
+ "whisk.ogg": "χτυπητήρι",
+ "whisper.ogg": "ψιθυρίζω",
+ "white.ogg": "λευκό",
+ "wide.ogg": "φαρδύ",
+ "wife.ogg": "σύζυγος",
+ "wig.ogg": "περούκα",
+ "win.ogg": "νικάω",
+ "wind.ogg": "άνεμος",
+ "window.ogg": "παράθυρο",
+ "window_glass.ogg": "τζάμι",
+ "wing.ogg": "φτερό",
+ "winter.ogg": "χειμώνας",
+ "wolf.ogg": "λύκος",
+ "woman.ogg": "γυναίκα",
+ "wood.ogg": "ξύλα",
+ "word.ogg": "λέξη",
+ "worker.ogg": "εργάτης",
+ "world.ogg": "κόσμος",
+ "wreath.ogg": "στεφάνι",
+ "wrench.ogg": "κλειδί",
+ "wrist.ogg": "καρπός",
+ "write.ogg": "γράφω",
+ "yellow.ogg": "κίτρινο",
+ "yogurt.ogg": "γιαούρτι",
+ "yum.ogg": "όρεξη",
+ "zebra.ogg": "ζέβρα",
+ "zipper.ogg": "φερμουάρ",
+ "zoo.ogg": "ζωολογικός κήπος"
+}
\ No newline at end of file
diff --git a/src/activities/lang/resource/content-en.json b/src/activities/lang/resource/content-en.json
index 4b64bbf93..91e6241b6 100644
--- a/src/activities/lang/resource/content-en.json
+++ b/src/activities/lang/resource/content-en.json
@@ -1,1108 +1,1093 @@
{
"10.ogg": "ten",
"11.ogg": "eleven",
"12.ogg": "twelve",
"16.ogg": "sixteen",
"U0030.ogg": "zero",
"U0031.ogg": "one",
"U0032.ogg": "two",
"U0033.ogg": "three",
"U0034.ogg": "four",
"U0035.ogg": "five",
"U0036.ogg": "six",
"U0037.ogg": "seven",
"U0038.ogg": "eight",
"U0039.ogg": "nine",
"accountant.ogg": "",
"ache.ogg": "",
"acorn.ogg": "",
"actor.ogg": "",
"air_horn.ogg": "",
"alarmclock.ogg": "",
"alligator.ogg": "alligator",
"alphabet.ogg": "",
"anchor.ogg": "anchor",
"angel.ogg": "angel",
"angry.ogg": "",
"animal.ogg": "animal",
"ankle.ogg": "",
"ant.ogg": "",
"anteater.ogg": "",
"antelope.ogg": "",
"apple.ogg": "",
"apple_tree.ogg": "",
"appliance.ogg": "",
"apricot.ogg": "",
"arm.ogg": "",
"armchair.ogg": "",
"artichoke.ogg": "",
"artist.ogg": "",
"asparagus.ogg": "",
"astronaut.ogg": "",
- "ate.ogg": "ate",
"athlete.ogg": "athlete",
"avocado.ogg": "",
"ax.ogg": "",
"baby_bottle.ogg": "",
"back.ogg": "back",
"badge.ogg": "badge",
"bag.ogg": "bag",
"bait.ogg": "bait",
- "bake.ogg": "bake",
"balance.ogg": "balance",
"bald.ogg": "",
"ball.ogg": "ball",
"ball_of_yarn.ogg": "",
"ball_soccer.ogg": "",
"ballet.ogg": "ballet",
"bank.ogg": "bank",
"bark.ogg": "bark",
"barn.ogg": "barn",
"bat.ogg": "bat",
"bath.ogg": "bath",
"bathing_suit.ogg": "",
"bay.ogg": "bay",
"beach.ogg": "beach",
- "bead.ogg": "bead",
"bean.ogg": "",
"bear.ogg": "",
"beard.ogg": "",
"beat.ogg": "",
"beaver.ogg": "",
"bed.ogg": "bed",
"bedroom.ogg": "",
"bee.ogg": "bee",
- "beef.ogg": "",
"beetle.ogg": "beetle",
"beg.ogg": "beg",
"behind.ogg": "",
"bell.ogg": "",
"belly.ogg": "",
"bench.ogg": "bench",
"bib.ogg": "bib",
"big.ogg": "big",
"big_top.ogg": "",
"bike.ogg": "bike",
"bird.ogg": "bird",
"bit.ogg": "bit",
"bite.ogg": "bite",
"black.ogg": "black",
"blackberry.ogg": "",
"blackbird.ogg": "",
"blade.ogg": "",
"blind.ogg": "blind",
"blink.ogg": "blink",
"block.ogg": "block",
"blond.ogg": "blond",
"blue.ogg": "blue",
"blueberry.ogg": "",
"blush.ogg": "",
"board.ogg": "board",
"boat.ogg": "boat",
"boil.ogg": "boil",
"bolt.ogg": "",
"bomb.ogg": "bomb",
"bone.ogg": "bone",
"book.ogg": "book",
"bookcase.ogg": "",
"bottom.ogg": "",
"box.ogg": "box",
"boxer.ogg": "",
"boy.ogg": "boy",
"braid.ogg": "braid",
"brain.ogg": "brain",
"branch.ogg": "branch",
"bread.ogg": "bread",
"break.ogg": "break",
"breast.ogg": "",
"brick.ogg": "brick",
"bricklayer.ogg": "",
"bride.ogg": "bride",
"bridge.ogg": "bridge",
"bright.ogg": "bright",
"broccoli.ogg": "",
"brother.ogg": "brother",
"brown.ogg": "brown",
"brush.ogg": "brush",
"bubble.ogg": "",
"bucket.ogg": "",
"bud.ogg": "bud",
"buffalo.ogg": "",
"bug.ogg": "bug",
"bulb.ogg": "",
"bull.ogg": "",
"bump.ogg": "bump",
"bun.ogg": "bun",
"bus.ogg": "",
"bush.ogg": "bush",
"butcher.ogg": "",
"butter.ogg": "",
"butterfly.ogg": "",
"button.ogg": "",
"cabbage.ogg": "",
"cabin.ogg": "cabin",
"cacao.ogg": "",
"cactus.ogg": "",
"cage.ogg": "cage",
"cake.ogg": "cake",
"call.ogg": "call",
"camel.ogg": "camel",
"camera.ogg": "",
"camp.ogg": "camp",
"can.ogg": "can",
"canary.ogg": "",
"candle.ogg": "candle",
"candy.ogg": "candy",
"cane.ogg": "cane",
"canoe.ogg": "canoe",
"canon.ogg": "",
"canyon.ogg": "",
"cap.ogg": "cap",
"cape.ogg": "cape",
"car.ogg": "car",
"carafe.ogg": "",
"card.ogg": "card",
"carnival.ogg": "",
"carpenter.ogg": "",
"carpet.ogg": "",
"carrot.ogg": "carrot",
"cart.ogg": "cart",
"cash.ogg": "cash",
"castle.ogg": "castle",
"cat.ogg": "cat",
"cat_female.ogg": "",
"catch.ogg": "catch",
"caterpillar.ogg": "",
"cauldron.ogg": "",
"cauliflower.ogg": "",
"cave.ogg": "cave",
"cavern.ogg": "",
"celery.ogg": "",
"centipede.ogg": "centipede",
"cereal.ogg": "",
"chain.ogg": "",
"chair.ogg": "chair",
"chalk.ogg": "chalk",
"chameleon.ogg": "",
"chandelier.ogg": "",
"chat.ogg": "chat",
"cheek.ogg": "",
"cheer.ogg": "cheer",
"cheese.ogg": "cheese",
"chef.ogg": "",
"cherry.ogg": "cherry",
"chest.ogg": "chest",
"chick.ogg": "chick",
"chicken.ogg": "chicken",
- "chief.ogg": "chief",
"child.ogg": "child",
"chimney.ogg": "",
"chimp.ogg": "chimp",
"chin.ogg": "chin",
"chocolate.ogg": "chocolate",
"chop.ogg": "chop",
"chore.ogg": "",
"christmas.ogg": "",
"cigar.ogg": "",
"circus.ogg": "",
"city.ogg": "",
"clam.ogg": "clam",
"clap.ogg": "clap",
"class.ogg": "class",
"claw.ogg": "claw",
"clay.ogg": "clay",
"clean.ogg": "clean",
"cleaning_lady.ogg": "",
"cliff.ogg": "cliff",
"climb.ogg": "climb",
"clock.ogg": "clock",
"cloth.ogg": "cloth",
"clothes_hanger.ogg": "",
"cloud.ogg": "cloud",
"cloudy.ogg": "",
"clover.ogg": "",
"clown.ogg": "clown",
"coach.ogg": "coach",
"coast.ogg": "",
"coat.ogg": "coat",
"cobra.ogg": "",
"coconut.ogg": "",
"cod.ogg": "",
"coffee.ogg": "",
"coin.ogg": "coin",
"cold.ogg": "cold",
"color.ogg": "color",
"colt.ogg": "",
"comb.ogg": "comb",
"cone.ogg": "cone",
+ "cook.ogg": "",
"cookie.ogg": "cookie",
"cork.ogg": "",
"corn.ogg": "corn",
"couch.ogg": "couch",
"cough.ogg": "",
"couple.ogg": "",
"cow.ogg": "cow",
"cowboy.ogg": "cowboy",
"crab.ogg": "crab",
"cradle.ogg": "",
"craft.ogg": "",
"crawl.ogg": "crawl",
"crazy.ogg": "crazy",
"creek.ogg": "",
"crepe.ogg": "",
"crib.ogg": "crib",
- "criminal.ogg": "",
"croak.ogg": "croak",
"crocodile.ogg": "crocodile",
"cross.ogg": "",
"crow.ogg": "crow",
"crown.ogg": "crown",
"crumb.ogg": "crumb",
"crust.ogg": "crust",
"cry.ogg": "cry",
"crystal.ogg": "",
"cube.ogg": "cube",
"cucumber.ogg": "cucumber",
"curtain.ogg": "",
"cut.ogg": "cut",
"cute.ogg": "cute",
"dad.ogg": "dad",
"daffodil.ogg": "",
"daisy.ogg": "",
"dam.ogg": "",
"dance.ogg": "dance",
"dandelion.ogg": "",
- "danger.ogg": "danger",
"dark.ogg": "",
"dart_board.ogg": "",
"date_fruit.ogg": "",
"deer.ogg": "",
"den.ogg": "den",
"desert.ogg": "",
"desk.ogg": "desk",
"dessert.ogg": "",
"diamond.ogg": "",
"dig.ogg": "dig",
"dirt.ogg": "dirt",
"dirty.ogg": "dirty",
"dish.ogg": "dish",
"dishcloth.ogg": "",
"dive.ogg": "dive",
"doctor.ogg": "",
"doe.ogg": "",
"dog.ogg": "dog",
"doll.ogg": "",
"dolphin.ogg": "",
"domino.ogg": "",
"door.ogg": "door",
"doormat.ogg": "",
"dot.ogg": "dot",
"doughnut.ogg": "",
"dove.ogg": "",
"dragon.ogg": "dragon",
"dragonfly.ogg": "",
- "drank.ogg": "drank",
"draw.ogg": "draw",
"drawer.ogg": "",
"dream.ogg": "dream",
"dress.ogg": "dress",
"drink.ogg": "drink",
- "drinking.ogg": "",
"drip.ogg": "",
"drive.ogg": "drive",
"drool.ogg": "drool",
"drum.ogg": "drum",
"dry.ogg": "dry",
"duck.ogg": "duck",
"duck_mother.ogg": "",
"dune.ogg": "dune",
"dwarf.ogg": "",
"eagle.ogg": "",
"ear.ogg": "ear",
"earth.ogg": "earth",
"eat.ogg": "eat",
"egg.ogg": "",
"eggplant.ogg": "",
"elbow.ogg": "",
"electrician.ogg": "",
"elk.ogg": "",
"empty.ogg": "empty",
"engine.ogg": "",
"engineer.ogg": "",
"eraser.ogg": "",
"explore.ogg": "explore",
"eyelash.ogg": "",
"eyes.ogg": "",
"face.ogg": "face",
"fair.ogg": "fair",
"fairy.ogg": "",
- "fall_down.ogg": "",
+ "fall.ogg": "",
"fall_season.ogg": "",
"family.ogg": "",
"fan.ogg": "fan",
"farm.ogg": "farm",
"farmer.ogg": "",
"fat.ogg": "fat",
"faucet.ogg": "",
"fawn.ogg": "",
+ "fear.ogg": "fear",
"feast.ogg": "feast",
"feather.ogg": "",
"feed.ogg": "",
- "feet.ogg": "feet",
- "fell.ogg": "fell",
"femur.ogg": "",
"fetch.ogg": "fetch",
"fig.ogg": "",
"fin.ogg": "fin",
"find.ogg": "find",
"finger.ogg": "",
"fire.ogg": "fire",
"fire_extinguisher.ogg": "",
"fireman.ogg": "",
"fish.ogg": "fish",
"fisherman.ogg": "",
"fist.ogg": "fist",
"flacon.ogg": "",
"flag.ogg": "flag",
"flame.ogg": "flame",
"flamingo.ogg": "",
"flash.ogg": "flash",
"flat.ogg": "flat",
"flies.ogg": "flies",
- "flight.ogg": "",
"float.ogg": "float",
"flour.ogg": "flour",
"flower.ogg": "flower",
"fluff.ogg": "",
"flute.ogg": "flute",
"fly.ogg": "fly",
"foam.ogg": "",
- "food.ogg": "food",
"foot.ogg": "foot",
"forest.ogg": "",
"fork.ogg": "fork",
"fountain.ogg": "fountain",
"fox.ogg": "fox",
"freeze.ogg": "freeze",
"friend.ogg": "friend",
"fries.ogg": "",
"frog.ogg": "frog",
"front.ogg": "front",
- "frown.ogg": "frown",
"fruit.ogg": "fruit",
"fudge.ogg": "fudge",
"full.ogg": "full",
- "fun.ogg": "fun",
"fur.ogg": "fur",
"game.ogg": "game",
"garage.ogg": "",
"garden.ogg": "garden",
"garlic.ogg": "",
"gem.ogg": "gem",
"giant.ogg": "giant",
"gift.ogg": "gift",
"giraffe.ogg": "giraffe",
"girl.ogg": "girl",
"glass.ogg": "glass",
"glasses.ogg": "",
"glove.ogg": "glove",
"glue.ogg": "glue",
"gnome.ogg": "gnome",
"goat.ogg": "goat",
"golden.ogg": "",
"golf.ogg": "",
"goose.ogg": "",
"gorilla.ogg": "",
"grain.ogg": "",
"grandmother.ogg": "",
"grape.ogg": "",
"grapefruit.ogg": "",
"grass.ogg": "grass",
"grave.ogg": "grave",
"gray.ogg": "gray",
"green.ogg": "green",
"grill.ogg": "",
"grin.ogg": "grin",
"ground.ogg": "ground",
"growl.ogg": "growl",
"guignol.ogg": "",
"guinea_pig.ogg": "",
"gum.ogg": "gum",
"hair.ogg": "hair",
"hair_dryer.ogg": "",
"half.ogg": "",
"ham.ogg": "",
+ "hamburger.ogg": "",
"hammer.ogg": "",
"hand.ogg": "hand",
"handlebar.ogg": "",
"happy.ogg": "happy",
"harp.ogg": "",
"hat.ogg": "hat",
"hatch.ogg": "hatch",
"hay.ogg": "hay",
"head.ogg": "head",
"hear.ogg": "hear",
"heat.ogg": "heat",
"hedge.ogg": "hedge",
"hedgehog.ogg": "",
"heel.ogg": "",
"helmet.ogg": "",
"hen.ogg": "hen",
"herd.ogg": "herd",
"high.ogg": "high",
"hike.ogg": "hike",
"hill.ogg": "",
"hip.ogg": "hip",
"hippopotamus.ogg": "",
"hit.ogg": "hit",
"hive.ogg": "",
"hockey.ogg": "",
"hole.ogg": "hole",
"home.ogg": "home",
"hook.ogg": "hook",
"hop.ogg": "hop",
"horse.ogg": "",
"hose.ogg": "hose",
"hospital.ogg": "",
"hot.ogg": "hot",
"hot_dog.ogg": "",
"hound.ogg": "hound",
"house.ogg": "",
"howl.ogg": "howl",
"hug.ogg": "hug",
"huge.ogg": "huge",
"hummingbird.ogg": "",
- "hunchback.ogg": "",
+ "hunchbacked.ogg": "",
"hunter.ogg": "hunter",
"husband.ogg": "",
"hut.ogg": "hut",
"hyena.ogg": "",
"ice.ogg": "ice",
"iceberg.ogg": "",
"iguana.ogg": "",
"ill.ogg": "",
"ink.ogg": "ink",
"island.ogg": "",
"jacket.ogg": "",
"jaguar.ogg": "",
"jam.ogg": "",
"jay.ogg": "",
"jelly.ogg": "",
"jellyfish.ogg": "",
"jewel.ogg": "jewel",
"job.ogg": "",
"jockey.ogg": "",
"jog.ogg": "jog",
+ "joy.ogg": "",
"judge.ogg": "judge",
"judo.ogg": "",
"juggler.ogg": "",
"juice.ogg": "juice",
"jump.ogg": "jump",
"kangaroo.ogg": "",
"keel.ogg": "",
"kernel.ogg": "",
"keyboard.ogg": "",
"kimono.ogg": "",
"king.ogg": "",
"kiss.ogg": "",
"kitchen.ogg": "",
"kite.ogg": "kite",
"kitten.ogg": "",
"kiwi.ogg": "",
"knee.ogg": "knee",
"kneel.ogg": "kneel",
"knife.ogg": "knife",
"knight.ogg": "knight",
"knit.ogg": "knit",
"knot.ogg": "knot",
"koala.ogg": "",
"lad.ogg": "lad",
"lady.ogg": "",
"ladybug.ogg": "",
"lake.ogg": "lake",
"lama.ogg": "",
"lamb.ogg": "lamb",
"lamp.ogg": "lamp",
"land.ogg": "land",
"lane.ogg": "lane",
"lap.ogg": "lap",
"lasso.ogg": "",
"laugh.ogg": "",
"lava.ogg": "",
"lawn.ogg": "lawn",
"lawyer.ogg": "",
"leaf.ogg": "",
"ledge.ogg": "ledge",
"leek.ogg": "",
"left.ogg": "left",
"leg.ogg": "",
- "leg_animal.ogg": "",
"lemon.ogg": "",
"lemonade.ogg": "",
"lemur.ogg": "",
"leopard.ogg": "",
"lettuce.ogg": "",
"librarian.ogg": "",
"lick.ogg": "lick",
"lid.ogg": "lid",
"lift.ogg": "lift",
"light.ogg": "light",
"lighthouse.ogg": "",
"lightning.ogg": "",
"lilac.ogg": "",
"lime.ogg": "lime",
"line.ogg": "line",
"link.ogg": "link",
"lion.ogg": "",
"lion_cub.ogg": "",
"lip.ogg": "lip",
"liquid.ogg": "liquid",
"lizard.ogg": "",
"lobster.ogg": "",
"log.ogg": "log",
"look.ogg": "look",
"lunch.ogg": "lunch",
"mad.ogg": "mad",
"magic.ogg": "magic",
"magnet.ogg": "",
"magnifying_glass.ogg": "",
"magpie.ogg": "",
"mail.ogg": "",
"man.ogg": "",
"mane.ogg": "mane",
"mango.ogg": "",
"map.ogg": "map",
"maple.ogg": "",
"marble.ogg": "",
"mashed_potatoes.ogg": "",
"mask.ogg": "mask",
"mast.ogg": "",
"mat.ogg": "mat",
"match.ogg": "match",
"mate.ogg": "mate",
"mattress.ogg": "",
"mauve.ogg": "",
"meal.ogg": "",
"meat.ogg": "",
"mechanic.ogg": "",
"medal.ogg": "",
"meet.ogg": "meet",
"melon.ogg": "",
- "men.ogg": "men",
"merry-go-round.ogg": "",
"mice.ogg": "mice",
"microphone.ogg": "",
"milk.ogg": "",
"mill.ogg": "",
"mimosa.ogg": "",
"mirror.ogg": "",
"mixer.ogg": "",
"mole.ogg": "mole",
"mom.ogg": "",
"moon.ogg": "",
"moose.ogg": "",
"mop.ogg": "mop",
"mosque.ogg": "",
"mosquito.ogg": "mosquito",
"mother.ogg": "",
"motorcycle.ogg": "",
"mountain.ogg": "",
"mouse.ogg": "",
"mouth.ogg": "mouth",
"movie.ogg": "",
"mower.ogg": "",
"mud.ogg": "mud",
"mug.ogg": "mug",
"mule.ogg": "mule",
"muscle.ogg": "",
"mushroom.ogg": "mushroom",
"music.ogg": "",
"musician.ogg": "",
"naked.ogg": "",
"nap.ogg": "nap",
"navel.ogg": "",
"neck.ogg": "neck",
"necklace.ogg": "",
"needle.ogg": "",
"nest.ogg": "nest",
"net.ogg": "net",
"newspaper.ogg": "",
"night.ogg": "night",
"nightgown.ogg": "",
"nose.ogg": "nose",
"nostril.ogg": "",
"notebook.ogg": "",
"number.ogg": "",
"nun.ogg": "",
"nurse.ogg": "",
"nurse_male.ogg": "",
"nut.ogg": "nut",
"oar.ogg": "oar",
"ocean.ogg": "ocean",
"office.ogg": "",
"olive.ogg": "",
"on.ogg": "on",
"onion.ogg": "",
"open.ogg": "",
"opossum.ogg": "",
"orange-color.ogg": "orange",
"orange.ogg": "orange",
"orchid.ogg": "",
"ostrich.ogg": "",
"otter.ogg": "",
"owl.ogg": "owl",
"ox.ogg": "ox",
"oyster.ogg": "",
"pacifier.ogg": "",
"page.ogg": "page",
"pair.ogg": "pair",
"pajamas.ogg": "",
"pal.ogg": "pal",
"palm_tree.ogg": "",
"pan.ogg": "pan",
"panda.ogg": "",
"panther.ogg": "",
"panties.ogg": "",
"pants.ogg": "",
"papaya.ogg": "",
"paper.ogg": "",
"parachute.ogg": "",
"parakeet.ogg": "",
"parrot.ogg": "",
"patch.ogg": "patch",
"path.ogg": "path",
"paw.ogg": "paw",
"pea.ogg": "",
"peach.ogg": "peach",
"peacock.ogg": "",
"peak.ogg": "",
"pear.ogg": "",
"pearl.ogg": "",
"peck.ogg": "peck",
"pedal.ogg": "",
"pelican.ogg": "",
"pen.ogg": "pen",
"pencil.ogg": "pencil",
"peony.ogg": "",
"people.ogg": "",
"pepper.ogg": "",
"peppers.ogg": "",
"pet.ogg": "pet",
"petal.ogg": "",
- "petite.ogg": "",
"phone.ogg": "",
"piano.ogg": "",
"picture.ogg": "picture",
"pie.ogg": "",
"pig.ogg": "pig",
"pigeon.ogg": "",
"pill.ogg": "",
"pillow.ogg": "",
"pilot.ogg": "",
"pine.ogg": "pine",
"pine_cone.ogg": "",
"pink.ogg": "pink",
"pip.ogg": "",
"pipe.ogg": "",
"piranha.ogg": "",
"pirate.ogg": "",
"pizza.ogg": "",
"plane.ogg": "plane",
"planet.ogg": "",
"plant.ogg": "plant",
"plate.ogg": "plate",
"play.ogg": "play",
"pliers.ogg": "",
"plow.ogg": "plow",
"plum.ogg": "plum",
"plumber.ogg": "",
"pocket.ogg": "",
"pod.ogg": "",
"pole.ogg": "pole",
"police.ogg": "",
"pompon.ogg": "",
"pond.ogg": "",
"pony.ogg": "",
"pool.ogg": "pool",
- "pop.ogg": "pop",
+ "popcorn.ogg": "pop",
"pope.ogg": "pope",
"porthole.ogg": "",
"post.ogg": "",
"pot.ogg": "pot",
"potato.ogg": "",
"pounce.ogg": "pounce",
"president.ogg": "",
"pretty.ogg": "pretty",
"price.ogg": "price",
"priest.ogg": "",
"prince.ogg": "prince",
"princess.ogg": "princess",
"prison.ogg": "",
"prisoner.ogg": "",
"prize.ogg": "prize",
"pug.ogg": "pug",
"pull.ogg": "",
"pullover.ogg": "",
"pumpkin.ogg": "",
"puppy.ogg": "puppy",
"pyramid.ogg": "",
"quarrel.ogg": "quarrel",
"queen.ogg": "queen",
"question.ogg": "question",
"quilt.ogg": "quilt",
"quiz.ogg": "quiz",
"rabbit.ogg": "",
"rabbit_baby.ogg": "",
"race.ogg": "",
"radio.ogg": "",
"radish.ogg": "",
"raft.ogg": "",
"rag.ogg": "rag",
"rage.ogg": "rage",
"rain.ogg": "",
"raincoat.ogg": "",
"rake.ogg": "rake",
"ramp.ogg": "ramp",
"ran.ogg": "ran",
"raspberry.ogg": "",
"rat.ogg": "rat",
"razor.ogg": "",
"read.ogg": "read",
"red.ogg": "red",
"reptile.ogg": "",
"rhinoceros.ogg": "",
"rice.ogg": "rice",
"ride.ogg": "ride",
"rifle.ogg": "",
"right.ogg": "right",
"rip.ogg": "rip",
"rise.ogg": "",
"river.ogg": "",
"road.ogg": "",
"roast.ogg": "",
"robe.ogg": "",
"robot.ogg": "",
"rock.ogg": "rock",
"rocket.ogg": "",
"rolling_pin.ogg": "",
"roof.ogg": "roof",
"room.ogg": "",
"root.ogg": "",
"rope.ogg": "rope",
"rose.ogg": "rose",
"round.ogg": "round",
"rowing.ogg": "",
"royal.ogg": "royal",
"rug.ogg": "rug",
"run.ogg": "run",
"sad.ogg": "sad",
"saddle.ogg": "",
"sail.ogg": "sail",
"sailor.ogg": "",
"salamander.ogg": "",
"salmon.ogg": "",
"sand.ogg": "sand",
"sandals.ogg": "",
"sandwich.ogg": "sandwich",
"sash.ogg": "",
- "sat.ogg": "sat",
"sauce.ogg": "sauce",
"sausage.ogg": "",
"scale.ogg": "scale",
"scar.ogg": "scar",
- "scared.ogg": "scared",
+ "scare.ogg": "",
"scarf.ogg": "scarf",
"school.ogg": "school",
"school_bag.ogg": "",
"science.ogg": "science",
"scissors.ogg": "",
"scorpion.ogg": "",
"scratch.ogg": "scratch",
"scream.ogg": "scream",
"screw.ogg": "screw",
"screwdriver.ogg": "",
"scribble.ogg": "scribble",
"sea.ogg": "",
"seat.ogg": "seat",
"see.ogg": "see",
"seed.ogg": "seed",
"shadow.ogg": "",
"shake.ogg": "shake",
"shark.ogg": "shark",
"shave.ogg": "",
"shed.ogg": "shed",
"sheep.ogg": "",
"shelf.ogg": "shelf",
"shell.ogg": "shell",
"ship.ogg": "ship",
"shirt.ogg": "shirt",
"shoe.ogg": "shoe",
"shoelace.ogg": "",
"shop.ogg": "shop",
"shore.ogg": "shore",
"short.ogg": "short",
"shovel.ogg": "",
"shower.ogg": "shower",
"shrimp.ogg": "shrimp",
"shrub.ogg": "shrub",
"shut.ogg": "shut",
"shutter.ogg": "",
"sick.ogg": "sick",
"sidewalk.ogg": "",
"sign.ogg": "sign",
"sing.ogg": "sing",
"sink.ogg": "sink",
"sip.ogg": "sip",
"sister.ogg": "",
"sit.ogg": "sit",
"skate.ogg": "skate",
"skeleton.ogg": "",
"ski.ogg": "ski",
"skimmer.ogg": "",
"skin.ogg": "skin",
"skirt.ogg": "skirt",
"skunk.ogg": "skunk",
"sky.ogg": "sky",
"slam.ogg": "",
"sled.ogg": "sled",
"sleep.ogg": "sleep",
"sleeve.ogg": "sleeve",
"sleigh.ogg": "sleigh",
"slide.ogg": "slide",
"slim.ogg": "",
"slime.ogg": "slime",
"slippers.ogg": "",
"slope.ogg": "slope",
"sloppy.ogg": "",
"slot.ogg": "",
"sloth.ogg": "",
"slug.ogg": "",
"small.ogg": "small",
"smell.ogg": "smell",
"smile.ogg": "smile",
"smock.ogg": "smock",
"smoke.ogg": "smoke",
"smooch.ogg": "smooch",
"snack.ogg": "snack",
"snail.ogg": "snail",
"snake.ogg": "snake",
"sneaker.ogg": "sneaker",
"sniff.ogg": "sniff",
"snow.ogg": "snow",
"soap.ogg": "",
"sob.ogg": "",
"sock.ogg": "sock",
"soldier.ogg": "",
"sole.ogg": "",
"sole_shoe.ogg": "",
"son.ogg": "",
"soup.ogg": "",
"spade.ogg": "",
"spaghetti.ogg": "spaghetti",
"spark.ogg": "",
"sparrow.ogg": "",
"spatula.ogg": "",
"speak.ogg": "",
"spear.ogg": "spear",
"spice.ogg": "",
"spider.ogg": "spider",
"spider_web.ogg": "",
"spike.ogg": "spike",
"spill.ogg": "spill",
"spinach.ogg": "",
"spine.ogg": "",
"spinning_top.ogg": "",
"splash.ogg": "splash",
"splatter.ogg": "splatter",
"sponge.ogg": "sponge",
"spool.ogg": "",
"spoon.ogg": "spoon",
"sport.ogg": "sport",
"spot.ogg": "spot",
"spray.ogg": "spray",
"spread.ogg": "spread",
"spring.ogg": "spring",
"spring_season.ogg": "",
"sprinkle.ogg": "sprinkle",
"square.ogg": "square",
"squash.ogg": "squash",
"squat.ogg": "squat",
"squid.ogg": "squid",
"squirrel.ogg": "squirrel",
"squirt.ogg": "squirt",
"stack.ogg": "stack",
"stage.ogg": "stage",
"staircase.ogg": "",
"stamp.ogg": "stamp",
"stand.ogg": "stand",
"star.ogg": "star",
"stare.ogg": "stare",
"starfish.ogg": "starfish",
- "steak.ogg": "",
"steam.ogg": "",
"steep.ogg": "",
"steeple.ogg": "",
"stem.ogg": "stem",
"step.ogg": "",
"stew.ogg": "stew",
"stick.ogg": "stick",
"sting.ogg": "sting",
"stinky.ogg": "",
"stitch.ogg": "",
"stomach.ogg": "",
"stone.ogg": "stone",
"stop.ogg": "stop",
"store.ogg": "store",
"stove.ogg": "stove",
"straight.ogg": "straight",
"strainer.ogg": "",
"straw.ogg": "straw",
"strawberry.ogg": "strawberry",
"stream.ogg": "stream",
"street.ogg": "street",
"stretch.ogg": "stretch",
"string.ogg": "string",
"stripe.ogg": "stripe",
"strong.ogg": "strong",
"student.ogg": "",
"study.ogg": "study",
"stump.ogg": "stump",
"sugar.ogg": "",
"suit.ogg": "suit",
"suitcase.ogg": "",
"summer.ogg": "summer",
"summit.ogg": "",
"sun.ogg": "sun",
"swan.ogg": "swan",
"sweat.ogg": "sweat",
"sweatshirt.ogg": "",
"swim.ogg": "swim",
"table.ogg": "",
"tablecloth.ogg": "",
"tadpole.ogg": "",
"tag.ogg": "tag",
"tail.ogg": "",
"tall.ogg": "tall",
"tape_measure.ogg": "",
"taxi.ogg": "",
"teach.ogg": "teach",
"teacher.ogg": "teacher",
"tear.ogg": "tear",
"teddy.ogg": "",
"teeth.ogg": "teeth",
"television.ogg": "",
"temple.ogg": "",
"tennis.ogg": "",
"tent.ogg": "",
"text.ogg": "",
"thick.ogg": "thick",
"thief.ogg": "",
"thigh.ogg": "thigh",
"think.ogg": "think",
"thread.ogg": "thread",
"throat.ogg": "throat",
"throw.ogg": "throw",
"thumb.ogg": "",
"tick.ogg": "tick",
"ticket.ogg": "",
"tiger.ogg": "",
"time.ogg": "time",
"tin.ogg": "",
"tire.ogg": "",
"tired.ogg": "tired",
"tissue.ogg": "",
"toad.ogg": "",
"toaster.ogg": "",
+ "to_drink.ogg": "",
"toe.ogg": "",
"toilet.ogg": "toilet",
"tomatoe.ogg": "",
"tongs.ogg": "",
"tongue.ogg": "",
"tool.ogg": "tool",
"top.ogg": "top",
"torch.ogg": "torch",
"touch.ogg": "touch",
"towel.ogg": "towel",
"toy.ogg": "toy",
"trail.ogg": "trail",
"train.ogg": "train",
"train_station.ogg": "",
"trap.ogg": "trap",
"trash.ogg": "trash",
"tray.ogg": "tray",
"treat.ogg": "treat",
"tree.ogg": "tree",
"triangle.ogg": "",
"tribe.ogg": "",
"trip.ogg": "",
"truck.ogg": "truck",
"tube.ogg": "tube",
"tulip.ogg": "",
"tune.ogg": "tune",
"turkey.ogg": "",
"turnip.ogg": "",
"turtle.ogg": "",
"tusk.ogg": "",
"twin_boys.ogg": "",
"twin_girls.ogg": "",
"umbrella.ogg": "",
"under.ogg": "under",
"uniform.ogg": "",
"van.ogg": "van",
"vapor.ogg": "",
"vase.ogg": "",
"vegetable.ogg": "",
"vein.ogg": "",
"verdure.ogg": "",
"vest.ogg": "",
"vet.ogg": "vet",
"viper.ogg": "",
"vowel.ogg": "",
"vulture.ogg": "",
"wag.ogg": "wag",
"walk.ogg": "walk",
"wall.ogg": "",
"walnut.ogg": "",
"wart.ogg": "",
"wash.ogg": "wash",
"wasp.ogg": "",
"watch.ogg": "watch",
"water.ogg": "water",
"wave.ogg": "",
"wedding.ogg": "",
"wedge.ogg": "wedge",
"weight.ogg": "",
"wet.ogg": "wet",
"whale.ogg": "",
"wheat.ogg": "wheat",
"wheel.ogg": "wheel",
"whisk.ogg": "whisk",
"whisper.ogg": "whisper",
"white.ogg": "white",
"wide.ogg": "",
"wife.ogg": "",
"wig.ogg": "wig",
"win.ogg": "win",
"wind.ogg": "wind",
"window.ogg": "",
"window_glass.ogg": "",
"wing.ogg": "wing",
"winter.ogg": "",
"wolf.ogg": "",
"woman.ogg": "",
"wood.ogg": "wood",
"word.ogg": "",
"worker.ogg": "",
"world.ogg": "",
"wreath.ogg": "",
"wrench.ogg": "wrench",
"wrist.ogg": "wrist",
"write.ogg": "write",
"yarn.ogg": "yarn",
"yellow.ogg": "",
"yogurt.ogg": "",
"yum.ogg": "yum",
"zebra.ogg": "",
"zipper.ogg": "",
"zoo.ogg": "zoo"
}
diff --git a/src/activities/lang/resource/content-en_GB.json b/src/activities/lang/resource/content-en_GB.json
new file mode 100644
index 000000000..04cb6ac4d
--- /dev/null
+++ b/src/activities/lang/resource/content-en_GB.json
@@ -0,0 +1,1092 @@
+{
+ "10.ogg": "ten",
+ "11.ogg": "eleven",
+ "12.ogg": "twelve",
+ "16.ogg": "sixteen",
+ "U0030.ogg": "zero",
+ "U0031.ogg": "one",
+ "U0032.ogg": "two",
+ "U0033.ogg": "three",
+ "U0034.ogg": "four",
+ "U0035.ogg": "five",
+ "U0036.ogg": "six",
+ "U0037.ogg": "seven",
+ "U0038.ogg": "eight",
+ "U0039.ogg": "nine",
+ "accountant.ogg": "accountant",
+ "ache.ogg": "ache",
+ "acorn.ogg": "acorn",
+ "actor.ogg": "actor",
+ "air_horn.ogg": "air horn",
+ "alarmclock.ogg": "alarmclock",
+ "alligator.ogg": "alligator",
+ "alphabet.ogg": "alphabet",
+ "anchor.ogg": "anchor",
+ "angel.ogg": "angel",
+ "angry.ogg": "angry",
+ "animal.ogg": "animal",
+ "ankle.ogg": "ankle",
+ "ant.ogg": "ant",
+ "anteater.ogg": "anteater",
+ "antelope.ogg": "antelope",
+ "apple.ogg": "apple",
+ "apple_tree.ogg": "apple tree",
+ "appliance.ogg": "appliance",
+ "apricot.ogg": "apricot",
+ "arm.ogg": "arm",
+ "armchair.ogg": "armchair",
+ "artichoke.ogg": "artichoke",
+ "artist.ogg": "artist",
+ "asparagus.ogg": "asparagus",
+ "astronaut.ogg": "astronaut",
+ "athlete.ogg": "athlete",
+ "avocado.ogg": "avocado",
+ "ax.ogg": "ax",
+ "baby_bottle.ogg": "baby bottle",
+ "back.ogg": "back",
+ "badge.ogg": "badge",
+ "bag.ogg": "bag",
+ "bait.ogg": "bait",
+ "balance.ogg": "balance",
+ "bald.ogg": "bald",
+ "ball.ogg": "ball",
+ "ball_of_yarn.ogg": "ball of yarn",
+ "ball_soccer.ogg": "soccer ball",
+ "ballet.ogg": "ballet",
+ "bank.ogg": "bank",
+ "banker_female.ogg": "banker female",
+ "bark.ogg": "to bark",
+ "barn.ogg": "barn",
+ "bat.ogg": "bat",
+ "bath.ogg": "bath",
+ "bathing_suit.ogg": "bathing suit",
+ "bay.ogg": "bay",
+ "beach.ogg": "beach",
+ "bean.ogg": "bean",
+ "bear.ogg": "bear",
+ "beard.ogg": "beard",
+ "beat.ogg": "to beat",
+ "beaver.ogg": "beaver",
+ "bed.ogg": "bed",
+ "bedroom.ogg": "bedroom",
+ "bee.ogg": "bee",
+ "beetle.ogg": "beetle",
+ "beg.ogg": "to beg",
+ "behind.ogg": "behind",
+ "bell.ogg": "bell",
+ "belly.ogg": "belly",
+ "bench.ogg": "bench",
+ "bib.ogg": "bib",
+ "big.ogg": "big",
+ "big_top.ogg": "big top",
+ "bike.ogg": "bike",
+ "bird.ogg": "bird",
+ "bit.ogg": "bit",
+ "bite.ogg": "to bite",
+ "black.ogg": "black",
+ "blackberry.ogg": "blackberry",
+ "blackbird.ogg": "blackbird",
+ "blade.ogg": "blade",
+ "blind.ogg": "blind",
+ "blink.ogg": "to blink",
+ "block.ogg": "block",
+ "blond.ogg": "blond",
+ "blue.ogg": "blue",
+ "blueberry.ogg": "blueberry",
+ "blush.ogg": "blush",
+ "board.ogg": "board",
+ "boat.ogg": "boat",
+ "boil.ogg": "to boil",
+ "bolt.ogg": "bolt",
+ "bomb.ogg": "bomb",
+ "bone.ogg": "bone",
+ "book.ogg": "book",
+ "bookcase.ogg": "bookcase",
+ "bottom.ogg": "bottom",
+ "box.ogg": "box",
+ "boxer.ogg": "boxer",
+ "boy.ogg": "boy",
+ "braid.ogg": "braid",
+ "brain.ogg": "brain",
+ "branch.ogg": "branch",
+ "bread.ogg": "bread",
+ "break.ogg": "to break",
+ "breast.ogg": "breast",
+ "brick.ogg": "brick",
+ "bricklayer.ogg": "bricklayer",
+ "bride.ogg": "bride",
+ "bridge.ogg": "bridge",
+ "bright.ogg": "bright",
+ "broccoli.ogg": "broccoli",
+ "brother.ogg": "brother",
+ "brown.ogg": "brown",
+ "brush.ogg": "brush",
+ "bubble.ogg": "bubble",
+ "bucket.ogg": "bucket",
+ "bud.ogg": "bud",
+ "buffalo.ogg": "buffalo",
+ "bug.ogg": "bug",
+ "bulb.ogg": "bulb",
+ "bull.ogg": "bull",
+ "bump.ogg": "bump",
+ "bun.ogg": "bun",
+ "bus.ogg": "bus",
+ "bush.ogg": "bush",
+ "butcher.ogg": "butcher",
+ "butter.ogg": "butter",
+ "butterfly.ogg": "butterfly",
+ "button.ogg": "button",
+ "cabbage.ogg": "cabbage",
+ "cabin.ogg": "cabin",
+ "cacao.ogg": "cacao",
+ "cactus.ogg": "cactus",
+ "cage.ogg": "cage",
+ "cake.ogg": "cake",
+ "call.ogg": "to call",
+ "camel.ogg": "camel",
+ "camera.ogg": "camera",
+ "camp.ogg": "camp",
+ "can.ogg": "can",
+ "canary.ogg": "canary",
+ "candle.ogg": "candle",
+ "candy.ogg": "candy",
+ "cane.ogg": "cane",
+ "canoe.ogg": "canoe",
+ "canon.ogg": "canon",
+ "canyon.ogg": "canyon",
+ "cap.ogg": "cap",
+ "cape.ogg": "cape",
+ "car.ogg": "car",
+ "carafe.ogg": "carafe",
+ "card.ogg": "card",
+ "carnival.ogg": "carnival",
+ "carpenter.ogg": "carpenter",
+ "carpet.ogg": "carpet",
+ "carrot.ogg": "carrot",
+ "cart.ogg": "cart",
+ "cash.ogg": "cash",
+ "castle.ogg": "castle",
+ "cat.ogg": "cat",
+ "cat_female.ogg": "female cat",
+ "catch.ogg": "to catch",
+ "caterpillar.ogg": "caterpillar",
+ "cauldron.ogg": "cauldron",
+ "cauliflower.ogg": "cauliflower",
+ "cave.ogg": "cave",
+ "cavern.ogg": "cavern",
+ "celery.ogg": "celery",
+ "centipede.ogg": "centipede",
+ "cereal.ogg": "cereal",
+ "chain.ogg": "chain",
+ "chair.ogg": "chair",
+ "chalk.ogg": "chalk",
+ "chameleon.ogg": "chameleon",
+ "chandelier.ogg": "chandelier",
+ "chat.ogg": "to chat",
+ "cheek.ogg": "cheek",
+ "cheer.ogg": "cheer",
+ "cheese.ogg": "cheese",
+ "chef.ogg": "chef",
+ "cherry.ogg": "cherry",
+ "chest.ogg": "chest",
+ "chick.ogg": "chick",
+ "chicken.ogg": "chicken",
+ "child.ogg": "child",
+ "chimney.ogg": "chimney",
+ "chimp.ogg": "chimp",
+ "chin.ogg": "chin",
+ "chocolate.ogg": "chocolate",
+ "chop.ogg": "to chop",
+ "chores.ogg": "chores",
+ "christmas.ogg": "christmas",
+ "cigar.ogg": "cigar",
+ "circus.ogg": "circus",
+ "city.ogg": "city",
+ "clam.ogg": "clam",
+ "clap.ogg": "to clap",
+ "class.ogg": "class",
+ "claw.ogg": "claw",
+ "clay.ogg": "clay",
+ "clean.ogg": "to clean",
+ "cleaning_lady.ogg": "cleaning lady",
+ "cliff.ogg": "cliff",
+ "climb.ogg": "climb",
+ "clock.ogg": "clock",
+ "cloth.ogg": "cloth",
+ "clothes_hanger.ogg": "clothes hanger",
+ "cloud.ogg": "cloud",
+ "cloudy.ogg": "cloudy",
+ "clover.ogg": "clover",
+ "clown.ogg": "clown",
+ "coach.ogg": "coach",
+ "coast.ogg": "coast",
+ "coat.ogg": "coat",
+ "cobra.ogg": "cobra",
+ "coconut.ogg": "coconut",
+ "cod.ogg": "cod",
+ "coffee.ogg": "coffee",
+ "coin.ogg": "coin",
+ "cold.ogg": "cold",
+ "color.ogg": "colour",
+ "colt.ogg": "colt",
+ "comb.ogg": "comb",
+ "cone.ogg": "cone",
+ "cook.ogg": "to cook",
+ "cookie.ogg": "cookie",
+ "cork.ogg": "cork",
+ "corn.ogg": "corn",
+ "couch.ogg": "couch",
+ "cough.ogg": "to cough",
+ "couple.ogg": "couple",
+ "cow.ogg": "cow",
+ "cowboy.ogg": "cowboy",
+ "crab.ogg": "crab",
+ "cradle.ogg": "cradle",
+ "craft.ogg": "craft",
+ "crawl.ogg": "to crawl",
+ "crazy.ogg": "crazy",
+ "creek.ogg": "creek",
+ "crepe.ogg": "crepe",
+ "crib.ogg": "crib",
+ "croak.ogg": "to croak",
+ "crocodile.ogg": "crocodile",
+ "cross.ogg": "cross",
+ "crow.ogg": "crow",
+ "crown.ogg": "crown",
+ "crumb.ogg": "crumb",
+ "crust.ogg": "crust",
+ "cry.ogg": "to cry",
+ "crystal.ogg": "crystal",
+ "cube.ogg": "cube",
+ "cucumber.ogg": "cucumber",
+ "curtain.ogg": "curtain",
+ "cut.ogg": "to cut",
+ "cute.ogg": "cute",
+ "dad.ogg": "dad",
+ "daffodil.ogg": "daffodil",
+ "daisy.ogg": "daisy",
+ "dam.ogg": "dam",
+ "dance.ogg": "dance",
+ "dandelion.ogg": "dandelion",
+ "dart_board.ogg": "dart board",
+ "date_fruit.ogg": "date fruit",
+ "deer.ogg": "deer",
+ "den.ogg": "den",
+ "desert.ogg": "desert",
+ "desk.ogg": "desk",
+ "dessert.ogg": "dessert",
+ "diamond.ogg": "diamond",
+ "dig.ogg": "to dig",
+ "dirt.ogg": "dirt",
+ "dirty.ogg": "dirty",
+ "dish.ogg": "dish",
+ "dishcloth.ogg": "dishcloth",
+ "dive.ogg": "dive",
+ "doctor.ogg": "doctor",
+ "doe.ogg": "doe",
+ "dog.ogg": "dog",
+ "doll.ogg": "doll",
+ "dolphin.ogg": "dolphin",
+ "domino.ogg": "domino",
+ "door.ogg": "door",
+ "doormat.ogg": "doormat",
+ "dot.ogg": "dot",
+ "doughnut.ogg": "doughnut",
+ "dove.ogg": "dove",
+ "dragon.ogg": "dragon",
+ "dragonfly.ogg": "dragonfly",
+ "draw.ogg": "to draw",
+ "drawer.ogg": "drawer",
+ "dream.ogg": "to dream",
+ "dress.ogg": "dress",
+ "drink.ogg": "drink",
+ "drip.ogg": "drip",
+ "drive.ogg": "to drive",
+ "drool.ogg": "to drool",
+ "drum.ogg": "drum",
+ "dry.ogg": "to dry",
+ "duck.ogg": "duck",
+ "duck_mother.ogg": "duck mother",
+ "dune.ogg": "dune",
+ "dwarf.ogg": "dwarf",
+ "eagle.ogg": "eagle",
+ "ear.ogg": "ear",
+ "earth.ogg": "earth",
+ "eat.ogg": "to eat",
+ "egg.ogg": "egg",
+ "eggplant.ogg": "eggplant",
+ "elbow.ogg": "elbow",
+ "electrician.ogg": "electrician",
+ "elk.ogg": "elk",
+ "empty.ogg": "empty",
+ "engine.ogg": "engine",
+ "engineer.ogg": "engineer",
+ "eraser.ogg": "eraser",
+ "explore.ogg": "explore",
+ "eyelash.ogg": "eyelash",
+ "eyes.ogg": "eyes",
+ "face.ogg": "face",
+ "fair.ogg": "fair",
+ "fairy.ogg": "fairy",
+ "fall.ogg": "to fall",
+ "fall_season.ogg": "fall season",
+ "family.ogg": "family",
+ "fan.ogg": "fan",
+ "farm.ogg": "farm",
+ "farmer.ogg": "farmer",
+ "fat.ogg": "fat",
+ "faucet.ogg": "faucet",
+ "fawn.ogg": "fawn",
+ "fear.ogg": "fear",
+ "feast.ogg": "feast",
+ "feather.ogg": "feather",
+ "feed.ogg": "to feed",
+ "femur.ogg": "femur",
+ "fetch.ogg": "to fetch",
+ "fig.ogg": "fig",
+ "fin.ogg": "fin",
+ "find.ogg": "to find",
+ "finger.ogg": "finger",
+ "fire.ogg": "fire",
+ "fire_extinguisher.ogg": "fire extinguisher",
+ "fireman.ogg": "fireman",
+ "fish.ogg": "fish",
+ "fisherman.ogg": "fisherman",
+ "fist.ogg": "fist",
+ "flacon.ogg": "flacon",
+ "flag.ogg": "flag",
+ "flame.ogg": "flame",
+ "flamingo.ogg": "flamingo",
+ "flash.ogg": "flash",
+ "flat.ogg": "flat",
+ "flies.ogg": "flies",
+ "float.ogg": "to float",
+ "flour.ogg": "flour",
+ "flower.ogg": "flower",
+ "fluff.ogg": "fluff",
+ "flute.ogg": "flute",
+ "fly.ogg": "to fly",
+ "foam.ogg": "foam",
+ "foot.ogg": "foot",
+ "forest.ogg": "forest",
+ "fork.ogg": "fork",
+ "fountain.ogg": "fountain",
+ "fox.ogg": "fox",
+ "freeze.ogg": "to freeze",
+ "friend.ogg": "friend",
+ "fries.ogg": "fries",
+ "frog.ogg": "frog",
+ "front.ogg": "front",
+ "fruit.ogg": "fruit",
+ "fudge.ogg": "fudge",
+ "full.ogg": "full",
+ "fur.ogg": "fur",
+ "game.ogg": "game",
+ "garage.ogg": "garage",
+ "garden.ogg": "garden",
+ "garlic.ogg": "garlic",
+ "gem.ogg": "gem",
+ "giant.ogg": "giant",
+ "gift.ogg": "gift",
+ "giraffe.ogg": "giraffe",
+ "girl.ogg": "girl",
+ "glass.ogg": "glass",
+ "glasses.ogg": "glasses",
+ "glove.ogg": "glove",
+ "glue.ogg": "glue",
+ "gnome.ogg": "gnome",
+ "goat.ogg": "goat",
+ "golden.ogg": "golden",
+ "golf.ogg": "golf",
+ "goose.ogg": "goose",
+ "gorilla.ogg": "gorilla",
+ "grain.ogg": "grain",
+ "grandmother.ogg": "grandmother",
+ "grape.ogg": "grape",
+ "grapefruit.ogg": "grapefruit",
+ "grass.ogg": "grass",
+ "grave.ogg": "grave",
+ "gray.ogg": "gray",
+ "green.ogg": "green",
+ "grill.ogg": "grill",
+ "grin.ogg": "grin",
+ "ground.ogg": "ground",
+ "growl.ogg": "to growl",
+ "guignol.ogg": "guignol",
+ "guinea_pig.ogg": "guinea pig",
+ "gum.ogg": "gum",
+ "hair.ogg": "hair",
+ "hair_dryer.ogg": "hair-dryer",
+ "half.ogg": "half",
+ "ham.ogg": "ham",
+ "hamburger.ogg": "hamburger",
+ "hammer.ogg": "hammer",
+ "hand.ogg": "hand",
+ "handlebar.ogg": "handlebar",
+ "happy.ogg": "happy",
+ "harp.ogg": "harp",
+ "hat.ogg": "hat",
+ "hatch.ogg": "to hatch",
+ "hay.ogg": "hay",
+ "head.ogg": "head",
+ "hear.ogg": "to hear",
+ "heat.ogg": "heat",
+ "hedge.ogg": "hedge",
+ "hedgehog.ogg": "hedgehog",
+ "heel.ogg": "heel",
+ "helmet.ogg": "helmet",
+ "hen.ogg": "hen",
+ "herd.ogg": "herd",
+ "high.ogg": "high",
+ "hike.ogg": "hike",
+ "hill.ogg": "hill",
+ "hip.ogg": "hip",
+ "hippopotamus.ogg": "hippopotamus",
+ "hit.ogg": "hit",
+ "hive.ogg": "hive",
+ "hockey.ogg": "hockey",
+ "hole.ogg": "hole",
+ "home.ogg": "home",
+ "hook.ogg": "hook",
+ "hop.ogg": "hop",
+ "horse.ogg": "horse",
+ "hose.ogg": "hose",
+ "hospital.ogg": "hospital",
+ "hot.ogg": "hot",
+ "hot_dog.ogg": "hot dog",
+ "hound.ogg": "hound",
+ "house.ogg": "house",
+ "howl.ogg": "to howl",
+ "hug.ogg": "to hug",
+ "huge.ogg": "huge",
+ "hummingbird.ogg": "hummingbird",
+ "hunchbacked.ogg": "hunchbacked",
+ "hunter.ogg": "hunter",
+ "husband.ogg": "husband",
+ "hut.ogg": "hut",
+ "hyena.ogg": "hyena",
+ "ice.ogg": "ice",
+ "iceberg.ogg": "iceberg",
+ "iguana.ogg": "iguana",
+ "ill.ogg": "ill",
+ "ink.ogg": "ink",
+ "island.ogg": "island",
+ "jacket.ogg": "jacket",
+ "jaguar.ogg": "jaguar",
+ "jam.ogg": "jam",
+ "jay.ogg": "jay",
+ "jelly.ogg": "jelly",
+ "jellyfish.ogg": "jellyfish",
+ "jewel.ogg": "jewel",
+ "job.ogg": "job",
+ "jockey.ogg": "jockey",
+ "jog.ogg": "jog",
+ "joy.ogg": "joy",
+ "judge.ogg": "judge",
+ "judo.ogg": "judo",
+ "juggler.ogg": "juggler",
+ "juice.ogg": "juice",
+ "jump.ogg": "to jump",
+ "kangaroo.ogg": "kangaroo",
+ "keel.ogg": "keel",
+ "kernel.ogg": "kernel",
+ "keyboard.ogg": "keyboard",
+ "kimono.ogg": "kimono",
+ "king.ogg": "king",
+ "kiss.ogg": "to kiss",
+ "kitchen.ogg": "kitchen",
+ "kite.ogg": "kite",
+ "kitten.ogg": "kitten",
+ "kiwi.ogg": "kiwi",
+ "knee.ogg": "knee",
+ "kneel.ogg": "to kneel",
+ "knife.ogg": "knife",
+ "knight.ogg": "knight",
+ "knit.ogg": "to knit",
+ "knot.ogg": "knot",
+ "koala.ogg": "koala",
+ "lad.ogg": "lad",
+ "lady.ogg": "lady",
+ "ladybug.ogg": "ladybug",
+ "lake.ogg": "lake",
+ "lama.ogg": "lama",
+ "lamb.ogg": "lamb",
+ "lamp.ogg": "lamp",
+ "land.ogg": "land",
+ "lane.ogg": "lane",
+ "lap.ogg": "lap",
+ "lasso.ogg": "lasso",
+ "laugh.ogg": "to laugh",
+ "lava.ogg": "lava",
+ "lawn.ogg": "lawn",
+ "lawyer.ogg": "lawyer",
+ "leaf.ogg": "leaf",
+ "ledge.ogg": "ledge",
+ "leek.ogg": "leek",
+ "left.ogg": "left",
+ "leg.ogg": "leg",
+ "lemon.ogg": "lemon",
+ "lemonade.ogg": "lemonade",
+ "lemur.ogg": "lemur",
+ "leopard.ogg": "leopard",
+ "lettuce.ogg": "lettuce",
+ "librarian.ogg": "librarian",
+ "lick.ogg": "to lick",
+ "lid.ogg": "lid",
+ "lift.ogg": "lift",
+ "light.ogg": "light",
+ "lighthouse.ogg": "lighthouse",
+ "lightning.ogg": "lightning",
+ "lilac.ogg": "lilac",
+ "lime.ogg": "lime",
+ "line.ogg": "line",
+ "link.ogg": "link",
+ "lion.ogg": "lion",
+ "lion_cub.ogg": "lion cub",
+ "lip.ogg": "lip",
+ "liquid.ogg": "liquid",
+ "lizard.ogg": "lizard",
+ "lobster.ogg": "lobster",
+ "log.ogg": "log",
+ "look.ogg": "to look",
+ "lunch.ogg": "lunch",
+ "mad.ogg": "mad",
+ "magic.ogg": "magic",
+ "magnet.ogg": "magnet",
+ "magnifying_glass.ogg": "magnifying glass",
+ "magpie.ogg": "magpie",
+ "mail.ogg": "mail",
+ "man.ogg": "man",
+ "mane.ogg": "mane",
+ "mango.ogg": "mango",
+ "map.ogg": "map",
+ "maple.ogg": "maple",
+ "marble.ogg": "marble",
+ "mashed_potatoes.ogg": "mashed potatoes",
+ "mask.ogg": "mask",
+ "mast.ogg": "mast",
+ "mat.ogg": "mat",
+ "match.ogg": "match",
+ "mate.ogg": "mate",
+ "mattress.ogg": "mattress",
+ "mauve.ogg": "mauve",
+ "meal.ogg": "meal",
+ "meat.ogg": "meat",
+ "mechanic.ogg": "mechanic",
+ "medal.ogg": "medal",
+ "meet.ogg": "to meet",
+ "melon.ogg": "melon",
+ "merry-go-round.ogg": "merry-go-round",
+ "mice.ogg": "mice",
+ "microphone.ogg": "microphone",
+ "milk.ogg": "milk",
+ "mill.ogg": "mill",
+ "mimosa.ogg": "mimosa",
+ "mirror.ogg": "mirror",
+ "mixer.ogg": "mixer",
+ "mole.ogg": "mole",
+ "mom.ogg": "mom",
+ "moon.ogg": "moon",
+ "moose.ogg": "moose",
+ "mop.ogg": "mop",
+ "mosque.ogg": "mosque",
+ "mosquito.ogg": "mosquito",
+ "mother.ogg": "mother",
+ "motorcycle.ogg": "motorcycle",
+ "mountain.ogg": "mountain",
+ "mouse.ogg": "mouse",
+ "mouth.ogg": "mouth",
+ "movie.ogg": "movie",
+ "mower.ogg": "mower",
+ "mud.ogg": "mud",
+ "mug.ogg": "mug",
+ "mule.ogg": "mule",
+ "muscle.ogg": "muscle",
+ "mushroom.ogg": "mushroom",
+ "music.ogg": "music",
+ "musician.ogg": "musician",
+ "naked.ogg": "naked",
+ "nap.ogg": "to nap",
+ "navel.ogg": "navel",
+ "neck.ogg": "neck",
+ "necklace.ogg": "necklace",
+ "needle.ogg": "needle",
+ "nest.ogg": "nest",
+ "net.ogg": "net",
+ "newspaper.ogg": "newspaper",
+ "night.ogg": "night",
+ "nightgown.ogg": "nightgown",
+ "nose.ogg": "nose",
+ "nostril.ogg": "nostril",
+ "notebook.ogg": "notebook",
+ "number.ogg": "number",
+ "nun.ogg": "nun",
+ "nurse.ogg": "nurse",
+ "nurse_male.ogg": "nurse male",
+ "nut.ogg": "nut",
+ "oar.ogg": "oar",
+ "ocean.ogg": "ocean",
+ "office.ogg": "office",
+ "olive.ogg": "olive",
+ "on.ogg": "on",
+ "onion.ogg": "onion",
+ "open.ogg": "open",
+ "opossum.ogg": "opossum",
+ "orange-color.ogg": "orange colour",
+ "orange.ogg": "orange",
+ "orchid.ogg": "orchid",
+ "ostrich.ogg": "ostrich",
+ "otter.ogg": "otter",
+ "owl.ogg": "owl",
+ "ox.ogg": "ox",
+ "oyster.ogg": "oyster",
+ "pacifier.ogg": "pacifier",
+ "page.ogg": "page",
+ "pair.ogg": "pair",
+ "pajamas.ogg": "pajamas",
+ "pal.ogg": "pal",
+ "palm_tree.ogg": "palm tree",
+ "pan.ogg": "pan",
+ "panda.ogg": "panda",
+ "panther.ogg": "panther",
+ "panties.ogg": "panties",
+ "pants.ogg": "pants",
+ "papaya.ogg": "papaya",
+ "paper.ogg": "paper",
+ "parachute.ogg": "parachute",
+ "parakeet.ogg": "parakeet",
+ "parrot.ogg": "parrot",
+ "patch.ogg": "patch",
+ "path.ogg": "path",
+ "paw.ogg": "paw",
+ "pea.ogg": "pea",
+ "peach.ogg": "peach",
+ "peacock.ogg": "peacock",
+ "peak.ogg": "peak",
+ "pear.ogg": "pear",
+ "pearl.ogg": "pearl",
+ "peck.ogg": "to peck",
+ "pedal.ogg": "pedal",
+ "pelican.ogg": "pelican",
+ "pen.ogg": "pen",
+ "pencil.ogg": "pencil",
+ "peony.ogg": "peony",
+ "people.ogg": "people",
+ "pepper.ogg": "pepper",
+ "peppers.ogg": "peppers",
+ "pet.ogg": "pet",
+ "petal.ogg": "petal",
+ "phone.ogg": "phone",
+ "piano.ogg": "piano",
+ "picture.ogg": "picture",
+ "pie.ogg": "pie",
+ "pig.ogg": "pig",
+ "pigeon.ogg": "pigeon",
+ "pill.ogg": "pill",
+ "pillow.ogg": "pillow",
+ "pilot.ogg": "pilot",
+ "pine.ogg": "pine",
+ "pine_cone.ogg": "pine cone",
+ "pink.ogg": "pink",
+ "pip.ogg": "pip",
+ "pipe.ogg": "pipe",
+ "piranha.ogg": "piranha",
+ "pirate.ogg": "pirate",
+ "pizza.ogg": "pizza",
+ "plane.ogg": "plane",
+ "planet.ogg": "planet",
+ "plant.ogg": "plant",
+ "plate.ogg": "plate",
+ "play.ogg": "to play",
+ "pliers.ogg": "pliers",
+ "plow.ogg": "to plow",
+ "plum.ogg": "plum",
+ "plumber.ogg": "plumber",
+ "pocket.ogg": "pocket",
+ "pod.ogg": "pod",
+ "pole.ogg": "pole",
+ "police.ogg": "police",
+ "pompon.ogg": "pompon",
+ "pond.ogg": "pond",
+ "pony.ogg": "pony",
+ "pool.ogg": "pool",
+ "popcorn.ogg": "popcorn",
+ "pope.ogg": "pope",
+ "porthole.ogg": "porthole",
+ "post.ogg": "post",
+ "pot.ogg": "pot",
+ "potato.ogg": "potato",
+ "pounce.ogg": "to pounce",
+ "president.ogg": "president",
+ "pretty.ogg": "pretty",
+ "price.ogg": "price",
+ "priest.ogg": "priest",
+ "prince.ogg": "prince",
+ "princess.ogg": "princess",
+ "prison.ogg": "prison",
+ "prisoner.ogg": "prisoner",
+ "prize.ogg": "prize",
+ "pug.ogg": "pug",
+ "pull.ogg": "to pull",
+ "pullover.ogg": "pullover",
+ "pumpkin.ogg": "pumpkin",
+ "puppy.ogg": "puppy",
+ "pyramid.ogg": "pyramid",
+ "quarrel.ogg": "to quarrel",
+ "queen.ogg": "queen",
+ "question.ogg": "question",
+ "quilt.ogg": "quilt",
+ "quiz.ogg": "quiz",
+ "rabbit.ogg": "rabbit",
+ "rabbit_baby.ogg": "baby rabbit",
+ "race.ogg": "race",
+ "radio.ogg": "radio",
+ "radish.ogg": "radish",
+ "raft.ogg": "raft",
+ "rag.ogg": "rag",
+ "rage.ogg": "rage",
+ "rain.ogg": "rain",
+ "raincoat.ogg": "raincoat",
+ "rake.ogg": "rake",
+ "ramp.ogg": "ramp",
+ "ran.ogg": "ran",
+ "raspberry.ogg": "raspberry",
+ "rat.ogg": "rat",
+ "razor.ogg": "razor",
+ "read.ogg": "to read",
+ "red.ogg": "red",
+ "reptile.ogg": "reptile",
+ "rhinoceros.ogg": "rhinoceros",
+ "rice.ogg": "rice",
+ "ride.ogg": "ride",
+ "rifle.ogg": "rifle",
+ "right.ogg": "right",
+ "rip.ogg": "to rip",
+ "rise.ogg": "to rise",
+ "river.ogg": "river",
+ "road.ogg": "road",
+ "roast.ogg": "roast",
+ "robe.ogg": "robe",
+ "robot.ogg": "robot",
+ "rock.ogg": "rock",
+ "rocket.ogg": "rocket",
+ "rolling_pin.ogg": "rolling pin",
+ "roof.ogg": "roof",
+ "room.ogg": "room",
+ "root.ogg": "root",
+ "rope.ogg": "rope",
+ "rose.ogg": "rose",
+ "round.ogg": "round",
+ "rowing.ogg": "rowing",
+ "royal.ogg": "royal",
+ "rug.ogg": "rug",
+ "run.ogg": "to run",
+ "sad.ogg": "sad",
+ "saddle.ogg": "saddle",
+ "sail.ogg": "sail",
+ "sailor.ogg": "sailor",
+ "salamander.ogg": "salamander",
+ "salmon.ogg": "salmon",
+ "sand.ogg": "sand",
+ "sandals.ogg": "sandals",
+ "sandwich.ogg": "sandwich",
+ "sash.ogg": "sash",
+ "sauce.ogg": "sauce",
+ "sausage.ogg": "sausage",
+ "scale.ogg": "scale",
+ "scar.ogg": "scar",
+ "scare.ogg": "to scare",
+ "scarf.ogg": "scarf",
+ "school.ogg": "school",
+ "school_bag.ogg": "school bag",
+ "science.ogg": "science",
+ "scissors.ogg": "scissors",
+ "scorpion.ogg": "scorpion",
+ "scratch.ogg": "to scratch",
+ "scream.ogg": "to scream",
+ "screw.ogg": "screw",
+ "screwdriver.ogg": "screwdriver",
+ "scribble.ogg": "to scribble",
+ "sea.ogg": "sea",
+ "seat.ogg": "seat",
+ "see.ogg": "to see",
+ "seed.ogg": "seed",
+ "shadow.ogg": "shadow",
+ "shake.ogg": "to shake",
+ "shark.ogg": "shark",
+ "shave.ogg": "to shave",
+ "shed.ogg": "shed",
+ "sheep.ogg": "sheep",
+ "shelf.ogg": "shelf",
+ "shell.ogg": "shell",
+ "ship.ogg": "ship",
+ "shirt.ogg": "shirt",
+ "shoe.ogg": "shoe",
+ "shoelace.ogg": "shoelace",
+ "shop.ogg": "shop",
+ "shore.ogg": "shore",
+ "short.ogg": "short",
+ "shovel.ogg": "shovel",
+ "shower.ogg": "shower",
+ "shrimp.ogg": "shrimp",
+ "shrub.ogg": "shrub",
+ "shut.ogg": "shut",
+ "shutter.ogg": "shutter",
+ "sick.ogg": "sick",
+ "sidewalk.ogg": "sidewalk",
+ "sign.ogg": "sign",
+ "sing.ogg": "to sing",
+ "sink.ogg": "sink",
+ "sip.ogg": "to sip",
+ "sister.ogg": "sister",
+ "sit.ogg": "to sit",
+ "skate.ogg": "skate",
+ "skeleton.ogg": "skeleton",
+ "ski.ogg": "ski",
+ "skimmer.ogg": "skimmer",
+ "skin.ogg": "skin",
+ "skirt.ogg": "skirt",
+ "skunk.ogg": "skunk",
+ "sky.ogg": "sky",
+ "slam.ogg": "to slam",
+ "sled.ogg": "sled",
+ "sleep.ogg": "to sleep",
+ "sleeve.ogg": "sleeve",
+ "sleigh.ogg": "sleigh",
+ "slide.ogg": "slide",
+ "slim.ogg": "slim",
+ "slime.ogg": "slime",
+ "slippers.ogg": "slippers",
+ "slope.ogg": "slope",
+ "sloppy.ogg": "sloppy",
+ "slot.ogg": "slot",
+ "sloth.ogg": "sloth",
+ "slug.ogg": "slug",
+ "small.ogg": "small",
+ "smell.ogg": "to smell",
+ "smile.ogg": "smile",
+ "smock.ogg": "smock",
+ "smoke.ogg": "smoke",
+ "smooch.ogg": "to smooch",
+ "snack.ogg": "snack",
+ "snail.ogg": "snail",
+ "snake.ogg": "snake",
+ "sneaker.ogg": "sneaker",
+ "sniff.ogg": "to sniff",
+ "snow.ogg": "snow",
+ "soap.ogg": "soap",
+ "sob.ogg": "sob",
+ "sock.ogg": "sock",
+ "soldier.ogg": "soldier",
+ "sole.ogg": "sole",
+ "sole_shoe.ogg": "sole shoe",
+ "son.ogg": "son",
+ "soup.ogg": "soup",
+ "spade.ogg": "spade",
+ "spaghetti.ogg": "spaghetti",
+ "spark.ogg": "spark",
+ "sparrow.ogg": "sparrow",
+ "spatula.ogg": "spatula",
+ "speak.ogg": "to speak",
+ "spear.ogg": "spear",
+ "spice.ogg": "spice",
+ "spider.ogg": "spider",
+ "spider_web.ogg": "spider web",
+ "spike.ogg": "spike",
+ "spill.ogg": "to spill",
+ "spinach.ogg": "spinach",
+ "spine.ogg": "spine",
+ "spinning_top.ogg": "spinning top",
+ "splash.ogg": "to splash",
+ "splatter.ogg": "splatter",
+ "sponge.ogg": "sponge",
+ "spool.ogg": "spool",
+ "spoon.ogg": "spoon",
+ "sport.ogg": "sport",
+ "spot.ogg": "spot",
+ "spray.ogg": "to spray",
+ "spread.ogg": "to spread",
+ "spring.ogg": "to spring",
+ "spring_season.ogg": "spring season",
+ "sprinkle.ogg": "sprinkle",
+ "square.ogg": "square",
+ "squash.ogg": "squash",
+ "squat.ogg": "to squat",
+ "squid.ogg": "squid",
+ "squirrel.ogg": "squirrel",
+ "squirt.ogg": "squirt",
+ "stack.ogg": "stack",
+ "stage.ogg": "stage",
+ "staircase.ogg": "staircase",
+ "stamp.ogg": "stamp",
+ "stand.ogg": "stand",
+ "star.ogg": "star",
+ "stare.ogg": "to stare",
+ "starfish.ogg": "starfish",
+ "steam.ogg": "steam",
+ "steep.ogg": "steep",
+ "steeple.ogg": "steeple",
+ "stem.ogg": "stem",
+ "step.ogg": "step",
+ "stew.ogg": "stew",
+ "stick.ogg": "stick",
+ "sting.ogg": "to sting",
+ "stinky.ogg": "stinky",
+ "stitch.ogg": "to stitch",
+ "stomach.ogg": "stomach",
+ "stone.ogg": "stone",
+ "stop.ogg": "to stop",
+ "store.ogg": "store",
+ "stove.ogg": "stove",
+ "straight.ogg": "straight",
+ "strainer.ogg": "strainer",
+ "straw.ogg": "straw",
+ "strawberry.ogg": "strawberry",
+ "stream.ogg": "stream",
+ "street.ogg": "street",
+ "stretch.ogg": "to stretch",
+ "string.ogg": "string",
+ "stripe.ogg": "stripe",
+ "strong.ogg": "strong",
+ "student.ogg": "student",
+ "study.ogg": "to study",
+ "stump.ogg": "stump",
+ "sugar.ogg": "sugar",
+ "suit.ogg": "suit",
+ "suitcase.ogg": "suitcase",
+ "summer.ogg": "summer",
+ "summit.ogg": "summit",
+ "sun.ogg": "sun",
+ "swan.ogg": "swan",
+ "sweat.ogg": "sweat",
+ "sweatshirt.ogg": "sweatshirt",
+ "swim.ogg": "swim",
+ "table.ogg": "table",
+ "tablecloth.ogg": "tablecloth",
+ "tadpole.ogg": "tadpole",
+ "tag.ogg": "tag",
+ "tail.ogg": "tail",
+ "tall.ogg": "tall",
+ "tape_measure.ogg": "tape measure",
+ "taxi.ogg": "taxi",
+ "teach.ogg": "to teach",
+ "teacher.ogg": "teacher",
+ "tear.ogg": "to tear",
+ "teddy.ogg": "teddy",
+ "teeth.ogg": "teeth",
+ "television.ogg": "television",
+ "temple.ogg": "temple",
+ "tennis.ogg": "tennis",
+ "tent.ogg": "tent",
+ "text.ogg": "text",
+ "thick.ogg": "thick",
+ "thief.ogg": "thief",
+ "thigh.ogg": "thigh",
+ "think.ogg": "to think",
+ "thread.ogg": "thread",
+ "throat.ogg": "throat",
+ "throw.ogg": "throw",
+ "thumb.ogg": "thumb",
+ "tick.ogg": "tick",
+ "ticket.ogg": "ticket",
+ "tiger.ogg": "tiger",
+ "time.ogg": "time",
+ "tin.ogg": "tin",
+ "tire.ogg": "tire",
+ "tired.ogg": "tired",
+ "tissue.ogg": "tissue",
+ "to_drink.ogg": "to drink",
+ "toad.ogg": "toad",
+ "toaster.ogg": "toaster",
+ "toe.ogg": "toe",
+ "toilet.ogg": "toilet",
+ "tomatoe.ogg": "tomatoe",
+ "tongs.ogg": "tongs",
+ "tongue.ogg": "tongue",
+ "tool.ogg": "tool",
+ "top.ogg": "top",
+ "torch.ogg": "torch",
+ "touch.ogg": "to touch",
+ "towel.ogg": "towel",
+ "toy.ogg": "toy",
+ "trail.ogg": "trail",
+ "train.ogg": "train",
+ "train_station.ogg": "train station",
+ "trap.ogg": "trap",
+ "trash.ogg": "trash",
+ "tray.ogg": "tray",
+ "treat.ogg": "treat",
+ "tree.ogg": "tree",
+ "triangle.ogg": "triangle",
+ "tribe.ogg": "tribe",
+ "trip.ogg": "trip",
+ "truck.ogg": "truck",
+ "tube.ogg": "tube",
+ "tulip.ogg": "tulip",
+ "tune.ogg": "tune",
+ "turkey.ogg": "turkey",
+ "turnip.ogg": "turnip",
+ "turtle.ogg": "turtle",
+ "tusk.ogg": "tusk",
+ "twin_boys.ogg": "twin boys",
+ "twin_girls.ogg": "twin girls",
+ "umbrella.ogg": "umbrella",
+ "under.ogg": "under",
+ "uniform.ogg": "uniform",
+ "van.ogg": "van",
+ "vapor.ogg": "vapour",
+ "vase.ogg": "vase",
+ "vegetable.ogg": "vegetable",
+ "vein.ogg": "vein",
+ "verdure.ogg": "verdure",
+ "vest.ogg": "vest",
+ "vet.ogg": "vet",
+ "viper.ogg": "viper",
+ "vowel.ogg": "vowel",
+ "vulture.ogg": "vulture",
+ "wag.ogg": "to wag",
+ "walk.ogg": "to walk",
+ "wall.ogg": "wall",
+ "walnut.ogg": "walnut",
+ "wart.ogg": "wart",
+ "wash.ogg": "to wash",
+ "wasp.ogg": "wasp",
+ "watch.ogg": "watch",
+ "water.ogg": "water",
+ "wave.ogg": "wave",
+ "wedding.ogg": "wedding",
+ "wedge.ogg": "wedge",
+ "weight.ogg": "weight",
+ "wet.ogg": "wet",
+ "whale.ogg": "whale",
+ "wheat.ogg": "wheat",
+ "wheel.ogg": "wheel",
+ "whisk.ogg": "whisk",
+ "whisper.ogg": "to whisper",
+ "white.ogg": "white",
+ "wide.ogg": "wide",
+ "wife.ogg": "wife",
+ "wig.ogg": "wig",
+ "win.ogg": "to win",
+ "wind.ogg": "wind",
+ "window.ogg": "window",
+ "window_glass.ogg": "window glass",
+ "wing.ogg": "wing",
+ "winter.ogg": "winter",
+ "wolf.ogg": "wolf",
+ "woman.ogg": "woman",
+ "wood.ogg": "wood",
+ "word.ogg": "word",
+ "worker.ogg": "worker",
+ "world.ogg": "world",
+ "wreath.ogg": "wreath",
+ "wrench.ogg": "wrench",
+ "wrist.ogg": "wrist",
+ "write.ogg": "to write",
+ "yellow.ogg": "yellow",
+ "yogurt.ogg": "yogurt",
+ "yum.ogg": "yum",
+ "zebra.ogg": "zebra",
+ "zipper.ogg": "zipper",
+ "zoo.ogg": "zoo"
+}
\ No newline at end of file
diff --git a/src/activities/lang/resource/content-es.json b/src/activities/lang/resource/content-es.json
index c127c2002..4359cb0ca 100644
--- a/src/activities/lang/resource/content-es.json
+++ b/src/activities/lang/resource/content-es.json
@@ -1,1243 +1,1092 @@
{
"10.ogg": "diez",
"11.ogg": "once",
"12.ogg": "doce",
"16.ogg": "dieciséis",
"U0030.ogg": "cero",
"U0031.ogg": "uno",
"U0032.ogg": "dos",
"U0033.ogg": "tres",
"U0034.ogg": "cuatro",
"U0035.ogg": "cinco",
"U0036.ogg": "seis",
"U0037.ogg": "siete",
"U0038.ogg": "ocho",
"U0039.ogg": "nueve",
- "accountant.ogg": "",
- "ache.ogg": "",
+ "accountant.ogg": "contable",
+ "ache.ogg": "dolor",
"acorn.ogg": "bellota",
"actor.ogg": "actor",
- "add.ogg": "anadir",
- "admire.ogg": "admirar",
- "age.ogg": "edad",
- "air.ogg": "aire",
- "air_horn.ogg": "",
- "alarmclock.ogg": "",
+ "air_horn.ogg": "bocina",
+ "alarmclock.ogg": "despertador",
"alligator.ogg": "caimán",
- "alone.ogg": "solo",
"alphabet.ogg": "alfabeto",
- "always.ogg": "siempre",
"anchor.ogg": "ancla",
- "angel.ogg": "angel",
- "angry.ogg": "",
+ "angel.ogg": "ángel",
+ "angry.ogg": "enfadado",
"animal.ogg": "animal",
"ankle.ogg": "tobillo",
- "answer.ogg": "responder",
"ant.ogg": "hormiga",
- "anteater.ogg": "",
- "antelope.ogg": "antilope",
+ "anteater.ogg": "oso hormiguero",
+ "antelope.ogg": "antílope",
"apple.ogg": "manzana",
- "apple_tree.ogg": "",
- "appliance.ogg": "",
+ "apple_tree.ogg": "manzano",
+ "appliance.ogg": "aparato",
"apricot.ogg": "albaricoque",
- "april.ogg": "abril",
"arm.ogg": "brazo",
"armchair.ogg": "sillón",
"artichoke.ogg": "alcachofa",
"artist.ogg": "artista",
- "ask.ogg": "pedir",
"asparagus.ogg": "espárragos",
"astronaut.ogg": "astronauta",
- "ate.ogg": "",
"athlete.ogg": "atleta",
- "august.ogg": "agosto",
"avocado.ogg": "aguacate",
- "ax.ogg": "",
- "baby.ogg": "bebe",
- "baby_bottle.ogg": "",
+ "ax.ogg": "hacha",
+ "baby_bottle.ogg": "biberón",
"back.ogg": "espalda",
- "bad.ogg": "malo",
- "badge.ogg": "",
+ "badge.ogg": "insignia",
"bag.ogg": "bolsa",
- "bait.ogg": "",
- "bake.ogg": "",
- "balance.ogg": "",
+ "bait.ogg": "cebo",
+ "balance.ogg": "balanza",
"bald.ogg": "calvo",
- "ball.ogg": "",
- "ball_of_yarn.ogg": "",
- "ball_soccer.ogg": "",
+ "ball.ogg": "bola",
+ "ball_of_yarn.ogg": "ovillo de lana",
+ "ball_soccer.ogg": "balón de fútbol",
"ballet.ogg": "ballet",
"bank.ogg": "banco",
+ "banker_female.ogg": "banquera",
"bark.ogg": "ladrido",
"barn.ogg": "granero",
- "basket.ogg": "canasta",
- "bat.ogg": "",
+ "bat.ogg": "murciélago",
"bath.ogg": "baño",
- "bathing_suit.ogg": "",
- "bay.ogg": "",
- "be.ogg": "ser",
+ "bathing_suit.ogg": "bañador",
+ "bay.ogg": "bahía",
"beach.ogg": "playa",
- "bead.ogg": "",
"bean.ogg": "frejol",
- "bear.ogg": "",
+ "bear.ogg": "oso",
"beard.ogg": "barba",
"beat.ogg": "batir",
- "beaver.ogg": "",
+ "beaver.ogg": "castor",
"bed.ogg": "cama",
"bedroom.ogg": "dormitorio",
"bee.ogg": "abeja",
- "beef.ogg": "carne de res",
- "beetle.ogg": "",
- "beg.ogg": "",
- "behind.ogg": "",
+ "beetle.ogg": "escarabajo",
+ "beg.ogg": "pedir",
+ "behind.ogg": "detrás",
"bell.ogg": "campana",
"belly.ogg": "vientre",
- "bench.ogg": "",
- "bet.ogg": "apostar",
+ "bench.ogg": "banco",
"bib.ogg": "babero",
"big.ogg": "grande",
- "big_top.ogg": "",
+ "big_top.ogg": "carpa de circo",
"bike.ogg": "bicicleta",
"bird.ogg": "pájaro",
- "birth.ogg": "nacimiento",
- "bit.ogg": "",
- "bite.ogg": "",
+ "bit.ogg": "poco",
+ "bite.ogg": "morder",
"black.ogg": "negro",
- "blackberry.ogg": "",
- "blackbird.ogg": "",
- "blade.ogg": "",
+ "blackberry.ogg": "mora",
+ "blackbird.ogg": "mirlo",
+ "blade.ogg": "corte",
"blind.ogg": "ciego",
- "blink.ogg": "",
- "block.ogg": "",
+ "blink.ogg": "guiño",
+ "block.ogg": "bloque",
"blond.ogg": "rubio",
"blue.ogg": "azul",
- "blueberry.ogg": "",
- "blush.ogg": "",
- "board.ogg": "",
- "boat.ogg": "barco",
+ "blueberry.ogg": "arándano",
+ "blush.ogg": "rubor",
+ "board.ogg": "tablón",
+ "boat.ogg": "bote",
"boil.ogg": "hervir",
- "bolt.ogg": "",
+ "bolt.ogg": "tuerca",
"bomb.ogg": "bomba",
"bone.ogg": "hueso",
"book.ogg": "libro",
- "bookcase.ogg": "",
- "bottom.ogg": "",
- "bowl.ogg": "cuenco",
+ "bookcase.ogg": "librería",
+ "bottom.ogg": "nalgas",
"box.ogg": "caja",
- "boxer.ogg": "",
+ "boxer.ogg": "boxeador",
"boy.ogg": "niño",
- "braid.ogg": "",
+ "braid.ogg": "trenza",
"brain.ogg": "cerebro",
"branch.ogg": "rama",
"bread.ogg": "pan",
"break.ogg": "romper",
- "breast.ogg": "",
- "brick.ogg": "",
- "bricklayer.ogg": "",
- "bride.ogg": "",
+ "breast.ogg": "pecho",
+ "brick.ogg": "ladrillo",
+ "bricklayer.ogg": "albañil",
+ "bride.ogg": "novia",
"bridge.ogg": "puente",
"bright.ogg": "brillante",
- "bring.ogg": "llevar",
"broccoli.ogg": "brócoli",
- "brother.ogg": "",
+ "brother.ogg": "hermano",
"brown.ogg": "marrón",
- "brush.ogg": "",
+ "brush.ogg": "brocha",
"bubble.ogg": "burbuja",
"bucket.ogg": "cubo",
- "bud.ogg": "",
- "buffalo.ogg": "",
+ "bud.ogg": "brote",
+ "buffalo.ogg": "búfalo",
"bug.ogg": "escarabajo",
- "build.ogg": "construir",
- "bulb.ogg": "",
- "bull.ogg": "",
- "bump.ogg": "",
- "bun.ogg": "",
+ "bulb.ogg": "bombilla",
+ "bull.ogg": "toro",
+ "bump.ogg": "bulto",
+ "bun.ogg": "brioche",
"bus.ogg": "autobús",
- "bush.ogg": "",
+ "bush.ogg": "arbusto",
"butcher.ogg": "carnicero",
"butter.ogg": "mantequilla",
"butterfly.ogg": "mariposa",
"button.ogg": "botón",
- "buy.ogg": "comprar",
- "cab.ogg": "cabina",
"cabbage.ogg": "repollo",
- "cabin.ogg": "",
- "cacao.ogg": "",
+ "cabin.ogg": "cabaña",
+ "cacao.ogg": "cacao",
"cactus.ogg": "cactus",
"cage.ogg": "jaula",
"cake.ogg": "pastel",
"call.ogg": "llamar",
"camel.ogg": "camello",
"camera.ogg": "cámara",
"camp.ogg": "campamento",
- "can.ogg": "",
- "canary.ogg": "",
+ "can.ogg": "lata",
+ "canary.ogg": "canario",
"candle.ogg": "vela",
"candy.ogg": "caramelo",
"cane.ogg": "bastón",
"canoe.ogg": "canoa",
- "canon.ogg": "",
- "canyon.ogg": "",
- "cap.ogg": "",
+ "canon.ogg": "cañón",
+ "canyon.ogg": "cañón",
+ "cap.ogg": "gorra",
"cape.ogg": "capa",
"car.ogg": "coche",
- "carafe.ogg": "",
- "card.ogg": "",
- "carnival.ogg": "",
- "carpenter.ogg": "",
+ "carafe.ogg": "jarra",
+ "card.ogg": "tarjeta",
+ "carnival.ogg": "carnaval",
+ "carpenter.ogg": "carpintero",
"carpet.ogg": "alfombra",
"carrot.ogg": "zanahoria",
- "cart.ogg": "",
- "cash.ogg": "",
+ "cart.ogg": "carro",
+ "cash.ogg": "dinero",
"castle.ogg": "castillo",
"cat.ogg": "gato",
- "cat_female.ogg": "",
- "catch.ogg": "",
+ "cat_female.ogg": "gata",
+ "catch.ogg": "pescar",
"caterpillar.ogg": "oruga",
- "cauldron.ogg": "",
+ "cauldron.ogg": "caldera",
"cauliflower.ogg": "coliflor",
"cave.ogg": "cueva",
- "cavern.ogg": "",
- "celery.ogg": "",
- "centipede.ogg": "",
+ "cavern.ogg": "caverna",
+ "celery.ogg": "apio",
+ "centipede.ogg": "cienpiés",
"cereal.ogg": "cereal",
"chain.ogg": "cadena",
"chair.ogg": "silla",
"chalk.ogg": "tiza",
- "chameleon.ogg": "",
- "chandelier.ogg": "",
+ "chameleon.ogg": "camaleón",
+ "chandelier.ogg": "araña",
"chat.ogg": "charlar",
- "cheek.ogg": "",
- "cheer.ogg": "",
+ "cheek.ogg": "mejilla",
+ "cheer.ogg": "animar",
"cheese.ogg": "queso",
- "chef.ogg": "",
+ "chef.ogg": "cocinero",
"cherry.ogg": "cereza",
- "chest.ogg": "",
+ "chest.ogg": "baúl",
"chick.ogg": "pollito",
"chicken.ogg": "pollo",
- "chief.ogg": "",
- "child.ogg": "",
+ "child.ogg": "niño",
"chimney.ogg": "chimenea",
- "chimp.ogg": "",
+ "chimp.ogg": "chimpancé",
"chin.ogg": "mentón",
"chocolate.ogg": "chocolate",
- "chop.ogg": "",
- "chore.ogg": "",
+ "chop.ogg": "cortar",
+ "chores.ogg": "quehaceres",
"christmas.ogg": "Navidad",
- "church.ogg": "iglesia",
"cigar.ogg": "cigarro",
- "circle.ogg": "círculo",
"circus.ogg": "circo",
"city.ogg": "ciudad",
- "clam.ogg": "",
- "clap.ogg": "",
+ "clam.ogg": "almeja",
+ "clap.ogg": "palmear",
"class.ogg": "clase",
"claw.ogg": "garra",
- "clay.ogg": "",
+ "clay.ogg": "arcilla",
"clean.ogg": "limpiar",
- "cleaning_lady.ogg": "",
- "cliff.ogg": "",
- "climb.ogg": "",
+ "cleaning_lady.ogg": "señora de la limpieza",
+ "cliff.ogg": "acantilado",
+ "climb.ogg": "escalada",
"clock.ogg": "reloj",
- "close.ogg": "cerrar",
"cloth.ogg": "ropa",
- "clothes_hanger.ogg": "",
+ "clothes_hanger.ogg": "colgador",
"cloud.ogg": "nube",
- "cloudy.ogg": "",
- "clover.ogg": "",
+ "cloudy.ogg": "nublado",
+ "clover.ogg": "trébol",
"clown.ogg": "payaso",
- "coach.ogg": "",
+ "coach.ogg": "entrenador",
"coast.ogg": "costa",
"coat.ogg": "abrigo",
"cobra.ogg": "cobra",
- "coconut.ogg": "",
- "cod.ogg": "",
- "coffee.ogg": "cafe",
+ "coconut.ogg": "coco",
+ "cod.ogg": "bacalao",
+ "coffee.ogg": "café",
"coin.ogg": "moneda",
"cold.ogg": "frio",
"color.ogg": "color",
- "colt.ogg": "",
+ "colt.ogg": "potro",
"comb.ogg": "peine",
"cone.ogg": "cono",
+ "cook.ogg": "cocinar",
"cookie.ogg": "galleta",
- "cork.ogg": "",
+ "cork.ogg": "corcho",
"corn.ogg": "maíz",
- "couch.ogg": "",
- "cough.ogg": "",
+ "couch.ogg": "sofá",
+ "cough.ogg": "toser",
"couple.ogg": "pareja",
"cow.ogg": "vaca",
- "cowboy.ogg": "",
+ "cowboy.ogg": "vaquero",
"crab.ogg": "cangrejo",
- "cradle.ogg": "",
- "craft.ogg": "",
- "crawl.ogg": "",
+ "cradle.ogg": "cuna",
+ "craft.ogg": "manualidad",
+ "crawl.ogg": "gatear",
"crazy.ogg": "loco",
- "cream.ogg": "crema",
- "creek.ogg": "",
- "crepe.ogg": "",
- "crib.ogg": "",
- "criminal.ogg": "",
- "croak.ogg": "",
+ "creek.ogg": "arroyo",
+ "crepe.ogg": "crep",
+ "crib.ogg": "cuna",
+ "croak.ogg": "croar",
"crocodile.ogg": "cocodrilo",
- "cross.ogg": "",
- "crow.ogg": "",
- "crown.ogg": "",
- "crumb.ogg": "",
- "crust.ogg": "",
+ "cross.ogg": "cruz",
+ "crow.ogg": "cuervo",
+ "crown.ogg": "corona",
+ "crumb.ogg": "migajas",
+ "crust.ogg": "corteza",
"cry.ogg": "llorar",
- "crystal.ogg": "",
- "cube.ogg": "",
+ "crystal.ogg": "cristal",
+ "cube.ogg": "cubo",
"cucumber.ogg": "pepino",
"curtain.ogg": "cortina",
"cut.ogg": "cortar",
- "cute.ogg": "",
+ "cute.ogg": "linda",
"dad.ogg": "papá",
- "daffodil.ogg": "",
+ "daffodil.ogg": "narciso",
"daisy.ogg": "margarita",
- "dam.ogg": "",
+ "dam.ogg": "presa",
"dance.ogg": "bailar",
- "dandelion.ogg": "",
- "danger.ogg": "peligro",
- "dark.ogg": "",
- "dart_board.ogg": "",
- "date_fruit.ogg": "",
- "day.ogg": "dia",
- "dead.ogg": "muerto",
- "december.ogg": "Diciembre",
+ "dandelion.ogg": "diente de león",
+ "dart_board.ogg": "tablero de dardos",
+ "date_fruit.ogg": "dátil",
"deer.ogg": "ciervo",
- "den.ogg": "",
+ "den.ogg": "guarida",
"desert.ogg": "desierto",
"desk.ogg": "escritorio",
"dessert.ogg": "postre",
"diamond.ogg": "diamante",
- "die.ogg": "morir",
"dig.ogg": "cavar",
- "dirt.ogg": "",
+ "dirt.ogg": "tierra",
"dirty.ogg": "sucio",
- "dish.ogg": "",
- "dishcloth.ogg": "",
+ "dish.ogg": "fuente",
+ "dishcloth.ogg": "paño de cocina",
"dive.ogg": "inmersión",
- "do.ogg": "hacer",
"doctor.ogg": "médico",
- "doe.ogg": "",
+ "doe.ogg": "ciervo",
"dog.ogg": "perro",
"doll.ogg": "muñeca",
- "dolphin.ogg": "",
- "domino.ogg": "",
- "donkey.ogg": "burro",
+ "dolphin.ogg": "delfín",
+ "domino.ogg": "dominó",
"door.ogg": "puerta",
- "doormat.ogg": "",
+ "doormat.ogg": "estera",
"dot.ogg": "punto",
- "doughnut.ogg": "",
- "dove.ogg": "",
+ "doughnut.ogg": "rosquilla",
+ "dove.ogg": "paloma",
"dragon.ogg": "dragón",
- "dragonfly.ogg": "",
- "drank.ogg": "",
+ "dragonfly.ogg": "libélula",
"draw.ogg": "dibujar",
- "drawer.ogg": "",
+ "drawer.ogg": "cajón",
"dream.ogg": "sueño",
"dress.ogg": "vestir",
"drink.ogg": "beber",
- "drinking.ogg": "",
- "drip.ogg": "",
+ "drip.ogg": "gota",
"drive.ogg": "conducir",
- "drool.ogg": "",
+ "drool.ogg": "babear",
"drum.ogg": "tambor",
"dry.ogg": "secar",
"duck.ogg": "pato",
- "duck_mother.ogg": "",
+ "duck_mother.ogg": "pata",
"dune.ogg": "duna",
"dwarf.ogg": "enano",
"eagle.ogg": "águila",
- "ear.ogg": "",
+ "ear.ogg": "oreja",
"earth.ogg": "tierra",
"eat.ogg": "comer",
"egg.ogg": "huevo",
- "eggplant.ogg": "",
+ "eggplant.ogg": "berenjena",
"elbow.ogg": "codo",
"electrician.ogg": "electricista",
- "elephant.ogg": "elefante",
- "elk.ogg": "",
+ "elk.ogg": "alce",
"empty.ogg": "vacío",
"engine.ogg": "motor",
"engineer.ogg": "ingeniero",
- "english.ogg": "Ingles",
"eraser.ogg": "borrador",
- "explore.ogg": "",
- "eyebrow.ogg": "ceja",
- "eyelash.ogg": "de pestañas",
+ "explore.ogg": "explorar",
+ "eyelash.ogg": "pestaña",
"eyes.ogg": "ojos",
"face.ogg": "cara",
- "fair.ogg": "",
+ "fair.ogg": "atracción",
"fairy.ogg": "hada",
"fall.ogg": "caer",
- "fall_down.ogg": "",
- "fall_season.ogg": "",
+ "fall_season.ogg": "otoño",
"family.ogg": "familia",
"fan.ogg": "ventilador",
- "far.ogg": "lejos",
"farm.ogg": "granja",
"farmer.ogg": "agricultor",
"fat.ogg": "grasa",
- "faucet.ogg": "",
- "fawn.ogg": "",
- "feast.ogg": "",
+ "faucet.ogg": "grifo",
+ "fawn.ogg": "cervatillo",
+ "fear.ogg": "miedo",
+ "feast.ogg": "banquete",
"feather.ogg": "pluma",
- "february.ogg": "Febrero",
- "feed.ogg": "",
- "feet.ogg": "pies",
- "fell.ogg": "",
- "female.ogg": "femenino",
- "femur.ogg": "",
- "fetch.ogg": "",
- "fig.ogg": "",
- "fill.ogg": "llenar",
+ "feed.ogg": "dar de comer",
+ "femur.ogg": "fémur",
+ "fetch.ogg": "traer",
+ "fig.ogg": "higo",
"fin.ogg": "aleta",
"find.ogg": "encontrar",
"finger.ogg": "dedo",
"fire.ogg": "fuego",
- "fire_extinguisher.ogg": "",
+ "fire_extinguisher.ogg": "extintor",
"fireman.ogg": "bombero",
- "first.ogg": "primero",
- "fish.ogg": "",
+ "fish.ogg": "pescado",
"fisherman.ogg": "pescador",
"fist.ogg": "puño",
- "flacon.ogg": "",
+ "flacon.ogg": "dosificador",
"flag.ogg": "bandera",
"flame.ogg": "llama",
- "flamingo.ogg": "",
- "flash.ogg": "",
- "flat.ogg": "",
- "flies.ogg": "",
- "flight.ogg": "",
- "float.ogg": "",
+ "flamingo.ogg": "flamenco",
+ "flash.ogg": "linterna",
+ "flat.ogg": "piso",
+ "flies.ogg": "mosca",
+ "float.ogg": "flotar",
"flour.ogg": "harina",
"flower.ogg": "flor",
- "fluff.ogg": "",
+ "fluff.ogg": "pelusa",
"flute.ogg": "flauta",
"fly.ogg": "volar",
- "foam.ogg": "",
- "food.ogg": "alimento",
+ "foam.ogg": "espuma",
"foot.ogg": "pie",
"forest.ogg": "bosque",
"fork.ogg": "tenedor",
- "fountain.ogg": "",
+ "fountain.ogg": "fuente",
"fox.ogg": "zorro",
- "frame.ogg": "marco",
- "france.ogg": "Francia",
- "freeze.ogg": "",
- "friday.ogg": "Viernes",
+ "freeze.ogg": "congelar",
"friend.ogg": "amigo",
- "fries.ogg": "",
+ "fries.ogg": "patata frita",
"frog.ogg": "rana",
"front.ogg": "frente",
- "frown.ogg": "",
"fruit.ogg": "fruta",
- "fudge.ogg": "",
- "full.ogg": "",
- "fun.ogg": "diversión",
+ "fudge.ogg": "dulce de chocolate",
+ "full.ogg": "lleno",
"fur.ogg": "piel",
"game.ogg": "juego",
- "gap.ogg": "brecha",
"garage.ogg": "garaje",
"garden.ogg": "jardín",
"garlic.ogg": "ajo",
- "gem.ogg": "",
- "germany.ogg": "Alemania",
- "get.ogg": "obtener",
+ "gem.ogg": "gema",
"giant.ogg": "gigante",
"gift.ogg": "regalo",
"giraffe.ogg": "jirafa",
"girl.ogg": "chica",
- "glass.ogg": "",
+ "glass.ogg": "vaso",
"glasses.ogg": "gafas",
"glove.ogg": "guante",
"glue.ogg": "pegamento",
- "gnome.ogg": "",
+ "gnome.ogg": "gnomo",
"goat.ogg": "cabra",
- "gold.ogg": "oro",
- "golden.ogg": "",
- "golf.ogg": "",
- "good.ogg": "bueno",
- "goose.ogg": "",
- "gorilla.ogg": "",
+ "golden.ogg": "dorada",
+ "golf.ogg": "golf",
+ "goose.ogg": "oca",
+ "gorilla.ogg": "gorila",
"grain.ogg": "grano",
- "grandfather.ogg": "abuelo",
"grandmother.ogg": "abuela",
"grape.ogg": "uva",
"grapefruit.ogg": "pomelo",
"grass.ogg": "hierba",
- "grave.ogg": "",
+ "grave.ogg": "tumba",
"gray.ogg": "gris",
- "great_britain.ogg": "Gran bretaña",
"green.ogg": "verde",
- "grill.ogg": "grilla",
- "grin.ogg": "",
- "ground.ogg": "",
- "grow.ogg": "crecer",
- "growl.ogg": "",
- "guignol.ogg": "",
- "guinea_pig.ogg": "",
- "gum.ogg": "",
+ "grill.ogg": "parrilla",
+ "grin.ogg": "sonrisa",
+ "ground.ogg": "tierra",
+ "growl.ogg": "gruñir",
+ "guignol.ogg": "títere",
+ "guinea_pig.ogg": "cobaya",
+ "gum.ogg": "chicle",
"hair.ogg": "cabello",
- "hair_dryer.ogg": "",
- "hairdresser.ogg": "peluquero",
+ "hair_dryer.ogg": "secador de pelo",
"half.ogg": "mitad",
"ham.ogg": "jamón",
"hamburger.ogg": "hamburguesa",
"hammer.ogg": "martillo",
- "hamster.ogg": "hámster",
"hand.ogg": "mano",
- "handlebar.ogg": "",
+ "handlebar.ogg": "manillar",
"happy.ogg": "feliz",
- "hard.ogg": "duro",
- "harp.ogg": "",
+ "harp.ogg": "arpa",
"hat.ogg": "sombrero",
"hatch.ogg": "escotilla",
"hay.ogg": "heno",
"head.ogg": "cabeza",
"hear.ogg": "escuchar",
- "heart.ogg": "corazón",
"heat.ogg": "calor",
- "hedge.ogg": "",
- "hedgehog.ogg": "",
- "heel.ogg": "",
+ "hedge.ogg": "seto",
+ "hedgehog.ogg": "erizo",
+ "heel.ogg": "talón",
"helmet.ogg": "casco",
- "help.ogg": "ayudar",
"hen.ogg": "gallina",
- "herd.ogg": "",
+ "herd.ogg": "rebaño",
"high.ogg": "alto",
"hike.ogg": "caminata",
"hill.ogg": "colina",
- "hip.ogg": "",
+ "hip.ogg": "cadera",
"hippopotamus.ogg": "hipopótamo",
"hit.ogg": "golpear",
"hive.ogg": "colmena",
- "hockey.ogg": "",
+ "hockey.ogg": "hockey",
"hole.ogg": "agujero",
- "home.ogg": "hogar",
- "hook.ogg": "",
+ "home.ogg": "casa",
+ "hook.ogg": "anzuelo",
"hop.ogg": "salto",
"horse.ogg": "caballo",
- "hose.ogg": "",
+ "hose.ogg": "manguera",
"hospital.ogg": "hospital",
"hot.ogg": "caliente",
- "hot_dog.ogg": "",
- "hound.ogg": "",
+ "hot_dog.ogg": "perrito caliente",
+ "hound.ogg": "perro de caza",
"house.ogg": "casa",
- "howl.ogg": "",
- "hug.ogg": "",
+ "howl.ogg": "aullar",
+ "hug.ogg": "abrazar",
"huge.ogg": "enorme",
- "hummingbird.ogg": "",
- "hunchback.ogg": "",
+ "hummingbird.ogg": "colibrí",
+ "hunchbacked.ogg": "jorobado",
"hunter.ogg": "cazador",
- "hurt.ogg": "daño",
"husband.ogg": "marido",
- "hut.ogg": "",
- "hyena.ogg": "",
+ "hut.ogg": "cabaña",
+ "hyena.ogg": "hiena",
"ice.ogg": "hielo",
- "iceberg.ogg": "",
- "iguana.ogg": "",
+ "iceberg.ogg": "iceberg",
+ "iguana.ogg": "iguana",
"ill.ogg": "enfermo",
"ink.ogg": "tinta",
"island.ogg": "isla",
- "italy.ogg": "Italia",
"jacket.ogg": "chaqueta",
- "jaguar.ogg": "",
+ "jaguar.ogg": "jaguar",
"jam.ogg": "mermelada",
- "january.ogg": "Enero",
- "jay.ogg": "",
+ "jay.ogg": "arrendajo",
"jelly.ogg": "jalea",
- "jellyfish.ogg": "",
+ "jellyfish.ogg": "medusa",
"jewel.ogg": "joya",
- "job.ogg": "",
- "jockey.ogg": "",
- "jog.ogg": "",
+ "job.ogg": "trabajo",
+ "jockey.ogg": "jockey",
+ "jog.ogg": "footing",
+ "joy.ogg": "gozo",
"judge.ogg": "juez",
- "judo.ogg": "",
- "juggler.ogg": "",
- "juice.ogg": "",
- "july.ogg": "Julio",
+ "judo.ogg": "judo",
+ "juggler.ogg": "malabarista",
+ "juice.ogg": "zumo",
"jump.ogg": "saltar",
- "june.ogg": "Junio",
"kangaroo.ogg": "canguro",
- "keel.ogg": "",
- "kernel.ogg": "",
- "keyboard.ogg": "",
- "kimono.ogg": "",
+ "keel.ogg": "equilibrio",
+ "kernel.ogg": "núcleo",
+ "keyboard.ogg": "teclado",
+ "kimono.ogg": "quimono",
"king.ogg": "rey",
"kiss.ogg": "beso",
"kitchen.ogg": "cocina",
"kite.ogg": "cometa",
- "kitten.ogg": "",
+ "kitten.ogg": "gatito",
"kiwi.ogg": "kiwi",
"knee.ogg": "rodilla",
- "kneel.ogg": "",
+ "kneel.ogg": "arrodillarse",
"knife.ogg": "cuchillo",
- "knight.ogg": "",
- "knit.ogg": "",
+ "knight.ogg": "caballero",
+ "knit.ogg": "tejer",
"knot.ogg": "nudo",
- "know.ogg": "saber",
"koala.ogg": "coala",
- "lad.ogg": "",
- "ladder.ogg": "escalera",
- "lady.ogg": "",
+ "lad.ogg": "mozo",
+ "lady.ogg": "dama",
"ladybug.ogg": "mariquita",
"lake.ogg": "lago",
- "lama.ogg": "",
+ "lama.ogg": "lama",
"lamb.ogg": "cordero",
"lamp.ogg": "lámpara",
- "land.ogg": "",
+ "land.ogg": "terreno",
"lane.ogg": "carril",
- "lap.ogg": "",
- "lasso.ogg": "",
+ "lap.ogg": "en la falda",
+ "lasso.ogg": "lazo",
"laugh.ogg": "reír",
"lava.ogg": "lava",
- "lawn.ogg": "cesped",
- "lawyer.ogg": "",
- "lazy.ogg": "perezoso",
+ "lawn.ogg": "césped",
+ "lawyer.ogg": "abogado",
"leaf.ogg": "hoja",
- "ledge.ogg": "",
+ "ledge.ogg": "repisa",
"leek.ogg": "puerro",
"left.ogg": "izquierda",
"leg.ogg": "pierna",
- "leg_animal.ogg": "",
"lemon.ogg": "limón",
- "lemonade.ogg": "",
- "lemur.ogg": "",
+ "lemonade.ogg": "limonada",
+ "lemur.ogg": "lémur",
"leopard.ogg": "leopardo",
"lettuce.ogg": "lechuga",
- "librarian.ogg": "librero",
+ "librarian.ogg": "bibliotecaria",
"lick.ogg": "lamer",
"lid.ogg": "tapa",
- "life.ogg": "vida",
- "lift.ogg": "",
+ "lift.ogg": "levantar",
"light.ogg": "luz",
"lighthouse.ogg": "faro",
- "lightning.ogg": "",
- "lilac.ogg": "",
- "lime.ogg": "",
- "line.ogg": "linea",
+ "lightning.ogg": "rayo",
+ "lilac.ogg": "lilas",
+ "lime.ogg": "lima",
+ "line.ogg": "código de barras",
"link.ogg": "enlace",
"lion.ogg": "león",
- "lion_cub.ogg": "",
+ "lion_cub.ogg": "cachorro de león",
"lip.ogg": "labio",
"liquid.ogg": "líquido",
"lizard.ogg": "lagartija",
"lobster.ogg": "langosta",
- "log.ogg": "",
- "look.ogg": "",
- "love.ogg": "amor",
- "luck.ogg": "suerte",
+ "log.ogg": "tronco",
+ "look.ogg": "mirarse",
"lunch.ogg": "almuerzo",
- "mad.ogg": "",
- "magic.ogg": "",
- "magnet.ogg": "",
- "magnifying_glass.ogg": "",
- "magpie.ogg": "",
+ "mad.ogg": "ira",
+ "magic.ogg": "mágico",
+ "magnet.ogg": "imán",
+ "magnifying_glass.ogg": "lupa",
+ "magpie.ogg": "garza",
"mail.ogg": "correo",
- "male.ogg": "masculino",
"man.ogg": "hombre",
- "mane.ogg": "",
- "mango.ogg": "",
+ "mane.ogg": "melena",
+ "mango.ogg": "mango",
"map.ogg": "mapa",
- "maple.ogg": "",
- "marble.ogg": "",
- "mashed_potatoes.ogg": "",
+ "maple.ogg": "arce",
+ "marble.ogg": "canica",
+ "mashed_potatoes.ogg": "puré de patata",
"mask.ogg": "máscara",
- "mast.ogg": "",
- "mat.ogg": "",
- "match.ogg": "",
- "mate.ogg": "",
- "mattress.ogg": "",
- "mauve.ogg": "",
- "may.ogg": "Mayo",
+ "mast.ogg": "mástil",
+ "mat.ogg": "alfombra",
+ "match.ogg": "cerilla",
+ "mate.ogg": "compañero",
+ "mattress.ogg": "colchón",
+ "mauve.ogg": "malva",
"meal.ogg": "comida",
"meat.ogg": "carne",
- "mechanic.ogg": "",
- "medal.ogg": "",
- "meet.ogg": "",
+ "mechanic.ogg": "mecánico",
+ "medal.ogg": "medalla",
+ "meet.ogg": "encontrarse",
"melon.ogg": "melón",
- "men.ogg": "",
- "merry-go-round.ogg": "",
- "mice.ogg": "",
- "microphone.ogg": "",
+ "merry-go-round.ogg": "carrusel",
+ "mice.ogg": "ratones",
+ "microphone.ogg": "micrófono",
"milk.ogg": "leche",
"mill.ogg": "molino",
- "mimosa.ogg": "",
+ "mimosa.ogg": "mimosa",
"mirror.ogg": "espejo",
- "mixer.ogg": "",
+ "mixer.ogg": "mezclador",
"mole.ogg": "topo",
- "mom.ogg": "",
- "monday.ogg": "Lunes",
- "monkey.ogg": "mono",
+ "mom.ogg": "mama",
"moon.ogg": "luna",
- "moose.ogg": "",
- "mop.ogg": "",
- "mosque.ogg": "",
+ "moose.ogg": "alce",
+ "mop.ogg": "fregona",
+ "mosque.ogg": "mezquita",
"mosquito.ogg": "mosquito",
"mother.ogg": "madre",
"motorcycle.ogg": "motocicleta",
"mountain.ogg": "montaña",
"mouse.ogg": "ratón",
"mouth.ogg": "boca",
"movie.ogg": "película",
- "mower.ogg": "",
+ "mower.ogg": "cortacésped",
"mud.ogg": "barro",
"mug.ogg": "jarra",
- "mule.ogg": "",
+ "mule.ogg": "mula",
"muscle.ogg": "músculo",
"mushroom.ogg": "hongo",
"music.ogg": "música",
"musician.ogg": "músico",
- "nail.ogg": "clavo",
- "naked.ogg": "",
- "nap.ogg": "",
- "navel.ogg": "",
+ "naked.ogg": "desnudo",
+ "nap.ogg": "siesta",
+ "navel.ogg": "ombligo",
"neck.ogg": "cuello",
"necklace.ogg": "collar",
"needle.ogg": "aguja",
"nest.ogg": "nido",
- "net.ogg": "",
+ "net.ogg": "red",
"newspaper.ogg": "periódico",
"night.ogg": "noche",
- "nightgown.ogg": "",
- "noise.ogg": "ruido",
- "north.ogg": "norte",
+ "nightgown.ogg": "camisón",
"nose.ogg": "nariz",
- "nostril.ogg": "ventana de la nariz",
- "note.ogg": "nota",
+ "nostril.ogg": "fosa nasal",
"notebook.ogg": "cuaderno",
- "november.ogg": "Noviembre",
- "now.ogg": "ahora",
"number.ogg": "número",
- "nun.ogg": "",
+ "nun.ogg": "monja",
"nurse.ogg": "enfermera",
- "nurse_male.ogg": "",
+ "nurse_male.ogg": "enfermero",
"nut.ogg": "nuez",
"oar.ogg": "remo",
"ocean.ogg": "océano",
- "october.ogg": "Octubre",
- "office.ogg": "",
- "oil.ogg": "aceite",
+ "office.ogg": "oficina",
"olive.ogg": "oliva",
- "on.ogg": "",
+ "on.ogg": "encima",
"onion.ogg": "cebolla",
"open.ogg": "abrir",
- "opossum.ogg": "",
- "orange-color.ogg": "",
+ "opossum.ogg": "zarigüeya",
+ "orange-color.ogg": "naranja",
"orange.ogg": "naranja",
- "orchid.ogg": "",
- "ostrich.ogg": "",
- "otter.ogg": "",
+ "orchid.ogg": "orquídea",
+ "ostrich.ogg": "avestruz",
+ "otter.ogg": "nutria",
"owl.ogg": "búho",
- "ox.ogg": "",
- "oyster.ogg": "",
- "pacifier.ogg": "",
+ "ox.ogg": "buey",
+ "oyster.ogg": "ostra",
+ "pacifier.ogg": "chupete",
"page.ogg": "página",
- "paint.ogg": "pintar",
"pair.ogg": "par",
- "pajamas.ogg": "",
- "pal.ogg": "",
- "palm_tree.ogg": "",
- "pan.ogg": "",
+ "pajamas.ogg": "pijama",
+ "pal.ogg": "colegas",
+ "palm_tree.ogg": "palmera",
+ "pan.ogg": "paella",
"panda.ogg": "panda",
"panther.ogg": "pantera",
- "panties.ogg": "",
+ "panties.ogg": "bragas",
"pants.ogg": "pantalones",
- "papaya.ogg": "",
+ "papaya.ogg": "papaya",
"paper.ogg": "papel",
- "parachute.ogg": "",
- "parakeet.ogg": "",
- "park.ogg": "parque",
+ "parachute.ogg": "paracaídas",
+ "parakeet.ogg": "periquito",
"parrot.ogg": "loro",
"patch.ogg": "parche",
"path.ogg": "camino",
- "paw.ogg": "",
- "pay.ogg": "pagar",
+ "paw.ogg": "pata",
"pea.ogg": "guisante",
"peach.ogg": "melocotón",
- "peacock.ogg": "",
- "peak.ogg": "",
+ "peacock.ogg": "pavo real",
+ "peak.ogg": "pico",
"pear.ogg": "pera",
"pearl.ogg": "perla",
- "peck.ogg": "",
- "pedal.ogg": "",
- "pelican.ogg": "",
+ "peck.ogg": "picotear",
+ "pedal.ogg": "pedal",
+ "pelican.ogg": "pelícano",
"pen.ogg": "pluma",
"pencil.ogg": "lápiz",
- "peony.ogg": "",
- "people.ogg": "",
+ "peony.ogg": "peonía",
+ "people.ogg": "gente",
"pepper.ogg": "pimienta",
- "peppers.ogg": "",
- "pet.ogg": "",
+ "peppers.ogg": "pimiento",
+ "pet.ogg": "mascota",
"petal.ogg": "pétalo",
- "petite.ogg": "",
"phone.ogg": "teléfono",
"piano.ogg": "piano",
"picture.ogg": "imagen",
- "pie.ogg": "",
+ "pie.ogg": "pastel",
"pig.ogg": "cerdo",
"pigeon.ogg": "paloma",
"pill.ogg": "píldora",
"pillow.ogg": "almohada",
"pilot.ogg": "piloto",
- "pine.ogg": "",
- "pine_cone.ogg": "",
- "pine_tree.ogg": "árbol de pino",
- "pineapple.ogg": "piña",
+ "pine.ogg": "pino",
+ "pine_cone.ogg": "piña",
"pink.ogg": "rosa",
- "pip.ogg": "",
- "pipe.ogg": "",
- "piranha.ogg": "",
+ "pip.ogg": "semilla",
+ "pipe.ogg": "pipa",
+ "piranha.ogg": "piraña",
"pirate.ogg": "pirata",
"pizza.ogg": "pizza",
- "plane.ogg": "",
+ "plane.ogg": "avión",
"planet.ogg": "planeta",
- "plant.ogg": "",
- "plate.ogg": "",
+ "plant.ogg": "planta",
+ "plate.ogg": "plato",
"play.ogg": "jugar",
- "please.ogg": "complacer",
- "pliers.ogg": "",
- "plow.ogg": "",
+ "pliers.ogg": "alicates",
+ "plow.ogg": "arar",
"plum.ogg": "ciruela",
"plumber.ogg": "fontanero",
"pocket.ogg": "bolsillo",
- "pod.ogg": "",
- "pole.ogg": "",
+ "pod.ogg": "vaina",
+ "pole.ogg": "palo",
"police.ogg": "policía",
- "pompon.ogg": "",
+ "pompon.ogg": "pompón",
"pond.ogg": "estanque",
- "pony.ogg": "",
+ "pony.ogg": "poni",
"pool.ogg": "piscina",
- "pop.ogg": "",
- "pope.ogg": "",
- "porthole.ogg": "",
- "post.ogg": "",
+ "popcorn.ogg": "palomitas",
+ "pope.ogg": "papa",
+ "porthole.ogg": "ojo de buey",
+ "post.ogg": "buzón",
"pot.ogg": "olla",
"potato.ogg": "patata",
- "pounce.ogg": "",
- "pray.ogg": "orar",
- "present.ogg": "presentar",
- "president.ogg": "",
+ "pounce.ogg": "saltar",
+ "president.ogg": "presidente",
"pretty.ogg": "bonita",
"price.ogg": "precio",
"priest.ogg": "sacerdote",
"prince.ogg": "príncipe",
"princess.ogg": "princesa",
- "print.ogg": "imprimir",
"prison.ogg": "prisión",
- "prisoner.ogg": "",
- "prize.ogg": "",
- "pug.ogg": "",
- "pull.ogg": "",
+ "prisoner.ogg": "prisionero",
+ "prize.ogg": "trofeo",
+ "pug.ogg": "pug",
+ "pull.ogg": "estirar",
"pullover.ogg": "jersey",
"pumpkin.ogg": "calabaza",
- "puppy.ogg": "",
- "purple.ogg": "púrpura",
+ "puppy.ogg": "cachorro",
"pyramid.ogg": "pirámide",
- "quarrel.ogg": "",
+ "quarrel.ogg": "pelea",
"queen.ogg": "reina",
"question.ogg": "cuestión",
- "quick.ogg": "rápido",
- "quiet.ogg": "tranquilo",
- "quilt.ogg": "",
- "quiz.ogg": "",
+ "quilt.ogg": "edredón",
+ "quiz.ogg": "examen",
"rabbit.ogg": "conejo",
- "rabbit_baby.ogg": "",
- "race.ogg": "",
+ "rabbit_baby.ogg": "bebé conejo",
+ "race.ogg": "carrera",
"radio.ogg": "radio",
- "radish.ogg": "",
- "raft.ogg": "",
- "rag.ogg": "",
- "rage.ogg": "",
+ "radish.ogg": "rábano",
+ "raft.ogg": "balsa",
+ "rag.ogg": "trapo",
+ "rage.ogg": "rabia",
"rain.ogg": "lluvia",
- "raincoat.ogg": "",
+ "raincoat.ogg": "impermeable",
"rake.ogg": "rastrillo",
- "ramp.ogg": "",
- "ran.ogg": "",
+ "ramp.ogg": "rampa",
+ "ran.ogg": "correr",
"raspberry.ogg": "frambuesa",
"rat.ogg": "rata",
- "razor.ogg": "",
+ "razor.ogg": "maquinilla de afeitar",
"read.ogg": "leer",
"red.ogg": "rojo",
"reptile.ogg": "reptil",
"rhinoceros.ogg": "rinoceronte",
"rice.ogg": "arroz",
- "ride.ogg": "",
- "rifle.ogg": "",
- "right.ogg": "",
- "ring.ogg": "anillo",
- "rip.ogg": "",
- "rise.ogg": "",
- "risk.ogg": "riesgo",
+ "ride.ogg": "ciclista",
+ "rifle.ogg": "rifle",
+ "right.ogg": "dreta",
+ "rip.ogg": "desgarrar",
+ "rise.ogg": "subir",
"river.ogg": "río",
"road.ogg": "carretera",
- "roast.ogg": "",
- "robe.ogg": "",
+ "roast.ogg": "asado",
+ "robe.ogg": "manto",
"robot.ogg": "robot",
- "rock.ogg": "",
+ "rock.ogg": "roca",
"rocket.ogg": "cohete",
- "rolling_pin.ogg": "",
+ "rolling_pin.ogg": "rodillo de cocina",
"roof.ogg": "techo",
- "room.ogg": "",
- "rooster.ogg": "gallo",
+ "room.ogg": "habitación",
"root.ogg": "raíz",
"rope.ogg": "cuerda",
- "rose.ogg": "",
- "round.ogg": "",
- "rowing.ogg": "",
- "royal.ogg": "",
- "rug.ogg": "",
- "run.ogg": "",
+ "rose.ogg": "rosa",
+ "round.ogg": "circular",
+ "rowing.ogg": "remo",
+ "royal.ogg": "real",
+ "rug.ogg": "alfombra",
+ "run.ogg": "correr",
"sad.ogg": "triste",
- "saddle.ogg": "",
+ "saddle.ogg": "silla de montar",
"sail.ogg": "navegar",
"sailor.ogg": "marinero",
- "salamander.ogg": "",
+ "salamander.ogg": "salamandra",
"salmon.ogg": "salmón",
"sand.ogg": "arena",
- "sandals.ogg": "sandalias",
- "sandwich.ogg": "",
- "sash.ogg": "",
- "sat.ogg": "",
- "saturday.ogg": "sábado",
+ "sandals.ogg": "sandalia",
+ "sandwich.ogg": "sándwich",
+ "sash.ogg": "faja",
"sauce.ogg": "salsa",
"sausage.ogg": "salchicha",
- "scale.ogg": "",
+ "scale.ogg": "balanza",
"scar.ogg": "cicatriz",
- "scared.ogg": "",
- "scarf.ogg": "",
+ "scare.ogg": "asustar",
+ "scarf.ogg": "bufanda",
"school.ogg": "escuela",
- "school_bag.ogg": "",
- "science.ogg": "",
+ "school_bag.ogg": "mochila",
+ "science.ogg": "ciencia",
"scissors.ogg": "tijeras",
"scorpion.ogg": "escorpión",
- "scratch.ogg": "",
+ "scratch.ogg": "arañar",
"scream.ogg": "gritar",
- "screen.ogg": "pantalla",
- "screw.ogg": "",
- "screwdriver.ogg": "",
- "scribble.ogg": "",
+ "screw.ogg": "tornillo",
+ "screwdriver.ogg": "destornillador",
+ "scribble.ogg": "garabato",
"sea.ogg": "mar",
- "seat.ogg": "",
+ "seat.ogg": "asiento",
"see.ogg": "ver",
"seed.ogg": "semilla",
- "sell.ogg": "vender",
- "september.ogg": "Septiembre",
"shadow.ogg": "sombra",
"shake.ogg": "sacudir",
"shark.ogg": "tiburón",
- "shave.ogg": "",
- "shed.ogg": "",
+ "shave.ogg": "esquilar",
+ "shed.ogg": "cobertizo",
"sheep.ogg": "oveja",
- "shelf.ogg": "",
+ "shelf.ogg": "estante",
"shell.ogg": "concha",
- "ship.ogg": "",
+ "ship.ogg": "barco",
"shirt.ogg": "camisa",
"shoe.ogg": "zapato",
- "shoelace.ogg": "",
- "shop.ogg": "",
- "shore.ogg": "",
+ "shoelace.ogg": "cordón",
+ "shop.ogg": "tienda",
+ "shore.ogg": "orilla",
"short.ogg": "corto",
"shovel.ogg": "pala",
"shower.ogg": "ducha",
"shrimp.ogg": "camarón",
- "shrub.ogg": "",
- "shut.ogg": "",
- "shutter.ogg": "",
- "sick.ogg": "",
- "sidewalk.ogg": "",
- "sign.ogg": "",
- "silence.ogg": "silencio",
- "silver.ogg": "plata",
+ "shrub.ogg": "arbusto",
+ "shut.ogg": "cerrada",
+ "shutter.ogg": "contraventana",
+ "sick.ogg": "enfermo",
+ "sidewalk.ogg": "acera",
+ "sign.ogg": "señal",
"sing.ogg": "cantar",
- "singer.ogg": "cantante",
- "sink.ogg": "",
- "sip.ogg": "",
+ "sink.ogg": "lavabo",
+ "sip.ogg": "sorber",
"sister.ogg": "hermana",
"sit.ogg": "sentarse",
- "skate.ogg": "",
- "skeleton.ogg": "",
+ "skate.ogg": "patinar",
+ "skeleton.ogg": "esqueleto",
"ski.ogg": "esquiar",
- "skimmer.ogg": "",
- "skin.ogg": "",
+ "skimmer.ogg": "espumadera",
+ "skin.ogg": "piel",
"skirt.ogg": "falda",
- "skunk.ogg": "",
+ "skunk.ogg": "mofeta",
"sky.ogg": "cielo",
- "slam.ogg": "",
- "sled.ogg": "",
+ "slam.ogg": "mate",
+ "sled.ogg": "trineo",
"sleep.ogg": "dormir",
"sleeve.ogg": "manga",
- "sleigh.ogg": "",
- "slide.ogg": "",
- "slim.ogg": "",
- "slime.ogg": "",
- "slippers.ogg": "",
- "slope.ogg": "",
- "sloppy.ogg": "",
- "slot.ogg": "",
- "sloth.ogg": "",
- "slow.ogg": "lento",
- "slug.ogg": "",
+ "sleigh.ogg": "trineo",
+ "slide.ogg": "tobogán",
+ "slim.ogg": "delgada",
+ "slime.ogg": "baba",
+ "slippers.ogg": "zapatilla",
+ "slope.ogg": "pendiente",
+ "sloppy.ogg": "mojado",
+ "slot.ogg": "ranura",
+ "sloth.ogg": "perezoso",
+ "slug.ogg": "babosa",
"small.ogg": "pequeño",
- "smart.ogg": "inteligente",
"smell.ogg": "olor",
"smile.ogg": "sonreír",
- "smock.ogg": "",
- "smoke.ogg": "",
- "smooch.ogg": "",
- "snack.ogg": "bocadillo",
+ "smock.ogg": "bata",
+ "smoke.ogg": "humo",
+ "smooch.ogg": "besar",
+ "snack.ogg": "piscolabis",
"snail.ogg": "caracol",
"snake.ogg": "serpiente",
- "sneaker.ogg": "",
- "sniff.ogg": "",
+ "sneaker.ogg": "zapatilla deportiva",
+ "sniff.ogg": "olfatear",
"snow.ogg": "nieve",
"soap.ogg": "jabón",
- "sob.ogg": "",
+ "sob.ogg": "sollozar",
"sock.ogg": "calcetín",
- "soft.ogg": "suave",
"soldier.ogg": "soldado",
- "sole.ogg": "",
- "sole_shoe.ogg": "",
+ "sole.ogg": "lenguado",
+ "sole_shoe.ogg": "suela del zapato",
"son.ogg": "hijo",
- "sorry.ogg": "arrepentido",
"soup.ogg": "sopa",
- "space.ogg": "espacio",
- "spade.ogg": "",
- "spaghetti.ogg": "",
- "spark.ogg": "",
- "sparrow.ogg": "",
- "spatula.ogg": "",
+ "spade.ogg": "pala",
+ "spaghetti.ogg": "espagueti",
+ "spark.ogg": "chispa",
+ "sparrow.ogg": "gorrión",
+ "spatula.ogg": "espátula",
"speak.ogg": "hablar",
- "spear.ogg": "",
+ "spear.ogg": "lanza",
"spice.ogg": "especia",
"spider.ogg": "araña",
- "spider_web.ogg": "",
- "spike.ogg": "",
+ "spider_web.ogg": "telaraña",
+ "spike.ogg": "erizo",
"spill.ogg": "derramar",
"spinach.ogg": "espinacas",
- "spine.ogg": "",
- "spinning_top.ogg": "",
- "splash.ogg": "",
- "splatter.ogg": "",
- "split.ogg": "dividido",
+ "spine.ogg": "espina",
+ "spinning_top.ogg": "peonza",
+ "splash.ogg": "salpicar",
+ "splatter.ogg": "salpicadura",
"sponge.ogg": "esponja",
- "spool.ogg": "",
+ "spool.ogg": "carrete",
"spoon.ogg": "cuchara",
"sport.ogg": "deporte",
- "spot.ogg": "",
- "spouse.ogg": "cónyuge",
- "spray.ogg": "",
- "spread.ogg": "",
- "spring.ogg": "",
- "spring_season.ogg": "",
- "sprinkle.ogg": "",
- "square.ogg": "",
- "squash.ogg": "",
- "squat.ogg": "",
- "squid.ogg": "",
+ "spot.ogg": "mancha",
+ "spray.ogg": "rociar",
+ "spread.ogg": "untar",
+ "spring.ogg": "botar",
+ "spring_season.ogg": "primavera",
+ "sprinkle.ogg": "chispas",
+ "square.ogg": "cuadrado",
+ "squash.ogg": "calabacín",
+ "squat.ogg": "agacharse",
+ "squid.ogg": "calamar",
"squirrel.ogg": "ardilla",
- "squirt.ogg": "",
- "stack.ogg": "",
- "stage.ogg": "",
- "stain.ogg": "mancha",
- "staircase.ogg": "",
+ "squirt.ogg": "pulverizador",
+ "stack.ogg": "pila",
+ "stage.ogg": "escenario",
+ "staircase.ogg": "escalera",
"stamp.ogg": "sello",
- "stand.ogg": "",
+ "stand.ogg": "derecho",
"star.ogg": "estrella",
- "stare.ogg": "",
- "starfish.ogg": "",
- "start.ogg": "iniciar",
- "steak.ogg": "filete",
- "steam.ogg": "",
- "steep.ogg": "",
- "steeple.ogg": "",
+ "stare.ogg": "mirar fijamente",
+ "starfish.ogg": "estrella de mar",
+ "steam.ogg": "vapor",
+ "steep.ogg": "empinado",
+ "steeple.ogg": "campanar",
"stem.ogg": "vástago",
- "step.ogg": "",
- "stew.ogg": "",
- "stick.ogg": "palo",
- "sting.ogg": "",
- "stinky.ogg": "",
- "stitch.ogg": "",
- "stomach.ogg": "",
+ "step.ogg": "peldaño",
+ "stew.ogg": "guiso",
+ "stick.ogg": "rama",
+ "sting.ogg": "aguijón",
+ "stinky.ogg": "apestoso",
+ "stitch.ogg": "puntada",
+ "stomach.ogg": "estómago",
"stone.ogg": "piedra",
"stop.ogg": "parar",
"store.ogg": "almacenar",
- "stove.ogg": "",
+ "stove.ogg": "fogón",
"straight.ogg": "recto",
- "strainer.ogg": "",
+ "strainer.ogg": "colador",
"straw.ogg": "paja",
"strawberry.ogg": "fresa",
- "stream.ogg": "",
+ "stream.ogg": "corriente",
"street.ogg": "calle",
- "stretch.ogg": "",
- "string.ogg": "",
- "stripe.ogg": "",
+ "stretch.ogg": "estirar",
+ "string.ogg": "cordel",
+ "stripe.ogg": "ralla",
"strong.ogg": "fuerte",
"student.ogg": "estudiante",
"study.ogg": "estudiar",
- "stump.ogg": "",
+ "stump.ogg": "tronco",
"sugar.ogg": "azúcar",
- "suit.ogg": "",
+ "suit.ogg": "arreglada",
"suitcase.ogg": "maleta",
"summer.ogg": "verano",
"summit.ogg": "cumbre",
- "sun.ogg": "sol",
- "sunday.ogg": "Domingo",
- "super.ogg": "súper",
- "swan.ogg": "",
+ "sun.ogg": "Sol",
+ "swan.ogg": "cisne",
"sweat.ogg": "sudar",
- "sweatshirt.ogg": "Sudadera",
- "sweet.ogg": "dulce",
+ "sweatshirt.ogg": "sudadera",
"swim.ogg": "nadar",
- "swiss.ogg": "suizo",
"table.ogg": "mesa",
- "tablecloth.ogg": "",
- "tadpole.ogg": "",
+ "tablecloth.ogg": "mantel",
+ "tadpole.ogg": "renacuajo",
"tag.ogg": "etiqueta",
"tail.ogg": "cola",
- "take.ogg": "tomar",
- "tall.ogg": "",
- "tape_measure.ogg": "",
- "task.ogg": "tarea",
- "taxi.ogg": "",
+ "tall.ogg": "alto",
+ "tape_measure.ogg": "cinta métrica",
+ "taxi.ogg": "taxi",
"teach.ogg": "enseñar",
"teacher.ogg": "maestro",
- "team.ogg": "equipo",
- "tear.ogg": "",
- "teddy.ogg": "",
- "teeth.ogg": "",
+ "tear.ogg": "rasgar",
+ "teddy.ogg": "peluche",
+ "teeth.ogg": "dentadura",
"television.ogg": "televisión",
- "tell.ogg": "contar",
"temple.ogg": "templo",
"tennis.ogg": "tenis",
- "tent.ogg": "",
+ "tent.ogg": "tienda",
"text.ogg": "texto",
- "thank.ogg": "agradecer",
- "thick.ogg": "",
+ "thick.ogg": "grueso",
"thief.ogg": "ladrón",
- "thigh.ogg": "",
+ "thigh.ogg": "muslo",
"think.ogg": "pensar",
- "thread.ogg": "",
- "throat.ogg": "",
- "throw.ogg": "",
+ "thread.ogg": "bobina",
+ "throat.ogg": "garganta",
+ "throw.ogg": "lanzar",
"thumb.ogg": "pulgar",
- "thursday.ogg": "Jueves",
- "tick.ogg": "",
+ "tick.ogg": "garrapata",
"ticket.ogg": "billete",
"tiger.ogg": "tigre",
"time.ogg": "tiempo",
- "tin.ogg": "",
- "tire.ogg": "",
+ "tin.ogg": "lata",
+ "tire.ogg": "neumático",
"tired.ogg": "cansado",
- "tissue.ogg": "tejido",
- "toad.ogg": "",
- "toaster.ogg": "",
- "today.ogg": "hoy",
- "toe.ogg": "",
- "toilet.ogg": "",
- "tomato.ogg": "tomate",
- "tomatoe.ogg": "",
- "tomorrow.ogg": "mañana",
- "tongs.ogg": "",
+ "tissue.ogg": "pañuelo",
+ "to_drink.ogg": "beber",
+ "toad.ogg": "sapo",
+ "toaster.ogg": "tostadora",
+ "toe.ogg": "dedo del pie",
+ "toilet.ogg": "váter",
+ "tomatoe.ogg": "tomate",
+ "tongs.ogg": "pinzas",
"tongue.ogg": "lengua",
"tool.ogg": "herramienta",
- "top.ogg": "",
- "torch.ogg": "",
- "touch.ogg": "",
+ "top.ogg": "cima",
+ "torch.ogg": "antorcha",
+ "touch.ogg": "tocar",
"towel.ogg": "toalla",
- "tower.ogg": "torre",
"toy.ogg": "juguete",
- "trail.ogg": "",
+ "trail.ogg": "sendero",
"train.ogg": "tren",
"train_station.ogg": "estación de tren",
- "trap.ogg": "",
- "trash.ogg": "",
- "tray.ogg": "",
- "treat.ogg": "",
+ "trap.ogg": "trampa",
+ "trash.ogg": "basura",
+ "tray.ogg": "bandeja",
+ "treat.ogg": "dulce",
"tree.ogg": "árbol",
"triangle.ogg": "triángulo",
- "tribe.ogg": "",
+ "tribe.ogg": "tribu",
"trip.ogg": "viaje",
"truck.ogg": "camión",
"tube.ogg": "tubo",
- "tuesday.ogg": "Martes",
"tulip.ogg": "tulipán",
- "tune.ogg": "",
- "tunnel.ogg": "túnel",
+ "tune.ogg": "melodía",
"turkey.ogg": "pavo",
- "turnip.ogg": "",
- "turtle.ogg": "tortuga marina",
- "tusk.ogg": "",
- "twin_boys.ogg": "",
- "twin_girls.ogg": "",
+ "turnip.ogg": "nabo",
+ "turtle.ogg": "tortuga",
+ "tusk.ogg": "colmillo",
+ "twin_boys.ogg": "gemelos",
+ "twin_girls.ogg": "gemelas",
"umbrella.ogg": "paraguas",
- "under.ogg": "",
+ "under.ogg": "debajo",
"uniform.ogg": "uniforme",
- "valley.ogg": "valle",
- "van.ogg": "",
- "vapor.ogg": "",
+ "van.ogg": "furgoneta",
+ "vapor.ogg": "vapor",
"vase.ogg": "florero",
- "vegetable.ogg": "",
- "vein.ogg": "",
- "verdure.ogg": "",
- "vest.ogg": "",
+ "vegetable.ogg": "vegetal",
+ "vein.ogg": "vena",
+ "verdure.ogg": "verdura",
+ "vest.ogg": "chaleco",
"vet.ogg": "veterinario",
"viper.ogg": "víbora",
- "voice.ogg": "voz",
"vowel.ogg": "vocal",
- "vulture.ogg": "",
- "wag.ogg": "",
- "wait.ogg": "esperar",
+ "vulture.ogg": "buitre",
+ "wag.ogg": "menear",
"walk.ogg": "caminar",
"wall.ogg": "pared",
- "walnut.ogg": "",
- "want.ogg": "querer",
- "wart.ogg": "",
+ "walnut.ogg": "nuez",
+ "wart.ogg": "verruga",
"wash.ogg": "lavar",
"wasp.ogg": "avispa",
- "watch.ogg": "",
+ "watch.ogg": "reloj",
"water.ogg": "agua",
"wave.ogg": "ola",
"wedding.ogg": "boda",
- "wedge.ogg": "",
- "wednesday.ogg": "miércoles",
+ "wedge.ogg": "cuña",
"weight.ogg": "peso",
- "well.ogg": "bien",
- "wet.ogg": "humedo",
- "whale.ogg": "",
+ "wet.ogg": "húmedo",
+ "whale.ogg": "ballena",
"wheat.ogg": "trigo",
"wheel.ogg": "rueda",
- "whisk.ogg": "",
- "whisper.ogg": "",
+ "whisk.ogg": "batidora",
+ "whisper.ogg": "susurrar",
"white.ogg": "blanco",
"wide.ogg": "ancho",
"wife.ogg": "esposa",
"wig.ogg": "peluca",
"win.ogg": "ganar",
"wind.ogg": "viento",
"window.ogg": "ventana",
- "window_glass.ogg": "",
- "wing.ogg": "",
+ "window_glass.ogg": "cristal de la ventana",
+ "wing.ogg": "ala",
"winter.ogg": "invierno",
"wolf.ogg": "lobo",
"woman.ogg": "mujer",
"wood.ogg": "madera",
"word.ogg": "palabra",
"worker.ogg": "obrero",
"world.ogg": "mundo",
- "wreath.ogg": "",
- "wrench.ogg": "",
- "wrist.ogg": "",
+ "wreath.ogg": "guirnalda",
+ "wrench.ogg": "llave inglesa",
+ "wrist.ogg": "muñeca",
"write.ogg": "escribir",
- "wrong.ogg": "erroneo",
- "yard.ogg": "patio",
"yellow.ogg": "amarillo",
- "yesterday.ogg": "ayer",
"yogurt.ogg": "yogur",
- "yum.ogg": "",
+ "yum.ogg": "delicioso",
"zebra.ogg": "cebra",
- "zipper.ogg": "",
- "zoo.ogg": ""
-}
+ "zipper.ogg": "cremallera",
+ "zoo.ogg": "zoológico"
+}
\ No newline at end of file
diff --git a/src/activities/lang/resource/content-fr.json b/src/activities/lang/resource/content-fr.json
index 631e15522..5b222044d 100644
--- a/src/activities/lang/resource/content-fr.json
+++ b/src/activities/lang/resource/content-fr.json
@@ -1,1107 +1,1079 @@
{
"10.ogg": "dix",
"11.ogg": "onze",
"12.ogg": "douze",
"16.ogg": "seize",
"U0030.ogg": "zéro",
"U0031.ogg": "un",
"U0032.ogg": "deux",
"U0033.ogg": "trois",
"U0034.ogg": "quatre",
"U0035.ogg": "cinq",
"U0036.ogg": "six",
"U0037.ogg": "sept",
"U0038.ogg": "huit",
"U0039.ogg": "neuf",
"accountant.ogg": "un comptable",
"ache.ogg": "la douleur",
"acorn.ogg": "un gland",
"actor.ogg": "un acteur",
"air_horn.ogg": "un klaxon",
"alarmclock.ogg": "un réveil",
"alligator.ogg": "un alligator",
"alphabet.ogg": "un alphabet",
"anchor.ogg": "une ancre",
"angel.ogg": "un ange",
"angry.ogg": "la colère",
"animal.ogg": "les animaux",
"ankle.ogg": "la cheville",
"ant.ogg": "une fourmi",
"anteater.ogg": "un fourmilier",
"antelope.ogg": "une antilope",
"apple.ogg": "une pomme",
"apple_tree.ogg": "un pommier",
"appliance.ogg": "un appareil",
"apricot.ogg": "un abricot",
"arm.ogg": "un bras",
"armchair.ogg": "un fauteuil",
"artichoke.ogg": "un artichaut",
"artist.ogg": "un artiste",
"asparagus.ogg": "une asperge",
"astronaut.ogg": "un astronaute",
- "ate.ogg": "manger",
"athlete.ogg": "un athlète",
"avocado.ogg": "un avocat",
"ax.ogg": "une hache",
"baby_bottle.ogg": "un biberon",
"back.ogg": "le dos",
"badge.ogg": "une décoration",
"bag.ogg": "un sac",
"bait.ogg": "un appât",
- "bake.ogg": "cuisiner",
"balance.ogg": "une balance",
"bald.ogg": "chauve",
"ball.ogg": "une balle",
"ball_of_yarn.ogg": "une pelote",
"ball_soccer.ogg": "un ballon de foot",
"ballet.ogg": "un ballet",
"bank.ogg": "une banque",
+ "banker_female.ogg": "banquière",
"bark.ogg": "aboyer",
"barn.ogg": "une grange",
"bat.ogg": "une chauve-souris",
"bath.ogg": "un bain",
"bathing_suit.ogg": "un maillot",
"bay.ogg": "une baie",
"beach.ogg": "une plage",
- "bead.ogg": "une bulle",
"bean.ogg": "un haricot",
"bear.ogg": "un ours",
"beard.ogg": "une barbe",
"beat.ogg": "se battre",
"beaver.ogg": "un castor",
"bed.ogg": "un lit",
"bedroom.ogg": "une chambre",
"bee.ogg": "une abeille",
- "beef.ogg": "du boeuf",
"beetle.ogg": "un scarabée",
"beg.ogg": "supplier",
"behind.ogg": "derrière",
"bell.ogg": "une cloche",
"belly.ogg": "le ventre",
"bench.ogg": "un banc",
"bib.ogg": "un bavoir",
"big.ogg": "grand",
"big_top.ogg": "un chapiteau",
"bike.ogg": "un vélo",
"bird.ogg": "un oiseau",
"bit.ogg": "un morceau",
"bite.ogg": "croquer",
"black.ogg": "noir",
"blackberry.ogg": "une mûre",
"blackbird.ogg": "un merle",
"blade.ogg": "une lame",
"blind.ogg": "un aveugle",
"blink.ogg": "cligner",
"block.ogg": "un bloc",
"blond.ogg": "blond",
"blue.ogg": "bleu",
"blueberry.ogg": "une myrtille",
"blush.ogg": "rougir",
"board.ogg": "une planche",
"boat.ogg": "une barque",
"boil.ogg": "bouillir",
"bolt.ogg": "un boulon",
"bomb.ogg": "une bombe",
"bone.ogg": "un os",
"book.ogg": "un livre",
"bookcase.ogg": "une bibliothèque",
"bottom.ogg": "le derrière",
"box.ogg": "une boîte",
"boxer.ogg": "boxer",
"boy.ogg": "un garçon",
"braid.ogg": "une tresse",
"brain.ogg": "un cerveau",
"branch.ogg": "une branche",
"bread.ogg": "du pain",
"break.ogg": "casser",
"breast.ogg": "la poitrine",
"brick.ogg": "une brique",
"bricklayer.ogg": "un maçon",
"bride.ogg": "la mariée",
"bridge.ogg": "un pont",
"bright.ogg": "brillant",
"broccoli.ogg": "un brocoli",
"brother.ogg": "un frère",
"brown.ogg": "brun",
"brush.ogg": "un pinceau",
"bubble.ogg": "une bulle",
"bucket.ogg": "un seau",
"bud.ogg": "un bourgeon",
"buffalo.ogg": "un buffle",
"bug.ogg": "un insecte",
"bulb.ogg": "une ampoule",
"bull.ogg": "un taureau",
"bump.ogg": "une bosse",
"bun.ogg": "une brioche",
"bus.ogg": "un bus",
"bush.ogg": "un buisson",
"butcher.ogg": "un boucher",
"butter.ogg": "du beurre",
"butterfly.ogg": "un papillon",
"button.ogg": "un bouton",
"cabbage.ogg": "un chou",
"cabin.ogg": "une cabane",
"cacao.ogg": "du cacao",
"cactus.ogg": "un cactus",
"cage.ogg": "une cage",
"cake.ogg": "un gâteau",
"call.ogg": "appeler",
"camel.ogg": "un chameau",
"camera.ogg": "un appareil photo",
"camp.ogg": "un camping",
"can.ogg": "une conserve",
"canary.ogg": "un canari",
"candle.ogg": "une bougie",
"candy.ogg": "un bonbon",
"cane.ogg": "une cane",
"canoe.ogg": "un canoë",
"canon.ogg": "un canon",
"canyon.ogg": "un canyon",
"cap.ogg": "une casquette",
"cape.ogg": "une cape",
"car.ogg": "une voiture",
"carafe.ogg": "une carafe",
"card.ogg": "une carte",
"carnival.ogg": "le carnaval",
"carpenter.ogg": "un charpentier",
"carpet.ogg": "un tapis",
"carrot.ogg": "une carotte",
"cart.ogg": "un chariot de supermarché",
"cash.ogg": "de l'argent",
"castle.ogg": "un château",
"cat.ogg": "un chat",
"cat_female.ogg": "une chatte",
"catch.ogg": "attraper",
"caterpillar.ogg": "une chenille",
"cauldron.ogg": "un chaudron",
"cauliflower.ogg": "un chou-fleur",
"cave.ogg": "une grotte",
"cavern.ogg": "une caverne",
"celery.ogg": "un céleri",
"centipede.ogg": "un mille-pattes",
"cereal.ogg": "une céréale",
"chain.ogg": "une chaîne",
"chair.ogg": "une chaise",
"chalk.ogg": "une craie",
"chameleon.ogg": "un caméléon",
"chandelier.ogg": "un lustre",
"chat.ogg": "discuter",
"cheek.ogg": "la joue",
"cheer.ogg": "encourager",
"cheese.ogg": "du fromage",
"chef.ogg": "une cuisinière",
"cherry.ogg": "une cerise",
"chest.ogg": "un coffre",
"chick.ogg": "un poussin",
"chicken.ogg": "un poulet",
- "chief.ogg": "un indien",
"child.ogg": "un enfant",
"chimney.ogg": "une cheminée",
"chimp.ogg": "un chimpanzé",
"chin.ogg": "le menton",
"chocolate.ogg": "du chocolat",
"chop.ogg": "découper",
- "chore.ogg": "des tâches ménagères",
+ "chores.ogg": "des tâches ménagères",
"christmas.ogg": "noël",
"cigar.ogg": "un cigare",
"circus.ogg": "un cirque",
"city.ogg": "une ville",
"clam.ogg": "une palourde",
"clap.ogg": "une tape",
"class.ogg": "une classe",
"claw.ogg": "une griffe",
"clay.ogg": "de l'argile",
"clean.ogg": "se laver",
"cleaning_lady.ogg": "une femme de ménage",
"cliff.ogg": "une falaise",
"climb.ogg": "escalader",
"clock.ogg": "un réveil",
"cloth.ogg": "du tissu",
"clothes_hanger.ogg": "un cintre",
"cloud.ogg": "un nuage",
"cloudy.ogg": "nuageux",
"clover.ogg": "un trèfle",
"clown.ogg": "un clown",
"coach.ogg": "une entraîneuse",
"coast.ogg": "une côte",
"coat.ogg": "un manteau",
"cobra.ogg": "un cobra",
"coconut.ogg": "une noix de coco",
"cod.ogg": "une morue",
"coffee.ogg": "un café",
"coin.ogg": "une pièce",
"cold.ogg": "le froid",
"color.ogg": "la couleur",
"colt.ogg": "un poulain",
"comb.ogg": "un peigne",
"cone.ogg": "un cône",
+ "cook.ogg": "cuisiner",
"cookie.ogg": "un biscuit",
"cork.ogg": "un bouchon",
"corn.ogg": "du maïs",
"couch.ogg": "un canapé",
"cough.ogg": "tousser",
"couple.ogg": "un couple",
"cow.ogg": "une vache",
"cowboy.ogg": "un cow-boy",
"crab.ogg": "un crabe",
"cradle.ogg": "un berceau",
"craft.ogg": "des travaux manuels",
"crawl.ogg": "ramper",
"crazy.ogg": "un fou",
"creek.ogg": "un ruisseau",
"crepe.ogg": "une crêpe",
"crib.ogg": "des berceaux",
- "criminal.ogg": "un criminel",
"croak.ogg": "coasser",
"crocodile.ogg": "un crocodile",
"cross.ogg": "une croix",
"crow.ogg": "un corbeau",
"crown.ogg": "une couronne",
"crumb.ogg": "une miette",
"crust.ogg": "une croûte",
"cry.ogg": "pleurer",
"crystal.ogg": "un cristal",
"cube.ogg": "un cube",
"cucumber.ogg": "un concombre",
"curtain.ogg": "un rideau",
"cut.ogg": "couper",
"cute.ogg": "adorable",
"dad.ogg": "un papa",
"daffodil.ogg": "une jonquille",
"daisy.ogg": "une marguerite",
"dam.ogg": "un barrage",
"dance.ogg": "danser",
"dandelion.ogg": "un pissenlit",
- "danger.ogg": "un danger",
- "dark.ogg": "",
"dart_board.ogg": "une cible",
"date_fruit.ogg": "une datte",
"deer.ogg": "un cerf",
"den.ogg": "une tanière",
"desert.ogg": "un désert",
"desk.ogg": "un bureau",
"dessert.ogg": "un dessert",
"diamond.ogg": "un diamant",
"dig.ogg": "creuser",
"dirt.ogg": "le sol",
"dirty.ogg": "sale",
"dish.ogg": "un plat",
"dishcloth.ogg": "un torchon",
"dive.ogg": "plonger",
"doctor.ogg": "une docteure",
"doe.ogg": "une biche",
"dog.ogg": "un chien",
"doll.ogg": "une poupée",
"dolphin.ogg": "un dauphin",
"domino.ogg": "un domino",
"door.ogg": "une porte",
"doormat.ogg": "un paillasson",
"dot.ogg": "un point",
"doughnut.ogg": "un beignet",
"dove.ogg": "une colombe",
"dragon.ogg": "un dragon",
"dragonfly.ogg": "une libellule",
- "drank.ogg": "une boisson",
"draw.ogg": "un dessin",
"drawer.ogg": "un tiroir",
"dream.ogg": "un rêve",
"dress.ogg": "une robe",
"drink.ogg": "une boisson",
- "drinking.ogg": "boire",
"drip.ogg": "une goutte",
"drive.ogg": "conduire",
"drool.ogg": "baver",
"drum.ogg": "un tambour",
"dry.ogg": "sécher",
"duck.ogg": "un canard",
"duck_mother.ogg": "une canne",
"dune.ogg": "une dune",
"dwarf.ogg": "un nain",
"eagle.ogg": "un aigle",
"ear.ogg": "une oreille",
"earth.ogg": "la Terre",
"eat.ogg": "manger",
"egg.ogg": "un oeuf",
"eggplant.ogg": "une aubergine",
"elbow.ogg": "le coude",
"electrician.ogg": "un électricien",
"elk.ogg": "un wapiti",
"empty.ogg": "vide",
"engine.ogg": "un moteur",
"engineer.ogg": "un ingénieur",
"eraser.ogg": "une gomme",
"explore.ogg": "des explorateurs",
"eyelash.ogg": "un cil",
"eyes.ogg": "les yeux",
"face.ogg": "un visage",
"fair.ogg": "un manège",
"fairy.ogg": "une fée",
- "fall_down.ogg": "tomber",
+ "fall.ogg": "tomber",
"fall_season.ogg": "l'automne",
"family.ogg": "une famille",
"fan.ogg": "un ventilateur",
"farm.ogg": "une ferme",
"farmer.ogg": "un fermier",
"fat.ogg": "gras",
"faucet.ogg": "un robinet",
"fawn.ogg": "un faon",
+ "fear.ogg": "avoir peur",
"feast.ogg": "un poulet",
"feather.ogg": "une plume",
"feed.ogg": "nourrir",
- "feet.ogg": "un pied",
- "fell.ogg": "tomber",
"femur.ogg": "un fémur",
"fetch.ogg": "rapporter",
"fig.ogg": "une figue",
"fin.ogg": "une nageoire",
"find.ogg": "trouver",
"finger.ogg": "un doigt",
"fire.ogg": "un feu",
"fire_extinguisher.ogg": "un extincteur",
"fireman.ogg": "un pompier",
"fish.ogg": "un poisson",
"fisherman.ogg": "un pêcheur",
"fist.ogg": "un poing",
"flacon.ogg": "un flacon",
"flag.ogg": "un drapeau",
"flame.ogg": "une flamme",
"flamingo.ogg": "un flamant rose",
"flash.ogg": "une lampe torche",
"flat.ogg": "un appartement",
"flies.ogg": "une mouche",
- "flight.ogg": "un vol",
"float.ogg": "flotter",
"flour.ogg": "la farine",
"flower.ogg": "une fleur",
"fluff.ogg": "une peluche",
"flute.ogg": "une flûte",
"fly.ogg": "voler",
"foam.ogg": "la mousse",
- "food.ogg": "un hamburger",
"foot.ogg": "un pied",
"forest.ogg": "une forêt",
"fork.ogg": "une fourchette",
"fountain.ogg": "une fontaine",
"fox.ogg": "un renard",
"freeze.ogg": "geler",
"friend.ogg": "des amis",
"fries.ogg": "une frite",
"frog.ogg": "une grenouille",
"front.ogg": "devant",
- "frown.ogg": "rechigner",
"fruit.ogg": "un fruit",
"fudge.ogg": "un caramel",
"full.ogg": "plein",
- "fun.ogg": "un jeu",
"fur.ogg": "la fourrure",
"game.ogg": "un jeu",
"garage.ogg": "un garage",
"garden.ogg": "un jardin",
"garlic.ogg": "de l'ail",
"gem.ogg": "une gemme",
"giant.ogg": "un géant",
"gift.ogg": "un cadeau",
"giraffe.ogg": "une girafe",
"girl.ogg": "une fille",
"glass.ogg": "un verre",
"glasses.ogg": "des lunettes",
"glove.ogg": "un gant",
"glue.ogg": "la colle",
"gnome.ogg": "un gnome",
"goat.ogg": "une chèvre",
"golden.ogg": "doré",
"golf.ogg": "le golf",
"goose.ogg": "une oie",
"gorilla.ogg": "un gorille",
"grain.ogg": "un épi",
"grandmother.ogg": "une grand-mère",
"grape.ogg": "une grappe de raisin",
"grapefruit.ogg": "un pamplemousse",
"grass.ogg": "une herbe",
"grave.ogg": "une tombe",
"gray.ogg": "gris",
"green.ogg": "vert",
"grill.ogg": "un barbecue",
"grin.ogg": "un sourire",
"ground.ogg": "la terre",
"growl.ogg": "grogner",
"guignol.ogg": "guignol",
"guinea_pig.ogg": "un cochon d'inde",
"gum.ogg": "du chewing-gum",
"hair.ogg": "les cheveux",
"hair_dryer.ogg": "un sèche-cheveux",
"half.ogg": "la moitié",
"ham.ogg": "un jambon",
"hammer.ogg": "un marteau",
"hand.ogg": "une main",
"handlebar.ogg": "un guidon",
"happy.ogg": "heureux",
"harp.ogg": "une harpe",
"hat.ogg": "un chapeau",
"hatch.ogg": "éclore",
"hay.ogg": "le foin",
"head.ogg": "la tête",
"hear.ogg": "entendre",
"heat.ogg": "la chaleur",
"hedge.ogg": "une bordure",
"hedgehog.ogg": "un hérisson",
"heel.ogg": "le talon",
"helmet.ogg": "un casque",
"hen.ogg": "une poule",
"herd.ogg": "un troupeau",
"high.ogg": "haut",
"hike.ogg": "une promenade",
"hill.ogg": "une colline",
"hip.ogg": "une hanche",
"hippopotamus.ogg": "un hippopotame",
"hit.ogg": "une bagarre",
"hive.ogg": "une ruche",
"hockey.ogg": "le hockey",
"hole.ogg": "un trou",
"home.ogg": "une maison",
"hook.ogg": "un hameçon",
"hop.ogg": "rebondir",
"horse.ogg": "un cheval",
"hose.ogg": "un tuyau",
"hospital.ogg": "un hôpital",
"hot.ogg": "chaud",
"hot_dog.ogg": "un hot-dog",
"hound.ogg": "un chien de chasse",
"house.ogg": "une maison",
"howl.ogg": "un hurlement",
"hug.ogg": "un calin",
"huge.ogg": "énorme",
"hummingbird.ogg": "un colibri",
- "hunchback.ogg": "un bossu",
+ "hunchbacked.ogg": "bossu",
"hunter.ogg": "un chasseur",
"husband.ogg": "un mari",
"hut.ogg": "une hutte",
"hyena.ogg": "une hyène",
"ice.ogg": "un glaçon",
"iceberg.ogg": "un iceberg",
"iguana.ogg": "un iguane",
"ill.ogg": "malade",
"ink.ogg": "de l'encre",
"island.ogg": "une île",
"jacket.ogg": "une veste",
"jaguar.ogg": "un jaguar",
"jam.ogg": "une confiture",
"jay.ogg": "un geai",
"jelly.ogg": "une gelée",
"jellyfish.ogg": "une méduse",
"jewel.ogg": "un bijou",
"job.ogg": "un travail",
"jockey.ogg": "un jockey",
"jog.ogg": "un joggeur",
+ "joy.ogg": "être content",
"judge.ogg": "un juge",
"judo.ogg": "une judokate",
"juggler.ogg": "une jongleuse",
"juice.ogg": "un jus",
"jump.ogg": "sauter",
"kangaroo.ogg": "un kangourou",
"keel.ogg": "une quille",
"kernel.ogg": "un noyau",
"keyboard.ogg": "un clavier",
"kimono.ogg": "un kimono",
"king.ogg": "un roi",
"kiss.ogg": "un baiser",
"kitchen.ogg": "une cuisine",
"kite.ogg": "un cerf-volant",
"kitten.ogg": "un chaton",
"kiwi.ogg": "un kiwi",
"knee.ogg": "un genou",
"kneel.ogg": "s'agenouiller",
"knife.ogg": "un couteau",
"knight.ogg": "un chevalier",
"knit.ogg": "tricoter",
"knot.ogg": "un noeud",
"koala.ogg": "un koala",
"lad.ogg": "un garçon",
"lady.ogg": "une dame",
"ladybug.ogg": "une coccinelle",
"lake.ogg": "un lac",
"lama.ogg": "un lama",
"lamb.ogg": "un agneau",
"lamp.ogg": "une lampe",
"land.ogg": "un terrain",
"lane.ogg": "le chemin",
- "lap.ogg": "",
"lasso.ogg": "un lasso",
"laugh.ogg": "rire",
"lava.ogg": "la lave",
"lawn.ogg": "la pelouse",
"lawyer.ogg": "un avocat",
"leaf.ogg": "une feuille",
"ledge.ogg": "un rebord",
"leek.ogg": "un poireau",
"left.ogg": "la gauche",
"leg.ogg": "la jambe",
- "leg_animal.ogg": "la patte",
"lemon.ogg": "un citron",
"lemonade.ogg": "une limonade",
"lemur.ogg": "un lémur",
"leopard.ogg": "un léopard",
"lettuce.ogg": "une laitue",
"librarian.ogg": "une bibliothécaire",
"lick.ogg": "lécher",
"lid.ogg": "un couvercle",
"lift.ogg": "soulever",
"light.ogg": "la lumière",
"lighthouse.ogg": "un phare",
"lightning.ogg": "la foudre",
"lilac.ogg": "un lilas",
"lime.ogg": "un citron vert",
"line.ogg": "un code-barres",
"link.ogg": "un chaînon",
"lion.ogg": "un lion",
"lion_cub.ogg": "un lionceau",
"lip.ogg": "une lèvre",
"liquid.ogg": "un liquide",
"lizard.ogg": "un lézard",
"lobster.ogg": "un homard",
"log.ogg": "une bûche",
"look.ogg": "regarder",
"lunch.ogg": "un casse-croûte",
- "mad.ogg": "la colère",
+ "mad.ogg": "être furieux",
"magic.ogg": "un magicien",
"magnet.ogg": "un aimant",
"magnifying_glass.ogg": "une loupe",
"magpie.ogg": "une pie",
"mail.ogg": "une enveloppe",
"man.ogg": "un homme",
"mane.ogg": "une crinière",
"mango.ogg": "une mangue",
"map.ogg": "une carte",
"maple.ogg": "un érable",
"marble.ogg": "une bille",
"mashed_potatoes.ogg": "une purée",
"mask.ogg": "un masque",
"mast.ogg": "un mât",
"mat.ogg": "une natte",
"match.ogg": "une allumette",
"mate.ogg": "un camarade",
"mattress.ogg": "un matelas",
"mauve.ogg": "violet",
"meal.ogg": "un repas",
"meat.ogg": "de la viande",
"mechanic.ogg": "un mécanicien",
"medal.ogg": "une médaille",
"meet.ogg": "rencontrer",
"melon.ogg": "un melon",
- "men.ogg": "une foule",
"merry-go-round.ogg": "un tourniquet",
"mice.ogg": "des souris",
"microphone.ogg": "un micro",
"milk.ogg": "du lait",
"mill.ogg": "un moulin",
"mimosa.ogg": "un mimosa",
"mirror.ogg": "un miroir",
"mixer.ogg": "un mixer",
"mole.ogg": "une taupe",
"mom.ogg": "une maman",
"moon.ogg": "une lune",
"moose.ogg": "un élan",
"mop.ogg": "un balai",
"mosque.ogg": "une mosquée",
"mosquito.ogg": "un moustique",
"mother.ogg": "une mère",
"motorcycle.ogg": "une moto",
"mountain.ogg": "une montagne",
"mouse.ogg": "une souris",
"mouth.ogg": "une bouche",
"movie.ogg": "un film",
"mower.ogg": "une tondeuse",
"mud.ogg": "la boue",
"mug.ogg": "une tasse",
"mule.ogg": "une mule",
"muscle.ogg": "un muscle",
"mushroom.ogg": "un champignon",
"music.ogg": "la musique",
"musician.ogg": "un musicien",
"naked.ogg": "nu",
"nap.ogg": "une sieste",
"navel.ogg": "le nombril",
"neck.ogg": "le cou",
"necklace.ogg": "un collier",
"needle.ogg": "une aiguille",
"nest.ogg": "un nid",
"net.ogg": "un filet",
"newspaper.ogg": "un journal",
"night.ogg": "la nuit",
"nightgown.ogg": "une chemise de nuit",
"nose.ogg": "le nez",
"nostril.ogg": "la narine",
"notebook.ogg": "un cahier",
"number.ogg": "un nombre",
"nun.ogg": "une religieuse",
"nurse.ogg": "une infirmière",
"nurse_male.ogg": "un infirmier",
"nut.ogg": "une cacahuète",
"oar.ogg": "une rame",
"ocean.ogg": "un océan",
"office.ogg": "un bureau",
"olive.ogg": "une olive",
"on.ogg": "sur",
"onion.ogg": "un oignon",
"open.ogg": "ouvert",
"opossum.ogg": "un opossum",
"orange-color.ogg": "orange",
"orange.ogg": "une orange",
"orchid.ogg": "une orchidée",
"ostrich.ogg": "une autruche",
"otter.ogg": "une loutre",
"owl.ogg": "un hibou",
"ox.ogg": "un boeuf",
"oyster.ogg": "une huître",
"pacifier.ogg": "une tétine",
"page.ogg": "une page",
"pair.ogg": "une paire",
"pajamas.ogg": "un pyjama",
- "pal.ogg": "",
"palm_tree.ogg": "un palmier",
"pan.ogg": "une poêle",
"panda.ogg": "un panda",
"panther.ogg": "une panthère",
"panties.ogg": "une culotte",
"pants.ogg": "un pantalon",
"papaya.ogg": "une papaye",
"paper.ogg": "un papier",
"parachute.ogg": "un parachute",
"parakeet.ogg": "une perruche",
"parrot.ogg": "un perroquet",
"patch.ogg": "une pièce",
"path.ogg": "un chemin",
"paw.ogg": "une patte",
"pea.ogg": "un petit pois",
"peach.ogg": "une pêche",
"peacock.ogg": "un paon",
"peak.ogg": "un pic",
"pear.ogg": "une poire",
"pearl.ogg": "une perle",
"peck.ogg": "picorer",
"pedal.ogg": "une pédale",
"pelican.ogg": "un pélican",
"pen.ogg": "un stylo",
"pencil.ogg": "un crayon",
"peony.ogg": "une pivoine",
"people.ogg": "les gens",
"pepper.ogg": "le poivre",
"peppers.ogg": "un poivron",
- "pet.ogg": "",
"petal.ogg": "un pétale",
- "petite.ogg": "la petite",
"phone.ogg": "un téléphone",
"piano.ogg": "un piano",
"picture.ogg": "une photo",
"pie.ogg": "une tarte",
"pig.ogg": "un cochon",
"pigeon.ogg": "un pigeon",
"pill.ogg": "une pilule",
"pillow.ogg": "un oreiller",
"pilot.ogg": "un pilote",
"pine.ogg": "un pin",
"pine_cone.ogg": "une pomme de pin",
"pink.ogg": "rose",
"pip.ogg": "un pépin",
"pipe.ogg": "une pipe",
"piranha.ogg": "un piranha",
"pirate.ogg": "un pirate",
"pizza.ogg": "une pizza",
"plane.ogg": "un avion",
"planet.ogg": "une planète",
"plant.ogg": "une plante",
"plate.ogg": "une assiette",
"play.ogg": "jouer",
"pliers.ogg": "une pince",
"plow.ogg": "labourer",
"plum.ogg": "une prune",
"plumber.ogg": "un plombier",
"pocket.ogg": "une poche",
"pod.ogg": "une cosse",
"pole.ogg": "un poteau",
"police.ogg": "un policier",
"pompon.ogg": "un pompon",
"pond.ogg": "un étang",
"pony.ogg": "un poney",
"pool.ogg": "une piscine",
- "pop.ogg": "du pop-corn",
+ "popcorn.ogg": "du pop-corn",
"pope.ogg": "le pape",
"porthole.ogg": "un hublot",
"post.ogg": "une boîte aux lettres",
"pot.ogg": "un pot",
"potato.ogg": "une pomme de terre",
"pounce.ogg": "bondir",
"president.ogg": "le président",
"pretty.ogg": "jolie",
"price.ogg": "le prix",
"priest.ogg": "un prêtre",
"prince.ogg": "un prince",
"princess.ogg": "une princesse",
"prison.ogg": "une prison",
"prisoner.ogg": "un prisonnier",
"prize.ogg": "un trophée",
"pug.ogg": "un bouledogue",
"pull.ogg": "tirer",
"pullover.ogg": "un pull-over",
"pumpkin.ogg": "une citrouille",
"puppy.ogg": "un chiot",
"pyramid.ogg": "une pyramide",
"quarrel.ogg": "se quereller",
"queen.ogg": "une reine",
"question.ogg": "une question",
"quilt.ogg": "une couette",
"quiz.ogg": "un quiz",
"rabbit.ogg": "un lapin",
"rabbit_baby.ogg": "un lapereau",
"race.ogg": "une course",
"radio.ogg": "une radio",
"radish.ogg": "un radis",
"raft.ogg": "un radeau",
- "rag.ogg": "",
"rage.ogg": "la rage",
"rain.ogg": "la pluie",
"raincoat.ogg": "un imperméable",
"rake.ogg": "un râteau",
"ramp.ogg": "une rampe",
- "ran.ogg": "",
"raspberry.ogg": "une framboise",
"rat.ogg": "un rat",
"razor.ogg": "un rasoir",
"read.ogg": "lire",
"red.ogg": "rouge",
"reptile.ogg": "un reptile",
"rhinoceros.ogg": "un rhinocéros",
"rice.ogg": "le riz",
- "ride.ogg": "",
"rifle.ogg": "un fusil",
"right.ogg": "la droite",
"rip.ogg": "déchirer",
"rise.ogg": "augmenter",
"river.ogg": "une rivière",
"road.ogg": "une route",
"roast.ogg": "un rôti",
- "robe.ogg": "",
"robot.ogg": "un robot",
"rock.ogg": "un caillou",
"rocket.ogg": "une fusée",
"rolling_pin.ogg": "un rouleau",
"roof.ogg": "un toit",
"room.ogg": "une pièce",
"root.ogg": "une racine",
"rope.ogg": "une corde",
"rose.ogg": "une rose",
"round.ogg": "un rond",
"rowing.ogg": "un aviron",
"royal.ogg": "royal",
"rug.ogg": "un tapis",
"run.ogg": "courir",
"sad.ogg": "triste",
"saddle.ogg": "une selle",
"sail.ogg": "un voilier",
"sailor.ogg": "un marin",
"salamander.ogg": "une salamandre",
"salmon.ogg": "un saumon",
"sand.ogg": "le sable",
"sandals.ogg": "une sandale",
"sandwich.ogg": "un sandwich",
"sash.ogg": "une ceinture",
- "sat.ogg": "s'asseoir",
"sauce.ogg": "une sauce",
"sausage.ogg": "une saucisse",
"scale.ogg": "une balance",
"scar.ogg": "une cicatrice",
- "scared.ogg": "effrayé",
+ "scare.ogg": "effrayé",
"scarf.ogg": "une écharpe",
"school.ogg": "une école",
"school_bag.ogg": "un sac",
"science.ogg": "la science",
"scissors.ogg": "un ciseau",
"scorpion.ogg": "un scorpion",
"scratch.ogg": "griffer",
"scream.ogg": "crier",
"screw.ogg": "une vis",
"screwdriver.ogg": "un tournevis",
"scribble.ogg": "gribouiller",
"sea.ogg": "la mer",
"seat.ogg": "un siège",
"see.ogg": "voir",
"seed.ogg": "une graine",
"shadow.ogg": "une ombre",
"shake.ogg": "secouer",
"shark.ogg": "un requin",
"shave.ogg": "se raser",
"shed.ogg": "un hangar",
"sheep.ogg": "un mouton",
"shelf.ogg": "une étagère",
"shell.ogg": "un coquillage",
"ship.ogg": "un bateau",
"shirt.ogg": "une chemise",
"shoe.ogg": "une chaussure",
"shoelace.ogg": "un lacet",
"shop.ogg": "un magasin",
"shore.ogg": "un rivage",
"short.ogg": "un short",
"shovel.ogg": "une pelle",
"shower.ogg": "une douche",
"shrimp.ogg": "une crevette",
"shrub.ogg": "un arbuste",
"shut.ogg": "fermé",
"shutter.ogg": "un volet",
"sick.ogg": "malade",
"sidewalk.ogg": "un trottoir",
"sign.ogg": "un panneau",
"sing.ogg": "chanter",
"sink.ogg": "un évier",
"sip.ogg": "siroter",
"sister.ogg": "une soeur",
"sit.ogg": "s'asseoir",
"skate.ogg": "un skate",
"skeleton.ogg": "un squelette",
"ski.ogg": "le ski",
"skimmer.ogg": "une écumoire",
"skin.ogg": "la peau",
"skirt.ogg": "une jupe",
"skunk.ogg": "une mouffette",
"sky.ogg": "le ciel",
"slam.ogg": "smasher",
"sled.ogg": "une luge",
"sleep.ogg": "dormir",
"sleeve.ogg": "une manche",
"sleigh.ogg": "un traîneau",
"slide.ogg": "un toboggan",
"slim.ogg": "mince",
"slime.ogg": "la bave",
"slippers.ogg": "un chausson",
"slope.ogg": "une pente",
"sloppy.ogg": "trempé",
"slot.ogg": "une fente",
"sloth.ogg": "un paresseux",
"slug.ogg": "une limace",
"small.ogg": "le petit",
"smell.ogg": "sentir",
"smile.ogg": "un sourire",
"smock.ogg": "une blouse",
"smoke.ogg": "la fumée",
"smooch.ogg": "s'embrasser",
- "snack.ogg": "",
"snail.ogg": "un escargot",
"snake.ogg": "un serpent",
"sneaker.ogg": "une basket",
"sniff.ogg": "renifler",
"snow.ogg": "la neige",
"soap.ogg": "le savon",
"sob.ogg": "sangloter",
"sock.ogg": "une chaussette",
"soldier.ogg": "un soldat",
"sole.ogg": "une sole",
"sole_shoe.ogg": "une semelle",
"son.ogg": "un fils",
"soup.ogg": "une soupe",
"spade.ogg": "une bêche",
"spaghetti.ogg": "un spaghetti",
"spark.ogg": "une étincelle",
"sparrow.ogg": "un moineau",
"spatula.ogg": "une spatule",
"speak.ogg": "parler",
"spear.ogg": "une lance",
"spice.ogg": "un épice",
"spider.ogg": "une araignée",
"spider_web.ogg": "une toile d'araignée",
"spike.ogg": "un hérisson",
"spill.ogg": "répandre",
"spinach.ogg": "un épinard",
"spine.ogg": "une colonne vertébrale",
"spinning_top.ogg": "une toupie",
"splash.ogg": "un jet",
"splatter.ogg": "une éclaboussure",
"sponge.ogg": "une éponge",
"spool.ogg": "une bobine",
"spoon.ogg": "une cuillère",
"sport.ogg": "le sport",
"spot.ogg": "une tâche",
"spray.ogg": "pulvériser",
"spread.ogg": "étaler",
"spring.ogg": "bondir",
"spring_season.ogg": "le printemps",
- "sprinkle.ogg": "",
"square.ogg": "un carré",
"squash.ogg": "une courge",
"squat.ogg": "s'accroupir",
"squid.ogg": "un calmar",
"squirrel.ogg": "un écureuil",
- "squirt.ogg": "",
"stack.ogg": "une pile",
"stage.ogg": "une scène",
"staircase.ogg": "un escalier",
"stamp.ogg": "un timbre",
"stand.ogg": "debout",
"star.ogg": "une étoile",
"stare.ogg": "un regard",
"starfish.ogg": "une étoile de mer",
- "steak.ogg": "un steak",
"steam.ogg": "la vapeur",
"steep.ogg": "raide",
"steeple.ogg": "un clocher",
"stem.ogg": "une tige",
"step.ogg": "une marche",
"stew.ogg": "un ragoût",
"stick.ogg": "une branche",
"sting.ogg": "piquer",
"stinky.ogg": "puant",
"stitch.ogg": "coudre",
"stomach.ogg": "un estomac",
"stone.ogg": "une pierre",
"stop.ogg": "arrêter",
"store.ogg": "un magasin",
"stove.ogg": "une cuisinière",
"straight.ogg": "droit",
"strainer.ogg": "une passoire",
"straw.ogg": "une paille",
"strawberry.ogg": "une fraise",
"stream.ogg": "une rivière",
"street.ogg": "une rue",
"stretch.ogg": "s'étirer",
"string.ogg": "une ficelle",
"stripe.ogg": "une bande",
"strong.ogg": "fort",
"student.ogg": "un étudiant",
"study.ogg": "étudier",
"stump.ogg": "une souche",
"sugar.ogg": "un sucre",
"suit.ogg": "un costume",
"suitcase.ogg": "une valise",
"summer.ogg": "un été",
"summit.ogg": "un sommet",
"sun.ogg": "le soleil",
"swan.ogg": "un cygne",
"sweat.ogg": "transpirer",
"sweatshirt.ogg": "un sweat-shirt",
"swim.ogg": "nager",
"table.ogg": "une table",
"tablecloth.ogg": "une nappe",
"tadpole.ogg": "un têtard",
"tag.ogg": "une étiquette",
"tail.ogg": "une queue",
"tall.ogg": "grand",
"tape_measure.ogg": "un mètre",
"taxi.ogg": "un taxi",
"teach.ogg": "enseigner",
"teacher.ogg": "un professeur",
"tear.ogg": "déchirer",
"teddy.ogg": "une peluche",
"teeth.ogg": "les dents",
"television.ogg": "une télévision",
"temple.ogg": "un temple",
"tennis.ogg": "le tennis",
"tent.ogg": "une tente",
"text.ogg": "un texte",
"thick.ogg": "épais",
"thief.ogg": "un voleur",
"thigh.ogg": "une cuisse",
"think.ogg": "penser",
"thread.ogg": "une bobine",
"throat.ogg": "la gorge",
"throw.ogg": "envoyer",
"thumb.ogg": "un pouce",
- "tick.ogg": "",
"ticket.ogg": "un billet",
"tiger.ogg": "un tigre",
"time.ogg": "le temps",
"tin.ogg": "une conserve",
"tire.ogg": "un pneu",
"tired.ogg": "fatigué",
"tissue.ogg": "un mouchoir",
+ "to_drink.ogg": "boire",
"toad.ogg": "un crapaud",
"toaster.ogg": "un grille-pain",
"toe.ogg": "un orteil",
"toilet.ogg": "les toilettes",
"tomatoe.ogg": "une tomate",
"tongs.ogg": "une pince",
"tongue.ogg": "une langue",
"tool.ogg": "un outil",
"top.ogg": "dessus",
"torch.ogg": "une torche",
"touch.ogg": "toucher",
"towel.ogg": "une serviette",
"toy.ogg": "un jouet",
"trail.ogg": "une piste",
"train.ogg": "un train",
"train_station.ogg": "une gare",
"trap.ogg": "un piège",
"trash.ogg": "la saleté",
"tray.ogg": "un plateau",
"treat.ogg": "un bonbon",
"tree.ogg": "un arbre",
"triangle.ogg": "un triangle",
"tribe.ogg": "une tribu",
"trip.ogg": "un voyage",
"truck.ogg": "un camion",
"tube.ogg": "un rouge à lèvres",
"tulip.ogg": "une tulipe",
"tune.ogg": "un air de musique",
"turkey.ogg": "une dinde",
"turnip.ogg": "un navet",
"turtle.ogg": "une tortue",
"tusk.ogg": "une défense",
"twin_boys.ogg": "un jumeau",
"twin_girls.ogg": "une jumelle",
"umbrella.ogg": "un parapluie",
"under.ogg": "sous",
"uniform.ogg": "un uniforme",
"van.ogg": "un fourgon",
- "vapor.ogg": "",
"vase.ogg": "un vase",
"vegetable.ogg": "un légume",
"vein.ogg": "une veine",
"verdure.ogg": "la verdure",
"vest.ogg": "un gilet",
"vet.ogg": "un vétérinaire",
"viper.ogg": "une vipère",
"vowel.ogg": "une voyelle",
"vulture.ogg": "un vautour",
"wag.ogg": "remuer la queue",
"walk.ogg": "marcher",
"wall.ogg": "un mur",
"walnut.ogg": "une noix",
"wart.ogg": "une verrue",
- "wash.ogg": "",
+ "wash.ogg": "se laver",
"wasp.ogg": "une guêpe",
"watch.ogg": "une montre",
"water.ogg": "de l'eau",
"wave.ogg": "une vague",
"wedding.ogg": "un mariage",
"wedge.ogg": "une cale",
"weight.ogg": "un poids",
"wet.ogg": "humide",
"whale.ogg": "une baleine",
"wheat.ogg": "le blé",
"wheel.ogg": "une roue",
"whisk.ogg": "un fouet",
"whisper.ogg": "chuchoter",
"white.ogg": "blanc",
"wide.ogg": "large",
- "wife.ogg": "",
+ "wife.ogg": "une épouse",
"wig.ogg": "une perruque",
"win.ogg": "gagner",
"wind.ogg": "le vent",
"window.ogg": "une fenêtre",
"window_glass.ogg": "une vitre",
"wing.ogg": "une aile",
"winter.ogg": "un hiver",
"wolf.ogg": "un loup",
"woman.ogg": "une femme",
"wood.ogg": "le bois",
"word.ogg": "un mot",
"worker.ogg": "un travailleur",
"world.ogg": "le monde",
"wreath.ogg": "une couronne",
"wrench.ogg": "une clé",
"wrist.ogg": "un poignet",
"write.ogg": "écrire",
"yellow.ogg": "jaune",
"yogurt.ogg": "un yaourt",
"yum.ogg": "miam-miam",
"zebra.ogg": "un zèbre",
"zipper.ogg": "une fermeture éclair",
"zoo.ogg": "un zoo"
-}
+}
\ No newline at end of file
diff --git a/src/activities/lang/resource/content-ga.json b/src/activities/lang/resource/content-ga.json
index 38fa72240..eb7cc5680 100755
--- a/src/activities/lang/resource/content-ga.json
+++ b/src/activities/lang/resource/content-ga.json
@@ -1,1121 +1,1083 @@
{
"10.ogg": "a deich",
"11.ogg": "a haon déag",
"12.ogg": "a dó dhéag",
"16.ogg": "a sé déag",
"U0030.ogg": "a náid",
"U0031.ogg": "a haon",
"U0032.ogg": "a dó",
"U0033.ogg": "a trí",
"U0034.ogg": "a ceathair",
"U0035.ogg": "a cúig",
"U0036.ogg": "a sé",
"U0037.ogg": "a seacht",
"U0038.ogg": "a hocht",
"U0039.ogg": "a naoi",
"accountant.ogg": "cuntasóir",
"ache.ogg": "pian",
"acorn.ogg": "dearcán",
"actor.ogg": "aisteoir",
"air_horn.ogg": "corn",
"alarmclock.ogg": "clog aláraim",
"alligator.ogg": "ailigéadar",
"alphabet.ogg": "aibítir",
"anchor.ogg": "ancaire",
"angel.ogg": "aingeal",
"angry.ogg": "feargach",
"animal.ogg": "ainmhithe",
"ankle.ogg": "murnán",
"ant.ogg": "seangán",
"anteater.ogg": "alpaire seangán",
"antelope.ogg": "antalóp",
"apple.ogg": "úll",
"apple_tree.ogg": "crann úll",
"appliance.ogg": "fearas tí",
"apricot.ogg": "aibreog",
"arm.ogg": "sciathán",
"armchair.ogg": "cathaoir uillinne",
"artichoke.ogg": "bliosán",
"artist.ogg": "ealaíontóir",
"asparagus.ogg": "asparagas",
"astronaut.ogg": "spásaire",
"athlete.ogg": "lúthchleasaí",
"avocado.ogg": "abhacád",
"ax.ogg": "tua",
"baby_bottle.ogg": "buidéal linbh",
"back.ogg": "droim",
"badge.ogg": "suaitheantas",
"bag.ogg": "mála",
"bait.ogg": "baoite",
- "bake.ogg": "bácáil",
"balance.ogg": "scálaí",
"bald.ogg": "maol",
"ball.ogg": "liathróid",
"ball_of_yarn.ogg": "bál snáth",
"ball_soccer.ogg": "liathróid sacair",
"ballet.ogg": "bailé",
"bank.ogg": "banc",
"bark.ogg": "tafann",
"barn.ogg": "scioból",
"bat.ogg": "sciathán leathair",
"bath.ogg": "dabhach",
"bathing_suit.ogg": "culaith shnámha",
"bay.ogg": "cuan",
"beach.ogg": "trá",
- "bead.ogg": "coirnín",
"bean.ogg": "pónaire",
"bear.ogg": "béar",
"beard.ogg": "féasóg",
"beat.ogg": "buail",
"beaver.ogg": "béabhar",
"bed.ogg": "leaba",
"bedroom.ogg": "seomra leapa",
"bee.ogg": "bumbóg",
- "beef.ogg": "mairteoil",
"beetle.ogg": "ciaróg",
"beg.ogg": "ag lorg déirce",
"behind.ogg": "ar chúl",
"bell.ogg": "cloigín",
"belly.ogg": "bolg",
"bench.ogg": "binse",
"bib.ogg": "bráidín",
"big.ogg": "mór",
"big_top.ogg": "puball sorcais",
"bike.ogg": "rothar",
"bird.ogg": "éan",
"bit.ogg": "greim",
"bite.ogg": "plaic",
"black.ogg": "dubh",
"blackberry.ogg": "sméara dubha",
"blackbird.ogg": "lon dubh",
"blade.ogg": "lann",
"blind.ogg": "dall",
"blink.ogg": "caoch",
"block.ogg": "bloicín",
"blond.ogg": "fionn",
"blue.ogg": "gorm",
"blueberry.ogg": "sméara gorma",
"blush.ogg": "luisne",
"board.ogg": "clár",
"boat.ogg": "bád",
"boil.ogg": "bruith",
"bolt.ogg": "bolta",
"bomb.ogg": "buama",
"bone.ogg": "cnámh",
"book.ogg": "leabhar",
"bookcase.ogg": "leabhragán",
"bottom.ogg": "tóin",
"box.ogg": "dornálaíocht",
"boxer.ogg": "dornálaí",
"boy.ogg": "buachaill",
"braid.ogg": "trilseán",
"brain.ogg": "inchinn",
"branch.ogg": "géag",
"bread.ogg": "arán",
"break.ogg": "briseadh",
"breast.ogg": "brollach",
"brick.ogg": "bríce",
"bricklayer.ogg": "bríceadóir",
"bride.ogg": "brídeach",
"bridge.ogg": "droichead",
"bright.ogg": "geal",
"broccoli.ogg": "brocailí",
"brother.ogg": "deartháir",
"brown.ogg": "donn",
"brush.ogg": "scuab",
"bubble.ogg": "bolgánach",
"bucket.ogg": "buicéad",
"bud.ogg": "bachlóg",
"buffalo.ogg": "buabhall",
"bug.ogg": "feithid",
"bulb.ogg": "bolgán",
"bull.ogg": "tarbh",
"bump.ogg": "cnapán",
"bun.ogg": "bunóg",
"bus.ogg": "bus",
"bush.ogg": "tom",
"butcher.ogg": "búistéir",
"butter.ogg": "im",
"butterfly.ogg": "féileacán",
"button.ogg": "cnaipe",
"cabbage.ogg": "cál",
"cabin.ogg": "bothán",
"cacao.ogg": "pónaire chacó",
"cactus.ogg": "cachtas",
"cage.ogg": "cás leoin",
"cake.ogg": "cáca",
"call.ogg": "glao",
"camel.ogg": "camall",
"camera.ogg": "ceamara",
"camp.ogg": "campáil",
"can.ogg": "canna",
"canary.ogg": "canáraí",
"candle.ogg": "coinneal",
"candy.ogg": "milseán",
"cane.ogg": "slat",
"canoe.ogg": "canú",
"canon.ogg": "canóin",
"canyon.ogg": "cainneon",
"cap.ogg": "caipín",
"cape.ogg": "clóca",
"car.ogg": "carr",
"carafe.ogg": "caraf",
"card.ogg": "cárta",
"carnival.ogg": "féile",
"carpenter.ogg": "siúinéir",
"carpet.ogg": "cairpéad",
"carrot.ogg": "meacan dearg",
"cart.ogg": "cairt",
"cash.ogg": "airgead",
"castle.ogg": "caisleán",
"cat.ogg": "cat",
"cat_female.ogg": "cat baineann",
"catch.ogg": "ceap",
"caterpillar.ogg": "péist cháil",
"cauldron.ogg": "coire",
"cauliflower.ogg": "cóilis",
"cave.ogg": "pluais",
"cavern.ogg": "uaimh",
"celery.ogg": "soilire",
"centipede.ogg": "céadchosach",
"cereal.ogg": "arbhar",
"chain.ogg": "slabhra",
"chair.ogg": "cathaoir",
"chalk.ogg": "cailc",
"chameleon.ogg": "caimileon",
"chandelier.ogg": "crann solais",
"chat.ogg": "comhrá",
"cheek.ogg": "leiceann",
"cheer.ogg": "gáir mholta",
"cheese.ogg": "cáis",
"chef.ogg": "cócaire",
"cherry.ogg": "silíní",
"chest.ogg": "cófra",
"chick.ogg": "sicín",
"chicken.ogg": "cearc",
- "chief.ogg": "taoiseach",
"child.ogg": "páiste",
"chimney.ogg": "simléir",
"chimp.ogg": "moncaí",
"chin.ogg": "smig",
"chocolate.ogg": "seacláid",
"chop.ogg": "ag gearradh",
- "chore.ogg": "obair tí",
"christmas.ogg": "nollaig",
"cigar.ogg": "todóg",
"circus.ogg": "sorcas",
"city.ogg": "cathair",
"clam.ogg": "breallacán",
"clap.ogg": "bualadh bos",
"class.ogg": "rang",
"claw.ogg": "crúb",
"clay.ogg": "cré",
"clean.ogg": "glan",
"cleaning_lady.ogg": "bean ghlantacháin",
"cliff.ogg": "aill",
"climb.ogg": "dreapadóireacht",
"clock.ogg": "clog",
"cloth.ogg": "bratóg",
"clothes_hanger.ogg": "crochadán éadaigh",
"cloud.ogg": "scamall",
"cloudy.ogg": "scamallach",
"clover.ogg": "seamair",
"clown.ogg": "fear grinn",
"coach.ogg": "bainisteoir",
"coast.ogg": "cósta",
"coat.ogg": "cóta",
"cobra.ogg": "cobra",
"coconut.ogg": "cnó cócó",
"cod.ogg": "trosc",
"coffee.ogg": "caife",
"coin.ogg": "boinn",
"cold.ogg": "fuar",
"color.ogg": "dath",
"colt.ogg": "bromach",
"comb.ogg": "cíor",
"cone.ogg": "coirceog",
"cookie.ogg": "briosca",
"cork.ogg": "corc",
"corn.ogg": "arbhar milis",
"couch.ogg": "tolg",
"cough.ogg": "casachtach",
"couple.ogg": "cúpla",
"cow.ogg": "bó",
"cowboy.ogg": "buachaill bó",
"crab.ogg": "crúbóg",
"cradle.ogg": "cliabhán",
"craft.ogg": "ceardaíocht",
"crawl.ogg": "lámhacán",
"crazy.ogg": "craiceáilte",
"creek.ogg": "sruthán",
"crepe.ogg": "sípris",
"crib.ogg": "cliabhán",
- "criminal.ogg": "coirpeach",
"croak.ogg": "grág",
"crocodile.ogg": "crogall",
"cross.ogg": "cros",
"crow.ogg": "préachán",
"crown.ogg": "coróin",
"crumb.ogg": "grabhróg",
"crust.ogg": "crústa",
"cry.ogg": "caoineadh",
"crystal.ogg": "criostal",
"cube.ogg": "ciúb",
"cucumber.ogg": "cúcamar",
"curtain.ogg": "cuirtín",
"cut.ogg": "gearr",
"cute.ogg": "gleoite",
"dad.ogg": "athair",
"daffodil.ogg": "lus an chromchinn",
"daisy.ogg": "nóinín",
"dam.ogg": "damba",
"dance.ogg": "damhsa",
"dandelion.ogg": "caisearbhán",
- "danger.ogg": "dainséar",
- "dark.ogg": "dorcha",
"dart_board.ogg": "clár dairteanna",
"date_fruit.ogg": "pailm dhátaí",
"deer.ogg": "fia",
"den.ogg": "pluais",
"desert.ogg": "milseog",
"desk.ogg": "deasc",
"dessert.ogg": "milseog",
"diamond.ogg": "diamant",
"dig.ogg": "tochail",
"dirt.ogg": "salachar",
"dirty.ogg": "salach",
"dish.ogg": "mias",
"dishcloth.ogg": "éadach soithí",
"dive.ogg": "tum",
"doctor.ogg": "dochtúir",
"doe.ogg": "coinín baineann",
"dog.ogg": "madadh",
"doll.ogg": "bábóg",
"dolphin.ogg": "deilfín",
"domino.ogg": "domanó",
"door.ogg": "doras",
"doormat.ogg": "mata tairsí",
"dot.ogg": "ponc",
"doughnut.ogg": "taoschnó",
"dove.ogg": "colm",
"dragon.ogg": "dragún",
"dragonfly.ogg": "snáthaid mhór",
- "drank.ogg": "d'ól",
"draw.ogg": "tarraing",
"drawer.ogg": "tarraiceán",
"dream.ogg": "brionglóid",
"dress.ogg": "culaith",
"drink.ogg": "deoch",
- "drinking.ogg": "Ól",
"drip.ogg": "sil",
"drive.ogg": "tiomáint",
"drool.ogg": "ag priosláil",
"drum.ogg": "druma",
"dry.ogg": "tirim",
"duck.ogg": "lachan",
"duck_mother.ogg": "lachan",
"dune.ogg": "dumhach",
"dwarf.ogg": "leipreachán",
"eagle.ogg": "iolar",
"ear.ogg": "cluas",
"earth.ogg": "an Domhan",
"eat.ogg": "ith",
"egg.ogg": "ubh",
"eggplant.ogg": "ubhthoradh",
- "eight.ogg": "a hocht",
"elbow.ogg": "uillinn",
"electrician.ogg": "leictreoir",
- "eleven.ogg": "a haon déag",
"elk.ogg": "fia mór",
"empty.ogg": "folamh",
"engine.ogg": "inneall",
"engineer.ogg": "innealtóir",
"eraser.ogg": "glantóir",
"explore.ogg": "taiscéalaíocht",
"eyelash.ogg": "fabhra",
"eyes.ogg": "súile",
"face.ogg": "aghaidh",
"fair.ogg": "aonach",
"fairy.ogg": "sióg",
- "fall_down.ogg": "tit",
+ "fall.ogg": "leag",
"fall_season.ogg": "fómhar",
"family.ogg": "teaghlach",
"fan.ogg": "fean",
"farm.ogg": "feirm",
"farmer.ogg": "feirmeoir",
"fat.ogg": "ramhar",
"faucet.ogg": "buacaire",
"fawn.ogg": "oisín",
"feast.ogg": "féasta",
"feather.ogg": "cleite",
"feed.ogg": "cothaigh",
- "feet.ogg": "cosa",
- "fell.ogg": "leag",
"femur.ogg": "féimear",
"fetch.ogg": "faigh é",
"fig.ogg": "fige",
"fin.ogg": "eite",
"find.ogg": "aimsigh",
"finger.ogg": "méar",
"fire.ogg": "tine",
"fire_extinguisher.ogg": "múchtóir tine",
"fireman.ogg": "fear dóiteáin",
"fish.ogg": "iasc",
"fisherman.ogg": "iascaire",
"fist.ogg": "dorn",
- "five.ogg": "a cúig",
"flacon.ogg": "fabhcún",
"flag.ogg": "bratacha",
"flame.ogg": "bladhaire",
"flamingo.ogg": "lasairéan",
"flash.ogg": "splanc solais",
"flat.ogg": "cothrom",
"flies.ogg": "cuileog",
- "flight.ogg": "eitilt",
"float.ogg": "snámh",
"flour.ogg": "plúr",
"flower.ogg": "bláth",
"fluff.ogg": "clúmh",
"flute.ogg": "fliúit",
"fly.ogg": "eitilt",
"foam.ogg": "cúr",
- "food.ogg": "bia",
"foot.ogg": "cos",
"forest.ogg": "coill",
"fork.ogg": "gabhlóg",
"fountain.ogg": "scairdeán",
- "four.ogg": "a ceathair",
"fox.ogg": "sionnach",
"freeze.ogg": "sioc",
"friend.ogg": "cara",
"fries.ogg": "sceallóga",
"frog.ogg": "frog",
"front.ogg": "chun tosaigh",
- "frown.ogg": "gnúis-searbh",
"fruit.ogg": "torthaí",
"fudge.ogg": "faoiste",
"full.ogg": "lán",
- "fun.ogg": "spraoi",
"fur.ogg": "fionnadh",
"game.ogg": "cluiche",
"garage.ogg": "garáiste",
"garden.ogg": "gairdín",
"garlic.ogg": "gairleog",
"gem.ogg": "seoid",
"giant.ogg": "fathach",
"gift.ogg": "bronntanas",
"giraffe.ogg": "sioráf",
"girl.ogg": "cailín",
"glass.ogg": "gloine",
"glasses.ogg": "gloiní",
"glove.ogg": "miotóg",
"glue.ogg": "gliú",
"gnome.ogg": "leipreachán",
"goat.ogg": "gabhar",
"golden.ogg": "órga",
"golf.ogg": "galf",
"goose.ogg": "gé",
"gorilla.ogg": "goraille",
"grain.ogg": "grán arbhar",
"grandmother.ogg": "seanmháthair",
"grape.ogg": "fíonchaor",
"grapefruit.ogg": "seadóg",
"grass.ogg": "féar",
"grave.ogg": "uaigh",
"gray.ogg": "liath",
"green.ogg": "glas",
"grill.ogg": "gríosc",
"grin.ogg": "miongháire",
"ground.ogg": "talamh",
"growl.ogg": "gnúsacht",
"guignol.ogg": "guignol",
"guinea_pig.ogg": "muc ghuine",
"gum.ogg": "guma",
"hair.ogg": "gruaig",
"hair_dryer.ogg": "triomadóir gruaige",
"half.ogg": "leath",
"ham.ogg": "liamhás",
"hammer.ogg": "casúr",
"hand.ogg": "lámh",
"handlebar.ogg": "hanla",
"happy.ogg": "sona",
"harp.ogg": "cláirseach",
"hat.ogg": "hata",
"hatch.ogg": "goradh",
"hay.ogg": "féar",
"head.ogg": "ceann",
"hear.ogg": "éist",
"heat.ogg": "teocht",
"hedge.ogg": "fál",
"hedgehog.ogg": "gráinneog",
"heel.ogg": "sáil",
"helmet.ogg": "clogad",
"hen.ogg": "cearc",
"herd.ogg": "bólacht",
"high.ogg": "ard",
"hike.ogg": "siúlóireacht",
"hill.ogg": "cnoc",
"hip.ogg": "cromán",
"hippopotamus.ogg": "dobhareach",
"hit.ogg": "buail",
"hive.ogg": "coirceog",
"hockey.ogg": "haca",
"hole.ogg": "poll",
"home.ogg": "baile",
"hook.ogg": "duán",
"hop.ogg": "preab",
"horse.ogg": "capall",
"hose.ogg": "píobán",
"hospital.ogg": "ospidéal",
"hot.ogg": "te",
"hot_dog.ogg": "ispín",
"hound.ogg": "cú",
"house.ogg": "teach",
"howl.ogg": "béic",
"hug.ogg": "barróg",
"huge.ogg": "ollmhór",
"hummingbird.ogg": "dordéan",
- "hunchback.ogg": "cruiteachán",
"hunter.ogg": "sealgaire",
"husband.ogg": "fhear céile",
"hut.ogg": "cró",
"hyena.ogg": "hiéana",
"ice.ogg": "oighear",
"iceberg.ogg": "cnoc oighir",
"iguana.ogg": "ioguána",
"ill.ogg": "breoite",
"ink.ogg": "dúch",
"island.ogg": "oileán",
"jacket.ogg": "seaicéad",
"jaguar.ogg": "iaguar",
"jam.ogg": "subh",
"jay.ogg": "scréachóg",
"jelly.ogg": "glóthach",
"jellyfish.ogg": "smugairle róin",
"jewel.ogg": "seoid",
"job.ogg": "jab",
"jockey.ogg": "marcach",
"jog.ogg": "bogshodar",
"judge.ogg": "breitheamh",
"judo.ogg": "júdó",
"juggler.ogg": "lámhchleasaí",
"juice.ogg": "sú",
"jump.ogg": "léim",
"kangaroo.ogg": "cangarú",
"keel.ogg": "cíle",
"kernel.ogg": "eithne",
"keyboard.ogg": "méarchlár",
"kimono.ogg": "kimono",
"king.ogg": "rí",
"kiss.ogg": "póg",
"kitchen.ogg": "cistin",
"kite.ogg": "eitleog",
"kitten.ogg": "piscín",
"kiwi.ogg": "cíobhaí",
"knee.ogg": "glúin",
"kneel.ogg": "téigh ar na glúine",
"knife.ogg": "scian",
"knight.ogg": "ridire",
"knit.ogg": "cniotáil",
"knot.ogg": "snaidhm",
"koala.ogg": "cóála",
"lad.ogg": "stócach",
"lady.ogg": "ban",
"ladybug.ogg": "bóín Dé",
"lake.ogg": "loch",
"lama.ogg": "láma",
"lamb.ogg": "uan",
"lamp.ogg": "lampa",
"land.ogg": "talamh",
"lane.ogg": "lána",
"lap.ogg": "ucht",
"lasso.ogg": "lasú",
"laugh.ogg": "gáire",
"lava.ogg": "laibhe",
"lawn.ogg": "plásóg",
"lawyer.ogg": "dlíodóir",
"leaf.ogg": "duilleog",
"ledge.ogg": "seilf",
"leek.ogg": "caineann",
"left.ogg": "clé",
"leg.ogg": "cos",
- "leg_animal.ogg": "cos",
"lemon.ogg": "líomóid",
"lemonade.ogg": "líomanáid",
"lemur.ogg": "léamar",
"leopard.ogg": "liopard",
"lettuce.ogg": "leitís",
"librarian.ogg": "leabharlannaí",
"lick.ogg": "lí",
"lid.ogg": "clár",
"lift.ogg": "tóg",
"light.ogg": "solas",
"lighthouse.ogg": "teach solais",
"lightning.ogg": "tintreach",
"lilac.ogg": "líológ",
"lime.ogg": "líoma",
"line.ogg": "líne",
"link.ogg": "nasc",
"lion.ogg": "leon",
"lion_cub.ogg": "coileán leoin",
"lip.ogg": "liobar",
"liquid.ogg": "leacht",
"lizard.ogg": "laghairt",
"lobster.ogg": "gliomach",
"log.ogg": "smután",
"look.ogg": "amharc",
"lunch.ogg": "lón",
"mad.ogg": "ar mire",
"magic.ogg": "draíocht",
"magnet.ogg": "maighnéad",
"magnifying_glass.ogg": "gloine formhéadúcháin",
"magpie.ogg": "snag breac",
"mail.ogg": "post",
"man.ogg": "fear",
"mane.ogg": "folt",
"mango.ogg": "mangó",
"map.ogg": "léarscáil",
"maple.ogg": "mailp",
"marble.ogg": "marmar",
"mashed_potatoes.ogg": "brúitín",
"mask.ogg": "masc",
"mast.ogg": "crann",
"mat.ogg": "mata",
"match.ogg": "cipín solais",
"mate.ogg": "cara",
"mattress.ogg": "tocht",
"mauve.ogg": "liathchorcra",
"meal.ogg": "béile",
"meat.ogg": "feoil",
"mechanic.ogg": "meicneoir",
"medal.ogg": "bonn",
"meet.ogg": "tionól",
"melon.ogg": "mealbhacán",
- "men.ogg": "fir",
"merry-go-round.ogg": "roithleagán ró",
"mice.ogg": "luchoga",
"microphone.ogg": "micreafón",
"milk.ogg": "bainne",
"mill.ogg": "muileann",
"mimosa.ogg": "míomós",
"mirror.ogg": "scáthán",
"mixer.ogg": "meascthóir",
"mole.ogg": "caochán",
"mom.ogg": "mamaí",
"moon.ogg": "gealach",
"moose.ogg": "mús",
"mop.ogg": "mapa",
"mosque.ogg": "mosc",
"mosquito.ogg": "corrmhíol",
"mother.ogg": "máthair",
"motorcycle.ogg": "rothar gluaiste",
"mountain.ogg": "cnoc",
"mouse.ogg": "luchóg",
"mouth.ogg": "béal",
"movie.ogg": "scannán",
"mower.ogg": "lomadóir",
"mud.ogg": "lábán",
"mug.ogg": "muga",
"mule.ogg": "miúil",
"muscle.ogg": "matán",
"mushroom.ogg": "beacán",
"music.ogg": "ceol",
"musician.ogg": "ceoltóir",
"naked.ogg": "nocht",
"nap.ogg": "néal",
"navel.ogg": "imleacán",
"neck.ogg": "muineál",
"necklace.ogg": "slabhra",
"needle.ogg": "snáthaid",
"nest.ogg": "nead",
"net.ogg": "eangach",
"newspaper.ogg": "nuachtán",
"night.ogg": "oíche",
"nightgown.ogg": "culaith oíche",
- "nine.ogg": "a naoi",
"nose.ogg": "gaosán",
"nostril.ogg": "polláire",
"notebook.ogg": "leabhar nótaí",
"number.ogg": "uimhir",
"nun.ogg": "bean rialta",
"nurse.ogg": "banaltra",
"nurse_male.ogg": "altra",
"nut.ogg": "cnó",
"oar.ogg": "maide rámha",
"ocean.ogg": "aigéin",
"office.ogg": "oifig",
"olive.ogg": "ológ",
"on.ogg": "ar siúl",
- "one.ogg": "a haon",
"onion.ogg": "oinniún",
"open.ogg": "oscail",
"opossum.ogg": "apasam",
- "orange.ogg": "oráiste",
"orange-color.ogg": "oráiste",
+ "orange.ogg": "oráiste",
"orchid.ogg": "magairlín",
"ostrich.ogg": "ostrais",
"otter.ogg": "madra uisce",
"owl.ogg": "cailleach oíche",
"ox.ogg": "damh",
"oyster.ogg": "oisre",
"pacifier.ogg": "gobán",
"page.ogg": "leathanach",
"pair.ogg": "péire",
"pajamas.ogg": "culaith oíche",
"pal.ogg": "cara",
"palm_tree.ogg": "crann pailme",
"pan.ogg": "panna",
"panda.ogg": "panda",
"panther.ogg": "pantar",
"panties.ogg": "fóbhristí",
"pants.ogg": "brístí",
"papaya.ogg": "papá",
"paper.ogg": "páipéar",
"parachute.ogg": "paraisiút",
"parakeet.ogg": "pearóid",
"parrot.ogg": "pearóid",
"patch.ogg": "paiste",
"path.ogg": "cosán",
"paw.ogg": "lapa",
"pea.ogg": "pis",
"peach.ogg": "péitseog",
"peacock.ogg": "péacóg",
"peak.ogg": "buaicphointe",
"pear.ogg": "piorra",
"pearl.ogg": "péarla",
"peck.ogg": "pioc",
"pedal.ogg": "troitheán",
"pelican.ogg": "peileacán",
"pen.ogg": "peann",
"pencil.ogg": "peann luaidhe",
"peony.ogg": "piaine",
"people.ogg": "daoine",
"pepper.ogg": "piobar",
"peppers.ogg": "piobair",
"pet.ogg": "peata",
"petal.ogg": "peiteal",
- "petite.ogg": "beag",
"phone.ogg": "fón",
"piano.ogg": "pianó",
"picture.ogg": "pictiúr",
"pie.ogg": "pióg",
"pig.ogg": "muc",
"pigeon.ogg": "colmán",
"pill.ogg": "piolla",
"pillow.ogg": "piliúr",
"pilot.ogg": "píolóta",
"pine.ogg": "péine",
"pine_cone.ogg": "caor phéine",
"pink.ogg": "bándearg",
"pip.ogg": "píoblach",
"pipe.ogg": "píopa",
"piranha.ogg": "piorána",
"pirate.ogg": "foghlaí mara",
"pizza.ogg": "pizza",
"plane.ogg": "eitleán",
"planet.ogg": "pláinéad",
"plant.ogg": "planda",
"plate.ogg": "plata",
"play.ogg": "súgradh",
"pliers.ogg": "teanchair",
"plow.ogg": "treabh",
"plum.ogg": "pluma",
"plumber.ogg": "pluiméir",
"pocket.ogg": "póca",
"pod.ogg": "faighneog",
"pole.ogg": "maide",
"police.ogg": "garda",
"pompon.ogg": "bobailín",
"pond.ogg": "linn",
"pony.ogg": "capaillín",
"pool.ogg": "linn",
- "pop.ogg": "pop",
+ "popcorn.ogg": "pop",
"pope.ogg": "pápa",
"porthole.ogg": "poll",
"post.ogg": "post",
"pot.ogg": "pota",
"potato.ogg": "práta",
"pounce.ogg": "ionsaí",
"president.ogg": "uachtarán",
"pretty.ogg": "álainn",
"price.ogg": "praghas",
"priest.ogg": "sagart",
"prince.ogg": "príonsa",
"princess.ogg": "banphrionsa",
"prison.ogg": "príosún",
"prisoner.ogg": "príosúnach",
"prize.ogg": "duais",
"pug.ogg": "smutmhadadh",
"pull.ogg": "tarraingt",
"pullover.ogg": "geansaí",
"pumpkin.ogg": "puimcín",
"puppy.ogg": "coileán",
"pyramid.ogg": "pirimid",
"quarrel.ogg": "achrann",
"queen.ogg": "banríon",
"question.ogg": "ceist",
"quilt.ogg": "cuilt",
"quiz.ogg": "tráth na gceist",
"rabbit.ogg": "coinín",
"rabbit_baby.ogg": "coinín óg",
"race.ogg": "rás",
"radio.ogg": "raidió",
"radish.ogg": "raidis",
"raft.ogg": "rafta",
"rag.ogg": "bratóg",
"rage.ogg": "ar buile",
"rain.ogg": "fearthainn",
"raincoat.ogg": "cóta báistí",
"rake.ogg": "ráca",
"ramp.ogg": "rampa",
"ran.ogg": "rith",
"raspberry.ogg": "sú craobh",
"rat.ogg": "francach",
"razor.ogg": "rásúr",
"read.ogg": "léamh",
"red.ogg": "dearg",
"reptile.ogg": "reiptíl",
"rhinoceros.ogg": "srónbheannach",
"rice.ogg": "rís",
"ride.ogg": "marcaíocht",
"rifle.ogg": "raidhfil",
"right.ogg": "deis",
"rip.ogg": "roiseadh",
"rise.ogg": "éirí",
"river.ogg": "abhainn",
"road.ogg": "bóthar",
"roast.ogg": "róst",
"robe.ogg": "róba",
"robot.ogg": "róbat",
"rock.ogg": "cloch",
"rocket.ogg": "roicéad",
"rolling_pin.ogg": "crann fuinte",
"roof.ogg": "díon",
"room.ogg": "seomra",
"root.ogg": "fréamh",
"rope.ogg": "rópa",
"rose.ogg": "rós",
"round.ogg": "cruinn",
"rowing.ogg": "rámhaíocht",
"royal.ogg": "ríoga",
"rug.ogg": "ruga",
"run.ogg": "rith",
"sad.ogg": "brónach",
"saddle.ogg": "diallait",
"sail.ogg": "seol",
"sailor.ogg": "mairnéalach",
"salamander.ogg": "salamandar",
"salmon.ogg": "bradán",
"sand.ogg": "gaineamh",
"sandals.ogg": "cuaráin",
"sandwich.ogg": "ceapaire",
"sash.ogg": "sais",
- "sat.ogg": "ina shuí",
"sauce.ogg": "anlann",
"sausage.ogg": "ispín",
"scale.ogg": "scála",
"scar.ogg": "colm",
- "scared.ogg": "scanraithe",
"scarf.ogg": "scairf",
"school.ogg": "scoil",
"school_bag.ogg": "mála scoile",
"science.ogg": "eolaíocht",
"scissors.ogg": "siosúr",
"scorpion.ogg": "scairp",
"scratch.ogg": "tochais",
"scream.ogg": "scread",
"screw.ogg": "scriú",
"screwdriver.ogg": "scriúire",
"scribble.ogg": "scriobláil",
"sea.ogg": "farraige",
"seat.ogg": "suíochán",
"see.ogg": "féach",
"seed.ogg": "síol",
- "seven.ogg": "a seacht",
"shadow.ogg": "scáth",
"shake.ogg": "creathadh",
"shark.ogg": "siorc",
"shave.ogg": "bearradh",
"shed.ogg": "bothán",
"sheep.ogg": "caora",
"shelf.ogg": "seilf",
"shell.ogg": "sliogáin",
"ship.ogg": "long",
"shirt.ogg": "léine",
"shoe.ogg": "bróg",
"shoelace.ogg": "iall",
"shop.ogg": "siopa",
"shore.ogg": "bruach",
"short.ogg": "gairid",
"shovel.ogg": "sluasaid",
"shower.ogg": "cith",
"shrimp.ogg": "ribe róibéis",
"shrub.ogg": "tor",
"shut.ogg": "druid",
"shutter.ogg": "comhla",
"sick.ogg": "tinn",
"sidewalk.ogg": "cosán",
"sign.ogg": "comhartha",
"sing.ogg": "ceol",
"sink.ogg": "go tóin poill",
"sip.ogg": "bolgam",
"sister.ogg": "deirfiúr",
"sit.ogg": "suí",
- "six.ogg": "a sé",
- "sixteen.ogg": "a sé déag",
"skate.ogg": "scátáil",
"skeleton.ogg": "cnámharlach",
"ski.ogg": "scí",
"skimmer.ogg": "scimín",
"skin.ogg": "craiceann",
"skirt.ogg": "sciorta",
"skunk.ogg": "scúnc",
"sky.ogg": "spéir",
"slam.ogg": "plab",
"sled.ogg": "sleamhnán",
"sleep.ogg": "codladh",
"sleeve.ogg": "clúdach",
"sleigh.ogg": "carr sleamhnáin",
"slide.ogg": "sleamhnaigh",
"slim.ogg": "caol",
"slime.ogg": "sram",
"slippers.ogg": "slipéar",
"slope.ogg": "fána",
"sloppy.ogg": "tútach",
"slot.ogg": "bearna",
"sloth.ogg": "spadán",
"slug.ogg": "seilide drúchta",
"small.ogg": "beag",
"smell.ogg": "boladh",
"smile.ogg": "miongháire",
"smock.ogg": "forléine",
"smoke.ogg": "toit",
"smooch.ogg": "póg",
"snack.ogg": "sneaic",
"snail.ogg": "seilide",
"snake.ogg": "nathair nimhe",
"sneaker.ogg": "bróg reatha",
"sniff.ogg": "bolaigh",
"snow.ogg": "sneachta",
"soap.ogg": "sópa",
"sob.ogg": "borrchaoineadh",
"sock.ogg": "stoca",
"soldier.ogg": "saighdiúir",
"sole.ogg": "bonn",
"sole_shoe.ogg": "bonn bróige",
"son.ogg": "mac",
"soup.ogg": "anraith",
"spade.ogg": "spád",
"spaghetti.ogg": "spaigití",
"spark.ogg": "splanc",
"sparrow.ogg": "gealbhan",
"spatula.ogg": "spadal",
"speak.ogg": "labhair",
"spear.ogg": "sleá",
"spice.ogg": "spíosra",
"spider.ogg": "damhán Alla",
"spider_web.ogg": "nead damháin alla",
"spike.ogg": "spíce",
"spill.ogg": "doirt",
"spinach.ogg": "spionáiste",
"spine.ogg": "cnámh droma",
"spinning_top.ogg": "caiseal",
"splash.ogg": "steallóg",
"splatter.ogg": "steall",
"sponge.ogg": "spúinseáil",
"spool.ogg": "spól",
"spoon.ogg": "spúnóg",
"sport.ogg": "spórt",
"spot.ogg": "spota",
"spray.ogg": "spraeáil",
"spread.ogg": "spré",
"spring.ogg": "earrach",
"spring_season.ogg": "earrach",
"sprinkle.ogg": "gráinnín",
"square.ogg": "cearnóg",
"squash.ogg": "brúigh",
"squat.ogg": "cromada",
"squid.ogg": "scuid",
"squirrel.ogg": "iorú rua",
"squirt.ogg": "scaird",
"stack.ogg": "cruach",
"stage.ogg": "ardán",
"staircase.ogg": "staighre",
"stamp.ogg": "stampa",
"stand.ogg": "seas",
"star.ogg": "réalt",
"stare.ogg": "stán",
"starfish.ogg": "crosóg mhara",
- "steak.ogg": "stéig",
"steam.ogg": "gal",
"steep.ogg": "crochta",
"steeple.ogg": "spuaic",
"stem.ogg": "sifín",
"step.ogg": "céim",
"stew.ogg": "stobh",
"stick.ogg": "bata",
"sting.ogg": "cealg",
"stinky.ogg": "bréan",
"stitch.ogg": "greim",
"stomach.ogg": "bolg",
"stone.ogg": "cloch",
"stop.ogg": "stad",
"store.ogg": "stóráil",
"stove.ogg": "sorn",
"straight.ogg": "díreach",
"strainer.ogg": "síothlán",
"straw.ogg": "tuí",
"strawberry.ogg": "sú talún",
"stream.ogg": "sruthán",
"street.ogg": "sráid",
"stretch.ogg": "sín",
"string.ogg": "corda",
"stripe.ogg": "stríocach",
"strong.ogg": "láidir",
"student.ogg": "mac Léinn",
"study.ogg": "staidéar",
"stump.ogg": "grágán",
"sugar.ogg": "siúcra",
"suit.ogg": "culaith",
"suitcase.ogg": "cás",
"summer.ogg": "samhradh",
"summit.ogg": "mullach",
"sun.ogg": "grian",
"swan.ogg": "eala",
"sweat.ogg": "allas",
"sweatshirt.ogg": "léine aclaíochta",
"swim.ogg": "snámh",
"table.ogg": "tábla",
"tablecloth.ogg": "éadach tábla",
"tadpole.ogg": "torbán",
"tag.ogg": "lipéad",
"tail.ogg": "eireaball",
"tall.ogg": "ard",
"tape_measure.ogg": "téip tomhais",
"taxi.ogg": "tacsaí",
"teach.ogg": "teagasc",
"teacher.ogg": "múinteoir",
"tear.ogg": "stróic",
"teddy.ogg": "teidí",
"teeth.ogg": "fiacla",
"television.ogg": "teilifís",
"temple.ogg": "teampall",
- "ten.ogg": "a deich",
"tennis.ogg": "leadóg",
"tent.ogg": "puball",
"text.ogg": "téacs",
"thick.ogg": "tiubh",
"thief.ogg": "gadaí",
"thigh.ogg": "leis",
"think.ogg": "smaoinigh",
"thread.ogg": "snáth",
- "three.ogg": "a trí",
"throat.ogg": "sceadamán",
"throw.ogg": "caith",
"thumb.ogg": "ordóg",
"tick.ogg": "sceartán féir",
"ticket.ogg": "ticéad",
"tiger.ogg": "tíogar",
"time.ogg": "am",
"tin.ogg": "stán",
"tire.ogg": "tuirseach",
"tired.ogg": "tuirseach",
"tissue.ogg": "ciarsúr",
"toad.ogg": "buaf",
"toaster.ogg": "tóstaer leictreach",
"toe.ogg": "ladhar",
"toilet.ogg": "leithreas",
"tomatoe.ogg": "tráta",
"tongs.ogg": "maide briste",
"tongue.ogg": "teanga",
"tool.ogg": "uirlis",
"top.ogg": "barr",
"torch.ogg": "tóirse",
"touch.ogg": "bain do",
"towel.ogg": "tuáille",
"toy.ogg": "bréagán",
"trail.ogg": "cosán",
"train.ogg": "traein",
"train_station.ogg": "stáisiún traenach",
"trap.ogg": "dol",
"trash.ogg": "bruscar",
"tray.ogg": "tráidire",
"treat.ogg": "féirín",
"tree.ogg": "crann",
"triangle.ogg": "triantán",
"tribe.ogg": "treibh",
"trip.ogg": "tuisle",
"truck.ogg": "trucail",
"tube.ogg": "feadán",
"tulip.ogg": "tiúilip",
"tune.ogg": "tiúnáil",
"turkey.ogg": "turcaí",
"turnip.ogg": "tornapa",
"turtle.ogg": "turtar",
"tusk.ogg": "starrfhiacail",
- "twelve.ogg": "a dó dhéag",
"twin_boys.ogg": "cúpla gasúr",
"twin_girls.ogg": "cúpla girseach",
- "two.ogg": "a dó",
"umbrella.ogg": "scáth fearthainne",
"under.ogg": "faoi",
"uniform.ogg": "éide",
"van.ogg": "veain",
"vapor.ogg": "gal",
"vase.ogg": "vása",
"vegetable.ogg": "glasra",
"vein.ogg": "féith",
"verdure.ogg": "fásra glas",
"vest.ogg": "veist",
"vet.ogg": "tréidlia",
"viper.ogg": "nathair nimhe",
"vowel.ogg": "guta",
"vulture.ogg": "bultúr",
"wag.ogg": "croith",
"walk.ogg": "siúl",
"wall.ogg": "balla",
"walnut.ogg": "gallchnó",
"wart.ogg": "faithne",
"wash.ogg": "ní",
"wasp.ogg": "seillean",
"watch.ogg": "uaireadóir",
"water.ogg": "uisce",
"wave.ogg": "tonn",
"wedding.ogg": "pósadh",
"wedge.ogg": "ding",
"weight.ogg": "meáchan",
"wet.ogg": "fliuch",
"whale.ogg": "míol mór",
"wheat.ogg": "cruithneacht",
"wheel.ogg": "rotha",
"whisk.ogg": "greadtóir",
"whisper.ogg": "cogar",
"white.ogg": "bán",
"wide.ogg": "leathan",
"wife.ogg": "bean chéile",
"wig.ogg": "folt bréige",
"win.ogg": "bua",
"wind.ogg": "gaoth",
"window.ogg": "fuinneog",
"window_glass.ogg": "fuinneog gloine",
"wing.ogg": "eiteog",
"winter.ogg": "geimhreadh",
"wolf.ogg": "mac tíre",
"woman.ogg": "bean",
"wood.ogg": "coill",
"word.ogg": "focal",
"worker.ogg": "oibrithe",
"world.ogg": "domhan",
"wreath.ogg": "fleasc",
"wrench.ogg": "rinse",
"wrist.ogg": "rosta",
"write.ogg": "scríobh",
"yellow.ogg": "buí",
"yogurt.ogg": "iógart",
"yum.ogg": "blasta",
"zebra.ogg": "séabra",
- "zero.ogg": "a náid",
"zipper.ogg": "zip",
"zoo.ogg": "zú"
-}
-
+}
\ No newline at end of file
diff --git a/src/activities/lang/resource/content-gd.json b/src/activities/lang/resource/content-gd.json
index c628fe1fa..388b0e9e0 100644
--- a/src/activities/lang/resource/content-gd.json
+++ b/src/activities/lang/resource/content-gd.json
@@ -1,1117 +1,564 @@
{
- "10.ogg": "",
- "11.ogg": "",
- "12.ogg": "",
- "16.ogg": "",
"U0030.ogg": "neoni",
"U0031.ogg": "aon",
"U0032.ogg": "dhà",
"U0033.ogg": "trì",
"U0034.ogg": "ceithir",
"U0035.ogg": "còig",
"U0036.ogg": "sia",
"U0037.ogg": "seachd",
"U0038.ogg": "ochd",
"U0039.ogg": "naoidh",
- "accountant.ogg": "",
- "ache.ogg": "",
- "acorn.ogg": "",
- "actor.ogg": "",
- "air_horn.ogg": "",
- "alarmclock.ogg": "",
"alligator.ogg": "ailigeutair mòr",
- "alphabet.ogg": "",
"anchor.ogg": "acair mhòr",
"angel.ogg": "aingeal bheag",
- "angry.ogg": "",
"animal.ogg": "beathaichean fiadhaich",
- "ankle.ogg": "",
- "ant.ogg": "",
- "anteater.ogg": "",
- "antelope.ogg": "",
- "apple.ogg": "",
- "apple_tree.ogg": "",
- "appliance.ogg": "",
- "apricot.ogg": "",
- "arm.ogg": "",
- "armchair.ogg": "",
- "artichoke.ogg": "",
- "artist.ogg": "",
- "asparagus.ogg": "",
- "astronaut.ogg": "",
- "ate.ogg": "dh'ith i a leòr",
"athlete.ogg": "ruithear math",
- "avocado.ogg": "",
- "ax.ogg": "",
- "baby_bottle.ogg": "",
"back.ogg": "druim goirt",
"badge.ogg": "saighdear mòr",
"bag.ogg": "baga mòr",
"bait.ogg": "baoit bheò",
- "bake.ogg": "fuineadh",
"balance.ogg": "meidh bheag",
- "bald.ogg": "",
"ball.ogg": "bàla mòr",
- "ball_of_yarn.ogg": "",
- "ball_soccer.ogg": "",
"ballet.ogg": "dannsair math",
"bank.ogg": "banca mòr",
- "banker.ogg": "bancair mòr",
"bark.ogg": "a' tabhann",
"barn.ogg": "sabhal mòr",
"bat.ogg": "ialtag bheag",
"bath.ogg": "amar teth",
- "bathing_suit.ogg": "",
"bay.ogg": "bàgh beag",
"beach.ogg": "tràigh mhòr",
- "bead.ogg": "builgean mòr",
- "bean.ogg": "",
- "bear.ogg": "",
- "beard.ogg": "",
- "beat.ogg": "",
- "beaver.ogg": "",
"bed.ogg": "leabaidh bheag",
- "bedroom.ogg": "",
"bee.ogg": "seillean beag",
- "beef.ogg": "",
"beetle.ogg": "daolag mhòr",
"beg.ogg": "a' guidhe",
- "behind.ogg": "",
- "bell.ogg": "",
- "belly.ogg": "",
"bench.ogg": "being bheag",
"bib.ogg": "uchdan gorm",
"big.ogg": "mòr",
- "big_top.ogg": "",
"bike.ogg": "baidhsagal beag",
"bird.ogg": "eun donn",
"bit.ogg": "balgam beag",
"bite.ogg": "a' toirt greim às",
"black.ogg": "dath dubh",
- "blackberry.ogg": "",
- "blackbird.ogg": "",
- "blade.ogg": "",
"blind.ogg": "fear dall",
"blink.ogg": "priobadh na sùla",
"block.ogg": "bloca gorm",
"blond.ogg": "falt bàn",
"blue.ogg": "dath gorm",
- "blueberry.ogg": "",
- "blush.ogg": "",
"board.ogg": "bòrd beag",
"boat.ogg": "ràmhach beag",
"boil.ogg": "a' goil",
- "bolt.ogg": "",
"bomb.ogg": "boma mòr",
"bone.ogg": "cnàimh mòr",
"book.ogg": "leabhar mòr",
- "bookcase.ogg": "",
- "bottom.ogg": "",
"box.ogg": "bogsa beag",
- "boxer.ogg": "",
"boy.ogg": "fireannach beag",
"braid.ogg": "dual fada",
"brain.ogg": "eanchainn mhòr",
"branch.ogg": "geug bheag",
"bread.ogg": "aran math",
"break.ogg": "cridhe briste",
- "breast.ogg": "",
"brick.ogg": "breigean mòra",
- "bricklayer.ogg": "",
"bride.ogg": "bean bainnse",
"bridge.ogg": "drochaid bheag",
"bright.ogg": "rionnag shoilleir",
- "broccoli.ogg": "",
"brother.ogg": "bràthair beag",
"brown.ogg": "dath donn",
"brush.ogg": "bruis mhòr",
- "bubble.ogg": "",
- "bucket.ogg": "",
"bud.ogg": "gucag bheag",
- "buffalo.ogg": "",
"bug.ogg": "biastag bheag",
- "bulb.ogg": "",
- "bull.ogg": "",
"bump.ogg": "cnap mòr",
"bun.ogg": "rola beag",
- "bus.ogg": "",
"bush.ogg": "preas mòr",
- "butcher.ogg": "",
- "butter.ogg": "",
- "butterfly.ogg": "",
- "button.ogg": "",
- "cabbage.ogg": "",
"cabin.ogg": "bothan beag",
- "cacao.ogg": "",
- "cactus.ogg": "",
"cage.ogg": "cèidse mhòr",
"cake.ogg": "cèic mhòr",
"call.ogg": "a' cur fòn",
"camel.ogg": "càmhal mòr",
- "camera.ogg": "",
"camp.ogg": "a' campadh",
"can.ogg": "canaichean beaga",
- "canary.ogg": "",
"candle.ogg": "coinneal bheag",
"candy.ogg": "siùcar beag ",
"cane.ogg": "bata mòr",
"canoe.ogg": "curach bheag",
- "canon.ogg": "",
- "canyon.ogg": "",
"cap.ogg": "bonaid bheag",
"cape.ogg": "guailleachan beag",
"car.ogg": "càr beag",
- "carafe.ogg": "",
"card.ogg": "cairt mhòr",
- "carnival.ogg": "",
- "carpenter.ogg": "",
- "carpet.ogg": "",
"carrot.ogg": "curran mòr",
"cart.ogg": "troilidh",
"cash.ogg": "airgead mòr",
"castle.ogg": "caisteal mòr",
"cat.ogg": "cat beag",
- "cat_female.ogg": "",
"catch.ogg": "ag iasgach",
- "caterpillar.ogg": "",
- "cauldron.ogg": "",
- "cauliflower.ogg": "",
"cave.ogg": "uamh mhòr",
- "cavern.ogg": "",
- "celery.ogg": "",
"centipede.ogg": "ceud-chasach fada",
- "cereal.ogg": "",
- "chain.ogg": "",
"chair.ogg": "sèithear beag",
"chalk.ogg": "cailc gheal",
- "chameleon.ogg": "",
- "chandelier.ogg": "",
"chat.ogg": "a' cabadaich",
- "cheek.ogg": "",
"cheer.ogg": "a' toirt misneachd",
"cheese.ogg": "càise mhath",
- "chef.ogg": "",
"cherry.ogg": "siris mhath",
"chest.ogg": "ciste mhòr",
"chick.ogg": "isean beag",
"chicken.ogg": "cearc bheag",
- "chief.ogg": "ceannard mòr",
"child.ogg": "duine-cloinne beag",
- "chimney.ogg": "",
"chimp.ogg": "muncaidh beag",
"chin.ogg": "smiogaid mòr",
"chocolate.ogg": "seòclaid mhath",
"chop.ogg": "a' gearradh",
- "chore.ogg": "",
- "christmas.ogg": "",
- "cigar.ogg": "",
- "circus.ogg": "",
- "city.ogg": "",
"clam.ogg": "creachann mòr",
"clap.ogg": "a' bualadh basan",
"class.ogg": "clas math",
"claw.ogg": "cròg mòr",
"clay.ogg": "criadh dhonn",
"clean.ogg": "a' nighe d' fhalt",
- "cleaning_lady.ogg": "",
"cliff.ogg": "bearradh mòr",
"climb.ogg": "a' streap",
"clock.ogg": "cleoc mòr",
"cloth.ogg": "aodach buidhe",
- "clothes_hanger.ogg": "",
"cloud.ogg": "neul beag",
- "cloudy.ogg": "",
- "clover.ogg": "",
"clown.ogg": "amadan mòr",
"coach.ogg": "còidse mhath",
- "coast.ogg": "",
"coat.ogg": "còta mòr",
- "cobra.ogg": "",
- "coconut.ogg": "",
- "cod.ogg": "",
- "coffee.ogg": "",
"coin.ogg": "bonn beag",
"cold.ogg": "fuar",
"color.ogg": "dathan",
- "colt.ogg": "",
"comb.ogg": "cìr mhòr",
"cone.ogg": "còn mòr",
"cook.ogg": "còcaire math",
"cookie.ogg": "briosgaid mhòr",
- "cork.ogg": "",
"corn.ogg": "dias mhòr",
"couch.ogg": "langasaid mhòr",
- "cough.ogg": "",
- "couple.ogg": "",
"cow.ogg": "bò bheag",
"cowboy.ogg": "gille-cruidh beag",
"crab.ogg": "crùbag mhòr",
- "cradle.ogg": "",
- "craft.ogg": "",
"crawl.ogg": "falbh air mhàgaran",
"crazy.ogg": "duine craicte",
- "creek.ogg": "",
- "crepe.ogg": "",
"crib.ogg": "cot mhòr",
- "criminal.ogg": "",
"croak.ogg": "a' gnàgail",
"crocodile.ogg": "crogall mòr",
- "cross.ogg": "",
"crow.ogg": "feannag bheag",
"crown.ogg": "crùn mòr",
"crumb.ogg": "criomag bheag",
"crust.ogg": "cùlan donn",
"cry.ogg": "a' gal",
- "crystal.ogg": "",
"cube.ogg": "ciùb beag",
"cucumber.ogg": "cularan beag",
- "curtain.ogg": "",
"cut.ogg": "siosar beag",
"cute.ogg": "snog",
- "cyclist.ogg": "rothaiche mòr",
"dad.ogg": "dadaidh mòr",
- "daffodil.ogg": "",
- "daisy.ogg": "",
- "dam.ogg": "",
"dance.ogg": "a' dannsadh",
- "dandelion.ogg": "",
- "danger.ogg": "cunnart mòr",
- "dark.ogg": "",
- "dart_board.ogg": "",
- "date_fruit.ogg": "",
- "deer.ogg": "",
"den.ogg": "saobhaidh mòr",
- "desert.ogg": "",
"desk.ogg": "deasg beag",
- "dessert.ogg": "",
- "diamond.ogg": "",
"dig.ogg": "a' cladhach",
"dirt.ogg": "ùir dhorch",
"dirty.ogg": "balach salach",
"dish.ogg": "soitheach beag",
- "dishcloth.ogg": "",
"dive.ogg": "a' daoibhigeadh",
- "doctor.ogg": "",
- "doe.ogg": "",
"dog.ogg": "cù beag",
- "doll.ogg": "",
- "dolphin.ogg": "",
- "domino.ogg": "",
"door.ogg": "doras mòr",
- "doormat.ogg": "",
"dot.ogg": "dotag bheag",
- "doughnut.ogg": "",
- "dove.ogg": "",
"dragon.ogg": "dràgon mòr",
- "dragonfly.ogg": "",
- "drank.ogg": "ag òl",
"draw.ogg": "a' dèanamh dealbh",
- "drawer.ogg": "",
"dream.ogg": "aisling mhath",
"dress.ogg": "dreasa bheag",
"drink.ogg": "deoch bhlàth",
- "drinking.ogg": "",
- "drip.ogg": "",
"drive.ogg": "a' draibheadh",
"drool.ogg": "a' sileadh sglongaid",
"drum.ogg": "druma mhòr",
"dry.ogg": "aodach tioram",
"duck.ogg": "tunnag bheag",
- "duck_mother.ogg": "",
"dune.ogg": "dùn-gainmhich mòr",
- "dwarf.ogg": "",
- "eagle.ogg": "",
"ear.ogg": "cluas bheag",
"earth.ogg": "an talamh",
"eat.ogg": "ag ithe",
- "egg.ogg": "",
- "eggplant.ogg": "",
- "elbow.ogg": "",
- "electrician.ogg": "",
- "elk.ogg": "",
"empty.ogg": "cana falamh",
- "engine.ogg": "",
- "engineer.ogg": "",
- "eraser.ogg": "",
"explore.ogg": "a' rannsachadh",
- "eyelash.ogg": "",
- "eyes.ogg": "",
"face.ogg": "aodann cruinn",
"fair.ogg": "faidhir bheag",
- "fairy.ogg": "",
- "fall_down.ogg": "",
- "fall_season.ogg": "",
- "family.ogg": "",
+ "fall.ogg": "thuit e",
"fan.ogg": "gaotharan beag",
"farm.ogg": "tuathanas beag",
- "farmer.ogg": "",
"fat.ogg": "gille reamhar",
- "faucet.ogg": "",
- "fawn.ogg": "",
"feast.ogg": "biadh math",
- "feather.ogg": "",
- "feed.ogg": "",
- "feet.ogg": "cas bheag",
- "fell.ogg": "thuit e",
- "femur.ogg": "",
"fetch.ogg": "faigh am pàipear",
- "fig.ogg": "",
"fin.ogg": "ite mhòr",
"find.ogg": "a' lorg",
- "finger.ogg": "",
"fire.ogg": "teine mòr",
- "fire_extinguisher.ogg": "",
- "fireman.ogg": "",
"fish.ogg": "iasg beag",
- "fisher.ogg": "iasgair math",
- "fisherman.ogg": "",
"fist.ogg": "dòrn mòr",
- "five.ogg": "a còig",
- "flacon.ogg": "",
"flag.ogg": "bratach bheag",
"flame.ogg": "lasair mhòr",
- "flamingo.ogg": "",
"flash.ogg": "leus mòr",
"flat.ogg": "flataichean beaga",
"flies.ogg": "cuileag bheag",
- "flight.ogg": "",
"float.ogg": "air fleòd",
"flour.ogg": "flùr geal",
"flower.ogg": "flùr beag",
- "fluff.ogg": "",
"flute.ogg": "fìdeag bheag",
"fly.ogg": "ag itealaich",
- "foam.ogg": "",
- "food.ogg": "biadh luath",
"foot.ogg": "cas mhòr",
- "forest.ogg": "",
"fork.ogg": "forca bheag",
"fountain.ogg": "fuaran beag",
"fox.ogg": "madadh-ruadh beag",
"freeze.ogg": "reòthadh mòr",
"friend.ogg": "caraid math",
- "fries.ogg": "",
"frog.ogg": "losgann beag",
"front.ogg": "air a bheulaibh",
- "frown.ogg": "tha drèin oirre",
"fruit.ogg": "measan milis",
"fudge.ogg": "tofaidh math",
"full.ogg": "gloine làn",
- "fun.ogg": "tha plòigh a' dol",
"fur.ogg": "bian blàth",
"game.ogg": "geama beag",
- "garage.ogg": "",
"garden.ogg": "gàrradh beag",
- "garlic.ogg": "",
"gem.ogg": "seud mòr",
"giant.ogg": "famhair mòr",
"gift.ogg": "prèasant beag",
"giraffe.ogg": "sioraf mòr",
"girl.ogg": "caileag bheag",
"glass.ogg": "gloine mhòr",
- "glasses.ogg": "",
"glove.ogg": "miotagan blàtha",
"glue.ogg": "glaodh math",
"gnome.ogg": "luchraban beag",
"goat.ogg": "gobhar bàn",
- "golden.ogg": "",
- "golf.ogg": "",
- "goose.ogg": "",
- "gorilla.ogg": "",
- "grain.ogg": "",
- "grandmother.ogg": "",
- "grape.ogg": "",
- "grapefruit.ogg": "",
"grass.ogg": "feur fada",
"grave.ogg": "uaigh bheag",
"gray.ogg": "dath liath",
"green.ogg": "dath uaine",
- "grill.ogg": "",
"grin.ogg": "fiamh-ghàire mòr",
"ground.ogg": "geadag bheag",
"growl.ogg": "a' toirt gnòdhan",
- "guignol.ogg": "",
- "guinea_pig.ogg": "",
"gum.ogg": "bìth milis",
"hair.ogg": "falt ruadh",
- "hair_dryer.ogg": "",
- "half.ogg": "",
- "ham.ogg": "",
- "hammer.ogg": "",
"hand.ogg": "làmh mhòr",
- "handlebar.ogg": "",
"happy.ogg": "toilichte",
- "harp.ogg": "",
"hat.ogg": "ad mhòr",
"hatch.ogg": "isean 'ga ghur",
"hay.ogg": "feur tioram",
"head.ogg": "ceann beag",
"hear.ogg": "a' cluinntinn",
"heat.ogg": "blàth",
"hedge.ogg": "callaid bheag",
- "hedgehog.ogg": "",
- "heel.ogg": "",
- "helmet.ogg": "",
"hen.ogg": "cearc mhòr",
"herd.ogg": "treud de chaoraich",
"high.ogg": "àrd",
"hike.ogg": "a' coiseachd",
- "hill.ogg": "",
"hip.ogg": "cruachann mhòr",
- "hippopotamus.ogg": "",
"hit.ogg": "a' bualadh a chèile",
- "hive.ogg": "",
- "hockey.ogg": "",
"hole.ogg": "toll beag",
"home.ogg": "dachaigh bheag",
"hook.ogg": "dubhan mòr",
"hop.ogg": "a' bocadaich",
- "horse.ogg": "",
"hose.ogg": "pìob-uisge mhòr",
- "hospital.ogg": "",
"hot.ogg": "teth",
- "hot_dog.ogg": "",
"hound.ogg": "cù-seilg beag",
- "house.ogg": "",
"howl.ogg": "ag ulfhairt",
"hug.ogg": "a' glacadh a chèile gu teann",
"huge.ogg": "anabarrach mòr",
- "hummingbird.ogg": "",
- "hunchback.ogg": "",
"hunter.ogg": "sealgair mòr",
- "husband.ogg": "",
"hut.ogg": "bothan mòr",
- "hyena.ogg": "",
"ice.ogg": "deigh fhuar",
- "iceberg.ogg": "",
- "iguana.ogg": "",
- "ill.ogg": "",
"ink.ogg": "inc phurpaidh",
- "island.ogg": "",
- "jacket.ogg": "",
- "jaguar.ogg": "",
- "jam.ogg": "",
- "jay.ogg": "",
- "jelly.ogg": "",
- "jellyfish.ogg": "",
"jewel.ogg": "seud beag",
- "job.ogg": "",
- "jockey.ogg": "",
"jog.ogg": "a' jogadh",
"judge.ogg": "britheamh mòr",
- "judo.ogg": "",
- "juggler.ogg": "",
"juice.ogg": "sùgh fuar",
"jump.ogg": "a' leumadh",
- "kangaroo.ogg": "",
- "keel.ogg": "",
- "kernel.ogg": "",
- "keyboard.ogg": "",
- "kimono.ogg": "",
- "king.ogg": "",
- "kiss.ogg": "",
- "kitchen.ogg": "",
"kite.ogg": "itealag bheag",
- "kitten.ogg": "",
- "kiwi.ogg": "",
"knee.ogg": "glùn bheag",
"kneel.ogg": "tha e a' cromadh air a ghlùinean",
"knife.ogg": "sgian bheag",
"knight.ogg": "ridir mòr",
"knit.ogg": "a' fighe",
"knot.ogg": "snaidhm mòr",
- "koala.ogg": "",
"lad.ogg": "balach beag",
- "lady.ogg": "",
- "ladybug.ogg": "",
"lake.ogg": "loch beag",
- "lama.ogg": "",
"lamb.ogg": "uan beag",
"lamp.ogg": "lampa mòr",
"land.ogg": "talamh fliuch",
"lane.ogg": "rathad beag",
"lap.ogg": "ann an uchd na seanmhar",
- "lasso.ogg": "",
- "laugh.ogg": "",
- "lava.ogg": "",
"lawn.ogg": "faiche bheag",
- "lawyer.ogg": "",
- "leaf.ogg": "",
"ledge.ogg": "stalla beag",
- "leek.ogg": "",
"left.ogg": "clì",
- "leg.ogg": "",
- "leg_animal.ogg": "",
- "lemon.ogg": "",
- "lemonade.ogg": "",
- "lemur.ogg": "",
- "leopard.ogg": "",
- "lettuce.ogg": "",
- "librarian.ogg": "",
"lick.ogg": "ag imlich",
"lid.ogg": "failcean mòr",
"lift.ogg": "a' togail",
"light.ogg": "solas math",
- "lighthouse.ogg": "",
- "lightning.ogg": "",
- "lilac.ogg": "",
"lime.ogg": "liomaideag shearbh",
"line.ogg": "loidhne ghorm",
"link.ogg": "dul beag",
- "lion.ogg": "",
- "lion_cub.ogg": "",
"lip.ogg": "bilean pinc",
"liquid.ogg": "boinne beag",
- "lizard.ogg": "",
- "lobster.ogg": "",
"log.ogg": "connadh tioram",
"look.ogg": "a' coimhead",
"lunch.ogg": "lòn math",
"mad.ogg": "air a' chaothach",
"magic.ogg": "draoidheachd mhath",
- "magnet.ogg": "",
- "magnifying_glass.ogg": "",
- "magpie.ogg": "",
- "mail.ogg": "",
- "man.ogg": "",
"mane.ogg": "muing mhòr",
- "mango.ogg": "",
"map.ogg": "mapa beag",
- "maple.ogg": "",
- "marble.ogg": "",
- "mashed_potatoes.ogg": "",
"mask.ogg": "aodannan beag",
- "mast.ogg": "",
"mat.ogg": "plàta beag",
"match.ogg": "lasadan beag",
"mate.ogg": "companach math",
- "mattress.ogg": "",
- "mauve.ogg": "",
- "meal.ogg": "",
- "meat.ogg": "",
- "mechanic.ogg": "",
- "medal.ogg": "",
"meet.ogg": "a' coinneachadh ri chèile",
- "melon.ogg": "",
- "men.ogg": "daoine",
- "merry-go-round.ogg": "",
"mice.ogg": "dà luchag bheag",
- "microphone.ogg": "",
- "milk.ogg": "",
- "mill.ogg": "",
- "mimosa.ogg": "",
- "mirror.ogg": "",
- "mixer.ogg": "",
"mole.ogg": "famh dhubh",
- "mom.ogg": "",
- "moon.ogg": "",
- "moose.ogg": "",
"mop.ogg": "mapaid mhòr",
- "mosque.ogg": "",
"mosquito.ogg": "meanbh-chuileag mhòr",
- "mother.ogg": "",
- "motorcycle.ogg": "",
- "mountain.ogg": "",
- "mouse.ogg": "",
"mouth.ogg": "beul mòr",
- "movie.ogg": "",
- "mower.ogg": "",
"mud.ogg": "poll salach",
"mug.ogg": "muga mòr",
"mule.ogg": "leth-asal beag",
- "muscle.ogg": "",
"mushroom.ogg": "agairg nan cuileagan",
- "music.ogg": "",
- "musician.ogg": "",
- "naked.ogg": "",
"nap.ogg": "norrag bheag",
- "navel.ogg": "",
"neck.ogg": "amhaich thana",
- "necklace.ogg": "",
- "needle.ogg": "",
"nest.ogg": "nead beag",
"net.ogg": "lìon beag",
- "newspaper.ogg": "",
"night.ogg": "oidhche dhorch",
- "nightgown.ogg": "",
"nose.ogg": "sròn mhòr",
- "nostril.ogg": "",
- "notebook.ogg": "",
- "number.ogg": "",
- "nun.ogg": "",
- "nurse.ogg": "",
- "nurse_male.ogg": "",
"nut.ogg": "cnò mhòr",
"oar.ogg": "dà ràmh mòr",
"ocean.ogg": "cuan mòr",
- "office.ogg": "",
- "olive.ogg": "",
"on.ogg": "air",
- "one.ogg": "a h-aon",
- "onion.ogg": "",
- "open.ogg": "",
- "opossum.ogg": "",
"orange-color.ogg": "orainsear mòr",
"orange.ogg": "dath orains",
- "orchid.ogg": "",
- "ostrich.ogg": "",
- "otter.ogg": "",
"owl.ogg": "cailleach-oidhche bheag",
"ox.ogg": "tarbh mòr",
- "oyster.ogg": "",
- "pacifier.ogg": "",
"page.ogg": "duilleag bheag",
"pair.ogg": "paidhir bhrògan",
- "pajamas.ogg": "",
"pal.ogg": "clann bheaga",
- "palm_tree.ogg": "",
"pan.ogg": "aghann bheag",
- "panda.ogg": "",
- "panther.ogg": "",
- "panties.ogg": "",
- "pants.ogg": "",
- "papaya.ogg": "",
- "paper.ogg": "",
- "parachute.ogg": "",
- "parakeet.ogg": "",
- "parrot.ogg": "",
"patch.ogg": "tuthag bheag",
"path.ogg": "slighe bheag",
"paw.ogg": "spòg mhòr",
- "pea.ogg": "",
"peach.ogg": "peitseag mhòr",
- "peacock.ogg": "",
- "peak.ogg": "",
- "pear.ogg": "",
- "pearl.ogg": "",
"peck.ogg": "a' sgobadh",
- "pedal.ogg": "",
- "pelican.ogg": "",
"pen.ogg": "peann beag",
"pencil.ogg": "peansail mòr",
- "peony.ogg": "",
- "people.ogg": "",
- "pepper.ogg": "",
- "peppers.ogg": "",
"pet.ogg": "peata beag",
- "petal.ogg": "",
- "petite.ogg": "",
- "phone.ogg": "",
- "piano.ogg": "",
"picture.ogg": "dealbh beag",
- "pie.ogg": "",
"pig.ogg": "muc bheag",
- "pigeon.ogg": "",
- "pill.ogg": "",
- "pillow.ogg": "",
- "pilot.ogg": "",
"pine.ogg": "giuthas mòr",
- "pine_cone.ogg": "",
"pink.ogg": "dath pinc",
- "pip.ogg": "",
- "pipe.ogg": "",
- "piranha.ogg": "",
- "pirate.ogg": "",
- "pizza.ogg": "",
"plane.ogg": "plèana beag",
- "planet.ogg": "",
"plant.ogg": "lus beag",
"plate.ogg": "truinnsear mòr",
"play.ogg": "a' cluich",
- "pliers.ogg": "",
"plow.ogg": "a' treabhadh",
"plum.ogg": "plumas milis",
- "plumber.ogg": "",
- "pocket.ogg": "",
- "pod.ogg": "",
"pole.ogg": "pòla beag",
- "police.ogg": "",
- "pompon.ogg": "",
- "pond.ogg": "",
- "pony.ogg": "",
"pool.ogg": "amar-snàimh beag",
- "pop.ogg": "popcorn",
+ "popcorn.ogg": "popcorn",
"pope.ogg": "am pàpa",
- "porthole.ogg": "",
- "post.ogg": "",
"pot.ogg": "poit bheag",
- "potato.ogg": "",
"pounce.ogg": "a' teumadh",
- "president.ogg": "",
"pretty.ogg": "bòidheach",
"price.ogg": "prìs mhòr",
- "priest.ogg": "",
"prince.ogg": "prionnsa beag",
"princess.ogg": "bana-phrionnsa bheag",
- "prison.ogg": "",
- "prisoner.ogg": "",
"prize.ogg": "duais mhòr",
"pug.ogg": "cù-smutach",
- "pull.ogg": "",
- "pullover.ogg": "",
- "pumpkin.ogg": "",
"puppy.ogg": "cuilean beag",
- "pyramid.ogg": "",
"quarrel.ogg": "ag argamaid",
"queen.ogg": "bànrigh mhòr",
"question.ogg": "ceist mhòr",
"quilt.ogg": "cuibhrig mhòr",
"quiz.ogg": "co-fharpais cheist",
- "rabbit.ogg": "",
- "rabbit_baby.ogg": "",
- "race.ogg": "",
- "radio.ogg": "",
- "radish.ogg": "",
- "raft.ogg": "",
"rag.ogg": "luideag bheag",
"rage.ogg": "tha fearg air",
- "rain.ogg": "",
- "raincoat.ogg": "",
"rake.ogg": "ràcan mòr",
"ramp.ogg": "rampa beag",
"ran.ogg": "a' ruith",
- "raspberry.ogg": "",
"rat.ogg": "radan mòr",
- "razor.ogg": "",
"read.ogg": "a' leughadh",
"red.ogg": "dath dearg",
- "reptile.ogg": "",
- "rhinoceros.ogg": "",
"rice.ogg": "rìs geal",
"ride.ogg": "a' falbh air baidhsagal",
- "rifle.ogg": "",
"right.ogg": "deas",
"rip.ogg": "a' sracadh",
- "rise.ogg": "",
- "river.ogg": "",
- "road.ogg": "",
- "roast.ogg": "",
- "robe.ogg": "",
- "robot.ogg": "",
"rock.ogg": "clach bheag",
- "rocket.ogg": "",
- "rolling_pin.ogg": "",
"roof.ogg": "mullach mòr",
- "room.ogg": "",
- "root.ogg": "",
"rope.ogg": "ròpa fada",
"rose.ogg": "ròs mòr",
"round.ogg": "cruinn",
- "rowing.ogg": "",
"royal.ogg": "rìgh mòr",
"rug.ogg": "ruga beag",
"run.ogg": "a' rèiseadh",
"sad.ogg": "brònach",
- "saddle.ogg": "",
"sail.ogg": "seòl beag",
- "sailor.ogg": "",
- "salamander.ogg": "",
- "salmon.ogg": "",
"sand.ogg": "gainmheach bog",
- "sandals.ogg": "",
"sandwich.ogg": "ceapaire mòr",
- "sash.ogg": "",
- "sat.ogg": "casruisgte",
"sauce.ogg": "sabhs dearg",
- "sausage.ogg": "",
"scale.ogg": "sgèile beag",
"scar.ogg": "eàrra mhòr",
- "scared.ogg": "tha an t-eagal air",
+ "scare.ogg": "tha an t-eagal air",
"scarf.ogg": "sgarfa mhòr",
"school.ogg": "sgoil mhòr",
- "school_bag.ogg": "",
"science.ogg": "saidheans mòr",
- "scissors.ogg": "",
- "scorpion.ogg": "",
"scratch.ogg": "a' sgrìobadh",
"scream.ogg": "a' leigeil èigh",
"screw.ogg": "sgriubha mhòr",
- "screwdriver.ogg": "",
"scribble.ogg": "a' sgrochladh",
- "sea.ogg": "",
"seat.ogg": "suidheachan mòr",
"see.ogg": "a' faicinn",
"seed.ogg": "sìol beag",
- "shadow.ogg": "",
"shake.ogg": "a' crathadh",
"shark.ogg": "cearban mòr",
- "shave.ogg": "",
"shed.ogg": "seada beag",
- "sheep.ogg": "",
"shelf.ogg": "sgeilp bheag",
"shell.ogg": "slige mhòr",
"ship.ogg": "bàta beag",
"shirt.ogg": "lèine bheag",
"shoe.ogg": "bròg mhòr",
- "shoelace.ogg": "",
"shop.ogg": "bùth beag nan dèideagan",
"shore.ogg": "tràigh bheag",
"short.ogg": "goirid",
- "shovel.ogg": "",
"shower.ogg": "frasair mòr",
"shrimp.ogg": "muasgan-caol",
"shrub.ogg": "tuba bheag",
"shut.ogg": "dùinte",
- "shutter.ogg": "",
"sick.ogg": "tinn",
- "sidewalk.ogg": "",
"sign.ogg": "sanas mòr",
"sing.ogg": "a' seinn",
"sink.ogg": "dòirteal beag",
"sip.ogg": "a' gabhail drùthag",
- "sister.ogg": "",
"sit.ogg": "na shuidhe",
"skate.ogg": "a' falbh air spèileabord ",
- "skeleton.ogg": "",
"ski.ogg": "a' sgìtheadh",
- "skimmer.ogg": "",
"skin.ogg": "craiceann bog",
"skirt.ogg": "sgiort bheag",
"skunk.ogg": "tùdair beag",
"sky.ogg": "turadh beag",
- "slam.ogg": "",
"sled.ogg": "càrn beag",
"sleep.ogg": "na chadal",
"sleeve.ogg": "muilcheann goirid",
"sleigh.ogg": "slaodan mòr",
"slide.ogg": "sleamhnag bheag",
- "slim.ogg": "",
"slime.ogg": "snàmhas",
- "slippers.ogg": "",
"slope.ogg": "leathad mòr",
- "sloppy.ogg": "",
- "slot.ogg": "",
- "sloth.ogg": "",
- "slug.ogg": "",
"small.ogg": "beag",
"smell.ogg": "fàileadh math",
"smile.ogg": "gàire mhòr",
"smock.ogg": "na luideagan",
"smoke.ogg": "ceò beag",
"smooch.ogg": "a' pògadh",
"snack.ogg": "biadh beag",
"snail.ogg": "seilcheag bheag",
"snake.ogg": "nathair mhòr",
"sneaker.ogg": "bròg-spòrs",
"sniff.ogg": "a' snòtadh",
"snow.ogg": "sneachd mòr",
- "soap.ogg": "",
- "sob.ogg": "",
"sock.ogg": "stocainn gheal",
- "soldier.ogg": "",
- "sole.ogg": "",
- "sole_shoe.ogg": "",
- "son.ogg": "",
- "soup.ogg": "",
- "spade.ogg": "",
"spaghetti.ogg": "spaghetti",
- "spark.ogg": "",
- "sparrow.ogg": "",
- "spatula.ogg": "",
- "speak.ogg": "",
"spear.ogg": "sleagh mhòr",
- "spice.ogg": "",
"spider.ogg": "damhan-allaidh mòr",
- "spider_web.ogg": "",
"spike.ogg": "gràineag bheag",
"spill.ogg": "a' dòrtadh",
- "spinach.ogg": "",
- "spine.ogg": "",
- "spinning_top.ogg": "",
"splash.ogg": "a' plubadaich",
"splatter.ogg": "steall beag",
"sponge.ogg": "spong mòr",
- "spool.ogg": "",
"spoon.ogg": "spàin mhòr",
"sport.ogg": "spòrs",
"spot.ogg": "aodach breac",
"spray.ogg": "a' stealladh",
"spread.ogg": "a' liacradh",
"spring.ogg": "sprionga mòr",
- "spring_season.ogg": "",
"sprinkle.ogg": "craiteachan beag",
"square.ogg": "ceàrnagach",
"squash.ogg": "peapag chrom",
"squat.ogg": "a' dèanamh gurraban",
"squid.ogg": "gibearnach beag",
"squirrel.ogg": "feòrag bheag",
"squirt.ogg": "botal-steallaidh",
"stack.ogg": "cruach mhòr",
"stage.ogg": "àrd-ùrlar beag",
- "staircase.ogg": "",
"stamp.ogg": "stampa beag",
"stand.ogg": "na sheasamh",
"star.ogg": "rionnag bheag",
"stare.ogg": "a' dùr-choimhead",
"starfish.ogg": "crosgag bheag",
- "steak.ogg": "",
- "steam.ogg": "",
- "steep.ogg": "",
- "steeple.ogg": "",
"stem.ogg": "gas bheag",
- "step.ogg": "",
"stew.ogg": "stiubha math",
"stick.ogg": "maide beag",
"sting.ogg": "gath beag",
- "stinky.ogg": "",
- "stitch.ogg": "",
- "stomach.ogg": "",
"stone.ogg": "dòirneag bheag",
"stop.ogg": "stad ort",
"store.ogg": "bùth beag",
"stove.ogg": "stòbha beag",
"straight.ogg": "dìreach",
- "strainer.ogg": "",
"straw.ogg": "stràbh beag",
"strawberry.ogg": "sùbh-làir milis",
"stream.ogg": "allt beag",
"street.ogg": "sràid mhòr",
"stretch.ogg": "a' sìneadh",
"string.ogg": "sreang fhada",
"stripe.ogg": "stiall ghorm",
"strong.ogg": "làidir",
- "student.ogg": "",
"study.ogg": "ag ionnsachadh",
"stump.ogg": "stoc mòr",
- "sugar.ogg": "",
"suit.ogg": "deise ghorm",
- "suitcase.ogg": "",
"summer.ogg": "samhradh math",
- "summit.ogg": "",
"sun.ogg": "grian bhlàth",
"swan.ogg": "eala bhàn",
"sweat.ogg": "a' cur fallas",
- "sweatshirt.ogg": "",
"swim.ogg": "a' snàmh",
- "table.ogg": "",
- "tablecloth.ogg": "",
- "tadpole.ogg": "",
"tag.ogg": "taga beag",
- "tail.ogg": "",
"tall.ogg": "àrd",
- "tape_measure.ogg": "",
- "taxi.ogg": "",
"teach.ogg": "a' teagasg",
"teacher.ogg": "tidsear math",
"tear.ogg": "a' reubadh",
- "teddy.ogg": "",
"teeth.ogg": "fiaclan geala",
- "television.ogg": "",
- "temple.ogg": "",
- "ten.ogg": "a deich",
- "tennis.ogg": "",
- "tent.ogg": "",
- "text.ogg": "",
"thick.ogg": "tiugh",
- "thief.ogg": "",
"thigh.ogg": "leis thana",
"think.ogg": "a' smaoineachadh",
"thread.ogg": "snàithlean pinc",
- "three.ogg": "a trì",
"throat.ogg": "sgòrnan goirt",
"throw.ogg": "a' tilgeil",
- "thumb.ogg": "",
"tick.ogg": "feursad beag",
- "ticket.ogg": "",
- "tiger.ogg": "",
"time.ogg": "an t-àm",
- "tin.ogg": "",
- "tire.ogg": "",
"tired.ogg": "sgìth",
- "tissue.ogg": "",
- "toad.ogg": "",
- "toaster.ogg": "",
- "toe.ogg": "",
"toilet.ogg": "an taigh-beag",
- "tomatoe.ogg": "",
- "tongs.ogg": "",
- "tongue.ogg": "",
"tool.ogg": "acainnean",
"top.ogg": "am mullach",
"torch.ogg": "leus gorm",
"touch.ogg": "a' beantainn",
"towel.ogg": "searbhadair buidhe",
"toy.ogg": "dèideag bheag",
"trail.ogg": "slighe thana",
"train.ogg": "trèan beag",
- "train_station.ogg": "",
"trap.ogg": "ribe beag",
"trash.ogg": "sgudal salach",
"tray.ogg": "treidhe bheag",
"treat.ogg": "siùcaran",
"tree.ogg": "craobh mhòr",
- "triangle.ogg": "",
- "tribe.ogg": "",
- "trip.ogg": "",
"truck.ogg": "làraidh dhearg",
"tube.ogg": "beul-dath dearg",
- "tulip.ogg": "",
"tune.ogg": "fonn math",
- "turkey.ogg": "",
- "turnip.ogg": "",
- "turtle.ogg": "",
- "tusk.ogg": "",
- "twin_boys.ogg": "",
- "twin_girls.ogg": "",
- "two.ogg": "a dhà",
- "umbrella.ogg": "",
"under.ogg": "foidhe",
- "uniform.ogg": "",
"van.ogg": "bhana beag",
- "vapor.ogg": "",
- "vase.ogg": "",
- "vegetable.ogg": "",
- "vein.ogg": "",
- "verdure.ogg": "",
- "vest.ogg": "",
"vet.ogg": "dotair math",
- "viper.ogg": "",
- "vowel.ogg": "",
- "vulture.ogg": "",
"wag.ogg": "a' crathadh earball",
"walk.ogg": "a' seasamh air leth-chas",
- "wall.ogg": "",
- "walnut.ogg": "",
- "wart.ogg": "",
"wash.ogg": "a' gabhail amar",
- "wasp.ogg": "",
"watch.ogg": "uaireadair beag",
"water.ogg": "uisge fuar",
- "wave.ogg": "",
- "wedding.ogg": "",
"wedge.ogg": "gèinn mòr",
- "weight.ogg": "",
"wet.ogg": "fliuch",
- "whale.ogg": "",
"wheat.ogg": "cruithneachd mhath",
"wheel.ogg": "cuibhle chruinn",
"whisk.ogg": "sguabag bheag",
"whisper.ogg": "a' cagair",
"white.ogg": "dath geal",
- "wide.ogg": "",
- "wife.ogg": "",
"wig.ogg": "falt fuadain",
"win.ogg": "a' buannachadh",
"wind.ogg": "gaoth mhòr",
- "window.ogg": "",
- "window_glass.ogg": "",
"wing.ogg": "sgiath bheag",
- "winter.ogg": "",
- "wolf.ogg": "",
- "woman.ogg": "",
"wood.ogg": "dèile fhada",
- "word.ogg": "",
- "worker.ogg": "",
- "world.ogg": "",
- "wreath.ogg": "",
"wrench.ogg": "toinnear beag",
"wrist.ogg": "caol an dùirn",
"write.ogg": "a' sgrìobhadh",
- "yarn.ogg": "iarna bheag",
- "yellow.ogg": "",
- "yogurt.ogg": "",
"yum.ogg": "blasta",
- "zebra.ogg": "",
- "zipper.ogg": "",
"zoo.ogg": "sutha beag"
-}
+}
\ No newline at end of file
diff --git a/src/activities/lang/resource/content-gl.json b/src/activities/lang/resource/content-gl.json
new file mode 100644
index 000000000..b378be66d
--- /dev/null
+++ b/src/activities/lang/resource/content-gl.json
@@ -0,0 +1,1092 @@
+{
+ "10.ogg": "dez",
+ "11.ogg": "once",
+ "12.ogg": "doce",
+ "16.ogg": "dezaseis",
+ "U0030.ogg": "cero",
+ "U0031.ogg": "un",
+ "U0032.ogg": "dous",
+ "U0033.ogg": "tres",
+ "U0034.ogg": "catro",
+ "U0035.ogg": "cinco",
+ "U0036.ogg": "seis",
+ "U0037.ogg": "sete",
+ "U0038.ogg": "oito",
+ "U0039.ogg": "nove",
+ "accountant.ogg": "contábel",
+ "ache.ogg": "dor",
+ "acorn.ogg": "landra",
+ "actor.ogg": "actor",
+ "air_horn.ogg": "bucina",
+ "alarmclock.ogg": "espertador",
+ "alligator.ogg": "caimán",
+ "alphabet.ogg": "garra",
+ "anchor.ogg": "áncora",
+ "angel.ogg": "anxo",
+ "angry.ogg": "anoxado",
+ "animal.ogg": "animal",
+ "ankle.ogg": "nocello",
+ "ant.ogg": "formiga",
+ "anteater.ogg": "oso formigueiro",
+ "antelope.ogg": "antílope",
+ "apple.ogg": "mazá",
+ "apple_tree.ogg": "maceira",
+ "appliance.ogg": "electrodoméstico",
+ "apricot.ogg": "albaricoque",
+ "arm.ogg": "brazo",
+ "armchair.ogg": "cadeira de brazos",
+ "artichoke.ogg": "alcachofa",
+ "artist.ogg": "artista",
+ "asparagus.ogg": "espárrago",
+ "astronaut.ogg": "astronauta",
+ "athlete.ogg": "atleta",
+ "avocado.ogg": "aguacate",
+ "ax.ogg": "machado",
+ "baby_bottle.ogg": "biberón",
+ "back.ogg": "atrás",
+ "badge.ogg": "placa",
+ "bag.ogg": "bolsa",
+ "bait.ogg": "cebo",
+ "balance.ogg": "equilibrio",
+ "bald.ogg": "calvo",
+ "ball.ogg": "bóla",
+ "ball_of_yarn.ogg": "bóla de fío",
+ "ball_soccer.ogg": "pelota de fútbol",
+ "ballet.ogg": "ballet",
+ "bank.ogg": "banco",
+ "banker_female.ogg": "banqueira",
+ "bark.ogg": "ladrar",
+ "barn.ogg": "palleiro",
+ "bat.ogg": "morcego",
+ "bath.ogg": "ducha",
+ "bathing_suit.ogg": "traxe de baño",
+ "bay.ogg": "baía",
+ "beach.ogg": "praia",
+ "bean.ogg": "faba",
+ "bear.ogg": "oso",
+ "beard.ogg": "barba",
+ "beat.ogg": "golpear",
+ "beaver.ogg": "castor",
+ "bed.ogg": "cama",
+ "bedroom.ogg": "dormitorio",
+ "bee.ogg": "abella",
+ "beetle.ogg": "escaravello",
+ "beg.ogg": "rogar",
+ "behind.ogg": "detrás",
+ "bell.ogg": "Campá",
+ "belly.ogg": "ventre",
+ "bench.ogg": "banco",
+ "bib.ogg": "babeiro",
+ "big.ogg": "grande",
+ "big_top.ogg": "carpa de circo",
+ "bike.ogg": "bicicleta",
+ "bird.ogg": "paxaro",
+ "bit.ogg": "mordedura",
+ "bite.ogg": "morder",
+ "black.ogg": "negro",
+ "blackberry.ogg": "amora",
+ "blackbird.ogg": "merlo",
+ "blade.ogg": "folla",
+ "blind.ogg": "cego",
+ "blink.ogg": "pestanexar",
+ "block.ogg": "bloque",
+ "blond.ogg": "louro",
+ "blue.ogg": "azul",
+ "blueberry.ogg": "arando",
+ "blush.ogg": "ruborizarse",
+ "board.ogg": "taboleiro",
+ "boat.ogg": "bote",
+ "boil.ogg": "cocer",
+ "bolt.ogg": "bulón",
+ "bomb.ogg": "bomba",
+ "bone.ogg": "óso",
+ "book.ogg": "libro",
+ "bookcase.ogg": "libraría",
+ "bottom.ogg": "fondo",
+ "box.ogg": "caixa",
+ "boxer.ogg": "boxeador",
+ "boy.ogg": "rapaz",
+ "braid.ogg": "trenza",
+ "brain.ogg": "cerebro",
+ "branch.ogg": "rama",
+ "bread.ogg": "pan",
+ "break.ogg": "romper",
+ "breast.ogg": "peito",
+ "brick.ogg": "ladrillo",
+ "bricklayer.ogg": "albanel",
+ "bride.ogg": "noiva",
+ "bridge.ogg": "ponte",
+ "bright.ogg": "brillante",
+ "broccoli.ogg": "brócoli",
+ "brother.ogg": "irmán",
+ "brown.ogg": "marrón",
+ "brush.ogg": "brocha",
+ "bubble.ogg": "burbulla",
+ "bucket.ogg": "cubo",
+ "bud.ogg": "abrocho",
+ "buffalo.ogg": "búfalo",
+ "bug.ogg": "bicho",
+ "bulb.ogg": "lámpada incandescente",
+ "bull.ogg": "touro",
+ "bump.ogg": "croque",
+ "bun.ogg": "bolo",
+ "bus.ogg": "bus",
+ "bush.ogg": "matogueira",
+ "butcher.ogg": "carniceiro",
+ "butter.ogg": "manteiga",
+ "butterfly.ogg": "bolboreta",
+ "button.ogg": "botón",
+ "cabbage.ogg": "repolo",
+ "cabin.ogg": "cabana",
+ "cacao.ogg": "cacao",
+ "cactus.ogg": "cacto",
+ "cage.ogg": "gaiola",
+ "cake.ogg": "pastel",
+ "call.ogg": "chamar",
+ "camel.ogg": "camelo",
+ "camera.ogg": "Cámara",
+ "camp.ogg": "campamento",
+ "can.ogg": "bote",
+ "canary.ogg": "canario",
+ "candle.ogg": "candea",
+ "candy.ogg": "doce",
+ "cane.ogg": "bastón",
+ "canoe.ogg": "canoa",
+ "canon.ogg": "canón",
+ "canyon.ogg": "canón",
+ "cap.ogg": "gorra",
+ "cape.ogg": "capa",
+ "car.ogg": "coche",
+ "carafe.ogg": "garrafa",
+ "card.ogg": "tarxeta",
+ "carnival.ogg": "entroido",
+ "carpenter.ogg": "carpinteiro",
+ "carpet.ogg": "alfombra",
+ "carrot.ogg": "cenoria",
+ "cart.ogg": "carros",
+ "cash.ogg": "efectivo",
+ "castle.ogg": "castelo",
+ "cat.ogg": "gato",
+ "cat_female.ogg": "gata",
+ "catch.ogg": "pescar",
+ "caterpillar.ogg": "eiruga",
+ "cauldron.ogg": "caldeiro",
+ "cauliflower.ogg": "coliflor",
+ "cave.ogg": "cova",
+ "cavern.ogg": "caverna",
+ "celery.ogg": "apio",
+ "centipede.ogg": "cempés",
+ "cereal.ogg": "cereal",
+ "chain.ogg": "cadea",
+ "chair.ogg": "cadeira",
+ "chalk.ogg": "xiz",
+ "chameleon.ogg": "camaleón",
+ "chandelier.ogg": "candelabro",
+ "chat.ogg": "conversar",
+ "cheek.ogg": "meixela",
+ "cheer.ogg": "animar",
+ "cheese.ogg": "queixo",
+ "chef.ogg": "cociñeiro",
+ "cherry.ogg": "cereixa",
+ "chest.ogg": "cofre",
+ "chick.ogg": "pito",
+ "chicken.ogg": "polo",
+ "child.ogg": "neno",
+ "chimney.ogg": "cheminea",
+ "chimp.ogg": "chimpancé",
+ "chin.ogg": "queixelo",
+ "chocolate.ogg": "chocolate",
+ "chop.ogg": "cortar",
+ "chores.ogg": "tarefas",
+ "christmas.ogg": "nadal",
+ "cigar.ogg": "cigarro",
+ "circus.ogg": "circo",
+ "city.ogg": "cidade",
+ "clam.ogg": "ameixa",
+ "clap.ogg": "chocar",
+ "class.ogg": "clase",
+ "claw.ogg": "gadoupa",
+ "clay.ogg": "barro",
+ "clean.ogg": "limpar",
+ "cleaning_lady.ogg": "limpador",
+ "cliff.ogg": "cantil",
+ "climb.ogg": "escalar",
+ "clock.ogg": "reloxo",
+ "cloth.ogg": "tea",
+ "clothes_hanger.ogg": "percha",
+ "cloud.ogg": "nube",
+ "cloudy.ogg": "anubrado",
+ "clover.ogg": "trevo",
+ "clown.ogg": "pallaso",
+ "coach.ogg": "adestrador",
+ "coast.ogg": "costa",
+ "coat.ogg": "abrigo",
+ "cobra.ogg": "cobra",
+ "coconut.ogg": "coco",
+ "cod.ogg": "bacallau",
+ "coffee.ogg": "café",
+ "coin.ogg": "moeda",
+ "cold.ogg": "frío",
+ "color.ogg": "cor",
+ "colt.ogg": "poldro",
+ "comb.ogg": "peite",
+ "cone.ogg": "cono",
+ "cook.ogg": "cociñar",
+ "cookie.ogg": "galleta",
+ "cork.ogg": "rolla",
+ "corn.ogg": "millo",
+ "couch.ogg": "sofá",
+ "cough.ogg": "tusir",
+ "couple.ogg": "parella",
+ "cow.ogg": "vaca",
+ "cowboy.ogg": "vaqueiro",
+ "crab.ogg": "caranguexo",
+ "cradle.ogg": "rolo",
+ "craft.ogg": "artesanía",
+ "crawl.ogg": "gatear",
+ "crazy.ogg": "tolo",
+ "creek.ogg": "regato",
+ "crepe.ogg": "filloa",
+ "crib.ogg": "berce",
+ "croak.ogg": "croar",
+ "crocodile.ogg": "crocodilo",
+ "cross.ogg": "cruz",
+ "crow.ogg": "corvo",
+ "crown.ogg": "coroa",
+ "crumb.ogg": "migallas",
+ "crust.ogg": "codia",
+ "cry.ogg": "chorar",
+ "crystal.ogg": "Cristal",
+ "cube.ogg": "cubo",
+ "cucumber.ogg": "cogombro",
+ "curtain.ogg": "cortina",
+ "cut.ogg": "cortar",
+ "cute.ogg": "adorábel",
+ "dad.ogg": "pai",
+ "daffodil.ogg": "narciso",
+ "daisy.ogg": "margarida",
+ "dam.ogg": "dam",
+ "dance.ogg": "bailar",
+ "dandelion.ogg": "mexacán",
+ "dart_board.ogg": "taboleiro de dardos",
+ "date_fruit.ogg": "dátil",
+ "deer.ogg": "cervo",
+ "den.ogg": "gorida",
+ "desert.ogg": "deserto",
+ "desk.ogg": "escritorio",
+ "dessert.ogg": "sobremesa",
+ "diamond.ogg": "diamante",
+ "dig.ogg": "cavar",
+ "dirt.ogg": "terra",
+ "dirty.ogg": "sucio",
+ "dish.ogg": "prato",
+ "dishcloth.ogg": "baeta",
+ "dive.ogg": "somerxerse",
+ "doctor.ogg": "médico",
+ "doe.ogg": "cerva",
+ "dog.ogg": "can",
+ "doll.ogg": "boneco",
+ "dolphin.ogg": "delfín",
+ "domino.ogg": "dominó",
+ "door.ogg": "porta",
+ "doormat.ogg": "felpudo",
+ "dot.ogg": "punto",
+ "doughnut.ogg": "rosquilla",
+ "dove.ogg": "pomba",
+ "dragon.ogg": "dragón",
+ "dragonfly.ogg": "libélula",
+ "draw.ogg": "debuxar",
+ "drawer.ogg": "caixón",
+ "dream.ogg": "soñar",
+ "dress.ogg": "vestido",
+ "drink.ogg": "bebida",
+ "drip.ogg": "gota",
+ "drive.ogg": "conducir",
+ "drool.ogg": "babear",
+ "drum.ogg": "tambor",
+ "dry.ogg": "secar",
+ "duck.ogg": "pato",
+ "duck_mother.ogg": "nai de pato",
+ "dune.ogg": "duna",
+ "dwarf.ogg": "anano",
+ "eagle.ogg": "aguia",
+ "ear.ogg": "orella",
+ "earth.ogg": "terra",
+ "eat.ogg": "comer",
+ "egg.ogg": "ovo",
+ "eggplant.ogg": "berenxena",
+ "elbow.ogg": "cóbado",
+ "electrician.ogg": "electricista",
+ "elk.ogg": "alce",
+ "empty.ogg": "baleiro",
+ "engine.ogg": "motor",
+ "engineer.ogg": "enxeñeiro",
+ "eraser.ogg": "borrador",
+ "explore.ogg": "explorar",
+ "eyelash.ogg": "pestana",
+ "eyes.ogg": "ollos",
+ "face.ogg": "cara",
+ "fair.ogg": "feira",
+ "fairy.ogg": "fada",
+ "fall.ogg": "caer",
+ "fall_season.ogg": "outono",
+ "family.ogg": "familia",
+ "fan.ogg": "Ventilador",
+ "farm.ogg": "granxa",
+ "farmer.ogg": "labrego",
+ "fat.ogg": "gordo",
+ "faucet.ogg": "billa",
+ "fawn.ogg": "cervato",
+ "fear.ogg": "medo",
+ "feast.ogg": "festín",
+ "feather.ogg": "pluma",
+ "feed.ogg": "alimentar",
+ "femur.ogg": "fémur",
+ "fetch.ogg": "coller",
+ "fig.ogg": "figo",
+ "fin.ogg": "aleta",
+ "find.ogg": "atopar",
+ "finger.ogg": "dedo",
+ "fire.ogg": "lume",
+ "fire_extinguisher.ogg": "extintor",
+ "fireman.ogg": "bombeiro",
+ "fish.ogg": "peixe",
+ "fisherman.ogg": "pescador",
+ "fist.ogg": "puño",
+ "flacon.ogg": "bote",
+ "flag.ogg": "bandeira",
+ "flame.ogg": "chama",
+ "flamingo.ogg": "flamengo",
+ "flash.ogg": "foco",
+ "flat.ogg": "piso",
+ "flies.ogg": "moscas",
+ "float.ogg": "flotar",
+ "flour.ogg": "fariña",
+ "flower.ogg": "flor",
+ "fluff.ogg": "felpa",
+ "flute.ogg": "frauta",
+ "fly.ogg": "voar",
+ "foam.ogg": "espuma",
+ "foot.ogg": "pé",
+ "forest.ogg": "bosque",
+ "fork.ogg": "garfo",
+ "fountain.ogg": "fonte",
+ "fox.ogg": "raposo",
+ "freeze.ogg": "conxelar",
+ "friend.ogg": "amigo",
+ "fries.ogg": "patacas fritidas",
+ "frog.ogg": "ra",
+ "front.ogg": "diante",
+ "fruit.ogg": "froita",
+ "fudge.ogg": "caramelo",
+ "full.ogg": "completo",
+ "fur.ogg": "pel",
+ "game.ogg": "xogo",
+ "garage.ogg": "garaxe",
+ "garden.ogg": "xardín",
+ "garlic.ogg": "allo",
+ "gem.ogg": "xema",
+ "giant.ogg": "xigante",
+ "gift.ogg": "agasallo",
+ "giraffe.ogg": "xirafa",
+ "girl.ogg": "rapaza",
+ "glass.ogg": "vaso",
+ "glasses.ogg": "gafas",
+ "glove.ogg": "guante",
+ "glue.ogg": "pegamento",
+ "gnome.ogg": "gnomo",
+ "goat.ogg": "cabra",
+ "golden.ogg": "dourado",
+ "golf.ogg": "golf",
+ "goose.ogg": "ganso",
+ "gorilla.ogg": "gorila",
+ "grain.ogg": "grao",
+ "grandmother.ogg": "avoa",
+ "grape.ogg": "uva",
+ "grapefruit.ogg": "granada",
+ "grass.ogg": "herba",
+ "grave.ogg": "tumba",
+ "gray.ogg": "gris",
+ "green.ogg": "verde",
+ "grill.ogg": "grella",
+ "grin.ogg": "sorriso",
+ "ground.ogg": "Toma de terra",
+ "growl.ogg": "gruñir",
+ "guignol.ogg": "monicreque",
+ "guinea_pig.ogg": "cobaia",
+ "gum.ogg": "goma de mascar",
+ "hair.ogg": "pelo",
+ "hair_dryer.ogg": "secador",
+ "half.ogg": "metade",
+ "ham.ogg": "xamón",
+ "hamburger.ogg": "hamburguesa",
+ "hammer.ogg": "martelo",
+ "hand.ogg": "man",
+ "handlebar.ogg": "guiador",
+ "happy.ogg": "feliz",
+ "harp.ogg": "arpa",
+ "hat.ogg": "sombreiro",
+ "hatch.ogg": "romper a casca",
+ "hay.ogg": "feo",
+ "head.ogg": "cabeza",
+ "hear.ogg": "escoitar",
+ "heat.ogg": "calor",
+ "hedge.ogg": "sebe",
+ "hedgehog.ogg": "ourizo",
+ "heel.ogg": "tacón",
+ "helmet.ogg": "casco",
+ "hen.ogg": "galiña",
+ "herd.ogg": "rabaño",
+ "high.ogg": "alta",
+ "hike.ogg": "escalar",
+ "hill.ogg": "outeiro",
+ "hip.ogg": "cadeira",
+ "hippopotamus.ogg": "Hipopótamo",
+ "hit.ogg": "golpe",
+ "hive.ogg": "colmea",
+ "hockey.ogg": "hóckey",
+ "hole.ogg": "burato",
+ "home.ogg": "casa",
+ "hook.ogg": "gancho",
+ "hop.ogg": "saltar",
+ "horse.ogg": "cabalo",
+ "hose.ogg": "mangueira",
+ "hospital.ogg": "hospital",
+ "hot.ogg": "quente",
+ "hot_dog.ogg": "bocadillo de salchicha",
+ "hound.ogg": "sabuxo",
+ "house.ogg": "casa",
+ "howl.ogg": "ouvear",
+ "hug.ogg": "abrazar",
+ "huge.ogg": "xigante",
+ "hummingbird.ogg": "colibrí",
+ "hunchbacked.ogg": "corcovado",
+ "hunter.ogg": "cazador",
+ "husband.ogg": "marido",
+ "hut.ogg": "choza",
+ "hyena.ogg": "hiena",
+ "ice.ogg": "xeo",
+ "iceberg.ogg": "iceberg",
+ "iguana.ogg": "iguana",
+ "ill.ogg": "enfermo",
+ "ink.ogg": "tinta",
+ "island.ogg": "illa",
+ "jacket.ogg": "chaqueta",
+ "jaguar.ogg": "xaguar",
+ "jam.ogg": "marmelada",
+ "jay.ogg": "gaio",
+ "jelly.ogg": "xelatina",
+ "jellyfish.ogg": "medusa",
+ "jewel.ogg": "xoia",
+ "job.ogg": "traballo",
+ "jockey.ogg": "xinete",
+ "jog.ogg": "correr",
+ "joy.ogg": "alegría",
+ "judge.ogg": "xuíz",
+ "judo.ogg": "judo",
+ "juggler.ogg": "malabarista",
+ "juice.ogg": "zume",
+ "jump.ogg": "saltar",
+ "kangaroo.ogg": "canguro",
+ "keel.ogg": "tirar",
+ "kernel.ogg": "froito",
+ "keyboard.ogg": "teclado",
+ "kimono.ogg": "quimono",
+ "king.ogg": "rei",
+ "kiss.ogg": "bicar",
+ "kitchen.ogg": "cociña",
+ "kite.ogg": "papaventos",
+ "kitten.ogg": "gatiño",
+ "kiwi.ogg": "kiwi",
+ "knee.ogg": "xeonllo",
+ "kneel.ogg": "axeonllar",
+ "knife.ogg": "coitelo",
+ "knight.ogg": "cabaleiro",
+ "knit.ogg": "tecer",
+ "knot.ogg": "nó",
+ "koala.ogg": "coala",
+ "lad.ogg": "neno",
+ "lady.ogg": "señora",
+ "ladybug.ogg": "xoaniña",
+ "lake.ogg": "lago",
+ "lama.ogg": "llama",
+ "lamb.ogg": "cordeiro",
+ "lamp.ogg": "lámpada",
+ "land.ogg": "terra",
+ "lane.ogg": "carril",
+ "lap.ogg": "colo",
+ "lasso.ogg": "lazo",
+ "laugh.ogg": "rir",
+ "lava.ogg": "lava",
+ "lawn.ogg": "céspede",
+ "lawyer.ogg": "avogado",
+ "leaf.ogg": "folla",
+ "ledge.ogg": "saínte",
+ "leek.ogg": "porro",
+ "left.ogg": "esquerda",
+ "leg.ogg": "perna",
+ "lemon.ogg": "limón",
+ "lemonade.ogg": "limoada",
+ "lemur.ogg": "lémure",
+ "leopard.ogg": "leopardo",
+ "lettuce.ogg": "leituga",
+ "librarian.ogg": "bibliotecario",
+ "lick.ogg": "lamber",
+ "lid.ogg": "tapa",
+ "lift.ogg": "levantamento",
+ "light.ogg": "luz",
+ "lighthouse.ogg": "faro",
+ "lightning.ogg": "lóstrego",
+ "lilac.ogg": "lila",
+ "lime.ogg": "lima",
+ "line.ogg": "liña",
+ "link.ogg": "ligazón",
+ "lion.ogg": "león",
+ "lion_cub.ogg": "cachorro de león",
+ "lip.ogg": "beizo",
+ "liquid.ogg": "líquido",
+ "lizard.ogg": "lagarto",
+ "lobster.ogg": "lagosta",
+ "log.ogg": "tronco",
+ "look.ogg": "mirar",
+ "lunch.ogg": "comida",
+ "mad.ogg": "Desviación absoluta da mediana",
+ "magic.ogg": "maxia",
+ "magnet.ogg": "imán",
+ "magnifying_glass.ogg": "lupa",
+ "magpie.ogg": "urraca",
+ "mail.ogg": "correo",
+ "man.ogg": "man",
+ "mane.ogg": "melena",
+ "mango.ogg": "mango",
+ "map.ogg": "mapa",
+ "maple.ogg": "pradairo",
+ "marble.ogg": "mármore",
+ "mashed_potatoes.ogg": "puré de patacas",
+ "mask.ogg": "máscara",
+ "mast.ogg": "mastro",
+ "mat.ogg": "tapete",
+ "match.ogg": "misto",
+ "mate.ogg": "colega",
+ "mattress.ogg": "colchón",
+ "mauve.ogg": "malva",
+ "meal.ogg": "comida",
+ "meat.ogg": "carne",
+ "mechanic.ogg": "mecánico",
+ "medal.ogg": "medalla",
+ "meet.ogg": "coñecer",
+ "melon.ogg": "melón",
+ "merry-go-round.ogg": "carrusel",
+ "mice.ogg": "ratos",
+ "microphone.ogg": "Micrófono",
+ "milk.ogg": "leite",
+ "mill.ogg": "muíño",
+ "mimosa.ogg": "mimosa",
+ "mirror.ogg": "réplica",
+ "mixer.ogg": "Mesturador",
+ "mole.ogg": "toupa",
+ "mom.ogg": "nai",
+ "moon.ogg": "lúa",
+ "moose.ogg": "alce",
+ "mop.ogg": "fregona",
+ "mosque.ogg": "mesquita",
+ "mosquito.ogg": "mosquito",
+ "mother.ogg": "nai",
+ "motorcycle.ogg": "moto",
+ "mountain.ogg": "montaña",
+ "mouse.ogg": "rato",
+ "mouth.ogg": "boca",
+ "movie.ogg": "filme",
+ "mower.ogg": "cortacéspede",
+ "mud.ogg": "lama",
+ "mug.ogg": "cunca",
+ "mule.ogg": "mula",
+ "muscle.ogg": "músculo",
+ "mushroom.ogg": "cogomelo",
+ "music.ogg": "música",
+ "musician.ogg": "músico",
+ "naked.ogg": "espido",
+ "nap.ogg": "botar unha soneca",
+ "navel.ogg": "embigo",
+ "neck.ogg": "pescozo",
+ "necklace.ogg": "colgante",
+ "needle.ogg": "agulla",
+ "nest.ogg": "niño",
+ "net.ogg": "rede",
+ "newspaper.ogg": "xornal",
+ "night.ogg": "noite",
+ "nightgown.ogg": "camisón",
+ "nose.ogg": "nariz",
+ "nostril.ogg": "orificio nasal",
+ "notebook.ogg": "caderno",
+ "number.ogg": "número",
+ "nun.ogg": "monxa",
+ "nurse.ogg": "enfermeira",
+ "nurse_male.ogg": "enfermeiro",
+ "nut.ogg": "abelá",
+ "oar.ogg": "remo",
+ "ocean.ogg": "océano",
+ "office.ogg": "oficina",
+ "olive.ogg": "oliva",
+ "on.ogg": "encima",
+ "onion.ogg": "cebola",
+ "open.ogg": "aberto",
+ "opossum.ogg": "sarigüé",
+ "orange-color.ogg": "cor laranxa",
+ "orange.ogg": "laranxa",
+ "orchid.ogg": "orquídea",
+ "ostrich.ogg": "avestruz",
+ "otter.ogg": "londra",
+ "owl.ogg": "curuxa",
+ "ox.ogg": "boi",
+ "oyster.ogg": "ostra",
+ "pacifier.ogg": "chupete",
+ "page.ogg": "páxina",
+ "pair.ogg": "parella",
+ "pajamas.ogg": "pixama",
+ "pal.ogg": "compañeiro",
+ "palm_tree.ogg": "palmeira",
+ "pan.ogg": "tixola",
+ "panda.ogg": "panda",
+ "panther.ogg": "pantera",
+ "panties.ogg": "bragas",
+ "pants.ogg": "pantalóns",
+ "papaya.ogg": "papaia",
+ "paper.ogg": "papel",
+ "parachute.ogg": "paracaídas",
+ "parakeet.ogg": "periquito",
+ "parrot.ogg": "papagaio",
+ "patch.ogg": "parche",
+ "path.ogg": "ruta",
+ "paw.ogg": "pouta",
+ "pea.ogg": "chícharo",
+ "peach.ogg": "pexego",
+ "peacock.ogg": "pavón",
+ "peak.ogg": "cume",
+ "pear.ogg": "pera",
+ "pearl.ogg": "perla",
+ "peck.ogg": "peteirar",
+ "pedal.ogg": "pedal",
+ "pelican.ogg": "pelicano",
+ "pen.ogg": "bolígrafo",
+ "pencil.ogg": "lapis",
+ "peony.ogg": "peonia",
+ "people.ogg": "persoas",
+ "pepper.ogg": "pemento",
+ "peppers.ogg": "pementos",
+ "pet.ogg": "mascota",
+ "petal.ogg": "pétalo",
+ "phone.ogg": "teléfono",
+ "piano.ogg": "piano",
+ "picture.ogg": "imaxe",
+ "pie.ogg": "torta",
+ "pig.ogg": "porco",
+ "pigeon.ogg": "pomba",
+ "pill.ogg": "pílula",
+ "pillow.ogg": "almofada",
+ "pilot.ogg": "piloto",
+ "pine.ogg": "piñeiro",
+ "pine_cone.ogg": "piña",
+ "pink.ogg": "rosa",
+ "pip.ogg": "semente",
+ "pipe.ogg": "pipa",
+ "piranha.ogg": "piraña",
+ "pirate.ogg": "pirata",
+ "pizza.ogg": "pizza",
+ "plane.ogg": "avión",
+ "planet.ogg": "planeta",
+ "plant.ogg": "planta",
+ "plate.ogg": "Placa",
+ "play.ogg": "xogar",
+ "pliers.ogg": "alicate",
+ "plow.ogg": "labrar",
+ "plum.ogg": "ameixa",
+ "plumber.ogg": "fontaneiro",
+ "pocket.ogg": "peto",
+ "pod.ogg": "bagullo",
+ "pole.ogg": "percha",
+ "police.ogg": "policía",
+ "pompon.ogg": "pompón",
+ "pond.ogg": "estanque",
+ "pony.ogg": "poni",
+ "pool.ogg": "piscina",
+ "popcorn.ogg": "flocos de millo",
+ "pope.ogg": "papa",
+ "porthole.ogg": "ollo de boi",
+ "post.ogg": "caixa do correo",
+ "pot.ogg": "ola",
+ "potato.ogg": "potato",
+ "pounce.ogg": "abalanzarse",
+ "president.ogg": "presidente",
+ "pretty.ogg": "guapo",
+ "price.ogg": "prezo",
+ "priest.ogg": "cura",
+ "prince.ogg": "príncipe",
+ "princess.ogg": "princesa",
+ "prison.ogg": "prisión",
+ "prisoner.ogg": "prisioneiro",
+ "prize.ogg": "premio",
+ "pug.ogg": "carlino",
+ "pull.ogg": "tirar",
+ "pullover.ogg": "xersei",
+ "pumpkin.ogg": "cabaza",
+ "puppy.ogg": "cachorro",
+ "pyramid.ogg": "pirámide",
+ "quarrel.ogg": "discutir",
+ "queen.ogg": "raíña",
+ "question.ogg": "pregunta",
+ "quilt.ogg": "edredón",
+ "quiz.ogg": "proba",
+ "rabbit.ogg": "coello",
+ "rabbit_baby.ogg": "cría de coello",
+ "race.ogg": "carreira",
+ "radio.ogg": "radio",
+ "radish.ogg": "ravo",
+ "raft.ogg": "balsa",
+ "rag.ogg": "trapo",
+ "rage.ogg": "ira",
+ "rain.ogg": "chuvia",
+ "raincoat.ogg": "chuvasqueiro",
+ "rake.ogg": "angazo",
+ "ramp.ogg": "rampla",
+ "ran.ogg": "correr",
+ "raspberry.ogg": "framboesa",
+ "rat.ogg": "rata",
+ "razor.ogg": "máquina de afeitar",
+ "read.ogg": "ler",
+ "red.ogg": "vermello",
+ "reptile.ogg": "réptil",
+ "rhinoceros.ogg": "rinoceronte",
+ "rice.ogg": "arroz",
+ "ride.ogg": "ciclismo",
+ "rifle.ogg": "rifle",
+ "right.ogg": "dereita",
+ "rip.ogg": "arrincar",
+ "rise.ogg": "subir",
+ "river.ogg": "río",
+ "road.ogg": "estrada",
+ "roast.ogg": "asado",
+ "robe.ogg": "toga",
+ "robot.ogg": "robot",
+ "rock.ogg": "rocha",
+ "rocket.ogg": "foguete",
+ "rolling_pin.ogg": "rodete",
+ "roof.ogg": "teito",
+ "room.ogg": "cuarto",
+ "root.ogg": "raíz",
+ "rope.ogg": "corda",
+ "rose.ogg": "rosa",
+ "round.ogg": "redondo",
+ "rowing.ogg": "remo",
+ "royal.ogg": "real",
+ "rug.ogg": "moqueta",
+ "run.ogg": "correr",
+ "sad.ogg": "triste",
+ "saddle.ogg": "montura",
+ "sail.ogg": "navegar",
+ "sailor.ogg": "mariñeiro",
+ "salamander.ogg": "salamántiga",
+ "salmon.ogg": "salmón",
+ "sand.ogg": "area",
+ "sandals.ogg": "sandalias",
+ "sandwich.ogg": "bocadillo",
+ "sash.ogg": "faixa",
+ "sauce.ogg": "salsa",
+ "sausage.ogg": "salchicha",
+ "scale.ogg": "balanza",
+ "scar.ogg": "cicatriz",
+ "scare.ogg": "asustar",
+ "scarf.ogg": "bufanda",
+ "school.ogg": "escola",
+ "school_bag.ogg": "mochila",
+ "science.ogg": "ciencia",
+ "scissors.ogg": "tesoiras",
+ "scorpion.ogg": "escorpión",
+ "scratch.ogg": "rabuñar",
+ "scream.ogg": "berrar",
+ "screw.ogg": "parafuso",
+ "screwdriver.ogg": "desaparafusador",
+ "scribble.ogg": "facer garabatos",
+ "sea.ogg": "mar",
+ "seat.ogg": "asento",
+ "see.ogg": "ver",
+ "seed.ogg": "semente",
+ "shadow.ogg": "sombra",
+ "shake.ogg": "axitar",
+ "shark.ogg": "quenlla",
+ "shave.ogg": "afeitar",
+ "shed.ogg": "caseta",
+ "sheep.ogg": "ovella",
+ "shelf.ogg": "estante",
+ "shell.ogg": "intérprete de ordes",
+ "ship.ogg": "barco",
+ "shirt.ogg": "camisa",
+ "shoe.ogg": "zapato",
+ "shoelace.ogg": "cordón",
+ "shop.ogg": "tenda",
+ "shore.ogg": "costa",
+ "short.ogg": "curto",
+ "shovel.ogg": "pa",
+ "shower.ogg": "ducha",
+ "shrimp.ogg": "gamba",
+ "shrub.ogg": "arbusto",
+ "shut.ogg": "pechado",
+ "shutter.ogg": "persiana",
+ "sick.ogg": "enfermo",
+ "sidewalk.ogg": "beirarrúa",
+ "sign.ogg": "asinar",
+ "sing.ogg": "cantar",
+ "sink.ogg": "vertedoiro",
+ "sip.ogg": "sorber",
+ "sister.ogg": "irmá",
+ "sit.ogg": "sentar",
+ "skate.ogg": "patinar",
+ "skeleton.ogg": "esqueleto",
+ "ski.ogg": "esquí",
+ "skimmer.ogg": "escumadeira",
+ "skin.ogg": "pel",
+ "skirt.ogg": "saia",
+ "skunk.ogg": "mofeta",
+ "sky.ogg": "ceo",
+ "slam.ogg": "encestar",
+ "sled.ogg": "zorra",
+ "sleep.ogg": "durmir",
+ "sleeve.ogg": "manga",
+ "sleigh.ogg": "zorra",
+ "slide.ogg": "tobogán",
+ "slim.ogg": "delgado",
+ "slime.ogg": "baba",
+ "slippers.ogg": "zapatillas",
+ "slope.ogg": "pendente",
+ "sloppy.ogg": "torpe",
+ "slot.ogg": "rañura",
+ "sloth.ogg": "preguiceiro",
+ "slug.ogg": "lesma",
+ "small.ogg": "pequeno",
+ "smell.ogg": "ulir",
+ "smile.ogg": "sorrir",
+ "smock.ogg": "blusón",
+ "smoke.ogg": "fume",
+ "smooch.ogg": "bicar",
+ "snack.ogg": "aperitivo",
+ "snail.ogg": "caracol",
+ "snake.ogg": "serpe",
+ "sneaker.ogg": "deportiva",
+ "sniff.ogg": "olfactear",
+ "snow.ogg": "neve",
+ "soap.ogg": "xabón",
+ "sob.ogg": "xemido",
+ "sock.ogg": "calcetín",
+ "soldier.ogg": "soldado",
+ "sole.ogg": "linguado",
+ "sole_shoe.ogg": "sola",
+ "son.ogg": "fillo",
+ "soup.ogg": "sopa",
+ "spade.ogg": "pa",
+ "spaghetti.ogg": "espaguete",
+ "spark.ogg": "chispa",
+ "sparrow.ogg": "gorrión",
+ "spatula.ogg": "espátula",
+ "speak.ogg": "falar",
+ "spear.ogg": "lanza",
+ "spice.ogg": "especia",
+ "spider.ogg": "araña",
+ "spider_web.ogg": "tea de araña",
+ "spike.ogg": "pincho",
+ "spill.ogg": "derramar",
+ "spinach.ogg": "espinaca",
+ "spine.ogg": "espiña vertebral",
+ "spinning_top.ogg": "buxaina",
+ "splash.ogg": "salpicar",
+ "splatter.ogg": "salpicadura",
+ "sponge.ogg": "esponxa",
+ "spool.ogg": "carrete",
+ "spoon.ogg": "culler",
+ "sport.ogg": "deporte",
+ "spot.ogg": "mancha",
+ "spray.ogg": "esparexer",
+ "spread.ogg": "estender",
+ "spring.ogg": "saltar",
+ "spring_season.ogg": "primavera",
+ "sprinkle.ogg": "esparexemento",
+ "square.ogg": "cadrado",
+ "squash.ogg": "apertar",
+ "squat.ogg": "agachar",
+ "squid.ogg": "lura",
+ "squirrel.ogg": "esquío",
+ "squirt.ogg": "pistola de auga",
+ "stack.ogg": "pía",
+ "stage.ogg": "escenario",
+ "staircase.ogg": "escaleira",
+ "stamp.ogg": "selo",
+ "stand.ogg": "de pé",
+ "star.ogg": "estrela",
+ "stare.ogg": "mirar",
+ "starfish.ogg": "estrela de mar",
+ "steam.ogg": "vapor",
+ "steep.ogg": "empinado",
+ "steeple.ogg": "campanario",
+ "stem.ogg": "talo",
+ "step.ogg": "pasando",
+ "stew.ogg": "guiso",
+ "stick.ogg": "vara",
+ "sting.ogg": "aguillón",
+ "stinky.ogg": "cheiroso",
+ "stitch.ogg": "coser",
+ "stomach.ogg": "estómago",
+ "stone.ogg": "pedra",
+ "stop.ogg": "deter",
+ "store.ogg": "tenda",
+ "stove.ogg": "fogón",
+ "straight.ogg": "rectas",
+ "strainer.ogg": "coador",
+ "straw.ogg": "palla",
+ "strawberry.ogg": "amorodo",
+ "stream.ogg": "arroio",
+ "street.ogg": "rúa",
+ "stretch.ogg": "estirar",
+ "string.ogg": "cordel",
+ "stripe.ogg": "banda",
+ "strong.ogg": "forte",
+ "student.ogg": "estudante",
+ "study.ogg": "estudar",
+ "stump.ogg": "toco",
+ "sugar.ogg": "azucre",
+ "suit.ogg": "traxe",
+ "suitcase.ogg": "maleta",
+ "summer.ogg": "verán",
+ "summit.ogg": "bico",
+ "sun.ogg": "sol",
+ "swan.ogg": "cisne",
+ "sweat.ogg": "suor",
+ "sweatshirt.ogg": "xersei",
+ "swim.ogg": "nadar",
+ "table.ogg": "mesa",
+ "tablecloth.ogg": "mantel",
+ "tadpole.ogg": "cágado",
+ "tag.ogg": "etiqueta",
+ "tail.ogg": "cola",
+ "tall.ogg": "alto",
+ "tape_measure.ogg": "metro",
+ "taxi.ogg": "taxi",
+ "teach.ogg": "ensinar",
+ "teacher.ogg": "mestre",
+ "tear.ogg": "rachar",
+ "teddy.ogg": "peluche",
+ "teeth.ogg": "dentes",
+ "television.ogg": "televisión",
+ "temple.ogg": "templo",
+ "tennis.ogg": "tenis",
+ "tent.ogg": "tenda",
+ "text.ogg": "texto",
+ "thick.ogg": "groso",
+ "thief.ogg": "ladrón",
+ "thigh.ogg": "coxa",
+ "think.ogg": "pensar",
+ "thread.ogg": "fío",
+ "throat.ogg": "garganta",
+ "throw.ogg": "lanzar",
+ "thumb.ogg": "polgar",
+ "tick.ogg": "carracha",
+ "ticket.ogg": "billete",
+ "tiger.ogg": "tigre",
+ "time.ogg": "tempo",
+ "tin.ogg": "lata",
+ "tire.ogg": "pneumático",
+ "tired.ogg": "cansado",
+ "tissue.ogg": "pano descartábel",
+ "to_drink.ogg": "beber",
+ "toad.ogg": "sapo",
+ "toaster.ogg": "tostadora",
+ "toe.ogg": "deda",
+ "toilet.ogg": "lavabo",
+ "tomatoe.ogg": "tomate",
+ "tongs.ogg": "pinza",
+ "tongue.ogg": "lingua",
+ "tool.ogg": "ferramenta",
+ "top.ogg": "parte superior",
+ "torch.ogg": "facho",
+ "touch.ogg": "tocar",
+ "towel.ogg": "toalla",
+ "toy.ogg": "xoguete",
+ "trail.ogg": "rastro",
+ "train.ogg": "tren",
+ "train_station.ogg": "estación ferroviaria",
+ "trap.ogg": "trampa",
+ "trash.ogg": "lixo",
+ "tray.ogg": "bandexa",
+ "treat.ogg": "lambetada",
+ "tree.ogg": "árbore",
+ "triangle.ogg": "triángulo",
+ "tribe.ogg": "tribo",
+ "trip.ogg": "viaxe",
+ "truck.ogg": "camión",
+ "tube.ogg": "tubo",
+ "tulip.ogg": "tulipán",
+ "tune.ogg": "melodía",
+ "turkey.ogg": "pavo",
+ "turnip.ogg": "nabo",
+ "turtle.ogg": "tartaruga",
+ "tusk.ogg": "cairo",
+ "twin_boys.ogg": "xemelgos",
+ "twin_girls.ogg": "xemelgas",
+ "umbrella.ogg": "paraugas",
+ "under.ogg": "debaixo",
+ "uniform.ogg": "uniforme",
+ "van.ogg": "furgoneta",
+ "vapor.ogg": "vapor",
+ "vase.ogg": "floreiro",
+ "vegetable.ogg": "vexetal",
+ "vein.ogg": "vea",
+ "verdure.ogg": "vexetación",
+ "vest.ogg": "chaleco",
+ "vet.ogg": "veterinario",
+ "viper.ogg": "víbora",
+ "vowel.ogg": "vogal",
+ "vulture.ogg": "voitre",
+ "wag.ogg": "menear",
+ "walk.ogg": "camiñar",
+ "wall.ogg": "parede",
+ "walnut.ogg": "noz",
+ "wart.ogg": "verruga",
+ "wash.ogg": "lavar",
+ "wasp.ogg": "avespa",
+ "watch.ogg": "reloxo",
+ "water.ogg": "auga",
+ "wave.ogg": "onda",
+ "wedding.ogg": "voda",
+ "wedge.ogg": "cuña",
+ "weight.ogg": "peso",
+ "wet.ogg": "mollado",
+ "whale.ogg": "balea",
+ "wheat.ogg": "trigo",
+ "wheel.ogg": "roda",
+ "whisk.ogg": "batedor",
+ "whisper.ogg": "musitar",
+ "white.ogg": "branco",
+ "wide.ogg": "ancho",
+ "wife.ogg": "esposa",
+ "wig.ogg": "perruca",
+ "win.ogg": "gañar",
+ "wind.ogg": "vento",
+ "window.ogg": "xanela",
+ "window_glass.ogg": "cristal de ventá",
+ "wing.ogg": "ala",
+ "winter.ogg": "inverno",
+ "wolf.ogg": "lobo",
+ "woman.ogg": "muller",
+ "wood.ogg": "madeira",
+ "word.ogg": "palabra",
+ "worker.ogg": "traballador",
+ "world.ogg": "mundo",
+ "wreath.ogg": "coroa de flores",
+ "wrench.ogg": "chave inglesa",
+ "wrist.ogg": "pulso",
+ "write.ogg": "escribir",
+ "yellow.ogg": "amarelo",
+ "yogurt.ogg": "iogur",
+ "yum.ogg": "rico",
+ "zebra.ogg": "cebra",
+ "zipper.ogg": "cremalleira",
+ "zoo.ogg": "zoo"
+}
\ No newline at end of file
diff --git a/src/activities/lang/resource/content-hu.json b/src/activities/lang/resource/content-hu.json
new file mode 100644
index 000000000..a9894e618
--- /dev/null
+++ b/src/activities/lang/resource/content-hu.json
@@ -0,0 +1,1092 @@
+{
+ "10.ogg": "tíz",
+ "11.ogg": "tizenegy",
+ "12.ogg": "tizenkettő",
+ "16.ogg": "tizenhat",
+ "U0030.ogg": "nulla",
+ "U0031.ogg": "egy",
+ "U0032.ogg": "kettő",
+ "U0033.ogg": "három",
+ "U0034.ogg": "négy",
+ "U0035.ogg": "öt",
+ "U0036.ogg": "hat",
+ "U0037.ogg": "hét",
+ "U0038.ogg": "nyolc",
+ "U0039.ogg": "kilenc",
+ "accountant.ogg": "könyvelő",
+ "ache.ogg": "fájdalom",
+ "acorn.ogg": "makk",
+ "actor.ogg": "színész",
+ "air_horn.ogg": "légvédelmi sziréna",
+ "alarmclock.ogg": "ébresztőóra",
+ "alligator.ogg": "aligátor",
+ "alphabet.ogg": "ábécé",
+ "anchor.ogg": "szigony",
+ "angel.ogg": "angyal",
+ "angry.ogg": "ideges",
+ "animal.ogg": "állat",
+ "ankle.ogg": "boka",
+ "ant.ogg": "hangya",
+ "anteater.ogg": "hangyász",
+ "antelope.ogg": "antilop",
+ "apple.ogg": "alma",
+ "apple_tree.ogg": "almafa",
+ "appliance.ogg": "eszköz",
+ "apricot.ogg": "sárgabarack",
+ "arm.ogg": "kar",
+ "armchair.ogg": "karosszék",
+ "artichoke.ogg": "articsóka",
+ "artist.ogg": "művész",
+ "asparagus.ogg": "spárga",
+ "astronaut.ogg": "űrhajós",
+ "athlete.ogg": "sportoló",
+ "avocado.ogg": "avokádó",
+ "ax.ogg": "balta",
+ "baby_bottle.ogg": "cumisüveg",
+ "back.ogg": "hát",
+ "badge.ogg": "jelvény",
+ "bag.ogg": "táska",
+ "bait.ogg": "csali",
+ "balance.ogg": "egyensúly",
+ "bald.ogg": "kopasz",
+ "ball.ogg": "labda",
+ "ball_of_yarn.ogg": "gombolyag",
+ "ball_soccer.ogg": "focilabda",
+ "ballet.ogg": "balett",
+ "bank.ogg": "bank",
+ "banker_female.ogg": "női bankár",
+ "bark.ogg": "ugat",
+ "barn.ogg": "istálló",
+ "bat.ogg": "ütő",
+ "bath.ogg": "fürdőkád",
+ "bathing_suit.ogg": "fürdőruha",
+ "bay.ogg": "öböl",
+ "beach.ogg": "part",
+ "bean.ogg": "bab",
+ "bear.ogg": "medve",
+ "beard.ogg": "szakáll",
+ "beat.ogg": "üt",
+ "beaver.ogg": "hód",
+ "bed.ogg": "ágy",
+ "bedroom.ogg": "hálószoba",
+ "bee.ogg": "méh",
+ "beetle.ogg": "bogár",
+ "beg.ogg": "könyörög",
+ "behind.ogg": "mögött",
+ "bell.ogg": "csengő",
+ "belly.ogg": "has",
+ "bench.ogg": "pad",
+ "bib.ogg": "partedli",
+ "big.ogg": "nagy",
+ "big_top.ogg": "nagy",
+ "bike.ogg": "bicikli",
+ "bird.ogg": "madár",
+ "bit.ogg": "darab",
+ "bite.ogg": "harap",
+ "black.ogg": "fekete",
+ "blackberry.ogg": "szeder",
+ "blackbird.ogg": "feketerigó",
+ "blade.ogg": "penge",
+ "blind.ogg": "vak",
+ "blink.ogg": "kacsint",
+ "block.ogg": "megállít",
+ "blond.ogg": "szőke",
+ "blue.ogg": "kék",
+ "blueberry.ogg": "áfonya",
+ "blush.ogg": "elpirul",
+ "board.ogg": "tábla",
+ "boat.ogg": "hajó",
+ "boil.ogg": "forral",
+ "bolt.ogg": "villám",
+ "bomb.ogg": "bomba",
+ "bone.ogg": "csont",
+ "book.ogg": "könyv",
+ "bookcase.ogg": "könyvespolc",
+ "bottom.ogg": "alja",
+ "box.ogg": "doboz",
+ "boxer.ogg": "bokszoló",
+ "boy.ogg": "fiú",
+ "braid.ogg": "fonat",
+ "brain.ogg": "agy",
+ "branch.ogg": "csapat",
+ "bread.ogg": "kenyér",
+ "break.ogg": "törik",
+ "breast.ogg": "mell",
+ "brick.ogg": "tégla",
+ "bricklayer.ogg": "kőműves",
+ "bride.ogg": "menyasszony",
+ "bridge.ogg": "híd",
+ "bright.ogg": "világos",
+ "broccoli.ogg": "brokkoli",
+ "brother.ogg": "báty",
+ "brown.ogg": "barna",
+ "brush.ogg": "kefe",
+ "bubble.ogg": "buborék",
+ "bucket.ogg": "vödör",
+ "bud.ogg": "haver",
+ "buffalo.ogg": "bika",
+ "bug.ogg": "poloska",
+ "bulb.ogg": "villanykörte",
+ "bull.ogg": "bika",
+ "bump.ogg": "dudor",
+ "bun.ogg": "zsemle",
+ "bus.ogg": "busz",
+ "bush.ogg": "bokor",
+ "butcher.ogg": "hentes",
+ "butter.ogg": "vaj",
+ "butterfly.ogg": "pillangó",
+ "button.ogg": "gomb",
+ "cabbage.ogg": "káposzta",
+ "cabin.ogg": "kabin",
+ "cacao.ogg": "kakaó",
+ "cactus.ogg": "kaktusz",
+ "cage.ogg": "ketrec",
+ "cake.ogg": "torta",
+ "call.ogg": "hív",
+ "camel.ogg": "teve",
+ "camera.ogg": "fényképezőgép",
+ "camp.ogg": "tábor",
+ "can.ogg": "konzervdoboz",
+ "canary.ogg": "kanári",
+ "candle.ogg": "gyertya",
+ "candy.ogg": "cukor",
+ "cane.ogg": "daru",
+ "canoe.ogg": "kenu",
+ "canon.ogg": "ágyú",
+ "canyon.ogg": "kanyon",
+ "cap.ogg": "sapka",
+ "cape.ogg": "köpeny",
+ "car.ogg": "autó",
+ "carafe.ogg": "üvegkancsó",
+ "card.ogg": "kártya",
+ "carnival.ogg": "karnevál",
+ "carpenter.ogg": "ács",
+ "carpet.ogg": "szőnyeg",
+ "carrot.ogg": "sárgarépa",
+ "cart.ogg": "kocsi",
+ "cash.ogg": "készpénz",
+ "castle.ogg": "kastély",
+ "cat.ogg": "macska",
+ "cat_female.ogg": "lány macska",
+ "catch.ogg": "elkap",
+ "caterpillar.ogg": "hernyó",
+ "cauldron.ogg": "üst",
+ "cauliflower.ogg": "karfiol",
+ "cave.ogg": "barlang",
+ "cavern.ogg": "barlang",
+ "celery.ogg": "zeller",
+ "centipede.ogg": "százlábú",
+ "cereal.ogg": "gabona",
+ "chain.ogg": "lánc",
+ "chair.ogg": "szék",
+ "chalk.ogg": "kréta",
+ "chameleon.ogg": "kaméleon",
+ "chandelier.ogg": "gyertyatartó",
+ "chat.ogg": "beszél",
+ "cheek.ogg": "arccsont",
+ "cheer.ogg": "örül",
+ "cheese.ogg": "sajt",
+ "chef.ogg": "séf",
+ "cherry.ogg": "cseresznye",
+ "chest.ogg": "mellkas",
+ "chick.ogg": "csibe",
+ "chicken.ogg": "csirke",
+ "child.ogg": "gyerek",
+ "chimney.ogg": "kémény",
+ "chimp.ogg": "maki",
+ "chin.ogg": "áll",
+ "chocolate.ogg": "csokoládé",
+ "chop.ogg": "vág",
+ "chores.ogg": "házimunka",
+ "christmas.ogg": "karácsony",
+ "cigar.ogg": "szivar",
+ "circus.ogg": "cirkusz",
+ "city.ogg": "város",
+ "clam.ogg": "kagyló",
+ "clap.ogg": "taps",
+ "class.ogg": "osztály",
+ "claw.ogg": "karom",
+ "clay.ogg": "gyurma",
+ "clean.ogg": "tisztít",
+ "cleaning_lady.ogg": "takarítónő",
+ "cliff.ogg": "szirt",
+ "climb.ogg": "mászik",
+ "clock.ogg": "óra",
+ "cloth.ogg": "rongy",
+ "clothes_hanger.ogg": "ruhaszárító",
+ "cloud.ogg": "felhő",
+ "cloudy.ogg": "felhős",
+ "clover.ogg": "lóhere",
+ "clown.ogg": "bohóc",
+ "coach.ogg": "edző",
+ "coast.ogg": "part",
+ "coat.ogg": "kabát",
+ "cobra.ogg": "kobra",
+ "coconut.ogg": "kókusz",
+ "cod.ogg": "tőkehal",
+ "coffee.ogg": "kávé",
+ "coin.ogg": "érme",
+ "cold.ogg": "hideg",
+ "color.ogg": "szín",
+ "colt.ogg": "pisztoly",
+ "comb.ogg": "fésű",
+ "cone.ogg": "toboz",
+ "cook.ogg": "főz",
+ "cookie.ogg": "süti",
+ "cork.ogg": "dugó",
+ "corn.ogg": "kukorica",
+ "couch.ogg": "kanapé",
+ "cough.ogg": "köhög",
+ "couple.ogg": "pár",
+ "cow.ogg": "tehén",
+ "cowboy.ogg": "cowboy",
+ "crab.ogg": "rák",
+ "cradle.ogg": "bölcső",
+ "craft.ogg": "kézimunka",
+ "crawl.ogg": "mászás",
+ "crazy.ogg": "őrült",
+ "creek.ogg": "szurdok",
+ "crepe.ogg": "fátyol",
+ "crib.ogg": "gyerekágy",
+ "croak.ogg": "brekegés",
+ "crocodile.ogg": "krokodil",
+ "cross.ogg": "kereszt",
+ "crow.ogg": "varjú",
+ "crown.ogg": "korona",
+ "crumb.ogg": "morzsa",
+ "crust.ogg": "héj",
+ "cry.ogg": "sír",
+ "crystal.ogg": "kristály",
+ "cube.ogg": "kocka",
+ "cucumber.ogg": "uborka",
+ "curtain.ogg": "függöny",
+ "cut.ogg": "vág",
+ "cute.ogg": "aranyos",
+ "dad.ogg": "apu",
+ "daffodil.ogg": "nárcisz",
+ "daisy.ogg": "margaréta",
+ "dam.ogg": "gát",
+ "dance.ogg": "tánc",
+ "dandelion.ogg": "pitypang",
+ "dart_board.ogg": "darts tábla",
+ "date_fruit.ogg": "datolya",
+ "deer.ogg": "szarvas",
+ "den.ogg": "odú",
+ "desert.ogg": "sivatag",
+ "desk.ogg": "asztal",
+ "dessert.ogg": "desszert",
+ "diamond.ogg": "gyémánt",
+ "dig.ogg": "ás",
+ "dirt.ogg": "piszok",
+ "dirty.ogg": "piszkos",
+ "dish.ogg": "tányér",
+ "dishcloth.ogg": "törlőrongy",
+ "dive.ogg": "merül",
+ "doctor.ogg": "orvos",
+ "doe.ogg": "dámvad",
+ "dog.ogg": "kutya",
+ "doll.ogg": "baba",
+ "dolphin.ogg": "delfin",
+ "domino.ogg": "dominó",
+ "door.ogg": "ajtó",
+ "doormat.ogg": "lábtörlő",
+ "dot.ogg": "pont",
+ "doughnut.ogg": "fánk",
+ "dove.ogg": "hattyú",
+ "dragon.ogg": "sárkány",
+ "dragonfly.ogg": "szitakötő",
+ "draw.ogg": "rajzol",
+ "drawer.ogg": "szekrény",
+ "dream.ogg": "álom",
+ "dress.ogg": "ruha",
+ "drink.ogg": "iszik",
+ "drip.ogg": "csepp",
+ "drive.ogg": "vezet",
+ "drool.ogg": "nyál",
+ "drum.ogg": "dob",
+ "dry.ogg": "száraz",
+ "duck.ogg": "kacsa",
+ "duck_mother.ogg": "anyakacsa",
+ "dune.ogg": "dűne",
+ "dwarf.ogg": "törpe",
+ "eagle.ogg": "sas",
+ "ear.ogg": "fül",
+ "earth.ogg": "Föld",
+ "eat.ogg": "eszik",
+ "egg.ogg": "tojás",
+ "eggplant.ogg": "padlizsán",
+ "elbow.ogg": "könyök",
+ "electrician.ogg": "villanyszerelő",
+ "elk.ogg": "jávorszarvas",
+ "empty.ogg": "üres",
+ "engine.ogg": "motor",
+ "engineer.ogg": "mérnök",
+ "eraser.ogg": "radír",
+ "explore.ogg": "felfedez",
+ "eyelash.ogg": "szempilla",
+ "eyes.ogg": "szem",
+ "face.ogg": "arc",
+ "fair.ogg": "jogos",
+ "fairy.ogg": "tündér",
+ "fall.ogg": "esik",
+ "fall_season.ogg": "ősz évszak",
+ "family.ogg": "család",
+ "fan.ogg": "legyező",
+ "farm.ogg": "tanya",
+ "farmer.ogg": "gazdálkodó",
+ "fat.ogg": "kövér",
+ "faucet.ogg": "csap",
+ "fawn.ogg": "őzborjú",
+ "fear.ogg": "félelem",
+ "feast.ogg": "ünnep",
+ "feather.ogg": "toll",
+ "feed.ogg": "etet",
+ "femur.ogg": "combcsont",
+ "fetch.ogg": "elkap",
+ "fig.ogg": "füge",
+ "fin.ogg": "ventillátor lapát",
+ "find.ogg": "talál",
+ "finger.ogg": "ujj",
+ "fire.ogg": "tűz",
+ "fire_extinguisher.ogg": "tűzoltó készülék",
+ "fireman.ogg": "tűzoltó",
+ "fish.ogg": "hal",
+ "fisherman.ogg": "halász",
+ "fist.ogg": "ököl",
+ "flacon.ogg": "sólyom",
+ "flag.ogg": "zászló",
+ "flame.ogg": "láng",
+ "flamingo.ogg": "flamingó",
+ "flash.ogg": "villám",
+ "flat.ogg": "lapos",
+ "flies.ogg": "cipzár",
+ "float.ogg": "úszó",
+ "flour.ogg": "liszt",
+ "flower.ogg": "virág",
+ "fluff.ogg": "pehely",
+ "flute.ogg": "furulya",
+ "fly.ogg": "légy",
+ "foam.ogg": "hab",
+ "foot.ogg": "láb",
+ "forest.ogg": "erdő",
+ "fork.ogg": "villa",
+ "fountain.ogg": "szökőkút",
+ "fox.ogg": "béka",
+ "freeze.ogg": "fagy",
+ "friend.ogg": "barát",
+ "fries.ogg": "sült krumpli",
+ "frog.ogg": "béka",
+ "front.ogg": "elől",
+ "fruit.ogg": "gyümölcs",
+ "fudge.ogg": "karamella",
+ "full.ogg": "teli",
+ "fur.ogg": "szőr",
+ "game.ogg": "játék",
+ "garage.ogg": "garázs",
+ "garden.ogg": "kert",
+ "garlic.ogg": "fokhagyma",
+ "gem.ogg": "ékkő",
+ "giant.ogg": "óriás",
+ "gift.ogg": "ajándék",
+ "giraffe.ogg": "zsiráf",
+ "girl.ogg": "lány",
+ "glass.ogg": "pohár",
+ "glasses.ogg": "szemüveg",
+ "glove.ogg": "kesztyű",
+ "glue.ogg": "ragasztó",
+ "gnome.ogg": "törpe",
+ "goat.ogg": "kecske",
+ "golden.ogg": "arany",
+ "golf.ogg": "golf",
+ "goose.ogg": "liba",
+ "gorilla.ogg": "gorilla",
+ "grain.ogg": "búza",
+ "grandmother.ogg": "nagymama",
+ "grape.ogg": "szőlő",
+ "grapefruit.ogg": "grapefruit",
+ "grass.ogg": "fű",
+ "grave.ogg": "sírkő",
+ "gray.ogg": "szürke",
+ "green.ogg": "zöld",
+ "grill.ogg": "vicsor",
+ "grin.ogg": "vigyor",
+ "ground.ogg": "talaj",
+ "growl.ogg": "morgás",
+ "guignol.ogg": "paprikajancsi",
+ "guinea_pig.ogg": "tengerimalac",
+ "gum.ogg": "rágó",
+ "hair.ogg": "haj",
+ "hair_dryer.ogg": "hajszárító",
+ "half.ogg": "fél",
+ "ham.ogg": "sonka",
+ "hamburger.ogg": "hamburger",
+ "hammer.ogg": "kalapács",
+ "hand.ogg": "kézfej",
+ "handlebar.ogg": "fogantyú",
+ "happy.ogg": "boldog",
+ "harp.ogg": "hárfa",
+ "hat.ogg": "kalap",
+ "hatch.ogg": "kikel",
+ "hay.ogg": "széna",
+ "head.ogg": "fej",
+ "hear.ogg": "hall",
+ "heat.ogg": "hőség",
+ "hedge.ogg": "sövény",
+ "hedgehog.ogg": "sündisznó",
+ "heel.ogg": "sarok",
+ "helmet.ogg": "sisak",
+ "hen.ogg": "tyúk",
+ "herd.ogg": "gulya",
+ "high.ogg": "magas",
+ "hike.ogg": "mászik",
+ "hill.ogg": "völgy",
+ "hip.ogg": "csípő",
+ "hippopotamus.ogg": "víziló",
+ "hit.ogg": "üt",
+ "hive.ogg": "méhraj",
+ "hockey.ogg": "hoki",
+ "hole.ogg": "lyuk",
+ "home.ogg": "otthon",
+ "hook.ogg": "kampó",
+ "hop.ogg": "ugrik",
+ "horse.ogg": "ló",
+ "hose.ogg": "locsolócső",
+ "hospital.ogg": "kórház",
+ "hot.ogg": "forró",
+ "hot_dog.ogg": "hot dog",
+ "hound.ogg": "vadászkutya",
+ "house.ogg": "ház",
+ "howl.ogg": "ugatás",
+ "hug.ogg": "ölelés",
+ "huge.ogg": "hatalmas",
+ "hummingbird.ogg": "kolibri",
+ "hunchbacked.ogg": "púpos",
+ "hunter.ogg": "vadász",
+ "husband.ogg": "férj",
+ "hut.ogg": "kunyhó",
+ "hyena.ogg": "hiéna",
+ "ice.ogg": "jég",
+ "iceberg.ogg": "jéghegy",
+ "iguana.ogg": "iguána",
+ "ill.ogg": "beteg",
+ "ink.ogg": "tinta",
+ "island.ogg": "sziget",
+ "jacket.ogg": "dzseki",
+ "jaguar.ogg": "jaguár",
+ "jam.ogg": "dzsem",
+ "jay.ogg": "szajkó",
+ "jelly.ogg": "zselé",
+ "jellyfish.ogg": "medúza",
+ "jewel.ogg": "drágakő",
+ "job.ogg": "munka",
+ "jockey.ogg": "zsoké",
+ "jog.ogg": "fut",
+ "joy.ogg": "öröm",
+ "judge.ogg": "bíró",
+ "judo.ogg": "dzsúdó",
+ "juggler.ogg": "zsonglőr",
+ "juice.ogg": "lé",
+ "jump.ogg": "ugrik",
+ "kangaroo.ogg": "kenguru",
+ "keel.ogg": "tőkesúly",
+ "kernel.ogg": "programmag",
+ "keyboard.ogg": "billentyűzet",
+ "kimono.ogg": "kimonó",
+ "king.ogg": "király",
+ "kiss.ogg": "csók",
+ "kitchen.ogg": "konyha",
+ "kite.ogg": "papírsárkány",
+ "kitten.ogg": "kiscica",
+ "kiwi.ogg": "kivi",
+ "knee.ogg": "térd",
+ "kneel.ogg": "térdel",
+ "knife.ogg": "kés",
+ "knight.ogg": "lovag",
+ "knit.ogg": "köt",
+ "knot.ogg": "csomó",
+ "koala.ogg": "koala",
+ "lad.ogg": "fiú",
+ "lady.ogg": "hölgy",
+ "ladybug.ogg": "katicabogár",
+ "lake.ogg": "tó",
+ "lama.ogg": "láma",
+ "lamb.ogg": "bárány",
+ "lamp.ogg": "lámpa",
+ "land.ogg": "szárazföld",
+ "lane.ogg": "vonal",
+ "lap.ogg": "sikátor",
+ "lasso.ogg": "lasszó",
+ "laugh.ogg": "nevet",
+ "lava.ogg": "láva",
+ "lawn.ogg": "gyep",
+ "lawyer.ogg": "bíró",
+ "leaf.ogg": "levél",
+ "ledge.ogg": "szegély",
+ "leek.ogg": "póréhagyma",
+ "left.ogg": "bal",
+ "leg.ogg": "lábszár",
+ "lemon.ogg": "citrom",
+ "lemonade.ogg": "limonádé",
+ "lemur.ogg": "lemúr",
+ "leopard.ogg": "leopárd",
+ "lettuce.ogg": "saláta",
+ "librarian.ogg": "könyvtáros",
+ "lick.ogg": "nyal",
+ "lid.ogg": "fedő",
+ "lift.ogg": "emel",
+ "light.ogg": "fény",
+ "lighthouse.ogg": "világítótorony",
+ "lightning.ogg": "villám",
+ "lilac.ogg": "lila",
+ "lime.ogg": "lime",
+ "line.ogg": "vonal",
+ "link.ogg": "kapcsolat",
+ "lion.ogg": "oroszlán",
+ "lion_cub.ogg": "oroszlánkölyök",
+ "lip.ogg": "ajak",
+ "liquid.ogg": "folyékony",
+ "lizard.ogg": "gyík",
+ "lobster.ogg": "rák",
+ "log.ogg": "fatönk",
+ "look.ogg": "kinézet",
+ "lunch.ogg": "ebéd",
+ "mad.ogg": "dühös",
+ "magic.ogg": "varázslat",
+ "magnet.ogg": "mágnes",
+ "magnifying_glass.ogg": "nagyító",
+ "magpie.ogg": "szarka",
+ "mail.ogg": "levél",
+ "man.ogg": "férfi",
+ "mane.ogg": "sörény",
+ "mango.ogg": "mangó",
+ "map.ogg": "térkép",
+ "maple.ogg": "juhar",
+ "marble.ogg": "üveggolyó",
+ "mashed_potatoes.ogg": "tört krumpli",
+ "mask.ogg": "maszk",
+ "mast.ogg": "pózna",
+ "mat.ogg": "szőnyeg",
+ "match.ogg": "pár",
+ "mate.ogg": "haver",
+ "mattress.ogg": "matrac",
+ "mauve.ogg": "mályva",
+ "meal.ogg": "étkezés",
+ "meat.ogg": "hús",
+ "mechanic.ogg": "szerelő",
+ "medal.ogg": "medál",
+ "meet.ogg": "találkozás",
+ "melon.ogg": "dinnye",
+ "merry-go-round.ogg": "körhinta",
+ "mice.ogg": "egerek",
+ "microphone.ogg": "mikrofon",
+ "milk.ogg": "tej",
+ "mill.ogg": "malom",
+ "mimosa.ogg": "mimóza",
+ "mirror.ogg": "tükör",
+ "mixer.ogg": "keverő",
+ "mole.ogg": "vakond",
+ "mom.ogg": "anyu",
+ "moon.ogg": "hold",
+ "moose.ogg": "szarvas",
+ "mop.ogg": "felmosó",
+ "mosque.ogg": "mecset",
+ "mosquito.ogg": "moszkító",
+ "mother.ogg": "anya",
+ "motorcycle.ogg": "motor",
+ "mountain.ogg": "hegy",
+ "mouse.ogg": "egér",
+ "mouth.ogg": "száj",
+ "movie.ogg": "film",
+ "mower.ogg": "kaszás",
+ "mud.ogg": "sár",
+ "mug.ogg": "bögre",
+ "mule.ogg": "öszvér",
+ "muscle.ogg": "izom",
+ "mushroom.ogg": "gomba",
+ "music.ogg": "zene",
+ "musician.ogg": "zenész",
+ "naked.ogg": "meztelen",
+ "nap.ogg": "pihenés",
+ "navel.ogg": "köldök",
+ "neck.ogg": "nyak",
+ "necklace.ogg": "nyaklánc",
+ "needle.ogg": "tű",
+ "nest.ogg": "fészek",
+ "net.ogg": "háló",
+ "newspaper.ogg": "újság",
+ "night.ogg": "éjszaka",
+ "nightgown.ogg": "hálóing",
+ "nose.ogg": "orr",
+ "nostril.ogg": "orrlyuk",
+ "notebook.ogg": "füzet",
+ "number.ogg": "szám",
+ "nun.ogg": "apáca",
+ "nurse.ogg": "nővér",
+ "nurse_male.ogg": "ápoló",
+ "nut.ogg": "dió",
+ "oar.ogg": "evező",
+ "ocean.ogg": "oceán",
+ "office.ogg": "iroda",
+ "olive.ogg": "oliva",
+ "on.ogg": "rajta",
+ "onion.ogg": "hagyma",
+ "open.ogg": "nyitva",
+ "opossum.ogg": "oposszum",
+ "orange-color.ogg": "narancssárga",
+ "orange.ogg": "narancs",
+ "orchid.ogg": "orhidea",
+ "ostrich.ogg": "strucc",
+ "otter.ogg": "vidra",
+ "owl.ogg": "bagoly",
+ "ox.ogg": "ökör",
+ "oyster.ogg": "osztriga",
+ "pacifier.ogg": "cumi",
+ "page.ogg": "lap",
+ "pair.ogg": "pár",
+ "pajamas.ogg": "pizsama",
+ "pal.ogg": "haver",
+ "palm_tree.ogg": "pálmafa",
+ "pan.ogg": "serpenyő",
+ "panda.ogg": "panda",
+ "panther.ogg": "párduc",
+ "panties.ogg": "alsónadrág",
+ "pants.ogg": "nadrág",
+ "papaya.ogg": "papaja",
+ "paper.ogg": "papír",
+ "parachute.ogg": "ejtőernyő",
+ "parakeet.ogg": "törpepapagáj",
+ "parrot.ogg": "papagáj",
+ "patch.ogg": "tapasz",
+ "path.ogg": "út",
+ "paw.ogg": "tappancs",
+ "pea.ogg": "borsó",
+ "peach.ogg": "őszibarack",
+ "peacock.ogg": "páva",
+ "peak.ogg": "orom",
+ "pear.ogg": "körte",
+ "pearl.ogg": "gyöngy",
+ "peck.ogg": "harkály",
+ "pedal.ogg": "pedál",
+ "pelican.ogg": "pelikán",
+ "pen.ogg": "toll",
+ "pencil.ogg": "ceruza",
+ "peony.ogg": "bazsarózsa",
+ "people.ogg": "emberek",
+ "pepper.ogg": "paprika",
+ "peppers.ogg": "paprikák",
+ "pet.ogg": "kisállat",
+ "petal.ogg": "szirom",
+ "phone.ogg": "telefon",
+ "piano.ogg": "zongora",
+ "picture.ogg": "kép",
+ "pie.ogg": "pite",
+ "pig.ogg": "malac",
+ "pigeon.ogg": "galamb",
+ "pill.ogg": "tabletta",
+ "pillow.ogg": "párna",
+ "pilot.ogg": "pilóta",
+ "pine.ogg": "fenyőfa",
+ "pine_cone.ogg": "toboz",
+ "pink.ogg": "rózsaszín",
+ "pip.ogg": "mag",
+ "pipe.ogg": "cső",
+ "piranha.ogg": "pirája",
+ "pirate.ogg": "kalóz",
+ "pizza.ogg": "pizza",
+ "plane.ogg": "repülőgép",
+ "planet.ogg": "bolygó",
+ "plant.ogg": "növény",
+ "plate.ogg": "tányér",
+ "play.ogg": "játszani",
+ "pliers.ogg": "fogó",
+ "plow.ogg": "eke",
+ "plum.ogg": "szilva",
+ "plumber.ogg": "vízszerelő",
+ "pocket.ogg": "zseb",
+ "pod.ogg": "gubó",
+ "pole.ogg": "rúd",
+ "police.ogg": "rendőrség",
+ "pompon.ogg": "pompon",
+ "pond.ogg": "tó",
+ "pony.ogg": "póni",
+ "pool.ogg": "medence",
+ "popcorn.ogg": "pattogatott kukorica",
+ "pope.ogg": "pápa",
+ "porthole.ogg": "hajóablak",
+ "post.ogg": "levelezés",
+ "pot.ogg": "cserép",
+ "potato.ogg": "krumpli",
+ "pounce.ogg": "porzó",
+ "president.ogg": "elnök",
+ "pretty.ogg": "csinos",
+ "price.ogg": "ár",
+ "priest.ogg": "lelkész",
+ "prince.ogg": "herceg",
+ "princess.ogg": "hercegnő",
+ "prison.ogg": "börtön",
+ "prisoner.ogg": "rab",
+ "prize.ogg": "díj",
+ "pug.ogg": "bokszoló",
+ "pull.ogg": "húz",
+ "pullover.ogg": "pulóver",
+ "pumpkin.ogg": "tök",
+ "puppy.ogg": "kölyökkutya",
+ "pyramid.ogg": "piramis",
+ "quarrel.ogg": "vita",
+ "queen.ogg": "királynő",
+ "question.ogg": "kérdés",
+ "quilt.ogg": "paplan",
+ "quiz.ogg": "kvíz",
+ "rabbit.ogg": "nyúl",
+ "rabbit_baby.ogg": "kisnyúl",
+ "race.ogg": "verseny",
+ "radio.ogg": "rádió",
+ "radish.ogg": "retek",
+ "raft.ogg": "hajóhíd",
+ "rag.ogg": "rongy",
+ "rage.ogg": "düh",
+ "rain.ogg": "eső",
+ "raincoat.ogg": "esőkabát",
+ "rake.ogg": "gereblye",
+ "ramp.ogg": "rámpa",
+ "ran.ogg": "futott",
+ "raspberry.ogg": "málna",
+ "rat.ogg": "patkány",
+ "razor.ogg": "penge",
+ "read.ogg": "olvas",
+ "red.ogg": "piros",
+ "reptile.ogg": "hüllő",
+ "rhinoceros.ogg": "orrszarvú",
+ "rice.ogg": "rizs",
+ "ride.ogg": "utazás",
+ "rifle.ogg": "fegyver",
+ "right.ogg": "jobb",
+ "rip.ogg": "halaskosár",
+ "rise.ogg": "felkel",
+ "river.ogg": "folyó",
+ "road.ogg": "út",
+ "roast.ogg": "sült",
+ "robe.ogg": "köntös",
+ "robot.ogg": "robot",
+ "rock.ogg": "kő",
+ "rocket.ogg": "rakéta",
+ "rolling_pin.ogg": "sodrófa",
+ "roof.ogg": "tető",
+ "room.ogg": "szoba",
+ "root.ogg": "gyökér",
+ "rope.ogg": "kötél",
+ "rose.ogg": "rózsa",
+ "round.ogg": "kerek",
+ "rowing.ogg": "evezés",
+ "royal.ogg": "királyi",
+ "rug.ogg": "szőnyeg",
+ "run.ogg": "fut",
+ "sad.ogg": "szomorú",
+ "saddle.ogg": "nyereg",
+ "sail.ogg": "hajózik",
+ "sailor.ogg": "tengerész",
+ "salamander.ogg": "szalamandra",
+ "salmon.ogg": "lazac",
+ "sand.ogg": "homok",
+ "sandals.ogg": "szandál",
+ "sandwich.ogg": "szendvics",
+ "sash.ogg": "selyemöv",
+ "sauce.ogg": "szósz",
+ "sausage.ogg": "kolbász",
+ "scale.ogg": "mérleg",
+ "scar.ogg": "sebhely",
+ "scare.ogg": "ilyeszt",
+ "scarf.ogg": "sál",
+ "school.ogg": "iskola",
+ "school_bag.ogg": "iskolatáska",
+ "science.ogg": "tudomány",
+ "scissors.ogg": "olló",
+ "scorpion.ogg": "skorpió",
+ "scratch.ogg": "karc",
+ "scream.ogg": "sikít",
+ "screw.ogg": "csavar",
+ "screwdriver.ogg": "csavarhúzó",
+ "scribble.ogg": "firkálás",
+ "sea.ogg": "tenger",
+ "seat.ogg": "ülés",
+ "see.ogg": "lát",
+ "seed.ogg": "mag",
+ "shadow.ogg": "árnyék",
+ "shake.ogg": "ráz",
+ "shark.ogg": "cápa",
+ "shave.ogg": "borotválkozik",
+ "shed.ogg": "fészer",
+ "sheep.ogg": "bárány",
+ "shelf.ogg": "polc",
+ "shell.ogg": "kagyló",
+ "ship.ogg": "hajó",
+ "shirt.ogg": "póló",
+ "shoe.ogg": "cipő",
+ "shoelace.ogg": "cipőfűző",
+ "shop.ogg": "bolt",
+ "shore.ogg": "part",
+ "short.ogg": "rövid",
+ "shovel.ogg": "ásó",
+ "shower.ogg": "fürdő",
+ "shrimp.ogg": "rák",
+ "shrub.ogg": "bokor",
+ "shut.ogg": "zár",
+ "shutter.ogg": "rekesz",
+ "sick.ogg": "beteg",
+ "sidewalk.ogg": "járda",
+ "sign.ogg": "felirat",
+ "sing.ogg": "énekel",
+ "sink.ogg": "süllyed",
+ "sip.ogg": "szív",
+ "sister.ogg": "lánytestvér",
+ "sit.ogg": "ül",
+ "skate.ogg": "korcsolya",
+ "skeleton.ogg": "csontváz",
+ "ski.ogg": "sí",
+ "skimmer.ogg": "merőkanál",
+ "skin.ogg": "bőr",
+ "skirt.ogg": "szoknya",
+ "skunk.ogg": "szkunk",
+ "sky.ogg": "ég",
+ "slam.ogg": "csapódás",
+ "sled.ogg": "szán",
+ "sleep.ogg": "alszik",
+ "sleeve.ogg": "ujj",
+ "sleigh.ogg": "szánkó",
+ "slide.ogg": "csúszik",
+ "slim.ogg": "vékony",
+ "slime.ogg": "slime",
+ "slippers.ogg": "mamusz",
+ "slope.ogg": "cső",
+ "sloppy.ogg": "lassú",
+ "slot.ogg": "retesz",
+ "sloth.ogg": "lusta",
+ "slug.ogg": "meztelen csiga",
+ "small.ogg": "kicsi",
+ "smell.ogg": "szag",
+ "smile.ogg": "mosoly",
+ "smock.ogg": "köpeny",
+ "smoke.ogg": "cigi",
+ "smooch.ogg": "smárol",
+ "snack.ogg": "snack",
+ "snail.ogg": "csiga",
+ "snake.ogg": "kígyó",
+ "sneaker.ogg": "edzőcipő",
+ "sniff.ogg": "szagol",
+ "snow.ogg": "hó",
+ "soap.ogg": "szappan",
+ "sob.ogg": "sír",
+ "sock.ogg": "zokni",
+ "soldier.ogg": "katona",
+ "sole.ogg": "talp",
+ "sole_shoe.ogg": "cipőtalp",
+ "son.ogg": "fia",
+ "soup.ogg": "leves",
+ "spade.ogg": "asó",
+ "spaghetti.ogg": "spagetti",
+ "spark.ogg": "csillogás",
+ "sparrow.ogg": "veréb",
+ "spatula.ogg": "spatula",
+ "speak.ogg": "beszél",
+ "spear.ogg": "lándzsa",
+ "spice.ogg": "fűszer",
+ "spider.ogg": "pók",
+ "spider_web.ogg": "pókháló",
+ "spike.ogg": "tüske",
+ "spill.ogg": "forgács",
+ "spinach.ogg": "spenót",
+ "spine.ogg": "gerinc",
+ "spinning_top.ogg": "búgócsiga",
+ "splash.ogg": "csobbanás",
+ "splatter.ogg": "befröcskölés",
+ "sponge.ogg": "szivacs",
+ "spool.ogg": "cséve",
+ "spoon.ogg": "kanál",
+ "sport.ogg": "sport",
+ "spot.ogg": "pont",
+ "spray.ogg": "spray",
+ "spread.ogg": "terjeszt",
+ "spring.ogg": "rugó",
+ "spring_season.ogg": "tavaszi évszak",
+ "sprinkle.ogg": "szórás",
+ "square.ogg": "szögletes",
+ "squash.ogg": "tök",
+ "squat.ogg": "zömök",
+ "squid.ogg": "polip",
+ "squirrel.ogg": "mókus",
+ "squirt.ogg": "fecskendő",
+ "stack.ogg": "halom",
+ "stage.ogg": "szinpad",
+ "staircase.ogg": "lépcsőforduló",
+ "stamp.ogg": "bélyegző",
+ "stand.ogg": "állvány",
+ "star.ogg": "csillag",
+ "stare.ogg": "lépcső",
+ "starfish.ogg": "tengeri csillag",
+ "steam.ogg": "gőz",
+ "steep.ogg": "meredek",
+ "steeple.ogg": "templomtorony",
+ "stem.ogg": "törzs",
+ "step.ogg": "lépés",
+ "stew.ogg": "pörkölt",
+ "stick.ogg": "bot",
+ "sting.ogg": "csípés",
+ "stinky.ogg": "büdös",
+ "stitch.ogg": "öltés",
+ "stomach.ogg": "has",
+ "stone.ogg": "kő",
+ "stop.ogg": "állj",
+ "store.ogg": "tároló",
+ "stove.ogg": "sütő",
+ "straight.ogg": "egyenes",
+ "strainer.ogg": "szűrő",
+ "straw.ogg": "szívószál",
+ "strawberry.ogg": "eper",
+ "stream.ogg": "folyam",
+ "street.ogg": "utca",
+ "stretch.ogg": "nyújt",
+ "string.ogg": "zsinór",
+ "stripe.ogg": "csík",
+ "strong.ogg": "erős",
+ "student.ogg": "tanuló",
+ "study.ogg": "tanul",
+ "stump.ogg": "rönk",
+ "sugar.ogg": "cukor",
+ "suit.ogg": "öltöny",
+ "suitcase.ogg": "bőrönd",
+ "summer.ogg": "nyár",
+ "summit.ogg": "csúcs",
+ "sun.ogg": "nap",
+ "swan.ogg": "hattyú",
+ "sweat.ogg": "édes",
+ "sweatshirt.ogg": "melegítőfelső",
+ "swim.ogg": "úszik",
+ "table.ogg": "asztal",
+ "tablecloth.ogg": "asztalterítő",
+ "tadpole.ogg": "ebihal",
+ "tag.ogg": "tag",
+ "tail.ogg": "farok",
+ "tall.ogg": "magas",
+ "tape_measure.ogg": "mérőszalag",
+ "taxi.ogg": "taxi",
+ "teach.ogg": "tanít",
+ "teacher.ogg": "tanár",
+ "tear.ogg": "könny",
+ "teddy.ogg": "maci",
+ "teeth.ogg": "fogsor",
+ "television.ogg": "televízió",
+ "temple.ogg": "templom",
+ "tennis.ogg": "tenisz",
+ "tent.ogg": "sátor",
+ "text.ogg": "szöveg",
+ "thick.ogg": "vékony",
+ "thief.ogg": "tolvaj",
+ "thigh.ogg": "comb",
+ "think.ogg": "gondol",
+ "thread.ogg": "szál",
+ "throat.ogg": "torok",
+ "throw.ogg": "eldob",
+ "thumb.ogg": "kisujj",
+ "tick.ogg": "kullancs",
+ "ticket.ogg": "jegy",
+ "tiger.ogg": "tigris",
+ "time.ogg": "idő",
+ "tin.ogg": "konzervdoboz",
+ "tire.ogg": "kerék",
+ "tired.ogg": "fáradt",
+ "tissue.ogg": "zsebkendő",
+ "to_drink.ogg": "inni",
+ "toad.ogg": "varangy",
+ "toaster.ogg": "pirítós",
+ "toe.ogg": "lábujj",
+ "toilet.ogg": "wc",
+ "tomatoe.ogg": "paradicsom",
+ "tongs.ogg": "csipeszek",
+ "tongue.ogg": "nyelv",
+ "tool.ogg": "eszköz",
+ "top.ogg": "fent",
+ "torch.ogg": "fáklya",
+ "touch.ogg": "érint",
+ "towel.ogg": "törölköző",
+ "toy.ogg": "játék",
+ "trail.ogg": "nyom",
+ "train.ogg": "vonat",
+ "train_station.ogg": "vasútállomás",
+ "trap.ogg": "csapda",
+ "trash.ogg": "szemét",
+ "tray.ogg": "tálca",
+ "treat.ogg": "élvezet",
+ "tree.ogg": "fa",
+ "triangle.ogg": "háromszög",
+ "tribe.ogg": "törzs",
+ "trip.ogg": "utazás",
+ "truck.ogg": "teherautó",
+ "tube.ogg": "cső",
+ "tulip.ogg": "tulipán",
+ "tune.ogg": "hang",
+ "turkey.ogg": "pulyka",
+ "turnip.ogg": "tarlórépa",
+ "turtle.ogg": "teknős",
+ "tusk.ogg": "agyar",
+ "twin_boys.ogg": "ikerfiúk",
+ "twin_girls.ogg": "ikerlányok",
+ "umbrella.ogg": "esernyő",
+ "under.ogg": "alatt",
+ "uniform.ogg": "egyenruha",
+ "van.ogg": "van",
+ "vapor.ogg": "pára",
+ "vase.ogg": "váza",
+ "vegetable.ogg": "zöldség",
+ "vein.ogg": "véna",
+ "verdure.ogg": "zöldell",
+ "vest.ogg": "mellény",
+ "vet.ogg": "nedves",
+ "viper.ogg": "vipera",
+ "vowel.ogg": "hang",
+ "vulture.ogg": "keselyű",
+ "wag.ogg": "csóvál",
+ "walk.ogg": "jár",
+ "wall.ogg": "fal",
+ "walnut.ogg": "dió",
+ "wart.ogg": "szemölcs",
+ "wash.ogg": "mos",
+ "wasp.ogg": "darázs",
+ "watch.ogg": "figyel",
+ "water.ogg": "víz",
+ "wave.ogg": "hullám",
+ "wedding.ogg": "esküvő",
+ "wedge.ogg": "ék alakú",
+ "weight.ogg": "súly",
+ "wet.ogg": "nedves",
+ "whale.ogg": "bálna",
+ "wheat.ogg": "búza",
+ "wheel.ogg": "kerék",
+ "whisk.ogg": "legyintés",
+ "whisper.ogg": "suttogás",
+ "white.ogg": "fehér",
+ "wide.ogg": "széles",
+ "wife.ogg": "feleség",
+ "wig.ogg": "paróka",
+ "win.ogg": "győz",
+ "wind.ogg": "szél",
+ "window.ogg": "ablak",
+ "window_glass.ogg": "ablaküveg",
+ "wing.ogg": "szárny",
+ "winter.ogg": "tél",
+ "wolf.ogg": "farkas",
+ "woman.ogg": "nő",
+ "wood.ogg": "fa",
+ "word.ogg": "szó",
+ "worker.ogg": "munkás",
+ "world.ogg": "világ",
+ "wreath.ogg": "koszorú",
+ "wrench.ogg": "csavarkulcs",
+ "wrist.ogg": "csukló",
+ "write.ogg": "ír",
+ "yellow.ogg": "sárga",
+ "yogurt.ogg": "joghurt",
+ "yum.ogg": "fincsi",
+ "zebra.ogg": "zebra",
+ "zipper.ogg": "cipzár",
+ "zoo.ogg": "állatkert"
+}
\ No newline at end of file
diff --git a/src/activities/lang/resource/content-id.json b/src/activities/lang/resource/content-id.json
new file mode 100644
index 000000000..c1b7d46e0
--- /dev/null
+++ b/src/activities/lang/resource/content-id.json
@@ -0,0 +1,1052 @@
+{
+ "10.ogg": "sepuluh",
+ "11.ogg": "sebelas",
+ "12.ogg": "dua belas",
+ "16.ogg": "enam belas",
+ "U0030.ogg": "nol",
+ "U0031.ogg": "satu",
+ "U0032.ogg": "dua",
+ "U0033.ogg": "tiga",
+ "U0034.ogg": "empat",
+ "U0035.ogg": "lima",
+ "U0036.ogg": "enam",
+ "U0037.ogg": "tujuh",
+ "U0038.ogg": "delapan",
+ "U0039.ogg": "sembilan",
+ "accountant.ogg": "akuntan",
+ "ache.ogg": "sakit",
+ "actor.ogg": "aktor",
+ "air_horn.ogg": "terompet",
+ "alarmclock.ogg": "beker",
+ "alligator.ogg": "aligator",
+ "alphabet.ogg": "abjad",
+ "anchor.ogg": "jangkar",
+ "angel.ogg": "malaikat",
+ "angry.ogg": "marah",
+ "animal.ogg": "binatang",
+ "ankle.ogg": "mata kaki",
+ "ant.ogg": "semut",
+ "anteater.ogg": "tenggiling",
+ "antelope.ogg": "kijang",
+ "apple.ogg": "apel",
+ "apple_tree.ogg": "pohon apel",
+ "appliance.ogg": "perlengkapan",
+ "apricot.ogg": "aprikot",
+ "arm.ogg": "lengan",
+ "artichoke.ogg": "artichoke",
+ "artist.ogg": "artis",
+ "asparagus.ogg": "asparagus",
+ "astronaut.ogg": "astronot",
+ "athlete.ogg": "atlet",
+ "avocado.ogg": "alpukat",
+ "ax.ogg": "kapak",
+ "baby_bottle.ogg": "botol bayi",
+ "back.ogg": "punggung",
+ "badge.ogg": "lencana",
+ "bag.ogg": "tas",
+ "bait.ogg": "umpan",
+ "balance.ogg": "neraca",
+ "bald.ogg": "botak",
+ "ball.ogg": "bola",
+ "ball_of_yarn.ogg": "bola benang",
+ "ball_soccer.ogg": "bola kaki",
+ "ballet.ogg": "balet",
+ "bank.ogg": "bank",
+ "banker_female.ogg": "bankir wanita",
+ "bark.ogg": "menggonggong",
+ "barn.ogg": "lumbung",
+ "bat.ogg": "kelelawar",
+ "bath.ogg": "tempat mandi",
+ "bathing_suit.ogg": "baju mandi",
+ "bay.ogg": "teluk",
+ "beach.ogg": "pantai",
+ "bean.ogg": "kacang-kacangan",
+ "bear.ogg": "beruang",
+ "beard.ogg": "jenggot",
+ "beat.ogg": "mengalahkan",
+ "beaver.ogg": "berang-berang",
+ "bed.ogg": "tempat tidur",
+ "bedroom.ogg": "kamar tidur",
+ "bee.ogg": "lebah",
+ "beetle.ogg": "kumbang",
+ "beg.ogg": "memohon",
+ "behind.ogg": "di belakang",
+ "bell.ogg": "bel",
+ "belly.ogg": "perut",
+ "bench.ogg": "bangku",
+ "bib.ogg": "cukin",
+ "big.ogg": "besar",
+ "big_top.ogg": "tenda sirkus",
+ "bike.ogg": "sepeda",
+ "bird.ogg": "burung",
+ "bit.ogg": "sedikit",
+ "bite.ogg": "menggigit",
+ "black.ogg": "hitam",
+ "blackberry.ogg": "blackberry",
+ "blackbird.ogg": "burung hitam",
+ "blade.ogg": "mata pisau",
+ "blind.ogg": "buta",
+ "blink.ogg": "berkedip",
+ "blond.ogg": "pirang",
+ "blue.ogg": "biru",
+ "blueberry.ogg": "blueberry",
+ "blush.ogg": "merona",
+ "board.ogg": "papan",
+ "boat.ogg": "perahu",
+ "boil.ogg": "merebus",
+ "bolt.ogg": "baut",
+ "bomb.ogg": "bom",
+ "bone.ogg": "tulang",
+ "book.ogg": "buku",
+ "bookcase.ogg": "rak buku",
+ "bottom.ogg": "pantat",
+ "box.ogg": "kotak",
+ "boxer.ogg": "petinju",
+ "boy.ogg": "anak laki-laki",
+ "braid.ogg": "kepang",
+ "brain.ogg": "otak",
+ "branch.ogg": "ranting",
+ "bread.ogg": "roti",
+ "break.ogg": "memecahkan",
+ "breast.ogg": "payudara",
+ "brick.ogg": "batu bata",
+ "bricklayer.ogg": "tukang batu",
+ "bride.ogg": "pengantin",
+ "bridge.ogg": "jembatan",
+ "bright.ogg": "terang",
+ "broccoli.ogg": "brokoli",
+ "brother.ogg": "saudara laki-laki",
+ "brown.ogg": "coklat",
+ "brush.ogg": "kuas",
+ "bubble.ogg": "gelembung",
+ "bucket.ogg": "ember",
+ "bud.ogg": "tunas",
+ "buffalo.ogg": "kerbau",
+ "bug.ogg": "serangga",
+ "bulb.ogg": "bola lampu",
+ "bull.ogg": "banteng",
+ "bump.ogg": "benjol",
+ "bun.ogg": "roti manis",
+ "bus.ogg": "bis",
+ "bush.ogg": "semak",
+ "butcher.ogg": "tukang daging",
+ "butter.ogg": "mentega",
+ "butterfly.ogg": "kupu-kupu",
+ "button.ogg": "kancing",
+ "cabbage.ogg": "kubis",
+ "cabin.ogg": "kabin",
+ "cacao.ogg": "kakao",
+ "cactus.ogg": "kaktus",
+ "cage.ogg": "kurungan",
+ "cake.ogg": "kue",
+ "call.ogg": "memanggil",
+ "camel.ogg": "unta",
+ "camera.ogg": "kamera",
+ "camp.ogg": "kemping",
+ "can.ogg": "kaleng",
+ "canary.ogg": "burung kenari",
+ "candle.ogg": "lilin",
+ "candy.ogg": "permen",
+ "cane.ogg": "tongkat",
+ "canoe.ogg": "kano",
+ "canon.ogg": "meriam",
+ "canyon.ogg": "tebing",
+ "cap.ogg": "topi",
+ "cape.ogg": "rompi",
+ "car.ogg": "mobil",
+ "carafe.ogg": "karaf",
+ "card.ogg": "kartu",
+ "carnival.ogg": "karnaval",
+ "carpenter.ogg": "tukang kayu",
+ "carpet.ogg": "karpet",
+ "carrot.ogg": "wortel",
+ "cash.ogg": "uang tunai",
+ "castle.ogg": "istana",
+ "cat.ogg": "kucing",
+ "cat_female.ogg": "kucing betina",
+ "catch.ogg": "menangkap",
+ "caterpillar.ogg": "ulat",
+ "cauldron.ogg": "cerek",
+ "cauliflower.ogg": "kembang kol",
+ "cave.ogg": "gua",
+ "cavern.ogg": "gua besar",
+ "celery.ogg": "seledri",
+ "centipede.ogg": "lipan",
+ "cereal.ogg": "gandum",
+ "chain.ogg": "rantai",
+ "chair.ogg": "kursi",
+ "chalk.ogg": "kapur tulis",
+ "chameleon.ogg": "bunglon",
+ "chandelier.ogg": "tempat lilin",
+ "chat.ogg": "ngobrol",
+ "cheek.ogg": "pipi",
+ "cheer.ogg": "pemandu sorak",
+ "cheese.ogg": "keju",
+ "chef.ogg": "koki",
+ "cherry.ogg": "ceri",
+ "chest.ogg": "peti",
+ "chick.ogg": "anak ayam",
+ "chicken.ogg": "ayam",
+ "child.ogg": "anak",
+ "chimney.ogg": "cerobong asap",
+ "chimp.ogg": "simpanse",
+ "chin.ogg": "dagu",
+ "chocolate.ogg": "coklat",
+ "chop.ogg": "memotong",
+ "chores.ogg": "tugas",
+ "christmas.ogg": "natal",
+ "cigar.ogg": "cerutu",
+ "circus.ogg": "sirkus",
+ "city.ogg": "kota",
+ "clam.ogg": "kerang",
+ "clap.ogg": "bertepuk tangan",
+ "class.ogg": "kelas",
+ "claw.ogg": "cakar",
+ "clay.ogg": "tanah liat",
+ "clean.ogg": "membersihkan",
+ "cliff.ogg": "jurang",
+ "climb.ogg": "mendaki",
+ "clock.ogg": "jam",
+ "cloth.ogg": "kain",
+ "clothes_hanger.ogg": "gantungan baju",
+ "cloud.ogg": "awan",
+ "cloudy.ogg": "berawan",
+ "clover.ogg": "semanggi",
+ "clown.ogg": "badut",
+ "coach.ogg": "pelatih",
+ "coast.ogg": "pesisir",
+ "coat.ogg": "mantel",
+ "cobra.ogg": "ular kobra",
+ "coconut.ogg": "kelapa",
+ "cod.ogg": "ikan kod",
+ "coffee.ogg": "kopi",
+ "coin.ogg": "koin",
+ "cold.ogg": "dingin",
+ "color.ogg": "warna",
+ "colt.ogg": "anak kuda jantan",
+ "comb.ogg": "sisir",
+ "cook.ogg": "memasak",
+ "cookie.ogg": "kue kering",
+ "cork.ogg": "sumbat gabus",
+ "corn.ogg": "jagung",
+ "couch.ogg": "sofa",
+ "cough.ogg": "batuk",
+ "couple.ogg": "pasangan",
+ "cow.ogg": "sapi",
+ "cowboy.ogg": "koboi",
+ "crab.ogg": "kepiting",
+ "cradle.ogg": "buaian",
+ "craft.ogg": "kerajinan",
+ "crawl.ogg": "merangkak",
+ "crazy.ogg": "gila",
+ "crib.ogg": "boks bayi",
+ "croak.ogg": "berkotek",
+ "crocodile.ogg": "buaya",
+ "cross.ogg": "salip",
+ "crow.ogg": "gagak",
+ "crown.ogg": "mahkota",
+ "crumb.ogg": "remah",
+ "cry.ogg": "menangis",
+ "crystal.ogg": "kristal",
+ "cube.ogg": "kubus",
+ "cucumber.ogg": "timun",
+ "curtain.ogg": "tirai",
+ "cut.ogg": "memotong",
+ "cute.ogg": "imut",
+ "dad.ogg": "ayah",
+ "daffodil.ogg": "bakung",
+ "daisy.ogg": "bunga aster",
+ "dam.ogg": "bendungan",
+ "dance.ogg": "menari",
+ "dart_board.ogg": "papan sasaran",
+ "date_fruit.ogg": "buah kurma",
+ "deer.ogg": "rusa",
+ "den.ogg": "sarang",
+ "desert.ogg": "gurun",
+ "desk.ogg": "meja tulis",
+ "dessert.ogg": "pencuci mulut",
+ "diamond.ogg": "berlian",
+ "dig.ogg": "menggali",
+ "dirt.ogg": "tanah",
+ "dirty.ogg": "kotor",
+ "dishcloth.ogg": "lap piring",
+ "dive.ogg": "menyelam",
+ "doctor.ogg": "dokter",
+ "doe.ogg": "kelinci betina",
+ "dog.ogg": "anjing",
+ "doll.ogg": "boneka",
+ "dolphin.ogg": "lumba-lumba",
+ "domino.ogg": "domino",
+ "door.ogg": "pintu",
+ "doormat.ogg": "keset",
+ "dot.ogg": "titik",
+ "doughnut.ogg": "donat",
+ "dove.ogg": "merpati",
+ "dragon.ogg": "naga",
+ "dragonfly.ogg": "capung",
+ "draw.ogg": "menggambar",
+ "drawer.ogg": "laci",
+ "dream.ogg": "bermimpi",
+ "dress.ogg": "gaun",
+ "drink.ogg": "minuman",
+ "drip.ogg": "menitis",
+ "drive.ogg": "mengemudi",
+ "drool.ogg": "ngiler",
+ "drum.ogg": "drum",
+ "dry.ogg": "menjemur",
+ "duck.ogg": "bebek",
+ "duck_mother.ogg": "ibu bebek",
+ "dune.ogg": "bukit pasir",
+ "dwarf.ogg": "kerdil",
+ "eagle.ogg": "elang",
+ "ear.ogg": "kuping",
+ "earth.ogg": "bumi",
+ "eat.ogg": "makan",
+ "egg.ogg": "telur",
+ "eggplant.ogg": "terong",
+ "elbow.ogg": "siku",
+ "electrician.ogg": "tukang listrik",
+ "elk.ogg": "rusa elk",
+ "empty.ogg": "kosong",
+ "engine.ogg": "mesin",
+ "engineer.ogg": "insinyur",
+ "eraser.ogg": "penghapus",
+ "explore.ogg": "Jelajahi",
+ "eyelash.ogg": "bulu mata",
+ "eyes.ogg": "mata",
+ "face.ogg": "muka",
+ "fair.ogg": "pekan raya",
+ "fairy.ogg": "peri",
+ "fall.ogg": "terjatuh",
+ "fall_season.ogg": "musim gugur",
+ "family.ogg": "keluarga",
+ "fan.ogg": "kipas angin",
+ "farm.ogg": "peternakan",
+ "farmer.ogg": "petani",
+ "fat.ogg": "gemuk",
+ "faucet.ogg": "keran",
+ "fawn.ogg": "anak rusa",
+ "fear.ogg": "ketakutan",
+ "feather.ogg": "bulu",
+ "feed.ogg": "menyuapi",
+ "femur.ogg": "tulang paha",
+ "fetch.ogg": "mengambil",
+ "fig.ogg": "buah ara",
+ "fin.ogg": "sirip",
+ "find.ogg": "menemukan",
+ "finger.ogg": "jari",
+ "fire.ogg": "api",
+ "fire_extinguisher.ogg": "pemadam api",
+ "fireman.ogg": "pemadam kebakaran",
+ "fish.ogg": "ikan",
+ "fisherman.ogg": "nelayan",
+ "fist.ogg": "kepalan tangan",
+ "flag.ogg": "bendera",
+ "flame.ogg": "nyala api",
+ "flamingo.ogg": "flamingo",
+ "flash.ogg": "senter",
+ "flat.ogg": "apartemen",
+ "flies.ogg": "lalat",
+ "float.ogg": "mengambang",
+ "flour.ogg": "tepung",
+ "flower.ogg": "bunga",
+ "flute.ogg": "seruling",
+ "fly.ogg": "terbang",
+ "foam.ogg": "busa",
+ "foot.ogg": "kaki",
+ "forest.ogg": "hutan",
+ "fork.ogg": "garpu",
+ "fountain.ogg": "air mancur",
+ "fox.ogg": "rubah",
+ "freeze.ogg": "membeku",
+ "friend.ogg": "teman",
+ "fries.ogg": "kentang goreng",
+ "frog.ogg": "kodok",
+ "front.ogg": "depan",
+ "fruit.ogg": "buah",
+ "fudge.ogg": "permen gula",
+ "full.ogg": "penuh",
+ "fur.ogg": "bulu",
+ "game.ogg": "permainan",
+ "garage.ogg": "garasi",
+ "garden.ogg": "taman",
+ "garlic.ogg": "bawang putih",
+ "gem.ogg": "permata",
+ "giant.ogg": "raksasa",
+ "gift.ogg": "kado",
+ "giraffe.ogg": "jerapah",
+ "girl.ogg": "anak perempuan",
+ "glass.ogg": "gelas",
+ "glasses.ogg": "kaca mata",
+ "glove.ogg": "sarung tangan",
+ "glue.ogg": "lem",
+ "gnome.ogg": "kurcaci",
+ "goat.ogg": "kambing",
+ "golden.ogg": "keemasan",
+ "golf.ogg": "golf",
+ "goose.ogg": "itik",
+ "gorilla.ogg": "gorila",
+ "grain.ogg": "gandum",
+ "grandmother.ogg": "nenek",
+ "grape.ogg": "anggur",
+ "grapefruit.ogg": "jeruk bali",
+ "grass.ogg": "rumput",
+ "grave.ogg": "kuburan",
+ "gray.ogg": "abu-abu",
+ "green.ogg": "hijau",
+ "grill.ogg": "panggangan",
+ "grin.ogg": "menyeringai",
+ "ground.ogg": "tanah",
+ "growl.ogg": "menggeram",
+ "guignol.ogg": "guignol",
+ "guinea_pig.ogg": "marmot",
+ "gum.ogg": "permen karet",
+ "hair.ogg": "rambut",
+ "hair_dryer.ogg": "pengering rambut",
+ "half.ogg": "setengah",
+ "ham.ogg": "ham",
+ "hamburger.ogg": "hamburger",
+ "hammer.ogg": "palu",
+ "hand.ogg": "tangan",
+ "handlebar.ogg": "stang",
+ "happy.ogg": "gembira",
+ "harp.ogg": "harpa",
+ "hat.ogg": "topi",
+ "hatch.ogg": "menetas",
+ "hay.ogg": "jerami",
+ "head.ogg": "kepala",
+ "hear.ogg": "mendengar",
+ "heat.ogg": "panas",
+ "hedge.ogg": "tanaman pagar",
+ "hedgehog.ogg": "landak",
+ "heel.ogg": "hak",
+ "helmet.ogg": "helm",
+ "hen.ogg": "ayam betina",
+ "herd.ogg": "kawanan binatang",
+ "high.ogg": "tinggi",
+ "hike.ogg": "mendaki",
+ "hill.ogg": "bukit",
+ "hip.ogg": "panggul",
+ "hippopotamus.ogg": "kuda nil",
+ "hit.ogg": "tinju",
+ "hive.ogg": "sarang lebah",
+ "hockey.ogg": "hoki",
+ "hole.ogg": "lubang",
+ "hook.ogg": "pengait",
+ "hop.ogg": "melompat",
+ "horse.ogg": "kuda",
+ "hose.ogg": "selang",
+ "hospital.ogg": "rumah sakit",
+ "hot.ogg": "panas",
+ "hot_dog.ogg": "hot dog",
+ "hound.ogg": "anjing pemburu",
+ "howl.ogg": "mengaum",
+ "hug.ogg": "memeluk",
+ "huge.ogg": "besar",
+ "hummingbird.ogg": "burung kolibri",
+ "hunchbacked.ogg": "berpunggung bungkuk",
+ "hunter.ogg": "pemburu",
+ "husband.ogg": "suami",
+ "hut.ogg": "gubuk",
+ "hyena.ogg": "dubuk",
+ "ice.ogg": "es",
+ "iceberg.ogg": "gunung es",
+ "iguana.ogg": "iguana",
+ "ill.ogg": "sakit",
+ "ink.ogg": "tinta",
+ "island.ogg": "pulau",
+ "jacket.ogg": "jaket",
+ "jaguar.ogg": "jaguar",
+ "jam.ogg": "selai",
+ "jay.ogg": "burung jay",
+ "jelly.ogg": "jeli",
+ "jellyfish.ogg": "ubur-ubur",
+ "jewel.ogg": "permata",
+ "job.ogg": "pekerjaan",
+ "jockey.ogg": "joki",
+ "jog.ogg": "joging",
+ "joy.ogg": "gembira",
+ "judge.ogg": "hakim",
+ "judo.ogg": "judo",
+ "juice.ogg": "jus",
+ "jump.ogg": "melompat",
+ "kangaroo.ogg": "kanguru",
+ "kernel.ogg": "biji",
+ "keyboard.ogg": "keyboard",
+ "kimono.ogg": "kimono",
+ "king.ogg": "raja",
+ "kiss.ogg": "mencium",
+ "kitchen.ogg": "dapur",
+ "kite.ogg": "layangan",
+ "kitten.ogg": "anak kucing",
+ "kiwi.ogg": "kiwi",
+ "knee.ogg": "lutut",
+ "kneel.ogg": "berlutut",
+ "knife.ogg": "pisau",
+ "knight.ogg": "kesatria",
+ "knit.ogg": "merajut",
+ "knot.ogg": "simpul",
+ "koala.ogg": "koala",
+ "lad.ogg": "anak muda",
+ "lady.ogg": "wanita",
+ "ladybug.ogg": "kepik",
+ "lake.ogg": "danau",
+ "lama.ogg": "llama",
+ "lamb.ogg": "anak domba",
+ "lamp.ogg": "lampu",
+ "land.ogg": "lahan",
+ "lane.ogg": "jalur",
+ "lap.ogg": "pangkuan",
+ "lasso.ogg": "laso",
+ "laugh.ogg": "ketawa",
+ "lava.ogg": "lahar",
+ "lawn.ogg": "halaman rumput",
+ "lawyer.ogg": "pengacara",
+ "leaf.ogg": "daun",
+ "leek.ogg": "bawang prei",
+ "left.ogg": "kiri",
+ "leg.ogg": "tungkai",
+ "lemon.ogg": "jeruk sitrun",
+ "lemonade.ogg": "limun",
+ "lemur.ogg": "kukang",
+ "leopard.ogg": "macan tutul",
+ "lettuce.ogg": "selada",
+ "librarian.ogg": "pustakawan",
+ "lick.ogg": "menjilat",
+ "lid.ogg": "penutup",
+ "lift.ogg": "angkat besi",
+ "light.ogg": "lampu",
+ "lighthouse.ogg": "mercu suar",
+ "lightning.ogg": "petir",
+ "lilac.ogg": "bunga lilac",
+ "lime.ogg": "jeruk nipis",
+ "line.ogg": "garis",
+ "link.ogg": "rantai",
+ "lion.ogg": "singa",
+ "lion_cub.ogg": "anak singa",
+ "lip.ogg": "bibir",
+ "liquid.ogg": "cair",
+ "lizard.ogg": "kadal",
+ "lobster.ogg": "lobster",
+ "log.ogg": "kayu gelondongan",
+ "look.ogg": "melihat",
+ "lunch.ogg": "makan siang",
+ "magic.ogg": "sulap",
+ "magnet.ogg": "besi berani",
+ "magnifying_glass.ogg": "kaca pembesar",
+ "magpie.ogg": "murai",
+ "mail.ogg": "surat",
+ "man.ogg": "pria",
+ "mane.ogg": "surai",
+ "mango.ogg": "mangga",
+ "map.ogg": "peta",
+ "maple.ogg": "pohon maple",
+ "marble.ogg": "kelereng",
+ "mashed_potatoes.ogg": "kentang tumbuk",
+ "mask.ogg": "masker",
+ "mast.ogg": "tiang kapal",
+ "mat.ogg": "tikar",
+ "match.ogg": "korek api",
+ "mate.ogg": "rekan",
+ "mattress.ogg": "matras",
+ "mauve.ogg": "ungu lembayung",
+ "meal.ogg": "makanan",
+ "meat.ogg": "daging",
+ "mechanic.ogg": "mekanik",
+ "medal.ogg": "medali",
+ "meet.ogg": "bertemu",
+ "melon.ogg": "melon",
+ "merry-go-round.ogg": "komedi putar",
+ "mice.ogg": "tikus",
+ "microphone.ogg": "mikropon",
+ "milk.ogg": "susu",
+ "mirror.ogg": "cermin",
+ "mixer.ogg": "alat pengaduk listrik",
+ "mole.ogg": "tikus mondok",
+ "mom.ogg": "mama",
+ "moon.ogg": "bulan",
+ "moose.ogg": "rusa moose",
+ "mop.ogg": "pengepel",
+ "mosque.ogg": "mesjid",
+ "mosquito.ogg": "nyamuk",
+ "mother.ogg": "ibu",
+ "motorcycle.ogg": "motor",
+ "mountain.ogg": "gunung",
+ "mouse.ogg": "tikus",
+ "mouth.ogg": "mulut",
+ "movie.ogg": "filem",
+ "mower.ogg": "mesin pemotong rumput",
+ "mud.ogg": "lumpur",
+ "mug.ogg": "cangkir",
+ "mule.ogg": "anak keledai",
+ "muscle.ogg": "otot",
+ "mushroom.ogg": "jamur",
+ "music.ogg": "musik",
+ "musician.ogg": "pemusik",
+ "naked.ogg": "telanjang",
+ "nap.ogg": "tidur",
+ "navel.ogg": "pusar",
+ "neck.ogg": "leher",
+ "necklace.ogg": "kalung",
+ "needle.ogg": "jarum",
+ "nest.ogg": "sarang",
+ "net.ogg": "jala-jala",
+ "newspaper.ogg": "koran",
+ "night.ogg": "malam",
+ "nightgown.ogg": "baju tidur",
+ "nose.ogg": "hidung",
+ "nostril.ogg": "lubang hidung",
+ "notebook.ogg": "buku catatan",
+ "number.ogg": "bilangan",
+ "nun.ogg": "biarawati",
+ "nurse.ogg": "perawat",
+ "nut.ogg": "kacang",
+ "oar.ogg": "mobil",
+ "ocean.ogg": "laut",
+ "office.ogg": "kantor",
+ "olive.ogg": "zaitun",
+ "on.ogg": "di atas",
+ "onion.ogg": "bawang",
+ "open.ogg": "terbuka",
+ "orange-color.ogg": "warna jingga",
+ "orange.ogg": "jeruk",
+ "orchid.ogg": "bunga anggrek",
+ "ostrich.ogg": "burung unta",
+ "otter.ogg": "berang-berang",
+ "owl.ogg": "burung hantu",
+ "ox.ogg": "lembu",
+ "oyster.ogg": "kerang",
+ "pacifier.ogg": "dot",
+ "page.ogg": "halaman",
+ "pair.ogg": "sepasang",
+ "pajamas.ogg": "piama",
+ "pal.ogg": "sahabat",
+ "palm_tree.ogg": "pohon palem",
+ "pan.ogg": "panci",
+ "panda.ogg": "panda",
+ "panther.ogg": "macan kumbang",
+ "panties.ogg": "celana dalam",
+ "pants.ogg": "celana panjang",
+ "papaya.ogg": "pepaya",
+ "paper.ogg": "kertas",
+ "parachute.ogg": "parasut",
+ "parakeet.ogg": "burung parkit",
+ "parrot.ogg": "burung beo",
+ "patch.ogg": "tambalan",
+ "paw.ogg": "kaki hewan",
+ "pea.ogg": "biji kacang polong",
+ "peach.ogg": "persik",
+ "peacock.ogg": "burung merak",
+ "peak.ogg": "puncak",
+ "pear.ogg": "pir",
+ "pearl.ogg": "mutiara",
+ "peck.ogg": "mematuk",
+ "pedal.ogg": "pedal",
+ "pelican.ogg": "burung pelikan",
+ "pen.ogg": "pena",
+ "pencil.ogg": "pensil",
+ "people.ogg": "orang-orang",
+ "pepper.ogg": "lada",
+ "peppers.ogg": "paprika",
+ "pet.ogg": "binatang peliharaan",
+ "petal.ogg": "kelopak bunga",
+ "phone.ogg": "telepon",
+ "piano.ogg": "piano",
+ "picture.ogg": "gambar",
+ "pie.ogg": "pai",
+ "pig.ogg": "babi",
+ "pigeon.ogg": " burung merpati",
+ "pill.ogg": "pil",
+ "pillow.ogg": "bantal",
+ "pilot.ogg": "pilot",
+ "pine.ogg": "pohon pinus",
+ "pine_cone.ogg": "biji pinus",
+ "pink.ogg": "merah muda",
+ "pip.ogg": "biji",
+ "pipe.ogg": "cangkelong",
+ "piranha.ogg": "ikan piranha",
+ "pirate.ogg": "bajak laut",
+ "pizza.ogg": "pizza",
+ "plane.ogg": "pesawat terbang",
+ "planet.ogg": "planet",
+ "plant.ogg": "tumbuhan",
+ "plate.ogg": "piring",
+ "play.ogg": "bermain",
+ "pliers.ogg": "tang",
+ "plow.ogg": "membajak",
+ "plum.ogg": "prem",
+ "plumber.ogg": "tukang ledeng",
+ "pocket.ogg": "kantong",
+ "pod.ogg": "kacang polong",
+ "pole.ogg": "tiang",
+ "police.ogg": "polisi",
+ "pond.ogg": "kolam",
+ "pony.ogg": "kuda poni",
+ "pool.ogg": "kolam berenang",
+ "popcorn.ogg": "berondong",
+ "pope.ogg": "paus",
+ "porthole.ogg": "jendela kapal",
+ "post.ogg": "pos",
+ "pot.ogg": "pot",
+ "potato.ogg": "kentang",
+ "pounce.ogg": "menerkam",
+ "president.ogg": "presiden",
+ "pretty.ogg": "cantik",
+ "price.ogg": "harga",
+ "priest.ogg": "pendeta",
+ "prince.ogg": "pangeran",
+ "princess.ogg": "putri",
+ "prison.ogg": "penjara",
+ "prisoner.ogg": "tahanan",
+ "prize.ogg": "hadiah",
+ "pug.ogg": "anjing pug",
+ "pull.ogg": "menarik",
+ "pumpkin.ogg": "labu",
+ "puppy.ogg": "anak anjing",
+ "pyramid.ogg": "piramida",
+ "quarrel.ogg": "bertengkar",
+ "queen.ogg": "ratu",
+ "question.ogg": "pertanyaan",
+ "quilt.ogg": "selimut",
+ "quiz.ogg": "kuis",
+ "rabbit.ogg": "kelinci",
+ "rabbit_baby.ogg": "anak kelinci",
+ "race.ogg": "lari",
+ "radio.ogg": "radio",
+ "radish.ogg": "lobak",
+ "raft.ogg": "rakit",
+ "rag.ogg": "lap",
+ "rain.ogg": "hujan",
+ "raincoat.ogg": "jas hujan",
+ "rake.ogg": "penggaruk",
+ "ramp.ogg": "lerengan",
+ "ran.ogg": "berlari",
+ "rat.ogg": "tikus",
+ "razor.ogg": "pisau cukur",
+ "read.ogg": "membaca",
+ "red.ogg": "merah",
+ "reptile.ogg": "reptil",
+ "rhinoceros.ogg": "badak",
+ "rice.ogg": "nasi",
+ "ride.ogg": "bersepeda",
+ "rifle.ogg": "senapan",
+ "right.ogg": "kanan",
+ "rip.ogg": "merobek",
+ "rise.ogg": "bangkit",
+ "river.ogg": "sungai",
+ "road.ogg": "jalan",
+ "roast.ogg": "daging panggang",
+ "robe.ogg": "jubah",
+ "robot.ogg": "robot",
+ "rock.ogg": "batu",
+ "rocket.ogg": "roket",
+ "rolling_pin.ogg": "gilingan adonan",
+ "roof.ogg": "atap",
+ "room.ogg": "kamar",
+ "root.ogg": "akar",
+ "rope.ogg": "tali",
+ "rose.ogg": "bunga mawar",
+ "round.ogg": "bulat",
+ "rowing.ogg": "mendayung",
+ "royal.ogg": "kerajaan",
+ "rug.ogg": "permadani",
+ "run.ogg": "berlari",
+ "sad.ogg": "sedih",
+ "saddle.ogg": "pelana",
+ "sail.ogg": "kapal layar",
+ "sailor.ogg": "pelaut",
+ "salamander.ogg": "salamander",
+ "salmon.ogg": "ikan salmon",
+ "sand.ogg": "pasir",
+ "sandals.ogg": "sandal",
+ "sandwich.ogg": "roti lapis",
+ "sash.ogg": "selempang",
+ "sauce.ogg": "saus",
+ "sausage.ogg": "sosis",
+ "scale.ogg": "timbangan",
+ "scar.ogg": "bekas luka",
+ "scare.ogg": "menakuti",
+ "scarf.ogg": "syal",
+ "school.ogg": "sekolah",
+ "school_bag.ogg": "tas sekolah",
+ "science.ogg": "sains",
+ "scissors.ogg": "gunting",
+ "scorpion.ogg": "kalajengking",
+ "scratch.ogg": "mencakar",
+ "scream.ogg": "menjerit",
+ "screw.ogg": "sekrup",
+ "screwdriver.ogg": "obeng",
+ "scribble.ogg": "mencoret-coret",
+ "sea.ogg": "laut",
+ "seat.ogg": "tempat duduk",
+ "see.ogg": "melihat",
+ "seed.ogg": "benih",
+ "shadow.ogg": "bayangan",
+ "shake.ogg": "mengguncang",
+ "shark.ogg": "ikan hiu",
+ "shave.ogg": "mencukur",
+ "shed.ogg": "gudang",
+ "sheep.ogg": "domba",
+ "shelf.ogg": "rak",
+ "shell.ogg": "kerang",
+ "ship.ogg": "kapal",
+ "shirt.ogg": "kemeja",
+ "shoe.ogg": "sepatu",
+ "shoelace.ogg": "tali sepatu",
+ "shop.ogg": "toko",
+ "shore.ogg": "tepi laut",
+ "short.ogg": "celana pendek",
+ "shovel.ogg": "pengki",
+ "shower.ogg": "pancuran",
+ "shrimp.ogg": "udang",
+ "shrub.ogg": "semak",
+ "shut.ogg": "tertutup",
+ "sick.ogg": "sakit",
+ "sidewalk.ogg": "trotoar",
+ "sign.ogg": "papan penunjuk jalan",
+ "sing.ogg": "menyanyi",
+ "sink.ogg": "wastafel",
+ "sip.ogg": "menyesap",
+ "sister.ogg": "saudari",
+ "sit.ogg": "duduk",
+ "skate.ogg": "sepatu luncur",
+ "skeleton.ogg": "tulang",
+ "ski.ogg": "ski",
+ "skin.ogg": "kulit",
+ "skirt.ogg": "rok",
+ "skunk.ogg": "sigung",
+ "sky.ogg": "langit",
+ "slam.ogg": "mengempaskan",
+ "sled.ogg": "kereta luncur",
+ "sleep.ogg": "tidur",
+ "sleeve.ogg": "lengan baju",
+ "sleigh.ogg": "kereta luncur",
+ "slide.ogg": "luncuran",
+ "slim.ogg": "ramping",
+ "slime.ogg": "lendir",
+ "slippers.ogg": "selop",
+ "slope.ogg": "lereng",
+ "sloppy.ogg": "ceroboh",
+ "slot.ogg": "celah",
+ "sloth.ogg": "kungkang",
+ "slug.ogg": "siput",
+ "small.ogg": "kecil",
+ "smell.ogg": "mencium",
+ "smile.ogg": "senyum",
+ "smock.ogg": "baju kerja",
+ "smoke.ogg": "asap",
+ "smooch.ogg": "berciuman",
+ "snack.ogg": "camilan",
+ "snail.ogg": "keong",
+ "snake.ogg": "ular",
+ "sneaker.ogg": "sepatu kets",
+ "sniff.ogg": "mengendus",
+ "snow.ogg": "salju",
+ "soap.ogg": "sabun",
+ "sob.ogg": "tersedu",
+ "sock.ogg": "kaos kaki",
+ "soldier.ogg": "tentara",
+ "sole.ogg": "ikan lidah",
+ "sole_shoe.ogg": "sol sepatu",
+ "son.ogg": "putra",
+ "soup.ogg": "sup",
+ "spade.ogg": "sekop",
+ "spaghetti.ogg": "spageti",
+ "spark.ogg": "bunga api",
+ "sparrow.ogg": "burung gereja",
+ "speak.ogg": "berbicara",
+ "spear.ogg": "tombak",
+ "spice.ogg": "bumbu",
+ "spider.ogg": "laba-laba",
+ "spider_web.ogg": "sarang laba-laba",
+ "spike.ogg": "duri",
+ "spill.ogg": "menumpahkan",
+ "spinach.ogg": "bayam",
+ "spine.ogg": "tulang belakang",
+ "spinning_top.ogg": "gasing",
+ "splash.ogg": "memercikkan",
+ "splatter.ogg": "percikan",
+ "sponge.ogg": "sepon",
+ "spoon.ogg": "sendok",
+ "sport.ogg": "olahraga",
+ "spot.ogg": "bintik",
+ "spray.ogg": "menyemprot",
+ "spread.ogg": "menyebarkan",
+ "spring.ogg": "melompat",
+ "spring_season.ogg": "musim semi",
+ "square.ogg": "kotak",
+ "squash.ogg": "labu siam",
+ "squat.ogg": "berjongkok",
+ "squid.ogg": "cumi-cumi",
+ "squirrel.ogg": "tupai",
+ "squirt.ogg": "semprotan",
+ "stack.ogg": "tumpukan",
+ "stage.ogg": "panggung",
+ "staircase.ogg": "tangga",
+ "stamp.ogg": "perangko",
+ "stand.ogg": "berdiri",
+ "star.ogg": "bintang",
+ "stare.ogg": "menatap",
+ "starfish.ogg": "bintang laut",
+ "steam.ogg": "uap",
+ "steep.ogg": "curam",
+ "steeple.ogg": "menara gereja",
+ "stem.ogg": "batang",
+ "step.ogg": "anak tangga",
+ "stew.ogg": "rebus",
+ "stick.ogg": "ranting",
+ "sting.ogg": "menyengat",
+ "stinky.ogg": "bau",
+ "stitch.ogg": "menjahit",
+ "stomach.ogg": "perut",
+ "stone.ogg": "batu",
+ "stop.ogg": "menghentikan",
+ "store.ogg": "toko",
+ "stove.ogg": "kompor",
+ "straight.ogg": "lurus",
+ "straw.ogg": "sedotan",
+ "strawberry.ogg": "stroberi",
+ "stream.ogg": "arus air",
+ "street.ogg": "jalan",
+ "stretch.ogg": "meregangkan",
+ "string.ogg": "tali",
+ "stripe.ogg": "belang",
+ "strong.ogg": "kuat",
+ "student.ogg": "murid",
+ "study.ogg": "belajar",
+ "stump.ogg": "tunggul",
+ "sugar.ogg": "gula",
+ "suit.ogg": "setelan",
+ "suitcase.ogg": "koper",
+ "summer.ogg": "musim panas",
+ "summit.ogg": "puncak",
+ "sun.ogg": "matahari",
+ "swan.ogg": "angsa",
+ "sweat.ogg": "keringat",
+ "sweatshirt.ogg": "sweter lengan panjang",
+ "swim.ogg": "berenang",
+ "table.ogg": "meja",
+ "tablecloth.ogg": "taplak meja",
+ "tadpole.ogg": "kecebong",
+ "tail.ogg": "ekor",
+ "tall.ogg": "tinggi",
+ "tape_measure.ogg": "pit ukur",
+ "taxi.ogg": "taksi",
+ "teach.ogg": "mengajarkan",
+ "teacher.ogg": "guru",
+ "tear.ogg": "merobek",
+ "teddy.ogg": "boneka teddy",
+ "teeth.ogg": "gigi",
+ "television.ogg": "televisi",
+ "temple.ogg": "kuil",
+ "tennis.ogg": "tenis",
+ "tent.ogg": "tenda",
+ "text.ogg": "teks",
+ "thick.ogg": "tebal",
+ "thief.ogg": "pencuri",
+ "thigh.ogg": "paha",
+ "think.ogg": "berpikir",
+ "thread.ogg": "benang",
+ "throat.ogg": "tenggorokan",
+ "throw.ogg": "melempar",
+ "thumb.ogg": "jempol",
+ "tick.ogg": "kutu",
+ "ticket.ogg": "tiket",
+ "tiger.ogg": "harimau",
+ "time.ogg": "waktu",
+ "tin.ogg": "kaleng",
+ "tire.ogg": "ban",
+ "tired.ogg": "lelah",
+ "tissue.ogg": "tisu",
+ "to_drink.ogg": "minum",
+ "toad.ogg": "katak",
+ "toaster.ogg": "pemanggang roti",
+ "toe.ogg": "jari kaki",
+ "toilet.ogg": "kamar kecil",
+ "tomatoe.ogg": "tomat",
+ "tongs.ogg": "penjepit",
+ "tongue.ogg": "lidah",
+ "tool.ogg": "perkakas",
+ "top.ogg": "puncak",
+ "torch.ogg": "obor",
+ "touch.ogg": "menyentuh",
+ "towel.ogg": "handuk",
+ "toy.ogg": "mainan",
+ "train.ogg": "kereta api",
+ "train_station.ogg": "stasiun kereta",
+ "trap.ogg": "perangkap",
+ "trash.ogg": "sampah",
+ "tray.ogg": "baki",
+ "tree.ogg": "pohon",
+ "triangle.ogg": "segitiga",
+ "tribe.ogg": "suku",
+ "trip.ogg": "perjalanan",
+ "truck.ogg": "truk",
+ "tube.ogg": "tabung",
+ "tulip.ogg": "tulip",
+ "tune.ogg": "nada",
+ "turkey.ogg": "ayam kalkun",
+ "turnip.ogg": "lobak",
+ "turtle.ogg": "penyu",
+ "tusk.ogg": "gading",
+ "twin_boys.ogg": "anak laki-laki kembar",
+ "twin_girls.ogg": "anak perempuan kembar",
+ "umbrella.ogg": "payung",
+ "under.ogg": "di bawah",
+ "uniform.ogg": "seragam",
+ "van.ogg": "mobil van",
+ "vapor.ogg": "uap",
+ "vase.ogg": "vas",
+ "vegetable.ogg": "sayuran",
+ "vein.ogg": "pembuluh darah",
+ "vest.ogg": "rompi",
+ "vet.ogg": "dokter hewan",
+ "viper.ogg": "ular tedung",
+ "vowel.ogg": "vokal",
+ "vulture.ogg": "burung bangkai",
+ "wag.ogg": "mengibas",
+ "walk.ogg": "berjalan",
+ "wall.ogg": "dinding",
+ "walnut.ogg": "kenari",
+ "wart.ogg": "kutil",
+ "wash.ogg": "mencuci",
+ "wasp.ogg": "tawon",
+ "watch.ogg": "jam tangan",
+ "water.ogg": "air",
+ "wave.ogg": "ombak",
+ "wedding.ogg": "pernikahan",
+ "wedge.ogg": "baji",
+ "weight.ogg": "beban",
+ "wet.ogg": "basah",
+ "whale.ogg": "ikan paus",
+ "wheat.ogg": "gandum",
+ "wheel.ogg": "roda",
+ "whisk.ogg": "pengaduk",
+ "whisper.ogg": "berbisik",
+ "white.ogg": "putih",
+ "wide.ogg": "lebar",
+ "wife.ogg": "istri",
+ "wig.ogg": "rambut palsu",
+ "win.ogg": "memenangkan",
+ "wind.ogg": "angin",
+ "window.ogg": "jendela",
+ "window_glass.ogg": "kaca jendela",
+ "wing.ogg": "sayap",
+ "winter.ogg": "musim dingin",
+ "wolf.ogg": "serigala",
+ "woman.ogg": "wanita",
+ "wood.ogg": "kayu",
+ "word.ogg": "kata",
+ "worker.ogg": "pekerja",
+ "world.ogg": "dunia",
+ "wreath.ogg": "rangkaian bunga",
+ "wrench.ogg": "kunci pas",
+ "wrist.ogg": "pergelangan tangan",
+ "write.ogg": "menulis",
+ "yellow.ogg": "kuning",
+ "yogurt.ogg": "yogurt",
+ "yum.ogg": "lezat",
+ "zebra.ogg": "zebra",
+ "zipper.ogg": "ritsleting",
+ "zoo.ogg": "kebun binatang"
+}
\ No newline at end of file
diff --git a/src/activities/lang/resource/content-it.json b/src/activities/lang/resource/content-it.json
index 83c774019..5dc16a781 100644
--- a/src/activities/lang/resource/content-it.json
+++ b/src/activities/lang/resource/content-it.json
@@ -1,1113 +1,459 @@
{
"10.ogg": "dieci",
"11.ogg": "undici",
"12.ogg": "dodici",
"16.ogg": "sedici",
"U0030.ogg": "zero",
"U0031.ogg": "uno",
"U0032.ogg": "due",
"U0033.ogg": "tre",
"U0034.ogg": "quattro",
"U0035.ogg": "cinque",
"U0036.ogg": "sei",
"U0037.ogg": "sette",
"U0038.ogg": "otto",
"U0039.ogg": "nove",
- "accountant.ogg": "",
- "ache.ogg": "",
- "acorn.ogg": "",
- "actor.ogg": "",
- "air_horn.ogg": "",
- "alarmclock.ogg": "",
"alligator.ogg": "l'alligatore",
- "alphabet.ogg": "",
"anchor.ogg": "l'ancora",
- "angel.ogg": "",
- "angry.ogg": "",
"animal.ogg": "gli animali",
- "ankle.ogg": "",
- "ant.ogg": "",
- "anteater.ogg": "",
- "antelope.ogg": "",
- "apple.ogg": "",
- "apple_tree.ogg": "",
- "appliance.ogg": "",
- "apricot.ogg": "",
- "arm.ogg": "",
- "armchair.ogg": "",
- "artichoke.ogg": "",
- "artist.ogg": "",
- "asparagus.ogg": "",
- "astronaut.ogg": "",
- "ate.ogg": "",
"athlete.ogg": "l'atleta",
- "avocado.ogg": "",
- "ax.ogg": "",
- "baby_bottle.ogg": "",
"back.ogg": "la schiena",
"badge.ogg": "la medaglia",
"bag.ogg": "lo zaino",
- "bait.ogg": "",
- "bake.ogg": "cucinare",
"balance.ogg": "la bilancia",
- "bald.ogg": "",
"ball.ogg": "la palla",
- "ball_of_yarn.ogg": "",
- "ball_soccer.ogg": "",
"ballet.ogg": "il balletto",
"bank.ogg": "la banca",
"bark.ogg": "abbaiare",
"barn.ogg": "il fienile",
"bat.ogg": "il pipistrello",
"bath.ogg": "la vasca da bagno",
- "bathing_suit.ogg": "",
"bay.ogg": "la baia",
"beach.ogg": "la spiaggia",
- "bead.ogg": "la perlina",
- "bean.ogg": "",
- "bear.ogg": "",
- "beard.ogg": "",
- "beat.ogg": "",
- "beaver.ogg": "",
"bed.ogg": "il letto",
- "bedroom.ogg": "",
"bee.ogg": "l'ape",
- "beef.ogg": "",
"beetle.ogg": "lo scarabeo",
"beg.ogg": "pregare",
- "behind.ogg": "",
- "bell.ogg": "",
- "belly.ogg": "",
"bench.ogg": "la panchina",
"bib.ogg": "il bavaglino",
- "big.ogg": "",
- "big_top.ogg": "",
"bike.ogg": "la bicicletta",
"bird.ogg": "l'uccello",
"bit.ogg": "il bocconcino",
"bite.ogg": "mordere",
"black.ogg": "nero",
- "blackberry.ogg": "",
- "blackbird.ogg": "",
- "blade.ogg": "",
- "blind.ogg": "",
- "blink.ogg": "",
"block.ogg": "il cubo",
- "blond.ogg": "",
"blue.ogg": "blu",
- "blueberry.ogg": "",
- "blush.ogg": "",
"board.ogg": "il cartello",
"boat.ogg": "la barca",
"boil.ogg": "bollire",
- "bolt.ogg": "",
"bomb.ogg": "la bomba",
"bone.ogg": "l'osso",
"book.ogg": "il libro",
- "bookcase.ogg": "",
- "bottom.ogg": "",
"box.ogg": "la scatola",
- "boxer.ogg": "",
"boy.ogg": "il ragazzo",
"braid.ogg": "la treccia",
"brain.ogg": "il cervello",
"branch.ogg": "il ramo",
"bread.ogg": "il pane",
- "break.ogg": "",
- "breast.ogg": "",
"brick.ogg": "i mattoni",
- "bricklayer.ogg": "",
"bride.ogg": "la sposa",
"bridge.ogg": "il ponte",
- "bright.ogg": "",
- "broccoli.ogg": "",
"brother.ogg": "il fratello",
"brown.ogg": "marrone",
"brush.ogg": "il pennello",
- "bubble.ogg": "",
- "bucket.ogg": "",
"bud.ogg": "la gemma",
- "buffalo.ogg": "",
"bug.ogg": "l'insetto",
- "bulb.ogg": "",
- "bull.ogg": "",
"bump.ogg": "il bernoccolo",
"bun.ogg": "il panino",
- "bus.ogg": "",
"bush.ogg": "il cespuglio",
- "butcher.ogg": "",
- "butter.ogg": "",
- "butterfly.ogg": "",
- "button.ogg": "",
- "cabbage.ogg": "",
- "cabin.ogg": "",
- "cacao.ogg": "",
- "cactus.ogg": "",
"cage.ogg": "la gabbia",
"cake.ogg": "il dolce",
"call.ogg": "chiamare",
"camel.ogg": "il cammello",
- "camera.ogg": "",
- "camp.ogg": "",
"can.ogg": "i barattoli",
- "canary.ogg": "",
"candle.ogg": "la candela",
"candy.ogg": "la caramella",
"cane.ogg": "il bastone",
"canoe.ogg": "la canoa",
- "canon.ogg": "",
- "canyon.ogg": "",
"cap.ogg": "il cappellino",
"cape.ogg": "il mantello",
"car.ogg": "l'automobile",
- "carafe.ogg": "",
"card.ogg": "la cartolina",
- "carnival.ogg": "",
- "carpenter.ogg": "",
- "carpet.ogg": "",
"carrot.ogg": "la carota",
"cart.ogg": "il carrello",
"cash.ogg": "i soldi",
"castle.ogg": "il castello",
"cat.ogg": "il gatto",
- "cat_female.ogg": "",
"catch.ogg": "pescare",
- "caterpillar.ogg": "",
- "cauldron.ogg": "",
- "cauliflower.ogg": "",
"cave.ogg": "la grotta",
- "cavern.ogg": "",
- "celery.ogg": "",
"centipede.ogg": "il centipede",
- "cereal.ogg": "",
- "chain.ogg": "",
"chair.ogg": "la sedia",
"chalk.ogg": "il gesso",
- "chameleon.ogg": "",
- "chandelier.ogg": "",
"chat.ogg": "bisbigliare",
- "cheek.ogg": "",
- "cheer.ogg": "",
"cheese.ogg": "il formaggio",
- "chef.ogg": "",
"cherry.ogg": "le ciliegie",
"chest.ogg": "il forziere",
"chick.ogg": "il pulcino",
"chicken.ogg": "la gallina",
- "chief.ogg": "",
"child.ogg": "il bambino",
- "chimney.ogg": "",
"chimp.ogg": "la scimmia",
"chin.ogg": "il mento",
"chocolate.ogg": "il cioccolato",
"chop.ogg": "affettare",
- "chore.ogg": "",
- "christmas.ogg": "",
- "cigar.ogg": "",
- "circus.ogg": "",
- "city.ogg": "",
"clam.ogg": "la conchiglia",
- "clap.ogg": "",
"class.ogg": "i compiti",
"claw.ogg": "gli artigli",
"clay.ogg": "l'argilla",
- "clean.ogg": "",
- "cleaning_lady.ogg": "",
"cliff.ogg": "il burrone",
- "climb.ogg": "",
"clock.ogg": "la sveglia",
"cloth.ogg": "il tessuto",
- "clothes_hanger.ogg": "",
"cloud.ogg": "la nuvola",
- "cloudy.ogg": "",
- "clover.ogg": "",
"clown.ogg": "il pagliaccio",
"coach.ogg": "l'allenatrice",
- "coast.ogg": "",
"coat.ogg": "il cappotto",
- "cobra.ogg": "",
- "coconut.ogg": "",
- "cod.ogg": "",
- "coffee.ogg": "",
"coin.ogg": "le monete",
- "cold.ogg": "",
- "color.ogg": "",
- "colt.ogg": "",
"comb.ogg": "il pettine",
- "cone.ogg": "",
+ "cook.ogg": "cucinare",
"cookie.ogg": "i biscotti",
- "cork.ogg": "",
"corn.ogg": "la pannocchia",
"couch.ogg": "il divano",
- "cough.ogg": "",
- "couple.ogg": "",
"cow.ogg": "la mucca",
"cowboy.ogg": "il cowboy",
"crab.ogg": "il granchio",
- "cradle.ogg": "",
- "craft.ogg": "",
"crawl.ogg": "gattonare",
- "crazy.ogg": "",
- "creek.ogg": "",
- "crepe.ogg": "",
"crib.ogg": "la culla",
- "criminal.ogg": "",
"croak.ogg": "gracidare",
"crocodile.ogg": "il coccodrillo",
- "cross.ogg": "",
"crow.ogg": "il corvo",
"crown.ogg": "la corona",
"crumb.ogg": "la briciola",
"crust.ogg": "la crosta",
"cry.ogg": "piangere",
- "crystal.ogg": "",
"cube.ogg": "il cubo",
"cucumber.ogg": "il cetriolo",
- "curtain.ogg": "",
"cut.ogg": "tagliare",
- "cute.ogg": "",
"dad.ogg": "il papà",
- "daffodil.ogg": "",
- "daisy.ogg": "",
- "dam.ogg": "",
- "dance.ogg": "",
- "dandelion.ogg": "",
- "danger.ogg": "",
- "dark.ogg": "",
- "dart_board.ogg": "",
- "date_fruit.ogg": "",
- "deer.ogg": "",
"den.ogg": "la tana",
- "desert.ogg": "",
"desk.ogg": "la scrivania",
- "dessert.ogg": "",
- "diamond.ogg": "",
"dig.ogg": "scavare",
- "dirt.ogg": "",
"dirty.ogg": "sporco",
"dish.ogg": "la zuppiera",
- "dishcloth.ogg": "",
- "dive.ogg": "",
- "doctor.ogg": "",
- "doe.ogg": "",
"dog.ogg": "il cane",
- "doll.ogg": "",
- "dolphin.ogg": "",
- "domino.ogg": "",
"door.ogg": "la porta",
- "doormat.ogg": "",
- "dot.ogg": "",
- "doughnut.ogg": "",
- "dove.ogg": "",
"dragon.ogg": "il drago",
- "dragonfly.ogg": "",
- "drank.ogg": "bere",
"draw.ogg": "disegnare",
- "drawer.ogg": "",
"dream.ogg": "sognare",
"dress.ogg": "il vestito",
"drink.ogg": "il caffè",
- "drinking.ogg": "",
- "drip.ogg": "",
"drive.ogg": "guida",
"drool.ogg": "sbava",
"drum.ogg": "il tamburo",
- "dry.ogg": "",
"duck.ogg": "l'anatra",
- "duck_mother.ogg": "",
"dune.ogg": "la duna",
- "dwarf.ogg": "",
- "eagle.ogg": "",
"ear.ogg": "l'orecchio",
"earth.ogg": "la terra",
"eat.ogg": "mangiare",
- "egg.ogg": "",
- "eggplant.ogg": "",
- "elbow.ogg": "",
- "electrician.ogg": "",
- "elk.ogg": "",
- "empty.ogg": "",
- "engine.ogg": "",
- "engineer.ogg": "",
- "eraser.ogg": "",
- "explore.ogg": "",
- "eyelash.ogg": "",
- "eyes.ogg": "",
"face.ogg": "la faccia",
- "fair.ogg": "",
- "fairy.ogg": "",
- "fall_down.ogg": "",
- "fall_season.ogg": "",
- "family.ogg": "",
"fan.ogg": "il ventilatore",
"farm.ogg": "la fattoria",
- "farmer.ogg": "",
- "fat.ogg": "",
- "faucet.ogg": "",
- "fawn.ogg": "",
- "feast.ogg": "",
- "feather.ogg": "",
- "feed.ogg": "",
- "feet.ogg": "i piedi",
- "fell.ogg": "",
- "femur.ogg": "",
"fetch.ogg": "riportare",
- "fig.ogg": "",
"fin.ogg": "la pinna",
"find.ogg": "trovare",
- "finger.ogg": "",
"fire.ogg": "il fuoco",
- "fire_extinguisher.ogg": "",
- "fireman.ogg": "",
"fish.ogg": "il pesce",
- "fisherman.ogg": "",
"fist.ogg": "il pugno",
- "five.ogg": "cinque",
- "flacon.ogg": "",
"flag.ogg": "la bandiera",
"flame.ogg": "la fiamma",
- "flamingo.ogg": "",
"flash.ogg": "la torcia elettrica",
- "flat.ogg": "",
"flies.ogg": "la mosca",
- "flight.ogg": "",
"float.ogg": "galleggiare",
"flour.ogg": "la farina",
"flower.ogg": "il fiore",
- "fluff.ogg": "",
"flute.ogg": "il flauto",
"fly.ogg": "volare",
- "foam.ogg": "",
- "food.ogg": "",
"foot.ogg": "il piede",
- "forest.ogg": "",
"fork.ogg": "la forchetta",
"fountain.ogg": "la fontana",
"fox.ogg": "la volpe",
"freeze.ogg": "congelare",
"friend.ogg": "gli amici",
- "fries.ogg": "",
"frog.ogg": "la rana",
- "front.ogg": "",
- "frown.ogg": "",
"fruit.ogg": "la frutta",
- "fudge.ogg": "",
- "full.ogg": "",
- "fun.ogg": "il divertimento",
"fur.ogg": "la pelliccia",
"game.ogg": "il giocattolo",
- "garage.ogg": "",
"garden.ogg": "il giardino",
- "garlic.ogg": "",
- "gem.ogg": "",
- "giant.ogg": "",
"gift.ogg": "il regalo",
"giraffe.ogg": "la giraffa",
"girl.ogg": "la ragazza",
"glass.ogg": "il bicchiere",
- "glasses.ogg": "",
"glove.ogg": "i guanti",
"glue.ogg": "la colla",
"gnome.ogg": "lo gnomo",
"goat.ogg": "la capra",
- "golden.ogg": "",
- "golf.ogg": "",
- "goose.ogg": "",
- "gorilla.ogg": "",
- "grain.ogg": "",
- "grandmother.ogg": "",
- "grape.ogg": "",
- "grapefruit.ogg": "",
"grass.ogg": "l'erba",
"grave.ogg": "la tomba",
"gray.ogg": "grigio",
"green.ogg": "verde",
- "grill.ogg": "",
"grin.ogg": "il ghigno",
"ground.ogg": "la terra",
"growl.ogg": "ringhiare",
- "guignol.ogg": "",
- "guinea_pig.ogg": "",
"gum.ogg": "la gomma da masticare",
"hair.ogg": "i capelli",
- "hair_dryer.ogg": "",
- "half.ogg": "",
- "ham.ogg": "",
- "hammer.ogg": "",
"hand.ogg": "la mano",
- "handlebar.ogg": "",
- "happy.ogg": "",
- "harp.ogg": "",
"hat.ogg": "il cappello",
"hatch.ogg": "schiudere",
"hay.ogg": "la paglia",
"head.ogg": "la testa",
"hear.ogg": "ascoltare",
"heat.ogg": "il caldo",
"hedge.ogg": "la siepe",
- "hedgehog.ogg": "",
- "heel.ogg": "",
- "helmet.ogg": "",
"hen.ogg": "la gallina",
"herd.ogg": "il gregge",
- "high.ogg": "",
- "hike.ogg": "",
- "hill.ogg": "",
"hip.ogg": "i fianchi",
- "hippopotamus.ogg": "",
- "hit.ogg": "",
- "hive.ogg": "",
- "hockey.ogg": "",
"hole.ogg": "il buco",
"home.ogg": "la casa",
"hook.ogg": "l'amo",
- "hop.ogg": "",
- "horse.ogg": "",
- "hose.ogg": "",
- "hospital.ogg": "",
- "hot.ogg": "",
- "hot_dog.ogg": "",
"hound.ogg": "il segugio",
- "house.ogg": "",
"howl.ogg": "ululare",
"hug.ogg": "abbracciare",
- "huge.ogg": "",
- "hummingbird.ogg": "",
- "hunchback.ogg": "",
"hunter.ogg": "il cacciatore",
- "husband.ogg": "",
"hut.ogg": "la capanna",
- "hyena.ogg": "",
"ice.ogg": "il ghiaccio",
- "iceberg.ogg": "",
- "iguana.ogg": "",
- "ill.ogg": "",
"ink.ogg": "l'inchiostro",
- "island.ogg": "",
- "jacket.ogg": "",
- "jaguar.ogg": "",
- "jam.ogg": "",
- "jay.ogg": "",
- "jelly.ogg": "",
- "jellyfish.ogg": "",
"jewel.ogg": "il gioiello",
- "job.ogg": "",
- "jockey.ogg": "",
"jog.ogg": "correre",
"judge.ogg": "il giudice",
- "judo.ogg": "",
- "juggler.ogg": "",
"juice.ogg": "il succo d'arancia",
"jump.ogg": "saltare",
- "kangaroo.ogg": "",
- "keel.ogg": "",
- "kernel.ogg": "",
- "keyboard.ogg": "",
- "kimono.ogg": "",
- "king.ogg": "",
- "kiss.ogg": "",
- "kitchen.ogg": "",
"kite.ogg": "l'aquilone",
- "kitten.ogg": "",
- "kiwi.ogg": "",
"knee.ogg": "il ginocchio",
- "kneel.ogg": "",
"knife.ogg": "il coltello",
"knight.ogg": "il cavaliere",
"knit.ogg": "lavorare ai ferri",
"knot.ogg": "il nodo",
- "koala.ogg": "",
- "lad.ogg": "",
- "lady.ogg": "",
- "ladybug.ogg": "",
"lake.ogg": "il lago",
- "lama.ogg": "",
"lamb.ogg": "l'agnello",
"lamp.ogg": "la lampada",
"land.ogg": "la terra",
"lane.ogg": "la strada",
"lap.ogg": "il grembo",
- "lasso.ogg": "",
- "laugh.ogg": "",
- "lava.ogg": "",
"lawn.ogg": "il prato",
- "lawyer.ogg": "",
- "leaf.ogg": "",
- "ledge.ogg": "",
- "leek.ogg": "",
- "left.ogg": "",
- "leg.ogg": "",
- "leg_animal.ogg": "",
- "lemon.ogg": "",
- "lemonade.ogg": "",
- "lemur.ogg": "",
- "leopard.ogg": "",
- "lettuce.ogg": "",
- "librarian.ogg": "",
"lick.ogg": "leccare",
"lid.ogg": "il coperchio",
"lift.ogg": "sollevare i pesi",
"light.ogg": "la luce",
- "lighthouse.ogg": "",
- "lightning.ogg": "",
- "lilac.ogg": "",
"lime.ogg": "il lime",
- "line.ogg": "",
"link.ogg": "l'anello",
- "lion.ogg": "",
- "lion_cub.ogg": "",
"lip.ogg": "le labbra",
- "liquid.ogg": "",
- "lizard.ogg": "",
- "lobster.ogg": "",
"log.ogg": "i ceppi",
"look.ogg": "guardare",
"lunch.ogg": "la merenda",
"mad.ogg": "la follia",
- "magic.ogg": "",
- "magnet.ogg": "",
- "magnifying_glass.ogg": "",
- "magpie.ogg": "",
- "mail.ogg": "",
- "man.ogg": "",
"mane.ogg": "la criniera",
- "mango.ogg": "",
"map.ogg": "la mappa",
- "maple.ogg": "",
- "marble.ogg": "",
- "mashed_potatoes.ogg": "",
"mask.ogg": "la maschera da sub",
- "mast.ogg": "",
"mat.ogg": "il tappetino",
"match.ogg": "i fiammiferi",
- "mate.ogg": "",
- "mattress.ogg": "",
- "mauve.ogg": "",
- "meal.ogg": "",
- "meat.ogg": "",
- "mechanic.ogg": "",
- "medal.ogg": "",
"meet.ogg": "incontrare",
- "melon.ogg": "",
- "men.ogg": "gli uomini",
- "merry-go-round.ogg": "",
"mice.ogg": "i topi",
- "microphone.ogg": "",
- "milk.ogg": "",
- "mill.ogg": "",
- "mimosa.ogg": "",
- "mirror.ogg": "",
- "mixer.ogg": "",
"mole.ogg": "la talpa",
- "mom.ogg": "",
- "moon.ogg": "",
- "moose.ogg": "",
- "mop.ogg": "",
- "mosque.ogg": "",
"mosquito.ogg": "la zanzara",
- "mother.ogg": "",
- "motorcycle.ogg": "",
- "mountain.ogg": "",
- "mouse.ogg": "",
"mouth.ogg": "la bocca",
- "movie.ogg": "",
- "mower.ogg": "",
"mud.ogg": "il fango",
"mug.ogg": "la tazza",
"mule.ogg": "il mulo",
- "muscle.ogg": "",
"mushroom.ogg": "il fungo",
- "music.ogg": "",
- "musician.ogg": "",
- "naked.ogg": "",
"nap.ogg": "pisolare",
- "navel.ogg": "",
"neck.ogg": "il collo",
- "necklace.ogg": "",
- "needle.ogg": "",
"nest.ogg": "il nido",
"net.ogg": "la rete",
- "newspaper.ogg": "",
"night.ogg": "la notte",
- "nightgown.ogg": "",
"nose.ogg": "il naso",
- "nostril.ogg": "",
- "notebook.ogg": "",
- "number.ogg": "",
- "nun.ogg": "",
- "nurse.ogg": "",
- "nurse_male.ogg": "",
"nut.ogg": "l'arachide",
"oar.ogg": "i remi",
"ocean.ogg": "l'oceano",
- "office.ogg": "",
- "olive.ogg": "",
- "on.ogg": "",
- "one.ogg": "uno",
- "onion.ogg": "",
- "open.ogg": "",
- "opossum.ogg": "",
"orange-color.ogg": "arancione",
"orange.ogg": "l'arancio",
- "orchid.ogg": "",
- "ostrich.ogg": "",
- "otter.ogg": "",
"owl.ogg": "il gufo",
"ox.ogg": "il bue",
- "oyster.ogg": "",
- "pacifier.ogg": "",
"page.ogg": "la pagina",
"pair.ogg": "un paio",
- "pajamas.ogg": "",
- "pal.ogg": "",
- "palm_tree.ogg": "",
"pan.ogg": "la padella",
- "panda.ogg": "",
- "panther.ogg": "",
- "panties.ogg": "",
- "pants.ogg": "",
- "papaya.ogg": "",
- "paper.ogg": "",
- "parachute.ogg": "",
- "parakeet.ogg": "",
- "parrot.ogg": "",
"patch.ogg": "la toppa",
"path.ogg": "il sentiero",
- "paw.ogg": "",
- "pea.ogg": "",
"peach.ogg": "la pesca",
- "peacock.ogg": "",
- "peak.ogg": "",
- "pear.ogg": "",
- "pearl.ogg": "",
"peck.ogg": "beccare",
- "pedal.ogg": "",
- "pelican.ogg": "",
"pen.ogg": "la penna",
"pencil.ogg": "la matita",
- "peony.ogg": "",
- "people.ogg": "",
- "pepper.ogg": "",
- "peppers.ogg": "",
- "pet.ogg": "",
- "petal.ogg": "",
- "petite.ogg": "",
- "phone.ogg": "",
- "piano.ogg": "",
"picture.ogg": "il quadro",
- "pie.ogg": "",
"pig.ogg": "il maiale",
- "pigeon.ogg": "",
- "pill.ogg": "",
- "pillow.ogg": "",
- "pilot.ogg": "",
"pine.ogg": "il pino",
- "pine_cone.ogg": "",
"pink.ogg": "rosa",
- "pip.ogg": "",
- "pipe.ogg": "",
- "piranha.ogg": "",
- "pirate.ogg": "",
- "pizza.ogg": "",
"plane.ogg": "l'aeroplano",
- "planet.ogg": "",
"plant.ogg": "la pianta",
"plate.ogg": "il piatto",
"play.ogg": "giocare",
- "pliers.ogg": "",
"plow.ogg": "dissodare",
"plum.ogg": "la prugna",
- "plumber.ogg": "",
- "pocket.ogg": "",
- "pod.ogg": "",
"pole.ogg": "il palo",
- "police.ogg": "",
- "pompon.ogg": "",
- "pond.ogg": "",
- "pony.ogg": "",
"pool.ogg": "la piscina",
- "pop.ogg": "",
"pope.ogg": "il papa",
- "porthole.ogg": "",
- "post.ogg": "",
"pot.ogg": "la pentola",
- "potato.ogg": "",
- "pounce.ogg": "",
- "president.ogg": "",
- "pretty.ogg": "",
"price.ogg": "il prezzo",
- "priest.ogg": "",
"prince.ogg": "il principe",
"princess.ogg": "la principessa",
- "prison.ogg": "",
- "prisoner.ogg": "",
"prize.ogg": "il premio",
- "pug.ogg": "",
- "pull.ogg": "",
- "pullover.ogg": "",
- "pumpkin.ogg": "",
"puppy.ogg": "il cucciolo",
- "pyramid.ogg": "",
"quarrel.ogg": "litigare",
"queen.ogg": "la regina",
"question.ogg": "la domanda",
"quilt.ogg": "la trapunta",
"quiz.ogg": "quiz",
- "rabbit.ogg": "",
- "rabbit_baby.ogg": "",
- "race.ogg": "",
- "radio.ogg": "",
- "radish.ogg": "",
- "raft.ogg": "",
"rag.ogg": "lo strofinaccio",
"rage.ogg": "la rabbia",
- "rain.ogg": "",
- "raincoat.ogg": "",
"rake.ogg": "il rastrello",
"ramp.ogg": "la rampa",
- "ran.ogg": "",
- "raspberry.ogg": "",
"rat.ogg": "il ratto",
- "razor.ogg": "",
"read.ogg": "leggere",
"red.ogg": "rosso",
- "reptile.ogg": "",
- "rhinoceros.ogg": "",
"rice.ogg": "il riso",
"ride.ogg": "andare in bicicletta",
- "rifle.ogg": "",
- "right.ogg": "",
"rip.ogg": "strappato",
- "rise.ogg": "",
- "river.ogg": "",
- "road.ogg": "",
- "roast.ogg": "",
- "robe.ogg": "",
- "robot.ogg": "",
"rock.ogg": "la roccia",
- "rocket.ogg": "",
- "rolling_pin.ogg": "",
"roof.ogg": "il tetto",
- "room.ogg": "",
- "root.ogg": "",
"rope.ogg": "la corda",
"rose.ogg": "la rosa",
- "round.ogg": "",
- "rowing.ogg": "",
- "royal.ogg": "",
"rug.ogg": "il tappeto",
"run.ogg": "corre",
"sad.ogg": "la tristezza",
- "saddle.ogg": "",
"sail.ogg": "la vela",
- "sailor.ogg": "",
- "salamander.ogg": "",
- "salmon.ogg": "",
"sand.ogg": "la sabbia",
- "sandals.ogg": "",
"sandwich.ogg": "il panino",
- "sash.ogg": "",
- "sat.ogg": "",
"sauce.ogg": "la salsa",
- "sausage.ogg": "",
"scale.ogg": "la bilancia",
"scar.ogg": "la cicatrice",
- "scared.ogg": "",
"scarf.ogg": "la sciarpa",
"school.ogg": "la scuola",
- "school_bag.ogg": "",
"science.ogg": "la scienza",
- "scissors.ogg": "",
- "scorpion.ogg": "",
- "scratch.ogg": "",
"scream.ogg": "urlare",
"screw.ogg": "la vite",
- "screwdriver.ogg": "",
"scribble.ogg": "lo scarabocchio",
- "sea.ogg": "",
"seat.ogg": "la sedia a dondolo",
"see.ogg": "vedere",
"seed.ogg": "il seme",
- "shadow.ogg": "",
- "shake.ogg": "",
"shark.ogg": "il pescecane",
- "shave.ogg": "",
- "shed.ogg": "",
- "sheep.ogg": "",
"shelf.ogg": "lo scaffale",
"shell.ogg": "la conchiglia",
"ship.ogg": "la nave",
"shirt.ogg": "la camicia",
"shoe.ogg": "la scarpa",
- "shoelace.ogg": "",
"shop.ogg": "il negozio",
"shore.ogg": "il bagnasciuga",
"short.ogg": "i pantaloni corti",
- "shovel.ogg": "",
"shower.ogg": "la doccia",
"shrimp.ogg": "il gambero",
- "shrub.ogg": "",
- "shut.ogg": "",
- "shutter.ogg": "",
- "sick.ogg": "",
- "sidewalk.ogg": "",
"sign.ogg": "il cartello",
"sing.ogg": "cantare",
"sink.ogg": "il lavandino",
"sip.ogg": "succhiare",
- "sister.ogg": "",
"sit.ogg": "sedere",
"skate.ogg": "pattinare",
- "skeleton.ogg": "",
"ski.ogg": "sciare",
- "skimmer.ogg": "",
"skin.ogg": "la pelle",
"skirt.ogg": "la gonna",
"skunk.ogg": "la puzzola",
"sky.ogg": "il cielo",
- "slam.ogg": "",
"sled.ogg": "la slitta",
"sleep.ogg": "dormire",
"sleeve.ogg": "la manica",
"sleigh.ogg": "la slitta",
"slide.ogg": "lo scivolo",
- "slim.ogg": "",
"slime.ogg": "la bava",
- "slippers.ogg": "",
- "slope.ogg": "",
- "sloppy.ogg": "",
- "slot.ogg": "",
- "sloth.ogg": "",
- "slug.ogg": "",
- "small.ogg": "",
- "smell.ogg": "",
"smile.ogg": "il sorriso",
- "smock.ogg": "",
"smoke.ogg": "il fumo",
- "smooch.ogg": "",
- "snack.ogg": "",
"snail.ogg": "la lumaca",
"snake.ogg": "il serpente",
"sneaker.ogg": "la scarpa da tennis",
"sniff.ogg": "annusare",
"snow.ogg": "la neve",
- "soap.ogg": "",
- "sob.ogg": "",
"sock.ogg": "il calzino",
- "soldier.ogg": "",
- "sole.ogg": "",
- "sole_shoe.ogg": "",
- "son.ogg": "",
- "soup.ogg": "",
- "spade.ogg": "",
"spaghetti.ogg": "gli spaghetti",
- "spark.ogg": "",
- "sparrow.ogg": "",
- "spatula.ogg": "",
- "speak.ogg": "",
"spear.ogg": "la lancia",
- "spice.ogg": "",
"spider.ogg": "il ragno",
- "spider_web.ogg": "",
"spike.ogg": "gli aculei",
- "spill.ogg": "",
- "spinach.ogg": "",
- "spine.ogg": "",
- "spinning_top.ogg": "",
- "splash.ogg": "",
- "splatter.ogg": "",
"sponge.ogg": "la spugna",
- "spool.ogg": "",
"spoon.ogg": "il cucchiaio",
"sport.ogg": "sport",
- "spot.ogg": "",
"spray.ogg": "spruzzare",
"spread.ogg": "spalmare",
- "spring.ogg": "",
- "spring_season.ogg": "",
- "sprinkle.ogg": "",
- "square.ogg": "",
"squash.ogg": "la zucca",
- "squat.ogg": "",
"squid.ogg": "il calamaro",
"squirrel.ogg": "lo scoiattolo",
- "squirt.ogg": "",
"stack.ogg": "una pila",
"stage.ogg": "il palco",
- "staircase.ogg": "",
"stamp.ogg": "il francobollo",
- "stand.ogg": "",
"star.ogg": "la stella",
"stare.ogg": "lo sguardo",
"starfish.ogg": "la stella di mare",
- "steak.ogg": "",
- "steam.ogg": "",
- "steep.ogg": "",
- "steeple.ogg": "",
"stem.ogg": "lo stelo",
- "step.ogg": "",
"stew.ogg": "lo stufato",
- "stick.ogg": "",
"sting.ogg": "pungere",
- "stinky.ogg": "",
- "stitch.ogg": "",
- "stomach.ogg": "",
"stone.ogg": "la pietra",
- "stop.ogg": "",
"store.ogg": "il negozio",
"stove.ogg": "la cucina",
- "straight.ogg": "",
- "strainer.ogg": "",
"straw.ogg": "la cannuccia",
"strawberry.ogg": "la fragola",
"stream.ogg": "il vapore",
"street.ogg": "la via",
- "stretch.ogg": "",
"string.ogg": "lo spago",
- "stripe.ogg": "",
- "strong.ogg": "",
- "student.ogg": "",
"study.ogg": "studiare",
"stump.ogg": "il ceppo",
- "sugar.ogg": "",
"suit.ogg": "l'abito",
- "suitcase.ogg": "",
"summer.ogg": "l'estate",
- "summit.ogg": "",
"sun.ogg": "il sole",
"swan.ogg": "il cigno",
"sweat.ogg": "il sudore",
- "sweatshirt.ogg": "",
"swim.ogg": "nuotare",
- "table.ogg": "",
- "tablecloth.ogg": "",
- "tadpole.ogg": "",
"tag.ogg": "il cartellino",
- "tail.ogg": "",
- "tall.ogg": "",
- "tape_measure.ogg": "",
- "taxi.ogg": "",
"teach.ogg": "insegnare",
"teacher.ogg": "la maestra",
"tear.ogg": "strappare",
- "teddy.ogg": "",
"teeth.ogg": "i denti",
- "television.ogg": "",
- "temple.ogg": "",
- "ten.ogg": "dieci",
- "tennis.ogg": "",
- "tent.ogg": "",
- "text.ogg": "",
- "thick.ogg": "",
- "thief.ogg": "",
"thigh.ogg": "la coscia",
"think.ogg": "pensare",
"thread.ogg": "il filo",
- "three.ogg": "tre",
"throat.ogg": "la gola",
"throw.ogg": "lanciare",
- "thumb.ogg": "",
"tick.ogg": "la zecca",
- "ticket.ogg": "",
- "tiger.ogg": "",
"time.ogg": "il tempo",
- "tin.ogg": "",
- "tire.ogg": "",
- "tired.ogg": "",
- "tissue.ogg": "",
- "toad.ogg": "",
- "toaster.ogg": "",
- "toe.ogg": "",
"toilet.ogg": "il gabinetto",
- "tomatoe.ogg": "",
- "tongs.ogg": "",
- "tongue.ogg": "",
"tool.ogg": "gli attrezzi",
"top.ogg": "la cima",
"torch.ogg": "la torcia",
"touch.ogg": "toccare",
"towel.ogg": "l'asciugamano",
"toy.ogg": "il giocattolo",
- "trail.ogg": "",
"train.ogg": "il treno",
- "train_station.ogg": "",
"trap.ogg": "la trappola",
"trash.ogg": "la spazzatura",
"tray.ogg": "il vassoio",
- "treat.ogg": "",
"tree.ogg": "l'albero",
- "triangle.ogg": "",
- "tribe.ogg": "",
- "trip.ogg": "",
"truck.ogg": "il camion",
"tube.ogg": "il rossetto",
- "tulip.ogg": "",
"tune.ogg": "le note",
- "turkey.ogg": "",
- "turnip.ogg": "",
- "turtle.ogg": "",
- "tusk.ogg": "",
- "twin_boys.ogg": "",
- "twin_girls.ogg": "",
- "two.ogg": "due",
- "umbrella.ogg": "",
- "under.ogg": "",
- "uniform.ogg": "",
- "van.ogg": "",
- "vapor.ogg": "",
- "vase.ogg": "",
- "vegetable.ogg": "",
- "vein.ogg": "",
- "verdure.ogg": "",
- "vest.ogg": "",
"vet.ogg": "il veterinario",
- "viper.ogg": "",
- "vowel.ogg": "",
- "vulture.ogg": "",
- "wag.ogg": "",
"walk.ogg": "camminare",
- "wall.ogg": "",
- "walnut.ogg": "",
- "wart.ogg": "",
- "wash.ogg": "",
- "wasp.ogg": "",
"watch.ogg": "l'orologio da polso",
"water.ogg": "l'acqua",
- "wave.ogg": "",
- "wedding.ogg": "",
"wedge.ogg": "il cuneo",
- "weight.ogg": "",
- "wet.ogg": "",
- "whale.ogg": "",
- "wheat.ogg": "",
"wheel.ogg": "la ruota",
- "whisk.ogg": "",
"whisper.ogg": "sussurrare",
"white.ogg": "bianco",
- "wide.ogg": "",
- "wife.ogg": "",
"wig.ogg": "la parrucca",
- "win.ogg": "",
"wind.ogg": "il vento",
- "window.ogg": "",
- "window_glass.ogg": "",
"wing.ogg": "l'ala",
- "winter.ogg": "",
- "wolf.ogg": "",
- "woman.ogg": "",
"wood.ogg": "il legno",
- "word.ogg": "",
- "worker.ogg": "",
- "world.ogg": "",
- "wreath.ogg": "",
"wrench.ogg": "la chiave inglese",
"wrist.ogg": "il polso",
- "write.ogg": "",
- "yarn.ogg": "",
- "yellow.ogg": "",
- "yogurt.ogg": "",
- "yum.ogg": "",
- "zebra.ogg": "",
- "zipper.ogg": "",
"zoo.ogg": "lo zoo"
-}
+}
\ No newline at end of file
diff --git a/src/activities/lang/resource/content-ja.json b/src/activities/lang/resource/content-ja.json
new file mode 100644
index 000000000..9e26dfeeb
--- /dev/null
+++ b/src/activities/lang/resource/content-ja.json
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/src/activities/lang/resource/content-ml.json b/src/activities/lang/resource/content-ml.json
new file mode 100644
index 000000000..213b6e659
--- /dev/null
+++ b/src/activities/lang/resource/content-ml.json
@@ -0,0 +1,1076 @@
+{
+ "10.ogg": "പത്ത്",
+ "11.ogg": "പതിനൊന്ന്",
+ "12.ogg": "പന്ത്രണ്ട്",
+ "16.ogg": "പതിനാറ്",
+ "U0030.ogg": "പൂജ്യം",
+ "U0031.ogg": "ഒന്ന്",
+ "U0032.ogg": "രണ്ട്",
+ "U0033.ogg": "മൂന്ന്",
+ "U0034.ogg": "നാല്",
+ "U0035.ogg": "അഞ്ച്",
+ "U0036.ogg": "ആറ്",
+ "U0037.ogg": "ഏഴ്",
+ "U0038.ogg": "എട്ട്",
+ "U0039.ogg": "ഒൻപത്",
+ "accountant.ogg": "അക്കൗണ്ടന്റ്",
+ "ache.ogg": "വേദന",
+ "acorn.ogg": "ഓക്ക് കായ",
+ "actor.ogg": "നടൻ",
+ "air_horn.ogg": "എയർ ഹോൺ",
+ "alarmclock.ogg": "അലാറം ക്ലോക്ക്",
+ "alligator.ogg": "ചീങ്കണ്ണി",
+ "alphabet.ogg": "അക്ഷരമാല",
+ "anchor.ogg": "നങ്കൂരം",
+ "angel.ogg": "ദേവത",
+ "angry.ogg": "ദേഷ്യം",
+ "animal.ogg": "മൃഗം",
+ "ankle.ogg": "കണങ്കാൽ",
+ "ant.ogg": "ഉറുമ്പ്",
+ "anteater.ogg": "ഉറുമ്പുതീനി",
+ "antelope.ogg": "കൃഷ്ണമൃഗം",
+ "apple.ogg": "ആപ്പിൾ",
+ "apple_tree.ogg": "ആപ്പിൾ മരം",
+ "appliance.ogg": "യന്ത്രോപകരണം",
+ "apricot.ogg": "ശീമബദാം പഴം",
+ "arm.ogg": "കൈ",
+ "armchair.ogg": "ചാരുകസേര",
+ "artichoke.ogg": "ആർട്ടിചോക്ക്",
+ "artist.ogg": "കലാകാരൻ",
+ "asparagus.ogg": "ശതാവരിച്ചെടി",
+ "astronaut.ogg": "ബഹിരകാശ യാത്രികൻ",
+ "athlete.ogg": "കായികതാരം",
+ "avocado.ogg": "വെണ്ണപ്പഴം",
+ "ax.ogg": "കോടാലി",
+ "baby_bottle.ogg": "പാൽകുപ്പി",
+ "back.ogg": "പുറം",
+ "badge.ogg": "ചിഹ്നം",
+ "bag.ogg": "ബാഗ്",
+ "bait.ogg": "ഇര",
+ "balance.ogg": "തുലാസ്",
+ "bald.ogg": "കഷണ്ടി",
+ "ball.ogg": "പന്ത്",
+ "ball_of_yarn.ogg": "നൂൽപന്ത്",
+ "ball_soccer.ogg": "സോക്കർ പന്ത്",
+ "ballet.ogg": "ബാലെ",
+ "bank.ogg": "ബാങ്ക്",
+ "bark.ogg": "കുരയ്ക്കുക",
+ "barn.ogg": "ധാന്യപ്പുര",
+ "bat.ogg": "വവ്വാൽ",
+ "bath.ogg": "കുളിത്തൊട്ടി",
+ "bathing_suit.ogg": "കുളിക്കാനുള്ള ഉടുപ്പ്",
+ "bay.ogg": "ഉൾക്കടൽ",
+ "beach.ogg": "കടൽത്തീരം",
+ "bean.ogg": "പയർ",
+ "bear.ogg": "കരടി",
+ "beard.ogg": "താടിരോമം",
+ "beat.ogg": "അടിക്കുക",
+ "beaver.ogg": "ബീവർ",
+ "bed.ogg": "കിടക്ക",
+ "bedroom.ogg": "കിടപ്പുമുറി",
+ "bee.ogg": "തേനീച്ച",
+ "beetle.ogg": "വണ്ട്",
+ "beg.ogg": "യാചിക്കുക",
+ "behind.ogg": "പുറകിൽ",
+ "bell.ogg": "മണി",
+ "belly.ogg": "വയർ",
+ "bench.ogg": "ബെഞ്ച്",
+ "bib.ogg": "മാർച്ചട്ട",
+ "big.ogg": "വലിയ",
+ "big_top.ogg": "വലിയ കൂടാരം",
+ "bike.ogg": "സൈക്കിൾ",
+ "bird.ogg": "പക്ഷി",
+ "bit.ogg": "കഷണം",
+ "bite.ogg": "കടിക്കുക",
+ "black.ogg": "കറുപ്പ്",
+ "blackberry.ogg": "ബ്ലാക്ബെറി",
+ "blackbird.ogg": "കരിങ്കുയിൽ",
+ "blade.ogg": "വായ്ത്തല",
+ "blind.ogg": "അന്ധനായ",
+ "blink.ogg": "കണ്ണു ചിമ്മുക",
+ "block.ogg": "കട്ട",
+ "blond.ogg": "ഇളം മഞ്ഞ മുടിയുള്ള",
+ "blue.ogg": "നീല",
+ "blueberry.ogg": "ഞാവൽപഴം",
+ "blush.ogg": "മുഖം ചുവക്കുക",
+ "board.ogg": "പലക",
+ "boat.ogg": "വഞ്ചി",
+ "boil.ogg": "തിളയ്ക്കുക",
+ "bolt.ogg": "ബോൾട്",
+ "bomb.ogg": "ബോംബ്",
+ "bone.ogg": "എല്ല്",
+ "book.ogg": "പുസ്തകം",
+ "bookcase.ogg": "പുസ്തക ഷെൽഫ്",
+ "bottom.ogg": "കീഴ്ഭാഗം",
+ "box.ogg": "പെട്ടി",
+ "boxer.ogg": "മുഷ്ടിയുദ്ധക്കാരൻ",
+ "boy.ogg": "ആൺകുട്ടി",
+ "braid.ogg": "മുടിപ്പിന്നൽ",
+ "brain.ogg": "തലച്ചോറ്",
+ "branch.ogg": "കൊമ്പ്",
+ "bread.ogg": "റൊട്ടി",
+ "break.ogg": "പിളർക്കുക",
+ "breast.ogg": "മുല",
+ "brick.ogg": "ഇഷ്ടിക",
+ "bricklayer.ogg": "കല്ലുപണിക്കാരൻ",
+ "bride.ogg": "വധു",
+ "bridge.ogg": "പാലം",
+ "bright.ogg": "തിളക്കമുള്ള",
+ "broccoli.ogg": "ബ്രോക്കോളി",
+ "brother.ogg": "സഹോദരൻ",
+ "brown.ogg": "തവിട്ട്",
+ "brush.ogg": "ബ്രഷ്",
+ "bubble.ogg": "കുമിള",
+ "bucket.ogg": "ബക്കറ്റ്",
+ "bud.ogg": "മൊട്ട്",
+ "buffalo.ogg": "പോത്ത്",
+ "bug.ogg": "ചെറുപ്രാണി",
+ "bulb.ogg": "ബൾബ്",
+ "bull.ogg": "കാള",
+ "bump.ogg": "മുഴ",
+ "bun.ogg": "ബൺ",
+ "bus.ogg": "ബസ്",
+ "bush.ogg": "കുറ്റിക്കാട്",
+ "butcher.ogg": "കശാപ്പുകാരൻ",
+ "butter.ogg": "വെണ്ണ",
+ "butterfly.ogg": "പൂമ്പാറ്റ",
+ "button.ogg": "കുടുക്ക്",
+ "cabbage.ogg": "കാബേജ്",
+ "cabin.ogg": "ചെറിയമുറി",
+ "cacao.ogg": "കൊക്കോ",
+ "cactus.ogg": "കള്ളിമുൾച്ചെടി",
+ "cage.ogg": "കൂട്",
+ "cake.ogg": "കേക്ക്",
+ "call.ogg": "വിളിക്കുക",
+ "camel.ogg": "ഒട്ടകം",
+ "camera.ogg": "ക്യാമറ",
+ "camp.ogg": "താവളം",
+ "can.ogg": "തകരപ്പാത്രം",
+ "canary.ogg": "മൈനാപ്പക്ഷി",
+ "candle.ogg": "മെഴുകുതിരി",
+ "candy.ogg": "മിഠായി",
+ "cane.ogg": "ചൂരൽവടി",
+ "canoe.ogg": "ചെറുതോണി",
+ "canon.ogg": "പീരങ്കി",
+ "canyon.ogg": "മലയിടുക്ക്",
+ "cap.ogg": "തൊപ്പി",
+ "cape.ogg": "കൈയില്ലാത്ത കുപ്പായം",
+ "car.ogg": "കാർ",
+ "card.ogg": "കാർഡ്",
+ "carnival.ogg": "ഘോഷയാത്ര",
+ "carpenter.ogg": "ആശാരി",
+ "carpet.ogg": "പരവതാനി",
+ "carrot.ogg": "കാരറ്റ്",
+ "cart.ogg": "ഉന്തുവണ്ടി",
+ "cash.ogg": "പണം",
+ "castle.ogg": "മാളിക",
+ "cat.ogg": "പൂച്ച",
+ "cat_female.ogg": "പെൺപൂച്ച",
+ "catch.ogg": "പിടിക്കുക",
+ "caterpillar.ogg": "ചിത്രശലഭപ്പുഴു",
+ "cauldron.ogg": "കുട്ടകം",
+ "cauliflower.ogg": "കോളിഫ്ലവര്‍",
+ "cave.ogg": "മട",
+ "cavern.ogg": "ഗുഹ",
+ "celery.ogg": "സെലറി",
+ "centipede.ogg": "പഴുതാര",
+ "cereal.ogg": "ധാന്യം",
+ "chain.ogg": "ചങ്ങല",
+ "chair.ogg": "കസേര",
+ "chalk.ogg": "ചോക്ക്",
+ "chameleon.ogg": "കമീലിയൊൺ",
+ "chandelier.ogg": "ബഹുശാഖദീപം",
+ "chat.ogg": "സല്ലപിക്കുക",
+ "cheek.ogg": "കവിള്‍ത്തടം",
+ "cheer.ogg": "ഉത്സാഹം",
+ "cheese.ogg": "ചീസ്",
+ "chef.ogg": "പ്രധാന പാചകക്കാരൻ",
+ "cherry.ogg": "ചെറി",
+ "chest.ogg": "പെട്ടകം",
+ "chick.ogg": "കോഴിക്കുഞ്ഞ്",
+ "chicken.ogg": "കോഴി",
+ "child.ogg": "കുട്ടി",
+ "chimney.ogg": "ചിമ്മിനി",
+ "chimp.ogg": "ആൾക്കുരങ്ങ്",
+ "chin.ogg": "താടി",
+ "chocolate.ogg": "ചോക്കലേറ്റ്‌",
+ "chop.ogg": "കഷണങ്ങളാക്കുക",
+ "christmas.ogg": "ക്രിസ്‌തുമസ്‌",
+ "cigar.ogg": "ചുരുട്ട്",
+ "circus.ogg": "സർക്കസ്സ്",
+ "city.ogg": "നഗരം",
+ "clam.ogg": "കക്ക",
+ "clap.ogg": "കൈയടിക്കുക",
+ "class.ogg": "ക്ലാസ്സ്",
+ "claw.ogg": "കൂർത്ത കാൽനഖം",
+ "clay.ogg": "കളിമണ്ണ്",
+ "clean.ogg": "വൃത്തിയാക്കുക",
+ "cleaning_lady.ogg": "വൃത്തിയാക്കുന്ന സ്ത്രീ",
+ "cliff.ogg": "തൂക്കാംപാറ",
+ "climb.ogg": "കയറുക",
+ "clock.ogg": "ഘടികാരം",
+ "cloth.ogg": "തുണി",
+ "clothes_hanger.ogg": "വസ്ത്രം തൂക്കിയിടുന്ന കൊളുത്ത്",
+ "cloud.ogg": "മേഘം",
+ "cloudy.ogg": "മേഘാവൃതം",
+ "clover.ogg": "ത്രിപത്രി",
+ "clown.ogg": "കോമാളി",
+ "coach.ogg": "പരിശീലക",
+ "coast.ogg": "തീരം",
+ "coat.ogg": "പുറങ്കുപ്പായം",
+ "cobra.ogg": "മൂർഖൻ പാമ്പ്",
+ "coconut.ogg": "തേങ്ങ",
+ "cod.ogg": "കോഡ്മത്സ്യം",
+ "coffee.ogg": "കാപ്പി",
+ "coin.ogg": "നാണയം",
+ "cold.ogg": "തണുപ്പ്",
+ "color.ogg": "നിറം",
+ "colt.ogg": "കുട്ടിക്കുതിര",
+ "comb.ogg": "ചീപ്പ്",
+ "cone.ogg": "കോൺ",
+ "cook.ogg": "പാചകം ചെയ്യുക",
+ "cookie.ogg": "കുക്കി",
+ "cork.ogg": "കോർക്ക്",
+ "corn.ogg": "ചോളം",
+ "couch.ogg": "സോഫ",
+ "cough.ogg": "ചുമയ്ക്കുക",
+ "couple.ogg": "ഇണ",
+ "cow.ogg": "പശു",
+ "cowboy.ogg": "കൗബോയ്",
+ "crab.ogg": "ഞണ്ട്",
+ "cradle.ogg": "തൊട്ടിൽ",
+ "craft.ogg": "കരകൗശലം",
+ "crawl.ogg": "ഇഴയുക",
+ "crazy.ogg": "ഭ്രാന്തുള്ള",
+ "creek.ogg": "അരുവി",
+ "crepe.ogg": "ക്രേയ്പ്",
+ "crib.ogg": "കൊച്ചുകുട്ടികള്‍ക്കുള്ള അഴിക്കട്ടില്‍",
+ "croak.ogg": "തവള കരയുക",
+ "crocodile.ogg": "മുതല",
+ "cross.ogg": "കുരിശ്",
+ "crow.ogg": "കാക്ക",
+ "crown.ogg": "കിരീടം",
+ "crumb.ogg": "നുറുക്ക്",
+ "crust.ogg": "പുറംപാളി",
+ "cry.ogg": "കരയുക",
+ "crystal.ogg": "സ്‌ഫടികം",
+ "cube.ogg": "സമചതുരക്കട്ട",
+ "cucumber.ogg": "വെള്ളരിക്ക",
+ "curtain.ogg": "ജനല്‍മറ",
+ "cut.ogg": "വെട്ടുക",
+ "cute.ogg": "ഭംഗിയുള്ള",
+ "dad.ogg": "അച്ഛൻ",
+ "daffodil.ogg": "ഡാഫോഡിൽ",
+ "daisy.ogg": "ഡെയ്സിച്ചെടി",
+ "dam.ogg": "അണക്കെട്ട്",
+ "dance.ogg": "നൃത്തം",
+ "dandelion.ogg": "ജമന്തി",
+ "dart_board.ogg": "ഡാർട്ട് ബോർഡ്",
+ "date_fruit.ogg": "ഈത്തപ്പഴം",
+ "deer.ogg": "മാൻ",
+ "den.ogg": "ഗര്‍ത്തം",
+ "desert.ogg": "മരുഭൂമി",
+ "desk.ogg": "എഴുത്തുമേശ",
+ "dessert.ogg": "മധുരപലഹാരം",
+ "diamond.ogg": "വജ്രം",
+ "dig.ogg": "കുഴിയ്ക്കുക",
+ "dirt.ogg": "ചേറ്",
+ "dirty.ogg": "അഴുക്കുപുരണ്ട",
+ "dish.ogg": "പാത്രം",
+ "dive.ogg": "മുങ്ങല്‍",
+ "doctor.ogg": "ഡോക്‌ടര്‍",
+ "doe.ogg": "മാന്‍പേട",
+ "dog.ogg": "പട്ടി",
+ "doll.ogg": "പാവ",
+ "dolphin.ogg": "ഡോൾഫിൻ",
+ "domino.ogg": "ഡൊമിനൊ",
+ "door.ogg": "വാതിൽ",
+ "dot.ogg": "കുത്ത്",
+ "doughnut.ogg": "ഡോനട്ട്‌",
+ "dove.ogg": "പ്രാവ്",
+ "dragon.ogg": "വ്യാളി",
+ "dragonfly.ogg": "തുമ്പി",
+ "draw.ogg": "വരയ്ക്കുക",
+ "drawer.ogg": "വലിപ്പ്",
+ "dream.ogg": "സ്വപ്നം കാണുക",
+ "dress.ogg": "വസ്‌ത്രം",
+ "drink.ogg": "കുടിക്കുക",
+ "drip.ogg": "തുള്ളി",
+ "drive.ogg": "ഓടിക്കുക",
+ "drool.ogg": "തുപ്പലൊലിക്കുക",
+ "drum.ogg": "ഡ്രം",
+ "dry.ogg": "ഉണക്കുക",
+ "duck.ogg": "താറാവ്",
+ "duck_mother.ogg": "അമ്മത്താറാവ്",
+ "dune.ogg": "മണല്‍ക്കൂന",
+ "dwarf.ogg": "കുള്ളന്‍",
+ "eagle.ogg": "പരുന്ത്",
+ "ear.ogg": "ചെവി",
+ "earth.ogg": "ഭൂമി",
+ "eat.ogg": "തിന്നുക",
+ "egg.ogg": "മുട്ട",
+ "eggplant.ogg": "വഴുതന",
+ "elbow.ogg": "കൈമുട്ട്",
+ "electrician.ogg": "ഇലക്ട്രീഷ്യൻ",
+ "elk.ogg": "എൽക്",
+ "empty.ogg": "ഒഴിഞ്ഞ",
+ "engine.ogg": "എന്‍ജിന്‍",
+ "engineer.ogg": "എന്‍ജിനീയര്‍",
+ "eraser.ogg": "ഇറേസർ",
+ "explore.ogg": "ദേശപര്യവേഷകന്‍",
+ "eyelash.ogg": "കണ്‍പീലി",
+ "eyes.ogg": "കണ്ണുകൾ",
+ "face.ogg": "മുഖം",
+ "fair.ogg": "മേള",
+ "fairy.ogg": "മാലാഖ",
+ "fall.ogg": "വീഴുക",
+ "fall_season.ogg": "ഇല പൊഴിയും കാലം",
+ "family.ogg": "കുടുംബം",
+ "fan.ogg": "ഫാൻ",
+ "farm.ogg": "കൃഷിഭൂമി",
+ "farmer.ogg": "കർഷകൻ",
+ "fat.ogg": "തടിയുള്ള",
+ "faucet.ogg": "കുഴലടപ്പ് ",
+ "fawn.ogg": "മാന്‍കുട്ടി",
+ "fear.ogg": "പേടി",
+ "feast.ogg": "വിരുന്നൂണ്",
+ "feather.ogg": "തൂവൽ",
+ "feed.ogg": "ഭക്ഷണം നൽകുക",
+ "femur.ogg": "തുടയെല്ല്‌",
+ "fetch.ogg": "കൊണ്ടുവരിക",
+ "fig.ogg": "അത്തിപ്പഴം",
+ "fin.ogg": "മീന്‍ചിറക്‌",
+ "find.ogg": "കണ്ടെത്തുക",
+ "finger.ogg": "വിരൽ",
+ "fire.ogg": "തീ",
+ "fire_extinguisher.ogg": "അഗ്നിശമനോപകരണം",
+ "fireman.ogg": "അഗ്നിശമനസേനാംഗം",
+ "fish.ogg": "മീൻ",
+ "fisherman.ogg": "മീൻപിടുത്തക്കാരൻ",
+ "fist.ogg": "മുഷ്‌ടി",
+ "flag.ogg": "പതാക",
+ "flame.ogg": "തീജ്വാല",
+ "flamingo.ogg": "ഫ്ലമിംഗൊ",
+ "flash.ogg": "ഫ്ലാഷ്",
+ "flat.ogg": "ഫ്ലാറ്റ്‌",
+ "flies.ogg": "ഈച്ച",
+ "float.ogg": "പൊങ്ങിക്കിടക്കുക",
+ "flour.ogg": "ധാന്യപ്പൊടി",
+ "flower.ogg": "പൂവ്",
+ "fluff.ogg": "മൃദുരോമം",
+ "flute.ogg": "ഓടക്കുഴൽ",
+ "fly.ogg": "പറക്കുക",
+ "foam.ogg": "പത",
+ "foot.ogg": "കാൽപാദം",
+ "forest.ogg": "കാട്",
+ "fork.ogg": "മുള്ളുകരണ്ടി",
+ "fountain.ogg": "ഫൗണ്ടെൻ",
+ "fox.ogg": "കുറുക്കന്‍",
+ "freeze.ogg": "മരവിക്കുക",
+ "friend.ogg": "സുഹൃത്ത്",
+ "fries.ogg": "വറുത്തത്",
+ "frog.ogg": "തവള",
+ "front.ogg": "മുമ്പിൽ",
+ "fruit.ogg": "പഴം",
+ "fudge.ogg": "ഫജ്",
+ "full.ogg": "നിറഞ്ഞ",
+ "fur.ogg": "ചെറുമൃദുരോമം",
+ "game.ogg": "കളി",
+ "garage.ogg": "ഗ്യാരേജ്",
+ "garden.ogg": "പൂന്തോട്ടം",
+ "garlic.ogg": "വെളുത്തുള്ളി",
+ "gem.ogg": "രത്നക്കല്ല്",
+ "giant.ogg": "ഭീമമായ",
+ "gift.ogg": "സമ്മാനം",
+ "giraffe.ogg": "ജിറാഫ്",
+ "girl.ogg": "പെൺകുട്ടി",
+ "glass.ogg": "ഗ്ലാസ്സ്‌",
+ "glasses.ogg": "കണ്ണട",
+ "glove.ogg": "കയ്യുറ",
+ "glue.ogg": "പശ",
+ "gnome.ogg": "ഗ്നോം",
+ "goat.ogg": "ആട്",
+ "golden.ogg": "സുവര്‍ണ്ണമായ",
+ "golf.ogg": "ഗോള്‍ഫ്‌",
+ "goose.ogg": "വാത്ത്",
+ "gorilla.ogg": "ഗോറില്ല",
+ "grain.ogg": "ധാന്യം",
+ "grandmother.ogg": "മുത്തശ്ശി",
+ "grape.ogg": "മുന്തിരിങ്ങ",
+ "grapefruit.ogg": "ചെറുമധുരനാരങ്ങ",
+ "grass.ogg": "പുല്ല്",
+ "grave.ogg": "കുഴിമാടം",
+ "gray.ogg": "ചാരനിറം",
+ "green.ogg": "പച്ചനിറം",
+ "grill.ogg": "ഗ്രിൽ",
+ "grin.ogg": "ഇളിപ്പ്",
+ "ground.ogg": "നിലം",
+ "growl.ogg": "മുരളുക",
+ "guignol.ogg": "ഗിന്യോൾ",
+ "guinea_pig.ogg": "ഗിനി പന്നി",
+ "gum.ogg": "ഗം",
+ "hair.ogg": "തലമുടി",
+ "hair_dryer.ogg": "ഹെയർ ഡ്രയർ",
+ "half.ogg": "പകുതി",
+ "ham.ogg": "പന്നിത്തുടയിറച്ചി",
+ "hamburger.ogg": "ഹാംബർഗർ",
+ "hammer.ogg": "ചുറ്റിക",
+ "hand.ogg": "കൈപ്പത്തി",
+ "handlebar.ogg": "ഹാൻഡിൽബാർ",
+ "happy.ogg": "സന്തുഷ്ടമായ",
+ "harp.ogg": "ഹാർപ്പ്",
+ "hat.ogg": "തൊപ്പി",
+ "hatch.ogg": "മുട്ട വിരിയുക",
+ "hay.ogg": "വൈക്കോല്‍",
+ "head.ogg": "തല",
+ "hear.ogg": "കേൾക്കുക",
+ "heat.ogg": "ചൂട്",
+ "hedge.ogg": "കുറ്റിച്ചെടി വേലി",
+ "hedgehog.ogg": "മുള്ളൻപന്നി",
+ "heel.ogg": "ഹീൽ",
+ "helmet.ogg": "ഹെല്‍മറ്റ്‌",
+ "hen.ogg": "പിടക്കോഴി",
+ "herd.ogg": "നാല്‍ക്കാലിക്കൂട്ടം",
+ "high.ogg": "ഉയർന്ന",
+ "hike.ogg": "കാൽനടയാത്ര",
+ "hill.ogg": "കുന്ന്",
+ "hip.ogg": "ഇടുപ്പ്",
+ "hippopotamus.ogg": "ഹിപ്പൊപ്പൊട്ടാമസ്‌",
+ "hit.ogg": "ഇടി",
+ "hive.ogg": "തേനീച്ചക്കൂട്‌",
+ "hockey.ogg": "ഹോക്കിക്കളി",
+ "hole.ogg": "മാളം",
+ "home.ogg": "പാർപ്പിടം",
+ "hook.ogg": "കൊളുത്ത്‌",
+ "hop.ogg": "ചാട്ടം",
+ "horse.ogg": "കുതിര",
+ "hose.ogg": "ഹോസ്",
+ "hospital.ogg": "ആശുപത്രി",
+ "hot.ogg": "ചൂടുള്ള",
+ "hot_dog.ogg": "ഹോട്ട്‌ ഡോഗ്‌",
+ "hound.ogg": "വേട്ടനായ്‌",
+ "house.ogg": "വീട്",
+ "howl.ogg": "ഓരിയിടുക",
+ "hug.ogg": "കെട്ടിപ്പിടിക്കുക",
+ "huge.ogg": "വളരെ വലിയ",
+ "hummingbird.ogg": "ഹമ്മിങ്ബേർഡ്",
+ "hunchbacked.ogg": "കൂനുള്ള",
+ "hunter.ogg": "വേട്ടക്കാരൻ",
+ "husband.ogg": "ഭർത്താവ്",
+ "hut.ogg": "കുടിൽ",
+ "hyena.ogg": "കഴുതപ്പുലി",
+ "ice.ogg": "മഞ്ഞുകട്ടി",
+ "iceberg.ogg": "മഞ്ഞുമല",
+ "iguana.ogg": "ഉടുമ്പ്‌",
+ "ill.ogg": "അസുഖം പിടിച്ച",
+ "ink.ogg": "മഷി",
+ "island.ogg": "ദ്വീപ്",
+ "jacket.ogg": "റൗക്ക",
+ "jaguar.ogg": "ജാഗ്വാർ",
+ "jam.ogg": "ജാം",
+ "jay.ogg": "സ്വര്‍ണ്ണചൂഡപ്പക്ഷി",
+ "jelly.ogg": "ജെല്ലി",
+ "jellyfish.ogg": "കടൽച്ചൊറി",
+ "jewel.ogg": "രത്‌നം",
+ "job.ogg": "ജോലി",
+ "jockey.ogg": "കുതിര സവാരിക്കാരൻ",
+ "jog.ogg": "വ്യായാമ ഓട്ടം",
+ "joy.ogg": "സന്തോഷം",
+ "judge.ogg": "ന്യായാധിപന്‍",
+ "judo.ogg": "ജൂഡോ",
+ "juggler.ogg": "അമ്മാനമാട്ടുന്നയാള്‍",
+ "juice.ogg": "പഴച്ചാറ്‌",
+ "jump.ogg": "ചാടുക",
+ "kangaroo.ogg": "കങ്കാരു",
+ "kernel.ogg": "പരിപ്പ്",
+ "keyboard.ogg": "കീബോർഡ്",
+ "kimono.ogg": "കിമോണോ",
+ "king.ogg": "രാജാവ്",
+ "kiss.ogg": "ചുംബിക്കുക",
+ "kitchen.ogg": "അടുക്കള",
+ "kite.ogg": "പട്ടം",
+ "kitten.ogg": "പൂച്ചക്കുട്ടി",
+ "kiwi.ogg": "കിവി",
+ "knee.ogg": "കാല്‍മുട്ട്‌",
+ "kneel.ogg": "മുട്ടുകുത്തുക",
+ "knife.ogg": "കത്തി",
+ "knight.ogg": "യോദ്ധാവ്‌",
+ "knit.ogg": "തുന്നിച്ചേർക്കുക",
+ "knot.ogg": "കെട്ട്",
+ "koala.ogg": "കൊയാല",
+ "lad.ogg": "ചെറുക്കന്‍",
+ "ladybug.ogg": "പൊന്നാമ",
+ "lake.ogg": "തടാകം",
+ "lama.ogg": "ല്ലാമ",
+ "lamb.ogg": "ചെമ്മരിയാട്ടിന്‍കുട്ടി",
+ "lamp.ogg": "വൈദ്യുതവിളക്ക്",
+ "land.ogg": "കര",
+ "lane.ogg": "ഇടവഴി",
+ "lap.ogg": "മടിത്തട്ട്‌",
+ "lasso.ogg": "ഊരാക്കുടുക്കുള്ള കയര്‍",
+ "laugh.ogg": "ചിരിക്കുക",
+ "lava.ogg": "ലാവ",
+ "lawn.ogg": "പച്ചപ്പുല്‍ത്തകിട്‌",
+ "lawyer.ogg": "അഭിഭാഷകന്‍",
+ "leaf.ogg": "ഇല",
+ "ledge.ogg": "ഉന്തിയപാറ",
+ "leek.ogg": "ലീക്ക്",
+ "left.ogg": "ഇടതുഭാഗം",
+ "leg.ogg": "കാൽ",
+ "lemon.ogg": "മഞ്ഞ ചെറുനാരങ്ങ",
+ "lemonade.ogg": "നാരങ്ങാവെള്ളം",
+ "lemur.ogg": "ലീമർ",
+ "leopard.ogg": "പുളളിപ്പുലി",
+ "lettuce.ogg": "പച്ചടിച്ചീര",
+ "librarian.ogg": "ലൈബ്രേറിയൻ",
+ "lick.ogg": "നക്കുക",
+ "lid.ogg": "അടപ്പ്",
+ "lift.ogg": "ഭാരമുയർത്തുക",
+ "light.ogg": "വെളിച്ചം",
+ "lighthouse.ogg": "വിളക്കുമാടം",
+ "lightning.ogg": "മിന്നൽ",
+ "lilac.ogg": "വയമ്പുചെടി",
+ "lime.ogg": "ചെറുനാരങ്ങ",
+ "line.ogg": "വര",
+ "link.ogg": "ചങ്ങലക്കണ്ണി",
+ "lion.ogg": "സിംഹം",
+ "lion_cub.ogg": "സിംഹക്കുട്ടി",
+ "lip.ogg": "ചുണ്ട്",
+ "liquid.ogg": "ദ്രാവകം",
+ "lizard.ogg": "പല്ലി",
+ "lobster.ogg": "കൊഞ്ച്‌",
+ "log.ogg": "മരത്തടി",
+ "look.ogg": "നോക്കുക",
+ "lunch.ogg": "ഉച്ചയൂണ്",
+ "mad.ogg": "ഭ്രാന്ത്",
+ "magic.ogg": "ജാലവിദ്യ",
+ "magnet.ogg": "കാന്തം",
+ "magnifying_glass.ogg": "ഭൂതക്കണ്ണാടി",
+ "magpie.ogg": "മാഗ്പൈ",
+ "mail.ogg": "കത്ത്",
+ "man.ogg": "പുരുഷൻ",
+ "mane.ogg": "സട",
+ "mango.ogg": "മാങ്ങ",
+ "map.ogg": "ഭൂപടം",
+ "maple.ogg": "മേപ്പിൾ",
+ "marble.ogg": "ഗോലി",
+ "mashed_potatoes.ogg": "ഉരുളക്കിഴങ്ങ് ഉടച്ചത്",
+ "mask.ogg": "മുഖംമൂടി",
+ "mast.ogg": "പായ്‌മരം",
+ "mat.ogg": "പായ്‌",
+ "match.ogg": "തീപ്പെട്ടിക്കൊള്ളി",
+ "mate.ogg": "ഇണ",
+ "mattress.ogg": "കിടക്ക",
+ "mauve.ogg": "മോവു നിറം",
+ "meal.ogg": "ഒരു നേരത്തെ ഭക്ഷണം",
+ "meat.ogg": "ഇറച്ചി",
+ "mechanic.ogg": "യന്ത്രപ്പണിക്കാരന്‍",
+ "medal.ogg": "മെഡൽ",
+ "meet.ogg": "കണ്ടുമുട്ടുക",
+ "melon.ogg": "മത്തൻ",
+ "merry-go-round.ogg": "ആട്ടത്തൊട്ടിൽ",
+ "mice.ogg": "ചുണ്ടെലികള്‍",
+ "microphone.ogg": "മൈക്രോഫോൺ",
+ "milk.ogg": "പാൽ",
+ "mill.ogg": "കാറ്റാടിമില്ല്‌",
+ "mimosa.ogg": "മഞ്ഞ തൊട്ടാവാടി",
+ "mirror.ogg": "കണ്ണാടി",
+ "mixer.ogg": "മിക്സർ",
+ "mole.ogg": "തുരപ്പനെലി",
+ "moon.ogg": "ചന്ദ്രന്‍",
+ "moose.ogg": "കടമാന്‍",
+ "mop.ogg": "മോപ്പ്",
+ "mosque.ogg": "മുസ്ലീംപള്ളി",
+ "mosquito.ogg": "കൊതുക്",
+ "mother.ogg": "അമ്മ",
+ "motorcycle.ogg": "മോട്ടോർ സൈക്കിൾ",
+ "mountain.ogg": "പര്‍വ്വതം",
+ "mouse.ogg": "ചുണ്ടെലി",
+ "mouth.ogg": "വായ",
+ "movie.ogg": "ചലച്ചിത്രം",
+ "mower.ogg": "പുല്ലരിയുന്ന യന്ത്രം",
+ "mud.ogg": "ചെളി",
+ "mule.ogg": "കോവര്‍കഴുത",
+ "muscle.ogg": "മാംസപേശി",
+ "mushroom.ogg": "കൂൺ",
+ "music.ogg": "സംഗീതം",
+ "musician.ogg": "സംഗീതജ്ഞന്‍",
+ "naked.ogg": "നഗ്നമായ",
+ "nap.ogg": "മയങ്ങുക",
+ "navel.ogg": "പൊക്കിള്‍",
+ "neck.ogg": "കഴുത്ത്",
+ "necklace.ogg": "മാല",
+ "needle.ogg": "സൂചി",
+ "nest.ogg": "കൂട്",
+ "net.ogg": "വല",
+ "newspaper.ogg": "പത്രം",
+ "night.ogg": "രാത്രി",
+ "nightgown.ogg": "രാത്രിവസ്‌ത്രം",
+ "nose.ogg": "മൂക്ക്",
+ "nostril.ogg": "മൂക്കിൻ്റെ ദ്വാരം",
+ "notebook.ogg": "നോട്ടുപുസ്തകം",
+ "number.ogg": "സംഖ്യ",
+ "nun.ogg": "കന്യാസ്‌ത്രീ",
+ "nurse.ogg": "നഴ്സ്",
+ "nut.ogg": "കായ്‌",
+ "oar.ogg": "തുഴ",
+ "ocean.ogg": "മഹാസമുദ്രം",
+ "office.ogg": "ഓഫീസ്",
+ "olive.ogg": "ഒലീവ്‌",
+ "on.ogg": "മുകളിൽ",
+ "onion.ogg": "ഉള്ളി",
+ "open.ogg": "തുറന്നിരിക്കുന്ന",
+ "opossum.ogg": "ഒപ്പോസം",
+ "orange-color.ogg": "ഓറഞ്ച് നിറം",
+ "orange.ogg": "ഓറഞ്ച്",
+ "orchid.ogg": "ഓർക്കിഡ്",
+ "ostrich.ogg": "ഒട്ടകപ്പക്ഷി",
+ "otter.ogg": "നീര്‍നായ്",
+ "owl.ogg": "മൂങ്ങ",
+ "ox.ogg": "കാള",
+ "oyster.ogg": "മുത്തുച്ചിപ്പി",
+ "page.ogg": "താൾ",
+ "pair.ogg": "ജോടി",
+ "pajamas.ogg": "പൈജാമ",
+ "pal.ogg": "ചങ്ങാതി",
+ "palm_tree.ogg": "പന",
+ "pan.ogg": "ചട്ടി",
+ "panda.ogg": "പാണ്ട",
+ "panther.ogg": "കരിംപുലി",
+ "panties.ogg": "സ്ത്രീകളുടെ അടിവസ്ത്രം",
+ "pants.ogg": "പാൻ്റ്സ്",
+ "papaya.ogg": "പപ്പായ",
+ "paper.ogg": "കടലാസ്",
+ "parachute.ogg": "പാരച്യൂട്ട്",
+ "parakeet.ogg": "പാരക്കീറ്റ്",
+ "parrot.ogg": "തത്ത",
+ "patch.ogg": "തുണിത്തുണ്ട്",
+ "path.ogg": "വഴി",
+ "paw.ogg": "നഖമുള്ള മൃഗപാദം",
+ "pea.ogg": "പയര്‍",
+ "peach.ogg": "പീച്ച്‌പഴം",
+ "peacock.ogg": "മയിൽ",
+ "peak.ogg": "പര്‍വ്വതശിഖരം",
+ "pear.ogg": "സബർജില്ലി",
+ "pearl.ogg": "മുത്ത്",
+ "peck.ogg": "കൊത്തിത്തിന്നുക",
+ "pedal.ogg": "പെഡൽ",
+ "pelican.ogg": "ഞാറപ്പക്ഷി",
+ "pen.ogg": "പേന",
+ "pencil.ogg": "പെൻസിൽ",
+ "peony.ogg": "പിയോനി",
+ "people.ogg": "ജനങ്ങൾ",
+ "pepper.ogg": "കുരുമുളക്",
+ "peppers.ogg": "മുളക്",
+ "pet.ogg": "വളർത്തുമൃഗം",
+ "petal.ogg": "ഇതൾ",
+ "phone.ogg": "ഫോൺ",
+ "piano.ogg": "പിയാനോ",
+ "picture.ogg": "ചിത്രം",
+ "pie.ogg": "പൈ",
+ "pig.ogg": "പന്നി",
+ "pigeon.ogg": "മാടപ്രാവ്",
+ "pill.ogg": "ഗുളിക",
+ "pillow.ogg": "തലയണ",
+ "pilot.ogg": "പൈലറ്റ്",
+ "pine.ogg": "പൈൻ",
+ "pine_cone.ogg": "പൈൻ കോൺ",
+ "pink.ogg": "പിങ്ക്",
+ "pip.ogg": "കുരു",
+ "pipe.ogg": "പുകവലിക്കുഴൽ",
+ "piranha.ogg": "പിറാന",
+ "pirate.ogg": "കടൽക്കൊള്ളക്കാരൻ",
+ "pizza.ogg": "പിസ്സ",
+ "plane.ogg": "വിമാനം",
+ "planet.ogg": "ഗ്രഹം",
+ "plant.ogg": "സസ്യം",
+ "plate.ogg": "പിഞ്ഞാണം",
+ "play.ogg": "കളിക്കുക",
+ "pliers.ogg": "ചെറുകൊടിൽ",
+ "plow.ogg": "ഉഴുതു മറിക്കുക",
+ "plum.ogg": "പ്ലം",
+ "plumber.ogg": "കുഴൽപണിക്കാരൻ",
+ "pocket.ogg": "കീശ",
+ "pod.ogg": "വിത്തുറ",
+ "pole.ogg": "കഴുക്കോൽ",
+ "police.ogg": "പോലീസ്",
+ "pond.ogg": "കുളം",
+ "pony.ogg": "ചെറുകുതിര",
+ "pool.ogg": "നീന്തൽക്കുളം",
+ "popcorn.ogg": "ചോളപ്പൊരി",
+ "pope.ogg": "മാർപാപ്പ",
+ "porthole.ogg": "കപ്പൽ ദ്വാരം",
+ "post.ogg": "തപാൽ പെട്ടി",
+ "pot.ogg": "കലം",
+ "potato.ogg": "ഉരുളക്കിഴങ്ങ്",
+ "pounce.ogg": "ചാടിവീഴുക",
+ "president.ogg": "രാഷ്ട്രപതി",
+ "pretty.ogg": "ചന്തമുള്ള",
+ "price.ogg": "വില",
+ "priest.ogg": "പുരോഹിതൻ",
+ "prince.ogg": "രാജകുമാരൻ",
+ "princess.ogg": "രാജകുമാരി",
+ "prison.ogg": "ജയിൽ",
+ "prisoner.ogg": "ജയിൽപ്പുള്ളി",
+ "prize.ogg": "പുരസ്കാരം",
+ "pug.ogg": "പഗ്",
+ "pull.ogg": "വലിക്കുക",
+ "pumpkin.ogg": "മത്തങ്ങ",
+ "puppy.ogg": "പട്ടിക്കുട്ടി",
+ "pyramid.ogg": "പിരമിഡ്",
+ "quarrel.ogg": "വഴക്കിടുക",
+ "queen.ogg": "രാജ്ഞി",
+ "question.ogg": "ചോദ്യം",
+ "quilt.ogg": "മെത്തവിരിപ്പ്",
+ "quiz.ogg": "പ്രശ്നോത്തരി",
+ "rabbit.ogg": "മുയൽ",
+ "rabbit_baby.ogg": "മുയൽ കുഞ്ഞ്",
+ "race.ogg": "വേഗതമത്സരം",
+ "radio.ogg": "റേഡിയോ",
+ "radish.ogg": "മുള്ളങ്കിക്കിഴങ്ങ്",
+ "raft.ogg": "ചങ്ങാടം",
+ "rag.ogg": "തുണിക്കഷ്ണം",
+ "rage.ogg": "രോഷം",
+ "rain.ogg": "മഴ",
+ "raincoat.ogg": "മഴക്കോട്ട്",
+ "rake.ogg": "വാരുകോൽ",
+ "ramp.ogg": "റാംപ്",
+ "ran.ogg": "ഓട്ടം",
+ "raspberry.ogg": "റാസ്ബെറി",
+ "rat.ogg": "എലി",
+ "razor.ogg": "ക്ഷൗരക്കത്തി",
+ "read.ogg": "വായിക്കുക",
+ "red.ogg": "ചുവപ്പ്",
+ "reptile.ogg": "ഇഴജന്തു",
+ "rhinoceros.ogg": "കണ്ടാമൃഗം",
+ "rice.ogg": "അരി",
+ "ride.ogg": "സവാരി",
+ "rifle.ogg": "കൈത്തോക്ക്",
+ "right.ogg": "വലതുഭാഗം",
+ "rip.ogg": "പറിച്ചെടുക്കുക",
+ "rise.ogg": "കൂടുക",
+ "river.ogg": "പുഴ",
+ "road.ogg": "റോഡ്",
+ "roast.ogg": "പൊരിച്ച ഇറച്ചി",
+ "robe.ogg": "മേലങ്കി",
+ "robot.ogg": "യന്ത്രമനുഷ്യൻ",
+ "rock.ogg": "പാറ",
+ "rocket.ogg": "റോക്കറ്റ്",
+ "rolling_pin.ogg": "മാവുപരത്തി",
+ "roof.ogg": "മേൽക്കൂര",
+ "room.ogg": "മുറി",
+ "root.ogg": "വേര്",
+ "rope.ogg": "കയർ",
+ "rose.ogg": "പനിനീർച്ചെടി",
+ "round.ogg": "വട്ടം",
+ "rowing.ogg": "തുഴയൽ",
+ "royal.ogg": "രാജകീയമായ",
+ "rug.ogg": "ചവിട്ടു മെത്ത",
+ "run.ogg": "ഓടുക",
+ "sad.ogg": "സങ്കടം",
+ "saddle.ogg": "കുതിരച്ചേണം",
+ "sail.ogg": "ജലയാത്ര",
+ "sailor.ogg": "നാവികൻ",
+ "salamander.ogg": "അരണ",
+ "salmon.ogg": "കോരമീൻ",
+ "sand.ogg": "മണൽ",
+ "sandals.ogg": "പാദരക്ഷ",
+ "sandwich.ogg": "സാൻഡ്വിച്ച്",
+ "sash.ogg": "അരക്കച്ച",
+ "sauce.ogg": "സോസ്",
+ "sausage.ogg": "സോസേജ്",
+ "scale.ogg": "തുലാസ്",
+ "scar.ogg": "പാട്",
+ "scare.ogg": "പേടിപ്പിക്കുക",
+ "scarf.ogg": "സ്കാർഫ്",
+ "school.ogg": "സ്കൂൾ",
+ "school_bag.ogg": "സ്കൂൾ ബാഗ്",
+ "science.ogg": "ശാസ്ത്രം",
+ "scissors.ogg": "കത്രിക",
+ "scorpion.ogg": "തേൾ",
+ "scratch.ogg": "മാന്തുക",
+ "scream.ogg": "അലറുക",
+ "screw.ogg": "സ്ക്രൂ",
+ "screwdriver.ogg": "സ്ക്രൂഡ്രൈവർ",
+ "scribble.ogg": "കുത്തിക്കുറിക്കുക",
+ "sea.ogg": "കടൽ",
+ "seat.ogg": "ഇരിപ്പിടം",
+ "see.ogg": "കാണുക",
+ "seed.ogg": "വിത്ത്",
+ "shadow.ogg": "നിഴൽ",
+ "shake.ogg": "കുലുക്കുക",
+ "shark.ogg": "സ്രാവ്",
+ "shave.ogg": "ക്ഷൗരം ചെയ്യുക",
+ "shed.ogg": "ഷെഡ്",
+ "sheep.ogg": "ചെമ്മരിയാട്",
+ "shelf.ogg": "ചുവരലമാര",
+ "shell.ogg": "പുറംതോട്",
+ "ship.ogg": "കപ്പൽ",
+ "shirt.ogg": "ഷർട്ട്",
+ "shoe.ogg": "ഷൂ",
+ "shoelace.ogg": "ഷൂ കെട്ടുന്ന ചരട്",
+ "shop.ogg": "കട",
+ "shore.ogg": "തീരം",
+ "short.ogg": "ഷോർട്ട്സ്",
+ "shovel.ogg": "കോരിക",
+ "shower.ogg": "ഷവർ",
+ "shrimp.ogg": "ചെമ്മീൻ",
+ "shrub.ogg": "കുറ്റിച്ചെടി",
+ "shut.ogg": "അടച്ച",
+ "shutter.ogg": "കതക്",
+ "sick.ogg": "രോഗിയായ",
+ "sidewalk.ogg": "നടപ്പാത",
+ "sign.ogg": "അടയാളം",
+ "sing.ogg": "പാടുക",
+ "sink.ogg": "സിങ്ക്",
+ "sip.ogg": "നുകരുക",
+ "sister.ogg": "സഹോദരി",
+ "sit.ogg": "ഇരിയ്ക്കുക",
+ "skate.ogg": "സ്കേറ്റിങ്",
+ "skeleton.ogg": "അസ്ഥികൂടം",
+ "ski.ogg": "സ്കീയിന്മേൽ പായുക",
+ "skimmer.ogg": "അരിപ്പത്തവി",
+ "skin.ogg": "തൊലി",
+ "skirt.ogg": "പാവാട",
+ "skunk.ogg": "കുട്ടിസ്രാങ്ക്",
+ "sky.ogg": "ആകാശം",
+ "slam.ogg": "ശക്തിയായി അടിയ്ക്കുക",
+ "sled.ogg": "ഉരുളില്ലാവണ്ടി",
+ "sleep.ogg": "ഉറങ്ങുക",
+ "sleeve.ogg": "കുപ്പായക്കൈ",
+ "sleigh.ogg": "തെന്നുവണ്ടി",
+ "slide.ogg": "സ്ലൈഡ്",
+ "slim.ogg": "മെലിഞ്ഞ",
+ "slime.ogg": "ഒച്ചിൻ്റെ ദ്രവം",
+ "slippers.ogg": "ചെരിപ്പ്",
+ "slope.ogg": "ചരിവ്",
+ "sloppy.ogg": "അലസമായ",
+ "slot.ogg": "വിടവ്",
+ "sloth.ogg": "തേവാങ്ക്",
+ "slug.ogg": "തോടില്ലാത്ത ഒച്ച്",
+ "small.ogg": "ചെറിയ",
+ "smell.ogg": "മണപ്പിക്കുക",
+ "smile.ogg": "പുഞ്ചിരി",
+ "smoke.ogg": "പുക",
+ "smooch.ogg": "കെട്ടിപ്പിടിച്ചു ചുംബിക്കുക",
+ "snack.ogg": "ലഘുഭക്ഷണം",
+ "snail.ogg": "ഒച്ച്",
+ "snake.ogg": "പാമ്പ്",
+ "sneaker.ogg": "സ്നീക്കർ",
+ "sniff.ogg": "മണം പിടിക്കുക",
+ "snow.ogg": "മഞ്ഞ്",
+ "soap.ogg": "സോപ്പ്",
+ "sob.ogg": "തേങ്ങൽ",
+ "sock.ogg": "സോക്ക്",
+ "soldier.ogg": "പട്ടാളക്കാരൻ",
+ "sole.ogg": "മാന്തൾ",
+ "sole_shoe.ogg": "ഷൂ സോൾ",
+ "son.ogg": "മകൻ",
+ "soup.ogg": "സൂപ്പ്",
+ "spade.ogg": "മൺവെട്ടി",
+ "spaghetti.ogg": "സ്പഗെറ്റി",
+ "spark.ogg": "തീപ്പൊരി",
+ "sparrow.ogg": "കുരുവി",
+ "spatula.ogg": "ചട്ടുകം",
+ "speak.ogg": "സംസാരിക്കുക",
+ "spear.ogg": "കുന്തം",
+ "spice.ogg": "സുഗന്ധവ്യഞ്ജനം",
+ "spider.ogg": "ചിലന്തി",
+ "spider_web.ogg": "ചിലന്തിവല",
+ "spike.ogg": "മുള്ള്",
+ "spill.ogg": "തുളുമ്പുക",
+ "spinach.ogg": "ചീര",
+ "spine.ogg": "നട്ടെല്ല്",
+ "spinning_top.ogg": "പമ്പരം",
+ "splash.ogg": "തെറിപ്പിക്കുക",
+ "sponge.ogg": "സ്പോഞ്ച്",
+ "spool.ogg": "നൂൽചുരുള്‍",
+ "spoon.ogg": "തവി",
+ "sport.ogg": "കായികം",
+ "spot.ogg": "പുള്ളി",
+ "spray.ogg": "തളിക്കുക",
+ "spread.ogg": "പടർത്തുക",
+ "spring.ogg": "തെറിക്കുക",
+ "spring_season.ogg": "വസന്തകാലം",
+ "sprinkle.ogg": "വിതറുക",
+ "square.ogg": "സമചതുരം",
+ "squash.ogg": "മത്തൻ കുടുംബം",
+ "squat.ogg": "കുത്തിയിരിക്കുക",
+ "squid.ogg": "കണവ",
+ "squirrel.ogg": "അണ്ണാൻ",
+ "squirt.ogg": "പീച്ചാങ്കുഴൽ",
+ "stack.ogg": "കൂമ്പാരം",
+ "stage.ogg": "അരങ്ങ്",
+ "staircase.ogg": "പടിക്കെട്ട്",
+ "stamp.ogg": "തപാൽസ്റ്റാമ്പ്",
+ "stand.ogg": "നിൽക്കുക",
+ "star.ogg": "നക്ഷത്രം",
+ "stare.ogg": "തുറിച്ചുനോക്കുക",
+ "starfish.ogg": "നക്ഷത്രമത്സ്യം",
+ "steam.ogg": "നീരാവി",
+ "steep.ogg": "ചെങ്കുത്തായ",
+ "steeple.ogg": "കെട്ടിട സ്തൂപിക",
+ "stem.ogg": "തണ്ട്",
+ "step.ogg": "നട",
+ "stew.ogg": "സ്റ്റ്യൂ",
+ "stick.ogg": "കമ്പ്",
+ "sting.ogg": "കുത്തുക",
+ "stinky.ogg": "ദുർഗന്ധമുള്ള",
+ "stitch.ogg": "തയ്ക്കുക",
+ "stomach.ogg": "ആമാശയം",
+ "stone.ogg": "കല്ല്",
+ "stop.ogg": "നിർത്തുക",
+ "store.ogg": "കലവറ",
+ "stove.ogg": "ഇരുമ്പടുപ്പ്",
+ "straight.ogg": "നേരേയുള്ള",
+ "strainer.ogg": "അരിപ്പ",
+ "straw.ogg": "സ്ട്രോ",
+ "strawberry.ogg": "സ്ട്രോബെറി",
+ "stream.ogg": "നീർച്ചാൽ",
+ "street.ogg": "തെരുവ്",
+ "stretch.ogg": "നിവർത്തുക",
+ "string.ogg": "ചരട്",
+ "stripe.ogg": "വര",
+ "strong.ogg": "ശക്തിയുള്ള",
+ "student.ogg": "വിദ്യാർത്ഥി",
+ "study.ogg": "പഠിക്കുക",
+ "stump.ogg": "മരക്കുറ്റി",
+ "sugar.ogg": "പഞ്ചസാര",
+ "suit.ogg": "വസ്ത്രം",
+ "suitcase.ogg": "യാത്രപ്പെട്ടി",
+ "summer.ogg": "വേനൽക്കാലം",
+ "summit.ogg": "കൊടുമുടി",
+ "sun.ogg": "സൂര്യൻ",
+ "swan.ogg": "അരയന്നം",
+ "sweat.ogg": "വിയർപ്പ്",
+ "sweatshirt.ogg": "ജാക്കറ്റ്",
+ "swim.ogg": "നീന്തൽ",
+ "table.ogg": "മേശ",
+ "tablecloth.ogg": "മേശവിരി",
+ "tadpole.ogg": "വാൽമാക്രി",
+ "tag.ogg": "ടാഗ്",
+ "tail.ogg": "വാൽ",
+ "tall.ogg": "ഉയരമുള്ള",
+ "tape_measure.ogg": "അളവു ടേപ്പ്",
+ "taxi.ogg": "ടാക്സി",
+ "teach.ogg": "പഠിപ്പിക്കുക",
+ "teacher.ogg": "അധ്യാപിക",
+ "tear.ogg": "കീറിക്കളയുക",
+ "teddy.ogg": "കളിപ്പാട്ടക്കരടി",
+ "teeth.ogg": "പല്ലുകൾ",
+ "television.ogg": "ടെലിവിഷൻ",
+ "temple.ogg": "ക്ഷേത്രം",
+ "tennis.ogg": "ടെന്നീസ് കളി",
+ "tent.ogg": "കൂടാരം",
+ "text.ogg": "വാക്യം",
+ "thick.ogg": "കട്ടിയുള്ള",
+ "thief.ogg": "കള്ളൻ",
+ "thigh.ogg": "തുട",
+ "think.ogg": "ചിന്തിക്കുക",
+ "thread.ogg": "നൂൽ",
+ "throat.ogg": "തൊണ്ട",
+ "throw.ogg": "വലിച്ചെറിയുക",
+ "thumb.ogg": "തള്ളവിരൽ",
+ "tick.ogg": "ചെള്ള്",
+ "ticket.ogg": "ടിക്കറ്റ്",
+ "tiger.ogg": "കടുവ",
+ "time.ogg": "സമയം",
+ "tin.ogg": "ടിൻ",
+ "tire.ogg": "ടയർ",
+ "tired.ogg": "ക്ഷീണിച്ച",
+ "tissue.ogg": "നേർത്ത കടലാസ്",
+ "to_drink.ogg": "കുടിക്കുക",
+ "toad.ogg": "പേക്കാന്തവള",
+ "toaster.ogg": "ടോസ്റ്റർ",
+ "toe.ogg": "കാൽവിരൽ",
+ "toilet.ogg": "കക്കൂസ്",
+ "tomatoe.ogg": "തക്കാളി",
+ "tongs.ogg": "കൊടിൽ",
+ "tongue.ogg": "നാവ്",
+ "tool.ogg": "പണിയായുധം",
+ "top.ogg": "മേലഗ്രം",
+ "torch.ogg": "പന്തം",
+ "touch.ogg": "തൊടുക",
+ "towel.ogg": "തോർത്ത്",
+ "toy.ogg": "കളിപ്പാട്ടം",
+ "trail.ogg": "കാലടിപ്പാത",
+ "train.ogg": "തീവണ്ടി",
+ "train_station.ogg": "റെയിൽവേ സ്റ്റേഷൻ",
+ "trap.ogg": "കെണി",
+ "trash.ogg": "ചവറ്",
+ "tray.ogg": "താലം",
+ "treat.ogg": "സത്ക്കാരം",
+ "tree.ogg": "മരം",
+ "triangle.ogg": "ത്രികോണം",
+ "tribe.ogg": "ഗോത്രം",
+ "trip.ogg": "യാത്ര",
+ "truck.ogg": "ലോറി",
+ "tube.ogg": "കുഴൽ",
+ "tulip.ogg": "തുലിപ്",
+ "tune.ogg": "ഈണം",
+ "turkey.ogg": "ടർക്കിക്കോഴി",
+ "turnip.ogg": "മധുരമുള്ളങ്കി",
+ "turtle.ogg": "ആമ",
+ "tusk.ogg": "വക്രദന്തം",
+ "twin_boys.ogg": "ഇരട്ട ആൺകുട്ടികൾ",
+ "twin_girls.ogg": "ഇരട്ട പെൺകുട്ടികൾ",
+ "umbrella.ogg": "കുട",
+ "under.ogg": "കീഴിൽ",
+ "uniform.ogg": "യൂണിഫോം",
+ "van.ogg": "വാൻ",
+ "vapor.ogg": "ബാഷ്പം",
+ "vase.ogg": "പൂച്ചട്ടി",
+ "vegetable.ogg": "പച്ചക്കറി",
+ "vein.ogg": "സിര",
+ "verdure.ogg": "സസ്യത്തഴപ്പ്",
+ "vest.ogg": "മേലങ്കി",
+ "vet.ogg": "മൃഗഡോക്ടർ",
+ "viper.ogg": "അണലി",
+ "vowel.ogg": "സ്വരാക്ഷരം",
+ "vulture.ogg": "കഴുകൻ",
+ "wag.ogg": "ആട്ടുക",
+ "walk.ogg": "നടക്കുക",
+ "wall.ogg": "ചുമർ",
+ "walnut.ogg": "അകരോട്ടണ്ടി",
+ "wart.ogg": "അരിമ്പാറ",
+ "wash.ogg": "കഴുകുക",
+ "wasp.ogg": "കടന്നൽ",
+ "watch.ogg": "വാച്ച്",
+ "water.ogg": "വെള്ളം",
+ "wave.ogg": "തിരമാല",
+ "wedding.ogg": "വിവാഹാഘോഷം",
+ "wedge.ogg": "ലോഹ ആപ്പ്",
+ "weight.ogg": "ഭാരം",
+ "wet.ogg": "നനഞ്ഞ",
+ "whale.ogg": "തിമിംഗലം",
+ "wheat.ogg": "ഗോതമ്പ്",
+ "wheel.ogg": "ചക്രം",
+ "whisk.ogg": "പതപ്പിക്കാനുള്ള ഉപകരണം",
+ "whisper.ogg": "സ്വകാര്യം പറയുക",
+ "white.ogg": "വെളുപ്പ്",
+ "wide.ogg": "വീതിയുള്ള",
+ "wife.ogg": "ഭാര്യ",
+ "wig.ogg": "വെപ്പുമുടി",
+ "win.ogg": "ജയിക്കുക",
+ "wind.ogg": "കാറ്റ്",
+ "window.ogg": "ജാലകം",
+ "window_glass.ogg": "ജാലക ചില്ല്",
+ "wing.ogg": "ചിറക്",
+ "winter.ogg": "ശീതകാലം",
+ "wolf.ogg": "ചെന്നായ",
+ "woman.ogg": "സ്ത്രീ",
+ "wood.ogg": "തടി",
+ "word.ogg": "വാക്ക്",
+ "worker.ogg": "തൊഴിലാളി",
+ "world.ogg": "ലോകം",
+ "wreath.ogg": "റീത്ത്",
+ "wrench.ogg": "തിരുക്കി",
+ "wrist.ogg": "കണങ്കൈ",
+ "write.ogg": "എഴുതുക",
+ "yellow.ogg": "മഞ്ഞ",
+ "yogurt.ogg": "തൈര്",
+ "yum.ogg": "രുചികരം",
+ "zebra.ogg": "വരയൻ കുതിര",
+ "zipper.ogg": "പൽനിരപ്പൂട്ട്",
+ "zoo.ogg": "മൃഗശാല"
+}
\ No newline at end of file
diff --git a/src/activities/lang/resource/content-nl.json b/src/activities/lang/resource/content-nl.json
new file mode 100644
index 000000000..884468e93
--- /dev/null
+++ b/src/activities/lang/resource/content-nl.json
@@ -0,0 +1,1092 @@
+{
+ "10.ogg": "tien",
+ "11.ogg": "elf",
+ "12.ogg": "twaalf",
+ "16.ogg": "zestien",
+ "U0030.ogg": "nul",
+ "U0031.ogg": "één",
+ "U0032.ogg": "twee",
+ "U0033.ogg": "drie",
+ "U0034.ogg": "vier",
+ "U0035.ogg": "vijf",
+ "U0036.ogg": "zes",
+ "U0037.ogg": "zeven",
+ "U0038.ogg": "acht",
+ "U0039.ogg": "negen",
+ "accountant.ogg": "boekhouder",
+ "ache.ogg": "pijngevoel",
+ "acorn.ogg": "eikel",
+ "actor.ogg": "actor",
+ "air_horn.ogg": "luchthoorn",
+ "alarmclock.ogg": "wekker",
+ "alligator.ogg": "alligator",
+ "alphabet.ogg": "alfabet",
+ "anchor.ogg": "anker",
+ "angel.ogg": "engel",
+ "angry.ogg": "kwaad",
+ "animal.ogg": "dier",
+ "ankle.ogg": "enkel",
+ "ant.ogg": "mier",
+ "anteater.ogg": "miereneter",
+ "antelope.ogg": "antiloop",
+ "apple.ogg": "appel",
+ "apple_tree.ogg": "appelboom",
+ "appliance.ogg": "toestel",
+ "apricot.ogg": "abrikoos",
+ "arm.ogg": "arm",
+ "armchair.ogg": "leunstoel",
+ "artichoke.ogg": "artisjok",
+ "artist.ogg": "artiest",
+ "asparagus.ogg": "asperge",
+ "astronaut.ogg": "astronaut",
+ "athlete.ogg": "atleet",
+ "avocado.ogg": "avocado",
+ "ax.ogg": "bijl",
+ "baby_bottle.ogg": "zuigfles",
+ "back.ogg": "rug",
+ "badge.ogg": "badge",
+ "bag.ogg": "zak",
+ "bait.ogg": "aas",
+ "balance.ogg": "weegschaal",
+ "bald.ogg": "spoedig",
+ "ball.ogg": "bal",
+ "ball_of_yarn.ogg": "bol garen",
+ "ball_soccer.ogg": "voetbal",
+ "ballet.ogg": "ballet",
+ "bank.ogg": "bank",
+ "banker_female.ogg": "vrouwelijke bankier",
+ "bark.ogg": "blaffen",
+ "barn.ogg": "schuur",
+ "bat.ogg": "vleermuis",
+ "bath.ogg": "bad",
+ "bathing_suit.ogg": "badpak",
+ "bay.ogg": "baai",
+ "beach.ogg": "strand",
+ "bean.ogg": "boon",
+ "bear.ogg": "beer",
+ "beard.ogg": "baard",
+ "beat.ogg": "slaan",
+ "beaver.ogg": "bever",
+ "bed.ogg": "bed",
+ "bedroom.ogg": "slaapkamer",
+ "bee.ogg": "bij",
+ "beetle.ogg": "kever",
+ "beg.ogg": "bedelen",
+ "behind.ogg": "achter",
+ "bell.ogg": "bel",
+ "belly.ogg": "buik",
+ "bench.ogg": "bankje",
+ "bib.ogg": "slabbetje",
+ "big.ogg": "groot",
+ "big_top.ogg": "circustent",
+ "bike.ogg": "fiets",
+ "bird.ogg": "vogel",
+ "bit.ogg": "bit",
+ "bite.ogg": "bijten",
+ "black.ogg": "zwart",
+ "blackberry.ogg": "braambes",
+ "blackbird.ogg": "merel",
+ "blade.ogg": "mes",
+ "blind.ogg": "blind",
+ "blink.ogg": "knipperen",
+ "block.ogg": "blok",
+ "blond.ogg": "blond",
+ "blue.ogg": "blauw",
+ "blueberry.ogg": "bosbes",
+ "blush.ogg": "blozen",
+ "board.ogg": "bord",
+ "boat.ogg": "boot",
+ "boil.ogg": "koken",
+ "bolt.ogg": "bout",
+ "bomb.ogg": "bom",
+ "bone.ogg": "bot",
+ "book.ogg": "boek",
+ "bookcase.ogg": "boekenkast",
+ "bottom.ogg": "billen",
+ "box.ogg": "doos",
+ "boxer.ogg": "bokser",
+ "boy.ogg": "jongen",
+ "braid.ogg": "vlecht",
+ "brain.ogg": "brein",
+ "branch.ogg": "branch",
+ "bread.ogg": "brood",
+ "break.ogg": "breken",
+ "breast.ogg": "borst",
+ "brick.ogg": "steen",
+ "bricklayer.ogg": "metselaar",
+ "bride.ogg": "bruid",
+ "bridge.ogg": "brug",
+ "bright.ogg": "helder",
+ "broccoli.ogg": "broccoli",
+ "brother.ogg": "broer",
+ "brown.ogg": "bruin",
+ "brush.ogg": "penseel",
+ "bubble.ogg": "bubbel",
+ "bucket.ogg": "emmer",
+ "bud.ogg": "knop",
+ "buffalo.ogg": "buffels",
+ "bug.ogg": "insect",
+ "bulb.ogg": "peertje",
+ "bull.ogg": "stier",
+ "bump.ogg": "buil",
+ "bun.ogg": "broodje",
+ "bus.ogg": "bus",
+ "bush.ogg": "struik",
+ "butcher.ogg": "slager",
+ "butter.ogg": "boter",
+ "butterfly.ogg": "vlinder",
+ "button.ogg": "knoop",
+ "cabbage.ogg": "kool",
+ "cabin.ogg": "cabine",
+ "cacao.ogg": "cacao",
+ "cactus.ogg": "cactus",
+ "cage.ogg": "kooi",
+ "cake.ogg": "cake",
+ "call.ogg": "roepen",
+ "camel.ogg": "kameel",
+ "camera.ogg": "camera",
+ "camp.ogg": "kamp",
+ "can.ogg": "kan",
+ "canary.ogg": "kanarie",
+ "candle.ogg": "kaars",
+ "candy.ogg": "snoepgoed",
+ "cane.ogg": "riet",
+ "canoe.ogg": "kano",
+ "canon.ogg": "kanon",
+ "canyon.ogg": "canyon",
+ "cap.ogg": "pet",
+ "cape.ogg": "cape",
+ "car.ogg": "auto",
+ "carafe.ogg": "karaf",
+ "card.ogg": "kaart",
+ "carnival.ogg": "carnaval",
+ "carpenter.ogg": "timmerman",
+ "carpet.ogg": "tapijt",
+ "carrot.ogg": "wortel",
+ "cart.ogg": "kar",
+ "cash.ogg": "geld",
+ "castle.ogg": "kasteel",
+ "cat.ogg": "kat",
+ "cat_female.ogg": "poes",
+ "catch.ogg": "vangen",
+ "caterpillar.ogg": "rups",
+ "cauldron.ogg": "ketel",
+ "cauliflower.ogg": "bloemkool",
+ "cave.ogg": "grot",
+ "cavern.ogg": "spelonk",
+ "celery.ogg": "selderij",
+ "centipede.ogg": "duizendpoot",
+ "cereal.ogg": "graan",
+ "chain.ogg": "ketting",
+ "chair.ogg": "stoel",
+ "chalk.ogg": "krijt",
+ "chameleon.ogg": "kameleon",
+ "chandelier.ogg": "kandelaar",
+ "chat.ogg": "spreken",
+ "cheek.ogg": "wang",
+ "cheer.ogg": "hoera",
+ "cheese.ogg": "kaas",
+ "chef.ogg": "chef",
+ "cherry.ogg": "kers",
+ "chest.ogg": "leunstoel",
+ "chick.ogg": "kuikentje",
+ "chicken.ogg": "kip",
+ "child.ogg": "kind",
+ "chimney.ogg": "schoorsteen",
+ "chimp.ogg": "chimpansee",
+ "chin.ogg": "kin",
+ "chocolate.ogg": "chocola",
+ "chop.ogg": "hakken",
+ "chores.ogg": "klusjes",
+ "christmas.ogg": "kerstmis",
+ "cigar.ogg": "sigaar",
+ "circus.ogg": "circus",
+ "city.ogg": "stad",
+ "clam.ogg": "mossel",
+ "clap.ogg": "klappen",
+ "class.ogg": "klas",
+ "claw.ogg": "klauw",
+ "clay.ogg": "klei",
+ "clean.ogg": "schoonmaken",
+ "cleaning_lady.ogg": "schoonmaakster",
+ "cliff.ogg": "klif",
+ "climb.ogg": "klimmen",
+ "clock.ogg": "klok",
+ "cloth.ogg": "kleding",
+ "clothes_hanger.ogg": "klerenhanger",
+ "cloud.ogg": "wolk",
+ "cloudy.ogg": "bewolkt",
+ "clover.ogg": "klaver",
+ "clown.ogg": "clown",
+ "coach.ogg": "coach",
+ "coast.ogg": "kust",
+ "coat.ogg": "jas",
+ "cobra.ogg": "cobra",
+ "coconut.ogg": "kokosnoot",
+ "cod.ogg": "kabeljauw",
+ "coffee.ogg": "koffie",
+ "coin.ogg": "munt",
+ "cold.ogg": "koud",
+ "color.ogg": "kleur",
+ "colt.ogg": "colt",
+ "comb.ogg": "kam",
+ "cone.ogg": "kegel",
+ "cook.ogg": "koken",
+ "cookie.ogg": "koekje",
+ "cork.ogg": "kurk",
+ "corn.ogg": "mais",
+ "couch.ogg": "divan",
+ "cough.ogg": "hoesten",
+ "couple.ogg": "koppel",
+ "cow.ogg": "koe",
+ "cowboy.ogg": "cowboy",
+ "crab.ogg": "kreeft",
+ "cradle.ogg": "wieg",
+ "craft.ogg": "ambacht",
+ "crawl.ogg": "kruipen",
+ "crazy.ogg": "gek",
+ "creek.ogg": "kreek",
+ "crepe.ogg": "pannenkoek",
+ "crib.ogg": "wieg",
+ "croak.ogg": "kwaken",
+ "crocodile.ogg": "krokodil",
+ "cross.ogg": "kruis",
+ "crow.ogg": "kraai",
+ "crown.ogg": "kroon",
+ "crumb.ogg": "kruimel",
+ "crust.ogg": "korst",
+ "cry.ogg": "huilen",
+ "crystal.ogg": "kristal",
+ "cube.ogg": "kubus",
+ "cucumber.ogg": "komkommer",
+ "curtain.ogg": "gordijn",
+ "cut.ogg": "snijden",
+ "cute.ogg": "schattig",
+ "dad.ogg": "vader",
+ "daffodil.ogg": "narcis",
+ "daisy.ogg": "madeliefje",
+ "dam.ogg": "dam",
+ "dance.ogg": "dans",
+ "dandelion.ogg": "paardenbloem",
+ "dart_board.ogg": "dartbord",
+ "date_fruit.ogg": "dadel",
+ "deer.ogg": "hert",
+ "den.ogg": "nest",
+ "desert.ogg": "woestijn",
+ "desk.ogg": "bureau",
+ "dessert.ogg": "nagerecht",
+ "diamond.ogg": "diamant",
+ "dig.ogg": "graven",
+ "dirt.ogg": "vuil",
+ "dirty.ogg": "vuil",
+ "dish.ogg": "schotel",
+ "dishcloth.ogg": "vaatdoek",
+ "dive.ogg": "duiken",
+ "doctor.ogg": "arts",
+ "doe.ogg": "hinde",
+ "dog.ogg": "hond",
+ "doll.ogg": "pop",
+ "dolphin.ogg": "dolfijn",
+ "domino.ogg": "dominostenen",
+ "door.ogg": "deur",
+ "doormat.ogg": "deurmat",
+ "dot.ogg": "punt",
+ "doughnut.ogg": "doughnut",
+ "dove.ogg": "duif",
+ "dragon.ogg": "draak",
+ "dragonfly.ogg": "libel",
+ "draw.ogg": "tekenen",
+ "drawer.ogg": "lade",
+ "dream.ogg": "dromen",
+ "dress.ogg": "jurk",
+ "drink.ogg": "drankje",
+ "drip.ogg": "druppel",
+ "drive.ogg": "besturen",
+ "drool.ogg": "kwijlen",
+ "drum.ogg": "trommel",
+ "dry.ogg": "drogen",
+ "duck.ogg": "eend",
+ "duck_mother.ogg": "moedereend",
+ "dune.ogg": "duin",
+ "dwarf.ogg": "dwerg",
+ "eagle.ogg": "arend",
+ "ear.ogg": "oor",
+ "earth.ogg": "aarde",
+ "eat.ogg": "eten",
+ "egg.ogg": "ei",
+ "eggplant.ogg": "aubergine",
+ "elbow.ogg": "elleboog",
+ "electrician.ogg": "elektricien",
+ "elk.ogg": "eland",
+ "empty.ogg": "leeg",
+ "engine.ogg": "engine",
+ "engineer.ogg": "technicus",
+ "eraser.ogg": "gum",
+ "explore.ogg": "verkennen",
+ "eyelash.ogg": "wimper",
+ "eyes.ogg": "ogen",
+ "face.ogg": "gezicht",
+ "fair.ogg": "markt",
+ "fairy.ogg": "fee",
+ "fall.ogg": "vallen",
+ "fall_season.ogg": "najaar",
+ "family.ogg": "familie",
+ "fan.ogg": "ventilator",
+ "farm.ogg": "boerderij",
+ "farmer.ogg": "boer",
+ "fat.ogg": "vet",
+ "faucet.ogg": "kraan",
+ "fawn.ogg": "reekalf",
+ "fear.ogg": "angst",
+ "feast.ogg": "feest",
+ "feather.ogg": "veer",
+ "feed.ogg": "voeden",
+ "femur.ogg": "dijbeen",
+ "fetch.ogg": "ophalen",
+ "fig.ogg": "vijg",
+ "fin.ogg": "vin",
+ "find.ogg": "zoeken",
+ "finger.ogg": "vinger",
+ "fire.ogg": "vuur",
+ "fire_extinguisher.ogg": "brandblusser",
+ "fireman.ogg": "brandweerman",
+ "fish.ogg": "vis",
+ "fisherman.ogg": "visser",
+ "fist.ogg": "vuist",
+ "flacon.ogg": "flacon",
+ "flag.ogg": "vlag",
+ "flame.ogg": "vlam",
+ "flamingo.ogg": "flamingo",
+ "flash.ogg": "zaklantaarn",
+ "flat.ogg": "vlak",
+ "flies.ogg": "vliegen",
+ "float.ogg": "drijven",
+ "flour.ogg": "meel",
+ "flower.ogg": "bloem",
+ "fluff.ogg": "pluis",
+ "flute.ogg": "fluit",
+ "fly.ogg": "vliegen",
+ "foam.ogg": "schuim",
+ "foot.ogg": "voet",
+ "forest.ogg": "bos",
+ "fork.ogg": "vork",
+ "fountain.ogg": "fontein",
+ "fox.ogg": "vos",
+ "freeze.ogg": "bevriezen",
+ "friend.ogg": "vriend",
+ "fries.ogg": "friet",
+ "frog.ogg": "kikker",
+ "front.ogg": "voorkant",
+ "fruit.ogg": "fruit",
+ "fudge.ogg": "fudge",
+ "full.ogg": "vol",
+ "fur.ogg": "vacht",
+ "game.ogg": "spel",
+ "garage.ogg": "garage",
+ "garden.ogg": "tuin",
+ "garlic.ogg": "knoflook",
+ "gem.ogg": "edelsteen",
+ "giant.ogg": "reusachtig",
+ "gift.ogg": "cadeau",
+ "giraffe.ogg": "giraffe",
+ "girl.ogg": "meisje",
+ "glass.ogg": "glas",
+ "glasses.ogg": "glazen",
+ "glove.ogg": "handschoen",
+ "glue.ogg": "lijm",
+ "gnome.ogg": "gnome",
+ "goat.ogg": "steenbok",
+ "golden.ogg": "gouden",
+ "golf.ogg": "golf",
+ "goose.ogg": "gans",
+ "gorilla.ogg": "gorilla",
+ "grain.ogg": "korrel",
+ "grandmother.ogg": "grootmoeder",
+ "grape.ogg": "druif",
+ "grapefruit.ogg": "grapefruit",
+ "grass.ogg": "gras",
+ "grave.ogg": "graf",
+ "gray.ogg": "grijs",
+ "green.ogg": "groen",
+ "grill.ogg": "gril",
+ "grin.ogg": "grijns",
+ "ground.ogg": "aarde",
+ "growl.ogg": "grommen",
+ "guignol.ogg": "guignol",
+ "guinea_pig.ogg": "cavia",
+ "gum.ogg": "kauwgom",
+ "hair.ogg": "haar",
+ "hair_dryer.ogg": "haardroger",
+ "half.ogg": "half",
+ "ham.ogg": "ham",
+ "hamburger.ogg": "hamburger",
+ "hammer.ogg": "hamer",
+ "hand.ogg": "hand",
+ "handlebar.ogg": "stuur",
+ "happy.ogg": "gelukkig",
+ "harp.ogg": "harp",
+ "hat.ogg": "hoed",
+ "hatch.ogg": "broeden",
+ "hay.ogg": "hooi",
+ "head.ogg": "hoofd",
+ "hear.ogg": "horen",
+ "heat.ogg": "hitte",
+ "hedge.ogg": "heg",
+ "hedgehog.ogg": "egel",
+ "heel.ogg": "hak",
+ "helmet.ogg": "helm",
+ "hen.ogg": "hen",
+ "herd.ogg": "kudde",
+ "high.ogg": "hoog",
+ "hike.ogg": "trektocht",
+ "hill.ogg": "heuvel",
+ "hip.ogg": "heup",
+ "hippopotamus.ogg": "nijlpaard",
+ "hit.ogg": "treffer",
+ "hive.ogg": "bijenkorf",
+ "hockey.ogg": "hockey",
+ "hole.ogg": "hol",
+ "home.ogg": "thuis",
+ "hook.ogg": "haak",
+ "hop.ogg": "hinkelen",
+ "horse.ogg": "paard",
+ "hose.ogg": "slang",
+ "hospital.ogg": "hospitaal",
+ "hot.ogg": "heet",
+ "hot_dog.ogg": "hot dog",
+ "hound.ogg": "hond",
+ "house.ogg": "huis",
+ "howl.ogg": "huilen",
+ "hug.ogg": "omhelzen",
+ "huge.ogg": "reusachtig",
+ "hummingbird.ogg": "kolibrie",
+ "hunchbacked.ogg": "gebocheld",
+ "hunter.ogg": "jager",
+ "husband.ogg": "echtgenoot",
+ "hut.ogg": "hut",
+ "hyena.ogg": "hyena",
+ "ice.ogg": "ijs",
+ "iceberg.ogg": "ijsberg",
+ "iguana.ogg": "leguaan",
+ "ill.ogg": "ziek",
+ "ink.ogg": "inkt",
+ "island.ogg": "eiland",
+ "jacket.ogg": "jasje",
+ "jaguar.ogg": "jaguar",
+ "jam.ogg": "jam",
+ "jay.ogg": "vlaamse gaai",
+ "jelly.ogg": "jelly",
+ "jellyfish.ogg": "kwal",
+ "jewel.ogg": "juweel",
+ "job.ogg": "werk",
+ "jockey.ogg": "jockey",
+ "jog.ogg": "joggen",
+ "joy.ogg": "vreugde",
+ "judge.ogg": "rechter",
+ "judo.ogg": "judo",
+ "juggler.ogg": "jongleur",
+ "juice.ogg": "sap",
+ "jump.ogg": "springen",
+ "kangaroo.ogg": "kangoeroe",
+ "keel.ogg": "kiel",
+ "kernel.ogg": "pit",
+ "keyboard.ogg": "toetsenbord",
+ "kimono.ogg": "kimono",
+ "king.ogg": "koning",
+ "kiss.ogg": "kussen",
+ "kitchen.ogg": "keuken",
+ "kite.ogg": "vlieger",
+ "kitten.ogg": "kitten",
+ "kiwi.ogg": "kiwi",
+ "knee.ogg": "knie",
+ "kneel.ogg": "knielen",
+ "knife.ogg": "mes",
+ "knight.ogg": "ridder",
+ "knit.ogg": "breien",
+ "knot.ogg": "knoop",
+ "koala.ogg": "koala",
+ "lad.ogg": "knaap",
+ "lady.ogg": "dame",
+ "ladybug.ogg": "lieveheersbeestje",
+ "lake.ogg": "meer",
+ "lama.ogg": "lama",
+ "lamb.ogg": "lam",
+ "lamp.ogg": "lamp",
+ "land.ogg": "land",
+ "lane.ogg": "laan",
+ "lap.ogg": "schoot",
+ "lasso.ogg": "lasso",
+ "laugh.ogg": "lachen",
+ "lava.ogg": "lava",
+ "lawn.ogg": "laan",
+ "lawyer.ogg": "advocaat",
+ "leaf.ogg": "blad",
+ "ledge.ogg": "richel",
+ "leek.ogg": "prei",
+ "left.ogg": "links",
+ "leg.ogg": "been",
+ "lemon.ogg": "citroen",
+ "lemonade.ogg": "limonade",
+ "lemur.ogg": "ringstaartmaki",
+ "leopard.ogg": "luipaard",
+ "lettuce.ogg": "sla",
+ "librarian.ogg": "bibliothecaris",
+ "lick.ogg": "likken",
+ "lid.ogg": "deksel",
+ "lift.ogg": "tillen",
+ "light.ogg": "licht",
+ "lighthouse.ogg": "vuurtoren",
+ "lightning.ogg": "bliksem",
+ "lilac.ogg": "sering",
+ "lime.ogg": "limoen",
+ "line.ogg": "lijn",
+ "link.ogg": "koppeling",
+ "lion.ogg": "leeuw",
+ "lion_cub.ogg": "leeuwenwelp",
+ "lip.ogg": "lip",
+ "liquid.ogg": "vloeibaar",
+ "lizard.ogg": "hagedis",
+ "lobster.ogg": "kreeft",
+ "log.ogg": "houtblok",
+ "look.ogg": "kijken",
+ "lunch.ogg": "lunch",
+ "mad.ogg": "mad",
+ "magic.ogg": "magisch",
+ "magnet.ogg": "magneet",
+ "magnifying_glass.ogg": "vergrootglas",
+ "magpie.ogg": "ekster",
+ "mail.ogg": "post",
+ "man.ogg": "man",
+ "mane.ogg": "manen",
+ "mango.ogg": "mango",
+ "map.ogg": "kaart",
+ "maple.ogg": "esdoorn",
+ "marble.ogg": "marble",
+ "mashed_potatoes.ogg": "aardappelpuree",
+ "mask.ogg": "masker",
+ "mast.ogg": "mast",
+ "mat.ogg": "mat",
+ "match.ogg": "wedstrijd",
+ "mate.ogg": "vriend",
+ "mattress.ogg": "matras",
+ "mauve.ogg": "mauve",
+ "meal.ogg": "maaltijd",
+ "meat.ogg": "vlees",
+ "mechanic.ogg": "monteur",
+ "medal.ogg": "medaille",
+ "meet.ogg": "ontmoeten",
+ "melon.ogg": "meloen",
+ "merry-go-round.ogg": "rotonde",
+ "mice.ogg": "muis",
+ "microphone.ogg": "microfoon",
+ "milk.ogg": "melk",
+ "mill.ogg": "molen",
+ "mimosa.ogg": "mimosa",
+ "mirror.ogg": "spiegel",
+ "mixer.ogg": "mixer",
+ "mole.ogg": "mol",
+ "mom.ogg": "mama",
+ "moon.ogg": "maan",
+ "moose.ogg": "eland",
+ "mop.ogg": "stokdweil",
+ "mosque.ogg": "moskee",
+ "mosquito.ogg": "mug",
+ "mother.ogg": "moeder",
+ "motorcycle.ogg": "motorfiets",
+ "mountain.ogg": "berg",
+ "mouse.ogg": "muis",
+ "mouth.ogg": "mond",
+ "movie.ogg": "film",
+ "mower.ogg": "maaier",
+ "mud.ogg": "modder",
+ "mug.ogg": "mok",
+ "mule.ogg": "muilezel",
+ "muscle.ogg": "spier",
+ "mushroom.ogg": "paddenstoel",
+ "music.ogg": "muziek",
+ "musician.ogg": "musicus",
+ "naked.ogg": "naakt",
+ "nap.ogg": "dutten",
+ "navel.ogg": "navel",
+ "neck.ogg": "nek",
+ "necklace.ogg": "ketting",
+ "needle.ogg": "naald",
+ "nest.ogg": "nest",
+ "net.ogg": "net",
+ "newspaper.ogg": "krant",
+ "night.ogg": "nacht",
+ "nightgown.ogg": "nachtpon",
+ "nose.ogg": "neus",
+ "nostril.ogg": "neusgat",
+ "notebook.ogg": "notitieboek",
+ "number.ogg": "nummer",
+ "nun.ogg": "non",
+ "nurse.ogg": "verpleegster",
+ "nurse_male.ogg": "verpleger",
+ "nut.ogg": "noot",
+ "oar.ogg": "roeispaan",
+ "ocean.ogg": "oceaan",
+ "office.ogg": "office",
+ "olive.ogg": "olijf",
+ "on.ogg": "aan",
+ "onion.ogg": "ui",
+ "open.ogg": "open",
+ "opossum.ogg": "opossum",
+ "orange-color.ogg": "oranje kleur",
+ "orange.ogg": "sinaasappel",
+ "orchid.ogg": "orchidee",
+ "ostrich.ogg": "struisvogel",
+ "otter.ogg": "otter",
+ "owl.ogg": "uil",
+ "ox.ogg": "os",
+ "oyster.ogg": "oester",
+ "pacifier.ogg": "fopspeen",
+ "page.ogg": "pagina",
+ "pair.ogg": "paar",
+ "pajamas.ogg": "pyjama",
+ "pal.ogg": "maat",
+ "palm_tree.ogg": "palmboom",
+ "pan.ogg": "pan",
+ "panda.ogg": "panda",
+ "panther.ogg": "panter",
+ "panties.ogg": "slipje",
+ "pants.ogg": "broek",
+ "papaya.ogg": "papaya",
+ "paper.ogg": "papier",
+ "parachute.ogg": "parachute",
+ "parakeet.ogg": "parkiet",
+ "parrot.ogg": "papegaai",
+ "patch.ogg": "lap",
+ "path.ogg": "pad",
+ "paw.ogg": "poot",
+ "pea.ogg": "erwt",
+ "peach.ogg": "perzik",
+ "peacock.ogg": "pauw",
+ "peak.ogg": "piek",
+ "pear.ogg": "peer",
+ "pearl.ogg": "parel",
+ "peck.ogg": "pikken",
+ "pedal.ogg": "pedaal",
+ "pelican.ogg": "pelikaan",
+ "pen.ogg": "pen",
+ "pencil.ogg": "potlood",
+ "peony.ogg": "pioen",
+ "people.ogg": "mensen",
+ "pepper.ogg": "peper",
+ "peppers.ogg": "peper",
+ "pet.ogg": "huisdier",
+ "petal.ogg": "bloemblad",
+ "phone.ogg": "telefoon",
+ "piano.ogg": "piano",
+ "picture.ogg": "afbeelding",
+ "pie.ogg": "taart",
+ "pig.ogg": "varken",
+ "pigeon.ogg": "duif",
+ "pill.ogg": "pil",
+ "pillow.ogg": "kussen",
+ "pilot.ogg": "piloot",
+ "pine.ogg": "pijnboom",
+ "pine_cone.ogg": "dennenappel",
+ "pink.ogg": "roze",
+ "pip.ogg": "pit",
+ "pipe.ogg": "pijp",
+ "piranha.ogg": "piranha",
+ "pirate.ogg": "piraat",
+ "pizza.ogg": "pizza",
+ "plane.ogg": "vliegtuig",
+ "planet.ogg": "planeet",
+ "plant.ogg": "plant",
+ "plate.ogg": "plaat",
+ "play.ogg": "spelen",
+ "pliers.ogg": "tang",
+ "plow.ogg": "ploegen",
+ "plum.ogg": "pruim",
+ "plumber.ogg": "loodgieter",
+ "pocket.ogg": "zak",
+ "pod.ogg": "peul",
+ "pole.ogg": "paal",
+ "police.ogg": "politie",
+ "pompon.ogg": "pompoen",
+ "pond.ogg": "vijver",
+ "pony.ogg": "pony",
+ "pool.ogg": "pool",
+ "popcorn.ogg": "popcorn",
+ "pope.ogg": "paus",
+ "porthole.ogg": "patrijspoort",
+ "post.ogg": "post",
+ "pot.ogg": "pot",
+ "potato.ogg": "aardappel",
+ "pounce.ogg": "grijpen",
+ "president.ogg": "president",
+ "pretty.ogg": "mooi",
+ "price.ogg": "prijs",
+ "priest.ogg": "priester",
+ "prince.ogg": "prins",
+ "princess.ogg": "princes",
+ "prison.ogg": "gevangenis",
+ "prisoner.ogg": "gevangene",
+ "prize.ogg": "prijs",
+ "pug.ogg": "mopshond",
+ "pull.ogg": "trekken",
+ "pullover.ogg": "pullover",
+ "pumpkin.ogg": "pompoen",
+ "puppy.ogg": "puppy",
+ "pyramid.ogg": "piramide",
+ "quarrel.ogg": "ruzie maken",
+ "queen.ogg": "koningin",
+ "question.ogg": "vraag",
+ "quilt.ogg": "lappendeken",
+ "quiz.ogg": "quiz",
+ "rabbit.ogg": "konijn",
+ "rabbit_baby.ogg": "babykonijn",
+ "race.ogg": "wedren",
+ "radio.ogg": "radio",
+ "radish.ogg": "radijs",
+ "raft.ogg": "vlot",
+ "rag.ogg": "vod",
+ "rage.ogg": "woede",
+ "rain.ogg": "regen",
+ "raincoat.ogg": "regenjas",
+ "rake.ogg": "hark",
+ "ramp.ogg": "helling",
+ "ran.ogg": "rennen",
+ "raspberry.ogg": "framboos",
+ "rat.ogg": "rat",
+ "razor.ogg": "scheermes",
+ "read.ogg": "lezen",
+ "red.ogg": "rood",
+ "reptile.ogg": "reptiel",
+ "rhinoceros.ogg": "neushoorn",
+ "rice.ogg": "rijst",
+ "ride.ogg": "paardrijden",
+ "rifle.ogg": "geweer",
+ "right.ogg": "rechts",
+ "rip.ogg": "scheuren",
+ "rise.ogg": "stijgen",
+ "river.ogg": "rivier",
+ "road.ogg": "weg",
+ "roast.ogg": "gebraad",
+ "robe.ogg": "gewaad",
+ "robot.ogg": "robot",
+ "rock.ogg": "rots",
+ "rocket.ogg": "raket",
+ "rolling_pin.ogg": "deegroller",
+ "roof.ogg": "dak",
+ "room.ogg": "kamer",
+ "root.ogg": "wortel",
+ "rope.ogg": "touw",
+ "rose.ogg": "roos",
+ "round.ogg": "afronden",
+ "rowing.ogg": "roeien",
+ "royal.ogg": "koninklijk",
+ "rug.ogg": "kleed",
+ "run.ogg": "rennen",
+ "sad.ogg": "treurig",
+ "saddle.ogg": "zadel",
+ "sail.ogg": "zeil",
+ "sailor.ogg": "zeeman",
+ "salamander.ogg": "salamander",
+ "salmon.ogg": "zalm",
+ "sand.ogg": "zand",
+ "sandals.ogg": "sandalen",
+ "sandwich.ogg": "sandwich",
+ "sash.ogg": "sjerp",
+ "sauce.ogg": "saus",
+ "sausage.ogg": "worstje",
+ "scale.ogg": "schaal",
+ "scar.ogg": "litteken",
+ "scare.ogg": "bang maken",
+ "scarf.ogg": "sjaal",
+ "school.ogg": "school",
+ "school_bag.ogg": "schooltas",
+ "science.ogg": "wetenschap",
+ "scissors.ogg": "schaar",
+ "scorpion.ogg": "schorpioen",
+ "scratch.ogg": "krassen",
+ "scream.ogg": "schreeuwen",
+ "screw.ogg": "schroef",
+ "screwdriver.ogg": "schroevendraaier",
+ "scribble.ogg": "krabbelen",
+ "sea.ogg": "zee",
+ "seat.ogg": "zitplaats",
+ "see.ogg": "zien",
+ "seed.ogg": "zaadje",
+ "shadow.ogg": "schaduw",
+ "shake.ogg": "schudden",
+ "shark.ogg": "haai",
+ "shave.ogg": "scheren",
+ "shed.ogg": "schuurtje",
+ "sheep.ogg": "schaap",
+ "shelf.ogg": "schap",
+ "shell.ogg": "shell",
+ "ship.ogg": "schip",
+ "shirt.ogg": "overhemd",
+ "shoe.ogg": "schoen",
+ "shoelace.ogg": "schoenveter",
+ "shop.ogg": "winkel",
+ "shore.ogg": "kust",
+ "short.ogg": "kort",
+ "shovel.ogg": "schep",
+ "shower.ogg": "douche",
+ "shrimp.ogg": "garnaal",
+ "shrub.ogg": "struik",
+ "shut.ogg": "dicht",
+ "shutter.ogg": "luik",
+ "sick.ogg": "ziek",
+ "sidewalk.ogg": "trottoir",
+ "sign.ogg": "teken",
+ "sing.ogg": "zingen",
+ "sink.ogg": "gootsteen",
+ "sip.ogg": "nippen",
+ "sister.ogg": "zuster",
+ "sit.ogg": "zitten",
+ "skate.ogg": "schaatsen",
+ "skeleton.ogg": "skelet",
+ "ski.ogg": "skiën",
+ "skimmer.ogg": "schuimspaan",
+ "skin.ogg": "huid",
+ "skirt.ogg": "rok",
+ "skunk.ogg": "stinkdier",
+ "sky.ogg": "hemel",
+ "slam.ogg": "dichtslaan",
+ "sled.ogg": "slee",
+ "sleep.ogg": "slapen",
+ "sleeve.ogg": "mouw",
+ "sleigh.ogg": "slee",
+ "slide.ogg": "glijbaan",
+ "slim.ogg": "smal",
+ "slime.ogg": "slijm",
+ "slippers.ogg": "slippers",
+ "slope.ogg": "helling",
+ "sloppy.ogg": "slordig",
+ "slot.ogg": "slot",
+ "sloth.ogg": "luiaard",
+ "slug.ogg": "naaktslak",
+ "small.ogg": "klein",
+ "smell.ogg": "ruiken",
+ "smile.ogg": "glimlach",
+ "smock.ogg": "hes",
+ "smoke.ogg": "rook",
+ "smooch.ogg": "glad maken",
+ "snack.ogg": "snack",
+ "snail.ogg": "slak",
+ "snake.ogg": "slang",
+ "sneaker.ogg": "gymschoen",
+ "sniff.ogg": "snuiven",
+ "snow.ogg": "sneeuw",
+ "soap.ogg": "zeep",
+ "sob.ogg": "snik",
+ "sock.ogg": "sok",
+ "soldier.ogg": "soldaat",
+ "sole.ogg": "zool",
+ "sole_shoe.ogg": "slipper",
+ "son.ogg": "zoon",
+ "soup.ogg": "soep",
+ "spade.ogg": "spade",
+ "spaghetti.ogg": "spaghetti",
+ "spark.ogg": "vonk",
+ "sparrow.ogg": "spreeuw",
+ "spatula.ogg": "spatel",
+ "speak.ogg": "spreken",
+ "spear.ogg": "speer",
+ "spice.ogg": "kruiden",
+ "spider.ogg": "spin",
+ "spider_web.ogg": "spinnenweb",
+ "spike.ogg": "stekel",
+ "spill.ogg": "morsen",
+ "spinach.ogg": "spinazie",
+ "spine.ogg": "wervelkolom",
+ "spinning_top.ogg": "tol",
+ "splash.ogg": "spetteren",
+ "splatter.ogg": "geklater",
+ "sponge.ogg": "spons",
+ "spool.ogg": "spoel",
+ "spoon.ogg": "lepel",
+ "sport.ogg": "sport",
+ "spot.ogg": "punt",
+ "spray.ogg": "besproeien",
+ "spread.ogg": "verspreiden",
+ "spring.ogg": "springen",
+ "spring_season.ogg": "voorjaar",
+ "sprinkle.ogg": "strooisel",
+ "square.ogg": "vierkant",
+ "squash.ogg": "moes",
+ "squat.ogg": "hurken",
+ "squid.ogg": "inktvis",
+ "squirrel.ogg": "eekhoorn",
+ "squirt.ogg": "spuit",
+ "stack.ogg": "stapel",
+ "stage.ogg": "toneel",
+ "staircase.ogg": "trap",
+ "stamp.ogg": "postzegel",
+ "stand.ogg": "standaard",
+ "star.ogg": "ster",
+ "stare.ogg": "staren",
+ "starfish.ogg": "zeester",
+ "steam.ogg": "stoom",
+ "steep.ogg": "steil",
+ "steeple.ogg": "toren",
+ "stem.ogg": "stam",
+ "step.ogg": "trede",
+ "stew.ogg": "ragoût",
+ "stick.ogg": "stok",
+ "sting.ogg": "steken",
+ "stinky.ogg": "stinkend",
+ "stitch.ogg": "borduren",
+ "stomach.ogg": "maag",
+ "stone.ogg": "kringen",
+ "stop.ogg": "stoppen",
+ "store.ogg": "opslagruimte",
+ "stove.ogg": "fornuis",
+ "straight.ogg": "recht",
+ "strainer.ogg": "vergiet",
+ "straw.ogg": "stro",
+ "strawberry.ogg": "aardbei",
+ "stream.ogg": "stroom",
+ "street.ogg": "straat",
+ "stretch.ogg": "uitrekken",
+ "string.ogg": "draad",
+ "stripe.ogg": "streep",
+ "strong.ogg": "sterk",
+ "student.ogg": "student",
+ "study.ogg": "studeren",
+ "stump.ogg": "stomp",
+ "sugar.ogg": "suiker",
+ "suit.ogg": "pak",
+ "suitcase.ogg": "koffer",
+ "summer.ogg": "zomer",
+ "summit.ogg": "bergtop",
+ "sun.ogg": "zon",
+ "swan.ogg": "zwaan",
+ "sweat.ogg": "zweet",
+ "sweatshirt.ogg": "sweatshirt",
+ "swim.ogg": "zwemmen",
+ "table.ogg": "tafel",
+ "tablecloth.ogg": "tafellaken",
+ "tadpole.ogg": "pad",
+ "tag.ogg": "label",
+ "tail.ogg": "staart",
+ "tall.ogg": "lang",
+ "tape_measure.ogg": "meetlint",
+ "taxi.ogg": "taxi",
+ "teach.ogg": "onderwijzen",
+ "teacher.ogg": "leraar",
+ "tear.ogg": "scheuren",
+ "teddy.ogg": "teddybeer",
+ "teeth.ogg": "tand",
+ "television.ogg": "televisie",
+ "temple.ogg": "tempel",
+ "tennis.ogg": "tennis",
+ "tent.ogg": "tent",
+ "text.ogg": "tekst",
+ "thick.ogg": "dik",
+ "thief.ogg": "dief",
+ "thigh.ogg": "dij",
+ "think.ogg": "denken",
+ "thread.ogg": "draad",
+ "throat.ogg": "keel",
+ "throw.ogg": "werpen",
+ "thumb.ogg": "duim",
+ "tick.ogg": "teek",
+ "ticket.ogg": "kaartje",
+ "tiger.ogg": "tiger",
+ "time.ogg": "tijd",
+ "tin.ogg": "blik",
+ "tire.ogg": "band",
+ "tired.ogg": "vermoeid",
+ "tissue.ogg": "tissue",
+ "to_drink.ogg": "drinken",
+ "toad.ogg": "pad",
+ "toaster.ogg": "toaster",
+ "toe.ogg": "teen",
+ "toilet.ogg": "toilet",
+ "tomatoe.ogg": "tomaat",
+ "tongs.ogg": "tang",
+ "tongue.ogg": "tong",
+ "tool.ogg": "gereedschap",
+ "top.ogg": "top",
+ "torch.ogg": "toorts",
+ "touch.ogg": "aanraken",
+ "towel.ogg": "handdoek",
+ "toy.ogg": "speeltje",
+ "trail.ogg": "spoor",
+ "train.ogg": "trein",
+ "train_station.ogg": "treinstation",
+ "trap.ogg": "val",
+ "trash.ogg": "prullenbak",
+ "tray.ogg": "dienblad",
+ "treat.ogg": "tractatie",
+ "tree.ogg": "boom",
+ "triangle.ogg": "driehoek",
+ "tribe.ogg": "stam",
+ "trip.ogg": "trip",
+ "truck.ogg": "vrachtwagen",
+ "tube.ogg": "tube",
+ "tulip.ogg": "tulp",
+ "tune.ogg": "tune",
+ "turkey.ogg": "kalkoen",
+ "turnip.ogg": "raap",
+ "turtle.ogg": "schildpad",
+ "tusk.ogg": "slagtand",
+ "twin_boys.ogg": "jongenstweeling",
+ "twin_girls.ogg": "meisjestweeling",
+ "umbrella.ogg": "paraplu",
+ "under.ogg": "onder",
+ "uniform.ogg": "uniform",
+ "van.ogg": "bestelwagen",
+ "vapor.ogg": "damp",
+ "vase.ogg": "vaas",
+ "vegetable.ogg": "groente",
+ "vein.ogg": "ader",
+ "verdure.ogg": "gebladerte",
+ "vest.ogg": "vest",
+ "vet.ogg": "dierenarts",
+ "viper.ogg": "adder",
+ "vowel.ogg": "klinker",
+ "vulture.ogg": "gier",
+ "wag.ogg": "kwispelen",
+ "walk.ogg": "lopen",
+ "wall.ogg": "muur",
+ "walnut.ogg": "walnoot",
+ "wart.ogg": "wrat",
+ "wash.ogg": "wassen",
+ "wasp.ogg": "wesp",
+ "watch.ogg": "horloge",
+ "water.ogg": "waterman",
+ "wave.ogg": "golf",
+ "wedding.ogg": "bruiloft",
+ "wedge.ogg": "wig",
+ "weight.ogg": "gewicht",
+ "wet.ogg": "nat",
+ "whale.ogg": "walvis",
+ "wheat.ogg": "tarwe",
+ "wheel.ogg": "wiel",
+ "whisk.ogg": "vliegenmepper",
+ "whisper.ogg": "fluisteren",
+ "white.ogg": "wit",
+ "wide.ogg": "breed",
+ "wife.ogg": "echtgenote",
+ "wig.ogg": "pruik",
+ "win.ogg": "winnen",
+ "wind.ogg": "Wind",
+ "window.ogg": "venster",
+ "window_glass.ogg": "vensterglas",
+ "wing.ogg": "vleugel",
+ "winter.ogg": "winter",
+ "wolf.ogg": "wolf",
+ "woman.ogg": "vrouw",
+ "wood.ogg": "hout",
+ "word.ogg": "woord",
+ "worker.ogg": "werkman",
+ "world.ogg": "wereld",
+ "wreath.ogg": "krans",
+ "wrench.ogg": "moersleutel",
+ "wrist.ogg": "pols",
+ "write.ogg": "schrijven",
+ "yellow.ogg": "geel",
+ "yogurt.ogg": "yogurt",
+ "yum.ogg": "yum",
+ "zebra.ogg": "zebra",
+ "zipper.ogg": "ritssluiting",
+ "zoo.ogg": "dierentuin"
+}
\ No newline at end of file
diff --git a/src/activities/lang/resource/content-nn.json b/src/activities/lang/resource/content-nn.json
new file mode 100644
index 000000000..356c6500d
--- /dev/null
+++ b/src/activities/lang/resource/content-nn.json
@@ -0,0 +1,200 @@
+{
+ "10.ogg": "ti",
+ "11.ogg": "elleve",
+ "12.ogg": "tolv",
+ "16.ogg": "seksten",
+ "U0030.ogg": "null",
+ "U0031.ogg": "éin",
+ "U0032.ogg": "to",
+ "U0033.ogg": "tre",
+ "U0034.ogg": "fire",
+ "U0035.ogg": "fem",
+ "U0036.ogg": "seks",
+ "U0037.ogg": "sju",
+ "U0038.ogg": "åtte",
+ "U0039.ogg": "ni",
+ "alphabet.ogg": "alfabet",
+ "angel.ogg": "engel",
+ "bark.ogg": "å bjeffa",
+ "beat.ogg": "å slå",
+ "beg.ogg": "å trygla",
+ "behind.ogg": "bak",
+ "bike.ogg": "sykkel",
+ "bit.ogg": "bit",
+ "bite.ogg": "å bita",
+ "black.ogg": "svart",
+ "blink.ogg": "å blunka",
+ "blue.ogg": "blå",
+ "boat.ogg": "båt",
+ "boil.ogg": "å koka",
+ "bone.ogg": "bein",
+ "break.ogg": "å knusa",
+ "brown.ogg": "brun",
+ "bubble.ogg": "boble",
+ "bus.ogg": "buss",
+ "call.ogg": "å ringja",
+ "camp.ogg": "leir",
+ "canoe.ogg": "kano",
+ "car.ogg": "bil",
+ "carnival.ogg": "karneval",
+ "catch.ogg": "å fiska",
+ "chat.ogg": "å prata",
+ "chop.ogg": "å skjera",
+ "chores.ogg": "husarbeid",
+ "christmas.ogg": "juletre",
+ "clap.ogg": "å klappa",
+ "clean.ogg": "å dusja",
+ "color.ogg": "fargar",
+ "cook.ogg": "å baka",
+ "cough.ogg": "å hosta",
+ "craft.ogg": "handarbeid",
+ "crawl.ogg": "å krypa",
+ "croak.ogg": "å kvekka",
+ "cry.ogg": "å grina",
+ "cut.ogg": "å klippa",
+ "dig.ogg": "å grava",
+ "dot.ogg": "prikk",
+ "draw.ogg": "å teikna",
+ "dream.ogg": "å drøyma",
+ "drive.ogg": "å køyra",
+ "drool.ogg": "å sikla",
+ "dry.ogg": "å tørka",
+ "eat.ogg": "å eta",
+ "engine.ogg": "motor",
+ "fairy.ogg": "fe",
+ "fall.ogg": "å detta",
+ "feed.ogg": "å mata",
+ "fetch.ogg": "å henta",
+ "find.ogg": "å finna",
+ "flat.ogg": "leilegheiter",
+ "float.ogg": "å flyta",
+ "fly.ogg": "å sveva",
+ "freeze.ogg": "å frysa",
+ "front.ogg": "framme",
+ "gnome.ogg": "alv",
+ "gray.ogg": "grå",
+ "green.ogg": "grøn",
+ "growl.ogg": "å knurra",
+ "guignol.ogg": "handdokke",
+ "half.ogg": "halv",
+ "hatch.ogg": "å klekkjast",
+ "hear.ogg": "å høyra",
+ "howl.ogg": "å ula",
+ "hug.ogg": "å klemma",
+ "jump.ogg": "å hoppa",
+ "king.ogg": "konge",
+ "kiss.ogg": "å kyssa",
+ "kneel.ogg": "å knela",
+ "knight.ogg": "riddar",
+ "knit.ogg": "å strikka",
+ "lad.ogg": "gut",
+ "left.ogg": "venstre",
+ "lick.ogg": "å sleikja",
+ "light.ogg": "lys",
+ "line.ogg": "strekkode",
+ "link.ogg": "lenkje",
+ "look.ogg": "å kikka",
+ "mauve.ogg": "lilla",
+ "meet.ogg": "å helsa",
+ "motorcycle.ogg": "motorsykkel",
+ "movie.ogg": "film",
+ "music.ogg": "musikk",
+ "nap.ogg": "å kvila",
+ "number.ogg": "tal",
+ "on.ogg": "på",
+ "orange-color.ogg": "oransje",
+ "parachute.ogg": "fallskjerm",
+ "peck.ogg": "å hakka",
+ "pedal.ogg": "pedal",
+ "pink.ogg": "rosa",
+ "pirate.ogg": "sjørøvar",
+ "plane.ogg": "fly",
+ "play.ogg": "å leika",
+ "plow.ogg": "å pløya",
+ "pope.ogg": "pave",
+ "porthole.ogg": "kuauge",
+ "pounce.ogg": "å skremma",
+ "president.ogg": "talar",
+ "price.ogg": "pris",
+ "prince.ogg": "prins",
+ "princess.ogg": "prinsesse",
+ "prisoner.ogg": "fange",
+ "pull.ogg": "å hala",
+ "quarrel.ogg": "å krangla",
+ "queen.ogg": "dronning",
+ "question.ogg": "spørsmål",
+ "quiz.ogg": "kviss",
+ "raft.ogg": "flåte",
+ "read.ogg": "å lesa",
+ "red.ogg": "raud",
+ "right.ogg": "høgre",
+ "rip.ogg": "å riva av",
+ "rise.ogg": "å auka",
+ "rocket.ogg": "rakett",
+ "round.ogg": "rund",
+ "run.ogg": "å springa",
+ "sail.ogg": "seglbåt",
+ "scare.ogg": "å kveppa",
+ "science.ogg": "vitskap",
+ "scratch.ogg": "å skrapa",
+ "scream.ogg": "å hyla",
+ "scribble.ogg": "å rabla",
+ "see.ogg": "å sjå",
+ "shake.ogg": "å rista",
+ "shave.ogg": "å klippe sau",
+ "ship.ogg": "seglskip",
+ "sing.ogg": "å syngja",
+ "sip.ogg": "å slurpa",
+ "sit.ogg": "å sitja",
+ "slam.ogg": "å skåra",
+ "sled.ogg": "kjelke",
+ "sleep.ogg": "å sove",
+ "smell.ogg": "å lukta",
+ "smooch.ogg": "å klina",
+ "sniff.ogg": "å lukta",
+ "speak.ogg": "å snakka",
+ "spill.ogg": "å søla",
+ "splash.ogg": "å spruta",
+ "splatter.ogg": "skvett",
+ "spot.ogg": "flekkar",
+ "spray.ogg": "å spraya",
+ "spread.ogg": "å smørja",
+ "spring.ogg": "å spretta",
+ "square.ogg": "firkant",
+ "squat.ogg": "å sitja på huk",
+ "stand.ogg": "å stå",
+ "stare.ogg": "å stirra",
+ "sting.ogg": "å stikka",
+ "stitch.ogg": "å sy",
+ "stop.ogg": "å stogga",
+ "stretch.ogg": "å tøya",
+ "stripe.ogg": "stripe",
+ "student.ogg": "elev",
+ "study.ogg": "å studera",
+ "taxi.ogg": "drosje",
+ "teach.ogg": "å læra",
+ "tear.ogg": "å riva",
+ "text.ogg": "tekst",
+ "thief.ogg": "tjuv",
+ "think.ogg": "å tenkja",
+ "to_drink.ogg": "å drikka",
+ "touch.ogg": "å røra",
+ "train.ogg": "tog",
+ "triangle.ogg": "trekant",
+ "trip.ogg": "tur",
+ "truck.ogg": "lastebil",
+ "tune.ogg": "melodi",
+ "under.ogg": "under",
+ "van.ogg": "varebil",
+ "vowel.ogg": "vokal",
+ "wag.ogg": "å logra",
+ "walk.ogg": "å gå",
+ "wash.ogg": "å bada",
+ "weight.ogg": "vekt",
+ "whisper.ogg": "å kviskra",
+ "white.ogg": "kvit",
+ "win.ogg": "å vinna",
+ "word.ogg": "ord",
+ "write.ogg": "å skriva",
+ "yellow.ogg": "gul"
+}
\ No newline at end of file
diff --git a/src/activities/lang/resource/content-pl.json b/src/activities/lang/resource/content-pl.json
index 4f851827e..623577d21 100644
--- a/src/activities/lang/resource/content-pl.json
+++ b/src/activities/lang/resource/content-pl.json
@@ -1,1108 +1,1092 @@
{
"10.ogg": "dziesięć",
"11.ogg": "jedenaście",
"12.ogg": "dwanaście",
"16.ogg": "szesnaście",
"U0030.ogg": "zero",
"U0031.ogg": "jeden",
"U0032.ogg": "dwa",
"U0033.ogg": "trzy",
"U0034.ogg": "cztery",
"U0035.ogg": "pięć",
"U0036.ogg": "sześć",
"U0037.ogg": "siedem",
"U0038.ogg": "osiem",
"U0039.ogg": "dziewięć",
"accountant.ogg": "księgowy",
"ache.ogg": "ból",
"acorn.ogg": "żołądź",
"actor.ogg": "aktor",
"air_horn.ogg": "klakson",
"alarmclock.ogg": "budzik",
"alligator.ogg": "aligator",
"alphabet.ogg": "alfabet",
"anchor.ogg": "kotwica",
"angel.ogg": "anioł",
"angry.ogg": "złość",
"animal.ogg": "zwierzę",
"ankle.ogg": "kostka",
"ant.ogg": "mrówka",
"anteater.ogg": "mrówkojad",
"antelope.ogg": "antylopa",
"apple.ogg": "jabłko",
"apple_tree.ogg": "jabłoń",
"appliance.ogg": "agd",
"apricot.ogg": "morela",
"arm.ogg": "ręka",
"armchair.ogg": "fotel",
"artichoke.ogg": "karczoch",
"artist.ogg": "artysta",
"asparagus.ogg": "szparagi",
"astronaut.ogg": "astronauta",
- "ate.ogg": "jeść",
"athlete.ogg": "atleta",
"avocado.ogg": "awokado",
"ax.ogg": "siekiera",
"baby_bottle.ogg": "butelka",
"back.ogg": "plecy",
"badge.ogg": "odznaka",
"bag.ogg": "torba",
"bait.ogg": "przynęta",
- "bake.ogg": "piec",
"balance.ogg": "szalka",
"bald.ogg": "łysina",
"ball.ogg": "piłka",
"ball_of_yarn.ogg": "włóczka",
"ball_soccer.ogg": "piłka",
"ballet.ogg": "balet",
"bank.ogg": "bank",
+ "banker_female.ogg": "bankierka",
"bark.ogg": "szczekać",
"barn.ogg": "stodoła",
"bat.ogg": "nietoperz",
"bath.ogg": "wanna",
"bathing_suit.ogg": "strój kąpielowy",
"bay.ogg": "zatoka",
"beach.ogg": "plaża",
- "bead.ogg": "koralik",
"bean.ogg": "fasola",
"bear.ogg": "niedźwiedź",
"beard.ogg": "broda",
"beat.ogg": "bić",
"beaver.ogg": "bóbr",
"bed.ogg": "łóżko",
"bedroom.ogg": "sypialnia",
"bee.ogg": "pszczoła",
- "beef.ogg": "wołowina",
"beetle.ogg": "chrząszcz",
"beg.ogg": "prosić",
"behind.ogg": "za",
"bell.ogg": "dzwonek",
"belly.ogg": "brzuch",
"bench.ogg": "ławka",
"bib.ogg": "śliniak",
"big.ogg": "duży",
"big_top.ogg": "namiot",
"bike.ogg": "rower",
"bird.ogg": "ptak",
"bit.ogg": "gryz",
"bite.ogg": "gryźć",
"black.ogg": "czarny",
"blackberry.ogg": "jeżyna",
"blackbird.ogg": "kos",
"blade.ogg": "ostrze",
"blind.ogg": "ślepy",
"blink.ogg": "mrugać",
"block.ogg": "kostka",
"blond.ogg": "blond",
"blue.ogg": "niebieski",
"blueberry.ogg": "jagoda",
"blush.ogg": "rumieniec",
"board.ogg": "deska",
"boat.ogg": "łódź",
"boil.ogg": "gotować się",
"bolt.ogg": "nakrętka",
"bomb.ogg": "bomba",
"bone.ogg": "kość",
"book.ogg": "książka",
"bookcase.ogg": "biblioteczka",
"bottom.ogg": "tyłek",
"box.ogg": "pudło",
"boxer.ogg": "bokser",
"boy.ogg": "chłopiec",
"braid.ogg": "warkocz",
"brain.ogg": "mózg",
"branch.ogg": "gałąź",
"bread.ogg": "chleb",
"break.ogg": "łamać",
"breast.ogg": "biust",
"brick.ogg": "cegła",
"bricklayer.ogg": "murarz",
"bride.ogg": "panna młoda",
"bridge.ogg": "most",
"bright.ogg": "jasny",
"broccoli.ogg": "brokuł",
"brother.ogg": "brat",
"brown.ogg": "brązowy",
"brush.ogg": "pędzel",
"bubble.ogg": "bańka",
"bucket.ogg": "wiadro",
"bud.ogg": "pączek",
"buffalo.ogg": "bizon",
"bug.ogg": "owad",
"bulb.ogg": "żarówka",
"bull.ogg": "byk",
"bump.ogg": "guz",
"bun.ogg": "bochenek",
"bus.ogg": "autobus",
"bush.ogg": "krzaki",
"butcher.ogg": "rzeźnik",
"butter.ogg": "masło",
"butterfly.ogg": "motyl",
"button.ogg": "guzik",
"cabbage.ogg": "kapusta",
"cabin.ogg": "chata",
"cacao.ogg": "kakao",
"cactus.ogg": "kaktus",
"cage.ogg": "klatka",
"cake.ogg": "tort",
"call.ogg": "dzwonić",
"camel.ogg": "wielbłąd",
"camera.ogg": "aparat",
"camp.ogg": "obóz",
"can.ogg": "puszka",
"canary.ogg": "kanarek",
"candle.ogg": "świeczka",
"candy.ogg": "cukierek",
"cane.ogg": "laska",
"canoe.ogg": "kanu",
"canon.ogg": "armata",
"canyon.ogg": "kanion",
"cap.ogg": "czapka",
"cape.ogg": "peleryna",
"car.ogg": "samochód",
"carafe.ogg": "karafka",
"card.ogg": "karta",
"carnival.ogg": "karnawał",
"carpenter.ogg": "stolarz",
"carpet.ogg": "dywan",
"carrot.ogg": "marchewka",
"cart.ogg": "wózek",
"cash.ogg": "pieniądze",
"castle.ogg": "zamek",
"cat.ogg": "kot",
"cat_female.ogg": "kocica",
"catch.ogg": "łapać",
"caterpillar.ogg": "gąsienica",
"cauldron.ogg": "kocioł",
"cauliflower.ogg": "kalafior",
"cave.ogg": "jaskinia",
"cavern.ogg": "pieczara",
"celery.ogg": "seler",
"centipede.ogg": "stonoga",
"cereal.ogg": "zboże",
"chain.ogg": "łańcuch",
"chair.ogg": "krzesło",
"chalk.ogg": "kreda",
"chameleon.ogg": "kameleon",
"chandelier.ogg": "żyrandol",
"chat.ogg": "rozmawiać",
"cheek.ogg": "policzek",
"cheer.ogg": "dopingowanie",
"cheese.ogg": "ser",
"chef.ogg": "szef",
"cherry.ogg": "wiśnia",
"chest.ogg": "szkrzynia",
"chick.ogg": "kurczak",
"chicken.ogg": "kura",
- "chief.ogg": "wódz",
"child.ogg": "dziecko",
"chimney.ogg": "komin",
"chimp.ogg": "szympans",
"chin.ogg": "broda",
"chocolate.ogg": "czekolada",
"chop.ogg": "kroić",
- "chore.ogg": "",
+ "chores.ogg": "chóry",
"christmas.ogg": "boże narodzenie",
"cigar.ogg": "cygaro",
"circus.ogg": "cyrk",
"city.ogg": "miasto",
"clam.ogg": "małża",
- "clap.ogg": "klaśnięcie",
+ "clap.ogg": "klasnąć",
"class.ogg": "klasa",
"claw.ogg": "pazury",
"clay.ogg": "glina",
- "clean.ogg": "mycie się",
+ "clean.ogg": "myć się",
"cleaning_lady.ogg": "sprzątaczka",
"cliff.ogg": "klif",
"climb.ogg": "wspinaczka",
"clock.ogg": "zegar",
"cloth.ogg": "tkanina",
"clothes_hanger.ogg": "wieszak",
"cloud.ogg": "chmura",
"cloudy.ogg": "pochmurno",
"clover.ogg": "koniczyna",
"clown.ogg": "klaun",
"coach.ogg": "trener",
"coast.ogg": "wybrzeże",
"coat.ogg": "kurtka",
"cobra.ogg": "kobra",
"coconut.ogg": "kokos",
"cod.ogg": "dorsz",
"coffee.ogg": "kawa",
"coin.ogg": "moneta",
"cold.ogg": "zimno",
"color.ogg": "kolor",
"colt.ogg": "źrebak",
"comb.ogg": "grzebień",
"cone.ogg": "pachołek",
+ "cook.ogg": "gotować",
"cookie.ogg": "ciastko",
"cork.ogg": "korek",
"corn.ogg": "kukurydza",
"couch.ogg": "kanapa",
- "cough.ogg": "kaszlenie",
+ "cough.ogg": "kaszleć",
"couple.ogg": "para",
"cow.ogg": "krowa",
"cowboy.ogg": "kowboj",
"crab.ogg": "krab",
"cradle.ogg": "kołyska",
"craft.ogg": "robótki ręczne",
- "crawl.ogg": "raczkowanie",
+ "crawl.ogg": "raczkować",
"crazy.ogg": "zbzikowany",
"creek.ogg": "strumyk",
"crepe.ogg": "naleśnik",
"crib.ogg": "kołyska",
- "criminal.ogg": "kryminalista",
- "croak.ogg": "rechot",
+ "croak.ogg": "rechotać",
"crocodile.ogg": "krokodyl",
"cross.ogg": "krzyż",
"crow.ogg": "kruk",
"crown.ogg": "korona",
"crumb.ogg": "okruszek",
"crust.ogg": "skórka",
"cry.ogg": "płakać",
"crystal.ogg": "kryształ",
"cube.ogg": "kostka",
"cucumber.ogg": "ogórek",
"curtain.ogg": "kurtyna",
"cut.ogg": "ciąć",
"cute.ogg": "urocza",
"dad.ogg": "ojciec",
"daffodil.ogg": "żonkil",
"daisy.ogg": "stokrotka",
"dam.ogg": "zapora",
"dance.ogg": "taniec",
"dandelion.ogg": "mniszek",
- "danger.ogg": "zagrożenie",
- "dark.ogg": "ciemność",
"dart_board.ogg": "tarcza",
"date_fruit.ogg": "daktyl",
"deer.ogg": "jeleń",
"den.ogg": "nora",
"desert.ogg": "pustynia",
"desk.ogg": "biurko",
"dessert.ogg": "deser",
"diamond.ogg": "diament",
"dig.ogg": "kopać",
"dirt.ogg": "błoto",
"dirty.ogg": "brudny",
"dish.ogg": "naczynie",
"dishcloth.ogg": "ściereczka",
"dive.ogg": "nurkowanie",
"doctor.ogg": "lekarz",
"doe.ogg": "sarna",
"dog.ogg": "pies",
"doll.ogg": "lalka",
"dolphin.ogg": "delfin",
"domino.ogg": "domino",
"door.ogg": "drzwi",
"doormat.ogg": "wycieraczka",
"dot.ogg": "kropka",
"doughnut.ogg": "pączek",
"dove.ogg": "gołąb",
"dragon.ogg": "smok",
"dragonfly.ogg": "ważka",
- "drank.ogg": "picie",
- "draw.ogg": "rysowanie",
+ "draw.ogg": "rysować",
"drawer.ogg": "szuflada",
- "dream.ogg": "sen",
+ "dream.ogg": "śnić",
"dress.ogg": "suknia",
"drink.ogg": "napój",
- "drinking.ogg": "picie",
"drip.ogg": "kropla",
- "drive.ogg": "kierowanie",
+ "drive.ogg": "kierować",
"drool.ogg": "ślinić się",
"drum.ogg": "bębenek",
"dry.ogg": "suszyć",
"duck.ogg": "kaczka",
"duck_mother.ogg": "mama kaczka",
"dune.ogg": "wydma",
"dwarf.ogg": "krasnoludek",
"eagle.ogg": "orzeł",
"ear.ogg": "ucho",
"earth.ogg": "ziemia",
"eat.ogg": "jeść",
"egg.ogg": "jajko",
"eggplant.ogg": "bakłażan",
"elbow.ogg": "łokieć",
"electrician.ogg": "elektryk",
"elk.ogg": "łoś",
"empty.ogg": "pusta",
"engine.ogg": "silnik",
"engineer.ogg": "inżynier",
"eraser.ogg": "gumka",
"explore.ogg": "zwiedzanie",
"eyelash.ogg": "rzęsa",
"eyes.ogg": "oczy",
"face.ogg": "twarz",
"fair.ogg": "karuzela",
"fairy.ogg": "wróżka",
- "fall_down.ogg": "rozpaść się",
+ "fall.ogg": "spaść",
"fall_season.ogg": "jesień",
"family.ogg": "rodzina",
"fan.ogg": "wiatrak",
"farm.ogg": "gospodarstwo",
"farmer.ogg": "rolnik",
"fat.ogg": "gruby",
"faucet.ogg": "kran",
"fawn.ogg": "jelonek",
+ "fear.ogg": "strach",
"feast.ogg": "uczta",
"feather.ogg": "piórko",
"feed.ogg": "karmić",
- "feet.ogg": "stopa",
- "fell.ogg": "upaść",
"femur.ogg": "kość udowa",
"fetch.ogg": "łapać",
"fig.ogg": "figa",
"fin.ogg": "płetwa",
"find.ogg": "znaleźć",
"finger.ogg": "palec",
"fire.ogg": "ogień",
"fire_extinguisher.ogg": "gaśnica",
"fireman.ogg": "strażak",
"fish.ogg": "ryba",
"fisherman.ogg": "rybak",
"fist.ogg": "pięść",
"flacon.ogg": "flakon",
"flag.ogg": "flaga",
"flame.ogg": "płomień",
"flamingo.ogg": "flaming",
"flash.ogg": "latarka",
"flat.ogg": "płaskie",
"flies.ogg": "mucha",
- "flight.ogg": "latać",
"float.ogg": "pływać",
"flour.ogg": "mąka",
"flower.ogg": "kwiat",
"fluff.ogg": "puszek",
"flute.ogg": "flet",
"fly.ogg": "latać",
"foam.ogg": "piana",
- "food.ogg": "jedzenie",
"foot.ogg": "stopa",
"forest.ogg": "las",
"fork.ogg": "widelec",
"fountain.ogg": "fontanna",
"fox.ogg": "lis",
"freeze.ogg": "zamarzać",
"friend.ogg": "przyjaciel",
"fries.ogg": "frytki",
"frog.ogg": "żaba",
"front.ogg": "z przodu",
- "frown.ogg": "złościć się",
"fruit.ogg": "owoc",
"fudge.ogg": "krówka",
"full.ogg": "pełna",
- "fun.ogg": "zabawa",
"fur.ogg": "futro",
"game.ogg": "gra",
"garage.ogg": "garaż",
"garden.ogg": "ogród",
"garlic.ogg": "czosnek",
"gem.ogg": "klejnot",
"giant.ogg": "olbrzymi",
"gift.ogg": "prezent",
"giraffe.ogg": "żyrafa",
"girl.ogg": "dziewczynka",
"glass.ogg": "szklanka",
"glasses.ogg": "okulary",
"glove.ogg": "rękawiczka",
"glue.ogg": "klej",
"gnome.ogg": "krasnal",
"goat.ogg": "koza",
"golden.ogg": "złota",
"golf.ogg": "golf",
"goose.ogg": "gęś",
"gorilla.ogg": "gory",
"grain.ogg": "zboże",
"grandmother.ogg": "babcia",
"grape.ogg": "winogrono",
"grapefruit.ogg": "grejfrut",
"grass.ogg": "trawa",
"grave.ogg": "grób",
"gray.ogg": "szary",
"green.ogg": "zielony",
"grill.ogg": "grill",
"grin.ogg": "uśmiech",
"ground.ogg": "gleba",
"growl.ogg": "szczerzyć",
"guignol.ogg": "guignol",
"guinea_pig.ogg": "świnka morska",
"gum.ogg": "guma",
"hair.ogg": "włosy",
"hair_dryer.ogg": "suszarka",
"half.ogg": "pół",
"ham.ogg": "szynka",
+ "hamburger.ogg": "hamburger",
"hammer.ogg": "młotek",
"hand.ogg": "ręka",
"handlebar.ogg": "uchwyt",
"happy.ogg": "szczęśliwy",
"harp.ogg": "harfa",
"hat.ogg": "czapka",
"hatch.ogg": "wykluć się",
"hay.ogg": "siano",
"head.ogg": "głowa",
"hear.ogg": "słuchać",
"heat.ogg": "ciepło",
"hedge.ogg": "płot",
"hedgehog.ogg": "jeż",
"heel.ogg": "obcas",
"helmet.ogg": "hełm",
"hen.ogg": "kura",
"herd.ogg": "stado",
"high.ogg": "wysoko",
"hike.ogg": "wędrówka",
"hill.ogg": "wzgórze",
"hip.ogg": "biodra",
"hippopotamus.ogg": "hipopotam",
"hit.ogg": "uderzyć",
"hive.ogg": "ul",
"hockey.ogg": "hokej",
"hole.ogg": "dziura",
"home.ogg": "dom",
"hook.ogg": "haczyk",
"hop.ogg": "skakanie",
"horse.ogg": "koń",
"hose.ogg": "wąż",
"hospital.ogg": "szpital",
"hot.ogg": "gorący",
"hot_dog.ogg": "hot dog",
"hound.ogg": "pies",
"house.ogg": "dom",
- "howl.ogg": "wycie",
+ "howl.ogg": "wyć",
"hug.ogg": "przytulać",
"huge.ogg": "ogromny",
"hummingbird.ogg": "koliber",
- "hunchback.ogg": "garbaty",
+ "hunchbacked.ogg": "garbaty",
"hunter.ogg": "myśliwy",
"husband.ogg": "mąż",
"hut.ogg": "chata",
"hyena.ogg": "hiena",
"ice.ogg": "lód",
"iceberg.ogg": "lodowiec",
"iguana.ogg": "iguana",
"ill.ogg": "chory",
"ink.ogg": "atrament",
"island.ogg": "wyspa",
"jacket.ogg": "kurtka",
"jaguar.ogg": "jaguar",
"jam.ogg": "dżem",
"jay.ogg": "sójka",
"jelly.ogg": "galaretka",
"jellyfish.ogg": "meduza",
"jewel.ogg": "klejnot",
"job.ogg": "praca",
"jockey.ogg": "jeździec",
"jog.ogg": "bieganie",
+ "joy.ogg": "radość",
"judge.ogg": "sędzia",
"judo.ogg": "judo",
"juggler.ogg": "żąglerka",
"juice.ogg": "sok",
- "jump.ogg": "skok",
+ "jump.ogg": "skakać",
"kangaroo.ogg": "kangur",
"keel.ogg": "kręgiel",
"kernel.ogg": "pestka",
"keyboard.ogg": "klawiatura",
"kimono.ogg": "kimono",
"king.ogg": "król",
"kiss.ogg": "całować",
"kitchen.ogg": "kuchnia",
"kite.ogg": "latawiec",
"kitten.ogg": "kotek",
"kiwi.ogg": "kiwi",
"knee.ogg": "kolano",
"kneel.ogg": "klękać",
"knife.ogg": "nóż",
"knight.ogg": "rycerz",
"knit.ogg": "szydełkować",
"knot.ogg": "węzeł",
"koala.ogg": "koala",
"lad.ogg": "chłopiec",
"lady.ogg": "kobieta",
"ladybug.ogg": "biedronka",
"lake.ogg": "jezioro",
"lama.ogg": "lama",
"lamb.ogg": "owca",
"lamp.ogg": "lampa",
"land.ogg": "teren",
"lane.ogg": "droga",
"lap.ogg": "kolana",
"lasso.ogg": "lasso",
"laugh.ogg": "śmiać się",
"lava.ogg": "lawa",
"lawn.ogg": "trawnik",
"lawyer.ogg": "prawnik",
"leaf.ogg": "liść",
"ledge.ogg": "półka",
"leek.ogg": "por",
"left.ogg": "lewy",
"leg.ogg": "noga",
- "leg_animal.ogg": "noga",
"lemon.ogg": "cytryna",
"lemonade.ogg": "lemoniada",
"lemur.ogg": "lemur",
"leopard.ogg": "leopard",
"lettuce.ogg": "sałata",
"librarian.ogg": "bibliotekarz",
"lick.ogg": "lizać",
"lid.ogg": "pokrywka",
"lift.ogg": "podnosić",
"light.ogg": "lampa",
"lighthouse.ogg": "latarnia",
"lightning.ogg": "piorun",
"lilac.ogg": "bez",
"lime.ogg": "limonka",
"line.ogg": "linia",
"link.ogg": "ogniowo",
"lion.ogg": "lew",
"lion_cub.ogg": "lwiątko",
"lip.ogg": "usta",
"liquid.ogg": "płynny",
"lizard.ogg": "jaszczurka",
"lobster.ogg": "homar",
"log.ogg": "kłoda",
"look.ogg": "patrzeć",
"lunch.ogg": "śniadanie",
"mad.ogg": "złość",
"magic.ogg": "magiczny",
"magnet.ogg": "magnes",
"magnifying_glass.ogg": "szkło powiększające",
"magpie.ogg": "sroka",
"mail.ogg": "list",
"man.ogg": "mężczyzna",
"mane.ogg": "grzywa",
"mango.ogg": "mango",
"map.ogg": "mapa",
"maple.ogg": "klon",
"marble.ogg": "marmur",
"mashed_potatoes.ogg": "puree",
"mask.ogg": "maska",
"mast.ogg": "maszt",
"mat.ogg": "mata",
"match.ogg": "zapałki",
"mate.ogg": "kolega",
"mattress.ogg": "materac",
"mauve.ogg": "fiołkowy",
"meal.ogg": "posiłek",
"meat.ogg": "mięso",
"mechanic.ogg": "mechanik",
"medal.ogg": "medal",
"meet.ogg": "spotykać się",
"melon.ogg": "melon",
- "men.ogg": "ludzie",
"merry-go-round.ogg": "karuzela",
"mice.ogg": "mysz",
"microphone.ogg": "mikrofon",
"milk.ogg": "mleko",
"mill.ogg": "wiatrak",
"mimosa.ogg": "mimoza",
"mirror.ogg": "lustro",
"mixer.ogg": "mikser",
"mole.ogg": "kret",
"mom.ogg": "mama",
"moon.ogg": "księżyc",
"moose.ogg": "łoś",
"mop.ogg": "mop",
"mosque.ogg": "meczet",
"mosquito.ogg": "komar",
"mother.ogg": "matka",
"motorcycle.ogg": "motocykl",
"mountain.ogg": "góra",
"mouse.ogg": "mysz",
"mouth.ogg": "usta",
"movie.ogg": "film",
"mower.ogg": "kosiarka",
"mud.ogg": "błoto",
"mug.ogg": "filiżanka",
"mule.ogg": "osioł",
"muscle.ogg": "mięsień",
"mushroom.ogg": "grzyb",
"music.ogg": "muzyka",
"musician.ogg": "muzyk",
"naked.ogg": "nagi",
"nap.ogg": "drzemka",
"navel.ogg": "pępek",
"neck.ogg": "kark",
"necklace.ogg": "naszyjnik",
"needle.ogg": "igła",
"nest.ogg": "gniazdo",
"net.ogg": "siatka",
"newspaper.ogg": "gazeta",
"night.ogg": "noc",
"nightgown.ogg": "koszula nocna",
"nose.ogg": "nos",
"nostril.ogg": "nozdrza",
"notebook.ogg": "zeszyt",
"number.ogg": "liczba",
"nun.ogg": "zakonnica",
"nurse.ogg": "pielęgniarz",
"nurse_male.ogg": "pielęgniarka",
"nut.ogg": "orzech",
"oar.ogg": "wiosła",
"ocean.ogg": "ocean",
"office.ogg": "biuro",
"olive.ogg": "oliwka",
"on.ogg": "na",
"onion.ogg": "cebula",
"open.ogg": "otwarte",
"opossum.ogg": "opos",
"orange-color.ogg": "pomarańczowy",
"orange.ogg": "pomarańcza",
"orchid.ogg": "orchidea",
"ostrich.ogg": "struś",
"otter.ogg": "wydra",
"owl.ogg": "sowa",
"ox.ogg": "wół",
"oyster.ogg": "małża",
"pacifier.ogg": "smoczek",
"page.ogg": "strona",
"pair.ogg": "para",
"pajamas.ogg": "pidżama",
"pal.ogg": "kolega",
"palm_tree.ogg": "palma",
"pan.ogg": "patelnia",
"panda.ogg": "panda",
"panther.ogg": "pantera",
"panties.ogg": "majtki",
"pants.ogg": "spodnie",
"papaya.ogg": "papaja",
"paper.ogg": "papier",
"parachute.ogg": "spadochron",
"parakeet.ogg": "papużka",
"parrot.ogg": "papuga",
"patch.ogg": "łata",
"path.ogg": "ścieżka",
"paw.ogg": "łapa",
"pea.ogg": "groszek",
"peach.ogg": "brzoskwinia",
"peacock.ogg": "paw",
"peak.ogg": "szczyt",
"pear.ogg": "gruszka",
"pearl.ogg": "perła",
"peck.ogg": "dziobać",
"pedal.ogg": "pedał",
"pelican.ogg": "pelikan",
"pen.ogg": "długopis",
"pencil.ogg": "ołówek",
"peony.ogg": "piwonia",
"people.ogg": "ludzie",
"pepper.ogg": "pieprz",
"peppers.ogg": "papryczki",
"pet.ogg": "zwierzęta",
"petal.ogg": "płatek",
- "petite.ogg": "drobna",
"phone.ogg": "telefon",
"piano.ogg": "pianino",
"picture.ogg": "zdjęcie",
"pie.ogg": "ciasto",
"pig.ogg": "świnia",
"pigeon.ogg": "gołąb",
"pill.ogg": "pigułka",
"pillow.ogg": "poduszka",
"pilot.ogg": "pilot",
"pine.ogg": "sosna",
"pine_cone.ogg": "szyszka",
"pink.ogg": "różowy",
"pip.ogg": "pestka",
"pipe.ogg": "fajka",
"piranha.ogg": "pirania",
"pirate.ogg": "pirat",
"pizza.ogg": "pizza",
"plane.ogg": "samolot",
"planet.ogg": "planeta",
"plant.ogg": "roślina",
"plate.ogg": "talerz",
"play.ogg": "bawić się",
"pliers.ogg": "obcążki",
"plow.ogg": "orać",
"plum.ogg": "śliwka",
"plumber.ogg": "hydraulik",
"pocket.ogg": "kieszeń",
"pod.ogg": "łupina",
"pole.ogg": "słupek",
"police.ogg": "policjant",
"pompon.ogg": "pompony",
"pond.ogg": "sadzawka",
"pony.ogg": "kucyk",
"pool.ogg": "pływalnia",
- "pop.ogg": "popkorn",
+ "popcorn.ogg": "popkorn",
"pope.ogg": "papież",
"porthole.ogg": "właz okienny",
"post.ogg": "poczta",
"pot.ogg": "garnek",
"potato.ogg": "ziemniak",
"pounce.ogg": "doskakiwać",
"president.ogg": "prezydent",
"pretty.ogg": "ładna",
"price.ogg": "cena",
"priest.ogg": "ksiądz",
"prince.ogg": "książe",
"princess.ogg": "księżniczka",
"prison.ogg": "więzienie",
"prisoner.ogg": "więzień",
"prize.ogg": "nagroda",
"pug.ogg": "mops",
"pull.ogg": "ciągnąć",
"pullover.ogg": "sweter",
"pumpkin.ogg": "dynia",
"puppy.ogg": "szczeniak",
"pyramid.ogg": "piramida",
"quarrel.ogg": "kłócić się",
"queen.ogg": "królowa",
"question.ogg": "pytanie",
"quilt.ogg": "kołdra",
"quiz.ogg": "kwiz",
"rabbit.ogg": "królik",
"rabbit_baby.ogg": "króliczek",
"race.ogg": "wyścig",
"radio.ogg": "radio",
"radish.ogg": "rzodkiewka",
"raft.ogg": "tratwa",
"rag.ogg": "szmatka",
"rage.ogg": "złość",
"rain.ogg": "deszcz",
"raincoat.ogg": "płaszcz",
"rake.ogg": "grabie",
"ramp.ogg": "rampa",
"ran.ogg": "bieg",
"raspberry.ogg": "malina",
"rat.ogg": "szczur",
"razor.ogg": "golarka",
"read.ogg": "czytać",
"red.ogg": "czerwony",
"reptile.ogg": "wąż",
"rhinoceros.ogg": "nosorożec",
"rice.ogg": "ryż",
"ride.ogg": "kolarstwo",
"rifle.ogg": "karabin",
"right.ogg": "prawo",
"rip.ogg": "chować",
"rise.ogg": "wzrost",
"river.ogg": "rzeka",
"road.ogg": "droga",
"roast.ogg": "pieczeń",
"robe.ogg": "szata",
"robot.ogg": "robot",
"rock.ogg": "skała",
"rocket.ogg": "rakieta",
"rolling_pin.ogg": "wałek",
"roof.ogg": "dach",
"room.ogg": "pokój",
"root.ogg": "korzeń",
"rope.ogg": "skakanka",
"rose.ogg": "róża",
"round.ogg": "okrągły",
"rowing.ogg": "wioślarstwo",
"royal.ogg": "królewski",
"rug.ogg": "dywan",
"run.ogg": "biegać",
- "sad.ogg": "smutna",
+ "sad.ogg": "smutek",
"saddle.ogg": "siodło",
"sail.ogg": "żagiel",
"sailor.ogg": "żeglarz",
"salamander.ogg": "salamandra",
"salmon.ogg": "łosoś",
"sand.ogg": "piasek",
"sandals.ogg": "sandały",
"sandwich.ogg": "kanapka",
"sash.ogg": "szarfa",
- "sat.ogg": "siedzieć",
"sauce.ogg": "sos",
"sausage.ogg": "kiełbasa",
"scale.ogg": "waga",
"scar.ogg": "blizna",
- "scared.ogg": "wystraszyć się",
+ "scare.ogg": "wystraszyć się",
"scarf.ogg": "szalik",
"school.ogg": "szkoła",
"school_bag.ogg": "tornister",
"science.ogg": "nauka",
"scissors.ogg": "nożyczki",
"scorpion.ogg": "skorpion",
"scratch.ogg": "drapać",
"scream.ogg": "krzyczeć",
"screw.ogg": "wkręt",
"screwdriver.ogg": "śrubokręt",
"scribble.ogg": "bazgrać",
"sea.ogg": "morze",
"seat.ogg": "krzesło",
"see.ogg": "widzieć",
"seed.ogg": "ziarna",
"shadow.ogg": "cień",
"shake.ogg": "potrząsać",
"shark.ogg": "rekin",
"shave.ogg": "golić",
"shed.ogg": "szopa",
"sheep.ogg": "owca",
"shelf.ogg": "półka",
"shell.ogg": "muszla",
"ship.ogg": "łódź",
"shirt.ogg": "koszula",
"shoe.ogg": "but",
"shoelace.ogg": "sznurówki",
"shop.ogg": "sklep",
"shore.ogg": "wybrzeże",
"short.ogg": "szorty",
"shovel.ogg": "szufelka",
"shower.ogg": "prysznic",
"shrimp.ogg": "krewetka",
"shrub.ogg": "krzew",
"shut.ogg": "zamknięte",
"shutter.ogg": "okiennica",
"sick.ogg": "chory",
"sidewalk.ogg": "chodnik",
"sign.ogg": "znak",
"sing.ogg": "śpiewać",
"sink.ogg": "umywalka",
"sip.ogg": "ssać",
"sister.ogg": "siostra",
"sit.ogg": "siedzieć",
"skate.ogg": "jazda na desce",
"skeleton.ogg": "szkielet",
"ski.ogg": "narciarstwo",
"skimmer.ogg": "cedzak",
"skin.ogg": "skóra",
"skirt.ogg": "spódnica",
"skunk.ogg": "skunks",
"sky.ogg": "niebo",
"slam.ogg": "wsad",
"sled.ogg": "sanki",
"sleep.ogg": "spać",
"sleeve.ogg": "rękaw",
"sleigh.ogg": "sanie",
"slide.ogg": "zjeżdżalnia",
"slim.ogg": "szczupła",
"slime.ogg": "śluz",
"slippers.ogg": "kapcie",
"slope.ogg": "serpentyna",
"sloppy.ogg": "niedbały",
"slot.ogg": "szczelina",
"sloth.ogg": "leniwiec",
"slug.ogg": "ślimak",
"small.ogg": "mała",
"smell.ogg": "wąchać",
"smile.ogg": "uśmiech",
"smock.ogg": "kaftan",
"smoke.ogg": "dym",
"smooch.ogg": "całować",
"snack.ogg": "przekąski",
"snail.ogg": "ślimak",
"snake.ogg": "wąż",
"sneaker.ogg": "but",
"sniff.ogg": "wąchać",
"snow.ogg": "śnieg",
"soap.ogg": "mydło",
"sob.ogg": "szlochać",
"sock.ogg": "skarpeta",
"soldier.ogg": "żołnierz",
"sole.ogg": "sola",
"sole_shoe.ogg": "podeszwa",
"son.ogg": "syn",
"soup.ogg": "zupa",
"spade.ogg": "szpadel",
"spaghetti.ogg": "spaghetti",
"spark.ogg": "iskra",
"sparrow.ogg": "wróbel",
"spatula.ogg": "szpatułka",
"speak.ogg": "mówić",
"spear.ogg": "włócznia",
"spice.ogg": "przyprawy",
"spider.ogg": "pająk",
"spider_web.ogg": "sieć",
"spike.ogg": "jeż",
"spill.ogg": "rozlać",
"spinach.ogg": "szpinak",
"spine.ogg": "kręgosłup",
"spinning_top.ogg": "bąk",
"splash.ogg": "chlustać",
"splatter.ogg": "bryzg",
"sponge.ogg": "szwamka",
"spool.ogg": "włóczka",
"spoon.ogg": "łyżka",
"sport.ogg": "sport",
"spot.ogg": "miejsce",
"spray.ogg": "rozpylać",
"spread.ogg": "rozsmarowywać",
"spring.ogg": "bujać",
"spring_season.ogg": "lato",
"sprinkle.ogg": "posypka",
"square.ogg": "kwadrat",
"squash.ogg": "kabaczek",
"squat.ogg": "przysiad",
"squid.ogg": "kałamarnica",
"squirrel.ogg": "wiewiórka",
"squirt.ogg": "spryskiwacz",
"stack.ogg": "stos",
"stage.ogg": "scena",
"staircase.ogg": "schody",
"stamp.ogg": "znaczek",
"stand.ogg": "stojący",
"star.ogg": "gwiazda",
"stare.ogg": "wzrok",
"starfish.ogg": "rozgwiazda",
- "steak.ogg": "stek",
"steam.ogg": "para",
"steep.ogg": "stromo",
"steeple.ogg": "wieża",
"stem.ogg": "łodyga",
"step.ogg": "schodek",
"stew.ogg": "potrawa",
"stick.ogg": "gałąź",
"sting.ogg": "żądło",
"stinky.ogg": "śmierdzący",
"stitch.ogg": "zszywać",
"stomach.ogg": "żołądek",
"stone.ogg": "kamień",
"stop.ogg": "stop",
"store.ogg": "sklep",
"stove.ogg": "palnik",
"straight.ogg": "prosta",
"strainer.ogg": "sitko",
"straw.ogg": "słomka",
"strawberry.ogg": "truskawka",
"stream.ogg": "strumień",
"street.ogg": "ulica",
"stretch.ogg": "rozciągać się",
"string.ogg": "nitka",
"stripe.ogg": "paski",
"strong.ogg": "silny",
"student.ogg": "uczeń",
"study.ogg": "uczyć się",
"stump.ogg": "pień",
"sugar.ogg": "cukier",
"suit.ogg": "garnitur",
"suitcase.ogg": "walizka",
"summer.ogg": "lato",
"summit.ogg": "szczyt",
"sun.ogg": "słońce",
"swan.ogg": "łabędź",
"sweat.ogg": "pot",
"sweatshirt.ogg": "bluza",
"swim.ogg": "pływanie",
"table.ogg": "stół",
"tablecloth.ogg": "obrus",
"tadpole.ogg": "kijanki",
"tag.ogg": "zawieszka",
"tail.ogg": "ogon",
"tall.ogg": "wysoki",
"tape_measure.ogg": "miara",
"taxi.ogg": "taxi",
"teach.ogg": "nauczać",
"teacher.ogg": "nauczyciel",
"tear.ogg": "rozrywać",
"teddy.ogg": "miś",
"teeth.ogg": "zęby",
"television.ogg": "telewizor",
"temple.ogg": "świątynia",
"tennis.ogg": "tenis",
"tent.ogg": "namiot",
"text.ogg": "tekst",
"thick.ogg": "thick",
"thief.ogg": "złodziej",
"thigh.ogg": "udo",
"think.ogg": "myśleć",
"thread.ogg": "nić",
"throat.ogg": "gardło",
"throw.ogg": "rzut",
"thumb.ogg": "kciuk",
"tick.ogg": "kleszcz",
"ticket.ogg": "bilet",
"tiger.ogg": "tygrys",
"time.ogg": "czas",
"tin.ogg": "konserwa",
"tire.ogg": "opona",
"tired.ogg": "zmęczony",
"tissue.ogg": "chusteczka",
+ "to_drink.ogg": "pić",
"toad.ogg": "ropucha",
"toaster.ogg": "toster",
"toe.ogg": "palec",
"toilet.ogg": "klozet",
"tomatoe.ogg": "pomidor",
"tongs.ogg": "szczypce",
"tongue.ogg": "język",
"tool.ogg": "narzędzie",
"top.ogg": "szczyt",
"torch.ogg": "pochodnia",
"touch.ogg": "dotyk",
"towel.ogg": "ręcznik",
"toy.ogg": "zabawka",
"trail.ogg": "szlak",
"train.ogg": "pociąg",
"train_station.ogg": "stacja",
"trap.ogg": "pułapka",
"trash.ogg": "śmieci",
"tray.ogg": "taca",
"treat.ogg": "smakołyki",
"tree.ogg": "drzewo",
"triangle.ogg": "trójkąt",
"tribe.ogg": "plemie",
"trip.ogg": "podróż",
"truck.ogg": "ciężarówka",
"tube.ogg": "szminka",
"tulip.ogg": "tulipan",
"tune.ogg": "melodia",
"turkey.ogg": "indyk",
"turnip.ogg": "rzepa",
"turtle.ogg": "żółw",
"tusk.ogg": "kły",
"twin_boys.ogg": "bliźniaki",
"twin_girls.ogg": "bliźniaczki",
"umbrella.ogg": "parasol",
"under.ogg": "pod",
"uniform.ogg": "mundur",
"van.ogg": "van",
"vapor.ogg": "para",
"vase.ogg": "waza",
"vegetable.ogg": "warzywo",
"vein.ogg": "żyły",
"verdure.ogg": "chaszcze",
"vest.ogg": "kamizelka",
"vet.ogg": "weterynarz",
"viper.ogg": "żmija",
"vowel.ogg": "samogłoski",
"vulture.ogg": "sęp",
"wag.ogg": "merdać",
"walk.ogg": "iść",
"wall.ogg": "ściana",
"walnut.ogg": "orzech",
"wart.ogg": "odcisk",
"wash.ogg": "myć się",
"wasp.ogg": "osa",
"watch.ogg": "zegarek",
"water.ogg": "woda",
"wave.ogg": "fala",
"wedding.ogg": "ślub",
"wedge.ogg": "klin",
"weight.ogg": "ciężar",
"wet.ogg": "mokry",
"whale.ogg": "wieloryb",
"wheat.ogg": "pszenica",
"wheel.ogg": "koło",
"whisk.ogg": "trzepaczka",
"whisper.ogg": "szept",
"white.ogg": "biały",
"wide.ogg": "szeroki",
"wife.ogg": "żona",
"wig.ogg": "peruka",
"win.ogg": "wygrać",
"wind.ogg": "wiatr",
"window.ogg": "okno",
"window_glass.ogg": "szyba",
"wing.ogg": "skrzydło",
"winter.ogg": "zima",
"wolf.ogg": "wilk",
"woman.ogg": "kobieta",
"wood.ogg": "deski",
"word.ogg": "słowa",
"worker.ogg": "robotnik",
"world.ogg": "świat",
"wreath.ogg": "wieniec",
"wrench.ogg": "klucz",
"wrist.ogg": "nadgarstek",
"write.ogg": "pisać",
- "yarn.ogg": "przędza",
"yellow.ogg": "żółty",
"yogurt.ogg": "jogurt",
"yum.ogg": "ochota",
"zebra.ogg": "zebra",
"zipper.ogg": "zamek",
"zoo.ogg": "zoo"
-}
+}
\ No newline at end of file
diff --git a/src/activities/lang/resource/content-pt.json b/src/activities/lang/resource/content-pt.json
new file mode 100644
index 000000000..936f73c9e
--- /dev/null
+++ b/src/activities/lang/resource/content-pt.json
@@ -0,0 +1,1092 @@
+{
+ "10.ogg": "dez",
+ "11.ogg": "onze",
+ "12.ogg": "doze",
+ "16.ogg": "dezasseis",
+ "U0030.ogg": "zero",
+ "U0031.ogg": "um",
+ "U0032.ogg": "dois",
+ "U0033.ogg": "três",
+ "U0034.ogg": "quatro",
+ "U0035.ogg": "cinco",
+ "U0036.ogg": "seis",
+ "U0037.ogg": "sete",
+ "U0038.ogg": "oito",
+ "U0039.ogg": "nove",
+ "accountant.ogg": "contabilista",
+ "ache.ogg": "dor",
+ "acorn.ogg": "bolota",
+ "actor.ogg": "actor",
+ "air_horn.ogg": "corneta",
+ "alarmclock.ogg": "despertador",
+ "alligator.ogg": "crocodilo",
+ "alphabet.ogg": "alfabeto",
+ "anchor.ogg": "âncora",
+ "angel.ogg": "anjo",
+ "angry.ogg": "zangado",
+ "animal.ogg": "animal",
+ "ankle.ogg": "tornozelo",
+ "ant.ogg": "formiga",
+ "anteater.ogg": "papa-formigas",
+ "antelope.ogg": "antílope",
+ "apple.ogg": "maçã",
+ "apple_tree.ogg": "macieira",
+ "appliance.ogg": "objecto",
+ "apricot.ogg": "alperce",
+ "arm.ogg": "braço",
+ "armchair.ogg": "poltrona",
+ "artichoke.ogg": "alcachofra",
+ "artist.ogg": "artista",
+ "asparagus.ogg": "espargo",
+ "astronaut.ogg": "astronauta",
+ "athlete.ogg": "atleta",
+ "avocado.ogg": "abacate",
+ "ax.ogg": "machado",
+ "baby_bottle.ogg": "biberão",
+ "back.ogg": "costas",
+ "badge.ogg": "medalha",
+ "bag.ogg": "saco",
+ "bait.ogg": "isco",
+ "balance.ogg": "balança",
+ "bald.ogg": "careca",
+ "ball.ogg": "bola",
+ "ball_of_yarn.ogg": "novelo",
+ "ball_soccer.ogg": "bola de futebol",
+ "ballet.ogg": "ballet",
+ "bank.ogg": "banco",
+ "banker_female.ogg": "bancária",
+ "bark.ogg": "ladrar",
+ "barn.ogg": "celeiro",
+ "bat.ogg": "morcego",
+ "bath.ogg": "banheira",
+ "bathing_suit.ogg": "fato de banho",
+ "bay.ogg": "baía",
+ "beach.ogg": "praia",
+ "bean.ogg": "feijão",
+ "bear.ogg": "urso",
+ "beard.ogg": "barba",
+ "beat.ogg": "bater",
+ "beaver.ogg": "castor",
+ "bed.ogg": "cama",
+ "bedroom.ogg": "quarto",
+ "bee.ogg": "abelha",
+ "beetle.ogg": "escaravelho",
+ "beg.ogg": "pedir",
+ "behind.ogg": "atrás",
+ "bell.ogg": "campainha",
+ "belly.ogg": "barriga",
+ "bench.ogg": "banco",
+ "bib.ogg": "bibe",
+ "big.ogg": "grande",
+ "big_top.ogg": "cúpula",
+ "bike.ogg": "bicicleta",
+ "bird.ogg": "pássaro",
+ "bit.ogg": "bit",
+ "bite.ogg": "morder",
+ "black.ogg": "preto",
+ "blackberry.ogg": "amora",
+ "blackbird.ogg": "melro",
+ "blade.ogg": "lâmina",
+ "blind.ogg": "cego",
+ "blink.ogg": "piscar",
+ "block.ogg": "bloco",
+ "blond.ogg": "louro",
+ "blue.ogg": "azul",
+ "blueberry.ogg": "mirtilo",
+ "blush.ogg": "corado",
+ "board.ogg": "tabuleiro",
+ "boat.ogg": "barco",
+ "boil.ogg": "cozer",
+ "bolt.ogg": "parafuso",
+ "bomb.ogg": "bomba",
+ "bone.ogg": "osso",
+ "book.ogg": "livro",
+ "bookcase.ogg": "estante",
+ "bottom.ogg": "fundo",
+ "box.ogg": "caixa",
+ "boxer.ogg": "pugilista",
+ "boy.ogg": "rapaz",
+ "braid.ogg": "trança",
+ "brain.ogg": "cérebro",
+ "branch.ogg": "ramo",
+ "bread.ogg": "pão",
+ "break.ogg": "quebrar",
+ "breast.ogg": "peito",
+ "brick.ogg": "tijolo",
+ "bricklayer.ogg": "pedreiro",
+ "bride.ogg": "noiva",
+ "bridge.ogg": "ponte",
+ "bright.ogg": "brilhante",
+ "broccoli.ogg": "brócolo",
+ "brother.ogg": "irmão",
+ "brown.ogg": "castanho",
+ "brush.ogg": "pincel",
+ "bubble.ogg": "bolha",
+ "bucket.ogg": "balde",
+ "bud.ogg": "rebento",
+ "buffalo.ogg": "búfalo",
+ "bug.ogg": "insecto",
+ "bulb.ogg": "lâmpada",
+ "bull.ogg": "touro",
+ "bump.ogg": "inchaço",
+ "bun.ogg": "brioche",
+ "bus.ogg": "autocarro",
+ "bush.ogg": "arbusto",
+ "butcher.ogg": "talhante",
+ "butter.ogg": "manteiga",
+ "butterfly.ogg": "borboleta",
+ "button.ogg": "botão",
+ "cabbage.ogg": "repolho",
+ "cabin.ogg": "cabana",
+ "cacao.ogg": "cacau",
+ "cactus.ogg": "cacto",
+ "cage.ogg": "gaiola",
+ "cake.ogg": "bolo",
+ "call.ogg": "chamar",
+ "camel.ogg": "camelo",
+ "camera.ogg": "câmara",
+ "camp.ogg": "campo",
+ "can.ogg": "lata",
+ "canary.ogg": "canário",
+ "candle.ogg": "vela",
+ "candy.ogg": "doce",
+ "cane.ogg": "bengala",
+ "canoe.ogg": "canoa",
+ "canon.ogg": "cânone",
+ "canyon.ogg": "penhasco",
+ "cap.ogg": "boné",
+ "cape.ogg": "capa",
+ "car.ogg": "carro",
+ "carafe.ogg": "jarro",
+ "card.ogg": "cartão",
+ "carnival.ogg": "carnaval",
+ "carpenter.ogg": "carpinteiro",
+ "carpet.ogg": "carpete",
+ "carrot.ogg": "cenoura",
+ "cart.ogg": "cesto",
+ "cash.ogg": "dinheiro",
+ "castle.ogg": "castelo",
+ "cat.ogg": "gato",
+ "cat_female.ogg": "gata",
+ "catch.ogg": "apanhar",
+ "caterpillar.ogg": "lagarta",
+ "cauldron.ogg": "caldeirão",
+ "cauliflower.ogg": "couve-flor",
+ "cave.ogg": "gruta",
+ "cavern.ogg": "caverna",
+ "celery.ogg": "aipo",
+ "centipede.ogg": "centopeia",
+ "cereal.ogg": "cereal",
+ "chain.ogg": "corrente",
+ "chair.ogg": "cadeira",
+ "chalk.ogg": "giz",
+ "chameleon.ogg": "camaleão",
+ "chandelier.ogg": "candelabro",
+ "chat.ogg": "conversar",
+ "cheek.ogg": "bochecha",
+ "cheer.ogg": "animar",
+ "cheese.ogg": "queijo",
+ "chef.ogg": "cozinheiro",
+ "cherry.ogg": "cereja",
+ "chest.ogg": "arca",
+ "chick.ogg": "passarinho",
+ "chicken.ogg": "galinha",
+ "child.ogg": "filho",
+ "chimney.ogg": "chaminé",
+ "chimp.ogg": "chimpanzé",
+ "chin.ogg": "queixo",
+ "chocolate.ogg": "chocolate",
+ "chop.ogg": "cortar",
+ "chores.ogg": "tarefas",
+ "christmas.ogg": "natal",
+ "cigar.ogg": "cigarro",
+ "circus.ogg": "circo",
+ "city.ogg": "cidade",
+ "clam.ogg": "amêijoa",
+ "clap.ogg": "bater palmas",
+ "class.ogg": "aula",
+ "claw.ogg": "garra",
+ "clay.ogg": "barro",
+ "clean.ogg": "limpar",
+ "cleaning_lady.ogg": "empregada de limpezas",
+ "cliff.ogg": "penhasco",
+ "climb.ogg": "trepar",
+ "clock.ogg": "relógio",
+ "cloth.ogg": "tecido",
+ "clothes_hanger.ogg": "bengaleiro",
+ "cloud.ogg": "nuvem",
+ "cloudy.ogg": "nublado",
+ "clover.ogg": "trevo",
+ "clown.ogg": "palhaço",
+ "coach.ogg": "treinador",
+ "coast.ogg": "costa",
+ "coat.ogg": "casaco",
+ "cobra.ogg": "cobra",
+ "coconut.ogg": "coco",
+ "cod.ogg": "bacalhau",
+ "coffee.ogg": "café",
+ "coin.ogg": "moeda",
+ "cold.ogg": "frio",
+ "color.ogg": "cor",
+ "colt.ogg": "potro",
+ "comb.ogg": "pente",
+ "cone.ogg": "cone",
+ "cook.ogg": "cozinhar",
+ "cookie.ogg": "biscoito",
+ "cork.ogg": "rolha",
+ "corn.ogg": "milho",
+ "couch.ogg": "sofá",
+ "cough.ogg": "tossir",
+ "couple.ogg": "casal",
+ "cow.ogg": "vaca",
+ "cowboy.ogg": "cowboy",
+ "crab.ogg": "caranguejo",
+ "cradle.ogg": "berço",
+ "craft.ogg": "artesanato",
+ "crawl.ogg": "arrastar",
+ "crazy.ogg": "maluco",
+ "creek.ogg": "estuário",
+ "crepe.ogg": "crepe",
+ "crib.ogg": "berço",
+ "croak.ogg": "coaxar",
+ "crocodile.ogg": "crocodilo",
+ "cross.ogg": "cruz",
+ "crow.ogg": "corvo",
+ "crown.ogg": "coroa",
+ "crumb.ogg": "migalha",
+ "crust.ogg": "côdea",
+ "cry.ogg": "chorar",
+ "crystal.ogg": "cristal",
+ "cube.ogg": "cubo",
+ "cucumber.ogg": "pepino",
+ "curtain.ogg": "cortina",
+ "cut.ogg": "cortar",
+ "cute.ogg": "fofo",
+ "dad.ogg": "pai",
+ "daffodil.ogg": "narciso",
+ "daisy.ogg": "margarida",
+ "dam.ogg": "barragem",
+ "dance.ogg": "dançar",
+ "dandelion.ogg": "dente-de-leão",
+ "dart_board.ogg": "alvo de dardos",
+ "date_fruit.ogg": "tâmara",
+ "deer.ogg": "veado",
+ "den.ogg": "toca",
+ "desert.ogg": "deserto",
+ "desk.ogg": "secretária",
+ "dessert.ogg": "sobremesa",
+ "diamond.ogg": "diamante",
+ "dig.ogg": "cavar",
+ "dirt.ogg": "terra",
+ "dirty.ogg": "sujo",
+ "dish.ogg": "prato",
+ "dishcloth.ogg": "pano de loiça",
+ "dive.ogg": "mergulhar",
+ "doctor.ogg": "médico",
+ "doe.ogg": "fêmea",
+ "dog.ogg": "cão",
+ "doll.ogg": "boneca",
+ "dolphin.ogg": "golfinho",
+ "domino.ogg": "dominó",
+ "door.ogg": "porta",
+ "doormat.ogg": "tapete de entrada",
+ "dot.ogg": "ponto",
+ "doughnut.ogg": "donut",
+ "dove.ogg": "pomba",
+ "dragon.ogg": "dragão",
+ "dragonfly.ogg": "libélula",
+ "draw.ogg": "desenhar",
+ "drawer.ogg": "gaveta",
+ "dream.ogg": "sonhar",
+ "dress.ogg": "vestido",
+ "drink.ogg": "bebida",
+ "drip.ogg": "pingo",
+ "drive.ogg": "conduzir",
+ "drool.ogg": "babar",
+ "drum.ogg": "tambor",
+ "dry.ogg": "secar",
+ "duck.ogg": "pato",
+ "duck_mother.ogg": "pata",
+ "dune.ogg": "duna",
+ "dwarf.ogg": "anão",
+ "eagle.ogg": "águia",
+ "ear.ogg": "orelha",
+ "earth.ogg": "terra",
+ "eat.ogg": "comer",
+ "egg.ogg": "ovo",
+ "eggplant.ogg": "beringela",
+ "elbow.ogg": "ombro",
+ "electrician.ogg": "electricista",
+ "elk.ogg": "alce",
+ "empty.ogg": "vazio",
+ "engine.ogg": "motor",
+ "engineer.ogg": "engenheiro",
+ "eraser.ogg": "borracha",
+ "explore.ogg": "explorar",
+ "eyelash.ogg": "pestanas",
+ "eyes.ogg": "olhos",
+ "face.ogg": "cara",
+ "fair.ogg": "feira",
+ "fairy.ogg": "fada",
+ "fall.ogg": "cair",
+ "fall_season.ogg": "outono",
+ "family.ogg": "família",
+ "fan.ogg": "ventoinha",
+ "farm.ogg": "quinta",
+ "farmer.ogg": "agricultor",
+ "fat.ogg": "gordo",
+ "faucet.ogg": "torneira",
+ "fawn.ogg": "gamo",
+ "fear.ogg": "medo",
+ "feast.ogg": "festejo",
+ "feather.ogg": "pena",
+ "feed.ogg": "alimentar",
+ "femur.ogg": "fémur",
+ "fetch.ogg": "apanhar",
+ "fig.ogg": "figo",
+ "fin.ogg": "barbatana",
+ "find.ogg": "procurar",
+ "finger.ogg": "dedo",
+ "fire.ogg": "fogo",
+ "fire_extinguisher.ogg": "extintor",
+ "fireman.ogg": "bombeiro",
+ "fish.ogg": "peixe",
+ "fisherman.ogg": "pescador",
+ "fist.ogg": "punho",
+ "flacon.ogg": "frasco",
+ "flag.ogg": "bandeira",
+ "flame.ogg": "chama",
+ "flamingo.ogg": "flamingo",
+ "flash.ogg": "lanterna",
+ "flat.ogg": "plano",
+ "flies.ogg": "moscas",
+ "float.ogg": "flutuar",
+ "flour.ogg": "farinha",
+ "flower.ogg": "flor",
+ "fluff.ogg": "pano turco",
+ "flute.ogg": "flauta",
+ "fly.ogg": "voar",
+ "foam.ogg": "espuma",
+ "foot.ogg": "pé",
+ "forest.ogg": "floresta",
+ "fork.ogg": "garfo",
+ "fountain.ogg": "fonte",
+ "fox.ogg": "raposa",
+ "freeze.ogg": "congelar",
+ "friend.ogg": "amigo",
+ "fries.ogg": "fritos",
+ "frog.ogg": "sapo",
+ "front.ogg": "frente",
+ "fruit.ogg": "fruta",
+ "fudge.ogg": "doce de leite",
+ "full.ogg": "cheio",
+ "fur.ogg": "pêlo",
+ "game.ogg": "jogo",
+ "garage.ogg": "garagem",
+ "garden.ogg": "jardim",
+ "garlic.ogg": "alho",
+ "gem.ogg": "gema",
+ "giant.ogg": "gigante",
+ "gift.ogg": "presente",
+ "giraffe.ogg": "girafa",
+ "girl.ogg": "menina",
+ "glass.ogg": "copo",
+ "glasses.ogg": "óculos",
+ "glove.ogg": "luva",
+ "glue.ogg": "cola",
+ "gnome.ogg": "gnomo",
+ "goat.ogg": "cabra",
+ "golden.ogg": "dourado",
+ "golf.ogg": "golfe",
+ "goose.ogg": "ganso",
+ "gorilla.ogg": "gorila",
+ "grain.ogg": "grão",
+ "grandmother.ogg": "avó",
+ "grape.ogg": "uva",
+ "grapefruit.ogg": "toranja",
+ "grass.ogg": "relva",
+ "grave.ogg": "sepultura",
+ "gray.ogg": "cinzento",
+ "green.ogg": "verde",
+ "grill.ogg": "grelhador",
+ "grin.ogg": "sorriso",
+ "ground.ogg": "chão",
+ "growl.ogg": "rugir",
+ "guignol.ogg": "marioneta",
+ "guinea_pig.ogg": "porquinho-da-índia",
+ "gum.ogg": "goma",
+ "hair.ogg": "cabelo",
+ "hair_dryer.ogg": "secador de cabelo",
+ "half.ogg": "metade",
+ "ham.ogg": "fiambre",
+ "hamburger.ogg": "hambúrguer",
+ "hammer.ogg": "martelo",
+ "hand.ogg": "mão",
+ "handlebar.ogg": "pega",
+ "happy.ogg": "feliz",
+ "harp.ogg": "harpa",
+ "hat.ogg": "chapéu",
+ "hatch.ogg": "chocar",
+ "hay.ogg": "palha",
+ "head.ogg": "cabeça",
+ "hear.ogg": "ouvir",
+ "heat.ogg": "calor",
+ "hedge.ogg": "arbusto",
+ "hedgehog.ogg": "ouriço",
+ "heel.ogg": "palma",
+ "helmet.ogg": "capacete",
+ "hen.ogg": "galinha",
+ "herd.ogg": "manada",
+ "high.ogg": "alto",
+ "hike.ogg": "caminhar",
+ "hill.ogg": "colina",
+ "hip.ogg": "anca",
+ "hippopotamus.ogg": "hipopótamo",
+ "hit.ogg": "bater",
+ "hive.ogg": "colmeia",
+ "hockey.ogg": "hóquei",
+ "hole.ogg": "buraco",
+ "home.ogg": "casa",
+ "hook.ogg": "gancho",
+ "hop.ogg": "salto",
+ "horse.ogg": "cavalo",
+ "hose.ogg": "mangueira",
+ "hospital.ogg": "hospital",
+ "hot.ogg": "quente",
+ "hot_dog.ogg": "cachorro-quente",
+ "hound.ogg": "cão selvagem",
+ "house.ogg": "casa",
+ "howl.ogg": "uivar",
+ "hug.ogg": "abraçar",
+ "huge.ogg": "enorme",
+ "hummingbird.ogg": "beija-flor",
+ "hunchbacked.ogg": "marreco",
+ "hunter.ogg": "caçador",
+ "husband.ogg": "marido",
+ "hut.ogg": "cabana",
+ "hyena.ogg": "hiena",
+ "ice.ogg": "gelo",
+ "iceberg.ogg": "icebergue",
+ "iguana.ogg": "iguana",
+ "ill.ogg": "doente",
+ "ink.ogg": "tinta",
+ "island.ogg": "ilha",
+ "jacket.ogg": "casaco",
+ "jaguar.ogg": "jaguar",
+ "jam.ogg": "compota",
+ "jay.ogg": "gaio",
+ "jelly.ogg": "geleia",
+ "jellyfish.ogg": "medusa",
+ "jewel.ogg": "jóia",
+ "job.ogg": "emprego",
+ "jockey.ogg": "cavaleiro",
+ "jog.ogg": "correr",
+ "joy.ogg": "alegria",
+ "judge.ogg": "juiz",
+ "judo.ogg": "judo",
+ "juggler.ogg": "malabarista",
+ "juice.ogg": "sumo",
+ "jump.ogg": "saltar",
+ "kangaroo.ogg": "canguru",
+ "keel.ogg": "quilha",
+ "kernel.ogg": "caroço",
+ "keyboard.ogg": "teclado",
+ "kimono.ogg": "quimono",
+ "king.ogg": "rei",
+ "kiss.ogg": "beijar",
+ "kitchen.ogg": "cozinha",
+ "kite.ogg": "papagaio",
+ "kitten.ogg": "gatinho",
+ "kiwi.ogg": "kiwi",
+ "knee.ogg": "joelho",
+ "kneel.ogg": "ajoelhar",
+ "knife.ogg": "faca",
+ "knight.ogg": "cavaleiro",
+ "knit.ogg": "tricotar",
+ "knot.ogg": "nó",
+ "koala.ogg": "coala",
+ "lad.ogg": "rapaz",
+ "lady.ogg": "senhora",
+ "ladybug.ogg": "joaninha",
+ "lake.ogg": "lago",
+ "lama.ogg": "lama",
+ "lamb.ogg": "cordeiro",
+ "lamp.ogg": "candeeiro",
+ "land.ogg": "terra",
+ "lane.ogg": "pista",
+ "lap.ogg": "colo",
+ "lasso.ogg": "laço",
+ "laugh.ogg": "rir",
+ "lava.ogg": "lava",
+ "lawn.ogg": "relvado",
+ "lawyer.ogg": "advogado",
+ "leaf.ogg": "folha",
+ "ledge.ogg": "penhasco",
+ "leek.ogg": "alho-francês",
+ "left.ogg": "esquerda",
+ "leg.ogg": "perna",
+ "lemon.ogg": "limão",
+ "lemonade.ogg": "limonada",
+ "lemur.ogg": "lémur",
+ "leopard.ogg": "leopardo",
+ "lettuce.ogg": "alface",
+ "librarian.ogg": "bibliotecário",
+ "lick.ogg": "lamber",
+ "lid.ogg": "tampa",
+ "lift.ogg": "levantamento",
+ "light.ogg": "luz",
+ "lighthouse.ogg": "farol",
+ "lightning.ogg": "relâmpago",
+ "lilac.ogg": "lilás",
+ "lime.ogg": "lima",
+ "line.ogg": "linha",
+ "link.ogg": "ligação",
+ "lion.ogg": "leão",
+ "lion_cub.ogg": "cria de leão",
+ "lip.ogg": "lábio",
+ "liquid.ogg": "líquido",
+ "lizard.ogg": "lagarto",
+ "lobster.ogg": "lagosta",
+ "log.ogg": "tronco",
+ "look.ogg": "olhar",
+ "lunch.ogg": "almoço",
+ "mad.ogg": "maluco",
+ "magic.ogg": "mágico",
+ "magnet.ogg": "íman",
+ "magnifying_glass.ogg": "lupa",
+ "magpie.ogg": "pega",
+ "mail.ogg": "correio",
+ "man.ogg": "homem",
+ "mane.ogg": "crina",
+ "mango.ogg": "manga",
+ "map.ogg": "mapa",
+ "maple.ogg": "ácer",
+ "marble.ogg": "berlinde",
+ "mashed_potatoes.ogg": "puré de batata",
+ "mask.ogg": "máscara",
+ "mast.ogg": "mastro",
+ "mat.ogg": "tapete",
+ "match.ogg": "fósforo",
+ "mate.ogg": "companheiro",
+ "mattress.ogg": "colchão",
+ "mauve.ogg": "lilás",
+ "meal.ogg": "refeição",
+ "meat.ogg": "carne",
+ "mechanic.ogg": "mecânico",
+ "medal.ogg": "medalha",
+ "meet.ogg": "encontrar",
+ "melon.ogg": "melão",
+ "merry-go-round.ogg": "carrossel",
+ "mice.ogg": "ratos",
+ "microphone.ogg": "microfone",
+ "milk.ogg": "leite",
+ "mill.ogg": "moinho",
+ "mimosa.ogg": "mimosa",
+ "mirror.ogg": "espelho",
+ "mixer.ogg": "misturador",
+ "mole.ogg": "toupeira",
+ "mom.ogg": "mamã",
+ "moon.ogg": "lua",
+ "moose.ogg": "alce",
+ "mop.ogg": "esfregona",
+ "mosque.ogg": "mesquita",
+ "mosquito.ogg": "mosquito",
+ "mother.ogg": "mãe",
+ "motorcycle.ogg": "mota",
+ "mountain.ogg": "montanha",
+ "mouse.ogg": "rato",
+ "mouth.ogg": "boca",
+ "movie.ogg": "filme",
+ "mower.ogg": "cortador",
+ "mud.ogg": "lama",
+ "mug.ogg": "caneca",
+ "mule.ogg": "mula",
+ "muscle.ogg": "músculo",
+ "mushroom.ogg": "cogumelo",
+ "music.ogg": "música",
+ "musician.ogg": "músico",
+ "naked.ogg": "nú",
+ "nap.ogg": "descansar",
+ "navel.ogg": "umbigo",
+ "neck.ogg": "pescoço",
+ "necklace.ogg": "colar",
+ "needle.ogg": "agulha",
+ "nest.ogg": "ninho",
+ "net.ogg": "rede",
+ "newspaper.ogg": "jornal",
+ "night.ogg": "noite",
+ "nightgown.ogg": "vestido de noite",
+ "nose.ogg": "nariz",
+ "nostril.ogg": "narina",
+ "notebook.ogg": "bloco de notas",
+ "number.ogg": "número",
+ "nun.ogg": "freira",
+ "nurse.ogg": "enfermeira",
+ "nurse_male.ogg": "enfermeiro",
+ "nut.ogg": "noz",
+ "oar.ogg": "remo",
+ "ocean.ogg": "oceano",
+ "office.ogg": "escritório",
+ "olive.ogg": "azeitona",
+ "on.ogg": "ligado",
+ "onion.ogg": "cebola",
+ "open.ogg": "aberto",
+ "opossum.ogg": "gambá",
+ "orange-color.ogg": "laranja",
+ "orange.ogg": "laranja",
+ "orchid.ogg": "orquídea",
+ "ostrich.ogg": "avestruz",
+ "otter.ogg": "lontra",
+ "owl.ogg": "coruja",
+ "ox.ogg": "boi",
+ "oyster.ogg": "ostra",
+ "pacifier.ogg": "chucha",
+ "page.ogg": "página",
+ "pair.ogg": "par",
+ "pajamas.ogg": "pijamas",
+ "pal.ogg": "camarada",
+ "palm_tree.ogg": "palmeira",
+ "pan.ogg": "forma",
+ "panda.ogg": "panda",
+ "panther.ogg": "pantera",
+ "panties.ogg": "cuecas",
+ "pants.ogg": "calças",
+ "papaya.ogg": "papaia",
+ "paper.ogg": "papel",
+ "parachute.ogg": "pára-quedas",
+ "parakeet.ogg": "periquito",
+ "parrot.ogg": "papagaio",
+ "patch.ogg": "remendo",
+ "path.ogg": "caminho",
+ "paw.ogg": "pata",
+ "pea.ogg": "ervilha",
+ "peach.ogg": "pêssego",
+ "peacock.ogg": "pavão",
+ "peak.ogg": "pico",
+ "pear.ogg": "pêra",
+ "pearl.ogg": "pérola",
+ "peck.ogg": "bicar",
+ "pedal.ogg": "pedal",
+ "pelican.ogg": "pelicano",
+ "pen.ogg": "caneta",
+ "pencil.ogg": "lápis",
+ "peony.ogg": "peónia",
+ "people.ogg": "pessoas",
+ "pepper.ogg": "pimenta",
+ "peppers.ogg": "pimentos",
+ "pet.ogg": "animal doméstico",
+ "petal.ogg": "pétala",
+ "phone.ogg": "telefone",
+ "piano.ogg": "piano",
+ "picture.ogg": "fotografia",
+ "pie.ogg": "tarte",
+ "pig.ogg": "porco",
+ "pigeon.ogg": "pardal",
+ "pill.ogg": "comprimido",
+ "pillow.ogg": "almofada",
+ "pilot.ogg": "piloto",
+ "pine.ogg": "pinheiro",
+ "pine_cone.ogg": "pinha",
+ "pink.ogg": "rosa",
+ "pip.ogg": "caroço",
+ "pipe.ogg": "tubo",
+ "piranha.ogg": "piranha",
+ "pirate.ogg": "pirata",
+ "pizza.ogg": "pizza",
+ "plane.ogg": "avião",
+ "planet.ogg": "planeta",
+ "plant.ogg": "planta",
+ "plate.ogg": "prato",
+ "play.ogg": "jogar",
+ "pliers.ogg": "alicates",
+ "plow.ogg": "arar",
+ "plum.ogg": "ameixa",
+ "plumber.ogg": "canalizador",
+ "pocket.ogg": "bolso",
+ "pod.ogg": "vagem",
+ "pole.ogg": "varão",
+ "police.ogg": "polícia",
+ "pompon.ogg": "pompom",
+ "pond.ogg": "charco",
+ "pony.ogg": "pónei",
+ "pool.ogg": "piscina",
+ "popcorn.ogg": "pipocas",
+ "pope.ogg": "papa",
+ "porthole.ogg": "escotilha",
+ "post.ogg": "poste",
+ "pot.ogg": "vaso",
+ "potato.ogg": "batata",
+ "pounce.ogg": "atacar",
+ "president.ogg": "presidente",
+ "pretty.ogg": "bonito",
+ "price.ogg": "preço",
+ "priest.ogg": "padre",
+ "prince.ogg": "príncipe",
+ "princess.ogg": "princesa",
+ "prison.ogg": "prisão",
+ "prisoner.ogg": "prisioneiro",
+ "prize.ogg": "prémio",
+ "pug.ogg": "buldogue",
+ "pull.ogg": "puxar",
+ "pullover.ogg": "pulover",
+ "pumpkin.ogg": "abóbora",
+ "puppy.ogg": "cãozinho",
+ "pyramid.ogg": "pirâmide",
+ "quarrel.ogg": "discutir",
+ "queen.ogg": "rainha",
+ "question.ogg": "questão",
+ "quilt.ogg": "colcha",
+ "quiz.ogg": "questionário",
+ "rabbit.ogg": "coelho",
+ "rabbit_baby.ogg": "coelhinho",
+ "race.ogg": "corrida",
+ "radio.ogg": "rádio",
+ "radish.ogg": "rabanete",
+ "raft.ogg": "maçaneta",
+ "rag.ogg": "trapo",
+ "rage.ogg": "raiva",
+ "rain.ogg": "chuva",
+ "raincoat.ogg": "impermeável",
+ "rake.ogg": "ancinho",
+ "ramp.ogg": "rampa",
+ "ran.ogg": "correu",
+ "raspberry.ogg": "framboesa",
+ "rat.ogg": "rato",
+ "razor.ogg": "lâmina",
+ "read.ogg": "ler",
+ "red.ogg": "vermelho",
+ "reptile.ogg": "réptil",
+ "rhinoceros.ogg": "rinoceronte",
+ "rice.ogg": "arroz",
+ "ride.ogg": "montar",
+ "rifle.ogg": "espingarda",
+ "right.ogg": "direita",
+ "rip.ogg": "rasgar",
+ "rise.ogg": "elevar",
+ "river.ogg": "rio",
+ "road.ogg": "estrada",
+ "roast.ogg": "assado",
+ "robe.ogg": "roupão",
+ "robot.ogg": "robot",
+ "rock.ogg": "rocha",
+ "rocket.ogg": "foguete",
+ "rolling_pin.ogg": "rolo da massa",
+ "roof.ogg": "tecto",
+ "room.ogg": "sala",
+ "root.ogg": "raiz",
+ "rope.ogg": "corda",
+ "rose.ogg": "rosa",
+ "round.ogg": "redondo",
+ "rowing.ogg": "remar",
+ "royal.ogg": "real",
+ "rug.ogg": "alcatifa",
+ "run.ogg": "correr",
+ "sad.ogg": "triste",
+ "saddle.ogg": "sela",
+ "sail.ogg": "vela",
+ "sailor.ogg": "marinheiro",
+ "salamander.ogg": "salamandra",
+ "salmon.ogg": "salmão",
+ "sand.ogg": "areia",
+ "sandals.ogg": "sandálias",
+ "sandwich.ogg": "sanduíche",
+ "sash.ogg": "banda",
+ "sauce.ogg": "molho",
+ "sausage.ogg": "salsicha",
+ "scale.ogg": "balança",
+ "scar.ogg": "cicatriz",
+ "scare.ogg": "assustar",
+ "scarf.ogg": "cachecol",
+ "school.ogg": "escola",
+ "school_bag.ogg": "mochila",
+ "science.ogg": "ciência",
+ "scissors.ogg": "tesouras",
+ "scorpion.ogg": "escorpião",
+ "scratch.ogg": "coçar",
+ "scream.ogg": "gritar",
+ "screw.ogg": "parafuso",
+ "screwdriver.ogg": "chave de parafusos",
+ "scribble.ogg": "rabiscar",
+ "sea.ogg": "mar",
+ "seat.ogg": "lugar",
+ "see.ogg": "ver",
+ "seed.ogg": "semente",
+ "shadow.ogg": "sombra",
+ "shake.ogg": "agitar",
+ "shark.ogg": "tubarão",
+ "shave.ogg": "barbear",
+ "shed.ogg": "estábulo",
+ "sheep.ogg": "ovelha",
+ "shelf.ogg": "prateleira",
+ "shell.ogg": "concha",
+ "ship.ogg": "barco",
+ "shirt.ogg": "camisa",
+ "shoe.ogg": "sapato",
+ "shoelace.ogg": "atacador",
+ "shop.ogg": "loja",
+ "shore.ogg": "beira-mar",
+ "short.ogg": "calção",
+ "shovel.ogg": "pá",
+ "shower.ogg": "chuveiro",
+ "shrimp.ogg": "camarão",
+ "shrub.ogg": "arbusto",
+ "shut.ogg": "fechado",
+ "shutter.ogg": "persiana",
+ "sick.ogg": "doente",
+ "sidewalk.ogg": "passeio",
+ "sign.ogg": "sinal",
+ "sing.ogg": "cantar",
+ "sink.ogg": "lavatório",
+ "sip.ogg": "sorver",
+ "sister.ogg": "irmã",
+ "sit.ogg": "sentar",
+ "skate.ogg": "skate",
+ "skeleton.ogg": "esqueleto",
+ "ski.ogg": "esqui",
+ "skimmer.ogg": "escumadeira",
+ "skin.ogg": "pele",
+ "skirt.ogg": "saia",
+ "skunk.ogg": "doninha",
+ "sky.ogg": "céu",
+ "slam.ogg": "bater a porta",
+ "sled.ogg": "trenó",
+ "sleep.ogg": "dormir",
+ "sleeve.ogg": "manga",
+ "sleigh.ogg": "trenó",
+ "slide.ogg": "deslizamento",
+ "slim.ogg": "magro",
+ "slime.ogg": "muco",
+ "slippers.ogg": "chinelo",
+ "slope.ogg": "rampa",
+ "sloppy.ogg": "escorregadio",
+ "slot.ogg": "lugar",
+ "sloth.ogg": "preguiça",
+ "slug.ogg": "lesma",
+ "small.ogg": "pequeno",
+ "smell.ogg": "cheirar",
+ "smile.ogg": "sorriso",
+ "smock.ogg": "bata",
+ "smoke.ogg": "fumo",
+ "smooch.ogg": "beijocar",
+ "snack.ogg": "petisco",
+ "snail.ogg": "caracol",
+ "snake.ogg": "cobra",
+ "sneaker.ogg": "ténis",
+ "sniff.ogg": "cheirar",
+ "snow.ogg": "neve",
+ "soap.ogg": "sabão",
+ "sob.ogg": "choro",
+ "sock.ogg": "meia",
+ "soldier.ogg": "soldado",
+ "sole.ogg": "linguado",
+ "sole_shoe.ogg": "sapato com sola",
+ "son.ogg": "filho",
+ "soup.ogg": "sopa",
+ "spade.ogg": "pá",
+ "spaghetti.ogg": "esparguete",
+ "spark.ogg": "faísca",
+ "sparrow.ogg": "pardal",
+ "spatula.ogg": "espátula",
+ "speak.ogg": "falar",
+ "spear.ogg": "lança",
+ "spice.ogg": "especiaria",
+ "spider.ogg": "aranha",
+ "spider_web.ogg": "teia de aranha",
+ "spike.ogg": "leopardo",
+ "spill.ogg": "entornar",
+ "spinach.ogg": "espinafre",
+ "spine.ogg": "espinha",
+ "spinning_top.ogg": "pião",
+ "splash.ogg": "espalhar líquido",
+ "splatter.ogg": "mancha",
+ "sponge.ogg": "esponja",
+ "spool.ogg": "bobine",
+ "spoon.ogg": "colher",
+ "sport.ogg": "desporto",
+ "spot.ogg": "ponto",
+ "spray.ogg": "pulverizar",
+ "spread.ogg": "espalhar",
+ "spring.ogg": "saltar",
+ "spring_season.ogg": "primavera",
+ "sprinkle.ogg": "pepitas",
+ "square.ogg": "quadrado",
+ "squash.ogg": "aboborinha",
+ "squat.ogg": "agachar",
+ "squid.ogg": "lula",
+ "squirrel.ogg": "esquilo",
+ "squirt.ogg": "navalha",
+ "stack.ogg": "pilha",
+ "stage.ogg": "palco",
+ "staircase.ogg": "escadaria",
+ "stamp.ogg": "carimbo",
+ "stand.ogg": "garagem",
+ "star.ogg": "estrela",
+ "stare.ogg": "mirar",
+ "starfish.ogg": "estrela-do-mar",
+ "steam.ogg": "vapor",
+ "steep.ogg": "inclinado",
+ "steeple.ogg": "torre",
+ "stem.ogg": "caule",
+ "step.ogg": "degrau",
+ "stew.ogg": "estufado",
+ "stick.ogg": "pau",
+ "sting.ogg": "picar",
+ "stinky.ogg": "malcheiroso",
+ "stitch.ogg": "costurar",
+ "stomach.ogg": "estômago",
+ "stone.ogg": "pedra",
+ "stop.ogg": "parar",
+ "store.ogg": "loja",
+ "stove.ogg": "aquecedor",
+ "straight.ogg": "direito",
+ "strainer.ogg": "peneira",
+ "straw.ogg": "palha",
+ "strawberry.ogg": "morango",
+ "stream.ogg": "corrente",
+ "street.ogg": "rua",
+ "stretch.ogg": "esticar",
+ "string.ogg": "fio",
+ "stripe.ogg": "risca",
+ "strong.ogg": "forte",
+ "student.ogg": "estudante",
+ "study.ogg": "estudar",
+ "stump.ogg": "tronco",
+ "sugar.ogg": "açúcar",
+ "suit.ogg": "fato",
+ "suitcase.ogg": "mala",
+ "summer.ogg": "verão",
+ "summit.ogg": "cume",
+ "sun.ogg": "sol",
+ "swan.ogg": "cisne",
+ "sweat.ogg": "suor",
+ "sweatshirt.ogg": "camisola",
+ "swim.ogg": "nadar",
+ "table.ogg": "mesa",
+ "tablecloth.ogg": "toalha de mesa",
+ "tadpole.ogg": "girino",
+ "tag.ogg": "marca",
+ "tail.ogg": "cauda",
+ "tall.ogg": "alto",
+ "tape_measure.ogg": "fita métrica",
+ "taxi.ogg": "táxi",
+ "teach.ogg": "ensinar",
+ "teacher.ogg": "professor",
+ "tear.ogg": "separar",
+ "teddy.ogg": "peluche",
+ "teeth.ogg": "dentes",
+ "television.ogg": "televisão",
+ "temple.ogg": "templo",
+ "tennis.ogg": "ténis",
+ "tent.ogg": "tenda",
+ "text.ogg": "texto",
+ "thick.ogg": "grosso",
+ "thief.ogg": "ladrão",
+ "thigh.ogg": "coxa",
+ "think.ogg": "pensar",
+ "thread.ogg": "fio",
+ "throat.ogg": "garganta",
+ "throw.ogg": "lançar",
+ "thumb.ogg": "polegar",
+ "tick.ogg": "ácaro",
+ "ticket.ogg": "bilhete",
+ "tiger.ogg": "tigre",
+ "time.ogg": "tempo",
+ "tin.ogg": "tina",
+ "tire.ogg": "pneu",
+ "tired.ogg": "cansado",
+ "tissue.ogg": "lenço",
+ "to_drink.ogg": "beber",
+ "toad.ogg": "sapo",
+ "toaster.ogg": "torradeira",
+ "toe.ogg": "unha",
+ "toilet.ogg": "sanita",
+ "tomatoe.ogg": "tomate",
+ "tongs.ogg": "tenaz",
+ "tongue.ogg": "língua",
+ "tool.ogg": "ferramenta",
+ "top.ogg": "topo",
+ "torch.ogg": "tocha",
+ "touch.ogg": "tocar",
+ "towel.ogg": "toalha",
+ "toy.ogg": "brinquedo",
+ "trail.ogg": "trilho",
+ "train.ogg": "comboio",
+ "train_station.ogg": "estação de comboio",
+ "trap.ogg": "armadilha",
+ "trash.ogg": "lixo",
+ "tray.ogg": "bandeja",
+ "treat.ogg": "guloseima",
+ "tree.ogg": "árvore",
+ "triangle.ogg": "triângulo",
+ "tribe.ogg": "tribo",
+ "trip.ogg": "viagem",
+ "truck.ogg": "camião",
+ "tube.ogg": "tubo",
+ "tulip.ogg": "túlipa",
+ "tune.ogg": "tom",
+ "turkey.ogg": "peru",
+ "turnip.ogg": "nabo",
+ "turtle.ogg": "tartaruga",
+ "tusk.ogg": "presas",
+ "twin_boys.ogg": "gémeos",
+ "twin_girls.ogg": "gémeas",
+ "umbrella.ogg": "guarda-chuva",
+ "under.ogg": "debaixo",
+ "uniform.ogg": "uniforme",
+ "van.ogg": "carrinha",
+ "vapor.ogg": "vapor",
+ "vase.ogg": "vasilhame",
+ "vegetable.ogg": "vegetal",
+ "vein.ogg": "veia",
+ "verdure.ogg": "verdura",
+ "vest.ogg": "veste",
+ "vet.ogg": "veterinário",
+ "viper.ogg": "víbora",
+ "vowel.ogg": "vogal",
+ "vulture.ogg": "vulto",
+ "wag.ogg": "abanar",
+ "walk.ogg": "andar",
+ "wall.ogg": "parede",
+ "walnut.ogg": "noz",
+ "wart.ogg": "verruga",
+ "wash.ogg": "lavar",
+ "wasp.ogg": "vespa",
+ "watch.ogg": "relógio",
+ "water.ogg": "água",
+ "wave.ogg": "onda",
+ "wedding.ogg": "casamento",
+ "wedge.ogg": "cunha",
+ "weight.ogg": "peso",
+ "wet.ogg": "molhado",
+ "whale.ogg": "baleia",
+ "wheat.ogg": "trigo",
+ "wheel.ogg": "roda",
+ "whisk.ogg": "batedeira",
+ "whisper.ogg": "sussurrar",
+ "white.ogg": "branco",
+ "wide.ogg": "largo",
+ "wife.ogg": "esposa",
+ "wig.ogg": "peruca",
+ "win.ogg": "vencer",
+ "wind.ogg": "vento",
+ "window.ogg": "janela",
+ "window_glass.ogg": "vidro da janela",
+ "wing.ogg": "asa",
+ "winter.ogg": "inverno",
+ "wolf.ogg": "lobo",
+ "woman.ogg": "mulher",
+ "wood.ogg": "madeira",
+ "word.ogg": "palavra",
+ "worker.ogg": "funcionário",
+ "world.ogg": "mundo",
+ "wreath.ogg": "coroa floral",
+ "wrench.ogg": "chave de porcas",
+ "wrist.ogg": "pulso",
+ "write.ogg": "escrever",
+ "yellow.ogg": "amarelo",
+ "yogurt.ogg": "iogurte",
+ "yum.ogg": "deleite",
+ "zebra.ogg": "zebra",
+ "zipper.ogg": "fecho",
+ "zoo.ogg": "zoológico"
+}
\ No newline at end of file
diff --git a/src/activities/lang/resource/content-pt_BR.json b/src/activities/lang/resource/content-pt_BR.json
index 201ed8243..249e8ef30 100644
--- a/src/activities/lang/resource/content-pt_BR.json
+++ b/src/activities/lang/resource/content-pt_BR.json
@@ -1,1113 +1,1092 @@
{
"10.ogg": "dez",
"11.ogg": "onze",
"12.ogg": "doze",
"16.ogg": "dezesseis",
"U0030.ogg": "zero",
"U0031.ogg": "um",
"U0032.ogg": "dois",
"U0033.ogg": "três",
"U0034.ogg": "quatro",
"U0035.ogg": "cinco",
"U0036.ogg": "seis",
"U0037.ogg": "sete",
"U0038.ogg": "oito",
"U0039.ogg": "nove",
- "accountant.ogg": "",
- "ache.ogg": "",
- "acorn.ogg": "",
- "actor.ogg": "",
- "air_horn.ogg": "",
- "alarmclock.ogg": "",
+ "accountant.ogg": "contador",
+ "ache.ogg": "dor",
+ "acorn.ogg": "bolota",
+ "actor.ogg": "ator",
+ "air_horn.ogg": "buzina",
+ "alarmclock.ogg": "despertador",
"alligator.ogg": "jacaré",
- "alphabet.ogg": "",
+ "alphabet.ogg": "alfabeto",
"anchor.ogg": "âncora",
"angel.ogg": "anjo",
- "angry.ogg": "",
- "animal.ogg": "animais",
- "ankle.ogg": "",
- "ant.ogg": "",
- "anteater.ogg": "",
- "antelope.ogg": "",
- "apple.ogg": "",
- "apple_tree.ogg": "",
- "appliance.ogg": "",
- "apricot.ogg": "",
- "arm.ogg": "",
- "armchair.ogg": "",
- "artichoke.ogg": "",
- "artist.ogg": "",
- "asparagus.ogg": "",
- "astronaut.ogg": "",
- "ate.ogg": "comer",
+ "angry.ogg": "zangado",
+ "animal.ogg": "animal",
+ "ankle.ogg": "tornozelo",
+ "ant.ogg": "formiga",
+ "anteater.ogg": "tamanduá",
+ "antelope.ogg": "antílope",
+ "apple.ogg": "maçã",
+ "apple_tree.ogg": "macieira",
+ "appliance.ogg": "utensílio",
+ "apricot.ogg": "damasco",
+ "arm.ogg": "braço",
+ "armchair.ogg": "poltrona",
+ "artichoke.ogg": "alcachofra",
+ "artist.ogg": "artista",
+ "asparagus.ogg": "aspargo",
+ "astronaut.ogg": "astronauta",
"athlete.ogg": "atleta",
- "avocado.ogg": "",
- "ax.ogg": "",
- "baby_bottle.ogg": "",
+ "avocado.ogg": "abacate",
+ "ax.ogg": "machado",
+ "baby_bottle.ogg": "mamadeira",
"back.ogg": "costas",
"badge.ogg": "insígnia",
- "bag.ogg": "mochila",
+ "bag.ogg": "bolsa",
"bait.ogg": "isca",
- "bake.ogg": "cozinhar",
"balance.ogg": "balança",
- "bald.ogg": "",
+ "bald.ogg": "careca",
"ball.ogg": "bola",
- "ball_of_yarn.ogg": "",
- "ball_soccer.ogg": "",
+ "ball_of_yarn.ogg": "novelo de lã",
+ "ball_soccer.ogg": "bola de futebol",
"ballet.ogg": "balé",
"bank.ogg": "banco",
+ "banker_female.ogg": "banqueira",
"bark.ogg": "latir",
"barn.ogg": "celeiro",
"bat.ogg": "morcego",
"bath.ogg": "banheira",
- "bathing_suit.ogg": "",
+ "bathing_suit.ogg": "roupa de banho",
"bay.ogg": "baía",
"beach.ogg": "praia",
- "bead.ogg": "bolha",
- "bean.ogg": "",
- "bear.ogg": "",
- "beard.ogg": "",
- "beat.ogg": "",
- "beaver.ogg": "",
+ "bean.ogg": "feijão",
+ "bear.ogg": "urso",
+ "beard.ogg": "barba",
+ "beat.ogg": "derrotar",
+ "beaver.ogg": "castor",
"bed.ogg": "cama",
- "bedroom.ogg": "",
+ "bedroom.ogg": "quarto",
"bee.ogg": "abelha",
- "beef.ogg": "",
"beetle.ogg": "besouro",
"beg.ogg": "implorar",
- "behind.ogg": "",
- "bell.ogg": "",
- "belly.ogg": "",
+ "behind.ogg": "atrás",
+ "bell.ogg": "sino",
+ "belly.ogg": "barriga",
"bench.ogg": "banco",
"bib.ogg": "babador",
"big.ogg": "grande",
- "big_top.ogg": "",
+ "big_top.ogg": "tenda de circo",
"bike.ogg": "bicicleta",
"bird.ogg": "pássaro",
"bit.ogg": "mordida",
"bite.ogg": "morder",
"black.ogg": "preto",
- "blackberry.ogg": "",
- "blackbird.ogg": "",
- "blade.ogg": "",
+ "blackberry.ogg": "amora",
+ "blackbird.ogg": "pássaro preto",
+ "blade.ogg": "lâmina",
"blind.ogg": "cego",
"blink.ogg": "piscar",
"block.ogg": "bloco",
"blond.ogg": "loira",
"blue.ogg": "azul",
- "blueberry.ogg": "",
- "blush.ogg": "",
+ "blueberry.ogg": "mirtilo",
+ "blush.ogg": "vergonha",
"board.ogg": "placa",
"boat.ogg": "barco",
"boil.ogg": "ferver",
- "bolt.ogg": "",
+ "bolt.ogg": "porca",
"bomb.ogg": "bomba",
"bone.ogg": "osso",
"book.ogg": "livro",
- "bookcase.ogg": "",
- "bottom.ogg": "",
+ "bookcase.ogg": "estante",
+ "bottom.ogg": "nádegas",
"box.ogg": "caixa",
- "boxer.ogg": "",
+ "boxer.ogg": "boxeador",
"boy.ogg": "menino",
"braid.ogg": "trança",
"brain.ogg": "cérebro",
"branch.ogg": "ramo",
"bread.ogg": "pão",
- "break.ogg": "partir",
- "breast.ogg": "",
+ "break.ogg": "quebrar",
+ "breast.ogg": "mama",
"brick.ogg": "tijolo",
- "bricklayer.ogg": "",
+ "bricklayer.ogg": "pedreiro",
"bride.ogg": "noiva",
"bridge.ogg": "ponte",
"bright.ogg": "brilhante",
- "broccoli.ogg": "",
+ "broccoli.ogg": "brócolis",
"brother.ogg": "irmão",
"brown.ogg": "marrom",
"brush.ogg": "pincel",
- "bubble.ogg": "",
- "bucket.ogg": "",
- "bud.ogg": "broto",
- "buffalo.ogg": "",
+ "bubble.ogg": "bolha",
+ "bucket.ogg": "balde",
+ "bud.ogg": "botão",
+ "buffalo.ogg": "búfalo",
"bug.ogg": "inseto",
- "bulb.ogg": "",
- "bull.ogg": "",
- "bump.ogg": "batida",
- "bun.ogg": "brioche",
- "bus.ogg": "",
+ "bulb.ogg": "lâmpada",
+ "bull.ogg": "touro",
+ "bump.ogg": "inchaço",
+ "bun.ogg": "pão doce",
+ "bus.ogg": "ônibus",
"bush.ogg": "arbusto",
- "butcher.ogg": "",
- "butter.ogg": "",
- "butterfly.ogg": "",
- "button.ogg": "",
- "cabbage.ogg": "",
+ "butcher.ogg": "açouqueiro",
+ "butter.ogg": "manteiga",
+ "butterfly.ogg": "borboleta",
+ "button.ogg": "botão",
+ "cabbage.ogg": "repolho",
"cabin.ogg": "cabana",
- "cacao.ogg": "",
- "cactus.ogg": "",
+ "cacao.ogg": "cacau",
+ "cactus.ogg": "cactus",
"cage.ogg": "gaiola",
"cake.ogg": "bolo",
"call.ogg": "ligar",
"camel.ogg": "camelo",
- "camera.ogg": "",
+ "camera.ogg": "câmera",
"camp.ogg": "acampamento",
"can.ogg": "lata",
- "canary.ogg": "",
+ "canary.ogg": "canário",
"candle.ogg": "vela",
- "candy.ogg": "doce",
+ "candy.ogg": "bala",
"cane.ogg": "bengala",
"canoe.ogg": "canoa",
- "canon.ogg": "",
- "canyon.ogg": "",
+ "canon.ogg": "canhão",
+ "canyon.ogg": "desfiladeiro",
"cap.ogg": "boné",
"cape.ogg": "capa",
"car.ogg": "carro",
- "carafe.ogg": "",
+ "carafe.ogg": "jarro",
"card.ogg": "cartão",
- "carnival.ogg": "",
- "carpenter.ogg": "",
- "carpet.ogg": "",
+ "carnival.ogg": "carnaval",
+ "carpenter.ogg": "carpinteiro",
+ "carpet.ogg": "tapete",
"carrot.ogg": "cenoura",
"cart.ogg": "carrinho",
"cash.ogg": "dinheiro",
"castle.ogg": "castelo",
"cat.ogg": "gato",
- "cat_female.ogg": "",
+ "cat_female.ogg": "gata",
"catch.ogg": "pegar",
- "caterpillar.ogg": "",
- "cauldron.ogg": "",
- "cauliflower.ogg": "",
+ "caterpillar.ogg": "lagarta",
+ "cauldron.ogg": "caudeirão",
+ "cauliflower.ogg": "couve-flor",
"cave.ogg": "caverna",
- "cavern.ogg": "",
- "celery.ogg": "",
+ "cavern.ogg": "gruta",
+ "celery.ogg": "aipo",
"centipede.ogg": "centopeia",
- "cereal.ogg": "",
- "chain.ogg": "",
+ "cereal.ogg": "cereal",
+ "chain.ogg": "corrente",
"chair.ogg": "cadeira",
"chalk.ogg": "giz",
- "chameleon.ogg": "",
- "chandelier.ogg": "",
+ "chameleon.ogg": "camaleão",
+ "chandelier.ogg": "lustre",
"chat.ogg": "conversar",
- "cheek.ogg": "",
- "cheer.ogg": "torcer",
+ "cheek.ogg": "bochecha",
+ "cheer.ogg": "torcida",
"cheese.ogg": "queijo",
- "chef.ogg": "",
+ "chef.ogg": "chefe de cozinha",
"cherry.ogg": "cereja",
"chest.ogg": "baú",
"chick.ogg": "pintinho",
"chicken.ogg": "frango",
- "chief.ogg": "cacique",
"child.ogg": "criança",
- "chimney.ogg": "",
+ "chimney.ogg": "chaminé",
"chimp.ogg": "chimpanzé",
"chin.ogg": "queixo",
"chocolate.ogg": "chocolate",
"chop.ogg": "cortar",
- "chore.ogg": "",
- "christmas.ogg": "",
- "cigar.ogg": "",
- "circus.ogg": "",
- "city.ogg": "",
- "clam.ogg": "molusco",
- "clap.ogg": "palma",
+ "chores.ogg": "tarefas domésticas",
+ "christmas.ogg": "natal",
+ "cigar.ogg": "charuto",
+ "circus.ogg": "circo",
+ "city.ogg": "cidade",
+ "clam.ogg": "marisco",
+ "clap.ogg": "bater",
"class.ogg": "aula",
"claw.ogg": "garra",
"clay.ogg": "argila",
"clean.ogg": "limpar",
- "cleaning_lady.ogg": "",
+ "cleaning_lady.ogg": "faxineira",
"cliff.ogg": "penhasco",
- "climb.ogg": "escalar",
+ "climb.ogg": "escalada",
"clock.ogg": "relógio",
"cloth.ogg": "tecido",
- "clothes_hanger.ogg": "",
+ "clothes_hanger.ogg": "cabide",
"cloud.ogg": "nuvem",
- "cloudy.ogg": "",
- "clover.ogg": "",
+ "cloudy.ogg": "nublado",
+ "clover.ogg": "trevo",
"clown.ogg": "palhaço",
- "coach.ogg": "treinador",
- "coast.ogg": "",
+ "coach.ogg": "treinadora",
+ "coast.ogg": "costa",
"coat.ogg": "casaco",
- "cobra.ogg": "",
- "coconut.ogg": "",
- "cod.ogg": "",
- "coffee.ogg": "",
+ "cobra.ogg": "cobra",
+ "coconut.ogg": "coco",
+ "cod.ogg": "bacalhau",
+ "coffee.ogg": "café",
"coin.ogg": "moeda",
"cold.ogg": "frio",
"color.ogg": "cor",
- "colt.ogg": "",
+ "colt.ogg": "potro",
"comb.ogg": "pente",
"cone.ogg": "cone",
+ "cook.ogg": "cozinhar",
"cookie.ogg": "biscoito",
- "cork.ogg": "",
+ "cork.ogg": "rolha",
"corn.ogg": "milho",
"couch.ogg": "sofá",
- "cough.ogg": "",
- "couple.ogg": "",
+ "cough.ogg": "tossir",
+ "couple.ogg": "casal",
"cow.ogg": "vaca",
"cowboy.ogg": "vaqueiro",
"crab.ogg": "caranguejo",
- "cradle.ogg": "",
- "craft.ogg": "",
+ "cradle.ogg": "berço",
+ "craft.ogg": "trabalhos manuais",
"crawl.ogg": "engatinhar",
"crazy.ogg": "doido",
- "creek.ogg": "",
- "crepe.ogg": "",
+ "creek.ogg": "riacho",
+ "crepe.ogg": "crepe",
"crib.ogg": "berço",
- "criminal.ogg": "",
"croak.ogg": "coaxar",
"crocodile.ogg": "crocodilo",
- "cross.ogg": "",
+ "cross.ogg": "cruz",
"crow.ogg": "corvo",
"crown.ogg": "coroa",
"crumb.ogg": "migalha",
"crust.ogg": "casca",
"cry.ogg": "chorar",
- "crystal.ogg": "",
+ "crystal.ogg": "cristal",
"cube.ogg": "cubo",
"cucumber.ogg": "pepino",
- "curtain.ogg": "",
+ "curtain.ogg": "curtina",
"cut.ogg": "cortar",
"cute.ogg": "fofa",
"dad.ogg": "pai",
- "daffodil.ogg": "",
- "daisy.ogg": "",
- "dam.ogg": "",
+ "daffodil.ogg": "narciso",
+ "daisy.ogg": "margarida",
+ "dam.ogg": "represa",
"dance.ogg": "dança",
- "dandelion.ogg": "",
- "danger.ogg": "perigo",
- "dark.ogg": "negra",
- "dart_board.ogg": "",
- "date_fruit.ogg": "",
- "deer.ogg": "",
+ "dandelion.ogg": "dente-de-leão",
+ "dart_board.ogg": "alvo de dardo",
+ "date_fruit.ogg": "tâmara",
+ "deer.ogg": "veado",
"den.ogg": "toca",
- "desert.ogg": "",
+ "desert.ogg": "deserto",
"desk.ogg": "escrivaninha",
- "dessert.ogg": "",
- "diamond.ogg": "",
- "dig.ogg": "escavar",
+ "dessert.ogg": "sobremesa",
+ "diamond.ogg": "diamante",
+ "dig.ogg": "cavar",
"dirt.ogg": "terra",
"dirty.ogg": "sujo",
"dish.ogg": "prato",
- "dishcloth.ogg": "",
+ "dishcloth.ogg": "pano de prato",
"dive.ogg": "mergulho",
- "doctor.ogg": "",
- "doe.ogg": "",
+ "doctor.ogg": "doutor",
+ "doe.ogg": "corça",
"dog.ogg": "cachorro",
- "doll.ogg": "",
- "dolphin.ogg": "",
- "domino.ogg": "",
+ "doll.ogg": "boneca",
+ "dolphin.ogg": "golfinho",
+ "domino.ogg": "dominó",
"door.ogg": "porta",
- "doormat.ogg": "",
+ "doormat.ogg": "capacho",
"dot.ogg": "ponto",
- "doughnut.ogg": "",
- "dove.ogg": "",
+ "doughnut.ogg": "rosquinha",
+ "dove.ogg": "pomba",
"dragon.ogg": "dragão",
- "dragonfly.ogg": "",
- "drank.ogg": "beber",
+ "dragonfly.ogg": "libélula",
"draw.ogg": "desenhar",
- "drawer.ogg": "",
+ "drawer.ogg": "gaveta",
"dream.ogg": "sonhar",
"dress.ogg": "vestido",
"drink.ogg": "bebida",
- "drinking.ogg": "",
- "drip.ogg": "",
+ "drip.ogg": "gota",
"drive.ogg": "dirigir",
"drool.ogg": "babar",
"drum.ogg": "tambor",
"dry.ogg": "secar",
"duck.ogg": "pato",
- "duck_mother.ogg": "",
+ "duck_mother.ogg": "mãe pata",
"dune.ogg": "duna",
- "dwarf.ogg": "",
- "eagle.ogg": "",
+ "dwarf.ogg": "anão",
+ "eagle.ogg": "águia",
"ear.ogg": "orelha",
- "earth.ogg": "mundo",
+ "earth.ogg": "Terra",
"eat.ogg": "comer",
- "egg.ogg": "",
- "eggplant.ogg": "",
- "elbow.ogg": "",
- "electrician.ogg": "",
- "elk.ogg": "",
+ "egg.ogg": "ovo",
+ "eggplant.ogg": "berinjela",
+ "elbow.ogg": "cotovelo",
+ "electrician.ogg": "eletricista",
+ "elk.ogg": "rena",
"empty.ogg": "vazia",
- "engine.ogg": "",
- "engineer.ogg": "",
- "eraser.ogg": "",
+ "engine.ogg": "motor",
+ "engineer.ogg": "engenheiro",
+ "eraser.ogg": "borracha",
"explore.ogg": "explorar",
- "eyelash.ogg": "",
- "eyes.ogg": "",
+ "eyelash.ogg": "cílio",
+ "eyes.ogg": "olhos",
"face.ogg": "rosto",
- "fair.ogg": "parque ambulante",
- "fairy.ogg": "",
- "fall_down.ogg": "",
- "fall_season.ogg": "",
- "family.ogg": "",
+ "fair.ogg": "feira",
+ "fairy.ogg": "fada",
+ "fall.ogg": "cair",
+ "fall_season.ogg": "outono",
+ "family.ogg": "família",
"fan.ogg": "ventilador",
"farm.ogg": "fazenda",
- "farmer.ogg": "",
+ "farmer.ogg": "fazendeiro",
"fat.ogg": "gordo",
- "faucet.ogg": "",
- "fawn.ogg": "",
+ "faucet.ogg": "torneira",
+ "fawn.ogg": "fulvo",
+ "fear.ogg": "medo",
"feast.ogg": "banquete",
- "feather.ogg": "",
- "feed.ogg": "",
- "feet.ogg": "pés",
- "fell.ogg": "cair",
- "femur.ogg": "",
+ "feather.ogg": "pena",
+ "feed.ogg": "alimentar",
+ "femur.ogg": "fêmur",
"fetch.ogg": "buscar",
- "fig.ogg": "",
+ "fig.ogg": "figo",
"fin.ogg": "barbatana",
"find.ogg": "encontrar",
- "finger.ogg": "",
+ "finger.ogg": "dedo",
"fire.ogg": "fogo",
- "fire_extinguisher.ogg": "",
- "fireman.ogg": "",
+ "fire_extinguisher.ogg": "extintor de incêndio",
+ "fireman.ogg": "bombeiro",
"fish.ogg": "peixe",
- "fisherman.ogg": "",
+ "fisherman.ogg": "pescador",
"fist.ogg": "punho",
- "five.ogg": "cinco",
- "flacon.ogg": "",
+ "flacon.ogg": "frasco",
"flag.ogg": "bandeira",
- "flame.ogg": "flama",
- "flamingo.ogg": "",
+ "flame.ogg": "chama",
+ "flamingo.ogg": "flamingo",
"flash.ogg": "lanterna",
- "flat.ogg": "achatado",
+ "flat.ogg": "apartamento",
"flies.ogg": "mosca",
- "flight.ogg": "",
- "float.ogg": "boiar",
+ "float.ogg": "flutuar",
"flour.ogg": "farinha",
"flower.ogg": "flor",
- "fluff.ogg": "",
+ "fluff.ogg": "penugem",
"flute.ogg": "flauta",
"fly.ogg": "voar",
- "foam.ogg": "",
- "food.ogg": "comida",
+ "foam.ogg": "espuma",
"foot.ogg": "pé",
- "forest.ogg": "",
+ "forest.ogg": "floresta",
"fork.ogg": "garfo",
"fountain.ogg": "fonte",
"fox.ogg": "raposa",
"freeze.ogg": "congelar",
"friend.ogg": "amigo",
- "fries.ogg": "",
+ "fries.ogg": "batata frita",
"frog.ogg": "sapo",
"front.ogg": "frente",
- "frown.ogg": "franzida",
"fruit.ogg": "fruta",
"fudge.ogg": "doce de chocolate",
"full.ogg": "cheio",
- "fun.ogg": "diversão",
"fur.ogg": "pêlo",
"game.ogg": "jogo",
- "garage.ogg": "",
+ "garage.ogg": "gragem",
"garden.ogg": "jardim",
- "garlic.ogg": "",
- "gem.ogg": "joia",
+ "garlic.ogg": "alho",
+ "gem.ogg": "jóia",
"giant.ogg": "gigante",
"gift.ogg": "presente",
"giraffe.ogg": "girafa",
"girl.ogg": "menina",
"glass.ogg": "copo",
- "glasses.ogg": "",
+ "glasses.ogg": "óculos",
"glove.ogg": "luva",
"glue.ogg": "cola",
"gnome.ogg": "gnomo",
- "goat.ogg": "cabra",
- "golden.ogg": "",
- "golf.ogg": "",
- "goose.ogg": "",
- "gorilla.ogg": "",
- "grain.ogg": "",
- "grandmother.ogg": "",
- "grape.ogg": "",
- "grapefruit.ogg": "",
+ "goat.ogg": "bode",
+ "golden.ogg": "dourada",
+ "golf.ogg": "golfe",
+ "goose.ogg": "ganso",
+ "gorilla.ogg": "gorila",
+ "grain.ogg": "grão",
+ "grandmother.ogg": "avó",
+ "grape.ogg": "uva",
+ "grapefruit.ogg": "toranja",
"grass.ogg": "grama",
"grave.ogg": "lápide",
"gray.ogg": "cinza",
"green.ogg": "verde",
- "grill.ogg": "",
+ "grill.ogg": "grelha",
"grin.ogg": "sorriso",
- "ground.ogg": "solo",
+ "ground.ogg": "chão",
"growl.ogg": "rosnar",
- "guignol.ogg": "",
- "guinea_pig.ogg": "",
- "gum.ogg": "chiclete",
+ "guignol.ogg": "Guinhol",
+ "guinea_pig.ogg": "porquinho da Índia",
+ "gum.ogg": "goma de mascar",
"hair.ogg": "cabelo",
- "hair_dryer.ogg": "",
- "half.ogg": "",
- "ham.ogg": "",
- "hammer.ogg": "",
+ "hair_dryer.ogg": "secador de cabelos",
+ "half.ogg": "metade",
+ "ham.ogg": "presunto",
+ "hamburger.ogg": "hamburger",
+ "hammer.ogg": "martelo",
"hand.ogg": "mão",
- "handlebar.ogg": "",
+ "handlebar.ogg": "guidão",
"happy.ogg": "feliz",
- "harp.ogg": "",
+ "harp.ogg": "harpa",
"hat.ogg": "chapéu",
"hatch.ogg": "chocar",
"hay.ogg": "feno",
"head.ogg": "cabeça",
"hear.ogg": "escutar",
"heat.ogg": "calor",
"hedge.ogg": "cerca viva",
- "hedgehog.ogg": "",
- "heel.ogg": "",
- "helmet.ogg": "",
+ "hedgehog.ogg": "ouriço",
+ "heel.ogg": "salto",
+ "helmet.ogg": "capacete",
"hen.ogg": "galinha",
"herd.ogg": "rebanho",
"high.ogg": "alto",
- "hike.ogg": "caminhar",
- "hill.ogg": "",
+ "hike.ogg": "caminhada",
+ "hill.ogg": "colina",
"hip.ogg": "quadril",
- "hippopotamus.ogg": "",
- "hit.ogg": "golpear",
- "hive.ogg": "",
- "hockey.ogg": "",
+ "hippopotamus.ogg": "hipopótamo",
+ "hit.ogg": "pancada",
+ "hive.ogg": "colmeia",
+ "hockey.ogg": "hóquei",
"hole.ogg": "buraco",
"home.ogg": "lar",
"hook.ogg": "gancho",
- "hop.ogg": "saltar",
- "horse.ogg": "",
+ "hop.ogg": "pulo",
+ "horse.ogg": "cavalo",
"hose.ogg": "mangueira",
- "hospital.ogg": "",
+ "hospital.ogg": "hospital",
"hot.ogg": "quente",
- "hot_dog.ogg": "",
+ "hot_dog.ogg": "cachorro quente",
"hound.ogg": "cão de caça",
- "house.ogg": "",
+ "house.ogg": "casa",
"howl.ogg": "uivar",
"hug.ogg": "abraçar",
"huge.ogg": "enorme",
- "hummingbird.ogg": "",
- "hunchback.ogg": "",
+ "hummingbird.ogg": "beija-flor",
+ "hunchbacked.ogg": "corcunda",
"hunter.ogg": "caçador",
- "husband.ogg": "",
- "hut.ogg": "oca",
- "hyena.ogg": "",
+ "husband.ogg": "marido",
+ "hut.ogg": "cabana",
+ "hyena.ogg": "hiena",
"ice.ogg": "gelo",
- "iceberg.ogg": "",
- "iguana.ogg": "",
- "ill.ogg": "",
+ "iceberg.ogg": "icebergue",
+ "iguana.ogg": "iguana",
+ "ill.ogg": "doente",
"ink.ogg": "tinta",
- "island.ogg": "",
- "jacket.ogg": "",
- "jaguar.ogg": "",
- "jam.ogg": "",
- "jay.ogg": "",
- "jelly.ogg": "",
- "jellyfish.ogg": "",
+ "island.ogg": "ilha",
+ "jacket.ogg": "jaqueta",
+ "jaguar.ogg": "onça",
+ "jam.ogg": "geleia",
+ "jay.ogg": "gaio",
+ "jelly.ogg": "gelatina",
+ "jellyfish.ogg": "água-viva",
"jewel.ogg": "jóia",
- "job.ogg": "",
- "jockey.ogg": "",
- "jog.ogg": "correr",
+ "job.ogg": "emprego",
+ "jockey.ogg": "jóquei",
+ "jog.ogg": "caminhada",
+ "joy.ogg": "alegria",
"judge.ogg": "juiz",
- "judo.ogg": "",
- "juggler.ogg": "",
+ "judo.ogg": "judô",
+ "juggler.ogg": "malabarista",
"juice.ogg": "suco",
"jump.ogg": "pular",
- "kangaroo.ogg": "",
- "keel.ogg": "",
- "kernel.ogg": "",
- "keyboard.ogg": "",
- "kimono.ogg": "",
- "king.ogg": "",
- "kiss.ogg": "",
- "kitchen.ogg": "",
+ "kangaroo.ogg": "canguru",
+ "keel.ogg": "pino de boliche",
+ "kernel.ogg": "caroço",
+ "keyboard.ogg": "teclado",
+ "kimono.ogg": "quimono",
+ "king.ogg": "rei",
+ "kiss.ogg": "beijar",
+ "kitchen.ogg": "cozinha",
"kite.ogg": "pipa",
- "kitten.ogg": "",
- "kiwi.ogg": "",
+ "kitten.ogg": "gatinho",
+ "kiwi.ogg": "kiwi",
"knee.ogg": "joelho",
"kneel.ogg": "ajoelhar",
"knife.ogg": "faca",
"knight.ogg": "cavaleiro",
"knit.ogg": "tricotar",
"knot.ogg": "nó",
- "koala.ogg": "",
+ "koala.ogg": "coala",
"lad.ogg": "rapaz",
- "lady.ogg": "",
- "ladybug.ogg": "",
+ "lady.ogg": "senhora",
+ "ladybug.ogg": "joaninha",
"lake.ogg": "lago",
- "lama.ogg": "",
+ "lama.ogg": "lhama",
"lamb.ogg": "cordeiro",
"lamp.ogg": "abajur",
- "land.ogg": "terreno",
+ "land.ogg": "terra",
"lane.ogg": "pista",
"lap.ogg": "colo",
- "lasso.ogg": "",
- "laugh.ogg": "",
- "lava.ogg": "",
+ "lasso.ogg": "laço",
+ "laugh.ogg": "rir",
+ "lava.ogg": "lava",
"lawn.ogg": "gramado",
- "lawyer.ogg": "",
- "leaf.ogg": "",
+ "lawyer.ogg": "advogado",
+ "leaf.ogg": "folha",
"ledge.ogg": "borda",
- "leek.ogg": "",
- "left.ogg": "esquerdo",
- "leg.ogg": "",
- "leg_animal.ogg": "",
- "lemon.ogg": "",
- "lemonade.ogg": "",
- "lemur.ogg": "",
- "leopard.ogg": "",
- "lettuce.ogg": "",
- "librarian.ogg": "",
+ "leek.ogg": "alho-poró",
+ "left.ogg": "esquerda",
+ "leg.ogg": "perna",
+ "lemon.ogg": "limão",
+ "lemonade.ogg": "limonada",
+ "lemur.ogg": "lêmure",
+ "leopard.ogg": "leopardo",
+ "lettuce.ogg": "alface",
+ "librarian.ogg": "bibliotecária",
"lick.ogg": "lamber",
"lid.ogg": "tampa",
- "lift.ogg": "levantar",
+ "lift.ogg": "levantamento",
"light.ogg": "luz",
- "lighthouse.ogg": "",
- "lightning.ogg": "",
- "lilac.ogg": "",
- "lime.ogg": "limão",
- "line.ogg": "listrado",
- "link.ogg": "argola",
- "lion.ogg": "",
- "lion_cub.ogg": "",
+ "lighthouse.ogg": "farol",
+ "lightning.ogg": "raio",
+ "lilac.ogg": "lilás",
+ "lime.ogg": "lima",
+ "line.ogg": "linha",
+ "link.ogg": "elo",
+ "lion.ogg": "leão",
+ "lion_cub.ogg": "filhote de leão",
"lip.ogg": "lábio",
"liquid.ogg": "líquido",
- "lizard.ogg": "",
- "lobster.ogg": "",
+ "lizard.ogg": "lagarto",
+ "lobster.ogg": "lagosta",
"log.ogg": "tora",
"look.ogg": "olhar",
"lunch.ogg": "lanche",
"mad.ogg": "furioso",
"magic.ogg": "mágica",
- "magnet.ogg": "",
- "magnifying_glass.ogg": "",
- "magpie.ogg": "",
- "mail.ogg": "",
- "man.ogg": "",
+ "magnet.ogg": "imã",
+ "magnifying_glass.ogg": "lente de aumento",
+ "magpie.ogg": "pega",
+ "mail.ogg": "correspondência",
+ "man.ogg": "homem",
"mane.ogg": "juba",
- "mango.ogg": "",
+ "mango.ogg": "manga",
"map.ogg": "mapa",
- "maple.ogg": "",
- "marble.ogg": "",
- "mashed_potatoes.ogg": "",
+ "maple.ogg": "bordo",
+ "marble.ogg": "bola de gude",
+ "mashed_potatoes.ogg": "purê de batatas",
"mask.ogg": "máscara",
- "mast.ogg": "",
- "mat.ogg": "capacho",
+ "mast.ogg": "mastro",
+ "mat.ogg": "esteira",
"match.ogg": "fósforo",
"mate.ogg": "colega",
- "mattress.ogg": "",
- "mauve.ogg": "",
- "meal.ogg": "",
- "meat.ogg": "",
- "mechanic.ogg": "",
- "medal.ogg": "",
+ "mattress.ogg": "colchão",
+ "mauve.ogg": "malva",
+ "meal.ogg": "refeição",
+ "meat.ogg": "carne",
+ "mechanic.ogg": "mecânico",
+ "medal.ogg": "medalha",
"meet.ogg": "encontrar",
- "melon.ogg": "",
- "men.ogg": "homens",
- "merry-go-round.ogg": "",
+ "melon.ogg": "melão",
+ "merry-go-round.ogg": "carrossel",
"mice.ogg": "ratas",
- "microphone.ogg": "",
- "milk.ogg": "",
- "mill.ogg": "",
- "mimosa.ogg": "",
- "mirror.ogg": "",
- "mixer.ogg": "",
+ "microphone.ogg": "microfone",
+ "milk.ogg": "leite",
+ "mill.ogg": "moinho",
+ "mimosa.ogg": "mimosa",
+ "mirror.ogg": "espelho",
+ "mixer.ogg": "batedeira",
"mole.ogg": "toupeira",
- "mom.ogg": "",
- "moon.ogg": "",
- "moose.ogg": "",
+ "mom.ogg": "mamãe",
+ "moon.ogg": "lua",
+ "moose.ogg": "alce",
"mop.ogg": "esfregão",
- "mosque.ogg": "",
+ "mosque.ogg": "mesquita",
"mosquito.ogg": "mosquito",
- "mother.ogg": "",
- "motorcycle.ogg": "",
- "mountain.ogg": "",
- "mouse.ogg": "",
+ "mother.ogg": "mãe",
+ "motorcycle.ogg": "motocicleta",
+ "mountain.ogg": "montanha",
+ "mouse.ogg": "rato",
"mouth.ogg": "boca",
- "movie.ogg": "",
- "mower.ogg": "",
+ "movie.ogg": "filme",
+ "mower.ogg": "cortador de grama",
"mud.ogg": "lama",
"mug.ogg": "caneca",
"mule.ogg": "mula",
- "muscle.ogg": "",
+ "muscle.ogg": "músculo",
"mushroom.ogg": "cogumelo",
- "music.ogg": "",
- "musician.ogg": "",
- "naked.ogg": "",
+ "music.ogg": "música",
+ "musician.ogg": "músico",
+ "naked.ogg": "pelado",
"nap.ogg": "cochilar",
- "navel.ogg": "",
+ "navel.ogg": "umbigo",
"neck.ogg": "pescoço",
- "necklace.ogg": "",
- "needle.ogg": "",
+ "necklace.ogg": "colar",
+ "needle.ogg": "agulha",
"nest.ogg": "ninho",
"net.ogg": "rede",
- "newspaper.ogg": "",
+ "newspaper.ogg": "jornal",
"night.ogg": "noite",
- "nightgown.ogg": "",
+ "nightgown.ogg": "camisola",
"nose.ogg": "nariz",
- "nostril.ogg": "",
- "notebook.ogg": "",
- "number.ogg": "",
- "nun.ogg": "",
- "nurse.ogg": "",
- "nurse_male.ogg": "",
+ "nostril.ogg": "narina",
+ "notebook.ogg": "caderno",
+ "number.ogg": "número",
+ "nun.ogg": "freira",
+ "nurse.ogg": "enfermeira",
+ "nurse_male.ogg": "enfermeiro",
"nut.ogg": "noz",
"oar.ogg": "remo",
"ocean.ogg": "oceano",
- "office.ogg": "",
- "olive.ogg": "",
+ "office.ogg": "escritório",
+ "olive.ogg": "azeitona",
"on.ogg": "sobre",
- "one.ogg": "um",
- "onion.ogg": "",
- "open.ogg": "",
- "opossum.ogg": "",
+ "onion.ogg": "cebola",
+ "open.ogg": "aberta",
+ "opossum.ogg": "gambá",
"orange-color.ogg": "laranja",
"orange.ogg": "laranja",
- "orchid.ogg": "",
- "ostrich.ogg": "",
- "otter.ogg": "",
+ "orchid.ogg": "orquídea",
+ "ostrich.ogg": "avestruz",
+ "otter.ogg": "lontra",
"owl.ogg": "coruja",
"ox.ogg": "boi",
- "oyster.ogg": "",
- "pacifier.ogg": "",
+ "oyster.ogg": "ostra",
+ "pacifier.ogg": "chupeta",
"page.ogg": "página",
"pair.ogg": "par",
- "pajamas.ogg": "",
- "pal.ogg": "camarada",
- "palm_tree.ogg": "",
- "pan.ogg": "frigideira",
- "panda.ogg": "",
- "panther.ogg": "",
- "panties.ogg": "",
- "pants.ogg": "",
- "papaya.ogg": "",
- "paper.ogg": "",
- "parachute.ogg": "",
- "parakeet.ogg": "",
- "parrot.ogg": "",
+ "pajamas.ogg": "pijama",
+ "pal.ogg": "amigo",
+ "palm_tree.ogg": "palmeira",
+ "pan.ogg": "panela",
+ "panda.ogg": "panda",
+ "panther.ogg": "pantera",
+ "panties.ogg": "calcinha",
+ "pants.ogg": "calça",
+ "papaya.ogg": "mamão",
+ "paper.ogg": "papel",
+ "parachute.ogg": "paraquedas",
+ "parakeet.ogg": "periquito",
+ "parrot.ogg": "papagaio",
"patch.ogg": "remendo",
"path.ogg": "caminho",
"paw.ogg": "pegada",
- "pea.ogg": "",
+ "pea.ogg": "ervilha",
"peach.ogg": "pêssego",
- "peacock.ogg": "",
- "peak.ogg": "",
- "pear.ogg": "",
- "pearl.ogg": "",
+ "peacock.ogg": "pavão",
+ "peak.ogg": "pico",
+ "pear.ogg": "pera",
+ "pearl.ogg": "pérola",
"peck.ogg": "bicar",
- "pedal.ogg": "",
- "pelican.ogg": "",
+ "pedal.ogg": "pedal",
+ "pelican.ogg": "pelicano",
"pen.ogg": "caneta",
"pencil.ogg": "lápis",
- "peony.ogg": "",
- "people.ogg": "",
- "pepper.ogg": "",
- "peppers.ogg": "",
+ "peony.ogg": "peônia",
+ "people.ogg": "pessoas",
+ "pepper.ogg": "pimenta",
+ "peppers.ogg": "pimentas",
"pet.ogg": "animal de estimação",
- "petal.ogg": "",
- "petite.ogg": "",
- "phone.ogg": "",
- "piano.ogg": "",
- "picture.ogg": "foto",
- "pie.ogg": "",
+ "petal.ogg": "pétala",
+ "phone.ogg": "telefone",
+ "piano.ogg": "piano",
+ "picture.ogg": "quadro",
+ "pie.ogg": "torta",
"pig.ogg": "porco",
- "pigeon.ogg": "",
- "pill.ogg": "",
- "pillow.ogg": "",
- "pilot.ogg": "",
+ "pigeon.ogg": "pombo",
+ "pill.ogg": "comprimido",
+ "pillow.ogg": "travesseiro",
+ "pilot.ogg": "piloto",
"pine.ogg": "pinheiro",
- "pine_cone.ogg": "",
+ "pine_cone.ogg": "pinha",
"pink.ogg": "rosa",
- "pip.ogg": "",
- "pipe.ogg": "",
- "piranha.ogg": "",
- "pirate.ogg": "",
- "pizza.ogg": "",
+ "pip.ogg": "semente",
+ "pipe.ogg": "cachimbo",
+ "piranha.ogg": "piranha",
+ "pirate.ogg": "pirata",
+ "pizza.ogg": "pizza",
"plane.ogg": "avião",
- "planet.ogg": "",
+ "planet.ogg": "planeta",
"plant.ogg": "planta",
"plate.ogg": "prato",
"play.ogg": "brincar",
- "pliers.ogg": "",
+ "pliers.ogg": "alicate",
"plow.ogg": "arar",
"plum.ogg": "ameixa",
- "plumber.ogg": "",
- "pocket.ogg": "",
- "pod.ogg": "",
- "pole.ogg": "pau",
- "police.ogg": "",
- "pompon.ogg": "",
- "pond.ogg": "",
- "pony.ogg": "",
+ "plumber.ogg": "encanador",
+ "pocket.ogg": "bolso",
+ "pod.ogg": "vagem",
+ "pole.ogg": "poste",
+ "police.ogg": "policial",
+ "pompon.ogg": "pompom",
+ "pond.ogg": "lagoa",
+ "pony.ogg": "pônei",
"pool.ogg": "piscina",
- "pop.ogg": "pipoca",
+ "popcorn.ogg": "pipoca",
"pope.ogg": "papa",
- "porthole.ogg": "",
- "post.ogg": "",
+ "porthole.ogg": "escotilha",
+ "post.ogg": "correio",
"pot.ogg": "pote",
- "potato.ogg": "",
+ "potato.ogg": "batata",
"pounce.ogg": "atacar",
- "president.ogg": "",
+ "president.ogg": "presidente",
"pretty.ogg": "bonita",
"price.ogg": "preço",
- "priest.ogg": "",
+ "priest.ogg": "padra",
"prince.ogg": "príncipe",
"princess.ogg": "princesa",
- "prison.ogg": "",
- "prisoner.ogg": "",
+ "prison.ogg": "prisão",
+ "prisoner.ogg": "prisioneiro",
"prize.ogg": "prêmio",
"pug.ogg": "pug",
- "pull.ogg": "",
- "pullover.ogg": "",
- "pumpkin.ogg": "",
- "puppy.ogg": "cachorro",
- "pyramid.ogg": "",
+ "pull.ogg": "puxar",
+ "pullover.ogg": "pulover",
+ "pumpkin.ogg": "moranga",
+ "puppy.ogg": "cachorrinho",
+ "pyramid.ogg": "pirâmide",
"quarrel.ogg": "discutir",
"queen.ogg": "rainha",
"question.ogg": "pergunta",
"quilt.ogg": "colcha",
"quiz.ogg": "enigma",
- "rabbit.ogg": "",
- "rabbit_baby.ogg": "",
- "race.ogg": "",
- "radio.ogg": "",
- "radish.ogg": "",
- "raft.ogg": "",
- "rag.ogg": "flanela",
+ "rabbit.ogg": "coelho",
+ "rabbit_baby.ogg": "coelho bebê",
+ "race.ogg": "corrida",
+ "radio.ogg": "rádio",
+ "radish.ogg": "rabanete",
+ "raft.ogg": "jangada",
+ "rag.ogg": "trapo",
"rage.ogg": "raiva",
- "rain.ogg": "",
- "raincoat.ogg": "",
- "rake.ogg": "ciscador",
+ "rain.ogg": "chuva",
+ "raincoat.ogg": "capa de chuva",
+ "rake.ogg": "ancinho",
"ramp.ogg": "rampa",
- "ran.ogg": "chegada",
- "raspberry.ogg": "",
+ "ran.ogg": "correu",
+ "raspberry.ogg": "framboesa",
"rat.ogg": "rato",
- "razor.ogg": "",
+ "razor.ogg": "navalha",
"read.ogg": "ler",
"red.ogg": "vermelho",
- "reptile.ogg": "",
- "rhinoceros.ogg": "",
+ "reptile.ogg": "réptil",
+ "rhinoceros.ogg": "rinoceronte",
"rice.ogg": "arroz",
- "ride.ogg": "pedalar",
- "rifle.ogg": "",
+ "ride.ogg": "passeio",
+ "rifle.ogg": "espingarda",
"right.ogg": "direita",
- "rip.ogg": "arrancar",
- "rise.ogg": "",
- "river.ogg": "",
- "road.ogg": "",
- "roast.ogg": "",
- "robe.ogg": "",
- "robot.ogg": "",
+ "rip.ogg": "rasgar",
+ "rise.ogg": "subir",
+ "river.ogg": "rio",
+ "road.ogg": "estrada",
+ "roast.ogg": "assado",
+ "robe.ogg": "manto",
+ "robot.ogg": "robô",
"rock.ogg": "rocha",
- "rocket.ogg": "",
- "rolling_pin.ogg": "",
+ "rocket.ogg": "foguete",
+ "rolling_pin.ogg": "rolo de massa",
"roof.ogg": "telhado",
- "room.ogg": "",
- "root.ogg": "",
+ "room.ogg": "sala",
+ "root.ogg": "raiz",
"rope.ogg": "corda",
"rose.ogg": "rosa",
"round.ogg": "redondo",
- "rowing.ogg": "",
+ "rowing.ogg": "remo",
"royal.ogg": "real",
"rug.ogg": "tapete",
"run.ogg": "correr",
- "sad.ogg": "tristeza",
- "saddle.ogg": "",
+ "sad.ogg": "triste",
+ "saddle.ogg": "sela",
"sail.ogg": "veleiro",
- "sailor.ogg": "",
- "salamander.ogg": "",
- "salmon.ogg": "",
+ "sailor.ogg": "marinheiro",
+ "salamander.ogg": "salamandra",
+ "salmon.ogg": "salmão",
"sand.ogg": "areia",
- "sandals.ogg": "",
+ "sandals.ogg": "sandálias",
"sandwich.ogg": "sanduíche",
- "sash.ogg": "",
- "sat.ogg": "sentar",
+ "sash.ogg": "faixa",
"sauce.ogg": "molho",
- "sausage.ogg": "",
- "scale.ogg": "balança de cozinha",
+ "sausage.ogg": "salsicha",
+ "scale.ogg": "balança",
"scar.ogg": "cicatriz",
- "scared.ogg": "assustar",
+ "scare.ogg": "assustar",
"scarf.ogg": "cachecol",
"school.ogg": "escola",
- "school_bag.ogg": "",
+ "school_bag.ogg": "mochila escolar",
"science.ogg": "ciência",
- "scissors.ogg": "",
- "scorpion.ogg": "",
+ "scissors.ogg": "tesoura",
+ "scorpion.ogg": "escorpião",
"scratch.ogg": "arranhar",
"scream.ogg": "gritar",
"screw.ogg": "parafuso",
- "screwdriver.ogg": "",
+ "screwdriver.ogg": "chave de fenda",
"scribble.ogg": "rabiscar",
- "sea.ogg": "",
- "seat.ogg": "assento",
- "see.ogg": "observar",
+ "sea.ogg": "mar",
+ "seat.ogg": "cadeira",
+ "see.ogg": "ver",
"seed.ogg": "semente",
- "shadow.ogg": "",
+ "shadow.ogg": "sombra",
"shake.ogg": "sacudir",
"shark.ogg": "tubarão",
- "shave.ogg": "",
- "shed.ogg": "celeiro",
- "sheep.ogg": "",
+ "shave.ogg": "barbear",
+ "shed.ogg": "barracão",
+ "sheep.ogg": "ovelha",
"shelf.ogg": "prateleira",
"shell.ogg": "concha",
"ship.ogg": "navio",
"shirt.ogg": "camisa",
"shoe.ogg": "sapato",
- "shoelace.ogg": "",
+ "shoelace.ogg": "cadarço",
"shop.ogg": "loja",
- "shore.ogg": "costa",
- "short.ogg": "short",
- "shovel.ogg": "",
+ "shore.ogg": "praia",
+ "short.ogg": "bermuda",
+ "shovel.ogg": "pá",
"shower.ogg": "chuveiro",
"shrimp.ogg": "camarão",
"shrub.ogg": "arbusto",
"shut.ogg": "fechado",
- "shutter.ogg": "",
+ "shutter.ogg": "veneziana",
"sick.ogg": "doente",
- "sidewalk.ogg": "",
+ "sidewalk.ogg": "calçada",
"sign.ogg": "placa",
"sing.ogg": "cantar",
"sink.ogg": "pia",
- "sip.ogg": "sorver",
- "sister.ogg": "",
+ "sip.ogg": "bebericar",
+ "sister.ogg": "irmã",
"sit.ogg": "sentar",
- "skate.ogg": "patinar",
- "skeleton.ogg": "",
- "ski.ogg": "esquiar",
- "skimmer.ogg": "",
+ "skate.ogg": "skate",
+ "skeleton.ogg": "esqueleto",
+ "ski.ogg": "esqui",
+ "skimmer.ogg": "escumadeira",
"skin.ogg": "pele",
"skirt.ogg": "saia",
"skunk.ogg": "gambá",
"sky.ogg": "céu",
- "slam.ogg": "",
+ "slam.ogg": "enterrar",
"sled.ogg": "trenó",
"sleep.ogg": "dormir",
"sleeve.ogg": "manga",
"sleigh.ogg": "trenó",
"slide.ogg": "escorregador",
- "slim.ogg": "",
+ "slim.ogg": "magra",
"slime.ogg": "muco",
- "slippers.ogg": "",
+ "slippers.ogg": "chinelos",
"slope.ogg": "declive",
- "sloppy.ogg": "",
- "slot.ogg": "",
- "sloth.ogg": "",
- "slug.ogg": "",
+ "sloppy.ogg": "desleixado",
+ "slot.ogg": "fresta",
+ "sloth.ogg": "bicho-preguiça",
+ "slug.ogg": "lesma",
"small.ogg": "pequeno",
"smell.ogg": "cheirar",
"smile.ogg": "sorriso",
- "smock.ogg": "jaleco",
+ "smock.ogg": "blusão",
"smoke.ogg": "fumaça",
"smooch.ogg": "beijar",
- "snack.ogg": "aperitivo",
+ "snack.ogg": "lanchinho",
"snail.ogg": "caracol",
"snake.ogg": "cobra",
"sneaker.ogg": "tênis",
- "sniff.ogg": "farejar",
+ "sniff.ogg": "cheirar",
"snow.ogg": "neve",
- "soap.ogg": "",
- "sob.ogg": "",
+ "soap.ogg": "sabão",
+ "sob.ogg": "soluço",
"sock.ogg": "meia",
- "soldier.ogg": "",
- "sole.ogg": "",
- "sole_shoe.ogg": "",
- "son.ogg": "",
- "soup.ogg": "",
- "spade.ogg": "",
+ "soldier.ogg": "soldado",
+ "sole.ogg": "linguado",
+ "sole_shoe.ogg": "sola do sapato",
+ "son.ogg": "filho",
+ "soup.ogg": "sopa",
+ "spade.ogg": "pá",
"spaghetti.ogg": "espaguete",
- "spark.ogg": "",
- "sparrow.ogg": "",
- "spatula.ogg": "",
- "speak.ogg": "",
+ "spark.ogg": "faísca",
+ "sparrow.ogg": "pardal",
+ "spatula.ogg": "espátula",
+ "speak.ogg": "falar",
"spear.ogg": "lança",
- "spice.ogg": "",
+ "spice.ogg": "tempero",
"spider.ogg": "aranha",
- "spider_web.ogg": "",
- "spike.ogg": "porco-espinho",
+ "spider_web.ogg": "teia de aranha",
+ "spike.ogg": "espinho",
"spill.ogg": "derramar",
- "spinach.ogg": "",
- "spine.ogg": "",
- "spinning_top.ogg": "",
- "splash.ogg": "respingar",
- "splatter.ogg": "mancha",
+ "spinach.ogg": "espinafre",
+ "spine.ogg": "coluna",
+ "spinning_top.ogg": "pião",
+ "splash.ogg": "espirrar",
+ "splatter.ogg": "respingo",
"sponge.ogg": "esponja",
- "spool.ogg": "",
+ "spool.ogg": "carretel",
"spoon.ogg": "colher",
"sport.ogg": "esporte",
- "spot.ogg": "manchado",
+ "spot.ogg": "mancha",
"spray.ogg": "borrifar",
"spread.ogg": "espalhar",
- "spring.ogg": "pular",
- "spring_season.ogg": "",
+ "spring.ogg": "saltar",
+ "spring_season.ogg": "primavera",
"sprinkle.ogg": "granulado",
"square.ogg": "quadrado",
"squash.ogg": "abóbora",
"squat.ogg": "agachar",
"squid.ogg": "lula",
"squirrel.ogg": "esquilo",
"squirt.ogg": "borrifador",
- "stack.ogg": "pilha de pratos",
+ "stack.ogg": "pilha",
"stage.ogg": "palco",
- "staircase.ogg": "",
+ "staircase.ogg": "escada",
"stamp.ogg": "selo",
"stand.ogg": "de pé",
"star.ogg": "estrela",
- "stare.ogg": "olhar",
- "starfish.ogg": "estrela do mar",
- "steak.ogg": "",
- "steam.ogg": "",
- "steep.ogg": "",
- "steeple.ogg": "",
+ "stare.ogg": "encarar",
+ "starfish.ogg": "estrela-do-mar",
+ "steam.ogg": "vapor",
+ "steep.ogg": "íngreme",
+ "steeple.ogg": "campanário",
"stem.ogg": "caule",
- "step.ogg": "",
+ "step.ogg": "degrau",
"stew.ogg": "ensopado",
"stick.ogg": "galho",
- "sting.ogg": "ferroar",
- "stinky.ogg": "",
- "stitch.ogg": "",
- "stomach.ogg": "",
+ "sting.ogg": "picar",
+ "stinky.ogg": "fedido",
+ "stitch.ogg": "coser",
+ "stomach.ogg": "estômago",
"stone.ogg": "pedra",
"stop.ogg": "parar",
- "store.ogg": "mercearia",
+ "store.ogg": "loja",
"stove.ogg": "fogão",
"straight.ogg": "reto",
- "strainer.ogg": "",
+ "strainer.ogg": "escorredor",
"straw.ogg": "canudo",
"strawberry.ogg": "morango",
- "stream.ogg": "córrego",
+ "stream.ogg": "riacho",
"street.ogg": "rua",
- "stretch.ogg": "alongar",
+ "stretch.ogg": "esticar",
"string.ogg": "fio",
- "stripe.ogg": "listrado",
+ "stripe.ogg": "listra",
"strong.ogg": "forte",
- "student.ogg": "",
+ "student.ogg": "estudante",
"study.ogg": "estudar",
- "stump.ogg": "tronco",
- "sugar.ogg": "",
+ "stump.ogg": "toco",
+ "sugar.ogg": "açúcar",
"suit.ogg": "terno",
- "suitcase.ogg": "",
+ "suitcase.ogg": "mala",
"summer.ogg": "verão",
- "summit.ogg": "",
+ "summit.ogg": "cume",
"sun.ogg": "sol",
"swan.ogg": "cisne",
"sweat.ogg": "suor",
- "sweatshirt.ogg": "",
- "swim.ogg": "nadar",
- "table.ogg": "",
- "tablecloth.ogg": "",
- "tadpole.ogg": "",
+ "sweatshirt.ogg": "suéter",
+ "swim.ogg": "natação",
+ "table.ogg": "mesa",
+ "tablecloth.ogg": "toalha de mesa",
+ "tadpole.ogg": "girino",
"tag.ogg": "etiqueta",
- "tail.ogg": "",
+ "tail.ogg": "cauda",
"tall.ogg": "alto",
- "tape_measure.ogg": "",
- "taxi.ogg": "",
+ "tape_measure.ogg": "trena",
+ "taxi.ogg": "táxi",
"teach.ogg": "ensinar",
- "teacher.ogg": "professor",
+ "teacher.ogg": "professora",
"tear.ogg": "rasgar",
- "teddy.ogg": "",
+ "teddy.ogg": "urso de pelúcia",
"teeth.ogg": "dentes",
- "television.ogg": "",
- "temple.ogg": "",
- "ten.ogg": "dez",
- "tennis.ogg": "",
- "tent.ogg": "",
- "text.ogg": "",
+ "television.ogg": "televisão",
+ "temple.ogg": "templo",
+ "tennis.ogg": "tênis",
+ "tent.ogg": "tenda",
+ "text.ogg": "texto",
"thick.ogg": "grosso",
- "thief.ogg": "",
+ "thief.ogg": "ladrão",
"thigh.ogg": "coxa",
"think.ogg": "pensar",
"thread.ogg": "linha",
- "three.ogg": "três",
"throat.ogg": "garganta",
- "throw.ogg": "arremessar",
- "thumb.ogg": "",
+ "throw.ogg": "arremesso",
+ "thumb.ogg": "polegar",
"tick.ogg": "carrapato",
- "ticket.ogg": "",
- "tiger.ogg": "",
+ "ticket.ogg": "ingresso",
+ "tiger.ogg": "tigre",
"time.ogg": "hora",
- "tin.ogg": "",
- "tire.ogg": "",
+ "tin.ogg": "lata",
+ "tire.ogg": "pneu",
"tired.ogg": "cansado",
- "tissue.ogg": "",
- "toad.ogg": "",
- "toaster.ogg": "",
- "toe.ogg": "",
+ "tissue.ogg": "lenço de papel",
+ "to_drink.ogg": "beber",
+ "toad.ogg": "sapo",
+ "toaster.ogg": "torradeira",
+ "toe.ogg": "dedo do pé",
"toilet.ogg": "banheiro",
- "tomatoe.ogg": "",
- "tongs.ogg": "",
- "tongue.ogg": "",
+ "tomatoe.ogg": "tomate",
+ "tongs.ogg": "pegador",
+ "tongue.ogg": "língua",
"tool.ogg": "ferramenta",
"top.ogg": "topo",
"torch.ogg": "tocha",
"touch.ogg": "tocar",
"towel.ogg": "toalha",
"toy.ogg": "brinquedo",
"trail.ogg": "trilha",
"train.ogg": "trem",
- "train_station.ogg": "",
+ "train_station.ogg": "estação de trem",
"trap.ogg": "ratoeira",
- "trash.ogg": "pá de lixo",
+ "trash.ogg": "lixo",
"tray.ogg": "bandeja",
- "treat.ogg": "doces",
+ "treat.ogg": "guloseimas",
"tree.ogg": "árvore",
- "triangle.ogg": "",
- "tribe.ogg": "",
- "trip.ogg": "",
+ "triangle.ogg": "triângulo",
+ "tribe.ogg": "tribo",
+ "trip.ogg": "viagem",
"truck.ogg": "caminhão",
"tube.ogg": "batom",
- "tulip.ogg": "",
+ "tulip.ogg": "tulipa",
"tune.ogg": "melodia",
- "turkey.ogg": "",
- "turnip.ogg": "",
- "turtle.ogg": "",
- "tusk.ogg": "",
- "twin_boys.ogg": "",
- "twin_girls.ogg": "",
- "two.ogg": "dois",
- "umbrella.ogg": "",
- "under.ogg": "embaixo",
- "uniform.ogg": "",
- "van.ogg": "van",
- "vapor.ogg": "",
- "vase.ogg": "",
- "vegetable.ogg": "",
- "vein.ogg": "",
- "verdure.ogg": "",
- "vest.ogg": "",
+ "turkey.ogg": "peru",
+ "turnip.ogg": "nabo",
+ "turtle.ogg": "tartaruga",
+ "tusk.ogg": "presa",
+ "twin_boys.ogg": "gêmeos",
+ "twin_girls.ogg": "gêmeas",
+ "umbrella.ogg": "guarda-chuva",
+ "under.ogg": "sob",
+ "uniform.ogg": "uniforme",
+ "van.ogg": "furgão",
+ "vapor.ogg": "vapor",
+ "vase.ogg": "vaso",
+ "vegetable.ogg": "vegetal",
+ "vein.ogg": "veia",
+ "verdure.ogg": "verdura",
+ "vest.ogg": "colete",
"vet.ogg": "veterinário",
- "viper.ogg": "",
- "vowel.ogg": "",
- "vulture.ogg": "",
+ "viper.ogg": "víbora",
+ "vowel.ogg": "vogal",
+ "vulture.ogg": "abutre",
"wag.ogg": "abanar",
"walk.ogg": "andar",
- "wall.ogg": "",
- "walnut.ogg": "",
- "wart.ogg": "",
+ "wall.ogg": "muro",
+ "walnut.ogg": "noz",
+ "wart.ogg": "verruga",
"wash.ogg": "lavar",
- "wasp.ogg": "",
- "watch.ogg": "relógio",
+ "wasp.ogg": "vespa",
+ "watch.ogg": "relógio de pulso",
"water.ogg": "água",
- "wave.ogg": "",
- "wedding.ogg": "",
+ "wave.ogg": "onda",
+ "wedding.ogg": "casamento",
"wedge.ogg": "cunha",
- "weight.ogg": "",
- "wet.ogg": "encharcado",
- "whale.ogg": "",
+ "weight.ogg": "peso",
+ "wet.ogg": "molhado",
+ "whale.ogg": "baleia",
"wheat.ogg": "trigo",
"wheel.ogg": "roda",
"whisk.ogg": "batedor",
"whisper.ogg": "cochichar",
"white.ogg": "branco",
- "wide.ogg": "",
- "wife.ogg": "",
+ "wide.ogg": "largo",
+ "wife.ogg": "esposa",
"wig.ogg": "peruca",
"win.ogg": "ganhar",
"wind.ogg": "vento",
- "window.ogg": "",
- "window_glass.ogg": "",
+ "window.ogg": "janela",
+ "window_glass.ogg": "vidraça",
"wing.ogg": "asa",
- "winter.ogg": "",
- "wolf.ogg": "",
- "woman.ogg": "",
+ "winter.ogg": "inverno",
+ "wolf.ogg": "lobo",
+ "woman.ogg": "mulher",
"wood.ogg": "madeira",
- "word.ogg": "",
- "worker.ogg": "",
- "world.ogg": "",
- "wreath.ogg": "",
+ "word.ogg": "palavra",
+ "worker.ogg": "trabalhador",
+ "world.ogg": "mundo",
+ "wreath.ogg": "grinalda",
"wrench.ogg": "chave inglesa",
"wrist.ogg": "pulso",
"write.ogg": "escrever",
- "yarn.ogg": "fio",
- "yellow.ogg": "",
- "yogurt.ogg": "",
- "yum.ogg": "delícia",
- "zebra.ogg": "",
- "zipper.ogg": "",
+ "yellow.ogg": "amarelo",
+ "yogurt.ogg": "iogurte",
+ "yum.ogg": "gostoso",
+ "zebra.ogg": "zebra",
+ "zipper.ogg": "zíper",
"zoo.ogg": "zoológico"
-}
+}
\ No newline at end of file
diff --git a/src/activities/lang/resource/content-ro.json b/src/activities/lang/resource/content-ro.json
index f235fbbe1..93dbfabb1 100644
--- a/src/activities/lang/resource/content-ro.json
+++ b/src/activities/lang/resource/content-ro.json
@@ -1,1106 +1,1092 @@
{
"10.ogg": "zece",
"11.ogg": "unsprezece",
"12.ogg": "doisprezece",
"16.ogg": "șaisprezece",
"U0030.ogg": "zero",
"U0031.ogg": "unu",
"U0032.ogg": "doi",
"U0033.ogg": "trei",
"U0034.ogg": "patru",
"U0035.ogg": "cinci",
"U0036.ogg": "șase",
"U0037.ogg": "șapte",
"U0038.ogg": "opt",
"U0039.ogg": "nouă",
"accountant.ogg": "contabil",
"ache.ogg": "durere",
"acorn.ogg": "ghindă",
"actor.ogg": "actor",
"air_horn.ogg": "goarnă",
"alarmclock.ogg": "ceas deșteptător",
"alligator.ogg": "aligator",
"alphabet.ogg": "alfabet",
"anchor.ogg": "ancoră",
"angel.ogg": "înger",
"angry.ogg": "supărată",
"animal.ogg": "animal",
"ankle.ogg": "gleznă",
"ant.ogg": "furnică",
"anteater.ogg": "furnicar",
"antelope.ogg": "antilopă",
"apple.ogg": "măr",
"apple_tree.ogg": "măr",
"appliance.ogg": "dispozitiv",
"apricot.ogg": "caisă",
"arm.ogg": "braț",
"armchair.ogg": "fotoliu",
"artichoke.ogg": "anghinare",
"artist.ogg": "artist",
"asparagus.ogg": "sparanghel",
"astronaut.ogg": "astronaut",
"athlete.ogg": "atlet",
"avocado.ogg": "avocado",
"ax.ogg": "topor",
"baby_bottle.ogg": "biberon",
"back.ogg": "spate",
"badge.ogg": "insignă",
"bag.ogg": "geantă",
"bait.ogg": "momeală",
- "bake.ogg": "copt",
"balance.ogg": "echilibru",
"bald.ogg": "chel",
"ball.ogg": "minge",
"ball_of_yarn.ogg": "ghem",
"ball_soccer.ogg": "minge de fotbal",
"ballet.ogg": "balet",
"bank.ogg": "bancă",
+ "banker_female.ogg": "bancheră",
"bark.ogg": "lătrat",
"barn.ogg": "hambar",
"bat.ogg": "liliac",
"bath.ogg": "baie",
"bathing_suit.ogg": "costum de baie",
"bay.ogg": "golf",
"beach.ogg": "plajă",
- "bead.ogg": "mărgea",
"bean.ogg": "boabă",
"bear.ogg": "urs",
"beard.ogg": "barbă",
"beat.ogg": "bătaie",
"beaver.ogg": "castor",
"bed.ogg": "pat",
"bedroom.ogg": "dormitor",
"bee.ogg": "albină",
- "beef.ogg": "carne de vită",
"beetle.ogg": "gândac",
"beg.ogg": "cerșit",
"behind.ogg": "în spate",
"bell.ogg": "clopot",
"belly.ogg": "burtă",
"bench.ogg": "bancă",
"bib.ogg": "bavețică",
"big.ogg": "mare",
"big_top.ogg": "cupolă",
"bike.ogg": "bicicletă",
"bird.ogg": "pasăre",
"bit.ogg": "bucățică",
"bite.ogg": "mușcat",
"black.ogg": "negru",
"blackberry.ogg": "mură",
"blackbird.ogg": "mierlă",
"blade.ogg": "lamă",
"blind.ogg": "orb",
"blink.ogg": "clipit",
"block.ogg": "(mono)bloc",
"blond.ogg": "blond",
"blue.ogg": "albastru",
"blueberry.ogg": "afină",
"blush.ogg": "înroșit",
"board.ogg": "scândură",
"boat.ogg": "barcă",
"boil.ogg": "fiert",
"bolt.ogg": "șurub",
"bomb.ogg": "bombă",
"bone.ogg": "os",
"book.ogg": "carte",
"bookcase.ogg": "biblioraft",
"bottom.ogg": "fund",
"box.ogg": "cutie",
"boxer.ogg": "boxer",
"boy.ogg": "băiat",
"braid.ogg": "codiță împletită",
"brain.ogg": "creier",
"branch.ogg": "ramură",
"bread.ogg": "pâine",
"break.ogg": "spart",
"breast.ogg": "sân",
"brick.ogg": "cărămidă",
"bricklayer.ogg": "zidar",
"bride.ogg": "mireasă",
"bridge.ogg": "pod",
"bright.ogg": "strălucitor",
"broccoli.ogg": "broccoli",
"brother.ogg": "frate",
"brown.ogg": "maro",
"brush.ogg": "pensulă",
"bubble.ogg": "bulă",
"bucket.ogg": "găleată",
"bud.ogg": "mugur",
"buffalo.ogg": "bizon",
"bug.ogg": "insectă",
"bulb.ogg": "bec",
"bull.ogg": "taur",
"bump.ogg": "cucui",
"bun.ogg": "chiflă",
"bus.ogg": "autobuz",
"bush.ogg": "tufiș",
"butcher.ogg": "măcelar",
"butter.ogg": "unt",
"butterfly.ogg": "fluture",
"button.ogg": "nasture",
"cabbage.ogg": "varză",
"cabin.ogg": "cabană",
"cacao.ogg": "cacao",
"cactus.ogg": "cactus",
"cage.ogg": "cușcă",
"cake.ogg": "tort",
"call.ogg": "chemat",
"camel.ogg": "cămilă",
"camera.ogg": "cameră foto",
"camp.ogg": "tabără",
"can.ogg": "conservă",
"canary.ogg": "canar",
"candle.ogg": "lumânare",
"candy.ogg": "bomboană",
"cane.ogg": "baston",
"canoe.ogg": "canoe",
"canon.ogg": "tun",
"canyon.ogg": "canion",
"cap.ogg": "șapcă",
"cape.ogg": "robă",
"car.ogg": "mașină",
"carafe.ogg": "carafă",
"card.ogg": "carte poștală",
"carnival.ogg": "carnaval",
"carpenter.ogg": "dulgher",
"carpet.ogg": "covor",
"carrot.ogg": "morcov",
"cart.ogg": "cărucior de cumpărături",
"cash.ogg": "bani în numerar",
"castle.ogg": "castel",
"cat.ogg": "pisică",
"cat_female.ogg": "pisică",
"catch.ogg": "prins",
"caterpillar.ogg": "omidă",
"cauldron.ogg": "cazan",
"cauliflower.ogg": "conopidă",
"cave.ogg": "peșteră",
"cavern.ogg": "cavernă",
"celery.ogg": "țelină",
"centipede.ogg": "centiped",
"cereal.ogg": "cereală",
"chain.ogg": "lanț",
"chair.ogg": "scaun",
"chalk.ogg": "cretă",
"chameleon.ogg": "cameleon",
"chandelier.ogg": "candelabru",
"chat.ogg": "pălăvrăgeală",
"cheek.ogg": "obraz",
"cheer.ogg": "înveselire",
"cheese.ogg": "brânză",
"chef.ogg": "bucătar șef",
"cherry.ogg": "cireașă",
"chest.ogg": "cufăr",
"chick.ogg": "puișor de găină",
"chicken.ogg": "pui de găină",
- "chief.ogg": "căpetenie",
"child.ogg": "copil",
"chimney.ogg": "horn",
"chimp.ogg": "cimpanzeu",
"chin.ogg": "bărbie",
"chocolate.ogg": "ciocolată",
"chop.ogg": "retezat",
- "chore.ogg": "treburi casnice",
+ "chores.ogg": "treburi casnice",
"christmas.ogg": "Crăciun",
"cigar.ogg": "trabuc",
"circus.ogg": "circ",
"city.ogg": "oraș",
"clam.ogg": "scoică",
"clap.ogg": "aplaudat",
"class.ogg": "oră de curs",
"claw.ogg": "gheară",
"clay.ogg": "lut",
"clean.ogg": "curățat",
"cleaning_lady.ogg": "femeie de servici",
"cliff.ogg": "faleză",
"climb.ogg": "urcare",
"clock.ogg": "ceas",
"cloth.ogg": "pânză",
"clothes_hanger.ogg": "umeraș",
"cloud.ogg": "nor",
"cloudy.ogg": "noros",
"clover.ogg": "trifoi",
"clown.ogg": "clovn",
"coach.ogg": "antrenor",
"coast.ogg": "coastă",
"coat.ogg": "palton",
"cobra.ogg": "cobră",
"coconut.ogg": "nucă de cocos",
"cod.ogg": "cod",
"coffee.ogg": "cafea",
"coin.ogg": "monedă",
"cold.ogg": "rece",
"color.ogg": "culoare",
"colt.ogg": "mânz",
"comb.ogg": "pieptene",
"cone.ogg": "con",
+ "cook.ogg": "gătit",
"cookie.ogg": "fursec",
"cork.ogg": "dop",
"corn.ogg": "porumb",
"couch.ogg": "canapea",
"cough.ogg": "tuse",
"couple.ogg": "cuplu",
"cow.ogg": "vacă",
"cowboy.ogg": "cowboy",
"crab.ogg": "crab",
"cradle.ogg": "leagăn",
"craft.ogg": "meșteșug",
"crawl.ogg": "târât",
"crazy.ogg": "nebun",
"creek.ogg": "pârâu",
"crepe.ogg": "clătituță",
"crib.ogg": "pătuț de bebeluș",
- "criminal.ogg": "criminal",
"croak.ogg": "orăcăit",
"crocodile.ogg": "crocodil",
"cross.ogg": "cruce",
"crow.ogg": "cioară",
"crown.ogg": "coroană",
"crumb.ogg": "fărâmitură",
"crust.ogg": "crustă",
"cry.ogg": "plâns",
"crystal.ogg": "cristal",
"cube.ogg": "cub",
"cucumber.ogg": "castravete",
"curtain.ogg": "cortină",
"cut.ogg": "tăiat",
"cute.ogg": "drăguț",
"dad.ogg": "tată",
"daffodil.ogg": "narcisă",
"daisy.ogg": "margaretă",
"dam.ogg": "baraj",
"dance.ogg": "dans",
"dandelion.ogg": "păpădie",
- "danger.ogg": "pericol",
- "dark.ogg": "închis",
"dart_board.ogg": "țintar",
"date_fruit.ogg": "curmală",
"deer.ogg": "cerb",
"den.ogg": "bârlog",
"desert.ogg": "deșert",
"desk.ogg": "masă",
"dessert.ogg": "desert",
"diamond.ogg": "diamant",
"dig.ogg": "săpat",
"dirt.ogg": "murdărie",
"dirty.ogg": "murdar",
"dish.ogg": "vas de mâncare",
"dishcloth.ogg": "lavetă",
"dive.ogg": "scufundare",
"doctor.ogg": "doctor",
"doe.ogg": "căprioară",
"dog.ogg": "câine",
"doll.ogg": "păpușă",
"dolphin.ogg": "delfin",
"domino.ogg": "domino",
"door.ogg": "ușă",
"doormat.ogg": "ștergător de picioare",
"dot.ogg": "punct",
"doughnut.ogg": "gogoașă",
"dove.ogg": "porumbel",
"dragon.ogg": "dragon",
"dragonfly.ogg": "libelulă",
- "drank.ogg": "băut",
"draw.ogg": "desen",
"drawer.ogg": "sertar",
"dream.ogg": "vis",
"dress.ogg": "rochie",
"drink.ogg": "băutură",
- "drinking.ogg": "băut",
"drip.ogg": "picătură",
"drive.ogg": "condus",
"drool.ogg": "salivat",
"drum.ogg": "tobă",
"dry.ogg": "uscat",
"duck.ogg": "rață",
"duck_mother.ogg": "rață",
"dune.ogg": "dună",
"dwarf.ogg": "pitic",
"eagle.ogg": "vultur",
"ear.ogg": "ureche",
"earth.ogg": "pământ",
"eat.ogg": "mâncat",
"egg.ogg": "ou",
"eggplant.ogg": "vânătă",
"elbow.ogg": "cot",
"electrician.ogg": "electrician",
"elk.ogg": "elan",
"empty.ogg": "gol",
"engine.ogg": "motor",
"engineer.ogg": "inginer",
"eraser.ogg": "radieră",
"explore.ogg": "explorare",
"eyelash.ogg": "geană",
"eyes.ogg": "ochi",
"face.ogg": "față",
"fair.ogg": "târg",
"fairy.ogg": "zână",
- "fall_down.ogg": "prăbușire",
+ "fall.ogg": "căzut",
"fall_season.ogg": "toamnă",
"family.ogg": "familie",
"fan.ogg": "ventilator",
"farm.ogg": "fermă",
"farmer.ogg": "fermier",
"fat.ogg": "gras",
"faucet.ogg": "robinet",
"fawn.ogg": "ieduț",
+ "fear.ogg": "frică",
"feast.ogg": "festin",
"feather.ogg": "pană",
"feed.ogg": "hrănit",
- "feet.ogg": "labele picioarelor",
- "fell.ogg": "căzut",
"femur.ogg": "femur",
"fetch.ogg": "aport",
"fig.ogg": "smochină",
"fin.ogg": "aripioară înotătoare",
"find.ogg": "găsit",
"finger.ogg": "deget",
"fire.ogg": "foc",
"fire_extinguisher.ogg": "extinctor",
"fireman.ogg": "pompier",
"fish.ogg": "pește",
"fisherman.ogg": "pescar",
"fist.ogg": "pumn",
"flacon.ogg": "flacon",
"flag.ogg": "steag",
"flame.ogg": "flacără",
"flamingo.ogg": "flamingo",
"flash.ogg": "lanternă",
"flat.ogg": "plan",
"flies.ogg": "muște",
- "flight.ogg": "zbor",
"float.ogg": "plutit",
"flour.ogg": "făină",
"flower.ogg": "floare",
"fluff.ogg": "puf",
"flute.ogg": "fluier",
"fly.ogg": "zbor",
"foam.ogg": "spumă",
- "food.ogg": "mâncare",
"foot.ogg": "laba piciorului",
"forest.ogg": "pădure",
"fork.ogg": "furculiță",
"fountain.ogg": "fântână",
"fox.ogg": "vulpe",
"freeze.ogg": "îngheț",
"friend.ogg": "prieten",
"fries.ogg": "cartofi pai",
"frog.ogg": "broască",
"front.ogg": "în față",
- "frown.ogg": "încruntat",
"fruit.ogg": "fruct",
"fudge.ogg": "caramele",
"full.ogg": "plin",
- "fun.ogg": "distractiv",
"fur.ogg": "blană",
"game.ogg": "joc",
"garage.ogg": "garaj",
"garden.ogg": "grădină",
"garlic.ogg": "usturoi",
"gem.ogg": "piatră prețioasă",
"giant.ogg": "gigant",
"gift.ogg": "cadou",
"giraffe.ogg": "girafă",
"girl.ogg": "fată",
"glass.ogg": "pahar",
"glasses.ogg": "ochelari",
"glove.ogg": "mănușă",
"glue.ogg": "lipici",
"gnome.ogg": "spiriduș",
"goat.ogg": "capră",
"golden.ogg": "aurit",
"golf.ogg": "golf",
"goose.ogg": "gâscă",
"gorilla.ogg": "gorilă",
"grain.ogg": "grâne",
"grandmother.ogg": "bunică",
"grape.ogg": "strugure",
"grapefruit.ogg": "grapefruit",
"grass.ogg": "iarbă",
"grave.ogg": "mormânt",
"gray.ogg": "gri",
"green.ogg": "verde",
"grill.ogg": "gril",
"grin.ogg": "rânjet",
"ground.ogg": "sol",
"growl.ogg": "mârâit",
"guignol.ogg": "păpușă franceză",
"guinea_pig.ogg": "cobai",
"gum.ogg": "gumă",
"hair.ogg": "păr",
"hair_dryer.ogg": "uscător",
"half.ogg": "jumătate",
"ham.ogg": "șuncă",
+ "hamburger.ogg": "hamburgher",
"hammer.ogg": "ciocan",
"hand.ogg": "mână",
"handlebar.ogg": "ghidon",
"happy.ogg": "fericit",
"harp.ogg": "harpă",
"hat.ogg": "pălărie",
"hatch.ogg": "eclozat",
"hay.ogg": "fân",
"head.ogg": "cap",
"hear.ogg": "auzit",
"heat.ogg": "căldură",
"hedge.ogg": "gard viu",
"hedgehog.ogg": "arici",
"heel.ogg": "toc",
"helmet.ogg": "cască",
"hen.ogg": "găină",
"herd.ogg": "turmă",
"high.ogg": "înalt",
"hike.ogg": "drumeție",
"hill.ogg": "deal",
"hip.ogg": "șold",
"hippopotamus.ogg": "hipopotam",
"hit.ogg": "lovit",
"hive.ogg": "stup",
"hockey.ogg": "hochei",
"hole.ogg": "gaură",
"home.ogg": "casă",
"hook.ogg": "cârlig",
"hop.ogg": "sărit",
"horse.ogg": "cal",
"hose.ogg": "furtun",
"hospital.ogg": "spital",
"hot.ogg": "fierbinte",
"hot_dog.ogg": "hot dog",
"hound.ogg": "ogar",
"house.ogg": "casă",
"howl.ogg": "urlat",
"hug.ogg": "îmbrățișat",
"huge.ogg": "uriaș",
"hummingbird.ogg": "colibri",
- "hunchback.ogg": "cocoșat",
+ "hunchbacked.ogg": "cocoșat",
"hunter.ogg": "vânător",
"husband.ogg": "soț",
"hut.ogg": "colibă",
"hyena.ogg": "hienă",
"ice.ogg": "gheață",
"iceberg.ogg": "iceberg",
"iguana.ogg": "iguană",
"ill.ogg": "bolnav",
"ink.ogg": "cerneală",
"island.ogg": "insulă",
"jacket.ogg": "jachetă",
"jaguar.ogg": "jaguar",
"jam.ogg": "gem",
"jay.ogg": "gaiță",
"jelly.ogg": "piftie",
"jellyfish.ogg": "meduză",
"jewel.ogg": "piatră prețioasă",
"job.ogg": "meserie",
"jockey.ogg": "jocheu",
"jog.ogg": "alergat",
+ "joy.ogg": "bucurie",
"judge.ogg": "judecător",
"judo.ogg": "judo",
"juggler.ogg": "jongler",
"juice.ogg": "suc",
"jump.ogg": "sărit",
"kangaroo.ogg": "cangur",
"keel.ogg": "chilă",
"kernel.ogg": "sâmbure",
"keyboard.ogg": "tastatură",
"kimono.ogg": "kimonou",
"king.ogg": "rege",
"kiss.ogg": "sărut",
"kitchen.ogg": "bucătărie",
"kite.ogg": "zmeu",
"kitten.ogg": "pisoi",
"kiwi.ogg": "kiwi",
"knee.ogg": "genunchi",
"kneel.ogg": "îngenuncheat",
"knife.ogg": "cuțit",
"knight.ogg": "cavaler",
"knit.ogg": "tricotat",
"knot.ogg": "nod",
"koala.ogg": "koala",
"lad.ogg": "flăcău",
"lady.ogg": "doamnă",
"ladybug.ogg": "mămăruță",
"lake.ogg": "lac",
"lama.ogg": "lamă",
"lamb.ogg": "miel",
"lamp.ogg": "lampă",
"land.ogg": "teren",
"lane.ogg": "bandă de circulație",
"lap.ogg": "poală",
"lasso.ogg": "lasou",
"laugh.ogg": "râs",
"lava.ogg": "lavă",
"lawn.ogg": "gazon",
"lawyer.ogg": "avocat",
"leaf.ogg": "frunză",
"ledge.ogg": "cornișă",
"leek.ogg": "praz",
"left.ogg": "stânga",
"leg.ogg": "picior",
- "leg_animal.ogg": "picior",
"lemon.ogg": "lămâie",
"lemonade.ogg": "limonadă",
"lemur.ogg": "lemur",
"leopard.ogg": "leopard",
"lettuce.ogg": "salată verde",
"librarian.ogg": "bibliotecar",
"lick.ogg": "lins",
"lid.ogg": "capac",
"lift.ogg": "ridicat",
"light.ogg": "lumină",
"lighthouse.ogg": "far",
"lightning.ogg": "fulger",
"lilac.ogg": "liliac",
"lime.ogg": "lămâie verde",
"line.ogg": "linie",
"link.ogg": "verigă",
"lion.ogg": "leu",
"lion_cub.ogg": "pui de leu",
"lip.ogg": "buză",
"liquid.ogg": "lichid",
"lizard.ogg": "șopârlă",
"lobster.ogg": "homar",
"log.ogg": "buștean",
"look.ogg": "privit",
"lunch.ogg": "prânz",
"mad.ogg": "turbat",
"magic.ogg": "magic",
"magnet.ogg": "magnet",
"magnifying_glass.ogg": "lupă",
"magpie.ogg": "coțofană",
"mail.ogg": "corespondență",
"man.ogg": "bărbat",
"mane.ogg": "coamă",
"mango.ogg": "mango",
"map.ogg": "hartă",
"maple.ogg": "arțar",
"marble.ogg": "bile",
"mashed_potatoes.ogg": "cartofi piure",
"mask.ogg": "mască",
"mast.ogg": "catarg",
"mat.ogg": "rogojină",
"match.ogg": "chibrit",
"mate.ogg": "coleg",
"mattress.ogg": "saltea",
"mauve.ogg": "mov",
"meal.ogg": "masă",
"meat.ogg": "carne",
"mechanic.ogg": "mecanic",
"medal.ogg": "medalie",
"meet.ogg": "întâlnit",
"melon.ogg": "pepene galben",
- "men.ogg": "oameni",
"merry-go-round.ogg": "carusel",
"mice.ogg": "șoareci",
"microphone.ogg": "microfon",
"milk.ogg": "lapte",
"mill.ogg": "moară",
"mimosa.ogg": "mimoză",
"mirror.ogg": "oglindă",
"mixer.ogg": "mixer",
"mole.ogg": "cârtiță",
"mom.ogg": "mamă",
"moon.ogg": "lună",
"moose.ogg": "elan",
"mop.ogg": "mop",
"mosque.ogg": "moschee",
"mosquito.ogg": "țânțar",
"mother.ogg": "mamă",
"motorcycle.ogg": "motocicletă",
"mountain.ogg": "munte",
"mouse.ogg": "șoarece",
"mouth.ogg": "gură",
"movie.ogg": "film",
"mower.ogg": "mașină de tuns iarba",
"mud.ogg": "noroi",
"mug.ogg": "cană mare",
"mule.ogg": "catâr",
"muscle.ogg": "mușchi",
"mushroom.ogg": "ciupercă",
"music.ogg": "muzică",
"musician.ogg": "muzician",
"naked.ogg": "dezbrăcat",
"nap.ogg": "ațipit",
"navel.ogg": "ombilic",
"neck.ogg": "gât",
"necklace.ogg": "lănțișor",
"needle.ogg": "ac",
"nest.ogg": "cuib",
"net.ogg": "plasă",
"newspaper.ogg": "ziar",
"night.ogg": "noapte",
"nightgown.ogg": "cămașă de noapte",
"nose.ogg": "nas",
"nostril.ogg": "nară",
"notebook.ogg": "caiet",
"number.ogg": "număr",
"nun.ogg": "călugăriță",
"nurse.ogg": "asistentă",
"nurse_male.ogg": "asistent",
"nut.ogg": "nucă",
"oar.ogg": "vâslă",
"ocean.ogg": "ocean",
"office.ogg": "birou",
"olive.ogg": "măslină",
"on.ogg": "pe",
"onion.ogg": "ceapă",
"open.ogg": "deschisă",
"opossum.ogg": "oposum",
- "orange.ogg": "portocală",
"orange-color.ogg": "portocaliu",
+ "orange.ogg": "portocală",
"orchid.ogg": "orhidee",
"ostrich.ogg": "struț",
"otter.ogg": "vidră",
"owl.ogg": "bufniță",
"ox.ogg": "bou",
"oyster.ogg": "stridie",
"pacifier.ogg": "suzetă",
"page.ogg": "pagină",
"pair.ogg": "pereche",
"pajamas.ogg": "pijama",
"pal.ogg": "prieten",
"palm_tree.ogg": "palmier",
"pan.ogg": "tigaie",
"panda.ogg": "panda",
"panther.ogg": "panteră",
"panties.ogg": "chiloți",
"pants.ogg": "pantaloni",
"papaya.ogg": "papaya",
"paper.ogg": "hârtie",
"parachute.ogg": "parașută",
"parakeet.ogg": "papagal mic",
"parrot.ogg": "papagal mare",
"patch.ogg": "petic",
"path.ogg": "cărare",
"paw.ogg": "labă",
"pea.ogg": "mazăre",
"peach.ogg": "piersică",
"peacock.ogg": "păun",
"peak.ogg": "pisc",
"pear.ogg": "pară",
"pearl.ogg": "perlă",
"peck.ogg": "ciugulit",
"pedal.ogg": "pedală",
"pelican.ogg": "pelican",
"pen.ogg": "stilou",
"pencil.ogg": "creion",
"peony.ogg": "bujor",
"people.ogg": "oameni",
"pepper.ogg": "piper",
"peppers.ogg": "ardei iuți",
"pet.ogg": "animal de companie",
"petal.ogg": "petală",
- "petite.ogg": "minion",
"phone.ogg": "telefon",
"piano.ogg": "pian",
"picture.ogg": "imagine",
"pie.ogg": "plăcintă",
"pig.ogg": "porc",
"pigeon.ogg": "porumbel",
"pill.ogg": "pilulă",
"pillow.ogg": "pernă",
"pilot.ogg": "pilot",
"pine.ogg": "pin",
"pine_cone.ogg": "con de brad",
"pink.ogg": "roz",
"pip.ogg": "sămânță",
"pipe.ogg": "pipă",
"piranha.ogg": "piranha",
"pirate.ogg": "pirat",
"pizza.ogg": "pizza",
"plane.ogg": "avion",
"planet.ogg": "planetă",
"plant.ogg": "plantă",
"plate.ogg": "farfurie plată",
"play.ogg": "jucat",
"pliers.ogg": "clește",
"plow.ogg": "arat",
"plum.ogg": "prună",
"plumber.ogg": "instalator",
"pocket.ogg": "buzunar",
"pod.ogg": "păstaie",
"pole.ogg": "prăjină",
"police.ogg": "poliție",
"pompon.ogg": "pompon",
"pond.ogg": "iaz",
"pony.ogg": "ponei",
"pool.ogg": "bazin",
- "pop.ogg": "pop corn",
+ "popcorn.ogg": "pop corn",
"pope.ogg": "papă",
"porthole.ogg": "hublou",
"post.ogg": "poștă",
"pot.ogg": "oală",
"potato.ogg": "cartof",
"pounce.ogg": "înhățat",
"president.ogg": "președinte",
"pretty.ogg": "frumoasă",
"price.ogg": "preț",
"priest.ogg": "preot",
"prince.ogg": "prinț",
"princess.ogg": "prințesă",
"prison.ogg": "închisoare",
"prisoner.ogg": "prizonier",
"prize.ogg": "premiu",
"pug.ogg": "mops",
"pull.ogg": "tras",
"pullover.ogg": "pulover",
"pumpkin.ogg": "dovleac",
"puppy.ogg": "cățeluș",
"pyramid.ogg": "piramidă",
"quarrel.ogg": "certat",
"queen.ogg": "regină",
"question.ogg": "întrebare",
"quilt.ogg": "plapumă",
"quiz.ogg": "test",
"rabbit.ogg": "iepure",
"rabbit_baby.ogg": "iepuraș",
"race.ogg": "cursă",
"radio.ogg": "radio",
"radish.ogg": "ridiche",
"raft.ogg": "plută",
"rag.ogg": "zdreanță",
"rage.ogg": "furie",
"rain.ogg": "ploaie",
"raincoat.ogg": "impermeabil",
"rake.ogg": "greblă",
"ramp.ogg": "rampă",
"ran.ogg": "fugă",
"raspberry.ogg": "zmeură",
"rat.ogg": "șobolan",
"razor.ogg": "lamă de bărbierit",
"read.ogg": "citit",
"red.ogg": "roșu",
"reptile.ogg": "reptilă",
"rhinoceros.ogg": "rinocer",
"rice.ogg": "orez",
"ride.ogg": "mers așezat pe ceva",
"rifle.ogg": "pușcă",
"right.ogg": "dreapta",
"rip.ogg": "rupt",
"rise.ogg": "creștere",
"river.ogg": "râu",
"road.ogg": "drum",
"roast.ogg": "friptură",
"robe.ogg": "robă",
"robot.ogg": "robot",
"rock.ogg": "rocă",
"rocket.ogg": "rachetă",
"rolling_pin.ogg": "ruliu",
"roof.ogg": "acoperiș",
"room.ogg": "cameră",
"root.ogg": "rădăcină",
"rope.ogg": "funie",
"rose.ogg": "trandafir",
"round.ogg": "rotund",
"rowing.ogg": "vâslit",
"royal.ogg": "regal",
"rug.ogg": "covoraș",
"run.ogg": "fugit",
"sad.ogg": "trist",
"saddle.ogg": "șa",
"sail.ogg": "velă",
"sailor.ogg": "marinar",
"salamander.ogg": "salamandră",
"salmon.ogg": "somon",
"sand.ogg": "nisip",
"sandals.ogg": "sandale",
"sandwich.ogg": "sandwich",
"sash.ogg": "brâu",
- "sat.ogg": "șezut",
"sauce.ogg": "sos",
"sausage.ogg": "cârnat",
"scale.ogg": "cântar",
"scar.ogg": "cicatrice",
- "scared.ogg": "speriat",
+ "scare.ogg": "speriat",
"scarf.ogg": "eșarfă",
"school.ogg": "școală",
"school_bag.ogg": "ghiozdan",
"science.ogg": "știință",
"scissors.ogg": "foarfecă",
"scorpion.ogg": "scorpion",
"scratch.ogg": "zgâriat",
"scream.ogg": "țipat",
"screw.ogg": "șurub",
"screwdriver.ogg": "șurubelniță",
"scribble.ogg": "mâzgălit",
"sea.ogg": "mare",
"seat.ogg": "scaun",
"see.ogg": "văzut",
"seed.ogg": "sămânță",
"shadow.ogg": "umbră",
"shake.ogg": "scuturat",
"shark.ogg": "rechin",
"shave.ogg": "ras",
"shed.ogg": "șură",
"sheep.ogg": "oaie",
"shelf.ogg": "raft",
"shell.ogg": "scoică",
"ship.ogg": "vas de navigat",
"shirt.ogg": "cămașă",
"shoe.ogg": "pantof",
"shoelace.ogg": "șiret",
"shop.ogg": "magazin",
"shore.ogg": "țărm",
"short.ogg": "pantalon scurt",
"shovel.ogg": "lopată",
"shower.ogg": "duș",
"shrimp.ogg": "crevete",
"shrub.ogg": "tufă",
"shut.ogg": "închis",
"shutter.ogg": "oblon",
"sick.ogg": "bolnav",
"sidewalk.ogg": "trotuar",
"sign.ogg": "semn",
"sing.ogg": "cântat",
"sink.ogg": "chiuvetă",
"sip.ogg": "sorbit",
"sister.ogg": "soră",
"sit.ogg": "așezat",
"skate.ogg": "patinat",
"skeleton.ogg": "schelet",
"ski.ogg": "schi",
"skimmer.ogg": "spumieră",
"skin.ogg": "piele",
"skirt.ogg": "fustă",
"skunk.ogg": "sconcs",
"sky.ogg": "cer",
"slam.ogg": "trântit",
"sled.ogg": "sanie",
"sleep.ogg": "dormit",
"sleeve.ogg": "mânecă",
"sleigh.ogg": "sanie trasă de cai",
"slide.ogg": "tobogan",
"slim.ogg": "suplu",
"slime.ogg": "mâzgă",
"slippers.ogg": "papuci",
"slope.ogg": "pantă",
"sloppy.ogg": "neglijent",
"slot.ogg": "fantă",
"sloth.ogg": "leneș",
"slug.ogg": "melc fără cochilie",
"small.ogg": "mic",
"smell.ogg": "mirosit",
"smile.ogg": "zâmbet",
"smock.ogg": "bluză",
"smoke.ogg": "fum",
"smooch.ogg": "drăgălit",
"snack.ogg": "gustare",
"snail.ogg": "melc",
"snake.ogg": "șarpe",
"sneaker.ogg": "adidas",
"sniff.ogg": "adulmecat",
"snow.ogg": "zăpadă",
"soap.ogg": "săpun",
"sob.ogg": "plâns în hohote",
"sock.ogg": "șosetă",
"soldier.ogg": "soldat",
"sole.ogg": "calcan",
"sole_shoe.ogg": "talpă",
"son.ogg": "fiu",
"soup.ogg": "supă",
"spade.ogg": "spadă",
"spaghetti.ogg": "spaghete",
"spark.ogg": "scânteie",
"sparrow.ogg": "vrabie",
"spatula.ogg": "spatulă",
"speak.ogg": "vorbit",
"spear.ogg": "suliță",
"spice.ogg": "condiment",
"spider.ogg": "păianjen",
"spider_web.ogg": "pânză de păianjen",
"spike.ogg": "țeapă",
"spill.ogg": "vărsat",
"spinach.ogg": "spanac",
"spine.ogg": "șira spinării",
"spinning_top.ogg": "titirez",
"splash.ogg": "împroșcat",
"splatter.ogg": "împroșcat",
"sponge.ogg": "burete",
"spool.ogg": "mosor",
"spoon.ogg": "lingură",
"sport.ogg": "sport",
"spot.ogg": "pată",
"spray.ogg": "pulverizat",
"spread.ogg": "întins",
"spring.ogg": "săltat",
"spring_season.ogg": "primăvară",
"sprinkle.ogg": "presărat",
"square.ogg": "pătrat",
"squash.ogg": "dovlecel",
"squat.ogg": "ghemuit",
"squid.ogg": "calmar",
"squirrel.ogg": "veveriță",
"squirt.ogg": "stropitor cu jet",
"stack.ogg": "stivă",
"stage.ogg": "scenă",
"staircase.ogg": "scări",
"stamp.ogg": "timbru",
"stand.ogg": "postură",
"star.ogg": "stea",
"stare.ogg": "holbat",
"starfish.ogg": "stea de mare",
- "steak.ogg": "friptură",
"steam.ogg": "abur",
"steep.ogg": "abrupt",
"steeple.ogg": "turlă",
"stem.ogg": "tulpină",
"step.ogg": "treaptă",
"stew.ogg": "tocăniță",
"stick.ogg": "băț",
"sting.ogg": "înțepat",
"stinky.ogg": "puturos",
"stitch.ogg": "copci",
"stomach.ogg": "stomac",
"stone.ogg": "piatră",
"stop.ogg": "oprit",
"store.ogg": "magazin",
"stove.ogg": "plită",
"straight.ogg": "drept",
"strainer.ogg": "strecurător",
"straw.ogg": "pai",
"strawberry.ogg": "căpșună",
"stream.ogg": "curent",
"street.ogg": "stradă",
"stretch.ogg": "întins",
"string.ogg": "șir",
"stripe.ogg": "dungă",
"strong.ogg": "puternic",
"student.ogg": "student",
"study.ogg": "studiat",
"stump.ogg": "ciot",
"sugar.ogg": "zahăr",
"suit.ogg": "costum",
"suitcase.ogg": "geamantan",
"summer.ogg": "vară",
"summit.ogg": "culme",
"sun.ogg": "soare",
"swan.ogg": "lebădă",
"sweat.ogg": "transpirație",
"sweatshirt.ogg": "sveter",
"swim.ogg": "înotat",
"table.ogg": "masă",
"tablecloth.ogg": "față de masă",
"tadpole.ogg": "mormoloc",
"tag.ogg": "etichetă",
"tail.ogg": "coadă",
"tall.ogg": "înalt",
"tape_measure.ogg": "ruletă",
"taxi.ogg": "taxi",
"teach.ogg": "predat",
"teacher.ogg": "profesoară",
"tear.ogg": "rupt",
"teddy.ogg": "ursuleț de pluș",
"teeth.ogg": "dinți",
"television.ogg": "televizor",
"temple.ogg": "templu",
"tennis.ogg": "tenis",
"tent.ogg": "cort",
"text.ogg": "text",
"thick.ogg": "gros",
"thief.ogg": "hoț",
"thigh.ogg": "coapsă",
"think.ogg": "gândit",
"thread.ogg": "fir",
"throat.ogg": "gâtlej",
"throw.ogg": "aruncat",
"thumb.ogg": "degetul mare",
"tick.ogg": "căpușă",
"ticket.ogg": "bilet",
"tiger.ogg": "tigru",
"time.ogg": "timp",
"tin.ogg": "conservă",
"tire.ogg": "anvelopă",
"tired.ogg": "obosit",
"tissue.ogg": "șervețel",
+ "to_drink.ogg": "băut",
"toad.ogg": "broască râioasă",
"toaster.ogg": "prăjitor de pâine",
"toe.ogg": "deget de la picior",
"toilet.ogg": "toaletă",
"tomatoe.ogg": "roșie",
"tongs.ogg": "clește de bucătărie",
"tongue.ogg": "limbă",
"tool.ogg": "unealtă",
"top.ogg": "vârf",
"torch.ogg": "torță",
"touch.ogg": "atins",
"towel.ogg": "prosop",
"toy.ogg": "jucărie",
"trail.ogg": "traseu",
"train.ogg": "tren",
"train_station.ogg": "gară",
"trap.ogg": "capcană",
"trash.ogg": "gunoi",
"tray.ogg": "tavă",
"treat.ogg": "tratație",
"tree.ogg": "copac",
"triangle.ogg": "triunghi",
"tribe.ogg": "trib",
"trip.ogg": "excursie",
"truck.ogg": "camion",
"tube.ogg": "tub",
"tulip.ogg": "lalea",
"tune.ogg": "melodie",
"turkey.ogg": "curcan",
"turnip.ogg": "gulie",
"turtle.ogg": "țestoasă",
"tusk.ogg": "colț extern",
"twin_boys.ogg": "gemeni",
"twin_girls.ogg": "gemene",
"umbrella.ogg": "umbrelă",
"under.ogg": "sub",
"uniform.ogg": "uniformă",
"van.ogg": "dubă",
"vapor.ogg": "vapori",
"vase.ogg": "vază",
"vegetable.ogg": "legume",
"vein.ogg": "venă",
"verdure.ogg": "verdeață",
"vest.ogg": "vestă",
"vet.ogg": "veterinar",
"viper.ogg": "viperă",
"vowel.ogg": "vocală",
"vulture.ogg": "vultur",
"wag.ogg": "dat din coadă",
"walk.ogg": "mers pe jos",
"wall.ogg": "perete",
"walnut.ogg": "nucă",
"wart.ogg": "neg",
"wash.ogg": "spălat",
"wasp.ogg": "viespe",
"watch.ogg": "ceas de mână",
"water.ogg": "apă",
"wave.ogg": "val",
"wedding.ogg": "nuntă",
"wedge.ogg": "pană",
"weight.ogg": "greutate",
"wet.ogg": "ud",
"whale.ogg": "balenă",
"wheat.ogg": "grâu",
"wheel.ogg": "roată",
"whisk.ogg": "tel",
"whisper.ogg": "șoptit",
"white.ogg": "alb",
"wide.ogg": "lat",
"wife.ogg": "soție",
"wig.ogg": "perucă",
"win.ogg": "câștigat",
"wind.ogg": "vânt",
"window.ogg": "fereastră",
"window_glass.ogg": "geam",
"wing.ogg": "aripă",
"winter.ogg": "iarnă",
"wolf.ogg": "lup",
"woman.ogg": "femeie",
"wood.ogg": "lemn",
"word.ogg": "cuvânt",
"worker.ogg": "muncitor",
"world.ogg": "lume",
"wreath.ogg": "coroană de flori",
"wrench.ogg": "cheie",
"wrist.ogg": "încheietura mâinii",
"write.ogg": "scris",
"yellow.ogg": "galben",
"yogurt.ogg": "iaurt",
"yum.ogg": "apetisant",
"zebra.ogg": "zebră",
"zipper.ogg": "fermoar",
"zoo.ogg": "grădină zoologică"
-}
+}
\ No newline at end of file
diff --git a/src/activities/lang/resource/content-sk.json b/src/activities/lang/resource/content-sk.json
index 40247ae8c..58082eec9 100644
--- a/src/activities/lang/resource/content-sk.json
+++ b/src/activities/lang/resource/content-sk.json
@@ -1,1111 +1,1062 @@
{
"10.ogg": "desať",
"11.ogg": "jedenásť",
"12.ogg": "dvanásť",
"16.ogg": "šestnásť",
"U0030.ogg": "nula",
"U0031.ogg": "jedna",
"U0032.ogg": "dva",
"U0033.ogg": "tri",
"U0034.ogg": "štyri",
"U0035.ogg": "päť",
"U0036.ogg": "šesť",
"U0037.ogg": "sedem",
"U0038.ogg": "osem",
"U0039.ogg": "deväť",
"accountant.ogg": "účtovník",
"ache.ogg": "bolesť",
"acorn.ogg": "žaluď",
"actor.ogg": "herec",
"air_horn.ogg": "klaxón",
"alarmclock.ogg": "budík",
"alligator.ogg": "aligátor",
"alphabet.ogg": "abeceda",
"anchor.ogg": "kotva",
"angel.ogg": "anjel",
"angry.ogg": "nahnevaný",
"animal.ogg": "zviera",
"ankle.ogg": "členok",
"ant.ogg": "mravec",
"anteater.ogg": "mravčiar",
"antelope.ogg": "antilopa",
"apple.ogg": "jablko",
"apple_tree.ogg": "jabloň",
"appliance.ogg": "spotrebič",
"apricot.ogg": "marhuľa",
"arm.ogg": "rameno",
"armchair.ogg": "kreslo",
"artichoke.ogg": "artičoka",
"artist.ogg": "umelec",
"asparagus.ogg": "špargľa",
"astronaut.ogg": "astronaut",
- "ate.ogg": "",
"athlete.ogg": "atlét",
"avocado.ogg": "avokádo",
"ax.ogg": "sekera",
"baby_bottle.ogg": "detská fľaša",
"back.ogg": "chrbát",
"badge.ogg": "odznak",
"bag.ogg": "taška",
"bait.ogg": "návnada",
- "bake.ogg": "piecť",
"balance.ogg": "rovnováha",
"bald.ogg": "plešatý",
"ball.ogg": "lopta",
"ball_of_yarn.ogg": "klbko priadze",
"ball_soccer.ogg": "futbalová lopta",
"ballet.ogg": "balet",
"bank.ogg": "banka",
"banker_female.ogg": "zamestnankyňa banky",
"bark.ogg": "brechať",
"barn.ogg": "stodola",
"bat.ogg": "netopier",
"bath.ogg": "vaňa",
"bathing_suit.ogg": "plavky",
"bay.ogg": "zátoka",
"beach.ogg": "pláž",
- "bead.ogg": "korálka",
"bean.ogg": "fazuľa",
"bear.ogg": "medveď",
"beard.ogg": "brada",
"beat.ogg": "biť sa",
"beaver.ogg": "bobor",
"bed.ogg": "posteľ",
"bedroom.ogg": "spálňa",
"bee.ogg": "včela",
- "beef.ogg": "hovädzina",
"beetle.ogg": "chrobák",
"beg.ogg": "žobrať",
"behind.ogg": "za",
"bell.ogg": "zvonec",
"belly.ogg": "brucho",
"bench.ogg": "lavička",
"bib.ogg": "podbradník",
"big.ogg": "veľký",
"big_top.ogg": "šapitó",
"bike.ogg": "bicykel",
"bird.ogg": "vták",
"bit.ogg": "kúsok",
"bite.ogg": "kúsať",
"black.ogg": "čierna",
"blackberry.ogg": "černica",
"blackbird.ogg": "drozd",
"blade.ogg": "čepeľ",
"blind.ogg": "slepý",
"blink.ogg": "mrkať",
"block.ogg": "kocka",
"blond.ogg": "plavý",
"blue.ogg": "modrá",
"blueberry.ogg": "čučoriedka",
"blush.ogg": "červenať sa",
"board.ogg": "tabuľka",
"boat.ogg": "čln",
"boil.ogg": "vrieť",
"bolt.ogg": "matica",
"bomb.ogg": "bomba",
"bone.ogg": "kosť",
"book.ogg": "kniha",
"bookcase.ogg": "knižnica",
"bottom.ogg": "zadok",
"box.ogg": "krabica",
"boxer.ogg": "boxer",
"boy.ogg": "chlapec",
"braid.ogg": "vrkoč",
"brain.ogg": "mozog",
"branch.ogg": "vetvička",
"bread.ogg": "chlieb",
"break.ogg": "zlomiť",
"breast.ogg": "prsia",
"brick.ogg": "tehla",
"bricklayer.ogg": "murár",
"bride.ogg": "nevesta",
"bridge.ogg": "most",
"bright.ogg": "svetlý",
"broccoli.ogg": "brokolica",
"brother.ogg": "brat",
"brown.ogg": "hnedý",
"brush.ogg": "štetec",
"bubble.ogg": "bublina",
"bucket.ogg": "vedro",
"bud.ogg": "púčik",
"buffalo.ogg": "býk",
"bug.ogg": "hmyz",
"bulb.ogg": "žiarovka",
"bull.ogg": "býk",
"bump.ogg": "hrča",
"bun.ogg": "žemľa",
"bus.ogg": "autobus",
"bush.ogg": "krík",
"butcher.ogg": "mäsiar",
"butter.ogg": "maslo",
"butterfly.ogg": "motýľ",
"button.ogg": "gombík",
"cabbage.ogg": "kapusta",
"cabin.ogg": "chalúpka",
"cacao.ogg": "kakao",
"cactus.ogg": "kaktus",
"cage.ogg": "klietka",
"cake.ogg": "torta",
"call.ogg": "volať",
"camel.ogg": "ťava",
"camera.ogg": "fotoaparát",
"camp.ogg": "kempovať",
- "can.ogg": "",
"canary.ogg": "kanárik",
"candle.ogg": "sviečka",
"candy.ogg": "sladkosť",
"cane.ogg": "palička",
"canoe.ogg": "kanoe",
"canon.ogg": "kanón",
"canyon.ogg": "kaňon",
"cap.ogg": "čapica",
"cape.ogg": "plášť",
"car.ogg": "auto",
"carafe.ogg": "karafa",
"card.ogg": "kartička",
"carnival.ogg": "karneval",
"carpenter.ogg": "tesár",
"carpet.ogg": "koberec",
"carrot.ogg": "mrkva",
"cart.ogg": "nákupný vozík",
"cash.ogg": "hotovosť",
"castle.ogg": "zámok",
"cat.ogg": "kocúr",
"cat_female.ogg": "mačka",
"catch.ogg": "chytiť",
"caterpillar.ogg": "húsenica",
"cauldron.ogg": "kotol",
"cauliflower.ogg": "karfiol",
- "cave.ogg": "",
"cavern.ogg": "jaskyňa",
"celery.ogg": "zeler",
"centipede.ogg": "stonožka",
"cereal.ogg": "obilnina",
"chain.ogg": "reťaz",
"chair.ogg": "stolička",
"chalk.ogg": "krieda",
"chameleon.ogg": "chameleón",
"chandelier.ogg": "luster",
"chat.ogg": "diskutovať",
"cheek.ogg": "líce",
"cheer.ogg": "povzbudzovať",
"cheese.ogg": "syr",
"chef.ogg": "šéfkuchár",
"cherry.ogg": "čerešňa",
"chest.ogg": "truhlica",
"chick.ogg": "kuriatko",
"chicken.ogg": "kura",
- "chief.ogg": "indián",
"child.ogg": "dieťa",
"chimney.ogg": "komín",
"chimp.ogg": "šimpanz",
"chin.ogg": "brada",
"chocolate.ogg": "čokoláda",
"chop.ogg": "krájať",
- "chore.ogg": "",
"chores.ogg": "drobná práca",
"christmas.ogg": "Vianoce",
"cigar.ogg": "cigara",
"circus.ogg": "cirkus",
"city.ogg": "mesto",
"clam.ogg": "mušľa",
"clap.ogg": "tlesknutie",
"class.ogg": "trieda",
"claw.ogg": "pazúr",
"clay.ogg": "hlina",
"clean.ogg": "čistý",
"cleaning_lady.ogg": "upratovačka",
"cliff.ogg": "útes",
"climb.ogg": "šplhať sa",
"clock.ogg": "hodiny",
"cloth.ogg": "handrička",
"clothes_hanger.ogg": "vešiak",
"cloud.ogg": "oblak",
"cloudy.ogg": "oblačno",
"clover.ogg": "štvorlístok",
"clown.ogg": "klaun",
"coach.ogg": "tréner",
"coast.ogg": "pobrežie",
"coat.ogg": "kabát",
"cobra.ogg": "kobra",
"coconut.ogg": "kokosový orech",
"cod.ogg": "treska",
"coffee.ogg": "káva",
"coin.ogg": "minca",
"cold.ogg": "zima",
"color.ogg": "farba",
"colt.ogg": "žriebä",
"comb.ogg": "hrebeň",
"cone.ogg": "kužeľ",
"cookie.ogg": "sušienka",
"cork.ogg": "zátka",
"corn.ogg": "kukurica",
"couch.ogg": "gauč",
"cough.ogg": "kašľať",
"couple.ogg": "dvojica",
"cow.ogg": "krava",
"cowboy.ogg": "kovboj",
"crab.ogg": "krab",
"cradle.ogg": "kolíska",
"craft.ogg": "remeslo",
"crawl.ogg": "plaziť sa",
"crazy.ogg": "bláznivý",
"creek.ogg": "potôčik",
"crepe.ogg": "palacinka",
"crib.ogg": "jasličky",
- "criminal.ogg": "kriminálnik",
"croak.ogg": "kvákať",
"crocodile.ogg": "krokodíl",
"cross.ogg": "kríž",
"crow.ogg": "vrana",
"crown.ogg": "koruna",
"crumb.ogg": "omrvinka",
"crust.ogg": "kôrka",
"cry.ogg": "plakať",
"crystal.ogg": "kryštál",
"cube.ogg": "kocka",
"cucumber.ogg": "uhorka",
"curtain.ogg": "záves",
"cut.ogg": "strihať",
"cute.ogg": "rozkošný",
"dad.ogg": "otecko",
"daffodil.ogg": "narcis",
"daisy.ogg": "margaréta",
"dam.ogg": "priehrada",
"dance.ogg": "tancovať",
"dandelion.ogg": "púpava",
- "danger.ogg": "nebezpečný",
- "dark.ogg": "",
"dart_board.ogg": "terčová doska",
"date_fruit.ogg": "datle",
"deer.ogg": "jeleň",
"den.ogg": "nora",
"desert.ogg": "púšť",
"desk.ogg": "stôl",
"dessert.ogg": "dezert",
"diamond.ogg": "diamant",
"dig.ogg": "kopať",
"dirt.ogg": "zemina",
"dirty.ogg": "špinavý",
"dish.ogg": "riad",
"dishcloth.ogg": "utierka na riad",
"dive.ogg": "potápať sa",
"doctor.ogg": "doktor",
"doe.ogg": "srna",
"dog.ogg": "pes",
"doll.ogg": "bábika",
"dolphin.ogg": "delfín",
"domino.ogg": "domino",
"door.ogg": "dvere",
"doormat.ogg": "rohožka",
"dot.ogg": "bodka",
"doughnut.ogg": "šiška",
"dove.ogg": "holubica",
"dragon.ogg": "drak",
"dragonfly.ogg": "vážka",
- "drank.ogg": "",
"draw.ogg": "kresliť",
"drawer.ogg": "zásuvka",
"dream.ogg": "sen",
"dress.ogg": "šaty",
"drink.ogg": "nápoj",
- "drinking.ogg": "piť",
"drip.ogg": "kvapka",
"drive.ogg": "šoférovať",
"drool.ogg": "slintať",
"drum.ogg": "bubon",
"dry.ogg": "schnúť",
"duck.ogg": "káčer",
"duck_mother.ogg": "kačka",
"dune.ogg": "duna",
"dwarf.ogg": "trpaslík",
"eagle.ogg": "orol",
"ear.ogg": "ucho",
"earth.ogg": "Zem",
"eat.ogg": "jesť",
"egg.ogg": "vajce",
"eggplant.ogg": "baklažán",
"elbow.ogg": "lakeť",
"electrician.ogg": "elektrikár",
"elk.ogg": "los",
"empty.ogg": "prázdny",
"engine.ogg": "motor",
"engineer.ogg": "strojár",
"eraser.ogg": "guma",
"explore.ogg": "prieskumníci",
"eyelash.ogg": "mihalnica",
"eyes.ogg": "oči",
"face.ogg": "tvár",
"fair.ogg": "kolotoč",
"fairy.ogg": "víla",
- "fall_down.ogg": "padať",
"fall_season.ogg": "jeseň",
"family.ogg": "rodina",
"fan.ogg": "ventilátor",
"farm.ogg": "farma",
"farmer.ogg": "farmár",
"fat.ogg": "tučný",
"faucet.ogg": "kohútik",
"fawn.ogg": "srnčiatko",
"feast.ogg": "hostina",
"feather.ogg": "pierko",
"feed.ogg": "kŕmiť",
- "feet.ogg": "",
- "fell.ogg": "",
"femur.ogg": "stehenná kosť",
"fetch.ogg": "priniesť",
"fig.ogg": "figa",
"fin.ogg": "plutva",
"find.ogg": "nájsť",
"finger.ogg": "prst",
"fire.ogg": "oheň",
"fire_extinguisher.ogg": "hasiaci prístroj",
"fireman.ogg": "požiarnik",
"fish.ogg": "ryba",
"fisherman.ogg": "rybár",
"fist.ogg": "päsť",
"flacon.ogg": "fľaštička",
"flag.ogg": "vlajka",
"flame.ogg": "plameň",
"flamingo.ogg": "plameniak",
"flash.ogg": "baterka",
"flat.ogg": "byt",
"flies.ogg": "mucha",
- "flight.ogg": "letieť",
"float.ogg": "nadnášať",
"flour.ogg": "múka",
"flower.ogg": "kvetina",
"fluff.ogg": "chumáčik",
"flute.ogg": "flauta",
"fly.ogg": "letieť",
"foam.ogg": "pena",
- "food.ogg": "hamburger",
"foot.ogg": "chodidlo",
"forest.ogg": "les",
"fork.ogg": "vidlička",
"fountain.ogg": "fontána",
"fox.ogg": "líška",
"freeze.ogg": "mrznúť",
"friend.ogg": "kamaráti",
"fries.ogg": "hranolky",
"frog.ogg": "žaba",
"front.ogg": "predok",
- "frown.ogg": "mračiť sa",
"fruit.ogg": "ovocie",
"fudge.ogg": "karamel",
"full.ogg": "plný",
- "fun.ogg": "zábava",
"fur.ogg": "kožušina",
"game.ogg": "hra",
"garage.ogg": "garáž",
"garden.ogg": "záhrada",
"garlic.ogg": "cesnak",
- "gem.ogg": "",
"giant.ogg": "silák",
"gift.ogg": "darček",
"giraffe.ogg": "žirafa",
"girl.ogg": "dievča",
"glass.ogg": "pohár",
"glasses.ogg": "okuliare",
"glove.ogg": "rukavica",
"glue.ogg": "lepidlo",
"gnome.ogg": "škriatok",
"goat.ogg": "koza",
"golden.ogg": "zlatý",
"golf.ogg": "golf",
"goose.ogg": "hus",
"gorilla.ogg": "gorila",
"grain.ogg": "obilie",
"grandmother.ogg": "babička",
"grape.ogg": "hrozno",
"grapefruit.ogg": "grep",
"grass.ogg": "tráva",
"grave.ogg": "hrob",
"gray.ogg": "šedý",
"green.ogg": "zelený",
"grill.ogg": "grilovať",
"grin.ogg": "úškrn",
"ground.ogg": "zem",
"growl.ogg": "vrčať",
- "guignol.ogg": "",
"guinea_pig.ogg": "morské prasiatko",
"gum.ogg": "žuvačka",
"hair.ogg": "vlasy",
"hair_dryer.ogg": "sušič vlasov",
"half.ogg": "polovica",
"ham.ogg": "šunka",
+ "hamburger.ogg": "hamburger",
"hammer.ogg": "kladivo",
"hand.ogg": "ruka",
"handlebar.ogg": "rúčka",
"happy.ogg": "šťastný",
"harp.ogg": "harfa",
"hat.ogg": "klobúk",
"hatch.ogg": "vyliahnuť sa",
"hay.ogg": "seno",
"head.ogg": "hlava",
"hear.ogg": "počúvať",
"heat.ogg": "teplo",
"hedge.ogg": "živý plot",
"hedgehog.ogg": "ježko",
"heel.ogg": "opätok",
"helmet.ogg": "prilba",
"hen.ogg": "sliepka",
"herd.ogg": "stádo",
"high.ogg": "vysoký",
"hike.ogg": "pešia túra",
"hill.ogg": "kopec",
"hip.ogg": "bok",
"hippopotamus.ogg": "hroch",
"hit.ogg": "udrieť",
"hive.ogg": "úľ",
"hockey.ogg": "hokej",
"hole.ogg": "diera",
- "home.ogg": "",
"hook.ogg": "háčik",
"hop.ogg": "hopsať",
"horse.ogg": "kôň",
"hose.ogg": "hadica",
"hospital.ogg": "nemocnica",
"hot.ogg": "horúci",
"hot_dog.ogg": "hotdog",
- "hound.ogg": "",
"house.ogg": "dom",
"howl.ogg": "zavýjať",
- "hug.ogg": "",
"huge.ogg": "obrovský",
"hummingbird.ogg": "kolibrík",
- "hunchback.ogg": "hrb",
"hunter.ogg": "lovec",
"husband.ogg": "manžel",
"hut.ogg": "chatrč",
"hyena.ogg": "hyena",
"ice.ogg": "ľad",
"iceberg.ogg": "ľadovec",
"iguana.ogg": "leguán",
"ill.ogg": "chorý",
"ink.ogg": "atrament",
"island.ogg": "ostrov",
"jacket.ogg": "sako",
"jaguar.ogg": "jaguár",
"jam.ogg": "lekvár",
"jay.ogg": "sojka",
"jelly.ogg": "želatína",
"jellyfish.ogg": "medúza",
"jewel.ogg": "šperk",
"job.ogg": "zamestnanie",
"jockey.ogg": "žokej",
"jog.ogg": "klusať",
"judge.ogg": "sudca",
"judo.ogg": "džudo",
"juggler.ogg": "žonglovať",
"juice.ogg": "džús",
"jump.ogg": "skákať",
"kangaroo.ogg": "kengura",
"keel.ogg": "prevrátiť",
"kernel.ogg": "kôstka",
"keyboard.ogg": "klávesnica",
"kimono.ogg": "kimono",
"king.ogg": "kráľ",
"kiss.ogg": "bozk",
"kitchen.ogg": "kuchyňa",
"kite.ogg": "šarkan",
"kitten.ogg": "mačiatko",
"kiwi.ogg": "kivi",
"knee.ogg": "koleno",
"kneel.ogg": "kľaknúť si",
"knife.ogg": "nôž",
"knight.ogg": "rytier",
"knit.ogg": "štrikovať",
"knot.ogg": "uzol",
"koala.ogg": "koala",
- "lad.ogg": "",
"lady.ogg": "dáma",
"ladybug.ogg": "lienka",
"lake.ogg": "jazero",
"lama.ogg": "lama",
"lamb.ogg": "jahňa",
"lamp.ogg": "lampa",
"land.ogg": "krajina",
- "lane.ogg": "",
- "lap.ogg": "",
"lasso.ogg": "laso",
"laugh.ogg": "smiech",
"lava.ogg": "láva",
"lawn.ogg": "trávnik",
"lawyer.ogg": "advokát",
"leaf.ogg": "list",
"ledge.ogg": "výčnelok",
"leek.ogg": "pór",
"left.ogg": "vľavo",
"leg.ogg": "noha",
- "leg_animal.ogg": "nôžka",
"lemon.ogg": "citrón",
"lemonade.ogg": "malinovka",
"lemur.ogg": "lemur",
"leopard.ogg": "leopard",
"lettuce.ogg": "šalát",
"librarian.ogg": "knihovníčka",
"lick.ogg": "olizovať",
"lid.ogg": "pokrievka",
"lift.ogg": "dvíhať",
"light.ogg": "svetlo",
"lighthouse.ogg": "maják",
"lightning.ogg": "blesky",
"lilac.ogg": "orgován",
"lime.ogg": "limeta",
"line.ogg": "čiarový kód",
"link.ogg": "spojenie",
"lion.ogg": "lev",
"lion_cub.ogg": "levíča",
"lip.ogg": "pery",
"liquid.ogg": "tekutý",
"lizard.ogg": "jašterica",
"lobster.ogg": "homár",
"log.ogg": "poleno",
"look.ogg": "vzhľad",
"lunch.ogg": "obed",
"mad.ogg": "šialený",
"magic.ogg": "kúzelník",
"magnet.ogg": "magnet",
"magnifying_glass.ogg": "lupa",
"magpie.ogg": "straka",
"mail.ogg": "obálka",
"man.ogg": "muž",
"mane.ogg": "hriva",
"mango.ogg": "mango",
"map.ogg": "mapa",
"maple.ogg": "javor",
"marble.ogg": "guľôčka",
"mashed_potatoes.ogg": "pyré",
"mask.ogg": "maska",
"mast.ogg": "sťažeň",
"mat.ogg": "rohožka",
"match.ogg": "zápalka",
- "mate.ogg": "",
- "mate_female.ogg": "kamarátka",
- "mate_male.ogg": "kamarát",
"mattress.ogg": "matrac",
"mauve.ogg": "fialová",
"meal.ogg": "jedlo",
"meat.ogg": "mäso",
"mechanic.ogg": "mechanik",
"medal.ogg": "medaila",
"meet.ogg": "stretnúť sa",
"melon.ogg": "melón",
- "men.ogg": "ľudia",
"merry-go-round.ogg": "kolotoč",
- "mice.ogg": "",
"microphone.ogg": "myši",
"milk.ogg": "mlieko",
"mill.ogg": "mlyn",
"mimosa.ogg": "mimóza",
"mirror.ogg": "zrkadlo",
"mixer.ogg": "mixér",
"mole.ogg": "krtko",
"mom.ogg": "mamička",
"moon.ogg": "mesiac",
"moose.ogg": "sob",
"mop.ogg": "mop",
"mosque.ogg": "mešita",
"mosquito.ogg": "komár",
"mother.ogg": "matka",
"motorcycle.ogg": "motorka",
"mountain.ogg": "hora",
"mouse.ogg": "myš",
"mouth.ogg": "ústa",
"movie.ogg": "film",
"mower.ogg": "kosačka",
"mud.ogg": "blato",
"mug.ogg": "šálka",
"mule.ogg": "oslík",
"muscle.ogg": "sval",
"mushroom.ogg": "huba",
"music.ogg": "hudba",
"musician.ogg": "muzikant",
"naked.ogg": "nahý",
"nap.ogg": "odpočinok",
"navel.ogg": "pupok",
"neck.ogg": "krk",
"necklace.ogg": "náhrdelník",
"needle.ogg": "ihla",
"nest.ogg": "hniezdo",
"net.ogg": "sieť",
"newspaper.ogg": "noviny",
"night.ogg": "noc",
"nightgown.ogg": "nočná košeľa",
"nose.ogg": "nos",
"nostril.ogg": "nosná dierka",
"notebook.ogg": "zápisník",
"number.ogg": "číslo",
"nun.ogg": "mníška",
"nurse.ogg": "zdravotná sestra",
"nurse_male.ogg": "zdravotník",
"nut.ogg": "orech",
"oar.ogg": "veslo",
"ocean.ogg": "oceán",
"office.ogg": "kancelária",
"olive.ogg": "oliva",
"on.ogg": "na",
"onion.ogg": "cibuľa",
"open.ogg": "otvoriť",
"opossum.ogg": "vačica",
"orange-color.ogg": "oranžová",
"orange.ogg": "pomaranč",
"orchid.ogg": "orchidea",
"ostrich.ogg": "pštros",
"otter.ogg": "vydra",
"owl.ogg": "sova",
"ox.ogg": "vôl",
"oyster.ogg": "ustrica",
"pacifier.ogg": "cumlík",
"page.ogg": "strana",
"pair.ogg": "pár",
"pajamas.ogg": "pyžamo",
- "pal.ogg": "",
"palm_tree.ogg": "palma",
"pan.ogg": "panvica",
"panda.ogg": "panda",
"panther.ogg": "panter",
"panties.ogg": "nohavičky",
"pants.ogg": "nohavice",
"papaya.ogg": "papája",
"paper.ogg": "papier",
"parachute.ogg": "padák",
"parakeet.ogg": "papagáj",
"parrot.ogg": "papagáj",
"patch.ogg": "záplata",
"path.ogg": "cestička",
"paw.ogg": "labka",
"pea.ogg": "hrášok",
"peach.ogg": "broskyňa",
"peacock.ogg": "páv",
"peak.ogg": "vrchol",
"pear.ogg": "hruška",
"pearl.ogg": "perla",
"peck.ogg": "zobať",
"pedal.ogg": "pedál",
"pelican.ogg": "pelikán",
"pen.ogg": "pero",
"pencil.ogg": "ceruzka",
"peony.ogg": "pivonka",
"people.ogg": "ľudia",
"pepper.ogg": "korenie",
"peppers.ogg": "papričky",
- "pet.ogg": "",
"petal.ogg": "lupienok",
- "petite.ogg": "maličký",
"phone.ogg": "telefón",
"piano.ogg": "klavír",
"picture.ogg": "obrázok",
"pie.ogg": "koláč",
"pig.ogg": "prasa",
"pigeon.ogg": "holub",
"pill.ogg": "pilulka",
"pillow.ogg": "vankúš",
"pilot.ogg": "pilot",
"pine.ogg": "borovica",
"pine_cone.ogg": "borovicová šuška",
"pink.ogg": "ružová",
"pip.ogg": "jadierko",
"pipe.ogg": "fajka",
"piranha.ogg": "piraňa",
"pirate.ogg": "pirát",
"pizza.ogg": "pizza",
"plane.ogg": "lietadlo",
"planet.ogg": "planéta",
"plant.ogg": "rastlina",
"plate.ogg": "tanier",
"play.ogg": "hrať sa",
"pliers.ogg": "kliešte",
"plow.ogg": "pluh",
"plum.ogg": "slivka",
"plumber.ogg": "inštalatér",
"pocket.ogg": "vrecko",
"pod.ogg": "struk",
"pole.ogg": "stĺpik",
"police.ogg": "policajt",
"pompon.ogg": "bambuľa",
"pond.ogg": "rybník",
"pony.ogg": "poník",
"pool.ogg": "kúpalisko",
- "pop.ogg": "popkorn",
+ "popcorn.ogg": "popkorn",
"pope.ogg": "pápež",
"porthole.ogg": "okienko",
"post.ogg": "poštová schránka",
"pot.ogg": "hrniec",
"potato.ogg": "zemiak",
"pounce.ogg": "vrhnúť sa",
"president.ogg": "prezident",
"pretty.ogg": "krása",
"price.ogg": "cena",
"priest.ogg": "kňaz",
"prince.ogg": "princ",
"princess.ogg": "princezná",
"prison.ogg": "väzenie",
"prisoner.ogg": "väzeň",
"prize.ogg": "trofej",
"pug.ogg": "buldog",
"pull.ogg": "ťahať",
"pullover.ogg": "pulóver",
"pumpkin.ogg": "tekvica",
"puppy.ogg": "šteniatko",
"pyramid.ogg": "pyramída",
"quarrel.ogg": "hádať sa",
"queen.ogg": "kráľovná",
"question.ogg": "otázka",
"quilt.ogg": "paplón",
"quiz.ogg": "kvíz",
"rabbit.ogg": "zajac",
"rabbit_baby.ogg": "zajačik",
"race.ogg": "preteky",
"radio.ogg": "rádio",
"radish.ogg": "reďkovka",
"raft.ogg": "plť",
"rag.ogg": "handra",
"rage.ogg": "zúrivosť",
"rain.ogg": "dážď",
"raincoat.ogg": "pršiplášť",
"rake.ogg": "hrable",
"ramp.ogg": "rampa",
- "ran.ogg": "",
"raspberry.ogg": "malina",
"rat.ogg": "potkan",
"razor.ogg": "holiaci strojček",
"read.ogg": "čítať",
"red.ogg": "červená",
"reptile.ogg": "plaz",
"rhinoceros.ogg": "had",
"rice.ogg": "ryža",
- "ride.ogg": "",
"rifle.ogg": "puška",
"right.ogg": "vpravo",
- "rip.ogg": "",
"rise.ogg": "stúpať",
"river.ogg": "rieka",
"road.ogg": "cesta",
"roast.ogg": "pečienka",
- "robe.ogg": "",
"robot.ogg": "robot",
"rock.ogg": "skala",
"rocket.ogg": "raketa",
"rolling_pin.ogg": "valček",
"roof.ogg": "strecha",
"room.ogg": "izba",
"root.ogg": "koreň",
"rope.ogg": "švihadlo",
"rose.ogg": "ruža",
"round.ogg": "kruh",
"rowing.ogg": "veslovať",
"royal.ogg": "kráľovský",
"rug.ogg": "koberček",
"run.ogg": "utekať",
"sad.ogg": "smutný",
"saddle.ogg": "sedlo",
"sail.ogg": "plaviť sa",
"sailor.ogg": "námorník",
"salamander.ogg": "mlok",
"salmon.ogg": "losos",
"sand.ogg": "piesok",
"sandals.ogg": "sandále",
"sandwich.ogg": "sendvič",
"sash.ogg": "šerpa",
- "sat.ogg": "sadnúť si",
"sauce.ogg": "omáčka",
"sausage.ogg": "párok",
"scale.ogg": "váha",
"scar.ogg": "jazva",
- "scared.ogg": "vystrašený",
+ "scare.ogg": "vystrašený",
"scarf.ogg": "šatka",
"school.ogg": "škola",
"school_bag.ogg": "aktovka",
"science.ogg": "veda",
"scissors.ogg": "nožnice",
"scorpion.ogg": "škorpión",
"scratch.ogg": "škriabať",
"scream.ogg": "kričať",
"screw.ogg": "skrutka",
"screwdriver.ogg": "skrutkovač",
"scribble.ogg": "čmárať",
"sea.ogg": "more",
"seat.ogg": "sedačka",
"see.ogg": "vidieť",
"seed.ogg": "semeno",
"shadow.ogg": "sedem",
"shake.ogg": "triasť",
"shark.ogg": "žralok",
"shave.ogg": "holiť sa",
"shed.ogg": "dielňa",
"sheep.ogg": "ovca",
"shelf.ogg": "polička",
"shell.ogg": "mušľa",
"ship.ogg": "loď",
"shirt.ogg": "košeľa",
"shoe.ogg": "topánka",
"shoelace.ogg": "šnúrka",
"shop.ogg": "obchod",
"shore.ogg": "breh",
"short.ogg": "šortky",
"shovel.ogg": "lopatka",
"shower.ogg": "sprcha",
"shrimp.ogg": "kreveta",
"shrub.ogg": "kríček",
"shut.ogg": "zatvoriť",
"shutter.ogg": "okenice",
"sick.ogg": "chorý",
"sidewalk.ogg": "chodník",
"sign.ogg": "značka",
"sing.ogg": "spievať",
"sink.ogg": "umývadlo",
"sip.ogg": "sŕkať",
"sister.ogg": "sestra",
"sit.ogg": "sedieť",
"skate.ogg": "jazdiť na skateboarde",
"skeleton.ogg": "kostra",
"ski.ogg": "lyžovať",
"skimmer.ogg": "zberačka",
"skin.ogg": "pokožka",
"skirt.ogg": "sukňa",
"skunk.ogg": "tchor",
"sky.ogg": "nebo",
"slam.ogg": "smeč",
"sled.ogg": "sánky",
"sleep.ogg": "spať",
"sleeve.ogg": "rukáv",
"sleigh.ogg": "sane",
"slide.ogg": "šmýkačka",
"slim.ogg": "tenký",
"slime.ogg": "sliz",
"slippers.ogg": "papuče",
"slope.ogg": "svah",
"sloppy.ogg": "poliaty",
"slot.ogg": "štrbina",
"sloth.ogg": "leňochod",
"slug.ogg": "slimák",
"small.ogg": "malý",
"smell.ogg": "voňať",
"smile.ogg": "usmievať sa",
"smock.ogg": "plášť",
"smoke.ogg": "fajčiť",
"smooch.ogg": "bozkávať",
- "snack.ogg": "",
"snail.ogg": "slimák",
"snake.ogg": "had",
"sneaker.ogg": "teniska",
"sniff.ogg": "oňuchávať",
"snow.ogg": "sneh",
"soap.ogg": "mydlo",
"sob.ogg": "nariekať",
"sock.ogg": "ponožka",
"soldier.ogg": "vojak",
"sole.ogg": "platesa",
"sole_shoe.ogg": "vložky do topánok",
"son.ogg": "syn",
"soup.ogg": "polievka",
"spade.ogg": "rýľ",
"spaghetti.ogg": "špagety",
"spark.ogg": "iskra",
"sparrow.ogg": "vrabec",
"spatula.ogg": "stierka",
"speak.ogg": "rozprávať",
"spear.ogg": "oštep",
"spice.ogg": "korenie",
"spider.ogg": "pavúk",
"spider_web.ogg": "pavúčia sieť",
"spike.ogg": "pichľavý",
"spill.ogg": "rozliať",
"spinach.ogg": "špenát",
"spine.ogg": "chrbtica",
"spinning_top.ogg": "vĺčik",
"splash.ogg": "špliechať",
"splatter.ogg": "machuľa",
"sponge.ogg": "špongia",
"spool.ogg": "špuľka",
"spoon.ogg": "lyžica",
"sport.ogg": "šport",
"spot.ogg": "škvrna",
"spray.ogg": "sprejovať",
"spread.ogg": "nátierka",
"spring.ogg": "pružina",
"spring_season.ogg": "jar",
- "sprinkle.ogg": "",
"square.ogg": "štvorec",
"squash.ogg": "tlačiť sa",
"squat.ogg": "drep",
"squid.ogg": "chobotnica",
"squirrel.ogg": "veverička",
- "squirt.ogg": "",
"stack.ogg": "kopa",
"stage.ogg": "javisko",
"staircase.ogg": "schodisko",
"stamp.ogg": "známka",
"stand.ogg": "stáť",
"star.ogg": "hviezda",
"stare.ogg": "zazerať",
"starfish.ogg": "hviezdica",
- "steak.ogg": "rezeň",
"steam.ogg": "para",
"steep.ogg": "strmý",
"steeple.ogg": "vežička",
"stem.ogg": "stonka",
"step.ogg": "schod",
"stew.ogg": "vývar",
"stick.ogg": "palička",
"sting.ogg": "žihadlo",
"stinky.ogg": "smradľavý",
"stitch.ogg": "steh",
"stomach.ogg": "žalúdok",
"stone.ogg": "kameň",
"stop.ogg": "zastaviť",
"store.ogg": "obchod",
"stove.ogg": "sporák",
"straight.ogg": "rovný",
"strainer.ogg": "sitko",
"straw.ogg": "slamka",
"strawberry.ogg": "jahoda",
"stream.ogg": "tok",
"street.ogg": "ulica",
"stretch.ogg": "natiahnuť sa",
"string.ogg": "špagát",
"stripe.ogg": "pásik",
"strong.ogg": "silný",
"student.ogg": "študent",
"study.ogg": "učiť sa",
"stump.ogg": "peň",
"sugar.ogg": "cukor",
"suit.ogg": "oblek",
"suitcase.ogg": "kufor",
"summer.ogg": "leto",
"summit.ogg": "výstup",
"sun.ogg": "slnko",
"swan.ogg": "labuť",
"sweat.ogg": "potiť sa",
"sweatshirt.ogg": "mikina",
"swim.ogg": "plávať",
"table.ogg": "stôl",
"tablecloth.ogg": "obrus",
"tadpole.ogg": "žubrienka",
"tag.ogg": "štítok",
"tail.ogg": "chvost",
"tall.ogg": "chvost",
"tape_measure.ogg": "meracie pásmo",
"taxi.ogg": "taxík",
"teach.ogg": "učiť",
"teacher.ogg": "učiteľ",
"tear.ogg": "trhať",
"teddy.ogg": "macík",
"teeth.ogg": "zuby",
"television.ogg": "televízia",
"temple.ogg": "chrám",
"tennis.ogg": "tenis",
"tent.ogg": "stan",
"text.ogg": "text",
"thick.ogg": "hrubý",
"thief.ogg": "zlodej",
"thigh.ogg": "stehno",
"think.ogg": "premýšľať",
"thread.ogg": "niť",
"throat.ogg": "hrdlo",
"throw.ogg": "hodiť",
"thumb.ogg": "palec",
- "tick.ogg": "",
"ticket.ogg": "vstupenka",
"tiger.ogg": "tiger",
"time.ogg": "čas",
"tin.ogg": "konzerva",
"tire.ogg": "pneumatika",
"tired.ogg": "unavený",
"tissue.ogg": "vreckovka",
+ "to_drink.ogg": "piť",
"toad.ogg": "ropucha",
"toaster.ogg": "hriankovač",
"toe.ogg": "palec",
"toilet.ogg": "záchod",
"tomatoe.ogg": "rajčina",
"tongs.ogg": "kliešte",
"tongue.ogg": "jazyk",
"tool.ogg": "nástroj",
"top.ogg": "vrch",
"torch.ogg": "fakľa",
"touch.ogg": "dotknúť sa",
"towel.ogg": "uterák",
"toy.ogg": "hračka",
"trail.ogg": "turistický chodník",
"train.ogg": "vlak",
"train_station.ogg": "vlaková stanica",
"trap.ogg": "pasca",
"trash.ogg": "odpadky",
"tray.ogg": "tácka",
"treat.ogg": "bonbóny",
"tree.ogg": "strom",
"triangle.ogg": "trojuholník",
"tribe.ogg": "kmeň",
"trip.ogg": "výlet",
"truck.ogg": "nákladiak",
"tube.ogg": "rúž",
"tulip.ogg": "tulipán",
"tune.ogg": "melódia",
"turkey.ogg": "moriak",
"turnip.ogg": "repa",
"turtle.ogg": "korytnačka",
"tusk.ogg": "kel",
"twin_boys.ogg": "dvojičky",
"twin_girls.ogg": "dvojičky",
"umbrella.ogg": "dáždnik",
"under.ogg": "pod",
"uniform.ogg": "uniforma",
"van.ogg": "dodávka",
- "vapor.ogg": "",
"vase.ogg": "váza",
"vegetable.ogg": "zelenina",
"vein.ogg": "žily",
"verdure.ogg": "zeleň",
"vest.ogg": "vesta",
"vet.ogg": "veterinár",
"viper.ogg": "zmija",
"vowel.ogg": "samohláska",
"vulture.ogg": "sup",
"wag.ogg": "vrtieť",
"walk.ogg": "vykračovať si",
"wall.ogg": "stena",
"walnut.ogg": "vlašský orech",
"wart.ogg": "bradavica",
- "wash.ogg": "",
"wasp.ogg": "osa",
"watch.ogg": "hodinky",
"water.ogg": "voda",
"wave.ogg": "vlna",
"wedding.ogg": "svadba",
"wedge.ogg": "klin",
"weight.ogg": "činky",
"wet.ogg": "mokrý",
"whale.ogg": "veľryba",
"wheat.ogg": "pšenica",
"wheel.ogg": "koleso",
"whisk.ogg": "metlička",
"whisper.ogg": "šepkať",
"white.ogg": "biela",
"wide.ogg": "široký",
- "wife.ogg": "",
"wig.ogg": "parochňa",
"win.ogg": "vyhrať",
"wind.ogg": "vietor",
"window.ogg": "okno",
"window_glass.ogg": "okenné sklo",
"wing.ogg": "krídlo",
"winter.ogg": "zima",
"wolf.ogg": "vlk",
"woman.ogg": "žena",
"wood.ogg": "drevo",
"word.ogg": "slovo",
"worker.ogg": "robotník",
"world.ogg": "svet",
"wreath.ogg": "veniec",
"wrench.ogg": "francúzsky kľúč",
"wrist.ogg": "zápästie",
"write.ogg": "písať",
"yellow.ogg": "žltý",
"yogurt.ogg": "jogurt",
"yum.ogg": "maškrtiť",
"zebra.ogg": "zebra",
"zipper.ogg": "zips",
"zoo.ogg": "zoologická záhrada"
-}
+}
\ No newline at end of file
diff --git a/src/activities/lang/resource/content-sv.json b/src/activities/lang/resource/content-sv.json
index bc58eb163..815bb98f2 100644
--- a/src/activities/lang/resource/content-sv.json
+++ b/src/activities/lang/resource/content-sv.json
@@ -1,1108 +1,1092 @@
{
"10.ogg": "tio",
"11.ogg": "elva",
"12.ogg": "tolv",
"16.ogg": "sexton",
"U0030.ogg": "noll",
"U0031.ogg": "ett",
"U0032.ogg": "två",
"U0033.ogg": "tre",
"U0034.ogg": "fyra",
"U0035.ogg": "fem",
"U0036.ogg": "sex",
"U0037.ogg": "sju",
"U0038.ogg": "åtta",
"U0039.ogg": "nio",
"accountant.ogg": "revisor",
"ache.ogg": "värk",
"acorn.ogg": "ekollon",
"actor.ogg": "skådespelare",
"air_horn.ogg": "lufthorn",
"alarmclock.ogg": "väckarklocka",
"alligator.ogg": "alligator",
- "alphabet.ogg": "alfabete",
+ "alphabet.ogg": "alfabet",
"anchor.ogg": "ankare",
"angel.ogg": "ängel",
"angry.ogg": "arg",
"animal.ogg": "djur",
"ankle.ogg": "vrist",
"ant.ogg": "myra",
"anteater.ogg": "myrslok",
"antelope.ogg": "antilop",
"apple.ogg": "äpple",
"apple_tree.ogg": "äppelträd",
"appliance.ogg": "apparat",
"apricot.ogg": "aprikos",
"arm.ogg": "arm",
"armchair.ogg": "fotölj",
"artichoke.ogg": "kronärtskocka",
"artist.ogg": "konstnär",
"asparagus.ogg": "sparris",
"astronaut.ogg": "astronaut",
- "ate.ogg": "åt",
"athlete.ogg": "idrottare",
"avocado.ogg": "avocado",
"ax.ogg": "yxa",
"baby_bottle.ogg": "nappflaska",
"back.ogg": "rygg",
"badge.ogg": "medalj",
"bag.ogg": "väska",
"bait.ogg": "bete",
- "bake.ogg": "baka",
"balance.ogg": "våg",
"bald.ogg": "flintskallig",
"ball.ogg": "boll",
"ball_of_yarn.ogg": "garnnystan",
"ball_soccer.ogg": "fotboll",
"ballet.ogg": "balett",
"bank.ogg": "bank",
+ "banker_female.ogg": "bankkvinna",
"bark.ogg": "skälla",
"barn.ogg": "ladugård",
"bat.ogg": "fladdermus",
"bath.ogg": "badkar",
"bathing_suit.ogg": "baddräkt",
"bay.ogg": "bukt",
"beach.ogg": "strand",
- "bead.ogg": "glaspärla",
"bean.ogg": "böna",
"bear.ogg": "björn",
"beard.ogg": "skägg",
"beat.ogg": "utmattad",
"beaver.ogg": "bäver",
"bed.ogg": "säng",
"bedroom.ogg": "sovrum",
"bee.ogg": "bi",
- "beef.ogg": "biffstek",
"beetle.ogg": "skalbagge",
"beg.ogg": "tigga",
"behind.ogg": "bakom",
"bell.ogg": "ringklocka",
"belly.ogg": "mage",
"bench.ogg": "bänk",
"bib.ogg": "haklapp",
"big.ogg": "stor",
"big_top.ogg": "cirkustält",
"bike.ogg": "cykel",
"bird.ogg": "fågel",
- "bit.ogg": "bett",
+ "bit.ogg": "bit",
"bite.ogg": "bita",
"black.ogg": "svart",
"blackberry.ogg": "björnbär",
"blackbird.ogg": "koltrast",
"blade.ogg": "knivblad",
"blind.ogg": "blind",
"blink.ogg": "blinka",
"block.ogg": "kloss",
"blond.ogg": "blond",
"blue.ogg": "blå",
"blueberry.ogg": "blåbär",
"blush.ogg": "rodna",
"board.ogg": "anslagstavla",
"boat.ogg": "båt",
"boil.ogg": "koka",
"bolt.ogg": "mutter",
"bomb.ogg": "bomb",
"bone.ogg": "ben",
"book.ogg": "bok",
"bookcase.ogg": "bokhylla",
"bottom.ogg": "stjärt",
"box.ogg": "låda",
"boxer.ogg": "boxare",
"boy.ogg": "pojke",
"braid.ogg": "fläta",
"brain.ogg": "hjärna",
"branch.ogg": "gren",
"bread.ogg": "bröd",
"break.ogg": "bryta",
"breast.ogg": "bröst",
"brick.ogg": "tegelsten",
"bricklayer.ogg": "murare",
"bride.ogg": "brud",
"bridge.ogg": "bro",
"bright.ogg": "ljusstark",
"broccoli.ogg": "broccoli",
"brother.ogg": "bror",
"brown.ogg": "brun",
"brush.ogg": "pensel",
"bubble.ogg": "bubbla",
"bucket.ogg": "hink",
"bud.ogg": "knopp",
"buffalo.ogg": "buffel",
"bug.ogg": "insekt",
"bulb.ogg": "glödlampa",
"bull.ogg": "tjur",
"bump.ogg": "bula",
"bun.ogg": "bulle",
"bus.ogg": "buss",
"bush.ogg": "buske",
"butcher.ogg": "slaktare",
"butter.ogg": "smör",
"butterfly.ogg": "fjäril",
"button.ogg": "knapp",
"cabbage.ogg": "kålhuvud",
"cabin.ogg": "stuga",
"cacao.ogg": "kakao",
"cactus.ogg": "kaktus",
"cage.ogg": "bur",
"cake.ogg": "tårta",
"call.ogg": "ringa",
"camel.ogg": "kamel",
"camera.ogg": "kamera",
"camp.ogg": "tälta",
"can.ogg": "konservburk",
"canary.ogg": "kanariefågel",
"candle.ogg": "stearinljus",
"candy.ogg": "karamell",
"cane.ogg": "käpp",
"canoe.ogg": "kanot",
"canon.ogg": "kanon",
"canyon.ogg": "ravin",
"cap.ogg": "keps",
"cape.ogg": "cape",
"car.ogg": "bil",
"carafe.ogg": "karaff",
"card.ogg": "kort",
"carnival.ogg": "karneval",
"carpenter.ogg": "snickare",
"carpet.ogg": "matta",
"carrot.ogg": "morot",
"cart.ogg": "kundvagn",
"cash.ogg": "kontanter",
"castle.ogg": "slott",
"cat.ogg": "katt",
"cat_female.ogg": "katta",
"catch.ogg": "fånga",
"caterpillar.ogg": "larv",
"cauldron.ogg": "kittel",
"cauliflower.ogg": "blomkål",
"cave.ogg": "grotta",
"cavern.ogg": "grotta",
"celery.ogg": "selleri",
"centipede.ogg": "tusenfoting",
"cereal.ogg": "säd",
"chain.ogg": "kedja",
"chair.ogg": "fotölj",
"chalk.ogg": "krita",
"chameleon.ogg": "kameleont",
"chandelier.ogg": "ljuskrona",
"chat.ogg": "prata",
"cheek.ogg": "kind",
"cheer.ogg": "heja på",
"cheese.ogg": "ost",
"chef.ogg": "kock",
"cherry.ogg": "körsbär",
"chest.ogg": "kista",
"chick.ogg": "fågelunge",
"chicken.ogg": "kyckling",
- "chief.ogg": "hövding",
"child.ogg": "barn",
"chimney.ogg": "skorsten",
"chimp.ogg": "schimpans",
"chin.ogg": "haka",
"chocolate.ogg": "choklad",
"chop.ogg": "hugga",
- "chore.ogg": "syssla",
+ "chores.ogg": "hushållsarbete",
"christmas.ogg": "jul",
"cigar.ogg": "cigarr",
"circus.ogg": "cirkus",
"city.ogg": "stad",
"clam.ogg": "mussla",
"clap.ogg": "klappa",
"class.ogg": "klass",
"claw.ogg": "klo",
"clay.ogg": "lera",
"clean.ogg": "tvätta sig",
"cleaning_lady.ogg": "lokalvårdare",
"cliff.ogg": "klippa",
"climb.ogg": "bestiga",
"clock.ogg": "väckarklocka",
"cloth.ogg": "tyg",
"clothes_hanger.ogg": "klädhängare",
"cloud.ogg": "moln",
"cloudy.ogg": "molnigt",
"clover.ogg": "klöver",
"clown.ogg": "clown",
"coach.ogg": "tränare",
"coast.ogg": "kust",
"coat.ogg": "jacka",
"cobra.ogg": "kobra",
"coconut.ogg": "kokosnöt",
"cod.ogg": "torsk",
"coffee.ogg": "kaffe",
"coin.ogg": "mynt",
"cold.ogg": "kall",
"color.ogg": "färg",
"colt.ogg": "föl",
"comb.ogg": "kam",
"cone.ogg": "trafikkon",
+ "cook.ogg": "att laga mat",
"cookie.ogg": "småkaka",
"cork.ogg": "kork",
"corn.ogg": "majs",
"couch.ogg": "soffa",
"cough.ogg": "hosta",
"couple.ogg": "par",
"cow.ogg": "ko",
"cowboy.ogg": "cowboy",
"crab.ogg": "krabba",
"cradle.ogg": "vagga",
- "craft.ogg": "hantverk",
+ "craft.ogg": "farkost",
"crawl.ogg": "krypa",
"crazy.ogg": "galen",
"creek.ogg": "å",
"crepe.ogg": "pannkaka",
"crib.ogg": "barnsäng",
- "criminal.ogg": "brottsling",
"croak.ogg": "kväka",
"crocodile.ogg": "krokodil",
"cross.ogg": "kors",
"crow.ogg": "kråka",
"crown.ogg": "krona",
"crumb.ogg": "smula",
"crust.ogg": "brödkant",
"cry.ogg": "gråta",
"crystal.ogg": "kristall",
"cube.ogg": "kub",
"cucumber.ogg": "gurka",
"curtain.ogg": "gardin",
"cut.ogg": "klippa",
"cute.ogg": "söt",
"dad.ogg": "pappa",
"daffodil.ogg": "påsklilja",
"daisy.ogg": "tusensköna",
"dam.ogg": "damm",
"dance.ogg": "dans",
"dandelion.ogg": "maskros",
- "danger.ogg": "fara",
- "dark.ogg": "mörk",
"dart_board.ogg": "piltavla",
"date_fruit.ogg": "dadel",
"deer.ogg": "rådjur",
"den.ogg": "ide",
"desert.ogg": "öken",
"desk.ogg": "skrivbord",
"dessert.ogg": "efterrätt",
"diamond.ogg": "diamant",
"dig.ogg": "gräva",
"dirt.ogg": "jord",
"dirty.ogg": "smutsig",
"dish.ogg": "skål",
"dishcloth.ogg": "disktrasa",
"dive.ogg": "dyka",
"doctor.ogg": "läkare",
"doe.ogg": "hind",
"dog.ogg": "hund",
"doll.ogg": "docka",
"dolphin.ogg": "delfin",
"domino.ogg": "domino",
"door.ogg": "dörr",
"doormat.ogg": "dörrmatta",
"dot.ogg": "punkt",
"doughnut.ogg": "munk",
"dove.ogg": "duva",
"dragon.ogg": "drake",
"dragonfly.ogg": "trollslända",
- "drank.ogg": "drack",
"draw.ogg": "rita",
"drawer.ogg": "låda",
"dream.ogg": "dröm",
"dress.ogg": "klänning",
"drink.ogg": "dryck",
- "drinking.ogg": "dricka",
"drip.ogg": "droppe",
"drive.ogg": "köra",
"drool.ogg": "drägla",
"drum.ogg": "trumma",
"dry.ogg": "torka",
"duck.ogg": "and",
"duck_mother.ogg": "andmamma",
"dune.ogg": "sanddyn",
"dwarf.ogg": "dvärg",
"eagle.ogg": "örn",
"ear.ogg": "öra",
"earth.ogg": "jorden",
"eat.ogg": "äta",
"egg.ogg": "ägg",
"eggplant.ogg": "aubergine",
"elbow.ogg": "armbåge",
"electrician.ogg": "elektriker",
"elk.ogg": "älg",
"empty.ogg": "tom",
"engine.ogg": "motor",
"engineer.ogg": "ingenjör",
"eraser.ogg": "suddgummi",
"explore.ogg": "utforska",
"eyelash.ogg": "ögonfrans",
"eyes.ogg": "ögon",
"face.ogg": "ansikte",
"fair.ogg": "nöjespark",
- "fairy.ogg": "älva",
- "fall_down.ogg": "falla",
+ "fairy.ogg": "fe",
+ "fall.ogg": "ramlade",
"fall_season.ogg": "höst",
"family.ogg": "familj",
"fan.ogg": "fläkt",
"farm.ogg": "bondgård",
"farmer.ogg": "bonde",
"fat.ogg": "fet",
"faucet.ogg": "kran",
"fawn.ogg": "hjortkalv",
+ "fear.ogg": "rädsla",
"feast.ogg": "festmåltid",
"feather.ogg": "fjäder",
"feed.ogg": "mata",
- "feet.ogg": "fötter",
- "fell.ogg": "ramlade",
"femur.ogg": "lårben",
"fetch.ogg": "hämta",
"fig.ogg": "fikon",
"fin.ogg": "fena",
"find.ogg": "hitta",
"finger.ogg": "finger",
"fire.ogg": "eld",
"fire_extinguisher.ogg": "eldsläckare",
"fireman.ogg": "brandman",
"fish.ogg": "fisk",
"fisherman.ogg": "fiskare",
"fist.ogg": "knytnäve",
"flacon.ogg": "tvålflaska",
"flag.ogg": "flagga",
"flame.ogg": "eldflamma",
"flamingo.ogg": "flamingo",
"flash.ogg": "ficklampa",
- "flat.ogg": "lägenhet",
+ "flat.ogg": "platt",
"flies.ogg": "flugor",
- "flight.ogg": "flyga",
"float.ogg": "flyta",
"flour.ogg": "mjöl",
"flower.ogg": "blomma",
"fluff.ogg": "fjun",
"flute.ogg": "flöjt",
"fly.ogg": "flyga",
"foam.ogg": "skum",
- "food.ogg": "mat",
"foot.ogg": "fot",
"forest.ogg": "skog",
"fork.ogg": "gaffel",
"fountain.ogg": "fontän",
"fox.ogg": "räv",
"freeze.ogg": "frysa",
"friend.ogg": "vän",
"fries.ogg": "pommes frites",
"frog.ogg": "groda",
- "front.ogg": "framför",
- "frown.ogg": "bister",
+ "front.ogg": "framsida",
"fruit.ogg": "frukt",
"fudge.ogg": "kola",
"full.ogg": "full",
- "fun.ogg": "rolig",
"fur.ogg": "päls",
"game.ogg": "leksak",
"garage.ogg": "garage",
"garden.ogg": "trädgård",
"garlic.ogg": "vitlök",
"gem.ogg": "juvel",
"giant.ogg": "jätte",
"gift.ogg": "present",
"giraffe.ogg": "giraff",
"girl.ogg": "flicka",
"glass.ogg": "glas",
"glasses.ogg": "glasögon",
"glove.ogg": "vante",
"glue.ogg": "lim",
- "gnome.ogg": "tomtenisse",
+ "gnome.ogg": "tomte",
"goat.ogg": "get",
"golden.ogg": "gyllene",
"golf.ogg": "golf",
"goose.ogg": "gås",
"gorilla.ogg": "gorilla",
"grain.ogg": "spannmål",
"grandmother.ogg": "farmor, mormor",
"grape.ogg": "druvklase",
"grapefruit.ogg": "grapefrukt",
"grass.ogg": "gräs",
"grave.ogg": "grav",
"gray.ogg": "grå",
"green.ogg": "grön",
"grill.ogg": "grill",
"grin.ogg": "flin",
"ground.ogg": "mark",
"growl.ogg": "morra",
"guignol.ogg": "Guignol",
"guinea_pig.ogg": "marsvin",
"gum.ogg": "tuggummi",
"hair.ogg": "hår",
"hair_dryer.ogg": "hårtork",
"half.ogg": "halv",
"ham.ogg": "skinka",
+ "hamburger.ogg": "hamburgare",
"hammer.ogg": "hammare",
"hand.ogg": "hand",
"handlebar.ogg": "styre",
"happy.ogg": "glad",
"harp.ogg": "harpa",
"hat.ogg": "hatt",
"hatch.ogg": "kläckas",
"hay.ogg": "hö",
"head.ogg": "huvud",
"hear.ogg": "höra",
"heat.ogg": "värme",
"hedge.ogg": "häck",
"hedgehog.ogg": "igelkott",
"heel.ogg": "klack",
"helmet.ogg": "hjälm",
"hen.ogg": "höna",
"herd.ogg": "hjord",
"high.ogg": "hög",
"hike.ogg": "fotvandra",
"hill.ogg": "kulle",
"hip.ogg": "höft",
"hippopotamus.ogg": "flodhäst",
"hit.ogg": "slå",
"hive.ogg": "kupa",
"hockey.ogg": "ishockey",
"hole.ogg": "hål",
"home.ogg": "hem",
"hook.ogg": "krok",
"hop.ogg": "hugga",
"horse.ogg": "häst",
"hose.ogg": "slang",
"hospital.ogg": "sjukhus",
"hot.ogg": "het",
"hot_dog.ogg": "varmkorv",
"hound.ogg": "hund",
"house.ogg": "hus",
"howl.ogg": "yla",
"hug.ogg": "krama",
"huge.ogg": "jättestor",
"hummingbird.ogg": "kolibri",
- "hunchback.ogg": "puckelrygg",
+ "hunchbacked.ogg": "puckelryggig",
"hunter.ogg": "jägare",
"husband.ogg": "make",
"hut.ogg": "hydda",
"hyena.ogg": "hyena",
"ice.ogg": "isbit",
"iceberg.ogg": "isberg",
"iguana.ogg": "iguana",
"ill.ogg": "sjuk",
"ink.ogg": "bläck",
"island.ogg": "ö",
"jacket.ogg": "jacka",
"jaguar.ogg": "jaguar",
"jam.ogg": "sylt",
"jay.ogg": "nötskrika",
"jelly.ogg": "aladåb",
"jellyfish.ogg": "manet",
"jewel.ogg": "juvel",
"job.ogg": "arbete",
"jockey.ogg": "jockey",
"jog.ogg": "jogga",
+ "joy.ogg": "glädje",
"judge.ogg": "domare",
"judo.ogg": "judo",
"juggler.ogg": "jonglör",
"juice.ogg": "juice",
"jump.ogg": "hoppa",
"kangaroo.ogg": "känguru",
"keel.ogg": "falla",
"kernel.ogg": "kärna",
"keyboard.ogg": "tangentbord",
"kimono.ogg": "kimono",
"king.ogg": "kung",
"kiss.ogg": "kyss",
"kitchen.ogg": "kök",
"kite.ogg": "drake",
"kitten.ogg": "kattunge",
"kiwi.ogg": "kiwi",
"knee.ogg": "knä",
"kneel.ogg": "knäböja",
"knife.ogg": "kniv",
"knight.ogg": "riddare",
"knit.ogg": "sticka",
"knot.ogg": "knut",
"koala.ogg": "koala",
- "lad.ogg": "grabb",
+ "lad.ogg": "pojke",
"lady.ogg": "dam",
"ladybug.ogg": "nyckelpiga",
"lake.ogg": "insjö",
"lama.ogg": "lama",
"lamb.ogg": "lamm",
"lamp.ogg": "lampa",
"land.ogg": "land",
"lane.ogg": "fil",
"lap.ogg": "knä",
"lasso.ogg": "lasso",
"laugh.ogg": "skratta",
"lava.ogg": "lava",
"lawn.ogg": "gräsmatta",
"lawyer.ogg": "advokat",
"leaf.ogg": "löv",
"ledge.ogg": "klippavsats",
"leek.ogg": "purjolök",
"left.ogg": "vänster",
"leg.ogg": "ben",
- "leg_animal.ogg": "ben",
"lemon.ogg": "citron",
"lemonade.ogg": "lemonad",
"lemur.ogg": "lemur",
"leopard.ogg": "leopard",
"lettuce.ogg": "sallad",
"librarian.ogg": "biblotekarie",
"lick.ogg": "slicka",
"lid.ogg": "lock",
"lift.ogg": "lyfta",
"light.ogg": "ljus",
"lighthouse.ogg": "fyr",
"lightning.ogg": "blixt",
"lilac.ogg": "syren",
"lime.ogg": "lime",
"line.ogg": "linje",
"link.ogg": "länk",
"lion.ogg": "lejon",
"lion_cub.ogg": "lejonunge",
"lip.ogg": "läpp",
"liquid.ogg": "vätska",
"lizard.ogg": "ödla",
"lobster.ogg": "hummer",
"log.ogg": "timmerstock",
"look.ogg": "titta",
"lunch.ogg": "lunch",
"mad.ogg": "arg",
"magic.ogg": "trolleri",
"magnet.ogg": "magnet",
"magnifying_glass.ogg": "förstoringsglas",
"magpie.ogg": "skata",
"mail.ogg": "brev",
"man.ogg": "man",
"mane.ogg": "man",
"mango.ogg": "mango",
"map.ogg": "karta",
"maple.ogg": "lönn",
"marble.ogg": "stenkula",
"mashed_potatoes.ogg": "potatismos",
"mask.ogg": "cyklop",
"mast.ogg": "mast",
"mat.ogg": "matta",
"match.ogg": "tändsticka",
"mate.ogg": "kompis",
"mattress.ogg": "madrass",
"mauve.ogg": "lila",
"meal.ogg": "måltid",
"meat.ogg": "kött",
"mechanic.ogg": "mekaniker",
"medal.ogg": "medalj",
"meet.ogg": "träffas",
"melon.ogg": "melon",
- "men.ogg": "människor",
"merry-go-round.ogg": "karusell",
"mice.ogg": "möss",
"microphone.ogg": "mikrofon",
"milk.ogg": "mjölk",
"mill.ogg": "väderkvarn",
"mimosa.ogg": "mimosa",
"mirror.ogg": "spegel",
"mixer.ogg": "visp",
"mole.ogg": "mullvad",
"mom.ogg": "mamma",
"moon.ogg": "måne",
"moose.ogg": "älg",
"mop.ogg": "mopp",
"mosque.ogg": "moské",
"mosquito.ogg": "mygga",
"mother.ogg": "mor",
"motorcycle.ogg": "motorcykel",
"mountain.ogg": "berg",
"mouse.ogg": "mus",
"mouth.ogg": "mun",
"movie.ogg": "film",
"mower.ogg": "gräsklippare",
"mud.ogg": "lera",
"mug.ogg": "kopp",
"mule.ogg": "mula",
"muscle.ogg": "muskel",
"mushroom.ogg": "svamp",
"music.ogg": "musik",
"musician.ogg": "musiker",
"naked.ogg": "naken",
"nap.ogg": "tupplur",
"navel.ogg": "navel",
"neck.ogg": "nacke",
"necklace.ogg": "halsband",
"needle.ogg": "nål",
"nest.ogg": "fågelbo",
"net.ogg": "nät",
"newspaper.ogg": "tidning",
"night.ogg": "natt",
"nightgown.ogg": "nattlinne",
"nose.ogg": "näsa",
"nostril.ogg": "näsborre",
"notebook.ogg": "anteckningsblock",
- "number.ogg": "siffra",
+ "number.ogg": "tal",
"nun.ogg": "nunna",
"nurse.ogg": "sjuksköterska",
"nurse_male.ogg": "manlig sjuksköterska",
"nut.ogg": "nöt",
"oar.ogg": "åra",
"ocean.ogg": "hav",
"office.ogg": "kontor",
"olive.ogg": "oliv",
"on.ogg": "på",
"onion.ogg": "lök",
"open.ogg": "öppen",
"opossum.ogg": "pungråtta",
"orange-color.ogg": "orange",
"orange.ogg": "apelsin",
"orchid.ogg": "orkidé",
"ostrich.ogg": "struts",
"otter.ogg": "utter",
"owl.ogg": "uggla",
"ox.ogg": "oxe",
"oyster.ogg": "ostron",
"pacifier.ogg": "napp",
"page.ogg": "sida",
"pair.ogg": "par",
"pajamas.ogg": "pyjamas",
"pal.ogg": "kamrat",
"palm_tree.ogg": "palm",
"pan.ogg": "stekpanna",
"panda.ogg": "panda",
"panther.ogg": "panter",
"panties.ogg": "trosor",
"pants.ogg": "byxor",
"papaya.ogg": "papaya",
"paper.ogg": "papper",
"parachute.ogg": "fallskärm",
"parakeet.ogg": "parakit",
"parrot.ogg": "papegoja",
"patch.ogg": "lapp",
"path.ogg": "stig",
"paw.ogg": "tass",
"pea.ogg": "ärta",
"peach.ogg": "persika",
"peacock.ogg": "påfågel",
"peak.ogg": "topp",
"pear.ogg": "päron",
"pearl.ogg": "pärla",
"peck.ogg": "picka",
"pedal.ogg": "pedal",
"pelican.ogg": "pelikan",
"pen.ogg": "bläckpenna",
"pencil.ogg": "blyertspenna",
"peony.ogg": "pion",
"people.ogg": "människor",
"pepper.ogg": "peppar",
"peppers.ogg": "paprika",
"pet.ogg": "sällskapsdjur",
"petal.ogg": "kronblad",
- "petite.ogg": "nätt",
"phone.ogg": "telefon",
"piano.ogg": "piano",
"picture.ogg": "tavla",
"pie.ogg": "paj",
"pig.ogg": "gris",
"pigeon.ogg": "duva",
"pill.ogg": "tablett",
"pillow.ogg": "kudde",
"pilot.ogg": "pilot",
"pine.ogg": "tall",
"pine_cone.ogg": "tallkotte",
"pink.ogg": "rosa",
"pip.ogg": "kärna",
"pipe.ogg": "pipa",
"piranha.ogg": "piraya",
"pirate.ogg": "pirat",
"pizza.ogg": "pizza",
"plane.ogg": "flygplan",
"planet.ogg": "planet",
"plant.ogg": "växt",
"plate.ogg": "tallrik",
"play.ogg": "leka",
"pliers.ogg": "tång",
"plow.ogg": "plog",
"plum.ogg": "plommon",
"plumber.ogg": "rörmokare",
"pocket.ogg": "ficka",
"pod.ogg": "ärtskida",
"pole.ogg": "stång",
"police.ogg": "polis",
"pompon.ogg": "pompong",
"pond.ogg": "damm",
"pony.ogg": "ponny",
"pool.ogg": "bassäng",
- "pop.ogg": "poppa",
+ "popcorn.ogg": "poppa",
"pope.ogg": "påve",
"porthole.ogg": "hyttventil",
"post.ogg": "post",
"pot.ogg": "kruka",
"potato.ogg": "potatis",
"pounce.ogg": "kasta sig över",
"president.ogg": "president",
"pretty.ogg": "söt",
"price.ogg": "pris",
"priest.ogg": "präst",
"prince.ogg": "prins",
"princess.ogg": "prinsessa",
"prison.ogg": "fängelse",
"prisoner.ogg": "fånge",
"prize.ogg": "pris",
"pug.ogg": "mops",
"pull.ogg": "dra",
"pullover.ogg": "tröja",
"pumpkin.ogg": "pumpa",
"puppy.ogg": "hundvalp",
"pyramid.ogg": "pyramid",
"quarrel.ogg": "gräla",
"queen.ogg": "drottning",
"question.ogg": "fråga",
"quilt.ogg": "täcke",
- "quiz.ogg": "frågelek",
+ "quiz.ogg": "prov",
"rabbit.ogg": "kanin",
"rabbit_baby.ogg": "kaninunge",
"race.ogg": "lopp",
"radio.ogg": "radio",
"radish.ogg": "rädisa",
"raft.ogg": "flotte",
"rag.ogg": "trasa",
"rage.ogg": "ilska",
"rain.ogg": "regn",
"raincoat.ogg": "regnkappa",
"rake.ogg": "kratta",
"ramp.ogg": "ramp",
"ran.ogg": "sprang",
"raspberry.ogg": "hallon",
"rat.ogg": "råtta",
"razor.ogg": "rakhyvel",
"read.ogg": "läsa",
"red.ogg": "röd",
"reptile.ogg": "reptil",
"rhinoceros.ogg": "noshörning",
"rice.ogg": "ris",
"ride.ogg": "cykla",
"rifle.ogg": "gevär",
"right.ogg": "höger",
"rip.ogg": "riva",
"rise.ogg": "stiga",
"river.ogg": "flod",
"road.ogg": "väg",
"roast.ogg": "stek",
"robe.ogg": "dräkt",
"robot.ogg": "robot",
"rock.ogg": "sten",
"rocket.ogg": "raket",
"rolling_pin.ogg": "kavel",
"roof.ogg": "tak",
"room.ogg": "rum",
"root.ogg": "rot",
"rope.ogg": "rep",
"rose.ogg": "ros",
"round.ogg": "rund",
"rowing.ogg": "rodd",
"royal.ogg": "kunglig",
"rug.ogg": "matta",
"run.ogg": "springa",
"sad.ogg": "ledsen",
"saddle.ogg": "sadel",
"sail.ogg": "segla",
"sailor.ogg": "sjöman",
"salamander.ogg": "salamander",
"salmon.ogg": "lax",
"sand.ogg": "sand",
"sandals.ogg": "sandaler",
"sandwich.ogg": "smörgås",
"sash.ogg": "skärp",
- "sat.ogg": "satt",
"sauce.ogg": "dressing",
"sausage.ogg": "korv",
"scale.ogg": "våg",
"scar.ogg": "ärr",
- "scared.ogg": "rädd",
+ "scare.ogg": "rädd",
"scarf.ogg": "halsduk",
"school.ogg": "skola",
"school_bag.ogg": "skolväska",
"science.ogg": "vetenskap",
"scissors.ogg": "sax",
"scorpion.ogg": "skorpion",
"scratch.ogg": "klösa",
"scream.ogg": "skrika",
"screw.ogg": "skruv",
"screwdriver.ogg": "skruvmejsel",
"scribble.ogg": "klottra",
"sea.ogg": "hav",
"seat.ogg": "sits",
"see.ogg": "se",
"seed.ogg": "frö",
"shadow.ogg": "skugga",
"shake.ogg": "skaka",
"shark.ogg": "haj",
"shave.ogg": "klippa",
"shed.ogg": "skjul",
"sheep.ogg": "får",
"shelf.ogg": "hylla",
"shell.ogg": "snäcka",
"ship.ogg": "skepp",
"shirt.ogg": "skjorta",
"shoe.ogg": "sko",
"shoelace.ogg": "skosnöre",
"shop.ogg": "affär",
"shore.ogg": "strand",
"short.ogg": "kortbyxor",
"shovel.ogg": "skyffel",
"shower.ogg": "dusch",
"shrimp.ogg": "räka",
"shrub.ogg": "buske",
"shut.ogg": "stänga",
"shutter.ogg": "fönsterlucka",
"sick.ogg": "sjuk",
"sidewalk.ogg": "trottoar",
"sign.ogg": "skylt",
"sing.ogg": "sjunga",
"sink.ogg": "tvättställ",
"sip.ogg": "suga",
"sister.ogg": "syster",
"sit.ogg": "sitta",
"skate.ogg": "åka skateboard",
"skeleton.ogg": "skelett",
"ski.ogg": "åka skidor",
"skimmer.ogg": "hålslev",
"skin.ogg": "hud",
"skirt.ogg": "kjol",
"skunk.ogg": "skunk",
"sky.ogg": "himmel",
"slam.ogg": "dunka",
"sled.ogg": "kälke",
"sleep.ogg": "sova",
"sleeve.ogg": "ärm",
"sleigh.ogg": "släde",
"slide.ogg": "rutschbana",
"slim.ogg": "smal",
"slime.ogg": "slem",
"slippers.ogg": "tofflor",
"slope.ogg": "backe",
"sloppy.ogg": "slabbig",
"slot.ogg": "inkast",
"sloth.ogg": "sengångare",
"slug.ogg": "snigel",
"small.ogg": "liten",
"smell.ogg": "lukta",
"smile.ogg": "leende",
"smock.ogg": "arbetsrock",
"smoke.ogg": "rök",
"smooch.ogg": "pussa",
"snack.ogg": "mellanmål",
"snail.ogg": "snigel",
"snake.ogg": "orm",
"sneaker.ogg": "gymnastiksko",
"sniff.ogg": "lukta",
"snow.ogg": "snö",
"soap.ogg": "tvål",
"sob.ogg": "snyfta",
"sock.ogg": "strumpa",
"soldier.ogg": "soldat",
"sole.ogg": "sjötunga",
"sole_shoe.ogg": "skosula",
"son.ogg": "son",
"soup.ogg": "soppa",
"spade.ogg": "spade",
"spaghetti.ogg": "spagetti",
"spark.ogg": "gnista",
"sparrow.ogg": "sparv",
"spatula.ogg": "spatel",
"speak.ogg": "tala",
"spear.ogg": "spjut",
"spice.ogg": "krydda",
"spider.ogg": "spindel",
"spider_web.ogg": "spindelnät",
"spike.ogg": "tagg",
"spill.ogg": "spilla",
"spinach.ogg": "spenat",
"spine.ogg": "ryggrad",
"spinning_top.ogg": "snurra",
"splash.ogg": "plaska",
- "splatter.ogg": "stänka",
+ "splatter.ogg": "stänk",
"sponge.ogg": "tvättsvamp",
"spool.ogg": "trådrulle",
"spoon.ogg": "sked",
"sport.ogg": "idrott",
- "spot.ogg": "prick",
+ "spot.ogg": "punkt",
"spray.ogg": "spreja",
"spread.ogg": "pålägg",
"spring.ogg": "fjäder",
"spring_season.ogg": "vår",
"sprinkle.ogg": "strössel",
"square.ogg": "fyrkant",
"squash.ogg": "squash",
"squat.ogg": "huka sig",
"squid.ogg": "bläckfisk",
"squirrel.ogg": "ekorre",
"squirt.ogg": "spruta",
"stack.ogg": "trave",
"stage.ogg": "scen",
"staircase.ogg": "trappa",
"stamp.ogg": "frimärke",
"stand.ogg": "stå",
"star.ogg": "stjärna",
"stare.ogg": "stirra",
"starfish.ogg": "sjöstjärna",
- "steak.ogg": "biffstek",
"steam.ogg": "ånga",
"steep.ogg": "brant",
"steeple.ogg": "kyrktorn",
"stem.ogg": "själk",
"step.ogg": "trappsteg",
"stew.ogg": "gryta",
"stick.ogg": "kvist",
"sting.ogg": "gadd",
"stinky.ogg": "illaluktande",
"stitch.ogg": "stygn",
"stomach.ogg": "mage",
"stone.ogg": "sten",
"stop.ogg": "stoppa",
"store.ogg": "butik",
"stove.ogg": "spis",
"straight.ogg": "rak",
"strainer.ogg": "sil",
"straw.ogg": "sugrör",
"strawberry.ogg": "jordgubbe",
"stream.ogg": "fors",
"street.ogg": "gata",
"stretch.ogg": "tänja",
"string.ogg": "snöre",
"stripe.ogg": "rand",
"strong.ogg": "stark",
"student.ogg": "student",
"study.ogg": "studera",
"stump.ogg": "stubbe",
"sugar.ogg": "socker",
"suit.ogg": "kostym",
"suitcase.ogg": "resväska",
"summer.ogg": "sommar",
"summit.ogg": "topp",
"sun.ogg": "sol",
"swan.ogg": "svan",
"sweat.ogg": "svett",
"sweatshirt.ogg": "tröja",
"swim.ogg": "simma",
"table.ogg": "bord",
"tablecloth.ogg": "duk",
"tadpole.ogg": "grodyngel",
"tag.ogg": "etikett",
"tail.ogg": "svans",
"tall.ogg": "lång",
"tape_measure.ogg": "måttband",
"taxi.ogg": "taxi",
"teach.ogg": "undervisa",
"teacher.ogg": "lärare",
"tear.ogg": "riva",
"teddy.ogg": "teddybjörn",
"teeth.ogg": "tänder",
"television.ogg": "television",
"temple.ogg": "tempel",
"tennis.ogg": "tennis",
"tent.ogg": "tält",
"text.ogg": "text",
"thick.ogg": "tjock",
"thief.ogg": "tjuv",
"thigh.ogg": "lår",
"think.ogg": "tänka",
"thread.ogg": "tråd",
"throat.ogg": "svalg",
"throw.ogg": "kasta",
"thumb.ogg": "tumme",
"tick.ogg": "fästing",
"ticket.ogg": "biljett",
"tiger.ogg": "tiger",
"time.ogg": "tid",
"tin.ogg": "konservburk",
"tire.ogg": "däck",
"tired.ogg": "trött",
"tissue.ogg": "näsduk",
+ "to_drink.ogg": "dricka",
"toad.ogg": "padda",
"toaster.ogg": "brödrost",
"toe.ogg": "tå",
"toilet.ogg": "toalett",
"tomatoe.ogg": "tomat",
"tongs.ogg": "tång",
"tongue.ogg": "tunga",
"tool.ogg": "verktyg",
"top.ogg": "topp",
"torch.ogg": "fackla",
"touch.ogg": "beröra",
"towel.ogg": "handduk",
"toy.ogg": "leksak",
"trail.ogg": "led",
"train.ogg": "tåg",
"train_station.ogg": "tågstation",
"trap.ogg": "fälla",
"trash.ogg": "skräp",
"tray.ogg": "bricka",
"treat.ogg": "godis",
"tree.ogg": "träd",
"triangle.ogg": "triangel",
"tribe.ogg": "stam",
"trip.ogg": "resa",
"truck.ogg": "lastbil",
"tube.ogg": "läppstift",
"tulip.ogg": "tulpan",
- "tune.ogg": "sång",
+ "tune.ogg": "låt",
"turkey.ogg": "kalkon",
"turnip.ogg": "rova",
"turtle.ogg": "sköldpadda",
"tusk.ogg": "bete",
"twin_boys.ogg": "tvillingbröder",
"twin_girls.ogg": "tvillingsystrar",
"umbrella.ogg": "paraply",
"under.ogg": "under",
"uniform.ogg": "uniform",
"van.ogg": "skåpbil",
"vapor.ogg": "ånga",
"vase.ogg": "vas",
"vegetable.ogg": "grönsak",
"vein.ogg": "ven",
"verdure.ogg": "grönska",
"vest.ogg": "väst",
"vet.ogg": "veterinär",
"viper.ogg": "huggorm",
"vowel.ogg": "vokal",
"vulture.ogg": "gam",
"wag.ogg": "vifta",
"walk.ogg": "gå",
"wall.ogg": "mur",
"walnut.ogg": "valnöt",
"wart.ogg": "vårta",
"wash.ogg": "tvätta",
"wasp.ogg": "geting",
"watch.ogg": "armbandsur",
"water.ogg": "vatten",
"wave.ogg": "våg",
"wedding.ogg": "bröllop",
"wedge.ogg": "kil",
"weight.ogg": "vikt",
"wet.ogg": "våt",
"whale.ogg": "val",
"wheat.ogg": "vete",
"wheel.ogg": "hjul",
"whisk.ogg": "visp",
"whisper.ogg": "viska",
"white.ogg": "vit",
"wide.ogg": "tjock",
"wife.ogg": "hustru",
"wig.ogg": "peruk",
"win.ogg": "vinna",
"wind.ogg": "vind",
"window.ogg": "fönster",
"window_glass.ogg": "fönsterglas",
"wing.ogg": "vinge",
"winter.ogg": "vinter",
"wolf.ogg": "varg",
"woman.ogg": "kvinna",
"wood.ogg": "trä",
"word.ogg": "ord",
"worker.ogg": "arbetare",
"world.ogg": "världen",
"wreath.ogg": "krans",
"wrench.ogg": "skiftnyckel",
"wrist.ogg": "handled",
"write.ogg": "skriva",
- "yarn.ogg": "garn",
"yellow.ogg": "gul",
"yogurt.ogg": "yoghurt",
"yum.ogg": "mums",
"zebra.ogg": "zebra",
"zipper.ogg": "blixtlås",
"zoo.ogg": "djurpark"
-}
+}
\ No newline at end of file
diff --git a/src/activities/lang/resource/content-uk.json b/src/activities/lang/resource/content-uk.json
index bf1de9621..b2e43ed7c 100644
--- a/src/activities/lang/resource/content-uk.json
+++ b/src/activities/lang/resource/content-uk.json
@@ -1,1108 +1,1092 @@
{
"10.ogg": "десять",
"11.ogg": "одинадцять",
"12.ogg": "дванадцять",
"16.ogg": "шістнадцять",
"U0030.ogg": "нуль",
"U0031.ogg": "один",
"U0032.ogg": "два",
"U0033.ogg": "три",
"U0034.ogg": "чотири",
"U0035.ogg": "п’ять",
"U0036.ogg": "шість",
"U0037.ogg": "сім",
"U0038.ogg": "вісім",
"U0039.ogg": "дев’ять",
"accountant.ogg": "обліковець",
"ache.ogg": "біль",
"acorn.ogg": "жолудь",
"actor.ogg": "актор",
"air_horn.ogg": "клаксон",
"alarmclock.ogg": "будильник",
"alligator.ogg": "алігатор",
"alphabet.ogg": "абетка",
"anchor.ogg": "якір",
"angel.ogg": "янгол",
"angry.ogg": "злість",
"animal.ogg": "тварина",
"ankle.ogg": "кісточка",
"ant.ogg": "мураха",
"anteater.ogg": "мурахоїд",
"antelope.ogg": "антилопа",
"apple.ogg": "яблуко",
"apple_tree.ogg": "яблуня",
"appliance.ogg": "приладдя",
"apricot.ogg": "абрикос",
"arm.ogg": "рука",
"armchair.ogg": "крісло",
"artichoke.ogg": "артишок",
"artist.ogg": "художник",
"asparagus.ogg": "спаржа",
"astronaut.ogg": "астронавт",
- "ate.ogg": "харчування",
"athlete.ogg": "атлет",
"avocado.ogg": "авокадо",
"ax.ogg": "сокира",
"baby_bottle.ogg": "пляшечка",
"back.ogg": "спина",
"badge.ogg": "медаль",
"bag.ogg": "рюкзак",
"bait.ogg": "хробак",
- "bake.ogg": "кулінарія",
"balance.ogg": "терези",
"bald.ogg": "лисина",
"ball.ogg": "м’яч",
"ball_of_yarn.ogg": "клубок",
"ball_soccer.ogg": "футбольний м’яч",
"ballet.ogg": "балет",
"bank.ogg": "банк",
+ "banker_female.ogg": "банкірша",
"bark.ogg": "гавкіт",
"barn.ogg": "комора",
"bat.ogg": "летюча миша",
"bath.ogg": "ванна",
"bathing_suit.ogg": "купальник",
"bay.ogg": "затока",
"beach.ogg": "пляж",
- "bead.ogg": "булька",
"bean.ogg": "біб",
"bear.ogg": "ведмідь",
"beard.ogg": "борода",
"beat.ogg": "удар",
"beaver.ogg": "бобер",
"bed.ogg": "ліжко",
"bedroom.ogg": "спальня",
"bee.ogg": "бджола",
- "beef.ogg": "м’ясо",
"beetle.ogg": "жук",
"beg.ogg": "благання",
"behind.ogg": "за",
"bell.ogg": "дзвінок",
"belly.ogg": "живіт",
"bench.ogg": "лава",
"bib.ogg": "нагрудник",
"big.ogg": "великий",
"big_top.ogg": "шатро",
"bike.ogg": "велосипед",
"bird.ogg": "пташка",
"bit.ogg": "укус",
"bite.ogg": "кусати",
"black.ogg": "чорний",
"blackberry.ogg": "ожина",
"blackbird.ogg": "дрізд",
"blade.ogg": "лезо",
"blind.ogg": "сліпий",
"blink.ogg": "підморгування",
"block.ogg": "кубик",
"blond.ogg": "білявий",
"blue.ogg": "синій",
"blueberry.ogg": "лохина",
"blush.ogg": "збентеженість",
"board.ogg": "дошка",
"boat.ogg": "човен",
"boil.ogg": "кипіння",
"bolt.ogg": "гайка",
"bomb.ogg": "бомба",
"bone.ogg": "кістка",
"book.ogg": "книга",
"bookcase.ogg": "книжкова шафа",
"bottom.ogg": "сідниці",
"box.ogg": "коробка",
"boxer.ogg": "боксер",
"boy.ogg": "хлопчик",
"braid.ogg": "коса",
"brain.ogg": "мізки",
"branch.ogg": "гілка",
"bread.ogg": "хліб",
"break.ogg": "розбити",
"breast.ogg": "груди",
"brick.ogg": "цеглина",
"bricklayer.ogg": "муляр",
"bride.ogg": "наречена",
"bridge.ogg": "міст",
"bright.ogg": "яскравий",
"broccoli.ogg": "броколі",
"brother.ogg": "брат",
"brown.ogg": "коричневий",
"brush.ogg": "щітка",
"bubble.ogg": "булька",
"bucket.ogg": "відро",
"bud.ogg": "пуп’янок",
"buffalo.ogg": "бізон",
"bug.ogg": "комаха",
"bulb.ogg": "лампа",
"bull.ogg": "бик",
"bump.ogg": "ґуля",
"bun.ogg": "кекс",
"bus.ogg": "автобус",
"bush.ogg": "кущ",
"butcher.ogg": "м’ясник",
"butter.ogg": "масло",
"butterfly.ogg": "метелик",
"button.ogg": "ґудзик",
"cabbage.ogg": "капуста",
"cabin.ogg": "хатка",
"cacao.ogg": "какао",
"cactus.ogg": "кактус",
"cage.ogg": "клітка",
"cake.ogg": "торт",
"call.ogg": "дзвінок",
"camel.ogg": "верблюд",
"camera.ogg": "фотоапарат",
"camp.ogg": "табір",
"can.ogg": "бляшанка",
"canary.ogg": "канарка",
"candle.ogg": "свічка",
"candy.ogg": "цукерка",
"cane.ogg": "ціпок",
"canoe.ogg": "каное",
"canon.ogg": "гармата",
"canyon.ogg": "каньйон",
"cap.ogg": "кепка",
"cape.ogg": "плащ",
"car.ogg": "автомобіль",
"carafe.ogg": "карафка",
"card.ogg": "листівка",
"carnival.ogg": "карнавал",
"carpenter.ogg": "тесля",
"carpet.ogg": "килим",
"carrot.ogg": "морквина",
"cart.ogg": "візок",
"cash.ogg": "гроші",
"castle.ogg": "замок",
"cat.ogg": "кіт",
"cat_female.ogg": "кішка",
"catch.ogg": "ловити",
"caterpillar.ogg": "гусінь",
"cauldron.ogg": "казан",
"cauliflower.ogg": "цвітна капуста",
"cave.ogg": "западина",
"cavern.ogg": "печера",
"celery.ogg": "селера",
"centipede.ogg": "багатоніжка",
"cereal.ogg": "зерно",
"chain.ogg": "ланцюг",
"chair.ogg": "стілець",
"chalk.ogg": "крейда",
"chameleon.ogg": "хамелеон",
"chandelier.ogg": "люстра",
"chat.ogg": "спілкування",
"cheek.ogg": "щока",
"cheer.ogg": "акробатичні танці",
"cheese.ogg": "сир",
"chef.ogg": "кухар",
"cherry.ogg": "вишня",
"chest.ogg": "скриня",
"chick.ogg": "курчатко",
"chicken.ogg": "курча",
- "chief.ogg": "вождь",
"child.ogg": "дитина",
"chimney.ogg": "димар",
"chimp.ogg": "мавпа",
"chin.ogg": "підборіддя",
"chocolate.ogg": "шоколад",
"chop.ogg": "різати",
- "chore.ogg": "хор",
+ "chores.ogg": "прибирання",
"christmas.ogg": "різдво",
"cigar.ogg": "сигара",
"circus.ogg": "цирк",
"city.ogg": "місто",
"clam.ogg": "мушля",
"clap.ogg": "плескання",
"class.ogg": "клас",
"claw.ogg": "пазурі",
"clay.ogg": "горщик",
"clean.ogg": "мити",
"cleaning_lady.ogg": "прибиральниця",
"cliff.ogg": "скеля",
"climb.ogg": "альпінізм",
"clock.ogg": "годинник",
"cloth.ogg": "тканина",
"clothes_hanger.ogg": "вішалка",
"cloud.ogg": "хмара",
"cloudy.ogg": "хмарність",
"clover.ogg": "конюшина",
"clown.ogg": "клоун",
"coach.ogg": "тренер",
"coast.ogg": "берег",
"coat.ogg": "куртка",
"cobra.ogg": "кобра",
"coconut.ogg": "кокос",
"cod.ogg": "тріска",
"coffee.ogg": "кава",
"coin.ogg": "монета",
"cold.ogg": "холод",
"color.ogg": "колір",
"colt.ogg": "жереб’ятко",
"comb.ogg": "гребінець",
"cone.ogg": "конус",
+ "cook.ogg": "кулінарія",
"cookie.ogg": "печиво",
"cork.ogg": "корок",
"corn.ogg": "кукурудза",
"couch.ogg": "диван",
"cough.ogg": "кашляти",
"couple.ogg": "пара",
"cow.ogg": "корова",
"cowboy.ogg": "ковбой",
"crab.ogg": "краб",
"cradle.ogg": "люлька",
"craft.ogg": "рукоділля",
"crawl.ogg": "повзти",
"crazy.ogg": "шалений",
"creek.ogg": "струмок",
"crepe.ogg": "млинець",
"crib.ogg": "дитяче ліжко",
- "criminal.ogg": "злочинець",
"croak.ogg": "квакати",
"crocodile.ogg": "крокодил",
"cross.ogg": "хрест",
"crow.ogg": "ворона",
"crown.ogg": "корона",
"crumb.ogg": "крихта",
"crust.ogg": "кірка",
"cry.ogg": "плакати",
"crystal.ogg": "кристал",
"cube.ogg": "куб",
"cucumber.ogg": "огірок",
"curtain.ogg": "завіса",
"cut.ogg": "різати",
"cute.ogg": "милий",
"dad.ogg": "тато",
"daffodil.ogg": "нарцис",
"daisy.ogg": "ромашка",
"dam.ogg": "гребля",
"dance.ogg": "танець",
"dandelion.ogg": "кульбаба",
- "danger.ogg": "небезпека",
- "dark.ogg": "темний",
"dart_board.ogg": "мішень",
"date_fruit.ogg": "фінік",
"deer.ogg": "олень",
"den.ogg": "барлога",
"desert.ogg": "пустеля",
"desk.ogg": "стіл",
"dessert.ogg": "десерт",
"diamond.ogg": "діамант",
"dig.ogg": "копати",
"dirt.ogg": "земля",
"dirty.ogg": "брудний",
"dish.ogg": "миска",
"dishcloth.ogg": "ганчірка",
"dive.ogg": "занурення",
"doctor.ogg": "лікар",
"doe.ogg": "самиця оленя",
"dog.ogg": "собака",
"doll.ogg": "лялька",
"dolphin.ogg": "дельфін",
"domino.ogg": "доміно",
"door.ogg": "двері",
"doormat.ogg": "килимок",
"dot.ogg": "крапка",
"doughnut.ogg": "пампушка",
"dove.ogg": "голуб",
"dragon.ogg": "дракон",
"dragonfly.ogg": "бабка",
- "drank.ogg": "пити",
"draw.ogg": "малювати",
"drawer.ogg": "комод",
"dream.ogg": "сон",
"dress.ogg": "плаття",
"drink.ogg": "питво",
- "drinking.ogg": "смоктати",
"drip.ogg": "крапля",
"drive.ogg": "водити",
"drool.ogg": "пускати слину",
"drum.ogg": "барабан",
"dry.ogg": "сушити",
"duck.ogg": "селезень",
"duck_mother.ogg": "качка",
"dune.ogg": "дюна",
"dwarf.ogg": "карлик",
"eagle.ogg": "орел",
"ear.ogg": "вухо",
"earth.ogg": "земля",
"eat.ogg": "їсти",
"egg.ogg": "яйце",
"eggplant.ogg": "баклажан",
"elbow.ogg": "лікоть",
"electrician.ogg": "електрик",
"elk.ogg": "лось",
"empty.ogg": "порожній",
"engine.ogg": "двигун",
"engineer.ogg": "інженер",
"eraser.ogg": "ґумка",
"explore.ogg": "туризм",
"eyelash.ogg": "вія",
"eyes.ogg": "очі",
"face.ogg": "обличчя",
"fair.ogg": "карусель",
"fairy.ogg": "фея",
- "fall_down.ogg": "падати",
+ "fall.ogg": "впасти",
"fall_season.ogg": "осінь",
"family.ogg": "сім’я",
"fan.ogg": "вентилятор",
"farm.ogg": "ферма",
"farmer.ogg": "фермер",
"fat.ogg": "товстий",
"faucet.ogg": "кран",
"fawn.ogg": "оленя",
+ "fear.ogg": "жах",
"feast.ogg": "ласощі",
"feather.ogg": "перо",
"feed.ogg": "їжа",
- "feet.ogg": "стопа",
- "fell.ogg": "впасти",
"femur.ogg": "стегно",
"fetch.ogg": "принести",
"fig.ogg": "фіга",
"fin.ogg": "плавець",
"find.ogg": "знайти",
"finger.ogg": "палець",
"fire.ogg": "багаття",
"fire_extinguisher.ogg": "вогнегасник",
"fireman.ogg": "пожежник",
"fish.ogg": "риба",
"fisherman.ogg": "рибалка",
"fist.ogg": "кулак",
"flacon.ogg": "флакон",
"flag.ogg": "прапор",
"flame.ogg": "вогонь",
"flamingo.ogg": "фламінго",
"flash.ogg": "ліхтар",
"flat.ogg": "плоский",
"flies.ogg": "муха",
- "flight.ogg": "літати",
"float.ogg": "плавати",
"flour.ogg": "борошно",
"flower.ogg": "квітка",
"fluff.ogg": "пушок",
"flute.ogg": "сопілка",
"fly.ogg": "літати",
"foam.ogg": "піна",
- "food.ogg": "їжа",
"foot.ogg": "foot",
"forest.ogg": "стопа",
"fork.ogg": "виделка",
"fountain.ogg": "фонтан",
"fox.ogg": "лисиця",
"freeze.ogg": "замерзати",
"friend.ogg": "друг",
"fries.ogg": "смажена картопля",
"frog.ogg": "жабка",
"front.ogg": "передній",
- "frown.ogg": "незадоволення",
"fruit.ogg": "фрукт",
"fudge.ogg": "помадка",
"full.ogg": "повний",
- "fun.ogg": "веселощі",
"fur.ogg": "хутро",
"game.ogg": "гра",
"garage.ogg": "гараж",
"garden.ogg": "сад",
"garlic.ogg": "часник",
"gem.ogg": "коштовний камінь",
"giant.ogg": "гігантський",
"gift.ogg": "подарунок",
"giraffe.ogg": "жирафа",
"girl.ogg": "дівчинка",
"glass.ogg": "стакан",
"glasses.ogg": "окуляри",
"glove.ogg": "рукавичка",
"glue.ogg": "клей",
"gnome.ogg": "гном",
"goat.ogg": "козел",
"golden.ogg": "золотий",
"golf.ogg": "гольф",
"goose.ogg": "гусак",
"gorilla.ogg": "горила",
"grain.ogg": "злак",
"grandmother.ogg": "бабуся",
"grape.ogg": "виноград",
"grapefruit.ogg": "грейпфрут",
"grass.ogg": "трава",
"grave.ogg": "надгробок",
"gray.ogg": "сірий",
"green.ogg": "зелений",
"grill.ogg": "гриль",
"grin.ogg": "зуби",
"ground.ogg": "ґрунт",
"growl.ogg": "шкіритися",
"guignol.ogg": "паяц",
"guinea_pig.ogg": "морська свинка",
"gum.ogg": "жуйка",
"hair.ogg": "волосся",
"hair_dryer.ogg": "фен",
"half.ogg": "половинний",
"ham.ogg": "шинка",
+ "hamburger.ogg": "гамбургер",
"hammer.ogg": "молоток",
"hand.ogg": "рука",
"handlebar.ogg": "руль",
"happy.ogg": "щасливий",
"harp.ogg": "арфа",
"hat.ogg": "капелюх",
"hatch.ogg": "вилупитися",
"hay.ogg": "сіно",
"head.ogg": "голова",
"hear.ogg": "чути",
"heat.ogg": "спека",
"hedge.ogg": "живопліт",
"hedgehog.ogg": "їжак",
"heel.ogg": "каблук",
"helmet.ogg": "шолом",
"hen.ogg": "курка",
"herd.ogg": "отара",
"high.ogg": "високий",
"hike.ogg": "пішохідний туризм",
"hill.ogg": "пагорб",
"hip.ogg": "поперек",
"hippopotamus.ogg": "бегемот",
"hit.ogg": "удар",
"hive.ogg": "рій",
"hockey.ogg": "хокей",
"hole.ogg": "дупло",
"home.ogg": "дім",
"hook.ogg": "гачок",
"hop.ogg": "стрибок",
"horse.ogg": "кінь",
"hose.ogg": "шланг",
"hospital.ogg": "лікарня",
"hot.ogg": "гарячий",
"hot_dog.ogg": "хот-дог",
"hound.ogg": "гончак",
"house.ogg": "будинок",
"howl.ogg": "виття",
"hug.ogg": "обійняти",
"huge.ogg": "величезний",
"hummingbird.ogg": "колібрі",
- "hunchback.ogg": "горбатий",
+ "hunchbacked.ogg": "горбун",
"hunter.ogg": "мисливець",
"husband.ogg": "наречений",
"hut.ogg": "курінь",
"hyena.ogg": "гієна",
"ice.ogg": "лід",
"iceberg.ogg": "айсберг",
"iguana.ogg": "ігуана",
"ill.ogg": "хворий",
"ink.ogg": "чорнило",
"island.ogg": "острів",
"jacket.ogg": "піджак",
"jaguar.ogg": "ягуар",
"jam.ogg": "варення",
"jay.ogg": "сойка",
"jelly.ogg": "желе",
"jellyfish.ogg": "медуза",
"jewel.ogg": "самоцвіт",
"job.ogg": "робота",
"jockey.ogg": "жокей",
"jog.ogg": "біг підтюпцем",
+ "joy.ogg": "задоволення",
"judge.ogg": "суддя",
"judo.ogg": "дзюдо",
"juggler.ogg": "жонглер",
"juice.ogg": "сік",
"jump.ogg": "стрибати",
"kangaroo.ogg": "кенгуру",
"keel.ogg": "кегля",
"kernel.ogg": "кісточка",
"keyboard.ogg": "клавіатура",
"kimono.ogg": "кімоно",
"king.ogg": "король",
"kiss.ogg": "поцілувати",
"kitchen.ogg": "кухня",
"kite.ogg": "повітряний змій",
"kitten.ogg": "кошеня",
"kiwi.ogg": "ківі",
"knee.ogg": "коліно",
"kneel.ogg": "ставати на коліна",
"knife.ogg": "ніж",
"knight.ogg": "рицар",
"knit.ogg": "в’язати",
"knot.ogg": "вузол",
"koala.ogg": "коала",
"lad.ogg": "хлопець",
"lady.ogg": "леді",
"ladybug.ogg": "сонечко",
"lake.ogg": "озеро",
"lama.ogg": "лама",
"lamb.ogg": "ягня",
"lamp.ogg": "лампа",
"land.ogg": "суходіл",
"lane.ogg": "дорога",
"lap.ogg": "коліна",
"lasso.ogg": "ласо",
"laugh.ogg": "посмішка",
"lava.ogg": "лава",
"lawn.ogg": "газон",
"lawyer.ogg": "юрист",
"leaf.ogg": "листок",
"ledge.ogg": "карниз",
"leek.ogg": "цибуля-порей",
"left.ogg": "лівий",
"leg.ogg": "нога",
- "leg_animal.ogg": "ніжка",
"lemon.ogg": "лимон",
"lemonade.ogg": "лимонад",
"lemur.ogg": "лемур",
"leopard.ogg": "леопард",
"lettuce.ogg": "латук",
"librarian.ogg": "бібліотекар",
"lick.ogg": "лизати",
"lid.ogg": "кришка",
"lift.ogg": "рух",
"light.ogg": "світильник",
"lighthouse.ogg": "маяк",
"lightning.ogg": "блискавка",
"lilac.ogg": "бузок",
"lime.ogg": "лайм",
"line.ogg": "лінійний",
"link.ogg": "ланка",
"lion.ogg": "лев",
"lion_cub.ogg": "левеня",
"lip.ogg": "губа",
"liquid.ogg": "рідина",
"lizard.ogg": "ящірка",
"lobster.ogg": "омар",
"log.ogg": "колода",
"look.ogg": "дивитися",
"lunch.ogg": "обід",
"mad.ogg": "лють",
"magic.ogg": "чарівний",
"magnet.ogg": "магніт",
"magnifying_glass.ogg": "лупа",
"magpie.ogg": "сорока",
"mail.ogg": "лист",
"man.ogg": "чоловік",
"mane.ogg": "грива",
"mango.ogg": "манго",
"map.ogg": "карта",
"maple.ogg": "клен",
"marble.ogg": "мармурова кулька",
"mashed_potatoes.ogg": "картопляне пюре",
"mask.ogg": "маска",
"mast.ogg": "щогла",
"mat.ogg": "мат",
"match.ogg": "сірник",
"mate.ogg": "друг",
"mattress.ogg": "матрац",
"mauve.ogg": "бузковий",
"meal.ogg": "страва",
"meat.ogg": "м’ясо",
"mechanic.ogg": "механік",
"medal.ogg": "медаль",
"meet.ogg": "зустріти",
"melon.ogg": "диня",
- "men.ogg": "люди",
"merry-go-round.ogg": "карусель",
"mice.ogg": "миші",
"microphone.ogg": "мікрофон",
"milk.ogg": "молоко",
"mill.ogg": "млин",
"mimosa.ogg": "мімоза",
"mirror.ogg": "дзеркало",
"mixer.ogg": "міксер",
"mole.ogg": "кріт",
"mom.ogg": "матуся",
"moon.ogg": "місяць",
"moose.ogg": "лось",
"mop.ogg": "швабра",
"mosque.ogg": "мечеть",
"mosquito.ogg": "москіт",
"mother.ogg": "мати",
"motorcycle.ogg": "мотоцикл",
"mountain.ogg": "гора",
"mouse.ogg": "миша",
"mouth.ogg": "рот",
"movie.ogg": "фільм",
"mower.ogg": "косарка",
"mud.ogg": "багнюка",
"mug.ogg": "кухоль",
"mule.ogg": "мул",
"muscle.ogg": "м’яз",
"mushroom.ogg": "гриб",
"music.ogg": "музика",
"musician.ogg": "музикант",
"naked.ogg": "голий",
"nap.ogg": "дрімати",
"navel.ogg": "пупок",
"neck.ogg": "шия",
"necklace.ogg": "намисто",
"needle.ogg": "голка",
"nest.ogg": "гніздо",
"net.ogg": "сітка",
"newspaper.ogg": "газета",
"night.ogg": "ніч",
"nightgown.ogg": "нічна сорочка",
"nose.ogg": "ніс",
"nostril.ogg": "ніздря",
"notebook.ogg": "нотатник",
"number.ogg": "число",
"nun.ogg": "монашка",
"nurse.ogg": "медсестра",
"nurse_male.ogg": "медбрат",
"nut.ogg": "горіх",
"oar.ogg": "весло",
"ocean.ogg": "океан",
"office.ogg": "офіс",
"olive.ogg": "оливка",
"on.ogg": "на",
"onion.ogg": "цибуля",
"open.ogg": "відчинений",
"opossum.ogg": "опосум",
"orange-color.ogg": "помаранчевий",
"orange.ogg": "апельсин",
"orchid.ogg": "орхідея",
"ostrich.ogg": "страус",
"otter.ogg": "видра",
"owl.ogg": "сова",
"ox.ogg": "бик",
"oyster.ogg": "устриця",
"pacifier.ogg": "пустунчик",
"page.ogg": "сторінка",
"pair.ogg": "пара",
"pajamas.ogg": "піжама",
"pal.ogg": "приятель",
"palm_tree.ogg": "пальма",
"pan.ogg": "сковорода",
"panda.ogg": "панда",
"panther.ogg": "пантера",
"panties.ogg": "труси",
"pants.ogg": "штани",
"papaya.ogg": "папая",
"paper.ogg": "аркуш",
"parachute.ogg": "парашут",
"parakeet.ogg": "довгохвостий папуга",
"parrot.ogg": "папуга",
"patch.ogg": "латка",
"path.ogg": "шлях",
"paw.ogg": "лапа",
"pea.ogg": "горох",
"peach.ogg": "персик",
"peacock.ogg": "павич",
"peak.ogg": "вершина",
"pear.ogg": "груша",
"pearl.ogg": "перлина",
"peck.ogg": "дзьобати",
"pedal.ogg": "педаль",
"pelican.ogg": "пелікан",
"pen.ogg": "ручка",
"pencil.ogg": "олівець",
"peony.ogg": "півонія",
"people.ogg": "люди",
"pepper.ogg": "перець",
"peppers.ogg": "перці",
"pet.ogg": "домашня тварина",
"petal.ogg": "пелюстка",
- "petite.ogg": "мініатюрний",
"phone.ogg": "телефон",
"piano.ogg": "рояль",
"picture.ogg": "картина",
"pie.ogg": "пиріг",
"pig.ogg": "свиня",
"pigeon.ogg": "горлиця",
"pill.ogg": "пігулка",
"pillow.ogg": "подушка",
"pilot.ogg": "пілот",
"pine.ogg": "сосна",
"pine_cone.ogg": "шишка",
"pink.ogg": "рожевий",
"pip.ogg": "кісточка",
"pipe.ogg": "люлька",
"piranha.ogg": "піранья",
"pirate.ogg": "пірат",
"pizza.ogg": "піца",
"plane.ogg": "літак",
"planet.ogg": "планета",
"plant.ogg": "рослина",
"plate.ogg": "тарілка",
"play.ogg": "гратися",
"pliers.ogg": "кліщі",
"plow.ogg": "орати",
"plum.ogg": "слива",
"plumber.ogg": "водопровідник",
"pocket.ogg": "кишеня",
"pod.ogg": "стручок",
"pole.ogg": "стовп",
"police.ogg": "поліціянт",
"pompon.ogg": "помпон",
"pond.ogg": "ставок",
"pony.ogg": "поні",
"pool.ogg": "басейн",
- "pop.ogg": "попкорн",
+ "popcorn.ogg": "попкорн",
"pope.ogg": "папа",
"porthole.ogg": "ілюмінатор",
"post.ogg": "поштова скринька",
"pot.ogg": "горщик",
"potato.ogg": "картопля",
"pounce.ogg": "накинутися",
"president.ogg": "президент",
"pretty.ogg": "красивий",
"price.ogg": "ціна",
"priest.ogg": "священик",
"prince.ogg": "принц",
"princess.ogg": "принцеса",
"prison.ogg": "тюрма",
"prisoner.ogg": "в’язень",
"prize.ogg": "приз",
"pug.ogg": "мопс",
"pull.ogg": "тягнути",
"pullover.ogg": "пуловер",
"pumpkin.ogg": "гарбуз",
"puppy.ogg": "щеня",
"pyramid.ogg": "піраміда",
"quarrel.ogg": "сварка",
"queen.ogg": "королева",
"question.ogg": "питання",
"quilt.ogg": "стьобана ковдра",
"quiz.ogg": "вікторина",
"rabbit.ogg": "кролик",
"rabbit_baby.ogg": "кроленя",
"race.ogg": "забіг",
"radio.ogg": "радіо",
"radish.ogg": "редиска",
"raft.ogg": "пліт",
"rag.ogg": "ганчірка",
"rage.ogg": "гнів",
"rain.ogg": "дощ",
"raincoat.ogg": "дощовик",
"rake.ogg": "граблі",
"ramp.ogg": "трамплін",
"ran.ogg": "біг",
"raspberry.ogg": "малина",
"rat.ogg": "щур",
"razor.ogg": "бритва",
"read.ogg": "читати",
"red.ogg": "червоний",
"reptile.ogg": "рептилія",
"rhinoceros.ogg": "носоріг",
"rice.ogg": "рис",
"ride.ogg": "перегони",
"rifle.ogg": "рушниця",
"right.ogg": "правий",
"rip.ogg": "рвати",
"rise.ogg": "підніматися",
"river.ogg": "ріка",
"road.ogg": "траса",
"roast.ogg": "печеня",
"robe.ogg": "мантія",
"robot.ogg": "робот",
"rock.ogg": "каміння",
"rocket.ogg": "ракета",
"rolling_pin.ogg": "качалка",
"roof.ogg": "дах",
"room.ogg": "кімната",
"root.ogg": "корінь",
"rope.ogg": "скакалка",
"rose.ogg": "троянда",
"round.ogg": "круглий",
"rowing.ogg": "веслування",
"royal.ogg": "королівський",
"rug.ogg": "килимок",
"run.ogg": "бігти",
"sad.ogg": "сум",
"saddle.ogg": "сідло",
"sail.ogg": "парус",
"sailor.ogg": "моряк",
"salamander.ogg": "саламандра",
"salmon.ogg": "лосось",
"sand.ogg": "пісок",
"sandals.ogg": "сандалі",
"sandwich.ogg": "сандвіч",
"sash.ogg": "пояс",
- "sat.ogg": "всістися",
"sauce.ogg": "соус",
"sausage.ogg": "ковбаса",
"scale.ogg": "ваги",
"scar.ogg": "шрам",
- "scared.ogg": "переляк",
+ "scare.ogg": "переляк",
"scarf.ogg": "шарф",
"school.ogg": "школа",
"school_bag.ogg": "шкільна сумка",
"science.ogg": "наука",
"scissors.ogg": "ножиці",
"scorpion.ogg": "скорпіон",
"scratch.ogg": "дряпати",
"scream.ogg": "верещати",
"screw.ogg": "шуруп",
"screwdriver.ogg": "викрутка",
"scribble.ogg": "малювати карлючки",
"sea.ogg": "море",
"seat.ogg": "сидіння",
"see.ogg": "дивитися",
"seed.ogg": "насіння",
"shadow.ogg": "тінь",
"shake.ogg": "трясти",
"shark.ogg": "акула",
"shave.ogg": "стригти",
"shed.ogg": "хижа",
"sheep.ogg": "вівця",
"shelf.ogg": "полиця",
"shell.ogg": "черепашка",
"ship.ogg": "корабель",
"shirt.ogg": "сорочка",
"shoe.ogg": "черевик",
"shoelace.ogg": "шнурок",
"shop.ogg": "магазин",
"shore.ogg": "узбережжя",
"short.ogg": "шорти",
"shovel.ogg": "совок",
"shower.ogg": "душ",
"shrimp.ogg": "креветка",
"shrub.ogg": "кущ",
"shut.ogg": "зачинений",
"shutter.ogg": "віконниця",
"sick.ogg": "хворий",
"sidewalk.ogg": "тротуар",
"sign.ogg": "знак",
"sing.ogg": "співати",
"sink.ogg": "раковина",
"sip.ogg": "сьорбати",
"sister.ogg": "сестра",
"sit.ogg": "сидіти",
"skate.ogg": "роликова дошка",
"skeleton.ogg": "скелет",
"ski.ogg": "лижі",
"skimmer.ogg": "шумівка",
"skin.ogg": "шкіра",
"skirt.ogg": "спідниця",
"skunk.ogg": "скунс",
"sky.ogg": "небо",
"slam.ogg": "вгатити",
"sled.ogg": "санчата",
"sleep.ogg": "спати",
"sleeve.ogg": "рукав",
"sleigh.ogg": "сани",
"slide.ogg": "гірка",
"slim.ogg": "стрункий",
"slime.ogg": "слиз",
"slippers.ogg": "капці",
"slope.ogg": "схил",
"sloppy.ogg": "неохайний",
"slot.ogg": "проріз",
"sloth.ogg": "лінивець",
"slug.ogg": "слимак",
"small.ogg": "малий",
"smell.ogg": "пахнути",
"smile.ogg": "посмішка",
"smock.ogg": "спецівка",
"smoke.ogg": "дим",
"smooch.ogg": "цілуватися",
"snack.ogg": "закуска",
"snail.ogg": "равлик",
"snake.ogg": "змія",
"sneaker.ogg": "кросівок",
"sniff.ogg": "нюхати",
"snow.ogg": "сніг",
"soap.ogg": "рідке мило",
"sob.ogg": "ридання",
"sock.ogg": "шкарпетка",
"soldier.ogg": "солдат",
"sole.ogg": "камбала",
"sole_shoe.ogg": "підошва",
"son.ogg": "син",
"soup.ogg": "суп",
"spade.ogg": "лопата",
"spaghetti.ogg": "спагеті",
"spark.ogg": "іскра",
"sparrow.ogg": "горобець",
"spatula.ogg": "лопатка",
"speak.ogg": "розмовляти",
"spear.ogg": "спис",
"spice.ogg": "спеція",
"spider.ogg": "павук",
"spider_web.ogg": "павутина",
"spike.ogg": "голка",
"spill.ogg": "розлити",
"spinach.ogg": "шпинат",
"spine.ogg": "хребет",
"spinning_top.ogg": "дзиґа",
"splash.ogg": "плескати",
"splatter.ogg": "розплескати",
"sponge.ogg": "губка",
"spool.ogg": "котушка",
"spoon.ogg": "ложка",
"sport.ogg": "спорт",
"spot.ogg": "плямистий",
"spray.ogg": "бризка",
"spread.ogg": "розмазувати",
"spring.ogg": "підскакувати",
"spring_season.ogg": "весна",
"sprinkle.ogg": "присипка",
"square.ogg": "квадратний",
"squash.ogg": "гарбуз-горлянка",
"squat.ogg": "присідати",
"squid.ogg": "кальмар",
"squirrel.ogg": "білка",
"squirt.ogg": "розбризкувач",
"stack.ogg": "стос",
"stage.ogg": "сцена",
"staircase.ogg": "сходи",
"stamp.ogg": "марка",
"stand.ogg": "стійкий",
"star.ogg": "зірка",
"stare.ogg": "вдивлятися",
"starfish.ogg": "морська зірка",
- "steak.ogg": "стейк",
"steam.ogg": "пара",
"steep.ogg": "крутий",
"steeple.ogg": "дзвіниця",
"stem.ogg": "стовбур",
"step.ogg": "сходинка",
"stew.ogg": "тушковане м’ясо",
"stick.ogg": "гілка",
"sting.ogg": "жалити",
"stinky.ogg": "смердючий",
"stitch.ogg": "вишивати",
"stomach.ogg": "шлунок",
"stone.ogg": "камінь",
"stop.ogg": "зупиняти",
"store.ogg": "крамниця",
"stove.ogg": "плита",
"straight.ogg": "прямий",
"strainer.ogg": "сито",
"straw.ogg": "соломинка",
"strawberry.ogg": "полуниця",
"stream.ogg": "потік",
"street.ogg": "вулиця",
"stretch.ogg": "розтягувати",
"string.ogg": "мотузка",
"stripe.ogg": "смугастий",
"strong.ogg": "сильний",
"student.ogg": "студент",
"study.ogg": "вчитися",
"stump.ogg": "пеньок",
"sugar.ogg": "цукор",
"suit.ogg": "костюм",
"suitcase.ogg": "валіза",
"summer.ogg": "літо",
"summit.ogg": "вершина",
"sun.ogg": "сонце",
"swan.ogg": "лебідь",
"sweat.ogg": "піт",
"sweatshirt.ogg": "фуфайка",
"swim.ogg": "плавання",
"table.ogg": "стіл",
"tablecloth.ogg": "скатерть",
"tadpole.ogg": "пуголовок",
"tag.ogg": "бирка",
"tail.ogg": "хвіст",
"tall.ogg": "високий",
"tape_measure.ogg": "рулетка",
"taxi.ogg": "таксі",
"teach.ogg": "навчати",
"teacher.ogg": "учителька",
"tear.ogg": "рвати",
"teddy.ogg": "ведмежа",
"teeth.ogg": "зуби",
"television.ogg": "телевізор",
"temple.ogg": "храм",
"tennis.ogg": "теніс",
"tent.ogg": "намет",
"text.ogg": "тест",
"thick.ogg": "товстий",
"thief.ogg": "злодій",
"thigh.ogg": "стегно",
"think.ogg": "думати",
"thread.ogg": "нитка",
"throat.ogg": "горло",
"throw.ogg": "кидок",
"thumb.ogg": "великий палець",
"tick.ogg": "кліщ",
"ticket.ogg": "квиток",
"tiger.ogg": "тигр",
"time.ogg": "час",
"tin.ogg": "бляшанка",
"tire.ogg": "шина",
"tired.ogg": "втомлений",
"tissue.ogg": "серветка",
+ "to_drink.ogg": "смоктати",
"toad.ogg": "жабка",
"toaster.ogg": "тостер",
"toe.ogg": "палець ноги",
"toilet.ogg": "туалет",
"tomatoe.ogg": "помідор",
"tongs.ogg": "щіпці",
"tongue.ogg": "язик",
"tool.ogg": "інструмент",
"top.ogg": "верхівка",
"torch.ogg": "факел",
"touch.ogg": "торкатися",
"towel.ogg": "рушник",
"toy.ogg": "іграшка",
"trail.ogg": "стежка",
"train.ogg": "потяг",
"train_station.ogg": "станція",
"trap.ogg": "пастка",
"trash.ogg": "сміття",
"tray.ogg": "підніс",
"treat.ogg": "ласощі",
"tree.ogg": "дерево",
"triangle.ogg": "трикутник",
"tribe.ogg": "плем’я",
"trip.ogg": "подорож",
"truck.ogg": "вантажівка",
"tube.ogg": "тюбик",
"tulip.ogg": "тюльпан",
"tune.ogg": "мелодія",
"turkey.ogg": "індик",
"turnip.ogg": "ріпа",
"turtle.ogg": "черепаха",
"tusk.ogg": "бивень",
"twin_boys.ogg": "близнята",
"twin_girls.ogg": "близнючки",
"umbrella.ogg": "парасолька",
"under.ogg": "під",
"uniform.ogg": "форма",
"van.ogg": "фургон",
"vapor.ogg": "випари",
"vase.ogg": "ваза",
"vegetable.ogg": "овоч",
"vein.ogg": "вена",
"verdure.ogg": "зелень",
"vest.ogg": "жилет",
"vet.ogg": "ветеринар",
"viper.ogg": "гадюка",
"vowel.ogg": "голосний",
"vulture.ogg": "стерв’ятник",
"wag.ogg": "вимахувати",
"walk.ogg": "гуляти",
"wall.ogg": "стіна",
"walnut.ogg": "горіх",
"wart.ogg": "мозоль",
"wash.ogg": "мити",
"wasp.ogg": "оса",
"watch.ogg": "наручний годинник",
"water.ogg": "вода",
"wave.ogg": "хвиля",
"wedding.ogg": "весілля",
"wedge.ogg": "клин",
"weight.ogg": "гиря",
"wet.ogg": "мокрий",
"whale.ogg": "кит",
"wheat.ogg": "пшениця",
"wheel.ogg": "колесо",
"whisk.ogg": "збивачка",
"whisper.ogg": "шепотіти",
"white.ogg": "білий",
"wide.ogg": "широкий",
"wife.ogg": "жінка",
"wig.ogg": "перука",
"win.ogg": "виграти",
"wind.ogg": "вітер",
"window.ogg": "вікно",
"window_glass.ogg": "шибка",
"wing.ogg": "крило",
"winter.ogg": "зима",
"wolf.ogg": "вовк",
"woman.ogg": "жінка",
"wood.ogg": "деревина",
"word.ogg": "слово",
"worker.ogg": "робітник",
"world.ogg": "світ",
"wreath.ogg": "вінок",
"wrench.ogg": "гайковий ключ",
"wrist.ogg": "зап’ясток",
"write.ogg": "писати",
- "yarn.ogg": "пряжа",
"yellow.ogg": "жовтий",
"yogurt.ogg": "йогурт",
"yum.ogg": "насолода смаком",
"zebra.ogg": "зебра",
"zipper.ogg": "блискавка",
"zoo.ogg": "зоопарк"
-}
+}
\ No newline at end of file
diff --git a/src/activities/lang/resource/content-zh_CN.json b/src/activities/lang/resource/content-zh_CN.json
new file mode 100644
index 000000000..9e26dfeeb
--- /dev/null
+++ b/src/activities/lang/resource/content-zh_CN.json
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/src/activities/lang/resource/content-zh_TW.json b/src/activities/lang/resource/content-zh_TW.json
new file mode 100644
index 000000000..0d64dadcc
--- /dev/null
+++ b/src/activities/lang/resource/content-zh_TW.json
@@ -0,0 +1,50 @@
+{
+ "alphabet.ogg": "字母",
+ "angel.ogg": "天使",
+ "behind.ogg": "在 … 的後面",
+ "bit.ogg": "一小塊",
+ "bone.ogg": "骨頭",
+ "bubble.ogg": "泡泡",
+ "camp.ogg": "露營",
+ "carnival.ogg": "嘉年華",
+ "chores.ogg": "雜事",
+ "christmas.ogg": "聖誕節",
+ "craft.ogg": "手工藝",
+ "dot.ogg": "點",
+ "engine.ogg": "引擎",
+ "fairy.ogg": "仙女",
+ "flat.ogg": "平原",
+ "front.ogg": "在 ... 的前面",
+ "gnome.ogg": "地精",
+ "guignol.ogg": "布袋木偶",
+ "half.ogg": "一半",
+ "king.ogg": "國王",
+ "knight.ogg": "騎士",
+ "lad.ogg": "少年",
+ "left.ogg": "左邊",
+ "light.ogg": "燈光",
+ "line.ogg": "線",
+ "link.ogg": "連結",
+ "movie.ogg": "電影",
+ "music.ogg": "音樂",
+ "number.ogg": "數字",
+ "on.ogg": "在 ... 之上",
+ "pedal.ogg": "腳踏板",
+ "pirate.ogg": "海盜",
+ "pope.ogg": "教皇",
+ "porthole.ogg": "(船或飛機的)舷窗",
+ "president.ogg": "總統",
+ "price.ogg": "價格",
+ "prince.ogg": "王子",
+ "princess.ogg": "公主",
+ "prisoner.ogg": "囚犯",
+ "queen.ogg": "皇后",
+ "question.ogg": "問題",
+ "quiz.ogg": "測驗",
+ "right.ogg": "右邊",
+ "rocket.ogg": "火箭",
+ "round.ogg": "圓形",
+ "science.ogg": "科學",
+ "splatter.ogg": "飛濺",
+ "spot.ogg": "斑點"
+}
\ No newline at end of file
diff --git a/src/activities/lang/resource/datasetToPo.py b/src/activities/lang/resource/datasetToPo.py
index 8d7799b69..cfebc4963 100755
--- a/src/activities/lang/resource/datasetToPo.py
+++ b/src/activities/lang/resource/datasetToPo.py
@@ -1,83 +1,104 @@
-#!/usr/bin/python
+#!/usr/bin/python3
#
# GCompris - datasetToPo.py
#
# Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
#
# This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+# along with this program; if not, see <https://www.gnu.org/licenses/>.
import sys
import json
import os
import datetime
+import urllib
+import polib
-if(len(sys.argv) < 2):
- print "Usage: dataSetToPo.py dataset.json [content-fr.json]"
- print " The optional argument is used to backport manually created json"
+from urllib.parse import quote
+
+if(len(sys.argv) < 3):
+ print("Usage: dataSetToPo.py dataset.json output.po [content-fr.json]")
+ print(" The optional argument is used to backport manually created json")
sys.exit(1)
def loadManualFile(manual):
json_data = open(manual)
manualData = json.load(json_data)
json_data.close()
return manualData
def getManualTranslation(manualData, key):
if not manualData:
return ""
key = key.split("/")[-1]
try:
return manualData[key]
except:
return ""
manualData = None
-if(len(sys.argv) == 3):
- manualData = loadManualFile(sys.argv[2])
-
+if(len(sys.argv) == 4):
+ manualData = loadManualFile(sys.argv[3])
dataset = sys.argv[1]
json_data = open(dataset)
data = json.load(json_data)
json_data.close()
+displayInConsole = False
+
# Get last modification time of data set
modtime = os.path.getmtime(dataset)
modtime_utc = datetime.datetime.utcfromtimestamp(modtime)
modtime_utc_string = modtime_utc.strftime('%Y-%m-%d %H:%M') + '+0000'
# Header
-print 'msgid ""'
-print 'msgstr ""'
-print '"Project-Id-Version: gcompris_qt\\n"'
-print '"POT-Creation-Date: ' + modtime_utc_string + '\\n"'
-print '"MIME-Version: 1.0\\n"'
-print '"Content-Type: text/plain; charset=UTF-8\\n"'
-print '"Content-Transfer-Encoding: 8bit\\n"'
-print ''
+po = polib.POFile()
+po.metadata = {
+ 'Project-Id-Version': 'gcompris_qt\\n',
+ 'Report-Msgid-Bugs-To': 'https://bugs.kde.org/enter_bug.cgi?product=gcompris',
+ 'POT-Creation-Date': modtime_utc_string,
+ 'PO-Revision-Date': modtime_utc_string,
+ 'Last-Translator': 'FULL NAME <EMAIL@ADDRESS>\n',
+ 'Language-Team': 'LANGUAGE <kde-i18n-doc@kde.org>\n',
+ 'MIME-Version': '1.0',
+ 'Content-Type': 'text/plain; charset=utf-8',
+ 'Content-Transfer-Encoding': '8bit',
+}
for chapter in data:
for lesson in chapter['content']:
for word in lesson['content']:
- print "#. " + chapter['name'] + \
- " / " + lesson['name'] + \
- " / " + word['description'] + \
- ": http://gcompris.net/incoming/lang/words.html#" + \
- word['image'].split('/')[-1].split(".")[0]
- print "#: " + "http://gcompris.net/incoming/lang/words.html#" + \
- word['image'].split('/')[-1].split(".")[0]
- print 'msgctxt "LangWords|"'
- print 'msgid "' + word['description'] + '"'
- print 'msgstr "' + getManualTranslation(manualData, word['voice']).encode('utf-8') + '"'
- print ""
+ voice = word['voice'].split('/')[-1].split(".")[0] + ".ogg"
+ imageLink = "https://gcompris.net/incoming/lang/words_by_section.html#" + \
+ urllib.parse.quote(word['description'].split('/')[-1].split(".")[0])
+ if displayInConsole:
+ print("#. " + chapter['name'] + \
+ " / " + lesson['name'] + \
+ " / " + word['description'] + \
+ ": "+ imageLink)
+ print('msgctxt "'+voice+'"|"')
+ print('msgid "' + word['description'] + '"')
+ print('msgstr "' + getManualTranslation(manualData, voice) + '"')
+ print("")
+
+ entry = polib.POEntry(
+ msgid = word['description'],
+ msgstr = getManualTranslation(manualData, voice),
+ msgctxt = voice,
+ comment = chapter['name'] + " / " + lesson['name'] + " / " + word['description'] +
+ "\n" + imageLink
+ )
+ po.append(entry)
+
+po.save(sys.argv[2])
diff --git a/src/activities/lang/resource/poToDataset.py b/src/activities/lang/resource/poToDataset.py
new file mode 100644
index 000000000..380a4ca85
--- /dev/null
+++ b/src/activities/lang/resource/poToDataset.py
@@ -0,0 +1,42 @@
+# -* coding: utf-8 -*-
+#!/usr/bin/python3
+#
+# GCompris - po2Dataset.py
+#
+# Copyright (C) 2019 Johnny Jazeix <jazeix@gmail.com>
+#
+# This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+
+import json
+import polib
+import sys
+import urllib
+
+from urllib.parse import unquote
+
+if len(sys.argv) != 3:
+ print("Usage: po2Dataset.py po_file json_file")
+ sys.exit(1)
+
+poFile = polib.pofile(sys.argv[1], encoding='utf-8')
+jsonFile = sys.argv[2]
+data = {}
+
+for entry in poFile.translated_entries():
+ word = entry.msgctxt
+ data[word] = entry.msgstr
+
+with open(jsonFile, "w", encoding='utf-8') as data_file:
+ json.dump(data, data_file, indent=4, sort_keys=True, ensure_ascii=False)
+
diff --git a/src/activities/lang/resource/words.json b/src/activities/lang/resource/words.json
index 35e0fad0f..15b317d78 100644
--- a/src/activities/lang/resource/words.json
+++ b/src/activities/lang/resource/words.json
@@ -1,5704 +1,5620 @@
[
{
"type": "chapter",
"name": "otherChapter",
"imgPrefix": "qrc:/gcompris/data/",
"content": [
{
"type": "lesson",
"name": "otherLesson",
"content": [
{
"description": "alphabet",
"image": "words/alphabet.png",
"voice": "voices-$CA/$LOCALE/words/alphabet.$CA"
},
+ {
+ "description": "angel",
+ "image": "words/angel.png",
+ "voice": "voices-$CA/$LOCALE/words/angel.$CA"
+ },
+ {
+ "description": "behind",
+ "image": "words/behind.png",
+ "voice": "voices-$CA/$LOCALE/words/behind.$CA"
+ },
{
"description": "bit",
"image": "words/bit.png",
"voice": "voices-$CA/$LOCALE/words/bit.$CA"
},
+ {
+ "description": "bone",
+ "image": "words/bone.png",
+ "voice": "voices-$CA/$LOCALE/words/bone.$CA"
+ },
{
"description": "bubble",
"image": "words/bubble.png",
"voice": "voices-$CA/$LOCALE/words/bubble.$CA"
},
+ {
+ "description": "camp",
+ "image": "words/camp.png",
+ "voice": "voices-$CA/$LOCALE/words/camp.$CA"
+ },
{
"description": "carnival",
"image": "words/carnival.png",
"voice": "voices-$CA/$LOCALE/words/carnival.$CA"
+ },
+ {
+ "description": "chores",
+ "image": "words/chores.png",
+ "voice": "voices-$CA/$LOCALE/words/chores.$CA"
+ },
+ {
+ "description": "christmas",
+ "image": "words/christmas.png",
+ "voice": "voices-$CA/$LOCALE/words/christmas.$CA"
},
{
"description": "craft",
"image": "words/craft.png",
"voice": "voices-$CA/$LOCALE/words/craft.$CA"
},
+ {
+ "description": "dot",
+ "image": "words/dot.png",
+ "voice": "voices-$CA/$LOCALE/words/dot.$CA"
+ },
+ {
+ "description": "engine",
+ "image": "words/engine.png",
+ "voice": "voices-$CA/$LOCALE/words/engine.$CA"
+ },
+ {
+ "description": "fairy",
+ "image": "words/fairy.png",
+ "voice": "voices-$CA/$LOCALE/words/fairy.$CA"
+ },
+ {
+ "description": "flat",
+ "image": "words/flat.png",
+ "voice": "voices-$CA/$LOCALE/words/flat.$CA"
+ },
+ {
+ "description": "front",
+ "image": "words/front.png",
+ "voice": "voices-$CA/$LOCALE/words/front.$CA"
+ },
+ {
+ "description": "gnome",
+ "image": "words/gnome.png",
+ "voice": "voices-$CA/$LOCALE/words/gnome.$CA"
+ },
+ {
+ "description": "guignol",
+ "image": "words/guignol.png",
+ "voice": "voices-$CA/$LOCALE/words/guignol.$CA"
+ },
+ {
+ "description": "half",
+ "image": "words/half.png",
+ "voice": "voices-$CA/$LOCALE/words/half.$CA"
+ },
+ {
+ "description": "king",
+ "image": "words/king.png",
+ "voice": "voices-$CA/$LOCALE/words/king.$CA"
+ },
+ {
+ "description": "knight",
+ "image": "words/knight.png",
+ "voice": "voices-$CA/$LOCALE/words/knight.$CA"
+ },
+ {
+ "description": "lad",
+ "image": "words/lad.png",
+ "voice": "voices-$CA/$LOCALE/words/lad.$CA"
+ },
+ {
+ "description": "left",
+ "image": "words/left.png",
+ "voice": "voices-$CA/$LOCALE/words/left.$CA"
+ },
+ {
+ "description": "light",
+ "image": "words/light.png",
+ "voice": "voices-$CA/$LOCALE/words/light.$CA"
+ },
+ {
+ "description": "line",
+ "image": "words/line.png",
+ "voice": "voices-$CA/$LOCALE/words/line.$CA"
+ },
{
"description": "link",
"image": "words/link.png",
"voice": "voices-$CA/$LOCALE/words/link.$CA"
},
+ {
+ "description": "movie",
+ "image": "words/movie.png",
+ "voice": "voices-$CA/$LOCALE/words/movie.$CA"
+ },
+ {
+ "description": "music",
+ "image": "words/music.png",
+ "voice": "voices-$CA/$LOCALE/words/music.$CA"
+ },
{
"description": "number",
"image": "words/number.png",
"voice": "voices-$CA/$LOCALE/words/number.$CA"
},
+ {
+ "description": "on",
+ "image": "words/on.png",
+ "voice": "voices-$CA/$LOCALE/words/on.$CA"
+ },
+ {
+ "description": "pedal",
+ "image": "words/pedal.png",
+ "voice": "voices-$CA/$LOCALE/words/pedal.$CA"
+ },
+ {
+ "description": "pirate",
+ "image": "words/pirate.png",
+ "voice": "voices-$CA/$LOCALE/words/pirate.$CA"
+ },
+ {
+ "description": "pope",
+ "image": "words/pope.png",
+ "voice": "voices-$CA/$LOCALE/words/pope.$CA"
+ },
+ {
+ "description": "porthole",
+ "image": "words/porthole.png",
+ "voice": "voices-$CA/$LOCALE/words/porthole.$CA"
+ },
+ {
+ "description": "president",
+ "image": "words/president.png",
+ "voice": "voices-$CA/$LOCALE/words/president.$CA"
+ },
+ {
+ "description": "price",
+ "image": "words/price.png",
+ "voice": "voices-$CA/$LOCALE/words/price.$CA"
+ },
+ {
+ "description": "prince",
+ "image": "words/prince.png",
+ "voice": "voices-$CA/$LOCALE/words/prince.$CA"
+ },
+ {
+ "description": "princess",
+ "image": "words/princess.png",
+ "voice": "voices-$CA/$LOCALE/words/princess.$CA"
+ },
+ {
+ "description": "prisoner",
+ "image": "words/prisoner.png",
+ "voice": "voices-$CA/$LOCALE/words/prisoner.$CA"
+ },
+ {
+ "description": "queen",
+ "image": "words/queen.png",
+ "voice": "voices-$CA/$LOCALE/words/queen.$CA"
+ },
{
"description": "question",
"image": "words/question.png",
"voice": "voices-$CA/$LOCALE/words/question.$CA"
},
{
"description": "quiz",
"image": "words/quiz.png",
"voice": "voices-$CA/$LOCALE/words/quiz.$CA"
},
+ {
+ "description": "right",
+ "image": "words/right.png",
+ "voice": "voices-$CA/$LOCALE/words/right.$CA"
+ },
+ {
+ "description": "rocket",
+ "image": "words/rocket.png",
+ "voice": "voices-$CA/$LOCALE/words/rocket.$CA"
+ },
+ {
+ "description": "round",
+ "image": "words/round.png",
+ "voice": "voices-$CA/$LOCALE/words/round.$CA"
+ },
{
"description": "science",
"image": "words/science.png",
"voice": "voices-$CA/$LOCALE/words/science.$CA"
},
{
"description": "splatter",
"image": "words/splatter.png",
"voice": "voices-$CA/$LOCALE/words/splatter.$CA"
},
+ {
+ "description": "spot",
+ "image": "words/spot.png",
+ "voice": "voices-$CA/$LOCALE/words/spot.$CA"
+ },
+ {
+ "description": "square",
+ "image": "words/square.png",
+ "voice": "voices-$CA/$LOCALE/words/square.$CA"
+ },
+ {
+ "description": "stand",
+ "image": "words/stand.png",
+ "voice": "voices-$CA/$LOCALE/words/stand.$CA"
+ },
+ {
+ "description": "stripe",
+ "image": "words/stripe.png",
+ "voice": "voices-$CA/$LOCALE/words/stripe.$CA"
+ },
+ {
+ "description": "student",
+ "image": "words/student.png",
+ "voice": "voices-$CA/$LOCALE/words/student.$CA"
+ },
{
"description": "text",
"image": "words/text.png",
"voice": "voices-$CA/$LOCALE/words/text.$CA"
},
+ {
+ "description": "thief",
+ "image": "words/thief.png",
+ "voice": "voices-$CA/$LOCALE/words/thief.$CA"
+ },
+ {
+ "description": "triangle",
+ "image": "words/triangle.png",
+ "voice": "voices-$CA/$LOCALE/words/triangle.$CA"
+ },
+ {
+ "description": "trip",
+ "image": "words/trip.png",
+ "voice": "voices-$CA/$LOCALE/words/trip.$CA"
+ },
{
"description": "tune",
"image": "words/tune.png",
"voice": "voices-$CA/$LOCALE/words/tune.$CA"
},
+ {
+ "description": "under",
+ "image": "words/under.png",
+ "voice": "voices-$CA/$LOCALE/words/under.$CA"
+ },
{
"description": "vowel",
"image": "words/vowel.png",
"voice": "voices-$CA/$LOCALE/words/vowel.$CA"
},
{
"description": "weight",
"image": "words/weight.png",
"voice": "voices-$CA/$LOCALE/words/weight.$CA"
},
{
"description": "word",
"image": "words/word.png",
"voice": "voices-$CA/$LOCALE/words/word.$CA"
}
]
},
{
"type": "lesson",
"name": "action",
"content": [
{
- "description": "ate",
- "image": "words/ate.png",
- "voice": "voices-$CA/$LOCALE/words/ate.$CA"
- },
- {
- "description": "bake",
- "image": "words/bake.png",
- "voice": "voices-$CA/$LOCALE/words/bake.$CA"
- },
- {
- "description": "bark",
+ "description": "to bark",
"image": "words/bark.png",
"voice": "voices-$CA/$LOCALE/words/bark.$CA"
},
{
- "description": "beat",
+ "description": "to beat",
"image": "words/beat.png",
"voice": "voices-$CA/$LOCALE/words/beat.$CA"
},
{
- "description": "beg",
+ "description": "to beg",
"image": "words/beg.png",
"voice": "voices-$CA/$LOCALE/words/beg.$CA"
},
{
- "description": "bite",
+ "description": "to bite",
"image": "words/bite.png",
"voice": "voices-$CA/$LOCALE/words/bite.$CA"
},
{
- "description": "blink",
+ "description": "to blink",
"image": "words/blink.png",
"voice": "voices-$CA/$LOCALE/words/blink.$CA"
},
{
- "description": "boil",
+ "description": "to boil",
"image": "words/boil.png",
"voice": "voices-$CA/$LOCALE/words/boil.$CA"
},
{
- "description": "break",
+ "description": "to break",
"image": "words/break.png",
"voice": "voices-$CA/$LOCALE/words/break.$CA"
},
{
- "description": "call",
+ "description": "to call",
"image": "words/call.png",
"voice": "voices-$CA/$LOCALE/words/call.$CA"
},
{
- "description": "catch",
+ "description": "to catch",
"image": "words/catch.png",
"voice": "voices-$CA/$LOCALE/words/catch.$CA"
},
{
- "description": "chat",
+ "description": "to chat",
"image": "words/chat.png",
"voice": "voices-$CA/$LOCALE/words/chat.$CA"
},
{
- "description": "chop",
+ "description": "to chop",
"image": "words/chop.png",
"voice": "voices-$CA/$LOCALE/words/chop.$CA"
},
{
- "description": "chores",
- "image": "words/chores.png",
- "voice": "voices-$CA/$LOCALE/words/chores.$CA"
- },
- {
- "description": "clap",
+ "description": "to clap",
"image": "words/clap.png",
"voice": "voices-$CA/$LOCALE/words/clap.$CA"
},
{
- "description": "clean",
+ "description": "to clean",
"image": "words/clean.png",
"voice": "voices-$CA/$LOCALE/words/clean.$CA"
},
{
- "description": "cough",
+ "description": "to cook",
+ "image": "words/cook.png",
+ "voice": "voices-$CA/$LOCALE/words/cook.$CA"
+ },
+ {
+ "description": "to cough",
"image": "words/cough.png",
"voice": "voices-$CA/$LOCALE/words/cough.$CA"
},
{
- "description": "crawl",
+ "description": "to crawl",
"image": "words/crawl.png",
"voice": "voices-$CA/$LOCALE/words/crawl.$CA"
},
{
- "description": "croak",
+ "description": "to croak",
"image": "words/croak.png",
"voice": "voices-$CA/$LOCALE/words/croak.$CA"
},
{
- "description": "cry",
+ "description": "to cry",
"image": "words/cry.png",
"voice": "voices-$CA/$LOCALE/words/cry.$CA"
},
{
- "description": "cut",
+ "description": "to cut",
"image": "words/cut.png",
"voice": "voices-$CA/$LOCALE/words/cut.$CA"
},
{
- "description": "dig",
+ "description": "to dig",
"image": "words/dig.png",
"voice": "voices-$CA/$LOCALE/words/dig.$CA"
},
{
- "description": "drank",
- "image": "words/drank.png",
- "voice": "voices-$CA/$LOCALE/words/drank.$CA"
- },
- {
- "description": "draw",
+ "description": "to draw",
"image": "words/draw.png",
"voice": "voices-$CA/$LOCALE/words/draw.$CA"
},
{
- "description": "dream",
+ "description": "to dream",
"image": "words/dream.png",
"voice": "voices-$CA/$LOCALE/words/dream.$CA"
},
{
- "description": "drinking",
- "image": "words/drinking.png",
- "voice": "voices-$CA/$LOCALE/words/drinking.$CA"
+ "description": "to drink",
+ "image": "words/to_drink.png",
+ "voice": "voices-$CA/$LOCALE/words/to_drink.$CA"
},
{
- "description": "drive",
+ "description": "to drive",
"image": "words/drive.png",
"voice": "voices-$CA/$LOCALE/words/drive.$CA"
},
{
- "description": "drool",
+ "description": "to drool",
"image": "words/drool.png",
"voice": "voices-$CA/$LOCALE/words/drool.$CA"
},
{
- "description": "dry",
+ "description": "to dry",
"image": "words/dry.png",
"voice": "voices-$CA/$LOCALE/words/dry.$CA"
},
{
- "description": "eat",
+ "description": "to eat",
"image": "words/eat.png",
"voice": "voices-$CA/$LOCALE/words/eat.$CA"
},
{
- "description": "fall down",
- "image": "words/fall_down.png",
- "voice": "voices-$CA/$LOCALE/words/fall_down.$CA"
- },
- {
- "description": "feed",
+ "description": "to feed",
"image": "words/feed.png",
"voice": "voices-$CA/$LOCALE/words/feed.$CA"
},
{
- "description": "fell",
- "image": "words/fell.png",
- "voice": "voices-$CA/$LOCALE/words/fell.$CA"
+ "description": "to fall",
+ "image": "words/fall.png",
+ "voice": "voices-$CA/$LOCALE/words/fall.$CA"
},
{
- "description": "fetch",
+ "description": "to fetch",
"image": "words/fetch.png",
"voice": "voices-$CA/$LOCALE/words/fetch.$CA"
},
{
- "description": "find",
+ "description": "to find",
"image": "words/find.png",
"voice": "voices-$CA/$LOCALE/words/find.$CA"
},
{
- "description": "flight",
- "image": "words/flight.png",
- "voice": "voices-$CA/$LOCALE/words/flight.$CA"
- },
- {
- "description": "float",
+ "description": "to float",
"image": "words/float.png",
"voice": "voices-$CA/$LOCALE/words/float.$CA"
},
{
- "description": "fly",
+ "description": "to fly",
"image": "words/fly.png",
"voice": "voices-$CA/$LOCALE/words/fly.$CA"
},
{
- "description": "freeze",
+ "description": "to freeze",
"image": "words/freeze.png",
"voice": "voices-$CA/$LOCALE/words/freeze.$CA"
},
{
- "description": "growl",
+ "description": "to growl",
"image": "words/growl.png",
"voice": "voices-$CA/$LOCALE/words/growl.$CA"
},
{
- "description": "hatch",
+ "description": "to hatch",
"image": "words/hatch.png",
"voice": "voices-$CA/$LOCALE/words/hatch.$CA"
},
{
- "description": "hear",
+ "description": "to hear",
"image": "words/hear.png",
"voice": "voices-$CA/$LOCALE/words/hear.$CA"
},
{
- "description": "howl",
+ "description": "to howl",
"image": "words/howl.png",
"voice": "voices-$CA/$LOCALE/words/howl.$CA"
},
{
- "description": "hug",
+ "description": "to hug",
"image": "words/hug.png",
"voice": "voices-$CA/$LOCALE/words/hug.$CA"
},
{
- "description": "jump",
+ "description": "to jump",
"image": "words/jump.png",
"voice": "voices-$CA/$LOCALE/words/jump.$CA"
},
{
- "description": "kiss",
+ "description": "to kiss",
"image": "words/kiss.png",
"voice": "voices-$CA/$LOCALE/words/kiss.$CA"
},
{
- "description": "kneel",
+ "description": "to kneel",
"image": "words/kneel.png",
"voice": "voices-$CA/$LOCALE/words/kneel.$CA"
},
{
- "description": "knit",
+ "description": "to knit",
"image": "words/knit.png",
"voice": "voices-$CA/$LOCALE/words/knit.$CA"
},
{
- "description": "lick",
+ "description": "to lick",
"image": "words/lick.png",
"voice": "voices-$CA/$LOCALE/words/lick.$CA"
},
{
- "description": "look",
+ "description": "to look",
"image": "words/look.png",
"voice": "voices-$CA/$LOCALE/words/look.$CA"
},
{
- "description": "meet",
+ "description": "to meet",
"image": "words/meet.png",
"voice": "voices-$CA/$LOCALE/words/meet.$CA"
},
{
- "description": "nap",
+ "description": "to nap",
"image": "words/nap.png",
"voice": "voices-$CA/$LOCALE/words/nap.$CA"
},
{
- "description": "peck",
+ "description": "to peck",
"image": "words/peck.png",
"voice": "voices-$CA/$LOCALE/words/peck.$CA"
},
{
- "description": "play",
+ "description": "to play",
"image": "words/play.png",
"voice": "voices-$CA/$LOCALE/words/play.$CA"
},
{
- "description": "plow",
+ "description": "to plow",
"image": "words/plow.png",
"voice": "voices-$CA/$LOCALE/words/plow.$CA"
},
{
- "description": "pounce",
+ "description": "to pounce",
"image": "words/pounce.png",
"voice": "voices-$CA/$LOCALE/words/pounce.$CA"
},
{
- "description": "pull",
+ "description": "to pull",
"image": "words/pull.png",
"voice": "voices-$CA/$LOCALE/words/pull.$CA"
},
{
- "description": "quarrel",
+ "description": "to quarrel",
"image": "words/quarrel.png",
"voice": "voices-$CA/$LOCALE/words/quarrel.$CA"
},
{
- "description": "read",
+ "description": "to read",
"image": "words/read.png",
"voice": "voices-$CA/$LOCALE/words/read.$CA"
},
{
- "description": "rip",
+ "description": "to rip",
"image": "words/rip.png",
"voice": "voices-$CA/$LOCALE/words/rip.$CA"
},
{
- "description": "rise",
+ "description": "to rise",
"image": "words/rise.png",
"voice": "voices-$CA/$LOCALE/words/rise.$CA"
},
{
- "description": "run",
+ "description": "to run",
"image": "words/run.png",
"voice": "voices-$CA/$LOCALE/words/run.$CA"
},
{
- "description": "sat",
- "image": "words/sat.png",
- "voice": "voices-$CA/$LOCALE/words/sat.$CA"
- },
- {
- "description": "scared",
- "image": "words/scared.png",
- "voice": "voices-$CA/$LOCALE/words/scared.$CA"
+ "description": "to scare",
+ "image": "words/scare.png",
+ "voice": "voices-$CA/$LOCALE/words/scare.$CA"
},
{
- "description": "scratch",
+ "description": "to scratch",
"image": "words/scratch.png",
"voice": "voices-$CA/$LOCALE/words/scratch.$CA"
},
{
- "description": "scream",
+ "description": "to scream",
"image": "words/scream.png",
"voice": "voices-$CA/$LOCALE/words/scream.$CA"
},
{
- "description": "scribble",
+ "description": "to scribble",
"image": "words/scribble.png",
"voice": "voices-$CA/$LOCALE/words/scribble.$CA"
},
{
- "description": "see",
+ "description": "to see",
"image": "words/see.png",
"voice": "voices-$CA/$LOCALE/words/see.$CA"
},
{
- "description": "shake",
+ "description": "to shake",
"image": "words/shake.png",
"voice": "voices-$CA/$LOCALE/words/shake.$CA"
},
{
- "description": "shave",
+ "description": "to shave",
"image": "words/shave.png",
"voice": "voices-$CA/$LOCALE/words/shave.$CA"
},
{
- "description": "sing",
+ "description": "to sing",
"image": "words/sing.png",
"voice": "voices-$CA/$LOCALE/words/sing.$CA"
},
{
- "description": "sip",
+ "description": "to sip",
"image": "words/sip.png",
"voice": "voices-$CA/$LOCALE/words/sip.$CA"
},
{
- "description": "sit",
+ "description": "to sit",
"image": "words/sit.png",
"voice": "voices-$CA/$LOCALE/words/sit.$CA"
},
{
- "description": "slam",
+ "description": "to slam",
"image": "words/slam.png",
"voice": "voices-$CA/$LOCALE/words/slam.$CA"
},
{
- "description": "sleep",
+ "description": "to sleep",
"image": "words/sleep.png",
"voice": "voices-$CA/$LOCALE/words/sleep.$CA"
},
{
- "description": "smell",
+ "description": "to smell",
"image": "words/smell.png",
"voice": "voices-$CA/$LOCALE/words/smell.$CA"
},
{
- "description": "smooch",
+ "description": "to smooch",
"image": "words/smooch.png",
"voice": "voices-$CA/$LOCALE/words/smooch.$CA"
},
{
- "description": "sniff",
+ "description": "to sniff",
"image": "words/sniff.png",
"voice": "voices-$CA/$LOCALE/words/sniff.$CA"
},
{
- "description": "speak",
+ "description": "to speak",
"image": "words/speak.png",
"voice": "voices-$CA/$LOCALE/words/speak.$CA"
},
{
- "description": "spill",
+ "description": "to spill",
"image": "words/spill.png",
"voice": "voices-$CA/$LOCALE/words/spill.$CA"
},
{
- "description": "splash",
+ "description": "to splash",
"image": "words/splash.png",
"voice": "voices-$CA/$LOCALE/words/splash.$CA"
},
{
- "description": "spray",
+ "description": "to spray",
"image": "words/spray.png",
"voice": "voices-$CA/$LOCALE/words/spray.$CA"
},
{
- "description": "spread",
+ "description": "to spread",
"image": "words/spread.png",
"voice": "voices-$CA/$LOCALE/words/spread.$CA"
},
{
- "description": "spring",
+ "description": "to spring",
"image": "words/spring.png",
"voice": "voices-$CA/$LOCALE/words/spring.$CA"
},
{
- "description": "squat",
+ "description": "to squat",
"image": "words/squat.png",
"voice": "voices-$CA/$LOCALE/words/squat.$CA"
},
{
- "description": "sting",
+ "description": "to stare",
+ "image": "words/stare.png",
+ "voice": "voices-$CA/$LOCALE/words/stare.$CA"
+ },
+ {
+ "description": "to sting",
"image": "words/sting.png",
"voice": "voices-$CA/$LOCALE/words/sting.$CA"
},
{
- "description": "stitch",
+ "description": "to stitch",
"image": "words/stitch.png",
"voice": "voices-$CA/$LOCALE/words/stitch.$CA"
},
{
- "description": "stop",
+ "description": "to stop",
"image": "words/stop.png",
"voice": "voices-$CA/$LOCALE/words/stop.$CA"
},
{
- "description": "stretch",
+ "description": "to stretch",
"image": "words/stretch.png",
"voice": "voices-$CA/$LOCALE/words/stretch.$CA"
},
{
- "description": "study",
+ "description": "to study",
"image": "words/study.png",
"voice": "voices-$CA/$LOCALE/words/study.$CA"
},
{
- "description": "teach",
+ "description": "to teach",
"image": "words/teach.png",
"voice": "voices-$CA/$LOCALE/words/teach.$CA"
},
{
- "description": "tear",
+ "description": "to tear",
"image": "words/tear.png",
"voice": "voices-$CA/$LOCALE/words/tear.$CA"
},
{
- "description": "think",
+ "description": "to think",
"image": "words/think.png",
"voice": "voices-$CA/$LOCALE/words/think.$CA"
},
{
- "description": "touch",
+ "description": "to touch",
"image": "words/touch.png",
"voice": "voices-$CA/$LOCALE/words/touch.$CA"
},
{
- "description": "wag",
+ "description": "to wag",
"image": "words/wag.png",
"voice": "voices-$CA/$LOCALE/words/wag.$CA"
},
{
- "description": "walk",
+ "description": "to walk",
"image": "words/walk.png",
"voice": "voices-$CA/$LOCALE/words/walk.$CA"
},
{
- "description": "wash",
+ "description": "to wash",
"image": "words/wash.png",
"voice": "voices-$CA/$LOCALE/words/wash.$CA"
},
{
- "description": "whisper",
+ "description": "to whisper",
"image": "words/whisper.png",
"voice": "voices-$CA/$LOCALE/words/whisper.$CA"
},
{
- "description": "win",
+ "description": "to win",
"image": "words/win.png",
"voice": "voices-$CA/$LOCALE/words/win.$CA"
},
{
- "description": "write",
+ "description": "to write",
"image": "words/write.png",
"voice": "voices-$CA/$LOCALE/words/write.$CA"
}
]
},
{
"type": "lesson",
"name": "adjective",
"content": [
{
- "description": "behind",
- "image": "words/behind.png",
- "voice": "voices-$CA/$LOCALE/words/behind.$CA"
+ "description": "bald",
+ "image": "words/bald.png",
+ "voice": "voices-$CA/$LOCALE/words/bald.$CA"
},
{
"description": "big",
"image": "words/big.png",
"voice": "voices-$CA/$LOCALE/words/big.$CA"
},
{
"description": "blind",
"image": "words/blind.png",
"voice": "voices-$CA/$LOCALE/words/blind.$CA"
},
{
"description": "blond",
"image": "words/blond.png",
"voice": "voices-$CA/$LOCALE/words/blond.$CA"
},
{
"description": "bright",
"image": "words/bright.png",
"voice": "voices-$CA/$LOCALE/words/bright.$CA"
},
{
"description": "crazy",
"image": "words/crazy.png",
"voice": "voices-$CA/$LOCALE/words/crazy.$CA"
},
{
"description": "cute",
"image": "words/cute.png",
"voice": "voices-$CA/$LOCALE/words/cute.$CA"
},
{
"description": "dirty",
"image": "words/dirty.png",
"voice": "voices-$CA/$LOCALE/words/dirty.$CA"
},
{
"description": "empty",
"image": "words/empty.png",
"voice": "voices-$CA/$LOCALE/words/empty.$CA"
},
{
- "description": "fat",
- "image": "words/fat.png",
- "voice": "voices-$CA/$LOCALE/words/fat.$CA"
- },
- {
- "description": "flat",
- "image": "words/flat.png",
- "voice": "voices-$CA/$LOCALE/words/flat.$CA"
- },
- {
- "description": "front",
- "image": "words/front.png",
- "voice": "voices-$CA/$LOCALE/words/front.$CA"
- },
- {
+ "description": "fat",
+ "image": "words/fat.png",
+ "voice": "voices-$CA/$LOCALE/words/fat.$CA"
+ },
+ {
"description": "full",
"image": "words/full.png",
"voice": "voices-$CA/$LOCALE/words/full.$CA"
},
{
"description": "giant",
"image": "words/giant.png",
"voice": "voices-$CA/$LOCALE/words/giant.$CA"
},
{
"description": "golden",
"image": "words/golden.png",
"voice": "voices-$CA/$LOCALE/words/golden.$CA"
},
- {
- "description": "half",
- "image": "words/half.png",
- "voice": "voices-$CA/$LOCALE/words/half.$CA"
- },
{
"description": "happy",
"image": "words/happy.png",
"voice": "voices-$CA/$LOCALE/words/happy.$CA"
},
{
"description": "high",
"image": "words/high.png",
"voice": "voices-$CA/$LOCALE/words/high.$CA"
},
{
"description": "hot",
"image": "words/hot.png",
"voice": "voices-$CA/$LOCALE/words/hot.$CA"
},
{
"description": "huge",
"image": "words/huge.png",
"voice": "voices-$CA/$LOCALE/words/huge.$CA"
},
{
- "description": "hunchback",
- "image": "words/hunchback.png",
- "voice": "voices-$CA/$LOCALE/words/hunchback.$CA"
+ "description": "hunchbacked",
+ "image": "words/hunchbacked.png",
+ "voice": "voices-$CA/$LOCALE/words/hunchbacked.$CA"
},
{
"description": "ill",
"image": "words/ill.png",
"voice": "voices-$CA/$LOCALE/words/ill.$CA"
},
- {
- "description": "left",
- "image": "words/left.png",
- "voice": "voices-$CA/$LOCALE/words/left.$CA"
- },
- {
- "description": "line",
- "image": "words/line.png",
- "voice": "voices-$CA/$LOCALE/words/line.$CA"
- },
{
"description": "liquid",
"image": "words/liquid.png",
"voice": "voices-$CA/$LOCALE/words/liquid.$CA"
},
{
"description": "magic",
"image": "words/magic.png",
"voice": "voices-$CA/$LOCALE/words/magic.$CA"
},
{
"description": "naked",
"image": "words/naked.png",
"voice": "voices-$CA/$LOCALE/words/naked.$CA"
},
- {
- "description": "on",
- "image": "words/on.png",
- "voice": "voices-$CA/$LOCALE/words/on.$CA"
- },
{
"description": "open",
"image": "words/open.png",
"voice": "voices-$CA/$LOCALE/words/open.$CA"
},
- {
- "description": "petite",
- "image": "words/petite.png",
- "voice": "voices-$CA/$LOCALE/words/petite.$CA"
- },
{
"description": "pretty",
"image": "words/pretty.png",
"voice": "voices-$CA/$LOCALE/words/pretty.$CA"
},
- {
- "description": "right",
- "image": "words/right.png",
- "voice": "voices-$CA/$LOCALE/words/right.$CA"
- },
- {
- "description": "round",
- "image": "words/round.png",
- "voice": "voices-$CA/$LOCALE/words/round.$CA"
- },
{
"description": "royal",
"image": "words/royal.png",
"voice": "voices-$CA/$LOCALE/words/royal.$CA"
},
{
"description": "shut",
"image": "words/shut.png",
"voice": "voices-$CA/$LOCALE/words/shut.$CA"
},
{
"description": "sick",
"image": "words/sick.png",
"voice": "voices-$CA/$LOCALE/words/sick.$CA"
},
{
"description": "slim",
"image": "words/slim.png",
"voice": "voices-$CA/$LOCALE/words/slim.$CA"
},
{
"description": "sloppy",
"image": "words/sloppy.png",
"voice": "voices-$CA/$LOCALE/words/sloppy.$CA"
},
{
"description": "small",
"image": "words/small.png",
"voice": "voices-$CA/$LOCALE/words/small.$CA"
},
- {
- "description": "spot",
- "image": "words/spot.png",
- "voice": "voices-$CA/$LOCALE/words/spot.$CA"
- },
- {
- "description": "square",
- "image": "words/square.png",
- "voice": "voices-$CA/$LOCALE/words/square.$CA"
- },
- {
- "description": "stand",
- "image": "words/stand.png",
- "voice": "voices-$CA/$LOCALE/words/stand.$CA"
- },
{
"description": "steep",
"image": "words/steep.png",
"voice": "voices-$CA/$LOCALE/words/steep.$CA"
},
{
"description": "stinky",
"image": "words/stinky.png",
"voice": "voices-$CA/$LOCALE/words/stinky.$CA"
},
{
"description": "straight",
"image": "words/straight.png",
"voice": "voices-$CA/$LOCALE/words/straight.$CA"
},
- {
- "description": "stripe",
- "image": "words/stripe.png",
- "voice": "voices-$CA/$LOCALE/words/stripe.$CA"
- },
{
"description": "strong",
"image": "words/strong.png",
"voice": "voices-$CA/$LOCALE/words/strong.$CA"
},
{
"description": "tall",
"image": "words/tall.png",
"voice": "voices-$CA/$LOCALE/words/tall.$CA"
},
{
"description": "thick",
"image": "words/thick.png",
"voice": "voices-$CA/$LOCALE/words/thick.$CA"
},
{
"description": "tired",
"image": "words/tired.png",
"voice": "voices-$CA/$LOCALE/words/tired.$CA"
},
- {
- "description": "triangle",
- "image": "words/triangle.png",
- "voice": "voices-$CA/$LOCALE/words/triangle.$CA"
- },
- {
- "description": "under",
- "image": "words/under.png",
- "voice": "voices-$CA/$LOCALE/words/under.$CA"
- },
{
"description": "wet",
"image": "words/wet.png",
"voice": "voices-$CA/$LOCALE/words/wet.$CA"
},
{
"description": "wide",
"image": "words/wide.png",
"voice": "voices-$CA/$LOCALE/words/wide.$CA"
}
]
},
{
"type": "lesson",
"name": "color",
"content": [
{
"description": "color",
"image": "words/color.png",
"voice": "voices-$CA/$LOCALE/words/color.$CA"
},
{
"description": "blue",
"image": "words/blue.png",
"voice": "voices-$CA/$LOCALE/words/blue.$CA"
},
{
"description": "brown",
"image": "words/brown.png",
"voice": "voices-$CA/$LOCALE/words/brown.$CA"
},
{
"description": "black",
"image": "words/black.png",
"voice": "voices-$CA/$LOCALE/words/black.$CA"
},
{
"description": "gray",
"image": "words/gray.png",
"voice": "voices-$CA/$LOCALE/words/gray.$CA"
},
{
"description": "green",
"image": "words/green.png",
"voice": "voices-$CA/$LOCALE/words/green.$CA"
},
{
"description": "mauve",
"image": "words/mauve.png",
"voice": "voices-$CA/$LOCALE/words/mauve.$CA"
},
{
"description": "orange color",
"image": "words/orange-color.png",
"voice": "voices-$CA/$LOCALE/words/orange-color.$CA"
},
{
"description": "pink",
"image": "words/pink.png",
"voice": "voices-$CA/$LOCALE/words/pink.$CA"
},
{
"description": "red",
"image": "words/red.png",
"voice": "voices-$CA/$LOCALE/words/red.$CA"
},
{
"description": "white",
"image": "words/white.png",
"voice": "voices-$CA/$LOCALE/words/white.$CA"
},
{
"description": "yellow",
"image": "words/yellow.png",
"voice": "voices-$CA/$LOCALE/words/yellow.$CA"
}
]
},
{
"type": "lesson",
"name": "number",
"content": [
{
"description": "zero",
"image": "words/zero.png",
"voice": "voices-$CA/$LOCALE/alphabet/U0030.$CA"
},
{
"description": "one",
"image": "words/one.png",
"voice": "voices-$CA/$LOCALE/alphabet/U0031.$CA"
},
{
"description": "two",
"image": "words/two.png",
"voice": "voices-$CA/$LOCALE/alphabet/U0032.$CA"
},
{
"description": "three",
"image": "words/three.png",
"voice": "voices-$CA/$LOCALE/alphabet/U0033.$CA"
},
{
"description": "four",
"image": "words/four.png",
"voice": "voices-$CA/$LOCALE/alphabet/U0034.$CA"
},
{
"description": "five",
"image": "words/five.png",
"voice": "voices-$CA/$LOCALE/alphabet/U0035.$CA"
},
{
"description": "six",
"image": "words/six.png",
"voice": "voices-$CA/$LOCALE/alphabet/U0036.$CA"
},
{
"description": "seven",
"image": "words/seven.png",
"voice": "voices-$CA/$LOCALE/alphabet/U0037.$CA"
},
{
"description": "eight",
"image": "words/eight.png",
"voice": "voices-$CA/$LOCALE/alphabet/U0038.$CA"
},
{
"description": "nine",
"image": "words/nine.png",
"voice": "voices-$CA/$LOCALE/alphabet/U0039.$CA"
},
{
"description": "ten",
"image": "words/ten.png",
"voice": "voices-$CA/$LOCALE/alphabet/10.$CA"
},
{
"description": "eleven",
"image": "words/eleven.png",
"voice": "voices-$CA/$LOCALE/alphabet/11.$CA"
},
{
"description": "twelve",
"image": "words/twelve.png",
"voice": "voices-$CA/$LOCALE/alphabet/12.$CA"
},
{
"description": "sixteen",
"image": "words/sixteen.png",
"voice": "voices-$CA/$LOCALE/alphabet/16.$CA"
}
]
}
]
},
{
"type": "chapter",
"name": "people",
"imgPrefix": "qrc:/gcompris/data/",
"content": [
{
"type": "lesson",
"name": "bodyparts",
"content": [
{
"description": "ankle",
"image": "words/ankle.png",
"voice": "voices-$CA/$LOCALE/words/ankle.$CA"
},
{
"description": "arm",
"image": "words/arm.png",
"voice": "voices-$CA/$LOCALE/words/arm.$CA"
},
{
"description": "back",
"image": "words/back.png",
"voice": "voices-$CA/$LOCALE/words/back.$CA"
},
- {
- "description": "bald",
- "image": "words/bald.png",
- "voice": "voices-$CA/$LOCALE/words/bald.$CA"
- },
{
"description": "beard",
"image": "words/beard.png",
"voice": "voices-$CA/$LOCALE/words/beard.$CA"
},
{
"description": "belly",
"image": "words/belly.png",
"voice": "voices-$CA/$LOCALE/words/belly.$CA"
},
{
"description": "bottom",
"image": "words/bottom.png",
"voice": "voices-$CA/$LOCALE/words/bottom.$CA"
},
{
"description": "braid",
"image": "words/braid.png",
"voice": "voices-$CA/$LOCALE/words/braid.$CA"
},
{
"description": "brain",
"image": "words/brain.png",
"voice": "voices-$CA/$LOCALE/words/brain.$CA"
},
{
"description": "breast",
"image": "words/breast.png",
"voice": "voices-$CA/$LOCALE/words/breast.$CA"
},
{
"description": "bump",
"image": "words/bump.png",
"voice": "voices-$CA/$LOCALE/words/bump.$CA"
},
{
"description": "cheek",
"image": "words/cheek.png",
"voice": "voices-$CA/$LOCALE/words/cheek.$CA"
},
{
"description": "chin",
"image": "words/chin.png",
"voice": "voices-$CA/$LOCALE/words/chin.$CA"
},
{
"description": "ear",
"image": "words/ear.png",
"voice": "voices-$CA/$LOCALE/words/ear.$CA"
},
{
"description": "elbow",
"image": "words/elbow.png",
"voice": "voices-$CA/$LOCALE/words/elbow.$CA"
},
{
"description": "eyelash",
"image": "words/eyelash.png",
"voice": "voices-$CA/$LOCALE/words/eyelash.$CA"
},
{
"description": "eyes",
"image": "words/eyes.png",
"voice": "voices-$CA/$LOCALE/words/eyes.$CA"
},
{
"description": "face",
"image": "words/face.png",
"voice": "voices-$CA/$LOCALE/words/face.$CA"
},
- {
- "description": "feet",
- "image": "words/feet.png",
- "voice": "voices-$CA/$LOCALE/words/feet.$CA"
- },
{
"description": "femur",
"image": "words/femur.png",
"voice": "voices-$CA/$LOCALE/words/femur.$CA"
},
{
"description": "finger",
"image": "words/finger.png",
"voice": "voices-$CA/$LOCALE/words/finger.$CA"
},
{
"description": "fist",
"image": "words/fist.png",
"voice": "voices-$CA/$LOCALE/words/fist.$CA"
},
{
"description": "foot",
"image": "words/foot.png",
"voice": "voices-$CA/$LOCALE/words/foot.$CA"
},
{
"description": "grin",
"image": "words/grin.png",
"voice": "voices-$CA/$LOCALE/words/grin.$CA"
},
{
"description": "hair",
"image": "words/hair.png",
"voice": "voices-$CA/$LOCALE/words/hair.$CA"
},
{
"description": "hand",
"image": "words/hand.png",
"voice": "voices-$CA/$LOCALE/words/hand.$CA"
},
{
"description": "head",
"image": "words/head.png",
"voice": "voices-$CA/$LOCALE/words/head.$CA"
},
{
"description": "hip",
"image": "words/hip.png",
"voice": "voices-$CA/$LOCALE/words/hip.$CA"
},
{
"description": "knee",
"image": "words/knee.png",
"voice": "voices-$CA/$LOCALE/words/knee.$CA"
},
{
"description": "lap",
"image": "words/lap.png",
"voice": "voices-$CA/$LOCALE/words/lap.$CA"
},
{
"description": "leg",
"image": "words/leg.png",
"voice": "voices-$CA/$LOCALE/words/leg.$CA"
},
{
"description": "lip",
"image": "words/lip.png",
"voice": "voices-$CA/$LOCALE/words/lip.$CA"
},
{
"description": "mouth",
"image": "words/mouth.png",
"voice": "voices-$CA/$LOCALE/words/mouth.$CA"
},
{
"description": "muscle",
"image": "words/muscle.png",
"voice": "voices-$CA/$LOCALE/words/muscle.$CA"
},
{
"description": "navel",
"image": "words/navel.png",
"voice": "voices-$CA/$LOCALE/words/navel.$CA"
},
{
"description": "neck",
"image": "words/neck.png",
"voice": "voices-$CA/$LOCALE/words/neck.$CA"
},
{
"description": "nose",
"image": "words/nose.png",
"voice": "voices-$CA/$LOCALE/words/nose.$CA"
},
{
"description": "nostril",
"image": "words/nostril.png",
"voice": "voices-$CA/$LOCALE/words/nostril.$CA"
},
{
"description": "scar",
"image": "words/scar.png",
"voice": "voices-$CA/$LOCALE/words/scar.$CA"
},
{
"description": "skeleton",
"image": "words/skeleton.png",
"voice": "voices-$CA/$LOCALE/words/skeleton.$CA"
},
{
"description": "skin",
"image": "words/skin.png",
"voice": "voices-$CA/$LOCALE/words/skin.$CA"
},
{
"description": "spine",
"image": "words/spine.png",
"voice": "voices-$CA/$LOCALE/words/spine.$CA"
},
- {
- "description": "stare",
- "image": "words/stare.png",
- "voice": "voices-$CA/$LOCALE/words/stare.$CA"
- },
{
"description": "stomach",
"image": "words/stomach.png",
"voice": "voices-$CA/$LOCALE/words/stomach.$CA"
},
{
"description": "sweat",
"image": "words/sweat.png",
"voice": "voices-$CA/$LOCALE/words/sweat.$CA"
},
{
"description": "teeth",
"image": "words/teeth.png",
"voice": "voices-$CA/$LOCALE/words/teeth.$CA"
},
{
"description": "thigh",
"image": "words/thigh.png",
"voice": "voices-$CA/$LOCALE/words/thigh.$CA"
},
{
"description": "throat",
"image": "words/throat.png",
"voice": "voices-$CA/$LOCALE/words/throat.$CA"
},
{
"description": "thumb",
"image": "words/thumb.png",
"voice": "voices-$CA/$LOCALE/words/thumb.$CA"
},
{
"description": "toe",
"image": "words/toe.png",
"voice": "voices-$CA/$LOCALE/words/toe.$CA"
},
{
"description": "tongue",
"image": "words/tongue.png",
"voice": "voices-$CA/$LOCALE/words/tongue.$CA"
},
{
"description": "vein",
"image": "words/vein.png",
"voice": "voices-$CA/$LOCALE/words/vein.$CA"
},
{
"description": "wart",
"image": "words/wart.png",
"voice": "voices-$CA/$LOCALE/words/wart.$CA"
},
{
"description": "wrist",
"image": "words/wrist.png",
"voice": "voices-$CA/$LOCALE/words/wrist.$CA"
}
]
},
{
"type": "lesson",
"name": "clothes",
"content": [
{
"description": "bathing suit",
"image": "words/bathing_suit.png",
"voice": "voices-$CA/$LOCALE/words/bathing_suit.$CA"
},
{
"description": "bib",
"image": "words/bib.png",
"voice": "voices-$CA/$LOCALE/words/bib.$CA"
},
{
"description": "button",
"image": "words/button.png",
"voice": "voices-$CA/$LOCALE/words/button.$CA"
},
{
"description": "cap",
"image": "words/cap.png",
"voice": "voices-$CA/$LOCALE/words/cap.$CA"
},
{
"description": "cape",
"image": "words/cape.png",
"voice": "voices-$CA/$LOCALE/words/cape.$CA"
},
{
"description": "coat",
"image": "words/coat.png",
"voice": "voices-$CA/$LOCALE/words/coat.$CA"
},
{
"description": "dress",
"image": "words/dress.png",
"voice": "voices-$CA/$LOCALE/words/dress.$CA"
},
{
"description": "glove",
"image": "words/glove.png",
"voice": "voices-$CA/$LOCALE/words/glove.$CA"
},
{
"description": "hat",
"image": "words/hat.png",
"voice": "voices-$CA/$LOCALE/words/hat.$CA"
},
{
"description": "heel",
"image": "words/heel.png",
"voice": "voices-$CA/$LOCALE/words/heel.$CA"
},
{
"description": "helmet",
"image": "words/helmet.png",
"voice": "voices-$CA/$LOCALE/words/helmet.$CA"
},
{
"description": "jacket",
"image": "words/jacket.png",
"voice": "voices-$CA/$LOCALE/words/jacket.$CA"
},
{
"description": "kimono",
"image": "words/kimono.png",
"voice": "voices-$CA/$LOCALE/words/kimono.$CA"
},
{
"description": "nightgown",
"image": "words/nightgown.png",
"voice": "voices-$CA/$LOCALE/words/nightgown.$CA"
},
{
"description": "pajamas",
"image": "words/pajamas.png",
"voice": "voices-$CA/$LOCALE/words/pajamas.$CA"
},
{
"description": "panties",
"image": "words/panties.png",
"voice": "voices-$CA/$LOCALE/words/panties.$CA"
},
{
"description": "pants",
"image": "words/pants.png",
"voice": "voices-$CA/$LOCALE/words/pants.$CA"
},
{
"description": "patch",
"image": "words/patch.png",
"voice": "voices-$CA/$LOCALE/words/patch.$CA"
},
{
"description": "pocket",
"image": "words/pocket.png",
"voice": "voices-$CA/$LOCALE/words/pocket.$CA"
},
{
"description": "pompon",
"image": "words/pompon.png",
"voice": "voices-$CA/$LOCALE/words/pompon.$CA"
},
{
"description": "pullover",
"image": "words/pullover.png",
"voice": "voices-$CA/$LOCALE/words/pullover.$CA"
},
{
"description": "raincoat",
"image": "words/raincoat.png",
"voice": "voices-$CA/$LOCALE/words/raincoat.$CA"
},
{
"description": "robe",
"image": "words/robe.png",
"voice": "voices-$CA/$LOCALE/words/robe.$CA"
},
{
"description": "sandals",
"image": "words/sandals.png",
"voice": "voices-$CA/$LOCALE/words/sandals.$CA"
},
{
"description": "sash",
"image": "words/sash.png",
"voice": "voices-$CA/$LOCALE/words/sash.$CA"
},
{
"description": "scarf",
"image": "words/scarf.png",
"voice": "voices-$CA/$LOCALE/words/scarf.$CA"
},
{
"description": "shirt",
"image": "words/shirt.png",
"voice": "voices-$CA/$LOCALE/words/shirt.$CA"
},
{
"description": "shoe",
"image": "words/shoe.png",
"voice": "voices-$CA/$LOCALE/words/shoe.$CA"
},
{
"description": "shoelace",
"image": "words/shoelace.png",
"voice": "voices-$CA/$LOCALE/words/shoelace.$CA"
},
{
"description": "short",
"image": "words/short.png",
"voice": "voices-$CA/$LOCALE/words/short.$CA"
},
{
"description": "skirt",
"image": "words/skirt.png",
"voice": "voices-$CA/$LOCALE/words/skirt.$CA"
},
{
"description": "sleeve",
"image": "words/sleeve.png",
"voice": "voices-$CA/$LOCALE/words/sleeve.$CA"
},
{
"description": "slippers",
"image": "words/slippers.png",
"voice": "voices-$CA/$LOCALE/words/slippers.$CA"
},
{
"description": "smock",
"image": "words/smock.png",
"voice": "voices-$CA/$LOCALE/words/smock.$CA"
},
{
"description": "sneaker",
"image": "words/sneaker.png",
"voice": "voices-$CA/$LOCALE/words/sneaker.$CA"
},
{
"description": "sock",
"image": "words/sock.png",
"voice": "voices-$CA/$LOCALE/words/sock.$CA"
},
{
"description": "sole shoe",
"image": "words/sole_shoe.png",
"voice": "voices-$CA/$LOCALE/words/sole_shoe.$CA"
},
{
"description": "suit",
"image": "words/suit.png",
"voice": "voices-$CA/$LOCALE/words/suit.$CA"
},
{
"description": "sweatshirt",
"image": "words/sweatshirt.png",
"voice": "voices-$CA/$LOCALE/words/sweatshirt.$CA"
},
{
"description": "uniform",
"image": "words/uniform.png",
"voice": "voices-$CA/$LOCALE/words/uniform.$CA"
},
{
"description": "vest",
"image": "words/vest.png",
"voice": "voices-$CA/$LOCALE/words/vest.$CA"
},
{
"description": "zipper",
"image": "words/zipper.png",
"voice": "voices-$CA/$LOCALE/words/zipper.$CA"
}
]
},
{
"type": "lesson",
"name": "emotion",
"content": [
{
"description": "ache",
"image": "words/ache.png",
"voice": "voices-$CA/$LOCALE/words/ache.$CA"
},
{
"description": "angry",
"image": "words/angry.png",
"voice": "voices-$CA/$LOCALE/words/angry.$CA"
},
{
"description": "blush",
"image": "words/blush.png",
"voice": "voices-$CA/$LOCALE/words/blush.$CA"
},
{
- "description": "danger",
- "image": "words/danger.png",
- "voice": "voices-$CA/$LOCALE/words/danger.$CA"
- },
- {
- "description": "frown",
- "image": "words/frown.png",
- "voice": "voices-$CA/$LOCALE/words/frown.$CA"
+ "description": "fear",
+ "image": "words/fear.png",
+ "voice": "voices-$CA/$LOCALE/words/fear.$CA"
},
{
- "description": "fun",
- "image": "words/fun.png",
- "voice": "voices-$CA/$LOCALE/words/fun.$CA"
+ "description": "joy",
+ "image": "words/joy.png",
+ "voice": "voices-$CA/$LOCALE/words/joy.$CA"
},
{
- "description": "laugh",
+ "description": "to laugh",
"image": "words/laugh.png",
"voice": "voices-$CA/$LOCALE/words/laugh.$CA"
},
{
"description": "mad",
"image": "words/mad.png",
"voice": "voices-$CA/$LOCALE/words/mad.$CA"
},
{
"description": "rage",
"image": "words/rage.png",
"voice": "voices-$CA/$LOCALE/words/rage.$CA"
},
{
"description": "sad",
"image": "words/sad.png",
"voice": "voices-$CA/$LOCALE/words/sad.$CA"
},
{
"description": "smile",
"image": "words/smile.png",
"voice": "voices-$CA/$LOCALE/words/smile.$CA"
},
{
"description": "sob",
"image": "words/sob.png",
"voice": "voices-$CA/$LOCALE/words/sob.$CA"
},
{
"description": "yum",
"image": "words/yum.png",
"voice": "voices-$CA/$LOCALE/words/yum.$CA"
}
]
},
{
"type": "lesson",
"name": "job",
"content": [
{
"description": "accountant",
"image": "words/accountant.png",
"voice": "voices-$CA/$LOCALE/words/accountant.$CA"
},
{
"description": "actor",
"image": "words/actor.png",
"voice": "voices-$CA/$LOCALE/words/actor.$CA"
},
{
"description": "artist",
"image": "words/artist.png",
"voice": "voices-$CA/$LOCALE/words/artist.$CA"
},
{
"description": "astronaut",
"image": "words/astronaut.png",
"voice": "voices-$CA/$LOCALE/words/astronaut.$CA"
},
{
"description": "boxer",
"image": "words/boxer.png",
"voice": "voices-$CA/$LOCALE/words/boxer.$CA"
},
{
"description": "banker female",
"image": "words/banker_female.png",
"voice": "voices-$CA/$LOCALE/words/banker_female.$CA"
},
{
"description": "bricklayer",
"image": "words/bricklayer.png",
"voice": "voices-$CA/$LOCALE/words/bricklayer.$CA"
},
{
"description": "butcher",
"image": "words/butcher.png",
"voice": "voices-$CA/$LOCALE/words/butcher.$CA"
},
{
"description": "carpenter",
"image": "words/carpenter.png",
"voice": "voices-$CA/$LOCALE/words/carpenter.$CA"
},
{
"description": "chef",
"image": "words/chef.png",
"voice": "voices-$CA/$LOCALE/words/chef.$CA"
},
- {
- "description": "chief",
- "image": "words/chief.png",
- "voice": "voices-$CA/$LOCALE/words/chief.$CA"
- },
{
"description": "cleaning lady",
"image": "words/cleaning_lady.png",
"voice": "voices-$CA/$LOCALE/words/cleaning_lady.$CA"
},
{
"description": "clown",
"image": "words/clown.png",
"voice": "voices-$CA/$LOCALE/words/clown.$CA"
},
{
"description": "coach",
"image": "words/coach.png",
"voice": "voices-$CA/$LOCALE/words/coach.$CA"
},
{
"description": "cowboy",
"image": "words/cowboy.png",
"voice": "voices-$CA/$LOCALE/words/cowboy.$CA"
},
- {
- "description": "criminal",
- "image": "words/criminal.png",
- "voice": "voices-$CA/$LOCALE/words/criminal.$CA"
- },
{
"description": "doctor",
"image": "words/doctor.png",
"voice": "voices-$CA/$LOCALE/words/doctor.$CA"
},
{
"description": "electrician",
"image": "words/electrician.png",
"voice": "voices-$CA/$LOCALE/words/electrician.$CA"
},
{
"description": "engineer",
"image": "words/engineer.png",
"voice": "voices-$CA/$LOCALE/words/engineer.$CA"
},
{
"description": "farmer",
"image": "words/farmer.png",
"voice": "voices-$CA/$LOCALE/words/farmer.$CA"
},
{
"description": "fireman",
"image": "words/fireman.png",
"voice": "voices-$CA/$LOCALE/words/fireman.$CA"
},
{
"description": "fisherman",
"image": "words/fisherman.png",
"voice": "voices-$CA/$LOCALE/words/fisherman.$CA"
},
{
"description": "hunter",
"image": "words/hunter.png",
"voice": "voices-$CA/$LOCALE/words/hunter.$CA"
},
{
"description": "job",
"image": "words/job.png",
"voice": "voices-$CA/$LOCALE/words/job.$CA"
},
{
"description": "jockey",
"image": "words/jockey.png",
"voice": "voices-$CA/$LOCALE/words/jockey.$CA"
},
{
"description": "judge",
"image": "words/judge.png",
"voice": "voices-$CA/$LOCALE/words/judge.$CA"
},
{
"description": "juggler",
"image": "words/juggler.png",
"voice": "voices-$CA/$LOCALE/words/juggler.$CA"
},
- {
- "description": "king",
- "image": "words/king.png",
- "voice": "voices-$CA/$LOCALE/words/king.$CA"
- },
- {
- "description": "knight",
- "image": "words/knight.png",
- "voice": "voices-$CA/$LOCALE/words/knight.$CA"
- },
- {
- "description": "lad",
- "image": "words/lad.png",
- "voice": "voices-$CA/$LOCALE/words/lad.$CA"
- },
{
"description": "lawyer",
"image": "words/lawyer.png",
"voice": "voices-$CA/$LOCALE/words/lawyer.$CA"
},
{
"description": "librarian",
"image": "words/librarian.png",
"voice": "voices-$CA/$LOCALE/words/librarian.$CA"
},
{
"description": "mechanic",
"image": "words/mechanic.png",
"voice": "voices-$CA/$LOCALE/words/mechanic.$CA"
},
{
"description": "musician",
"image": "words/musician.png",
"voice": "voices-$CA/$LOCALE/words/musician.$CA"
},
{
"description": "nun",
"image": "words/nun.png",
"voice": "voices-$CA/$LOCALE/words/nun.$CA"
},
{
"description": "nurse",
"image": "words/nurse.png",
"voice": "voices-$CA/$LOCALE/words/nurse.$CA"
},
{
"description": "nurse male",
"image": "words/nurse_male.png",
"voice": "voices-$CA/$LOCALE/words/nurse_male.$CA"
},
{
"description": "pilot",
"image": "words/pilot.png",
"voice": "voices-$CA/$LOCALE/words/pilot.$CA"
},
- {
- "description": "pirate",
- "image": "words/pirate.png",
- "voice": "voices-$CA/$LOCALE/words/pirate.$CA"
- },
{
"description": "plumber",
"image": "words/plumber.png",
"voice": "voices-$CA/$LOCALE/words/plumber.$CA"
},
{
"description": "police",
"image": "words/police.png",
"voice": "voices-$CA/$LOCALE/words/police.$CA"
},
- {
- "description": "pope",
- "image": "words/pope.png",
- "voice": "voices-$CA/$LOCALE/words/pope.$CA"
- },
- {
- "description": "president",
- "image": "words/president.png",
- "voice": "voices-$CA/$LOCALE/words/president.$CA"
- },
{
"description": "priest",
"image": "words/priest.png",
"voice": "voices-$CA/$LOCALE/words/priest.$CA"
},
- {
- "description": "prince",
- "image": "words/prince.png",
- "voice": "voices-$CA/$LOCALE/words/prince.$CA"
- },
- {
- "description": "princess",
- "image": "words/princess.png",
- "voice": "voices-$CA/$LOCALE/words/princess.$CA"
- },
- {
- "description": "prisoner",
- "image": "words/prisoner.png",
- "voice": "voices-$CA/$LOCALE/words/prisoner.$CA"
- },
- {
- "description": "queen",
- "image": "words/queen.png",
- "voice": "voices-$CA/$LOCALE/words/queen.$CA"
- },
{
"description": "sailor",
"image": "words/sailor.png",
"voice": "voices-$CA/$LOCALE/words/sailor.$CA"
},
{
"description": "soldier",
"image": "words/soldier.png",
"voice": "voices-$CA/$LOCALE/words/soldier.$CA"
},
- {
- "description": "female soldier",
- "image": "words/soldier_female.png",
- "voice": "voices-$CA/$LOCALE/words/soldier_female.$CA"
- },
- {
- "description": "student",
- "image": "words/student.png",
- "voice": "voices-$CA/$LOCALE/words/student.$CA"
- },
{
"description": "teacher",
"image": "words/teacher.png",
"voice": "voices-$CA/$LOCALE/words/teacher.$CA"
},
- {
- "description": "thief",
- "image": "words/thief.png",
- "voice": "voices-$CA/$LOCALE/words/thief.$CA"
- },
{
"description": "vet",
"image": "words/vet.png",
"voice": "voices-$CA/$LOCALE/words/vet.$CA"
},
{
"description": "worker",
"image": "words/worker.png",
"voice": "voices-$CA/$LOCALE/words/worker.$CA"
}
]
},
{
"type": "lesson",
"name": "people",
"content": [
- {
- "description": "angel",
- "image": "words/angel.png",
- "voice": "voices-$CA/$LOCALE/words/angel.$CA"
- },
- {
- "description": "fairy",
- "image": "words/fairy.png",
- "voice": "voices-$CA/$LOCALE/words/fairy.$CA"
- },
{
"description": "wedding",
"image": "words/wedding.png",
"voice": "voices-$CA/$LOCALE/words/wedding.$CA"
},
{
"description": "boy",
"image": "words/boy.png",
"voice": "voices-$CA/$LOCALE/words/boy.$CA"
},
{
"description": "bride",
"image": "words/bride.png",
"voice": "voices-$CA/$LOCALE/words/bride.$CA"
},
{
"description": "brother",
"image": "words/brother.png",
"voice": "voices-$CA/$LOCALE/words/brother.$CA"
},
{
"description": "child",
"image": "words/child.png",
"voice": "voices-$CA/$LOCALE/words/child.$CA"
},
{
"description": "couple",
"image": "words/couple.png",
"voice": "voices-$CA/$LOCALE/words/couple.$CA"
},
{
"description": "dad",
"image": "words/dad.png",
"voice": "voices-$CA/$LOCALE/words/dad.$CA"
},
{
"description": "dwarf",
"image": "words/dwarf.png",
"voice": "voices-$CA/$LOCALE/words/dwarf.$CA"
},
{
"description": "family",
"image": "words/family.png",
"voice": "voices-$CA/$LOCALE/words/family.$CA"
},
{
"description": "friend",
"image": "words/friend.png",
"voice": "voices-$CA/$LOCALE/words/friend.$CA"
},
{
"description": "girl",
"image": "words/girl.png",
"voice": "voices-$CA/$LOCALE/words/girl.$CA"
},
- {
- "description": "gnome",
- "image": "words/gnome.png",
- "voice": "voices-$CA/$LOCALE/words/gnome.$CA"
- },
{
"description": "grandmother",
"image": "words/grandmother.png",
"voice": "voices-$CA/$LOCALE/words/grandmother.$CA"
},
{
"description": "husband",
"image": "words/husband.png",
"voice": "voices-$CA/$LOCALE/words/husband.$CA"
},
{
"description": "lady",
"image": "words/lady.png",
"voice": "voices-$CA/$LOCALE/words/lady.$CA"
},
{
"description": "man",
"image": "words/man.png",
"voice": "voices-$CA/$LOCALE/words/man.$CA"
},
{
"description": "mate",
"image": "words/mate.png",
"voice": "voices-$CA/$LOCALE/words/mate.$CA"
},
- {
- "description": "mate female",
- "image": "words/mate_female.png",
- "voice": "voices-$CA/$LOCALE/words/mate_female.$CA"
- },
- {
- "description": "mate male",
- "image": "words/mate_male.png",
- "voice": "voices-$CA/$LOCALE/words/mate_male.$CA"
- },
- {
- "description": "men",
- "image": "words/men.png",
- "voice": "voices-$CA/$LOCALE/words/men.$CA"
- },
{
"description": "mom",
"image": "words/mom.png",
"voice": "voices-$CA/$LOCALE/words/mom.$CA"
},
{
"description": "mother",
"image": "words/mother.png",
"voice": "voices-$CA/$LOCALE/words/mother.$CA"
},
{
"description": "pal",
"image": "words/pal.png",
"voice": "voices-$CA/$LOCALE/words/pal.$CA"
},
{
"description": "people",
"image": "words/people.png",
"voice": "voices-$CA/$LOCALE/words/people.$CA"
},
{
"description": "sister",
"image": "words/sister.png",
"voice": "voices-$CA/$LOCALE/words/sister.$CA"
},
{
"description": "son",
"image": "words/son.png",
"voice": "voices-$CA/$LOCALE/words/son.$CA"
},
{
"description": "tribe",
"image": "words/tribe.png",
"voice": "voices-$CA/$LOCALE/words/tribe.$CA"
},
{
"description": "twin boys",
"image": "words/twin_boys.png",
"voice": "voices-$CA/$LOCALE/words/twin_boys.$CA"
},
{
"description": "twin girls",
"image": "words/twin_girls.png",
"voice": "voices-$CA/$LOCALE/words/twin_girls.$CA"
},
{
"description": "wife",
"image": "words/wife.png",
"voice": "voices-$CA/$LOCALE/words/wife.$CA"
},
{
"description": "woman",
"image": "words/woman.png",
"voice": "voices-$CA/$LOCALE/words/woman.$CA"
}
]
},
{
"type": "lesson",
"name": "sport",
"content": [
{
"description": "athlete",
"image": "words/athlete.png",
"voice": "voices-$CA/$LOCALE/words/athlete.$CA"
},
{
"description": "ballet",
"image": "words/ballet.png",
"voice": "voices-$CA/$LOCALE/words/ballet.$CA"
},
- {
- "description": "camp",
- "image": "words/camp.png",
- "voice": "voices-$CA/$LOCALE/words/camp.$CA"
- },
{
"description": "cheer",
"image": "words/cheer.png",
"voice": "voices-$CA/$LOCALE/words/cheer.$CA"
},
{
"description": "climb",
"image": "words/climb.png",
"voice": "voices-$CA/$LOCALE/words/climb.$CA"
},
{
"description": "dance",
"image": "words/dance.png",
"voice": "voices-$CA/$LOCALE/words/dance.$CA"
},
{
"description": "dive",
"image": "words/dive.png",
"voice": "voices-$CA/$LOCALE/words/dive.$CA"
},
{
"description": "explore",
"image": "words/explore.png",
"voice": "voices-$CA/$LOCALE/words/explore.$CA"
},
{
"description": "golf",
"image": "words/golf.png",
"voice": "voices-$CA/$LOCALE/words/golf.$CA"
},
{
"description": "hike",
"image": "words/hike.png",
"voice": "voices-$CA/$LOCALE/words/hike.$CA"
},
{
"description": "hit",
"image": "words/hit.png",
"voice": "voices-$CA/$LOCALE/words/hit.$CA"
},
{
"description": "hockey",
"image": "words/hockey.png",
"voice": "voices-$CA/$LOCALE/words/hockey.$CA"
},
{
"description": "hop",
"image": "words/hop.png",
"voice": "voices-$CA/$LOCALE/words/hop.$CA"
},
{
"description": "jog",
"image": "words/jog.png",
"voice": "voices-$CA/$LOCALE/words/jog.$CA"
},
{
"description": "judo",
"image": "words/judo.png",
"voice": "voices-$CA/$LOCALE/words/judo.$CA"
},
{
"description": "lift",
"image": "words/lift.png",
"voice": "voices-$CA/$LOCALE/words/lift.$CA"
},
{
"description": "race",
"image": "words/race.png",
"voice": "voices-$CA/$LOCALE/words/race.$CA"
},
{
"description": "ran",
"image": "words/ran.png",
"voice": "voices-$CA/$LOCALE/words/ran.$CA"
},
{
"description": "ride",
"image": "words/ride.png",
"voice": "voices-$CA/$LOCALE/words/ride.$CA"
},
{
"description": "rowing",
"image": "words/rowing.png",
"voice": "voices-$CA/$LOCALE/words/rowing.$CA"
},
{
"description": "skate",
"image": "words/skate.png",
"voice": "voices-$CA/$LOCALE/words/skate.$CA"
},
{
"description": "ski",
"image": "words/ski.png",
"voice": "voices-$CA/$LOCALE/words/ski.$CA"
},
{
"description": "sport",
"image": "words/sport.png",
"voice": "voices-$CA/$LOCALE/words/sport.$CA"
},
{
"description": "swim",
"image": "words/swim.png",
"voice": "voices-$CA/$LOCALE/words/swim.$CA"
},
{
"description": "tennis",
"image": "words/tennis.png",
"voice": "voices-$CA/$LOCALE/words/tennis.$CA"
},
{
"description": "throw",
"image": "words/throw.png",
"voice": "voices-$CA/$LOCALE/words/throw.$CA"
}
]
},
{
"type": "lesson",
"name": "food",
"content": [
- {
- "description": "beef",
- "image": "words/beef.png",
- "voice": "voices-$CA/$LOCALE/words/beef.$CA"
- },
- {
- "description": "bone",
- "image": "words/bone.png",
- "voice": "voices-$CA/$LOCALE/words/bone.$CA"
- },
{
"description": "bread",
"image": "words/bread.png",
"voice": "voices-$CA/$LOCALE/words/bread.$CA"
},
{
"description": "bun",
"image": "words/bun.png",
"voice": "voices-$CA/$LOCALE/words/bun.$CA"
},
{
"description": "butter",
"image": "words/butter.png",
"voice": "voices-$CA/$LOCALE/words/butter.$CA"
},
{
"description": "cake",
"image": "words/cake.png",
"voice": "voices-$CA/$LOCALE/words/cake.$CA"
},
{
"description": "candy",
"image": "words/candy.png",
"voice": "voices-$CA/$LOCALE/words/candy.$CA"
},
{
"description": "cereal",
"image": "words/cereal.png",
"voice": "voices-$CA/$LOCALE/words/cereal.$CA"
},
{
"description": "cheese",
"image": "words/cheese.png",
"voice": "voices-$CA/$LOCALE/words/cheese.$CA"
},
{
"description": "chocolate",
"image": "words/chocolate.png",
"voice": "voices-$CA/$LOCALE/words/chocolate.$CA"
},
{
"description": "coffee",
"image": "words/coffee.png",
"voice": "voices-$CA/$LOCALE/words/coffee.$CA"
},
{
"description": "cookie",
"image": "words/cookie.png",
"voice": "voices-$CA/$LOCALE/words/cookie.$CA"
},
{
"description": "crepe",
"image": "words/crepe.png",
"voice": "voices-$CA/$LOCALE/words/crepe.$CA"
},
{
"description": "crumb",
"image": "words/crumb.png",
"voice": "voices-$CA/$LOCALE/words/crumb.$CA"
},
{
"description": "crust",
"image": "words/crust.png",
"voice": "voices-$CA/$LOCALE/words/crust.$CA"
},
{
"description": "dessert",
"image": "words/dessert.png",
"voice": "voices-$CA/$LOCALE/words/dessert.$CA"
},
{
"description": "doughnut",
"image": "words/doughnut.png",
"voice": "voices-$CA/$LOCALE/words/doughnut.$CA"
},
{
"description": "drink",
"image": "words/drink.png",
"voice": "voices-$CA/$LOCALE/words/drink.$CA"
},
{
"description": "egg",
"image": "words/egg.png",
"voice": "voices-$CA/$LOCALE/words/egg.$CA"
},
{
"description": "feast",
"image": "words/feast.png",
"voice": "voices-$CA/$LOCALE/words/feast.$CA"
},
{
"description": "flour",
"image": "words/flour.png",
"voice": "voices-$CA/$LOCALE/words/flour.$CA"
},
- {
- "description": "food",
- "image": "words/food.png",
- "voice": "voices-$CA/$LOCALE/words/food.$CA"
- },
{
"description": "fries",
"image": "words/fries.png",
"voice": "voices-$CA/$LOCALE/words/fries.$CA"
},
{
"description": "fudge",
"image": "words/fudge.png",
"voice": "voices-$CA/$LOCALE/words/fudge.$CA"
},
{
"description": "gum",
"image": "words/gum.png",
"voice": "voices-$CA/$LOCALE/words/gum.$CA"
},
{
"description": "ham",
"image": "words/ham.png",
"voice": "voices-$CA/$LOCALE/words/ham.$CA"
},
+ {
+ "description": "hamburger",
+ "image": "words/hamburger.png",
+ "voice": "voices-$CA/$LOCALE/words/hamburger.$CA"
+ },
{
"description": "hot dog",
"image": "words/hot_dog.png",
"voice": "voices-$CA/$LOCALE/words/hot_dog.$CA"
},
{
"description": "ice",
"image": "words/ice.png",
"voice": "voices-$CA/$LOCALE/words/ice.$CA"
},
{
"description": "jam",
"image": "words/jam.png",
"voice": "voices-$CA/$LOCALE/words/jam.$CA"
},
{
"description": "jelly",
"image": "words/jelly.png",
"voice": "voices-$CA/$LOCALE/words/jelly.$CA"
},
{
"description": "juice",
"image": "words/juice.png",
"voice": "voices-$CA/$LOCALE/words/juice.$CA"
},
{
"description": "lemonade",
"image": "words/lemonade.png",
"voice": "voices-$CA/$LOCALE/words/lemonade.$CA"
},
{
"description": "lunch",
"image": "words/lunch.png",
"voice": "voices-$CA/$LOCALE/words/lunch.$CA"
},
{
"description": "mashed potatoes",
"image": "words/mashed_potatoes.png",
"voice": "voices-$CA/$LOCALE/words/mashed_potatoes.$CA"
},
{
"description": "meal",
"image": "words/meal.png",
"voice": "voices-$CA/$LOCALE/words/meal.$CA"
},
{
"description": "meat",
"image": "words/meat.png",
"voice": "voices-$CA/$LOCALE/words/meat.$CA"
},
{
"description": "milk",
"image": "words/milk.png",
"voice": "voices-$CA/$LOCALE/words/milk.$CA"
},
{
"description": "pepper",
"image": "words/pepper.png",
"voice": "voices-$CA/$LOCALE/words/pepper.$CA"
},
{
"description": "pie",
"image": "words/pie.png",
"voice": "voices-$CA/$LOCALE/words/pie.$CA"
},
{
"description": "pizza",
"image": "words/pizza.png",
"voice": "voices-$CA/$LOCALE/words/pizza.$CA"
},
{
- "description": "pop",
- "image": "words/pop.png",
- "voice": "voices-$CA/$LOCALE/words/pop.$CA"
+ "description": "popcorn",
+ "image": "words/popcorn.png",
+ "voice": "voices-$CA/$LOCALE/words/popcorn.$CA"
},
{
"description": "rice",
"image": "words/rice.png",
"voice": "voices-$CA/$LOCALE/words/rice.$CA"
},
{
"description": "roast",
"image": "words/roast.png",
"voice": "voices-$CA/$LOCALE/words/roast.$CA"
},
{
"description": "sandwich",
"image": "words/sandwich.png",
"voice": "voices-$CA/$LOCALE/words/sandwich.$CA"
},
{
"description": "sauce",
"image": "words/sauce.png",
"voice": "voices-$CA/$LOCALE/words/sauce.$CA"
},
{
"description": "sausage",
"image": "words/sausage.png",
"voice": "voices-$CA/$LOCALE/words/sausage.$CA"
},
{
"description": "snack",
"image": "words/snack.png",
"voice": "voices-$CA/$LOCALE/words/snack.$CA"
},
{
"description": "soup",
"image": "words/soup.png",
"voice": "voices-$CA/$LOCALE/words/soup.$CA"
},
{
"description": "spaghetti",
"image": "words/spaghetti.png",
"voice": "voices-$CA/$LOCALE/words/spaghetti.$CA"
},
{
"description": "spice",
"image": "words/spice.png",
"voice": "voices-$CA/$LOCALE/words/spice.$CA"
},
{
"description": "sprinkle",
"image": "words/sprinkle.png",
"voice": "voices-$CA/$LOCALE/words/sprinkle.$CA"
},
- {
- "description": "steak",
- "image": "words/steak.png",
- "voice": "voices-$CA/$LOCALE/words/steak.$CA"
- },
{
"description": "stew",
"image": "words/stew.png",
"voice": "voices-$CA/$LOCALE/words/stew.$CA"
},
{
"description": "sugar",
"image": "words/sugar.png",
"voice": "voices-$CA/$LOCALE/words/sugar.$CA"
},
{
"description": "treat",
"image": "words/treat.png",
"voice": "voices-$CA/$LOCALE/words/treat.$CA"
},
{
"description": "yogurt",
"image": "words/yogurt.png",
"voice": "voices-$CA/$LOCALE/words/yogurt.$CA"
}
]
}
]
},
{
"type": "chapter",
"name": "nature",
"imgPrefix": "qrc:/gcompris/data/",
"content": [
{
"type": "lesson",
"name": "animal",
"content": [
{
"description": "alligator",
"image": "words/alligator.png",
"voice": "voices-$CA/$LOCALE/words/alligator.$CA"
},
{
"description": "animal",
"image": "words/animal.png",
"voice": "voices-$CA/$LOCALE/words/animal.$CA"
},
{
"description": "ant",
"image": "words/ant.png",
"voice": "voices-$CA/$LOCALE/words/ant.$CA"
},
{
"description": "anteater",
"image": "words/anteater.png",
"voice": "voices-$CA/$LOCALE/words/anteater.$CA"
},
{
"description": "antelope",
"image": "words/antelope.png",
"voice": "voices-$CA/$LOCALE/words/antelope.$CA"
},
{
"description": "bait",
"image": "words/bait.png",
"voice": "voices-$CA/$LOCALE/words/bait.$CA"
},
{
"description": "bat",
"image": "words/bat.png",
"voice": "voices-$CA/$LOCALE/words/bat.$CA"
},
{
"description": "bear",
"image": "words/bear.png",
"voice": "voices-$CA/$LOCALE/words/bear.$CA"
},
{
"description": "beaver",
"image": "words/beaver.png",
"voice": "voices-$CA/$LOCALE/words/beaver.$CA"
},
{
"description": "bee",
"image": "words/bee.png",
"voice": "voices-$CA/$LOCALE/words/bee.$CA"
},
{
"description": "beetle",
"image": "words/beetle.png",
"voice": "voices-$CA/$LOCALE/words/beetle.$CA"
},
{
"description": "bird",
"image": "words/bird.png",
"voice": "voices-$CA/$LOCALE/words/bird.$CA"
},
{
"description": "blackbird",
"image": "words/blackbird.png",
"voice": "voices-$CA/$LOCALE/words/blackbird.$CA"
},
{
"description": "buffalo",
"image": "words/buffalo.png",
"voice": "voices-$CA/$LOCALE/words/buffalo.$CA"
},
{
"description": "bug",
"image": "words/bug.png",
"voice": "voices-$CA/$LOCALE/words/bug.$CA"
},
{
"description": "bull",
"image": "words/bull.png",
"voice": "voices-$CA/$LOCALE/words/bull.$CA"
},
{
"description": "butterfly",
"image": "words/butterfly.png",
"voice": "voices-$CA/$LOCALE/words/butterfly.$CA"
},
{
"description": "camel",
"image": "words/camel.png",
"voice": "voices-$CA/$LOCALE/words/camel.$CA"
},
{
"description": "canary",
"image": "words/canary.png",
"voice": "voices-$CA/$LOCALE/words/canary.$CA"
},
{
"description": "cat",
"image": "words/cat.png",
"voice": "voices-$CA/$LOCALE/words/cat.$CA"
},
{
"description": "caterpillar",
"image": "words/caterpillar.png",
"voice": "voices-$CA/$LOCALE/words/caterpillar.$CA"
},
{
"description": "female cat",
"image": "words/cat_female.png",
"voice": "voices-$CA/$LOCALE/words/cat_female.$CA"
},
{
"description": "centipede",
"image": "words/centipede.png",
"voice": "voices-$CA/$LOCALE/words/centipede.$CA"
},
{
"description": "chameleon",
"image": "words/chameleon.png",
"voice": "voices-$CA/$LOCALE/words/chameleon.$CA"
},
{
"description": "chick",
"image": "words/chick.png",
"voice": "voices-$CA/$LOCALE/words/chick.$CA"
},
{
"description": "chicken",
"image": "words/chicken.png",
"voice": "voices-$CA/$LOCALE/words/chicken.$CA"
},
{
"description": "chimp",
"image": "words/chimp.png",
"voice": "voices-$CA/$LOCALE/words/chimp.$CA"
},
{
"description": "clam",
"image": "words/clam.png",
"voice": "voices-$CA/$LOCALE/words/clam.$CA"
},
{
"description": "claw",
"image": "words/claw.png",
"voice": "voices-$CA/$LOCALE/words/claw.$CA"
},
{
"description": "cobra",
"image": "words/cobra.png",
"voice": "voices-$CA/$LOCALE/words/cobra.$CA"
},
{
"description": "cod",
"image": "words/cod.png",
"voice": "voices-$CA/$LOCALE/words/cod.$CA"
},
{
"description": "colt",
"image": "words/colt.png",
"voice": "voices-$CA/$LOCALE/words/colt.$CA"
},
{
"description": "cow",
"image": "words/cow.png",
"voice": "voices-$CA/$LOCALE/words/cow.$CA"
},
{
"description": "crab",
"image": "words/crab.png",
"voice": "voices-$CA/$LOCALE/words/crab.$CA"
},
{
"description": "crocodile",
"image": "words/crocodile.png",
"voice": "voices-$CA/$LOCALE/words/crocodile.$CA"
},
{
"description": "crow",
"image": "words/crow.png",
"voice": "voices-$CA/$LOCALE/words/crow.$CA"
},
{
"description": "deer",
"image": "words/deer.png",
"voice": "voices-$CA/$LOCALE/words/deer.$CA"
},
{
"description": "den",
"image": "words/den.png",
"voice": "voices-$CA/$LOCALE/words/den.$CA"
},
{
"description": "doe",
"image": "words/doe.png",
"voice": "voices-$CA/$LOCALE/words/doe.$CA"
},
{
"description": "dog",
"image": "words/dog.png",
"voice": "voices-$CA/$LOCALE/words/dog.$CA"
},
{
"description": "dolphin",
"image": "words/dolphin.png",
"voice": "voices-$CA/$LOCALE/words/dolphin.$CA"
},
{
"description": "dove",
"image": "words/dove.png",
"voice": "voices-$CA/$LOCALE/words/dove.$CA"
},
{
"description": "dragon",
"image": "words/dragon.png",
"voice": "voices-$CA/$LOCALE/words/dragon.$CA"
},
{
"description": "dragonfly",
"image": "words/dragonfly.png",
"voice": "voices-$CA/$LOCALE/words/dragonfly.$CA"
},
{
"description": "duck",
"image": "words/duck.png",
"voice": "voices-$CA/$LOCALE/words/duck.$CA"
},
{
"description": "duck mother",
"image": "words/duck_mother.png",
"voice": "voices-$CA/$LOCALE/words/duck_mother.$CA"
},
{
"description": "eagle",
"image": "words/eagle.png",
"voice": "voices-$CA/$LOCALE/words/eagle.$CA"
},
{
"description": "elk",
"image": "words/elk.png",
"voice": "voices-$CA/$LOCALE/words/elk.$CA"
},
{
"description": "fawn",
"image": "words/fawn.png",
"voice": "voices-$CA/$LOCALE/words/fawn.$CA"
},
{
"description": "feather",
"image": "words/feather.png",
"voice": "voices-$CA/$LOCALE/words/feather.$CA"
},
{
"description": "fin",
"image": "words/fin.png",
"voice": "voices-$CA/$LOCALE/words/fin.$CA"
},
{
"description": "fish",
"image": "words/fish.png",
"voice": "voices-$CA/$LOCALE/words/fish.$CA"
},
{
"description": "flamingo",
"image": "words/flamingo.png",
"voice": "voices-$CA/$LOCALE/words/flamingo.$CA"
},
{
"description": "flies",
"image": "words/flies.png",
"voice": "voices-$CA/$LOCALE/words/flies.$CA"
},
{
"description": "fox",
"image": "words/fox.png",
"voice": "voices-$CA/$LOCALE/words/fox.$CA"
},
{
"description": "frog",
"image": "words/frog.png",
"voice": "voices-$CA/$LOCALE/words/frog.$CA"
},
{
"description": "fur",
"image": "words/fur.png",
"voice": "voices-$CA/$LOCALE/words/fur.$CA"
},
{
"description": "giraffe",
"image": "words/giraffe.png",
"voice": "voices-$CA/$LOCALE/words/giraffe.$CA"
},
{
"description": "goat",
"image": "words/goat.png",
"voice": "voices-$CA/$LOCALE/words/goat.$CA"
},
{
"description": "goose",
"image": "words/goose.png",
"voice": "voices-$CA/$LOCALE/words/goose.$CA"
},
{
"description": "gorilla",
"image": "words/gorilla.png",
"voice": "voices-$CA/$LOCALE/words/gorilla.$CA"
},
{
"description": "guinea pig",
"image": "words/guinea_pig.png",
"voice": "voices-$CA/$LOCALE/words/guinea_pig.$CA"
},
{
"description": "hedgehog",
"image": "words/hedgehog.png",
"voice": "voices-$CA/$LOCALE/words/hedgehog.$CA"
},
{
"description": "hen",
"image": "words/hen.png",
"voice": "voices-$CA/$LOCALE/words/hen.$CA"
},
{
"description": "herd",
"image": "words/herd.png",
"voice": "voices-$CA/$LOCALE/words/herd.$CA"
},
{
"description": "hippopotamus",
"image": "words/hippopotamus.png",
"voice": "voices-$CA/$LOCALE/words/hippopotamus.$CA"
},
{
"description": "hive",
"image": "words/hive.png",
"voice": "voices-$CA/$LOCALE/words/hive.$CA"
},
{
"description": "horse",
"image": "words/horse.png",
"voice": "voices-$CA/$LOCALE/words/horse.$CA"
},
{
"description": "hound",
"image": "words/hound.png",
"voice": "voices-$CA/$LOCALE/words/hound.$CA"
},
{
"description": "hummingbird",
"image": "words/hummingbird.png",
"voice": "voices-$CA/$LOCALE/words/hummingbird.$CA"
},
{
"description": "hyena",
"image": "words/hyena.png",
"voice": "voices-$CA/$LOCALE/words/hyena.$CA"
},
{
"description": "iguana",
"image": "words/iguana.png",
"voice": "voices-$CA/$LOCALE/words/iguana.$CA"
},
{
"description": "jaguar",
"image": "words/jaguar.png",
"voice": "voices-$CA/$LOCALE/words/jaguar.$CA"
},
{
"description": "jay",
"image": "words/jay.png",
"voice": "voices-$CA/$LOCALE/words/jay.$CA"
},
{
"description": "jellyfish",
"image": "words/jellyfish.png",
"voice": "voices-$CA/$LOCALE/words/jellyfish.$CA"
},
{
"description": "kangaroo",
"image": "words/kangaroo.png",
"voice": "voices-$CA/$LOCALE/words/kangaroo.$CA"
},
{
"description": "kitten",
"image": "words/kitten.png",
"voice": "voices-$CA/$LOCALE/words/kitten.$CA"
},
{
"description": "koala",
"image": "words/koala.png",
"voice": "voices-$CA/$LOCALE/words/koala.$CA"
},
{
"description": "ladybug",
"image": "words/ladybug.png",
"voice": "voices-$CA/$LOCALE/words/ladybug.$CA"
},
{
"description": "lama",
"image": "words/lama.png",
"voice": "voices-$CA/$LOCALE/words/lama.$CA"
},
{
"description": "lamb",
"image": "words/lamb.png",
"voice": "voices-$CA/$LOCALE/words/lamb.$CA"
},
- {
- "description": "leg animal",
- "image": "words/leg_animal.png",
- "voice": "voices-$CA/$LOCALE/words/leg_animal.$CA"
- },
{
"description": "lemur",
"image": "words/lemur.png",
"voice": "voices-$CA/$LOCALE/words/lemur.$CA"
},
{
"description": "leopard",
"image": "words/leopard.png",
"voice": "voices-$CA/$LOCALE/words/leopard.$CA"
},
{
"description": "lion",
"image": "words/lion.png",
"voice": "voices-$CA/$LOCALE/words/lion.$CA"
},
{
"description": "lion cub",
"image": "words/lion_cub.png",
"voice": "voices-$CA/$LOCALE/words/lion_cub.$CA"
},
{
"description": "lizard",
"image": "words/lizard.png",
"voice": "voices-$CA/$LOCALE/words/lizard.$CA"
},
{
"description": "lobster",
"image": "words/lobster.png",
"voice": "voices-$CA/$LOCALE/words/lobster.$CA"
},
{
"description": "magpie",
"image": "words/magpie.png",
"voice": "voices-$CA/$LOCALE/words/magpie.$CA"
},
{
"description": "mane",
"image": "words/mane.png",
"voice": "voices-$CA/$LOCALE/words/mane.$CA"
},
{
"description": "mice",
"image": "words/mice.png",
"voice": "voices-$CA/$LOCALE/words/mice.$CA"
},
{
"description": "mole",
"image": "words/mole.png",
"voice": "voices-$CA/$LOCALE/words/mole.$CA"
},
{
"description": "moose",
"image": "words/moose.png",
"voice": "voices-$CA/$LOCALE/words/moose.$CA"
},
{
"description": "mosquito",
"image": "words/mosquito.png",
"voice": "voices-$CA/$LOCALE/words/mosquito.$CA"
},
{
"description": "mouse",
"image": "words/mouse.png",
"voice": "voices-$CA/$LOCALE/words/mouse.$CA"
},
{
"description": "mule",
"image": "words/mule.png",
"voice": "voices-$CA/$LOCALE/words/mule.$CA"
},
{
"description": "opossum",
"image": "words/opossum.png",
"voice": "voices-$CA/$LOCALE/words/opossum.$CA"
},
{
"description": "ostrich",
"image": "words/ostrich.png",
"voice": "voices-$CA/$LOCALE/words/ostrich.$CA"
},
{
"description": "otter",
"image": "words/otter.png",
"voice": "voices-$CA/$LOCALE/words/otter.$CA"
},
{
"description": "owl",
"image": "words/owl.png",
"voice": "voices-$CA/$LOCALE/words/owl.$CA"
},
{
"description": "ox",
"image": "words/ox.png",
"voice": "voices-$CA/$LOCALE/words/ox.$CA"
},
{
"description": "oyster",
"image": "words/oyster.png",
"voice": "voices-$CA/$LOCALE/words/oyster.$CA"
},
{
"description": "panda",
"image": "words/panda.png",
"voice": "voices-$CA/$LOCALE/words/panda.$CA"
},
{
"description": "panther",
"image": "words/panther.png",
"voice": "voices-$CA/$LOCALE/words/panther.$CA"
},
{
"description": "parakeet",
"image": "words/parakeet.png",
"voice": "voices-$CA/$LOCALE/words/parakeet.$CA"
},
{
"description": "parrot",
"image": "words/parrot.png",
"voice": "voices-$CA/$LOCALE/words/parrot.$CA"
},
{
"description": "paw",
"image": "words/paw.png",
"voice": "voices-$CA/$LOCALE/words/paw.$CA"
},
{
"description": "peacock",
"image": "words/peacock.png",
"voice": "voices-$CA/$LOCALE/words/peacock.$CA"
},
{
"description": "pelican",
"image": "words/pelican.png",
"voice": "voices-$CA/$LOCALE/words/pelican.$CA"
},
{
"description": "pet",
"image": "words/pet.png",
"voice": "voices-$CA/$LOCALE/words/pet.$CA"
},
{
"description": "pig",
"image": "words/pig.png",
"voice": "voices-$CA/$LOCALE/words/pig.$CA"
},
{
"description": "pigeon",
"image": "words/pigeon.png",
"voice": "voices-$CA/$LOCALE/words/pigeon.$CA"
},
{
"description": "piranha",
"image": "words/piranha.png",
"voice": "voices-$CA/$LOCALE/words/piranha.$CA"
},
{
"description": "pony",
"image": "words/pony.png",
"voice": "voices-$CA/$LOCALE/words/pony.$CA"
},
{
"description": "pug",
"image": "words/pug.png",
"voice": "voices-$CA/$LOCALE/words/pug.$CA"
},
{
"description": "puppy",
"image": "words/puppy.png",
"voice": "voices-$CA/$LOCALE/words/puppy.$CA"
},
{
"description": "rabbit",
"image": "words/rabbit.png",
"voice": "voices-$CA/$LOCALE/words/rabbit.$CA"
},
{
"description": "baby rabbit",
"image": "words/rabbit_baby.png",
"voice": "voices-$CA/$LOCALE/words/rabbit_baby.$CA"
},
{
"description": "rat",
"image": "words/rat.png",
"voice": "voices-$CA/$LOCALE/words/rat.$CA"
},
{
"description": "reptile",
"image": "words/reptile.png",
"voice": "voices-$CA/$LOCALE/words/reptile.$CA"
},
{
"description": "rhinoceros",
"image": "words/rhinoceros.png",
"voice": "voices-$CA/$LOCALE/words/rhinoceros.$CA"
},
{
"description": "salamander",
"image": "words/salamander.png",
"voice": "voices-$CA/$LOCALE/words/salamander.$CA"
},
{
"description": "salmon",
"image": "words/salmon.png",
"voice": "voices-$CA/$LOCALE/words/salmon.$CA"
},
{
"description": "scorpion",
"image": "words/scorpion.png",
"voice": "voices-$CA/$LOCALE/words/scorpion.$CA"
},
{
"description": "shark",
"image": "words/shark.png",
"voice": "voices-$CA/$LOCALE/words/shark.$CA"
},
{
"description": "sheep",
"image": "words/sheep.png",
"voice": "voices-$CA/$LOCALE/words/sheep.$CA"
},
{
"description": "shell",
"image": "words/shell.png",
"voice": "voices-$CA/$LOCALE/words/shell.$CA"
},
{
"description": "shrimp",
"image": "words/shrimp.png",
"voice": "voices-$CA/$LOCALE/words/shrimp.$CA"
},
{
"description": "skunk",
"image": "words/skunk.png",
"voice": "voices-$CA/$LOCALE/words/skunk.$CA"
},
{
"description": "slime",
"image": "words/slime.png",
"voice": "voices-$CA/$LOCALE/words/slime.$CA"
},
{
"description": "sloth",
"image": "words/sloth.png",
"voice": "voices-$CA/$LOCALE/words/sloth.$CA"
},
{
"description": "slug",
"image": "words/slug.png",
"voice": "voices-$CA/$LOCALE/words/slug.$CA"
},
{
"description": "snail",
"image": "words/snail.png",
"voice": "voices-$CA/$LOCALE/words/snail.$CA"
},
{
"description": "snake",
"image": "words/snake.png",
"voice": "voices-$CA/$LOCALE/words/snake.$CA"
},
{
"description": "sole",
"image": "words/sole.png",
"voice": "voices-$CA/$LOCALE/words/sole.$CA"
},
{
"description": "sparrow",
"image": "words/sparrow.png",
"voice": "voices-$CA/$LOCALE/words/sparrow.$CA"
},
{
"description": "spider",
"image": "words/spider.png",
"voice": "voices-$CA/$LOCALE/words/spider.$CA"
},
{
"description": "spike",
"image": "words/spike.png",
"voice": "voices-$CA/$LOCALE/words/spike.$CA"
},
{
"description": "squid",
"image": "words/squid.png",
"voice": "voices-$CA/$LOCALE/words/squid.$CA"
},
{
"description": "squirrel",
"image": "words/squirrel.png",
"voice": "voices-$CA/$LOCALE/words/squirrel.$CA"
},
{
"description": "starfish",
"image": "words/starfish.png",
"voice": "voices-$CA/$LOCALE/words/starfish.$CA"
},
{
"description": "swan",
"image": "words/swan.png",
"voice": "voices-$CA/$LOCALE/words/swan.$CA"
},
{
"description": "tadpole",
"image": "words/tadpole.png",
"voice": "voices-$CA/$LOCALE/words/tadpole.$CA"
},
{
"description": "tail",
"image": "words/tail.png",
"voice": "voices-$CA/$LOCALE/words/tail.$CA"
},
{
"description": "tick",
"image": "words/tick.png",
"voice": "voices-$CA/$LOCALE/words/tick.$CA"
},
{
"description": "tiger",
"image": "words/tiger.png",
"voice": "voices-$CA/$LOCALE/words/tiger.$CA"
},
{
"description": "toad",
"image": "words/toad.png",
"voice": "voices-$CA/$LOCALE/words/toad.$CA"
},
{
"description": "turkey",
"image": "words/turkey.png",
"voice": "voices-$CA/$LOCALE/words/turkey.$CA"
},
{
"description": "turtle",
"image": "words/turtle.png",
"voice": "voices-$CA/$LOCALE/words/turtle.$CA"
},
{
"description": "tusk",
"image": "words/tusk.png",
"voice": "voices-$CA/$LOCALE/words/tusk.$CA"
},
{
"description": "viper",
"image": "words/viper.png",
"voice": "voices-$CA/$LOCALE/words/viper.$CA"
},
{
"description": "vulture",
"image": "words/vulture.png",
"voice": "voices-$CA/$LOCALE/words/vulture.$CA"
},
{
"description": "wasp",
"image": "words/wasp.png",
"voice": "voices-$CA/$LOCALE/words/wasp.$CA"
},
{
"description": "whale",
"image": "words/whale.png",
"voice": "voices-$CA/$LOCALE/words/whale.$CA"
},
{
"description": "wing",
"image": "words/wing.png",
"voice": "voices-$CA/$LOCALE/words/wing.$CA"
},
{
"description": "wolf",
"image": "words/wolf.png",
"voice": "voices-$CA/$LOCALE/words/wolf.$CA"
},
{
"description": "zebra",
"image": "words/zebra.png",
"voice": "voices-$CA/$LOCALE/words/zebra.$CA"
}
]
},
{
"type": "lesson",
"name": "fruit",
"content": [
{
"description": "apple",
"image": "words/apple.png",
"voice": "voices-$CA/$LOCALE/words/apple.$CA"
},
{
"description": "apricot",
"image": "words/apricot.png",
"voice": "voices-$CA/$LOCALE/words/apricot.$CA"
},
{
"description": "blackberry",
"image": "words/blackberry.png",
"voice": "voices-$CA/$LOCALE/words/blackberry.$CA"
},
{
"description": "blueberry",
"image": "words/blueberry.png",
"voice": "voices-$CA/$LOCALE/words/blueberry.$CA"
},
{
"description": "cacao",
"image": "words/cacao.png",
"voice": "voices-$CA/$LOCALE/words/cacao.$CA"
},
{
"description": "cherry",
"image": "words/cherry.png",
"voice": "voices-$CA/$LOCALE/words/cherry.$CA"
},
{
"description": "coconut",
"image": "words/coconut.png",
"voice": "voices-$CA/$LOCALE/words/coconut.$CA"
},
{
"description": "date fruit",
"image": "words/date_fruit.png",
"voice": "voices-$CA/$LOCALE/words/date_fruit.$CA"
},
{
"description": "fig",
"image": "words/fig.png",
"voice": "voices-$CA/$LOCALE/words/fig.$CA"
},
{
"description": "fruit",
"image": "words/fruit.png",
"voice": "voices-$CA/$LOCALE/words/fruit.$CA"
},
{
"description": "grape",
"image": "words/grape.png",
"voice": "voices-$CA/$LOCALE/words/grape.$CA"
},
{
"description": "grapefruit",
"image": "words/grapefruit.png",
"voice": "voices-$CA/$LOCALE/words/grapefruit.$CA"
},
{
"description": "kernel",
"image": "words/kernel.png",
"voice": "voices-$CA/$LOCALE/words/kernel.$CA"
},
{
"description": "kiwi",
"image": "words/kiwi.png",
"voice": "voices-$CA/$LOCALE/words/kiwi.$CA"
},
{
"description": "lemon",
"image": "words/lemon.png",
"voice": "voices-$CA/$LOCALE/words/lemon.$CA"
},
{
"description": "lime",
"image": "words/lime.png",
"voice": "voices-$CA/$LOCALE/words/lime.$CA"
},
{
"description": "mango",
"image": "words/mango.png",
"voice": "voices-$CA/$LOCALE/words/mango.$CA"
},
{
"description": "melon",
"image": "words/melon.png",
"voice": "voices-$CA/$LOCALE/words/melon.$CA"
},
{
"description": "orange",
"image": "words/orange.png",
"voice": "voices-$CA/$LOCALE/words/orange.$CA"
},
{
"description": "papaya",
"image": "words/papaya.png",
"voice": "voices-$CA/$LOCALE/words/papaya.$CA"
},
{
"description": "peach",
"image": "words/peach.png",
"voice": "voices-$CA/$LOCALE/words/peach.$CA"
},
{
"description": "pear",
"image": "words/pear.png",
"voice": "voices-$CA/$LOCALE/words/pear.$CA"
},
{
"description": "plum",
"image": "words/plum.png",
"voice": "voices-$CA/$LOCALE/words/plum.$CA"
},
{
"description": "raspberry",
"image": "words/raspberry.png",
"voice": "voices-$CA/$LOCALE/words/raspberry.$CA"
},
{
"description": "strawberry",
"image": "words/strawberry.png",
"voice": "voices-$CA/$LOCALE/words/strawberry.$CA"
}
]
},
{
"type": "lesson",
"name": "nature",
"content": [
{
"description": "bay",
"image": "words/bay.png",
"voice": "voices-$CA/$LOCALE/words/bay.$CA"
},
{
"description": "beach",
"image": "words/beach.png",
"voice": "voices-$CA/$LOCALE/words/beach.$CA"
},
{
"description": "canyon",
"image": "words/canyon.png",
"voice": "voices-$CA/$LOCALE/words/canyon.$CA"
},
{
"description": "cave",
"image": "words/cave.png",
"voice": "voices-$CA/$LOCALE/words/cave.$CA"
},
{
"description": "cavern",
"image": "words/cavern.png",
"voice": "voices-$CA/$LOCALE/words/cavern.$CA"
},
{
"description": "cliff",
"image": "words/cliff.png",
"voice": "voices-$CA/$LOCALE/words/cliff.$CA"
},
{
"description": "cloud",
"image": "words/cloud.png",
"voice": "voices-$CA/$LOCALE/words/cloud.$CA"
},
{
"description": "cloudy",
"image": "words/cloudy.png",
"voice": "voices-$CA/$LOCALE/words/cloudy.$CA"
},
{
"description": "coast",
"image": "words/coast.png",
"voice": "voices-$CA/$LOCALE/words/coast.$CA"
},
{
"description": "cold",
"image": "words/cold.png",
"voice": "voices-$CA/$LOCALE/words/cold.$CA"
},
{
"description": "creek",
"image": "words/creek.png",
"voice": "voices-$CA/$LOCALE/words/creek.$CA"
},
{
"description": "crystal",
"image": "words/crystal.png",
"voice": "voices-$CA/$LOCALE/words/crystal.$CA"
},
{
"description": "desert",
"image": "words/desert.png",
"voice": "voices-$CA/$LOCALE/words/desert.$CA"
},
{
"description": "diamond",
"image": "words/diamond.png",
"voice": "voices-$CA/$LOCALE/words/diamond.$CA"
},
{
"description": "dirt",
"image": "words/dirt.png",
"voice": "voices-$CA/$LOCALE/words/dirt.$CA"
},
{
"description": "drip",
"image": "words/drip.png",
"voice": "voices-$CA/$LOCALE/words/drip.$CA"
},
{
"description": "dune",
"image": "words/dune.png",
"voice": "voices-$CA/$LOCALE/words/dune.$CA"
},
{
"description": "earth",
"image": "words/earth.png",
"voice": "voices-$CA/$LOCALE/words/earth.$CA"
},
{
"description": "fall season",
"image": "words/fall_season.png",
"voice": "voices-$CA/$LOCALE/words/fall_season.$CA"
},
{
"description": "fire",
"image": "words/fire.png",
"voice": "voices-$CA/$LOCALE/words/fire.$CA"
},
{
"description": "flame",
"image": "words/flame.png",
"voice": "voices-$CA/$LOCALE/words/flame.$CA"
},
{
"description": "forest",
"image": "words/forest.png",
"voice": "voices-$CA/$LOCALE/words/forest.$CA"
},
{
"description": "garden",
"image": "words/garden.png",
"voice": "voices-$CA/$LOCALE/words/garden.$CA"
},
{
"description": "gem",
"image": "words/gem.png",
"voice": "voices-$CA/$LOCALE/words/gem.$CA"
},
{
"description": "ground",
"image": "words/ground.png",
"voice": "voices-$CA/$LOCALE/words/ground.$CA"
},
{
"description": "heat",
"image": "words/heat.png",
"voice": "voices-$CA/$LOCALE/words/heat.$CA"
},
{
"description": "hill",
"image": "words/hill.png",
"voice": "voices-$CA/$LOCALE/words/hill.$CA"
},
{
"description": "hole",
"image": "words/hole.png",
"voice": "voices-$CA/$LOCALE/words/hole.$CA"
},
{
"description": "iceberg",
"image": "words/iceberg.png",
"voice": "voices-$CA/$LOCALE/words/iceberg.$CA"
},
{
"description": "island",
"image": "words/island.png",
"voice": "voices-$CA/$LOCALE/words/island.$CA"
},
{
"description": "lake",
"image": "words/lake.png",
"voice": "voices-$CA/$LOCALE/words/lake.$CA"
},
{
"description": "land",
"image": "words/land.png",
"voice": "voices-$CA/$LOCALE/words/land.$CA"
},
{
"description": "lava",
"image": "words/lava.png",
"voice": "voices-$CA/$LOCALE/words/lava.$CA"
},
{
"description": "ledge",
"image": "words/ledge.png",
"voice": "voices-$CA/$LOCALE/words/ledge.$CA"
},
{
"description": "lightning",
"image": "words/lightning.png",
"voice": "voices-$CA/$LOCALE/words/lightning.$CA"
},
{
"description": "moon",
"image": "words/moon.png",
"voice": "voices-$CA/$LOCALE/words/moon.$CA"
},
{
"description": "mountain",
"image": "words/mountain.png",
"voice": "voices-$CA/$LOCALE/words/mountain.$CA"
},
{
"description": "mud",
"image": "words/mud.png",
"voice": "voices-$CA/$LOCALE/words/mud.$CA"
},
{
"description": "night",
"image": "words/night.png",
"voice": "voices-$CA/$LOCALE/words/night.$CA"
},
{
"description": "ocean",
"image": "words/ocean.png",
"voice": "voices-$CA/$LOCALE/words/ocean.$CA"
},
{
"description": "path",
"image": "words/path.png",
"voice": "voices-$CA/$LOCALE/words/path.$CA"
},
{
"description": "peak",
"image": "words/peak.png",
"voice": "voices-$CA/$LOCALE/words/peak.$CA"
},
{
"description": "planet",
"image": "words/planet.png",
"voice": "voices-$CA/$LOCALE/words/planet.$CA"
},
{
"description": "pond",
"image": "words/pond.png",
"voice": "voices-$CA/$LOCALE/words/pond.$CA"
},
{
"description": "rain",
"image": "words/rain.png",
"voice": "voices-$CA/$LOCALE/words/rain.$CA"
},
{
"description": "river",
"image": "words/river.png",
"voice": "voices-$CA/$LOCALE/words/river.$CA"
},
{
"description": "rock",
"image": "words/rock.png",
"voice": "voices-$CA/$LOCALE/words/rock.$CA"
},
{
"description": "sand",
"image": "words/sand.png",
"voice": "voices-$CA/$LOCALE/words/sand.$CA"
},
{
"description": "sea",
"image": "words/sea.png",
"voice": "voices-$CA/$LOCALE/words/sea.$CA"
},
{
"description": "shadow",
"image": "words/shadow.png",
"voice": "voices-$CA/$LOCALE/words/shadow.$CA"
},
{
"description": "shore",
"image": "words/shore.png",
"voice": "voices-$CA/$LOCALE/words/shore.$CA"
},
{
"description": "sky",
"image": "words/sky.png",
"voice": "voices-$CA/$LOCALE/words/sky.$CA"
},
{
"description": "slope",
"image": "words/slope.png",
"voice": "voices-$CA/$LOCALE/words/slope.$CA"
},
{
"description": "smoke",
"image": "words/smoke.png",
"voice": "voices-$CA/$LOCALE/words/smoke.$CA"
},
{
"description": "snow",
"image": "words/snow.png",
"voice": "voices-$CA/$LOCALE/words/snow.$CA"
},
{
"description": "spider web",
"image": "words/spider_web.png",
"voice": "voices-$CA/$LOCALE/words/spider_web.$CA"
},
{
"description": "spring season",
"image": "words/spring_season.png",
"voice": "voices-$CA/$LOCALE/words/spring_season.$CA"
},
{
"description": "star",
"image": "words/star.png",
"voice": "voices-$CA/$LOCALE/words/star.$CA"
},
{
"description": "steam",
"image": "words/steam.png",
"voice": "voices-$CA/$LOCALE/words/steam.$CA"
},
{
"description": "stone",
"image": "words/stone.png",
"voice": "voices-$CA/$LOCALE/words/stone.$CA"
},
{
"description": "stream",
"image": "words/stream.png",
"voice": "voices-$CA/$LOCALE/words/stream.$CA"
},
{
"description": "summer",
"image": "words/summer.png",
"voice": "voices-$CA/$LOCALE/words/summer.$CA"
},
{
"description": "summit",
"image": "words/summit.png",
"voice": "voices-$CA/$LOCALE/words/summit.$CA"
},
{
"description": "sun",
"image": "words/sun.png",
"voice": "voices-$CA/$LOCALE/words/sun.$CA"
},
{
"description": "time",
"image": "words/time.png",
"voice": "voices-$CA/$LOCALE/words/time.$CA"
},
{
"description": "top",
"image": "words/top.png",
"voice": "voices-$CA/$LOCALE/words/top.$CA"
},
{
"description": "trail",
"image": "words/trail.png",
"voice": "voices-$CA/$LOCALE/words/trail.$CA"
},
{
"description": "water",
"image": "words/water.png",
"voice": "voices-$CA/$LOCALE/words/water.$CA"
},
{
"description": "wave",
"image": "words/wave.png",
"voice": "voices-$CA/$LOCALE/words/wave.$CA"
},
{
"description": "wind",
"image": "words/wind.png",
"voice": "voices-$CA/$LOCALE/words/wind.$CA"
},
{
"description": "winter",
"image": "words/winter.png",
"voice": "voices-$CA/$LOCALE/words/winter.$CA"
},
{
"description": "world",
"image": "words/world.png",
"voice": "voices-$CA/$LOCALE/words/world.$CA"
},
{
"description": "vapor",
"image": "words/vapor.png",
"voice": "voices-$CA/$LOCALE/words/vapor.$CA"
}
]
},
{
"type": "lesson",
"name": "plant",
"content": [
{
"description": "acorn",
"image": "words/acorn.png",
"voice": "voices-$CA/$LOCALE/words/acorn.$CA"
},
{
"description": "apple tree",
"image": "words/apple_tree.png",
"voice": "voices-$CA/$LOCALE/words/apple_tree.$CA"
},
{
"description": "branch",
"image": "words/branch.png",
"voice": "voices-$CA/$LOCALE/words/branch.$CA"
},
{
"description": "bud",
"image": "words/bud.png",
"voice": "voices-$CA/$LOCALE/words/bud.$CA"
},
{
"description": "bush",
"image": "words/bush.png",
"voice": "voices-$CA/$LOCALE/words/bush.$CA"
},
{
"description": "cactus",
"image": "words/cactus.png",
"voice": "voices-$CA/$LOCALE/words/cactus.$CA"
},
{
"description": "clover",
"image": "words/clover.png",
"voice": "voices-$CA/$LOCALE/words/clover.$CA"
},
{
"description": "daffodil",
"image": "words/daffodil.png",
"voice": "voices-$CA/$LOCALE/words/daffodil.$CA"
},
{
"description": "daisy",
"image": "words/daisy.png",
"voice": "voices-$CA/$LOCALE/words/daisy.$CA"
},
{
"description": "dandelion",
"image": "words/dandelion.png",
"voice": "voices-$CA/$LOCALE/words/dandelion.$CA"
},
{
"description": "flower",
"image": "words/flower.png",
"voice": "voices-$CA/$LOCALE/words/flower.$CA"
},
{
"description": "grain",
"image": "words/grain.png",
"voice": "voices-$CA/$LOCALE/words/grain.$CA"
},
{
"description": "grass",
"image": "words/grass.png",
"voice": "voices-$CA/$LOCALE/words/grass.$CA"
},
{
"description": "hay",
"image": "words/hay.png",
"voice": "voices-$CA/$LOCALE/words/hay.$CA"
},
{
"description": "hedge",
"image": "words/hedge.png",
"voice": "voices-$CA/$LOCALE/words/hedge.$CA"
},
{
"description": "lawn",
"image": "words/lawn.png",
"voice": "voices-$CA/$LOCALE/words/lawn.$CA"
},
{
"description": "leaf",
"image": "words/leaf.png",
"voice": "voices-$CA/$LOCALE/words/leaf.$CA"
},
{
"description": "lilac",
"image": "words/lilac.png",
"voice": "voices-$CA/$LOCALE/words/lilac.$CA"
},
{
"description": "maple",
"image": "words/maple.png",
"voice": "voices-$CA/$LOCALE/words/maple.$CA"
},
{
"description": "mimosa",
"image": "words/mimosa.png",
"voice": "voices-$CA/$LOCALE/words/mimosa.$CA"
},
{
"description": "orchid",
"image": "words/orchid.png",
"voice": "voices-$CA/$LOCALE/words/orchid.$CA"
},
{
"description": "palm tree",
"image": "words/palm_tree.png",
"voice": "voices-$CA/$LOCALE/words/palm_tree.$CA"
},
{
"description": "peony",
"image": "words/peony.png",
"voice": "voices-$CA/$LOCALE/words/peony.$CA"
},
{
"description": "petal",
"image": "words/petal.png",
"voice": "voices-$CA/$LOCALE/words/petal.$CA"
},
{
"description": "pine",
"image": "words/pine.png",
"voice": "voices-$CA/$LOCALE/words/pine.$CA"
},
{
"description": "pine cone",
"image": "words/pine_cone.png",
"voice": "voices-$CA/$LOCALE/words/pine_cone.$CA"
},
{
"description": "pip",
"image": "words/pip.png",
"voice": "voices-$CA/$LOCALE/words/pip.$CA"
},
{
"description": "plant",
"image": "words/plant.png",
"voice": "voices-$CA/$LOCALE/words/plant.$CA"
},
{
"description": "root",
"image": "words/root.png",
"voice": "voices-$CA/$LOCALE/words/root.$CA"
},
{
"description": "rose",
"image": "words/rose.png",
"voice": "voices-$CA/$LOCALE/words/rose.$CA"
},
{
"description": "seed",
"image": "words/seed.png",
"voice": "voices-$CA/$LOCALE/words/seed.$CA"
},
{
"description": "shrub",
"image": "words/shrub.png",
"voice": "voices-$CA/$LOCALE/words/shrub.$CA"
},
{
"description": "stem",
"image": "words/stem.png",
"voice": "voices-$CA/$LOCALE/words/stem.$CA"
},
{
"description": "stick",
"image": "words/stick.png",
"voice": "voices-$CA/$LOCALE/words/stick.$CA"
},
{
"description": "stump",
"image": "words/stump.png",
"voice": "voices-$CA/$LOCALE/words/stump.$CA"
},
{
"description": "tree",
"image": "words/tree.png",
"voice": "voices-$CA/$LOCALE/words/tree.$CA"
},
{
"description": "tulip",
"image": "words/tulip.png",
"voice": "voices-$CA/$LOCALE/words/tulip.$CA"
},
{
"description": "verdure",
"image": "words/verdure.png",
"voice": "voices-$CA/$LOCALE/words/verdure.$CA"
}
]
},
{
"type": "lesson",
"name": "vegetables",
"content": [
{
"description": "artichoke",
"image": "words/artichoke.png",
"voice": "voices-$CA/$LOCALE/words/artichoke.$CA"
},
{
"description": "asparagus",
"image": "words/asparagus.png",
"voice": "voices-$CA/$LOCALE/words/asparagus.$CA"
},
{
"description": "avocado",
"image": "words/avocado.png",
"voice": "voices-$CA/$LOCALE/words/avocado.$CA"
},
{
"description": "bean",
"image": "words/bean.png",
"voice": "voices-$CA/$LOCALE/words/bean.$CA"
},
{
"description": "broccoli",
"image": "words/broccoli.png",
"voice": "voices-$CA/$LOCALE/words/broccoli.$CA"
},
{
"description": "cabbage",
"image": "words/cabbage.png",
"voice": "voices-$CA/$LOCALE/words/cabbage.$CA"
},
{
"description": "carrot",
"image": "words/carrot.png",
"voice": "voices-$CA/$LOCALE/words/carrot.$CA"
},
{
"description": "cauliflower",
"image": "words/cauliflower.png",
"voice": "voices-$CA/$LOCALE/words/cauliflower.$CA"
},
{
"description": "celery",
"image": "words/celery.png",
"voice": "voices-$CA/$LOCALE/words/celery.$CA"
},
{
"description": "corn",
"image": "words/corn.png",
"voice": "voices-$CA/$LOCALE/words/corn.$CA"
},
{
"description": "cucumber",
"image": "words/cucumber.png",
"voice": "voices-$CA/$LOCALE/words/cucumber.$CA"
},
{
"description": "eggplant",
"image": "words/eggplant.png",
"voice": "voices-$CA/$LOCALE/words/eggplant.$CA"
},
{
"description": "garlic",
"image": "words/garlic.png",
"voice": "voices-$CA/$LOCALE/words/garlic.$CA"
},
{
"description": "leek",
"image": "words/leek.png",
"voice": "voices-$CA/$LOCALE/words/leek.$CA"
},
{
"description": "lettuce",
"image": "words/lettuce.png",
"voice": "voices-$CA/$LOCALE/words/lettuce.$CA"
},
{
"description": "mushroom",
"image": "words/mushroom.png",
"voice": "voices-$CA/$LOCALE/words/mushroom.$CA"
},
{
"description": "nut",
"image": "words/nut.png",
"voice": "voices-$CA/$LOCALE/words/nut.$CA"
},
{
"description": "olive",
"image": "words/olive.png",
"voice": "voices-$CA/$LOCALE/words/olive.$CA"
},
{
"description": "onion",
"image": "words/onion.png",
"voice": "voices-$CA/$LOCALE/words/onion.$CA"
},
{
"description": "pea",
"image": "words/pea.png",
"voice": "voices-$CA/$LOCALE/words/pea.$CA"
},
{
"description": "peppers",
"image": "words/peppers.png",
"voice": "voices-$CA/$LOCALE/words/peppers.$CA"
},
{
"description": "pod",
"image": "words/pod.png",
"voice": "voices-$CA/$LOCALE/words/pod.$CA"
},
{
"description": "potato",
"image": "words/potato.png",
"voice": "voices-$CA/$LOCALE/words/potato.$CA"
},
{
"description": "pumpkin",
"image": "words/pumpkin.png",
"voice": "voices-$CA/$LOCALE/words/pumpkin.$CA"
},
{
"description": "radish",
"image": "words/radish.png",
"voice": "voices-$CA/$LOCALE/words/radish.$CA"
},
{
"description": "spinach",
"image": "words/spinach.png",
"voice": "voices-$CA/$LOCALE/words/spinach.$CA"
},
{
"description": "squash",
"image": "words/squash.png",
"voice": "voices-$CA/$LOCALE/words/squash.$CA"
},
{
"description": "tomatoe",
"image": "words/tomatoe.png",
"voice": "voices-$CA/$LOCALE/words/tomatoe.$CA"
},
{
"description": "turnip",
"image": "words/turnip.png",
"voice": "voices-$CA/$LOCALE/words/turnip.$CA"
},
{
"description": "vegetable",
"image": "words/vegetable.png",
"voice": "voices-$CA/$LOCALE/words/vegetable.$CA"
},
{
"description": "walnut",
"image": "words/walnut.png",
"voice": "voices-$CA/$LOCALE/words/walnut.$CA"
},
{
"description": "wheat",
"image": "words/wheat.png",
"voice": "voices-$CA/$LOCALE/words/wheat.$CA"
}
]
}
]
},
{
"type": "chapter",
"name": "object",
"imgPrefix": "qrc:/gcompris/data/",
"content": [
{
"type": "lesson",
"name": "construction",
"content": [
{
"description": "bank",
"image": "words/bank.png",
"voice": "voices-$CA/$LOCALE/words/bank.$CA"
},
{
"description": "barn",
"image": "words/barn.png",
"voice": "voices-$CA/$LOCALE/words/barn.$CA"
},
{
"description": "bedroom",
"image": "words/bedroom.png",
"voice": "voices-$CA/$LOCALE/words/bedroom.$CA"
},
{
"description": "big top",
"image": "words/big_top.png",
"voice": "voices-$CA/$LOCALE/words/big_top.$CA"
},
{
"description": "bridge",
"image": "words/bridge.png",
"voice": "voices-$CA/$LOCALE/words/bridge.$CA"
},
{
"description": "cabin",
"image": "words/cabin.png",
"voice": "voices-$CA/$LOCALE/words/cabin.$CA"
},
{
"description": "cage",
"image": "words/cage.png",
"voice": "voices-$CA/$LOCALE/words/cage.$CA"
},
{
"description": "castle",
"image": "words/castle.png",
"voice": "voices-$CA/$LOCALE/words/castle.$CA"
},
{
"description": "chimney",
"image": "words/chimney.png",
"voice": "voices-$CA/$LOCALE/words/chimney.$CA"
},
{
"description": "circus",
"image": "words/circus.png",
"voice": "voices-$CA/$LOCALE/words/circus.$CA"
},
{
"description": "city",
"image": "words/city.png",
"voice": "voices-$CA/$LOCALE/words/city.$CA"
},
{
"description": "dam",
"image": "words/dam.png",
"voice": "voices-$CA/$LOCALE/words/dam.$CA"
},
{
"description": "door",
"image": "words/door.png",
"voice": "voices-$CA/$LOCALE/words/door.$CA"
},
{
"description": "fair",
"image": "words/fair.png",
"voice": "voices-$CA/$LOCALE/words/fair.$CA"
},
{
"description": "farm",
"image": "words/farm.png",
"voice": "voices-$CA/$LOCALE/words/farm.$CA"
},
{
"description": "fountain",
"image": "words/fountain.png",
"voice": "voices-$CA/$LOCALE/words/fountain.$CA"
},
{
"description": "garage",
"image": "words/garage.png",
"voice": "voices-$CA/$LOCALE/words/garage.$CA"
},
{
"description": "grave",
"image": "words/grave.png",
"voice": "voices-$CA/$LOCALE/words/grave.$CA"
},
{
"description": "home",
"image": "words/home.png",
"voice": "voices-$CA/$LOCALE/words/home.$CA"
},
{
"description": "hospital",
"image": "words/hospital.png",
"voice": "voices-$CA/$LOCALE/words/hospital.$CA"
},
{
"description": "house",
"image": "words/house.png",
"voice": "voices-$CA/$LOCALE/words/house.$CA"
},
{
"description": "hut",
"image": "words/hut.png",
"voice": "voices-$CA/$LOCALE/words/hut.$CA"
},
{
"description": "kitchen",
"image": "words/kitchen.png",
"voice": "voices-$CA/$LOCALE/words/kitchen.$CA"
},
{
"description": "lane",
"image": "words/lane.png",
"voice": "voices-$CA/$LOCALE/words/lane.$CA"
},
{
"description": "lighthouse",
"image": "words/lighthouse.png",
"voice": "voices-$CA/$LOCALE/words/lighthouse.$CA"
},
{
"description": "merry-go-round",
"image": "words/merry-go-round.png",
"voice": "voices-$CA/$LOCALE/words/merry-go-round.$CA"
},
{
"description": "mill",
"image": "words/mill.png",
"voice": "voices-$CA/$LOCALE/words/mill.$CA"
},
{
"description": "mosque",
"image": "words/mosque.png",
"voice": "voices-$CA/$LOCALE/words/mosque.$CA"
},
{
"description": "office",
"image": "words/office.png",
"voice": "voices-$CA/$LOCALE/words/office.$CA"
},
{
"description": "pool",
"image": "words/pool.png",
"voice": "voices-$CA/$LOCALE/words/pool.$CA"
},
{
"description": "post",
"image": "words/post.png",
"voice": "voices-$CA/$LOCALE/words/post.$CA"
},
{
"description": "prison",
"image": "words/prison.png",
"voice": "voices-$CA/$LOCALE/words/prison.$CA"
},
{
"description": "pyramid",
"image": "words/pyramid.png",
"voice": "voices-$CA/$LOCALE/words/pyramid.$CA"
},
{
"description": "ramp",
"image": "words/ramp.png",
"voice": "voices-$CA/$LOCALE/words/ramp.$CA"
},
{
"description": "road",
"image": "words/road.png",
"voice": "voices-$CA/$LOCALE/words/road.$CA"
},
{
"description": "roof",
"image": "words/roof.png",
"voice": "voices-$CA/$LOCALE/words/roof.$CA"
},
{
"description": "room",
"image": "words/room.png",
"voice": "voices-$CA/$LOCALE/words/room.$CA"
},
{
"description": "school",
"image": "words/school.png",
"voice": "voices-$CA/$LOCALE/words/school.$CA"
},
{
"description": "shed",
"image": "words/shed.png",
"voice": "voices-$CA/$LOCALE/words/shed.$CA"
},
{
"description": "shop",
"image": "words/shop.png",
"voice": "voices-$CA/$LOCALE/words/shop.$CA"
},
{
"description": "shutter",
"image": "words/shutter.png",
"voice": "voices-$CA/$LOCALE/words/shutter.$CA"
},
{
"description": "sidewalk",
"image": "words/sidewalk.png",
"voice": "voices-$CA/$LOCALE/words/sidewalk.$CA"
},
{
"description": "stage",
"image": "words/stage.png",
"voice": "voices-$CA/$LOCALE/words/stage.$CA"
},
{
"description": "staircase",
"image": "words/staircase.png",
"voice": "voices-$CA/$LOCALE/words/staircase.$CA"
},
{
"description": "steeple",
"image": "words/steeple.png",
"voice": "voices-$CA/$LOCALE/words/steeple.$CA"
},
{
"description": "step",
"image": "words/step.png",
"voice": "voices-$CA/$LOCALE/words/step.$CA"
},
{
"description": "store",
"image": "words/store.png",
"voice": "voices-$CA/$LOCALE/words/store.$CA"
},
{
"description": "street",
"image": "words/street.png",
"voice": "voices-$CA/$LOCALE/words/street.$CA"
},
{
"description": "temple",
"image": "words/temple.png",
"voice": "voices-$CA/$LOCALE/words/temple.$CA"
},
{
"description": "tent",
"image": "words/tent.png",
"voice": "voices-$CA/$LOCALE/words/tent.$CA"
},
{
"description": "train station",
"image": "words/train_station.png",
"voice": "voices-$CA/$LOCALE/words/train_station.$CA"
},
{
"description": "wall",
"image": "words/wall.png",
"voice": "voices-$CA/$LOCALE/words/wall.$CA"
},
{
"description": "window",
"image": "words/window.png",
"voice": "voices-$CA/$LOCALE/words/window.$CA"
},
{
"description": "window glass",
"image": "words/window_glass.png",
"voice": "voices-$CA/$LOCALE/words/window_glass.$CA"
},
{
"description": "zoo",
"image": "words/zoo.png",
"voice": "voices-$CA/$LOCALE/words/zoo.$CA"
},
{
"description": "class",
"image": "words/class.png",
"voice": "voices-$CA/$LOCALE/words/class.$CA"
}
]
},
{
"type": "lesson",
"name": "furniture",
"content": [
{
"description": "armchair",
"image": "words/armchair.png",
"voice": "voices-$CA/$LOCALE/words/armchair.$CA"
},
{
"description": "bath",
"image": "words/bath.png",
"voice": "voices-$CA/$LOCALE/words/bath.$CA"
},
{
"description": "bed",
"image": "words/bed.png",
"voice": "voices-$CA/$LOCALE/words/bed.$CA"
},
{
"description": "bench",
"image": "words/bench.png",
"voice": "voices-$CA/$LOCALE/words/bench.$CA"
},
{
"description": "bookcase",
"image": "words/bookcase.png",
"voice": "voices-$CA/$LOCALE/words/bookcase.$CA"
},
{
"description": "carpet",
"image": "words/carpet.png",
"voice": "voices-$CA/$LOCALE/words/carpet.$CA"
},
{
"description": "chair",
"image": "words/chair.png",
"voice": "voices-$CA/$LOCALE/words/chair.$CA"
},
{
"description": "chest",
"image": "words/chest.png",
"voice": "voices-$CA/$LOCALE/words/chest.$CA"
},
{
"description": "couch",
"image": "words/couch.png",
"voice": "voices-$CA/$LOCALE/words/couch.$CA"
},
{
"description": "cradle",
"image": "words/cradle.png",
"voice": "voices-$CA/$LOCALE/words/cradle.$CA"
},
{
"description": "crib",
"image": "words/crib.png",
"voice": "voices-$CA/$LOCALE/words/crib.$CA"
},
{
"description": "desk",
"image": "words/desk.png",
"voice": "voices-$CA/$LOCALE/words/desk.$CA"
},
{
"description": "doormat",
"image": "words/doormat.png",
"voice": "voices-$CA/$LOCALE/words/doormat.$CA"
},
{
"description": "drawer",
"image": "words/drawer.png",
"voice": "voices-$CA/$LOCALE/words/drawer.$CA"
},
{
"description": "fan",
"image": "words/fan.png",
"voice": "voices-$CA/$LOCALE/words/fan.$CA"
},
{
"description": "lamp",
"image": "words/lamp.png",
"voice": "voices-$CA/$LOCALE/words/lamp.$CA"
},
- {
- "description": "light",
- "image": "words/light.png",
- "voice": "voices-$CA/$LOCALE/words/light.$CA"
- },
{
"description": "mat",
"image": "words/mat.png",
"voice": "voices-$CA/$LOCALE/words/mat.$CA"
},
{
"description": "mattress",
"image": "words/mattress.png",
"voice": "voices-$CA/$LOCALE/words/mattress.$CA"
},
{
"description": "quilt",
"image": "words/quilt.png",
"voice": "voices-$CA/$LOCALE/words/quilt.$CA"
},
{
"description": "rug",
"image": "words/rug.png",
"voice": "voices-$CA/$LOCALE/words/rug.$CA"
},
{
"description": "seat",
"image": "words/seat.png",
"voice": "voices-$CA/$LOCALE/words/seat.$CA"
},
{
"description": "shelf",
"image": "words/shelf.png",
"voice": "voices-$CA/$LOCALE/words/shelf.$CA"
},
{
"description": "shower",
"image": "words/shower.png",
"voice": "voices-$CA/$LOCALE/words/shower.$CA"
},
{
"description": "sink",
"image": "words/sink.png",
"voice": "voices-$CA/$LOCALE/words/sink.$CA"
},
{
"description": "stove",
"image": "words/stove.png",
"voice": "voices-$CA/$LOCALE/words/stove.$CA"
},
{
"description": "table",
"image": "words/table.png",
"voice": "voices-$CA/$LOCALE/words/table.$CA"
},
{
"description": "television",
"image": "words/television.png",
"voice": "voices-$CA/$LOCALE/words/television.$CA"
},
{
"description": "toilet",
"image": "words/toilet.png",
"voice": "voices-$CA/$LOCALE/words/toilet.$CA"
}
]
},
{
"type": "lesson",
"name": "houseware",
"content": [
{
"description": "appliance",
"image": "words/appliance.png",
"voice": "voices-$CA/$LOCALE/words/appliance.$CA"
},
{
"description": "baby bottle",
"image": "words/baby_bottle.png",
"voice": "voices-$CA/$LOCALE/words/baby_bottle.$CA"
},
{
"description": "balance",
"image": "words/balance.png",
"voice": "voices-$CA/$LOCALE/words/balance.$CA"
},
{
"description": "blade",
"image": "words/blade.png",
"voice": "voices-$CA/$LOCALE/words/blade.$CA"
},
{
"description": "can",
"image": "words/can.png",
"voice": "voices-$CA/$LOCALE/words/can.$CA"
},
{
"description": "carafe",
"image": "words/carafe.png",
"voice": "voices-$CA/$LOCALE/words/carafe.$CA"
},
{
"description": "cauldron",
"image": "words/cauldron.png",
"voice": "voices-$CA/$LOCALE/words/cauldron.$CA"
},
{
"description": "chandelier",
"image": "words/chandelier.png",
"voice": "voices-$CA/$LOCALE/words/chandelier.$CA"
},
{
"description": "clock",
"image": "words/clock.png",
"voice": "voices-$CA/$LOCALE/words/clock.$CA"
},
{
"description": "curtain",
"image": "words/curtain.png",
"voice": "voices-$CA/$LOCALE/words/curtain.$CA"
},
{
"description": "dish",
"image": "words/dish.png",
"voice": "voices-$CA/$LOCALE/words/dish.$CA"
},
{
"description": "fork",
"image": "words/fork.png",
"voice": "voices-$CA/$LOCALE/words/fork.$CA"
},
{
"description": "glass",
"image": "words/glass.png",
"voice": "voices-$CA/$LOCALE/words/glass.$CA"
},
{
"description": "knife",
"image": "words/knife.png",
"voice": "voices-$CA/$LOCALE/words/knife.$CA"
},
{
"description": "lid",
"image": "words/lid.png",
"voice": "voices-$CA/$LOCALE/words/lid.$CA"
},
{
"description": "mop",
"image": "words/mop.png",
"voice": "voices-$CA/$LOCALE/words/mop.$CA"
},
{
"description": "mug",
"image": "words/mug.png",
"voice": "voices-$CA/$LOCALE/words/mug.$CA"
},
{
"description": "pan",
"image": "words/pan.png",
"voice": "voices-$CA/$LOCALE/words/pan.$CA"
},
{
"description": "plate",
"image": "words/plate.png",
"voice": "voices-$CA/$LOCALE/words/plate.$CA"
},
{
"description": "pot",
"image": "words/pot.png",
"voice": "voices-$CA/$LOCALE/words/pot.$CA"
},
{
"description": "scale",
"image": "words/scale.png",
"voice": "voices-$CA/$LOCALE/words/scale.$CA"
},
{
"description": "skimmer",
"image": "words/skimmer.png",
"voice": "voices-$CA/$LOCALE/words/skimmer.$CA"
},
{
"description": "spatula",
"image": "words/spatula.png",
"voice": "voices-$CA/$LOCALE/words/spatula.$CA"
},
{
"description": "sponge",
"image": "words/sponge.png",
"voice": "voices-$CA/$LOCALE/words/sponge.$CA"
},
{
"description": "spoon",
"image": "words/spoon.png",
"voice": "voices-$CA/$LOCALE/words/spoon.$CA"
},
{
"description": "strainer",
"image": "words/strainer.png",
"voice": "voices-$CA/$LOCALE/words/strainer.$CA"
},
{
"description": "tablecloth",
"image": "words/tablecloth.png",
"voice": "voices-$CA/$LOCALE/words/tablecloth.$CA"
},
{
"description": "tin",
"image": "words/tin.png",
"voice": "voices-$CA/$LOCALE/words/tin.$CA"
},
{
"description": "toaster",
"image": "words/toaster.png",
"voice": "voices-$CA/$LOCALE/words/toaster.$CA"
},
{
"description": "tongs",
"image": "words/tongs.png",
"voice": "voices-$CA/$LOCALE/words/tongs.$CA"
},
{
"description": "trash",
"image": "words/trash.png",
"voice": "voices-$CA/$LOCALE/words/trash.$CA"
},
{
"description": "tray",
"image": "words/tray.png",
"voice": "voices-$CA/$LOCALE/words/tray.$CA"
},
{
"description": "vase",
"image": "words/vase.png",
"voice": "voices-$CA/$LOCALE/words/vase.$CA"
},
{
"description": "whisk",
"image": "words/whisk.png",
"voice": "voices-$CA/$LOCALE/words/whisk.$CA"
},
{
"description": "alarmclock",
"image": "words/alarmclock.png",
"voice": "voices-$CA/$LOCALE/words/alarmclock.$CA"
}
]
},
{
"type": "lesson",
"name": "object",
"content": [
{
"description": "faucet",
"image": "words/faucet.png",
"voice": "voices-$CA/$LOCALE/words/faucet.$CA"
},
{
"description": "air horn",
"image": "words/air_horn.png",
"voice": "voices-$CA/$LOCALE/words/air_horn.$CA"
},
{
"description": "anchor",
"image": "words/anchor.png",
"voice": "voices-$CA/$LOCALE/words/anchor.$CA"
},
{
"description": "badge",
"image": "words/badge.png",
"voice": "voices-$CA/$LOCALE/words/badge.$CA"
},
{
"description": "bag",
"image": "words/bag.png",
"voice": "voices-$CA/$LOCALE/words/bag.$CA"
},
{
"description": "ball",
"image": "words/ball.png",
"voice": "voices-$CA/$LOCALE/words/ball.$CA"
},
{
"description": "soccer ball",
"image": "words/ball_soccer.png",
"voice": "voices-$CA/$LOCALE/words/ball_soccer.$CA"
},
- {
- "description": "bead",
- "image": "words/bead.png",
- "voice": "voices-$CA/$LOCALE/words/bead.$CA"
- },
{
"description": "bell",
"image": "words/bell.png",
"voice": "voices-$CA/$LOCALE/words/bell.$CA"
},
{
"description": "block",
"image": "words/block.png",
"voice": "voices-$CA/$LOCALE/words/block.$CA"
},
{
"description": "board",
"image": "words/board.png",
"voice": "voices-$CA/$LOCALE/words/board.$CA"
},
{
"description": "bomb",
"image": "words/bomb.png",
"voice": "voices-$CA/$LOCALE/words/bomb.$CA"
},
{
"description": "book",
"image": "words/book.png",
"voice": "voices-$CA/$LOCALE/words/book.$CA"
},
{
"description": "box",
"image": "words/box.png",
"voice": "voices-$CA/$LOCALE/words/box.$CA"
},
{
"description": "bucket",
"image": "words/bucket.png",
"voice": "voices-$CA/$LOCALE/words/bucket.$CA"
},
{
"description": "bulb",
"image": "words/bulb.png",
"voice": "voices-$CA/$LOCALE/words/bulb.$CA"
},
{
"description": "camera",
"image": "words/camera.png",
"voice": "voices-$CA/$LOCALE/words/camera.$CA"
},
{
"description": "candle",
"image": "words/candle.png",
"voice": "voices-$CA/$LOCALE/words/candle.$CA"
},
{
"description": "cane",
"image": "words/cane.png",
"voice": "voices-$CA/$LOCALE/words/cane.$CA"
},
{
"description": "canon",
"image": "words/canon.png",
"voice": "voices-$CA/$LOCALE/words/canon.$CA"
},
{
"description": "card",
"image": "words/card.png",
"voice": "voices-$CA/$LOCALE/words/card.$CA"
},
{
"description": "cart",
"image": "words/cart.png",
"voice": "voices-$CA/$LOCALE/words/cart.$CA"
},
{
"description": "cash",
"image": "words/cash.png",
"voice": "voices-$CA/$LOCALE/words/cash.$CA"
},
{
"description": "chain",
"image": "words/chain.png",
"voice": "voices-$CA/$LOCALE/words/chain.$CA"
},
{
"description": "chalk",
"image": "words/chalk.png",
"voice": "voices-$CA/$LOCALE/words/chalk.$CA"
},
{
"description": "cigar",
"image": "words/cigar.png",
"voice": "voices-$CA/$LOCALE/words/cigar.$CA"
},
{
"description": "clay",
"image": "words/clay.png",
"voice": "voices-$CA/$LOCALE/words/clay.$CA"
},
{
"description": "cloth",
"image": "words/cloth.png",
"voice": "voices-$CA/$LOCALE/words/cloth.$CA"
},
{
"description": "clothes hanger",
"image": "words/clothes_hanger.png",
"voice": "voices-$CA/$LOCALE/words/clothes_hanger.$CA"
},
{
"description": "coin",
"image": "words/coin.png",
"voice": "voices-$CA/$LOCALE/words/coin.$CA"
},
{
"description": "comb",
"image": "words/comb.png",
"voice": "voices-$CA/$LOCALE/words/comb.$CA"
},
{
"description": "cone",
"image": "words/cone.png",
"voice": "voices-$CA/$LOCALE/words/cone.$CA"
},
{
"description": "cork",
"image": "words/cork.png",
"voice": "voices-$CA/$LOCALE/words/cork.$CA"
},
{
"description": "cross",
"image": "words/cross.png",
"voice": "voices-$CA/$LOCALE/words/cross.$CA"
},
{
"description": "crown",
"image": "words/crown.png",
"voice": "voices-$CA/$LOCALE/words/crown.$CA"
},
{
"description": "cube",
"image": "words/cube.png",
"voice": "voices-$CA/$LOCALE/words/cube.$CA"
},
{
"description": "tire",
"image": "words/tire.png",
"voice": "voices-$CA/$LOCALE/words/tire.$CA"
},
{
"description": "dart board",
"image": "words/dart_board.png",
"voice": "voices-$CA/$LOCALE/words/dart_board.$CA"
},
{
"description": "dishcloth",
"image": "words/dishcloth.png",
"voice": "voices-$CA/$LOCALE/words/dishcloth.$CA"
},
{
"description": "doll",
"image": "words/doll.png",
"voice": "voices-$CA/$LOCALE/words/doll.$CA"
},
{
"description": "domino",
"image": "words/domino.png",
"voice": "voices-$CA/$LOCALE/words/domino.$CA"
},
{
"description": "drum",
"image": "words/drum.png",
"voice": "voices-$CA/$LOCALE/words/drum.$CA"
},
{
"description": "eraser",
"image": "words/eraser.png",
"voice": "voices-$CA/$LOCALE/words/eraser.$CA"
},
{
"description": "fire extinguisher",
"image": "words/fire_extinguisher.png",
"voice": "voices-$CA/$LOCALE/words/fire_extinguisher.$CA"
},
{
"description": "flacon",
"image": "words/flacon.png",
"voice": "voices-$CA/$LOCALE/words/flacon.$CA"
},
{
"description": "flag",
"image": "words/flag.png",
"voice": "voices-$CA/$LOCALE/words/flag.$CA"
},
{
"description": "fluff",
"image": "words/fluff.png",
"voice": "voices-$CA/$LOCALE/words/fluff.$CA"
},
{
"description": "flute",
"image": "words/flute.png",
"voice": "voices-$CA/$LOCALE/words/flute.$CA"
},
{
"description": "game",
"image": "words/game.png",
"voice": "voices-$CA/$LOCALE/words/game.$CA"
},
{
"description": "gift",
"image": "words/gift.png",
"voice": "voices-$CA/$LOCALE/words/gift.$CA"
},
{
"description": "glasses",
"image": "words/glasses.png",
"voice": "voices-$CA/$LOCALE/words/glasses.$CA"
},
{
"description": "glue",
"image": "words/glue.png",
"voice": "voices-$CA/$LOCALE/words/glue.$CA"
},
{
"description": "grill",
"image": "words/grill.png",
"voice": "voices-$CA/$LOCALE/words/grill.$CA"
},
{
"description": "hair-dryer",
"image": "words/hair_dryer.png",
"voice": "voices-$CA/$LOCALE/words/hair_dryer.$CA"
},
{
"description": "handlebar",
"image": "words/handlebar.png",
"voice": "voices-$CA/$LOCALE/words/handlebar.$CA"
},
{
"description": "harp",
"image": "words/harp.png",
"voice": "voices-$CA/$LOCALE/words/harp.$CA"
},
{
"description": "hook",
"image": "words/hook.png",
"voice": "voices-$CA/$LOCALE/words/hook.$CA"
},
{
"description": "hose",
"image": "words/hose.png",
"voice": "voices-$CA/$LOCALE/words/hose.$CA"
},
{
"description": "ink",
"image": "words/ink.png",
"voice": "voices-$CA/$LOCALE/words/ink.$CA"
},
{
"description": "jewel",
"image": "words/jewel.png",
"voice": "voices-$CA/$LOCALE/words/jewel.$CA"
},
{
"description": "keel",
"image": "words/keel.png",
"voice": "voices-$CA/$LOCALE/words/keel.$CA"
},
{
"description": "keyboard",
"image": "words/keyboard.png",
"voice": "voices-$CA/$LOCALE/words/keyboard.$CA"
},
{
"description": "kite",
"image": "words/kite.png",
"voice": "voices-$CA/$LOCALE/words/kite.$CA"
},
{
"description": "knot",
"image": "words/knot.png",
"voice": "voices-$CA/$LOCALE/words/knot.$CA"
},
{
"description": "lasso",
"image": "words/lasso.png",
"voice": "voices-$CA/$LOCALE/words/lasso.$CA"
},
{
"description": "log",
"image": "words/log.png",
"voice": "voices-$CA/$LOCALE/words/log.$CA"
},
{
"description": "magnet",
"image": "words/magnet.png",
"voice": "voices-$CA/$LOCALE/words/magnet.$CA"
},
{
"description": "magnifying glass",
"image": "words/magnifying_glass.png",
"voice": "voices-$CA/$LOCALE/words/magnifying_glass.$CA"
},
{
"description": "mail",
"image": "words/mail.png",
"voice": "voices-$CA/$LOCALE/words/mail.$CA"
},
{
"description": "map",
"image": "words/map.png",
"voice": "voices-$CA/$LOCALE/words/map.$CA"
},
{
"description": "marble",
"image": "words/marble.png",
"voice": "voices-$CA/$LOCALE/words/marble.$CA"
},
{
"description": "mask",
"image": "words/mask.png",
"voice": "voices-$CA/$LOCALE/words/mask.$CA"
},
{
"description": "mast",
"image": "words/mast.png",
"voice": "voices-$CA/$LOCALE/words/mast.$CA"
},
{
"description": "match",
"image": "words/match.png",
"voice": "voices-$CA/$LOCALE/words/match.$CA"
},
{
"description": "medal",
"image": "words/medal.png",
"voice": "voices-$CA/$LOCALE/words/medal.$CA"
},
{
"description": "microphone",
"image": "words/microphone.png",
"voice": "voices-$CA/$LOCALE/words/microphone.$CA"
},
{
"description": "mirror",
"image": "words/mirror.png",
"voice": "voices-$CA/$LOCALE/words/mirror.$CA"
},
{
"description": "mixer",
"image": "words/mixer.png",
"voice": "voices-$CA/$LOCALE/words/mixer.$CA"
},
{
"description": "necklace",
"image": "words/necklace.png",
"voice": "voices-$CA/$LOCALE/words/necklace.$CA"
},
{
"description": "nest",
"image": "words/nest.png",
"voice": "voices-$CA/$LOCALE/words/nest.$CA"
},
{
"description": "net",
"image": "words/net.png",
"voice": "voices-$CA/$LOCALE/words/net.$CA"
},
{
"description": "newspaper",
"image": "words/newspaper.png",
"voice": "voices-$CA/$LOCALE/words/newspaper.$CA"
},
{
"description": "notebook",
"image": "words/notebook.png",
"voice": "voices-$CA/$LOCALE/words/notebook.$CA"
},
{
"description": "oar",
"image": "words/oar.png",
"voice": "voices-$CA/$LOCALE/words/oar.$CA"
},
{
"description": "pacifier",
"image": "words/pacifier.png",
"voice": "voices-$CA/$LOCALE/words/pacifier.$CA"
},
{
"description": "page",
"image": "words/page.png",
"voice": "voices-$CA/$LOCALE/words/page.$CA"
},
{
"description": "pair",
"image": "words/pair.png",
"voice": "voices-$CA/$LOCALE/words/pair.$CA"
},
{
"description": "paper",
"image": "words/paper.png",
"voice": "voices-$CA/$LOCALE/words/paper.$CA"
},
{
"description": "pearl",
"image": "words/pearl.png",
"voice": "voices-$CA/$LOCALE/words/pearl.$CA"
},
{
"description": "pen",
"image": "words/pen.png",
"voice": "voices-$CA/$LOCALE/words/pen.$CA"
},
{
"description": "pencil",
"image": "words/pencil.png",
"voice": "voices-$CA/$LOCALE/words/pencil.$CA"
},
{
"description": "phone",
"image": "words/phone.png",
"voice": "voices-$CA/$LOCALE/words/phone.$CA"
},
{
"description": "piano",
"image": "words/piano.png",
"voice": "voices-$CA/$LOCALE/words/piano.$CA"
},
{
"description": "picture",
"image": "words/picture.png",
"voice": "voices-$CA/$LOCALE/words/picture.$CA"
},
{
"description": "pill",
"image": "words/pill.png",
"voice": "voices-$CA/$LOCALE/words/pill.$CA"
},
{
"description": "pillow",
"image": "words/pillow.png",
"voice": "voices-$CA/$LOCALE/words/pillow.$CA"
},
{
"description": "pipe",
"image": "words/pipe.png",
"voice": "voices-$CA/$LOCALE/words/pipe.$CA"
},
{
"description": "pole",
"image": "words/pole.png",
"voice": "voices-$CA/$LOCALE/words/pole.$CA"
},
{
"description": "prize",
"image": "words/prize.png",
"voice": "voices-$CA/$LOCALE/words/prize.$CA"
},
{
"description": "radio",
"image": "words/radio.png",
"voice": "voices-$CA/$LOCALE/words/radio.$CA"
},
{
"description": "rag",
"image": "words/rag.png",
"voice": "voices-$CA/$LOCALE/words/rag.$CA"
},
{
"description": "razor",
"image": "words/razor.png",
"voice": "voices-$CA/$LOCALE/words/razor.$CA"
},
{
"description": "rifle",
"image": "words/rifle.png",
"voice": "voices-$CA/$LOCALE/words/rifle.$CA"
},
{
"description": "robot",
"image": "words/robot.png",
"voice": "voices-$CA/$LOCALE/words/robot.$CA"
},
{
"description": "rolling pin",
"image": "words/rolling_pin.png",
"voice": "voices-$CA/$LOCALE/words/rolling_pin.$CA"
},
{
"description": "rope",
"image": "words/rope.png",
"voice": "voices-$CA/$LOCALE/words/rope.$CA"
},
{
"description": "saddle",
"image": "words/saddle.png",
"voice": "voices-$CA/$LOCALE/words/saddle.$CA"
},
{
"description": "school bag",
"image": "words/school_bag.png",
"voice": "voices-$CA/$LOCALE/words/school_bag.$CA"
},
{
"description": "sign",
"image": "words/sign.png",
"voice": "voices-$CA/$LOCALE/words/sign.$CA"
},
{
"description": "sleigh",
"image": "words/sleigh.png",
"voice": "voices-$CA/$LOCALE/words/sleigh.$CA"
},
{
"description": "slide",
"image": "words/slide.png",
"voice": "voices-$CA/$LOCALE/words/slide.$CA"
},
{
"description": "slot",
"image": "words/slot.png",
"voice": "voices-$CA/$LOCALE/words/slot.$CA"
},
{
"description": "soap",
"image": "words/soap.png",
"voice": "voices-$CA/$LOCALE/words/soap.$CA"
},
{
"description": "spark",
"image": "words/spark.png",
"voice": "voices-$CA/$LOCALE/words/spark.$CA"
},
{
"description": "spinning top",
"image": "words/spinning_top.png",
"voice": "voices-$CA/$LOCALE/words/spinning_top.$CA"
},
{
"description": "spool",
"image": "words/spool.png",
"voice": "voices-$CA/$LOCALE/words/spool.$CA"
},
{
"description": "squirt",
"image": "words/squirt.png",
"voice": "voices-$CA/$LOCALE/words/squirt.$CA"
},
{
"description": "stack",
"image": "words/stack.png",
"voice": "voices-$CA/$LOCALE/words/stack.$CA"
},
{
"description": "stamp",
"image": "words/stamp.png",
"voice": "voices-$CA/$LOCALE/words/stamp.$CA"
},
{
"description": "straw",
"image": "words/straw.png",
"voice": "voices-$CA/$LOCALE/words/straw.$CA"
},
{
"description": "string",
"image": "words/string.png",
"voice": "voices-$CA/$LOCALE/words/string.$CA"
},
{
"description": "suitcase",
"image": "words/suitcase.png",
"voice": "voices-$CA/$LOCALE/words/suitcase.$CA"
},
{
"description": "tag",
"image": "words/tag.png",
"voice": "voices-$CA/$LOCALE/words/tag.$CA"
},
{
"description": "teddy",
"image": "words/teddy.png",
"voice": "voices-$CA/$LOCALE/words/teddy.$CA"
},
{
"description": "thread",
"image": "words/thread.png",
"voice": "voices-$CA/$LOCALE/words/thread.$CA"
},
{
"description": "ticket",
"image": "words/ticket.png",
"voice": "voices-$CA/$LOCALE/words/ticket.$CA"
},
{
"description": "tissue",
"image": "words/tissue.png",
"voice": "voices-$CA/$LOCALE/words/tissue.$CA"
},
{
"description": "torch",
"image": "words/torch.png",
"voice": "voices-$CA/$LOCALE/words/torch.$CA"
},
{
"description": "towel",
"image": "words/towel.png",
"voice": "voices-$CA/$LOCALE/words/towel.$CA"
},
{
"description": "toy",
"image": "words/toy.png",
"voice": "voices-$CA/$LOCALE/words/toy.$CA"
},
{
"description": "trap",
"image": "words/trap.png",
"voice": "voices-$CA/$LOCALE/words/trap.$CA"
},
{
"description": "tube",
"image": "words/tube.png",
"voice": "voices-$CA/$LOCALE/words/tube.$CA"
},
{
"description": "umbrella",
"image": "words/umbrella.png",
"voice": "voices-$CA/$LOCALE/words/umbrella.$CA"
},
{
"description": "watch",
"image": "words/watch.png",
"voice": "voices-$CA/$LOCALE/words/watch.$CA"
},
{
"description": "wheel",
"image": "words/wheel.png",
"voice": "voices-$CA/$LOCALE/words/wheel.$CA"
},
{
"description": "wig",
"image": "words/wig.png",
"voice": "voices-$CA/$LOCALE/words/wig.$CA"
},
{
"description": "wood",
"image": "words/wood.png",
"voice": "voices-$CA/$LOCALE/words/wood.$CA"
},
{
"description": "wreath",
"image": "words/wreath.png",
"voice": "voices-$CA/$LOCALE/words/wreath.$CA"
},
{
"description": "ball of yarn",
"image": "words/ball_of_yarn.png",
"voice": "voices-$CA/$LOCALE/words/ball_of_yarn.$CA"
},
- {
- "description": "christmas",
- "image": "words/christmas.png",
- "voice": "voices-$CA/$LOCALE/words/christmas.$CA"
- },
{
"description": "foam",
"image": "words/foam.png",
"voice": "voices-$CA/$LOCALE/words/foam.$CA"
- },
- {
- "description": "guignol",
- "image": "words/guignol.png",
- "voice": "voices-$CA/$LOCALE/words/guignol.$CA"
- },
- {
- "description": "movie",
- "image": "words/movie.png",
- "voice": "voices-$CA/$LOCALE/words/movie.$CA"
- },
- {
- "description": "music",
- "image": "words/music.png",
- "voice": "voices-$CA/$LOCALE/words/music.$CA"
- },
- {
- "description": "price",
- "image": "words/price.png",
- "voice": "voices-$CA/$LOCALE/words/price.$CA"
- },
- {
- "description": "dot",
- "image": "words/dot.png",
- "voice": "voices-$CA/$LOCALE/words/dot.$CA"
}
]
},
{
"type": "lesson",
"name": "tool",
"content": [
{
"description": "ax",
"image": "words/ax.png",
"voice": "voices-$CA/$LOCALE/words/ax.$CA"
},
{
"description": "bolt",
"image": "words/bolt.png",
"voice": "voices-$CA/$LOCALE/words/bolt.$CA"
},
{
"description": "brick",
"image": "words/brick.png",
"voice": "voices-$CA/$LOCALE/words/brick.$CA"
},
{
"description": "brush",
"image": "words/brush.png",
"voice": "voices-$CA/$LOCALE/words/brush.$CA"
},
{
"description": "flash",
"image": "words/flash.png",
"voice": "voices-$CA/$LOCALE/words/flash.$CA"
},
{
"description": "hammer",
"image": "words/hammer.png",
"voice": "voices-$CA/$LOCALE/words/hammer.$CA"
},
{
"description": "mower",
"image": "words/mower.png",
"voice": "voices-$CA/$LOCALE/words/mower.$CA"
},
{
"description": "needle",
"image": "words/needle.png",
"voice": "voices-$CA/$LOCALE/words/needle.$CA"
},
{
"description": "pliers",
"image": "words/pliers.png",
"voice": "voices-$CA/$LOCALE/words/pliers.$CA"
},
{
"description": "rake",
"image": "words/rake.png",
"voice": "voices-$CA/$LOCALE/words/rake.$CA"
},
{
"description": "scissors",
"image": "words/scissors.png",
"voice": "voices-$CA/$LOCALE/words/scissors.$CA"
},
{
"description": "screw",
"image": "words/screw.png",
"voice": "voices-$CA/$LOCALE/words/screw.$CA"
},
{
"description": "screwdriver",
"image": "words/screwdriver.png",
"voice": "voices-$CA/$LOCALE/words/screwdriver.$CA"
},
{
"description": "shovel",
"image": "words/shovel.png",
"voice": "voices-$CA/$LOCALE/words/shovel.$CA"
},
{
"description": "spade",
"image": "words/spade.png",
"voice": "voices-$CA/$LOCALE/words/spade.$CA"
},
{
"description": "spear",
"image": "words/spear.png",
"voice": "voices-$CA/$LOCALE/words/spear.$CA"
},
{
"description": "tape measure",
"image": "words/tape_measure.png",
"voice": "voices-$CA/$LOCALE/words/tape_measure.$CA"
},
{
"description": "tool",
"image": "words/tool.png",
"voice": "voices-$CA/$LOCALE/words/tool.$CA"
},
{
"description": "wedge",
"image": "words/wedge.png",
"voice": "voices-$CA/$LOCALE/words/wedge.$CA"
},
{
"description": "wrench",
"image": "words/wrench.png",
"voice": "voices-$CA/$LOCALE/words/wrench.$CA"
- },
- {
- "description": "trip",
- "image": "words/trip.png",
- "voice": "voices-$CA/$LOCALE/words/trip.$CA"
- },
+ }
+ ]
+ },
+ {
+ "type": "lesson",
+ "name": "transport",
+ "content": [
{
"description": "bike",
"image": "words/bike.png",
"voice": "voices-$CA/$LOCALE/words/bike.$CA"
},
{
"description": "boat",
"image": "words/boat.png",
"voice": "voices-$CA/$LOCALE/words/boat.$CA"
},
{
"description": "bus",
"image": "words/bus.png",
"voice": "voices-$CA/$LOCALE/words/bus.$CA"
},
{
"description": "canoe",
"image": "words/canoe.png",
"voice": "voices-$CA/$LOCALE/words/canoe.$CA"
},
{
"description": "car",
"image": "words/car.png",
"voice": "voices-$CA/$LOCALE/words/car.$CA"
},
- {
- "description": "engine",
- "image": "words/engine.png",
- "voice": "voices-$CA/$LOCALE/words/engine.$CA"
- },
{
"description": "motorcycle",
"image": "words/motorcycle.png",
"voice": "voices-$CA/$LOCALE/words/motorcycle.$CA"
},
{
"description": "parachute",
"image": "words/parachute.png",
"voice": "voices-$CA/$LOCALE/words/parachute.$CA"
},
- {
- "description": "pedal",
- "image": "words/pedal.png",
- "voice": "voices-$CA/$LOCALE/words/pedal.$CA"
- },
{
"description": "plane",
"image": "words/plane.png",
"voice": "voices-$CA/$LOCALE/words/plane.$CA"
},
- {
- "description": "porthole",
- "image": "words/porthole.png",
- "voice": "voices-$CA/$LOCALE/words/porthole.$CA"
- },
{
"description": "raft",
"image": "words/raft.png",
"voice": "voices-$CA/$LOCALE/words/raft.$CA"
},
- {
- "description": "rocket",
- "image": "words/rocket.png",
- "voice": "voices-$CA/$LOCALE/words/rocket.$CA"
- },
{
"description": "sail",
"image": "words/sail.png",
"voice": "voices-$CA/$LOCALE/words/sail.$CA"
},
{
"description": "ship",
"image": "words/ship.png",
"voice": "voices-$CA/$LOCALE/words/ship.$CA"
},
{
"description": "sled",
"image": "words/sled.png",
"voice": "voices-$CA/$LOCALE/words/sled.$CA"
},
{
"description": "taxi",
"image": "words/taxi.png",
"voice": "voices-$CA/$LOCALE/words/taxi.$CA"
},
{
"description": "train",
"image": "words/train.png",
"voice": "voices-$CA/$LOCALE/words/train.$CA"
},
{
"description": "truck",
"image": "words/truck.png",
"voice": "voices-$CA/$LOCALE/words/truck.$CA"
},
{
"description": "van",
"image": "words/van.png",
"voice": "voices-$CA/$LOCALE/words/van.$CA"
}
]
}
]
}
]
diff --git a/src/activities/lang/spell_it.js b/src/activities/lang/spell_it.js
index 2bbecd726..bd1f8423e 100644
--- a/src/activities/lang/spell_it.js
+++ b/src/activities/lang/spell_it.js
@@ -1,175 +1,175 @@
/* GCompris - spell_it.js
*
* Copyright (C) Siddhesh suthar <siddhesh.it@gmail.com> (Qt Quick port)
*
* Authors:
* Pascal Georges (pascal.georges1@free.fr) (GTK+ version)
* Holger Kaelberer <holger.k@elberer.de> (Qt Quick port of imageid)
* Siddhesh suthar <siddhesh.it@gmail.com> (Qt Quick port)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Integration Lang dataset)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
.import GCompris 1.0 as GCompris
.import "qrc:/gcompris/src/core/core.js" as Core
.import "qrc:/gcompris/src/activities/lang/lang_api.js" as Lang
var spellItems;
var wordList;
var remainingWords
// @return true if the quiz was ran
function init(loadedItems_, wordList_, mode_) {
spellItems = loadedItems_
wordList = wordList_
// Do not set the focus on mobile or the mobile OS keyboard will pop up
// instead of ours.
if(!GCompris.ApplicationInfo.isMobile)
spellItems.answer.forceActiveFocus()
initLevel()
return true
}
function initLevel() {
remainingWords = wordList.slice();
Core.shuffle(remainingWords)
spellItems.score.currentSubLevel = 0
spellItems.score.numberOfSubLevels = wordList.length
/* populate VirtualKeyboard for mobile:
* 1. for < 10 letters print them all in the same row
* 2. for > 10 letters create 3 rows with equal amount of keys per row
* if possible, otherwise more keys in the upper rows
*/
// first generate a map of needed letters
var letters = [];
for (var i = 0; i < wordList.length; i++) {
var currentWord = wordList[i].translatedTxt;
for (var j = 0; j < currentWord.length; j++) {
var letter = currentWord.charAt(j);
if(letters.indexOf(letter) === -1)
letters.push(currentWord.charAt(j));
}
}
letters = GCompris.ApplicationInfo.localeSort(letters, spellItems.locale);
// generate layout from letter map
var layout = [];
var row = 0;
var offset = 0;
while (offset < letters.length-1) {
var cols = letters.length <= 10
? letters.length
: (Math.ceil((letters.length-offset) / (3 - row)));
layout[row] = new Array();
for (var j = 0; j < cols; j++)
layout[row][j] = { label: letters[j+offset] };
offset += j;
row++;
}
layout[row-1].push({ label: spellItems.keyboard.backspace });
spellItems.keyboard.layout = layout;
initSubLevel()
}
function initSubLevel() {
spellItems.score.currentSubLevel++
spellItems.goodWord = wordList[spellItems.score.currentSubLevel - 1]
spellItems.wordImage.changeSource(spellItems.goodWord.image)
spellItems.hintText.changeHint(spellItems.goodWord.translatedTxt[0])
spellItems.hintText.visible = true
spellItems.answer.text = ""
spellItems.maximumLengthAnswer = spellItems.goodWord.translatedTxt.length + 1
}
function nextSubLevel() {
if(spellItems.score.currentSubLevel == spellItems.score.numberOfSubLevels ) {
spellItems.bonus.good("smiley")
} else {
initSubLevel();
}
}
function checkAnswer(answer_) {
if(spellItems.goodWord.translatedTxt == answer_) {
nextSubLevel()
return true
}
else {
badWordSelected(spellItems.score.currentSubLevel - 1, answer_)
}
}
// Append to the front of queue of words for the sublevel the error
function badWordSelected(wordIndex, answer) {
if (remainingWords[0] != wordIndex)
remainingWords.unshift(wordIndex);
provideHint(answer)
}
//function to construct hint based on the answer entered by user
function provideHint(answer_) {
var answer = answer_
var hint = ""
var firstIncorrectIndex = 0
for (var i=0 ; i< spellItems.goodWord.translatedTxt.length; i++) {
var goodChar = spellItems.goodWord.translatedTxt[i]
//skipping hint if the suggestion is a space
if( goodChar == " ") {
hint = hint + " "
continue
}
if( answer[i] == goodChar) {
hint = hint + goodChar
} else {
if(firstIncorrectIndex == 0) {
hint = hint + goodChar
firstIncorrectIndex = i
} else {
hint = hint + "."
}
}
}
spellItems.hintText.changeHint(hint)
spellItems.hintText.visible = true
}
// to handle virtual key board key press events
function processKeyPress(text_){
var answer = spellItems.answer
var text = text_
if ( text == spellItems.keyboard.backspace) {
backspace(answer)
return
}
answer.insert(answer.length,text)
}
function backspace(answer) {
answer.text = answer.text.slice(0, -1)
if(answer.text.length === 0) {
answer.text = ""
} else {
checkAnswer(answer.text)
}
}
diff --git a/src/activities/leftright/ActivityInfo.qml b/src/activities/leftright/ActivityInfo.qml
index 7120144db..935f55e00 100644
--- a/src/activities/leftright/ActivityInfo.qml
+++ b/src/activities/leftright/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "leftright/Leftright.qml"
difficulty: 2
icon: "leftright/leftright.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
//: Activity title
title: qsTr("Find your left and right hands")
//: Help title
description: qsTr("Determine if a hand is a right or a left hand")
// intro: "Guess if the picture presents a left or right hand and click on the correct answer."
//: Help goal
goal: qsTr("Distinguish right and left hands from different points of view. Spatial representation")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("You can see a hand: is it a left hand or a right hand? Click on the left button, or the right button depending on the displayed hand.")
credit: ""
section: "discovery"
createdInVersion: 0
}
diff --git a/src/activities/leftright/Leftright.qml b/src/activities/leftright/Leftright.qml
index 6a04b5594..dfd838f9a 100644
--- a/src/activities/leftright/Leftright.qml
+++ b/src/activities/leftright/Leftright.qml
@@ -1,201 +1,197 @@
/* GCompris - Leftright.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Pascal Georges <pascal.georges1@free.fr> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "leftright.js" as Activity
ActivityBase {
id: activity
onStart: focus = true;
pageComponent: Image {
id: background
source: "qrc:/gcompris/src/activities/leftright/resource/back.svg"
sourceSize.width: Math.max(parent.width, parent.height)
focus: true
signal start
signal stop
fillMode: Image.PreserveAspectCrop
QtObject {
id: items
property alias bar: bar
property alias bonus: bonus
property GCSfx audioEffects: activity.audioEffects
property alias imageAnimOff: imageAnimOff
property alias leftButton: leftButton
property alias rightButton: rightButton
property alias score: score
property bool buttonsBlocked: false
}
Keys.onLeftPressed: Activity.leftClickPressed()
Keys.onRightPressed: Activity.rightClickPressed()
Keys.enabled: !items.buttonsBlocked
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
onStart: { Activity.start(items) }
onStop: { Activity.stop() }
- Item {
- id: topBorder
- height: background.height * 0.08
- }
-
Image {
id: blackBoard
anchors.horizontalCenter: parent.horizontalCenter
- anchors.top: topBorder.bottom
+ anchors.top: score.bottom
fillMode: Image.PreserveAspectFit
sourceSize.width: Math.min(background.width,
(background.height - leftButton.height - bar.height) * 1.3)
source: "qrc:/gcompris/src/activities/leftright/resource/blackboard.svg"
Image {
id: handImage
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
fillMode: Image.PreserveAspectFit
scale: blackBoard.height / 300 * 0.8
opacity: 0
}
Image {
id: lightImage
source: "qrc:/gcompris/src/activities/leftright/resource/light.svg"
sourceSize.width: parent.width
sourceSize.height: parent.height
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
anchors.topMargin: 40
opacity: 0
}
ParallelAnimation {
id: imageAnimOff
onRunningChanged: {
if (!imageAnimOff.running) {
handImage.source = Activity.getCurrentHandImage()
handImage.rotation = Activity.getCurrentHandRotation()
imageAnimOn.start()
}
}
NumberAnimation {
target: handImage
property: "opacity"
from: 1; to: 0
duration: 300
easing.type: Easing.InOutQuad
}
NumberAnimation {
target: lightImage
property: "opacity"
from: 0.2; to: 0
duration: 300
easing.type: Easing.InOutQuad
}
}
ParallelAnimation {
id: imageAnimOn
onStopped: bonus.isPlaying ? items.buttonsBlocked = true : items.buttonsBlocked = false
NumberAnimation {
target: handImage
property: "opacity"
from: 0; to: 1.0
duration: 300
easing.type: Easing.InOutQuad
}
NumberAnimation {
target: lightImage
property: "opacity"
from: 0; to: 0.2
duration: 300
easing.type: Easing.InOutQuad
}
}
AnswerButton {
id: leftButton
width: blackBoard.width * 0.45
height: background.height * 0.15
anchors.left: blackBoard.left
anchors.top: blackBoard.bottom
anchors.margins: 10
textLabel: qsTr("Left hand")
audioEffects: activity.audioEffects
onPressed: items.buttonsBlocked = true
onCorrectlyPressed: Activity.leftClick()
blockAllButtonClicks: items.buttonsBlocked
onIncorrectlyPressed: items.buttonsBlocked = false
}
AnswerButton {
id: rightButton
width: blackBoard.width * 0.45
height: background.height * 0.15
anchors.right: blackBoard.right
anchors.top: blackBoard.bottom
anchors.margins: 10
audioEffects: activity.audioEffects
textLabel: qsTr("Right hand")
onPressed: items.buttonsBlocked = true
onCorrectlyPressed: Activity.rightClick()
blockAllButtonClicks: items.buttonsBlocked
onIncorrectlyPressed: items.buttonsBlocked = false
}
}
DialogHelp {
id: dialogHelpLeftRight
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level }
onHelpClicked: {
displayDialog(dialogHelpLeftRight)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: home()
}
Bonus {
id: bonus
onStart: items.buttonsBlocked = true
onStop: items.buttonsBlocked = false
}
Score {
id: score
anchors.top: background.top
+ anchors.topMargin: parent.height * 0.01
anchors.bottom: undefined
}
}
}
diff --git a/src/activities/leftright/leftright.js b/src/activities/leftright/leftright.js
index 1c1245755..a965ace93 100644
--- a/src/activities/leftright/leftright.js
+++ b/src/activities/leftright/leftright.js
@@ -1,174 +1,174 @@
/* GCompris - leftright.js
*
* Copyright (C) 2014 Bruno Coudoin
*
* Authors:
* Pascal Georges <pascal.georges1@free.fr> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.import QtQuick 2.6 as Quick
.import "qrc:/gcompris/src/core/core.js" as Core
var currentHands = []
var levels = [
{ "images": [
"main_droite_dessus_0.png",
"main_droite_paume_0.png" ,
"main_gauche_dessus_0.png",
"main_gauche_paume_0.png" ],
"rotations": [-90]
},
{ "images": [
"main_droite_dessus_0.png",
"main_droite_paume_0.png",
"main_gauche_dessus_0.png",
"main_gauche_paume_0.png" ],
"rotations": [0, 180]
},
{ "images": [
"main_droite_dessus_0.png",
"main_droite_paume_0.png",
"main_gauche_dessus_0.png",
"main_gauche_paume_0.png" ],
"rotations": [90]
},
{ "images": [
"poing_droit_dessus_0.png",
"poing_droit_paume_0.png",
"poing_gauche_dessus_0.png",
"poing_gauche_paume_0.png" ],
"rotations": [-90]
},
{ "images": [
"poing_droit_dessus_0.png",
"poing_droit_paume_0.png",
"poing_gauche_dessus_0.png",
"poing_gauche_paume_0.png" ],
"rotations": [0, 180]
},
{ "images": [
"poing_droit_dessus_0.png",
"poing_droit_paume_0.png",
"poing_gauche_dessus_0.png",
"poing_gauche_paume_0.png" ],
"rotations": [90]
},
]
var currentImageId;
var currentLevel;
var items
function start(items_) {
items = items_
currentLevel = 0
items.score.currentSubLevel = 1
initLevel()
}
function stop() {
}
function initLevel() {
items.bar.level = currentLevel + 1
currentImageId = 0
currentHands = new Array()
var level = levels[currentLevel]
var counter = 0
for (var i = 0 ; i < level.images.length ; i++) {
for (var r = 0 ; r < level.rotations.length ; r++) {
currentHands[counter++] = {
'image': level.images[i],
'rotation': level.rotations[r] }
}
}
items.score.numberOfSubLevels = level.images.length * level.rotations.length
currentHands = Core.shuffle(currentHands)
displayHand()
}
function nextLevel() {
if(levels.length <= ++currentLevel ) {
currentLevel = 0
}
items.score.currentSubLevel = 1
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = levels.length - 1
}
items.score.currentSubLevel = 1
initLevel();
}
function displayHand() {
items.leftButton.isCorrectAnswer = isLeft()
items.rightButton.isCorrectAnswer = isRight()
items.imageAnimOff.start()
}
function getCurrentHandImage() {
return "qrc:/gcompris/src/activities/leftright/resource/" +
currentHands[currentImageId].image
}
function getCurrentHandRotation() {
return currentHands[currentImageId].rotation
}
function displayNextHand() {
items.score.currentSubLevel ++
items.score.playWinAnimation();
if(currentHands.length <= ++currentImageId ) {
items.bonus.good("flower")
nextLevel()
}
displayHand()
}
function isLeft() {
return (currentHands[currentImageId].image.indexOf("gauche") !== -1) ? true : false
}
function leftClick() {
if(isLeft()) {
displayNextHand()
}
}
function isRight() {
return (currentHands[currentImageId].image.indexOf("droit") !== -1) ? true : false
}
function rightClick() {
if(isRight()) {
displayNextHand()
}
}
function leftClickPressed() {
items.leftButton.pressed()
}
function rightClickPressed() {
items.rightButton.pressed()
}
diff --git a/src/activities/letter-in-word/ActivityInfo.qml b/src/activities/letter-in-word/ActivityInfo.qml
index e31abd5cd..bbc17dd2b 100644
--- a/src/activities/letter-in-word/ActivityInfo.qml
+++ b/src/activities/letter-in-word/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2016 Akshat Tandon <akshat.tandon@research.iiit.ac.in>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "letter-in-word/LetterInWord.qml"
difficulty: 2
icon: "letter-in-word/letter-in-word.svg"
author: "Akshat Tandon &lt;akshat.tandon@research.iiit.ac.ins&gt;"
demo: true
//: Activity title
title: qsTr("Letter in which word")
//: Help title
description: qsTr("A letter is written and/or spoken. Some words are displayed, the children must find the word or the words in which this letter appears.")
//intro: "Click on all the words containing the wanted letter."
//: Help goal
goal: qsTr("Select all the words which contain the spoken letter.")
//: Help prerequisite
prerequisite: qsTr("spellings, letter recognition")
//: Help manual
- manual: ""
+ manual: qsTr("A letter is displayed on the flag attached to the plane, select all the words or the objects in which the letter appears and then press OK.")
credit: ""
section: "reading"
createdInVersion: 7000
}
diff --git a/src/activities/letter-in-word/Card.qml b/src/activities/letter-in-word/Card.qml
index 1ed885ef2..4792937d7 100644
--- a/src/activities/letter-in-word/Card.qml
+++ b/src/activities/letter-in-word/Card.qml
@@ -1,162 +1,162 @@
/* GCompris - Card.qml
*
* Copyright (C) 2016 Akshat Tandon <akshat.tandon@research.iiit.ac.in>
*
* Authors:
* Akshat Tandon <akshat.tandon@research.iiit.ac.in>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import QtGraphicalEffects 1.0
import "../../core"
import "letter-in-word.js" as Activity
Item {
id: cardItem
height: wordPic.height + cardImage.height - 30 * ApplicationInfo.ratio
property bool mouseActive: true
Image {
id: wordPic
sourceSize.width: cardItem.width - 6
sourceSize.height: cardItem.width - 5
fillMode: Image.PreserveAspectFit
source: imgurl
z: -5
}
Image {
id: tick
source: "qrc:/gcompris/src/core/resource/apply.svg"
sourceSize.width: cardImage.width / 3
sourceSize.height: cardImage.width / 3
visible: false
anchors {
leftMargin: cardItem.right - 0.01
bottomMargin: parent.top - 10
}
}
Image {
id: cardImage
anchors.top: wordPic.bottom
anchors.topMargin: -30 * ApplicationInfo.ratio
sourceSize.width: cardItem.width - 10
fillMode: Image.PreserveAspectFit
source: Activity.resUrl2 + "cloud.svg"
z: (state == 'marked') ? 1 : -1
GCText {
id: textItem
z: 11
// textFound is the rich text with letter found, spelling is the text in the dataset
text:"<font color=\"#2a2a2a\">" + (selected ? textFound : spelling) + "</font>"
property string textFound: spelling
textFormat: Text.RichText
font.pointSize: NaN // need to clear font.pointSize explicitly
font.pixelSize: spelling.length > 5 ? (spelling.length > 7 ? cardImage.width * 0.19 : cardImage.width * 0.25): cardImage.width * 0.30
font.bold: true
style: Text.Outline
width: cardImage.width
height: cardImage.height
wrapMode: spelling.indexOf(' ') === -1 ? Text.WrapAnywhere : Text.WordWrap
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
styleColor: "white"
}
states:
State {
name: "marked"; when: selected && mouseActive
PropertyChanges {
target: tick
visible: true
}
}
SequentialAnimation {
id: successAnimation
running: selected
loops: 2
NumberAnimation {
target: cardImage
easing.type: Easing.InOutQuad
property: "rotation"
to: 20; duration: 500
}
NumberAnimation {
target: cardImage
easing.type: Easing.InOutQuad
property: "rotation"; to: -20
duration: 500
}
onRunningChanged: {
if(!running && selected) {
rotationStop.restart()
}
}
}
SequentialAnimation {
id: failureAnimation
NumberAnimation {
target: cardImage
property: "opacity"
to: 1; duration: 400
}
}
NumberAnimation {
id: rotationStop
running: !selected
target: cardImage
property: "rotation"
to: 0
duration: 500
easing.type: Easing.Linear
}
}
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: ApplicationInfo.isMobile ? false : true
onClicked: {
select();
}
}
function playWord() {
var locale = ApplicationInfo.getVoicesLocale(items.locale)
activity.audioVoices.append(
ApplicationInfo.getAudioFilePathForLocale(voice, locale))
}
function select() {
if(mouseActive && !successAnimation.running) {
if (Activity.checkWord(index)) {
successAnimation.restart();
if(selected)
playWord();
}
else {
failureAnimation.restart()
}
}
}
}
diff --git a/src/activities/letter-in-word/LetterInWord.qml b/src/activities/letter-in-word/LetterInWord.qml
index dc51c7228..c404f3c53 100644
--- a/src/activities/letter-in-word/LetterInWord.qml
+++ b/src/activities/letter-in-word/LetterInWord.qml
@@ -1,434 +1,434 @@
/* GCompris - LetterInWord.qml
*
* Copyright (C) 2014 Holger Kaelberer <holger.k@elberer.de>
* 2016 Akshat Tandon <akshat.tandon@research.iiit.ac.in>
*
* Authors:
* Holger Kaelberer <holger.k@elberer.de> (Click on Letter - Qt Quick port)
* Akshat Tandon <akshat.tandon@research.iiit.ac.in> (Modifications to Click on Letter code
* to make Letter in which word activity)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import QtGraphicalEffects 1.0
import QtQuick.Controls 1.5
import GCompris 1.0
import "../../core"
import "letter-in-word.js" as Activity
import "qrc:/gcompris/src/core/core.js" as Core
ActivityBase {
id: activity
focus: true
onStart: focus = true
pageComponent: Image {
id: background
source: Activity.resUrl + "hillside.svg"
sourceSize.width: parent.width
fillMode: Image.PreserveAspectCrop
focus: true
// system locale by default
property string locale: "system"
property bool englishFallback: false
property bool keyboardMode: false
signal start
signal stop
signal voiceError
Component.onCompleted: {
dialogActivityConfig.getInitialConfiguration()
activity.start.connect(start)
activity.stop.connect(stop)
}
QtObject {
id: items
property Item main: activity.main
property alias bar: bar
property alias background: background
property alias wordsModel: wordsModel
property int currentLetterCase: ApplicationSettings.fontCapitalization
property int currentMode: normalModeWordCount
readonly property int easyModeWordCount: 5
readonly property int normalModeWordCount: 11
property GCAudio audioVoices: activity.audioVoices
property alias parser: parser
property alias animateX: animateX
property alias repeatItem: repeatItem
property alias score: score
property alias bonus: bonus
property alias locale: background.locale
property alias questionItem: questionItem
property alias englishFallbackDialog: englishFallbackDialog
property string question
}
onStart: {
activity.audioVoices.error.connect(voiceError)
Activity.start(items);
}
onStop: Activity.stop()
onWidthChanged: {
animateX.restart();
}
onHeightChanged: {
animateX.restart();
}
ExclusiveGroup {
id: configOptions
}
DialogActivityConfig {
id: dialogActivityConfig
currentActivity: activity
content: Component {
Item {
property alias localeBox: localeBox
property alias easyModeConfig: easyModeConfig
property alias normalModeConfig: normalModeConfig
property alias letterCaseBox: letterCaseBox
height: column.height
property alias availableLangs: langs.languages
LanguageList {
id: langs
}
Column {
id: column
spacing: 10
width: dialogActivityConfig.width
height: dialogActivityConfig.height
GCDialogCheckBox {
id: normalModeConfig
width: column.width - 50
text: qsTr("All words")
checked: (items.currentMode === items.normalModeWordCount) ? true : false
exclusiveGroup: configOptions
}
GCDialogCheckBox {
id: easyModeConfig
width: column.width - 50
text: qsTr("Only 5 words")
checked: (items.currentMode === items.easyModeWordCount) ? true : false
exclusiveGroup: configOptions
}
Flow {
spacing: 5
width: dialogActivityConfig.width
GCComboBox {
id: letterCaseBox
label: qsTr("Select case for letter to be searched")
background: dialogActivityConfig
model: [
{"text": qsTr("Mixed Case"), "value": Font.MixedCase},
{"text": qsTr("Upper Case"), "value": Font.AllUppercase},
{"text": qsTr("Lower Case"), "value": Font.AllLowercase}
]
currentText: model[items.currentLetterCase].text
currentIndex: items.currentLetterCase
}
}
Flow {
spacing: 5
width: dialogActivityConfig.width
GCComboBox {
id: localeBox
model: langs.languages
background: dialogActivityConfig
label: qsTr("Select your locale")
}
}
}
}
}
onClose: home()
onLoadData: {
if(dataToSave && dataToSave["savedMode"]) {
items.currentMode = dataToSave["savedMode"] === "5" ? items.easyModeWordCount : items.normalModeWordCount
}
if(dataToSave && dataToSave["savedLetterCase"]) {
items.currentLetterCase = dataToSave["savedLetterCase"]
}
if(dataToSave && dataToSave["locale"]) {
background.locale = dataToSave["locale"];
}
}
onSaveData: {
var oldLocale = background.locale;
var newLocale =
dialogActivityConfig.configItem.availableLangs[dialogActivityConfig.loader.item.localeBox.currentIndex].locale;
// Remove .UTF-8
if(newLocale.indexOf('.') != -1) {
newLocale = newLocale.substring(0, newLocale.indexOf('.'))
}
var oldMode = items.currentMode
items.currentMode = dialogActivityConfig.loader.item.easyModeConfig.checked ? items.easyModeWordCount : items.normalModeWordCount
var oldLetterCase = items.currentLetterCase
items.currentLetterCase = dialogActivityConfig.loader.item.letterCaseBox.model[dialogActivityConfig.loader.item.letterCaseBox.currentIndex].value
dataToSave = {"locale": newLocale, "savedMode": items.currentMode, "savedLetterCase": items.currentLetterCase}
background.locale = newLocale;
// Restart the activity with new information
if(oldLocale !== newLocale || oldMode !== items.currentMode || oldLetterCase !== items.currentLetterCase) {
background.stop();
background.start();
}
}
function setDefaultValues() {
var localeUtf8 = background.locale;
if(background.locale != "system") {
localeUtf8 += ".UTF-8";
}
for(var i = 0 ; i < dialogActivityConfig.configItem.availableLangs.length ; i ++) {
if(dialogActivityConfig.configItem.availableLangs[i].locale === localeUtf8) {
dialogActivityConfig.loader.item.localeBox.currentIndex = i;
break;
}
}
}
}
DialogHelp {
id: dialogHelpLeftRight
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level | config }
onHelpClicked: {
displayDialog(dialogHelpLeftRight)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: home()
onConfigClicked: {
dialogActivityConfig.active = true
dialogActivityConfig.setDefaultValues()
displayDialog(dialogActivityConfig)
}
}
Score {
id: score
anchors.top: parent.top
anchors.topMargin: 10 * ApplicationInfo.ratio
anchors.left: parent.left
anchors.leftMargin: 10 * ApplicationInfo.ratio
anchors.bottom: undefined
anchors.right: undefined
}
Bonus {
id: bonus
interval: 100
Component.onCompleted: {
win.connect(Activity.nextSubLevel);
}
}
Item {
id: planeText
width: plane.width
height: plane.height
x: -width
anchors.top: parent.top
anchors.topMargin: 5 * ApplicationInfo.ratio
Image {
id: plane
anchors.centerIn: planeText
anchors.top: parent.top
source: Activity.resUrl + "plane.svg"
sourceSize.height: itemHeight
}
GCText {
id: questionItem
anchors {
right: planeText.right
rightMargin: 2 * plane.width / 3
verticalCenter: planeText.verticalCenter
bottomMargin: 10 * ApplicationInfo.ratio
}
fontSize: hugeSize
font.weight: Font.DemiBold
color: "#2a2a2a"
text: items.question
}
PropertyAnimation {
id: animateX
target: planeText
properties: "x"
from: -planeText.width
//to:background.width/2 - planeText.width/2
to: bar.level <= 2 ? background.width/3.7 : background.width
duration: bar.level <= 2 ? 5500: 11000
//easing.type: Easing.OutQuad
easing.type: bar.level <= 2 ? Easing.OutQuad: Easing.OutInCirc
}
}
BarButton {
id: repeatItem
source: "qrc:/gcompris/src/core/resource/bar_repeat.svg"
sourceSize.width: 80 * ApplicationInfo.ratio
anchors {
top: parent.top
right: parent.right
margins: 10
}
onClicked:{
Activity.playLetter(Activity.currentLetter);
animateX.restart();
}
}
Keys.onPressed: {
if(event.key === Qt.Key_Space) {
wordsView.currentItem.select()
}
}
Keys.onReleased: {
keyboardMode = true
event.accepted = false
}
Keys.onEnterPressed: wordsView.currentItem.select();
Keys.onReturnPressed: wordsView.currentItem.select();
Keys.onRightPressed: wordsView.moveCurrentIndexRight();
Keys.onLeftPressed: wordsView.moveCurrentIndexLeft();
Keys.onDownPressed: wordsView.moveCurrentIndexDown();
Keys.onUpPressed: wordsView.moveCurrentIndexUp();
ListModel {
id: wordsModel
}
property int itemWidth: Math.min(parent.width / 7.5, parent.height / 6.5)
property int itemHeight: itemWidth * 1.11
GridView {
id: wordsView
anchors.bottom: bar.top
anchors.left: parent.left
anchors.right: parent.right
anchors.top: planeText.bottom
anchors.topMargin: 10 * ApplicationInfo.ratio
anchors.leftMargin: 15 * ApplicationInfo.ratio
anchors.rightMargin: 15 * ApplicationInfo.ratio
anchors.bottomMargin: 10 * ApplicationInfo.ratio
cellWidth: itemWidth + 25 * ApplicationInfo.ratio
cellHeight: itemHeight + 15 * ApplicationInfo.ratio
clip: false
interactive: false
//verticalLayoutDirection: GridView.BottomToTop
layoutDirection: Qt.LeftToRight
keyNavigationWraps: true
model: wordsModel
delegate: Card {
width: background.itemWidth
Connections {
target: bonus
onStart: {
mouseActive = false;
}
onStop: {
mouseActive = true;
}
}
}
highlight: Rectangle {
width: wordsView.cellWidth - wordsView.spacing
height: wordsView.cellHeight - wordsView.spacing
color: "#AAFFFFFF"
border.width: 3
border.color: "black"
visible: background.keyboardMode
Behavior on x { SpringAnimation { spring: 2; damping: 0.2 } }
Behavior on y { SpringAnimation { spring: 2; damping: 0.2 } }
}
}
BarButton {
id: ok
source: "qrc:/gcompris/src/core/resource/bar_ok.svg"
width: wordsView.cellWidth*0.8
height: width
sourceSize.width: wordsView.cellWidth
anchors {
right: parent.right
rightMargin: 3 * ApplicationInfo.ratio
bottom: wordsView.bottom
}
MouseArea {
anchors.fill: parent
onClicked: {
Activity.checkAnswer();
}
}
}
JsonParser {
id: parser
onError: console.error("Click_on_letter: Error parsing JSON: " + msg);
}
Loader {
id: englishFallbackDialog
sourceComponent: GCDialog {
parent: activity.main
message: qsTr("We are sorry, we don't have yet a translation for your language.") + " " +
- qsTr("GCompris is developed by the KDE community, you can translate GCompris by joining a translation team on <a href=\"%2\">%2</a>").arg("http://l10n.kde.org/") +
+ qsTr("GCompris is developed by the KDE community, you can translate GCompris by joining a translation team on <a href=\"%2\">%2</a>").arg("https://l10n.kde.org/") +
"<br /> <br />" +
qsTr("We switched to English for this activity but you can select another language in the configuration dialog.")
onClose: background.englishFallback = false
}
anchors.fill: parent
focus: true
active: background.englishFallback
onStatusChanged: if (status == Loader.Ready) item.start()
}
}
}
diff --git a/src/activities/letter-in-word/letter-in-word.js b/src/activities/letter-in-word/letter-in-word.js
index df984a5df..05f6e2e11 100644
--- a/src/activities/letter-in-word/letter-in-word.js
+++ b/src/activities/letter-in-word/letter-in-word.js
@@ -1,237 +1,237 @@
/* GCompris - letter-in-word.js
*
* Copyright (C) 2014 Holger Kaelberer
* 2016 Akshat Tandon
*
* Authors:
* Holger Kaelberer <holger.k@elberer.de> (Qt Quick port of click-on-letter)
* Akshat Tandon <akshat.tandon@research.iiit.ac.in>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
.import GCompris 1.0 as GCompris //for ApplicationInfo
.import "qrc:/gcompris/src/core/core.js" as Core
.import "qrc:/gcompris/src/activities/lang/lang_api.js" as Lang
var url = "qrc:/gcompris/src/activities/letter-in-word/resource/"
var resUrl = "qrc:/gcompris/src/activities/braille_fun/resource/"
var resUrl2 = "qrc:/gcompris/src/activities/click_on_letter/resource/"
var levels;
var currentLevel;
var maxLevel;
var currentSubLevel;
var currentLetter;
var maxSubLevel;
var questions;
var words;
var items;
var dataset = null;
var frequency;
var incorrectFlag = false;
var locale;
function start(_items) {
Core.checkForVoices(_items.main);
items = _items;
// register the voices for the locale
locale = GCompris.ApplicationInfo.getVoicesLocale(items.locale)
GCompris.DownloadManager.updateResource(GCompris.DownloadManager.getVoicesResourceForLocale(locale))
loadDataset();
levels = Lang.getAllLessons(dataset)
currentLevel = 0;
currentSubLevel = 0;
maxLevel = levels.length;
initLevel();
}
function loadDataset() {
var resourceUrl = "qrc:/gcompris/src/activities/lang/resource/"
var data = Lang.loadDataset(items.parser, resourceUrl, locale);
dataset = data["dataset"];
items.background.englishFallback = data["englishFallback"];
}
function stop() {
items.animateX.stop()
}
function shuffleString(s) {
var a = s;
var n = a.length;
for(var i = n-1; i > 0; --i) {
var j = Math.floor(Math.random() * (i + 1));
var tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
return a.join("");
}
function initLevel() {
items.bar.level = currentLevel + 1;
if (currentSubLevel == 0 && !incorrectFlag) {
var level = levels[currentLevel];
words = Lang.getLessonWords(dataset, level);
Core.shuffle(words);
var limit = Math.min(items.currentMode, words.length);
words = words.slice(0, limit);
frequency = calculateFrequency();
var tempQuestions = generateQuestions();
maxSubLevel = tempQuestions.length;
items.score.numberOfSubLevels = maxSubLevel;
items.score.currentSubLevel = 1;
questions = shuffleString(tempQuestions);
items.wordsModel.clear();
for (var i = 0; i < words.length; i++) {
items.wordsModel.append({
"spelling": words[i].translatedTxt,
"imgurl": words[i].image,
"selected": false,
"voice": words[i].voice
});
}
}
else {
items.score.currentSubLevel = currentSubLevel + 1;
}
incorrectFlag = false;
for(var i = 0; i < words.length; i++) {
items.wordsModel.setProperty(i, "selected", false);
}
currentLetter = questions[currentSubLevel];
items.question = currentLetter;
items.animateX.restart();
if(items.currentLetterCase == Quick.Font.MixedCase) {
items.questionItem.font.capitalization = (Math.floor(Math.random() * 2) < 1) ? Quick.Font.AllLowercase : Quick.Font.AllUppercase
}
else {
items.questionItem.font.capitalization = items.currentLetterCase
}
if (GCompris.ApplicationSettings.isAudioVoicesEnabled &&
GCompris.DownloadManager.haveLocalResource(
GCompris.DownloadManager.getVoicesResourceForLocale(locale))) {
items.audioVoices.silence(100)
playLetter(currentLetter)
}
}
function calculateFrequency() {
var freq = [];
- //regex pattern to detect whether the character is an english alphabet or some accented latin chacarcter
+ //regex pattern to detect whether the character is an english alphabet or some accented latin character
var pattern = /[A-Za-z\u00C0-\u017F]/;
for(var i = 0; i < words.length; i++) {
var currentWord = words[i].translatedTxt;
for(var j = 0; j < currentWord.length; j++) {
var character = currentWord.charAt(j);
//consider the character if and only if it is an alphabet or an accented latin character
if(pattern.test(character)) {
if(freq[character]) {
freq[character]++;
}
else {
freq[character] = 1;
}
}
}
}
return freq;
}
function generateQuestions() {
var freqArr = [];
var ques = [];
for(var character in frequency) {
freqArr.push([character, frequency[character]]);
}
freqArr.sort(function(a, b) {return b[1] - a[1]});
var limit = Math.min(10, freqArr.length);
for(var i = 0; i < limit; i++) {
ques.push(freqArr[i][0])
}
return ques;
}
function playLetter(letter) {
items.audioVoices.append(GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/"+locale+"/alphabet/"
+ Core.getSoundFilenamForChar(letter)))
}
function nextLevel() {
items.audioVoices.clearQueue()
if(maxLevel <= ++currentLevel) {
currentLevel = 0
}
currentSubLevel = 0;
initLevel();
}
function previousLevel() {
items.audioVoices.clearQueue()
if(--currentLevel < 0) {
currentLevel = maxLevel - 1
}
currentSubLevel = 0;
initLevel();
}
function nextSubLevel() {
if( ++currentSubLevel >= maxSubLevel) {
currentSubLevel = 0
nextLevel()
}
initLevel();
}
function checkAnswer() {
var allCorrectSelected = true
var modelEntry;
var letterIndex;
for(var i = 0; i < words.length; i++) {
modelEntry = items.wordsModel.get(i);
letterIndex = modelEntry.spelling.indexOf(currentLetter);
if(letterIndex != -1 && modelEntry.selected == false) {
allCorrectSelected = false;
break;
}
if(letterIndex == -1 && modelEntry.selected == true) {
allCorrectSelected = false;
break;
}
}
if(allCorrectSelected == true) {
items.bonus.good("flower");
}
else {
items.bonus.bad("flower");
}
}
function checkWord(index) {
var modelEntry = items.wordsModel.get(index);
items.wordsModel.setProperty(index, "selected", !modelEntry.selected);
return modelEntry.selected;
}
diff --git a/src/activities/lightsoff/ActivityInfo.qml b/src/activities/lightsoff/ActivityInfo.qml
index e2c299d1d..bfec4d233 100644
--- a/src/activities/lightsoff/ActivityInfo.qml
+++ b/src/activities/lightsoff/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Stephane Mankowski <stephane@mankowski.fr>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "lightsoff/Lightsoff.qml"
difficulty: 6
icon: "lightsoff/lightsoff.svg"
author: "Stephane Mankowski &lt;stephane@mankowski.fr&gt;"
demo: true
//: Activity title
title: qsTr("Lights Off")
//: Help title
description: qsTr("The aim is to switch off all the lights.")
// intro: "Click on the lamps to turn them off."
//: Help goal
goal: qsTr("The aim is to switch off all the lights.")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("The effect of pressing a button is to toggle the state of that button, and of its immediate vertical and horizontal neighbors. The sun and the color of the sky depend on the number of clicks needed to solve the puzzle. If you click on Tux, the solution is shown.")
credit: qsTr("The solver algorithm is described on Wikipedia. To know more about the Lights Off game: &lt;http://en.wikipedia.org/wiki/Lights_Out_(game)&gt;")
section: "puzzle"
createdInVersion: 0
}
diff --git a/src/activities/lightsoff/Lightsoff.qml b/src/activities/lightsoff/Lightsoff.qml
index 5d6c32796..51155a231 100644
--- a/src/activities/lightsoff/Lightsoff.qml
+++ b/src/activities/lightsoff/Lightsoff.qml
@@ -1,249 +1,249 @@
/* GCompris - lightsoff.qml
*
* Copyright (C) 2014 Stephane Mankowski <stephane@mankowski.fr>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Stephane Mankowski <stephane@mankowski.fr> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
import "lightsoff.js" as Activity
ActivityBase {
id: activity
onStart: focus = true
onStop: {
}
pageComponent: Rectangle {
id: background
color: "blue"
anchors.fill: parent
signal start
signal stop
property bool keyNavigationVisible: false
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property alias background: background
property alias bar: bar
property alias bonus: bonus
property alias skyColor: background.color
property alias modelTable: modelTable
property bool blockClicks: false
property int nbCell: 5
property int cellSize: Math.min(
(parent.height - 200) / items.nbCell,
(parent.width - 40) / items.nbCell)
property int nbCelToWin: 0
}
onStart: {
Activity.start(items)
}
onStop: {
Activity.stop()
}
Keys.enabled: !items.blockClicks
Keys.onPressed: {
background.keyNavigationVisible = true
if (event.key === Qt.Key_Left)
grid.moveCurrentIndexLeft()
if (event.key === Qt.Key_Right)
grid.moveCurrentIndexRight()
if (event.key === Qt.Key_Down)
grid.moveCurrentIndexDown()
if (event.key === Qt.Key_Up)
grid.moveCurrentIndexUp()
if (event.key === Qt.Key_Space || event.key === Qt.Key_Enter || event.key === Qt.Key_Return)
Activity.windowPressed(grid.currentIndex)
}
/* The background picture */
Image {
source: Activity.url + "back.svg"
anchors.bottom: parent.bottom
fillMode: Image.TileHorizontally
sourceSize.height: (parent.height - (gridarea.y + gridarea.height)) * 1.2
z: 2
}
Image {
source: Activity.url + "building.svg"
fillMode: Image.PreserveAspectFit
anchors.fill: gridarea
anchors.margins: -1 * Math.ceil(items.nbCell / 2) * items.cellSize
z: 2
}
Image {
source: Activity.url + "front.svg"
anchors.bottom: parent.bottom
fillMode: Image.TileHorizontally
sourceSize.height: 20 + tux.height * 0.5
z: 999
}
/* The sun */
Image {
id: sun
source: Activity.url + "sun.svg"
sourceSize.height: items.cellSize * 2 * items.nbCell / 5
anchors {
left: parent.left
leftMargin: 10
bottom: parent.bottom
bottomMargin: parent.height / 3 + 2 / 3 * parent.height
* items.nbCelToWin / (items.nbCell * items.nbCell)
}
z: 1
Behavior on anchors.bottomMargin {
PropertyAnimation {
duration: 1000
}
}
}
/* Tux */
BarButton {
id: tux
fillMode: Image.PreserveAspectFit
source: Activity.url + "tux.svg"
sourceSize.width: parent.width - grid.width < 200 ?
bar.height * 1.2 :
Math.min((parent.width - grid.width - 40) / 2, 150)
z: 3
visible: true
anchors {
right: parent.right
rightMargin: 20
bottom: parent.bottom
bottomMargin: 20
}
onClicked: Activity.solve()
}
/* The grid */
Rectangle {
id: gridarea
anchors.fill: grid
anchors.margins: items.cellSize / -10
opacity: 0
z: 4
}
GridView {
id: grid
anchors.top: parent.top
anchors.topMargin: (parent.height - height) / 6
anchors.horizontalCenter: parent.horizontalCenter
width: items.nbCell * items.cellSize
height: width
cellWidth: items.cellSize
cellHeight: items.cellSize
z: 5
ListModel {
id: modelTable
}
model: modelTable
delegate: Rectangle {
color: "transparent"
height: items.cellSize
width: items.cellSize
border {
color: soluce === 1 ? "red" : "transparent"
width: items.cellSize / 40
}
radius: items.cellSize / 10
BarButton {
anchors.fill: parent
fillMode: Image.PreserveAspectFit
source: Activity.url + "off.svg"
sourceSize.height: items.cellSize
mouseArea.hoverEnabled: !items.blockClicks
mouseArea.enabled: !items.blockClicks
onClicked: Activity.windowPressed(index)
visible: true
Image {
anchors.fill: parent
fillMode: Image.PreserveAspectFit
source: Activity.url + "on.svg"
opacity: lighton === 1 ? 1 : 0
sourceSize.height: items.cellSize
Behavior on opacity {
PropertyAnimation {
duration: 200
}
}
}
}
}
interactive: false
keyNavigationWraps: true
highlightFollowsCurrentItem: true
highlight: Rectangle {
width: items.cellSize
height: items.cellSize
color: "#AAFFFFFF"
radius: items.cellSize / 10
visible: background.keyNavigationVisible
Behavior on x { SpringAnimation { spring: 2; damping: 0.2 } }
Behavior on y { SpringAnimation { spring: 2; damping: 0.2 } }
}
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: BarEnumContent {
value: help | home | level | reload
}
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
onReloadClicked: Activity.initLevel()
}
Bonus {
id: bonus
onStop: items.blockClicks = false
Component.onCompleted: win.connect(Activity.nextLevel)
}
}
}
diff --git a/src/activities/lightsoff/lightsoff.js b/src/activities/lightsoff/lightsoff.js
index 72c4baa0f..2a12a029a 100644
--- a/src/activities/lightsoff/lightsoff.js
+++ b/src/activities/lightsoff/lightsoff.js
@@ -1,268 +1,268 @@
/* GCompris - lightsoff.js
*
* Copyright (C) 2014 Stephane Mankowski <stephane@mankowski.fr>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Stephane Mankowski <stephane@mankowski.fr> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
var levels = [[0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0], // 1
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // 1 soluce
[1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // 2
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], // 2 soluce
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0], // 3
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], // 3 soluce
[1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1], // 4
[1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0], // 4 soluce
[0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0], // 5
[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0], // 5 soluce
[1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1], // 6
[1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1], // 6 soluce
[0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1], // 7
[0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1], // 7 soluce
[1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0], // 8
[0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1], // 8 soluce
[1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0], // 9
[1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0], // 9 soluce
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], // 10
[1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1], // 10 soluce
[0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0], // 11
[1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1], // 11 soluce
[0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0], // 12
[1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0], // 12 soluce
[0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0], // 13
[0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0], // 13 soluce
[1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1], // 14
[0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0], // 14 soluce
[1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1], // 15
[1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1], // 15 soluce
[1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1], // 16
[1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1], // 16 soluce
[0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0], // 17
[0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0], // 17 soluce
[1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1], // 18
[1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1], // 18 soluce
[1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1], // 19
[1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1], // 19 soluce
[1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1], // 20
[0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0], // 20 soluce
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], // 21
[0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0], // 21 soluce
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1], // 22
[1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0], // 22 soluce
[1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1], // 23
[0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1], // 23 soluce
[1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1], // 24
[1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1], // 24 soluce
[1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1], // 25
[1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0], // 25 soluce
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1], // 26
[0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0], // 26 soluce
[1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1], // 27
[0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1], // 27 soluce
[1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1], // 28
[1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1], // 28 soluce
[0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0], // 29
[0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0], // 29 soluce
[0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0], // 30
[1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0], // 30 soluce
[0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1], // 31
[1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1], // 31 soluce
[1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1], // 32
[1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1], // 32 soluce
[1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1], // 33
[0, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0], // 33 soluce
[0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0], // 34
[1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0], // 34 soluce
[0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1], // 35
[1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0], // 35 soluce
[1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1], // 36
[1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0], // 36 soluce
[0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0], // 37
[0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1], // 37 soluce
[0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0], // 38
[0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1], // 38 soluce
[1, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0], // 39
[1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1], // 39 soluce
[1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0], // 40
[0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0], // 40 soluce
[1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0], // 41
[0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0], // 41 soluce
[0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0], // 42
[1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0], // 42 soluce
[0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0], // 43
[1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0], // 43 soluce
[0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 1], // 44
[0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0], // 44 soluce
[0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0], // 45
[0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1], // 45 soluce
[1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1], // 46
[0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1], // 46 soluce
[1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1], // 47
[0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1], // 47 soluce
[0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1], // 48
[1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1], // 48 soluce
[0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0], // 49
[0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0], // 49 soluce
[0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0], // 50
[1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0], // 50 soluce
[0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0], // 51
[0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1], // 51 soluce
[1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0], // 52
[1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1], // 52 soluce
[1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1], // 53
[0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0], // 53 soluce
[1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1], // 54
[1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1], // 54 soluce
[1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0], // 55
[0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0], // 55 soluce
[0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0], // 56
[0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0], // 56 soluce
[1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0], // 57
[1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0]] // 57 soluce
var currentLevel = 0
var numberOfLevel = 100
var items
var table
var soluc
var showSoluce = false
var size = 5
var url = "qrc:/gcompris/src/activities/lightsoff/resource/"
function start(items_) {
items = items_
currentLevel = 0
initLevel()
}
function stop() {}
function initLevel() {
items.bar.level = currentLevel + 1
/* Is it a static or dynamic level ? */
if (currentLevel > levels.length / 2) {
/* Dynamic */
size=Math.min(Math.floor((currentLevel+1)/10), 9)
table = new Array(size * size)
soluc = new Array(size * size)
for (var i = 0; i < size * size; ++i) {
table[i] = 0
soluc[i] = 0
}
for (var j = 0; j < currentLevel; ++j) {
switchLightNoCheck(Math.floor(size * size * Math.random()))
}
} else {
/* Static */
size = 5
table = levels[currentLevel * 2].slice(0)
soluc = levels[currentLevel * 2 + 1].slice(0)
}
showSoluce = false
items.modelTable.clear()
items.nbCell = size
refreshModel()
checkResult()
}
function nextLevel() {
if (numberOfLevel <= ++currentLevel) {
currentLevel = 0
}
initLevel()
}
function previousLevel() {
if (--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
initLevel()
}
function switchLightNoCheck(index) {
/* Switch the selected item */
table[index] = 1 - table[index]
/* Swith the soluce */
soluc[index] = 1 - soluc[index]
/* Switch neighbor left */
if (index % size !== 0)
table[index - 1] = 1 - table[index - 1]
/* Switch neighbor right */
if (index % size !== size - 1)
table[index + 1] = 1 - table[index + 1]
/* Switch neighbor up */
if (index > size - 1)
table[index - size] = 1 - table[index - size]
/* Switch neighbor down */
if (index < size * size -size)
table[index + size] = 1 - table[index + size]
}
function refreshModel() {
for (var i = 0; i < size * size; ++i) {
items.modelTable.set(i, { 'lighton': table[i], 'soluce': showSoluce ? soluc[i] : 0})
}
}
function switchLight(index) {
/* Switch the selected item */
switchLightNoCheck(index)
/* Refresh the lights */
refreshModel()
/* Check the result */
checkResult()
}
function checkResult() {
/* Check the result */
var nb = 0
table.forEach(function (entry) {
nb += entry
})
if (nb === 0) {
items.blockClicks = true
items.bonus.good("tux")
}
/* Check the soluce */
items.nbCelToWin = nb
items.skyColor = Qt.rgba(0, (127 - 127 * (size * size - nb) / (size * size)) / 255,
(255 - 255 * (size * size - nb) / (size * size)) / 255, 1)
}
function solve() {
showSoluce = !showSoluce
/* Refresh the lights */
refreshModel()
}
function windowPressed(index) {
audioEffects.play('qrc:/gcompris/src/core/resource/sounds/scroll.wav')
switchLight(index)
}
diff --git a/src/activities/louis-braille/ActivityInfo.qml b/src/activities/louis-braille/ActivityInfo.qml
index ef7b5ba18..d78708121 100644
--- a/src/activities/louis-braille/ActivityInfo.qml
+++ b/src/activities/louis-braille/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Arkit Vora <arkitvora123@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "louis-braille/LouisBraille.qml"
difficulty: 4
icon: "louis-braille/louis-braille.svg"
author: "Arkit Vora &lt;arkitvora123@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("The History of Louis Braille")
//: Help title
description: qsTr("Review the major dates of the inventor of the Braille System")
//intro: "Discover the history of Louis Braille."
//: Help goal
goal: ""
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("Read the history of Louis Braille, his biography, and the invention of the Braille system. Click on the previous and next buttons to move between the story pages. At the end, arrange the sequence in chronological order.")
credit: qsTr("Louis Braille Video: &lt;http:\/\/www.youtube.com/watch?v=9bdfC2j_4x4&gt;")
section: "discovery braille"
createdInVersion: 4000
}
diff --git a/src/activities/louis-braille/LouisBraille.qml b/src/activities/louis-braille/LouisBraille.qml
index b1fc1eb8b..29d70dfba 100644
--- a/src/activities/louis-braille/LouisBraille.qml
+++ b/src/activities/louis-braille/LouisBraille.qml
@@ -1,288 +1,291 @@
/* GCompris - louis-braille.qml
*
* Copyright (C) 2014 Arkit Vora <arkitvora123@gmail.com>
*
* Authors:
* <Srishti Sethi> (GTK+ version)
* Arkit Vora <arkitvora123@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "../braille_alphabets"
import "louis-braille.js" as Activity
import "louis_braille_data.js" as Dataset
import "qrc:/gcompris/src/core/core.js" as Core
ActivityBase {
id: activity
onStart: focus = true
onStop: {}
pageComponent: Rectangle {
id: background
anchors.fill: parent
color: "#ABCDEF"
signal start
signal stop
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property alias background: background
property alias bar: bar
property alias bonus: bonus
property int count: 0
property var dataset: Dataset.dataset
}
onStart: { Activity.start(items) }
onStop: { Activity.stop() }
Image {
id: charList
y: 20 * ApplicationInfo.ratio
anchors.horizontalCenter: parent.horizontalCenter
source: Activity.url + "top_back.svg"
sourceSize.width: parent.width * 0.90
-
Row {
id: row
spacing: 10 * ApplicationInfo.ratio
anchors.centerIn: charList
anchors.horizontalCenterOffset: 5
width: parent.width
Repeater {
id: cardRepeater
model: ["L","O","U","I","S"," ","B","R","A","I","L","L","E"]
+ // workaround for https://bugreports.qt.io/browse/QTBUG-72643 (qml binding with global variable in Repeater do not work)
+ property alias rowSpacing: row.spacing
Item {
id: inner
height: charList.height * 0.95
- width:(charList.width - 13 * row.spacing)/ 13
+ width: (charList.width - 13 * cardRepeater.rowSpacing)/ 13
Rectangle {
id: rect1
- width: charList.width / 13
+ width: charList.width / 13
height: ins.height
border.width: 3
- opacity: index==5 ? 0 :1
+ opacity: index == 5 ? 0 :1
border.color: "black"
color: "white"
BrailleChar {
id: ins
width: parent.width * 0.9
anchors.centerIn: parent
clickable: false
brailleChar: modelData
}
}
GCText {
text: modelData
font.weight: Font.DemiBold
style: Text.Outline
styleColor: "white"
color: "black"
fontSize: regularSize
anchors {
top: rect1.bottom
topMargin: 4 * ApplicationInfo.ratio
horizontalCenter: rect1.horizontalCenter
}
}
}
}
}
}
Keys.onRightPressed: background.next()
Keys.onLeftPressed: background.previous()
function previous() {
if(items.count == 0)
items.count = items.dataset.length - 1
else
items.count--
}
function next() {
if(items.count == items.dataset.length - 1) {
list.shuffle()
items.count = 0
list.visible = true
} else {
items.count++
}
}
Image {
id: previous
anchors.right: img.left
anchors.rightMargin: 20 * ApplicationInfo.ratio
anchors.verticalCenter: img.verticalCenter
source: "qrc:/gcompris/src/core/resource/bar_previous.svg"
sourceSize.height: 80 * ApplicationInfo.ratio
Behavior on scale { PropertyAnimation { duration: 100} }
MouseArea {
anchors.fill: parent
hoverEnabled: true
onEntered: previous.scale = 1.1
onExited: previous.scale = 1
onClicked: background.previous()
}
}
// The image description
Rectangle {
id: info_rect
border.color: "black"
border.width: 1 * ApplicationInfo.ratio
color: "white"
width: parent.width * 0.9
- height:info.height * 1.3
+ height: background.height/5
anchors.top: charList.bottom
anchors.horizontalCenter: parent.horizontalCenter
anchors.topMargin: 5 * ApplicationInfo.ratio
GCText {
- id:info
+ id: info
color: "black"
anchors.centerIn: parent
- horizontalAlignment: Text.AlignHCenter
+ horizontalAlignment: Text.AlignHCenter
width: parent.width * 0.94
+ height: info_rect.height
wrapMode: Text.WordWrap
fontSize: regularSize
text: items.dataset[items.count].text
+ fontSizeMode: Text.Fit
}
}
// Image and date
Image {
id: img
anchors.top: info_rect.bottom
anchors.topMargin: 10 * ApplicationInfo.ratio
anchors.horizontalCenter: parent.horizontalCenter
sourceSize.height: parent.height - (charList.height + info_rect.height + bar.height)
height: (parent.height - (charList.height + info_rect.height + bar.height)) * 0.8
width: parent.width * 0.7
source: items.dataset[items.count].img
fillMode: Image.PreserveAspectFit
Rectangle {
id: year_rect
border.color: "black"
border.width: 1
color: "white"
width: year.width * 1.1
height: year.height * 1.1
anchors {
bottom: img.bottom
horizontalCenter: img.horizontalCenter
bottomMargin: 5 * ApplicationInfo.ratio
}
GCText {
id: year
color: "black"
fontSize: regularSize
anchors.centerIn: year_rect
text: items.dataset[items.count].year
}
}
MouseArea {
anchors.fill: parent
onClicked: background.next()
}
}
Image {
id: next
anchors.left: img.right
anchors.leftMargin: 20 * ApplicationInfo.ratio
anchors.verticalCenter: img.verticalCenter
source: "qrc:/gcompris/src/core/resource/bar_next.svg"
sourceSize.height: 80 * ApplicationInfo.ratio
Behavior on scale { PropertyAnimation { duration: 100} }
MouseArea {
anchors.fill: parent
hoverEnabled: true
onEntered: next.scale = 1.1
onExited: next.scale = 1
onClicked: background.next()
}
}
Keys.onUpPressed: list.up()
Keys.onDownPressed: list.down()
Keys.onEnterPressed: list.space()
Keys.onReturnPressed: list.space()
Keys.onSpacePressed: list.space()
ReorderList {
id: list
visible: false
bonus: bonus
signal shuffle
onShuffle: {
containerModel.clear()
var dataitems = Object.create(items.dataset)
dataitems = Core.shuffle(dataitems)
for(var i = 0 ; i < dataitems.length ; i++) {
containerModel.append(dataitems[i]);
}
}
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | reload }
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
onReloadClicked: {
items.count = 0
list.visible = false
}
}
Bonus {
id: bonus
Component.onCompleted: win.connect(list.shuffle)
}
}
}
diff --git a/src/activities/louis-braille/ReorderList.qml b/src/activities/louis-braille/ReorderList.qml
index f9c98b183..292ef4a33 100644
--- a/src/activities/louis-braille/ReorderList.qml
+++ b/src/activities/louis-braille/ReorderList.qml
@@ -1,191 +1,209 @@
/* GCompris - List.qml
*
* Copyright (C) 2014 Arkit Vora <arkitvora123@gmail.com>
*
* Authors:
* <Srishti Sethi> (GTK+ version)
* Arkit Vora <arkitvora123@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "louis-braille.js" as Activity
Rectangle {
id: wholeBody
width: parent.width
height: parent.height
color: "#ff55afad"
property color goodColor: colorMode ? "#ffc1ffb4" : "#FFF"
property color badColor: colorMode ? "#FFF" : "#FFF"
property bool colorMode: true
property Item bonus
property int selectedIndex: -1
property alias containerModel: list.model
+ property int listPix: wholeBody.height /30
signal up
signal down
signal space
onUp: list.decrementCurrentIndex()
onDown: list.incrementCurrentIndex()
onSpace: {
if(list.currentIndex == selectedIndex) {
selectedIndex = -1
} else if(selectedIndex != -1) {
containerModel.move(selectedIndex, list.currentIndex, 1)
list.currentIndex -= 1
selectedIndex = -1
} else {
selectedIndex = list.currentIndex
}
}
function checkWin() {
var win = true
// The shifted numbering comes from the header in the List
for(var i = 1; i < list.count + 1; i++) {
if(!list.contentItem.children[i] ||
list.contentItem.children[i].placed === false)
win = false
}
if(win) {
list.currentIndex = -1
bonus.good("tux")
}
}
Component {
id: listElement
Rectangle {
id: listRect
color: wholeBody.selectedIndex == index ? "#b5b9ff" : (placed ? goodColor : badColor)
border.width: list.currentIndex == index ? 0 : 1
border.color: "#ff525c5c"
radius: 3
width: list.width
height: Math.max(textinfo.height * 1.3, 50 * ApplicationInfo.ratio)
property int sequence: model.sequence
property bool placed: model.sequence === index
property string text: model.text
SequentialAnimation {
id: borderAnim
running: list.currentIndex == index
loops: Animation.Infinite
NumberAnimation {
target: listRect
property: "border.width"
to: 5; duration: 500
easing.type: Easing.InOutQuad
}
NumberAnimation {
target: listRect
property: "border.width"
to: 0; duration: 500
easing.type: Easing.InOutQuad
}
}
GCText {
id: textinfo
text: listRect.text
anchors.centerIn: parent
horizontalAlignment: Text.AlignHCenter
width: parent.width * 0.94
wrapMode: Text.WordWrap
- fontSize: regularSize
+ font.pixelSize: listPix
}
MouseArea {
id: dragArea
anchors.fill: parent
onClicked: {
wholeBody.selectedIndex = -1
if(list.currentIndex == index) {
list.currentIndex = -1
} else if(list.currentIndex == -1) {
list.currentIndex = index
} else {
containerModel.move(list.currentIndex, index, 1)
list.currentIndex = -1
}
}
}
Behavior on color {
ColorAnimation {
duration: 200
}
}
}
}
ListModel {
id: containerModel
}
ListView {
id: list
anchors {
fill: parent
- bottomMargin: bar.height
+ bottomMargin: bar.height*1.5 + listScrollerB.height+20
leftMargin: 30 * ApplicationInfo.ratio
rightMargin: 30 * ApplicationInfo.ratio
topMargin: 10 * ApplicationInfo.ratio
}
width: parent.width * 0.7
model: containerModel
spacing: 5 * ApplicationInfo.ratio
delegate: listElement
interactive: true
header: Rectangle {
width: parent.width
height: heading.height + 10
color: "#cceaeaea"
GCText {
id: heading
text: qsTr("Arrange the events in the order in which they happened. " +
"Select the line to move, then touch its target position.")
width: parent.width - 4
wrapMode: Text.WordWrap
- fontSize: regularSize
+ horizontalAlignment: Text.AlignHCenter
+ font.pointSize: NaN
+ font.pixelSize: listPix
}
}
onCurrentIndexChanged: timer.restart()
displaced: Transition {
NumberAnimation { properties: "y"; duration: 500 }
}
move: Transition {
NumberAnimation { properties: "y"; duration: 500 }
}
Component.onCompleted: currentIndex = -1
}
+ GCButtonScroll {
+ id:listScrollerB
+ upVisible: list.visibleArea.yPosition <= 0 ? 0 : 1
+ downVisible: list.visibleArea.yPosition + list.visibleArea.heightRatio >= 1 ? 0 : 1
+ anchors {
+ bottom: parent.bottom
+ bottomMargin: bar.height +10
+ horizontalCenter: parent.horizontalCenter
+ }
+ isHorizontal: true
+ onUp: list.flick(0,700)
+ onDown: list.flick(0,-700)
+
+ }
+
Timer {
id: timer
interval: 1000
running: false
repeat: false
onTriggered: wholeBody.checkWin()
}
}
diff --git a/src/activities/louis-braille/louis-braille.js b/src/activities/louis-braille/louis-braille.js
index 0d25122ae..a001b7849 100644
--- a/src/activities/louis-braille/louis-braille.js
+++ b/src/activities/louis-braille/louis-braille.js
@@ -1,43 +1,43 @@
/* GCompris - louis-braille.js
*
* Copyright (C) 2014 Arkit Vora <arkitvora123@gmail.com>
*
* Authors:
* <Srishti Sethi> (GTK+ version)
* Arkit Vora <arkitvora123@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
.import "qrc:/gcompris/src/core/core.js" as Core
var items
var url = "qrc:/gcompris/src/activities/louis-braille/resource/"
function start(items_) {
items = items_
initLevel()
}
function stop() {
}
function initLevel() {
// Write the sequence in the dataset
for(var i = 0 ; i < items.dataset.length ; i++)
items.dataset[i].sequence = i
items.count = 0
}
diff --git a/src/activities/louis-braille/louis_braille_data.js b/src/activities/louis-braille/louis_braille_data.js
index b343ce0fb..82831c989 100644
--- a/src/activities/louis-braille/louis_braille_data.js
+++ b/src/activities/louis-braille/louis_braille_data.js
@@ -1,77 +1,77 @@
/* GCompris - louis_braille_data.js
*
* Copyright (C) 2014 Arkit Vora <arkitvora123@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
var baseUrl = "qrc:/gcompris/src/activities/louis-braille/resource/"
var dataset = [
{
"text": qsTr("Born on January 4th 1809 in Coupvray near Paris in France."),
"year": "1809",
"img": baseUrl + "louis.png"
},
{
"text": qsTr("Louis Braille injured his right eye with a stitching awl from his father's workshop."),
"year": "1812",
"img": baseUrl + "workshop.jpg"
},
{
"text": qsTr("At the age of three, Louis became blind due to a severe infection that spread to his left eye."),
"year": "1812",
"img": baseUrl + "fireplace.jpg"
},
{
"text": qsTr("At the age of 10, he was sent to Paris to study at the Royal Institute for Blind Youth."),
"year": "1819",
"img": baseUrl + "rnib.jpg"
},
{
"text": qsTr("He impressed his classmates and began to play the piano and the organ."),
"year": "1820",
"img": baseUrl + "piano.svg"
},
{
"text": qsTr("Charles Barbier, a French soldier, visited his school and shared his invention of night writing, a code of 12 raised dots to share information on battlefields."),
"year": "1821",
"img": baseUrl + "night_printing.jpg"
},
{
"text": qsTr("Louis trimmed Barbier's 12 dots into 6 and invented the Braille system."),
"year": "1824",
"img": baseUrl + "braille.jpg"
},
{
"text": qsTr("He became a teacher after graduating and promoted his method while secretly teaching it at the Institute."),
"year": "1828",
"img": baseUrl + "teach.jpg"
},
{
"text": qsTr("He revised and extended braille to include mathematics, symbols, punctuations and music notations."),
"year": "1837",
"img": baseUrl + "chart.png"
},
{
"text": qsTr("He died of tuberculosis. He is buried in the Pantheon in Paris. A monument is erected to honor him."),
"year": "1852",
"img": baseUrl + "statue.jpg"
},
{
"text": qsTr("Braille got accepted as a world wide standard. Louis Braille proved that if you have motivation you can do incredible things."),
"year": "After his Death",
"img": baseUrl + "braille_ball.jpg"
}
];
diff --git a/src/activities/magic-hat-minus/ActivityInfo.qml b/src/activities/magic-hat-minus/ActivityInfo.qml
index af4d88e06..f960174ae 100644
--- a/src/activities/magic-hat-minus/ActivityInfo.qml
+++ b/src/activities/magic-hat-minus/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Thibaut ROMAIN <thibrom@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "magic-hat-minus/MagicHat.qml"
difficulty: 2
icon: "magic-hat-minus/magic-hat-minus.svg"
author: "Thibaut ROMAIN &lt;thibrom@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("The magician hat")
//: Help title
description: qsTr("Count how many items are under the magic hat after some have got away")
// intro: "Click on the hat. How many stars are still hiding under the hat."
//: Help goal
goal: qsTr("Learn subtraction")
//: Help prerequisite
prerequisite: qsTr("Subtraction")
//: Help manual
manual: qsTr("Click on the hat to open it. Stars go in and a few stars escape. You have to count how many are still under the hat. Click on the bottom area to input your answer and on the OK button to validate your answer.")
credit: ""
section: "math numeration"
createdInVersion: 0
}
diff --git a/src/activities/magic-hat-minus/Hat.qml b/src/activities/magic-hat-minus/Hat.qml
index 95e677592..c69e00af1 100644
--- a/src/activities/magic-hat-minus/Hat.qml
+++ b/src/activities/magic-hat-minus/Hat.qml
@@ -1,121 +1,121 @@
/* GCompris - Hat.qml
*
* Copyright (C) 2014 Thibaut ROMAIN <thibrom@gmail.com>
*
* Authors:
* Thibaut ROMAIN <thibrom@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
import "magic-hat.js" as Activity
Item {
id: hatItem
width: parent.width
height: parent.height
property alias state: hatImg.state
property alias target: offStar
property int starsSize
property GCSfx audioEffects
function getTarget() {
return offStar
}
Image {
id: hatImg
source: Activity.url + "hat.svg"
sourceSize.width: hatItem.width / 3
fillMode: Image.PreserveAspectFit
anchors.centerIn: parent
state: "NormalPosition"
transform: Rotation {
id: rotate
origin.x: 0
origin.y: hatImg.height
axis.x: 0
axis.y: 0
axis.z: 1
Behavior on angle {
animation: rotAnim
}
}
states: [
State {
name: "NormalPosition"
PropertyChanges {
target: rotate
angle: 0
}
},
State {
name: "Rotated"
PropertyChanges {
target: rotate
angle: -45
}
},
State {
name: "GuessNumber"
PropertyChanges{
target: hatImg
source: Activity.url + "hat-point.svg"
}
PropertyChanges {
target: rotate
angle: 0
}
}
]
}
RotationAnimation {
id: rotAnim
direction: hatImg.state == "Rotated" ?
RotationAnimation.Counterclockwise :
RotationAnimation.Clockwise
duration: 500
onRunningChanged: if(!rotAnim.running && hatImg.state == "Rotated") {
Activity.moveStarsUnderHat()
}
}
MouseArea {
id: hatMouseArea
anchors.fill:hatImg
onClicked: {
if(hatImg.state == "NormalPosition")
hatImg.state = "Rotated"
}
}
// The target for the moving stars
Item {
id: offStar
height: hatItem.starsSize
width: hatItem.starsSize
y: hatImg.y + hatImg.paintedHeight - height
anchors {
horizontalCenter: parent.horizontalCenter
}
z: hatImg.z - 1
}
}
diff --git a/src/activities/magic-hat-minus/MagicHat.qml b/src/activities/magic-hat-minus/MagicHat.qml
index 1805a7ef7..2936a3926 100644
--- a/src/activities/magic-hat-minus/MagicHat.qml
+++ b/src/activities/magic-hat-minus/MagicHat.qml
@@ -1,237 +1,239 @@
/* GCompris - MagicHat.qml
*
* Copyright (C) 2014 Thibaut ROMAIN <thibrom@gmail.com>
*
* Authors:
* <Bruno Coudoin> (GTK+ version)
* Thibaut ROMAIN <thibrom@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "magic-hat.js" as Activity
import "."
ActivityBase {
id: activity
onStart: focus = true
onStop: {}
property string mode: "minus"
pageComponent: Image {
id: background
anchors.fill: parent
source: Activity.url + "background.svg"
sourceSize.width: Math.max(parent.width, parent.height)
fillMode: Image.PreserveAspectCrop
property int starSize: Math.min(rightLayout.width / 12,
- background.height / 16)
+ background.height / 21)
signal start
signal stop
property var starColors : ["1", "2", "3"]
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
onStart: Activity.start(items, mode)
onStop: Activity.stop()
+ property bool vert: background.width >= (background.height - okButton.height)
+
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property alias background: background
property GCSfx audioEffects: activity.audioEffects
property alias bar: bar
property alias bonus: bonus
property alias hat: theHat
property alias introductionText: introText
property var repeatersList:
[repeaterFirstRow, repeaterSecondRow, repeaterAnswerRow]
}
Item {
id: mainlayout
anchors.left: background.left
width: background.width * 0.4
height: background.height
z: 11
Hat {
id: theHat
starsSize: background.starSize
audioEffects: activity.audioEffects
}
GCText {
id: introText
anchors {
horizontalCenter: parent.horizontalCenter
top: parent.top
topMargin: 20 * ApplicationInfo.ratio
}
width: parent.width - 5 * ApplicationInfo.ratio
fontSize: regularSize
font.bold: true
style: Text.Outline
styleColor: "black"
color: "white"
wrapMode: TextEdit.WordWrap
horizontalAlignment: TextEdit.AlignHCenter
text: qsTr("Click on the hat to begin the game")
}
GCText {
//: The math operation
text: mode == "minus" ? qsTr("−") : qsTr("+")
anchors.right: mainlayout.right
anchors.rightMargin: 10
y: secondRow.y
fontSize: 66
color: "white"
style: Text.Outline
styleColor: "black"
}
}
Grid {
id: rightLayout
anchors {
left: mainlayout.right
- right: background.right
- rightMargin: 10
+ right: background.vert ? okButton.left : background.right
+ rightMargin: background.vert ? 0 : 10
verticalCenter: background.verticalCenter
verticalCenterOffset: background.height/8
}
height: background.height
columns: 1
Column {
id: firstRow
height: background.starSize * 4
spacing: 5
z: 10
Repeater {
id: repeaterFirstRow
model: 3
StarsBar {
barGroupIndex: 0
barIndex: index
width: rightLayout.width
backgroundColor: "grey"
starsColor: starColors[index]
theHat: items.hat
starsSize: background.starSize
opacity: 0
}
}
}
Column {
id: secondRow
height: background.starSize * 4
spacing: 5
z: 9
Repeater {
id: repeaterSecondRow
model: 3
StarsBar {
barGroupIndex: 1
barIndex: index
width: rightLayout.width
backgroundColor: "grey"
starsColor: starColors[index]
theHat: items.hat
starsSize: background.starSize
opacity: 0
}
}
}
Rectangle {
width: (background.starSize + 5) * 10 - 5
height: 5 * ApplicationInfo.ratio
color: "white"
}
Rectangle {
width: (background.starSize + 5) * 10 - 5
height: 10 * ApplicationInfo.ratio
opacity: 0
}
Column {
id: answerRow
height: background.starSize * 4
spacing: 5
Repeater {
id: repeaterAnswerRow
model: 3
StarsBar {
barGroupIndex: 2
barIndex: index
width: rightLayout.width
backgroundColor: "#53b9c9"
starsColor: starColors[index]
authorizeClick: false
theHat: items.hat
starsSize: background.starSize
opacity: 0
}
}
}
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level }
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
}
BarButton {
id: okButton
anchors {
bottom: bar.top
right: parent.right
rightMargin: 10 * ApplicationInfo.ratio
bottomMargin: 10 * ApplicationInfo.ratio
}
source: "qrc:/gcompris/src/core/resource/bar_ok.svg"
sourceSize.width: 60 * ApplicationInfo.ratio
onClicked: Activity.verifyAnswer()
}
Bonus {
id: bonus
Component.onCompleted: win.connect(Activity.nextLevel)
}
}
}
diff --git a/src/activities/magic-hat-minus/Star.qml b/src/activities/magic-hat-minus/Star.qml
index 7e39e5ea1..dd6d690b2 100644
--- a/src/activities/magic-hat-minus/Star.qml
+++ b/src/activities/magic-hat-minus/Star.qml
@@ -1,141 +1,141 @@
/* GCompris - MagicHat.qml
*
* Copyright (C) 2014 Thibaut ROMAIN <thibrom@gmail.com>
*
* Authors:
* <Bruno Coudoin> (GTK+ version)
* Thibaut ROMAIN <thibrom@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "magic-hat.js" as Activity
Item {
id: mainItem
property bool isClickable: false
property bool displayBounds: true
property bool selected: false
property string backgroundColor
property Item initialParent
property Item theHat
property Item newTarget
property int barGroupIndex
property int barIndex
property string wantedColor: "1"
state: "Init"
width: 34
height: 34
MouseArea {
id: mouseArea
anchors.fill: parent
enabled: isClickable
hoverEnabled: true
onClicked: {
mainItem.selected = !mainItem.selected
Activity.userClickedAStar(barIndex, mainItem.selected)
}
}
Rectangle {
id: contour
anchors.fill: parent
border.color: "black"
border.width: mouseArea.containsMouse ? 2 : 1
opacity: displayBounds ? 1.0 : 0.0
color: mainItem.backgroundColor
}
Image {
id: starImg
source: mainItem.selected ?
Activity.url + "star-" + wantedColor + ".svg" : Activity.url + "star-0.svg"
sourceSize.width: contour.width - 4
sourceSize.height: contour.height - 4
anchors.centerIn: contour
fillMode: Image.PreserveAspectFit
opacity: 1
visible: true
}
states: [
State {
name: "Init"
ParentChange {
target: mainItem
parent: mainItem.initialParent
x: 0
y: 0
rotation: 0
}
PropertyChanges {
target: mainItem
opacity: mainItem.displayBounds ? 1 : 0
}
},
State {
name: "MoveUnderHat"
ParentChange {
target: mainItem
parent: mainItem.theHat
x: 0
y: 0
rotation: 180
}
PropertyChanges {
target: mainItem
opacity: 1
}
},
State {
name: "MoveToTarget"
ParentChange {
target: mainItem
parent: mainItem.newTarget
x: 0
y: 0
rotation: 0
}
PropertyChanges {
target: mainItem
opacity: 1
}
}
]
Behavior on x {
PropertyAnimation {
easing.type: Easing.OutQuad
duration: 1000
onRunningChanged: {
if(!running) {
if(mainItem.state == "MoveUnderHat")
Activity.animation1Finished(mainItem.barGroupIndex)
else if(mainItem.state == "MoveToTarget")
Activity.animation2Finished()
}
}
}
}
Behavior on y {
PropertyAnimation {easing.type: Easing.OutQuad; duration: 1000}
}
Behavior on rotation {
PropertyAnimation {easing.type: Easing.OutQuad; duration: 1000}
}
}
diff --git a/src/activities/magic-hat-minus/StarsBar.qml b/src/activities/magic-hat-minus/StarsBar.qml
index 506e1d445..a36a0a503 100644
--- a/src/activities/magic-hat-minus/StarsBar.qml
+++ b/src/activities/magic-hat-minus/StarsBar.qml
@@ -1,107 +1,107 @@
/* GCompris - MagicHat.qml
*
* Copyright (C) 2014 Thibaut ROMAIN <thibrom@gmail.com>
*
* Authors:
* <Bruno Coudoin> (GTK+ version)
* Thibaut ROMAIN <thibrom@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "magic-hat.js" as Activity
Item {
id: item
height: starsSize
property int barGroupIndex
property int barIndex
property int nbStarsOn: 0
property bool authorizeClick: false
property int starsSize
property string backgroundColor
property string starsColor: "1"
property Item theHat
property alias repeaterStars: repeaterStars
Row {
id: rowlayout
height: item.height
spacing: 5
Repeater {
id: repeaterStars
model: item.opacity == 1 ? 10 : 0
Item {
id: star
width: item.starsSize
height: item.starsSize
property alias starFixed: starFixed
property alias starToMove: starToMove
Star {
id: starFixed
barGroupIndex: item.barGroupIndex
barIndex: item.barIndex
backgroundColor: item.backgroundColor
wantedColor: starsColor
selected: index < nbStarsOn ? true : false
width: item.starsSize
height: item.starsSize
displayBounds: true
isClickable: item.authorizeClick
}
Star {
id: starToMove
barGroupIndex: item.barGroupIndex
backgroundColor: item.backgroundColor
wantedColor: starsColor
selected: index < nbStarsOn ? true : false
width: item.starsSize
height: item.starsSize
displayBounds: false
isClickable: false
enabled: selected ? true : false
initialParent: star
theHat: item.theHat.target
}
}
}
}
function moveStars() {
activity.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/smudge.wav")
for(var i=0; i<nbStarsOn; i++) {
repeaterStars.itemAt(i).starToMove.state = "MoveUnderHat"
}
}
function moveBackMinusStars(newRootItem, nbStars) {
for(var i=0; i<nbStars; i++) {
repeaterStars.itemAt(i).starToMove.newTarget =
newRootItem.repeaterStars.itemAt(i)
repeaterStars.itemAt(i).starToMove.state = "MoveToTarget"
}
}
function initStars() {
for(var i=0; i<repeaterStars.count; i++) {
repeaterStars.itemAt(i).starToMove.state = "Init"
}
}
function resetStars() {
for(var i=0; i<repeaterStars.count; i++) {
repeaterStars.itemAt(i).starFixed.selected = i < nbStarsOn ? true : false
}
}
}
diff --git a/src/activities/magic-hat-minus/magic-hat.js b/src/activities/magic-hat-minus/magic-hat.js
index 018f0e9ed..57f06c4c6 100644
--- a/src/activities/magic-hat-minus/magic-hat.js
+++ b/src/activities/magic-hat-minus/magic-hat.js
@@ -1,231 +1,231 @@
/* GCompris - Hat.qml
*
* Copyright (C) 2014 Thibaut ROMAIN
*
* Authors:
* Thibaut ROMAIN <thibrom@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
var url = "qrc:/gcompris/src/activities/magic-hat-minus/resource/"
var currentLevel
var numberOfLevel = 9
var numberOfUserStars
var items;
var mode;
var magicHat
var numberOfStars
var nbStarsToAddOrRemove
var nbStarsToCount
var animationCount
function start(items_, mode_) {
items = items_
mode = mode_
magicHat = items.hat
currentLevel = 0
initLevel()
}
function stop() {
}
function initLevel() {
items.bar.level = currentLevel + 1
magicHat.state = "NormalPosition"
numberOfStars = new Array(0, 0, 0)
numberOfUserStars = new Array(0, 0, 0)
nbStarsToAddOrRemove = new Array(0, 0, 0)
nbStarsToCount = new Array(0, 0, 0)
animationCount = 0
if(currentLevel > 0) {
items.introductionText.visible = false
} else {
items.introductionText.visible = true
}
for(var j=0; j<3; j++) {
items.repeatersList[0].itemAt(j).initStars()
items.repeatersList[1].itemAt(j).initStars()
items.repeatersList[2].itemAt(j).resetStars()
}
var maxValue = mode === "minus" ? 10 : 9
switch(currentLevel) {
case 0: numberOfStars[0] = getRandomInt(2,4)
break;
case 1: numberOfStars[0] = getRandomInt(2,6)
break;
case 2: numberOfStars[0] = getRandomInt(2,maxValue)
break;
case 3: numberOfStars[0] = getRandomInt(2,5)
numberOfStars[1] = getRandomInt(2,5)
break;
case 4: numberOfStars[0] = getRandomInt(2,8)
numberOfStars[1] = getRandomInt(2,8)
break;
case 5: numberOfStars[0] = getRandomInt(2,maxValue)
numberOfStars[1] = getRandomInt(2,maxValue)
break;
case 6: numberOfStars[0] = getRandomInt(2,4)
numberOfStars[1] = getRandomInt(2,4)
numberOfStars[2] = getRandomInt(2,4)
break;
case 7: numberOfStars[0] = getRandomInt(2,6)
numberOfStars[1] = getRandomInt(2,6)
numberOfStars[2] = getRandomInt(2,6)
break;
case 8: numberOfStars[0] = getRandomInt(2,8)
numberOfStars[1] = getRandomInt(2,8)
numberOfStars[2] = getRandomInt(2,8)
break;
case 9: numberOfStars[0] = getRandomInt(2,maxValue)
numberOfStars[1] = getRandomInt(2,maxValue)
numberOfStars[2] = getRandomInt(2,maxValue)
break;
}
for(var i=0; i<3; i++) {
items.repeatersList[0].itemAt(i).nbStarsOn = numberOfStars[i]
items.repeatersList[1].itemAt(i).nbStarsOn = 0
items.repeatersList[2].itemAt(i).nbStarsOn = 0
items.repeatersList[2].itemAt(i).authorizeClick = false
if(numberOfStars[i] > 0) {
items.repeatersList[0].itemAt(i).opacity = 1
items.repeatersList[1].itemAt(i).opacity = 1
items.repeatersList[2].itemAt(i).opacity = 1
if(mode === "minus")
nbStarsToAddOrRemove[i] = getRandomInt(1, numberOfStars[i]-1)
else
nbStarsToAddOrRemove[i] = getRandomInt(1, 10-numberOfStars[i])
}
else {
items.repeatersList[0].itemAt(i).opacity = 0
items.repeatersList[1].itemAt(i).opacity = 0
items.repeatersList[2].itemAt(i).opacity = 0
}
}
if(mode === "minus") {
for(var i=0; i<3; i++) {
nbStarsToCount[i] = numberOfStars[i] - nbStarsToAddOrRemove[i]
items.repeatersList[1].itemAt(i).nbStarsOn = 0
}
} else {
for(var i=0; i<3; i++) {
nbStarsToCount[i] = numberOfStars[i]+nbStarsToAddOrRemove[i]
items.repeatersList[1].itemAt(i).nbStarsOn = nbStarsToAddOrRemove[i]
}
}
}
function userClickedAStar(barIndex,state) {
if(state)
numberOfUserStars[barIndex]++
else
numberOfUserStars[barIndex]--
}
function verifyAnswer() {
if(numberOfUserStars[0] === nbStarsToCount[0] &&
numberOfUserStars[1] === nbStarsToCount[1] &&
numberOfUserStars[2] === nbStarsToCount[2]) {
items.bonus.good("flower")
} else {
items.bonus.bad("flower")
}
}
function nextLevel() {
if(numberOfLevel <= ++currentLevel ) {
currentLevel = 0
}
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
initLevel();
}
function moveStarsUnderHat() {
if(currentLevel == 0) {
items.introductionText.visible = false
}
for(var j=0; j<3; j++) {
items.repeatersList[0].itemAt(j).moveStars()
}
}
function moveBackMinusStars() {
for(var j=0; j<3; j++) {
items.repeatersList[0].itemAt(j).
moveBackMinusStars(items.repeatersList[1].itemAt(j),
nbStarsToAddOrRemove[j])
}
}
function movePlusStars() {
for(var j=0; j<3; j++) {
items.repeatersList[1].itemAt(j).moveStars()
}
}
// Function called everytime the first animation ends
function animation1Finished(barGroupIndex) {
animationCount++
if(barGroupIndex == 0) {
if(animationCount === numberOfStars[0] + numberOfStars[1] + numberOfStars[2]) {
animationCount = 0
if(mode === "minus")
moveBackMinusStars()
else
movePlusStars()
}
} else {
animationCount = 0
userGuessNumberState()
}
}
// Function called everytime the second animation ends
function animation2Finished()
{
animationCount++
if(animationCount === nbStarsToAddOrRemove[0] +
nbStarsToAddOrRemove[1] + nbStarsToAddOrRemove[2]) {
animationCount = 0
userGuessNumberState()
}
}
function userGuessNumberState() {
for(var i=0; i<3; i++) {
if(numberOfStars[i] + nbStarsToAddOrRemove[i])
items.repeatersList[2].itemAt(i).authorizeClick = true
}
magicHat.state = "GuessNumber"
}
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
diff --git a/src/activities/magic-hat-plus/ActivityInfo.qml b/src/activities/magic-hat-plus/ActivityInfo.qml
index 11ef8ae37..9739e21eb 100644
--- a/src/activities/magic-hat-plus/ActivityInfo.qml
+++ b/src/activities/magic-hat-plus/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Thib ROMAIN <thibrom@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "magic-hat-plus/MagicHatPlus.qml"
difficulty: 2
icon: "magic-hat-plus/magic-hat-plus.svg"
author: "Thib ROMAIN &lt;thibrom@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("The magician hat")
//: Help title
description: qsTr("Count how many items are under the magic hat")
// intro: "Count the number of stars hidden under the hat and then click on the stars to indicate their number."
//: Help goal
goal: qsTr("Learn addition")
//: Help prerequisite
prerequisite: qsTr("Addition")
//: Help manual
manual: qsTr("Click on the hat to open it. Under the hat, how many stars can you see moving around? Count carefully. Click on the bottom area to input your answer and on the OK button to validate your answer.")
credit: ""
section: "math numeration"
createdInVersion: 0
}
diff --git a/src/activities/magic-hat-plus/MagicHatPlus.qml b/src/activities/magic-hat-plus/MagicHatPlus.qml
index e8ebd5e88..c8c640741 100644
--- a/src/activities/magic-hat-plus/MagicHatPlus.qml
+++ b/src/activities/magic-hat-plus/MagicHatPlus.qml
@@ -1,29 +1,29 @@
/* GCompris - MagicHat.qml
*
* Copyright (C) 2014 Thibaut ROMAIN <thibrom@gmail.com>
*
* Authors:
* <Bruno Coudoin> (GTK+ version)
* Thibaut ROMAIN <thibrom@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
import "../magic-hat-minus/"
-MagicHat{
+MagicHat {
mode: "plus"
}
diff --git a/src/activities/maze/ActivityInfo.qml b/src/activities/maze/ActivityInfo.qml
index 09a718532..582056658 100644
--- a/src/activities/maze/ActivityInfo.qml
+++ b/src/activities/maze/ActivityInfo.qml
@@ -1,45 +1,45 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Stephane Mankowski <stephane@mankowski.fr>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "maze/Maze.qml"
difficulty: 1
icon: "maze/maze.svg"
author: "Stephane Mankowski &lt;stephane@mankowski.fr&gt;"
demo: true
//: Activity title
title: qsTr("Maze")
//: Help title
description: qsTr("Help Tux get out of this maze")
// intro: "Use the arrows keys or swipe the touch screen to help Tux find his way out."
//: Help goal
goal: ""
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("Use the arrow keys or swipe the touch screen to move Tux up to the door.") + "<br><br>" +
qsTr("At the first levels, Tux walks comfortably, one step on each move request, through the maze.") + "<br><br>" +
qsTr("For larger mazes, there is a special walking mode, called \"run-fast-mode\". If this run-fast-mode is enabled, Tux will run all the way automatically until he reaches a fork and you have to decide which way to go further.") + "<br><br>" +
qsTr("You can see whether this mode is enabled or not, by looking at Tux's feet: If Tux is barefooted, \"run-fast-mode\" is disabled. And if he wears red sport shoes, \"run-fast-mode\" is enabled.") + "<br><br>" +
qsTr("At higher levels, run-fast-mode will be enabled automatically. If you want to use this feature in earlier levels or want to disable it in advanced levels, click on the \"barefoot / sportshoe\"-icon in the upper left corner of the screen to toggle the run-fast-mode.
\t")
credit: ""
section: "discovery maze"
createdInVersion: 0
}
diff --git a/src/activities/maze/Maze.qml b/src/activities/maze/Maze.qml
index 1886d4ba7..d10059f9a 100644
--- a/src/activities/maze/Maze.qml
+++ b/src/activities/maze/Maze.qml
@@ -1,349 +1,348 @@
/* GCompris - maze.qml
*
* Copyright (C) 2014 Stephane Mankowski <stephane@mankowski.fr>
*
* Authors:
* Bastiaan Verhoef <b.f.verhoef@student.utwente.nl> (GTK+ version)
* Stephane Mankowski <stephane@mankowski.fr> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
-import QtMultimedia 5.0
import "../../core"
import "maze.js" as Activity
ActivityBase {
id: activity
property bool relativeMode: false
property bool invisibleMode: false
onStart: focus = true
onStop: {
}
Keys.onPressed: Activity.processPressedKey(event)
pageComponent: Image {
id: background
source: Activity.url + "maze_bg.svg"
sourceSize.width: parent.width
anchors.fill: parent
signal start
signal stop
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property alias background: background
property alias bar: bar
property alias bonus: bonus
property alias mazeRows: maze.rows
property alias mazeColumns: maze.columns
property alias mazeRepeater: mazeRepeater.model
property GCSfx audioEffects: activity.audioEffects
property alias message: message
property int playerx: 0
property int playery: 0
property int playerr: 270
property int doory: 0
property int cellSize: Math.min((parent.height - 200) / mazeRows,
(parent.width - 40) / mazeColumns)
property int wallSize: Math.max(2, cellSize / 10)
property bool wallVisible: true
property bool fastMode: false
}
onStart: {
Activity.start(items, relativeMode, invisibleMode)
}
onStop: {
Activity.stop()
}
Rectangle {
color: "#E3DEDB"
anchors.fill: maze
}
Grid {
id: maze
anchors.top: parent.top
anchors.topMargin: (parent.height - height) / 2
anchors.horizontalCenter: parent.horizontalCenter
columns: 0
rows: 0
spacing: 0
Repeater {
id: mazeRepeater
Item {
width: items.cellSize
height: items.cellSize
Rectangle {
id: north
width: items.cellSize + items.wallSize
height: items.wallSize
radius: height / 2
anchors.top: parent.top
anchors.left: parent.left
anchors.topMargin: -items.wallSize / 2
anchors.leftMargin: -items.wallSize / 2
color: "#B38B56"
visible: modelData & 1 ? items.wallVisible : false
z: 1
}
Rectangle {
id: south
width: items.cellSize + items.wallSize
height: items.wallSize
radius: height / 2
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.bottomMargin: -items.wallSize / 2
anchors.leftMargin: -items.wallSize / 2
color: "#B38B56"
visible: modelData & 4 ? items.wallVisible : false
z: 1
}
Rectangle {
id: east
width: items.wallSize
height: items.cellSize + items.wallSize
radius: width / 2
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.bottomMargin: -items.wallSize / 2
anchors.rightMargin: -items.wallSize / 2
color: "#B38B56"
visible: modelData & 8 ? items.wallVisible : false
z: 1
}
Rectangle {
id: west
width: items.wallSize
height: items.cellSize + items.wallSize
radius: width / 2
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.bottomMargin: -items.wallSize / 2
anchors.leftMargin: -items.wallSize / 2
color: "#B38B56"
visible: modelData & 2 ? items.wallVisible : false
z: 1
}
}
}
}
MultiPointTouchArea {
anchors.fill: parent
touchPoints: [ TouchPoint { id: point1 } ]
property real startX
property real startY
// Workaround to avoid having 2 times the onReleased event
property bool started
onPressed: {
startX = point1.x
startY = point1.y
started = true
}
onReleased: {
if(!started)
return false
var moveX = point1.x - startX
var moveY = point1.y - startY
// Find the direction with the most move
if(Math.abs(moveX) * ApplicationInfo.ratio > 10 &&
Math.abs(moveX) > Math.abs(moveY)) {
if(moveX > 10 * ApplicationInfo.ratio)
Activity.clickRight()
else if(moveX < -10 * ApplicationInfo.ratio)
Activity.clickLeft()
} else if(Math.abs(moveY) * ApplicationInfo.ratio > 10 &&
Math.abs(moveX) < Math.abs(moveY)) {
if(moveY > 10 * ApplicationInfo.ratio)
Activity.clickDown()
else if(moveY < -10 * ApplicationInfo.ratio)
Activity.clickUp()
} else {
// No move, just a tap or mouse click
if(point1.x > player.x + player.width)
Activity.clickRight()
else if(point1.x < player.x)
Activity.clickLeft()
else if(point1.y < player.y)
Activity.clickUp()
else if(point1.y > player.y + player.height)
Activity.clickDown()
}
started = false
}
}
// Show an hint to show that can move by swiping anywhere
Image {
anchors {
right: parent.right
bottom: parent.bottom
margins: 12
}
source: "qrc:/gcompris/src/core/resource/arrows_move.svg"
sourceSize.width: 140
opacity: bar.level == 1 && ApplicationInfo.isMobile ? 1 : 0
}
Image {
id: player
source: Activity.url + "tux_top_south.svg"
sourceSize.width: items.cellSize * 0.8
x: maze.x + items.cellSize * 0.05 + items.wallSize / 2 + items.playerx * items.cellSize
y: maze.y + items.cellSize * 0.20 + items.wallSize / 2 + items.playery * items.cellSize
z: 2
rotation: items.playerr
Timer {
id: timeAutoMove
interval: 10
running: false
repeat: false
onTriggered: Activity.autoMove()
}
Behavior on x {
SequentialAnimation {
NumberAnimation {
duration: 100
}
ScriptAction {
script: timeAutoMove.running = true
}
}
}
Behavior on y {
SequentialAnimation {
NumberAnimation {
duration: 100
}
ScriptAction {
script: timeAutoMove.running = true
}
}
}
Behavior on rotation {
PropertyAnimation {
duration: 100
}
}
Image {
id: shoes
source: Activity.url + "tux_shoes_top_south.svg"
sourceSize.width: items.cellSize * 0.8
anchors.centerIn: parent
visible: items.fastMode
}
}
Image {
id: door
source: Activity.url + "door.svg"
width: items.cellSize * 0.6
height: items.cellSize * 0.8
y: maze.y + items.cellSize * 0.05 + items.wallSize / 2 + items.doory * items.cellSize
z: 1
anchors.right: maze.right
anchors.rightMargin: items.cellSize * 0.15 + items.wallSize / 2
}
BarButton {
id: fastmode
source: Activity.url + "fast-mode-button.svg"
sourceSize.width: 66 * bar.barZoom
visible: !message.visible
x: 10 * ApplicationInfo.ratio
y: 10 * ApplicationInfo.ratio
onClicked: items.fastMode = !items.fastMode
}
BarButton {
id: switchMaze
source: Activity.url + "maze-2d-bubble.svg"
anchors {
right: parent.right
top: parent.top
margins: 10
}
sourceSize.width: 66 * bar.barZoom
visible: invisibleMode
onClicked: {
items.wallVisible = !items.wallVisible
message.visible = items.wallVisible
}
}
GCText {
id: message
anchors {
left: parent.left
right: switchMaze.left
top: parent.top
margins: 10
}
width: background.width - x - 20
fontSize: regularSize
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
visible: false
wrapMode: Text.Wrap
text: qsTr("Look at your position, then switch back to invisible mode to continue your moves")
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: BarEnumContent {
value: help | home | level
}
onHelpClicked: displayDialog(dialogHelp)
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
}
Bonus {
id: bonus
Component.onCompleted: win.connect(Activity.nextLevel)
}
}
}
diff --git a/src/activities/maze/maze.js b/src/activities/maze/maze.js
index a2a3611f9..430fc6090 100644
--- a/src/activities/maze/maze.js
+++ b/src/activities/maze/maze.js
@@ -1,495 +1,495 @@
/* GCompris - maze.js
*
* Copyright (C) 2014 Stephane Mankowski <stephane@mankowski.fr>
*
* Authors:
* Bastiaan Verhoef <b.f.verhoef@student.utwente.nl> (GTK+ version)
* Stephane Mankowski <stephane@mankowski.fr> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
var url = "qrc:/gcompris/src/activities/maze/resource/"
var currentLevel = 0
var numberOfLevel = 25
var items
var relativeMode
var invisibleMode
var NORTH = 1
var WEST = 2
var SOUTH = 4
var EAST = 8
var SET = 16
var mazeColumns = 0
var mazeRows = 0
var maze = 0
var win = false
function start(items_, relativeMode_, invisibleMode_) {
items = items_
relativeMode = relativeMode_
invisibleMode = invisibleMode_
currentLevel = 0
initLevel()
}
function stop() {}
function initLevel() {
items.wallVisible = !invisibleMode
items.bar.level = currentLevel + 1
win = false
/* Set main variables */
if (currentLevel + 1 == 1) {
mazeColumns = 4
mazeRows = 4
} else if (currentLevel + 1 == 2) {
mazeColumns = 5
mazeRows = 4
} else if (currentLevel + 1 == 3) {
mazeColumns = 5
mazeRows = 5
} else if (currentLevel + 1 == 4) {
mazeColumns = 6
mazeRows = 5
} else if (currentLevel + 1 == 5) {
mazeColumns = 6
mazeRows = 6
} else if (currentLevel + 1 == 6) {
mazeColumns = 6
mazeRows = 7
} else if (currentLevel + 1 == 7) {
mazeColumns = 7
mazeRows = 7
} else if (currentLevel + 1 == 8) {
mazeColumns = 8
mazeRows = 7
} else if (currentLevel + 1 == 9) {
mazeColumns = 8
mazeRows = 8
} else if (currentLevel + 1 == 10) {
mazeColumns = 9
mazeRows = 8
} else if (currentLevel + 1 == 11) {
mazeColumns = 9
mazeRows = 9
} else if (currentLevel + 1 == 12) {
mazeColumns = 10
mazeRows = 9
} else if (currentLevel + 1 == 13) {
mazeColumns = 10
mazeRows = 10
} else if (currentLevel + 1 == 14) {
mazeColumns = 8
mazeRows = 16
} else if (currentLevel + 1 == 15) {
mazeColumns = 14
mazeRows = 14
} else if (currentLevel + 1 == 16) {
mazeColumns = 16
mazeRows = 15
} else if (currentLevel + 1 == 17) {
mazeColumns = 17
mazeRows = 16
} else if (currentLevel + 1 == 18) {
mazeColumns = 18
} else if (currentLevel + 1 == 19) {
mazeColumns = 19
mazeRows = 18
} else if (currentLevel + 1 == 20) {
mazeColumns = 19
mazeRows = 19
} else if (currentLevel + 1 == 21) {
mazeColumns = 20
mazeRows = 19
} else if (currentLevel + 1 == 22) {
mazeColumns = 20
mazeRows = 20
} else if (currentLevel + 1 == 23) {
mazeColumns = 19
mazeRows = 21
} else if (currentLevel + 1 == 24) {
mazeColumns = 23
mazeRows = 21
} else if (currentLevel + 1 == 25) {
mazeColumns = 23
mazeRows = 23
}
items.mazeRows = mazeRows
items.mazeColumns = mazeColumns
/* Build maze */
maze = []
for (var id = 0; id < mazeColumns * mazeRows; ++id) {
maze[id] = 15
}
/* Generate maze */
generateMaze(Math.floor(Math.random() * mazeColumns),
Math.floor(Math.random() * mazeRows))
/* Remove set */
for (id = 0; id < mazeColumns * mazeRows; ++id) {
maze[id] = maze[id] ^ SET
}
/* Set maze */
items.mazeRepeater = maze
/* Set initial position of player */
items.playerx = 0
items.playery = Math.floor(Math.random() * mazeRows)
/* Set position of door */
items.doory = Math.floor(Math.random() * mazeRows)
items.fastMode = (currentLevel + 1 >= 14)
}
function getId(x, y) {
return x + y * mazeColumns
}
function check(x, y) {
if (maze[getId(x, y)] & SET)
return 1
return 0
}
function isPossible(x, y) {
var wall = maze[getId(x, y)]
var pos = []
wall = wall ^ SET
pos[0] = 0
if (x === 0) {
wall = wall ^ WEST
}
if (y === 0) {
wall = wall ^ NORTH
}
if (x === mazeColumns - 1) {
wall = wall ^ EAST
}
if (y === mazeRows - 1) {
wall = wall ^ SOUTH
}
if (wall & EAST) {
if (check(x + 1, y) === 0) {
pos[0] = pos[0] + 1
pos[pos[0]] = EAST
}
}
if (wall & SOUTH) {
if (check(x, y + 1) === 0) {
pos[0] = pos[0] + 1
pos[pos[0]] = SOUTH
}
}
if (wall & WEST) {
if (check(x - 1, y) === 0) {
pos[0] = pos[0] + 1
pos[pos[0]] = WEST
}
}
if (wall & NORTH) {
if (check(x, y - 1) === 0) {
pos[0] = pos[0] + 1
pos[pos[0]] = NORTH
}
}
return pos
}
function generateMaze(x, y) {
maze[getId(x, y)] = maze[getId(x, y)] + SET
var po = isPossible(x, y)
while (po[0] > 0) {
var ran = po[Math.floor(Math.random() * po[0]) + 1]
switch (ran) {
case EAST:
maze[getId(x, y)] = maze[getId(x, y)] ^ EAST
maze[getId(x + 1, y)] = maze[getId(x + 1, y)] ^ WEST
generateMaze(x + 1, y)
break
case SOUTH:
maze[getId(x, y)] = maze[getId(x, y)] ^ SOUTH
maze[getId(x, y + 1)] = maze[getId(x, y + 1)] ^ NORTH
generateMaze(x, y + 1)
break
case WEST:
maze[getId(x, y)] = maze[getId(x, y)] ^ WEST
maze[getId(x - 1, y)] = maze[getId(x - 1, y)] ^ EAST
generateMaze(x - 1, y)
break
case NORTH:
maze[getId(x, y)] = maze[getId(x, y)] ^ NORTH
maze[getId(x, y - 1)] = maze[getId(x, y - 1)] ^ SOUTH
generateMaze(x, y - 1)
break
}
po = isPossible(x, y)
}
}
function nextLevel() {
if (numberOfLevel <= ++currentLevel) {
currentLevel = 0
}
initLevel()
}
function previousLevel() {
if (--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
initLevel()
}
function getMaze() {
return maze
}
function autoMove() {
if (items && items.fastMode) {
var number = 0
var result = 0
if (getPlayerRotation() !== 90 && !(maze[getId(
items.playerx,
items.playery)] & EAST)) {
number++
result |= EAST
}
if (getPlayerRotation() !== 270 && !(maze[getId(
items.playerx,
items.playery)] & WEST)) {
number++
result |= WEST
}
if (getPlayerRotation() !== 180
&& !(maze[getId(items.playerx, items.playery)] & SOUTH)) {
number++
result |= SOUTH
}
if (getPlayerRotation() !== 0 && !(maze[getId(
items.playerx,
items.playery)] & NORTH)) {
number++
result |= NORTH
}
if (number == 1) {
if (items.playery !== items.doory
|| items.playerx !== mazeColumns - 1) {
switch (result) {
case EAST:
items.playerr = 270
++items.playerx
break
case WEST:
items.playerr = 90
--items.playerx
break
case NORTH:
items.playerr = 180
--items.playery
break
case SOUTH:
items.playerr = 0
++items.playery
break
}
/* Check if success */
checkSuccess()
}
}
}
}
/* 0= SOUTH
* 90= WEST
* 180 = NORTH
* 270 =EST
*/
function getPlayerRotation() {
return ((items.playerr % 360) + 360) % 360
}
function checkSuccess() {
if (items.playery === items.doory && items.playerx === mazeColumns - 1) {
win = true
items.bonus.good("lion")
}
}
function processPressedKey(event) {
/* Mode invisible */
if (invisibleMode && event.key === Qt.Key_Space) {
items.wallVisible = !items.wallVisible
items.message.visible = items.wallVisible
}
if ( !win ) {
/* Move the player */
switch (event.key) {
case Qt.Key_Right:
clickRight()
event.accepted = true
break
case Qt.Key_Left:
clickLeft()
event.accepted = true
break
case Qt.Key_Up:
clickUp()
event.accepted = true
break
case Qt.Key_Down:
clickDown()
event.accepted = true
break
}
}
}
function clickRight() {
/* Move the player */
if ((!invisibleMode || !items.wallVisible)
&& (items.playery !== items.doory
|| items.playerx !== mazeColumns - 1)) {
if (relativeMode) {
/* Relative mode */
if (items.playerr % 90 === 0)
items.playerr += 90
} else {
/* Absolute mode */
var curpos = getPlayerRotation()
items.playerr = items.playerr - (curpos === 0 ? 90 : curpos - 270)
if (!(maze[getId(items.playerx, items.playery)] & EAST)) {
++items.playerx
} else {
items.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/brick.wav")
}
}
}
/* Check if success */
checkSuccess()
}
function clickLeft() {
/* Move the player */
if ((!invisibleMode || !items.wallVisible)
&& (items.playery !== items.doory
|| items.playerx !== mazeColumns - 1)) {
if (relativeMode) {
/* Relative mode */
if (items.playerr % 90 === 0)
items.playerr -= 90
} else {
/* Absolute mode */
var curpos = getPlayerRotation()
items.playerr = items.playerr - curpos + 90
if (!(maze[getId(items.playerx, items.playery)] & WEST)) {
--items.playerx
} else {
items.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/brick.wav")
}
}
}
/* Check if success */
checkSuccess()
}
function clickDown() {
/* Move the player */
if ((!invisibleMode || !items.wallVisible)
&& (items.playery !== items.doory
|| items.playerx !== mazeColumns - 1)) {
if (relativeMode) {
/* Relative mode */
if (items.playerr % 90 === 0) {
if (items.playerr >= 180)
items.playerr -= 180
else
items.playerr += 180
}
} else {
/* Absolute mode */
var curpos = getPlayerRotation()
items.playerr = items.playerr - (curpos === 270 ? -90 : curpos)
if (!(maze[getId(items.playerx, items.playery)] & SOUTH)) {
++items.playery
} else {
items.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/brick.wav")
}
}
}
/* Check if success */
checkSuccess()
}
function clickUp() {
/* Move the player */
if ((!invisibleMode || !items.wallVisible)
&& (items.playery !== items.doory
|| items.playerx !== mazeColumns - 1)) {
if (relativeMode) {
/* Relative mode */
if (getPlayerRotation() === 270) {
if (!(maze[getId(items.playerx, items.playery)] & EAST)) {
++items.playerx
} else {
items.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/brick.wav")
}
} else if (getPlayerRotation() === 180) {
if (!(maze[getId(items.playerx, items.playery)] & NORTH)) {
--items.playery
} else {
items.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/brick.wav")
}
} else if (getPlayerRotation() === 90) {
if (!(maze[getId(items.playerx, items.playery)] & WEST)) {
--items.playerx
} else {
items.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/brick.wav")
}
} else {
if (!(maze[getId(items.playerx, items.playery)] & SOUTH)) {
++items.playery
} else {
items.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/brick.wav")
}
}
} else {
/* Absolute mode */
var curpos = getPlayerRotation()
items.playerr = items.playerr - curpos + 180
if (!(maze[getId(items.playerx, items.playery)] & NORTH)) {
--items.playery
} else {
items.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/brick.wav")
}
}
}
/* Check if success */
checkSuccess()
}
diff --git a/src/activities/mazeinvisible/ActivityInfo.qml b/src/activities/mazeinvisible/ActivityInfo.qml
index b221718f4..cefc988ba 100644
--- a/src/activities/mazeinvisible/ActivityInfo.qml
+++ b/src/activities/mazeinvisible/ActivityInfo.qml
@@ -1,45 +1,45 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Stephane Mankowski <stephane@mankowski.fr>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "mazeinvisible/Mazeinvisible.qml"
difficulty: 4
icon: "mazeinvisible/mazeinvisible.svg"
author: "Stephane Mankowski &lt;stephane@mankowski.fr&gt;"
demo: true
//: Activity title
title: qsTr("Invisible Maze")
//: Help title
description: qsTr("Guide Tux out of the invisible maze")
// intro: "Use the arrow keys or swipe the touch screen to guide Tux out. Use the maze icon or the space key to see the map."
//: Help goal
goal: ""
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("Use the arrow keys or swipe the touch screen to move Tux up to the door. Use the maze icon or the spacebar to switch between invisible and visible modes. Visible mode just gives you an indication of your position, like a map. You cannot move Tux in visible mode.") + "<br><br>" +
qsTr("At the first levels, Tux walks comfortably, one step on each move request, through the maze.") + "<br><br>" +
qsTr("For larger mazes, there is a special walking mode, called \"run-fast-mode\". If this run-fast-mode is enabled, Tux will run all the way automatically until he reaches a fork and you have to decide which way to go further.") + "<br><br>" +
qsTr("You can see whether this mode is enabled or not, by looking at Tux's feet: If Tux is barefooted, \"run-fast-mode\" is disabled. And if he wears red sport shoes, \"run-fast-mode\" is enabled.") + "<br><br>" +
qsTr("At higher levels, run-fast-mode will be enabled automatically. If you want to use this feature in earlier levels or want to disable it in advanced levels, click on the \"barefoot / sportshoe\"-icon in the upper left corner of the screen to toggle the run-fast-mode.
\t")
credit: ""
section: "discovery maze"
createdInVersion: 0
}
diff --git a/src/activities/mazeinvisible/Mazeinvisible.qml b/src/activities/mazeinvisible/Mazeinvisible.qml
index eb382f191..38c987761 100644
--- a/src/activities/mazeinvisible/Mazeinvisible.qml
+++ b/src/activities/mazeinvisible/Mazeinvisible.qml
@@ -1,27 +1,27 @@
/* GCompris - mazeinvisible.qml
*
* Copyright (C) 2014 Stephane Mankowski <stephane@mankowski.fr>
*
* Authors:
* Bastiaan Verhoef <b.f.verhoef@student.utwente.nl> (GTK+ version)
* Stephane Mankowski <stephane@mankowski.fr> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../maze"
Maze {
invisibleMode: true
}
diff --git a/src/activities/mazerelative/ActivityInfo.qml b/src/activities/mazerelative/ActivityInfo.qml
index 3fa294480..13c2b6fc4 100644
--- a/src/activities/mazerelative/ActivityInfo.qml
+++ b/src/activities/mazerelative/ActivityInfo.qml
@@ -1,46 +1,46 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Stephane Mankowski <stephane@mankowski.fr>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "mazerelative/Mazerelative.qml"
difficulty: 3
icon: "mazerelative/mazerelative.svg"
author: "Stephane Mankowski &lt;stephane@mankowski.fr&gt;"
demo: true
//: Activity title
title: qsTr("Relative Maze")
//: Help title
description: qsTr("Help Tux get out of this maze (Move is relative)")
// intro: "Help Tux find his way out. Left and right are used to turn and up to go forward."
//: Help goal
goal: ""
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("Use the arrow keys or swipe the touch screen to move Tux up to the door.") + "<br><br>" +
qsTr("In this maze, the move is relative (first person). Left and right are used to turn and up to go forward.") + "<br><br>" +
qsTr("At the first levels, Tux walks comfortably, one step on each move request, through the maze.") + "<br><br>" +
qsTr("For larger mazes, there is a special walking mode, called \"run-fast-mode\". If this run-fast-mode is enabled, Tux will run all the way automatically until he reaches a fork and you have to decide which way to go further.") + "<br><br>" +
qsTr("You can see whether this mode is enabled or not, by looking at Tux's feet: If Tux is barefooted, \"run-fast-mode\" is disabled. And if he wears red sport shoes, \"run-fast-mode\" is enabled.") + "<br><br>" +
qsTr("At higher levels, run-fast-mode will be enabled automatically. If you want to use this feature in earlier levels or want to disable it in advanced levels, click on the \"barefoot / sportshoe\"-icon in the upper left corner of the screen to toggle the run-fast-mode.
\t")
credit: ""
section: "discovery mazeMenu"
createdInVersion: 0
}
diff --git a/src/activities/mazerelative/Mazerelative.qml b/src/activities/mazerelative/Mazerelative.qml
index e2277e954..c9422650b 100644
--- a/src/activities/mazerelative/Mazerelative.qml
+++ b/src/activities/mazerelative/Mazerelative.qml
@@ -1,26 +1,27 @@
/* GCompris - mazerelative.qml
*
* Copyright (C) 2014 Stephane Mankowski <stephane@mankowski.fr>
*
* Authors:
* Bastiaan Verhoef <b.f.verhoef@student.utwente.nl> (GTK+ version)
* Stephane Mankowski <stephane@mankowski.fr> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../maze"
+
Maze {
relativeMode: true
}
diff --git a/src/activities/melody/ActivityInfo.qml b/src/activities/melody/ActivityInfo.qml
index b08818cfb..ca6b86955 100644
--- a/src/activities/melody/ActivityInfo.qml
+++ b/src/activities/melody/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "melody/Melody.qml"
difficulty: 2
icon: "melody/melody.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
//: Activity title
title: qsTr("Melody")
//: Help title
description: qsTr("Reproduce a sound sequence")
// intro: "Listen to the sound sequence played, and reproduce it by clicking on the xylophone's bars"
//: Help goal
goal: qsTr("Ear-training activity")
//: Help prerequisite
prerequisite: qsTr("Move and click the mouse")
//: Help manual
manual: qsTr("Listen to the sound sequence played, and repeat it by clicking on the xylophone's bars. You can listen again by clicking on the repeat button.")
credit: ""
section: "discovery memory music"
createdInVersion: 5000
}
diff --git a/src/activities/melody/Melody.qml b/src/activities/melody/Melody.qml
index 2944453e5..af54b43d3 100644
--- a/src/activities/melody/Melody.qml
+++ b/src/activities/melody/Melody.qml
@@ -1,254 +1,254 @@
/* GCompris - melody.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Jose JORGE <jjorge@free.fr> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
ActivityBase {
id: activity
onStart: focus = true
onStop: {}
isMusicalActivity: true
pageComponent: Image {
id: background
anchors.fill: parent
source: items.url + 'xylofon_background.svg'
sourceSize.width: Math.max(parent.width, parent.height)
fillMode: Image.PreserveAspectCrop
signal start
signal stop
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property string url: "qrc:/gcompris/src/activities/melody/resource/"
property var question
property var questionToPlay
property var answer
property alias questionInterval: questionPlayer.interval
property int numberOfLevel: 10
property bool running: false
}
onStart: {
bar.level = 1
score.numberOfSubLevels = 5
score.currentSubLevel = 1
initLevel()
items.running = true
}
onStop: {
knock.stop()
questionPlayer.stop()
items.running = false
}
Image {
id: xylofon
anchors {
fill: parent
margins: 10 * ApplicationInfo.ratio
}
source: items.url + 'xylofon.svg'
sourceSize.width: parent.width * 0.7
fillMode: Image.PreserveAspectFit
}
Repeater {
id: parts
model: 4
Image {
id: part
source: items.url + 'xylofon_part' + (index + 1) + '.svg'
rotation: - 80
anchors.horizontalCenter: xylofon.horizontalCenter
anchors.horizontalCenterOffset: (- xylofon.paintedWidth) * 0.3 + xylofon.paintedWidth * index * 0.22
anchors.verticalCenter: xylofon.verticalCenter
anchors.verticalCenterOffset: - xylofon.paintedHeight * 0.1
sourceSize.width: xylofon.paintedWidth * 0.5
fillMode: Image.PreserveAspectFit
property alias anim: anim
SequentialAnimation {
id: anim
NumberAnimation {
target: part
property: "scale"
from: 1; to: 0.95
duration: 150
easing.type: Easing.InOutQuad
}
NumberAnimation {
target: part
property: "scale"
from: 0.95; to: 1
duration: 150
easing.type: Easing.OutElastic
}
}
MouseArea {
anchors.fill: parent
enabled: !questionPlayer.running
onClicked: {
anim.start()
background.playNote(index)
items.answer.push(index)
background.checkAnswer()
}
}
}
}
function playNote(index) {
activity.audioEffects.play(ApplicationInfo.getAudioFilePath(items.url +
'xylofon_son' + (index + 1) + ".wav"))
}
Timer {
id: knock
interval: 1000
repeat: false
onTriggered: {
questionPlayer.start()
}
}
Timer {
id: questionPlayer
onTriggered: {
var partIndex = items.questionToPlay.shift()
if(partIndex !== undefined) {
parts.itemAt(partIndex).anim.start()
background.playNote(partIndex)
start()
}
}
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level | repeat }
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: {
score.currentSubLevel = 1
if(bar.level == 1) {
bar.level = items.numberOfLevel
} else {
bar.level--
}
initLevel();
}
onNextLevelClicked: parent.nextLevel()
onHomeClicked: activity.home()
onRepeatClicked: parent.repeat()
}
Bonus {
id: bonus
onWin: {
parent.nextSubLevel()
parent.repeat()
}
onLoose: parent.repeat()
}
Score {
id: score
anchors.bottom: undefined
anchors.right: parent.right
anchors.rightMargin: 10 * ApplicationInfo.ratio
anchors.top: parent.top
}
function initLevel() {
items.question = []
questionPlayer.stop()
var numberOfParts = 4
if(bar.level < 3)
numberOfParts = 2
else if(bar.level < 5)
numberOfParts = 3
for(var i = 0; i < bar.level + 2; ++i) {
items.question.push(Math.floor(Math.random() * numberOfParts))
}
items.questionInterval = 1200 - Math.min(500, 100 * bar.level)
items.answer = []
}
function nextSubLevel() {
if(score.currentSubLevel < score.numberOfSubLevels) {
score.currentSubLevel++
initLevel()
return
}
nextLevel()
}
function nextLevel() {
score.currentSubLevel = 1
if(items.numberOfLevel === bar.level ) {
bar.level = 1
} else {
bar.level++
}
initLevel();
}
function repeat() {
if(items.running == true) {
questionPlayer.stop()
activity.audioEffects.play(ApplicationInfo.getAudioFilePath(items.url + 'knock.wav'))
items.questionToPlay = items.question.slice()
items.answer = []
knock.start()
}
}
function checkAnswer() {
if(items.answer.join() == items.question.join())
bonus.good('lion')
else if(items.answer.length >= items.question.length)
bonus.bad('lion')
}
}
}
diff --git a/src/activities/memory-case-association-tux/ActivityInfo.qml b/src/activities/memory-case-association-tux/ActivityInfo.qml
index ca2850b1e..2f0bbe390 100644
--- a/src/activities/memory-case-association-tux/ActivityInfo.qml
+++ b/src/activities/memory-case-association-tux/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2017 Aman Kumar Gupta <gupta2140@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "memory-case-association-tux/MemoryCaseAssociationTux.qml"
difficulty: 2
icon: "memory-case-association-tux/memory-case-association-tux.svg"
author: "Aman Kumar Gupta &lt;gupta2140@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Case association memory game against Tux")
//: Help title
description: qsTr("Turn the cards over to match the alphabet with its lower/uppercase value against Tux.")
//intro: "Match the upper case card with its lower case pair."
//: Help goal
goal: qsTr("Learning lower and upper case alphabets, memory.")
//: Help prerequisite
prerequisite: qsTr("Knowing alphabets")
//: Help manual
manual: qsTr("You can see some cards, but you can't see what's on the other side of them. Each card is hiding the lower/uppercase of an alphabet, and you have to associate all the upper case letters with its lower case and vice versa. Tux teacher does the same.")
credit: ""
section: "reading"
createdInVersion: 9000
}
diff --git a/src/activities/memory-case-association-tux/MemoryCaseAssociationTux.qml b/src/activities/memory-case-association-tux/MemoryCaseAssociationTux.qml
index 4898a2725..9e71de20d 100644
--- a/src/activities/memory-case-association-tux/MemoryCaseAssociationTux.qml
+++ b/src/activities/memory-case-association-tux/MemoryCaseAssociationTux.qml
@@ -1,27 +1,27 @@
/* GCompris - MemoryCaseAssociationTux.qml
*
* Copyright (C) 2017 Aman Kumar Gupta <gupta2140@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../memory"
import "../memory-case-association/dataset.js" as Dataset
MemoryCommon {
dataset: Dataset.get()
backgroundImg: "qrc:/gcompris/src/activities/memory/resource/background.svg"
withTux: true
}
diff --git a/src/activities/memory-case-association/ActivityInfo.qml b/src/activities/memory-case-association/ActivityInfo.qml
index c7c179402..96bed2b5a 100644
--- a/src/activities/memory-case-association/ActivityInfo.qml
+++ b/src/activities/memory-case-association/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2017 Aman Kumar Gupta <gupta2140@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "memory-case-association/MemoryCaseAssociation.qml"
difficulty: 2
icon: "memory-case-association/memory-case-association.svg"
author: "Aman Kumar Gupta &lt;gupta2140@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Case association memory game")
//: Help title
description: qsTr("Turn the cards over to match the alphabet with its lower/uppercase value.")
//intro: "Match the upper case card with its lower case pair."
//: Help goal
goal: qsTr("Learning lower and upper case alphabets, memory.")
//: Help prerequisite
prerequisite: qsTr("Knowing alphabets")
//: Help manual
manual: qsTr("You can see some cards, but you can't see what's on the other side of them. Each card is hiding the lower/uppercase of an alphabet, and you have to associate all the upper case letters with its lower case and vice versa.")
credit: ""
section: "reading"
createdInVersion: 9000
}
diff --git a/src/activities/memory-case-association/MemoryCaseAssociation.qml b/src/activities/memory-case-association/MemoryCaseAssociation.qml
index 262aa1920..925a3984a 100644
--- a/src/activities/memory-case-association/MemoryCaseAssociation.qml
+++ b/src/activities/memory-case-association/MemoryCaseAssociation.qml
@@ -1,26 +1,26 @@
/* GCompris - MemoryCaseAssociation.qml
*
* Copyright (C) 2017 Aman Kumar Gupta <gupta2140@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../memory"
import "dataset.js" as Dataset
MemoryCommon {
dataset: Dataset.get()
backgroundImg: "qrc:/gcompris/src/activities/memory/resource/background.svg"
}
diff --git a/src/activities/memory-case-association/dataset.js b/src/activities/memory-case-association/dataset.js
index bbec1dda2..029102e1f 100644
--- a/src/activities/memory-case-association/dataset.js
+++ b/src/activities/memory-case-association/dataset.js
@@ -1,163 +1,163 @@
/* GCompris - dataset.js
*
* Copyright (C) 2017 Aman Kumar Gupta <gupta2140@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.import GCompris 1.0 as GCompris //for ApplicationInfo
.import "qrc:/gcompris/src/core/core.js" as Core
var url = "qrc:/gcompris/src/activities/categorization/resource/images/alphabets/"
var images = [
[url + 'lowerA.svg', url + 'upperA.svg'],
[url + 'lowerB.svg', url + 'upperB.svg'],
[url + 'lowerC.svg', url + 'upperC.svg'],
[url + 'lowerD.svg', url + 'upperD.svg'],
[url + 'lowerE.svg', url + 'upperE.svg'],
[url + 'lowerF.svg', url + 'upperF.svg'],
[url + 'lowerG.svg', url + 'upperG.svg'],
[url + 'lowerH.svg', url + 'upperH.svg'],
[url + 'lowerI.svg', url + 'upperI.svg'],
[url + 'lowerJ.svg', url + 'upperJ.svg'],
[url + 'lowerK.svg', url + 'upperK.svg'],
[url + 'lowerL.svg', url + 'upperL.svg'],
[url + 'lowerM.svg', url + 'upperM.svg'],
[url + 'lowerN.svg', url + 'upperN.svg'],
[url + 'lowerO.svg', url + 'upperO.svg'],
[url + 'lowerP.svg', url + 'upperP.svg'],
[url + 'lowerQ.svg', url + 'upperQ.svg'],
[url + 'lowerR.svg', url + 'upperR.svg'],
[url + 'lowerS.svg', url + 'upperS.svg'],
[url + 'lowerT.svg', url + 'upperT.svg'],
[url + 'lowerU.svg', url + 'upperU.svg'],
[url + 'lowerV.svg', url + 'upperV.svg'],
[url + 'lowerW.svg', url + 'upperW.svg'],
[url + 'lowerX.svg', url + 'upperX.svg'],
[url + 'lowerY.svg', url + 'upperY.svg'],
[url + 'lowerZ.svg', url + 'upperZ.svg']
]
var sounds = [
[GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('A')),
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('A'))],
[GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('B')),
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('B'))],
[GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('C')),
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('C'))],
[GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('D')),
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('D'))],
[GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('E')),
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('E'))],
[GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('F')),
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('F'))],
[GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('G')),
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('G'))],
[GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('H')),
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('H'))],
[GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('I')),
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('I'))],
[GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('J')),
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('J'))],
[GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('K')),
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('K'))],
[GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('L')),
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('L'))],
[GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('M')),
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('M'))],
[GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('N')),
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('N'))],
[GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('O')),
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('O'))],
[GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('P')),
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('P'))],
[GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('Q')),
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('Q'))],
[GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('R')),
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('R'))],
[GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('S')),
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('S'))],
[GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('T')),
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('T'))],
[GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('U')),
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('U'))],
[GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('V')),
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('V'))],
[GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('W')),
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('W'))],
[GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('X')),
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('X'))],
[GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('Y')),
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('Y'))],
[GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('Z')),
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/" + Core.getSoundFilenamForChar('Z'))]
]
var memory_cards = [
{ // Level 1
columns: 3,
rows: 2,
images: images.slice(0, 6),
sounds: sounds.slice(0, 6)
},
{ // Level 2
columns: 4,
rows: 2,
images: images.slice(6, 14),
sounds: sounds.slice(6, 14)
},
{ // Level 3
columns: 5,
rows: 2,
images: images.slice(14, 24),
sounds: sounds.slice(14, 24)
},
{ // Level 4
columns: 4,
rows: 3,
images: images.slice(14, 26),
sounds: sounds.slice(14, 26)
}
]
function get() {
return memory_cards
}
\ No newline at end of file
diff --git a/src/activities/memory-enumerate/ActivityInfo.qml b/src/activities/memory-enumerate/ActivityInfo.qml
index 02772d342..d1faef75d 100644
--- a/src/activities/memory-enumerate/ActivityInfo.qml
+++ b/src/activities/memory-enumerate/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "memory-enumerate/MemoryEnumerate.qml"
difficulty: 2
icon: "memory-enumerate/memory-enumerate.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
//: Activity title
title: qsTr("Enumeration memory game")
//: Help title
description: qsTr("Turn the cards over to match the number with the drawn picture.")
// intro: "Match a number card with a card displaying the same number of butterflies."
//: Help goal
goal: qsTr("Numeration training, memory.")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("You can see some cards, but you can't see what's on the other side of them. Each card is hiding a number of pictures, or the written number.")
credit: ""
section: "math numeration"
createdInVersion: 0
}
diff --git a/src/activities/memory-enumerate/MemoryEnumerate.qml b/src/activities/memory-enumerate/MemoryEnumerate.qml
index 33efdd6d1..88eda863a 100644
--- a/src/activities/memory-enumerate/MemoryEnumerate.qml
+++ b/src/activities/memory-enumerate/MemoryEnumerate.qml
@@ -1,30 +1,30 @@
/* gcompris - MemoryMathAdd.qml
*
* Copyright (C) 2014 JB BUTET <ashashiwa@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* JB BUTET <ashashiwa@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../memory"
import "dataset.js" as Dataset
MemoryCommon {
dataset: Dataset.get()
backgroundImg: "qrc:/gcompris/src/activities/memory/resource/background.svg"
}
diff --git a/src/activities/memory-enumerate/dataset.js b/src/activities/memory-enumerate/dataset.js
index 2c94166e0..42437fd0e 100644
--- a/src/activities/memory-enumerate/dataset.js
+++ b/src/activities/memory-enumerate/dataset.js
@@ -1,122 +1,122 @@
/* GCompris
*
* Copyright (C) 2014 Bruno Coudoin
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.import GCompris 1.0 as GCompris //for ApplicationInfo
var url = "qrc:/gcompris/src/activities/memory-enumerate/resource/"
var texts = [
["", 0],
["", 1],
["", 2],
["", 3],
["", 4],
["", 5],
["", 6],
["", 7],
["", 8],
["", 9]
]
var images = [
[url + 'math_0.svg', ''],
[url + 'math_1.svg', ''],
[url + 'math_2.svg', ''],
[url + 'math_3.svg', ''],
[url + 'math_4.svg', ''],
[url + 'math_5.svg', ''],
[url + 'math_6.svg', ''],
[url + 'math_7.svg', ''],
[url + 'math_8.svg', ''],
[url + 'math_9.svg', '']
]
var sounds = [
["",
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/U0030.$CA")],
["",
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/U0031.$CA")],
["",
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/U0032.$CA")],
["",
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/U0033.$CA")],
["",
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/U0034.$CA")],
["",
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/U0035.$CA")],
["",
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/U0036.$CA")],
["",
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/U0037.$CA")],
["",
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/U0038.$CA")],
["",
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/U0039.$CA")],
["",
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/10.$CA")],
["",
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/11.$CA")],
["",
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/12.$CA")],
["",
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/13.$CA")],
["",
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/14.$CA")],
["",
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/15.$CA")],
["",
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/16.$CA")],
["",
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/17.$CA")],
["",
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/18.$CA")],
["",
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/19.$CA")],
["",
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/20.$CA")]
]
var memory_cards = [
{ // Level 1
columns: 3,
rows: 2,
texts: texts.slice(0, 6),
images: images.slice(0, 6),
sounds: sounds.slice(0, 6)
},
{ // Level 2
columns: 3,
rows: 2,
texts: texts.slice(4, 10),
images: images.slice(4, 10),
sounds: sounds.slice(4, 10)
},
{ // Level 3
columns: 5,
rows: 2,
texts: texts.slice(0, 10),
images: images.slice(0, 10),
sounds: sounds.slice(0, 10)
}
]
function get() {
return memory_cards
}
diff --git a/src/activities/memory-math-add-minus-mult-div-tux/ActivityInfo.qml b/src/activities/memory-math-add-minus-mult-div-tux/ActivityInfo.qml
index 68d839c18..9a7ddf4dc 100644
--- a/src/activities/memory-math-add-minus-mult-div-tux/ActivityInfo.qml
+++ b/src/activities/memory-math-add-minus-mult-div-tux/ActivityInfo.qml
@@ -1,42 +1,42 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 JB BUTET <ashashiwa@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "memory-math-add-minus-mult-div-tux/MemoryMathAddMinusMultDivTux.qml"
difficulty: 6
icon: "memory-math-add-minus-mult-div-tux/memory-math-add-minus-mult-div-tux.svg"
author: "JB BUTET &lt;ashashiwa@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("All operations memory game against Tux")
//: Help title
description: qsTr("Turn the cards over to find a matching operation, until all the cards are gone.")
// intro: "Turn over two cards to match the calculation with its answer."
//: Help goal
goal: qsTr("Practice addition, subtraction, multiplication, division, until all the cards are gone.")
//: Help prerequisite
prerequisite: qsTr("Addition, subtraction, multiplication, division")
//: Help manual
manual: qsTr("You can see some cards, but you can't see what's on the other side of them. Each card is hiding an operation, or the answer to it.
In this game, these cards are hiding the two parts of an operation. You need to find the two parts of the operation, and bring them together again. Click on a card to see what number it's hiding, then try to find the other card that goes with it, to make a whole operation. You can only turn over two cards in one go, so you need to remember where the numbers are hiding, then you can match them when you find their other half. You're doing the job of the equals sign, and the numbers need you to put them together and make a proper equality. When you do that, both those cards disappear! When you've made them all disappear, found more than Tux, you've won the game!")
credit: ""
section: "math memory"
createdInVersion: 0
}
diff --git a/src/activities/memory-math-add-minus-mult-div-tux/MemoryMathAddMinusMultDivTux.qml b/src/activities/memory-math-add-minus-mult-div-tux/MemoryMathAddMinusMultDivTux.qml
index 6682a07fd..852e3bd09 100644
--- a/src/activities/memory-math-add-minus-mult-div-tux/MemoryMathAddMinusMultDivTux.qml
+++ b/src/activities/memory-math-add-minus-mult-div-tux/MemoryMathAddMinusMultDivTux.qml
@@ -1,31 +1,31 @@
/* gcompris
*
* Copyright (C) 2014 JB BUTET <ashashiwa@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* JB BUTET <ashashiwa@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../memory"
import "memory-addminusmultdivdataset.js" as Dataset
MemoryCommon {
dataset: Dataset.get()
backgroundImg: "qrc:/gcompris/src/activities/memory/resource/background.svg"
withTux: true
}
diff --git a/src/activities/memory-math-add-minus-mult-div-tux/memory-addminusmultdivdataset.js b/src/activities/memory-math-add-minus-mult-div-tux/memory-addminusmultdivdataset.js
index bbae88446..33899df14 100644
--- a/src/activities/memory-math-add-minus-mult-div-tux/memory-addminusmultdivdataset.js
+++ b/src/activities/memory-math-add-minus-mult-div-tux/memory-addminusmultdivdataset.js
@@ -1,77 +1,77 @@
/* GCompris
*
* Copyright (C) 2014 Bruno Coudoin
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.import "qrc:/gcompris/src/activities/memory/math_util.js" as Memory
var memory_cards = [
{ // Level 1
columns: 5,
rows: 2,
texts: Memory.getAddMinusMultDivTable(1)
},
{ // Level 2
columns: 5,
rows: 2,
texts: Memory.getAddMinusMultDivTable(2)
},
{ // Level 3
columns: 5,
rows: 2,
texts: Memory.getAddMinusMultDivTable(3)
},
{ // Level 4
columns: 5,
rows: 2,
texts: Memory.getAddMinusMultDivTable(4)
},
{ // Level 5
columns: 5,
rows: 2,
texts: Memory.getAddMinusMultDivTable(5)
},
{ // Level 6
columns: 5,
rows: 2,
texts: Memory.getAddMinusMultDivTable(6)
},
{ // Level 7
columns: 5,
rows: 2,
texts: Memory.getAddMinusMultDivTable(7)
},
{ // Level 8
columns: 5,
rows: 2,
texts: Memory.getAddMinusMultDivTable(8)
},
{ // Level 9
columns: 5,
rows: 2,
texts: Memory.getAddMinusMultDivTable(9)
},
{ // Level 10
columns: 5,
rows: 2,
texts: Memory.getAddMinusMultDivTable(10)
}
]
function get() {
return memory_cards
}
diff --git a/src/activities/memory-math-add-minus-mult-div/ActivityInfo.qml b/src/activities/memory-math-add-minus-mult-div/ActivityInfo.qml
index d07ee3737..4db5a7ed2 100644
--- a/src/activities/memory-math-add-minus-mult-div/ActivityInfo.qml
+++ b/src/activities/memory-math-add-minus-mult-div/ActivityInfo.qml
@@ -1,42 +1,42 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 JB BUTET <ashashiwa@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "memory-math-add-minus-mult-div/MemoryMathAddMinusMultDiv.qml"
difficulty: 6
icon: "memory-math-add-minus-mult-div/memory-math-add-minus-mult-div.svg"
author: "JB BUTET &lt;ashashiwa@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("All operations memory game")
//: Help title
description: qsTr("Turn the cards over to find a matching operation, until all the cards are gone.")
// intro: "Turn over two cards to match the calculation with its answer."
//: Help goal
goal: qsTr("Practice addition, subtraction, multiplication, division, until all the cards are gone.")
//: Help prerequisite
prerequisite: qsTr("Addition, subtraction, multiplication, division")
//: Help manual
manual: qsTr("You can see some cards, but you can't see what's on the other side of them. Each card is hiding an operation, or the answer to it.
In this game, these cards are hiding the two parts of an operation. You need to find the two parts of the operation, and bring them together again. Click on a card to see what number it's hiding, then try to find the other card that goes with it, to make a whole operation. You can only turn over two cards in one go, so you need to remember where the numbers are hiding, then you can match them when you find their other half. You're doing the job of the equals sign, and the numbers need you to put them together and make a proper equality. When you do that, both those cards disappear! When you've made them all disappear, found all the operations, you've won the game!")
credit: ""
section: "math memory"
createdInVersion: 0
}
diff --git a/src/activities/memory-math-add-minus-mult-div/MemoryMathAddMinusMultDiv.qml b/src/activities/memory-math-add-minus-mult-div/MemoryMathAddMinusMultDiv.qml
index f50d07209..d367d0544 100644
--- a/src/activities/memory-math-add-minus-mult-div/MemoryMathAddMinusMultDiv.qml
+++ b/src/activities/memory-math-add-minus-mult-div/MemoryMathAddMinusMultDiv.qml
@@ -1,30 +1,30 @@
/* gcompris - MemoryMathAddMinusMultDiv.qml
*
* Copyright (C) 2014 JB BUTET <ashashiwa@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* JB BUTET <ashashiwa@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../memory"
import "memory-addminusmultdivdataset.js" as Dataset
MemoryCommon {
dataset: Dataset.get()
backgroundImg: "qrc:/gcompris/src/activities/memory/resource/background.svg"
}
diff --git a/src/activities/memory-math-add-minus-mult-div/memory-addminusmultdivdataset.js b/src/activities/memory-math-add-minus-mult-div/memory-addminusmultdivdataset.js
index 69cf58154..5ab8e5c23 100644
--- a/src/activities/memory-math-add-minus-mult-div/memory-addminusmultdivdataset.js
+++ b/src/activities/memory-math-add-minus-mult-div/memory-addminusmultdivdataset.js
@@ -1,77 +1,77 @@
/* GCompris
*
* Copyright (C) 2014 Bruno Coudoin
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.import "qrc:/gcompris/src/activities/memory/math_util.js" as Memory
var memory_cards = [
{ // Level 1
columns: 5,
rows: 2,
texts: Memory.getAddMinusMultTable(1)
},
{ // Level 2
columns: 5,
rows: 2,
texts: Memory.getAddMinusMultTable(2)
},
{ // Level 3
columns: 5,
rows: 2,
texts: Memory.getAddMinusMultTable(3)
},
{ // Level 4
columns: 5,
rows: 2,
texts: Memory.getAddMinusMultTable(4)
},
{ // Level 5
columns: 5,
rows: 2,
texts: Memory.getAddMinusMultTable(5)
},
{ // Level 6
columns: 5,
rows: 2,
texts: Memory.getAddMinusMultTable(6)
},
{ // Level 7
columns: 5,
rows: 2,
texts: Memory.getAddMinusMultTable(7)
},
{ // Level 8
columns: 5,
rows: 2,
texts: Memory.getAddMinusMultTable(8)
},
{ // Level 9
columns: 5,
rows: 2,
texts: Memory.getAddMinusMultTable(9)
},
{ // Level 10
columns: 5,
rows: 2,
texts: Memory.getAddMinusMultTable(10)
}
]
function get() {
return memory_cards
}
diff --git a/src/activities/memory-math-add-minus-tux/ActivityInfo.qml b/src/activities/memory-math-add-minus-tux/ActivityInfo.qml
index 964dd7c45..a13d0f3b4 100644
--- a/src/activities/memory-math-add-minus-tux/ActivityInfo.qml
+++ b/src/activities/memory-math-add-minus-tux/ActivityInfo.qml
@@ -1,42 +1,42 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 JB BUTET <ashashiwa@mgail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "memory-math-add-minus-tux/MemoryMathAddMinusTux.qml"
difficulty: 4
icon: "memory-math-add-minus-tux/memory-math-add-minus-tux.svg"
author: "JB BUTET &lt;ashashiwa@mgail.com&gt;"
demo: true
//: Activity title
title: qsTr("Addition and subtraction memory game against Tux")
//: Help title
description: qsTr("Turn the cards over to find two numbers which add or subtract the same, until all the cards are gone.")
// intro: "Turn over two cards to match the calculation with its answer."
//: Help goal
goal: qsTr("Practice addition, subtraction, until all the cards are gone.")
//: Help prerequisite
prerequisite: qsTr("Addition and subtraction")
//: Help manual
manual: qsTr("You can see some cards, but you can't see what's on the other side of them. Each card is hiding an operation, or the answer to it.
In this game, these cards are hiding the two parts of an operation. You need to find the two parts of the operation, and bring them together again. Click on a card to see what number it's hiding, then try to find the other card that goes with it, to make a whole operation. You can only turn over two cards in one go, so you need to remember where the numbers are hiding, then you can match them when you find their other half. You're doing the job of the equals sign, and the numbers need you to put them together and make a proper equality. When you do that, both those cards disappear! When you've made them all disappear, found more than Tux, and you've won the game!")
credit: ""
section: "math memory"
createdInVersion: 0
}
diff --git a/src/activities/memory-math-add-minus-tux/MemoryMathAddMinusTux.qml b/src/activities/memory-math-add-minus-tux/MemoryMathAddMinusTux.qml
index 6cfb6ab02..c57640ee5 100644
--- a/src/activities/memory-math-add-minus-tux/MemoryMathAddMinusTux.qml
+++ b/src/activities/memory-math-add-minus-tux/MemoryMathAddMinusTux.qml
@@ -1,31 +1,31 @@
/* gcompris
*
* Copyright (C) 2014 JB BUTET <ashashiwa@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* JB BUTET <ashashiwa@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../memory"
import "../memory-math-add-minus/memory-addminusdataset.js" as Dataset
MemoryCommon {
dataset: Dataset.get()
backgroundImg: "qrc:/gcompris/src/activities/memory/resource/background.svg"
withTux: true
}
diff --git a/src/activities/memory-math-add-minus/ActivityInfo.qml b/src/activities/memory-math-add-minus/ActivityInfo.qml
index 8791f424d..20acb2ee0 100644
--- a/src/activities/memory-math-add-minus/ActivityInfo.qml
+++ b/src/activities/memory-math-add-minus/ActivityInfo.qml
@@ -1,42 +1,42 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 JB BUTET <ashashiwa@mgail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "memory-math-add-minus/MemoryMathAddMinus.qml"
difficulty: 4
icon: "memory-math-add-minus/memory-math-add-minus.svg"
author: "JB BUTET &lt;ashashiwa@mgail.com&gt;"
demo: true
//: Activity title
title: qsTr("Addition and subtraction memory game")
//: Help title
description: qsTr("Turn the cards over to find two numbers which add or subtract the same, until all the cards are gone.")
// intro: "Turn over two cards to match the calculation with its answer."
//: Help goal
goal: qsTr("Practice addition, subtraction, until all the cards are gone.")
//: Help prerequisite
prerequisite: qsTr("Addition and subtraction")
//: Help manual
manual: qsTr("You can see some cards, but you can't see what's on the other side of them. Each card is hiding an operation, or the answer to it.
In this game, these cards are hiding the two parts of an operation. You need to find the two parts of the operation, and bring them together again. Click on a card to see what number it's hiding, then try to find the other card that goes with it, to make a whole operation. You can only turn over two cards in one go, so you need to remember where the numbers are hiding, then you can match them when you find their other half. You're doing the job of the equals sign, and the numbers need you to put them together and make a proper equality. When you do that, both those cards disappear! When you've made them all disappear, found all the operations, you've won the game!")
credit: ""
section: "math memory"
createdInVersion: 0
}
diff --git a/src/activities/memory-math-add-minus/MemoryMathAddMinus.qml b/src/activities/memory-math-add-minus/MemoryMathAddMinus.qml
index c2546ad19..f3baa5264 100644
--- a/src/activities/memory-math-add-minus/MemoryMathAddMinus.qml
+++ b/src/activities/memory-math-add-minus/MemoryMathAddMinus.qml
@@ -1,30 +1,30 @@
/* gcompris - MemoryMathAddMinus.qml
*
* Copyright (C) 2014 JB BUTET <ashashiwa@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* JB BUTET <ashashiwa@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../memory"
import "memory-addminusdataset.js" as Dataset
MemoryCommon {
dataset: Dataset.get()
backgroundImg: "qrc:/gcompris/src/activities/memory/resource/background.svg"
}
diff --git a/src/activities/memory-math-add-minus/memory-addminusdataset.js b/src/activities/memory-math-add-minus/memory-addminusdataset.js
index 7f79cc928..8827ab68f 100644
--- a/src/activities/memory-math-add-minus/memory-addminusdataset.js
+++ b/src/activities/memory-math-add-minus/memory-addminusdataset.js
@@ -1,77 +1,77 @@
/* GCompris
*
* Copyright (C) 2014 Bruno Coudoin
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.import "qrc:/gcompris/src/activities/memory/math_util.js" as Memory
var memory_cards = [
{ // Level 1
columns: 5,
rows: 2,
texts: Memory.getAddMinusTable(1)
},
{ // Level 2
columns: 5,
rows: 2,
texts: Memory.getAddMinusTable(2)
},
{ // Level 3
columns: 5,
rows: 2,
texts: Memory.getAddMinusTable(3)
},
{ // Level 4
columns: 5,
rows: 2,
texts: Memory.getAddMinusTable(4)
},
{ // Level 5
columns: 5,
rows: 2,
texts: Memory.getAddMinusTable(5)
},
{ // Level 6
columns: 5,
rows: 2,
texts: Memory.getAddMinusTable(6)
},
{ // Level 7
columns: 5,
rows: 2,
texts: Memory.getAddMinusTable(7)
},
{ // Level 8
columns: 5,
rows: 2,
texts: Memory.getAddMinusTable(8)
},
{ // Level 9
columns: 5,
rows: 2,
texts: Memory.getAddMinusTable(9)
},
{ // Level 10
columns: 5,
rows: 2,
texts: Memory.getAddMinusTable(10)
}
]
function get() {
return memory_cards
}
diff --git a/src/activities/memory-math-add-tux/ActivityInfo.qml b/src/activities/memory-math-add-tux/ActivityInfo.qml
index 5210962ff..157946de9 100644
--- a/src/activities/memory-math-add-tux/ActivityInfo.qml
+++ b/src/activities/memory-math-add-tux/ActivityInfo.qml
@@ -1,44 +1,44 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 JB BUTET <ashashiwa@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "memory-math-add-tux/MemoryMathAddTux.qml"
difficulty: 3
icon: "memory-math-add-tux/memory-math-add-tux.svg"
author: "JB BUTET &lt;ashashiwa@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Addition memory game against Tux")
//: Help title
- description: qsTr("Turn the cards over to find two numbers which add up the same, until all the cards are gone. Tux will do the same. You have to beat it !")
+ description: qsTr("Turn the cards over to find two numbers which add up the same, until all the cards are gone. Tux will do the same. You have to beat it!")
// intro: "Turn over two cards to match the calculation with its answer."
//: Help goal
goal: qsTr("Practice adding up, until all the cards are gone.")
//: Help prerequisite
prerequisite: qsTr("Addition")
//: Help manual
manual: qsTr("You can see some cards, but you can't see what's on the other side of them. Each card is hiding an adding-up sum, or the answer to the sum.
An adding-up sum looks like this: 2 + 2 = 4
The numbers on one side of the equals sign (=) have to be the same as the number on the other side. So 2 (1, 2) and 2 more (3, 4) makes 4. Count aloud when you work this out, and count on your fingers, because the more ways you do something, the better you remember it. You can also use blocks, or buttons, or anything you can count. If you have lots of brothers and sisters, you can count them! Or the kids in your class at school. Sing counting songs. Count lots of things, for practice, and you'll be very good at adding-up!
In this game, these cards are hiding the two parts of an adding-up sum (also called an addition sum). You need to find the two parts of the sum, and bring them together again. Click on a card to see what number it's hiding, then try to find the other card that goes with it, to make a whole sum. You can only turn over two cards in one go, so you need to remember where the numbers are hiding, then you can match them when you find their other half. You're doing the job of the equals sign, and the numbers need you to put them together and make a proper sum. When you do that, both those cards disappear! When you've made them all disappear, found more sums than Tux and you've won the game!")
credit: ""
section: "math memory"
createdInVersion: 0
}
diff --git a/src/activities/memory-math-add-tux/MemoryMathAddTux.qml b/src/activities/memory-math-add-tux/MemoryMathAddTux.qml
index a1df00daf..0fb5f328f 100644
--- a/src/activities/memory-math-add-tux/MemoryMathAddTux.qml
+++ b/src/activities/memory-math-add-tux/MemoryMathAddTux.qml
@@ -1,31 +1,31 @@
/* gcompris
*
* Copyright (C) 2014 JB BUTET <ashashiwa@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* JB BUTET <ashashiwa@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../memory"
import "../memory-math-add/memory-adddataset.js" as Dataset
MemoryCommon {
dataset: Dataset.get()
backgroundImg: "qrc:/gcompris/src/activities/memory/resource/background.svg"
withTux: true
}
diff --git a/src/activities/memory-math-add/ActivityInfo.qml b/src/activities/memory-math-add/ActivityInfo.qml
index 33daa8d16..6029a6c4b 100644
--- a/src/activities/memory-math-add/ActivityInfo.qml
+++ b/src/activities/memory-math-add/ActivityInfo.qml
@@ -1,44 +1,44 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 JB BUTET <ashashiwa@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "memory-math-add/MemoryMathAdd.qml"
difficulty: 3
icon: "memory-math-add/memory-math-add.svg"
author: "JB BUTET &lt;ashashiwa@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Addition memory game")
//: Help title
description: qsTr("Turn the cards over to find two numbers which add up the same, until all the cards are gone.")
// intro: "Turn over two cards to match the calculation with its answer."
//: Help goal
goal: qsTr("Practice adding up, until all the cards are gone.")
//: Help prerequisite
prerequisite: qsTr("Addition")
//: Help manual
manual: qsTr("You can see some cards, but you can't see what's on the other side of them. Each card is hiding an adding-up sum, or the answer to the sum.
An adding-up sum looks like this: 2 + 2 = 4
The numbers on one side of the equals sign (=) have to be the same as the number on the other side. So 2 (1, 2) and 2 more (3, 4) makes 4. Count aloud when you work this out, and count on your fingers, because the more ways you do something, the better you remember it. You can also use blocks, or buttons, or anything you can count. If you have lots of brothers and sisters, you can count them! Or the kids in your class at school. Sing counting songs. Count lots of things, for practice, and you'll be very good at adding-up!
In this game, these cards are hiding the two parts of an adding-up sum (also called an addition sum). You need to find the two parts of the sum, and bring them together again. Click on a card to see what number it's hiding, then try to find the other card that goes with it, to make a whole sum. You can only turn over two cards in one go, so you need to remember where the numbers are hiding, then you can match them when you find their other half. You're doing the job of the equals sign, and the numbers need you to put them together and make a proper sum. When you do that, both those cards disappear! When you've made them all disappear, found all the sums, you've won the game!")
credit: ""
section: "math memory"
createdInVersion: 0
}
diff --git a/src/activities/memory-math-add/MemoryMathAdd.qml b/src/activities/memory-math-add/MemoryMathAdd.qml
index dc75e0c84..6cf207d79 100644
--- a/src/activities/memory-math-add/MemoryMathAdd.qml
+++ b/src/activities/memory-math-add/MemoryMathAdd.qml
@@ -1,30 +1,30 @@
/* gcompris - MemoryMathAdd.qml
*
* Copyright (C) 2014 JB BUTET <ashashiwa@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* JB BUTET <ashashiwa@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../memory"
import "memory-adddataset.js" as Dataset
MemoryCommon {
dataset: Dataset.get()
backgroundImg: "qrc:/gcompris/src/activities/memory/resource/background.svg"
}
diff --git a/src/activities/memory-math-add/memory-adddataset.js b/src/activities/memory-math-add/memory-adddataset.js
index b14dcd4bb..950ea0312 100644
--- a/src/activities/memory-math-add/memory-adddataset.js
+++ b/src/activities/memory-math-add/memory-adddataset.js
@@ -1,77 +1,77 @@
/* GCompris
*
* Copyright (C) 2014 Bruno Coudoin
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.import "qrc:/gcompris/src/activities/memory/math_util.js" as Memory
var memory_cards = [
{ // Level 1
columns: 5,
rows: 2,
texts: Memory.getAddTable(1)
},
{ // Level 2
columns: 5,
rows: 2,
texts: Memory.getAddTable(2)
},
{ // Level 3
columns: 5,
rows: 2,
texts: Memory.getAddTable(3)
},
{ // Level 4
columns: 5,
rows: 2,
texts: Memory.getAddTable(4)
},
{ // Level 5
columns: 5,
rows: 2,
texts: Memory.getAddTable(5)
},
{ // Level 6
columns: 5,
rows: 2,
texts: Memory.getAddTable(6)
},
{ // Level 7
columns: 5,
rows: 2,
texts: Memory.getAddTable(7)
},
{ // Level 8
columns: 5,
rows: 2,
texts: Memory.getAddTable(8)
},
{ // Level 9
columns: 5,
rows: 2,
texts: Memory.getAddTable(9)
},
{ // Level 10
columns: 5,
rows: 2,
texts: Memory.getAddTable(10)
}
]
function get() {
return memory_cards
}
diff --git a/src/activities/memory-math-div-tux/ActivityInfo.qml b/src/activities/memory-math-div-tux/ActivityInfo.qml
index 73d35fbfd..98613b573 100644
--- a/src/activities/memory-math-div-tux/ActivityInfo.qml
+++ b/src/activities/memory-math-div-tux/ActivityInfo.qml
@@ -1,42 +1,42 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 JB BUTET <ashashiwa@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "memory-math-div-tux/MemoryMathDivTux.qml"
difficulty: 6
icon: "memory-math-div-tux/memory-math-div-tux.svg"
author: "JB BUTET &lt;ashashiwa@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Division memory game against Tux")
//: Help title
description: qsTr("Turn the cards over to find a matching operation, until all the cards are gone.")
// intro: "Turn over two cards to match the calculation with its answer."
//: Help goal
goal: qsTr("Practice division, until all the cards are gone.")
//: Help prerequisite
prerequisite: qsTr("Division")
//: Help manual
manual: qsTr("You can see some cards, but you can't see what's on the other side of them. Each card is hiding an operation, or the answer to it.
In this game, these cards are hiding the two parts of an operation. You need to find the two parts of the operation, and bring them together again. Click on a card to see what number it's hiding, then try to find the other card that goes with it, to make a whole operation. You can only turn over two cards in one go, so you need to remember where the numbers are hiding, then you can match them when you find their other half. You're doing the job of the equals sign, and the numbers need you to put them together and make a proper equality. When you do that, both those cards disappear! When you've made them all disappear, found more than Tux and you've won the game!")
credit: ""
section: "math memory"
createdInVersion: 0
}
diff --git a/src/activities/memory-math-div-tux/MemoryMathDivTux.qml b/src/activities/memory-math-div-tux/MemoryMathDivTux.qml
index 7b5845afa..58b69c36d 100644
--- a/src/activities/memory-math-div-tux/MemoryMathDivTux.qml
+++ b/src/activities/memory-math-div-tux/MemoryMathDivTux.qml
@@ -1,31 +1,31 @@
/* gcompris
*
* Copyright (C) 2014 JB BUTET <ashashiwa@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* JB BUTET <ashashiwa@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../memory"
import "../memory-math-div/memory-divdataset.js" as Dataset
MemoryCommon {
dataset: Dataset.get()
backgroundImg: "qrc:/gcompris/src/activities/memory/resource/background.svg"
withTux: true
}
diff --git a/src/activities/memory-math-div/ActivityInfo.qml b/src/activities/memory-math-div/ActivityInfo.qml
index 8d3521d8a..202cdd160 100644
--- a/src/activities/memory-math-div/ActivityInfo.qml
+++ b/src/activities/memory-math-div/ActivityInfo.qml
@@ -1,42 +1,42 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 JB BUTET <ashashiwa@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "memory-math-div/MemoryMathDiv.qml"
difficulty: 6
icon: "memory-math-div/memory-math-div.svg"
author: "JB BUTET &lt;ashashiwa@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Division memory game")
//: Help title
description: qsTr("Turn the cards over to find a matching operation, until all the cards are gone.")
// intro: "Turn over two cards to match the calculation with its answer."
//: Help goal
goal: qsTr("Practice division, until all the cards are gone.")
//: Help prerequisite
prerequisite: qsTr("Division")
//: Help manual
manual: qsTr("You can see some cards, but you can't see what's on the other side of them. Each card is hiding an operation, or the answer to it.
In this game, these cards are hiding the two parts of an operation. You need to find the two parts of the operation, and bring them together again. Click on a card to see what number it's hiding, then try to find the other card that goes with it, to make a whole operation. You can only turn over two cards in one go, so you need to remember where the numbers are hiding, then you can match them when you find their other half. You're doing the job of the equals sign, and the numbers need you to put them together and make a proper equality. When you do that, both those cards disappear! When you've made them all disappear, found all the operations, you've won the game!")
credit: ""
section: "math memory"
createdInVersion: 0
}
diff --git a/src/activities/memory-math-div/MemoryMathDiv.qml b/src/activities/memory-math-div/MemoryMathDiv.qml
index 594af8307..433a5298d 100644
--- a/src/activities/memory-math-div/MemoryMathDiv.qml
+++ b/src/activities/memory-math-div/MemoryMathDiv.qml
@@ -1,30 +1,30 @@
/* gcompris - MemoryMathDiv.qml
*
* Copyright (C) 2014 JB BUTET <ashashiwa@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* JB BUTET <ashashiwa@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../memory"
import "memory-divdataset.js" as Dataset
MemoryCommon {
dataset: Dataset.get()
backgroundImg: "qrc:/gcompris/src/activities/memory/resource/background.svg"
}
diff --git a/src/activities/memory-math-div/memory-divdataset.js b/src/activities/memory-math-div/memory-divdataset.js
index d8188c0d4..2fad3cccd 100644
--- a/src/activities/memory-math-div/memory-divdataset.js
+++ b/src/activities/memory-math-div/memory-divdataset.js
@@ -1,77 +1,77 @@
/* GCompris
*
* Copyright (C) 2014 Bruno Coudoin
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.import "qrc:/gcompris/src/activities/memory/math_util.js" as Memory
var memory_cards = [
{ // Level 1
columns: 5,
rows: 2,
texts: Memory.getDivTable(1)
},
{ // Level 2
columns: 5,
rows: 2,
texts: Memory.getDivTable(2)
},
{ // Level 3
columns: 5,
rows: 2,
texts: Memory.getDivTable(3)
},
{ // Level 4
columns: 5,
rows: 2,
texts: Memory.getDivTable(4)
},
{ // Level 5
columns: 5,
rows: 2,
texts: Memory.getDivTable(5)
},
{ // Level 6
columns: 5,
rows: 2,
texts: Memory.getDivTable(6)
},
{ // Level 7
columns: 5,
rows: 2,
texts: Memory.getDivTable(7)
},
{ // Level 8
columns: 5,
rows: 2,
texts: Memory.getDivTable(8)
},
{ // Level 9
columns: 5,
rows: 2,
texts: Memory.getDivTable(9)
},
{ // Level 10
columns: 5,
rows: 2,
texts: Memory.getDivTable(10)
}
]
function get() {
return memory_cards
}
diff --git a/src/activities/memory-math-minus-tux/ActivityInfo.qml b/src/activities/memory-math-minus-tux/ActivityInfo.qml
index b40172c00..a27d8271f 100644
--- a/src/activities/memory-math-minus-tux/ActivityInfo.qml
+++ b/src/activities/memory-math-minus-tux/ActivityInfo.qml
@@ -1,42 +1,42 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 JB BUTET <ashashiwa@mgail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "memory-math-minus-tux/MemoryMathMinusTux.qml"
difficulty: 4
icon: "memory-math-minus-tux/memory-math-minus-tux.svg"
author: "JB BUTET &lt;ashashiwa@mgail.com&gt;"
demo: true
//: Activity title
title: qsTr("Subtraction memory game against Tux")
//: Help title
description: qsTr("Turn the cards over to find two numbers which subtract the same, until all the cards are gone.")
// intro: "Turn over two cards to match the calculation with its answer."
//: Help goal
goal: qsTr("Practice subtraction, until all the cards are gone. Tux will do the same")
//: Help prerequisite
prerequisite: qsTr("subtraction")
//: Help manual
manual: qsTr("You can see some cards, but you can't see what's on the other side of them. Each card is hiding an operation, or the answer to it.
In this game, these cards are hiding the two parts of an operation. You need to find the two parts of the operation, and bring them together again. Click on a card to see what number it's hiding, then try to find the other card that goes with it, to make a whole operation. You can only turn over two cards in one go, so you need to remember where the numbers are hiding, then you can match them when you find their other half. You're doing the job of the equals sign, and the numbers need you to put them together and make a proper equality. When you do that, both those cards disappear! When you've made them all disappear, found more operations than Tux and you've won the game!")
credit: ""
section: "math memory"
createdInVersion: 0
}
diff --git a/src/activities/memory-math-minus-tux/MemoryMathMinusTux.qml b/src/activities/memory-math-minus-tux/MemoryMathMinusTux.qml
index 9e0af62a6..ef270eeb2 100644
--- a/src/activities/memory-math-minus-tux/MemoryMathMinusTux.qml
+++ b/src/activities/memory-math-minus-tux/MemoryMathMinusTux.qml
@@ -1,27 +1,27 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 JB BUTET <ashashiwa@mgail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../memory"
import "../memory-math-minus/memory-minusdataset.js" as Dataset
MemoryCommon {
dataset: Dataset.get()
backgroundImg: "qrc:/gcompris/src/activities/memory/resource/background.svg"
withTux: true
}
diff --git a/src/activities/memory-math-minus/ActivityInfo.qml b/src/activities/memory-math-minus/ActivityInfo.qml
index 6d2e69e07..61c840ca0 100644
--- a/src/activities/memory-math-minus/ActivityInfo.qml
+++ b/src/activities/memory-math-minus/ActivityInfo.qml
@@ -1,42 +1,42 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 JB BUTET <ashashiwa@mgail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "memory-math-minus/MemoryMathMinus.qml"
difficulty: 4
icon: "memory-math-minus/memory-math-minus.svg"
author: "JB BUTET &lt;ashashiwa@mgail.com&gt;"
demo: true
//: Activity title
title: qsTr("Subtraction memory game")
//: Help title
description: qsTr("Turn the cards over to find two numbers which subtract the same, until all the cards are gone.")
// intro: "Turn over two cards to match the calculation with its answer."
//: Help goal
goal: qsTr("Practice subtraction, until all the cards are gone.")
//: Help prerequisite
prerequisite: qsTr("Subtraction")
//: Help manual
manual: qsTr("You can see some cards, but you can't see what's on the other side of them. Each card is hiding an operation, or the answer to it.
In this game, these cards are hiding the two parts of an operation. You need to find the two parts of the operation, and bring them together again. Click on a card to see what number it's hiding, then try to find the other card that goes with it, to make a whole operation. You can only turn over two cards in one go, so you need to remember where the numbers are hiding, then you can match them when you find their other half. You're doing the job of the equals sign, and the numbers need you to put them together and make a proper equality. When you do that, both those cards disappear! When you've made them all disappear, found all the operations, you've won the game!")
credit: ""
section: "math memory"
createdInVersion: 0
}
diff --git a/src/activities/memory-math-minus/MemoryMathMinus.qml b/src/activities/memory-math-minus/MemoryMathMinus.qml
index 657711887..6024643b6 100644
--- a/src/activities/memory-math-minus/MemoryMathMinus.qml
+++ b/src/activities/memory-math-minus/MemoryMathMinus.qml
@@ -1,30 +1,30 @@
/* gcompris - MemoryMathMinus.qml
*
* Copyright (C) 2014 JB BUTET <ashashiwa@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* JB BUTET <ashashiwa@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../memory"
import "memory-minusdataset.js" as Dataset
MemoryCommon {
dataset: Dataset.get()
backgroundImg: "qrc:/gcompris/src/activities/memory/resource/background.svg"
}
diff --git a/src/activities/memory-math-minus/memory-minusdataset.js b/src/activities/memory-math-minus/memory-minusdataset.js
index 4c025fb4f..c62cd80fd 100644
--- a/src/activities/memory-math-minus/memory-minusdataset.js
+++ b/src/activities/memory-math-minus/memory-minusdataset.js
@@ -1,77 +1,77 @@
/* GCompris
*
* Copyright (C) 2014 Bruno Coudoin
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.import "qrc:/gcompris/src/activities/memory/math_util.js" as Memory
var memory_cards = [
{ // Level 1
columns: 5,
rows: 2,
texts: Memory.getMinusTable(1)
},
{ // Level 2
columns: 5,
rows: 2,
texts: Memory.getMinusTable(2)
},
{ // Level 3
columns: 5,
rows: 2,
texts: Memory.getMinusTable(3)
},
{ // Level 4
columns: 5,
rows: 2,
texts: Memory.getMinusTable(4)
},
{ // Level 5
columns: 5,
rows: 2,
texts: Memory.getMinusTable(5)
},
{ // Level 6
columns: 5,
rows: 2,
texts: Memory.getMinusTable(6)
},
{ // Level 7
columns: 5,
rows: 2,
texts: Memory.getMinusTable(7)
},
{ // Level 8
columns: 5,
rows: 2,
texts: Memory.getMinusTable(8)
},
{ // Level 9
columns: 5,
rows: 2,
texts: Memory.getMinusTable(9)
},
{ // Level 10
columns: 5,
rows: 2,
texts: Memory.getMinusTable(10)
}
]
function get() {
return memory_cards
}
diff --git a/src/activities/memory-math-mult-div-tux/ActivityInfo.qml b/src/activities/memory-math-mult-div-tux/ActivityInfo.qml
index baf07ba8c..8c226ac5e 100644
--- a/src/activities/memory-math-mult-div-tux/ActivityInfo.qml
+++ b/src/activities/memory-math-mult-div-tux/ActivityInfo.qml
@@ -1,42 +1,42 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 JB BUTET <ashashiwa@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "memory-math-mult-div-tux/MemoryMathMultDivTux.qml"
difficulty: 6
icon: "memory-math-mult-div-tux/memory-math-mult-div-tux.svg"
author: "JB BUTET &lt;ashashiwa@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Multiplication and division memory game against Tux")
//: Help title
description: qsTr("Turn the cards over to find a matching operation, until all the cards are gone.")
// intro: "Turn over two cards to match the calculation with its answer."
//: Help goal
goal: qsTr("Practice multiplication, division, until all the cards are gone.")
//: Help prerequisite
prerequisite: qsTr("Multiplication, division")
//: Help manual
manual: qsTr("You can see some cards, but you can't see what's on the other side of them. Each card is hiding an operation, or the answer to it.
In this game, these cards are hiding the two parts of an operation. You need to find the two parts of the operation, and bring them together again. Click on a card to see what number it's hiding, then try to find the other card that goes with it, to make a whole operation. You can only turn over two cards in one go, so you need to remember where the numbers are hiding, then you can match them when you find their other half. You're doing the job of the equals sign, and the numbers need you to put them together and make a proper equality. When you do that, both those cards disappear! When you've made them all disappear, found more than Tux and you've won the game!")
credit: ""
section: "math memory"
createdInVersion: 0
}
diff --git a/src/activities/memory-math-mult-div-tux/MemoryMathMultDivTux.qml b/src/activities/memory-math-mult-div-tux/MemoryMathMultDivTux.qml
index ad2d3af1f..6c6c66c29 100644
--- a/src/activities/memory-math-mult-div-tux/MemoryMathMultDivTux.qml
+++ b/src/activities/memory-math-mult-div-tux/MemoryMathMultDivTux.qml
@@ -1,31 +1,31 @@
/* gcompris
*
* Copyright (C) 2014 JB BUTET <ashashiwa@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* JB BUTET <ashashiwa@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../memory"
import "../memory-math-mult-div/memory-multdivdataset.js" as Dataset
MemoryCommon {
dataset: Dataset.get()
backgroundImg: "qrc:/gcompris/src/activities/memory/resource/background.svg"
withTux: true
}
diff --git a/src/activities/memory-math-mult-div/ActivityInfo.qml b/src/activities/memory-math-mult-div/ActivityInfo.qml
index bf5d38b41..4f94d8bdf 100644
--- a/src/activities/memory-math-mult-div/ActivityInfo.qml
+++ b/src/activities/memory-math-mult-div/ActivityInfo.qml
@@ -1,42 +1,42 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 JB BUTET <ashashiwa@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "memory-math-mult-div/MemoryMathMultDiv.qml"
difficulty: 6
icon: "memory-math-mult-div/memory-math-mult-div.svg"
author: "JB BUTET &lt;ashashiwa@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Multiplication and division memory game")
//: Help title
description: qsTr("Turn the cards over to find a matching operation, until all the cards are gone.")
// intro: "Turn over two cards to match the calculation with its answer."
//: Help goal
goal: qsTr("Practice multiplication, division, until all the cards are gone.")
//: Help prerequisite
prerequisite: qsTr("Multiplication, division")
//: Help manual
manual: qsTr("You can see some cards, but you can't see what's on the other side of them. Each card is hiding an operation, or the answer to it.
In this game, these cards are hiding the two parts of an operation. You need to find the two parts of the operation, and bring them together again. Click on a card to see what number it's hiding, then try to find the other card that goes with it, to make a whole operation. You can only turn over two cards in one go, so you need to remember where the numbers are hiding, then you can match them when you find their other half. You're doing the job of the equals sign, and the numbers need you to put them together and make a proper equality. When you do that, both those cards disappear! When you've made them all disappear, found all the operations, you've won the game!")
credit: ""
section: "math memory"
createdInVersion: 0
}
diff --git a/src/activities/memory-math-mult-div/MemoryMathMultDiv.qml b/src/activities/memory-math-mult-div/MemoryMathMultDiv.qml
index 78752a7fc..2f6eab018 100644
--- a/src/activities/memory-math-mult-div/MemoryMathMultDiv.qml
+++ b/src/activities/memory-math-mult-div/MemoryMathMultDiv.qml
@@ -1,30 +1,30 @@
/* gcompris - MemoryMathMultDiv.qml
*
* Copyright (C) 2014 JB BUTET <ashashiwa@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* JB BUTET <ashashiwa@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../memory"
import "memory-multdivdataset.js" as Dataset
MemoryCommon {
dataset: Dataset.get()
backgroundImg: "qrc:/gcompris/src/activities/memory/resource/background.svg"
}
diff --git a/src/activities/memory-math-mult-div/memory-multdivdataset.js b/src/activities/memory-math-mult-div/memory-multdivdataset.js
index 9918b153e..0043ba5e7 100644
--- a/src/activities/memory-math-mult-div/memory-multdivdataset.js
+++ b/src/activities/memory-math-mult-div/memory-multdivdataset.js
@@ -1,77 +1,77 @@
/* GCompris
*
* Copyright (C) 2014 Bruno Coudoin
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.import "qrc:/gcompris/src/activities/memory/math_util.js" as Memory
var memory_cards = [
{ // Level 1
columns: 5,
rows: 2,
texts: Memory.getMultDivTable(1)
},
{ // Level 2
columns: 5,
rows: 2,
texts: Memory.getMultDivTable(2)
},
{ // Level 3
columns: 5,
rows: 2,
texts: Memory.getMultDivTable(3)
},
{ // Level 4
columns: 5,
rows: 2,
texts: Memory.getMultDivTable(4)
},
{ // Level 5
columns: 5,
rows: 2,
texts: Memory.getMultDivTable(5)
},
{ // Level 6
columns: 5,
rows: 2,
texts: Memory.getMultDivTable(6)
},
{ // Level 7
columns: 5,
rows: 2,
texts: Memory.getMultDivTable(7)
},
{ // Level 8
columns: 5,
rows: 2,
texts: Memory.getMultDivTable(8)
},
{ // Level 9
columns: 5,
rows: 2,
texts: Memory.getMultDivTable(9)
},
{ // Level 10
columns: 5,
rows: 2,
texts: Memory.getMultDivTable(10)
}
]
function get() {
return memory_cards
}
diff --git a/src/activities/memory-math-mult-tux/ActivityInfo.qml b/src/activities/memory-math-mult-tux/ActivityInfo.qml
index 151a85dcf..fde9ad3df 100644
--- a/src/activities/memory-math-mult-tux/ActivityInfo.qml
+++ b/src/activities/memory-math-mult-tux/ActivityInfo.qml
@@ -1,42 +1,42 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 JB BUTET <ashashiwa@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "memory-math-mult-tux/MemoryMathMultTux.qml"
difficulty: 5
icon: "memory-math-mult-tux/memory-math-mult-tux.svg"
author: "JB BUTET &lt;ashashiwa@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Multiplication memory game against Tux")
//: Help title
description: qsTr("Turn the cards over to find two numbers which multiply the same, until all the cards are gone.")
// intro: "Turn over two cards to match the calculation with its answer."
//: Help goal
goal: qsTr("Practice multiplication, until all the cards are gone.")
//: Help prerequisite
prerequisite: qsTr("Multiplication")
//: Help manual
manual: qsTr("You can see some cards, but you can't see what's on the other side of them. Each card is hiding an operation, or the answer to it.
In this game, these cards are hiding the two parts of an operation. You need to find the two parts of the operation, and bring them together again. Click on a card to see what number it's hiding, then try to find the other card that goes with it, to make a whole operation. You can only turn over two cards in one go, so you need to remember where the numbers are hiding, then you can match them when you find their other half. You're doing the job of the equals sign, and the numbers need you to put them together and make a proper equality. When you do that, both those cards disappear! When you've made them all disappear, found more than Tux and you've won the game!")
credit: ""
section: "math memory"
createdInVersion: 0
}
diff --git a/src/activities/memory-math-mult-tux/MemoryMathMultTux.qml b/src/activities/memory-math-mult-tux/MemoryMathMultTux.qml
index 60b1a94ae..768674c4b 100644
--- a/src/activities/memory-math-mult-tux/MemoryMathMultTux.qml
+++ b/src/activities/memory-math-mult-tux/MemoryMathMultTux.qml
@@ -1,31 +1,31 @@
/* gcompris
*
* Copyright (C) 2014 JB BUTET <ashashiwa@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* JB BUTET <ashashiwa@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../memory"
import "../memory-math-mult/memory-multdataset.js" as Dataset
MemoryCommon {
dataset: Dataset.get()
backgroundImg: "qrc:/gcompris/src/activities/memory/resource/background.svg"
withTux: true
}
diff --git a/src/activities/memory-math-mult/ActivityInfo.qml b/src/activities/memory-math-mult/ActivityInfo.qml
index def9945ac..dff39dc20 100644
--- a/src/activities/memory-math-mult/ActivityInfo.qml
+++ b/src/activities/memory-math-mult/ActivityInfo.qml
@@ -1,42 +1,42 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 JB BUTET <ashashiwa@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "memory-math-mult/MemoryMathMult.qml"
difficulty: 5
icon: "memory-math-mult/memory-math-mult.svg"
author: "JB BUTET &lt;ashashiwa@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Multiplication memory game")
//: Help title
description: qsTr("Turn the cards over to find two numbers which multiply the same, until all the cards are gone.")
// intro: "Turn over two cards to match the calculation with its answer."
//: Help goal
goal: qsTr("Practice multiplication, until all the cards are gone.")
//: Help prerequisite
prerequisite: qsTr("Multiplication")
//: Help manual
manual: qsTr("You can see some cards, but you can't see what's on the other side of them. Each card is hiding an operation, or the answer to it.
In this game, these cards are hiding the two parts of an operation. You need to find the two parts of the operation, and bring them together again. Click on a card to see what number it's hiding, then try to find the other card that goes with it, to make a whole operation. You can only turn over two cards in one go, so you need to remember where the numbers are hiding, then you can match them when you find their other half. You're doing the job of the equals sign, and the numbers need you to put them together and make a proper equality. When you do that, both those cards disappear! When you've made them all disappear, found all the operations, you've won the game!")
credit: ""
section: "math memory"
createdInVersion: 0
}
diff --git a/src/activities/memory-math-mult/MemoryMathMult.qml b/src/activities/memory-math-mult/MemoryMathMult.qml
index 0fc16f6d6..877c1b18c 100644
--- a/src/activities/memory-math-mult/MemoryMathMult.qml
+++ b/src/activities/memory-math-mult/MemoryMathMult.qml
@@ -1,30 +1,30 @@
/* gcompris - MemoryMathMult.qml
*
* Copyright (C) 2014 JB BUTET <ashashiwa@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* JB BUTET <ashashiwa@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../memory"
import "memory-multdataset.js" as Dataset
MemoryCommon {
dataset: Dataset.get()
backgroundImg: "qrc:/gcompris/src/activities/memory/resource/background.svg"
}
diff --git a/src/activities/memory-math-mult/memory-multdataset.js b/src/activities/memory-math-mult/memory-multdataset.js
index 3c0dde646..e79e04d5e 100644
--- a/src/activities/memory-math-mult/memory-multdataset.js
+++ b/src/activities/memory-math-mult/memory-multdataset.js
@@ -1,77 +1,77 @@
/* GCompris
*
* Copyright (C) 2014 Bruno Coudoin
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.import "qrc:/gcompris/src/activities/memory/math_util.js" as Memory
var memory_cards = [
{ // Level 1
columns: 5,
rows: 2,
texts: Memory.getMultTable(1)
},
{ // Level 2
columns: 5,
rows: 2,
texts: Memory.getMultTable(2)
},
{ // Level 3
columns: 5,
rows: 2,
texts: Memory.getMultTable(3)
},
{ // Level 4
columns: 5,
rows: 2,
texts: Memory.getMultTable(4)
},
{ // Level 5
columns: 5,
rows: 2,
texts: Memory.getMultTable(5)
},
{ // Level 6
columns: 5,
rows: 2,
texts: Memory.getMultTable(6)
},
{ // Level 7
columns: 5,
rows: 2,
texts: Memory.getMultTable(7)
},
{ // Level 8
columns: 5,
rows: 2,
texts: Memory.getMultTable(8)
},
{ // Level 9
columns: 5,
rows: 2,
texts: Memory.getMultTable(9)
},
{ // Level 10
columns: 5,
rows: 2,
texts: Memory.getMultTable(10)
}
]
function get() {
return memory_cards
}
diff --git a/src/activities/memory-sound-tux/ActivityInfo.qml b/src/activities/memory-sound-tux/ActivityInfo.qml
index 2691a127a..b6968cd68 100644
--- a/src/activities/memory-sound-tux/ActivityInfo.qml
+++ b/src/activities/memory-sound-tux/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "memory-sound-tux/MemorySoundTux.qml"
difficulty: 2
icon: "memory-sound-tux/memory-sound-tux.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
//: Activity title
title: qsTr("Audio memory game against Tux")
//: Help title
description: qsTr("Play the audio memory game against Tux")
// intro: "Click on an audio card and find its double."
//: Help goal
goal: qsTr("Train your audio memory and remove all the cards.")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("A set of cards is shown. Each card has an associated sound, and each sound has a twin exactly the same. Click on a card to hear its hidden sound, and try to match the twins. You can only activate two cards at once, so you need to remember where a sound is, while you listen to its twin. When you turn over the twins, they both disappear.")
credit: ""
section: "discovery memory music"
createdInVersion: 0
}
diff --git a/src/activities/memory-sound-tux/MemorySoundTux.qml b/src/activities/memory-sound-tux/MemorySoundTux.qml
index 5a80d89db..270395b1a 100644
--- a/src/activities/memory-sound-tux/MemorySoundTux.qml
+++ b/src/activities/memory-sound-tux/MemorySoundTux.qml
@@ -1,31 +1,31 @@
/* gcompris - MemorySound.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../memory"
import "../memory-sound/memorysounddataset.js" as Dataset
MemoryCommon {
dataset: Dataset.get()
backgroundImg: "qrc:/gcompris/src/activities/memory-sound/resource/gcompris_band.svg"
withTux: true
}
diff --git a/src/activities/memory-sound/ActivityInfo.qml b/src/activities/memory-sound/ActivityInfo.qml
index ad3e6a582..d36ac0697 100644
--- a/src/activities/memory-sound/ActivityInfo.qml
+++ b/src/activities/memory-sound/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 JB BUTET <ashashiwa@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "memory-sound/MemorySound.qml"
difficulty: 2
icon: "memory-sound/memory-sound.svg"
author: "JB BUTET &lt;ashashiwa@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Audio memory game")
//: Help title
description: qsTr("Click on cards and listen to find the matching sounds")
// intro: "Click on an audio card and find its double."
//: Help goal
goal: qsTr("Train your audio memory and remove all the cards.")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("A set of cards is shown. Each card has an associated sound, and each sound has a twin exactly the same. Click on a card to hear its hidden sound, and try to match the twins. You can only activate two cards at once, so you need to remember where a sound is, while you listen to its twin. When you turn over the twins, they both disappear.")
credit: ""
section: "discovery memory music"
createdInVersion: 0
}
diff --git a/src/activities/memory-sound/MemorySound.qml b/src/activities/memory-sound/MemorySound.qml
index ea1d62547..f9601e825 100644
--- a/src/activities/memory-sound/MemorySound.qml
+++ b/src/activities/memory-sound/MemorySound.qml
@@ -1,31 +1,31 @@
/* gcompris - MemorySound.qml
*
* Copyright (C) 2014 JB BUTET <ashashiwa@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* JB BUTET <ashashiwa@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../memory"
import "memorysounddataset.js" as Dataset
MemoryCommon {
dataset: Dataset.get()
backgroundImg: "qrc:/gcompris/src/activities/memory-sound/resource/gcompris_band.svg"
}
diff --git a/src/activities/memory-sound/memorysounddataset.js b/src/activities/memory-sound/memorysounddataset.js
index bb199c387..5d7d4cfa9 100644
--- a/src/activities/memory-sound/memorysounddataset.js
+++ b/src/activities/memory-sound/memorysounddataset.js
@@ -1,117 +1,117 @@
/* GCompris
*
* Copyright (C) 2014 Bruno Coudoin
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.import GCompris 1.0 as GCompris
var url = "qrc:/gcompris/src/activities/memory-sound/resource/"
var memory_sounds =
[
[ GCompris.ApplicationInfo.getAudioFilePath(url + 'guitar_melody.$CA'), GCompris.ApplicationInfo.getAudioFilePath(url + 'guitar_melody.$CA')],
[ GCompris.ApplicationInfo.getAudioFilePath(url + 'guitar_son1.$CA'), GCompris.ApplicationInfo.getAudioFilePath(url + 'guitar_son1.$CA')],
[ GCompris.ApplicationInfo.getAudioFilePath(url + 'guitar_son2.$CA'), GCompris.ApplicationInfo.getAudioFilePath(url + 'guitar_son2.$CA')],
[ GCompris.ApplicationInfo.getAudioFilePath(url + 'guitar_son3.$CA'), GCompris.ApplicationInfo.getAudioFilePath(url + 'guitar_son3.$CA')],
[ GCompris.ApplicationInfo.getAudioFilePath(url + 'guitar_son4.$CA'), GCompris.ApplicationInfo.getAudioFilePath(url + 'guitar_son4.$CA')],
[ GCompris.ApplicationInfo.getAudioFilePath(url + 'LRApplauses_1_LA_cut.$CA'), GCompris.ApplicationInfo.getAudioFilePath(url + 'LRApplauses_1_LA_cut.$CA')],
[ GCompris.ApplicationInfo.getAudioFilePath(url + 'LRBark_1_LA_cut.$CA'), GCompris.ApplicationInfo.getAudioFilePath(url + 'LRBark_1_LA_cut.$CA')],
[ GCompris.ApplicationInfo.getAudioFilePath(url + 'LRBark_3_LA_cut.$CA'), GCompris.ApplicationInfo.getAudioFilePath(url + 'LRBark_3_LA_cut.$CA')],
[ GCompris.ApplicationInfo.getAudioFilePath(url + 'LRBuddhist_gong_05_LA.$CA'), GCompris.ApplicationInfo.getAudioFilePath(url + 'LRBuddhist_gong_05_LA.$CA')],
[ GCompris.ApplicationInfo.getAudioFilePath(url + 'LRDoor_Open_2_LA.$CA'), GCompris.ApplicationInfo.getAudioFilePath(url + 'LRDoor_Open_2_LA.$CA')],
[ GCompris.ApplicationInfo.getAudioFilePath(url + 'LRFactory_noise_01_LA.$CA'), GCompris.ApplicationInfo.getAudioFilePath(url + 'LRFactory_noise_01_LA.$CA')],
[ GCompris.ApplicationInfo.getAudioFilePath(url + 'LRFactory_noise_02_LA.$CA'), GCompris.ApplicationInfo.getAudioFilePath(url + 'LRFactory_noise_02_LA.$CA')],
[ GCompris.ApplicationInfo.getAudioFilePath(url + 'LRFactory_noise_03_LA.$CA'), GCompris.ApplicationInfo.getAudioFilePath(url + 'LRFactory_noise_03_LA.$CA')],
[ GCompris.ApplicationInfo.getAudioFilePath(url + 'LRFactory_noise_04_LA.$CA'), GCompris.ApplicationInfo.getAudioFilePath(url + 'LRFactory_noise_04_LA.$CA')],
[ GCompris.ApplicationInfo.getAudioFilePath(url + 'LRFactory_noise_05_LA.$CA'), GCompris.ApplicationInfo.getAudioFilePath(url + 'LRFactory_noise_05_LA.$CA')],
[ GCompris.ApplicationInfo.getAudioFilePath(url + 'LRFactory_noise_06_LA.$CA'), GCompris.ApplicationInfo.getAudioFilePath(url + 'LRFactory_noise_06_LA.$CA')],
[ GCompris.ApplicationInfo.getAudioFilePath(url + 'LRFireballs_01_LA.$CA'), GCompris.ApplicationInfo.getAudioFilePath(url + 'LRFireballs_01_LA.$CA')],
[ GCompris.ApplicationInfo.getAudioFilePath(url + 'LRFrogsInPondDuringStormLACut.$CA'), GCompris.ApplicationInfo.getAudioFilePath(url + 'LRFrogsInPondDuringStormLACut.$CA')],
[ GCompris.ApplicationInfo.getAudioFilePath(url + 'LRHeart_beat_01_LA.$CA'), GCompris.ApplicationInfo.getAudioFilePath(url + 'LRHeart_beat_01_LA.$CA')],
[ GCompris.ApplicationInfo.getAudioFilePath(url + 'LRHits_01_LA.$CA'), GCompris.ApplicationInfo.getAudioFilePath(url + 'LRHits_01_LA.$CA')],
[ GCompris.ApplicationInfo.getAudioFilePath(url + 'LRLaPause_short.$CA'), GCompris.ApplicationInfo.getAudioFilePath(url + 'LRLaPause_short.$CA')],
[ GCompris.ApplicationInfo.getAudioFilePath(url + 'LRObject_falling_01_LA.$CA'), GCompris.ApplicationInfo.getAudioFilePath(url + 'LRObject_falling_01_LA.$CA')],
[ GCompris.ApplicationInfo.getAudioFilePath(url + 'LRObject_falling_02_LA.$CA'), GCompris.ApplicationInfo.getAudioFilePath(url + 'LRObject_falling_02_LA.$CA')],
[ GCompris.ApplicationInfo.getAudioFilePath(url + 'LRRain_in_garden_01_LA_cut.$CA'), GCompris.ApplicationInfo.getAudioFilePath(url + 'LRRain_in_garden_01_LA_cut.$CA')],
[ GCompris.ApplicationInfo.getAudioFilePath(url + 'LRRing_01_LA.$CA'), GCompris.ApplicationInfo.getAudioFilePath(url + 'LRRing_01_LA.$CA')],
[ GCompris.ApplicationInfo.getAudioFilePath(url + 'LRStartAndStopCarEngine1LACut.$CA'), GCompris.ApplicationInfo.getAudioFilePath(url + 'LRStartAndStopCarEngine1LACut.$CA')],
[ GCompris.ApplicationInfo.getAudioFilePath(url + 'LRTrain_slowing_down_01_LA_cut.$CA'), GCompris.ApplicationInfo.getAudioFilePath(url + 'LRTrain_slowing_down_01_LA_cut.$CA')],
[ GCompris.ApplicationInfo.getAudioFilePath(url + 'LRWeird_1_LA.$CA'), GCompris.ApplicationInfo.getAudioFilePath(url + 'LRWeird_1_LA.$CA')],
[ GCompris.ApplicationInfo.getAudioFilePath(url + 'LRWeird_2_LA.$CA'), GCompris.ApplicationInfo.getAudioFilePath(url + 'LRWeird_2_LA.$CA')],
[ GCompris.ApplicationInfo.getAudioFilePath(url + 'LRWeird_3_LA.$CA'), GCompris.ApplicationInfo.getAudioFilePath(url + 'LRWeird_3_LA.$CA')],
[ GCompris.ApplicationInfo.getAudioFilePath(url + 'LRWeird_4_LA.$CA'), GCompris.ApplicationInfo.getAudioFilePath(url + 'LRWeird_4_LA.$CA')],
[ GCompris.ApplicationInfo.getAudioFilePath(url + 'LRWeird_5_LA.$CA'), GCompris.ApplicationInfo.getAudioFilePath(url + 'LRWeird_5_LA.$CA')],
[ GCompris.ApplicationInfo.getAudioFilePath(url + 'LRWeird_6_LA.$CA'), GCompris.ApplicationInfo.getAudioFilePath(url + 'LRWeird_6_LA.$CA')]
]
var images = []
var memory_cards = [
{ // Level 1
columns: 3,
rows: 2,
sounds: memory_sounds,
images: images
},
{ // Level 2
columns: 4,
rows: 2,
sounds: memory_sounds,
images: images
},
{ // Level 3
columns: 5,
rows: 2,
sounds: memory_sounds,
images: images
},
{ // Level 4
columns: 4,
rows: 3,
sounds: memory_sounds,
images: images
},
{ // Level 5
columns: 5,
rows: 6,
sounds: memory_sounds,
images: images
},
{ // Level 6
columns: 5,
rows: 4,
sounds: memory_sounds,
images: images
},
{ // Level 7
columns: 6,
rows: 4,
sounds: memory_sounds,
images: images
},
]
function get() {
// Images are the same, create a list as large as memory_sounds
for(var i in memory_sounds)
images.push([url + 'Tux_play.png', url + 'Tux_play.png'])
return memory_cards
}
diff --git a/src/activities/memory-tux/ActivityInfo.qml b/src/activities/memory-tux/ActivityInfo.qml
index 65affde64..730e5277e 100644
--- a/src/activities/memory-tux/ActivityInfo.qml
+++ b/src/activities/memory-tux/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 JB BUTET <ashashiwa@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "memory-tux/MemoryTux.qml"
difficulty: 1
icon: "memory-tux/memory-tux.svg"
author: "JB BUTET &lt;ashashiwa@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Memory Game with images against Tux")
//: Help title
description: qsTr("Flip the cards to find the matching pairs against Tux")
// intro: "Click on a card and find its double."
//: Help goal
goal: qsTr("Train your memory and remove all the cards")
//: Help prerequisite
prerequisite: qsTr("Mouse-manipulation")
//: Help manual
manual: qsTr("A set of blank cards is shown. Each card has a picture on the other side, and each picture card has a twin exactly the same. Click on a card to see its hidden picture, and try to match the twins. You can only turn over two cards at once, so you need to remember where a picture is, while you look for its twin. When you turn over the twins, they both disappear. Tux teacher do the same.")
credit: ""
section: "discovery memory"
createdInVersion: 0
}
diff --git a/src/activities/memory-tux/MemoryTux.qml b/src/activities/memory-tux/MemoryTux.qml
index 806ed0d23..184b10811 100644
--- a/src/activities/memory-tux/MemoryTux.qml
+++ b/src/activities/memory-tux/MemoryTux.qml
@@ -1,31 +1,31 @@
/* gcompris
*
* Copyright (C) 2014 JB BUTET <ashashiwa@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* JB BUTET <ashashiwa@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../memory"
import "../memory/memorydataset.js" as Dataset
MemoryCommon {
dataset: Dataset.get()
backgroundImg: "qrc:/gcompris/src/activities/memory/resource/background.svg"
withTux: true
}
diff --git a/src/activities/memory-wordnumber/ActivityInfo.qml b/src/activities/memory-wordnumber/ActivityInfo.qml
index 09c5170d7..7bb5179b7 100644
--- a/src/activities/memory-wordnumber/ActivityInfo.qml
+++ b/src/activities/memory-wordnumber/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "memory-wordnumber/MemoryWordnumber.qml"
difficulty: 3
icon: "memory-wordnumber/memory-wordnumber.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
//: Activity title
title: qsTr("Wordnumber memory game")
//: Help title
description: qsTr("Turn the cards over to match the number with the word matching it.")
// intro: "Match the numeric with the word."
//: Help goal
goal: qsTr("Reading numbers, memory.")
//: Help prerequisite
prerequisite: qsTr("Reading")
//: Help manual
manual: qsTr("You can see some cards, but you can't see what's on the other side of them. Each card is hiding the numeral form of a number, or the word to write it.")
credit: ""
section: "reading"
createdInVersion: 0
}
diff --git a/src/activities/memory-wordnumber/MemoryWordnumber.qml b/src/activities/memory-wordnumber/MemoryWordnumber.qml
index be5a8ef00..0cafabc61 100644
--- a/src/activities/memory-wordnumber/MemoryWordnumber.qml
+++ b/src/activities/memory-wordnumber/MemoryWordnumber.qml
@@ -1,30 +1,30 @@
/* GCompris - Memory.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../memory"
import "dataset.js" as Dataset
MemoryCommon {
dataset: Dataset.get()
backgroundImg: "qrc:/gcompris/src/activities/memory-wordnumber/resource/background.svg"
}
diff --git a/src/activities/memory-wordnumber/dataset.js b/src/activities/memory-wordnumber/dataset.js
index 08c213a39..5f0b4d122 100644
--- a/src/activities/memory-wordnumber/dataset.js
+++ b/src/activities/memory-wordnumber/dataset.js
@@ -1,127 +1,127 @@
/* GCompris
*
* Copyright (C) 2014 Bruno Coudoin
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.import GCompris 1.0 as GCompris //for ApplicationInfo
var texts = [
[qsTr("zero"), 0],
[qsTr("one"), 1],
[qsTr("two"), 2],
[qsTr("three"), 3],
[qsTr("four"), 4],
[qsTr("five"), 5],
[qsTr("six"), 6],
[qsTr("seven"), 7],
[qsTr("eight"), 8],
[qsTr("nine"), 9],
[qsTr("ten"), 10],
[qsTr("eleven"), 11],
[qsTr("twelve"), 12],
[qsTr("thirteen"), 13],
[qsTr("fourteen"), 14],
[qsTr("fifteen"), 15],
[qsTr("sixteen"), 16],
[qsTr("seventeen"), 17],
[qsTr("eighteen"), 18],
[qsTr("nineteen"), 19],
[qsTr("twenty"), 20]
]
var sounds = [
["",
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/U0030.$CA")],
["",
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/U0031.$CA")],
["",
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/U0032.$CA")],
["",
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/U0033.$CA")],
["",
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/U0034.$CA")],
["",
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/U0035.$CA")],
["",
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/U0036.$CA")],
["",
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/U0037.$CA")],
["",
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/U0038.$CA")],
["",
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/U0039.$CA")],
["",
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/10.$CA")],
["",
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/11.$CA")],
["",
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/12.$CA")],
["",
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/13.$CA")],
["",
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/14.$CA")],
["",
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/15.$CA")],
["",
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/16.$CA")],
["",
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/17.$CA")],
["",
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/18.$CA")],
["",
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/19.$CA")],
["",
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/20.$CA")]
]
var memory_cards = [
{ // Level 1
columns: 3,
rows: 2,
texts: texts.slice(0, 6),
sounds: sounds.slice(0, 6)
},
{ // Level 2
columns: 3,
rows: 2,
texts: texts.slice(5, 11),
sounds: sounds.slice(5, 11)
},
{ // Level 3
columns: 5,
rows: 2,
texts: texts.slice(0, 11),
sounds: sounds.slice(0, 11)
},
{ // Level 4
columns: 5,
rows: 2,
texts: texts.slice(10, 21),
sounds: sounds.slice(10, 21)
},
{ // Level 5
columns: 6,
rows: 3,
texts: texts.slice(0, 21),
sounds: sounds.slice(0, 21)
}
]
function get() {
return memory_cards
}
diff --git a/src/activities/memory/ActivityInfo.qml b/src/activities/memory/ActivityInfo.qml
index f53e64d4b..d039d2ead 100644
--- a/src/activities/memory/ActivityInfo.qml
+++ b/src/activities/memory/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 JB BUTET <ashashiwa@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "memory/Memory.qml"
difficulty: 1
icon: "memory/memory.svg"
author: "JB BUTET &lt;ashashiwa@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Memory Game with images")
//: Help title
description: qsTr("Flip the cards to find the matching pairs")
// intro: "Click on a card and find its double."
//: Help goal
goal: qsTr("Train your memory and remove all the cards")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("A set of blank cards is shown. Each card has a picture on the other side, and each picture card has a twin exactly the same. Click on a card to see its hidden picture, and try to match the twins. You can only turn over two cards at once, so you need to remember where a picture is, while you look for its twin. When you turn over the twins, they both disappear.")
credit: ""
section: "discovery memory"
createdInVersion: 0
}
diff --git a/src/activities/memory/CardItem.qml b/src/activities/memory/CardItem.qml
index cf733097d..408cdbe5c 100644
--- a/src/activities/memory/CardItem.qml
+++ b/src/activities/memory/CardItem.qml
@@ -1,152 +1,152 @@
/* gcompris - CardItem.qml
*
* Copyright (C) 2014 JB BUTET <ashashiwa@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* JB BUTET <ashashiwa@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "memory.js" as Activity
Flipable {
id: card
property var pairData
property bool isBack: true
property bool isShown: false
property bool isFound: false
property bool tuxTurn
property GCAudio audioVoices
property GCSfx audioEffects
onIsFoundChanged: {
opacity = 0
timer.start()
}
Timer {
id: timer
interval: 100
running: false
repeat: false
onTriggered: particles.burst(50)
}
ParticleSystemStarLoader {
id: particles
clip: false
}
Timer {
id: animationTimer
interval: 1500
running: false
repeat: false
onTriggered: selectionReady()
}
back: Image {
source: card.pairData.emptyCard
sourceSize.width: parent.width
fillMode: Image.PreserveAspectFit
anchors.centerIn: parent
anchors.fill: parent
Image {
id: contentImage
source: card.pairData.image
width: parent.paintedWidth * 0.9
height: parent.paintedHeight * 0.9
sourceSize.width: contentImage.width
sourceSize.height: contentImage.height
anchors.centerIn: parent
fillMode: Image.PreserveAspectFit
}
GCText {
anchors.centerIn: parent
fontSize: largeSize
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
color: "black"
font.bold: true
style: Text.Outline
styleColor: "white"
text: card.pairData.text
}
}
// Warning front and back property are reversed. Could not find
// a way to display back at start time without this trick
front: Image {
fillMode: Image.PreserveAspectFit
source: card.pairData.back
sourceSize.width: parent.width
anchors.centerIn: parent
anchors.fill: parent
}
transform: Rotation {
id: rotation
origin.x: card.width / 2
origin.y: card.height / 2
axis.x: 0; axis.y: 1; axis.z: 0
angle: 0
}
transitions: Transition {
NumberAnimation { target: rotation; property: "angle"; duration: 750 }
}
MouseArea {
anchors.fill: parent
enabled: card.isBack && !card.isFound && !card.tuxTurn && items.selectionCount < 2
onClicked: selected()
}
function selected() {
card.isBack = false
card.isShown = true
items.selectionCount++
animationTimer.start()
audioEffects.play(Activity.url + "card_flip.wav")
}
function selectionReady() {
var pairs = Activity.addPlayQueue(card)
var win = Activity.reverseCardsIfNeeded()
if(tuxTurn && win || tuxTurn && !pairs)
Activity.tuxPlay()
if (card.pairData.sound) {
audioVoices.play(card.pairData.sound)
}
}
Behavior on opacity { NumberAnimation { duration: 1000 } }
- states : [
+ states: [
State {
name: "front"
PropertyChanges { target: rotation; angle: 180 }
when: !card.isBack
}
]
}
diff --git a/src/activities/memory/Memory.qml b/src/activities/memory/Memory.qml
index e6811e4ae..4930ad347 100644
--- a/src/activities/memory/Memory.qml
+++ b/src/activities/memory/Memory.qml
@@ -1,30 +1,30 @@
/* GCompris - Memory.qml
*
* Copyright (C) 2014 JB BUTET <ashashiwa@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* JB BUTET <ashashiwa@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../memory"
import "memorydataset.js" as Dataset
MemoryCommon {
dataset: Dataset.get()
backgroundImg: Dataset.url + "background.svg"
}
diff --git a/src/activities/memory/MemoryCommon.qml b/src/activities/memory/MemoryCommon.qml
index 0852e2d4a..cd28e182f 100644
--- a/src/activities/memory/MemoryCommon.qml
+++ b/src/activities/memory/MemoryCommon.qml
@@ -1,195 +1,247 @@
/* GCompris - MemoryCommon.qml
*
* Copyright (C) 2014 JB BUTET <ashashiwa@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* JB BUTET <ashashiwa@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "."
import "../../core"
import "memory.js" as Activity
ActivityBase {
id: activity
focus: true
property string backgroundImg
property var dataset
property bool withTux: false
- property string additionnalPath
onStart: focus = true
onStop: {}
pageComponent: Image {
id: background
source: activity.backgroundImg
sourceSize.width: Math.max(parent.width, parent.height)
fillMode: Image.PreserveAspectCrop
focus: true
signal start
signal stop
property alias items: items
+ property bool keyNavigationVisible: false
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
QtObject {
id: items
property alias bar: bar
property alias bonus: bonus
property GCSfx audioEffects: activity.audioEffects
property bool withTux: activity.withTux
property bool tuxTurn: false
property var playQueue
property int selectionCount
property int tuxScore: tuxScore.text
property int playerScore: playerScore.text
property var dataset: activity.dataset
property alias containerModel: containerModel
- property alias cardRepeater: cardRepeater
property alias grid: grid
+ property bool blockClicks: false
property int columns
property int rows
+ property int spacing: 5 * ApplicationInfo.ratio
}
onStart: Activity.start(items)
onStop: Activity.stop()
ListModel {
id: containerModel
}
- Grid {
+
+ GridView {
id: grid
- spacing: 5 * ApplicationInfo.ratio
- columns: items.columns
- rows: items.rows
+ width: background.width - (items.columns + 1) * items.spacing - anchors.margins
+ height: background.height - (items.rows + 1) * items.spacing - anchors.margins
+ cellWidth: (background.width - (items.columns + 1) * items.spacing) / items.columns - anchors.margins
+ cellHeight: (background.height - (items.rows + 1) * items.spacing) / (items.rows + 0.5) - anchors.margins
anchors {
left: background.left
- right: background.rigth
+ right: background.right
top: background.top
- margins: 10 * ApplicationInfo.ratio
+ bottom: background.bottom
+ margins: 5 * ApplicationInfo.ratio
+ }
+
+ model: containerModel
+
+ function getItemAtIndex(i) {
+ var xi = (i % items.columns) * cellWidth + anchors.margins
+ var yi = (i / items.columns) * cellHeight + anchors.margins
+ return itemAt(xi, yi)
}
- Repeater {
- id: cardRepeater
- model: containerModel
-
- delegate: CardItem {
- pairData: pairData_
- tuxTurn: background.items.tuxTurn
- width: (background.width - (grid.columns + 1) * grid.spacing) / grid.columns
- height: (background.height - (grid.rows + 1) * grid.spacing) / (grid.rows + 0.5)
- audioVoices: activity.audioVoices
- audioEffects: activity.audioEffects
- }
+ delegate: CardItem {
+ pairData: pairData_
+ tuxTurn: background.items.tuxTurn
+ width: (background.width - (items.columns + 1) * items.spacing) / items.columns - 15 * ApplicationInfo.ratio
+ height: (background.height - (items.rows + 1) * items.spacing) / (items.rows + 0.5) - 15 * ApplicationInfo.ratio
+ audioVoices: activity.audioVoices
+ audioEffects: activity.audioEffects
+ onIsFoundChanged: background.keyNavigationVisible = false
+ }
+ interactive: false
+ keyNavigationWraps: true
+ highlightFollowsCurrentItem: true
+ highlight: Rectangle {
+ color: "#AAFFFFFF"
+ radius: 10
+ visible: background.keyNavigationVisible
+ Behavior on x { SpringAnimation { spring: 2; damping: 0.2 } }
+ Behavior on y { SpringAnimation { spring: 2; damping: 0.2 } }
}
add: Transition {
PathAnimation {
path: Path {
PathCurve { x: background.width / 3}
PathCurve { y: background.height / 3}
PathCurve {}
}
easing.type: Easing.InOutQuad
duration: 2000
}
}
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level }
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: home()
}
Image {
id: player
source: 'qrc:/gcompris/src/activities/memory/resource/children.svg'
anchors {
bottom: bar.bottom
right: parent.right
rightMargin: 2 * ApplicationInfo.ratio
}
width: height * 0.83
height: bar.height * 1.2
GCText {
id: playerScore
anchors.centerIn: parent
anchors.verticalCenterOffset: parent.height / 6
color: "black"
font.bold: true
fontSize: largeSize
style: Text.Outline
styleColor: "white"
text: items.playerScore
}
}
Image {
id: tux
visible: activity.withTux
source: 'qrc:/gcompris/src/activities/memory/resource/tux-teacher.svg'
anchors {
bottom: bar.bottom
right: player.left
rightMargin: 2 * ApplicationInfo.ratio
}
width: height * 0.83
height: bar.height * 1.2
GCText {
id: tuxScore
anchors.centerIn: parent
anchors.verticalCenterOffset: parent.height / 6
color: "black"
font.bold: true
fontSize: largeSize
style: Text.Outline
styleColor: "white"
text: items.tuxScore
}
}
Bonus {
id: bonus
interval: 2000
Component.onCompleted: win.connect(Activity.nextLevel)
}
- }
+ Keys.enabled: !items.blockClicks
+ Keys.onPressed: {
+ background.keyNavigationVisible = true
+ if(event.key === Qt.Key_Left) {
+ grid.moveCurrentIndexLeft()
+ // skip the highlight on the already found cards
+ while(grid.currentItem.isFound && !items.blockClicks) {
+ grid.moveCurrentIndexLeft()
+ }
+ }
+ else if(event.key === Qt.Key_Right) {
+ grid.moveCurrentIndexRight()
+ // skip the highlight on the already found cards
+ while(grid.currentItem.isFound && !items.blockClicks) {
+ grid.moveCurrentIndexRight()
+ }
+ }
+ else if(event.key === Qt.Key_Up) {
+ grid.moveCurrentIndexUp()
+ // skip the highlight on the already found cards
+ while(grid.currentItem.isFound && !items.blockClicks) {
+ grid.moveCurrentIndexUp()
+ }
+ }
+ else if(event.key === Qt.Key_Down) {
+ grid.moveCurrentIndexDown()
+ // skip the highlight on the already found cards
+ while(grid.currentItem.isFound && !items.blockClicks) {
+ grid.moveCurrentIndexDown()
+ }
+ }
+ else if(event.key === Qt.Key_Space || event.key === Qt.Key_Enter || event.key === Qt.Key_Return)
+ if(grid.currentItem.isBack && !grid.currentItem.isFound && !grid.currentItem.tuxTurn && items.selectionCount < 2) grid.currentItem.selected()
+ }
+ }
}
diff --git a/src/activities/memory/math_util.js b/src/activities/memory/math_util.js
index 653c32cb3..c3c9b4fa4 100644
--- a/src/activities/memory/math_util.js
+++ b/src/activities/memory/math_util.js
@@ -1,111 +1,111 @@
/* GCompris
*
* Copyright (C) 2014 Bruno Coudoin
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.import "qrc:/gcompris/src/core/core.js" as Core
function getAddTable(table) {
var result = []
for(var i = 1; i <= 10; ++i) {
if(Math.floor(Math.random()*2))
// The mathematical addition sign
result.push(["" + table + " " + qsTr("+") + " " + i,
table + i])
else
result.push(["" + i + " " + qsTr("+") + " " + table,
table + i])
}
return result
}
function getMinusTable(table) {
var result = []
for(var i = 1; i <= 10; ++i) {
// The mathematical subtraction sign
result.push(["" + (i + table) + " " + qsTr("−") + " " + table,
i])
}
return result
}
function getMultTable(table) {
var result = []
for(var i = 1; i <= 10; ++i) {
if(Math.floor(Math.random()*2))
// The mathematical multiplication sign
result.push(["" + table + " " + qsTr("×") + " " + i,
table * i])
else
result.push(["" + i + " " + qsTr("×") + " " + table,
table * i])
}
return result
}
function getDivTable(table) {
var result = []
for(var i = 1; i <= 10; ++i) {
// The mathematical division sign
result.push(["" + i * table + " " + qsTr("÷") + " " + table,
i])
}
return result
}
function removeDuplicates(tAll) {
Core.shuffle(tAll)
var result = []
// Remove duplicate values with the same result
for(var i = 0; i < tAll.length; ++i) {
var gotIt = false
for(var j = 0; j < result.length; ++j) {
if(tAll[i][1] === result[j][1])
gotIt = 1
}
if(!gotIt)
result.push(tAll[i])
}
return result
}
function getAddMinusTable(table) {
var t1 = getAddTable(table)
var t2 = getMinusTable(table)
return removeDuplicates(t1.concat(t2))
}
function getAddMinusMultTable(table) {
var t1 = getAddTable(table)
var t2 = getMinusTable(table)
var t3 = getMultTable(table)
return removeDuplicates(t1.concat(t2, t3))
}
function getAddMinusMultDivTable(table) {
var t1 = getAddTable(table)
var t2 = getMinusTable(table)
var t3 = getMultTable(table)
var t4 = getDivTable(table)
return removeDuplicates(t1.concat(t2, t3, t4))
}
function getMultDivTable(table) {
var t1 = getMultTable(table)
var t2 = getDivTable(table)
return removeDuplicates(t1.concat(t2))
}
diff --git a/src/activities/memory/memory.js b/src/activities/memory/memory.js
index 9bd374207..32255162b 100644
--- a/src/activities/memory/memory.js
+++ b/src/activities/memory/memory.js
@@ -1,262 +1,264 @@
/* gcompris - memory.js
*
* Copyright (C) 2014 JB BUTET
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* JB BUTET <ashashiwa@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
.import "qrc:/gcompris/src/core/core.js" as Core
var url = "qrc:/gcompris/src/activities/memory/resource/"
var items
var currentLevel
var numberOfLevel
var nbOfPair
var cardLeft
var cardList
function start(items_) {
items = items_
currentLevel = 0
numberOfLevel = items.dataset.length
initLevel()
}
function stop() {
}
function initLevel() {
items.bar.level = currentLevel + 1
items.containerModel.clear()
items.playQueue = []
items.tuxTurn = false
items.selectionCount = 0
+ items.blockClicks = false
// compute the number of cards
var columns = items.dataset[currentLevel].columns
var rows = items.dataset[currentLevel].rows
var images = items.dataset[currentLevel].images
var sounds = items.dataset[currentLevel].sounds
var texts = items.dataset[currentLevel].texts
items.columns = columns
items.rows = rows
nbOfPair = rows * columns / 2
cardLeft = nbOfPair * 2
// Check the provided dataset has enough data
var maxData = Math.max(
images ? images.length : 0,
sounds ? sounds.length : 0,
texts ? texts.length : 0)
if(rows * columns > maxData) {
console.log("ERROR: Memory dataset does not have enough data pairs at level ",
currentLevel + 1)
return
}
// Create a list of indexes for the shuffling
// This way we can keep the 3 lists in sync
var shuffleIds = []
for(var i = 0; i < maxData; ++i) {
shuffleIds.push(i)
}
Core.shuffle(shuffleIds)
// place randomly a level-defined number of pairs
cardList = []
for(var ix = 0; ix < nbOfPair; ++ix) {
// select a random item
for(var j = 0; j < 2; ++j) {
cardList.push( {
image: images ? images[shuffleIds[ix]][j] : "",
sound: sounds ? sounds[shuffleIds[ix]][j] : "",
text: texts ? texts[shuffleIds[ix]][j] : "",
matchCode: ix,
back: url + "backcard.svg",
emptyCard: url + "emptycard.svg"
} )
}
}
cardList = Core.shuffle(cardList)
// fill the model
for(i = 0; i < cardList.length; ++i) {
items.containerModel.append( { pairData_: cardList[i] } )
}
items.tuxScore = 0
items.playerScore = 0
}
// Return a pair of cards that have already been shown
function getShownPair() {
-
for(var i = 0; i < nbOfPair * 2; ++i) {
- var cardItem1 = items.cardRepeater.itemAt(i)
+ var cardItem1 = items.grid.getItemAtIndex(i)
for(var j = 0; j < nbOfPair * 2; ++j) {
- var cardItem2 = items.cardRepeater.itemAt(j)
+ var cardItem2 = items.grid.getItemAtIndex(j)
if(i != j &&
!cardItem1.isFound &&
cardItem1.isShown &&
!cardItem2.isFound &&
cardItem2.isShown &&
(cardItem1.pairData.matchCode ===
cardItem2.pairData.matchCode) ) {
return [cardItem1, cardItem2]
}
}
}
return
}
// Calc randomly is Tux is a good player
// Return true if Tux should play correctly
function getRandomTuxIsGood() {
return Math.random() * numberOfLevel < currentLevel
}
function chooseCard() {
// Tux looks in the shown card to make his choice
if(getRandomTuxIsGood()) {
var shownPair = getShownPair()
if(shownPair) {
if(shownPair[0].isBack) {
return shownPair[0]
} else {
return shownPair[1]
}
}
}
// If no pairs shown select a random card
var listCardNonReturned = []
for(var i = 0; i < cardList.length; ++i) {
- if (items.cardRepeater.itemAt(i).isFound == false &&
- items.cardRepeater.itemAt(i).isBack)
- listCardNonReturned.push(items.cardRepeater.itemAt(i))
+ if (items.grid.getItemAtIndex(i).isFound == false &&
+ items.grid.getItemAtIndex(i).isBack)
+ listCardNonReturned.push(items.grid.getItemAtIndex(i))
}
//select randomly a card in it
return listCardNonReturned[Math.floor(Math.random() * listCardNonReturned.length)]
}
function reverseCardsIfNeeded() {
if(items.playQueue.length >= 2) {
items.selectionCount = 0
var item1 = items.playQueue.shift()
var item2 = items.playQueue.shift()
var tuxTurn = item1.tuxTurn
if (item1.card.pairData.matchCode ===
item2.card.pairData.matchCode) {
// the 2 cards are the same
item1.card.isBack = false // stay faced
item1.card.isFound = true // signal for hidden state
item2.card.isBack = false
item2.card.isFound = true
cardLeft = cardLeft - 2
if (tuxTurn)
items.tuxScore++
else
items.playerScore++
if(cardLeft === 0) { // no more cards in the level
if(items.withTux) {
if (items.tuxScore < items.playerScore) {
youWon()
} else {
youLoose()
}
} else {
youWon()
}
} else {
if(items.withTux && items.tuxTurn) {
tuxPlay()
} else {
items.audioEffects.play('qrc:/gcompris/src/core/resource/sounds/win.wav')
}
}
} else {
// pictures clicked are not the same
item1.card.isBack = true
item2.card.isBack = true
if(items.withTux)
items.tuxTurn = !items.tuxTurn
// The user lost, it's Tux turn
if (items.withTux && items.tuxTurn) {
tuxPlay()
}
}
}
}
function tuxPlay() {
// choose a card
chooseCard().selected()
}
function youWon() {
+ items.blockClicks = true
items.bonus.good("flower")
}
function youLoose(){
+ items.blockClicks = true
items.bonus.bad("flower")
- if (items.withTux){
+ if (items.withTux) {
initLevel()
}
}
function nextLevel() {
- if(numberOfLevel <= ++currentLevel ) {
+ if(numberOfLevel <= ++currentLevel) {
currentLevel = 0
}
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
initLevel();
}
function dumpPlayQueue() {
for(var i in items.playQueue)
console.log(items.playQueue[i].card, items.playQueue[i].tuxTurn)
}
// Return true is we have enough to make a pair
function addPlayQueue(card) {
items.playQueue.push({'card': card, 'tuxTurn': items.tuxTurn})
return items.playQueue.length >= 2
}
diff --git a/src/activities/memory/memorydataset.js b/src/activities/memory/memorydataset.js
index bd769dc6f..ff1374868 100644
--- a/src/activities/memory/memorydataset.js
+++ b/src/activities/memory/memorydataset.js
@@ -1,80 +1,80 @@
/* GCompris
*
* Copyright (C) 2014 Bruno Coudoin
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
var url = "qrc:/gcompris/src/activities/memory/resource/"
var images = [
[url + '01_cat.svg', url + '01_cat.svg'],
[url + '02_pig.svg', url + '02_pig.svg'],
[url + '03_bear.svg', url + '03_bear.svg'],
[url + '04_hippopotamus.svg', url + '04_hippopotamus.svg'],
[url + '05_penguin.svg', url + '05_penguin.svg'],
[url + '06_cow.svg', url + '06_cow.svg'],
[url + '07_sheep.svg', url + '07_sheep.svg'],
[url + '08_turtle.svg', url + '08_turtle.svg'],
[url + '09_panda.svg', url + '09_panda.svg'],
[url + '10_chicken.svg', url + '10_chicken.svg'],
[url + '11_redbird.svg', url + '11_redbird.svg'],
[url + '12_wolf.svg', url + '12_wolf.svg'],
[url + '13_monkey.svg', url + '13_monkey.svg'],
[url + '14_fox.svg', url + '14_fox.svg'],
[url + '15_bluebirds.svg', url + '15_bluebirds.svg'],
[url + '16_elephant.svg', url + '16_elephant.svg'],
[url + '17_lion.svg', url + '17_lion.svg'],
[url + '18_gnu.svg', url + '18_gnu.svg'],
[url + '19_bluebaby.svg', url + '19_bluebaby.svg'],
[url + '20_greenbaby.svg', url + '20_greenbaby.svg'],
[url + '21_frog.svg', url + '21_frog.svg']
]
var memory_cards = [
{ // Level 1
columns: 3,
rows: 2,
images: images
},
{ // Level 2
columns: 4,
rows: 2,
images: images
},
{ // Level 3
columns: 5,
rows: 2,
images: images
},
{ // Level 4
columns: 4,
rows: 3,
images: images
},
{ // Level 5
columns: 6,
rows: 3,
images: images
},
{ // Level 6
columns: 5,
rows: 4,
images: images
}
]
function get() {
return memory_cards
}
diff --git a/src/activities/menu/ActivityInfo.qml b/src/activities/menu/ActivityInfo.qml
index 169e16831..a2e68c47b 100644
--- a/src/activities/menu/ActivityInfo.qml
+++ b/src/activities/menu/ActivityInfo.qml
@@ -1,56 +1,56 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "menu/Menu.qml"
difficulty: 0
//: Activity title
title: qsTr("GCompris Main Menu")
//: Help title
description: qsTr("Select an activity to run it.")
//: Help goal
goal: qsTr("GCompris is a high quality educational software suite, including a large number of activities for children aged 2 to 10.")
//: Help prerequisite
prerequisite: qsTr("Some of the activities are game orientated, but nonetheless still educational.")
//: Help manual
manual: qsTr("Select an icon to enter an activity or to display a list of activities in a category.
At the bottom of the screen is the GCompris control bar. Notice that you can hide or show the bar by touching its anchor.
The following icons are displayed:
(note that each icon is displayed only if available in the current activity)
Home - Exit an activity, go back to menu (Ctrl+W and escape key)
Arrows - Display the current level. Click to select another level
Lips - Repeat the question
Question Mark - Help
Reload - Start the activity from the beginning again
Tool - The configuration menu
G - About GCompris
Quit - Quit GCompris (Ctrl+Q)
The stars show suitable age groups for each game:
1, 2 or 3 simple stars - from 2 to 6 years old
1, 2 or 3 complex stars - 7 years and up
Shortcuts:
Ctrl+B Show or Hide the control bar
Ctrl+F Toggle full screen
Ctrl+M Toggle mute for the background music
Ctrl+S Toggle the activity section bar
" )
credit: ""
section: "/"
createdInVersion: 0
}
diff --git a/src/activities/menu/ConfigurationItem.qml b/src/activities/menu/ConfigurationItem.qml
index cc650651d..758c3a4be 100644
--- a/src/activities/menu/ConfigurationItem.qml
+++ b/src/activities/menu/ConfigurationItem.qml
@@ -1,731 +1,731 @@
/* GCompris - ConfigurationItem.qml
*
* Copyright (C) 2014-2016 Johnny Jazeix <jazeix@gmail.com>
*
* Authors:
* Johnny Jazeix <jazeix@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import QtQuick.Controls 1.5
import QtQuick.Controls.Styles 1.4
import GCompris 1.0
import "../../core"
import "qrc:/gcompris/src/core/core.js" as Core
Item {
id: dialogConfig
property var languages: allLangs.languages
height: column.height
LanguageList {
id: allLangs
}
Column {
id: column
spacing: 10
width: parent.width
move: Transition {
NumberAnimation { properties: "x,y"; duration: 120 }
}
// Put configuration here
Row {
id: demoModeBox
width: parent.width
spacing: 10
property bool checked: !ApplicationSettings.isDemoMode
Image {
sourceSize.height: 50 * ApplicationInfo.ratio
source:
demoModeBox.checked ? "qrc:/gcompris/src/core/resource/apply.svg" :
"qrc:/gcompris/src/core/resource/cancel.svg"
MouseArea {
anchors.fill: parent
onClicked: {
if(ApplicationSettings.isDemoMode)
ApplicationSettings.isDemoMode = false
}
}
}
Button {
width: parent.parent.width - 50 * ApplicationInfo.ratio - 10 * 2
height: parent.height
enabled: ApplicationSettings.isDemoMode
anchors.leftMargin: 10
anchors.verticalCenter: parent.verticalCenter
text: demoModeBox.checked ? qsTr("You have the full version") :
qsTr("Buy the full version").toUpperCase()
style: ButtonStyle {
background: Rectangle {
implicitWidth: 100
implicitHeight: 25
border.width: control.activeFocus ? 4 : 2
border.color: "black"
radius: 10
gradient: Gradient {
GradientStop { position: 0 ; color: control.pressed ? "#87ff5c" :
ApplicationSettings.isDemoMode ? "#ffe85c" : "#EEEEEE"}
GradientStop { position: 1 ; color: control.pressed ? "#44ff00" :
ApplicationSettings.isDemoMode ? "#f8d600" : "#AAAAAA"}
}
}
label: GCText {
text: control.text
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
wrapMode: Text.WordWrap
}
}
onClicked: {
if(ApplicationSettings.activationMode == 1) {
if(ApplicationSettings.isDemoMode)
ApplicationSettings.isDemoMode = false
} else if(ApplicationSettings.activationMode == 2) {
activationCodeEntry.visible = !activationCodeEntry.visible
}
}
}
}
Column {
id: activationCodeEntry
width: parent.width
spacing: 10
visible: false
opacity: 0
Behavior on opacity { NumberAnimation { duration: 200 } }
onVisibleChanged: {
if(visible) {
activationInput.forceActiveFocus()
activationInput.cursorPosition = 0
opacity = 1
} else {
activationInput.focus = false
opacity = 0
}
}
GCText {
id: activationInstruction
fontSize: regularSize
color: "black"
style: Text.Outline
styleColor: "white"
horizontalAlignment: Text.AlignHCenter
width: parent.width
wrapMode: TextEdit.WordWrap
- text: qsTr("On <a href='http://gcompris.net'>http://gcompris.net</a> " +
+ text: qsTr("On <a href='https://gcompris.net'>https://gcompris.net</a> " +
"you will find the instructions to obtain an activation code.")
Component.onCompleted: ApplicationInfo.isDownloadAllowed ?
linkActivated.connect(Qt.openUrlExternally) : null
}
TextInput {
id: activationInput
width: parent.width
focus: true
font.weight: Font.DemiBold
font.pointSize: ApplicationSettings.baseFontSize
+ 14 * ApplicationInfo.fontRatio
color: 'black'
horizontalAlignment: Text.AlignHCenter
inputMask: '>HHHH-HHHH-HHHH;#'
text: ApplicationSettings.codeKey
onTextChanged: {
var code = text.replace(/-/g,'')
var codeValidity = ApplicationSettings.checkActivationCode(code);
switch (codeValidity) {
case 0:
activationMsg.text = qsTr('Enter your activation code');
break;
case 1:
activationMsg.text = qsTr('Sorry, your code is too old for this version of GCompris');
break;
case 2:
activationMsg.text = qsTr('Your code is valid, thanks a lot for your support');
activationCodeEntry.visible = false
ApplicationSettings.codeKey = code
break;
}
}
}
GCText {
id: activationMsg
width: parent.width
color: "black"
fontSize: regularSize
horizontalAlignment: TextInput.AlignHCenter
wrapMode: TextEdit.WordWrap
}
}
GCDialogCheckBox {
id: displayLockedActivitiesBox
text: qsTr("Show locked activities")
visible: ApplicationSettings.isDemoMode
checked: showLockedActivities
onCheckedChanged: {
showLockedActivities = checked;
}
}
GCDialogCheckBox {
id: enableAudioVoicesBox
text: qsTr("Enable audio voices")
checked: isAudioVoicesEnabled
onCheckedChanged: {
isAudioVoicesEnabled = checked;
}
}
GCDialogCheckBox {
id: enableAudioEffectsBox
text: qsTr("Enable audio effects")
checked: isAudioEffectsEnabled
onCheckedChanged: {
isAudioEffectsEnabled = checked;
}
}
GCDialogCheckBox {
id: enableFullscreenBox
text: qsTr("Fullscreen")
checked: isFullscreen
onCheckedChanged: {
isFullscreen = checked;
}
visible: !ApplicationInfo.isMobile
}
GCDialogCheckBox {
id: enableVirtualKeyboardBox
text: qsTr("Virtual Keyboard")
checked: isVirtualKeyboard
onCheckedChanged: {
isVirtualKeyboard = checked;
}
}
GCDialogCheckBox {
id: enableAutomaticDownloadsBox
checked: isAutomaticDownloadsEnabled
text: qsTr("Enable automatic downloads/updates of sound files")
visible: ApplicationInfo.isDownloadAllowed
onCheckedChanged: {
isAutomaticDownloadsEnabled = checked;
}
}
/* Technically wordset config is a string that holds the wordset name or '' for the
* internal wordset. But as we support only internal and words its best to show the
* user a boolean choice.
*/
GCDialogCheckBox {
id: wordsetBox
checked: DownloadManager.isDataRegistered("words")
text: enabled ? qsTr("Use full word image set") : qsTr("Download full word image set")
visible: ApplicationInfo.isDownloadAllowed
enabled: !DownloadManager.isDataRegistered("words")
onCheckedChanged: {
wordset = checked ? 'data2/words/words.rcc' : '';
}
}
GCDialogCheckBox {
id: sectionVisibleBox
checked: sectionVisible
text: qsTr("The activity section menu is visible")
onCheckedChanged: {
sectionVisible = checked;
}
}
Flow {
spacing: 5
width: parent.width
GCComboBox {
id: fontBox
model: fonts
background: dialogActivityConfig
label: qsTr("Font selector")
}
}
Flow {
spacing: 5
width: parent.width
GCSlider {
id: baseFontSizeSlider
width: 250 * ApplicationInfo.ratio
maximumValue: ApplicationSettings.baseFontSizeMax
minimumValue: ApplicationSettings.baseFontSizeMin
value: baseFontSize
onValueChanged: ApplicationSettings.baseFontSize = value;
scrollEnabled: false
}
GCText {
id: baseFontSizeText
text: qsTr("Font size")
fontSize: mediumSize
wrapMode: Text.WordWrap
}
Button {
height: 30 * ApplicationInfo.ratio
text: qsTr("Default");
style: GCButtonStyle {}
onClicked: baseFontSizeSlider.value = 0.0
}
}
Flow {
spacing: 5
width: parent.width
GCComboBox {
id: fontCapitalizationBox
model: fontCapitalizationModel
background: dialogActivityConfig
label: qsTr("Font Capitalization")
}
}
Flow {
spacing: 5
width: parent.width
GCSlider {
id: fontLetterSpacingSlider
width: 250 * ApplicationInfo.ratio
maximumValue: ApplicationSettings.fontLetterSpacingMax
minimumValue: ApplicationSettings.fontLetterSpacingMin
value: fontLetterSpacing
onValueChanged: ApplicationSettings.fontLetterSpacing = value;
scrollEnabled: false
}
GCText {
id: fontLetterSpacingText
text: qsTr("Font letter spacing")
fontSize: mediumSize
wrapMode: Text.WordWrap
}
Button {
height: 30 * ApplicationInfo.ratio
text: qsTr("Default");
style: GCButtonStyle {}
onClicked: fontLetterSpacingSlider.value = ApplicationSettings.fontLetterSpacingMin
}
}
Flow {
spacing: 5
width: parent.width
GCComboBox {
id: languageBox
model: dialogConfig.languages
background: dialogActivityConfig
onCurrentIndexChanged: voicesRow.localeChanged();
label: qsTr("Language selector")
}
}
Flow {
id: voicesRow
width: parent.width
spacing: 5 * ApplicationInfo.ratio
property bool haveLocalResource: false
function localeChanged() {
var language = dialogConfig.languages[languageBox.currentIndex].text;
voicesRow.haveLocalResource = DownloadManager.isDataRegistered(
"voices-" + ApplicationInfo.CompressedAudio + "/" +
ApplicationInfo.getVoicesLocale(dialogConfig.languages[languageBox.currentIndex].locale)
)
}
Connections {
target: DownloadManager
onDownloadFinished: voicesRow.localeChanged()
}
GCText {
id: voicesText
text: qsTr("Localized voices")
fontSize: mediumSize
wrapMode: Text.WordWrap
}
Image {
id: voicesImage
sourceSize.height: 30 * ApplicationInfo.ratio
source: voicesRow.haveLocalResource ? "qrc:/gcompris/src/core/resource/apply.svg" :
"qrc:/gcompris/src/core/resource/cancel.svg"
}
Button {
id: voicesButton
height: 30 * ApplicationInfo.ratio
visible: ApplicationInfo.isDownloadAllowed
text: voicesRow.haveLocalResource ? qsTr("Check for updates") :
qsTr("Download")
style: GCButtonStyle {}
onClicked: {
if (DownloadManager.downloadResource(
DownloadManager.getVoicesResourceForLocale(dialogConfig.languages[languageBox.currentIndex].locale)))
{
var downloadDialog = Core.showDownloadDialog(dialogConfig.parent.rootItem, {});
}
}
}
}
Flow {
width: parent.width
spacing: 5 * ApplicationInfo.ratio
GCText {
text: qsTr("Difficulty filter:")
fontSize: mediumSize
height: 50 * ApplicationInfo.ratio
}
// Padding
Item {
height: 1
width: 10 * ApplicationInfo.ratio
}
Image {
source: "qrc:/gcompris/src/core/resource/bar_next.svg"
sourceSize.height: Math.min(50 * ApplicationInfo.ratio, parent.width / 8)
MouseArea {
anchors.fill: parent
onClicked: {
filterRepeater.setMin(filterRepeater.min + 1)
}
}
}
// Padding
Item {
height: 1
width: 5 * ApplicationInfo.ratio
}
// Level filtering
Repeater {
id: filterRepeater
model: 6
property int min: ApplicationSettings.filterLevelMin
property int max: ApplicationSettings.filterLevelMax
function setMin(value) {
var newMin
if(min < 1)
newMin = 1
else if(min > 6)
newMin = 6
else if(max >= value)
newMin = value
if(newMin)
ApplicationSettings.filterLevelMin = newMin
}
function setMax(value) {
var newMax
if(max < 1)
newMax = 1
else if(max > 6)
newMax = 6
else if(min <= value)
newMax = value
if(newMax)
ApplicationSettings.filterLevelMax = newMax
}
Image {
source: "qrc:/gcompris/src/core/resource/difficulty" +
(modelData + 1) + ".svg";
sourceSize.width: Math.min(50 * ApplicationInfo.ratio, parent.width / 8)
opacity: modelData + 1 >= filterRepeater.min &&
modelData + 1 <= filterRepeater.max
? 1 : 0.4
property int value: modelData + 1
MouseArea {
anchors.fill: parent
onClicked: {
if(parent.value < filterRepeater.max) {
if(parent.opacity == 1)
filterRepeater.setMin(parent.value + 1)
else
filterRepeater.setMin(parent.value)
} else if(parent.value > filterRepeater.min) {
if(parent.opacity == 1)
filterRepeater.setMax(parent.value - 1)
else
filterRepeater.setMax(parent.value)
}
}
}
}
}
// Padding
Item {
height: 1
width: 5 * ApplicationInfo.ratio
}
Image {
source: "qrc:/gcompris/src/core/resource/bar_previous.svg"
sourceSize.height: Math.min(50 * ApplicationInfo.ratio, parent.width / 8)
MouseArea {
anchors.fill: parent
onClicked: {
filterRepeater.setMax(filterRepeater.max - 1)
}
}
}
}
}
property bool showLockedActivities: ApplicationSettings.showLockedActivities
property bool isAudioVoicesEnabled: ApplicationSettings.isAudioVoicesEnabled
property bool isAudioEffectsEnabled: ApplicationSettings.isAudioEffectsEnabled
property bool isFullscreen: ApplicationSettings.isFullscreen
property bool isVirtualKeyboard: ApplicationSettings.isVirtualKeyboard
property bool isAutomaticDownloadsEnabled: ApplicationSettings.isAutomaticDownloadsEnabled
property bool sectionVisible: ApplicationSettings.sectionVisible
property string wordset: ApplicationSettings.wordset
property int baseFontSize // don't bind to ApplicationSettings.baseFontSize
property real fontLetterSpacing // don't bind to ApplicationSettings.fontLetterSpacing
// or we get a binding loop warning
function loadFromConfig() {
// Synchronize settings with data
showLockedActivities = ApplicationSettings.showLockedActivities
isAudioVoicesEnabled = ApplicationSettings.isAudioVoicesEnabled
enableAudioVoicesBox.checked = isAudioVoicesEnabled
isAudioEffectsEnabled = ApplicationSettings.isAudioEffectsEnabled
enableAudioEffectsBox.checked = isAudioEffectsEnabled
isFullscreen = ApplicationSettings.isFullscreen
enableFullscreenBox.checked = isFullscreen
isVirtualKeyboard = ApplicationSettings.isVirtualKeyboard
enableVirtualKeyboardBox.checked = isVirtualKeyboard
isAutomaticDownloadsEnabled = ApplicationSettings.isAutomaticDownloadsEnabled
enableAutomaticDownloadsBox.checked = isAutomaticDownloadsEnabled
sectionVisible = ApplicationSettings.sectionVisible
sectionVisibleBox.checked = sectionVisible
wordset = ApplicationSettings.wordset
wordsetBox.checked = DownloadManager.isDataRegistered("words") || ApplicationSettings.wordset == 'data2/words/words.rcc'
wordsetBox.enabled = !DownloadManager.isDataRegistered("words")
baseFontSize = ApplicationSettings.baseFontSize;
fontLetterSpacing = ApplicationSettings.fontLetterSpacing;
// Set locale
for(var i = 0 ; i < dialogConfig.languages.length ; i ++) {
if(dialogConfig.languages[i].locale === ApplicationSettings.locale) {
languageBox.currentIndex = i;
break;
}
}
// Set font
for(var i = 0 ; i < fonts.count ; i ++) {
if(fonts.get(i).text == ApplicationSettings.font) {
fontBox.currentIndex = i;
break;
}
}
// Set font capitalization
for(var i = 0 ; i < fontCapitalizationModel.length ; i ++) {
if(fontCapitalizationModel[i].value == ApplicationSettings.fontCapitalization) {
fontCapitalizationBox.currentIndex = i;
break;
}
}
}
function save() {
ApplicationSettings.showLockedActivities = showLockedActivities
ApplicationSettings.isAudioVoicesEnabled = isAudioVoicesEnabled
ApplicationSettings.isAudioEffectsEnabled = isAudioEffectsEnabled
ApplicationSettings.isFullscreen = isFullscreen
ApplicationSettings.isVirtualKeyboard = isVirtualKeyboard
ApplicationSettings.isAutomaticDownloadsEnabled = isAutomaticDownloadsEnabled
ApplicationSettings.sectionVisible = sectionVisible
ApplicationSettings.wordset = wordset
ApplicationSettings.isEmbeddedFont = fonts.get(fontBox.currentIndex).isLocalResource;
ApplicationSettings.font = fonts.get(fontBox.currentIndex).text
ApplicationSettings.fontCapitalization = fontCapitalizationModel[fontCapitalizationBox.currentIndex].value
ApplicationSettings.saveBaseFontSize();
ApplicationSettings.notifyFontLetterSpacingChanged();
if (ApplicationSettings.locale != dialogConfig.languages[languageBox.currentIndex].locale) {
ApplicationSettings.locale = dialogConfig.languages[languageBox.currentIndex].locale
if(ApplicationInfo.isDownloadAllowed && !DownloadManager.isDataRegistered(
"voices-" + ApplicationInfo.CompressedAudio + "/" +
ApplicationInfo.getVoicesLocale(dialogConfig.languages[languageBox.currentIndex].locale)
))
{
// ask for downloading new voices
Core.showMessageDialog(main,
qsTr("You selected a new locale. You need to restart GCompris to play in your new locale.<br/>Do you want to download the corresponding sound files now?"),
qsTr("Yes"), function() {
// yes -> start download
if (DownloadManager.downloadResource(
DownloadManager.getVoicesResourceForLocale(ApplicationSettings.locale)))
var downloadDialog = Core.showDownloadDialog(main, {});
},
qsTr("No"), null,
null
);
} else {
// check for updates or/and register new voices
DownloadManager.updateResource(
DownloadManager.getVoicesResourceForLocale(ApplicationSettings.locale))
}
}
// download words.rcc if needed
if(ApplicationSettings.wordset != "") {
// we want to use the external dataset, it is either in
// words/words.rcc or full-${CA}.rcc
if(DownloadManager.isDataRegistered("words")) {
// we either have it, we try to update in the background
// or we are downloading it
if(DownloadManager.haveLocalResource(wordset))
DownloadManager.updateResource(wordset)
}
else {
// download automatically if automatic download else ask for download
if(isAutomaticDownloadsEnabled) {
var prevAutomaticDownload = ApplicationSettings.isAutomaticDownloadsEnabled
ApplicationSettings.isAutomaticDownloadsEnabled = true;
DownloadManager.updateResource(wordset);
ApplicationSettings.isAutomaticDownloadsEnabled = prevAutomaticDownload
}
else {
Core.showMessageDialog(main,
qsTr("The images for several activities are not yet installed. ")
+ qsTr("Do you want to download them now?"),
qsTr("Yes"),
function() {
if (DownloadManager.downloadResource(wordset))
var downloadDialog = Core.showDownloadDialog(pageView.currentItem, {});
},
qsTr("No"), function() { ApplicationSettings.wordset = '' },
null
);
}
}
}
}
ListModel {
id: fonts
Component.onCompleted: {
var systemFonts = Qt.fontFamilies();
var rccFonts = ApplicationInfo.getFontsFromRcc();
// Remove explicitly all *symbol* and *ding* fonts
var excludedFonts = ApplicationInfo.getSystemExcludedFonts();
excludedFonts.push("ding");
excludedFonts.push("symbol");
// first display fonts from rcc
for(var i = 0 ; i < rccFonts.length ; ++ i) {
// Append fonts from resources
fonts.append({ "text": rccFonts[i], "isLocalResource": true });
}
for(var i = 0 ; i < systemFonts.length ; ++ i) {
var isExcluded = false;
var systemFont = systemFonts[i].toLowerCase();
// Remove symbol fonts
for(var j = 0 ; j < excludedFonts.length ; ++ j) {
if(systemFont.indexOf(excludedFonts[j].toLowerCase()) != -1) {
isExcluded = true;
break;
}
}
// Remove fonts from rcc (if you have a default font from rcc, Qt will add it to systemFonts)
for(var j = 0 ; j < rccFonts.length ; ++ j) {
if(rccFonts[j].toLowerCase().indexOf(systemFont) != -1) {
isExcluded = true;
break;
}
}
// Finally, we know if we add this font or not
if(!isExcluded) {
fonts.append({ "text": systemFonts[i], "isLocalResource": false });
}
}
}
}
property var fontCapitalizationModel: [
{ text: qsTr("Mixed case (default)"), value: Font.MixedCase },
{ text: qsTr("All uppercase"), value: Font.AllUppercase },
{ text: qsTr("All lowercase"), value: Font.AllLowercase }
]
function hasConfigChanged() {
return (ApplicationSettings.locale !== dialogConfig.languages[languageBox.currentIndex].locale ||
(ApplicationSettings.sectionVisible != sectionVisible) ||
(ApplicationSettings.wordset != wordset) ||
(ApplicationSettings.font != fonts.get(fontBox.currentIndex).text) ||
(ApplicationSettings.isEmbeddedFont != fonts.get(fontBox.currentIndex).isLocalResource) ||
(ApplicationSettings.isEmbeddedFont != fonts.get(fontBox.currentIndex).isLocalResource) ||
(ApplicationSettings.fontCapitalization != fontCapitalizationModel[(fontcapitalizationBox.currentIndex)].value) ||
(ApplicationSettings.fontLetterSpacing != fontLetterSpacing) ||
(ApplicationSettings.isAudioVoicesEnabled != isAudioVoicesEnabled) ||
(ApplicationSettings.isAudioEffectsEnabled != isAudioEffectsEnabled) ||
(ApplicationSettings.isFullscreen != isFullscreen) ||
(ApplicationSettings.isVirtualKeyboard != isVirtualKeyboard) ||
(ApplicationSettings.isAutomaticDownloadsEnabled != isAutomaticDownloadsEnabled) ||
(ApplicationSettings.baseFontSize != baseFontSize) ||
(ApplicationSettings.showLockedActivities != showLockedActivities)
);
}
}
diff --git a/src/activities/menu/Menu.qml b/src/activities/menu/Menu.qml
index 151d3aabb..09ae6e51a 100644
--- a/src/activities/menu/Menu.qml
+++ b/src/activities/menu/Menu.qml
@@ -1,767 +1,782 @@
/* GCompris - Menu.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
import GCompris 1.0
import QtGraphicalEffects 1.0
import "qrc:/gcompris/src/core/core.js" as Core
import QtQuick.Controls 1.5
import QtQuick.Controls.Styles 1.4
/**
* GCompris' top level menu screen.
*
* Displays a grid of available activities divided subdivided in activity
* categories/sections.
*
* The visibility of the section row is toggled by the setting
* ApplicationSettings.sectionVisible.
*
* The list of available activities depends on the following settings:
*
* * ApplicationSettings.showLockedActivities
* * ApplicationSettings.filterLevelMin
* * ApplicationSettings.filterLevelMax
*
* @inherit QtQuick.Item
*/
ActivityBase {
id: activity
focus: true
activityInfo: ActivityInfoTree.rootMenu
onBack: {
pageView.pop(to);
// Restore focus that has been taken by the loaded activity
if(pageView.currentItem == activity)
focus = true;
}
onHome: {
if(pageView.depth === 1 && !ApplicationSettings.isKioskMode) {
Core.quit(main);
}
else {
pageView.pop();
// Restore focus that has been taken by the loaded activity
if(pageView.currentItem == activity)
focus = true;
}
}
onDisplayDialog: pageView.push(dialog)
onDisplayDialogs: {
var toPush = new Array();
for (var i = 0; i < dialogs.length; i++) {
toPush.push({item: dialogs[i]});
}
pageView.push(toPush);
}
+ Connections {
+ // At the launch of the application, box2d check is performed after we
+ // first initialize the menu. This connection is to refresh
+ // automatically the menu at start.
+ target: ApplicationInfo
+ onIsBox2DInstalledChanged: {
+ ActivityInfoTree.filterByTag(activity.currentTag)
+ ActivityInfoTree.filterLockedActivities()
+ ActivityInfoTree.filterEnabledActivities()
+ }
+ }
+
// @cond INTERNAL_DOCS
property string url: "qrc:/gcompris/src/activities/menu/resource/"
property var sections: [
{
icon: activity.url + "all.svg",
tag: "favorite"
},
{
icon: activity.url + "computer.svg",
tag: "computer"
},
{
icon: activity.url + "discovery.svg",
tag: "discovery"
},
{
icon: activity.url + "experience.svg",
tag: "experiment"
},
{
icon: activity.url + "fun.svg",
tag: "fun"
},
{
icon: activity.url + "math.svg",
tag: "math"
},
{
icon: activity.url + "puzzle.svg",
tag: "puzzle"
},
{
icon: activity.url + "reading.svg",
tag: "reading"
},
{
icon: activity.url + "strategy.svg",
tag: "strategy"
},
{
icon: activity.url + "search-icon.svg",
tag: "search"
}
]
property string currentTag: sections[0].tag
/// @endcond
property string clickMode: "play"
pageComponent: Image {
id: background
source: activity.url + "background.svg"
sourceSize.width: Math.max(parent.width, parent.height)
height: main.height
fillMode: Image.PreserveAspectCrop
Timer {
// triggered once at startup to populate the keyboard
id: keyboardFiller
interval: 1000; running: true;
onTriggered: { keyboard.populate(); }
}
function loadActivity() {
// @TODO init of item would be better in setsource but it crashes on Qt5.6
// https://bugreports.qt.io/browse/QTBUG-49793
activityLoader.item.audioVoices = audioVoices
activityLoader.item.audioEffects = audioEffects
activityLoader.item.loading = loading
//take the focus away from textField before starting an activity
searchTextField.focus = false
pageView.push(activityLoader.item)
}
Loader {
id: activityLoader
asynchronous: true
onStatusChanged: {
if (status == Loader.Loading) {
loading.start();
} else if (status == Loader.Ready) {
loading.stop();
loadActivity();
} else if (status == Loader.Error)
loading.stop();
}
}
// Filters
- property bool horizontal: main.width > main.height
+ property bool horizontal: main.width >= main.height
property int sectionIconWidth: {
if(horizontal)
return Math.min(100 * ApplicationInfo.ratio, main.width / (sections.length + 1))
else if(activity.currentTag === "search" && ApplicationSettings.isVirtualKeyboard)
return Math.min(100 * ApplicationInfo.ratio, (background.height - (bar.height+keyboard.height)) / (sections.length + 1))
else
return Math.min(100 * ApplicationInfo.ratio, (background.height - bar.height) / (sections.length + 1))
}
property int sectionIconHeight: sectionIconWidth
property int sectionCellWidth: sectionIconWidth * 1.1
property int sectionCellHeight: sectionIconHeight * 1.1
property var currentActiveGrid: activitiesGrid
property bool keyboardMode: false
Keys.onPressed: {
// Ctrl-modifiers should never be handled by the search-field
if (event.modifiers === Qt.ControlModifier) {
if (event.key === Qt.Key_S) {
// Ctrl+S toggle show / hide section
ApplicationSettings.sectionVisible = !ApplicationSettings.sectionVisible
}
} else if(currentTag === "search") {
// forward to the virtual keyboard the pressed keys
if(event.key == Qt.Key_Backspace)
keyboard.keypress(keyboard.backspace);
else
keyboard.keypress(event.text);
} else if(event.key === Qt.Key_Space && currentActiveGrid.currentItem) {
currentActiveGrid.currentItem.selectCurrentItem()
}
}
Keys.onReleased: {
keyboardMode = true
event.accepted = false
}
Keys.onTabPressed: currentActiveGrid = ((currentActiveGrid == activitiesGrid) ?
section : activitiesGrid);
Keys.onEnterPressed: if(currentActiveGrid.currentItem) currentActiveGrid.currentItem.selectCurrentItem();
Keys.onReturnPressed: if(currentActiveGrid.currentItem) currentActiveGrid.currentItem.selectCurrentItem();
Keys.onRightPressed: if(currentActiveGrid.currentItem) currentActiveGrid.moveCurrentIndexRight();
Keys.onLeftPressed: if(currentActiveGrid.currentItem) currentActiveGrid.moveCurrentIndexLeft();
Keys.onDownPressed: if(currentActiveGrid.currentItem && !currentActiveGrid.atYEnd) currentActiveGrid.moveCurrentIndexDown();
Keys.onUpPressed: if(currentActiveGrid.currentItem && !currentActiveGrid.atYBeginning) currentActiveGrid.moveCurrentIndexUp();
GridView {
id: section
model: sections
width: horizontal ? main.width : sectionCellWidth
height: {
if(horizontal)
return sectionCellHeight
else if(activity.currentTag === "search" && ApplicationSettings.isVirtualKeyboard)
return sectionCellHeight * (sections.length+1)
else
return main.height - bar.height
}
x: ApplicationSettings.sectionVisible ? section.initialX : -sectionCellWidth
y: ApplicationSettings.sectionVisible ? section.initialY : -sectionCellHeight
+ visible: ApplicationSettings.sectionVisible
cellWidth: sectionCellWidth
cellHeight: sectionCellHeight
interactive: false
keyNavigationWraps: true
property int initialX: 4
property int initialY: 4
Component {
id: sectionDelegate
Item {
id: backgroundSection
width: sectionCellWidth
height: sectionCellHeight
Image {
source: modelData.icon
sourceSize.height: sectionIconHeight
anchors.margins: 5
anchors.horizontalCenter: parent.horizontalCenter
}
ParticleSystemStarLoader {
id: particles
anchors.fill: backgroundSection
clip: false
}
MouseArea {
anchors.fill: backgroundSection
onClicked: {
selectCurrentItem()
}
}
function selectCurrentItem() {
section.currentIndex = index
activity.currentTag = modelData.tag
particles.burst(10)
if(modelData.tag === "search") {
ActivityInfoTree.filterBySearch(searchTextField.text);
}
else {
ActivityInfoTree.filterByTag(modelData.tag)
ActivityInfoTree.filterLockedActivities()
ActivityInfoTree.filterEnabledActivities()
}
}
}
}
delegate: sectionDelegate
highlight: Item {
width: sectionCellWidth
height: sectionCellHeight
Rectangle {
anchors.fill: parent
color: "#5AFFFFFF"
}
Image {
source: "qrc:/gcompris/src/core/resource/button.svg"
anchors.fill: parent
}
Behavior on x { SpringAnimation { spring: 2; damping: 0.2 } }
Behavior on y { SpringAnimation { spring: 2; damping: 0.2 } }
}
}
// Activities
property int iconWidth: 120 * ApplicationInfo.ratio
- property int iconHeight: 120 * ApplicationInfo.ratio
property int activityCellWidth:
horizontal ? background.width / Math.floor(background.width / iconWidth) :
(background.width - section.width) / Math.floor((background.width - section.width) / iconWidth)
- property int activityCellHeight: iconHeight * 1.7
+ property int activityCellHeight: iconWidth * 1.7
Loader {
id: warningOverlay
anchors {
top: horizontal ? section.bottom : parent.top
bottom: parent.bottom
left: horizontal ? parent.left : section.right
right: parent.right
margins: 4
}
active: (ActivityInfoTree.menuTree.length === 0) && (currentTag === "favorite")
sourceComponent: Item {
anchors.fill: parent
GCText {
id: instructionTxt
fontSize: smallSize
y: height * 0.2
x: (parent.width - width) / 2
z: 2
width: parent.width * 0.6
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.WordWrap
font.weight: Font.DemiBold
color: 'white'
text: qsTr("Put your favorite activities here by selecting the " +
"sun at the top right of that activity.")
}
Rectangle {
anchors.fill: instructionTxt
anchors.margins: -6
z: 1
opacity: 0.5
radius: 10
border.width: 2
border.color: "black"
gradient: Gradient {
GradientStop { position: 0.0; color: "#000" }
GradientStop { position: 0.9; color: "#666" }
GradientStop { position: 1.0; color: "#AAA" }
}
}
}
}
GridView {
id: activitiesGrid
anchors {
top: {
if(searchBar.visible)
return searchBar.bottom
else
return horizontal ? section.bottom : parent.top
}
bottom: bar.top
left: horizontal ? parent.left : section.right
margins: 4
}
width: background.width
cellWidth: activityCellWidth
cellHeight: activityCellHeight
clip: true
model: ActivityInfoTree.menuTree
keyNavigationWraps: true
property int spacing: 10
delegate: Item {
id: delegateItem
width: activityCellWidth - activitiesGrid.spacing
height: activityCellHeight - activitiesGrid.spacing
enabled: clickMode === "play" || currentLevel != ""
Rectangle {
id: activityBackground
- width: activityCellWidth - activitiesGrid.spacing
- height: activityCellHeight - activitiesGrid.spacing
+ width: parent.width
+ height: parent.height
anchors.horizontalCenter: parent.horizontalCenter
color: "white"
opacity: 0.5
}
Image {
source: "qrc:/gcompris/src/activities/" + icon;
anchors.top: activityBackground.top
anchors.horizontalCenter: parent.horizontalCenter
- sourceSize.height: iconHeight
+ width: iconWidth - activitiesGrid.spacing
+ height: width
+ sourceSize.width: width
+ fillMode: Image.PreserveAspectFit
anchors.margins: 5
opacity: delegateItem.enabled ? 1 : 0.5
Image {
source: "qrc:/gcompris/src/core/resource/difficulty" +
ActivityInfoTree.menuTree[index].difficulty + ".svg";
anchors.top: parent.top
sourceSize.width: iconWidth * 0.15
x: 5
}
Image {
anchors {
horizontalCenter: parent.horizontalCenter
top: parent.top
rightMargin: 4
}
source: demo || !ApplicationSettings.isDemoMode
? "" :
activity.url + "lock.svg"
sourceSize.width: 30 * ApplicationInfo.ratio
}
Image {
anchors {
left: parent.left
bottom: parent.bottom
}
source: ActivityInfoTree.menuTree[index].createdInVersion == ApplicationInfo.GCVersionCode
? activity.url + "new.svg" : ""
sourceSize.width: 30 * ApplicationInfo.ratio
}
GCText {
id: title
anchors.top: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
horizontalAlignment: Text.AlignHCenter
width: activityBackground.width
fontSizeMode: Text.Fit
minimumPointSize: 7
fontSize: regularSize
elide: Text.ElideRight
maximumLineCount: 2
wrapMode: Text.WordWrap
text: ActivityInfoTree.menuTree[index].title
}
// If we have enough room at the bottom display the description
GCText {
id: description
visible: delegateItem.height - (title.y + title.height) > description.height ? 1 : 0
anchors.top: title.bottom
anchors.horizontalCenter: parent.horizontalCenter
horizontalAlignment: Text.AlignHCenter
width: activityBackground.width
fontSizeMode: Text.Fit
minimumPointSize: 7
fontSize: regularSize
elide: Text.ElideRight
maximumLineCount: 3
wrapMode: Text.WordWrap
text: ActivityInfoTree.menuTree[index].description
}
}
ParticleSystemStarLoader {
id: particles
anchors.fill: activityBackground
}
MouseArea {
anchors.fill: activityBackground
onClicked: selectCurrentItem()
}
Image {
source: activity.url + (favorite ? "all.svg" : "all_disabled.svg");
anchors {
top: parent.top
right: parent.right
rightMargin: 4 * ApplicationInfo.ratio
}
sourceSize.width: iconWidth * 0.25
visible: ApplicationSettings.sectionVisible
MouseArea {
anchors.fill: parent
onClicked: favorite = !favorite
}
}
DialogChooseLevel {
id: dialogChooseLevel
onClose: {
home()
}
onSaveData: {
currentLevel = dialogChooseLevel.chosenLevel
ApplicationSettings.setCurrentLevel(name, currentLevel)
}
onStartActivity: {
clickMode = "play"
selectCurrentItem()
}
}
function selectCurrentItem() {
if(pageView.busy || !delegateItem.enabled)
return
if(clickMode == "play") {
particles.burst(50)
ActivityInfoTree.currentActivity = ActivityInfoTree.menuTree[index]
activityLoader.setSource("qrc:/gcompris/src/activities/" + ActivityInfoTree.currentActivity.name,
{
'menu': activity,
'activityInfo': ActivityInfoTree.currentActivity,
'levelFolder': currentLevel
})
if (activityLoader.status == Loader.Ready) loadActivity()
}
else {
dialogChooseLevel.currentActivity = ActivityInfoTree.menuTree[index]
dialogChooseLevel.chosenLevel = currentLevel;
displayDialog(dialogChooseLevel);
}
}
}
highlight: Rectangle {
width: activityCellWidth - activitiesGrid.spacing
height: activityCellHeight - activitiesGrid.spacing
color: "#AAFFFFFF"
border.width: 3
border.color: "black"
visible: background.keyboardMode
Behavior on x { SpringAnimation { spring: 2; damping: 0.2 } }
Behavior on y { SpringAnimation { spring: 2; damping: 0.2 } }
}
Rectangle {
id: activitiesMask
visible: false
anchors.fill: activitiesGrid
gradient: Gradient {
GradientStop { position: 0.0; color: "#FFFFFFFF" }
GradientStop { position: 0.92; color: "#FFFFFFFF" }
GradientStop { position: 0.96; color: "#00FFFFFF"}
}
}
layer.enabled: ApplicationInfo.useOpenGL
layer.effect: OpacityMask {
id: activitiesOpacity
source: activitiesGrid
maskSource: activitiesMask
anchors.fill: activitiesGrid
}
}
// The scroll buttons
GCButtonScroll {
visible: !ApplicationInfo.useOpenGL
anchors.right: parent.right
anchors.rightMargin: 5 * ApplicationInfo.ratio
anchors.bottom: activitiesGrid.bottom
anchors.bottomMargin: 30 * ApplicationInfo.ratio
onUp: activitiesGrid.flick(0, 1127)
onDown: activitiesGrid.flick(0, -1127)
upVisible: activitiesGrid.visibleArea.yPosition <= 0 ? false : true
downVisible: activitiesGrid.visibleArea.yPosition >= 1 ? false : true
}
Rectangle {
id: searchBar
width: horizontal ? parent.width/2 : parent.width - (section.width+10)
height: searchTextField.height
visible: clickMode === "activityConfig" || activity.currentTag === "search"
anchors {
top: horizontal ? section.bottom : parent.top
left: horizontal ? undefined : section.right
}
anchors.topMargin: horizontal ? 0 : 4
anchors.bottomMargin: horizontal ? 0 : 4
anchors.horizontalCenter: horizontal ? parent.horizontalCenter : undefined
opacity: 0.5
radius: 10
border.width: 2
border.color: "black"
gradient: Gradient {
GradientStop { position: 0.3; color: "#000" }
GradientStop { position: 0.9; color: "#666" }
GradientStop { position: 1.0; color: "#AAA" }
}
Connections {
// On mobile with GCompris' virtual keyboard activated:
// Force invisibility of Androids virtual keyboard:
target: (ApplicationInfo.isMobile && activity.currentTag === "search"
&& ApplicationSettings.isVirtualKeyboard) ? Qt.inputMethod : null
onVisibleChanged: {
if (ApplicationSettings.isVirtualKeyboard && visible)
Qt.inputMethod.hide();
}
onAnimatingChanged: {
// note: seems to be never fired!
if (ApplicationSettings.isVirtualKeyboard && Qt.inputMethod.visible)
Qt.inputMethod.hide();
}
}
Connections {
target: activity
onCurrentTagChanged: {
if (activity.currentTag === 'search') {
searchTextField.focus = true;
} else
activity.focus = true;
}
}
GCText {
id: activitySettingsLabel
text: qsTr("Activity Settings")
visible: clickMode === "activityConfig"
width: parent.width
height: paintedHeight
anchors.verticalCenter: parent.verticalCenter
horizontalAlignment: Text.AlignHCenter
color: "black"
}
TextField {
id: searchTextField
width: parent.width
visible: activity.currentTag === "search"
textColor: "black"
font.pointSize: 16
font.bold: true
horizontalAlignment: TextInput.AlignHCenter
verticalAlignment: TextInput.AlignVCenter
font.family: GCSingletonFontLoader.fontLoader.name
inputMethodHints: Qt.ImhNoPredictiveText
// Note: we give focus to the textfield also in case
// isMobile && !ApplicationSettings.isVirtualKeyboard
// in conjunction with auto-hiding the inputMethod to always get
// an input-cursor:
activeFocusOnPress: true //ApplicationInfo.isMobile ? !ApplicationSettings.isVirtualKeyboard : true
Keys.onReturnPressed: {
if (ApplicationInfo.isMobile && !ApplicationSettings.isVirtualKeyboard)
Qt.inputMethod.hide();
activity.focus = true;
}
onEditingFinished: {
if (ApplicationInfo.isMobile && !ApplicationSettings.isVirtualKeyboard)
Qt.inputMethod.hide();
activity.focus = true;
}
style: TextFieldStyle {
placeholderTextColor: "black"
}
placeholderText: qsTr("Search specific activities")
onTextChanged: ActivityInfoTree.filterBySearch(searchTextField.text);
}
}
VirtualKeyboard {
id: keyboard
readonly property var letter: ActivityInfoTree.characters
width: parent.width
visible: activity.currentTag === "search" && ApplicationSettings.isVirtualKeyboard
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
onKeypress: {
if(text == keyboard.backspace) {
searchTextField.text = searchTextField.text.slice(0, -1);
}
else if(text == keyboard.space) {
searchTextField.text = searchTextField.text.concat(" ");
}
else {
searchTextField.text = searchTextField.text.concat(text);
}
}
function populate() {
var tmplayout = [];
var row = 0;
var offset = 0;
var cols;
while(offset < letter.length-1) {
if(letter.length <= 100) {
cols = Math.ceil((letter.length-offset) / (3 - row));
}
else {
cols = background.horizontal ? (Math.ceil((letter.length-offset) / (15 - row)))
:(Math.ceil((letter.length-offset) / (22 - row)))
if(row == 0) {
tmplayout[row] = new Array();
tmplayout[row].push({ label: keyboard.backspace });
tmplayout[row].push({ label: keyboard.space });
row ++;
}
}
tmplayout[row] = new Array();
for (var j = 0; j < cols; j++)
tmplayout[row][j] = { label: letter[j+offset] };
offset += j;
row ++;
}
if(letter.length <= 100) {
tmplayout[0].push({ label: keyboard.space });
tmplayout[row-1].push({ label: keyboard.backspace });
}
keyboard.layout = tmplayout
}
}
Bar {
id: bar
// No exit button on mobile, UI Guidelines prohibits it
content: BarEnumContent {
value: help | config | activityConfig | about | (ApplicationInfo.isMobile ? 0 : exit)
}
anchors.bottom: keyboard.visible ? keyboard.top : parent.bottom
onAboutClicked: {
searchTextField.focus = false
displayDialog(dialogAbout)
}
onHelpClicked: {
searchTextField.focus = false
displayDialog(dialogHelp)
}
onActivityConfigClicked: {
if(clickMode == "play") {
clickMode = "activityConfig"
}
else {
clickMode = "play"
}
}
onConfigClicked: {
searchTextField.focus = false
dialogActivityConfig.active = true
dialogActivityConfig.loader.item.loadFromConfig()
displayDialog(dialogActivityConfig)
}
}
DialogAbout {
id: dialogAbout
onClose: home()
}
DialogHelp {
id: dialogHelp
onClose: home()
activityInfo: ActivityInfoTree.rootMenu
}
DialogActivityConfig {
id: dialogActivityConfig
currentActivity: activity
content: Component {
ConfigurationItem {
id: configItem
width: dialogActivityConfig.width - 50 * ApplicationInfo.ratio
}
}
onSaveData: {
dialogActivityConfig.configItem.save();
}
onClose: {
if(activity.currentTag != "search") {
ActivityInfoTree.filterByTag(activity.currentTag)
ActivityInfoTree.filterLockedActivities()
ActivityInfoTree.filterEnabledActivities()
} else
ActivityInfoTree.filterBySearch(searchTextField.text);
home()
}
}
}
}
diff --git a/src/activities/mining/ActivityInfo.qml b/src/activities/mining/ActivityInfo.qml
index 5cbc1ae7e..cae68c6b1 100644
--- a/src/activities/mining/ActivityInfo.qml
+++ b/src/activities/mining/ActivityInfo.qml
@@ -1,46 +1,46 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "mining/Mining.qml"
difficulty: 1
icon: "mining/mining.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
//: Activity title
title: qsTr("Mining for gold")
//: Help title
description: qsTr("Use the mousewheel to approach the rockwall and look for gold nuggets.")
//intro: "Looking at the rockwall, you can see a sparkle somewhere. Move the mouse cursor next to this sparkle and use the mousewheel or the zoom gesture to zoom in."
//: Help goal
goal: qsTr("Learn to use the mousewheel or the zoom / pinch gesture to zoom in and out.")
//: Help prerequisite
prerequisite: qsTr("You should be familiar with moving the mouse and clicking.")
//: Help manual
manual: qsTr("Looking at the rockwall, you can see a sparkle somewhere. Move next to this sparkle and use the mousewheel or the zoom gesture to zoom in. If you zoomed in at maximum, a gold nugget will appear at the position of the sparkle. Click on the gold nugget to collect it.
Having collected the nugget, use the mousewheel or the pinch gesture to zoom out again. If you zoomed out at maximum, another sparkle will appear, showing the next gold nugget to collect. Collect enough nuggets to complete the level.
The truck in the lower, right corner of the screen will tell you the number of already collected nuggets and the total number of nuggets to collect in this level.")
credit: qsTr("Thanks to the Tuxpaint team for providing the following sounds under GPL:
- realrainbow.ogg - used when a new gold nugget appears
- metalpaint.wav - remixed and used when a gold nugget is collected")
section: "computer mouse"
createdInVersion: 0
}
diff --git a/src/activities/mining/CMakeLists.txt b/src/activities/mining/CMakeLists.txt
index 13ff06be7..baace446f 100644
--- a/src/activities/mining/CMakeLists.txt
+++ b/src/activities/mining/CMakeLists.txt
@@ -1 +1 @@
-GCOMPRIS_ADD_RCC(activities/mining *.qml *.svg *.js resource/*.svg resource/*.${COMPRESSED_AUDIO})
+GCOMPRIS_ADD_RCC(activities/mining *.qml *.svg *.js resource/*)
diff --git a/src/activities/mining/Mining.qml b/src/activities/mining/Mining.qml
index cd07153c8..04928a0e3 100644
--- a/src/activities/mining/Mining.qml
+++ b/src/activities/mining/Mining.qml
@@ -1,543 +1,543 @@
/* GCompris - mining.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Peter Albrecht <pa-dev@gmx.de> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "mining.js" as Activity
ActivityBase {
id: activity
onStart: focus = true
onStop: {}
pageComponent: Item {
id: background
anchors.fill: parent
signal start
signal stop
property bool gotIt: false
- property bool horizontalLayout: background.width > background.height
+ property bool horizontalLayout: background.width >= background.height
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property alias background: background
property alias miningBg: miningBg
property alias bar: bar
property alias bonus: bonus
property alias mineModel: mineObjects.model
property Item nugget
}
onStart: { Activity.start(items) }
onStop: { Activity.stop() }
Image {
id: miningBg
source: Activity.url + "rockwall.svg"
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
sourceSize.width: parent.width
width: parent.width
height: parent.height
scale: miningBg._MIN_SCALE
property int subLevel
property int maxSubLevel
property real _MAX_SCALE: 3
property real _MIN_SCALE: 1
onScaleChanged: items.nugget.checkOnScreen()
Image {
source: Activity.url + "vertical_border.svg"
sourceSize.height: parent.height
width: parent.width * 0.05
anchors {
top: parent.top
left: parent.left
bottom: parent.bottom
}
}
Image {
source: Activity.url + "vertical_border.svg"
sourceSize.height: parent.height
width: parent.width * 0.05
anchors {
top: parent.top
right: parent.right
bottom: parent.bottom
}
}
Image {
source: Activity.url + "horizontal_border.svg"
sourceSize.width: parent.width
height: parent.height * 0.05
anchors {
top: parent.top
right: parent.right
left: parent.left
}
}
GridView {
id: mineObjects
anchors.fill: parent
cellWidth: parent.width / 4
cellHeight: parent.height / 4
delegate: Item {
width: mineObjects.cellWidth
height: mineObjects.cellHeight
// Calculated value true when the nugget is on the visible
// part of the screen
property bool onScreen: true
property alias nuggetImg: nuggetImg
signal hit(real x, real y)
signal checkOnScreen
onHit: {
if(!mouseArea.enabled)
return
var point = parent.mapToItem(nuggetImg, x, y)
if(point.x > 0 && point.x < nuggetImg.width &&
point.y > 0 && point.y < nuggetImg.height)
nuggetImg.hit()
}
onCheckOnScreen: {
// Calc if the nugget is visible or not
var nuggetCoord1 =
background.mapFromItem(miningBg,
items.nugget.x + items.nugget.nuggetImg.x,
items.nugget.y + items.nugget.nuggetImg.y)
var nuggetCoord2 =
background.mapFromItem(miningBg,
items.nugget.x + items.nugget.nuggetImg.x + items.nugget.nuggetImg.width,
items.nugget.y + items.nugget.nuggetImg.y + items.nugget.nuggetImg.height)
if(nuggetCoord1.x > miningBg.width ||
nuggetCoord2.x < 0 ||
nuggetCoord1.y > miningBg.height ||
nuggetCoord2.y < 0)
onScreen = false
else
onScreen = true
}
Image {
id: nuggetImg
source: Activity.url + "gold_nugget.svg"
sourceSize.width: mineObjects.cellWidth * 3
width: mineObjects.cellWidth * modelData.widthFactor / 2
height: mineObjects.cellHeight * modelData.widthFactor / 2
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
opacity: modelData.isTarget &&
miningBg.scale === miningBg._MAX_SCALE &&
!background.gotIt ? 1 : 0
signal hit
onHit: {
- activity.audioEffects.play(Activity.url + "pickaxe."+ApplicationInfo.CompressedAudio)
+ activity.audioEffects.play(Activity.url + "pickaxe.wav")
background.gotIt = true
tuto.setState("Unzoom")
}
Component.onCompleted: {
if(modelData.isTarget)
items.nugget = parent
}
MouseArea {
id: mouseArea
anchors.fill: parent
enabled: modelData.isTarget &&
miningBg.scale === miningBg._MAX_SCALE
onClicked: parent.hit()
}
Behavior on opacity { PropertyAnimation { duration: 1000 } }
}
Image {
id: cell
source: modelData.source
sourceSize.width: mineObjects.cellWidth * 3
width: mineObjects.cellWidth * modelData.widthFactor
height: mineObjects.cellHeight * modelData.widthFactor
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
rotation: modelData.rotation
opacity: !modelData.isTarget ? 1 : (background.gotIt ? 0 : 1)
Component.onCompleted: {
- activity.audioEffects.play(Activity.url + "realrainbow."+ApplicationInfo.CompressedAudio)
+ activity.audioEffects.play(Activity.url + "realrainbow.wav")
}
ParallelAnimation {
running: modelData.isTarget && !background.gotIt
loops: Animation.Infinite
SequentialAnimation {
loops: Animation.Infinite
NumberAnimation {
target: cell
property: "rotation"
from: 0; to: 360
duration: 5000;
easing.type: Easing.InOutQuad
}
NumberAnimation {
target: cell; property: "rotation"
from: 360; to: 0
duration: 5000;
easing.type: Easing.InOutQuad
}
}
SequentialAnimation {
loops: Animation.Infinite
NumberAnimation {
target: cell; property: "scale"
from: 0; to: 1
duration: 3000;
easing.type: Easing.InOutQuad
}
PauseAnimation { duration: 300 + Math.random() * 300 }
NumberAnimation {
target: cell
property: "scale"
from: 1; to: 0
duration: 1000;
easing.type: Easing.InOutQuad
}
}
}
}
}
}
function updateScale(zoomDelta, x, y) {
var xx1 = background.mapFromItem(miningBg, x, y)
var previousScale = miningBg.scale
if (zoomDelta > 0 && miningBg.scale < miningBg._MAX_SCALE) {
if(miningBg.scale < miningBg._MAX_SCALE - 0.1)
miningBg.scale += 0.1;
else
miningBg.scale = miningBg._MAX_SCALE
if(gotIt)
tuto.setState("Unzoom")
else if(miningBg.scale < miningBg._MAX_SCALE)
tuto.setState(items.nugget.onScreen ? "ZoomOk" : "ZoomBad")
else
tuto.setState(items.nugget.onScreen ? "NuggetSeen" : "NuggetNotSeen")
} else if (zoomDelta < 0) {
if(miningBg.scale > miningBg._MIN_SCALE) {
miningBg.scale -= 0.1;
if(gotIt)
tuto.setState("Unzoom")
else if(miningBg.scale > miningBg._MIN_SCALE)
tuto.setState(items.nugget.onScreen ? "UnzoomOk" : "UnzoomBad")
else
tuto.setState("Started")
} else if (gotIt) {
gotIt = false
if(miningBg.subLevel == miningBg.maxSubLevel) {
bonus.good("lion")
} else {
miningBg.subLevel++
miningBg.scale = miningBg._MIN_SCALE
Activity.createLevel()
}
tuto.setState("Stopped")
} else {
miningBg.anchors.horizontalCenterOffset = 0
miningBg.anchors.verticalCenterOffset = 0
tuto.setState("Started")
}
}
if(previousScale != miningBg.scale) {
var xx2 = background.mapFromItem(miningBg, x, y)
miningBg.anchors.horizontalCenterOffset += xx1.x - xx2.x
miningBg.anchors.verticalCenterOffset += xx1.y - xx2.y
}
}
MouseArea {
anchors.fill: parent
propagateComposedEvents: true
onWheel: miningBg.updateScale(wheel.angleDelta.y, wheel.x, wheel.y)
}
MultiPointTouchArea {
anchors.fill: parent
mouseEnabled: false
minimumTouchPoints: 1
maximumTouchPoints: 2
// To determine if we zoom or unzoom
property int prevDist: 0
// To avoid having too many updates or the zoom flickers
property date dateEvent: new Date()
touchPoints: [
TouchPoint { id: point1 },
TouchPoint { id: point2 }
]
onReleased: prevDist = 0
onTouchUpdated: {
if(!point2.pressed) {
mineObjects.itemAt(point1.x, point1.y).hit(point1.x, point1.y)
return
}
// Calc Distance
var dist = Math.floor(Math.sqrt(Math.pow(point1.x - point2.x, 2) +
Math.pow(point1.y - point2.y, 2)))
var newDateEvent = new Date()
if(prevDist != dist &&
newDateEvent.getTime() - dateEvent.getTime() > 50) {
miningBg.updateScale(dist - prevDist,
(point1.x + point2.x) / 2,
(point1.y + point2.y) / 2)
dateEvent = newDateEvent
}
prevDist = dist
}
}
}
Image {
id: carriage
source: Activity.url + "gold_carriage.svg"
sourceSize.height: background.horizontalLayout ? 120 * ApplicationInfo.ratio : 80 * ApplicationInfo.ratio
anchors {
right: parent.right
bottom: background.horizontalLayout ? parent.bottom : bar.top
}
GCText {
id: score
anchors {
horizontalCenter: parent.horizontalCenter
verticalCenter: parent.verticalCenter
horizontalCenterOffset: parent.width / 10
}
text: miningBg.subLevel + "/" + miningBg.maxSubLevel
color: "white"
font.bold: true
style: Text.Outline
styleColor: "black"
fontSize: 22
}
}
Rectangle {
id: tutoBackground
color: "#C0b7b353"
border.color: "black"
border.width: 2
radius: 10
anchors {
left: parent.left
right: parent.right
top: parent.top
margins: 10
}
height: tuto.height + anchors.margins * 2
visible: tuto.state != "Stopped"
Behavior on height { PropertyAnimation { duration: 100 } }
GCText {
id: tuto
fontSize: 13
anchors {
left: parent.left
right: parent.right
top: parent.top
margins: 10
}
color: "white"
wrapMode: TextEdit.WordWrap
horizontalAlignment: TextEdit.AlignHCenter
property string newState
function setState(nextState) {
if(bar.level == 1) {
if(newState != nextState) {
newState = nextState
anim.restart()
}
} else {
newState = "Stopped"
anim.restart()
}
}
states: [
State {
name: "Started"
PropertyChanges {
target: tuto;
text: qsTr("Find the sparkle and zoom in around it. If you have a mouse, point the cursor on the sparkle then use the scroll wheel. If you have a trackpad, point the cursor on the sparkle then drag one finger on the right area or two fingers on the center. On a touch area, drag two fingers away from the sparkle, one in each direction.")
}
},
State {
name: "Stopped"
PropertyChanges { target: tuto; text: ""}
},
State {
name: "ZoomOk"
PropertyChanges {
target: tuto
text: qsTr("Perfect you are zooming. Continue until you see the nugget.")}
},
State {
name: "ZoomBad"
PropertyChanges {
target: tuto
text: qsTr("Hum, take care, you are zooming too far from the sparkle.")}
},
State {
name: "NuggetSeen"
PropertyChanges {
target: tuto
text: qsTr("Now you see the nugget, click on it to catch it.")}
},
State {
name: "NuggetNotSeen"
PropertyChanges {
target: tuto
text: qsTr("Hum, you are too far from the nugget to see it. Unzoom then zoom again as close as you can from the sparkle.")}
},
State {
name: "Unzoom"
PropertyChanges {
target: tuto
text: qsTr("Now unzoom and try to find another sparkle.")}
},
State {
name: "UnzoomBad"
PropertyChanges {
target: tuto
text: qsTr("Continue to unzoom until you see the sparkle.")}
},
State {
name: "UnzoomOk"
PropertyChanges {
target: tuto
text: qsTr("Now you see the sparkle, go ahead, you can zoom on it.")}
}
]
SequentialAnimation {
id: anim
PropertyAnimation {
target: tuto
property: "opacity"
easing.type: Easing.Linear
from: 1.0; to: 0
duration: 200
}
PropertyAction {
target: tuto
property: "state"
value: tuto.newState
}
PropertyAnimation {
target: tuto
property: "opacity"
easing.type: Easing.Linear
from: 0; to: 1.0
duration: 200
}
}
Behavior on opacity { PropertyAnimation { duration: 100 } }
transitions: Transition {
PropertyAnimation {
target: tuto
property: "opacity"
to: 1.0
}
}
}
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level }
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
onLevelChanged: {
miningBg.subLevel = 1
miningBg.anchors.horizontalCenterOffset = 0
miningBg.anchors.verticalCenterOffset = 0
miningBg.scale = miningBg._MIN_SCALE
tuto.setState("Started")
switch(bar.level) {
case 1:
miningBg.maxSubLevel = 2
break
case 2:
miningBg.maxSubLevel = 4
break
case 3:
miningBg.maxSubLevel = 10
break
}
}
}
Bonus {
id: bonus
Component.onCompleted: win.connect(Activity.nextLevel)
}
}
}
diff --git a/src/activities/mining/mining.js b/src/activities/mining/mining.js
index 2b37d89e8..ec3dcf713 100644
--- a/src/activities/mining/mining.js
+++ b/src/activities/mining/mining.js
@@ -1,91 +1,91 @@
/* GCompris - mining.js
*
* Copyright (C) 2014 Bruno Coudoin
*
* Authors:
* Peter Albrecht <pa-dev@gmx.de> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
var url = "qrc:/gcompris/src/activities/mining/resource/"
var currentLevel = 0
var numberOfLevel = 3
var items
function start(items_) {
items = items_
currentLevel = 0
initLevel()
}
function stop() {
}
function getItem(source) {
return {
source: source ?
url + source + ".svg" :
"",
rotation: Math.floor(Math.random() * 180) - 90,
widthFactor: source === "sparkle" ? 0.4 : 0.2 + Math.random() * 0.4,
isTarget: source === "sparkle"
}
}
function createLevel() {
var miningItems = new Array()
for(var i = 0; i < 16; i++) {
var index = (Math.floor(Math.random() * 16) + 1)
if(index < 5)
miningItems[i] = getItem("stone" + (Math.floor(Math.random() * 4) + 1))
else
miningItems[i] = getItem("")
}
// Place the sparkle
// The Grid is 4*4 but we skip the last line free for the bar
// The borders are harder to get so we allow them only on higher
// levels.
if(currentLevel < 2) {
var choices = [5, 6, 9, 10]
miningItems[choices[(Math.floor(Math.random() * 4))]] = getItem("sparkle")
} else {
miningItems[(Math.floor(Math.random() * 12))] = getItem("sparkle")
}
items.mineModel = miningItems
}
function initLevel() {
items.bar.level = currentLevel + 1
createLevel()
}
function nextLevel() {
if(numberOfLevel <= ++currentLevel ) {
currentLevel = 0
}
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
initLevel();
}
diff --git a/src/activities/mining/resource/pickaxe.ogg b/src/activities/mining/resource/pickaxe.ogg
deleted file mode 100644
index ea2dbb7bc..000000000
Binary files a/src/activities/mining/resource/pickaxe.ogg and /dev/null differ
diff --git a/src/activities/mining/resource/pickaxe.wav b/src/activities/mining/resource/pickaxe.wav
new file mode 100644
index 000000000..faddd8581
Binary files /dev/null and b/src/activities/mining/resource/pickaxe.wav differ
diff --git a/src/activities/mining/resource/realrainbow.ogg b/src/activities/mining/resource/realrainbow.ogg
deleted file mode 100644
index 69d0a1f3b..000000000
Binary files a/src/activities/mining/resource/realrainbow.ogg and /dev/null differ
diff --git a/src/activities/mining/resource/realrainbow.wav b/src/activities/mining/resource/realrainbow.wav
new file mode 100644
index 000000000..499c51821
Binary files /dev/null and b/src/activities/mining/resource/realrainbow.wav differ
diff --git a/src/activities/missing-letter/ActivityInfo.qml b/src/activities/missing-letter/ActivityInfo.qml
index a9b4ee011..f268113b3 100644
--- a/src/activities/missing-letter/ActivityInfo.qml
+++ b/src/activities/missing-letter/ActivityInfo.qml
@@ -1,41 +1,41 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Amit Tomar <a.tomar@outlook.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo
{
name: "missing-letter/MissingLetter.qml"
difficulty: 2
icon: "missing-letter/missing-letter.svg"
author: "Amit Tomar &lt;a.tomar@outlook.com&gt;"
demo: true
//: Activity title
title: qsTr("Missing Letter")
//: Help title
description: ""
// intro: "Find the missing letter and complete the word by clicking on one of the letters proposed on the side."
//: Help goal
goal: qsTr("Training reading skills")
//: Help prerequisite
prerequisite: qsTr("Word reading")
//: Help manual
manual: qsTr("An object is displayed in the main area, and an incomplete word is printed under the picture. Select the missing letter to complete the word.")
credit: ""
section: "reading"
createdInVersion: 0
}
diff --git a/src/activities/missing-letter/MissingLetter.qml b/src/activities/missing-letter/MissingLetter.qml
index ae70ee6a7..b822e395c 100644
--- a/src/activities/missing-letter/MissingLetter.qml
+++ b/src/activities/missing-letter/MissingLetter.qml
@@ -1,375 +1,375 @@
/* GCompris - missing-letter.qml
*
* Copyright (C) 2014 "Amit Tomar" <a.tomar@outlook.com>
*
* Authors:
* "Pascal Georges" <pascal.georgis1.free.fr> (GTK+ version)
* "Amit Tomar" <a.tomar@outlook.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "missing-letter.js" as Activity
ActivityBase {
id: activity
onStart: focus = true
onStop: {}
// When going on configuration, it steals the focus and re set it to the activity.
// We need to set it back to the textinput item in order to have key events.
onFocusChanged: {
if(focus) {
Activity.focusTextInput()
}
}
pageComponent: Image {
id: background
source: Activity.url + "background.svg"
sourceSize.width: Math.max(parent.width, parent.height)
fillMode: Image.PreserveAspectCrop
// system locale by default
property string locale: "system"
property bool englishFallback: false
property bool downloadWordsNeeded: false
signal start
signal stop
Component.onCompleted: {
dialogActivityConfig.getInitialConfiguration()
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property alias background: background
property alias bar: bar
property alias bonus: bonus
property alias score: score
property alias questionImage: questionImage
property alias questionText: questionText
property alias answers: answers
property GCAudio audioVoices: activity.audioVoices
property alias englishFallbackDialog: englishFallbackDialog
property alias parser: parser
property alias locale: background.locale
property string answer
property alias textinput: textinput
property bool isGoodAnswer: false
property bool buttonsBlocked: false
}
onStart: {
Activity.init(items)
Activity.focusTextInput()
Activity.start()
}
onStop: {
Activity.stop()
}
TextInput {
// Helper element to capture composed key events like french ô which
// are not available via Keys.onPressed() on linux. Must be
// disabled on mobile!
id: textinput
anchors.centerIn: background
enabled: !ApplicationInfo.isMobile
focus: true
visible: false
onTextChanged: {
if (text != '') {
var typedText = text
var answerText = Activity.getCurrentQuestion().answer
if(ApplicationSettings.fontCapitalization === Font.AllUppercase)
typedText = text.toLocaleUpperCase()
else if(ApplicationSettings.fontCapitalization === Font.AllLowercase)
typedText = text.toLocaleLowerCase()
if(!items.isGoodAnswer && (typedText === answerText)) {
questionAnim.start()
Activity.showAnswer()
}
text = '';
}
}
}
// Buttons with possible answers shown on the left of screen
Column {
id: buttonHolder
spacing: 10 * ApplicationInfo.ratio
x: holder.x - width - 10 * ApplicationInfo.ratio
y: holder.y
add: Transition {
NumberAnimation { properties: "y"; from: holder.y; duration: 500 }
}
Repeater {
id: answers
AnswerButton {
width: 120 * ApplicationInfo.ratio
height: (holder.height
- buttonHolder.spacing * answers.model.length) / answers.model.length
textLabel: modelData
blockAllButtonClicks: items.buttonsBlocked
isCorrectAnswer: modelData === items.answer
onCorrectlyPressed: questionAnim.start()
onPressed: {
items.buttonsBlocked = true
if(!items.isGoodAnswer) {
modelData == items.answer ? Activity.showAnswer() : ''
}
}
onIncorrectlyPressed: items.buttonsBlocked = false
}
}
}
// Picture holder for different images being shown
Rectangle {
id: holder
width: Math.max(questionImage.width * 1.1, questionImage.height * 1.1)
height: questionTextBg.y + questionTextBg.height
x: (background.width - width - 130 * ApplicationInfo.ratio) / 2 +
130 * ApplicationInfo.ratio
y: 20
color: "black"
radius: 10
border.width: 2
border.color: "black"
gradient: Gradient {
GradientStop { position: 0.0; color: "#80FFFFFF" }
GradientStop { position: 0.9; color: "#80EEEEEE" }
GradientStop { position: 1.0; color: "#80AAAAAA" }
}
Item {
id: spacer
height: 20
}
Image {
id: questionImage
anchors.horizontalCenter: holder.horizontalCenter
anchors.top: spacer.bottom
width: Math.min((background.width - 120 * ApplicationInfo.ratio) * 0.7,
(background.height - 100 * ApplicationInfo.ratio) * 0.7)
height: width
}
Rectangle {
id: questionTextBg
width: holder.width
height: questionText.height * 1.1
anchors.horizontalCenter: holder.horizontalCenter
anchors.top: questionImage.bottom
radius: 10
border.width: 2
border.color: "black"
gradient: Gradient {
GradientStop { position: 0.0; color: "#000" }
GradientStop { position: 0.9; color: "#666" }
GradientStop { position: 1.0; color: "#AAA" }
}
GCText {
id: questionText
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
style: Text.Outline
styleColor: "black"
color: "white"
fontSize: largeSize
wrapMode: Text.WordWrap
width: holder.width
SequentialAnimation {
id: questionAnim
NumberAnimation {
target: questionText
property: 'scale'
to: 1.05
duration: 500
easing.type: Easing.OutQuad
}
NumberAnimation {
target: questionText
property: 'scale'
to: 0.95
duration: 1000
easing.type: Easing.OutQuad
}
NumberAnimation {
target: questionText
property: 'scale'
to: 1.0
duration: 500
easing.type: Easing.OutQuad
}
ScriptAction {
script: Activity.nextSubLevel()
}
}
}
}
}
Score {
id: score
anchors.bottom: undefined
anchors.bottomMargin: 10 * ApplicationInfo.ratio
anchors.right: parent.right
anchors.rightMargin: 10 * ApplicationInfo.ratio
anchors.top: parent.top
}
DialogActivityConfig {
id: dialogActivityConfig
currentActivity: activity
content: Component {
Item {
property alias localeBox: localeBox
height: column.height
property alias availableLangs: langs.languages
LanguageList {
id: langs
}
Column {
id: column
spacing: 10
width: parent.width
Flow {
spacing: 5
width: dialogActivityConfig.width
GCComboBox {
id: localeBox
model: langs.languages
background: dialogActivityConfig
label: qsTr("Select your locale")
}
}
}
}
}
onClose: home()
onLoadData: {
if(dataToSave && dataToSave["locale"]) {
background.locale = dataToSave["locale"];
}
}
onSaveData: {
var oldLocale = background.locale;
var newLocale =
dialogActivityConfig.configItem.availableLangs[dialogActivityConfig.loader.item.localeBox.currentIndex].locale;
// Remove .UTF-8
if(newLocale.indexOf('.') != -1) {
newLocale = newLocale.substring(0, newLocale.indexOf('.'))
}
dataToSave = {"locale": newLocale }
background.locale = newLocale;
// Restart the activity with new information
if(oldLocale !== newLocale) {
background.stop();
background.start();
}
}
function setDefaultValues() {
var localeUtf8 = background.locale;
if(background.locale != "system") {
localeUtf8 += ".UTF-8";
}
for(var i = 0 ; i < dialogActivityConfig.configItem.availableLangs.length ; i ++) {
if(dialogActivityConfig.configItem.availableLangs[i].locale === localeUtf8) {
dialogActivityConfig.loader.item.localeBox.currentIndex = i;
break;
}
}
}
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level | repeat | config }
onHelpClicked: displayDialog(dialogHelp)
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
onRepeatClicked: Activity.playCurrentWord()
onConfigClicked: {
dialogActivityConfig.active = true
dialogActivityConfig.setDefaultValues()
displayDialog(dialogActivityConfig)
}
}
Bonus {
id: bonus
onStart: items.buttonsBlocked = true
onStop: items.buttonsBlocked = false
Component.onCompleted: win.connect(Activity.nextLevel)
}
JsonParser {
id: parser
onError: console.error("missing letter: Error parsing json: " + msg);
}
Loader {
id: englishFallbackDialog
sourceComponent: GCDialog {
parent: activity.main
message: qsTr("We are sorry, we don't have yet a translation for your language.") + " " +
- qsTr("GCompris is developed by the KDE community, you can translate GCompris by joining a translation team on <a href=\"%2\">%2</a>").arg("http://l10n.kde.org/") +
+ qsTr("GCompris is developed by the KDE community, you can translate GCompris by joining a translation team on <a href=\"%2\">%2</a>").arg("https://l10n.kde.org/") +
"<br /> <br />" +
qsTr("We switched to English for this activity but you can select another language in the configuration dialog.")
onClose: background.englishFallback = false
}
anchors.fill: parent
focus: true
active: background.englishFallback
onStatusChanged: if (status == Loader.Ready) item.start()
}
}
}
diff --git a/src/activities/missing-letter/missing-letter.js b/src/activities/missing-letter/missing-letter.js
index c6ed8e47d..e4ce1ee21 100644
--- a/src/activities/missing-letter/missing-letter.js
+++ b/src/activities/missing-letter/missing-letter.js
@@ -1,258 +1,258 @@
/* GCompris - missing-letter.js
*
* Copyright (C) 2014 "Amit Tomar" <a.tomar@outlook.com>
*
* Authors:
* "Pascal Georges" <pascal.georgis1.free.fr> (GTK+ version)
* "Amit Tomar" <a.tomar@outlook.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
.import "qrc:/gcompris/src/core/core.js" as Core
.import GCompris 1.0 as GCompris //for ApplicationInfo
.import "qrc:/gcompris/src/activities/lang/lang_api.js" as Lang
var url = "qrc:/gcompris/src/activities/missing-letter/resource/"
var langUrl = "qrc:/gcompris/src/activities/lang/resource/";
var items
var currentLevel
var numberOfLevel
var questions
var dataset
var lessons
// Do not propose these letter in the choices
var ignoreLetters = '[ ,;:\\-\u0027]'
function init(items_) {
items = items_
}
function start() {
currentLevel = 0
var locale = GCompris.ApplicationInfo.getVoicesLocale(items.locale)
// register the voices for the locale
GCompris.DownloadManager.updateResource(GCompris.DownloadManager.getVoicesResourceForLocale(locale))
dataset = Lang.load(items.parser, langUrl,
GCompris.ApplicationSettings.wordset ? "words.json" : "words_sample.json",
"content-"+ locale +".json")
// If dataset is empty, we try to load from short locale
// and if not present again, we switch to default one
var localeUnderscoreIndex = locale.indexOf('_')
if(!dataset) {
var localeShort;
// We will first look again for locale xx (without _XX if exist)
if(localeUnderscoreIndex > 0) {
localeShort = locale.substring(0, localeUnderscoreIndex)
} else {
localeShort = locale;
}
dataset = Lang.load(items.parser, langUrl,
GCompris.ApplicationSettings.wordset ? "words.json" : "words_sample.json",
"content-"+localeShort+ ".json")
}
// If still dataset is empty then fallback to english
if(!dataset) {
// English fallback
items.background.englishFallback = true
dataset = Lang.load(items.parser, langUrl,
GCompris.ApplicationSettings.wordset ? "words.json" : "words_sample.json",
"content-en.json")
} else {
items.background.englishFallback = false
}
lessons = Lang.getAllLessons(dataset)
questions = initDataset()
numberOfLevel = questions.length
initLevel()
}
function initDataset() {
var questions = []
for (var lessonIndex = 0; lessonIndex < lessons.length; lessonIndex++) {
var lesson = Lang.getLessonWords(dataset, lessons[lessonIndex])
var guessLetters = getRandomLetters(lesson)
questions[lessonIndex] = []
for (var j in lesson) {
var clearQuestion = lesson[j].translatedTxt
if(GCompris.ApplicationSettings.fontCapitalization === Quick.Font.AllUppercase)
clearQuestion = clearQuestion.toLocaleUpperCase()
else if(GCompris.ApplicationSettings.fontCapitalization === Quick.Font.AllLowercase)
clearQuestion = clearQuestion.toLocaleLowerCase()
var maskedQuestion = getRandomMaskedQuestion(clearQuestion, guessLetters, lessonIndex)
questions[lessonIndex].push(
{
'image': lesson[j].image,
'clearQuestion': clearQuestion,
'maskedQuestion': maskedQuestion[0],
'answer': maskedQuestion[1],
'choices': maskedQuestion[2],
'voice': lesson[j].voice,
})
}
}
return questions
}
// Get all the letters for all the words in the lesson excluding ignoreLetters
function getRandomLetters(lesson) {
var letters = []
var re = new RegExp(ignoreLetters, 'g');
for (var i in lesson) {
if(GCompris.ApplicationSettings.fontCapitalization === Quick.Font.AllUppercase)
letters = letters.concat(lesson[i].translatedTxt.replace(re, '').toLocaleUpperCase().split(''))
else if(GCompris.ApplicationSettings.fontCapitalization === Quick.Font.AllLowercase)
letters = letters.concat(lesson[i].translatedTxt.replace(re, '').toLocaleLowerCase().split(''))
else
letters = letters.concat(lesson[i].translatedTxt.replace(re, '').split(''))
}
return sortUnique(letters)
}
// Get a random letter in the given word excluding ignoreLetters
function getRandomLetter(word) {
var re = new RegExp(ignoreLetters, 'g')
var letters = word.replace(re, '').split('')
var letter = Core.shuffle(letters)[0]
if(GCompris.ApplicationSettings.fontCapitalization === Quick.Font.AllUppercase)
return letter.toLocaleUpperCase()
else if(GCompris.ApplicationSettings.fontCapitalization === Quick.Font.AllLowercase)
return letter.toLocaleLowerCase()
return letter
}
function getRandomMaskedQuestion(clearQuestion, guessLetters, level) {
var maskedQuestion = clearQuestion
var goodLetter = getRandomLetter(maskedQuestion)
var index = maskedQuestion.search(goodLetter)
// Replace the char at index with '_'
var repl = maskedQuestion.split('')
repl[index] = '_'
maskedQuestion = repl.join('')
// Get some other letter to confuse the children
var confusingLetters = []
for(var i = 0; i < Math.min(level + 2, 6); i++) {
var letter = guessLetters.shift()
confusingLetters.push(letter)
guessLetters.push(letter)
}
confusingLetters.push(goodLetter)
return [maskedQuestion, goodLetter, Core.shuffle(sortUnique(confusingLetters))]
}
function sortUnique(arr) {
arr = GCompris.ApplicationInfo.localeSort(arr, items.locale);
var ret = [arr[0]];
for (var i = 1; i < arr.length; i++) { // start loop at 1 as element 0 can never be a duplicate
if (arr[i-1] !== arr[i]) {
ret.push(arr[i]);
}
}
return ret;
}
function stop() {
}
function initLevel() {
items.bar.level = currentLevel + 1
items.score.currentSubLevel = 1
items.score.numberOfSubLevels = questions[currentLevel].length
showQuestion()
}
function getCurrentQuestion() {
return questions[currentLevel][items.score.currentSubLevel - 1]
}
function showQuestion() {
var question = getCurrentQuestion()
playWord(question.voice)
items.answer = question.answer
items.answers.model = question.choices
items.questionText.text = question.maskedQuestion
items.questionImage.source = question.image
items.isGoodAnswer = false
items.buttonsBlocked = false
}
function nextLevel() {
if(numberOfLevel <= ++currentLevel) {
currentLevel = 0
}
initLevel();
}
function nextSubLevel() {
var question = getCurrentQuestion()
if(items.score.currentSubLevel >= questions[currentLevel].length) {
items.bonus.good('flower')
return
}
items.score.currentSubLevel ++;
showQuestion()
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
initLevel();
}
function showAnswer() {
var question = getCurrentQuestion()
playLetter(question.answer)
items.isGoodAnswer = true
items.questionText.text = question.clearQuestion
}
function playLetter(letter) {
var locale = GCompris.ApplicationInfo.getVoicesLocale(items.locale)
items.audioVoices.append(GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/"+locale+"/alphabet/" +
Core.getSoundFilenamForChar(letter)))
}
function playCurrentWord() {
var question = getCurrentQuestion()
playWord(question.voice)
}
function playWord(word) {
var locale = GCompris.ApplicationInfo.getVoicesLocale(items.locale)
var wordLocalized = word.replace("$LOCALE", locale)
items.audioVoices.append(GCompris.ApplicationInfo.getAudioFilePath(wordLocalized))
}
function focusTextInput() {
if (!GCompris.ApplicationInfo.isMobile && items && items.textinput)
items.textinput.forceActiveFocus();
}
diff --git a/src/activities/money/ActivityInfo.qml b/src/activities/money/ActivityInfo.qml
index 339a87d92..ab30d78fb 100644
--- a/src/activities/money/ActivityInfo.qml
+++ b/src/activities/money/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "money/Money.qml"
difficulty: 2
icon: "money/money.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
//: Activity title
title: qsTr("Money")
//: Help title
description: qsTr("Practice money usage")
// intro: "Click or tap on the money to pay."
//: Help goal
goal: qsTr("You must buy the different items and give the exact price. At higher levels, several items are displayed, and you must first calculate the total price.")
//: Help prerequisite
prerequisite: qsTr("Can count")
//: Help manual
manual: qsTr("Click or tap on the coins or paper money at the bottom of the screen to pay. If you want to remove a coin or note, click or tap on it on the upper screen area.")
credit: ""
section: "math numeration money"
createdInVersion: 0
}
diff --git a/src/activities/money/Money.qml b/src/activities/money/Money.qml
index ecf8f4887..e5287263a 100644
--- a/src/activities/money/Money.qml
+++ b/src/activities/money/Money.qml
@@ -1,28 +1,28 @@
/* GCompris - Money.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
MoneyCore {
dataset: "WITHOUT_CENTS"
}
diff --git a/src/activities/money/MoneyArea.qml b/src/activities/money/MoneyArea.qml
new file mode 100644
index 000000000..6a9fbe11f
--- /dev/null
+++ b/src/activities/money/MoneyArea.qml
@@ -0,0 +1,89 @@
+/* GCompris - MoneyArea.qml
+ *
+ * Copyright (C) 2018 Smit S. Patil <smit17av@gmial.com>
+ *
+ * Authors:
+ * Smit S. Patil <smit17av@gmail.com>
+ *
+ * This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+ */
+import QtQuick 2.6
+
+import "../../core"
+import "money.js" as Activity
+
+Rectangle {
+ id: moneyAreaBody
+ height: (columnLayout.itemHeight + 10) * columnLayout.nbLines
+ width: columnLayout.width
+ color: "#55333333"
+ border.color: "black"
+ border.width: 2
+ radius: 5
+
+ property alias pocketModel: pocketModel
+ property alias answer: pocket
+ signal transaction(int index)
+
+ Flow {
+ anchors.topMargin: 4
+ anchors.bottomMargin: 4
+ anchors.leftMargin: 10
+ anchors.rightMargin: 10
+ anchors.fill: parent
+ spacing: 10
+
+ add: Transition {
+ NumberAnimation {
+ properties: "x"
+ from: parent.width * 0.05
+ easing.type: Easing.InOutQuad
+ }
+ }
+
+ move: Transition {
+ NumberAnimation {
+ properties: "x,y"
+ easing.type: Easing.InOutQuad
+ }
+ }
+
+ Repeater {
+ id: pocket
+ model: ListModel { id: pocketModel }
+ Image {
+ source: Activity.url + img
+ sourceSize.height: columnLayout.itemHeight
+ height: columnLayout.itemHeight
+
+ property bool selected: false
+
+ MultiPointTouchArea {
+ anchors.fill: parent
+ onReleased: moneyAreaBody.transaction(index)
+ }
+
+ Rectangle{
+ width: parent.width * 1.1
+ height: parent.height * 1.1
+ color: "#88111111"
+ anchors.centerIn : parent
+ radius: 5
+ visible: selected
+ z: -1
+ }
+ }
+ }
+ }
+}
diff --git a/src/activities/money/MoneyCore.qml b/src/activities/money/MoneyCore.qml
index 48db1ac6a..e5795abe2 100644
--- a/src/activities/money/MoneyCore.qml
+++ b/src/activities/money/MoneyCore.qml
@@ -1,310 +1,269 @@
/* GCompris - MoneyCore.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
import "money.js" as Activity
ActivityBase {
id: activity
onStart: focus = true
onStop: {}
property var dataset
pageComponent: Image {
id: background
anchors.fill: parent
source: Activity.url + "/background.svg"
sourceSize.width: parent.width
signal start
signal stop
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property alias background: background
property GCSfx audioEffects: activity.audioEffects
- property alias answerModel: answerModel
- property alias pocketModel: pocketModel
+ property alias answerModel: answerArea.pocketModel
+ property alias pocketModel: pocketArea.pocketModel
property alias store: store
property alias instructions: instructions
property alias tux: tux
property alias tuxMoney: tuxMoney
property alias bar: bar
property alias bonus: bonus
+ property int itemIndex
+ property var selectedArea
+ property alias pocket: pocketArea.answer
+ property alias answer: answerArea.answer
}
onStart: { Activity.start(items, dataset) }
onStop: { Activity.stop() }
Column {
- id: column
+ id: columnLayout
spacing: 10
x: parent.width * 0.05
y: parent.height * 0.05
width: parent.width * 0.9
property int nbColumns: 5
property int nbLines: 2
property int itemWidth:
Math.min(width / nbColumns - 10 - 10 / nbColumns,
parent.height * 0.4 / nbLines - 10 - 10 / nbLines)
property int itemHeight: itemWidth * 0.59
// === The Answer Area ===
- Rectangle {
+ MoneyArea {
id: answerArea
- height: (column.itemHeight + 10) * column.nbLines
- width: column.width
- color: "#55333333"
- border.color: "black"
- border.width: 2
- radius: 5
-
- Flow {
- anchors.topMargin: 4
- anchors.bottomMargin: 4
- anchors.leftMargin: 10
- anchors.rightMargin: 10
- anchors.fill: parent
- spacing: 10
-
- add: Transition {
- NumberAnimation {
- properties: "x"
- from: parent.width * 0.05
- easing.type: Easing.InOutQuad
- }
- }
-
- move: Transition {
- NumberAnimation {
- properties: "x,y"
- easing.type: Easing.InOutQuad
- }
- }
-
- Repeater {
- id: answer
- model: ListModel { id: answerModel }
- Image {
- source: Activity.url + img
- sourceSize.height: column.itemHeight
- height: column.itemHeight
-
- MultiPointTouchArea {
- anchors.fill: parent
- onReleased: Activity.unpay(index)
- }
- }
- }
- }
+ onTransaction: Activity.unpay(index)
}
// === The Store Area ===
property int nbStoreColumns: activity.dataset === "BACK_WITHOUT_CENTS" ||
activity.dataset === "BACK_WITH_CENTS" ? store.model.length + 1 : store.model.length
//tempSpace is a workaround to replace instructionsArea.realHeight that is freezing with Qt-5.9.1
- property int tempSpace: bar.level === 1 ? 140 + column.spacing : 0
+ property int tempSpace: bar.level === 1 ? 140 + columnLayout.spacing : 0
property int itemStoreWidth:
- Math.min((column.width - storeAreaFlow.spacing * nbStoreColumns) / nbStoreColumns,
+ Math.min((columnLayout.width - storeAreaFlow.spacing * nbStoreColumns) / nbStoreColumns,
(parent.height - answerArea.height -
pocketArea.height - bar.height) * 0.8) - tempSpace
property int itemStoreHeight: itemStoreWidth
Rectangle {
id: storeArea
- height: (column.itemStoreHeight + 10)
- width: column.width
+ height: (columnLayout.itemStoreHeight + 10)
+ width: columnLayout.width
color: "#55333333"
border.color: "black"
border.width: 2
radius: 5
Flow {
id: storeAreaFlow
anchors.topMargin: 4
anchors.bottomMargin: 4
anchors.leftMargin: 20
anchors.rightMargin: 20
anchors.fill: parent
spacing: 40
add: Transition {
NumberAnimation {
properties: "x"
from: parent.width * 0.05
duration: 300
}
}
Image {
id: tux
visible: activity.dataset === "BACK_WITHOUT_CENTS" ||
activity.dataset === "BACK_WITH_CENTS"
source: Activity.url + "/tux.svg"
- sourceSize.height: column.itemStoreHeight
- sourceSize.width: column.itemStoreHeight
+ sourceSize.height: columnLayout.itemStoreHeight
+ sourceSize.width: columnLayout.itemStoreHeight
Repeater {
id: tuxMoney
Image {
source: Activity.url + modelData.img
- sourceSize.height: column.itemStoreHeight * 0.4
+ sourceSize.height: columnLayout.itemStoreHeight * 0.4
x: tux.x + index * 20
y: tux.y + tux.height / 2 + index * 20
}
}
}
Repeater {
id: store
Image {
source: Activity.url + modelData.img
- sourceSize.height: column.itemStoreHeight
- sourceSize.width: column.itemStoreHeight
+ sourceSize.height: columnLayout.itemStoreHeight
+ sourceSize.width: columnLayout.itemStoreHeight
GCText {
text: modelData.price
fontSize: 16
font.weight: Font.DemiBold
style: Text.Outline
styleColor: "black"
color: "white"
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
anchors.topMargin: index % 2 == 0 ? 0 : parent.height - height
}
}
}
}
}
// == The instructions Area ==
Rectangle {
id: instructionsArea
height: instructions.height
- width: column.width
+ width: columnLayout.width
color: "#55333333"
border.color: "black"
border.width: 2
radius: 5
anchors.topMargin: 4
anchors.bottomMargin: 4
anchors.leftMargin: 10
anchors.rightMargin: 10
visible: bar.level === 1
- property int realHeight: bar.level === 1 ? height + column.spacing : 0
+ property int realHeight: bar.level === 1 ? height + columnLayout.spacing : 0
GCText {
id: instructions
horizontalAlignment: Text.AlignHCenter
- width: column.width
- height: column.height / 6
+ width: columnLayout.width
+ height: columnLayout.height / 6
wrapMode: Text.WordWrap
fontSizeMode: Text.Fit
}
}
// === The Pocket Area ===
- Rectangle {
+ MoneyArea {
id: pocketArea
- height: (column.itemHeight + 10) * column.nbLines
- width: column.width
- color: "#661111AA"
- border.color: "black"
- border.width: 2
- radius: 5
+ onTransaction: Activity.pay(index)
+ }
+ }
- Flow {
- anchors.topMargin: 4
- anchors.bottomMargin: 4
- anchors.leftMargin: 10
- anchors.rightMargin: 10
- anchors.fill: parent
- spacing: 10
- add: Transition {
- NumberAnimation {
- properties: "x"
- from: parent.width * 0.05
- easing.type: Easing.InOutQuad
- }
- }
+ Keys.onPressed: {
+ if(event.key === Qt.Key_Tab) {
+ if(items.selectedArea.count !== 0 && items.itemIndex !== -1)
+ items.selectedArea.itemAt(items.itemIndex).selected = false
- move: Transition {
- NumberAnimation {
- properties: "x,y"
- easing.type: Easing.InOutQuad
- }
- }
+ if(items.selectedArea == items.pocket) {
+ items.selectedArea = items.answer
+ }
+ else {
+ items.selectedArea = items.pocket
+ }
+ items.itemIndex = 0
+ }
- Repeater {
- id: pocket
- model: ListModel { id: pocketModel }
- Image {
- source: Activity.url + img
- sourceSize.height: column.itemHeight
- height: column.itemHeight
+ if(items.selectedArea.count !== 0) {
+ if(items.itemIndex >= 0)
+ items.selectedArea.itemAt(items.itemIndex).selected = false
- MultiPointTouchArea {
- anchors.fill: parent
- onReleased: Activity.pay(index)
- }
- }
- }
+ if(event.key === Qt.Key_Right) {
+ if(items.itemIndex != (items.selectedArea.count-1))
+ items.itemIndex++
+ else
+ items.itemIndex = 0
+ }
+ if(event.key === Qt.Key_Left) {
+ if(items.itemIndex > 0)
+ items.itemIndex--
+ else
+ items.itemIndex = items.selectedArea.count-1
+ }
+ if([Qt.Key_Space, Qt.Key_Enter, Qt.Key_Return].indexOf(event.key) != -1 && items.itemIndex !== -1 ) {
+ if(items.selectedArea == items.pocket)
+ Activity.pay(items.itemIndex)
+ else
+ Activity.unpay(items.itemIndex)
+ if(items.itemIndex > 0)
+ items.itemIndex--
}
}
+ if(items.selectedArea.count !== 0 && items.itemIndex !== -1)
+ items.selectedArea.itemAt(items.itemIndex).selected = true
}
-
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level }
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
}
Bonus {
id: bonus
Component.onCompleted: win.connect(Activity.nextLevel)
}
}
}
diff --git a/src/activities/money/money.js b/src/activities/money/money.js
index 8c50c92e7..dd44ac123 100644
--- a/src/activities/money/money.js
+++ b/src/activities/money/money.js
@@ -1,779 +1,784 @@
/* GCompris - money.js
*
* Copyright (C) 2014 Bruno Coudoin
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import "qrc:/gcompris/src/core/core.js" as Core
.import GCompris 1.0 as GCompris
var url = "qrc:/gcompris/src/activities/money/resource/"
// We create 3 prices categories to make the game more realistic.
// List of images to use in the game (cheap objects)
var cheapObjects = [
"apple.svg",
"orange.svg",
"banane.svg",
"pamplemousse.svg",
"carot.svg",
"cerise.svg",
"cake.svg"
]
var normalObjects = [
"umbrella.svg",
"pencil.svg",
"bottle.svg",
"light.svg",
"eggpot.svg"
]
var expensiveObjects = [
"lamp.svg",
"football.svg",
"bicycle.svg"
]
var moneyItems = {
MONEY_EURO_COIN_1C: { img: "c1c.svg", val: 0.01 },
MONEY_EURO_COIN_2C: { img: "c2c.svg", val: 0.02 },
MONEY_EURO_COIN_5C: { img: "c5c.svg", val: 0.05 },
MONEY_EURO_COIN_10C: { img: "c10c.svg", val: 0.1 },
MONEY_EURO_COIN_20C: { img: "c20c.svg", val: 0.20 },
MONEY_EURO_COIN_50C: { img: "c50c.svg", val: 0.5 },
MONEY_EURO_COIN_1E: { img: "c1e.svg", val: 1.0 },
MONEY_EURO_COIN_2E: { img: "c2e.svg", val: 2.0 },
MONEY_EURO_PAPER_5E: { img: "n5e.svg", val: 5.0 },
MONEY_EURO_PAPER_10E: { img: "n10e.svg", val: 10.0 },
MONEY_EURO_PAPER_20E: { img: "n20e.svg", val: 20.0 },
MONEY_EURO_PAPER_50E: { img: "n50e.svg", val: 50.0 },
}
var fullDataset = {
WITHOUT_CENTS: [
{
numberOfItem: 1,
minPrice: 3,
maxPrice: 10,
pocket: [
moneyItems.MONEY_EURO_PAPER_5E,
moneyItems.MONEY_EURO_PAPER_5E,
moneyItems.MONEY_EURO_PAPER_5E,
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_COIN_1E
]
},
{
numberOfItem: 1,
minPrice: 10,
maxPrice: 20,
pocket: [
moneyItems.MONEY_EURO_PAPER_10E,
moneyItems.MONEY_EURO_PAPER_5E,
moneyItems.MONEY_EURO_PAPER_5E,
moneyItems.MONEY_EURO_PAPER_5E,
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_COIN_1E
]
},
{
numberOfItem: 2,
minPrice: 20,
maxPrice: 30,
pocket: [
moneyItems.MONEY_EURO_PAPER_10E,
moneyItems.MONEY_EURO_PAPER_10E,
moneyItems.MONEY_EURO_PAPER_5E,
moneyItems.MONEY_EURO_PAPER_5E,
moneyItems.MONEY_EURO_PAPER_5E,
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_COIN_1E
]
},
{
numberOfItem: 2,
minPrice: 30,
maxPrice: 40,
pocket: [
moneyItems.MONEY_EURO_PAPER_10E,
moneyItems.MONEY_EURO_PAPER_10E,
moneyItems.MONEY_EURO_PAPER_5E,
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_PAPER_10E,
moneyItems.MONEY_EURO_PAPER_5E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_COIN_1E
]
},
{
numberOfItem: 3,
minPrice: 40,
maxPrice: 50,
pocket: [
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_PAPER_10E,
moneyItems.MONEY_EURO_PAPER_10E,
moneyItems.MONEY_EURO_PAPER_5E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_PAPER_5E,
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_PAPER_20E,
moneyItems.MONEY_EURO_COIN_1E
]
},
{
numberOfItem: 3,
minPrice: 50,
maxPrice: 60,
pocket: [
moneyItems.MONEY_EURO_PAPER_10E,
moneyItems.MONEY_EURO_PAPER_20E,
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_PAPER_20E,
moneyItems.MONEY_EURO_PAPER_5E,
moneyItems.MONEY_EURO_PAPER_5E,
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_COIN_1E
]
},
{
numberOfItem: 4,
minPrice: 60,
maxPrice: 70,
pocket: [
moneyItems.MONEY_EURO_PAPER_50E,
moneyItems.MONEY_EURO_PAPER_20E,
moneyItems.MONEY_EURO_PAPER_10E,
moneyItems.MONEY_EURO_PAPER_5E,
moneyItems.MONEY_EURO_PAPER_5E,
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_COIN_1E
]
},
{
numberOfItem: 4,
minPrice: 70,
maxPrice: 80,
pocket: [
moneyItems.MONEY_EURO_PAPER_50E,
moneyItems.MONEY_EURO_PAPER_20E,
moneyItems.MONEY_EURO_PAPER_5E,
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_PAPER_10E,
moneyItems.MONEY_EURO_PAPER_5E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_COIN_1E
]
},
{
numberOfItem: 4,
minPrice: 50,
maxPrice: 100,
pocket: [
moneyItems.MONEY_EURO_PAPER_10E,
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_PAPER_5E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_PAPER_50E,
moneyItems.MONEY_EURO_PAPER_20E,
moneyItems.MONEY_EURO_PAPER_5E,
moneyItems.MONEY_EURO_PAPER_5E
]
}
],
WITH_CENTS: [
{
numberOfItem: 1,
minPrice: 1,
maxPrice: 3,
pocket: [
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_COIN_5C,
moneyItems.MONEY_EURO_COIN_2C,
moneyItems.MONEY_EURO_COIN_20C,
moneyItems.MONEY_EURO_COIN_50C,
moneyItems.MONEY_EURO_COIN_20C,
moneyItems.MONEY_EURO_COIN_10C,
moneyItems.MONEY_EURO_COIN_1C,
moneyItems.MONEY_EURO_COIN_1C,
]
},
{
numberOfItem: 1,
minPrice: 1,
maxPrice: 3,
pocket: [
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_COIN_5C,
moneyItems.MONEY_EURO_COIN_2C,
moneyItems.MONEY_EURO_COIN_20C,
moneyItems.MONEY_EURO_COIN_50C,
moneyItems.MONEY_EURO_COIN_20C,
moneyItems.MONEY_EURO_COIN_10C,
moneyItems.MONEY_EURO_COIN_1C,
moneyItems.MONEY_EURO_COIN_1C
]
},
{
numberOfItem: 2,
minPrice: 1,
maxPrice: 3,
pocket: [
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_COIN_5C,
moneyItems.MONEY_EURO_COIN_2C,
moneyItems.MONEY_EURO_COIN_20C,
moneyItems.MONEY_EURO_COIN_50C,
moneyItems.MONEY_EURO_COIN_20C,
moneyItems.MONEY_EURO_COIN_10C,
moneyItems.MONEY_EURO_COIN_1C,
moneyItems.MONEY_EURO_COIN_1C,
]
},
{
numberOfItem: 3,
minPrice: 1,
maxPrice: 3,
pocket: [
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_COIN_5C,
moneyItems.MONEY_EURO_COIN_2C,
moneyItems.MONEY_EURO_COIN_20C,
moneyItems.MONEY_EURO_COIN_50C,
moneyItems.MONEY_EURO_COIN_20C,
moneyItems.MONEY_EURO_COIN_10C,
moneyItems.MONEY_EURO_COIN_1C,
moneyItems.MONEY_EURO_COIN_1C
]
},
{
numberOfItem: 4,
minPrice: 0,
maxPrice: 4,
pocket: [
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_COIN_5C,
moneyItems.MONEY_EURO_COIN_2C,
moneyItems.MONEY_EURO_COIN_20C,
moneyItems.MONEY_EURO_COIN_50C,
moneyItems.MONEY_EURO_COIN_20C,
moneyItems.MONEY_EURO_COIN_10C,
moneyItems.MONEY_EURO_COIN_1C,
moneyItems.MONEY_EURO_COIN_1C,
]
}
],
BACK_WITHOUT_CENTS: [
{
numberOfItem: 1,
minPrice: 3,
maxPrice: 9,
paid: 10,
pocket: [
moneyItems.MONEY_EURO_PAPER_5E,
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_PAPER_5E,
moneyItems.MONEY_EURO_PAPER_5E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_COIN_1E,
]
},
{
numberOfItem: 1,
minPrice: 1,
maxPrice: 19,
paid: 20,
pocket: [
moneyItems.MONEY_EURO_PAPER_10E,
moneyItems.MONEY_EURO_PAPER_5E,
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_PAPER_5E,
moneyItems.MONEY_EURO_PAPER_5E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_COIN_1E
]
},
{
numberOfItem: 2,
minPrice: 2,
maxPrice: 29,
paid: 30,
pocket: [
moneyItems.MONEY_EURO_PAPER_10E,
moneyItems.MONEY_EURO_PAPER_10E,
moneyItems.MONEY_EURO_PAPER_5E,
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_PAPER_5E,
moneyItems.MONEY_EURO_PAPER_5E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_COIN_1E
]
},
{
numberOfItem: 2,
minPrice: 2,
maxPrice: 39,
paid: 40,
pocket: [
moneyItems.MONEY_EURO_PAPER_10E,
moneyItems.MONEY_EURO_PAPER_10E,
moneyItems.MONEY_EURO_PAPER_5E,
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_PAPER_10E,
moneyItems.MONEY_EURO_PAPER_5E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_COIN_1E
]
},
{
numberOfItem: 3,
minPrice: 3,
maxPrice: 49,
paid: 50,
pocket: [
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_PAPER_10E,
moneyItems.MONEY_EURO_PAPER_10E,
moneyItems.MONEY_EURO_PAPER_5E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_PAPER_5E,
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_PAPER_20E,
moneyItems.MONEY_EURO_COIN_1E
]
},
{
numberOfItem: 3,
minPrice: 3,
maxPrice: 60,
paid: 100,
pocket: [
moneyItems.MONEY_EURO_PAPER_10E,
moneyItems.MONEY_EURO_PAPER_50E,
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_PAPER_20E,
moneyItems.MONEY_EURO_PAPER_20E,
moneyItems.MONEY_EURO_PAPER_5E,
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_COIN_1E
]
},
{
numberOfItem: 4,
minPrice: 4,
maxPrice: 70,
paid: 100,
pocket: [
moneyItems.MONEY_EURO_PAPER_10E,
moneyItems.MONEY_EURO_PAPER_50E,
moneyItems.MONEY_EURO_PAPER_5E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_PAPER_10E,
moneyItems.MONEY_EURO_PAPER_20E,
moneyItems.MONEY_EURO_PAPER_5E,
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_COIN_1E
]
},
{
numberOfItem: 4,
minPrice: 4,
maxPrice: 80,
paid: 100,
pocket: [
moneyItems.MONEY_EURO_PAPER_50E,
moneyItems.MONEY_EURO_PAPER_20E,
moneyItems.MONEY_EURO_PAPER_10E,
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_PAPER_10E,
moneyItems.MONEY_EURO_PAPER_5E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_COIN_1E
]
},
{
numberOfItem: 4,
minPrice: 4,
maxPrice: 99,
paid: 100,
pocket: [
moneyItems.MONEY_EURO_PAPER_10E,
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_PAPER_5E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_PAPER_50E,
moneyItems.MONEY_EURO_PAPER_20E,
moneyItems.MONEY_EURO_PAPER_5E,
moneyItems.MONEY_EURO_PAPER_5E
]
}
],
BACK_WITH_CENTS: [
{
numberOfItem: 1,
minPrice: 1,
maxPrice: 3,
paid: 5,
pocket: [
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_COIN_5C,
moneyItems.MONEY_EURO_COIN_2C,
moneyItems.MONEY_EURO_COIN_20C,
moneyItems.MONEY_EURO_COIN_50C,
moneyItems.MONEY_EURO_COIN_20C,
moneyItems.MONEY_EURO_COIN_10C,
moneyItems.MONEY_EURO_COIN_1C,
moneyItems.MONEY_EURO_COIN_1C
]
},
{
numberOfItem: 1,
minPrice: 1,
maxPrice: 3,
paid: 5,
pocket: [
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_COIN_5C,
moneyItems.MONEY_EURO_COIN_2C,
moneyItems.MONEY_EURO_COIN_20C,
moneyItems.MONEY_EURO_COIN_50C,
moneyItems.MONEY_EURO_COIN_20C,
moneyItems.MONEY_EURO_COIN_10C,
moneyItems.MONEY_EURO_COIN_1C,
moneyItems.MONEY_EURO_COIN_1C
]
},
{
numberOfItem: 2,
minPrice: 1,
maxPrice: 3,
paid: 5,
pocket: [
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_COIN_5C,
moneyItems.MONEY_EURO_COIN_2C,
moneyItems.MONEY_EURO_COIN_20C,
moneyItems.MONEY_EURO_COIN_50C,
moneyItems.MONEY_EURO_COIN_20C,
moneyItems.MONEY_EURO_COIN_10C,
moneyItems.MONEY_EURO_COIN_1C,
moneyItems.MONEY_EURO_COIN_1C
]
},
{
numberOfItem: 3,
minPrice: 1,
maxPrice: 3,
paid: 5,
pocket: [
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_COIN_5C,
moneyItems.MONEY_EURO_COIN_2C,
moneyItems.MONEY_EURO_COIN_20C,
moneyItems.MONEY_EURO_COIN_50C,
moneyItems.MONEY_EURO_COIN_20C,
moneyItems.MONEY_EURO_COIN_10C,
moneyItems.MONEY_EURO_COIN_1C,
moneyItems.MONEY_EURO_COIN_1C
]
},
{
numberOfItem: 4,
minPrice: 0,
maxPrice: 4,
paid: 5,
pocket: [
moneyItems.MONEY_EURO_COIN_2E,
moneyItems.MONEY_EURO_COIN_1E,
moneyItems.MONEY_EURO_COIN_5C,
moneyItems.MONEY_EURO_COIN_2C,
moneyItems.MONEY_EURO_COIN_20C,
moneyItems.MONEY_EURO_COIN_50C,
moneyItems.MONEY_EURO_COIN_20C,
moneyItems.MONEY_EURO_COIN_10C,
moneyItems.MONEY_EURO_COIN_1C,
moneyItems.MONEY_EURO_COIN_1C
]
}
]
}
var currentLevel
var numberOfLevel
var dataset
var items
var centsMode
var backMode
var priceTotal
function start(items_, datasetName) {
items = items_
switch(datasetName) {
case "WITHOUT_CENTS":
dataset = fullDataset.WITHOUT_CENTS
centsMode = false
backMode = false
break
case "WITH_CENTS":
dataset = fullDataset.WITH_CENTS
centsMode = true
backMode = false
break
case "BACK_WITHOUT_CENTS":
dataset = fullDataset.BACK_WITHOUT_CENTS
centsMode = false
backMode = true
break
case "BACK_WITH_CENTS":
dataset = fullDataset.BACK_WITH_CENTS
centsMode = true
backMode = true
break
}
currentLevel = 0
numberOfLevel = dataset.length
initLevel()
}
function stop() {
}
function initLevel() {
items.bar.level = currentLevel + 1
items.answerModel.clear()
items.pocketModel.clear()
var data = dataset[currentLevel]
var pocket = Core.shuffle(data.pocket)
for (var i in pocket)
items.pocketModel.append(pocket[i])
// fill up the store in a random way
var storeModel = new Array()
priceTotal = Math.floor(data.minPrice + Math.random() *
(data.maxPrice - data.minPrice))
var priceCounter = 0
for(var i = 0; i < data.numberOfItem; i++) {
var price
if(i < data.numberOfItem - 1)
// Calc a random price for each item based on the previous prices
price = Math.floor((centsMode ? 0 : 1) +
Math.random() *
((priceTotal - priceCounter) / data.numberOfItem))
else
// Put the remaining missing price on the last item
price = priceTotal - priceCounter
var cents = 0
if(centsMode) {
if(currentLevel === 0)
cents += 0.10 + Math.floor(Math.random() * 9) / 10
else
cents += 0.01 + Math.floor(Math.random() * 9) / 100
priceTotal += cents
price += cents
}
var locale = GCompris.ApplicationSettings.locale
if(locale == "system") {
locale = Qt.locale().name == "C" ? "en_US" : Qt.locale().name
}
var priceText = Number(price).toLocaleCurrencyString(Qt.locale(locale))
if(!centsMode) {
// Strip floating part
priceText = priceText.replace((/.00/), "")
}
storeModel.push({img: getRandomObject(price),
price: priceText})
priceCounter += price
}
items.store.model = storeModel
if(!backMode) {
items.instructions.text =
qsTr("Click on the coins or paper money at the bottom of the screen to pay." +
" If you want to remove a coin or note, click on it on the upper screen area.")
} else {
var tuxMoney
switch(data.paid) {
case 5:
tuxMoney = [moneyItems.MONEY_EURO_PAPER_5E]
break
case 10:
tuxMoney = [moneyItems.MONEY_EURO_PAPER_10E]
break
case 20:
tuxMoney = [moneyItems.MONEY_EURO_PAPER_20E]
break
case 30:
tuxMoney = [moneyItems.MONEY_EURO_PAPER_20E, moneyItems.MONEY_EURO_PAPER_10E]
break
case 40:
tuxMoney = [moneyItems.MONEY_EURO_PAPER_20E, moneyItems.MONEY_EURO_PAPER_20E]
break
case 50:
tuxMoney = [moneyItems.MONEY_EURO_PAPER_50E]
break
case 100:
tuxMoney = [moneyItems.MONEY_EURO_PAPER_50E, moneyItems.MONEY_EURO_PAPER_50E]
break
}
items.tuxMoney.model = tuxMoney
var tuxTotal = 0
for(var i=0; i < tuxMoney.length; i++)
tuxTotal += tuxMoney[i].val
var locale = GCompris.ApplicationSettings.locale
if(locale == "system") {
locale = Qt.locale().name == "C" ? "en_US" : Qt.locale().name
}
var priceText = Number(tuxTotal).toLocaleCurrencyString(Qt.locale(locale))
if(!centsMode) {
// Strip floating part
priceText = priceText.replace((/.00/), "")
}
/* The money sign is inserted based on the current locale */
items.instructions.text = qsTr("Tux just bought some items in your shop.\n" +
"He gives you %1, please give back his change.")
.arg(priceText)
}
+
+ //Keyboard reset
+ items.itemIndex = -1
+ items.selectedArea = items.pocket
+
}
// Given a price return a random object
function getRandomObject(price) {
var list
if(price < 5)
list = cheapObjects
else if(price < 10)
list = normalObjects
else
list = expensiveObjects
return list[Math.floor(Math.random() * list.length)]
}
function checkAnswer() {
var paid = 0
for (var i = 0; i < items.answerModel.count; ++i)
paid += items.answerModel.get(i).val
paid = paid.toFixed(2)
if(!backMode) {
if(paid === priceTotal.toFixed(2))
items.bonus.good("flower")
} else {
if(paid === (dataset[currentLevel].paid - priceTotal).toFixed(2))
items.bonus.good("flower")
}
}
function pay(index) {
items.audioEffects.play(url + "money1.wav")
// Add it to the anwser
items.answerModel.append(items.pocketModel.get(index))
// Remove it from the pocket
items.pocketModel.remove(index, 1)
checkAnswer()
}
function unpay(index) {
items.audioEffects.play(url + "money2.wav")
// Add it to the pocket
items.pocketModel.append(items.answerModel.get(index))
// Remove it from the Answer
items.answerModel.remove(index, 1)
checkAnswer()
}
function nextLevel() {
if(numberOfLevel <= ++currentLevel ) {
currentLevel = 0
}
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
initLevel();
}
diff --git a/src/activities/money/resource/c10c.svg b/src/activities/money/resource/c10c.svg
index 1b874eb75..e5c2f55c4 100644
--- a/src/activities/money/resource/c10c.svg
+++ b/src/activities/money/resource/c10c.svg
@@ -1,198 +1,207 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="svg699"
sodipodi:version="0.32"
width="499.99976"
height="499.99982"
xml:space="preserve"
sodipodi:docname="c10c.svg"
- inkscape:version="0.91 r13725"
+ inkscape:version="0.92.1 r15371"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
sodipodi:modified="true"
version="1.0"><metadata
id="metadata29"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs701"><linearGradient
id="linearGradient651"><stop
style="stop-color:#c78f00;stop-opacity:1;"
offset="0"
id="stop652" /><stop
style="stop-color:#ffea6b;stop-opacity:1;"
offset="1"
id="stop653" /></linearGradient><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2193"
spreadMethod="reflect"
x1="613.86011"
y1="431.21839"
x2="457.34703"
y2="678.72295"
- gradientTransform="scale(1.0254124,0.9752174)"
+ gradientTransform="matrix(0.75123508,0,0,0.75123514,109.42662,137.34723)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2195"
spreadMethod="reflect"
x1="238.54836"
y1="768.71062"
x2="505.7361"
y2="471.83698"
- gradientUnits="userSpaceOnUse" /><linearGradient
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.7000003,0,0,0.7000003,122.77543,179.40249)" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2197"
spreadMethod="reflect"
x1="286.06671"
y1="307.05434"
x2="461.8503"
y2="147.59049"
gradientTransform="scale(0.9767462,1.0238074)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2199"
spreadMethod="reflect"
x1="382.07347"
y1="269.31339"
x2="533.9103"
y2="131.57308"
gradientTransform="scale(0.8819901,1.1337996)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2201"
spreadMethod="reflect"
x1="572.36365"
y1="204.5671"
x2="631.66211"
y2="150.77391"
gradientTransform="scale(0.935494,1.0689539)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2203"
spreadMethod="reflect"
x1="763.8678"
y1="158.54136"
x2="806.98456"
y2="119.42756"
gradientTransform="scale(0.6957958,1.4372033)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2205"
spreadMethod="reflect"
x1="266.82405"
y1="418.96704"
x2="342.59325"
y2="350.23224"
gradientTransform="scale(1.6403562,0.6096237)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2207"
spreadMethod="reflect"
x1="578.59925"
y1="267.88094"
x2="622.33322"
y2="228.20723"
gradientTransform="scale(1.0295592,0.9712894)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2209"
spreadMethod="reflect"
x1="459.52562"
y1="275.18938"
x2="506.24941"
y2="232.80342"
gradientTransform="scale(1.0716088,0.9331764)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2211"
spreadMethod="reflect"
x1="898.9716"
y1="153.9525"
x2="942.47289"
y2="114.48988"
gradientTransform="scale(0.6819639,1.4663532)"
gradientUnits="userSpaceOnUse" /></defs><sodipodi:namedview
id="base"
- inkscape:zoom="0.36014217"
- inkscape:cx="-112.48363"
- inkscape:cy="526.18109"
- inkscape:window-width="1366"
- inkscape:window-height="713"
- inkscape:window-x="-2"
- inkscape:window-y="-3"
+ inkscape:zoom="0.72028434"
+ inkscape:cx="-271.44863"
+ inkscape:cy="410.94882"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
inkscape:current-layer="g2181"
showgrid="false"
inkscape:window-maximized="1" /><g
id="g2181"
- transform="translate(-159.25189,-348.00905)"><path
- transform="matrix(1.046596,0,0,1.100465,-19.0697,-60.07892)"
- sodipodi:ry="227.17661"
- sodipodi:rx="238.86951"
- sodipodi:cy="598.00891"
- sodipodi:cx="409.25195"
- d="M 648.12146,598.00891 A 238.86951,227.17661 0 0 1 409.25195,825.18552 238.86951,227.17661 0 0 1 170.38245,598.00891 238.86951,227.17661 0 0 1 409.25195,370.83231 238.86951,227.17661 0 0 1 648.12146,598.00891 Z"
+ transform="translate(-159.25189,-348.00905)"><ellipse
id="path720"
- style="fill:url(#linearGradient2193);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- sodipodi:type="arc" /><rect
- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none"
- id="rect4082"
- width="405.39548"
- height="255.45467"
- x="209.23215"
- y="525.91382"
- ry="115.40278" /><path
+ style="fill:url(#linearGradient2193);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.75123516pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ cx="409.25177"
+ cy="598.00897"
+ rx="174.99998"
+ ry="175" /><path
id="path726"
- d="M 646.7517,598.0089 C 646.7517,729.1765 540.4193,835.509 409.2517,835.509 C 278.0841,835.509 171.7518,729.1765 171.7518,598.0089 C 171.7518,466.8414 278.0841,360.5089 409.2517,360.5089 C 540.4193,360.5089 646.7517,466.8414 646.7517,598.0089 z M 263.3689,760.6925 L 350.604,760.6925 L 352.8014,747.6384 L 350.8238,747.3484 L 339.3975,746.188 C 329.2897,745.3177 327.312,744.1574 327.312,738.6457 C 327.312,734.5844 327.9712,726.752 329.0699,719.4998 L 354.9987,549.2175 L 292.3741,568.9435 L 290.3964,582.8678 L 298.5267,580.8372 C 304.0201,579.6768 309.7332,578.5165 311.2713,578.5165 C 314.7871,578.5165 316.7647,579.9669 317.4239,583.1579 L 316.545,588.0894 L 315.0068,602.5939 L 297.428,719.4998 C 292.5938,744.4475 292.1543,745.0276 279.8491,745.8979 L 267.3242,747.3484 L 265.3466,747.6384 L 263.3689,760.6925 z M 415.4261,655.9702 C 420.0405,623.7703 423.9958,602.3038 428.6102,585.1885 C 433.4444,566.0426 438.2786,558.7904 445.7496,558.7904 C 452.5614,558.7904 455.8575,564.8823 455.8575,577.6462 C 455.8575,609.5559 443.5522,692.2314 433.2247,729.6529 C 428.6102,746.4781 424.2155,752.8601 416.9642,752.8601 C 410.1524,752.8601 406.8564,746.7682 406.8564,734.2943 C 406.8564,723.2709 408.1748,708.7665 410.3722,692.5215 L 415.4261,655.9702 z M 447.7272,545.7364 C 430.5878,545.7364 416.5248,557.34 403.7801,581.4174 C 387.2999,612.4568 378.2907,654.5197 378.2907,699.1935 C 378.2907,744.1574 389.717,765.9141 413.4485,765.9141 C 436.9602,765.9141 456.0772,745.3177 469.2612,705.5755 C 478.7099,677.4368 484.423,642.0459 484.423,611.2964 C 484.423,567.7832 472.1178,545.7364 447.7272,545.7364 z M 564.8463,735.7448 C 554.9582,741.2565 547.0477,743.5772 540.2359,743.5772 C 525.7333,743.5772 518.7018,732.8439 518.7018,710.7971 C 518.7018,689.9106 522.8768,664.963 530.128,642.6261 C 536.2806,624.0603 543.5319,614.7775 551.8819,614.7775 C 558.2542,614.7775 561.3305,620.5793 561.3305,632.1828 L 561.3305,633.3432 L 561.3305,635.6639 L 560.2318,646.1071 L 559.7924,648.7179 L 577.8107,648.7179 L 583.9633,608.6856 C 573.8555,603.7543 564.8463,601.7236 554.9582,601.7236 C 515.6255,601.7236 485.5217,646.9774 485.5217,706.1557 C 485.5217,743.2871 501.5624,764.1735 530.3478,764.1735 C 539.3569,764.1735 548.3661,762.1429 561.77,756.9213 L 564.8463,735.7448 z "
- style="font-size:12px;fill:url(#linearGradient2195);fill-rule:evenodd;stroke-width:1" /><g
+ d="m 575.50181,598.00891 c 0,91.81736 -74.43272,166.25014 -166.25007,166.25014 -91.81736,0 -166.24999,-74.43278 -166.24999,-166.25014 0,-91.81729 74.43263,-166.25008 166.24999,-166.25008 91.81735,0 166.25007,74.43279 166.25007,166.25008 z"
+ style="font-size:12px;fill:url(#linearGradient2195);fill-rule:evenodd;stroke-width:0.70000029"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="sssss" /><g
style="font-size:12px;fill:url(#linearGradient2197)"
- transform="matrix(0.710214,0,0,0.665599,52.38253,308.7468)"
+ transform="matrix(0.49715,0,0,0.46591949,159.44321,395.52536)"
id="g944"><path
id="path943"
- d="M 489.2781,157.6309 C 486.7725,158.6472 483.694,159.9616 480.8916,161.4231 C 479.3419,161.0055 475.428,159.2736 475.428,155.3341 C 475.428,151.3946 478.7154,148.2011 482.7708,148.2011 C 488.0788,148.2011 490.7398,151.8121 489.2781,157.6309 z M 521.9314,154.5415 C 521.9314,158.4811 518.0176,160.213 516.6769,160.8394 C 513.0392,159.5867 510.1692,158.6899 508.0812,158.0913 C 505.5757,152.2726 509.2807,147.4085 514.5889,147.4085 C 518.644,147.4085 521.9314,150.6021 521.9314,154.5415 z M 554.0133,282.1463 C 539.7204,299.0921 519.7959,311.7673 487.7231,311.2372 C 455.0333,310.1367 444.7336,294.8341 446.4288,254.5974 C 447.4384,237.4799 453.0554,223.2215 459.4115,212.5429 C 462.707,204.534 471.5472,201.7454 476.9885,177.1512 C 485.6153,185.4841 494.4355,188.3269 497.9466,188.3677 C 504.6303,188.4997 521.1268,180.7489 526.5206,174.9439 C 532.8029,196.1211 539.725,203.2866 544.2499,208.414 C 571.8131,240.2076 557.189,277.6971 554.0133,282.1463 z M 494.2871,157.0588 C 487.7115,157.6404 481.7311,160.3453 477.7269,163.5282 C 475.279,165.2092 472.0644,157.8887 472.0644,152.4116 C 472.0644,145.0207 475.2644,139.5457 483.471,139.5457 C 490.9986,139.5457 495.5149,147.9387 494.2871,157.0588 z M 503.3984,157.4551 C 509.7709,158.1484 517.8879,161.2707 522.7624,163.7729 C 525.4762,165.4536 527.6282,158.285 527.6282,152.8079 C 527.6282,147.0021 523.8588,139.1494 514.7603,139.1494 C 505.191,139.1494 502.0372,145.9572 503.3984,157.4551 z M 504.7202,106.7478 C 474.7132,106.4276 457.1089,126.4945 461.8612,178.9302 C 463.5845,198.2381 361.0517,308.565 481.4685,323.2273 L 525.5737,324.0199 C 606.8295,319.2645 591.7019,249.1051 588.8989,241.103 C 580.6322,213.4795 553.1952,187.4526 553.0018,172.6248 C 552.814,127.3526 535.8651,106.2749 504.7202,106.7478 z M 529.3964,169.2447 C 529.7524,177.204 506.4211,188.5796 497.5232,188.5796 C 490.247,188.5796 473.2299,177.6226 472.7098,170.2413 C 472.4321,166.698 484.8286,156.8974 498.0721,157.1776 C 508.6449,157.1776 529.106,164.0661 529.3964,169.2447 z M 505.6319,158.6713 C 504.8923,159.1122 502.5108,159.8841 502.2685,159.8142 C 501.7591,159.7069 502.9358,158.8886 503.1344,158.3848 C 503.3119,157.9112 506.3718,158.2303 505.6319,158.6713 z M 491.2411,158.3369 C 491.2346,158.7713 491.7574,159.5856 492.1907,159.5931 C 492.5879,159.0685 492.9824,158.6462 493.4274,158.2207 C 493.8848,157.8292 491.2476,157.996 491.2411,158.3369 z M 475.86,171.0084 C 475.1974,169.8919 481.8043,180.5114 494.4183,180.9245 C 505.2062,181.3048 518.8716,172.4247 527.1629,168.9206 C 494.2345,184.859 489.641,183.0493 475.86,171.0084 z M 532.9812,126.1648 C 531.3254,129.0911 525.7228,129.7142 520.4675,127.5566 C 515.2121,125.3989 512.294,121.2776 513.9498,118.3513 C 515.6056,115.425 521.2082,114.8019 526.4636,116.9596 C 531.7189,119.1172 534.6369,123.2386 532.9812,126.1648 z "
- style="font-size:12px;fill:url(#linearGradient2199);fill-rule:evenodd" /><path
+ d="m 489.2781,157.6309 c -2.5056,1.0163 -5.5841,2.3307 -8.3865,3.7922 -1.5497,-0.4176 -5.4636,-2.1495 -5.4636,-6.089 0,-3.9395 3.2874,-7.133 7.3428,-7.133 5.308,0 7.969,3.611 6.5073,9.4298 z m 32.6533,-3.0894 c 0,3.9396 -3.9138,5.6715 -5.2545,6.2979 -3.6377,-1.2527 -6.5077,-2.1495 -8.5957,-2.7481 -2.5055,-5.8187 1.1995,-10.6828 6.5077,-10.6828 4.0551,0 7.3425,3.1936 7.3425,7.133 z m 32.0819,127.6048 c -14.2929,16.9458 -34.2174,29.621 -66.2902,29.0909 -32.6898,-1.1005 -42.9895,-16.4031 -41.2943,-56.6398 1.0096,-17.1175 6.6266,-31.3759 12.9827,-42.0545 3.2955,-8.0089 12.1357,-10.7975 17.577,-35.3917 8.6268,8.3329 17.447,11.1757 20.9581,11.2165 6.6837,0.132 23.1802,-7.6188 28.574,-13.4238 6.2823,21.1772 13.2044,28.3427 17.7293,33.4701 27.5632,31.7936 12.9391,69.2831 9.7634,73.7323 z M 494.2871,157.0588 c -6.5756,0.5816 -12.556,3.2865 -16.5602,6.4694 -2.4479,1.681 -5.6625,-5.6395 -5.6625,-11.1166 0,-7.3909 3.2,-12.8659 11.4066,-12.8659 7.5276,0 12.0439,8.393 10.8161,17.5131 z m 9.1113,0.3963 c 6.3725,0.6933 14.4895,3.8156 19.364,6.3178 2.7138,1.6807 4.8658,-5.4879 4.8658,-10.965 0,-5.8058 -3.7694,-13.6585 -12.8679,-13.6585 -9.5693,0 -12.7231,6.8078 -11.3619,18.3057 z m 1.3218,-50.7073 c -30.007,-0.3202 -47.6113,19.7467 -42.859,72.1824 1.7233,19.3079 -100.8095,129.6348 19.6073,144.2971 l 44.1052,0.7926 c 81.2558,-4.7554 66.1282,-74.9148 63.3252,-82.9169 -8.2667,-27.6235 -35.7037,-53.6504 -35.8971,-68.4782 -0.1878,-45.2722 -17.1367,-66.3499 -48.2816,-65.877 z m 24.6762,62.4969 c 0.356,7.9593 -22.9753,19.3349 -31.8732,19.3349 -7.2762,0 -24.2933,-10.957 -24.8134,-18.3383 -0.2777,-3.5433 12.1188,-13.3439 25.3623,-13.0637 10.5728,0 31.0339,6.8885 31.3243,12.0671 z m -23.7645,-10.5734 c -0.7396,0.4409 -3.1211,1.2128 -3.3634,1.1429 -0.5094,-0.1073 0.6673,-0.9256 0.8659,-1.4294 0.1775,-0.4736 3.2374,-0.1545 2.4975,0.2865 z m -14.3908,-0.3344 c -0.007,0.4344 0.5163,1.2487 0.9496,1.2562 0.3972,-0.5246 0.7917,-0.9469 1.2367,-1.3724 0.4574,-0.3915 -2.1798,-0.2247 -2.1863,0.1162 z M 475.86,171.0084 c -0.6626,-1.1165 5.9443,9.503 18.5583,9.9161 10.7879,0.3803 24.4533,-8.4998 32.7446,-12.0039 -32.9284,15.9384 -37.5219,14.1287 -51.3029,2.0878 z m 57.1212,-44.8436 c -1.6558,2.9263 -7.2584,3.5494 -12.5137,1.3918 -5.2554,-2.1577 -8.1735,-6.279 -6.5177,-9.2053 1.6558,-2.9263 7.2584,-3.5494 12.5138,-1.3917 5.2553,2.1576 8.1733,6.279 6.5176,9.2052 z"
+ style="font-size:12px;fill:url(#linearGradient2199);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /><path
transform="matrix(1.381431,0,0,1.342002,-335.1481,-21.47379)"
sodipodi:nodetypes="cccccccccccccccccccccc"
id="path871"
- d="M 594.8524,209.0117 C 594.8524,220.1016 597.3741,225.5481 596.0694,225.5481 C 594.7647,225.5481 591.5893,219.8928 591.5893,208.8029 C 591.5893,197.7133 595.8087,185.5974 597.1134,185.5974 C 598.4181,185.5974 594.8524,197.9221 594.8524,209.0117 z M 632.27,169.5802 C 636.4462,173.2967 639.9597,177.6751 641.0037,183.062 C 633.8452,176.8398 621.8843,173.9586 614.9343,172.3301 C 621.0488,172.1213 630.1226,172.5034 632.27,169.5802 z M 595.6275,172.1593 C 597.9116,174.2791 597.2725,175.7726 598.0951,178.5188 C 598.4549,175.911 602.5729,173.9295 604.8118,171.9481 C 601.9592,172.4361 598.4801,172.5065 595.6275,172.1593 z M 578.9845,168.302 C 576.6727,170.9576 573.7897,175.239 570.9888,182.7921 C 576.8947,176.1524 582.6886,175.629 589.2209,172.9565 C 583.3151,172.7478 581.1318,171.2251 578.9845,168.302 z M 624.5364,145.5447 C 621.5836,154.254 608.0056,162.0592 600.9178,162.0592 C 596.7828,162.0592 588.4029,155.7413 586.9264,147.0322 C 592.4305,152.4557 598.446,156.1755 603.0832,156.3597 C 608.2112,156.4881 619.7769,150.57 624.5364,145.5447 z "
- style="font-size:12px;fill:url(#linearGradient2201);fill-rule:evenodd" /><path
+ d="m 594.8524,209.0117 c 0,11.0899 2.5217,16.5364 1.217,16.5364 -1.3047,0 -4.4801,-5.6553 -4.4801,-16.7452 0,-11.0896 4.2194,-23.2055 5.5241,-23.2055 1.3047,0 -2.261,12.3247 -2.261,23.4143 z M 632.27,169.5802 c 4.1762,3.7165 7.6897,8.0949 8.7337,13.4818 -7.1585,-6.2222 -19.1194,-9.1034 -26.0694,-10.7319 6.1145,-0.2088 15.1883,0.1733 17.3357,-2.7499 z m -36.6425,2.5791 c 2.2841,2.1198 1.645,3.6133 2.4676,6.3595 0.3598,-2.6078 4.4778,-4.5893 6.7167,-6.5707 -2.8526,0.488 -6.3317,0.5584 -9.1843,0.2112 z m -16.643,-3.8573 c -2.3118,2.6556 -5.1948,6.937 -7.9957,14.4901 5.9059,-6.6397 11.6998,-7.1631 18.2321,-9.8356 -5.9058,-0.2087 -8.0891,-1.7314 -10.2364,-4.6545 z m 45.5519,-22.7573 c -2.9528,8.7093 -16.5308,16.5145 -23.6186,16.5145 -4.135,0 -12.5149,-6.3179 -13.9914,-15.027 5.5041,5.4235 11.5196,9.1433 16.1568,9.3275 5.128,0.1284 16.6937,-5.7897 21.4532,-10.815 z"
+ style="font-size:12px;fill:url(#linearGradient2201);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /><path
transform="matrix(1.381431,0,0,1.342002,-335.1483,-21.47379)"
sodipodi:nodetypes="csccc"
id="path758"
- d="M 566.1781,204.0047 C 566.1781,224.5982 593.4836,225.0052 587.8079,232.522 C 582.6399,239.91 550.7196,226.5353 550.7196,205.9419 C 552.8076,190.3594 555.5661,185.5046 574.6452,156.366 C 587.5403,159.1975 566.1781,183.4112 566.1781,204.0047 z "
- style="font-size:12px;fill:url(#linearGradient2203);fill-rule:evenodd" /><g
+ d="m 566.1781,204.0047 c 0,20.5935 27.3055,21.0005 21.6298,28.5173 -5.168,7.388 -37.0883,-5.9867 -37.0883,-26.5801 2.088,-15.5825 4.8465,-20.4373 23.9256,-49.5759 12.8951,2.8315 -8.4671,27.0452 -8.4671,47.6387 z"
+ style="font-size:12px;fill:url(#linearGradient2203);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /><g
style="font-size:12px;fill:url(#linearGradient2205)"
transform="matrix(1.381431,0,0,1.342002,-325.2191,-15.60249)"
id="g1065"><path
transform="translate(-7.1875,-4.375031)"
sodipodi:nodetypes="csssscsss"
id="path842"
- d="M 662.6023,249.8415 C 652.9563,254.7202 643.0236,269.4045 630.2927,263.3619 C 621.3526,259.2146 625.6634,249.1638 625.1563,243.5311 C 624.668,230.5505 623.5071,211.1312 631.9468,211.184 C 642.1547,211.246 638.0258,215.2545 645.4196,217.3441 C 653.505,219.306 658.7389,209.0467 664.847,213.6095 C 669.4787,219.944 664.6217,223.322 670.205,229.4906 C 673.1685,233.0602 677.7506,232.9839 680.3539,235.8973 C 685.7736,241.3478 668.3201,246.6544 662.6023,249.8415 z "
- style="font-size:12px;fill:url(#linearGradient2207);fill-rule:evenodd" /><path
+ d="m 662.6023,249.8415 c -9.646,4.8787 -19.5787,19.563 -32.3096,13.5204 -8.9401,-4.1473 -4.6293,-14.1981 -5.1364,-19.8308 -0.4883,-12.9806 -1.6492,-32.3999 6.7905,-32.3471 10.2079,0.062 6.079,4.0705 13.4728,6.1601 8.0854,1.9619 13.3193,-8.2974 19.4274,-3.7346 4.6317,6.3345 -0.2253,9.7125 5.358,15.8811 2.9635,3.5696 7.5456,3.4933 10.1489,6.4067 5.4197,5.4505 -12.0338,10.7571 -17.7516,13.9442 z"
+ style="font-size:12px;fill:url(#linearGradient2207);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /><path
transform="translate(-7.1875,-4.375031)"
sodipodi:nodetypes="cssssssss"
id="path843"
- d="M 550.8908,255.4014 C 562.5947,256.6532 574.367,267.8037 584.6032,256.5396 C 591.8317,248.7246 584.743,239.3914 580.5155,234.7902 C 570.7341,224.8274 565.2408,206.427 556.2229,206.4986 C 548.5882,206.8092 550.0632,210.9825 544.7009,215.234 C 537.4953,220.6488 532.9891,216.239 528.6392,223.1506 C 525.9871,226.8955 526.7585,231.7788 527.8864,236.9511 C 528.6785,241.8714 527.0976,242.9494 525.4163,244.55 C 519.9332,250.7329 540.853,254.0325 550.8908,255.4014 z "
- style="font-size:12px;fill:url(#linearGradient2209);fill-rule:evenodd" /></g><path
+ d="m 550.8908,255.4014 c 11.7039,1.2518 23.4762,12.4023 33.7124,1.1382 7.2285,-7.815 0.1398,-17.1482 -4.0877,-21.7494 -9.7814,-9.9628 -15.2747,-28.3632 -24.2926,-28.2916 -7.6347,0.3106 -6.1597,4.4839 -11.522,8.7354 -7.2056,5.4148 -11.7118,1.005 -16.0617,7.9166 -2.6521,3.7449 -1.8807,8.6282 -0.7528,13.8005 0.7921,4.9203 -0.7888,5.9983 -2.4701,7.5989 -5.4831,6.1829 15.4367,9.4825 25.4745,10.8514 z"
+ style="font-size:12px;fill:url(#linearGradient2209);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /></g><path
transform="matrix(1.381431,0,0,1.342002,-335.1483,-21.47379)"
sodipodi:nodetypes="cscss"
id="path857"
- d="M 649.8842,196.2501 C 649.4318,220.8146 631.991,220.9147 636.6064,229.3612 C 642.8768,241.2543 669.5186,218.7807 669.5186,198.1874 C 669.5186,178.0113 641.3187,150.3852 638.2491,152.2475 C 619.1027,166.4884 650.6787,175.7879 649.8842,196.2501 z "
- style="font-size:12px;fill:url(#linearGradient2211);fill-rule:evenodd" /></g></g></svg>
\ No newline at end of file
+ d="m 649.8842,196.2501 c -0.4524,24.5645 -17.8932,24.6646 -13.2778,33.1111 6.2704,11.8931 32.9122,-10.5805 32.9122,-31.1738 0,-20.1761 -28.1999,-47.8022 -31.2695,-45.9399 -19.1464,14.2409 12.4296,23.5404 11.6351,44.0026 z"
+ style="font-size:12px;fill:url(#linearGradient2211);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /></g><path
+ style="opacity:1;vector-effect:none;fill:#fcfcfc;fill-opacity:1;stroke:none;stroke-width:11.66666508;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ d="m 368.94041,563.85444 -50.12299,13.8086 -1.38313,9.74804 5.68977,-1.42187 c 3.84538,-0.81228 7.84423,-1.62468 8.92091,-1.62468 2.46106,0 3.84518,1.01564 4.30662,3.24934 l -0.61522,3.45216 -1.07552,10.15136 -15.35163,79.50194 c -3.38394,17.46341 -3.69332,17.86833 -12.30697,18.47754 l -8.76594,1.01629 -1.38542,0.20278 -1.38314,9.13738 h 65.72982 l 1.53809,-9.13738 -1.38315,-0.20278 -7.99805,-0.81121 c -7.07546,-0.60921 -8.46061,-1.42143 -8.46061,-5.27962 0,-2.84291 0.46139,-8.32645 1.23046,-13.403 z"
+ id="path854"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccsccccccccccccscc" /><path
+ style="opacity:1;vector-effect:none;fill:#fcfcfc;fill-opacity:1;stroke:none;stroke-width:9.99999905;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ d="m 441.44835,564.1415 c -15.88307,0 -28.91425,8.00494 -40.72461,24.61719 -15.27225,21.41574 -23.62109,50.4371 -23.62109,81.25975 0,31.02282 10.58814,46.03515 32.58008,46.03515 21.78828,0 39.50494,-14.21068 51.72266,-41.63086 8.75604,-19.41429 14.04881,-43.83322 14.04881,-65.04881 0,-30.02207 -11.40304,-45.23242 -34.00585,-45.23242 z m -1.83202,9.00586 c 6.31244,0 9.36717,4.20335 9.36717,13.00977 0,22.01624 -11.40407,79.05791 -20.9746,104.87694 -4.27623,11.60852 -8.34862,16.01171 -15.06836,16.01171 -6.31244,0 -9.36718,-4.20232 -9.36718,-12.80858 0,-7.6057 1.22152,-17.61208 3.25781,-28.82032 l 4.68358,-25.21876 c 4.27616,-22.21632 7.94253,-37.02718 12.21876,-48.83591 4.47979,-13.2097 8.95943,-18.21485 15.88282,-18.21485 z m 107.10935,47.63671 v 3.00196 z m -29.98437,35.3418 c -22.35808,0 -39.46873,16.98309 -39.46873,39.1914 0,13.93467 9.11782,21.77343 25.48045,21.77343 5.12109,0 10.24204,-0.7631 17.86132,-2.72265 l 1.74805,-7.94727 c -5.62075,2.06846 -10.11813,2.93945 -13.99023,2.93945 -8.24375,0 -12.24024,-4.02703 -12.24024,-12.30077 0,-7.83821 2.37424,-17.20142 6.4961,-25.58398 3.49735,-6.96734 7.61886,-10.45116 12.36523,-10.45116 3.62225,0 5.3711,2.17861 5.3711,6.53318 v 0.43555 0.87109 l -0.62501,3.91798 -0.24999,0.98046 h 10.24219 l 3.49804,-15.02343 c -5.74562,-1.85065 -10.86751,-2.61328 -16.48828,-2.61328 z"
+ id="path860"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="scsscsssscsscccscccsssccsscsscccccas" /></g></svg>
\ No newline at end of file
diff --git a/src/activities/money/resource/c1c.svg b/src/activities/money/resource/c1c.svg
index 663304fa4..27dadcd88 100644
--- a/src/activities/money/resource/c1c.svg
+++ b/src/activities/money/resource/c1c.svg
@@ -1,193 +1,201 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="svg699"
sodipodi:version="0.32"
width="503.34711"
height="500.98511"
xml:space="preserve"
sodipodi:docname="c1c.svg"
- inkscape:version="0.91 r13725"
+ inkscape:version="0.92.1 r15371"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
sodipodi:modified="true"
version="1.0"><metadata
id="metadata29"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs701"><linearGradient
id="linearGradient651"><stop
style="stop-color:#c73500;stop-opacity:1;"
offset="0"
id="stop652" /><stop
style="stop-color:#ffb76b;stop-opacity:1;"
offset="1"
id="stop653" /></linearGradient><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2193"
- gradientTransform="scale(1.0023546,0.9976509)"
+ gradientTransform="matrix(0.60023018,0,0,0.59741351,159.63844,209.72636)"
spreadMethod="pad"
x1="673.50358"
y1="300.07902"
x2="225.41876"
y2="504.08385"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2195"
x1="164.09622"
y1="520.24765"
x2="639.09577"
y2="520.24765"
- gradientUnits="userSpaceOnUse" /><linearGradient
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5988202,0,0,0.5988202,161.11219,208.71288)" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2197"
spreadMethod="reflect"
x1="286.06671"
y1="307.05434"
x2="461.8503"
y2="147.59049"
gradientTransform="scale(0.9767462,1.0238074)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2199"
spreadMethod="reflect"
x1="382.07347"
y1="269.31339"
x2="533.9103"
y2="131.57308"
gradientTransform="scale(0.8819901,1.1337996)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2201"
spreadMethod="reflect"
x1="572.36365"
y1="204.5671"
x2="631.66211"
y2="150.77391"
gradientTransform="scale(0.935494,1.0689539)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2203"
spreadMethod="reflect"
x1="763.8678"
y1="158.54136"
x2="806.98456"
y2="119.42756"
gradientTransform="scale(0.6957958,1.4372033)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2205"
spreadMethod="reflect"
x1="266.82405"
y1="418.96704"
x2="342.59325"
y2="350.23224"
gradientTransform="scale(1.6403562,0.6096237)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2207"
spreadMethod="reflect"
x1="578.59925"
y1="267.88094"
x2="622.33322"
y2="228.20723"
gradientTransform="scale(1.0295592,0.9712894)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2209"
spreadMethod="reflect"
x1="459.52562"
y1="275.18938"
x2="506.24941"
y2="232.80342"
gradientTransform="scale(1.0716088,0.9331764)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2211"
spreadMethod="reflect"
x1="898.9716"
y1="153.9525"
x2="942.47289"
y2="114.48988"
gradientTransform="scale(0.6819639,1.4663532)"
gradientUnits="userSpaceOnUse" /></defs><sodipodi:namedview
id="base"
inkscape:zoom="0.36014217"
- inkscape:cx="-597.0145"
+ inkscape:cx="-1189.8359"
inkscape:cy="526.18109"
- inkscape:window-width="1366"
- inkscape:window-height="713"
- inkscape:window-x="-2"
- inkscape:window-y="-3"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
inkscape:current-layer="g2181"
showgrid="false"
inkscape:window-maximized="1" /><g
id="g2181"
transform="translate(-149.92241,-269.75517)"><path
- transform="translate(-2.46109,1.692474)"
sodipodi:nodetypes="ccccccc"
id="path687"
- d="M 655.7306,518.5551 C 655.7306,656.8984 543.0531,769.0478 404.0571,769.0478 C 265.0618,769.0478 152.3835,656.8984 152.3835,518.5551 C 152.3835,380.2119 265.0618,268.0627 404.0571,268.0627 C 543.0531,268.0627 655.7306,380.2119 655.7306,518.5551 z M 396.9986,636.0575 L 396.9986,636.0575 z "
- style="font-size:48px;font-style:italic;font-weight:bold;fill:url(#linearGradient2193);fill-opacity:1;stroke-width:1;font-family:Luxi Serif" /><rect
- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.50000000000000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 552.30317,520.24763 c 0,82.84277 -67.47356,150.00009 -150.70717,150.00009 -83.2332,0 -150.70724,-67.15732 -150.70724,-150.00009 0,-82.8427 67.47404,-149.99991 150.70724,-149.99991 83.23361,0 150.70717,67.15721 150.70717,149.99991 z m -154.93395,70.36282 z"
+ style="font-style:italic;font-weight:bold;font-size:48px;font-family:'Luxi Serif';fill:url(#linearGradient2193);fill-opacity:1;stroke-width:0.59882021"
+ inkscape:connector-curvature="0" /><rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.09587073;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect5648"
- width="310.98831"
- height="358.19186"
- x="197.12599"
- y="340.35468"
- ry="109.32895" /><path
+ width="186.22609"
+ height="214.49252"
+ x="279.15521"
+ y="412.52411"
+ ry="65.468384" /><path
id="path752"
- d="M 214.0922,647.2856 L 379.4561,647.2856 L 383.6214,630.0712 L 379.8726,629.6887 L 358.2129,628.1585 C 339.0523,627.0109 335.3035,625.4807 335.3035,618.2124 C 335.3035,612.8568 336.5531,602.5282 338.6358,592.9646 L 387.7868,368.4123 L 269.0747,394.4251 L 265.3258,412.7872 L 280.7376,410.1094 C 291.1509,408.5792 301.9808,407.049 304.8966,407.049 C 311.5611,407.049 315.3099,408.9618 316.5595,413.1697 L 314.8934,419.6729 L 311.9776,438.8001 L 278.6549,592.9646 C 269.4912,625.8633 268.6581,626.6283 245.3322,627.776 L 221.5898,629.6887 L 217.841,630.0712 L 214.0922,647.2856 z M 390.9698,631.2727 L 390.9698,631.2727 z M 639.0957,520.2476 C 639.0957,651.4152 532.7637,757.7475 401.5958,757.7475 C 270.4286,757.7475 164.0962,651.4152 164.0962,520.2476 C 164.0962,389.0801 270.4286,282.7479 401.5958,282.7479 C 532.7637,282.7479 639.0957,389.0801 639.0957,520.2476 z M 254.0036,467.903 L 254.0036,467.903 z M 462.5704,635.2231 C 455.7123,637.8353 450.2259,638.9352 445.5015,638.9352 C 435.443,638.9352 430.5661,633.8482 430.5661,623.3992 C 430.5661,613.5002 433.4618,601.6763 438.491,591.0898 C 442.7582,582.2907 447.7875,577.8911 453.5787,577.8911 C 457.9983,577.8911 460.132,580.6408 460.132,586.1403 L 460.132,586.6903 L 460.132,587.7902 L 459.37,592.7397 L 459.0652,593.9771 L 471.562,593.9771 L 475.8293,575.0039 C 468.8188,572.6666 462.5704,571.7042 455.7123,571.7042 C 428.4325,571.7042 407.5536,593.1521 407.5536,621.1994 C 407.5536,638.7977 418.6789,648.6968 438.6434,648.6968 C 444.8919,648.6968 451.1403,647.7344 460.4368,645.2596 L 462.5704,635.2231 z "
- style="font-size:48px;font-style:italic;font-weight:bold;fill:url(#linearGradient2195);stroke-width:1;font-family:Luxi Serif" /><g
+ d="m 289.31493,596.32057 h 99.02324 l 2.49427,-10.30833 -2.24486,-0.22905 -12.97027,-0.91631 c -11.47375,-0.68721 -13.71861,-1.60352 -13.71861,-5.95593 0,-3.20704 0.74829,-9.39201 1.99545,-15.11889 l 29.43261,-134.46646 -71.0872,15.57699 -2.24492,10.9956 9.2289,-1.60352 c 6.23569,-0.91631 12.72086,-1.83263 14.4669,-1.83263 3.99083,0 6.23569,1.14542 6.98398,3.6652 l -0.9977,3.89425 -1.74604,11.45375 -19.9543,92.31682 c -5.48741,19.7004 -5.98629,20.1585 -19.95431,20.84577 l -14.21743,1.14536 -2.24486,0.22905 z m 105.91788,-9.58885 z m 148.5828,-66.48407 c 0,78.54581 -63.67375,142.21974 -142.21974,142.21974 -78.54557,0 -142.21956,-63.67393 -142.21956,-142.21974 0,-78.54575 63.67399,-142.21962 142.21956,-142.21962 78.54599,0 142.21974,63.67387 142.21974,142.21962 z m -230.60093,-31.345 z M 438.10869,589.0973 c -4.10677,1.56424 -7.39213,2.22288 -10.2212,2.22288 -6.02323,0 -8.94362,-3.0462 -8.94362,-9.30327 0,-5.92772 1.73401,-13.00811 4.74559,-19.34752 2.55529,-5.26908 5.56693,-7.90365 9.03482,-7.90365 2.64655,0 3.92425,1.64658 3.92425,4.93979 v 0.32935 0.65864 l -0.4563,2.96386 -0.18252,0.74098 h 7.48334 l 2.55534,-11.36153 c -4.19803,-1.39962 -7.9397,-1.97593 -12.04647,-1.97593 -16.33569,0 -28.8384,12.84344 -28.8384,29.63873 0,10.53821 6.66206,16.466 18.6172,16.466 3.74173,0 7.4834,-0.57631 13.05033,-2.05827 z"
+ style="font-style:italic;font-weight:bold;font-size:48px;font-family:'Luxi Serif';fill:url(#linearGradient2195);stroke-width:0.59882021"
+ inkscape:connector-curvature="0" /><g
style="font-size:12px;fill:url(#linearGradient2197)"
- transform="matrix(1.081439,0,0,1.058679,-45.76,217.3552)"
+ transform="matrix(0.64758752,0,0,0.63395838,133.71018,338.86956)"
id="g944"><path
id="path943"
- d="M 489.2781,157.6309 C 486.7725,158.6472 483.694,159.9616 480.8916,161.4231 C 479.3419,161.0055 475.428,159.2736 475.428,155.3341 C 475.428,151.3946 478.7154,148.2011 482.7708,148.2011 C 488.0788,148.2011 490.7398,151.8121 489.2781,157.6309 z M 521.9314,154.5415 C 521.9314,158.4811 518.0176,160.213 516.6769,160.8394 C 513.0392,159.5867 510.1692,158.6899 508.0812,158.0913 C 505.5757,152.2726 509.2807,147.4085 514.5889,147.4085 C 518.644,147.4085 521.9314,150.6021 521.9314,154.5415 z M 554.0133,282.1463 C 539.7204,299.0921 519.7959,311.7673 487.7231,311.2372 C 455.0333,310.1367 444.7336,294.8341 446.4288,254.5974 C 447.4384,237.4799 453.0554,223.2215 459.4115,212.5429 C 462.707,204.534 471.5472,201.7454 476.9885,177.1512 C 485.6153,185.4841 494.4355,188.3269 497.9466,188.3677 C 504.6303,188.4997 521.1268,180.7489 526.5206,174.9439 C 532.8029,196.1211 539.725,203.2866 544.2499,208.414 C 571.8131,240.2076 557.189,277.6971 554.0133,282.1463 z M 494.2871,157.0588 C 487.7115,157.6404 481.7311,160.3453 477.7269,163.5282 C 475.279,165.2092 472.0644,157.8887 472.0644,152.4116 C 472.0644,145.0207 475.2644,139.5457 483.471,139.5457 C 490.9986,139.5457 495.5149,147.9387 494.2871,157.0588 z M 503.3984,157.4551 C 509.7709,158.1484 517.8879,161.2707 522.7624,163.7729 C 525.4762,165.4536 527.6282,158.285 527.6282,152.8079 C 527.6282,147.0021 523.8588,139.1494 514.7603,139.1494 C 505.191,139.1494 502.0372,145.9572 503.3984,157.4551 z M 504.7202,106.7478 C 474.7132,106.4276 457.1089,126.4945 461.8612,178.9302 C 463.5845,198.2381 361.0517,308.565 481.4685,323.2273 L 525.5737,324.0199 C 606.8295,319.2645 591.7019,249.1051 588.8989,241.103 C 580.6322,213.4795 553.1952,187.4526 553.0018,172.6248 C 552.814,127.3526 535.8651,106.2749 504.7202,106.7478 z M 529.3964,169.2447 C 529.7524,177.204 506.4211,188.5796 497.5232,188.5796 C 490.247,188.5796 473.2299,177.6226 472.7098,170.2413 C 472.4321,166.698 484.8286,156.8974 498.0721,157.1776 C 508.6449,157.1776 529.106,164.0661 529.3964,169.2447 z M 505.6319,158.6713 C 504.8923,159.1122 502.5108,159.8841 502.2685,159.8142 C 501.7591,159.7069 502.9358,158.8886 503.1344,158.3848 C 503.3119,157.9112 506.3718,158.2303 505.6319,158.6713 z M 491.2411,158.3369 C 491.2346,158.7713 491.7574,159.5856 492.1907,159.5931 C 492.5879,159.0685 492.9824,158.6462 493.4274,158.2207 C 493.8848,157.8292 491.2476,157.996 491.2411,158.3369 z M 475.86,171.0084 C 475.1974,169.8919 481.8043,180.5114 494.4183,180.9245 C 505.2062,181.3048 518.8716,172.4247 527.1629,168.9206 C 494.2345,184.859 489.641,183.0493 475.86,171.0084 z M 532.9812,126.1648 C 531.3254,129.0911 525.7228,129.7142 520.4675,127.5566 C 515.2121,125.3989 512.294,121.2776 513.9498,118.3513 C 515.6056,115.425 521.2082,114.8019 526.4636,116.9596 C 531.7189,119.1172 534.6369,123.2386 532.9812,126.1648 z "
- style="font-size:12px;fill:url(#linearGradient2199);fill-rule:evenodd" /><path
+ d="m 489.2781,157.6309 c -2.5056,1.0163 -5.5841,2.3307 -8.3865,3.7922 -1.5497,-0.4176 -5.4636,-2.1495 -5.4636,-6.089 0,-3.9395 3.2874,-7.133 7.3428,-7.133 5.308,0 7.969,3.611 6.5073,9.4298 z m 32.6533,-3.0894 c 0,3.9396 -3.9138,5.6715 -5.2545,6.2979 -3.6377,-1.2527 -6.5077,-2.1495 -8.5957,-2.7481 -2.5055,-5.8187 1.1995,-10.6828 6.5077,-10.6828 4.0551,0 7.3425,3.1936 7.3425,7.133 z m 32.0819,127.6048 c -14.2929,16.9458 -34.2174,29.621 -66.2902,29.0909 -32.6898,-1.1005 -42.9895,-16.4031 -41.2943,-56.6398 1.0096,-17.1175 6.6266,-31.3759 12.9827,-42.0545 3.2955,-8.0089 12.1357,-10.7975 17.577,-35.3917 8.6268,8.3329 17.447,11.1757 20.9581,11.2165 6.6837,0.132 23.1802,-7.6188 28.574,-13.4238 6.2823,21.1772 13.2044,28.3427 17.7293,33.4701 27.5632,31.7936 12.9391,69.2831 9.7634,73.7323 z M 494.2871,157.0588 c -6.5756,0.5816 -12.556,3.2865 -16.5602,6.4694 -2.4479,1.681 -5.6625,-5.6395 -5.6625,-11.1166 0,-7.3909 3.2,-12.8659 11.4066,-12.8659 7.5276,0 12.0439,8.393 10.8161,17.5131 z m 9.1113,0.3963 c 6.3725,0.6933 14.4895,3.8156 19.364,6.3178 2.7138,1.6807 4.8658,-5.4879 4.8658,-10.965 0,-5.8058 -3.7694,-13.6585 -12.8679,-13.6585 -9.5693,0 -12.7231,6.8078 -11.3619,18.3057 z m 1.3218,-50.7073 c -30.007,-0.3202 -47.6113,19.7467 -42.859,72.1824 1.7233,19.3079 -100.8095,129.6348 19.6073,144.2971 l 44.1052,0.7926 c 81.2558,-4.7554 66.1282,-74.9148 63.3252,-82.9169 -8.2667,-27.6235 -35.7037,-53.6504 -35.8971,-68.4782 -0.1878,-45.2722 -17.1367,-66.3499 -48.2816,-65.877 z m 24.6762,62.4969 c 0.356,7.9593 -22.9753,19.3349 -31.8732,19.3349 -7.2762,0 -24.2933,-10.957 -24.8134,-18.3383 -0.2777,-3.5433 12.1188,-13.3439 25.3623,-13.0637 10.5728,0 31.0339,6.8885 31.3243,12.0671 z m -23.7645,-10.5734 c -0.7396,0.4409 -3.1211,1.2128 -3.3634,1.1429 -0.5094,-0.1073 0.6673,-0.9256 0.8659,-1.4294 0.1775,-0.4736 3.2374,-0.1545 2.4975,0.2865 z m -14.3908,-0.3344 c -0.007,0.4344 0.5163,1.2487 0.9496,1.2562 0.3972,-0.5246 0.7917,-0.9469 1.2367,-1.3724 0.4574,-0.3915 -2.1798,-0.2247 -2.1863,0.1162 z M 475.86,171.0084 c -0.6626,-1.1165 5.9443,9.503 18.5583,9.9161 10.7879,0.3803 24.4533,-8.4998 32.7446,-12.0039 -32.9284,15.9384 -37.5219,14.1287 -51.3029,2.0878 z m 57.1212,-44.8436 c -1.6558,2.9263 -7.2584,3.5494 -12.5137,1.3918 -5.2554,-2.1577 -8.1735,-6.279 -6.5177,-9.2053 1.6558,-2.9263 7.2584,-3.5494 12.5138,-1.3917 5.2553,2.1576 8.1733,6.279 6.5176,9.2052 z"
+ style="font-size:12px;fill:url(#linearGradient2199);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /><path
transform="matrix(1.381431,0,0,1.342002,-335.1481,-21.47379)"
sodipodi:nodetypes="cccccccccccccccccccccc"
id="path871"
- d="M 594.8524,209.0117 C 594.8524,220.1016 597.3741,225.5481 596.0694,225.5481 C 594.7647,225.5481 591.5893,219.8928 591.5893,208.8029 C 591.5893,197.7133 595.8087,185.5974 597.1134,185.5974 C 598.4181,185.5974 594.8524,197.9221 594.8524,209.0117 z M 632.27,169.5802 C 636.4462,173.2967 639.9597,177.6751 641.0037,183.062 C 633.8452,176.8398 621.8843,173.9586 614.9343,172.3301 C 621.0488,172.1213 630.1226,172.5034 632.27,169.5802 z M 595.6275,172.1593 C 597.9116,174.2791 597.2725,175.7726 598.0951,178.5188 C 598.4549,175.911 602.5729,173.9295 604.8118,171.9481 C 601.9592,172.4361 598.4801,172.5065 595.6275,172.1593 z M 578.9845,168.302 C 576.6727,170.9576 573.7897,175.239 570.9888,182.7921 C 576.8947,176.1524 582.6886,175.629 589.2209,172.9565 C 583.3151,172.7478 581.1318,171.2251 578.9845,168.302 z M 624.5364,145.5447 C 621.5836,154.254 608.0056,162.0592 600.9178,162.0592 C 596.7828,162.0592 588.4029,155.7413 586.9264,147.0322 C 592.4305,152.4557 598.446,156.1755 603.0832,156.3597 C 608.2112,156.4881 619.7769,150.57 624.5364,145.5447 z "
- style="font-size:12px;fill:url(#linearGradient2201);fill-rule:evenodd" /><path
+ d="m 594.8524,209.0117 c 0,11.0899 2.5217,16.5364 1.217,16.5364 -1.3047,0 -4.4801,-5.6553 -4.4801,-16.7452 0,-11.0896 4.2194,-23.2055 5.5241,-23.2055 1.3047,0 -2.261,12.3247 -2.261,23.4143 z M 632.27,169.5802 c 4.1762,3.7165 7.6897,8.0949 8.7337,13.4818 -7.1585,-6.2222 -19.1194,-9.1034 -26.0694,-10.7319 6.1145,-0.2088 15.1883,0.1733 17.3357,-2.7499 z m -36.6425,2.5791 c 2.2841,2.1198 1.645,3.6133 2.4676,6.3595 0.3598,-2.6078 4.4778,-4.5893 6.7167,-6.5707 -2.8526,0.488 -6.3317,0.5584 -9.1843,0.2112 z m -16.643,-3.8573 c -2.3118,2.6556 -5.1948,6.937 -7.9957,14.4901 5.9059,-6.6397 11.6998,-7.1631 18.2321,-9.8356 -5.9058,-0.2087 -8.0891,-1.7314 -10.2364,-4.6545 z m 45.5519,-22.7573 c -2.9528,8.7093 -16.5308,16.5145 -23.6186,16.5145 -4.135,0 -12.5149,-6.3179 -13.9914,-15.027 5.5041,5.4235 11.5196,9.1433 16.1568,9.3275 5.128,0.1284 16.6937,-5.7897 21.4532,-10.815 z"
+ style="font-size:12px;fill:url(#linearGradient2201);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /><path
transform="matrix(1.381431,0,0,1.342002,-335.1483,-21.47379)"
sodipodi:nodetypes="csccc"
id="path758"
- d="M 566.1781,204.0047 C 566.1781,224.5982 593.4836,225.0052 587.8079,232.522 C 582.6399,239.91 550.7196,226.5353 550.7196,205.9419 C 552.8076,190.3594 555.5661,185.5046 574.6452,156.366 C 587.5403,159.1975 566.1781,183.4112 566.1781,204.0047 z "
- style="font-size:12px;fill:url(#linearGradient2203);fill-rule:evenodd" /><g
+ d="m 566.1781,204.0047 c 0,20.5935 27.3055,21.0005 21.6298,28.5173 -5.168,7.388 -37.0883,-5.9867 -37.0883,-26.5801 2.088,-15.5825 4.8465,-20.4373 23.9256,-49.5759 12.8951,2.8315 -8.4671,27.0452 -8.4671,47.6387 z"
+ style="font-size:12px;fill:url(#linearGradient2203);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /><g
style="font-size:12px;fill:url(#linearGradient2205)"
transform="matrix(1.381431,0,0,1.342002,-325.2191,-15.60249)"
id="g1065"><path
transform="translate(-7.1875,-4.375031)"
sodipodi:nodetypes="csssscsss"
id="path842"
- d="M 662.6023,249.8415 C 652.9563,254.7202 643.0236,269.4045 630.2927,263.3619 C 621.3526,259.2146 625.6634,249.1638 625.1563,243.5311 C 624.668,230.5505 623.5071,211.1312 631.9468,211.184 C 642.1547,211.246 638.0258,215.2545 645.4196,217.3441 C 653.505,219.306 658.7389,209.0467 664.847,213.6095 C 669.4787,219.944 664.6217,223.322 670.205,229.4906 C 673.1685,233.0602 677.7506,232.9839 680.3539,235.8973 C 685.7736,241.3478 668.3201,246.6544 662.6023,249.8415 z "
- style="font-size:12px;fill:url(#linearGradient2207);fill-rule:evenodd" /><path
+ d="m 662.6023,249.8415 c -9.646,4.8787 -19.5787,19.563 -32.3096,13.5204 -8.9401,-4.1473 -4.6293,-14.1981 -5.1364,-19.8308 -0.4883,-12.9806 -1.6492,-32.3999 6.7905,-32.3471 10.2079,0.062 6.079,4.0705 13.4728,6.1601 8.0854,1.9619 13.3193,-8.2974 19.4274,-3.7346 4.6317,6.3345 -0.2253,9.7125 5.358,15.8811 2.9635,3.5696 7.5456,3.4933 10.1489,6.4067 5.4197,5.4505 -12.0338,10.7571 -17.7516,13.9442 z"
+ style="font-size:12px;fill:url(#linearGradient2207);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /><path
transform="translate(-7.1875,-4.375031)"
sodipodi:nodetypes="cssssssss"
id="path843"
- d="M 550.8908,255.4014 C 562.5947,256.6532 574.367,267.8037 584.6032,256.5396 C 591.8317,248.7246 584.743,239.3914 580.5155,234.7902 C 570.7341,224.8274 565.2408,206.427 556.2229,206.4986 C 548.5882,206.8092 550.0632,210.9825 544.7009,215.234 C 537.4953,220.6488 532.9891,216.239 528.6392,223.1506 C 525.9871,226.8955 526.7585,231.7788 527.8864,236.9511 C 528.6785,241.8714 527.0976,242.9494 525.4163,244.55 C 519.9332,250.7329 540.853,254.0325 550.8908,255.4014 z "
- style="font-size:12px;fill:url(#linearGradient2209);fill-rule:evenodd" /></g><path
+ d="m 550.8908,255.4014 c 11.7039,1.2518 23.4762,12.4023 33.7124,1.1382 7.2285,-7.815 0.1398,-17.1482 -4.0877,-21.7494 -9.7814,-9.9628 -15.2747,-28.3632 -24.2926,-28.2916 -7.6347,0.3106 -6.1597,4.4839 -11.522,8.7354 -7.2056,5.4148 -11.7118,1.005 -16.0617,7.9166 -2.6521,3.7449 -1.8807,8.6282 -0.7528,13.8005 0.7921,4.9203 -0.7888,5.9983 -2.4701,7.5989 -5.4831,6.1829 15.4367,9.4825 25.4745,10.8514 z"
+ style="font-size:12px;fill:url(#linearGradient2209);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /></g><path
transform="matrix(1.381431,0,0,1.342002,-335.1483,-21.47379)"
sodipodi:nodetypes="cscss"
id="path857"
- d="M 649.8842,196.2501 C 649.4318,220.8146 631.991,220.9147 636.6064,229.3612 C 642.8768,241.2543 669.5186,218.7807 669.5186,198.1874 C 669.5186,178.0113 641.3187,150.3852 638.2491,152.2475 C 619.1027,166.4884 650.6787,175.7879 649.8842,196.2501 z "
- style="font-size:12px;fill:url(#linearGradient2211);fill-rule:evenodd" /></g></g></svg>
\ No newline at end of file
+ d="m 649.8842,196.2501 c -0.4524,24.5645 -17.8932,24.6646 -13.2778,33.1111 6.2704,11.8931 32.9122,-10.5805 32.9122,-31.1738 0,-20.1761 -28.1999,-47.8022 -31.2695,-45.9399 -19.1464,14.2409 12.4296,23.5404 11.6351,44.0026 z"
+ style="font-size:12px;fill:url(#linearGradient2211);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /></g></g></svg>
\ No newline at end of file
diff --git a/src/activities/money/resource/c1e.svg b/src/activities/money/resource/c1e.svg
index 679366357..bc9aa9e19 100644
--- a/src/activities/money/resource/c1e.svg
+++ b/src/activities/money/resource/c1e.svg
@@ -1,235 +1,244 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="svg699"
sodipodi:version="0.32"
width="503.34711"
height="500.98511"
xml:space="preserve"
sodipodi:docname="c1e.svg"
- inkscape:version="0.91 r13725"
+ inkscape:version="0.92.1 r15371"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
sodipodi:modified="true"
version="1.0"><metadata
id="metadata32"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs701"><linearGradient
id="linearGradient651"><stop
style="stop-color:#c78a00;stop-opacity:1;"
offset="0"
id="stop652" /><stop
style="stop-color:#ffe56a;stop-opacity:1;"
offset="1"
id="stop653" /></linearGradient><linearGradient
id="linearGradient834"><stop
style="stop-color:#191919;stop-opacity:1;"
offset="0"
id="stop835" /><stop
style="stop-color:#e6e6e6;stop-opacity:1;"
offset="1"
id="stop836" /></linearGradient><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2200"
- gradientTransform="scale(1.0023546,0.9976509)"
+ gradientTransform="matrix(0.95036446,0,0,0.94590473,20.957637,26.896433)"
spreadMethod="reflect"
x1="101.80905"
y1="739.47278"
x2="503.54039"
y2="472.69859"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2202"
spreadMethod="reflect"
x1="606.97739"
y1="308.21331"
x2="287.83704"
y2="423.25226"
- gradientUnits="userSpaceOnUse" /><linearGradient
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.94813199,0,0,0.94813199,20.957637,26.896433)" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient834"
id="linearGradient2204"
x1="617.6757"
y1="76.381846"
x2="269.76705"
y2="279.5849"
- gradientTransform="scale(1.0257553,0.9748914)"
+ gradientTransform="matrix(0.87212868,0,0,0.87212905,151.55486,300.00746)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient834"
id="linearGradient2206"
spreadMethod="pad"
x1="793.34177"
y1="352.44251"
x2="107.85096"
y2="349.3007"
- gradientTransform="scale(0.7156919,1.3972492)"
+ gradientTransform="matrix(0.67857039,0,0,1.3247767,20.957637,26.896433)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient834"
id="linearGradient2208"
x1="286.0667"
y1="307.05434"
x2="461.85029"
y2="147.59049"
gradientTransform="scale(0.9767462,1.0238074)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient834"
id="linearGradient2210"
x1="382.07346"
y1="269.31339"
x2="533.91029"
y2="131.57308"
gradientTransform="scale(0.8819901,1.1337996)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient834"
id="linearGradient2212"
x1="572.36365"
y1="204.5671"
x2="631.6621"
y2="150.77391"
gradientTransform="scale(0.935494,1.0689539)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient834"
id="linearGradient2214"
x1="763.86779"
y1="158.54136"
x2="806.98456"
y2="119.42756"
gradientTransform="scale(0.6957958,1.4372033)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient834"
id="linearGradient2216"
x1="266.82405"
y1="418.96704"
x2="342.59325"
y2="350.23224"
gradientTransform="scale(1.6403562,0.6096237)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient834"
id="linearGradient2218"
x1="578.59924"
y1="267.88094"
x2="622.33321"
y2="228.20723"
gradientTransform="scale(1.0295592,0.9712894)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient834"
id="linearGradient2220"
x1="459.52561"
y1="275.18938"
x2="506.24941"
y2="232.80342"
gradientTransform="scale(1.0716088,0.9331764)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient834"
id="linearGradient2222"
x1="898.9716"
y1="153.9525"
x2="942.47288"
y2="114.48987"
gradientTransform="scale(0.6819639,1.4663532)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2226"
- gradientTransform="scale(4.7399352,0.2109733)"
+ gradientTransform="matrix(4.4940842,0,0,0.20003053,20.957637,26.896433)"
x1="52.618559"
y1="3075.7264"
x2="52.572449"
y2="3055.5108"
gradientUnits="userSpaceOnUse" /></defs><sodipodi:namedview
id="base"
inkscape:zoom="0.36014217"
- inkscape:cx="-258.25939"
+ inkscape:cx="-851.08083"
inkscape:cy="526.18109"
- inkscape:window-width="1366"
- inkscape:window-height="748"
- inkscape:window-x="-2"
- inkscape:window-y="-3"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
inkscape:current-layer="g2184"
showgrid="false"
inkscape:window-maximized="1" /><g
id="g2184"
transform="translate(-152.3835,-268.0627)"><path
sodipodi:nodetypes="ccccccc"
id="path687"
- d="M 655.7306,518.5551 C 655.7306,656.8984 543.0531,769.0478 404.0571,769.0478 C 265.0618,769.0478 152.3835,656.8984 152.3835,518.5551 C 152.3835,380.2119 265.0618,268.0627 404.0571,268.0627 C 543.0531,268.0627 655.7306,380.2119 655.7306,518.5551 z M 396.9986,636.0575 L 396.9986,636.0575 z "
- style="font-size:48px;font-style:italic;font-weight:bold;fill:url(#linearGradient2200);fill-opacity:1;stroke-width:1;font-family:Luxi Serif" /><path
+ d="m 642.6768,518.55511 c 0,131.16771 -106.83314,237.50014 -238.6197,237.50014 -131.78589,0 -238.61979,-106.33243 -238.61979,-237.50014 0,-131.16762 106.8339,-237.49986 238.61979,-237.49986 131.78656,0 238.6197,106.33224 238.6197,237.49986 z M 397.36471,629.96289 Z"
+ style="font-style:italic;font-weight:bold;font-size:48px;font-family:'Luxi Serif';fill:url(#linearGradient2200);fill-opacity:1;stroke-width:0.94813198"
+ inkscape:connector-curvature="0" /><path
sodipodi:nodetypes="cccccccccccccccccccccccc"
id="path665"
- d="M 640.3757,519.7365 C 640.3757,650.9041 534.0437,757.2364 402.8758,757.2364 C 271.7086,757.2364 165.3762,650.9041 165.3762,519.7365 C 165.3762,388.569 271.7086,282.2368 402.8758,282.2368 C 534.0437,282.2368 640.3757,388.569 640.3757,519.7365 z M 216.9033,648.3585 L 391.8088,648.3585 L 396.2148,631.1442 L 369.3399,629.2315 C 349.0737,628.0838 345.1086,626.5537 345.1086,619.2854 C 345.1086,613.9298 346.4303,603.6012 348.6331,594.0376 L 400.6198,369.4857 L 275.0583,395.4985 L 271.0931,413.8605 L 287.3942,411.1827 C 298.4084,409.6526 309.8631,408.1224 312.9471,408.1224 C 319.9962,408.1224 323.9613,410.0351 325.283,414.2431 L 323.5208,420.7463 L 320.4368,439.8734 L 285.1913,594.0376 C 275.4988,626.9362 274.6177,627.7013 249.9459,628.8489 L 224.8335,630.7616 L 220.8684,631.1442 L 216.9033,648.3585 z "
- style="font-size:48px;font-style:italic;font-weight:bold;fill:url(#linearGradient2202);fill-opacity:1;stroke-width:1;font-family:Luxi Serif" /><path
- transform="matrix(0.896743,0,0,0.94353,137.7416,288.0517)"
- sodipodi:ry="192.09787"
- sodipodi:rx="202.12038"
- sodipodi:cy="245.55115"
- sodipodi:cx="295.6637"
- d="M 497.78407,245.55115 A 202.12038,192.09787 0 0 1 295.6637,437.64902 202.12038,192.09787 0 0 1 93.54332,245.55115 202.12038,192.09787 0 0 1 295.6637,53.453278 202.12038,192.09787 0 0 1 497.78407,245.55115 Z"
+ d="m 628.11833,519.67523 c 0,124.3642 -100.81677,225.18125 -225.18126,225.18125 -124.36382,0 -225.18097,-100.81705 -225.18097,-225.18125 0,-124.3641 100.81715,-225.18106 225.18097,-225.18106 124.36449,0 225.18126,100.81696 225.18126,225.18106 z M 226.6106,641.62586 h 165.8335 l 4.17747,-16.32142 -25.48096,-1.8135 c -19.21503,-1.08817 -22.97447,-2.5389 -22.97447,-9.43021 0,-5.07782 1.25315,-14.87069 3.34169,-23.93825 l 49.29026,-212.90484 -119.04888,24.66357 -3.75953,17.4096 15.45559,-2.53891 c 10.44292,-1.45074 21.30349,-2.90157 24.22753,-2.90157 6.68347,0 10.44291,1.81349 11.69606,5.80323 l -1.6708,6.1659 -2.92404,18.13501 -33.41739,146.16801 c -9.18977,31.19222 -10.02516,31.91763 -33.41729,33.00571 l -23.80987,1.81349 -3.75944,0.36276 z"
+ style="font-style:italic;font-weight:bold;font-size:48px;font-family:'Luxi Serif';fill:url(#linearGradient2202);fill-opacity:1;stroke-width:0.94813198"
+ inkscape:connector-curvature="0" /><ellipse
id="path654"
- style="fill:url(#linearGradient2204);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- sodipodi:type="arc" /><path
+ style="fill:url(#linearGradient2204);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.87212884pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ cx="402.93719"
+ cy="519.67529"
+ rx="171.84895"
+ ry="171.84901" /><path
sodipodi:nodetypes="csssscccsscsscccccccc"
id="path689"
- d="M 277.5117,650.4873 L 389.9606,650.4873 C 392.1534,650.4873 395.256,649.8242 395.9378,647.7401 L 400.6622,633.2998 C 401.2892,631.3832 397.0027,628.8104 394.9918,628.66 L 371.8883,626.9315 C 355.3736,626.4395 349.5372,624.877 349.5372,621.4248 C 349.5372,616.0498 350.8497,605.7373 353.0372,596.1748 L 404.202,374.118 C 404.6708,372.0832 401.924,369.1266 399.8853,369.5785 L 279.0571,396.3595 L 271.2419,413.0638 C 270.5672,414.5058 273.9554,415.3324 275.5372,415.1521 L 291.7872,413.2998 C 302.8497,411.7998 314.2872,410.2373 317.3497,410.2373 C 324.4122,410.2373 328.3497,412.1748 329.7247,416.3623 L 327.9122,422.8623 L 324.8497,441.9873 L 289.5997,596.1748 C 281.2247,624.6123 277.533,629.4049 260.3455,630.7174 C 265.5955,637.9049 271.1992,644.2373 277.5117,650.4873 z "
- style="font-size:48px;font-style:italic;font-weight:bold;fill:url(#linearGradient2206);stroke-width:1;font-family:Luxi Serif" /><g
+ d="m 284.07536,643.64425 h 106.6164 c 2.07906,0 5.02074,-0.62871 5.66717,-2.60471 l 4.47936,-13.69131 c 0.59448,-1.81719 -3.46969,-4.25655 -5.37629,-4.39914 l -21.90517,-1.63885 c -15.65811,-0.46648 -21.19179,-1.94794 -21.19179,-5.22108 0,-5.09621 1.24442,-14.87382 3.31846,-23.94033 l 48.51099,-210.53916 c 0.44448,-1.92926 -2.15985,-4.7325 -4.09281,-4.30404 l -114.56108,25.39192 -7.40984,15.83788 c -0.6397,1.36721 2.57276,2.15093 4.07251,1.97999 l 15.40715,-1.75623 c 10.48871,-1.4222 21.33297,-2.90365 24.23662,-2.90365 6.69618,0 10.42945,1.837 11.73313,5.8073 l -1.71848,6.16286 -2.90366,18.13303 -33.42165,146.1901 c -7.94061,26.9625 -11.44083,31.50652 -27.73684,32.75094 4.97769,6.8147 10.29074,12.81865 16.27582,18.74448 z"
+ style="font-style:italic;font-weight:bold;font-size:48px;font-family:'Luxi Serif';fill:url(#linearGradient2206);stroke-width:0.94813198"
+ inkscape:connector-curvature="0" /><g
style="font-size:12px;fill:url(#linearGradient2208)"
- transform="matrix(0.788523,0,0,0.749812,90.02661,337.1856)"
+ transform="matrix(0.74762388,0,0,0.71092074,106.31475,346.59288)"
id="g944"><path
id="path943"
- d="M 489.2781,157.6309 C 486.7725,158.6472 483.694,159.9616 480.8916,161.4231 C 479.3419,161.0055 475.428,159.2736 475.428,155.3341 C 475.428,151.3946 478.7154,148.2011 482.7708,148.2011 C 488.0788,148.2011 490.7398,151.8121 489.2781,157.6309 z M 521.9314,154.5415 C 521.9314,158.4811 518.0176,160.213 516.6769,160.8394 C 513.0392,159.5867 510.1692,158.6899 508.0812,158.0913 C 505.5757,152.2726 509.2807,147.4085 514.5889,147.4085 C 518.644,147.4085 521.9314,150.6021 521.9314,154.5415 z M 554.0133,282.1463 C 539.7204,299.0921 519.7959,311.7673 487.7231,311.2372 C 455.0333,310.1367 444.7336,294.8341 446.4288,254.5974 C 447.4384,237.4799 453.0554,223.2215 459.4115,212.5429 C 462.707,204.534 471.5472,201.7454 476.9885,177.1512 C 485.6153,185.4841 494.4355,188.3269 497.9466,188.3677 C 504.6303,188.4997 521.1268,180.7489 526.5206,174.9439 C 532.8029,196.1211 539.725,203.2866 544.2499,208.414 C 571.8131,240.2076 557.189,277.6971 554.0133,282.1463 z M 494.2871,157.0588 C 487.7115,157.6404 481.7311,160.3453 477.7269,163.5282 C 475.279,165.2092 472.0644,157.8887 472.0644,152.4116 C 472.0644,145.0207 475.2644,139.5457 483.471,139.5457 C 490.9986,139.5457 495.5149,147.9387 494.2871,157.0588 z M 503.3984,157.4551 C 509.7709,158.1484 517.8879,161.2707 522.7624,163.7729 C 525.4762,165.4536 527.6282,158.285 527.6282,152.8079 C 527.6282,147.0021 523.8588,139.1494 514.7603,139.1494 C 505.191,139.1494 502.0372,145.9572 503.3984,157.4551 z M 504.7202,106.7478 C 474.7132,106.4276 457.1089,126.4945 461.8612,178.9302 C 463.5845,198.2381 361.0517,308.565 481.4685,323.2273 L 525.5737,324.0199 C 606.8295,319.2645 591.7019,249.1051 588.8989,241.103 C 580.6322,213.4795 553.1952,187.4526 553.0018,172.6248 C 552.814,127.3526 535.8651,106.2749 504.7202,106.7478 z M 529.3964,169.2447 C 529.7524,177.204 506.4211,188.5796 497.5232,188.5796 C 490.247,188.5796 473.2299,177.6226 472.7098,170.2413 C 472.4321,166.698 484.8286,156.8974 498.0721,157.1776 C 508.6449,157.1776 529.106,164.0661 529.3964,169.2447 z M 505.6319,158.6713 C 504.8923,159.1122 502.5108,159.8841 502.2685,159.8142 C 501.7591,159.7069 502.9358,158.8886 503.1344,158.3848 C 503.3119,157.9112 506.3718,158.2303 505.6319,158.6713 z M 491.2411,158.3369 C 491.2346,158.7713 491.7574,159.5856 492.1907,159.5931 C 492.5879,159.0685 492.9824,158.6462 493.4274,158.2207 C 493.8848,157.8292 491.2476,157.996 491.2411,158.3369 z M 475.86,171.0084 C 475.1974,169.8919 481.8043,180.5114 494.4183,180.9245 C 505.2062,181.3048 518.8716,172.4247 527.1629,168.9206 C 494.2345,184.859 489.641,183.0493 475.86,171.0084 z M 532.9812,126.1648 C 531.3254,129.0911 525.7228,129.7142 520.4675,127.5566 C 515.2121,125.3989 512.294,121.2776 513.9498,118.3513 C 515.6056,115.425 521.2082,114.8019 526.4636,116.9596 C 531.7189,119.1172 534.6369,123.2386 532.9812,126.1648 z "
- style="font-size:12px;fill:url(#linearGradient2210);fill-rule:evenodd" /><path
+ d="m 489.2781,157.6309 c -2.5056,1.0163 -5.5841,2.3307 -8.3865,3.7922 -1.5497,-0.4176 -5.4636,-2.1495 -5.4636,-6.089 0,-3.9395 3.2874,-7.133 7.3428,-7.133 5.308,0 7.969,3.611 6.5073,9.4298 z m 32.6533,-3.0894 c 0,3.9396 -3.9138,5.6715 -5.2545,6.2979 -3.6377,-1.2527 -6.5077,-2.1495 -8.5957,-2.7481 -2.5055,-5.8187 1.1995,-10.6828 6.5077,-10.6828 4.0551,0 7.3425,3.1936 7.3425,7.133 z m 32.0819,127.6048 c -14.2929,16.9458 -34.2174,29.621 -66.2902,29.0909 -32.6898,-1.1005 -42.9895,-16.4031 -41.2943,-56.6398 1.0096,-17.1175 6.6266,-31.3759 12.9827,-42.0545 3.2955,-8.0089 12.1357,-10.7975 17.577,-35.3917 8.6268,8.3329 17.447,11.1757 20.9581,11.2165 6.6837,0.132 23.1802,-7.6188 28.574,-13.4238 6.2823,21.1772 13.2044,28.3427 17.7293,33.4701 27.5632,31.7936 12.9391,69.2831 9.7634,73.7323 z M 494.2871,157.0588 c -6.5756,0.5816 -12.556,3.2865 -16.5602,6.4694 -2.4479,1.681 -5.6625,-5.6395 -5.6625,-11.1166 0,-7.3909 3.2,-12.8659 11.4066,-12.8659 7.5276,0 12.0439,8.393 10.8161,17.5131 z m 9.1113,0.3963 c 6.3725,0.6933 14.4895,3.8156 19.364,6.3178 2.7138,1.6807 4.8658,-5.4879 4.8658,-10.965 0,-5.8058 -3.7694,-13.6585 -12.8679,-13.6585 -9.5693,0 -12.7231,6.8078 -11.3619,18.3057 z m 1.3218,-50.7073 c -30.007,-0.3202 -47.6113,19.7467 -42.859,72.1824 1.7233,19.3079 -100.8095,129.6348 19.6073,144.2971 l 44.1052,0.7926 c 81.2558,-4.7554 66.1282,-74.9148 63.3252,-82.9169 -8.2667,-27.6235 -35.7037,-53.6504 -35.8971,-68.4782 -0.1878,-45.2722 -17.1367,-66.3499 -48.2816,-65.877 z m 24.6762,62.4969 c 0.356,7.9593 -22.9753,19.3349 -31.8732,19.3349 -7.2762,0 -24.2933,-10.957 -24.8134,-18.3383 -0.2777,-3.5433 12.1188,-13.3439 25.3623,-13.0637 10.5728,0 31.0339,6.8885 31.3243,12.0671 z m -23.7645,-10.5734 c -0.7396,0.4409 -3.1211,1.2128 -3.3634,1.1429 -0.5094,-0.1073 0.6673,-0.9256 0.8659,-1.4294 0.1775,-0.4736 3.2374,-0.1545 2.4975,0.2865 z m -14.3908,-0.3344 c -0.007,0.4344 0.5163,1.2487 0.9496,1.2562 0.3972,-0.5246 0.7917,-0.9469 1.2367,-1.3724 0.4574,-0.3915 -2.1798,-0.2247 -2.1863,0.1162 z M 475.86,171.0084 c -0.6626,-1.1165 5.9443,9.503 18.5583,9.9161 10.7879,0.3803 24.4533,-8.4998 32.7446,-12.0039 -32.9284,15.9384 -37.5219,14.1287 -51.3029,2.0878 z m 57.1212,-44.8436 c -1.6558,2.9263 -7.2584,3.5494 -12.5137,1.3918 -5.2554,-2.1577 -8.1735,-6.279 -6.5177,-9.2053 1.6558,-2.9263 7.2584,-3.5494 12.5138,-1.3917 5.2553,2.1576 8.1733,6.279 6.5176,9.2052 z"
+ style="font-size:12px;fill:url(#linearGradient2210);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /><path
transform="matrix(1.381431,0,0,1.342002,-335.1481,-21.47379)"
sodipodi:nodetypes="cccccccccccccccccccccc"
id="path871"
- d="M 594.8524,209.0117 C 594.8524,220.1016 597.3741,225.5481 596.0694,225.5481 C 594.7647,225.5481 591.5893,219.8928 591.5893,208.8029 C 591.5893,197.7133 595.8087,185.5974 597.1134,185.5974 C 598.4181,185.5974 594.8524,197.9221 594.8524,209.0117 z M 632.27,169.5802 C 636.4462,173.2967 639.9597,177.6751 641.0037,183.062 C 633.8452,176.8398 621.8843,173.9586 614.9343,172.3301 C 621.0488,172.1213 630.1226,172.5034 632.27,169.5802 z M 595.6275,172.1593 C 597.9116,174.2791 597.2725,175.7726 598.0951,178.5188 C 598.4549,175.911 602.5729,173.9295 604.8118,171.9481 C 601.9592,172.4361 598.4801,172.5065 595.6275,172.1593 z M 578.9845,168.302 C 576.6727,170.9576 573.7897,175.239 570.9888,182.7921 C 576.8947,176.1524 582.6886,175.629 589.2209,172.9565 C 583.3151,172.7478 581.1318,171.2251 578.9845,168.302 z M 624.5364,145.5447 C 621.5836,154.254 608.0056,162.0592 600.9178,162.0592 C 596.7828,162.0592 588.4029,155.7413 586.9264,147.0322 C 592.4305,152.4557 598.446,156.1755 603.0832,156.3597 C 608.2112,156.4881 619.7769,150.57 624.5364,145.5447 z "
- style="font-size:12px;fill:url(#linearGradient2212);fill-rule:evenodd" /><path
+ d="m 594.8524,209.0117 c 0,11.0899 2.5217,16.5364 1.217,16.5364 -1.3047,0 -4.4801,-5.6553 -4.4801,-16.7452 0,-11.0896 4.2194,-23.2055 5.5241,-23.2055 1.3047,0 -2.261,12.3247 -2.261,23.4143 z M 632.27,169.5802 c 4.1762,3.7165 7.6897,8.0949 8.7337,13.4818 -7.1585,-6.2222 -19.1194,-9.1034 -26.0694,-10.7319 6.1145,-0.2088 15.1883,0.1733 17.3357,-2.7499 z m -36.6425,2.5791 c 2.2841,2.1198 1.645,3.6133 2.4676,6.3595 0.3598,-2.6078 4.4778,-4.5893 6.7167,-6.5707 -2.8526,0.488 -6.3317,0.5584 -9.1843,0.2112 z m -16.643,-3.8573 c -2.3118,2.6556 -5.1948,6.937 -7.9957,14.4901 5.9059,-6.6397 11.6998,-7.1631 18.2321,-9.8356 -5.9058,-0.2087 -8.0891,-1.7314 -10.2364,-4.6545 z m 45.5519,-22.7573 c -2.9528,8.7093 -16.5308,16.5145 -23.6186,16.5145 -4.135,0 -12.5149,-6.3179 -13.9914,-15.027 5.5041,5.4235 11.5196,9.1433 16.1568,9.3275 5.128,0.1284 16.6937,-5.7897 21.4532,-10.815 z"
+ style="font-size:12px;fill:url(#linearGradient2212);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /><path
transform="matrix(1.381431,0,0,1.342002,-335.1483,-21.47379)"
sodipodi:nodetypes="csccc"
id="path758"
- d="M 566.1781,204.0047 C 566.1781,224.5982 593.4836,225.0052 587.8079,232.522 C 582.6399,239.91 550.7196,226.5353 550.7196,205.9419 C 552.8076,190.3594 555.5661,185.5046 574.6452,156.366 C 587.5403,159.1975 566.1781,183.4112 566.1781,204.0047 z "
- style="font-size:12px;fill:url(#linearGradient2214);fill-rule:evenodd" /><g
+ d="m 566.1781,204.0047 c 0,20.5935 27.3055,21.0005 21.6298,28.5173 -5.168,7.388 -37.0883,-5.9867 -37.0883,-26.5801 2.088,-15.5825 4.8465,-20.4373 23.9256,-49.5759 12.8951,2.8315 -8.4671,27.0452 -8.4671,47.6387 z"
+ style="font-size:12px;fill:url(#linearGradient2214);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /><g
style="font-size:12px;fill:url(#linearGradient2216)"
transform="matrix(1.381431,0,0,1.342002,-325.2191,-15.60249)"
id="g1065"><path
transform="translate(-7.1875,-4.375031)"
sodipodi:nodetypes="csssscsss"
id="path842"
- d="M 662.6023,249.8415 C 652.9563,254.7202 643.0236,269.4045 630.2927,263.3619 C 621.3526,259.2146 625.6634,249.1638 625.1563,243.5311 C 624.668,230.5505 623.5071,211.1312 631.9468,211.184 C 642.1547,211.246 638.0258,215.2545 645.4196,217.3441 C 653.505,219.306 658.7389,209.0467 664.847,213.6095 C 669.4787,219.944 664.6217,223.322 670.205,229.4906 C 673.1685,233.0602 677.7506,232.9839 680.3539,235.8973 C 685.7736,241.3478 668.3201,246.6544 662.6023,249.8415 z "
- style="font-size:12px;fill:url(#linearGradient2218);fill-rule:evenodd" /><path
+ d="m 662.6023,249.8415 c -9.646,4.8787 -19.5787,19.563 -32.3096,13.5204 -8.9401,-4.1473 -4.6293,-14.1981 -5.1364,-19.8308 -0.4883,-12.9806 -1.6492,-32.3999 6.7905,-32.3471 10.2079,0.062 6.079,4.0705 13.4728,6.1601 8.0854,1.9619 13.3193,-8.2974 19.4274,-3.7346 4.6317,6.3345 -0.2253,9.7125 5.358,15.8811 2.9635,3.5696 7.5456,3.4933 10.1489,6.4067 5.4197,5.4505 -12.0338,10.7571 -17.7516,13.9442 z"
+ style="font-size:12px;fill:url(#linearGradient2218);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /><path
transform="translate(-7.1875,-4.375031)"
sodipodi:nodetypes="cssssssss"
id="path843"
- d="M 550.8908,255.4014 C 562.5947,256.6532 574.367,267.8037 584.6032,256.5396 C 591.8317,248.7246 584.743,239.3914 580.5155,234.7902 C 570.7341,224.8274 565.2408,206.427 556.2229,206.4986 C 548.5882,206.8092 550.0632,210.9825 544.7009,215.234 C 537.4953,220.6488 532.9891,216.239 528.6392,223.1506 C 525.9871,226.8955 526.7585,231.7788 527.8864,236.9511 C 528.6785,241.8714 527.0976,242.9494 525.4163,244.55 C 519.9332,250.7329 540.853,254.0325 550.8908,255.4014 z "
- style="font-size:12px;fill:url(#linearGradient2220);fill-rule:evenodd" /></g><path
+ d="m 550.8908,255.4014 c 11.7039,1.2518 23.4762,12.4023 33.7124,1.1382 7.2285,-7.815 0.1398,-17.1482 -4.0877,-21.7494 -9.7814,-9.9628 -15.2747,-28.3632 -24.2926,-28.2916 -7.6347,0.3106 -6.1597,4.4839 -11.522,8.7354 -7.2056,5.4148 -11.7118,1.005 -16.0617,7.9166 -2.6521,3.7449 -1.8807,8.6282 -0.7528,13.8005 0.7921,4.9203 -0.7888,5.9983 -2.4701,7.5989 -5.4831,6.1829 15.4367,9.4825 25.4745,10.8514 z"
+ style="font-size:12px;fill:url(#linearGradient2220);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /></g><path
transform="matrix(1.381431,0,0,1.342002,-335.1483,-21.47379)"
sodipodi:nodetypes="cscss"
id="path857"
- d="M 649.8842,196.2501 C 649.4318,220.8146 631.991,220.9147 636.6064,229.3612 C 642.8768,241.2543 669.5186,218.7807 669.5186,198.1874 C 669.5186,178.0113 641.3187,150.3852 638.2491,152.2475 C 619.1027,166.4884 650.6787,175.7879 649.8842,196.2501 z "
- style="font-size:12px;fill:url(#linearGradient2222);fill-rule:evenodd" /></g><path
+ d="m 649.8842,196.2501 c -0.4524,24.5645 -17.8932,24.6646 -13.2778,33.1111 6.2704,11.8931 32.9122,-10.5805 32.9122,-31.1738 0,-20.1761 -28.1999,-47.8022 -31.2695,-45.9399 -19.1464,14.2409 12.4296,23.5404 11.6351,44.0026 z"
+ style="font-size:12px;fill:url(#linearGradient2222);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /></g><path
sodipodi:nodetypes="cccccccccccccccccc"
id="path686"
- d="M 274.875,648.125 L 391.5,648.125 L 395.9375,630.9375 L 391.3045,629.234 L 369.6955,628.367 C 349.383,627.2421 344.8125,626.3125 344.8125,619.0625 C 344.8125,613.6875 346.125,603.375 348.3125,593.8125 L 400.3125,369.25 L 274.75,395.25 L 270.8125,413.625 L 287.0625,410.9375 C 298.125,409.4375 309.5625,407.875 312.625,407.875 C 319.6875,407.875 323.625,409.8125 325,414 L 323.1875,420.5 L 320.125,439.625 L 284.875,593.8125 C 276.5,622.25 274.6875,626.625 257.5,627.9375 C 262.75,635.125 268.5625,641.875 274.875,648.125 z "
- style="font-size:48px;font-style:italic;font-weight:bold;fill:#ffffff;stroke-width:6;font-family:Luxi Serif;fill-opacity:1;stroke:#000000;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" /><path
+ d="m 281.57542,641.40447 h 110.57589 l 4.20734,-16.29601 -4.3927,-1.61515 -20.48818,-0.82203 c -19.25893,-1.06655 -23.59237,-1.94793 -23.59237,-8.82189 0,-5.09621 1.24442,-14.87382 3.31846,-23.94033 l 49.30287,-212.91489 -119.04983,24.65143 -3.73327,17.42192 15.40715,-2.5481 c 10.48871,-1.4222 21.33297,-2.90366 24.23662,-2.90366 6.69618,0 10.42945,1.83701 11.73314,5.80731 l -1.71849,6.16286 -2.90366,18.13302 -33.42165,146.19011 c -7.94061,26.9625 -9.6591,31.11058 -25.95511,32.355 4.97769,6.8147 10.48871,13.21459 16.47379,19.14041 z"
+ style="font-style:italic;font-weight:bold;font-size:48px;font-family:'Luxi Serif';fill:#ffffff;fill-opacity:1;stroke:#000000;stroke-width:5.68879175;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ inkscape:connector-curvature="0" /><path
sodipodi:nodetypes="csccs"
id="path692"
- d="M 217.1543,648.3299 C 215.8113,648.3348 217.887,650.8419 219.6599,650.8355 L 277.707,650.6266 L 274.9926,648.1212 L 217.1543,648.3299 z "
- style="font-size:12px;fill:url(#linearGradient2226);fill-rule:evenodd" /></g></svg>
\ No newline at end of file
+ d="m 226.84858,641.59875 c -1.27334,0.005 0.69469,2.3817 2.37564,2.37564 l 55.03631,-0.19807 -2.57361,-2.37545 z"
+ style="font-size:12px;fill:url(#linearGradient2226);fill-rule:evenodd;stroke-width:0.94813198"
+ inkscape:connector-curvature="0" /></g></svg>
\ No newline at end of file
diff --git a/src/activities/money/resource/c20c.svg b/src/activities/money/resource/c20c.svg
index 74120236e..1363a7bf8 100644
--- a/src/activities/money/resource/c20c.svg
+++ b/src/activities/money/resource/c20c.svg
@@ -1,194 +1,200 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="svg699"
sodipodi:version="0.32"
width="501.75558"
height="499.43585"
xml:space="preserve"
sodipodi:docname="c20c.svg"
- inkscape:version="0.91 r13725"
+ inkscape:version="0.92.1 r15371"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
sodipodi:modified="true"
version="1.0"><metadata
id="metadata29"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs701"><linearGradient
id="linearGradient651"><stop
style="stop-color:#c78f00;stop-opacity:1;"
offset="0"
id="stop652" /><stop
style="stop-color:#ffea6b;stop-opacity:1;"
offset="1"
id="stop653" /></linearGradient><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2193"
spreadMethod="reflect"
x1="672.22038"
y1="300.29517"
x2="225.53678"
y2="503.66204"
- gradientTransform="scale(1.0023197,0.9976857)"
- gradientUnits="userSpaceOnUse" /><linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient651"
- id="linearGradient2195"
- spreadMethod="reflect"
- x1="624.25226"
- y1="364.3883"
- x2="449.83822"
- y2="535.09138"
+ gradientTransform="matrix(0.75258895,0,0,0.74910951,98.098096,130.77946)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2197"
spreadMethod="reflect"
x1="286.06671"
y1="307.05434"
x2="461.8503"
y2="147.59049"
gradientTransform="scale(0.9767462,1.0238074)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2199"
spreadMethod="reflect"
x1="382.07347"
y1="269.31339"
x2="533.9103"
y2="131.57308"
gradientTransform="scale(0.8819901,1.1337996)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2201"
spreadMethod="reflect"
x1="572.36365"
y1="204.5671"
x2="631.66211"
y2="150.77391"
gradientTransform="scale(0.935494,1.0689539)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2203"
spreadMethod="reflect"
x1="763.8678"
y1="158.54136"
x2="806.98456"
y2="119.42756"
gradientTransform="scale(0.6957958,1.4372033)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2205"
spreadMethod="reflect"
x1="266.82405"
y1="418.96704"
x2="342.59325"
y2="350.23224"
gradientTransform="scale(1.6403562,0.6096237)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2207"
spreadMethod="reflect"
x1="578.59925"
y1="267.88094"
x2="622.33322"
y2="228.20723"
gradientTransform="scale(1.0295592,0.9712894)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2209"
spreadMethod="reflect"
x1="459.52562"
y1="275.18938"
x2="506.24941"
y2="232.80342"
gradientTransform="scale(1.0716088,0.9331764)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2211"
spreadMethod="reflect"
x1="898.9716"
y1="153.9525"
x2="942.47289"
y2="114.48988"
gradientTransform="scale(0.6819639,1.4663532)"
- gradientUnits="userSpaceOnUse" /></defs><sodipodi:namedview
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient651"
+ id="linearGradient2195-3"
+ spreadMethod="reflect"
+ x1="238.54836"
+ y1="768.71063"
+ x2="505.73611"
+ y2="471.83698"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.75084604,0,0,0.75084572,93.858186,70.783575)" /></defs><sodipodi:namedview
id="base"
- inkscape:zoom="0.36014217"
- inkscape:cx="-597.0145"
- inkscape:cy="526.18109"
- inkscape:window-width="1366"
- inkscape:window-height="713"
- inkscape:window-x="-2"
- inkscape:window-y="-3"
+ inkscape:zoom="0.72028434"
+ inkscape:cx="-399.29277"
+ inkscape:cy="298.51718"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
inkscape:current-layer="g2181"
showgrid="false"
inkscape:window-maximized="1" /><g
id="g2181"
transform="translate(-150.26544,-270.07808)"><path
- transform="translate(-2.46109,1.692474)"
sodipodi:nodetypes="ccssssssssssssssscssssssssssssssscssssssssssssssscsssssssssssssss"
id="path687"
- d="M 644.9887,517.6599 C 644.9887,526.3063 655.2905,528.5844 654.4312,537.0052 C 653.5721,545.426 652.2938,560.8849 650.6175,569.0381 C 648.9413,577.1914 646.8671,585.2003 644.4159,593.0439 C 641.9648,600.8877 639.1367,608.566 635.9529,616.0582 C 632.7691,623.5504 629.2294,630.8562 625.355,637.9548 C 621.4807,645.0534 611.3658,657.8506 606.843,664.5138 C 602.3203,671.1769 596.3027,665.8003 591.1738,671.9858 C 586.0448,678.1716 590.0726,686.4705 584.3796,692.1367 C 578.6868,697.803 570.3599,706.7426 564.145,711.8475 C 557.9302,716.9523 551.465,721.7661 544.7704,726.2676 C 538.0759,730.7691 531.152,734.9585 524.0199,738.8147 C 516.8878,742.6709 509.5475,746.194 502.02,749.3629 C 494.4926,752.5317 486.778,755.3465 478.8973,757.7862 C 471.0167,760.2258 462.97,762.2903 454.7783,763.9587 C 446.5866,765.6271 431.9838,766.8994 423.5233,767.7545 C 415.0627,768.6097 411.8492,760.9914 403.162,760.9914 C 394.4748,760.9914 392.1564,768.6097 383.696,767.7545 C 375.2354,766.8994 361.5279,765.6271 353.3362,763.9587 C 345.1445,762.2903 337.0978,760.2258 329.2172,757.7862 C 321.3365,755.3465 313.6219,752.5317 306.0945,749.3629 C 298.567,746.194 291.2267,742.6709 284.0946,738.8147 C 276.9625,734.9585 260.3144,722.8129 253.6199,718.3116 C 246.9253,713.8099 252.8362,705.4602 246.6214,700.3552 C 240.4065,695.2502 234.4421,703.1146 228.7492,697.4482 C 223.0562,691.7819 214.9825,684.0774 209.8536,677.8917 C 204.7246,671.7061 199.8882,665.2711 195.3654,658.608 C 190.8427,651.9448 186.6336,645.0534 182.7592,637.9548 C 178.8848,630.8562 175.3451,623.5504 172.1613,616.0582 C 168.9774,608.566 166.1494,600.8877 163.6983,593.0439 C 161.2471,585.2003 159.1729,577.1914 157.4966,569.0381 C 155.8204,560.8849 153.6469,544.5754 152.7877,536.1547 C 151.9284,527.7339 160.4064,526.3063 160.4064,517.6599 C 160.4064,509.0135 151.9284,507.6083 152.7877,499.1875 C 153.6469,490.7666 155.8204,476.2253 157.4966,468.0721 C 159.1729,459.9189 161.2471,451.9099 163.6983,444.0663 C 166.1494,436.2227 168.9774,428.5442 172.1613,421.0521 C 175.3451,413.56 178.8848,406.2541 182.7592,399.1555 C 186.6336,392.0569 190.8427,385.1656 195.3654,378.5023 C 199.8882,371.8392 209.4492,358.3174 214.5782,352.1316 C 219.7071,345.946 227.4911,348.2776 233.1841,342.6114 C 238.8771,336.9451 231.8487,332.7302 238.0636,327.6253 C 244.2784,322.5204 256.6495,315.3444 263.3441,310.8428 C 270.0386,306.3412 276.9625,302.1519 284.0946,298.2957 C 291.2267,294.4395 298.567,290.9165 306.0945,287.7477 C 313.6219,284.5787 321.3365,281.764 329.2172,279.3243 C 337.0978,276.8847 345.1445,274.8202 353.3362,273.1518 C 361.5279,271.4834 375.2354,269.3159 383.696,268.4608 C 392.1564,267.6055 394.4748,274.3288 403.162,274.3288 C 411.8492,274.3288 414.1675,268.5007 422.6281,269.3559 C 431.0886,270.2111 446.5866,271.4834 454.7783,273.1518 C 462.97,274.8202 471.0167,276.8847 478.8973,279.3243 C 486.778,281.764 494.4926,284.5787 502.02,287.7477 C 509.5475,290.9165 516.8878,294.4395 524.0199,298.2957 C 531.152,302.1519 538.0759,306.3412 544.7704,310.8428 C 551.465,315.3444 567.7025,328.0388 572.9852,334.1031 C 577.4321,340.0921 573.6724,345.4882 579.3652,351.1544 C 585.0583,356.8207 593.1318,353.033 598.2608,359.2186 C 603.3897,365.4044 608.2261,371.8392 612.7488,378.5023 C 617.2716,385.1656 621.4807,392.0569 625.355,399.1555 C 629.2294,406.2541 632.7691,413.56 635.9529,421.0521 C 639.1367,428.5442 641.9648,436.2227 644.4159,444.0663 C 646.8671,451.9099 648.9413,459.9189 650.6175,468.0721 C 652.2938,476.2253 653.5721,491.6841 654.4312,500.1049 C 655.2905,508.5257 644.9887,509.0135 644.9887,517.6599 z "
- style="font-size:48px;font-style:italic;font-weight:bold;fill:url(#linearGradient2193);fill-opacity:1;stroke-width:1;font-family:Luxi Serif" /><rect
- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.50000000000000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
- id="rect5120"
- width="438.71564"
- height="249.90132"
- x="186.3623"
- y="448.80722"
- ry="109.32895" /><path
- id="path634"
- d="M 265.3258,412.7872 L 265.3258,412.7872 z M 390.9698,631.2727 L 390.9698,631.2727 z M 639.0957,520.2476 C 639.0957,651.4152 532.7637,757.7475 401.5958,757.7475 C 270.4286,757.7475 164.0962,651.4152 164.0962,520.2476 C 164.0962,389.0801 270.4286,282.7479 401.5958,282.7479 C 532.7637,282.7479 639.0957,389.0801 639.0957,520.2476 z M 254.0036,467.903 L 254.0036,467.903 z M 460.132,586.1403 C 460.132,586.1403 460.132,580.6408 460.132,586.1403 z M 238.6012,590.4054 L 238.6012,590.4054 z M 612.4983,536.131 C 612.4983,536.131 612.4983,524.7069 612.4983,536.131 z M 462.2734,451.0216 C 439.6089,451.0216 421.0123,462.4457 404.1594,486.1507 C 382.3665,516.7101 370.4532,558.1224 370.4532,602.1051 C 370.4532,646.3734 385.5628,667.7936 416.9444,667.7936 C 448.0354,667.7936 473.3151,647.5158 490.7493,608.3883 C 503.2438,580.6849 510.7986,545.8415 510.7986,515.5677 C 510.7986,472.7274 494.5267,451.0216 462.2734,451.0216 z M 419.5596,559.5503 C 425.6615,527.8485 430.8918,506.7141 436.9938,489.8635 C 443.3863,471.0138 449.7789,463.8737 459.6583,463.8737 C 468.6659,463.8737 473.0245,469.8714 473.0245,482.4378 C 473.0245,513.8541 456.7526,595.2506 443.0958,632.0933 C 436.9938,648.6582 431.1823,654.9415 421.5935,654.9415 C 412.5859,654.9415 408.2273,648.9438 408.2273,636.663 C 408.2273,625.81 409.9707,611.5299 412.8764,595.5362 L 419.5596,559.5503 z M 371.6154,456.1625 L 371.6154,456.1625 z M 577.7341,654.0496 C 569.7135,657.0012 563.297,658.2439 557.7717,658.2439 C 546.0082,658.2439 540.3047,652.4962 540.3047,640.6899 C 540.3047,629.5051 543.6912,616.1454 549.5729,604.1838 C 554.5635,594.2417 560.4453,589.2707 567.2182,589.2707 C 572.387,589.2707 574.8823,592.3776 574.8823,598.5914 L 574.8823,599.2128 L 574.8823,600.4555 L 573.9911,606.048 L 573.6346,607.4461 L 588.2499,607.4461 L 593.2405,586.0084 C 585.0417,583.3676 577.7341,582.2802 569.7135,582.2802 C 537.8094,582.2802 513.3913,606.514 513.3913,638.2044 C 513.3913,658.0886 526.4024,669.2734 549.7512,669.2734 C 557.0588,669.2734 564.3664,668.186 575.2388,665.3898 L 577.7341,654.0496 z M 230.0577,667.3028 L 338.3315,667.3028 L 344.4006,632.2173 L 269.8714,632.2173 C 272.7846,619.1689 279.8248,606.7005 291.7204,594.5223 L 301.9165,583.7937 C 305.3153,580.3141 312.3555,574.2249 321.5806,566.9758 C 356.7817,539.1393 366.9779,522.9014 366.9779,494.485 C 366.9779,466.3586 351.9264,452.1503 321.8234,452.1503 C 305.0725,452.1503 289.2927,455.6299 268.6576,463.7489 L 262.1029,502.8939 L 278.3682,502.8939 L 278.8538,500.2843 L 281.0386,488.6857 C 283.7091,474.1876 293.177,466.0686 307.9857,466.0686 C 322.7944,466.0686 329.8347,475.0575 329.8347,493.9051 C 329.8347,516.5222 320.8523,539.7193 305.3153,557.987 L 285.6512,580.8941 L 277.6399,589.8829 L 263.3167,606.1206 C 250.4501,620.6187 240.2539,636.5667 232.4854,653.3846 L 230.0577,667.3028 z "
- style="font-size:48px;font-style:italic;font-weight:bold;fill:url(#linearGradient2195);font-family:Luxi Serif" /><g
+ d="m 582.38602,519.46291 c 0,6.49211 7.73507,8.20262 7.08986,14.52535 -0.64504,6.32274 -1.60486,17.93001 -2.8635,24.05182 -1.25857,6.12187 -2.81597,12.13534 -4.65646,18.02468 -1.84039,5.88949 -3.96385,11.65473 -6.3544,17.28023 -2.39055,5.62549 -5.04833,11.11103 -7.95741,16.44099 -2.90901,5.32997 -10.50375,14.93871 -13.89968,19.94175 -3.39586,5.00297 -7.91415,0.96597 -11.76518,5.61033 -3.8511,4.64459 -0.82683,10.8758 -5.1014,15.13025 -4.27442,4.25452 -10.52666,10.9668 -15.19309,14.7998 -4.66636,3.83293 -9.52074,7.44735 -14.54737,10.82729 -5.02655,3.37994 -10.22534,6.52554 -15.58044,9.42095 -5.35513,2.89542 -10.86657,5.54072 -16.51857,7.92009 -5.65193,2.37929 -11.44441,4.49277 -17.36161,6.32461 -5.91713,1.83176 -11.95898,3.38189 -18.10969,4.6346 -6.15071,1.25271 -17.11519,2.20802 -23.46773,2.85008 -6.35262,0.64211 -8.76545,-5.07807 -15.28822,-5.07807 -6.52277,0 -8.26353,5.72018 -14.61598,5.07807 -6.35263,-0.64206 -16.64487,-1.59737 -22.79558,-2.85008 -6.15072,-1.25271 -12.19255,-2.80284 -18.10969,-4.6346 -5.9172,-1.83184 -11.70968,-3.94532 -17.36161,-6.32461 -5.652,-2.37937 -11.16344,-5.02467 -16.51856,-7.92009 -5.35512,-2.89541 -17.85529,-12.0149 -22.88184,-15.39469 -5.02662,-3.38009 -0.58843,-9.64943 -5.2548,-13.48251 -4.66645,-3.83307 -9.1448,2.07188 -13.4193,-2.18272 -4.27456,-4.25452 -10.33669,-10.03943 -14.1877,-14.68395 -3.8511,-4.64443 -7.4825,-9.47613 -10.87843,-14.4791 -3.39586,-5.00305 -6.55624,-10.17743 -9.46532,-15.5074 -2.90909,-5.32996 -5.56686,-10.8155 -7.95741,-16.44099 -2.39062,-5.6255 -4.51402,-11.39074 -6.35441,-17.28023 -1.84048,-5.88934 -3.39789,-11.90281 -4.65654,-18.02468 -1.25856,-6.12181 -2.89053,-18.36775 -3.53567,-24.69041 -0.64519,-6.32273 5.7205,-7.39465 5.7205,-13.88676 0,-6.49213 -6.36569,-7.54722 -5.7205,-13.86996 0.64514,-6.32281 2.27711,-17.24109 3.53567,-23.36291 1.25865,-6.1218 2.81606,-12.13534 4.65654,-18.02469 1.84039,-5.88933 3.96379,-11.65472 6.35441,-17.28015 2.39055,-5.62541 5.04832,-11.11103 7.95741,-16.441 2.90908,-5.32996 6.06946,-10.50427 9.46532,-15.50738 3.39593,-5.00297 10.57478,-15.15578 14.42588,-19.80037 3.85102,-4.64445 9.69561,-2.89378 13.97019,-7.14823 4.27457,-4.25452 -1.00269,-7.41925 3.66376,-11.25226 4.66636,-3.83299 13.95517,-9.22109 18.98179,-12.60109 5.02655,-3.38001 10.22533,-6.52555 15.58045,-9.42095 5.35512,-2.89542 10.86656,-5.54065 16.51856,-7.91994 5.65193,-2.37944 11.44441,-4.49285 17.36161,-6.32468 5.91714,-1.83177 11.95897,-3.38189 18.10969,-4.63461 6.15071,-1.25271 16.44295,-2.88017 22.79558,-3.52222 6.35245,-0.64221 8.09321,4.40597 14.61598,4.40597 6.52277,0 8.26345,-4.376 14.61606,-3.73389 6.35255,0.64213 17.98918,1.59743 24.13989,2.85014 6.15071,1.25272 12.19256,2.80284 18.10969,4.63461 5.9172,1.83183 11.70968,3.94524 17.36161,6.32468 5.652,2.37929 11.16344,5.02452 16.51857,7.91994 5.3551,2.8954 10.55389,6.04094 15.58044,9.42095 5.02663,3.38 17.2185,12.91157 21.18501,17.46493 3.33894,4.49683 0.51597,8.54847 4.79041,12.80292 4.27464,4.25452 10.3366,1.41054 14.18769,6.05498 3.85103,4.64459 7.48243,9.47615 10.87828,14.47912 3.39594,5.00311 6.55632,10.17742 9.46533,15.50738 2.90908,5.32997 5.56686,10.81559 7.95741,16.441 2.39055,5.62543 4.51401,11.39082 6.3544,17.28015 1.84049,5.88935 3.39789,11.90289 4.65646,18.02469 1.25864,6.12182 2.21846,17.729 2.8635,24.05173 0.64521,6.32275 -7.08986,6.68901 -7.08986,13.18114 z"
+ style="font-style:italic;font-weight:bold;font-size:48px;font-family:'Luxi Serif';fill:url(#linearGradient2193);fill-opacity:1;stroke-width:0.75084716"
+ inkscape:connector-curvature="0" /><path
+ id="path726"
+ d="m 579.46913,519.79598 c 0,98.48662 -79.83927,178.32592 -178.32594,178.32592 -98.48666,0 -178.32584,-79.8393 -178.32584,-178.32592 0,-98.48655 79.83918,-178.32586 178.32584,-178.32586 98.48667,0 178.32594,79.83931 178.32594,178.32586 z"
+ style="font-size:12px;fill:url(#linearGradient2195-3);fill-rule:evenodd;stroke-width:0.75084591"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="sssss" /><g
style="font-size:12px;fill:url(#linearGradient2197)"
- transform="matrix(0.710214,0,0,0.665599,45.70086,221.885)"
+ transform="matrix(0.53326215,0,0,0.49976312,134.26036,296.11037)"
id="g944"><path
id="path943"
- d="M 489.2781,157.6309 C 486.7725,158.6472 483.694,159.9616 480.8916,161.4231 C 479.3419,161.0055 475.428,159.2736 475.428,155.3341 C 475.428,151.3946 478.7154,148.2011 482.7708,148.2011 C 488.0788,148.2011 490.7398,151.8121 489.2781,157.6309 z M 521.9314,154.5415 C 521.9314,158.4811 518.0176,160.213 516.6769,160.8394 C 513.0392,159.5867 510.1692,158.6899 508.0812,158.0913 C 505.5757,152.2726 509.2807,147.4085 514.5889,147.4085 C 518.644,147.4085 521.9314,150.6021 521.9314,154.5415 z M 554.0133,282.1463 C 539.7204,299.0921 519.7959,311.7673 487.7231,311.2372 C 455.0333,310.1367 444.7336,294.8341 446.4288,254.5974 C 447.4384,237.4799 453.0554,223.2215 459.4115,212.5429 C 462.707,204.534 471.5472,201.7454 476.9885,177.1512 C 485.6153,185.4841 494.4355,188.3269 497.9466,188.3677 C 504.6303,188.4997 521.1268,180.7489 526.5206,174.9439 C 532.8029,196.1211 539.725,203.2866 544.2499,208.414 C 571.8131,240.2076 557.189,277.6971 554.0133,282.1463 z M 494.2871,157.0588 C 487.7115,157.6404 481.7311,160.3453 477.7269,163.5282 C 475.279,165.2092 472.0644,157.8887 472.0644,152.4116 C 472.0644,145.0207 475.2644,139.5457 483.471,139.5457 C 490.9986,139.5457 495.5149,147.9387 494.2871,157.0588 z M 503.3984,157.4551 C 509.7709,158.1484 517.8879,161.2707 522.7624,163.7729 C 525.4762,165.4536 527.6282,158.285 527.6282,152.8079 C 527.6282,147.0021 523.8588,139.1494 514.7603,139.1494 C 505.191,139.1494 502.0372,145.9572 503.3984,157.4551 z M 504.7202,106.7478 C 474.7132,106.4276 457.1089,126.4945 461.8612,178.9302 C 463.5845,198.2381 361.0517,308.565 481.4685,323.2273 L 525.5737,324.0199 C 606.8295,319.2645 591.7019,249.1051 588.8989,241.103 C 580.6322,213.4795 553.1952,187.4526 553.0018,172.6248 C 552.814,127.3526 535.8651,106.2749 504.7202,106.7478 z M 529.3964,169.2447 C 529.7524,177.204 506.4211,188.5796 497.5232,188.5796 C 490.247,188.5796 473.2299,177.6226 472.7098,170.2413 C 472.4321,166.698 484.8286,156.8974 498.0721,157.1776 C 508.6449,157.1776 529.106,164.0661 529.3964,169.2447 z M 505.6319,158.6713 C 504.8923,159.1122 502.5108,159.8841 502.2685,159.8142 C 501.7591,159.7069 502.9358,158.8886 503.1344,158.3848 C 503.3119,157.9112 506.3718,158.2303 505.6319,158.6713 z M 491.2411,158.3369 C 491.2346,158.7713 491.7574,159.5856 492.1907,159.5931 C 492.5879,159.0685 492.9824,158.6462 493.4274,158.2207 C 493.8848,157.8292 491.2476,157.996 491.2411,158.3369 z M 475.86,171.0084 C 475.1974,169.8919 481.8043,180.5114 494.4183,180.9245 C 505.2062,181.3048 518.8716,172.4247 527.1629,168.9206 C 494.2345,184.859 489.641,183.0493 475.86,171.0084 z M 532.9812,126.1648 C 531.3254,129.0911 525.7228,129.7142 520.4675,127.5566 C 515.2121,125.3989 512.294,121.2776 513.9498,118.3513 C 515.6056,115.425 521.2082,114.8019 526.4636,116.9596 C 531.7189,119.1172 534.6369,123.2386 532.9812,126.1648 z "
- style="font-size:12px;fill:url(#linearGradient2199);fill-rule:evenodd" /><path
+ d="m 489.2781,157.6309 c -2.5056,1.0163 -5.5841,2.3307 -8.3865,3.7922 -1.5497,-0.4176 -5.4636,-2.1495 -5.4636,-6.089 0,-3.9395 3.2874,-7.133 7.3428,-7.133 5.308,0 7.969,3.611 6.5073,9.4298 z m 32.6533,-3.0894 c 0,3.9396 -3.9138,5.6715 -5.2545,6.2979 -3.6377,-1.2527 -6.5077,-2.1495 -8.5957,-2.7481 -2.5055,-5.8187 1.1995,-10.6828 6.5077,-10.6828 4.0551,0 7.3425,3.1936 7.3425,7.133 z m 32.0819,127.6048 c -14.2929,16.9458 -34.2174,29.621 -66.2902,29.0909 -32.6898,-1.1005 -42.9895,-16.4031 -41.2943,-56.6398 1.0096,-17.1175 6.6266,-31.3759 12.9827,-42.0545 3.2955,-8.0089 12.1357,-10.7975 17.577,-35.3917 8.6268,8.3329 17.447,11.1757 20.9581,11.2165 6.6837,0.132 23.1802,-7.6188 28.574,-13.4238 6.2823,21.1772 13.2044,28.3427 17.7293,33.4701 27.5632,31.7936 12.9391,69.2831 9.7634,73.7323 z M 494.2871,157.0588 c -6.5756,0.5816 -12.556,3.2865 -16.5602,6.4694 -2.4479,1.681 -5.6625,-5.6395 -5.6625,-11.1166 0,-7.3909 3.2,-12.8659 11.4066,-12.8659 7.5276,0 12.0439,8.393 10.8161,17.5131 z m 9.1113,0.3963 c 6.3725,0.6933 14.4895,3.8156 19.364,6.3178 2.7138,1.6807 4.8658,-5.4879 4.8658,-10.965 0,-5.8058 -3.7694,-13.6585 -12.8679,-13.6585 -9.5693,0 -12.7231,6.8078 -11.3619,18.3057 z m 1.3218,-50.7073 c -30.007,-0.3202 -47.6113,19.7467 -42.859,72.1824 1.7233,19.3079 -100.8095,129.6348 19.6073,144.2971 l 44.1052,0.7926 c 81.2558,-4.7554 66.1282,-74.9148 63.3252,-82.9169 -8.2667,-27.6235 -35.7037,-53.6504 -35.8971,-68.4782 -0.1878,-45.2722 -17.1367,-66.3499 -48.2816,-65.877 z m 24.6762,62.4969 c 0.356,7.9593 -22.9753,19.3349 -31.8732,19.3349 -7.2762,0 -24.2933,-10.957 -24.8134,-18.3383 -0.2777,-3.5433 12.1188,-13.3439 25.3623,-13.0637 10.5728,0 31.0339,6.8885 31.3243,12.0671 z m -23.7645,-10.5734 c -0.7396,0.4409 -3.1211,1.2128 -3.3634,1.1429 -0.5094,-0.1073 0.6673,-0.9256 0.8659,-1.4294 0.1775,-0.4736 3.2374,-0.1545 2.4975,0.2865 z m -14.3908,-0.3344 c -0.007,0.4344 0.5163,1.2487 0.9496,1.2562 0.3972,-0.5246 0.7917,-0.9469 1.2367,-1.3724 0.4574,-0.3915 -2.1798,-0.2247 -2.1863,0.1162 z M 475.86,171.0084 c -0.6626,-1.1165 5.9443,9.503 18.5583,9.9161 10.7879,0.3803 24.4533,-8.4998 32.7446,-12.0039 -32.9284,15.9384 -37.5219,14.1287 -51.3029,2.0878 z m 57.1212,-44.8436 c -1.6558,2.9263 -7.2584,3.5494 -12.5137,1.3918 -5.2554,-2.1577 -8.1735,-6.279 -6.5177,-9.2053 1.6558,-2.9263 7.2584,-3.5494 12.5138,-1.3917 5.2553,2.1576 8.1733,6.279 6.5176,9.2052 z"
+ style="font-size:12px;fill:url(#linearGradient2199);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /><path
transform="matrix(1.381431,0,0,1.342002,-335.1481,-21.47379)"
sodipodi:nodetypes="cccccccccccccccccccccc"
id="path871"
- d="M 594.8524,209.0117 C 594.8524,220.1016 597.3741,225.5481 596.0694,225.5481 C 594.7647,225.5481 591.5893,219.8928 591.5893,208.8029 C 591.5893,197.7133 595.8087,185.5974 597.1134,185.5974 C 598.4181,185.5974 594.8524,197.9221 594.8524,209.0117 z M 632.27,169.5802 C 636.4462,173.2967 639.9597,177.6751 641.0037,183.062 C 633.8452,176.8398 621.8843,173.9586 614.9343,172.3301 C 621.0488,172.1213 630.1226,172.5034 632.27,169.5802 z M 595.6275,172.1593 C 597.9116,174.2791 597.2725,175.7726 598.0951,178.5188 C 598.4549,175.911 602.5729,173.9295 604.8118,171.9481 C 601.9592,172.4361 598.4801,172.5065 595.6275,172.1593 z M 578.9845,168.302 C 576.6727,170.9576 573.7897,175.239 570.9888,182.7921 C 576.8947,176.1524 582.6886,175.629 589.2209,172.9565 C 583.3151,172.7478 581.1318,171.2251 578.9845,168.302 z M 624.5364,145.5447 C 621.5836,154.254 608.0056,162.0592 600.9178,162.0592 C 596.7828,162.0592 588.4029,155.7413 586.9264,147.0322 C 592.4305,152.4557 598.446,156.1755 603.0832,156.3597 C 608.2112,156.4881 619.7769,150.57 624.5364,145.5447 z "
- style="font-size:12px;fill:url(#linearGradient2201);fill-rule:evenodd" /><path
+ d="m 594.8524,209.0117 c 0,11.0899 2.5217,16.5364 1.217,16.5364 -1.3047,0 -4.4801,-5.6553 -4.4801,-16.7452 0,-11.0896 4.2194,-23.2055 5.5241,-23.2055 1.3047,0 -2.261,12.3247 -2.261,23.4143 z M 632.27,169.5802 c 4.1762,3.7165 7.6897,8.0949 8.7337,13.4818 -7.1585,-6.2222 -19.1194,-9.1034 -26.0694,-10.7319 6.1145,-0.2088 15.1883,0.1733 17.3357,-2.7499 z m -36.6425,2.5791 c 2.2841,2.1198 1.645,3.6133 2.4676,6.3595 0.3598,-2.6078 4.4778,-4.5893 6.7167,-6.5707 -2.8526,0.488 -6.3317,0.5584 -9.1843,0.2112 z m -16.643,-3.8573 c -2.3118,2.6556 -5.1948,6.937 -7.9957,14.4901 5.9059,-6.6397 11.6998,-7.1631 18.2321,-9.8356 -5.9058,-0.2087 -8.0891,-1.7314 -10.2364,-4.6545 z m 45.5519,-22.7573 c -2.9528,8.7093 -16.5308,16.5145 -23.6186,16.5145 -4.135,0 -12.5149,-6.3179 -13.9914,-15.027 5.5041,5.4235 11.5196,9.1433 16.1568,9.3275 5.128,0.1284 16.6937,-5.7897 21.4532,-10.815 z"
+ style="font-size:12px;fill:url(#linearGradient2201);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /><path
transform="matrix(1.381431,0,0,1.342002,-335.1483,-21.47379)"
sodipodi:nodetypes="csccc"
id="path758"
- d="M 566.1781,204.0047 C 566.1781,224.5982 593.4836,225.0052 587.8079,232.522 C 582.6399,239.91 550.7196,226.5353 550.7196,205.9419 C 552.8076,190.3594 555.5661,185.5046 574.6452,156.366 C 587.5403,159.1975 566.1781,183.4112 566.1781,204.0047 z "
- style="font-size:12px;fill:url(#linearGradient2203);fill-rule:evenodd" /><g
+ d="m 566.1781,204.0047 c 0,20.5935 27.3055,21.0005 21.6298,28.5173 -5.168,7.388 -37.0883,-5.9867 -37.0883,-26.5801 2.088,-15.5825 4.8465,-20.4373 23.9256,-49.5759 12.8951,2.8315 -8.4671,27.0452 -8.4671,47.6387 z"
+ style="font-size:12px;fill:url(#linearGradient2203);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /><g
style="font-size:12px;fill:url(#linearGradient2205)"
transform="matrix(1.381431,0,0,1.342002,-325.2191,-15.60249)"
id="g1065"><path
transform="translate(-7.1875,-4.375031)"
sodipodi:nodetypes="csssscsss"
id="path842"
- d="M 662.6023,249.8415 C 652.9563,254.7202 643.0236,269.4045 630.2927,263.3619 C 621.3526,259.2146 625.6634,249.1638 625.1563,243.5311 C 624.668,230.5505 623.5071,211.1312 631.9468,211.184 C 642.1547,211.246 638.0258,215.2545 645.4196,217.3441 C 653.505,219.306 658.7389,209.0467 664.847,213.6095 C 669.4787,219.944 664.6217,223.322 670.205,229.4906 C 673.1685,233.0602 677.7506,232.9839 680.3539,235.8973 C 685.7736,241.3478 668.3201,246.6544 662.6023,249.8415 z "
- style="font-size:12px;fill:url(#linearGradient2207);fill-rule:evenodd" /><path
+ d="m 662.6023,249.8415 c -9.646,4.8787 -19.5787,19.563 -32.3096,13.5204 -8.9401,-4.1473 -4.6293,-14.1981 -5.1364,-19.8308 -0.4883,-12.9806 -1.6492,-32.3999 6.7905,-32.3471 10.2079,0.062 6.079,4.0705 13.4728,6.1601 8.0854,1.9619 13.3193,-8.2974 19.4274,-3.7346 4.6317,6.3345 -0.2253,9.7125 5.358,15.8811 2.9635,3.5696 7.5456,3.4933 10.1489,6.4067 5.4197,5.4505 -12.0338,10.7571 -17.7516,13.9442 z"
+ style="font-size:12px;fill:url(#linearGradient2207);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /><path
transform="translate(-7.1875,-4.375031)"
sodipodi:nodetypes="cssssssss"
id="path843"
- d="M 550.8908,255.4014 C 562.5947,256.6532 574.367,267.8037 584.6032,256.5396 C 591.8317,248.7246 584.743,239.3914 580.5155,234.7902 C 570.7341,224.8274 565.2408,206.427 556.2229,206.4986 C 548.5882,206.8092 550.0632,210.9825 544.7009,215.234 C 537.4953,220.6488 532.9891,216.239 528.6392,223.1506 C 525.9871,226.8955 526.7585,231.7788 527.8864,236.9511 C 528.6785,241.8714 527.0976,242.9494 525.4163,244.55 C 519.9332,250.7329 540.853,254.0325 550.8908,255.4014 z "
- style="font-size:12px;fill:url(#linearGradient2209);fill-rule:evenodd" /></g><path
+ d="m 550.8908,255.4014 c 11.7039,1.2518 23.4762,12.4023 33.7124,1.1382 7.2285,-7.815 0.1398,-17.1482 -4.0877,-21.7494 -9.7814,-9.9628 -15.2747,-28.3632 -24.2926,-28.2916 -7.6347,0.3106 -6.1597,4.4839 -11.522,8.7354 -7.2056,5.4148 -11.7118,1.005 -16.0617,7.9166 -2.6521,3.7449 -1.8807,8.6282 -0.7528,13.8005 0.7921,4.9203 -0.7888,5.9983 -2.4701,7.5989 -5.4831,6.1829 15.4367,9.4825 25.4745,10.8514 z"
+ style="font-size:12px;fill:url(#linearGradient2209);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /></g><path
transform="matrix(1.381431,0,0,1.342002,-335.1483,-21.47379)"
sodipodi:nodetypes="cscss"
id="path857"
- d="M 649.8842,196.2501 C 649.4318,220.8146 631.991,220.9147 636.6064,229.3612 C 642.8768,241.2543 669.5186,218.7807 669.5186,198.1874 C 669.5186,178.0113 641.3187,150.3852 638.2491,152.2475 C 619.1027,166.4884 650.6787,175.7879 649.8842,196.2501 z "
- style="font-size:12px;fill:url(#linearGradient2211);fill-rule:evenodd" /></g></g></svg>
\ No newline at end of file
+ d="m 649.8842,196.2501 c -0.4524,24.5645 -17.8932,24.6646 -13.2778,33.1111 6.2704,11.8931 32.9122,-10.5805 32.9122,-31.1738 0,-20.1761 -28.1999,-47.8022 -31.2695,-45.9399 -19.1464,14.2409 12.4296,23.5404 11.6351,44.0026 z"
+ style="font-size:12px;fill:url(#linearGradient2211);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /></g><path
+ style="opacity:1;vector-effect:none;fill:#fcfcfc;fill-opacity:1;stroke:none;stroke-width:10.71428585;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ d="m 447.04218,468.15696 c -17.01758,0 -30.97956,8.57673 -43.63352,26.37556 -16.36313,22.94544 -25.30832,54.03975 -25.30832,87.06404 0,33.23872 11.34444,49.32337 34.90723,49.32337 23.34459,0 42.32673,-15.22574 55.41714,-44.60449 9.38147,-20.80102 15.05231,-46.96416 15.05231,-69.69516 0,-32.16652 -12.21755,-48.46332 -36.43484,-48.46332 z m -105.4562,0.84752 c -12.57737,0 -24.42528,2.61342 -39.91909,8.70955 l -4.92187,29.39104 h 12.21261 l 0.36411,-1.95871 1.64063,-8.70954 c 2.00514,-10.88586 9.11461,-16.98172 20.23368,-16.98172 11.11906,0 16.40625,6.74955 16.40625,20.90122 0,16.98199 -6.74508,34.39968 -18.41099,48.11593 l -14.76562,17.19937 -6.01424,6.74873 -10.75404,12.19169 c -9.66085,10.88586 -17.31786,22.86131 -23.15082,35.48898 l -1.82268,10.45061 h 81.29674 l 4.55775,-26.34417 h -55.96121 c 2.18736,-9.79737 7.47448,-19.1589 16.40625,-28.30287 l 7.65485,-8.05664 c 2.55199,-2.61264 7.83898,-7.18399 14.76563,-12.62695 26.43064,-20.90097 34.08692,-33.09303 34.08692,-54.42941 0,-21.11863 -11.30211,-31.78711 -33.90486,-31.78711 z m 103.49331,8.80161 c 6.76333,0 10.03626,4.50359 10.03626,13.93904 0,23.58884 -12.21864,84.70493 -22.4728,112.36816 -4.58167,12.43771 -8.94494,17.15542 -16.14467,17.15542 -6.76332,0 -10.03626,-4.50249 -10.03626,-13.72349 0,-8.14896 1.30878,-18.87009 3.49051,-30.8789 l 5.01813,-27.0201 c 4.5816,-23.8032 8.50984,-39.67199 13.09152,-52.32421 4.79978,-14.15325 9.59939,-19.51592 17.01731,-19.51592 z m 114.76003,51.03935 c 0,-1.07222 0,-1.0725 0,3.21638 0,0 0,-2.14416 0,-3.21638 z m -32.12611,37.86621 c -23.95509,0 -42.28794,18.19617 -42.28794,41.9908 0,14.93 9.7691,23.32867 27.30049,23.32867 5.48688,0 10.97362,-0.81761 19.13714,-2.91712 l 1.87291,-8.51494 c -6.02224,2.21621 -10.84086,3.14942 -14.98954,3.14942 -8.83258,0 -13.11453,-4.31468 -13.11453,-13.17941 0,-8.39807 2.54382,-18.43008 6.96009,-27.41141 3.74717,-7.46499 8.16307,-11.19768 13.24847,-11.19768 3.88098,0 5.75474,2.33425 5.75474,6.99986 v 0.46666 0.93331 l -0.66964,4.19782 -0.26786,1.05051 h 10.97378 l 3.74791,-16.09655 c -6.15603,-1.98284 -11.64377,-2.79994 -17.66602,-2.79994 z"
+ id="path860"
+ inkscape:connector-curvature="0" /></g></svg>
\ No newline at end of file
diff --git a/src/activities/money/resource/c2c.svg b/src/activities/money/resource/c2c.svg
index c41a7918b..31c2e1a31 100644
--- a/src/activities/money/resource/c2c.svg
+++ b/src/activities/money/resource/c2c.svg
@@ -1,221 +1,230 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="svg699"
sodipodi:version="0.32"
width="503.34711"
height="500.98511"
xml:space="preserve"
sodipodi:docname="c2c.svg"
- inkscape:version="0.91 r13725"
+ inkscape:version="0.92.1 r15371"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
sodipodi:modified="true"
version="1.0"><metadata
id="metadata34"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs701"><linearGradient
id="linearGradient651"><stop
style="stop-color:#c73500;stop-opacity:1;"
offset="0"
id="stop652" /><stop
style="stop-color:#ffb76b;stop-opacity:1;"
offset="1"
id="stop653" /></linearGradient><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2200"
- gradientTransform="scale(1.0023546,0.9976509)"
+ gradientTransform="matrix(0.65024934,0,0,0.64719795,139.4753,183.84957)"
spreadMethod="pad"
x1="673.50358"
y1="300.07902"
x2="225.41876"
y2="504.08385"
gradientUnits="userSpaceOnUse" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="radialGradient2202"
cx="530.08106"
cy="546.61578"
fx="530.08106"
fy="546.61578"
r="69.522829"
- gradientTransform="scale(0.8853156,1.1295408)"
+ gradientTransform="matrix(0.57432358,0,0,0.73275781,141.07186,182.75164)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2204"
x1="164.09622"
y1="520.24765"
x2="639.09577"
y2="520.24765"
- gradientUnits="userSpaceOnUse" /><radialGradient
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.64872186,0,0,0.64872186,141.07186,182.75164)" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="radialGradient2206"
spreadMethod="reflect"
cx="433.9216"
cy="140.66141"
fx="433.9216"
fy="140.66141"
r="171.15651"
gradientTransform="scale(0.9767462,1.0238074)"
gradientUnits="userSpaceOnUse" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="radialGradient2208"
spreadMethod="reflect"
cx="509.78629"
cy="125.58794"
fx="509.78629"
fy="125.58794"
r="147.84009"
gradientTransform="scale(0.8819901,1.1337996)"
gradientUnits="userSpaceOnUse" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="radialGradient2210"
spreadMethod="reflect"
cx="622.2407"
cy="148.43647"
fx="622.2407"
fy="148.43647"
r="57.737566"
gradientTransform="scale(0.935494,1.0689539)"
gradientUnits="userSpaceOnUse" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="radialGradient2212"
spreadMethod="reflect"
cx="800.13412"
cy="117.72797"
fx="800.13412"
fy="117.72797"
r="41.981818"
gradientTransform="scale(0.6957958,1.4372033)"
gradientUnits="userSpaceOnUse" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="radialGradient2214"
spreadMethod="reflect"
cx="330.55496"
cy="347.24556"
fx="330.55496"
fy="347.24556"
r="73.774761"
gradientTransform="scale(1.6403562,0.6096237)"
gradientUnits="userSpaceOnUse" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="radialGradient2216"
spreadMethod="reflect"
cx="615.38471"
cy="226.48331"
fx="615.38471"
fy="226.48331"
r="42.582778"
gradientTransform="scale(1.0295592,0.9712894)"
gradientUnits="userSpaceOnUse" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="radialGradient2218"
spreadMethod="reflect"
cx="498.82588"
cy="230.96165"
fx="498.82588"
fy="230.96165"
r="45.493906"
gradientTransform="scale(1.0716088,0.9331764)"
gradientUnits="userSpaceOnUse" /><radialGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="radialGradient2220"
spreadMethod="reflect"
cx="935.56135"
cy="112.77513"
fx="935.56135"
fy="112.77513"
r="42.356219"
gradientTransform="scale(0.6819639,1.4663532)"
gradientUnits="userSpaceOnUse" /></defs><sodipodi:namedview
id="base"
inkscape:zoom="0.36014217"
- inkscape:cx="372.04724"
+ inkscape:cx="-813.59564"
inkscape:cy="526.18109"
- inkscape:window-width="1366"
- inkscape:window-height="713"
- inkscape:window-x="-2"
- inkscape:window-y="-3"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
inkscape:current-layer="g2186"
showgrid="false"
inkscape:window-maximized="1" /><g
id="g2186"
transform="translate(-149.92241,-269.75517)"><path
- transform="translate(-2.46109,1.692474)"
sodipodi:nodetypes="ccccccc"
id="path687"
- d="M 655.7306,518.5551 C 655.7306,656.8984 543.0531,769.0478 404.0571,769.0478 C 265.0618,769.0478 152.3835,656.8984 152.3835,518.5551 C 152.3835,380.2119 265.0618,268.0627 404.0571,268.0627 C 543.0531,268.0627 655.7306,380.2119 655.7306,518.5551 z M 396.9986,636.0575 L 396.9986,636.0575 z "
- style="font-size:48px;font-style:italic;font-weight:bold;fill:url(#linearGradient2200);fill-opacity:1;stroke-width:1;font-family:Luxi Serif" /><rect
- y="547.896"
- x="400.90024"
- height="123.6109"
- width="96.884201"
+ d="m 564.8621,520.24762 c 0,89.74634 -73.09636,162.5001 -163.2661,162.5001 -90.1693,0 -163.26618,-72.75376 -163.26618,-162.5001 0,-89.74626 73.09688,-162.4999 163.26618,-162.4999 90.16974,0 163.2661,72.75364 163.2661,162.4999 z m -167.84512,76.22639 z"
+ style="font-style:italic;font-weight:bold;font-size:48px;font-family:'Luxi Serif';fill:url(#linearGradient2200);fill-opacity:1;stroke-width:0.64872187"
+ inkscape:connector-curvature="0" /><rect
+ y="538.18378"
+ x="401.14465"
+ height="80.189102"
+ width="62.850903"
id="rect713"
- style="font-size:12px;fill:url(#radialGradient2202);fill-rule:evenodd;stroke-width:1" /><rect
- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.50000000000000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ style="font-size:12px;fill:url(#radialGradient2202);fill-rule:evenodd;stroke-width:0.64872187" /><rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.27052665;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect7178"
- width="316.54166"
- height="299.88156"
- x="191.57263"
- y="382.00491"
- ry="104.67665" /><path
+ width="205.3475"
+ height="194.53973"
+ x="265.34924"
+ y="430.56659"
+ ry="67.906036" /><path
id="path746"
- d="M 462.5704,635.2231 C 455.7123,637.8353 450.2259,638.9352 445.5015,638.9352 C 435.443,638.9352 430.5661,633.8482 430.5661,623.3992 C 430.5661,613.5002 433.4618,601.6763 438.491,591.0898 C 442.7582,582.2907 447.7875,577.8911 453.5787,577.8911 C 457.9983,577.8911 460.132,580.6408 460.132,586.1403 L 460.132,586.6903 L 460.132,587.7902 L 459.37,592.7397 L 459.0652,593.9771 L 471.562,593.9771 L 475.8293,575.0039 C 468.8188,572.6666 462.5704,571.7042 455.7123,571.7042 C 428.4325,571.7042 407.5536,593.1521 407.5536,621.1994 C 407.5536,638.7977 418.6789,648.6968 438.6434,648.6968 C 444.8919,648.6968 451.1403,647.7344 460.4368,645.2596 L 462.5704,635.2231 z M 217.1752,648.0641 C 243.7075,647.6965 291.624,646.9611 306.2761,646.9611 C 312.6122,646.9611 312.6122,646.9611 383.4968,648.0641 C 389.4369,625.6359 391.4169,619.3854 396.565,610.1935 L 393.3969,607.9875 C 380.3288,610.1935 372.0127,610.9289 360.9246,610.9289 L 271.4278,610.9289 L 358.9446,529.3048 C 381.9128,507.9797 394.981,482.2423 394.981,458.3434 C 394.981,420.8405 366.0727,395.8385 322.1163,395.8385 C 300.7321,395.8385 284.4959,400.986 264.2997,414.59 L 242.1235,464.5939 L 254.0036,467.903 L 259.5477,459.0788 C 274.1998,435.9152 284.4959,428.9293 304.2961,428.9293 C 330.0363,428.9293 346.6685,443.6364 346.6685,466.4323 C 346.6685,503.1999 315.7802,550.2624 255.5876,604.3107 L 217.1752,638.8722 L 217.1752,648.0641 z M 639.0957,520.2476 C 639.0957,651.4152 532.7637,757.7475 401.5958,757.7475 C 270.4286,757.7475 164.0962,651.4152 164.0962,520.2476 C 164.0962,389.0801 270.4286,282.7479 401.5958,282.7479 C 532.7637,282.7479 639.0957,389.0801 639.0957,520.2476 z M 390.9698,631.2727 L 390.9698,631.2727 z "
- style="font-size:48px;font-style:italic;font-weight:bold;fill:url(#linearGradient2204);stroke-width:1;font-family:Luxi Serif" /><g
+ d="m 441.15141,594.83477 c -4.449,1.69459 -8.00814,2.40812 -11.07297,2.40812 -6.52516,0 -9.68892,-3.30005 -9.68892,-10.07855 0,-6.42169 1.87851,-14.09212 5.14106,-20.95981 2.76823,-5.70817 6.03084,-8.56229 9.78772,-8.56229 2.8671,0 4.25127,1.7838 4.25127,5.35144 v 0.3568 0.71352 l -0.49432,3.21085 -0.19773,0.80273 h 8.10695 l 2.76828,-12.30832 c -4.54786,-1.51626 -8.60134,-2.14059 -13.05034,-2.14059 -17.697,0 -31.2416,13.91372 -31.2416,32.10862 0,11.41639 7.21723,17.83817 20.16863,17.83817 4.05354,0 8.10702,-0.62434 14.13786,-2.2298 z M 281.95818,603.165 c 17.21208,-0.23846 48.29657,-0.71554 57.8017,-0.71554 4.11036,0 4.11036,0 50.09476,0.71554 3.85348,-14.54966 5.13794,-18.60449 8.47763,-24.56748 l -2.05522,-1.43109 c -8.47756,1.43109 -13.8724,1.90815 -21.0655,1.90815 h -58.05853 l 56.77407,-52.95134 c 14.89997,-13.83405 23.3776,-30.53046 23.3776,-46.03421 0,-24.32895 -18.75345,-40.54829 -47.26892,-40.54829 -13.8724,0 -24.40519,3.33929 -37.5069,12.1645 l -14.38618,32.43863 7.70688,2.14669 3.59658,-5.72445 c 9.50513,-15.02674 16.18443,-19.55864 29.02926,-19.55864 16.69824,0 27.4879,9.54082 27.4879,24.32901 0,23.85195 -20.03791,54.38242 -59.08617,89.44473 l -24.91896,22.42081 z m 273.70906,-82.91736 c 0,85.0913 -68.97989,154.07139 -154.07138,154.07139 -85.09104,0 -154.07119,-68.98009 -154.07119,-154.07139 0,-85.09122 68.98015,-154.07125 154.07119,-154.07125 85.09149,0 154.07138,68.98003 154.07138,154.07125 z m -160.9647,72.02441 z"
+ style="font-style:italic;font-weight:bold;font-size:48px;font-family:'Luxi Serif';fill:url(#linearGradient2204);stroke-width:0.64872187"
+ inkscape:connector-curvature="0" /><g
style="font-size:12px;fill:url(#radialGradient2206)"
- transform="matrix(1.081439,0,0,1.058679,-45.76,217.3552)"
+ transform="matrix(0.70155315,0,0,0.68678825,111.38636,323.75471)"
id="g944"><path
id="path943"
- d="M 489.2781,157.6309 C 486.7725,158.6472 483.694,159.9616 480.8916,161.4231 C 479.3419,161.0055 475.428,159.2736 475.428,155.3341 C 475.428,151.3946 478.7154,148.2011 482.7708,148.2011 C 488.0788,148.2011 490.7398,151.8121 489.2781,157.6309 z M 521.9314,154.5415 C 521.9314,158.4811 518.0176,160.213 516.6769,160.8394 C 513.0392,159.5867 510.1692,158.6899 508.0812,158.0913 C 505.5757,152.2726 509.2807,147.4085 514.5889,147.4085 C 518.644,147.4085 521.9314,150.6021 521.9314,154.5415 z M 554.0133,282.1463 C 539.7204,299.0921 519.7959,311.7673 487.7231,311.2372 C 455.0333,310.1367 444.7336,294.8341 446.4288,254.5974 C 447.4384,237.4799 453.0554,223.2215 459.4115,212.5429 C 462.707,204.534 471.5472,201.7454 476.9885,177.1512 C 485.6153,185.4841 494.4355,188.3269 497.9466,188.3677 C 504.6303,188.4997 521.1268,180.7489 526.5206,174.9439 C 532.8029,196.1211 539.725,203.2866 544.2499,208.414 C 571.8131,240.2076 557.189,277.6971 554.0133,282.1463 z M 494.2871,157.0588 C 487.7115,157.6404 481.7311,160.3453 477.7269,163.5282 C 475.279,165.2092 472.0644,157.8887 472.0644,152.4116 C 472.0644,145.0207 475.2644,139.5457 483.471,139.5457 C 490.9986,139.5457 495.5149,147.9387 494.2871,157.0588 z M 503.3984,157.4551 C 509.7709,158.1484 517.8879,161.2707 522.7624,163.7729 C 525.4762,165.4536 527.6282,158.285 527.6282,152.8079 C 527.6282,147.0021 523.8588,139.1494 514.7603,139.1494 C 505.191,139.1494 502.0372,145.9572 503.3984,157.4551 z M 504.7202,106.7478 C 474.7132,106.4276 457.1089,126.4945 461.8612,178.9302 C 463.5845,198.2381 361.0517,308.565 481.4685,323.2273 L 525.5737,324.0199 C 606.8295,319.2645 591.7019,249.1051 588.8989,241.103 C 580.6322,213.4795 553.1952,187.4526 553.0018,172.6248 C 552.814,127.3526 535.8651,106.2749 504.7202,106.7478 z M 529.3964,169.2447 C 529.7524,177.204 506.4211,188.5796 497.5232,188.5796 C 490.247,188.5796 473.2299,177.6226 472.7098,170.2413 C 472.4321,166.698 484.8286,156.8974 498.0721,157.1776 C 508.6449,157.1776 529.106,164.0661 529.3964,169.2447 z M 505.6319,158.6713 C 504.8923,159.1122 502.5108,159.8841 502.2685,159.8142 C 501.7591,159.7069 502.9358,158.8886 503.1344,158.3848 C 503.3119,157.9112 506.3718,158.2303 505.6319,158.6713 z M 491.2411,158.3369 C 491.2346,158.7713 491.7574,159.5856 492.1907,159.5931 C 492.5879,159.0685 492.9824,158.6462 493.4274,158.2207 C 493.8848,157.8292 491.2476,157.996 491.2411,158.3369 z M 475.86,171.0084 C 475.1974,169.8919 481.8043,180.5114 494.4183,180.9245 C 505.2062,181.3048 518.8716,172.4247 527.1629,168.9206 C 494.2345,184.859 489.641,183.0493 475.86,171.0084 z M 532.9812,126.1648 C 531.3254,129.0911 525.7228,129.7142 520.4675,127.5566 C 515.2121,125.3989 512.294,121.2776 513.9498,118.3513 C 515.6056,115.425 521.2082,114.8019 526.4636,116.9596 C 531.7189,119.1172 534.6369,123.2386 532.9812,126.1648 z "
- style="font-size:12px;fill:url(#radialGradient2208);fill-rule:evenodd" /><path
+ d="m 489.2781,157.6309 c -2.5056,1.0163 -5.5841,2.3307 -8.3865,3.7922 -1.5497,-0.4176 -5.4636,-2.1495 -5.4636,-6.089 0,-3.9395 3.2874,-7.133 7.3428,-7.133 5.308,0 7.969,3.611 6.5073,9.4298 z m 32.6533,-3.0894 c 0,3.9396 -3.9138,5.6715 -5.2545,6.2979 -3.6377,-1.2527 -6.5077,-2.1495 -8.5957,-2.7481 -2.5055,-5.8187 1.1995,-10.6828 6.5077,-10.6828 4.0551,0 7.3425,3.1936 7.3425,7.133 z m 32.0819,127.6048 c -14.2929,16.9458 -34.2174,29.621 -66.2902,29.0909 -32.6898,-1.1005 -42.9895,-16.4031 -41.2943,-56.6398 1.0096,-17.1175 6.6266,-31.3759 12.9827,-42.0545 3.2955,-8.0089 12.1357,-10.7975 17.577,-35.3917 8.6268,8.3329 17.447,11.1757 20.9581,11.2165 6.6837,0.132 23.1802,-7.6188 28.574,-13.4238 6.2823,21.1772 13.2044,28.3427 17.7293,33.4701 27.5632,31.7936 12.9391,69.2831 9.7634,73.7323 z M 494.2871,157.0588 c -6.5756,0.5816 -12.556,3.2865 -16.5602,6.4694 -2.4479,1.681 -5.6625,-5.6395 -5.6625,-11.1166 0,-7.3909 3.2,-12.8659 11.4066,-12.8659 7.5276,0 12.0439,8.393 10.8161,17.5131 z m 9.1113,0.3963 c 6.3725,0.6933 14.4895,3.8156 19.364,6.3178 2.7138,1.6807 4.8658,-5.4879 4.8658,-10.965 0,-5.8058 -3.7694,-13.6585 -12.8679,-13.6585 -9.5693,0 -12.7231,6.8078 -11.3619,18.3057 z m 1.3218,-50.7073 c -30.007,-0.3202 -47.6113,19.7467 -42.859,72.1824 1.7233,19.3079 -100.8095,129.6348 19.6073,144.2971 l 44.1052,0.7926 c 81.2558,-4.7554 66.1282,-74.9148 63.3252,-82.9169 -8.2667,-27.6235 -35.7037,-53.6504 -35.8971,-68.4782 -0.1878,-45.2722 -17.1367,-66.3499 -48.2816,-65.877 z m 24.6762,62.4969 c 0.356,7.9593 -22.9753,19.3349 -31.8732,19.3349 -7.2762,0 -24.2933,-10.957 -24.8134,-18.3383 -0.2777,-3.5433 12.1188,-13.3439 25.3623,-13.0637 10.5728,0 31.0339,6.8885 31.3243,12.0671 z m -23.7645,-10.5734 c -0.7396,0.4409 -3.1211,1.2128 -3.3634,1.1429 -0.5094,-0.1073 0.6673,-0.9256 0.8659,-1.4294 0.1775,-0.4736 3.2374,-0.1545 2.4975,0.2865 z m -14.3908,-0.3344 c -0.007,0.4344 0.5163,1.2487 0.9496,1.2562 0.3972,-0.5246 0.7917,-0.9469 1.2367,-1.3724 0.4574,-0.3915 -2.1798,-0.2247 -2.1863,0.1162 z M 475.86,171.0084 c -0.6626,-1.1165 5.9443,9.503 18.5583,9.9161 10.7879,0.3803 24.4533,-8.4998 32.7446,-12.0039 -32.9284,15.9384 -37.5219,14.1287 -51.3029,2.0878 z m 57.1212,-44.8436 c -1.6558,2.9263 -7.2584,3.5494 -12.5137,1.3918 -5.2554,-2.1577 -8.1735,-6.279 -6.5177,-9.2053 1.6558,-2.9263 7.2584,-3.5494 12.5138,-1.3917 5.2553,2.1576 8.1733,6.279 6.5176,9.2052 z"
+ style="font-size:12px;fill:url(#radialGradient2208);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /><path
transform="matrix(1.381431,0,0,1.342002,-335.1481,-21.47379)"
sodipodi:nodetypes="cccccccccccccccccccccc"
id="path871"
- d="M 594.8524,209.0117 C 594.8524,220.1016 597.3741,225.5481 596.0694,225.5481 C 594.7647,225.5481 591.5893,219.8928 591.5893,208.8029 C 591.5893,197.7133 595.8087,185.5974 597.1134,185.5974 C 598.4181,185.5974 594.8524,197.9221 594.8524,209.0117 z M 632.27,169.5802 C 636.4462,173.2967 639.9597,177.6751 641.0037,183.062 C 633.8452,176.8398 621.8843,173.9586 614.9343,172.3301 C 621.0488,172.1213 630.1226,172.5034 632.27,169.5802 z M 595.6275,172.1593 C 597.9116,174.2791 597.2725,175.7726 598.0951,178.5188 C 598.4549,175.911 602.5729,173.9295 604.8118,171.9481 C 601.9592,172.4361 598.4801,172.5065 595.6275,172.1593 z M 578.9845,168.302 C 576.6727,170.9576 573.7897,175.239 570.9888,182.7921 C 576.8947,176.1524 582.6886,175.629 589.2209,172.9565 C 583.3151,172.7478 581.1318,171.2251 578.9845,168.302 z M 624.5364,145.5447 C 621.5836,154.254 608.0056,162.0592 600.9178,162.0592 C 596.7828,162.0592 588.4029,155.7413 586.9264,147.0322 C 592.4305,152.4557 598.446,156.1755 603.0832,156.3597 C 608.2112,156.4881 619.7769,150.57 624.5364,145.5447 z "
- style="font-size:12px;fill:url(#radialGradient2210);fill-rule:evenodd" /><path
+ d="m 594.8524,209.0117 c 0,11.0899 2.5217,16.5364 1.217,16.5364 -1.3047,0 -4.4801,-5.6553 -4.4801,-16.7452 0,-11.0896 4.2194,-23.2055 5.5241,-23.2055 1.3047,0 -2.261,12.3247 -2.261,23.4143 z M 632.27,169.5802 c 4.1762,3.7165 7.6897,8.0949 8.7337,13.4818 -7.1585,-6.2222 -19.1194,-9.1034 -26.0694,-10.7319 6.1145,-0.2088 15.1883,0.1733 17.3357,-2.7499 z m -36.6425,2.5791 c 2.2841,2.1198 1.645,3.6133 2.4676,6.3595 0.3598,-2.6078 4.4778,-4.5893 6.7167,-6.5707 -2.8526,0.488 -6.3317,0.5584 -9.1843,0.2112 z m -16.643,-3.8573 c -2.3118,2.6556 -5.1948,6.937 -7.9957,14.4901 5.9059,-6.6397 11.6998,-7.1631 18.2321,-9.8356 -5.9058,-0.2087 -8.0891,-1.7314 -10.2364,-4.6545 z m 45.5519,-22.7573 c -2.9528,8.7093 -16.5308,16.5145 -23.6186,16.5145 -4.135,0 -12.5149,-6.3179 -13.9914,-15.027 5.5041,5.4235 11.5196,9.1433 16.1568,9.3275 5.128,0.1284 16.6937,-5.7897 21.4532,-10.815 z"
+ style="font-size:12px;fill:url(#radialGradient2210);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /><path
transform="matrix(1.381431,0,0,1.342002,-335.1483,-21.47379)"
sodipodi:nodetypes="csccc"
id="path758"
- d="M 566.1781,204.0047 C 566.1781,224.5982 593.4836,225.0052 587.8079,232.522 C 582.6399,239.91 550.7196,226.5353 550.7196,205.9419 C 552.8076,190.3594 555.5661,185.5046 574.6452,156.366 C 587.5403,159.1975 566.1781,183.4112 566.1781,204.0047 z "
- style="font-size:12px;fill:url(#radialGradient2212);fill-rule:evenodd" /><g
+ d="m 566.1781,204.0047 c 0,20.5935 27.3055,21.0005 21.6298,28.5173 -5.168,7.388 -37.0883,-5.9867 -37.0883,-26.5801 2.088,-15.5825 4.8465,-20.4373 23.9256,-49.5759 12.8951,2.8315 -8.4671,27.0452 -8.4671,47.6387 z"
+ style="font-size:12px;fill:url(#radialGradient2212);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /><g
style="font-size:12px;fill:url(#radialGradient2214)"
transform="matrix(1.381431,0,0,1.342002,-325.2191,-15.60249)"
id="g1065"><path
transform="translate(-7.1875,-4.375031)"
sodipodi:nodetypes="csssscsss"
id="path842"
- d="M 662.6023,249.8415 C 652.9563,254.7202 643.0236,269.4045 630.2927,263.3619 C 621.3526,259.2146 625.6634,249.1638 625.1563,243.5311 C 624.668,230.5505 623.5071,211.1312 631.9468,211.184 C 642.1547,211.246 638.0258,215.2545 645.4196,217.3441 C 653.505,219.306 658.7389,209.0467 664.847,213.6095 C 669.4787,219.944 664.6217,223.322 670.205,229.4906 C 673.1685,233.0602 677.7506,232.9839 680.3539,235.8973 C 685.7736,241.3478 668.3201,246.6544 662.6023,249.8415 z "
- style="font-size:12px;fill:url(#radialGradient2216);fill-rule:evenodd" /><path
+ d="m 662.6023,249.8415 c -9.646,4.8787 -19.5787,19.563 -32.3096,13.5204 -8.9401,-4.1473 -4.6293,-14.1981 -5.1364,-19.8308 -0.4883,-12.9806 -1.6492,-32.3999 6.7905,-32.3471 10.2079,0.062 6.079,4.0705 13.4728,6.1601 8.0854,1.9619 13.3193,-8.2974 19.4274,-3.7346 4.6317,6.3345 -0.2253,9.7125 5.358,15.8811 2.9635,3.5696 7.5456,3.4933 10.1489,6.4067 5.4197,5.4505 -12.0338,10.7571 -17.7516,13.9442 z"
+ style="font-size:12px;fill:url(#radialGradient2216);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /><path
transform="translate(-7.1875,-4.375031)"
sodipodi:nodetypes="cssssssss"
id="path843"
- d="M 550.8908,255.4014 C 562.5947,256.6532 574.367,267.8037 584.6032,256.5396 C 591.8317,248.7246 584.743,239.3914 580.5155,234.7902 C 570.7341,224.8274 565.2408,206.427 556.2229,206.4986 C 548.5882,206.8092 550.0632,210.9825 544.7009,215.234 C 537.4953,220.6488 532.9891,216.239 528.6392,223.1506 C 525.9871,226.8955 526.7585,231.7788 527.8864,236.9511 C 528.6785,241.8714 527.0976,242.9494 525.4163,244.55 C 519.9332,250.7329 540.853,254.0325 550.8908,255.4014 z "
- style="font-size:12px;fill:url(#radialGradient2218);fill-rule:evenodd" /></g><path
+ d="m 550.8908,255.4014 c 11.7039,1.2518 23.4762,12.4023 33.7124,1.1382 7.2285,-7.815 0.1398,-17.1482 -4.0877,-21.7494 -9.7814,-9.9628 -15.2747,-28.3632 -24.2926,-28.2916 -7.6347,0.3106 -6.1597,4.4839 -11.522,8.7354 -7.2056,5.4148 -11.7118,1.005 -16.0617,7.9166 -2.6521,3.7449 -1.8807,8.6282 -0.7528,13.8005 0.7921,4.9203 -0.7888,5.9983 -2.4701,7.5989 -5.4831,6.1829 15.4367,9.4825 25.4745,10.8514 z"
+ style="font-size:12px;fill:url(#radialGradient2218);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /></g><path
transform="matrix(1.381431,0,0,1.342002,-335.1483,-21.47379)"
sodipodi:nodetypes="cscss"
id="path857"
- d="M 649.8842,196.2501 C 649.4318,220.8146 631.991,220.9147 636.6064,229.3612 C 642.8768,241.2543 669.5186,218.7807 669.5186,198.1874 C 669.5186,178.0113 641.3187,150.3852 638.2491,152.2475 C 619.1027,166.4884 650.6787,175.7879 649.8842,196.2501 z "
- style="font-size:12px;fill:url(#radialGradient2220);fill-rule:evenodd" /></g><path
+ d="m 649.8842,196.2501 c -0.4524,24.5645 -17.8932,24.6646 -13.2778,33.1111 6.2704,11.8931 32.9122,-10.5805 32.9122,-31.1738 0,-20.1761 -28.1999,-47.8022 -31.2695,-45.9399 -19.1464,14.2409 12.4296,23.5404 11.6351,44.0026 z"
+ style="font-size:12px;fill:url(#radialGradient2220);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /></g><path
sodipodi:nodetypes="cscccccccccccccccccccccccc"
id="path712"
- d="M 215.5171,645.7443 C 216.5171,646.9255 218.8319,649.6217 218.8414,647.9427 L 218.8921,639.0568 L 257.1421,604.4318 C 317.1421,550.3068 347.8921,503.1818 347.8921,466.3693 C 347.8921,453.5568 342.6421,443.2443 333.3921,436.8693 C 340.5796,443.3693 344.5796,452.6193 344.5796,463.8693 C 344.5796,500.6818 313.7671,547.8068 253.8296,601.9318 L 215.5171,636.5568 L 215.5171,645.7443 z M 394.0796,608.1818 C 381.2671,610.3693 373.0171,611.0568 362.1421,611.0568 L 271.7734,611.0568 L 274.4609,608.5568 L 358.7671,608.5568 C 369.8296,608.5568 378.1421,607.8068 391.1421,605.6193 L 394.2671,607.8068 C 394.2046,607.9318 394.1421,608.0568 394.0796,608.1818 z M 373.3921,410.9943 C 360.7671,399.6193 342.3296,393.1818 320.0796,393.1818 C 298.7671,393.1818 282.6421,398.3068 262.5171,411.9318 L 240.9827,461.4662 C 240.392,462.825 242.2595,464.2441 243.739,464.9535 L 265.8296,414.4318 C 285.9546,400.8068 302.1421,395.6818 323.4546,395.6818 C 343.8921,395.6818 361.0796,401.1193 373.3921,410.9943 z "
- style="font-size:48px;font-style:italic;font-weight:bold;fill:#a23412;fill-opacity:1;stroke-width:1;font-family:URW Palladio L" /></g></svg>
\ No newline at end of file
+ d="m 280.88254,601.6601 c 0.64872,0.76627 2.15037,2.51535 2.15653,1.42616 l 0.0329,-5.76449 24.81362,-22.46199 c 38.92331,-35.11207 58.8715,-65.6831 58.8715,-89.56416 0,-8.31176 -3.40579,-15.0017 -9.40646,-19.1373 4.66269,4.21669 7.25758,10.21737 7.25758,17.51548 0,23.88108 -19.98875,54.4521 -58.87152,89.56417 l -24.85415,22.462 z m 115.83739,-24.36761 c -8.31175,1.41907 -13.6637,1.86507 -20.71855,1.86507 h -58.62416 l 1.74344,-1.62181 h 54.69128 c 7.17649,0 12.56899,-0.48653 21.00237,-1.90561 l 2.02726,1.41908 c -0.0405,0.081 -0.0811,0.16217 -0.12164,0.24327 z M 383.2995,449.37264 c -8.19012,-7.37921 -20.15093,-11.55536 -34.58499,-11.55536 -13.82588,0 -24.28652,3.32469 -37.34204,12.16353 l -13.96985,32.13405 c -0.3832,0.88149 0.8283,1.80209 1.78808,2.2623 l 14.33065,-32.77454 c 13.05552,-8.83883 23.55672,-12.16354 37.3826,-12.16354 13.25825,0 24.40816,3.52743 32.39555,9.93356 z"
+ style="font-style:italic;font-weight:bold;font-size:48px;font-family:'URW Palladio L';fill:#a23412;fill-opacity:1;stroke-width:0.64872187"
+ inkscape:connector-curvature="0" /></g></svg>
\ No newline at end of file
diff --git a/src/activities/money/resource/c2e.svg b/src/activities/money/resource/c2e.svg
index 8c3136ca6..fe6023b28 100644
--- a/src/activities/money/resource/c2e.svg
+++ b/src/activities/money/resource/c2e.svg
@@ -1,229 +1,235 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="svg699"
sodipodi:version="0.32"
width="503.34711"
height="500.98511"
xml:space="preserve"
sodipodi:docname="c2e.svg"
- inkscape:version="0.91 r13725"
+ inkscape:version="0.92.1 r15371"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
sodipodi:modified="true"
version="1.0"><metadata
id="metadata33"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs701"><linearGradient
id="linearGradient651"><stop
style="stop-color:#c78a00;stop-opacity:1;"
offset="0"
id="stop652" /><stop
style="stop-color:#ffe56a;stop-opacity:1;"
offset="1"
id="stop653" /></linearGradient><linearGradient
id="linearGradient834"><stop
style="stop-color:#191919;stop-opacity:1;"
offset="0"
id="stop835" /><stop
style="stop-color:#e6e6e6;stop-opacity:1;"
offset="1"
id="stop836" /></linearGradient><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient834"
id="linearGradient2201"
- gradientTransform="scale(1.0023546,0.9976509)"
+ gradientTransform="matrix(1.0003836,0,0,0.99568919,-1.6665809,2.7121263)"
spreadMethod="reflect"
x1="673.50358"
y1="300.07903"
x2="225.41876"
y2="504.08388"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient834"
id="linearGradient2203"
x1="796.23499"
y1="326.76798"
x2="395.45412"
y2="553.13495"
- gradientUnits="userSpaceOnUse" /><linearGradient
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.99803367,0,0,0.99803367,-0.48783527,1.5331142)" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2205"
- gradientTransform="scale(1.0049384,0.9950859)"
+ gradientTransform="matrix(1.0059141,0,0,1.0059138,1.974738,9.8612797)"
x1="217.44162"
y1="507.38584"
x2="577.10179"
y2="507.38584"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2209"
spreadMethod="reflect"
x1="286.06671"
y1="307.05434"
x2="461.8503"
y2="147.59049"
gradientTransform="scale(0.9767462,1.0238074)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2211"
spreadMethod="reflect"
x1="382.07347"
y1="269.31339"
x2="533.9103"
y2="131.57308"
gradientTransform="scale(0.8819901,1.1337996)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2213"
spreadMethod="reflect"
x1="572.36365"
y1="204.5671"
x2="631.66211"
y2="150.77391"
gradientTransform="scale(0.935494,1.0689539)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2215"
spreadMethod="reflect"
x1="763.8678"
y1="158.54136"
x2="806.98456"
y2="119.42756"
gradientTransform="scale(0.6957958,1.4372033)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2217"
spreadMethod="reflect"
x1="266.82405"
y1="418.96704"
x2="342.59325"
y2="350.23224"
gradientTransform="scale(1.6403562,0.6096237)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2219"
spreadMethod="reflect"
x1="578.59925"
y1="267.88094"
x2="622.33322"
y2="228.20723"
gradientTransform="scale(1.0295592,0.9712894)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2221"
spreadMethod="reflect"
x1="459.52562"
y1="275.18938"
x2="506.24941"
y2="232.80342"
gradientTransform="scale(1.0716088,0.9331764)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2223"
spreadMethod="reflect"
x1="898.9716"
y1="153.9525"
x2="942.47289"
y2="114.48988"
gradientTransform="scale(0.6819639,1.4663532)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient834"
id="linearGradient2225"
- gradientTransform="scale(4.1135534,0.2430988)"
+ gradientTransform="matrix(4.1054648,0,0,0.24262079,0.78966979,1.0229803)"
x1="60.417931"
y1="2676.5681"
x2="60.52325"
y2="2644.241"
gradientUnits="userSpaceOnUse" /></defs><sodipodi:namedview
id="base"
inkscape:zoom="0.25465897"
- inkscape:cx="-205.07733"
+ inkscape:cx="-1043.4535"
inkscape:cy="243.14482"
- inkscape:window-width="1366"
- inkscape:window-height="748"
- inkscape:window-x="-2"
- inkscape:window-y="-3"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
inkscape:current-layer="g2185"
showgrid="false"
inkscape:window-maximized="1" /><g
id="g2185"
transform="translate(-149.92241,-269.75517)"><path
- transform="translate(-2.46109,1.692474)"
sodipodi:nodetypes="ccccccc"
id="path687"
- d="M 655.7306,518.5551 C 655.7306,656.8984 543.0531,769.0478 404.0571,769.0478 C 265.0618,769.0478 152.3835,656.8984 152.3835,518.5551 C 152.3835,380.2119 265.0618,268.0627 404.0571,268.0627 C 543.0531,268.0627 655.7306,380.2119 655.7306,518.5551 z M 396.9986,636.0575 L 396.9986,636.0575 z "
- style="font-size:48px;font-style:italic;font-weight:bold;fill:url(#linearGradient2201);fill-opacity:1;stroke-width:1;font-family:Luxi Serif" /><path
- transform="translate(-1.280022,0.511139)"
+ d="m 652.77464,520.24757 c 0,138.07128 -112.45594,250.00015 -251.17863,250.00015 -138.72199,0 -251.17873,-111.92887 -251.17873,-250.00015 0,-138.07117 112.45674,-249.99985 251.17873,-249.99985 138.72269,0 251.17863,111.92868 251.17863,249.99985 z M 394.55139,637.51893 Z"
+ style="font-style:italic;font-weight:bold;font-size:48px;font-family:'Luxi Serif';fill:url(#linearGradient2201);fill-opacity:1;stroke-width:0.9980337"
+ inkscape:connector-curvature="0" /><path
id="path708"
- d="M 218.4552,647.553 C 244.9875,647.1854 292.904,646.45 307.5561,646.45 C 313.8922,646.45 313.8922,646.45 384.7768,647.553 C 390.7169,625.1248 392.6969,618.8743 397.845,609.6824 L 394.6769,607.4764 C 381.6088,609.6824 373.2927,610.4178 362.2046,610.4178 L 272.7078,610.4178 L 360.2246,528.7937 C 383.1928,507.4686 396.261,481.7312 396.261,457.8323 C 396.261,420.3294 367.3527,395.3274 323.3963,395.3274 C 302.0121,395.3274 285.7759,400.4749 265.5797,414.0789 L 243.4035,464.0828 L 255.2836,467.3919 L 260.8277,458.5677 C 275.4798,435.4041 285.7759,428.4182 305.5761,428.4182 C 331.3163,428.4182 347.9485,443.1253 347.9485,465.9212 C 347.9485,502.6888 317.0602,549.7513 256.8676,603.7996 L 218.4552,638.3611 L 218.4552,647.553 z M 640.3757,519.7365 C 640.3757,650.9041 534.0437,757.2364 402.8758,757.2364 C 271.7086,757.2364 165.3762,650.9041 165.3762,519.7365 C 165.3762,388.569 271.7086,282.2368 402.8758,282.2368 C 534.0437,282.2368 640.3757,388.569 640.3757,519.7365 z M 392.2498,630.7616 L 392.2498,630.7616 z "
- style="font-size:48px;font-style:italic;font-weight:bold;fill:url(#linearGradient2203);stroke-width:1;font-family:URW Palladio L" /><path
- transform="matrix(1.002943,0,0,1.012873,1.187403,8.855713)"
- sodipodi:ry="178.94638"
- sodipodi:rx="180.71815"
- sodipodi:cy="504.89249"
- sodipodi:cx="399.23358"
- d="M 579.95174,504.89249 A 180.71815,178.94638 0 0 1 399.23358,683.83887 180.71815,178.94638 0 0 1 218.51543,504.89249 180.71815,178.94638 0 0 1 399.23358,325.94611 180.71815,178.94638 0 0 1 579.95174,504.89249 Z"
+ d="m 217.53781,647.81281 c 26.48013,-0.36688 74.30241,-1.10083 88.9257,-1.10083 6.32364,0 6.32364,0 77.06885,1.10083 5.92842,-22.3841 7.90453,-28.62231 13.04251,-37.79613 l -3.16187,-2.20167 c -13.04241,2.20167 -21.34215,2.93562 -32.40845,2.93562 h -89.32082 l 87.34471,-81.4636 c 22.92304,-21.28317 35.96554,-46.96996 35.96554,-70.82187 0,-37.42915 -28.85145,-62.38199 -72.72142,-62.38199 -21.34215,0 -37.54643,5.13738 -57.70291,18.71463 l -22.1326,49.90557 11.85674,3.3026 5.5332,-8.80685 c 14.62329,-23.11806 24.89914,-30.09022 44.66041,-30.09022 25.68959,0 42.28908,14.67818 42.28908,37.42926 0,36.6953 -30.82756,83.66526 -90.9018,137.60728 l -38.33687,34.49354 z M 638.62867,520.24764 c 0,130.90968 -106.12291,237.0329 -237.03289,237.0329 -130.90929,0 -237.0326,-106.12322 -237.0326,-237.0329 0,-130.90958 106.12331,-237.0327 237.0326,-237.0327 130.90998,0 237.03289,106.12312 237.03289,237.0327 z m -247.638,110.80679 z"
+ style="font-style:italic;font-weight:bold;font-size:48px;font-family:'URW Palladio L';fill:url(#linearGradient2203);stroke-width:0.9980337"
+ inkscape:connector-curvature="0" /><ellipse
id="path709"
- style="fill:url(#linearGradient2205);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- sodipodi:type="arc" /><path
+ style="fill:url(#linearGradient2205);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.00591394pt;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ cx="401.59592"
+ cy="520.24768"
+ rx="180.89362"
+ ry="180.89355" /><path
sodipodi:nodetypes="cccccssssccccccssssc"
id="path705"
- d="M 277.9261,650.2158 C 267.7386,639.9033 258.8011,628.4033 251.4886,615.7783 L 261.0511,607.1533 C 321.2386,553.0908 352.1136,506.0283 352.1136,469.2783 C 352.1136,446.4658 335.4886,431.7783 309.7386,431.7783 C 289.9261,431.7783 272.995,444.5381 259.1422,468.1674 C 258.0054,470.1064 255.3783,472.2754 253.2245,471.551 L 243.375,468.2384 C 242.1133,467.8141 241.9,465.4795 242.567,464.3275 L 269.7386,417.4033 C 289.9261,403.8408 306.1761,398.6533 327.5511,398.6533 C 371.5511,398.6533 400.4261,423.6533 400.4261,461.1533 C 400.4261,485.0908 387.3636,510.7783 364.4261,532.1533 L 276.8636,613.7783 L 366.3636,613.7783 C 377.4886,613.7783 381.1841,608.4753 393.4348,608.7527 C 396.7011,608.8267 401.4836,611.3406 399.9631,615.1163 C 396.1489,623.5397 392.7153,634.8535 389.3437,645.4745 C 388.5762,648.2343 385.2855,650.6135 380.2257,650.6135 C 374.6632,650.6135 295.8011,649.9033 277.9261,650.2158 z "
- style="font-size:12px;fill:#ffffff;fill-rule:evenodd;stroke-width:6;stroke:#000000;fill-opacity:1;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none" /><g
+ d="M 278.16927,649.96024 C 268.0018,639.66802 259.08188,628.19063 251.78376,615.59046 l 9.54369,-8.60804 c 60.06916,-53.9562 90.88345,-100.92616 90.88345,-137.6039 0,-22.76764 -16.59231,-37.42626 -42.29168,-37.42626 -19.77354,0 -36.67135,12.73471 -50.49691,36.31755 -1.13457,1.93518 -3.7565,4.09992 -5.90607,3.37694 l -9.83013,-3.30608 c -1.25922,-0.42347 -1.4721,-2.75348 -0.80641,-3.90321 l 27.11817,-46.83193 c 20.14781,-13.53584 36.36585,-18.71314 57.69882,-18.71314 43.91349,0 72.73171,24.95085 72.73171,62.37711 0,23.89043 -13.03682,49.52742 -35.92921,70.86039 l -87.39033,81.4645 h 89.32402 c 11.10312,0 14.79135,-5.29257 27.01797,-5.01572 3.25987,0.0738 8.03297,2.58281 6.51546,6.35109 -3.8067,8.40683 -7.23355,19.69839 -10.59852,30.2985 -0.76599,2.75438 -4.05022,5.1289 -9.10007,5.1289 -5.55156,0 -84.2586,-0.70881 -102.09845,-0.39692 z"
+ style="font-size:12px;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:5.9882021;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ inkscape:connector-curvature="0" /><g
style="font-size:12px;fill:url(#linearGradient2209)"
- transform="matrix(0.896439,0,0,0.911599,29.62592,306.5531)"
+ transform="matrix(0.89467631,0,0,0.9098065,30.357335,306.97329)"
id="g944"><path
id="path943"
- d="M 489.2781,157.6309 C 486.7725,158.6472 483.694,159.9616 480.8916,161.4231 C 479.3419,161.0055 475.428,159.2736 475.428,155.3341 C 475.428,151.3946 478.7154,148.2011 482.7708,148.2011 C 488.0788,148.2011 490.7398,151.8121 489.2781,157.6309 z M 521.9314,154.5415 C 521.9314,158.4811 518.0176,160.213 516.6769,160.8394 C 513.0392,159.5867 510.1692,158.6899 508.0812,158.0913 C 505.5757,152.2726 509.2807,147.4085 514.5889,147.4085 C 518.644,147.4085 521.9314,150.6021 521.9314,154.5415 z M 554.0133,282.1463 C 539.7204,299.0921 519.7959,311.7673 487.7231,311.2372 C 455.0333,310.1367 444.7336,294.8341 446.4288,254.5974 C 447.4384,237.4799 453.0554,223.2215 459.4115,212.5429 C 462.707,204.534 471.5472,201.7454 476.9885,177.1512 C 485.6153,185.4841 494.4355,188.3269 497.9466,188.3677 C 504.6303,188.4997 521.1268,180.7489 526.5206,174.9439 C 532.8029,196.1211 539.725,203.2866 544.2499,208.414 C 571.8131,240.2076 557.189,277.6971 554.0133,282.1463 z M 494.2871,157.0588 C 487.7115,157.6404 481.7311,160.3453 477.7269,163.5282 C 475.279,165.2092 472.0644,157.8887 472.0644,152.4116 C 472.0644,145.0207 475.2644,139.5457 483.471,139.5457 C 490.9986,139.5457 495.5149,147.9387 494.2871,157.0588 z M 503.3984,157.4551 C 509.7709,158.1484 517.8879,161.2707 522.7624,163.7729 C 525.4762,165.4536 527.6282,158.285 527.6282,152.8079 C 527.6282,147.0021 523.8588,139.1494 514.7603,139.1494 C 505.191,139.1494 502.0372,145.9572 503.3984,157.4551 z M 504.7202,106.7478 C 474.7132,106.4276 457.1089,126.4945 461.8612,178.9302 C 463.5845,198.2381 361.0517,308.565 481.4685,323.2273 L 525.5737,324.0199 C 606.8295,319.2645 591.7019,249.1051 588.8989,241.103 C 580.6322,213.4795 553.1952,187.4526 553.0018,172.6248 C 552.814,127.3526 535.8651,106.2749 504.7202,106.7478 z M 529.3964,169.2447 C 529.7524,177.204 506.4211,188.5796 497.5232,188.5796 C 490.247,188.5796 473.2299,177.6226 472.7098,170.2413 C 472.4321,166.698 484.8286,156.8974 498.0721,157.1776 C 508.6449,157.1776 529.106,164.0661 529.3964,169.2447 z M 505.6319,158.6713 C 504.8923,159.1122 502.5108,159.8841 502.2685,159.8142 C 501.7591,159.7069 502.9358,158.8886 503.1344,158.3848 C 503.3119,157.9112 506.3718,158.2303 505.6319,158.6713 z M 491.2411,158.3369 C 491.2346,158.7713 491.7574,159.5856 492.1907,159.5931 C 492.5879,159.0685 492.9824,158.6462 493.4274,158.2207 C 493.8848,157.8292 491.2476,157.996 491.2411,158.3369 z M 475.86,171.0084 C 475.1974,169.8919 481.8043,180.5114 494.4183,180.9245 C 505.2062,181.3048 518.8716,172.4247 527.1629,168.9206 C 494.2345,184.859 489.641,183.0493 475.86,171.0084 z M 532.9812,126.1648 C 531.3254,129.0911 525.7228,129.7142 520.4675,127.5566 C 515.2121,125.3989 512.294,121.2776 513.9498,118.3513 C 515.6056,115.425 521.2082,114.8019 526.4636,116.9596 C 531.7189,119.1172 534.6369,123.2386 532.9812,126.1648 z "
- style="font-size:12px;fill:url(#linearGradient2211);fill-rule:evenodd" /><path
+ d="m 489.2781,157.6309 c -2.5056,1.0163 -5.5841,2.3307 -8.3865,3.7922 -1.5497,-0.4176 -5.4636,-2.1495 -5.4636,-6.089 0,-3.9395 3.2874,-7.133 7.3428,-7.133 5.308,0 7.969,3.611 6.5073,9.4298 z m 32.6533,-3.0894 c 0,3.9396 -3.9138,5.6715 -5.2545,6.2979 -3.6377,-1.2527 -6.5077,-2.1495 -8.5957,-2.7481 -2.5055,-5.8187 1.1995,-10.6828 6.5077,-10.6828 4.0551,0 7.3425,3.1936 7.3425,7.133 z m 32.0819,127.6048 c -14.2929,16.9458 -34.2174,29.621 -66.2902,29.0909 -32.6898,-1.1005 -42.9895,-16.4031 -41.2943,-56.6398 1.0096,-17.1175 6.6266,-31.3759 12.9827,-42.0545 3.2955,-8.0089 12.1357,-10.7975 17.577,-35.3917 8.6268,8.3329 17.447,11.1757 20.9581,11.2165 6.6837,0.132 23.1802,-7.6188 28.574,-13.4238 6.2823,21.1772 13.2044,28.3427 17.7293,33.4701 27.5632,31.7936 12.9391,69.2831 9.7634,73.7323 z M 494.2871,157.0588 c -6.5756,0.5816 -12.556,3.2865 -16.5602,6.4694 -2.4479,1.681 -5.6625,-5.6395 -5.6625,-11.1166 0,-7.3909 3.2,-12.8659 11.4066,-12.8659 7.5276,0 12.0439,8.393 10.8161,17.5131 z m 9.1113,0.3963 c 6.3725,0.6933 14.4895,3.8156 19.364,6.3178 2.7138,1.6807 4.8658,-5.4879 4.8658,-10.965 0,-5.8058 -3.7694,-13.6585 -12.8679,-13.6585 -9.5693,0 -12.7231,6.8078 -11.3619,18.3057 z m 1.3218,-50.7073 c -30.007,-0.3202 -47.6113,19.7467 -42.859,72.1824 1.7233,19.3079 -100.8095,129.6348 19.6073,144.2971 l 44.1052,0.7926 c 81.2558,-4.7554 66.1282,-74.9148 63.3252,-82.9169 -8.2667,-27.6235 -35.7037,-53.6504 -35.8971,-68.4782 -0.1878,-45.2722 -17.1367,-66.3499 -48.2816,-65.877 z m 24.6762,62.4969 c 0.356,7.9593 -22.9753,19.3349 -31.8732,19.3349 -7.2762,0 -24.2933,-10.957 -24.8134,-18.3383 -0.2777,-3.5433 12.1188,-13.3439 25.3623,-13.0637 10.5728,0 31.0339,6.8885 31.3243,12.0671 z m -23.7645,-10.5734 c -0.7396,0.4409 -3.1211,1.2128 -3.3634,1.1429 -0.5094,-0.1073 0.6673,-0.9256 0.8659,-1.4294 0.1775,-0.4736 3.2374,-0.1545 2.4975,0.2865 z m -14.3908,-0.3344 c -0.007,0.4344 0.5163,1.2487 0.9496,1.2562 0.3972,-0.5246 0.7917,-0.9469 1.2367,-1.3724 0.4574,-0.3915 -2.1798,-0.2247 -2.1863,0.1162 z M 475.86,171.0084 c -0.6626,-1.1165 5.9443,9.503 18.5583,9.9161 10.7879,0.3803 24.4533,-8.4998 32.7446,-12.0039 -32.9284,15.9384 -37.5219,14.1287 -51.3029,2.0878 z m 57.1212,-44.8436 c -1.6558,2.9263 -7.2584,3.5494 -12.5137,1.3918 -5.2554,-2.1577 -8.1735,-6.279 -6.5177,-9.2053 1.6558,-2.9263 7.2584,-3.5494 12.5138,-1.3917 5.2553,2.1576 8.1733,6.279 6.5176,9.2052 z"
+ style="font-size:12px;fill:url(#linearGradient2211);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /><path
transform="matrix(1.381431,0,0,1.342002,-335.1481,-21.47379)"
sodipodi:nodetypes="cccccccccccccccccccccc"
id="path871"
- d="M 594.8524,209.0117 C 594.8524,220.1016 597.3741,225.5481 596.0694,225.5481 C 594.7647,225.5481 591.5893,219.8928 591.5893,208.8029 C 591.5893,197.7133 595.8087,185.5974 597.1134,185.5974 C 598.4181,185.5974 594.8524,197.9221 594.8524,209.0117 z M 632.27,169.5802 C 636.4462,173.2967 639.9597,177.6751 641.0037,183.062 C 633.8452,176.8398 621.8843,173.9586 614.9343,172.3301 C 621.0488,172.1213 630.1226,172.5034 632.27,169.5802 z M 595.6275,172.1593 C 597.9116,174.2791 597.2725,175.7726 598.0951,178.5188 C 598.4549,175.911 602.5729,173.9295 604.8118,171.9481 C 601.9592,172.4361 598.4801,172.5065 595.6275,172.1593 z M 578.9845,168.302 C 576.6727,170.9576 573.7897,175.239 570.9888,182.7921 C 576.8947,176.1524 582.6886,175.629 589.2209,172.9565 C 583.3151,172.7478 581.1318,171.2251 578.9845,168.302 z M 624.5364,145.5447 C 621.5836,154.254 608.0056,162.0592 600.9178,162.0592 C 596.7828,162.0592 588.4029,155.7413 586.9264,147.0322 C 592.4305,152.4557 598.446,156.1755 603.0832,156.3597 C 608.2112,156.4881 619.7769,150.57 624.5364,145.5447 z "
- style="font-size:12px;fill:url(#linearGradient2213);fill-rule:evenodd" /><path
+ d="m 594.8524,209.0117 c 0,11.0899 2.5217,16.5364 1.217,16.5364 -1.3047,0 -4.4801,-5.6553 -4.4801,-16.7452 0,-11.0896 4.2194,-23.2055 5.5241,-23.2055 1.3047,0 -2.261,12.3247 -2.261,23.4143 z M 632.27,169.5802 c 4.1762,3.7165 7.6897,8.0949 8.7337,13.4818 -7.1585,-6.2222 -19.1194,-9.1034 -26.0694,-10.7319 6.1145,-0.2088 15.1883,0.1733 17.3357,-2.7499 z m -36.6425,2.5791 c 2.2841,2.1198 1.645,3.6133 2.4676,6.3595 0.3598,-2.6078 4.4778,-4.5893 6.7167,-6.5707 -2.8526,0.488 -6.3317,0.5584 -9.1843,0.2112 z m -16.643,-3.8573 c -2.3118,2.6556 -5.1948,6.937 -7.9957,14.4901 5.9059,-6.6397 11.6998,-7.1631 18.2321,-9.8356 -5.9058,-0.2087 -8.0891,-1.7314 -10.2364,-4.6545 z m 45.5519,-22.7573 c -2.9528,8.7093 -16.5308,16.5145 -23.6186,16.5145 -4.135,0 -12.5149,-6.3179 -13.9914,-15.027 5.5041,5.4235 11.5196,9.1433 16.1568,9.3275 5.128,0.1284 16.6937,-5.7897 21.4532,-10.815 z"
+ style="font-size:12px;fill:url(#linearGradient2213);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /><path
transform="matrix(1.381431,0,0,1.342002,-335.1483,-21.47379)"
sodipodi:nodetypes="csccc"
id="path758"
- d="M 566.1781,204.0047 C 566.1781,224.5982 593.4836,225.0052 587.8079,232.522 C 582.6399,239.91 550.7196,226.5353 550.7196,205.9419 C 552.8076,190.3594 555.5661,185.5046 574.6452,156.366 C 587.5403,159.1975 566.1781,183.4112 566.1781,204.0047 z "
- style="font-size:12px;fill:url(#linearGradient2215);fill-rule:evenodd" /><g
+ d="m 566.1781,204.0047 c 0,20.5935 27.3055,21.0005 21.6298,28.5173 -5.168,7.388 -37.0883,-5.9867 -37.0883,-26.5801 2.088,-15.5825 4.8465,-20.4373 23.9256,-49.5759 12.8951,2.8315 -8.4671,27.0452 -8.4671,47.6387 z"
+ style="font-size:12px;fill:url(#linearGradient2215);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /><g
style="font-size:12px;fill:url(#linearGradient2217)"
transform="matrix(1.381431,0,0,1.342002,-325.2191,-15.60249)"
id="g1065"><path
transform="translate(-7.1875,-4.375031)"
sodipodi:nodetypes="csssscsss"
id="path842"
- d="M 662.6023,249.8415 C 652.9563,254.7202 643.0236,269.4045 630.2927,263.3619 C 621.3526,259.2146 625.6634,249.1638 625.1563,243.5311 C 624.668,230.5505 623.5071,211.1312 631.9468,211.184 C 642.1547,211.246 638.0258,215.2545 645.4196,217.3441 C 653.505,219.306 658.7389,209.0467 664.847,213.6095 C 669.4787,219.944 664.6217,223.322 670.205,229.4906 C 673.1685,233.0602 677.7506,232.9839 680.3539,235.8973 C 685.7736,241.3478 668.3201,246.6544 662.6023,249.8415 z "
- style="font-size:12px;fill:url(#linearGradient2219);fill-rule:evenodd" /><path
+ d="m 662.6023,249.8415 c -9.646,4.8787 -19.5787,19.563 -32.3096,13.5204 -8.9401,-4.1473 -4.6293,-14.1981 -5.1364,-19.8308 -0.4883,-12.9806 -1.6492,-32.3999 6.7905,-32.3471 10.2079,0.062 6.079,4.0705 13.4728,6.1601 8.0854,1.9619 13.3193,-8.2974 19.4274,-3.7346 4.6317,6.3345 -0.2253,9.7125 5.358,15.8811 2.9635,3.5696 7.5456,3.4933 10.1489,6.4067 5.4197,5.4505 -12.0338,10.7571 -17.7516,13.9442 z"
+ style="font-size:12px;fill:url(#linearGradient2219);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /><path
transform="translate(-7.1875,-4.375031)"
sodipodi:nodetypes="cssssssss"
id="path843"
- d="M 550.8908,255.4014 C 562.5947,256.6532 574.367,267.8037 584.6032,256.5396 C 591.8317,248.7246 584.743,239.3914 580.5155,234.7902 C 570.7341,224.8274 565.2408,206.427 556.2229,206.4986 C 548.5882,206.8092 550.0632,210.9825 544.7009,215.234 C 537.4953,220.6488 532.9891,216.239 528.6392,223.1506 C 525.9871,226.8955 526.7585,231.7788 527.8864,236.9511 C 528.6785,241.8714 527.0976,242.9494 525.4163,244.55 C 519.9332,250.7329 540.853,254.0325 550.8908,255.4014 z "
- style="font-size:12px;fill:url(#linearGradient2221);fill-rule:evenodd" /></g><path
+ d="m 550.8908,255.4014 c 11.7039,1.2518 23.4762,12.4023 33.7124,1.1382 7.2285,-7.815 0.1398,-17.1482 -4.0877,-21.7494 -9.7814,-9.9628 -15.2747,-28.3632 -24.2926,-28.2916 -7.6347,0.3106 -6.1597,4.4839 -11.522,8.7354 -7.2056,5.4148 -11.7118,1.005 -16.0617,7.9166 -2.6521,3.7449 -1.8807,8.6282 -0.7528,13.8005 0.7921,4.9203 -0.7888,5.9983 -2.4701,7.5989 -5.4831,6.1829 15.4367,9.4825 25.4745,10.8514 z"
+ style="font-size:12px;fill:url(#linearGradient2221);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /></g><path
transform="matrix(1.381431,0,0,1.342002,-335.1483,-21.47379)"
sodipodi:nodetypes="cscss"
id="path857"
- d="M 649.8842,196.2501 C 649.4318,220.8146 631.991,220.9147 636.6064,229.3612 C 642.8768,241.2543 669.5186,218.7807 669.5186,198.1874 C 669.5186,178.0113 641.3187,150.3852 638.2491,152.2475 C 619.1027,166.4884 650.6787,175.7879 649.8842,196.2501 z "
- style="font-size:12px;fill:url(#linearGradient2223);fill-rule:evenodd" /></g><path
+ d="m 649.8842,196.2501 c -0.4524,24.5645 -17.8932,24.6646 -13.2778,33.1111 6.2704,11.8931 32.9122,-10.5805 32.9122,-31.1738 0,-20.1761 -28.1999,-47.8022 -31.2695,-45.9399 -19.1464,14.2409 12.4296,23.5404 11.6351,44.0026 z"
+ style="font-size:12px;fill:url(#linearGradient2223);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /></g><path
sodipodi:nodetypes="csccs"
id="path692"
- d="M 218.1983,647.4948 C 216.8553,647.5098 219.7662,650.4244 221.5391,650.4178 L 277.9158,650.209 L 274.1574,646.8684 L 218.1983,647.4948 z "
- style="font-size:12px;fill:url(#linearGradient2225);fill-rule:evenodd" /></g></svg>
\ No newline at end of file
+ d="m 218.55892,647.24459 c -1.34036,0.015 1.56481,2.92384 3.33423,2.91725 l 56.26584,-0.20839 -3.75101,-3.33403 z"
+ style="font-size:12px;fill:url(#linearGradient2225);fill-rule:evenodd;stroke-width:0.9980337"
+ inkscape:connector-curvature="0" /></g></svg>
\ No newline at end of file
diff --git a/src/activities/money/resource/c50c.svg b/src/activities/money/resource/c50c.svg
index 14fc2c6d8..3ba924d38 100644
--- a/src/activities/money/resource/c50c.svg
+++ b/src/activities/money/resource/c50c.svg
@@ -1,203 +1,210 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="svg699"
sodipodi:version="0.32"
width="501.22955"
height="501.22958"
xml:space="preserve"
sodipodi:docname="c50c.svg"
- inkscape:version="0.91 r13725"
+ inkscape:version="0.92.1 r15371"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
sodipodi:modified="true"
version="1.0"><metadata
id="metadata31"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs701"><linearGradient
id="linearGradient651"><stop
style="stop-color:#c78f00;stop-opacity:1;"
offset="0"
id="stop652" /><stop
style="stop-color:#ffea6b;stop-opacity:1;"
offset="1"
id="stop653" /></linearGradient><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2197"
spreadMethod="reflect"
x1="517.34941"
y1="268.43047"
x2="205.89884"
y2="462.62924"
- gradientTransform="scale(1.0399431,0.9615911)"
- gradientUnits="userSpaceOnUse" /><linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient651"
- id="linearGradient2199"
- spreadMethod="reflect"
- x1="624.25226"
- y1="364.3883"
- x2="449.83822"
- y2="535.09138"
+ gradientTransform="matrix(0.852864,0,0,0.85286407,94.7321,163.19893)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2201"
spreadMethod="reflect"
x1="571.82491"
y1="131.99118"
x2="378.53539"
y2="251.5887"
gradientTransform="scale(0.9767462,1.0238074)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2203"
spreadMethod="reflect"
x1="628.90322"
y1="118.09884"
x2="461.94527"
y2="221.40376"
gradientTransform="scale(0.8819901,1.1337996)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2205"
spreadMethod="reflect"
x1="668.7607"
y1="145.51168"
x2="603.55684"
y2="185.85645"
gradientTransform="scale(0.935494,1.0689539)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2207"
spreadMethod="reflect"
x1="833.95948"
y1="115.60131"
x2="786.54881"
y2="144.93657"
gradientTransform="scale(0.6957958,1.4372033)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2209"
spreadMethod="reflect"
x1="389.99636"
y1="343.50837"
x2="306.68146"
y2="395.0593"
gradientTransform="scale(1.6403562,0.6096237)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2211"
spreadMethod="reflect"
x1="649.69428"
y1="224.32621"
x2="601.60494"
y2="254.0814"
gradientTransform="scale(1.0295592,0.9712894)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2213"
spreadMethod="reflect"
x1="535.48099"
y1="228.65708"
x2="484.10407"
y2="260.44645"
gradientTransform="scale(1.0716088,0.9331764)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2215"
spreadMethod="reflect"
x1="969.68838"
y1="110.6295"
x2="921.85489"
y2="140.22638"
gradientTransform="scale(0.6819639,1.4663532)"
- gradientUnits="userSpaceOnUse" /></defs><sodipodi:namedview
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient651"
+ id="linearGradient2195"
+ spreadMethod="reflect"
+ x1="238.54836"
+ y1="768.71063"
+ x2="505.73611"
+ y2="471.83698"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.79803563,0,0,0.79803563,74.98846,43.026089)" /></defs><sodipodi:namedview
id="base"
- inkscape:zoom="0.36014217"
- inkscape:cx="-112.48363"
- inkscape:cy="526.18109"
- inkscape:window-width="1366"
- inkscape:window-height="713"
- inkscape:window-x="-2"
- inkscape:window-y="-3"
+ inkscape:zoom="0.72028434"
+ inkscape:cx="-178.98274"
+ inkscape:cy="376.96192"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
inkscape:current-layer="g2183"
showgrid="false"
inkscape:window-maximized="1" /><g
id="g2183"
transform="translate(-150.97116,-269.64373)"><path
- transform="matrix(1.027654,0,0,1.111389,17.07555,72.83612)"
sodipodi:nodetypes="cssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssscssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssscssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssscsssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssc"
id="path690"
- d="M 614.5446,402.8408 C 614.5446,403.8138 618.0473,404.5149 618.034,405.485 C 618.0208,406.455 618.0009,407.4236 617.9743,408.3907 C 617.9478,409.3578 614.4054,410.3234 614.3657,411.2874 C 614.3261,412.2514 617.7893,413.2139 617.7367,414.1748 C 617.684,415.1357 617.6248,416.095 617.5591,417.0527 C 617.4935,418.0104 613.9119,419.2368 613.8334,420.1912 C 613.7548,421.1456 617.1794,421.828 617.088,422.779 C 616.9966,423.7301 616.8989,424.6794 616.7949,425.627 C 616.6909,426.5746 613.3635,427.2501 613.2468,428.1942 C 613.13,429.1383 616.2239,430.351 616.0946,431.2915 C 615.9654,432.2321 615.8298,433.1708 615.688,434.1076 C 615.5462,435.0445 611.5963,435.4387 611.4421,436.3719 C 611.2879,437.305 614.9294,438.7771 614.7629,439.7064 C 614.5964,440.6358 614.4237,441.5632 614.2449,442.4886 C 614.0662,443.4141 610.6642,443.5264 610.4733,444.4478 C 610.2823,445.3694 613.3022,447.1002 613.0992,448.0177 C 612.8962,448.9351 612.6871,449.8506 612.472,450.764 C 612.257,451.6774 609.1114,451.7774 608.8845,452.6867 C 608.6575,453.5959 611.3491,455.3143 611.1102,456.2193 C 610.8713,457.1243 610.6266,458.0271 610.376,458.9278 C 610.1254,459.8284 606.3596,459.9158 606.0973,460.812 C 605.8348,461.7083 609.0761,463.4135 608.8022,464.3054 C 608.5284,465.1972 608.2486,466.0867 607.9631,466.974 C 607.6777,467.8613 604.462,467.9351 604.1651,468.8177 C 603.8682,469.7003 606.4901,471.3919 606.1818,472.2699 C 605.8735,473.1479 605.5596,474.0235 605.24,474.8967 C 604.9204,475.7699 601.6707,475.559 601.34,476.4274 C 601.0092,477.2957 603.5973,479.2434 603.2554,480.1069 C 602.9135,480.9703 602.566,481.8313 602.213,482.6898 C 601.86,483.5483 598.577,483.3227 598.2131,484.1761 C 597.8492,485.0295 600.4042,486.962 600.0294,487.8103 C 599.6545,488.6586 599.2743,489.5044 598.8886,490.3474 C 598.5029,491.1906 595.1874,490.9493 594.7911,491.7873 C 594.3947,492.6251 596.9174,494.5418 596.5104,495.3743 C 596.1033,496.2068 595.691,497.0366 595.2733,497.8636 C 594.8557,498.6906 590.9234,498.4333 590.4953,499.2549 C 590.0672,500.0765 593.1432,501.9768 592.7047,502.7928 C 592.2662,503.6088 591.8224,504.422 591.3735,505.2323 C 590.9247,506.0426 587.8386,505.2276 587.3795,506.0322 C 586.9203,506.8369 589.0882,509.2611 588.6189,510.0599 C 588.1496,510.8587 587.6752,511.6546 587.1959,512.4476 C 586.7164,513.2405 583.015,512.408 582.5256,513.195 C 582.0363,513.9821 584.7588,516.3885 584.2594,517.1696 C 583.7601,517.9505 583.2558,518.7285 582.7466,519.5034 C 582.2374,520.2783 579.3837,519.4277 578.8647,520.1964 C 578.3457,520.9651 580.1614,523.3533 579.6328,524.1158 C 579.104,524.8783 578.5706,525.6376 578.0322,526.3939 C 577.4939,527.1501 574.6112,526.2806 574.0634,527.0304 C 573.5156,527.7802 575.3026,530.1493 574.7452,530.8926 C 574.1879,531.636 573.6259,532.3761 573.0593,533.113 C 572.4926,533.8498 569.5817,532.9608 569.0057,533.691 C 568.4297,534.4213 570.1887,536.7706 569.6035,537.4942 C 569.0183,538.2177 568.4285,538.9379 567.8342,539.6547 C 567.2399,540.3715 564.3015,539.4623 563.6981,540.1724 C 563.0947,540.8823 564.8263,543.2113 564.214,543.9144 C 563.6016,544.6174 562.9847,545.317 562.3635,546.0131 C 561.7422,546.7092 558.4844,545.7792 557.8544,546.4683 C 557.2244,547.1573 559.2219,549.4653 558.5831,550.1472 C 557.9443,550.8292 557.3011,551.5075 556.6536,552.1823 C 556.0061,552.857 553.0146,551.3647 552.3586,552.0322 C 551.7025,552.6997 553.3818,555.5267 552.7172,556.1868 C 552.0527,556.847 551.3839,557.5034 550.7109,558.1561 C 550.0378,558.8088 547.0211,557.2944 546.3398,557.9396 C 545.6584,558.5848 547.3126,561.3896 546.623,562.0272 C 545.9334,562.6648 545.2397,563.2987 544.5419,563.9287 C 543.8441,564.5587 541.0952,563.0214 540.3893,563.6437 C 539.6835,564.2661 541.0207,567.0478 540.3068,567.6623 C 539.5929,568.2768 538.8749,568.8874 538.1531,569.494 C 537.4313,570.1006 534.6584,568.54 533.9287,569.1388 C 533.199,569.7375 534.5125,572.4955 533.7751,573.0861 C 533.0376,573.6768 532.2963,574.2635 531.5511,574.8461 C 530.8058,575.4288 528.0098,573.844 527.257,574.4185 C 526.5042,574.9929 527.7947,577.7266 527.0343,578.2928 C 526.274,578.8591 525.5099,579.4211 524.7421,579.9791 C 523.9742,580.537 521.448,578.657 520.6729,579.2065 C 519.8976,579.7561 520.8735,582.7352 520.091,583.2763 C 519.3085,583.8174 518.5223,584.3543 517.7327,584.8868 C 516.9429,585.4194 513.81,583.514 513.0131,584.038 C 512.2163,584.562 513.7555,587.5154 512.9516,588.0307 C 512.1476,588.546 511.3402,589.0569 510.5293,589.5635 C 509.7184,590.0701 507.1493,587.8681 506.3315,588.3658 C 505.5137,588.8635 506.4471,592.0611 505.6225,592.5499 C 504.7979,593.0388 503.9698,593.5231 503.1385,594.003 C 502.3071,594.4829 499.7177,592.2542 498.8796,592.725 C 498.0416,593.1959 498.9549,596.3663 498.1103,596.828 C 497.2656,597.2897 496.4177,597.7469 495.5666,598.1995 C 494.7155,598.652 492.3988,596.1253 491.5412,596.5686 C 490.6837,597.0119 491.2852,600.4251 490.4213,600.8591 C 489.5574,601.293 488.6903,601.7222 487.8201,602.1468 C 486.95,602.5713 484.9069,600.0165 484.0305,600.4316 C 483.1541,600.8466 483.4445,604.2315 482.5621,604.637 C 481.6797,605.0425 480.7941,605.4432 479.9057,605.8391 C 479.0172,606.2349 476.371,604.1921 475.4765,604.5783 C 474.5821,604.9645 475.4394,607.7795 474.5391,608.1559 C 473.6388,608.5323 472.7356,608.9037 471.8295,609.2703 C 470.9234,609.6368 468.8446,607.2943 467.9328,607.6508 C 467.0211,608.0074 467.2762,611.0632 466.3588,611.4099 C 465.4414,611.7565 464.5211,612.098 463.5982,612.4346 C 462.6752,612.7711 460.2872,610.3983 459.3587,610.7247 C 458.4304,611.0511 458.9615,614.0766 458.0276,614.3928 C 457.0938,614.7089 456.1573,615.02 455.2181,615.3258 C 454.279,615.6317 452.4599,612.9578 451.5156,613.2532 C 450.5711,613.5488 450.5016,616.8137 449.552,617.0987 C 448.6025,617.3837 447.6505,617.6636 446.6959,617.9381 C 445.7413,618.2126 443.6144,615.7778 442.6548,616.0416 C 441.6953,616.3057 441.903,619.2684 440.9386,619.5217 C 439.9741,619.775 439.0072,620.0229 438.0379,620.2654 C 437.0686,620.508 435.8044,617.7705 434.8304,618.0023 C 433.8564,618.234 433.1724,621.4349 432.1936,621.6558 C 431.2149,621.8766 430.2339,622.092 429.2505,622.3019 C 428.2673,622.5118 426.1118,620.012 425.124,620.2108 C 424.1362,620.4097 424.3159,623.3072 423.3237,623.4949 C 422.3315,623.6827 421.337,623.8649 420.3404,624.0414 C 419.3438,624.218 417.7601,621.4143 416.7592,621.5797 C 415.7584,621.7449 415.3403,624.8792 414.3352,625.0332 C 413.3301,625.1872 412.323,625.3355 411.3138,625.4781 C 410.3047,625.6207 408.4162,622.7829 407.4029,622.914 C 406.3896,623.0451 406.2519,626.1451 405.2347,626.2646 C 404.2175,626.3842 403.1984,626.4979 402.1774,626.6059 C 401.1563,626.7138 399.5485,623.8413 398.5237,623.9376 C 397.4989,624.0338 397.0571,627.0988 396.0286,627.1832 C 395,627.2677 393.9697,627.3463 392.9375,627.4188 C 391.9053,627.4915 390.8714,624.0428 389.8357,624.1034 C 388.8,624.1642 387.7625,627.7343 386.7233,627.783 C 385.6841,627.8317 384.6432,627.8744 383.6006,627.911 C 382.558,627.9476 381.5138,624.7332 380.4679,624.7577 C 379.422,624.7823 378.3745,628.0457 377.3253,628.058 C 376.2762,628.0703 375.2255,628.0764 374.1732,628.0764 C 373.1209,628.0764 371.7777,624.8253 370.7286,624.813 C 369.6795,624.8007 368.9244,628.0273 367.8785,628.0027 C 366.8326,627.9782 365.7884,627.9476 364.7458,627.911 C 363.7032,627.8744 362.6623,624.8571 361.6231,624.8084 C 360.5839,624.7597 359.5464,627.6796 358.5107,627.6188 C 357.475,627.5582 356.4411,627.4915 355.4089,627.4188 C 354.3767,627.3463 353.6388,624.2931 352.6102,624.2086 C 351.5817,624.1242 350.2626,627.0084 349.2378,626.9122 C 348.213,626.8159 347.1901,626.7138 346.169,626.6059 C 345.148,626.4979 344.7138,623.6801 343.6966,623.5604 C 342.6795,623.4409 341.0793,626.0197 340.0662,625.8886 C 339.0529,625.7575 338.0417,625.6207 337.0326,625.4781 C 336.0234,625.3355 335.8936,622.483 334.8885,622.329 C 333.8835,622.175 332.0031,624.7195 331.0023,624.5543 C 330.0014,624.3889 329.0026,624.218 328.006,624.0414 C 327.0094,623.8649 326.5999,620.7081 325.6076,620.5203 C 324.6154,620.3326 323.0404,623.1139 322.0526,622.915 C 321.0648,622.7162 320.0792,622.5118 319.0959,622.3019 C 318.1126,622.092 317.7164,618.902 316.7377,618.6812 C 315.759,618.4603 314.1977,621.2086 313.2236,620.9769 C 312.2495,620.7451 311.2779,620.508 310.3086,620.2654 C 309.3393,620.0229 309.8346,616.8004 308.8701,616.5471 C 307.9056,616.2938 305.4814,619.0098 304.5218,618.7458 C 303.5623,618.4819 302.6051,618.2126 301.6505,617.9381 C 300.696,617.6636 300.9137,614.4091 299.9642,614.1241 C 299.0147,613.8391 296.8979,616.5234 295.9536,616.2278 C 295.0092,615.9324 294.0674,615.6317 293.1283,615.3258 C 292.1892,615.02 292.4225,612.0048 291.4886,611.6887 C 290.5548,611.3724 288.4539,613.7553 287.5254,613.4289 C 286.597,613.1025 285.6713,612.7711 284.7483,612.4346 C 283.8253,612.098 284.0749,609.0523 283.1575,608.7057 C 282.2401,608.359 280.1556,610.7116 279.2438,610.355 C 278.332,609.9984 277.4231,609.6368 276.517,609.2703 C 275.6109,608.9037 275.8775,605.5577 274.9772,605.1813 C 274.0769,604.8049 272.0097,607.3983 271.1152,607.0121 C 270.2208,606.6259 269.3293,606.2349 268.4408,605.8391 C 267.5523,605.4432 267.8366,602.3383 266.9542,601.9328 C 266.0717,601.5273 264.0225,603.8212 263.1461,603.4062 C 262.2698,602.9911 261.3965,602.5713 260.5263,602.1468 C 259.6562,601.7222 259.9589,599.1297 259.095,598.6958 C 258.231,598.2618 256.2005,599.9865 255.3429,599.5432 C 254.4854,599.0999 253.631,598.652 252.7799,598.1995 C 251.9288,597.7469 252.8355,594.856 251.9909,594.3942 C 251.1463,593.9326 248.5502,595.9 247.7122,595.4291 C 246.8741,594.9583 246.0394,594.4829 245.208,594.003 C 244.3766,593.5231 245.0108,590.605 244.1862,590.1161 C 243.3616,589.6274 241.0781,591.5677 240.2603,591.07 C 239.4425,590.5723 238.6281,590.0701 237.8172,589.5635 C 237.0063,589.0569 237.9535,586.6531 237.1496,586.1378 C 236.3457,585.6225 233.7906,586.9957 232.9937,586.4717 C 232.1969,585.9478 231.4035,585.4194 230.6138,584.8868 C 229.8241,584.3543 230.7927,581.6541 230.0102,581.113 C 229.2277,580.5718 226.6941,582.1899 225.9189,581.6403 C 225.1437,581.0908 224.3722,580.537 223.6044,579.9791 C 222.8366,579.4211 223.8272,576.6958 223.0669,576.1295 C 222.3065,575.5633 219.7952,577.1562 219.0424,576.5818 C 218.2896,576.0073 217.5406,575.4288 216.7954,574.8461 C 216.0502,574.2635 217.356,571.7839 216.6186,571.1932 C 215.881,570.6026 213.1003,571.9008 212.3706,571.3021 C 211.6409,570.7033 210.9151,570.1006 210.1933,569.494 C 209.4715,568.8874 210.8008,566.3839 210.0869,565.7694 C 209.373,565.1548 206.6159,566.4294 205.91,565.8071 C 205.2042,565.1848 204.5023,564.5587 203.8046,563.9287 C 203.1068,563.2987 204.4603,561.0423 203.7707,560.4047 C 203.0811,559.7671 200.3484,560.7481 199.6671,560.1029 C 198.9858,559.4577 198.3086,558.8088 197.6356,558.1561 C 196.9626,557.5034 198.6334,555.2245 197.9689,554.5643 C 197.3043,553.9042 194.3044,554.863 193.6483,554.1955 C 192.9922,553.5281 192.3404,552.857 191.6929,552.1823 C 191.0454,551.5075 192.157,548.9363 191.5181,548.2543 C 190.8793,547.5724 188.4901,548.7798 187.8601,548.0908 C 187.23,547.4017 186.6043,546.7092 185.983,546.0131 C 185.3617,545.317 187.0845,542.7245 186.4721,542.0215 C 185.8598,541.3184 182.9122,542.5048 182.3089,541.7948 C 181.7055,541.0848 181.1066,540.3715 180.5123,539.6547 C 179.9179,538.9379 181.6677,536.3248 181.0826,535.6013 C 180.4974,534.8777 177.5772,536.0438 177.0012,535.3135 C 176.4252,534.5833 175.8539,533.8498 175.2872,533.113 C 174.7205,532.3761 176.7906,530.0135 176.2333,529.2701 C 175.6759,528.5268 172.4913,529.4027 171.9435,528.6529 C 171.3957,527.9031 170.8526,527.1501 170.3143,526.3939 C 169.776,525.6376 172.1669,523.2557 171.6383,522.4933 C 171.1096,521.7308 167.6612,522.5876 167.1422,521.8189 C 166.6233,521.0502 166.1091,520.2783 165.5999,519.5034 C 165.0907,518.7285 166.926,516.328 166.4267,515.5471 C 165.9273,514.766 163.0933,515.6046 162.6039,514.8175 C 162.1145,514.0305 161.6301,513.2405 161.1507,512.4476 C 160.6713,511.6546 162.829,509.5066 162.3597,508.7078 C 161.8904,507.909 158.794,508.4594 158.3349,507.6547 C 157.8758,506.8501 157.4218,506.0426 156.9729,505.2323 C 156.524,504.422 158.7124,502.2567 158.2738,501.4407 C 157.8353,500.6247 154.7699,501.1581 154.3418,500.3365 C 153.9137,499.515 153.4908,498.6906 153.0732,497.8636 C 152.6555,497.0366 154.8753,495.1252 154.4682,494.2927 C 154.0612,493.4602 151.0273,493.7067 150.631,492.8689 C 150.2346,492.031 149.8435,491.1906 149.4579,490.3474 C 149.0722,489.5044 151.6164,487.5769 151.2416,486.7286 C 150.8667,485.8803 147.5728,486.1111 147.2089,485.2577 C 146.8449,484.4043 146.4865,483.5483 146.1335,482.6898 C 145.7805,481.8313 149.235,480.4294 148.893,479.5661 C 148.5511,478.7025 144.4128,478.3774 144.082,477.5091 C 143.7513,476.6407 143.4261,475.7699 143.1065,474.8967 C 142.7869,474.0235 145.3975,472.0663 145.0892,471.1883 C 144.7809,470.3103 141.5538,470.5115 141.2569,469.6289 C 140.96,468.7463 140.6688,467.8613 140.3833,466.974 C 140.0979,466.0867 143.3276,464.9268 143.0537,464.035 C 142.7798,463.1431 139.0022,462.5195 138.7399,461.6232 C 138.4776,460.727 138.2211,459.8284 137.9705,458.9278 C 137.7199,458.0271 140.3996,456.3131 140.1608,455.4081 C 139.922,454.5031 136.7645,454.4072 136.5376,453.498 C 136.3106,452.5887 136.0895,451.6774 135.8745,450.764 C 135.6594,449.8506 138.6673,448.1238 138.4643,447.2065 C 138.2613,446.2889 134.8472,446.1807 134.6563,445.2591 C 134.4653,444.3376 134.2804,443.4141 134.1017,442.4886 C 133.9229,441.5632 136.6747,440.3654 136.5082,439.436 C 136.3416,438.5067 133.2568,437.8458 133.1026,436.9127 C 132.9484,435.9795 132.8003,435.0445 132.6586,434.1076 C 132.5168,433.1708 135.5982,431.9617 135.4689,431.0211 C 135.3396,430.0806 131.9996,429.4087 131.8829,428.4646 C 131.7661,427.5205 131.6557,426.5746 131.5516,425.627 C 131.4476,424.6794 133.9819,423.7301 133.8906,422.779 C 133.7992,421.828 131.0822,420.8752 131.0036,419.9208 C 130.9251,418.9664 130.853,418.0104 130.7873,417.0527 C 130.7217,416.095 133.587,414.8653 133.5343,413.9044 C 133.4817,412.9435 130.511,412.2514 130.4714,411.2874 C 130.4317,410.3234 130.3987,409.3578 130.3721,408.3907 C 130.3457,407.4236 133.5426,405.9142 133.5295,404.9442 C 133.5162,403.9741 130.2925,403.5433 130.2925,402.5703 C 130.2925,401.5973 130.2992,400.6258 130.3125,399.6557 C 130.3257,398.6856 133.8551,397.4466 133.8815,396.4795 C 133.9081,395.5124 130.4317,394.8172 130.4714,393.8532 C 130.511,392.8892 130.5572,391.9267 130.6098,390.9658 C 130.6625,390.0049 133.6462,388.7752 133.7118,387.8175 C 133.7775,386.8598 130.9251,386.1742 131.0036,385.2198 C 131.0822,384.2654 131.1671,383.3126 131.2585,382.3616 C 131.3498,381.4106 134.3721,380.4612 134.4761,379.5136 C 134.5802,378.566 131.7661,377.6201 131.8829,376.676 C 131.9996,375.7319 132.1226,374.7896 132.2519,373.8491 C 132.3812,372.9086 135.4413,372.5107 135.5831,371.5739 C 135.7248,370.637 132.9484,369.161 133.1026,368.2279 C 133.2568,367.2948 133.4171,366.3635 133.5837,365.4342 C 133.7502,364.5049 136.8474,364.659 137.0262,363.7335 C 137.2049,362.8081 134.4653,360.803 134.6563,359.8815 C 134.8472,358.9599 135.0443,358.0404 135.2473,357.1229 C 135.4503,356.2054 138.5839,355.8308 138.799,354.9174 C 139.014,354.004 136.3106,352.5518 136.5376,351.6426 C 136.7645,350.7334 136.9975,349.8263 137.2363,348.9213 C 137.4751,348.0163 140.6444,347.6542 140.895,346.7536 C 141.1456,345.8529 138.4776,344.4136 138.7399,343.5173 C 139.0022,342.6211 139.2704,341.727 139.5443,340.8352 C 139.8182,339.9434 142.7299,340.1354 143.0154,339.2481 C 143.3008,338.361 140.96,336.3943 141.2569,335.5116 C 141.5538,334.629 141.8564,333.7487 142.1647,332.8707 C 142.473,331.9927 145.419,331.9283 145.7386,331.0551 C 146.0582,330.1819 143.7513,328.4998 144.082,327.6315 C 144.4128,326.7631 144.7492,325.8972 145.0911,325.0337 C 145.4331,324.1702 148.1201,324.3908 148.4731,323.5323 C 148.8261,322.674 146.8449,320.7363 147.2089,319.8828 C 147.5728,319.0294 147.9422,318.1786 148.3171,317.3302 C 148.6919,316.4819 151.7043,316.9883 152.09,316.1452 C 152.4756,315.3021 150.2346,313.1095 150.631,312.2717 C 151.0273,311.4339 151.4291,310.5987 151.8361,309.7662 C 152.2432,308.9338 155.2876,309.4561 155.7053,308.629 C 156.1228,307.802 153.9137,305.6256 154.3418,304.804 C 154.7699,303.9825 155.2032,303.1637 155.6418,302.3477 C 156.0803,301.5318 158.8636,302.0706 159.3125,301.2604 C 159.7614,300.45 157.8758,298.2904 158.3349,297.4857 C 158.794,296.6812 159.2583,295.8794 159.7276,295.0806 C 160.1969,294.2819 162.7184,294.8381 163.1979,294.045 C 163.6772,293.2522 162.1145,291.1101 162.6039,290.323 C 163.0933,289.536 163.5877,288.752 164.0871,287.971 C 164.5864,287.19 167.4303,287.7642 167.9395,286.9892 C 168.4487,286.2143 166.6233,284.0904 167.1422,283.3216 C 167.6612,282.5529 168.1851,281.7872 168.7138,281.0247 C 169.2424,280.2623 172.4081,281.1254 172.9464,280.3691 C 173.4847,279.6129 171.3957,277.2375 171.9435,276.4876 C 172.4913,275.7379 173.0439,274.9912 173.6012,274.2479 C 174.1585,273.5045 176.7677,274.1166 177.3344,273.3797 C 177.9011,272.6428 176.4252,270.5573 177.0012,269.827 C 177.5772,269.0968 178.1578,268.3699 178.743,267.6464 C 179.3281,266.9229 181.965,267.8252 182.5595,267.1084 C 183.1538,266.3916 181.7055,264.0557 182.3089,263.3458 C 182.9122,262.6358 183.5202,261.9292 184.1325,261.2262 C 184.7449,260.5231 187.3804,260.7149 188.0302,259.9387 C 189.2007,258.9743 187.23,257.7387 187.8601,257.0497 C 188.4901,256.3606 189.1246,255.6751 189.7634,254.9932 C 190.4023,254.3114 193.0925,255.2555 193.7401,254.5809 C 194.3876,253.9061 192.9922,251.6125 193.6483,250.945 C 194.3044,250.2776 194.9647,249.6138 195.6293,248.9536 C 196.2938,248.2935 198.7173,249.2597 199.3903,248.607 C 200.0633,247.9543 198.9858,245.6828 199.6671,245.0376 C 200.3484,244.3924 201.0339,243.7509 201.7235,243.1133 C 202.4131,242.4757 204.8615,243.7346 205.5593,243.1048 C 206.257,242.4748 205.2042,239.9557 205.91,239.3335 C 206.6159,238.7112 207.3258,238.0927 208.0397,237.4783 C 208.7536,236.8637 210.9338,238.1461 211.6556,237.5394 C 212.3774,236.9327 211.6409,234.4371 212.3706,233.8384 C 213.1003,233.2398 213.8339,232.645 214.5714,232.0543 C 215.3089,231.4636 217.5125,232.7698 218.2576,232.1872 C 219.0028,231.6046 218.2896,229.1331 219.0424,228.5587 C 219.7952,227.9843 220.5518,227.4139 221.3122,226.8477 C 222.0725,226.2814 224.5913,227.8827 225.3591,227.3246 C 226.1269,226.7669 225.1437,224.0497 225.9189,223.5002 C 226.6941,222.9506 227.473,222.4053 228.2555,221.8642 C 229.038,221.323 231.5788,222.6791 232.3685,222.1466 C 233.1582,221.6139 232.1969,219.1927 232.9937,218.6688 C 233.7906,218.1448 234.591,217.6252 235.3949,217.1098 C 236.1988,216.5946 238.761,217.9765 239.5719,217.4699 C 240.3828,216.9634 239.4425,214.5682 240.2603,214.0705 C 241.0781,213.5728 241.8993,213.0794 242.724,212.5906 C 243.5486,212.1017 246.1313,213.7808 246.9627,213.3009 C 247.7941,212.8209 246.8741,210.1822 247.7122,209.7114 C 248.5502,209.2405 249.3916,208.7743 250.2362,208.3125 C 251.0808,207.8508 253.0986,209.557 253.9497,209.1044 C 254.8008,208.6519 254.4854,206.0406 255.3429,205.5973 C 256.2005,205.1541 257.0612,204.7154 257.9252,204.2815 C 258.7891,203.8476 261.1184,205.5817 261.9886,205.157 C 262.8588,204.7326 262.2698,202.1494 263.1461,201.7343 C 264.0225,201.3193 264.9019,200.909 265.7844,200.5035 C 266.6668,200.0981 269.307,201.8606 270.1955,201.4648 C 271.084,201.0689 270.2208,198.5146 271.1152,198.1284 C 272.0097,197.7422 272.9071,197.3609 273.8074,196.9846 C 274.7077,196.6082 276.7807,198.4001 277.6868,198.0336 C 278.5929,197.667 278.332,195.1421 279.2438,194.7855 C 280.1556,194.4289 281.0703,194.0773 281.9877,193.7307 C 282.9051,193.3841 284.9951,195.4762 285.9181,195.1398 C 286.8411,194.8033 286.597,192.038 287.5254,191.7116 C 288.4539,191.3852 289.385,191.0639 290.3188,190.7477 C 291.2527,190.4315 293.6515,192.2839 294.5906,191.978 C 295.5296,191.6722 295.0092,189.2081 295.9536,188.9126 C 296.8979,188.6171 297.8449,188.3268 298.7944,188.0418 C 299.7439,187.7567 301.5733,190.181 302.5278,189.9065 C 303.4824,189.6319 303.5623,186.6586 304.5218,186.3947 C 305.4814,186.1307 306.4434,185.8721 307.4079,185.6188 C 308.3724,185.3655 309.9242,187.8218 310.8935,187.5792 C 311.8628,187.3366 312.2495,184.3954 313.2236,184.1636 C 314.1977,183.9319 315.1741,183.7055 316.1528,183.4847 C 317.1315,183.2639 318.4051,185.4823 319.3884,185.2723 C 320.3717,185.0624 321.0648,182.4243 322.0526,182.2254 C 323.0404,182.0266 324.0305,181.8333 325.0227,181.6456 C 326.015,181.4578 327.5943,183.9799 328.5909,183.8032 C 329.5875,183.6267 330.0014,180.7516 331.0023,180.5863 C 332.0031,180.421 333.0061,180.2613 334.0112,180.1073 C 335.0163,179.9533 336.6083,182.5092 337.6175,182.3666 C 338.6266,182.224 339.0529,179.383 340.0662,179.2519 C 341.0793,179.1208 342.0946,178.9954 343.1117,178.8759 C 344.1289,178.7563 345.7329,181.0763 346.7539,180.9684 C 347.775,180.8606 348.213,178.3246 349.2378,178.2284 C 350.2626,178.1321 351.2893,178.0418 352.3178,177.9573 C 353.3464,177.8728 354.6692,180.2281 355.7013,180.1554 C 356.7335,180.0827 357.475,177.5823 358.5107,177.5217 C 359.5464,177.4609 360.5839,177.4062 361.6231,177.3575 C 362.6623,177.3088 363.7032,179.9702 364.7458,179.9336 C 365.7884,179.897 366.8326,177.1623 367.8785,177.1378 C 368.9244,177.1133 369.972,177.0949 371.0211,177.0826 C 372.0702,177.0703 373.1209,180.2524 374.1732,180.2524 C 375.2255,180.2524 376.2762,177.0703 377.3253,177.0826 C 378.3745,177.0949 379.422,177.1133 380.4679,177.1378 C 381.5138,177.1623 381.9833,180.3811 383.0259,180.4178 C 384.0685,180.4544 385.6841,177.3088 386.7233,177.3575 C 387.7625,177.4062 388.8,177.4609 389.8357,177.5217 C 390.8714,177.5823 391.3204,180.6236 392.3526,180.6962 C 393.3848,180.7689 395,177.8728 396.0286,177.9573 C 397.0571,178.0418 398.0838,178.1321 399.1086,178.2284 C 400.1334,178.3246 400.5714,180.8606 401.5925,180.9684 C 402.6135,181.0763 404.2175,178.7563 405.2347,178.8759 C 406.2519,178.9954 407.267,179.1208 408.2802,179.2519 C 409.2935,179.383 409.1349,181.6832 410.144,181.8258 C 411.1532,181.9684 413.3301,179.9533 414.3352,180.1073 C 415.3403,180.2613 416.3433,180.421 417.3441,180.5863 C 418.345,180.7516 418.174,183.3563 419.1706,183.5328 C 420.1672,183.7095 422.3315,181.4578 423.3237,181.6456 C 424.3159,181.8333 425.306,182.0266 426.2938,182.2254 C 427.2816,182.4243 427.0975,185.3328 428.0807,185.5428 C 429.0641,185.7527 431.2149,183.2639 432.1936,183.4847 C 433.1724,183.7055 434.1488,183.9319 435.1228,184.1636 C 436.0969,184.3954 436.1913,187.0662 437.1606,187.3088 C 438.1299,187.5514 439.9741,185.3655 440.9386,185.6188 C 441.903,185.8721 442.8651,186.1307 443.8246,186.3947 C 444.7842,186.6586 444.2791,189.3615 445.2336,189.6361 C 446.1883,189.9106 448.6025,187.7567 449.552,188.0418 C 450.5016,188.3268 451.4485,188.6171 452.3929,188.9126 C 453.3372,189.2081 452.8167,191.9427 453.7558,192.2484 C 454.695,192.5543 457.0938,190.4315 458.0276,190.7477 C 458.9615,191.0639 459.8926,191.3852 460.821,191.7116 C 461.7495,192.038 461.213,194.8033 462.136,195.1398 C 463.0588,195.4762 465.4414,193.3841 466.3588,193.7307 C 467.2762,194.0773 468.1909,194.4289 469.1026,194.7855 C 470.0144,195.1421 469.4612,197.9374 470.3672,198.304 C 471.2734,198.6705 473.6388,196.6082 474.5391,196.9846 C 475.4394,197.3609 476.3368,197.7422 477.2312,198.1284 C 478.1257,198.5146 477.5549,201.0689 478.4434,201.4648 C 479.3318,201.8606 481.6797,200.0981 482.5621,200.5035 C 483.4445,200.909 484.3239,201.3193 485.2003,201.7343 C 486.0767,202.1494 485.4878,204.7325 486.3578,205.157 C 487.2281,205.5816 489.5574,203.8476 490.4213,204.2815 C 491.2852,204.7154 492.1459,205.1541 493.0035,205.5973 C 493.8611,206.0406 492.6683,208.3815 493.5194,208.834 C 494.3706,209.2865 497.2656,207.8508 498.1103,208.3125 C 498.9549,208.7743 499.7963,209.2405 500.6343,209.7114 C 501.4724,210.1822 500.5524,212.5504 501.3838,213.0304 C 502.2151,213.5103 504.7979,212.1017 505.6225,212.5906 C 506.4471,213.0794 507.2684,213.5728 508.0862,214.0705 C 508.904,214.5682 507.9637,216.9635 508.7746,217.47 C 509.5855,217.9766 512.1476,216.5946 512.9516,217.1098 C 513.7555,217.6252 514.5559,218.1448 515.3527,218.6688 C 516.1496,219.1927 515.1882,221.6139 515.978,222.1466 C 516.7676,222.6791 519.3085,221.323 520.091,221.8642 C 520.8735,222.4053 521.6523,222.9506 522.4276,223.5002 C 523.2027,224.0497 521.9271,226.226 522.6949,226.7838 C 523.4628,227.3418 526.274,226.2814 527.0343,226.8477 C 527.7947,227.4139 528.5513,227.9843 529.3041,228.5587 C 530.0569,229.1331 529.0511,231.6046 529.7964,232.1872 C 530.5416,232.7698 532.9774,231.5348 533.7751,232.0543 C 535.0974,233.1859 534.0764,235.1327 534.2212,235.7313 C 534.951,236.3299 537.4313,235.0398 538.1531,235.6465 C 538.8749,236.2531 539.5929,236.8637 540.3068,237.4783 C 541.0207,238.0927 539.391,240.604 540.0969,241.2264 C 540.8027,241.8486 543.8441,240.5819 544.5419,241.2119 C 545.2397,241.8418 545.9334,242.4757 546.623,243.1133 C 547.3126,243.7509 545.9508,245.4741 546.6323,246.1193 C 547.3135,246.7645 550.0378,246.3318 550.7109,246.9844 C 551.3839,247.6371 552.0527,248.2935 552.7172,248.9536 C 553.3818,249.6138 551.9949,251.9001 552.651,252.5675 C 553.3071,253.235 556.0061,252.2836 556.6536,252.9583 C 557.3011,253.633 557.9443,254.3114 558.5831,254.9932 C 559.2219,255.6751 557.8093,257.9831 558.4393,258.6722 C 559.0693,259.3612 561.7422,258.4313 562.3635,259.1274 C 562.9847,259.8235 563.6016,260.5231 564.214,261.2262 C 564.8263,261.9292 563.0947,263.9879 563.6981,264.6978 C 564.3015,265.4078 567.2399,264.7691 567.8342,265.4859 C 568.4285,266.2027 569.0183,266.9229 569.6035,267.6464 C 570.1887,268.3699 568.4297,270.7193 569.0057,271.4495 C 569.5817,272.1799 572.4926,271.2907 573.0593,272.0276 C 573.6259,272.7645 574.1879,273.5045 574.7452,274.2479 C 575.3026,274.9912 573.2232,277.3604 573.771,278.1101 C 574.3188,278.86 577.4939,277.9904 578.0322,278.7467 C 578.5706,279.5029 579.104,280.2623 579.6328,281.0247 C 580.1614,281.7872 578.3457,284.1754 578.8647,284.9441 C 579.3837,285.7129 582.2374,284.8622 582.7466,285.6371 C 583.2558,286.4121 583.7601,287.19 584.2594,287.971 C 584.7588,288.752 582.3287,290.888 582.8181,291.675 C 583.3075,292.4621 586.7164,291.9001 587.1959,292.6929 C 587.6752,293.486 588.1496,294.2819 588.6189,295.0806 C 589.0882,295.8794 586.9203,297.7629 587.3795,298.5674 C 587.8386,299.372 590.9247,299.0979 591.3735,299.9083 C 591.8224,300.7186 592.2662,301.5318 592.7047,302.3477 C 593.1432,303.1637 590.6521,305.0641 591.0801,305.8857 C 591.5082,306.7073 594.8557,306.4499 595.2733,307.2769 C 595.691,308.104 596.1033,308.9338 596.5104,309.7662 C 596.9174,310.5987 594.3947,312.5156 594.7911,313.3534 C 595.1874,314.1911 598.5029,313.95 598.8886,314.7931 C 599.2743,315.6362 599.6545,316.4819 600.0294,317.3302 C 600.4042,318.1786 597.8492,319.8407 598.2131,320.6941 C 598.577,321.5476 601.86,321.5923 602.213,322.4507 C 602.566,323.3092 602.9135,324.1702 603.2554,325.0337 C 603.5973,325.8972 601.3016,327.5743 601.6324,328.4427 C 601.9631,329.311 604.9204,329.3707 605.24,330.2439 C 605.5596,331.1171 605.8735,331.9927 606.1818,332.8707 C 606.4901,333.7487 603.5757,335.4402 603.8726,336.3228 C 604.1696,337.2055 607.6777,337.2793 607.9631,338.1665 C 608.2486,339.0538 608.5284,339.9434 608.8022,340.8352 C 609.0761,341.727 606.4197,343.4323 606.6821,344.3285 C 606.9445,345.2248 610.1254,345.3121 610.376,346.2128 C 610.6266,347.1134 610.8713,348.0163 611.1102,348.9213 C 611.3491,349.8263 608.3651,351.2742 608.592,352.1834 C 608.8188,353.0927 612.257,353.4632 612.472,354.3766 C 612.6871,355.29 612.8962,356.2054 613.0992,357.1229 C 613.3022,358.0404 610.8672,359.7711 611.0581,360.6927 C 611.2491,361.6143 614.0662,361.7265 614.2449,362.6519 C 614.4237,363.5774 614.5964,364.5049 614.7629,365.4342 C 614.9294,366.3635 611.8729,367.8356 612.027,368.7687 C 612.1812,369.7018 615.5462,370.0961 615.688,371.033 C 615.8298,371.9698 615.9654,372.9086 616.0946,373.8491 C 616.2239,374.7896 613.4225,376.2727 613.5392,377.2168 C 613.6559,378.1609 616.6909,378.566 616.7949,379.5136 C 616.8989,380.4612 616.9966,381.4106 617.088,382.3616 C 617.1794,383.3126 614.3398,384.8062 614.4183,385.7606 C 614.4969,386.715 617.4935,387.1302 617.5591,388.0879 C 617.6248,389.0456 617.684,390.0049 617.7367,390.9658 C 617.7893,391.9267 614.6187,392.8892 614.6581,393.8532 C 614.6979,394.8172 617.9478,395.7828 617.9743,396.7499 C 618.0009,397.717 618.0208,398.6856 618.034,399.6557 C 618.0473,400.6258 614.5446,401.8677 614.5446,402.8408 z "
- style="font-size:12px;fill:url(#linearGradient2197);fill-rule:evenodd;stroke-width:1" /><rect
- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.50000000000000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
- id="rect6160"
- width="430.38559"
- height="249.90131"
- x="187.06802"
- y="440.44824"
- ry="104.67665" /><path
- sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
- id="path648"
- d="M 577.7341,654.0496 C 569.7135,657.0012 563.297,658.2439 557.7717,658.2439 C 546.0082,658.2439 540.3047,652.4962 540.3047,640.6899 C 540.3047,629.5051 543.6912,616.1454 549.5729,604.1838 C 554.5635,594.2417 560.4453,589.2707 567.2182,589.2707 C 572.387,589.2707 574.8823,592.3776 574.8823,598.5914 L 574.8823,599.2128 L 574.8823,600.4555 L 573.9911,606.048 L 573.6346,607.4461 L 588.2499,607.4461 L 593.2405,586.0084 C 585.0417,583.3676 577.7341,582.2802 569.7135,582.2802 C 537.8094,582.2802 513.3913,606.514 513.3913,638.2044 C 513.3913,658.0886 526.4024,669.2734 549.7512,669.2734 C 557.0588,669.2734 564.3664,668.186 575.2388,665.3898 L 577.7341,654.0496 z M 218.4849,661.2247 C 236.7908,665.7944 248.9948,667.7936 259.7459,667.7936 C 307.9805,667.7936 346.917,633.8069 346.917,592.109 C 346.917,556.4087 321.0562,538.1302 271.9498,538.7014 L 260.9081,538.7014 L 274.8555,487.8643 L 365.2229,487.8643 L 371.6154,456.1625 L 264.1044,456.1625 L 244.3456,552.9815 C 250.7382,552.1247 256.5496,551.8391 260.6176,551.8391 C 288.8029,551.8391 302.1691,564.6912 302.1691,590.681 C 302.1691,626.0957 282.9915,654.9415 259.7459,654.9415 C 248.7042,654.9415 242.6022,650.6575 242.6022,643.5174 C 242.6022,642.375 242.8928,639.519 244.0551,634.0925 L 245.2173,625.5244 L 245.5079,622.954 L 226.0397,622.954 L 218.4849,661.2247 z M 419.5596,559.5503 C 425.6615,527.8485 430.8918,506.7141 436.9938,489.8635 C 443.3863,471.0138 449.7789,463.8737 459.6583,463.8737 C 468.6659,463.8737 473.0245,469.8714 473.0245,482.4378 C 473.0245,513.8541 456.7526,595.2506 443.0958,632.0933 C 436.9938,648.6582 431.1823,654.9415 421.5935,654.9415 C 412.5859,654.9415 408.2273,648.9438 408.2273,636.663 C 408.2273,625.81 409.9707,611.5299 412.8764,595.5362 L 419.5596,559.5503 z M 462.2734,451.0216 C 439.6089,451.0216 421.0123,462.4457 404.1594,486.1507 C 382.3665,516.7101 370.4532,558.1224 370.4532,602.1051 C 370.4532,646.3734 385.5628,667.7936 416.9444,667.7936 C 448.0354,667.7936 473.3151,647.5158 490.7493,608.3883 C 503.2438,580.6849 510.7986,545.8415 510.7986,515.5677 C 510.7986,472.7274 494.5267,451.0216 462.2734,451.0216 z M 612.4983,536.131 C 612.4983,536.131 612.4983,524.7069 612.4983,536.131 z M 238.6012,590.4054 L 238.6012,590.4054 z M 460.132,586.1403 C 460.132,586.1403 460.132,580.6408 460.132,586.1403 z M 254.0036,467.903 L 254.0036,467.903 z M 639.0957,520.2476 C 639.0957,651.4152 532.7637,757.7475 401.5958,757.7475 C 270.4286,757.7475 164.0962,651.4152 164.0962,520.2476 C 164.0962,389.0801 270.4286,282.7479 401.5958,282.7479 C 532.7637,282.7479 639.0957,389.0801 639.0957,520.2476 z M 390.9698,631.2727 L 390.9698,631.2727 z M 265.3258,412.7872 L 265.3258,412.7872 z "
- style="font-size:48px;font-style:italic;font-weight:bold;fill:url(#linearGradient2199);font-family:Luxi Serif" /><g
+ d="m 598.72407,520.49055 c 0,0.86299 2.87259,1.48481 2.86168,2.34522 -0.0108,0.86033 -0.0271,1.71941 -0.049,2.57716 -0.0217,0.85775 -2.92688,1.71417 -2.95943,2.56917 -0.0325,0.855 2.80771,1.70867 2.76457,2.56092 -0.0432,0.85225 -0.0918,1.70308 -0.14565,2.55249 -0.0538,0.84942 -2.99109,1.93715 -3.05547,2.78363 -0.0645,0.84649 2.74408,1.45173 2.66912,2.2952 -0.075,0.84356 -0.15508,1.68552 -0.24037,2.52598 -0.0853,0.84045 -2.81412,1.43958 -2.90982,2.27693 -0.0958,0.83735 2.44154,1.91293 2.3355,2.74708 -0.10596,0.83425 -0.21717,1.66681 -0.33346,2.49769 -0.11629,0.83096 -3.35563,1.18059 -3.48209,2.00827 -0.12646,0.8276 2.85996,2.13325 2.72341,2.95747 -0.13655,0.82432 -0.27818,1.64685 -0.42481,2.46762 -0.14656,0.82085 -2.93656,0.92046 -3.09312,1.73767 -0.15664,0.8174 2.32,2.3525 2.15352,3.16625 -0.16648,0.81367 -0.33797,1.62566 -0.51437,2.43578 -0.17632,0.81012 -2.75605,0.89882 -2.94213,1.7053 -0.18617,0.8064 2.02123,2.3305 1.82531,3.13317 -0.19592,0.80267 -0.3966,1.60339 -0.60212,2.40225 -0.20552,0.79877 -3.29388,0.87629 -3.50899,1.67115 -0.21528,0.79496 2.44293,2.30735 2.2183,3.09841 -0.22454,0.79096 -0.45401,1.57988 -0.68815,2.36686 -0.23406,0.78697 -2.87127,0.85243 -3.11476,1.63523 -0.24349,0.7828 1.90674,2.28314 1.65391,3.06186 -0.25284,0.77872 -0.51027,1.55532 -0.77238,2.32979 -0.26211,0.77447 -2.92721,0.58741 -3.19842,1.35762 -0.27129,0.77012 1.85123,2.4976 1.57084,3.26346 -0.2804,0.76578 -0.56538,1.52942 -0.85488,2.29085 -0.2895,0.76143 -2.98191,0.56134 -3.28035,1.31825 -0.29843,0.7569 1.79694,2.4709 1.48956,3.22328 -0.30745,0.75238 -0.61926,1.50255 -0.93557,2.25023 -0.31632,0.74786 -3.03538,0.53384 -3.36039,1.27709 -0.32509,0.74307 1.74379,2.44305 1.41001,3.18142 -0.33387,0.73837 -0.672,1.47434 -1.01455,2.20783 -0.34248,0.73349 -3.56739,0.50529 -3.91847,1.23399 -0.35109,0.7287 2.17156,2.41413 1.81194,3.13787 -0.35962,0.72373 -0.72358,1.44498 -1.09173,2.16366 -0.36806,0.71868 -2.89899,-0.004 -3.2755,0.70946 -0.37659,0.71371 1.40132,2.86381 1.01644,3.57229 -0.38488,0.70848 -0.77394,1.41439 -1.16701,2.11772 -0.39324,0.70325 -3.42879,-0.0351 -3.83015,0.66289 -0.40127,0.69811 1.83147,2.83241 1.42191,3.52519 -0.40948,0.69261 -0.82306,1.38264 -1.24066,2.06992 -0.4176,0.68728 -2.75794,-0.0671 -3.18357,0.61464 -0.42564,0.68179 1.06343,2.79995 0.62992,3.47624 -0.43367,0.67628 -0.87112,1.34973 -1.31266,2.02051 -0.44146,0.6707 -2.80559,-0.10049 -3.25484,0.56453 -0.44925,0.66503 1.01628,2.76625 0.55915,3.42551 -0.45705,0.65934 -0.91795,1.31576 -1.38262,1.96934 -0.46475,0.65349 -2.852,-0.13499 -3.32438,0.51264 -0.47238,0.64773 0.97018,2.73139 0.49026,3.37317 -0.47993,0.6417 -0.96363,1.28046 -1.45102,1.91622 -0.48739,0.63575 -2.89719,-0.17065 -3.39204,0.45916 -0.49485,0.62963 0.92525,2.69529 0.42309,3.31889 -0.50223,0.62351 -1.00815,1.24401 -1.5176,1.8614 -0.50953,0.61739 -3.18128,-0.20745 -3.69794,0.40373 -0.51667,0.6111 1.12149,2.65813 0.59761,3.26293 -0.52389,0.60489 -1.05138,1.20649 -1.5824,1.80499 -0.53102,0.59841 -2.98437,-0.72515 -3.52236,-0.13313 -0.53807,0.59203 0.83914,3.09938 0.29409,3.68484 -0.54496,0.58555 -1.09344,1.16774 -1.64537,1.74663 -0.55202,0.5789 -3.02603,-0.76426 -3.58477,-0.19202 -0.55882,0.57225 0.7978,3.05991 0.23225,3.62542 -0.56554,0.56551 -1.13445,1.12773 -1.70672,1.6865 -0.57227,0.55876 -2.82666,-0.80471 -3.40558,-0.25278 -0.57883,0.55203 0.51782,3.0192 -0.0677,3.56422 -0.58548,0.54502 -1.17431,1.08658 -1.76627,1.62459 -0.59195,0.53801 -2.86602,-0.84613 -3.46445,-0.31504 -0.59844,0.53101 0.47877,2.97716 -0.12597,3.50098 -0.60483,0.52391 -1.21278,1.04427 -1.82392,1.561 -0.61122,0.51681 -2.90424,-0.88879 -3.52162,-0.37925 -0.61737,0.50945 0.44097,2.93405 -0.18264,3.43623 -0.62352,0.50227 -1.25017,1.00072 -1.87984,1.49563 -0.62976,0.49482 -2.70152,-1.17261 -3.33718,-0.68524 -0.63583,0.48745 0.16451,3.12971 -0.47722,3.60963 -0.64173,0.47991 -1.2865,0.95611 -1.93406,1.4284 -0.64772,0.47238 -3.21703,-1.21758 -3.87057,-0.75283 -0.65346,0.46475 0.60884,3.08421 -0.0504,3.54125 -0.65936,0.45703 -1.32152,0.91016 -1.98654,1.35948 -0.66503,0.44932 -2.77196,-1.5037 -3.44265,-1.06227 -0.67068,0.44142 0.0948,3.27747 -0.58145,3.711 -0.67626,0.43362 -1.35539,0.86316 -2.03715,1.2888 -0.68183,0.42564 -2.80542,-1.55106 -3.49275,-1.1335 -0.68725,0.41766 0.0618,3.22958 -0.6309,3.63908 -0.69275,0.40949 -1.38812,0.815 -2.08611,1.21642 -0.69799,0.40134 -2.59793,-1.83967 -3.30126,-1.44649 -0.70324,0.39317 -0.20994,3.42044 -0.91843,3.80537 -0.70849,0.38484 -1.41961,0.76551 -2.13326,1.1421 -0.71358,0.3765 -2.38914,-1.88943 -3.10788,-1.52126 -0.71874,0.36807 -0.48058,3.37024 -1.20424,3.72989 -0.72366,0.35965 -1.44995,0.71505 -2.17853,1.06618 -0.72867,0.35105 -2.89883,-1.46077 -3.63242,-1.11824 -0.7335,0.34253 -0.0304,2.83924 -0.76877,3.17308 -0.73834,0.33384 -1.47906,0.66325 -2.22216,0.9884 -0.7431,0.32506 -2.44793,-1.75258 -3.19571,-1.43639 -0.74769,0.31628 -0.53848,3.02656 -1.29084,3.33406 -0.75237,0.30741 -1.50711,0.6103 -2.26399,0.90884 -0.75696,0.29845 -2.71537,-1.80606 -3.47684,-1.51656 -0.7613,0.28949 -0.32575,2.9729 -1.09164,3.25335 -0.76582,0.28035 -1.53385,0.55628 -2.30409,0.8275 -0.77016,0.27131 -2.26202,-2.10025 -3.03645,-1.83825 -0.77459,0.26218 -0.83158,3.15791 -1.61036,3.41069 -0.77869,0.25277 -1.55943,0.50103 -2.3423,0.74449 -0.78288,0.24346 -2.52716,-1.91604 -3.31414,-1.68206 -0.78689,0.23423 -0.61655,2.86194 -1.40746,3.0866 -0.79099,0.22466 -1.58396,0.44453 -2.37888,0.65961 -0.79493,0.21517 -1.83171,-2.2128 -2.6305,-2.00721 -0.79878,0.2055 -1.35973,3.04448 -2.16245,3.2404 -0.80264,0.19583 -1.60717,0.38688 -2.41366,0.57304 -0.80633,0.18617 -2.57407,-2.03098 -3.38417,-1.85466 -0.8101,0.17642 -0.66272,2.7463 -1.47643,2.91277 -0.81371,0.16657 -1.62931,0.32817 -2.44663,0.48471 -0.81732,0.15663 -2.11612,-2.33005 -2.93696,-2.18336 -0.82077,0.14652 -1.16365,2.92643 -1.98794,3.06302 -0.82429,0.13658 -1.65022,0.26812 -2.47787,0.39459 -0.82757,0.12648 -2.37634,-2.39045 -3.20735,-2.27418 -0.83102,0.11628 -0.94395,2.86576 -1.77816,2.97175 -0.83421,0.10608 -1.66998,0.20692 -2.50731,0.30271 -0.83741,0.0957 -2.15598,-2.45201 -2.99642,-2.36659 -0.84045,0.0853 -1.20277,2.80376 -2.04625,2.87862 -0.84356,0.0749 -1.68852,0.14465 -2.53503,0.20896 -0.84652,0.0645 -1.69442,-2.99428 -2.54381,-2.94053 -0.84938,0.0539 -1.70024,3.22035 -2.5525,3.26355 -0.85225,0.0432 -1.7059,0.0811 -2.56094,0.11352 -0.85505,0.0325 -1.7114,-2.81848 -2.56915,-2.79675 -0.85775,0.0218 -1.71681,2.91622 -2.57727,2.92713 -0.86037,0.0109 -1.72206,0.0163 -2.58505,0.0163 -0.863,0 -1.96457,-2.8835 -2.82494,-2.89441 -0.86038,-0.0109 -1.47964,2.85086 -2.33739,2.82905 -0.85775,-0.0217 -1.7141,-0.0489 -2.56915,-0.0813 -0.85504,-0.0325 -1.70869,-2.70859 -2.56094,-2.75179 -0.85226,-0.0432 -1.70312,2.54656 -2.5525,2.49263 -0.84939,-0.0537 -1.69729,-0.1129 -2.54381,-0.17738 -0.84651,-0.0643 -1.45167,-2.77228 -2.29523,-2.84723 -0.84348,-0.0748 -1.92528,2.48323 -2.76573,2.39791 -0.84044,-0.0854 -1.67933,-0.17597 -2.51674,-0.27167 -0.83733,-0.0958 -1.19342,-2.59498 -2.02763,-2.70114 -0.83413,-0.10599 -2.14646,2.18122 -2.97731,2.06495 -0.83102,-0.11628 -1.66031,-0.23761 -2.48788,-0.36409 -0.82765,-0.12647 -0.9341,-2.65644 -1.75839,-2.79303 -0.82421,-0.13659 -2.36633,2.12021 -3.1871,1.97369 -0.82084,-0.1467 -1.63996,-0.29828 -2.45728,-0.45491 -0.81732,-0.15654 -1.15315,-2.9564 -1.96694,-3.12297 -0.81371,-0.16648 -2.10538,2.30034 -2.91548,2.12393 -0.8101,-0.17632 -1.6184,-0.35761 -2.42481,-0.54378 -0.80641,-0.18616 -1.13134,-3.01547 -1.93398,-3.2113 -0.80263,-0.19593 -2.08307,2.24162 -2.88193,2.03612 -0.79887,-0.20559 -1.59568,-0.41588 -2.39061,-0.63105 -0.79493,-0.21508 -0.38873,-3.07321 -1.17973,-3.29787 -0.79099,-0.22466 -2.77909,2.18424 -3.56606,1.95009 -0.7869,-0.23406 -1.5719,-0.47291 -2.35478,-0.71637 -0.78279,-0.24346 -0.60425,-3.12998 -1.38294,-3.38275 -0.77869,-0.25278 -2.51469,2.12801 -3.28912,1.86583 -0.77451,-0.262 -1.54689,-0.5287 -2.31705,-0.80001 -0.77016,-0.27122 -0.57883,-2.94549 -1.34473,-3.22585 -0.76581,-0.28054 -2.48877,1.83293 -3.25024,1.54343 -0.76139,-0.28949 -1.52056,-0.58342 -2.27752,-0.88187 -0.75696,-0.29854 -0.55226,-2.99986 -1.30462,-3.30727 -0.75237,-0.3075 -2.46188,1.77909 -3.20965,1.46281 -0.74778,-0.31628 -1.49317,-0.63699 -2.23627,-0.96205 -0.7431,-0.32515 -0.52446,-3.29282 -1.2628,-3.62666 -0.73834,-0.33384 -2.43367,1.96632 -3.16725,1.62379 -0.7335,-0.34253 -1.46463,-0.68932 -2.19329,-1.04037 -0.72867,-0.35113 -0.49551,-3.10496 -1.21917,-3.46461 -0.72375,-0.35965 -2.40431,1.67488 -3.12305,1.3068 -0.71866,-0.36817 -1.43486,-0.7405 -2.14852,-1.117 -0.71357,-0.37659 -0.46532,-2.67596 -1.17381,-3.0608 -0.70858,-0.38492 -2.3738,1.14476 -3.07713,0.75159 -0.70324,-0.39318 -1.40394,-0.79043 -2.10193,-1.19177 -0.69799,-0.40142 0.0456,-2.96545 -0.64706,-3.37503 -0.69266,-0.40941 -2.82174,1.33553 -3.50899,0.91788 -0.68733,-0.41757 -1.37188,-0.83921 -2.05371,-1.26485 -0.68184,-0.42564 -0.16173,-3.01379 -0.83799,-3.44741 -0.67626,-0.43344 -2.54897,1.28747 -3.21965,0.84604 -0.67069,-0.44142 -1.33858,-0.88684 -2.00361,-1.33616 -0.66502,-0.44932 0.11179,-2.58132 -0.5475,-3.03835 -0.65928,-0.45704 -2.75474,0.76089 -3.40828,0.29614 -0.65346,-0.46466 -1.30413,-0.93331 -1.95177,-1.40569 -0.64764,-0.47229 0.14672,-2.86718 -0.49502,-3.3471 -0.64173,-0.48001 -2.71955,0.95513 -3.3553,0.46768 -0.63574,-0.48737 -1.26846,-0.97855 -1.89813,-1.47337 -0.62968,-0.49491 0.18272,-2.91206 -0.44081,-3.41433 -0.62361,-0.50218 -2.68314,0.91061 -3.30052,0.40116 -0.61738,-0.50954 -1.23163,-1.02263 -1.84278,-1.53944 -0.61114,-0.51673 0.45975,-2.71596 -0.14499,-3.23987 -0.60491,-0.52382 -2.88538,0.62759 -3.48381,0.0966 -0.59844,-0.5311 -1.19367,-1.06565 -1.78562,-1.60366 -0.59196,-0.53801 0.49821,-2.75844 -0.0873,-3.30346 -0.58548,-0.54511 -2.84659,0.58537 -3.4255,0.0334 -0.57884,-0.55194 -1.15447,-1.10725 -1.72666,-1.66601 -0.57227,-0.55877 0.53775,-2.56004 -0.0278,-3.12554 -0.56554,-0.56551 -2.80665,0.30457 -3.36539,-0.26768 -0.55874,-0.57225 -1.11411,-1.14778 -1.66604,-1.72668 -0.55193,-0.57889 0.8183,-2.60012 0.27334,-3.18567 -0.54504,-0.58546 -3.00528,0.26493 -3.54335,-0.3271 -0.53808,-0.59194 -1.07262,-1.18716 -1.60364,-1.78557 -0.53102,-0.5985 0.38061,-2.87897 -0.14335,-3.48386 -0.52389,-0.6048 -2.48329,0.46608 -2.99995,-0.14501 -0.51675,-0.61119 -1.02989,-1.22539 -1.53942,-1.84278 -0.50954,-0.61739 0.90334,-2.91676 0.40111,-3.54027 -0.50215,-0.6236 -2.9195,0.42866 -3.41427,-0.20106 -0.49485,-0.62972 -0.98601,-1.26237 -1.4734,-1.89812 -0.48747,-0.63576 0.94755,-2.95339 0.46771,-3.59509 -0.47993,-0.64178 -2.87481,0.39247 -3.34719,-0.25525 -0.47238,-0.64764 -0.9409,-1.2982 -1.40566,-1.95169 -0.46475,-0.65358 1.23295,-2.74904 0.7759,-3.40839 -0.45712,-0.65925 -3.06883,0.11761 -3.51809,-0.54741 -0.44925,-0.66502 -0.89465,-1.33288 -1.33612,-2.00358 -0.44146,-0.67078 1.51933,-2.78336 1.08582,-3.45956 -0.43359,-0.67628 -3.26164,0.0836 -3.68728,-0.59814 -0.42555,-0.68178 -0.84725,-1.36641 -1.26485,-2.05369 -0.41759,-0.68728 1.08755,-2.81636 0.67807,-3.50896 -0.40956,-0.69278 -2.73374,0.051 -3.1351,-0.6471 -0.40136,-0.69802 -0.79862,-1.39869 -1.19178,-2.10194 -0.39316,-0.70333 1.37638,-2.60846 0.99151,-3.31694 -0.38488,-0.70848 -2.92426,-0.22031 -3.30077,-0.93403 -0.37651,-0.71362 -0.74884,-1.42982 -1.11698,-2.1485 -0.36815,-0.71868 1.42657,-2.63914 1.06687,-3.36288 -0.35961,-0.72373 -2.87357,-0.25065 -3.22466,-0.97935 -0.35108,-0.72861 -0.69791,-1.4598 -1.04038,-2.19329 -0.34256,-0.73349 1.47791,-2.42877 1.14405,-3.16714 -0.33379,-0.73837 -2.82191,-0.51974 -3.14692,-1.26281 -0.32509,-0.74316 -0.64583,-1.48853 -0.96206,-2.23639 -0.31632,-0.74768 1.7702,-2.45724 1.46282,-3.20962 -0.30746,-0.75239 -3.00881,-0.54768 -3.30724,-1.30459 -0.29852,-0.75691 -0.59245,-1.51612 -0.88195,-2.27755 -0.28949,-0.76143 2.54356,-2.00481 2.26309,-2.7705 -0.2804,-0.76595 -3.67424,-1.05429 -3.94553,-1.82442 -0.27121,-0.77021 -0.53791,-1.54254 -0.80002,-2.31701 -0.2621,-0.77447 1.87887,-2.51037 1.62603,-3.28909 -0.25284,-0.77873 -2.89941,-0.60028 -3.1429,-1.38308 -0.24349,-0.78281 -0.4823,-1.56774 -0.71644,-2.35471 -0.23406,-0.78698 2.41464,-1.81573 2.19001,-2.60669 -0.22463,-0.79105 -3.32266,-1.34414 -3.53777,-2.1391 -0.21512,-0.79487 -0.42548,-1.59186 -0.63099,-2.39063 -0.20552,-0.79886 1.99212,-2.31906 1.79627,-3.12173 -0.19584,-0.80267 -2.78532,-0.88773 -2.9714,-1.69412 -0.18617,-0.80649 -0.36749,-1.61475 -0.54382,-2.42487 -0.1764,-0.81012 2.2904,-2.34167 2.12391,-3.15525 -0.16648,-0.81385 -2.9664,-0.90982 -3.12296,-1.72721 -0.15664,-0.81731 -0.30828,-1.63639 -0.45483,-2.45724 -0.14664,-0.82077 2.11013,-1.88313 1.97358,-2.70744 -0.13663,-0.82423 -2.66649,-1.4104 -2.79295,-2.23799 -0.12646,-0.82769 -0.24792,-1.65697 -0.36413,-2.48793 -0.11629,-0.83088 2.41079,-1.90327 2.30475,-2.73751 -0.10604,-0.83416 -2.8452,-1.43009 -2.9409,-2.26744 -0.0958,-0.83735 -0.18633,-1.6763 -0.27171,-2.51675 -0.0853,-0.84046 1.99311,-1.68242 1.91823,-2.52598 -0.075,-0.84347 -2.30318,-1.68854 -2.36764,-2.53502 -0.0644,-0.84649 -0.12351,-1.69439 -0.17739,-2.54381 -0.0538,-0.84941 2.29605,-1.94007 2.25283,-2.79232 -0.0431,-0.85225 -2.47943,-1.46609 -2.5119,-2.32109 -0.0326,-0.855 -0.0596,-1.71142 -0.0814,-2.56917 -0.0216,-0.85775 2.60015,-2.19649 2.5894,-3.05681 -0.0109,-0.86041 -2.65468,-1.2425 -2.65468,-2.10548 0,-0.86298 0.005,-1.72464 0.0164,-2.58505 0.0108,-0.86041 2.90531,-1.95932 2.92696,-2.81707 0.0218,-0.85775 -2.8292,-1.47434 -2.79664,-2.32934 0.0325,-0.855 0.0704,-1.70867 0.1135,-2.56092 0.0432,-0.85225 2.49017,-1.94291 2.54397,-2.79232 0.0539,-0.84942 -2.28539,-1.4575 -2.22101,-2.30398 0.0645,-0.84649 0.13408,-1.69156 0.20904,-2.53503 0.0749,-0.84347 2.55348,-1.68552 2.63878,-2.52597 0.0854,-0.84046 -2.22249,-1.6794 -2.1267,-2.51676 0.0957,-0.83735 0.19658,-1.6731 0.30262,-2.50726 0.10604,-0.83416 2.61564,-1.18707 2.73193,-2.01794 0.11621,-0.83097 -2.16073,-2.14008 -2.03427,-2.96767 0.12646,-0.82759 0.25792,-1.65359 0.39455,-2.47782 0.13655,-0.82422 2.67658,-0.68754 2.82322,-1.5084 0.14655,-0.82076 -2.10021,-2.59915 -1.94357,-3.41645 0.15656,-0.8174 0.3182,-1.63293 0.48468,-2.44669 0.16648,-0.81376 2.73637,-1.146 2.91277,-1.95612 0.17633,-0.81012 -2.04075,-2.09812 -1.85458,-2.90452 0.18608,-0.8064 0.37716,-1.61093 0.573,-2.4136 0.19585,-0.80268 2.79501,-1.12383 3.00053,-1.9226 0.20552,-0.79886 -1.98253,-2.07542 -1.76741,-2.87037 0.21511,-0.79487 0.43506,-1.58787 0.65969,-2.37884 0.22463,-0.79096 2.61253,-0.62067 2.84667,-1.40765 0.23406,-0.78679 -1.68565,-2.53112 -1.44216,-3.31401 0.24349,-0.7828 0.49166,-1.56357 0.7445,-2.34229 0.25283,-0.77873 2.66887,-0.83585 2.93097,-1.61031 0.26211,-0.77447 -1.62979,-2.26638 -1.35858,-3.0365 0.27129,-0.77021 0.54717,-1.5382 0.82757,-2.30406 0.28047,-0.76587 2.4841,-0.57021 2.7736,-1.33164 0.28949,-0.76125 -1.3353,-2.47986 -1.03678,-3.23685 0.29843,-0.75691 0.60138,-1.51151 0.90884,-2.26398 0.30737,-0.75238 2.77786,-0.30324 3.09418,-1.05101 0.31623,-0.74777 -1.52163,-2.69246 -1.19654,-3.43553 0.32501,-0.74307 0.65453,-1.48383 0.98831,-2.2222 0.33387,-0.73828 2.8306,-0.27504 3.17316,-1.00862 0.34239,-0.73349 -1.4693,-2.6638 -1.11822,-3.3925 0.35109,-0.72862 0.70644,-1.45484 1.06614,-2.17857 0.35962,-0.72365 2.64222,-0.24577 3.01037,-0.96436 0.36814,-0.71877 -1.17825,-2.63418 -0.80174,-3.34789 0.37651,-0.71354 0.75729,-1.42468 1.14216,-2.13316 0.38488,-0.70839 2.45278,-0.21508 2.84602,-0.91851 0.39308,-0.70315 -0.8885,-2.60305 -0.48714,-3.30115 0.40136,-0.69801 0.80682,-1.39337 1.21638,-2.08606 0.40948,-0.69269 2.74178,-0.18342 3.15937,-0.87079 0.4176,-0.68728 -1.07942,-2.57103 -0.65387,-3.2529 0.42564,-0.68178 0.85529,-1.36091 1.28888,-2.03719 0.43351,-0.6762 3.02972,0.0893 3.47119,-0.58147 0.44146,-0.6707 -1.27174,-2.77751 -0.82249,-3.44262 0.44926,-0.66493 0.90245,-1.3272 1.35949,-1.98646 0.45705,-0.65934 2.59687,-0.11645 3.06162,-0.77003 0.46476,-0.65358 -0.74564,-2.50327 -0.27326,-3.151 0.47238,-0.64763 0.94854,-1.29234 1.42846,-1.93404 0.47985,-0.64169 2.64239,0.15859 3.12994,-0.47717 0.48739,-0.63575 -0.70037,-2.70753 -0.20552,-3.33716 0.49477,-0.62972 0.9934,-1.25642 1.49555,-1.87994 0.50223,-0.6236 2.66362,-0.45348 3.19653,-1.14192 0.95993,-0.85535 -0.65625,-1.95124 -0.1395,-2.56234 0.51666,-0.61118 1.03702,-1.21917 1.56091,-1.82397 0.52396,-0.60471 2.73021,0.23264 3.26131,-0.36568 0.53102,-0.5985 -0.61336,-2.63277 -0.0753,-3.22479 0.53807,-0.59194 1.07958,-1.18068 1.62463,-1.76623 0.54496,-0.58547 2.53249,0.27148 3.08442,-0.30741 0.55193,-0.5789 -0.33174,-2.59357 0.227,-3.16581 0.55874,-0.57225 1.12092,-1.14122 1.68647,-1.70672 0.56555,-0.56551 2.57349,0.55105 3.14576,-0.008 0.57219,-0.55877 -0.29122,-2.79303 0.28762,-3.34488 0.57891,-0.55194 1.1611,-1.1005 1.74658,-1.64543 0.58547,-0.54511 2.37347,0.59229 2.96542,0.0542 0.59195,-0.5381 -0.0121,-2.75152 0.58638,-3.28253 0.59843,-0.53092 1.20006,-1.05846 1.80489,-1.58237 0.60482,-0.52391 2.41201,0.6346 3.02307,0.11787 0.61114,-0.51672 0.0262,-2.70877 0.64362,-3.21822 0.61738,-0.50946 1.23787,-1.01536 1.86148,-1.51754 0.62353,-0.50227 2.68921,0.91797 3.31889,0.42297 0.62967,-0.49464 -0.17665,-2.9046 0.45909,-3.39197 0.63575,-0.48746 1.27453,-0.9711 1.91626,-1.45102 0.64174,-0.48 2.72546,0.72276 3.3731,0.25047 0.64764,-0.47247 -0.14073,-2.6199 0.51273,-3.08456 0.65354,-0.46476 1.30996,-0.9256 1.96924,-1.38273 0.65928,-0.45694 2.76056,0.7687 3.42559,0.31939 0.66502,-0.44924 -0.10613,-2.57361 0.56456,-3.01504 0.67068,-0.44142 1.34415,-0.87903 2.02049,-1.31256 0.67626,-0.43362 2.79435,1.05562 3.47619,0.62998 0.68183,-0.42572 -0.0727,-2.76607 0.61467,-3.18363 0.68725,-0.41766 1.37728,-0.83114 2.06995,-1.24073 0.69266,-0.40949 2.34747,1.10379 3.04546,0.70236 0.69799,-0.40133 0.43933,-2.71737 1.14257,-3.11055 0.70333,-0.39309 1.40919,-0.78218 2.11776,-1.16702 0.70849,-0.38484 2.61877,1.15318 3.33243,0.7765 0.71365,-0.37641 0.23061,-2.66753 0.94927,-3.03569 0.71874,-0.36808 1.43994,-0.73199 2.16369,-1.09164 0.72366,-0.35956 2.8889,1.20366 3.61757,0.85261 0.72866,-0.35114 0.0208,-2.61662 0.75425,-2.95915 0.73358,-0.34254 1.46955,-0.68072 2.20789,-1.01447 0.73834,-0.33384 2.43842,1.25545 3.18152,0.93039 0.7431,-0.32515 0.52913,-2.56456 1.27691,-2.88084 0.74777,-0.31628 1.49792,-0.62813 2.25029,-0.93554 0.75236,-0.30741 2.46638,1.54814 3.22334,1.24978 0.75696,-0.29845 0.55677,-2.75108 1.31816,-3.04058 0.76147,-0.28949 1.52507,-0.57446 2.29088,-0.85491 0.7659,-0.28045 2.73317,1.3625 3.50333,1.09119 0.77008,-0.27122 0.3433,-2.45671 1.11781,-2.71879 0.77443,-0.26209 1.55107,-0.51957 2.32976,-0.77234 0.77869,-0.25287 2.27899,1.89732 3.06178,1.65386 0.78288,-0.24355 0.8484,-2.88066 1.6353,-3.11472 0.78697,-0.23415 1.57591,-0.46351 2.3669,-0.68817 0.791,-0.22466 2.06364,1.9539 2.85857,1.73873 0.79493,-0.21517 1.11206,-2.8238 1.91093,-3.02939 0.79886,-0.20551 1.59961,-0.40631 2.40225,-0.60214 0.80264,-0.19584 1.84713,1.77173 2.65354,1.58547 0.80641,-0.18616 1.37483,-2.52597 2.18493,-2.70238 0.8101,-0.17632 1.62209,-0.34777 2.43579,-0.51424 0.8138,-0.16657 2.10899,2.07036 2.92631,1.91364 0.81732,-0.15655 1.15676,-2.70656 1.9776,-2.85317 0.82077,-0.14661 1.64333,-0.28825 2.46762,-0.42484 0.82429,-0.13659 2.1299,2.13032 2.95755,2.00384 0.82757,-0.12647 1.17718,-2.64624 2.0082,-2.76252 0.83085,-0.11628 1.6635,-0.2275 2.49763,-0.33348 0.83421,-0.10608 2.14966,1.9516 2.98699,1.8559 0.83741,-0.0956 1.19662,-2.34487 2.03706,-2.43019 0.84045,-0.0854 1.68245,-0.1655 2.52593,-0.24045 0.84356,-0.0749 1.9284,2.01404 2.77483,1.94956 0.84652,-0.0645 1.45462,-2.28216 2.30401,-2.33591 0.84938,-0.0539 1.70024,-0.10244 2.5525,-0.14563 0.85225,-0.0432 1.7059,2.31728 2.56094,2.28482 0.85505,-0.0325 1.7114,-2.45795 2.56915,-2.47968 0.85775,-0.0217 1.71689,-0.038 2.57727,-0.049 0.86037,-0.0109 1.72206,2.81139 2.58506,2.81139 0.86299,0 1.72468,-2.8223 2.58505,-2.81139 0.86046,0.0109 1.71952,0.0272 2.57727,0.049 0.85775,0.0217 1.24279,2.87658 2.09783,2.90913 0.85504,0.0325 2.18001,-2.75746 3.03226,-2.71427 0.85226,0.0432 1.70312,0.0917 2.5525,0.14563 0.84939,0.0537 1.21761,2.75117 2.06413,2.81556 0.84651,0.0645 2.17115,-2.50415 3.01471,-2.42921 0.84348,0.075 1.68548,0.15504 2.52593,0.24045 0.84044,0.0853 1.19965,2.33458 2.03706,2.43019 0.83733,0.0957 2.15278,-1.96198 2.98699,-1.8559 0.83421,0.10598 1.6667,0.2172 2.49763,0.33348 0.83102,0.11628 0.70095,2.15639 1.52852,2.28287 0.82765,0.12648 2.61294,-1.66078 3.43723,-1.52419 0.82429,0.13659 1.64685,0.27823 2.46762,0.42484 0.82084,0.14661 0.6806,2.4568 1.49792,2.61334 0.81732,0.15672 2.59228,-1.84038 3.40599,-1.67381 0.81371,0.16647 1.62569,0.33792 2.43579,0.51424 0.8101,0.17641 0.65912,2.75604 1.46545,2.9423 0.80649,0.18617 2.57038,-2.02123 3.37302,-1.82539 0.80272,0.19583 1.60347,0.39663 2.40225,0.60214 0.79887,0.20559 0.87629,2.5744 1.67122,2.78957 0.79493,0.21517 2.30737,-1.72357 3.09836,-1.49891 0.79091,0.22466 1.57993,0.45402 2.36683,0.68817 0.78697,0.23406 0.37273,2.63134 1.15552,2.87489 0.78296,0.24346 2.76286,-1.6669 3.54155,-1.41403 0.77878,0.25277 1.55533,0.51025 2.32984,0.77234 0.77443,0.26208 0.34756,2.68748 1.11773,2.95862 0.77024,0.27131 2.73751,-1.61147 3.50333,-1.33102 0.76589,0.28045 1.52949,0.56542 2.29088,0.85491 0.76147,0.2895 0.32148,2.74213 1.07844,3.04058 0.7568,0.29836 2.71078,-1.55719 3.46315,-1.24978 0.75236,0.30741 1.50251,0.61926 2.2502,0.93554 0.74778,0.31628 0.2941,2.79551 1.03711,3.12066 0.74318,0.32506 2.68306,-1.50405 3.4214,-1.17021 0.73835,0.33375 1.47431,0.67193 2.20781,1.01447 0.73359,0.34253 0.26547,2.60801 0.99413,2.95915 0.72859,0.35105 2.65412,-1.21217 3.37778,-0.85261 0.72366,0.35965 1.44486,0.72356 2.1636,1.09164 0.71874,0.36816 0.23578,2.65919 0.94928,3.03569 0.71373,0.37659 2.62401,-1.16134 3.3325,-0.7765 0.70849,0.38484 1.41435,0.77393 2.11768,1.16702 0.70332,0.39318 -0.2749,2.46939 0.42309,2.87073 0.69807,0.40133 3.07228,-0.87203 3.76503,-0.46254 0.69266,0.40959 1.3827,0.82307 2.06994,1.24073 0.68734,0.41756 -0.0672,2.51799 0.61467,2.94372 0.68176,0.42564 2.79993,-0.82369 3.47619,-0.39007 0.67626,0.43353 1.34981,0.87114 2.0205,1.31256 0.67068,0.44143 -0.10047,2.56589 0.56456,3.01512 0.66502,0.44932 2.76622,-0.77641 3.42558,-0.31947 0.65928,0.45713 1.3157,0.91797 1.96916,1.38273 0.65354,0.46466 -0.13491,2.61209 0.51281,3.08456 0.64756,0.47229 2.73137,-0.73047 3.3731,-0.25047 0.64173,0.47992 1.28043,0.96356 1.91626,1.45102 0.63566,0.48737 -0.41046,2.41759 0.21921,2.91232 0.62976,0.49491 2.93525,-0.44559 3.55877,0.0567 0.62361,0.50218 1.24411,1.00808 1.86148,1.51754 0.61738,0.50945 -0.20749,2.7015 0.40374,3.21822 0.61114,0.51673 2.60876,-0.57863 3.26296,-0.11787 1.08442,1.00365 0.2471,2.73032 0.36585,3.26124 0.59851,0.53092 2.63262,-0.61331 3.22457,-0.0752 0.59196,0.53801 1.18079,1.07957 1.76627,1.62468 0.58547,0.54493 -0.75106,2.77227 -0.17214,3.3243 0.57883,0.55185 3.0731,-0.57163 3.64537,-0.0129 0.57227,0.55868 1.14118,1.1209 1.70672,1.68641 0.56555,0.5655 -0.55127,2.09386 0.008,2.66611 0.55866,0.57225 2.79287,0.18847 3.34489,0.76728 0.55193,0.5789 1.10041,1.16108 1.64537,1.74655 0.54505,0.58555 -0.59236,2.61334 -0.0543,3.20527 0.53808,0.59203 2.75154,-0.2518 3.28256,0.34661 0.53102,0.59842 1.05851,1.20011 1.5824,1.80482 0.52388,0.6048 -0.6346,2.65183 -0.11793,3.26301 0.51666,0.6111 2.70873,-0.21366 3.21826,0.40373 0.50945,0.6174 1.01537,1.23789 1.5176,1.86149 0.50216,0.62352 -0.91794,2.44944 -0.42309,3.07907 0.49485,0.62972 2.90465,0.0632 3.39204,0.69899 0.48739,0.63575 0.97109,1.27452 1.45102,1.91621 0.47992,0.6417 -0.96264,2.72545 -0.49026,3.37309 0.47238,0.64781 2.85963,-0.14085 3.32438,0.51273 0.46467,0.65358 0.92557,1.30991 1.38262,1.96925 0.45713,0.65926 -1.2482,2.76057 -0.79895,3.4255 0.44926,0.66511 3.05318,-0.10616 3.49464,0.56462 0.44154,0.6707 0.87899,1.34423 1.31266,2.02043 0.43351,0.67628 -1.05556,2.79445 -0.62992,3.47623 0.42563,0.68187 2.76597,-0.0726 3.18357,0.61465 0.4176,0.68737 0.83118,1.37731 1.24066,2.07 0.40956,0.69269 -1.58338,2.58718 -1.18202,3.28519 0.40136,0.6981 3.19702,0.19965 3.59026,0.90281 0.39307,0.70342 0.78213,1.40933 1.16701,2.11772 0.38488,0.70848 -1.39303,2.37901 -1.01644,3.09255 0.37651,0.71362 2.90744,0.47051 3.2755,1.18928 0.36815,0.71868 0.73211,1.43993 1.09173,2.16358 0.35962,0.72373 -1.68335,2.40926 -1.33234,3.13796 0.35108,0.7287 3.09639,0.5004 3.43887,1.23389 0.34255,0.73358 0.68068,1.46956 1.01455,2.20784 0.33378,0.73837 -1.7351,2.43853 -1.41001,3.1816 0.32501,0.74298 3.04407,0.52914 3.36039,1.27691 0.31631,0.74777 0.62812,1.49785 0.93557,2.25023 0.30738,0.75247 -1.78799,2.22664 -1.48956,2.98354 0.29844,0.757 2.99085,0.79664 3.28035,1.55798 0.2895,0.76143 0.57448,1.52508 0.85488,2.29095 0.28039,0.76586 -1.60233,2.25333 -1.33104,3.02354 0.27121,0.77012 2.69651,0.82307 2.95862,1.59754 0.26211,0.77447 0.51954,1.55106 0.77238,2.32979 0.25283,0.77872 -2.13728,2.27896 -1.89379,3.06177 0.24357,0.78289 3.12058,0.84835 3.35464,1.63523 0.23414,0.78697 0.46361,1.57599 0.68815,2.36695 0.22463,0.79097 -1.9539,2.30345 -1.7387,3.09831 0.21519,0.79496 2.82387,0.87239 3.02939,1.67125 0.20552,0.79877 0.4062,1.59957 0.60212,2.40225 0.19592,0.80267 -2.25128,2.08685 -2.06519,2.89325 0.186,0.80649 3.00569,1.13509 3.18201,1.94522 0.1764,0.81012 0.34789,1.62201 0.51437,2.43577 0.16648,0.81376 -1.83048,2.34877 -1.67392,3.16616 0.15664,0.8174 2.46696,0.91691 2.61352,1.73768 0.14663,0.82085 0.28826,1.64348 0.42481,2.4677 0.13655,0.82423 -2.37011,2.12988 -2.24373,2.95747 0.12646,0.8276 2.88612,1.17731 3.00241,2.00828 0.11629,0.83087 0.2275,1.66352 0.33346,2.49768 0.10604,0.83416 -2.19141,2.14957 -2.0957,2.98692 0.0957,0.83735 2.58473,1.19664 2.67002,2.0371 0.0853,0.84045 0.16541,1.6825 0.24037,2.52597 0.075,0.84347 -2.25382,2.16819 -2.18944,3.01468 0.0645,0.84649 2.52199,1.21474 2.57579,2.06415 0.0539,0.84941 0.10243,1.70025 0.14565,2.5525 0.0431,0.85225 -2.55709,1.70592 -2.52478,2.56092 0.0326,0.855 2.69791,1.71142 2.71964,2.56917 0.0218,0.85775 0.0381,1.71683 0.049,2.57724 0.0109,0.86041 -2.86168,1.96189 -2.86168,2.82496 z"
+ style="font-size:12px;fill:url(#linearGradient2197);fill-rule:evenodd;stroke-width:0.85286403"
+ inkscape:connector-curvature="0" /><path
+ id="path726"
+ d="m 591.11936,520.25849 c 0,104.67641 -84.85705,189.53353 -189.53347,189.53353 -104.67641,0 -189.53337,-84.85712 -189.53337,-189.53353 0,-104.67634 84.85696,-189.53347 189.53337,-189.53347 104.67642,0 189.53347,84.85713 189.53347,189.53347 z"
+ style="font-size:12px;fill:url(#linearGradient2195);fill-rule:evenodd;stroke-width:0.79803562"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="sssss" /><path
+ style="opacity:1;vector-effect:none;fill:#fcfcfc;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.5016288"
+ d="M 299.04492 195.36133 C 280.9578 195.36133 266.11721 204.479 252.66797 223.39648 C 235.27642 247.78402 225.76953 280.8318 225.76953 315.93164 C 225.76953 351.25941 237.82739 368.35352 262.87109 368.35352 C 287.68287 368.35352 307.85639 352.17053 321.76953 320.94531 C 331.74061 298.83696 337.76953 271.03071 337.76953 246.87109 C 337.76953 212.68292 324.78426 195.36133 299.04492 195.36133 z M 140.89844 199.46484 L 125.13086 276.72852 C 130.2324 276.04476 134.87077 275.81836 138.11719 275.81836 C 160.61011 275.81836 171.27539 286.07362 171.27539 306.81445 C 171.27539 335.07671 155.97274 358.09766 137.42188 358.09766 C 128.61019 358.09766 123.74023 354.67854 123.74023 348.98047 C 123.74023 348.06879 123.97088 345.78953 124.89844 341.45898 L 125.82617 334.62109 L 126.05859 332.57031 L 110.52148 332.57031 L 104.95508 360.76367 A 180.48428 183.26096 0 0 0 107.04297 363.72852 C 120.22383 366.92201 129.36241 368.35352 137.42188 368.35352 C 175.9149 368.35352 206.98633 341.23157 206.98633 307.95508 C 206.98633 279.4649 186.34891 264.87814 147.16016 265.33398 L 138.34766 265.33398 L 149.47852 224.76367 L 221.5957 224.76367 L 226.69727 199.46484 L 140.89844 199.46484 z M 296.95898 205.61719 C 304.14738 205.61719 307.625 210.40514 307.625 220.43359 C 307.625 245.50498 294.63887 310.46143 283.74023 339.86328 C 278.87061 353.08269 274.23425 358.09766 266.58203 358.09766 C 259.39363 358.09766 255.91406 353.31031 255.91406 343.50977 C 255.91406 334.84867 257.30614 323.45302 259.625 310.68945 L 264.95898 281.9707 C 269.82853 256.67147 274.00146 239.80679 278.87109 226.35938 C 283.97254 211.3166 289.07485 205.61719 296.95898 205.61719 z M 418.92969 259.86328 C 418.92969 258.72367 418.92969 258.72282 418.92969 263.28125 C 418.92969 263.28125 418.92969 261.00289 418.92969 259.86328 z M 384.78711 300.11133 C 359.32645 300.11133 339.83984 319.4501 339.83984 344.74023 C 339.83984 360.60857 350.22225 369.53516 368.85547 369.53516 C 374.26663 369.53516 379.70876 368.77323 387.39258 366.88281 A 180.48428 183.26096 0 0 0 389.80664 363.6543 L 391.1875 357.38477 C 384.78676 359.74026 379.66526 360.73242 375.25586 360.73242 C 365.86815 360.73242 361.31836 356.14648 361.31836 346.72461 C 361.31836 337.79872 364.01907 327.13564 368.71289 317.58984 C 372.69558 309.65567 377.38989 305.68945 382.79492 305.68945 C 386.91982 305.68945 388.91211 308.1681 388.91211 313.12695 L 388.91211 313.62305 L 388.91211 314.61523 L 388.20117 319.07812 L 387.91602 320.19336 L 399.58008 320.19336 L 403.5625 303.08594 C 397.01955 300.97849 391.18785 300.11133 384.78711 300.11133 z "
+ transform="translate(150.97116,269.64373)"
+ id="path849" /><g
style="font-size:12px;fill:url(#linearGradient2201)"
- transform="matrix(0.710214,0,0,0.665599,45.70086,221.885)"
+ transform="matrix(0.56677739,0,0,0.53117295,117.57617,282.14552)"
id="g944"><path
id="path943"
- d="M 489.2781,157.6309 C 486.7725,158.6472 483.694,159.9616 480.8916,161.4231 C 479.3419,161.0055 475.428,159.2736 475.428,155.3341 C 475.428,151.3946 478.7154,148.2011 482.7708,148.2011 C 488.0788,148.2011 490.7398,151.8121 489.2781,157.6309 z M 521.9314,154.5415 C 521.9314,158.4811 518.0176,160.213 516.6769,160.8394 C 513.0392,159.5867 510.1692,158.6899 508.0812,158.0913 C 505.5757,152.2726 509.2807,147.4085 514.5889,147.4085 C 518.644,147.4085 521.9314,150.6021 521.9314,154.5415 z M 554.0133,282.1463 C 539.7204,299.0921 519.7959,311.7673 487.7231,311.2372 C 455.0333,310.1367 444.7336,294.8341 446.4288,254.5974 C 447.4384,237.4799 453.0554,223.2215 459.4115,212.5429 C 462.707,204.534 471.5472,201.7454 476.9885,177.1512 C 485.6153,185.4841 494.4355,188.3269 497.9466,188.3677 C 504.6303,188.4997 521.1268,180.7489 526.5206,174.9439 C 532.8029,196.1211 539.725,203.2866 544.2499,208.414 C 571.8131,240.2076 557.189,277.6971 554.0133,282.1463 z M 494.2871,157.0588 C 487.7115,157.6404 481.7311,160.3453 477.7269,163.5282 C 475.279,165.2092 472.0644,157.8887 472.0644,152.4116 C 472.0644,145.0207 475.2644,139.5457 483.471,139.5457 C 490.9986,139.5457 495.5149,147.9387 494.2871,157.0588 z M 503.3984,157.4551 C 509.7709,158.1484 517.8879,161.2707 522.7624,163.7729 C 525.4762,165.4536 527.6282,158.285 527.6282,152.8079 C 527.6282,147.0021 523.8588,139.1494 514.7603,139.1494 C 505.191,139.1494 502.0372,145.9572 503.3984,157.4551 z M 504.7202,106.7478 C 474.7132,106.4276 457.1089,126.4945 461.8612,178.9302 C 463.5845,198.2381 361.0517,308.565 481.4685,323.2273 L 525.5737,324.0199 C 606.8295,319.2645 591.7019,249.1051 588.8989,241.103 C 580.6322,213.4795 553.1952,187.4526 553.0018,172.6248 C 552.814,127.3526 535.8651,106.2749 504.7202,106.7478 z M 529.3964,169.2447 C 529.7524,177.204 506.4211,188.5796 497.5232,188.5796 C 490.247,188.5796 473.2299,177.6226 472.7098,170.2413 C 472.4321,166.698 484.8286,156.8974 498.0721,157.1776 C 508.6449,157.1776 529.106,164.0661 529.3964,169.2447 z M 505.6319,158.6713 C 504.8923,159.1122 502.5108,159.8841 502.2685,159.8142 C 501.7591,159.7069 502.9358,158.8886 503.1344,158.3848 C 503.3119,157.9112 506.3718,158.2303 505.6319,158.6713 z M 491.2411,158.3369 C 491.2346,158.7713 491.7574,159.5856 492.1907,159.5931 C 492.5879,159.0685 492.9824,158.6462 493.4274,158.2207 C 493.8848,157.8292 491.2476,157.996 491.2411,158.3369 z M 475.86,171.0084 C 475.1974,169.8919 481.8043,180.5114 494.4183,180.9245 C 505.2062,181.3048 518.8716,172.4247 527.1629,168.9206 C 494.2345,184.859 489.641,183.0493 475.86,171.0084 z M 532.9812,126.1648 C 531.3254,129.0911 525.7228,129.7142 520.4675,127.5566 C 515.2121,125.3989 512.294,121.2776 513.9498,118.3513 C 515.6056,115.425 521.2082,114.8019 526.4636,116.9596 C 531.7189,119.1172 534.6369,123.2386 532.9812,126.1648 z "
- style="font-size:12px;fill:url(#linearGradient2203);fill-rule:evenodd" /><path
+ d="m 489.2781,157.6309 c -2.5056,1.0163 -5.5841,2.3307 -8.3865,3.7922 -1.5497,-0.4176 -5.4636,-2.1495 -5.4636,-6.089 0,-3.9395 3.2874,-7.133 7.3428,-7.133 5.308,0 7.969,3.611 6.5073,9.4298 z m 32.6533,-3.0894 c 0,3.9396 -3.9138,5.6715 -5.2545,6.2979 -3.6377,-1.2527 -6.5077,-2.1495 -8.5957,-2.7481 -2.5055,-5.8187 1.1995,-10.6828 6.5077,-10.6828 4.0551,0 7.3425,3.1936 7.3425,7.133 z m 32.0819,127.6048 c -14.2929,16.9458 -34.2174,29.621 -66.2902,29.0909 -32.6898,-1.1005 -42.9895,-16.4031 -41.2943,-56.6398 1.0096,-17.1175 6.6266,-31.3759 12.9827,-42.0545 3.2955,-8.0089 12.1357,-10.7975 17.577,-35.3917 8.6268,8.3329 17.447,11.1757 20.9581,11.2165 6.6837,0.132 23.1802,-7.6188 28.574,-13.4238 6.2823,21.1772 13.2044,28.3427 17.7293,33.4701 27.5632,31.7936 12.9391,69.2831 9.7634,73.7323 z M 494.2871,157.0588 c -6.5756,0.5816 -12.556,3.2865 -16.5602,6.4694 -2.4479,1.681 -5.6625,-5.6395 -5.6625,-11.1166 0,-7.3909 3.2,-12.8659 11.4066,-12.8659 7.5276,0 12.0439,8.393 10.8161,17.5131 z m 9.1113,0.3963 c 6.3725,0.6933 14.4895,3.8156 19.364,6.3178 2.7138,1.6807 4.8658,-5.4879 4.8658,-10.965 0,-5.8058 -3.7694,-13.6585 -12.8679,-13.6585 -9.5693,0 -12.7231,6.8078 -11.3619,18.3057 z m 1.3218,-50.7073 c -30.007,-0.3202 -47.6113,19.7467 -42.859,72.1824 1.7233,19.3079 -100.8095,129.6348 19.6073,144.2971 l 44.1052,0.7926 c 81.2558,-4.7554 66.1282,-74.9148 63.3252,-82.9169 -8.2667,-27.6235 -35.7037,-53.6504 -35.8971,-68.4782 -0.1878,-45.2722 -17.1367,-66.3499 -48.2816,-65.877 z m 24.6762,62.4969 c 0.356,7.9593 -22.9753,19.3349 -31.8732,19.3349 -7.2762,0 -24.2933,-10.957 -24.8134,-18.3383 -0.2777,-3.5433 12.1188,-13.3439 25.3623,-13.0637 10.5728,0 31.0339,6.8885 31.3243,12.0671 z m -23.7645,-10.5734 c -0.7396,0.4409 -3.1211,1.2128 -3.3634,1.1429 -0.5094,-0.1073 0.6673,-0.9256 0.8659,-1.4294 0.1775,-0.4736 3.2374,-0.1545 2.4975,0.2865 z m -14.3908,-0.3344 c -0.007,0.4344 0.5163,1.2487 0.9496,1.2562 0.3972,-0.5246 0.7917,-0.9469 1.2367,-1.3724 0.4574,-0.3915 -2.1798,-0.2247 -2.1863,0.1162 z M 475.86,171.0084 c -0.6626,-1.1165 5.9443,9.503 18.5583,9.9161 10.7879,0.3803 24.4533,-8.4998 32.7446,-12.0039 -32.9284,15.9384 -37.5219,14.1287 -51.3029,2.0878 z m 57.1212,-44.8436 c -1.6558,2.9263 -7.2584,3.5494 -12.5137,1.3918 -5.2554,-2.1577 -8.1735,-6.279 -6.5177,-9.2053 1.6558,-2.9263 7.2584,-3.5494 12.5138,-1.3917 5.2553,2.1576 8.1733,6.279 6.5176,9.2052 z"
+ style="font-size:12px;fill:url(#linearGradient2203);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /><path
transform="matrix(1.381431,0,0,1.342002,-335.1481,-21.47379)"
sodipodi:nodetypes="cccccccccccccccccccccc"
id="path871"
- d="M 594.8524,209.0117 C 594.8524,220.1016 597.3741,225.5481 596.0694,225.5481 C 594.7647,225.5481 591.5893,219.8928 591.5893,208.8029 C 591.5893,197.7133 595.8087,185.5974 597.1134,185.5974 C 598.4181,185.5974 594.8524,197.9221 594.8524,209.0117 z M 632.27,169.5802 C 636.4462,173.2967 639.9597,177.6751 641.0037,183.062 C 633.8452,176.8398 621.8843,173.9586 614.9343,172.3301 C 621.0488,172.1213 630.1226,172.5034 632.27,169.5802 z M 595.6275,172.1593 C 597.9116,174.2791 597.2725,175.7726 598.0951,178.5188 C 598.4549,175.911 602.5729,173.9295 604.8118,171.9481 C 601.9592,172.4361 598.4801,172.5065 595.6275,172.1593 z M 578.9845,168.302 C 576.6727,170.9576 573.7897,175.239 570.9888,182.7921 C 576.8947,176.1524 582.6886,175.629 589.2209,172.9565 C 583.3151,172.7478 581.1318,171.2251 578.9845,168.302 z M 624.5364,145.5447 C 621.5836,154.254 608.0056,162.0592 600.9178,162.0592 C 596.7828,162.0592 588.4029,155.7413 586.9264,147.0322 C 592.4305,152.4557 598.446,156.1755 603.0832,156.3597 C 608.2112,156.4881 619.7769,150.57 624.5364,145.5447 z "
- style="font-size:12px;fill:url(#linearGradient2205);fill-rule:evenodd" /><path
+ d="m 594.8524,209.0117 c 0,11.0899 2.5217,16.5364 1.217,16.5364 -1.3047,0 -4.4801,-5.6553 -4.4801,-16.7452 0,-11.0896 4.2194,-23.2055 5.5241,-23.2055 1.3047,0 -2.261,12.3247 -2.261,23.4143 z M 632.27,169.5802 c 4.1762,3.7165 7.6897,8.0949 8.7337,13.4818 -7.1585,-6.2222 -19.1194,-9.1034 -26.0694,-10.7319 6.1145,-0.2088 15.1883,0.1733 17.3357,-2.7499 z m -36.6425,2.5791 c 2.2841,2.1198 1.645,3.6133 2.4676,6.3595 0.3598,-2.6078 4.4778,-4.5893 6.7167,-6.5707 -2.8526,0.488 -6.3317,0.5584 -9.1843,0.2112 z m -16.643,-3.8573 c -2.3118,2.6556 -5.1948,6.937 -7.9957,14.4901 5.9059,-6.6397 11.6998,-7.1631 18.2321,-9.8356 -5.9058,-0.2087 -8.0891,-1.7314 -10.2364,-4.6545 z m 45.5519,-22.7573 c -2.9528,8.7093 -16.5308,16.5145 -23.6186,16.5145 -4.135,0 -12.5149,-6.3179 -13.9914,-15.027 5.5041,5.4235 11.5196,9.1433 16.1568,9.3275 5.128,0.1284 16.6937,-5.7897 21.4532,-10.815 z"
+ style="font-size:12px;fill:url(#linearGradient2205);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /><path
transform="matrix(1.381431,0,0,1.342002,-335.1483,-21.47379)"
sodipodi:nodetypes="csccc"
id="path758"
- d="M 566.1781,204.0047 C 566.1781,224.5982 593.4836,225.0052 587.8079,232.522 C 582.6399,239.91 550.7196,226.5353 550.7196,205.9419 C 552.8076,190.3594 555.5661,185.5046 574.6452,156.366 C 587.5403,159.1975 566.1781,183.4112 566.1781,204.0047 z "
- style="font-size:12px;fill:url(#linearGradient2207);fill-rule:evenodd" /><g
+ d="m 566.1781,204.0047 c 0,20.5935 27.3055,21.0005 21.6298,28.5173 -5.168,7.388 -37.0883,-5.9867 -37.0883,-26.5801 2.088,-15.5825 4.8465,-20.4373 23.9256,-49.5759 12.8951,2.8315 -8.4671,27.0452 -8.4671,47.6387 z"
+ style="font-size:12px;fill:url(#linearGradient2207);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /><g
style="font-size:12px;fill:url(#linearGradient2209)"
transform="matrix(1.381431,0,0,1.342002,-325.2191,-15.60249)"
id="g1065"><path
transform="translate(-7.1875,-4.375031)"
sodipodi:nodetypes="csssscsss"
id="path842"
- d="M 662.6023,249.8415 C 652.9563,254.7202 643.0236,269.4045 630.2927,263.3619 C 621.3526,259.2146 625.6634,249.1638 625.1563,243.5311 C 624.668,230.5505 623.5071,211.1312 631.9468,211.184 C 642.1547,211.246 638.0258,215.2545 645.4196,217.3441 C 653.505,219.306 658.7389,209.0467 664.847,213.6095 C 669.4787,219.944 664.6217,223.322 670.205,229.4906 C 673.1685,233.0602 677.7506,232.9839 680.3539,235.8973 C 685.7736,241.3478 668.3201,246.6544 662.6023,249.8415 z "
- style="font-size:12px;fill:url(#linearGradient2211);fill-rule:evenodd" /><path
+ d="m 662.6023,249.8415 c -9.646,4.8787 -19.5787,19.563 -32.3096,13.5204 -8.9401,-4.1473 -4.6293,-14.1981 -5.1364,-19.8308 -0.4883,-12.9806 -1.6492,-32.3999 6.7905,-32.3471 10.2079,0.062 6.079,4.0705 13.4728,6.1601 8.0854,1.9619 13.3193,-8.2974 19.4274,-3.7346 4.6317,6.3345 -0.2253,9.7125 5.358,15.8811 2.9635,3.5696 7.5456,3.4933 10.1489,6.4067 5.4197,5.4505 -12.0338,10.7571 -17.7516,13.9442 z"
+ style="font-size:12px;fill:url(#linearGradient2211);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /><path
transform="translate(-7.1875,-4.375031)"
sodipodi:nodetypes="cssssssss"
id="path843"
- d="M 550.8908,255.4014 C 562.5947,256.6532 574.367,267.8037 584.6032,256.5396 C 591.8317,248.7246 584.743,239.3914 580.5155,234.7902 C 570.7341,224.8274 565.2408,206.427 556.2229,206.4986 C 548.5882,206.8092 550.0632,210.9825 544.7009,215.234 C 537.4953,220.6488 532.9891,216.239 528.6392,223.1506 C 525.9871,226.8955 526.7585,231.7788 527.8864,236.9511 C 528.6785,241.8714 527.0976,242.9494 525.4163,244.55 C 519.9332,250.7329 540.853,254.0325 550.8908,255.4014 z "
- style="font-size:12px;fill:url(#linearGradient2213);fill-rule:evenodd" /></g><path
+ d="m 550.8908,255.4014 c 11.7039,1.2518 23.4762,12.4023 33.7124,1.1382 7.2285,-7.815 0.1398,-17.1482 -4.0877,-21.7494 -9.7814,-9.9628 -15.2747,-28.3632 -24.2926,-28.2916 -7.6347,0.3106 -6.1597,4.4839 -11.522,8.7354 -7.2056,5.4148 -11.7118,1.005 -16.0617,7.9166 -2.6521,3.7449 -1.8807,8.6282 -0.7528,13.8005 0.7921,4.9203 -0.7888,5.9983 -2.4701,7.5989 -5.4831,6.1829 15.4367,9.4825 25.4745,10.8514 z"
+ style="font-size:12px;fill:url(#linearGradient2213);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /></g><path
transform="matrix(1.381431,0,0,1.342002,-335.1483,-21.47379)"
sodipodi:nodetypes="cscss"
id="path857"
- d="M 649.8842,196.2501 C 649.4318,220.8146 631.991,220.9147 636.6064,229.3612 C 642.8768,241.2543 669.5186,218.7807 669.5186,198.1874 C 669.5186,178.0113 641.3187,150.3852 638.2491,152.2475 C 619.1027,166.4884 650.6787,175.7879 649.8842,196.2501 z "
- style="font-size:12px;fill:url(#linearGradient2215);fill-rule:evenodd" /></g><path
+ d="m 649.8842,196.2501 c -0.4524,24.5645 -17.8932,24.6646 -13.2778,33.1111 6.2704,11.8931 32.9122,-10.5805 32.9122,-31.1738 0,-20.1761 -28.1999,-47.8022 -31.2695,-45.9399 -19.1464,14.2409 12.4296,23.5404 11.6351,44.0026 z"
+ style="font-size:12px;fill:url(#linearGradient2215);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /></g><path
sodipodi:nodetypes="ccccccssccccccccccccccccccccccccccccccsssccccccc"
id="path651"
- d="M 214.4996,656.813 C 214.1092,658.6191 218.0231,660.4254 219.5856,660.5504 L 227.0512,624.4489 L 240.1137,624.4489 L 240.4262,622.0114 L 240.7387,619.4489 L 228.1522,619.4489 C 225.1378,619.4489 222.3948,619.7489 221.7668,622.6971 L 214.4996,656.813 z M 458.1137,447.6364 C 435.3637,447.6364 416.7387,459.0114 399.8012,482.6989 C 377.9887,513.2614 365.9887,554.6364 365.9887,598.6364 C 365.9887,628.3239 372.8012,647.6989 386.9887,657.0114 C 376.8012,646.6364 371.8637,628.8239 371.8637,603.6364 C 371.8637,559.6989 383.8012,518.2614 405.6762,487.7614 C 422.5512,464.0739 441.2387,452.6364 463.9262,452.6364 C 474.8637,452.6364 483.9887,455.1364 491.1137,460.2614 C 483.3012,451.7614 472.2387,447.6364 458.1137,447.6364 z M 289.4543,560.2442 C 295.3293,566.4942 297.5512,575.3239 297.5512,587.1989 C 297.5512,622.5739 278.3012,651.4489 254.9887,651.4489 C 250.7387,651.4489 247.1762,650.8239 244.6762,649.4489 C 246.7387,653.8864 252.3637,656.4489 260.8637,656.4489 C 284.1762,656.4489 303.3637,627.6364 303.3637,592.1989 C 303.3637,576.8239 299.2668,566.3692 289.4543,560.2442 z M 466.1137,466.3864 C 467.9887,469.1989 468.8637,473.4489 468.8637,479.0114 C 468.8637,510.3864 452.5512,591.7614 438.8637,628.5739 C 432.7387,645.1364 426.9262,651.4489 417.3012,651.4489 C 415.4262,651.4489 413.8012,651.1989 412.4262,650.5114 C 414.4887,654.5739 418.0512,656.4489 423.1762,656.4489 C 432.7387,656.4489 438.6137,650.1364 444.7387,633.5739 C 458.4262,596.7614 474.7387,515.4489 474.7387,484.0114 C 474.7387,474.0114 471.9887,468.1364 466.1137,466.3864 z M 370.3522,457.7614 L 265.2387,457.7614 L 244.8808,552.1075 C 242.1371,551.6873 239.9389,549.727 240.7324,547.4444 L 260.6785,457.581 C 261.1453,455.4781 263.4107,453.352 265.5648,453.352 L 362.7469,453.352 C 364.7213,453.352 369.2935,456.0947 370.3522,457.7614 z M 328.4262,553.0114 C 315.8637,544.2614 297.3012,540.0114 273.0512,540.2614 L 260.8076,539.6708 L 262.1825,534.9661 L 267.2387,535.2614 C 295.6762,534.9489 316.3012,540.8864 328.4262,553.0114 z "
- style="font-size:48px;font-style:italic;font-weight:bold;fill:#c68500;fill-opacity:1;stroke-width:1;font-family:Luxi Serif" /><path
+ d="m 252.2839,629.23437 c -0.31156,1.44133 2.81188,2.88283 4.05881,2.98258 l 5.95783,-28.81035 h 10.42437 l 0.24938,-1.94521 0.24939,-2.04497 h -10.0445 c -2.4056,0 -4.59462,0.23941 -5.09579,2.59218 z M 446.69708,462.3036 c -18.15535,0 -33.0188,9.07768 -46.53556,27.98119 -17.40719,24.39002 -26.98364,57.40882 -26.98364,92.52247 0,23.69174 5.43663,39.15372 16.75878,46.58544 -8.13,-8.27964 -12.07031,-22.49468 -12.07031,-42.59525 0,-35.06377 9.52657,-68.13245 26.98364,-92.47259 13.46688,-18.90352 28.38021,-28.03107 46.48568,-28.03107 8.72854,0 16.01063,1.99509 21.69665,6.08503 -6.23467,-6.78331 -15.06296,-10.07522 -26.33524,-10.07522 z m -134.59652,89.86525 c 4.68847,4.98773 6.46163,12.03416 6.46163,21.51086 0,28.23057 -15.36223,51.27391 -33.96647,51.27391 -3.39166,0 -6.23467,-0.49878 -8.22977,-1.59608 1.64596,3.54129 6.13492,5.58626 12.91824,5.58626 18.60424,0 33.91659,-22.99345 33.91659,-51.2739 0,-12.26983 -3.26948,-20.61307 -11.10022,-25.50105 z M 453.08138,477.2668 c 1.49632,2.24448 2.1946,5.63614 2.1946,10.07523 0,25.03842 -13.01798,89.97872 -23.94112,119.35648 -4.88798,13.21749 -9.52657,18.25511 -17.20768,18.25511 -1.49633,0 -2.79314,-0.19951 -3.89044,-0.74816 1.64595,3.24202 4.48896,4.73834 8.57891,4.73834 7.63123,0 12.3197,-5.03761 17.20768,-18.2551 10.92314,-29.37776 23.94112,-94.26818 23.94112,-119.35648 0,-7.98038 -2.1946,-12.66885 -6.88307,-14.06542 z m -76.42127,-6.88307 H 292.7756 l -16.24637,75.29173 c -2.18957,-0.33534 -3.94382,-1.89973 -3.31058,-3.72133 l 15.91774,-71.71436 c 0.37252,-1.6782 2.1804,-3.37491 3.89945,-3.37491 h 77.55496 c 1.57564,0 5.22443,2.18878 6.06931,3.51887 z m -33.45852,76.01307 c -10.02534,-6.98283 -24.83891,-10.37449 -44.19132,-10.17498 l -9.77085,-0.47132 1.09722,-3.75452 4.03504,0.23566 c 22.69419,-0.24939 39.15371,4.48896 48.82991,14.16516 z"
+ style="font-style:italic;font-weight:bold;font-size:48px;font-family:'Luxi Serif';fill:#c68500;fill-opacity:1;stroke-width:0.79803747"
+ inkscape:connector-curvature="0" /><path
sodipodi:nodetypes="ccccssccccccccccscccccss"
id="path666"
- d="M 569.125,589.125 C 573.375,589.5625 575.4375,592.625 575.4375,598.0625 L 575.4375,598.625 L 575.4375,599.875 L 573.9773,606.9543 C 573.5713,608.9227 569.7838,603.9155 569.9603,601.9134 L 570.4375,596.5 L 570.4375,595.3125 L 570.4375,594.6875 C 570.4375,592.3125 570.0625,590.4375 569.125,589.125 z M 592.7682,585.6903 C 588.7737,585.1766 576.4375,582.0625 570.1875,582.0625 C 537.75,582.0625 512.875,605.8125 512.875,636.875 C 512.875,646.4375 516.4801,655.2528 522.6676,660.3778 C 513.2926,655.4403 507.875,645.4375 507.875,633.5 C 507.875,602.4375 532.6875,578.6875 565.1875,578.6875 C 573.3125,578.6875 581.0401,579.2408 589.0625,582.375 C 590.5879,582.9709 592.7444,584.1511 592.7682,585.6903 z M 571.2245,650.5241 C 563.2047,653.6404 558.625,653.125 553,653.125 C 549.3125,653.125 546.1875,652.5625 543.875,651.3125 C 546.75,654.8125 552.0639,657.7528 558.6264,657.7528 C 562.6889,657.7528 571.9633,656.6635 576.2591,654.125 C 577.3093,653.5044 573.4254,649.6688 571.2245,650.5241 z "
- style="font-size:48px;font-style:italic;font-weight:bold;fill:#c88e00;fill-opacity:1;stroke-width:1;font-family:Luxi Serif" /></g></svg>
\ No newline at end of file
+ d="m 535.28826,575.21681 c 3.39166,0.34914 5.03761,2.79313 5.03761,7.13246 v 0.44889 0.99755 l -1.16529,5.64955 c -0.32401,1.57085 -3.34657,-2.42508 -3.20572,-4.02283 l 0.38082,-4.3201 v -0.94766 -0.49878 c 0,-1.89534 -0.29926,-3.39166 -1.04742,-4.43908 z m 18.86816,-2.74102 c -3.18776,-0.40995 -13.03251,-2.89512 -18.02025,-2.89512 -25.88634,0 -45.73752,18.95339 -45.73752,43.74243 0,7.63123 2.87701,14.66617 7.81486,18.75611 -7.4816,-3.94031 -11.80505,-11.92292 -11.80505,-21.44949 0,-24.78904 19.80131,-43.74243 45.73753,-43.74243 6.48405,0 12.65097,0.44156 19.05314,2.94277 1.21733,0.47555 2.9383,1.41739 2.95729,2.64573 z m -17.19268,51.7398 c -6.4001,2.48693 -10.05487,2.07562 -14.54384,2.07562 -2.94276,0 -5.43663,-0.4489 -7.28209,-1.44645 2.29436,2.79314 6.53505,5.13961 11.77217,5.13961 3.24203,0 10.64335,-0.86931 14.07156,-2.89513 0.8381,-0.49526 -2.2614,-3.55621 -4.0178,-2.87365 z"
+ style="font-style:italic;font-weight:bold;font-size:48px;font-family:'Luxi Serif';fill:#c88e00;fill-opacity:1;stroke-width:0.79803747"
+ inkscape:connector-curvature="0" /></g></svg>
\ No newline at end of file
diff --git a/src/activities/money/resource/c5c.svg b/src/activities/money/resource/c5c.svg
index bd3bd9f15..0214d6ed4 100644
--- a/src/activities/money/resource/c5c.svg
+++ b/src/activities/money/resource/c5c.svg
@@ -1,193 +1,210 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="svg699"
sodipodi:version="0.32"
width="503.34711"
height="500.98511"
xml:space="preserve"
sodipodi:docname="c5c.svg"
- inkscape:version="0.91 r13725"
+ inkscape:version="0.92.1 r15371"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
sodipodi:modified="true"
version="1.0"><metadata
id="metadata29"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs701"><linearGradient
id="linearGradient651"><stop
style="stop-color:#c73500;stop-opacity:1;"
offset="0"
id="stop652" /><stop
style="stop-color:#ffb76b;stop-opacity:1;"
offset="1"
id="stop653" /></linearGradient><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2193"
gradientUnits="userSpaceOnUse"
- gradientTransform="scale(1.0023546,0.9976509)"
+ gradientTransform="matrix(0.70026856,0,0,0.69698245,119.31219,157.97281)"
spreadMethod="pad"
- x1="673.5036"
- y1="300.07901"
- x2="103.53201"
- y2="595.92963" /><linearGradient
+ x1="654.19025"
+ y1="519.77606"
+ x2="152.59843"
+ y2="525.50427" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2195"
- x1="624.25223"
- y1="364.38833"
- x2="449.83819"
- y2="535.09138"
- gradientUnits="userSpaceOnUse" /><linearGradient
+ x1="164.75224"
+ y1="521.77063"
+ x2="639.0957"
+ y2="520.24756"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.69862359,0,0,0.69862359,121.03156,156.79042)" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2197"
spreadMethod="reflect"
x1="286.06671"
y1="307.05434"
x2="461.8503"
y2="147.59049"
gradientTransform="scale(0.9767462,1.0238074)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2199"
spreadMethod="reflect"
x1="382.07347"
y1="269.31339"
x2="533.9103"
y2="131.57308"
gradientTransform="scale(0.8819901,1.1337996)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2201"
spreadMethod="reflect"
x1="572.36365"
y1="204.5671"
x2="631.66211"
y2="150.77391"
gradientTransform="scale(0.935494,1.0689539)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2203"
spreadMethod="reflect"
x1="763.8678"
y1="158.54136"
x2="806.98456"
y2="119.42756"
gradientTransform="scale(0.6957958,1.4372033)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2205"
spreadMethod="reflect"
x1="266.82405"
y1="418.96704"
x2="342.59325"
y2="350.23224"
gradientTransform="scale(1.6403562,0.6096237)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2207"
spreadMethod="reflect"
x1="578.59925"
y1="267.88094"
x2="622.33322"
y2="228.20723"
gradientTransform="scale(1.0295592,0.9712894)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2209"
spreadMethod="reflect"
x1="459.52562"
y1="275.18938"
x2="506.24941"
y2="232.80342"
gradientTransform="scale(1.0716088,0.9331764)"
gradientUnits="userSpaceOnUse" /><linearGradient
inkscape:collect="always"
xlink:href="#linearGradient651"
id="linearGradient2211"
spreadMethod="reflect"
x1="898.9716"
y1="153.9525"
x2="942.47289"
y2="114.48988"
gradientTransform="scale(0.6819639,1.4663532)"
- gradientUnits="userSpaceOnUse" /></defs><sodipodi:namedview
+ gradientUnits="userSpaceOnUse" /><linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient651"
+ id="linearGradient2204"
+ x1="164.09622"
+ y1="520.24762"
+ x2="639.09576"
+ y2="520.24762"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5988202,0,0,0.5988202,161.11219,208.71288)" /></defs><sodipodi:namedview
id="base"
- inkscape:zoom="0.36014217"
- inkscape:cx="-597.0145"
- inkscape:cy="526.18109"
- inkscape:window-width="1366"
- inkscape:window-height="713"
- inkscape:window-x="-2"
- inkscape:window-y="-3"
+ inkscape:zoom="1.0186359"
+ inkscape:cx="34.658284"
+ inkscape:cy="348.88219"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
inkscape:current-layer="g2181"
showgrid="false"
inkscape:window-maximized="1" /><g
id="g2181"
transform="translate(-149.92241,-269.75517)"><path
- transform="translate(-2.46109,1.692474)"
sodipodi:nodetypes="ccccccc"
id="path687"
- d="M 655.7306,518.5551 C 655.7306,656.8984 543.0531,769.0478 404.0571,769.0478 C 265.0618,769.0478 152.3835,656.8984 152.3835,518.5551 C 152.3835,380.2119 265.0618,268.0627 404.0571,268.0627 C 543.0531,268.0627 655.7306,380.2119 655.7306,518.5551 z M 396.9986,636.0575 L 396.9986,636.0575 z "
- style="font-size:48px;font-style:italic;font-weight:bold;fill:url(#linearGradient2193);fill-opacity:1;stroke-width:1;font-family:Luxi Serif" /><rect
- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:3.50000000000000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ d="m 577.42104,520.24761 c 0,96.6499 -78.71916,175.00011 -175.82504,175.00011 -97.1054,0 -175.82511,-78.35021 -175.82511,-175.00011 0,-96.64981 78.71971,-174.99989 175.82511,-174.99989 97.10588,0 175.82504,78.35008 175.82504,174.99989 z m -180.75628,82.08996 z"
+ style="font-style:italic;font-weight:bold;font-size:48px;font-family:'Luxi Serif';fill:url(#linearGradient2193);fill-opacity:1;stroke-width:0.6986236"
+ inkscape:connector-curvature="0" /><rect
+ style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2.44518256;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect3312"
- width="302.65823"
- height="366.52191"
- x="180.4659"
- y="343.13138"
- ry="142.99908" /><path
+ width="211.44418"
+ height="256.06085"
+ x="247.10927"
+ y="396.51007"
+ ry="99.902527" /><path
id="path759"
- d="M 201.564,638.9766 C 226.6537,644.7762 243.3802,647.3135 258.1154,647.3135 C 324.2248,647.3135 377.5902,604.1793 377.5902,551.2585 C 377.5902,505.9495 342.146,482.7513 274.8419,483.4762 L 259.7084,483.4762 L 278.8244,418.9562 L 402.6799,418.9562 L 411.4414,378.7219 L 264.0892,378.7219 L 237.0082,501.5998 C 245.7697,500.5124 253.7347,500.1499 259.3102,500.1499 C 297.9404,500.1499 316.2598,516.4612 316.2598,549.4461 C 316.2598,594.3926 289.9754,631.0023 258.1154,631.0023 C 242.9819,631.0023 234.6187,625.5652 234.6187,616.5034 C 234.6187,615.0535 235.017,611.4288 236.61,604.5418 L 238.203,593.6677 L 238.6012,590.4054 L 211.9185,590.4054 L 201.564,638.9766 z M 462.5704,635.2231 C 455.7123,637.8353 450.2259,638.9352 445.5015,638.9352 C 435.443,638.9352 430.5661,633.8482 430.5661,623.3992 C 430.5661,613.5002 433.4618,601.6763 438.491,591.0898 C 442.7582,582.2907 447.7875,577.8911 453.5787,577.8911 C 457.9983,577.8911 460.132,580.6408 460.132,586.1403 L 460.132,586.6903 L 460.132,587.7902 L 459.37,592.7397 L 459.0652,593.9771 L 471.562,593.9771 L 475.8293,575.0039 C 468.8188,572.6666 462.5704,571.7042 455.7123,571.7042 C 428.4325,571.7042 407.5536,593.1521 407.5536,621.1994 C 407.5536,638.7977 418.6789,648.6968 438.6434,648.6968 C 444.8919,648.6968 451.1403,647.7344 460.4368,645.2596 L 462.5704,635.2231 z M 254.0036,467.903 L 254.0036,467.903 z M 639.0957,520.2476 C 639.0957,651.4152 532.7637,757.7475 401.5958,757.7475 C 270.4286,757.7475 164.0962,651.4152 164.0962,520.2476 C 164.0962,389.0801 270.4286,282.7479 401.5958,282.7479 C 532.7637,282.7479 639.0957,389.0801 639.0957,520.2476 z M 390.9698,631.2727 L 390.9698,631.2727 z M 265.3258,412.7872 L 265.3258,412.7872 z "
- style="font-size:48px;font-style:italic;font-weight:bold;fill:url(#linearGradient2195);stroke-width:1;font-family:Luxi Serif" /><g
+ d="m 261.84893,603.19451 c 17.52825,4.05174 29.21377,5.82436 39.50814,5.82436 46.18558,0 83.4679,-30.13457 83.4679,-67.10629 0,-31.65393 -24.76215,-47.86074 -71.78238,-47.35431 h -10.57262 l 13.35489,-45.0752 h 86.52837 l 6.121,-28.10862 H 305.5305 l -18.91942,85.84539 c 6.12098,-0.75968 11.68553,-1.01293 15.5807,-1.01293 26.98796,0 39.78633,11.39546 39.78633,34.43949 0,31.40068 -18.3629,56.97708 -40.62104,56.97708 -10.57263,0 -16.41535,-3.79848 -16.41535,-10.12927 0,-1.01293 0.27826,-3.54524 1.39116,-8.35666 l 1.11291,-7.5969 0.27819,-2.27912 h -18.64116 z m 182.34521,-2.62228 c -4.79123,1.82495 -8.62415,2.59336 -11.92473,2.59336 -7.0271,0 -10.43423,-3.5539 -10.43423,-10.85382 0,-6.91567 2.02302,-15.17612 5.53653,-22.5721 2.98117,-6.14726 6.49475,-9.22093 10.54062,-9.22093 3.08764,0 4.57829,1.92101 4.57829,5.76309 v 0.38424 0.76842 l -0.53235,3.45783 -0.21294,0.86448 h 8.73056 l 2.98124,-13.25512 c -4.89771,-1.63289 -9.26299,-2.30525 -14.05422,-2.30525 -19.05831,0 -33.6448,14.98401 -33.6448,34.57852 0,12.29458 7.7724,19.21033 21.72007,19.21033 4.36535,0 8.73063,-0.67236 15.22538,-2.40131 z M 298.48446,483.67847 Z m 269.03442,36.56917 c 0,91.63678 -74.28604,165.92303 -165.92303,165.92303 -91.6365,0 -165.92282,-74.28625 -165.92282,-165.92303 0,-91.63671 74.28632,-165.92289 165.92282,-165.92289 91.63699,0 165.92303,74.28618 165.92303,165.92289 z m -173.3466,77.56475 z M 306.39442,445.17327 Z"
+ style="font-style:italic;font-weight:bold;font-size:48px;font-family:'Luxi Serif';fill:url(#linearGradient2195);stroke-width:0.6986236"
+ inkscape:connector-curvature="0" /><g
style="font-size:12px;fill:url(#linearGradient2197)"
- transform="matrix(1.081439,0,0,1.058679,-35.73745,215.6848)"
+ transform="matrix(0.75551877,0,0,0.73961811,96.064528,307.47288)"
id="g944"><path
id="path943"
- d="M 489.2781,157.6309 C 486.7725,158.6472 483.694,159.9616 480.8916,161.4231 C 479.3419,161.0055 475.428,159.2736 475.428,155.3341 C 475.428,151.3946 478.7154,148.2011 482.7708,148.2011 C 488.0788,148.2011 490.7398,151.8121 489.2781,157.6309 z M 521.9314,154.5415 C 521.9314,158.4811 518.0176,160.213 516.6769,160.8394 C 513.0392,159.5867 510.1692,158.6899 508.0812,158.0913 C 505.5757,152.2726 509.2807,147.4085 514.5889,147.4085 C 518.644,147.4085 521.9314,150.6021 521.9314,154.5415 z M 554.0133,282.1463 C 539.7204,299.0921 519.7959,311.7673 487.7231,311.2372 C 455.0333,310.1367 444.7336,294.8341 446.4288,254.5974 C 447.4384,237.4799 453.0554,223.2215 459.4115,212.5429 C 462.707,204.534 471.5472,201.7454 476.9885,177.1512 C 485.6153,185.4841 494.4355,188.3269 497.9466,188.3677 C 504.6303,188.4997 521.1268,180.7489 526.5206,174.9439 C 532.8029,196.1211 539.725,203.2866 544.2499,208.414 C 571.8131,240.2076 557.189,277.6971 554.0133,282.1463 z M 494.2871,157.0588 C 487.7115,157.6404 481.7311,160.3453 477.7269,163.5282 C 475.279,165.2092 472.0644,157.8887 472.0644,152.4116 C 472.0644,145.0207 475.2644,139.5457 483.471,139.5457 C 490.9986,139.5457 495.5149,147.9387 494.2871,157.0588 z M 503.3984,157.4551 C 509.7709,158.1484 517.8879,161.2707 522.7624,163.7729 C 525.4762,165.4536 527.6282,158.285 527.6282,152.8079 C 527.6282,147.0021 523.8588,139.1494 514.7603,139.1494 C 505.191,139.1494 502.0372,145.9572 503.3984,157.4551 z M 504.7202,106.7478 C 474.7132,106.4276 457.1089,126.4945 461.8612,178.9302 C 463.5845,198.2381 361.0517,308.565 481.4685,323.2273 L 525.5737,324.0199 C 606.8295,319.2645 591.7019,249.1051 588.8989,241.103 C 580.6322,213.4795 553.1952,187.4526 553.0018,172.6248 C 552.814,127.3526 535.8651,106.2749 504.7202,106.7478 z M 529.3964,169.2447 C 529.7524,177.204 506.4211,188.5796 497.5232,188.5796 C 490.247,188.5796 473.2299,177.6226 472.7098,170.2413 C 472.4321,166.698 484.8286,156.8974 498.0721,157.1776 C 508.6449,157.1776 529.106,164.0661 529.3964,169.2447 z M 505.6319,158.6713 C 504.8923,159.1122 502.5108,159.8841 502.2685,159.8142 C 501.7591,159.7069 502.9358,158.8886 503.1344,158.3848 C 503.3119,157.9112 506.3718,158.2303 505.6319,158.6713 z M 491.2411,158.3369 C 491.2346,158.7713 491.7574,159.5856 492.1907,159.5931 C 492.5879,159.0685 492.9824,158.6462 493.4274,158.2207 C 493.8848,157.8292 491.2476,157.996 491.2411,158.3369 z M 475.86,171.0084 C 475.1974,169.8919 481.8043,180.5114 494.4183,180.9245 C 505.2062,181.3048 518.8716,172.4247 527.1629,168.9206 C 494.2345,184.859 489.641,183.0493 475.86,171.0084 z M 532.9812,126.1648 C 531.3254,129.0911 525.7228,129.7142 520.4675,127.5566 C 515.2121,125.3989 512.294,121.2776 513.9498,118.3513 C 515.6056,115.425 521.2082,114.8019 526.4636,116.9596 C 531.7189,119.1172 534.6369,123.2386 532.9812,126.1648 z "
- style="font-size:12px;fill:url(#linearGradient2199);fill-rule:evenodd" /><path
+ d="m 489.2781,157.6309 c -2.5056,1.0163 -5.5841,2.3307 -8.3865,3.7922 -1.5497,-0.4176 -5.4636,-2.1495 -5.4636,-6.089 0,-3.9395 3.2874,-7.133 7.3428,-7.133 5.308,0 7.969,3.611 6.5073,9.4298 z m 32.6533,-3.0894 c 0,3.9396 -3.9138,5.6715 -5.2545,6.2979 -3.6377,-1.2527 -6.5077,-2.1495 -8.5957,-2.7481 -2.5055,-5.8187 1.1995,-10.6828 6.5077,-10.6828 4.0551,0 7.3425,3.1936 7.3425,7.133 z m 32.0819,127.6048 c -14.2929,16.9458 -34.2174,29.621 -66.2902,29.0909 -32.6898,-1.1005 -42.9895,-16.4031 -41.2943,-56.6398 1.0096,-17.1175 6.6266,-31.3759 12.9827,-42.0545 3.2955,-8.0089 12.1357,-10.7975 17.577,-35.3917 8.6268,8.3329 17.447,11.1757 20.9581,11.2165 6.6837,0.132 23.1802,-7.6188 28.574,-13.4238 6.2823,21.1772 13.2044,28.3427 17.7293,33.4701 27.5632,31.7936 12.9391,69.2831 9.7634,73.7323 z M 494.2871,157.0588 c -6.5756,0.5816 -12.556,3.2865 -16.5602,6.4694 -2.4479,1.681 -5.6625,-5.6395 -5.6625,-11.1166 0,-7.3909 3.2,-12.8659 11.4066,-12.8659 7.5276,0 12.0439,8.393 10.8161,17.5131 z m 9.1113,0.3963 c 6.3725,0.6933 14.4895,3.8156 19.364,6.3178 2.7138,1.6807 4.8658,-5.4879 4.8658,-10.965 0,-5.8058 -3.7694,-13.6585 -12.8679,-13.6585 -9.5693,0 -12.7231,6.8078 -11.3619,18.3057 z m 1.3218,-50.7073 c -30.007,-0.3202 -47.6113,19.7467 -42.859,72.1824 1.7233,19.3079 -100.8095,129.6348 19.6073,144.2971 l 44.1052,0.7926 c 81.2558,-4.7554 66.1282,-74.9148 63.3252,-82.9169 -8.2667,-27.6235 -35.7037,-53.6504 -35.8971,-68.4782 -0.1878,-45.2722 -17.1367,-66.3499 -48.2816,-65.877 z m 24.6762,62.4969 c 0.356,7.9593 -22.9753,19.3349 -31.8732,19.3349 -7.2762,0 -24.2933,-10.957 -24.8134,-18.3383 -0.2777,-3.5433 12.1188,-13.3439 25.3623,-13.0637 10.5728,0 31.0339,6.8885 31.3243,12.0671 z m -23.7645,-10.5734 c -0.7396,0.4409 -3.1211,1.2128 -3.3634,1.1429 -0.5094,-0.1073 0.6673,-0.9256 0.8659,-1.4294 0.1775,-0.4736 3.2374,-0.1545 2.4975,0.2865 z m -14.3908,-0.3344 c -0.007,0.4344 0.5163,1.2487 0.9496,1.2562 0.3972,-0.5246 0.7917,-0.9469 1.2367,-1.3724 0.4574,-0.3915 -2.1798,-0.2247 -2.1863,0.1162 z M 475.86,171.0084 c -0.6626,-1.1165 5.9443,9.503 18.5583,9.9161 10.7879,0.3803 24.4533,-8.4998 32.7446,-12.0039 -32.9284,15.9384 -37.5219,14.1287 -51.3029,2.0878 z m 57.1212,-44.8436 c -1.6558,2.9263 -7.2584,3.5494 -12.5137,1.3918 -5.2554,-2.1577 -8.1735,-6.279 -6.5177,-9.2053 1.6558,-2.9263 7.2584,-3.5494 12.5138,-1.3917 5.2553,2.1576 8.1733,6.279 6.5176,9.2052 z"
+ style="font-size:12px;fill:url(#linearGradient2199);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /><path
transform="matrix(1.381431,0,0,1.342002,-335.1481,-21.47379)"
sodipodi:nodetypes="cccccccccccccccccccccc"
id="path871"
- d="M 594.8524,209.0117 C 594.8524,220.1016 597.3741,225.5481 596.0694,225.5481 C 594.7647,225.5481 591.5893,219.8928 591.5893,208.8029 C 591.5893,197.7133 595.8087,185.5974 597.1134,185.5974 C 598.4181,185.5974 594.8524,197.9221 594.8524,209.0117 z M 632.27,169.5802 C 636.4462,173.2967 639.9597,177.6751 641.0037,183.062 C 633.8452,176.8398 621.8843,173.9586 614.9343,172.3301 C 621.0488,172.1213 630.1226,172.5034 632.27,169.5802 z M 595.6275,172.1593 C 597.9116,174.2791 597.2725,175.7726 598.0951,178.5188 C 598.4549,175.911 602.5729,173.9295 604.8118,171.9481 C 601.9592,172.4361 598.4801,172.5065 595.6275,172.1593 z M 578.9845,168.302 C 576.6727,170.9576 573.7897,175.239 570.9888,182.7921 C 576.8947,176.1524 582.6886,175.629 589.2209,172.9565 C 583.3151,172.7478 581.1318,171.2251 578.9845,168.302 z M 624.5364,145.5447 C 621.5836,154.254 608.0056,162.0592 600.9178,162.0592 C 596.7828,162.0592 588.4029,155.7413 586.9264,147.0322 C 592.4305,152.4557 598.446,156.1755 603.0832,156.3597 C 608.2112,156.4881 619.7769,150.57 624.5364,145.5447 z "
- style="font-size:12px;fill:url(#linearGradient2201);fill-rule:evenodd" /><path
+ d="m 594.8524,209.0117 c 0,11.0899 2.5217,16.5364 1.217,16.5364 -1.3047,0 -4.4801,-5.6553 -4.4801,-16.7452 0,-11.0896 4.2194,-23.2055 5.5241,-23.2055 1.3047,0 -2.261,12.3247 -2.261,23.4143 z M 632.27,169.5802 c 4.1762,3.7165 7.6897,8.0949 8.7337,13.4818 -7.1585,-6.2222 -19.1194,-9.1034 -26.0694,-10.7319 6.1145,-0.2088 15.1883,0.1733 17.3357,-2.7499 z m -36.6425,2.5791 c 2.2841,2.1198 1.645,3.6133 2.4676,6.3595 0.3598,-2.6078 4.4778,-4.5893 6.7167,-6.5707 -2.8526,0.488 -6.3317,0.5584 -9.1843,0.2112 z m -16.643,-3.8573 c -2.3118,2.6556 -5.1948,6.937 -7.9957,14.4901 5.9059,-6.6397 11.6998,-7.1631 18.2321,-9.8356 -5.9058,-0.2087 -8.0891,-1.7314 -10.2364,-4.6545 z m 45.5519,-22.7573 c -2.9528,8.7093 -16.5308,16.5145 -23.6186,16.5145 -4.135,0 -12.5149,-6.3179 -13.9914,-15.027 5.5041,5.4235 11.5196,9.1433 16.1568,9.3275 5.128,0.1284 16.6937,-5.7897 21.4532,-10.815 z"
+ style="font-size:12px;fill:url(#linearGradient2201);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /><path
transform="matrix(1.381431,0,0,1.342002,-335.1483,-21.47379)"
sodipodi:nodetypes="csccc"
id="path758"
- d="M 566.1781,204.0047 C 566.1781,224.5982 593.4836,225.0052 587.8079,232.522 C 582.6399,239.91 550.7196,226.5353 550.7196,205.9419 C 552.8076,190.3594 555.5661,185.5046 574.6452,156.366 C 587.5403,159.1975 566.1781,183.4112 566.1781,204.0047 z "
- style="font-size:12px;fill:url(#linearGradient2203);fill-rule:evenodd" /><g
+ d="m 566.1781,204.0047 c 0,20.5935 27.3055,21.0005 21.6298,28.5173 -5.168,7.388 -37.0883,-5.9867 -37.0883,-26.5801 2.088,-15.5825 4.8465,-20.4373 23.9256,-49.5759 12.8951,2.8315 -8.4671,27.0452 -8.4671,47.6387 z"
+ style="font-size:12px;fill:url(#linearGradient2203);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /><g
style="font-size:12px;fill:url(#linearGradient2205)"
transform="matrix(1.381431,0,0,1.342002,-325.2191,-15.60249)"
id="g1065"><path
transform="translate(-7.1875,-4.375031)"
sodipodi:nodetypes="csssscsss"
id="path842"
- d="M 662.6023,249.8415 C 652.9563,254.7202 643.0236,269.4045 630.2927,263.3619 C 621.3526,259.2146 625.6634,249.1638 625.1563,243.5311 C 624.668,230.5505 623.5071,211.1312 631.9468,211.184 C 642.1547,211.246 638.0258,215.2545 645.4196,217.3441 C 653.505,219.306 658.7389,209.0467 664.847,213.6095 C 669.4787,219.944 664.6217,223.322 670.205,229.4906 C 673.1685,233.0602 677.7506,232.9839 680.3539,235.8973 C 685.7736,241.3478 668.3201,246.6544 662.6023,249.8415 z "
- style="font-size:12px;fill:url(#linearGradient2207);fill-rule:evenodd" /><path
+ d="m 662.6023,249.8415 c -9.646,4.8787 -19.5787,19.563 -32.3096,13.5204 -8.9401,-4.1473 -4.6293,-14.1981 -5.1364,-19.8308 -0.4883,-12.9806 -1.6492,-32.3999 6.7905,-32.3471 10.2079,0.062 6.079,4.0705 13.4728,6.1601 8.0854,1.9619 13.3193,-8.2974 19.4274,-3.7346 4.6317,6.3345 -0.2253,9.7125 5.358,15.8811 2.9635,3.5696 7.5456,3.4933 10.1489,6.4067 5.4197,5.4505 -12.0338,10.7571 -17.7516,13.9442 z"
+ style="font-size:12px;fill:url(#linearGradient2207);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /><path
transform="translate(-7.1875,-4.375031)"
sodipodi:nodetypes="cssssssss"
id="path843"
- d="M 550.8908,255.4014 C 562.5947,256.6532 574.367,267.8037 584.6032,256.5396 C 591.8317,248.7246 584.743,239.3914 580.5155,234.7902 C 570.7341,224.8274 565.2408,206.427 556.2229,206.4986 C 548.5882,206.8092 550.0632,210.9825 544.7009,215.234 C 537.4953,220.6488 532.9891,216.239 528.6392,223.1506 C 525.9871,226.8955 526.7585,231.7788 527.8864,236.9511 C 528.6785,241.8714 527.0976,242.9494 525.4163,244.55 C 519.9332,250.7329 540.853,254.0325 550.8908,255.4014 z "
- style="font-size:12px;fill:url(#linearGradient2209);fill-rule:evenodd" /></g><path
+ d="m 550.8908,255.4014 c 11.7039,1.2518 23.4762,12.4023 33.7124,1.1382 7.2285,-7.815 0.1398,-17.1482 -4.0877,-21.7494 -9.7814,-9.9628 -15.2747,-28.3632 -24.2926,-28.2916 -7.6347,0.3106 -6.1597,4.4839 -11.522,8.7354 -7.2056,5.4148 -11.7118,1.005 -16.0617,7.9166 -2.6521,3.7449 -1.8807,8.6282 -0.7528,13.8005 0.7921,4.9203 -0.7888,5.9983 -2.4701,7.5989 -5.4831,6.1829 15.4367,9.4825 25.4745,10.8514 z"
+ style="font-size:12px;fill:url(#linearGradient2209);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /></g><path
transform="matrix(1.381431,0,0,1.342002,-335.1483,-21.47379)"
sodipodi:nodetypes="cscss"
id="path857"
- d="M 649.8842,196.2501 C 649.4318,220.8146 631.991,220.9147 636.6064,229.3612 C 642.8768,241.2543 669.5186,218.7807 669.5186,198.1874 C 669.5186,178.0113 641.3187,150.3852 638.2491,152.2475 C 619.1027,166.4884 650.6787,175.7879 649.8842,196.2501 z "
- style="font-size:12px;fill:url(#linearGradient2211);fill-rule:evenodd" /></g></g></svg>
\ No newline at end of file
+ d="m 649.8842,196.2501 c -0.4524,24.5645 -17.8932,24.6646 -13.2778,33.1111 6.2704,11.8931 32.9122,-10.5805 32.9122,-31.1738 0,-20.1761 -28.1999,-47.8022 -31.2695,-45.9399 -19.1464,14.2409 12.4296,23.5404 11.6351,44.0026 z"
+ style="font-size:12px;fill:url(#linearGradient2211);fill-rule:evenodd"
+ inkscape:connector-curvature="0" /></g></g></svg>
\ No newline at end of file
diff --git a/src/activities/money_back/ActivityInfo.qml b/src/activities/money_back/ActivityInfo.qml
index e5e781a93..ccbd91d09 100644
--- a/src/activities/money_back/ActivityInfo.qml
+++ b/src/activities/money_back/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "money_back/MoneyBack.qml"
difficulty: 3
icon: "money_back/money_back.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
//: Activity title
title: qsTr("Give Tux his change")
//: Help title
description: qsTr("Practice money usage by giving Tux his change")
// intro: "Click on the money at the bottom of the screen to give Tux his change."
//: Help goal
goal: qsTr("Tux bought different items from you and shows you his money. You must give him back his change. At higher levels, several items are displayed, and you must first calculate the total price.")
//: Help prerequisite
prerequisite: qsTr("Can count")
//: Help manual
manual: qsTr("Click on the coins or paper money at the bottom of the screen to pay. If you want to remove a coin or note, click on it on the upper screen area.")
credit: ""
section: "math numeration money"
createdInVersion: 0
}
diff --git a/src/activities/money_back/MoneyBack.qml b/src/activities/money_back/MoneyBack.qml
index ba4da80bf..823222b07 100644
--- a/src/activities/money_back/MoneyBack.qml
+++ b/src/activities/money_back/MoneyBack.qml
@@ -1,29 +1,29 @@
/* GCompris - MoneyBack.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import "../money"
MoneyCore {
dataset: "BACK_WITHOUT_CENTS"
}
diff --git a/src/activities/money_back_cents/ActivityInfo.qml b/src/activities/money_back_cents/ActivityInfo.qml
index ea2601b2d..6709efb9e 100644
--- a/src/activities/money_back_cents/ActivityInfo.qml
+++ b/src/activities/money_back_cents/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "money_back_cents/MoneyBackCents.qml"
difficulty: 5
icon: "money_back_cents/money_back_cents.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
//: Activity title
title: qsTr("Give Tux his change, including cents")
//: Help title
description: qsTr("Practice money usage by giving Tux his change")
// intro: "Click on the money at the bottom of the screen to give Tux his change."
//: Help goal
goal: qsTr("Tux bought different items from you and shows you his money. You must give him back his change. At higher levels, several items are displayed, and you must first calculate the total price.")
//: Help prerequisite
prerequisite: qsTr("Can count")
//: Help manual
manual: qsTr("Click on the coins or paper money at the bottom of the screen to pay. If you want to remove a coin or note, click on it on the upper screen area.")
credit: ""
section: "math numeration money"
createdInVersion: 0
}
diff --git a/src/activities/money_back_cents/MoneyBackCents.qml b/src/activities/money_back_cents/MoneyBackCents.qml
index ea373b99a..acd88b865 100644
--- a/src/activities/money_back_cents/MoneyBackCents.qml
+++ b/src/activities/money_back_cents/MoneyBackCents.qml
@@ -1,29 +1,29 @@
/* GCompris - Money.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import "../money"
MoneyCore {
dataset: "BACK_WITH_CENTS"
}
diff --git a/src/activities/money_cents/ActivityInfo.qml b/src/activities/money_cents/ActivityInfo.qml
index 4e7faaa62..8171023e0 100644
--- a/src/activities/money_cents/ActivityInfo.qml
+++ b/src/activities/money_cents/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "money_cents/MoneyCents.qml"
difficulty: 5
icon: "money_cents/money_cents.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
//: Activity title
title: qsTr("Money with cents")
//: Help title
description: qsTr("Practice money usage including cents")
// intro: "Click on the money to pay."
//: Help goal
goal: qsTr("You must buy the different items and give the exact price. At higher levels, several items are displayed, and you must first calculate the total price.")
//: Help prerequisite
prerequisite: qsTr("Can count")
//: Help manual
manual: qsTr("Click on the coins or paper money at the bottom of the screen to pay. If you want to remove a coin or note, click on it on the upper screen area.")
credit: ""
section: "math numeration money"
createdInVersion: 0
}
diff --git a/src/activities/money_cents/MoneyCents.qml b/src/activities/money_cents/MoneyCents.qml
index 39b10070c..d0823cd6d 100644
--- a/src/activities/money_cents/MoneyCents.qml
+++ b/src/activities/money_cents/MoneyCents.qml
@@ -1,29 +1,29 @@
/* GCompris - MoneyCents.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import "../money"
MoneyCore {
dataset: "WITH_CENTS"
}
diff --git a/src/activities/mosaic/ActivityInfo.qml b/src/activities/mosaic/ActivityInfo.qml
index 4e70b4b90..d53439ac6 100644
--- a/src/activities/mosaic/ActivityInfo.qml
+++ b/src/activities/mosaic/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "mosaic/Mosaic.qml"
difficulty: 1
icon: "mosaic/mosaic.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
//: Activity title
title: qsTr("Rebuild the mosaic")
//: Help title
description: qsTr("Put each item at the same place as in the given example.")
// intro: "Put each item at the same place as in the given example."
//: Help goal
goal: ""
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("First select the item you want to put then click on a spot on the empty area")
credit: ""
section: "discovery"
createdInVersion: 0
}
diff --git a/src/activities/mosaic/Mosaic.qml b/src/activities/mosaic/Mosaic.qml
index 6fad13381..f8b881d50 100644
--- a/src/activities/mosaic/Mosaic.qml
+++ b/src/activities/mosaic/Mosaic.qml
@@ -1,382 +1,382 @@
/* GCompris - mosaic.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Clement coudoin <clement.coudoin@free.fr> (GTK+ version)
* Bruno.coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "mosaic.js" as Activity
ActivityBase {
id: activity
onStart: focus = true
onStop: {}
pageComponent: Image {
id: background
source: Activity.url + "background.svg"
sourceSize.width: Math.max(parent.width, parent.height)
fillMode: Image.PreserveAspectCrop
anchors.fill: parent
signal start
signal stop
property bool keyboardMode: false
property var areaWithKeyboardFocus: selector
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property GCSfx audioEffects: activity.audioEffects
property alias question: question
property alias answer: answer
property alias selector: selector
property alias nbItems: column.nbItems
property alias background: background
property alias bar: bar
property alias bonus: bonus
property string selectedItem
}
onStart: { Activity.start(items) }
onStop: { Activity.stop() }
Keys.onLeftPressed: {
keyboardMode = true
areaWithKeyboardFocus.moveCurrentIndexLeft()
}
Keys.onRightPressed: {
keyboardMode = true
areaWithKeyboardFocus.moveCurrentIndexRight()
}
Keys.onUpPressed: {
keyboardMode = true
areaWithKeyboardFocus.moveCurrentIndexUp()
}
Keys.onDownPressed: {
keyboardMode = true
areaWithKeyboardFocus.moveCurrentIndexDown()
}
Keys.onEnterPressed: {
selectCell()
}
Keys.onSpacePressed: {
selectCell()
}
Keys.onReturnPressed: {
selectCell()
}
Keys.onTabPressed: {
keyboardMode = true
areaWithKeyboardFocus.changeAreaWithKeyboardFocus()
}
function selectCell() {
keyboardMode = true
areaWithKeyboardFocus.selectCurrentCell(areaWithKeyboardFocus.currentItem)
}
Column {
id: column
spacing: 10
x: parent.width * 0.05
y: parent.height * 0.05
width: parent.width * 0.9
property int nbItems: 24
- property bool horizontal: background.width > background.height
+ property bool horizontal: background.width >= background.height
property int nbColumns: Activity.questionLayout[nbItems][0]
property int nbLines: Activity.questionLayout[nbItems][1]
property int itemWidth: horizontal ?
Math.min(width / 2 / nbColumns - 10 - 10 / nbColumns / 2,
parent.height / 2 / nbLines - 10 - 10 / nbLines / 2) :
Math.min(width / nbColumns - 10 - 10 / nbColumns / 2,
parent.height * 0.25 / nbLines - 10 - 10 / nbLines / 2)
property int itemHeight: itemWidth
property int nbSelectorColumns: horizontal ?
Activity.selectorLayout[nbItems][0] :
Activity.selectorLayout[nbItems][0] / 2
property int nbSelectorLines: horizontal ?
Activity.selectorLayout[nbItems][1] :
Activity.selectorLayout[nbItems][1] * 2
Grid {
id: row
spacing: 10
columns: column.horizontal ? 2 : 1
// === The Question Area ===
Rectangle {
height: (column.itemHeight + 10) * column.nbLines
width: column.horizontal ? column.width / 2 : column.width + 10
color: "#55333333"
border.color: "black"
border.width: 2
radius: 5
GridView {
id: question
width: (column.nbColumns * column.itemWidth) + (12.5 * (column.nbColumns - 1))
height: parent.height
x: 2 * ApplicationInfo.ratio
y: 2 * ApplicationInfo.ratio
cellHeight: cellWidth
cellWidth: width / column.nbColumns
interactive: false
keyNavigationWraps: true
delegate: Image {
source: Activity.url + modelData
fillMode: Image.PreserveAspectFit
width: question.cellWidth - 5 * ApplicationInfo.ratio
height: width
sourceSize.width: width
sourceSize.height: height
}
}
}
// === The Answer Area ===
Rectangle {
height: (column.itemHeight + 10) * column.nbLines
width: column.horizontal ? column.width / 2 : column.width + 10
color: "#55333333"
border.color: "black"
border.width: 2
radius: 5
GridView {
id: answer
width: (column.nbColumns * column.itemWidth) + (12.5 * (column.nbColumns - 1))
height: parent.height
x: 2 * ApplicationInfo.ratio
cellHeight: cellWidth
cellWidth: width / column.nbColumns
interactive: false
keyNavigationWraps: true
highlightFollowsCurrentItem: true
highlight: Rectangle {
color: "red"
border.width: 3
border.color: "black"
opacity: 0.6
visible: background.keyboardMode && (background.areaWithKeyboardFocus === answer)
Behavior on x { SpringAnimation { spring: 2; damping: 0.2 } }
Behavior on y { SpringAnimation { spring: 2; damping: 0.2 } }
}
// If the image was directly used as a delegate (without containing it in the item), the highlight element would have been be hard to notice as it would get completely hidden by the image due to the same sizes.
delegate: Item {
id: cellItem
width: answer.cellWidth
height: answer.cellHeight
readonly property int cellIndex: index
Image {
id: imageAnswerId
source: Activity.url + modelData
fillMode: Image.PreserveAspectFit
width: answer.cellWidth - 5 * ApplicationInfo.ratio
height: width
sourceSize.width: width
sourceSize.height: height
anchors.centerIn: parent
MouseArea {
anchors.fill: parent
onClicked: answer.selectCurrentCell(cellItem)
}
}
}
function selectCurrentCell(selectedCell) {
Activity.answerSelected(selectedCell.cellIndex)
}
function changeAreaWithKeyboardFocus() {
areaWithKeyboardFocus = selector
}
}
}
}
// === The Selector ===
Rectangle {
height: (column.itemWidth + 10) * column.nbSelectorLines
width: column.width + 10
color: "#661111AA"
border.color: "black"
border.width: 2
radius: 5
GridView {
id: selector
width: (column.nbSelectorColumns * column.itemWidth) + (12.5 * (column.nbSelectorColumns - 1))
height: parent.height
x: 2 * ApplicationInfo.ratio
y: 2 * ApplicationInfo.ratio
cellHeight: cellWidth
cellWidth: width / column.nbSelectorColumns
interactive: false
keyNavigationWraps: true
highlightFollowsCurrentItem: true
highlight: Rectangle {
color: "red"
border.width: 3
border.color: "black"
opacity: 0.6
visible: background.keyboardMode && (background.areaWithKeyboardFocus === selector)
Behavior on x { SpringAnimation { spring: 2; damping: 0.2 } }
Behavior on y { SpringAnimation { spring: 2; damping: 0.2 } }
}
delegate: Image {
id: imageId
source: Activity.url + modelData
fillMode: Image.PreserveAspectFit
width: selector.cellWidth - 5 * ApplicationInfo.ratio
height: width
sourceSize.width: width
sourceSize.height: height
z: iAmSelected ? 10 : 1
readonly property bool iAmSelected: items.selectedItem === modelData
readonly property string imageName: modelData
states: [
State {
name: "notclicked"
when: !imageId.iAmSelected && !mouseArea.containsMouse
PropertyChanges {
target: imageId
scale: 0.8
}
},
State {
name: "clicked"
when: mouseArea.pressed
PropertyChanges {
target: imageId
scale: 0.7
}
},
State {
name: "hover"
when: mouseArea.containsMouse
PropertyChanges {
target: imageId
scale: 1.1
}
},
State {
name: "selected"
when: imageId.iAmSelected
PropertyChanges {
target: imageId
scale: 1
}
}
]
SequentialAnimation {
id: anim
running: imageId.iAmSelected
loops: Animation.Infinite
alwaysRunToEnd: true
NumberAnimation {
target: imageId
property: "rotation"
from: 0; to: 10
duration: 200
easing.type: Easing.OutQuad
}
NumberAnimation {
target: imageId
property: "rotation"
from: 10; to: -10
duration: 400
easing.type: Easing.InOutQuad
}
NumberAnimation {
target: imageId
property: "rotation"
from: -10; to: 0
duration: 200
easing.type: Easing.InQuad
}
}
Behavior on scale { NumberAnimation { duration: 70 } }
MouseArea {
id: mouseArea
anchors.fill: imageId
hoverEnabled: true
onClicked: selector.selectCurrentCell(parent)
}
}
function selectCurrentCell(selectedCell) {
items.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/scroll.wav")
items.selectedItem = selectedCell.imageName
}
function changeAreaWithKeyboardFocus() {
areaWithKeyboardFocus = answer
}
}
}
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level }
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
}
Bonus {
id: bonus
Component.onCompleted: win.connect(Activity.nextLevel)
}
}
}
diff --git a/src/activities/mosaic/mosaic.js b/src/activities/mosaic/mosaic.js
index c5bdd1b91..16885ab97 100644
--- a/src/activities/mosaic/mosaic.js
+++ b/src/activities/mosaic/mosaic.js
@@ -1,139 +1,139 @@
/* GCompris - mosaic.js
*
* Copyright (C) 2014 Bruno Coudoin
*
* Authors:
* Clement coudoin <clement.coudoin@free.fr> (GTK+ version)
* Bruno.coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
.import "qrc:/gcompris/src/core/core.js" as Core
var images = [
"aquarela_colors.svg",
"giraffe.svg",
"pencil.svg",
"mouse_on_cheese.svg",
"mushroom_house.svg",
"pencils_paper.svg",
"pencils.svg",
"white_cake.svg",
"die_1.svg",
"die_2.svg",
"die_3.svg",
"die_4.svg",
"die_5.svg",
"die_6.svg",
"die_7.svg",
"die_0.svg",
"digital_die0.svg",
"digital_die1.svg",
"digital_die2.svg",
"digital_die3.svg",
"digital_die4.svg",
"digital_die5.svg",
"digital_die6.svg",
"digital_die7.svg"
]
var questionModel
var answerModel
var selectorModel
var url = "qrc:/gcompris/src/activities/mosaic/resource/"
// What is the grid layout based on the number of items
var questionLayout = {
8: [4, 2],
16: [4, 4],
24: [6, 4]
}
var selectorLayout = {
8: [8, 1],
16: [8, 2],
24: [12, 2]
}
var currentLevel = 0
var numberOfLevel = 16
var items
function start(items_) {
items = items_
currentLevel = 0
initLevel()
}
function stop() {
}
function initLevel() {
items.bar.level = currentLevel + 1
items.background.areaWithKeyboardFocus = items.selector
items.selectedItem = ""
if(currentLevel < 4) {
items.nbItems = 8
selectorModel = images.slice(currentLevel,
currentLevel + items.nbItems);
} else if(currentLevel < 8) {
items.nbItems = 16
selectorModel = images.slice(currentLevel - 4,
currentLevel - 4 + items.nbItems);
} else {
items.nbItems = 24
selectorModel = images.slice(0, items.nbItems);
}
items.selector.model = selectorModel
questionModel = Core.shuffle(selectorModel)
items.question.model = questionModel
answerModel = new Array()
for(var i=0; i < questionModel.length; i++)
answerModel.push("die_0.svg")
items.answer.model = answerModel
}
function nextLevel() {
if(numberOfLevel <= ++currentLevel ) {
currentLevel = 0
}
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
initLevel();
}
function answerSelected(index) {
if(!items.selectedItem)
return
items.audioEffects.play("qrc:/gcompris/src/activities/redraw/resource/brush.wav")
answerModel[index] = items.selectedItem
items.answer.model = answerModel
if(answerModel.toString() === questionModel.toString()) {
items.bonus.good("flower")
}
}
diff --git a/src/activities/nine_men_morris/ActivityInfo.qml b/src/activities/nine_men_morris/ActivityInfo.qml
index 66d620d28..0a971776b 100644
--- a/src/activities/nine_men_morris/ActivityInfo.qml
+++ b/src/activities/nine_men_morris/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2016 Pulkit Gupta <pulkitnsit@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "nine_men_morris/NineMenMorris.qml"
difficulty: 2
icon: "nine_men_morris/nine_men_morris.svg"
author: "Pulkit Gupta &lt;pulkitnsit@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Nine men's morris (against Tux)")
//: Help title
description: qsTr("Reduce the opponent to two pieces, or by leaving him without a legal move.")
//intro: "Click on the dot where you wish to place your piece and try to take all Tux's pieces."
//: Help goal
goal: qsTr("Form mills (line of 3 pieces) to remove pieces of Tux until Tux has only two pieces, or doesn't have a legal move")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("Play with the computer. First take turns to place nine pieces, and then take turns to move pieces")
credit: ""
section: "strategy"
createdInVersion: 7000
}
diff --git a/src/activities/nine_men_morris/DragPoint.qml b/src/activities/nine_men_morris/DragPoint.qml
index 5d0b05cce..0d8e2657e 100644
--- a/src/activities/nine_men_morris/DragPoint.qml
+++ b/src/activities/nine_men_morris/DragPoint.qml
@@ -1,98 +1,98 @@
/* GCompris - DragPoint.qml
*
* Copyright (C) 2016 Pulkit Gupta <pulkitnsit@gmail.com>
*
* Authors:
* Pulkit Gupta <pulkitnsit@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
import "nine_men_morris.js" as Activity
import GCompris 1.0
Rectangle {
id: dragPoint
width: parent.width / 26
height: width
radius: width / 2
opacity: 1.0
border.color: "#803300"
border.width: state == "EMPTY" ? 0 : width/6
state: "AVAILABLE"
property int index
property bool firstPhase
property bool pieceBeingMoved
property int pieceIndex
property QtObject leftPoint
property QtObject rightPoint
property QtObject upperPoint
property QtObject lowerPoint
states: [
State {
name: "AVAILABLE" // Green color
PropertyChanges {
target: dragPoint
color: "#00ff00"
}
},
State {
name: "UNAVAILABLE"
PropertyChanges {
target: dragPoint
color: "#ff0000"
}
},
State {
name: "EMPTY" // Brown color
PropertyChanges {
target: dragPoint
color: "#803300"
}
},
State {
name: "1"
PropertyChanges {
target: dragPoint
color: "#ff0000"
}
},
State {
name: "2"
PropertyChanges {
target: dragPoint
color: "#ff0000"
}
}
]
MouseArea {
id: area
enabled: parent.state == "AVAILABLE" && !pieceBeingMoved
anchors.centerIn: parent
width: 2.5 * parent.width
height: 2.5 * parent.height
onClicked: {
if (firstPhase)
Activity.handleCreate(index)
else
Activity.movePiece(index)
}
}
}
diff --git a/src/activities/nine_men_morris/NineMenMorris.qml b/src/activities/nine_men_morris/NineMenMorris.qml
index 82311e181..2bae9b376 100644
--- a/src/activities/nine_men_morris/NineMenMorris.qml
+++ b/src/activities/nine_men_morris/NineMenMorris.qml
@@ -1,366 +1,366 @@
/* GCompris - NineMenMorris.qml
*
* Copyright (C) 2016 Pulkit Gupta <pulkitnsit@gmail.com>
*
* Authors:
* Pulkit Gupta <pulkitnsit@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
import "nine_men_morris.js" as Activity
import "."
ActivityBase {
id: activity
property bool twoPlayer: false
onStart: focus = true
onStop: {}
pageComponent: Image {
id: background
anchors.fill: parent
source: Activity.url + "background.svg"
sourceSize.width: Math.max(parent.width, parent.height)
fillMode: Image.PreserveAspectCrop
signal start
signal stop
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property alias dragPointsModel: dragPointsModel
property alias dragPoints: dragPoints
property alias firstInitial: firstInitial
property alias firstPlayerPieces: firstPlayerPieces
property alias firstPlayerPiecesModel: firstPlayerPiecesModel
property alias firstPieceNumberCount: firstPieceNumber.count
property alias player1score: player1score
property alias secondInitial: secondInitial
property alias secondPlayerPieces: secondPlayerPieces
property alias secondPlayerPiecesModel: secondPlayerPiecesModel
property alias secondPieceNumberCount: secondPieceNumber.count
property alias player2score: player2score
property alias trigTuxMove: trigTuxMove
property bool gameDone
property int turn
property bool playSecond
property bool firstPhase
property bool pieceBeingMoved
property alias bar: bar
property alias bonus: bonus
property alias instructionTxt: instruction.text
property alias tutorialSection: tutorialSection
}
onStart: Activity.start(items, twoPlayer)
onStop: Activity.stop()
// Tux move delay
Timer {
id: trigTuxMove
repeat: false
interval: 1500
onTriggered: {
Activity.doMove()
items.player2score.endTurn()
items.player1score.beginTurn()
}
}
Image {
id: board
source: Activity.url + "board.svg"
sourceSize.width: Math.min(background.height - 1.4 * player1score.height - 1.2 * bar.height,
background.width - 2.2 * firstInitial.width)
anchors {
verticalCenter: parent.verticalCenter
horizontalCenter: parent.horizontalCenter
verticalCenterOffset : -0.25 * player1score.height
}
Repeater {
id: dragPoints
model: dragPointsModel
delegate: point
Component {
id: point
DragPoint {
id: dragPoint
x: posX * parent.width - width / 2
y: posY * parent.height - height / 2
index: myIndex
firstPhase: items.firstPhase
pieceBeingMoved: items.pieceBeingMoved
}
}
}
}
ListModel {
id: dragPointsModel
}
Rectangle {
id: firstInitial
anchors {
left: player1score.left
top: player1score.bottom
topMargin: player1score.height * 0.5
}
width: player1score.width * 1.2
height: player1score.height * 1.2
visible: items.firstPhase
opacity: 0.8
radius: 10
border.width: 2
border.color: "black"
gradient: Gradient {
GradientStop { position: 0.0; color: "#6b4723" }
GradientStop { position: 0.9; color: "#996633" }
GradientStop { position: 1.0; color: "#AAA" }
}
Repeater {
id: firstPlayerPieces
model: firstPlayerPiecesModel
delegate: firstPieceInitial
Component {
id: firstPieceInitial
Piece {
id: firstPiece
state: "1"
firstPhase: items.firstPhase
sourceSize.height: Math.min(firstInitial.height * 0.8, firstInitial.width * 0.4)
x: firstInitial.width * 0.06
anchors.verticalCenter: firstInitial.verticalCenter
chance: items.turn % 2
playSecond: items.playSecond
gameDone: items.gameDone
pieceBeingMoved: items.pieceBeingMoved
}
}
}
GCText {
id: firstPieceNumber
anchors {
verticalCenter: parent.verticalCenter
right: parent.right
rightMargin: parent.width * 0.1
}
fontSize: mediumSize
color: "white"
style: Text.Outline
styleColor: "black"
horizontalAlignment: Text.AlignHCenter
property int count: 9
text: "X%1".arg(count)
}
}
ListModel {
id: firstPlayerPiecesModel
}
Rectangle {
id: secondInitial
anchors {
right: player2score.right
top: player2score.bottom
topMargin: player2score.height * 0.5
}
width: firstInitial.width
height: firstInitial.height
visible: items.firstPhase
opacity: 0.8
radius: 10
border.width: 2
border.color: "black"
gradient: Gradient {
GradientStop { position: 0.0; color: "#6b4723" }
GradientStop { position: 0.9; color: "#996633" }
GradientStop { position: 1.0; color: "#AAA" }
}
Repeater {
id: secondPlayerPieces
model: secondPlayerPiecesModel
delegate: secondPieceInitial
Component {
id: secondPieceInitial
Piece {
id: secondPiece
state: "2"
firstPhase: items.firstPhase
sourceSize.height: Math.min(secondInitial.height * 0.8, secondInitial.width * 0.4)
x: secondInitial.width * 0.06
anchors.verticalCenter: secondInitial.verticalCenter
chance: items.turn % 2
playSecond: items.playSecond
gameDone: items.gameDone
pieceBeingMoved: items.pieceBeingMoved
}
}
}
GCText {
id: secondPieceNumber
anchors {
verticalCenter: parent.verticalCenter
right: parent.right
rightMargin: parent.width * 0.1
}
fontSize: mediumSize
color: "white"
style: Text.Outline
styleColor: "black"
horizontalAlignment: Text.AlignHCenter
property int count: 9
text: "X%1".arg(count)
}
}
ListModel {
id: secondPlayerPiecesModel
}
// Instruction section starts
GCText {
id: instruction
anchors {
horizontalCenter: parent.horizontalCenter
top: parent.top
topMargin: 5
}
fontSizeMode: Text.Fit
minimumPixelSize: 10
color: "white"
style: Text.Outline
styleColor: "black"
horizontalAlignment: Text.AlignHLeft
width: implicitWidth
height: implicitHeight
z: 2
}
Rectangle {
id: instructionContainer
anchors.top: instruction.top
anchors.horizontalCenter: parent.horizontalCenter
width: instruction.width + 20
height: instruction.height + 2
opacity: 0.8
radius: 10
border.width: 2
border.color: "black"
gradient: Gradient {
GradientStop { position: 0.0; color: "#000" }
GradientStop { position: 0.9; color: "#666" }
GradientStop { position: 1.0; color: "#AAA" }
}
}
// Instruction section ends
// Player scores section start
ScoreItem {
id: player2score
player: 2
height: Math.min(background.height / 9, Math.min(background.width / 9, bar.height * 1.2))
width: height * 11 / 8
anchors {
top: background.top
topMargin: 5
right: background.right
rightMargin: 5
}
playerImageSource: Activity.url + "TuxBlack.svg"
backgroundImageSource: Activity.url + "score_2.svg"
playerScaleOriginX: player2score.width
}
ScoreItem {
id: player1score
player: 1
height: Math.min(background.height / 9, Math.min(background.width / 9, bar.height * 1.2))
width: height * 11 / 8
anchors {
top: background.top
topMargin: 5
left: background.left
leftMargin: 5
}
playerImageSource: Activity.url + "KonqiWhite.svg"
backgroundImageSource: Activity.url + "score_1.svg"
}
// Player scores section ends
// Tutorial section starts
Image {
id: tutorialImage
source: Activity.url + "background.svg"
anchors.fill: parent
z: 5
visible: twoPlayer ? false : true
Tutorial {
id: tutorialSection
tutorialDetails: Activity.tutorialInstructions
onSkipPressed: {
Activity.initLevel()
tutorialImage.visible = false
}
}
}
// Tutorial section ends
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: twoPlayer ? (help | home | reload)
: tutorialImage.visible ? (help | home)
: (help | home | level | reload) }
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
onReloadClicked: {
Activity.reset()
}
}
Bonus {
id: bonus
}
}
}
diff --git a/src/activities/nine_men_morris/Piece.qml b/src/activities/nine_men_morris/Piece.qml
index 2ea7fb8ec..7376736ec 100644
--- a/src/activities/nine_men_morris/Piece.qml
+++ b/src/activities/nine_men_morris/Piece.qml
@@ -1,150 +1,150 @@
/* GCompris - Piece.qml
*
* Copyright (C) 2016 Pulkit Gupta <pulkitnsit@gmail.com>
*
* Authors:
* Pulkit Gupta <pulkitnsit@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
import "nine_men_morris.js" as Activity
import GCompris 1.0
Image {
id: piece
property QtObject pieceParent
property double moveX
property double moveY
property int parentIndex: -1
property bool canBeRemoved: false
property bool firstPhase
property bool isSelected: false
property bool playSecond
property bool gameDone
property bool pieceBeingMoved
property int chance
opacity: 1.0
ParallelAnimation {
id: pieceAnimation
NumberAnimation {
target: piece
easing.type: Easing.OutQuad
property: "x"
to: moveX
duration: 430
}
NumberAnimation {
target: piece
easing.type: Easing.OutQuad
property: "y"
to: moveY
duration: 430
}
onStarted: {
piece.anchors.verticalCenter = undefined
piece.anchors.centerIn = undefined
}
onStopped: {
piece.parent = pieceParent
piece.anchors.centerIn = pieceParent
piece.parent.state = piece.state
piece.parent.pieceIndex = index
if (Activity.checkMill(piece.parentIndex,piece.state))
Activity.updateRemovablePiece()
else if (firstPhase)
Activity.continueGame()
else
Activity.checkGameWon()
}
}
NumberAnimation {
id: removePieceAnimation
target: piece
property: "opacity"
to: 0
duration: 430
onStarted: { Activity.removePieceSelected(index) }
onStopped: { Activity.removePiece(index) }
}
states: [
State {
name: "1" // Player 1
PropertyChanges {
target: piece
source: playSecond ? Activity.url + "black_piece.svg" : Activity.url + "white_piece.svg"
}
},
State {
name: "2" // Player 2
PropertyChanges {
target: piece
source: playSecond ? Activity.url + "white_piece.svg" : Activity.url + "black_piece.svg"
}
}
]
MouseArea {
id: area
property bool turn: chance ? piece.state == "2" : piece.state == "1"
enabled: ((canBeRemoved && !turn) || (!firstPhase && turn)) &&
(piece.parentIndex != -1) && !gameDone && (!pieceBeingMoved || canBeRemoved)
anchors.centerIn: parent
width: parent.width
height: parent.height
onClicked: {
if (canBeRemoved)
removePieceAnimation.start()
else {
isSelected = true
Activity.pieceSelected(index);
}
}
}
Rectangle {
id: boundary
anchors.centerIn: piece
width: piece.width
height: width
visible: ((piece.visible && area.enabled && firstPhase) || isSelected) || canBeRemoved
opacity: 1
radius: width / 2
border.width: width / 10
border.color: canBeRemoved ? "red" : "green"
color: "transparent"
z: -1
}
function move(pieceChangeParent) {
piece.pieceParent = pieceChangeParent
piece.parentIndex = pieceChangeParent.index
piece.sourceSize.height = Qt.binding(function() { return pieceParent.width * 2.5 })
var coord = piece.parent.mapFromItem(pieceChangeParent.parent, pieceChangeParent.x + pieceChangeParent.width / 2 -
piece.width / 2, pieceChangeParent.y + pieceChangeParent.height / 2 - piece.height / 2)
piece.moveX = coord.x
piece.moveY = coord.y
pieceAnimation.start()
}
function remove() {
removePieceAnimation.start()
}
}
diff --git a/src/activities/nine_men_morris/nine_men_morris.js b/src/activities/nine_men_morris/nine_men_morris.js
index 4e59511b6..4bf007cde 100644
--- a/src/activities/nine_men_morris/nine_men_morris.js
+++ b/src/activities/nine_men_morris/nine_men_morris.js
@@ -1,1720 +1,1720 @@
/* GCompris - nine_men_morris.js
*
* Copyright (C) 2016 Pulkit Gupta <pulkitnsit@gmail.com>
*
* Authors:
* Pulkit Gupta <pulkitnsit@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
var currentLevel = 0
var numberOfLevel = 5
var items
var url = "qrc:/gcompris/src/activities/nine_men_morris/resource/"
var currentPiece
var twoPlayer
var stopper //For stopping game when doing reset
var currentRepeater
var otherRepeater
var numberOfFirstPieces
var numberOfSecondPieces
var numberOfPieces
var numberOfDragPoints
var depthMax
var tutorialInstructions = [
{
"instruction": qsTr("You and Tux start with 9 pieces each, and take turns to place your pieces on to the empty spots (by clicking on the spots) on the board."),
"instructionImage" : "qrc:/gcompris/src/activities/nine_men_morris/resource/tutorial1.svg"
},
{
"instruction": qsTr("If you form a mill (line of 3 pieces), then select a piece of Tux, and remove it. Pieces of formed mill can not be removed unless no other pieces are left on board."),
"instructionImage": "qrc:/gcompris/src/activities/nine_men_morris/resource/tutorial2.svg"
},
{
"instruction": qsTr("After all the pieces are placed, you and Tux will take turns to move them. Click on one of your pieces, and then on the adjacent empty spot to move it there. Green color spot indicates where you can move."),
"instructionImage": "qrc:/gcompris/src/activities/nine_men_morris/resource/tutorial3.svg"
},
{
"instruction": qsTr("If you are left with 3 pieces, your pieces will gain the ability to 'fly' and can be moved to any vacant spot on the board."),
"instructionImage": "qrc:/gcompris/src/activities/nine_men_morris/resource/tutorial4.svg"
},
{
"instruction": qsTr("If you immobilize the computer or leave it with less than 3 pieces, then you win the game."),
"instructionImage": "qrc:/gcompris/src/activities/nine_men_morris/resource/tutorial5.svg"
}
]
function start(items_, twoPlayer_) {
items = items_
currentLevel = 1
twoPlayer = twoPlayer_
numberOfLevel = 6
numberOfPieces = 9
numberOfDragPoints = 24
items.playSecond = false
// Creating drag points
items.dragPointsModel.append({
"posX": 0.05,
"posY": 0.948,
"myIndex": 0
})
items.dragPointsModel.append({
"posX": 0.500,
"posY": 0.948,
"myIndex": 1
})
items.dragPointsModel.append({
"posX": 0.95,
"posY": 0.948,
"myIndex": 2
})
items.dragPointsModel.append({
"posX": 0.19,
"posY": 0.814,
"myIndex": 3
})
items.dragPointsModel.append({
"posX": 0.500,
"posY": 0.814,
"myIndex": 4
})
items.dragPointsModel.append({
"posX": 0.81,
"posY": 0.814,
"myIndex": 5
})
items.dragPointsModel.append({
"posX": 0.313,
"posY": 0.687,
"myIndex": 6
})
items.dragPointsModel.append({
"posX": 0.500,
"posY": 0.687,
"myIndex": 7
})
items.dragPointsModel.append({
"posX": 0.689,
"posY": 0.687,
"myIndex": 8
})
items.dragPointsModel.append({
"posX": 0.05,
"posY": 0.499,
"myIndex": 9
})
items.dragPointsModel.append({
"posX": 0.19,
"posY": 0.499,
"myIndex": 10
})
items.dragPointsModel.append({
"posX": 0.313,
"posY": 0.499,
"myIndex": 11
})
items.dragPointsModel.append({
"posX": 0.689,
"posY": 0.499,
"myIndex": 12
})
items.dragPointsModel.append({
"posX": 0.81,
"posY": 0.499,
"myIndex": 13
})
items.dragPointsModel.append({
"posX": 0.95,
"posY": 0.499,
"myIndex": 14
})
items.dragPointsModel.append({
"posX": 0.313,
"posY": 0.311,
"myIndex": 15
})
items.dragPointsModel.append({
"posX": 0.500,
"posY": 0.311,
"myIndex": 16
})
items.dragPointsModel.append({
"posX": 0.689,
"posY": 0.311,
"myIndex": 17
})
items.dragPointsModel.append({
"posX": 0.19,
"posY": 0.188,
"myIndex": 18
})
items.dragPointsModel.append({
"posX": 0.500,
"posY": 0.188,
"myIndex": 19
})
items.dragPointsModel.append({
"posX": 0.81,
"posY": 0.188,
"myIndex": 20
})
items.dragPointsModel.append({
"posX": 0.05,
"posY": 0.054,
"myIndex": 21
})
items.dragPointsModel.append({
"posX": 0.500,
"posY": 0.054,
"myIndex": 22
})
items.dragPointsModel.append({
"posX": 0.95,
"posY": 0.054,
"myIndex": 23
})
// For assigning left and right point
for (var i = 0 ; i < numberOfDragPoints ; i++) {
if(i % 3)
items.dragPoints.itemAt(i).leftPoint = items.dragPoints.itemAt(i - 1)
else
items.dragPoints.itemAt(i).leftPoint = null
if((i + 1) % 3)
items.dragPoints.itemAt(i).rightPoint = items.dragPoints.itemAt(i + 1)
else
items.dragPoints.itemAt(i).rightPoint = null
}
// Start assigning upper and lower point
items.dragPoints.itemAt(0).upperPoint = items.dragPoints.itemAt(9)
items.dragPoints.itemAt(0).lowerPoint = null
items.dragPoints.itemAt(1).upperPoint = items.dragPoints.itemAt(4)
items.dragPoints.itemAt(1).lowerPoint = null
items.dragPoints.itemAt(2).upperPoint = items.dragPoints.itemAt(14)
items.dragPoints.itemAt(2).lowerPoint = null
items.dragPoints.itemAt(3).upperPoint = items.dragPoints.itemAt(10)
items.dragPoints.itemAt(3).lowerPoint = null
items.dragPoints.itemAt(4).upperPoint = items.dragPoints.itemAt(7)
items.dragPoints.itemAt(4).lowerPoint = items.dragPoints.itemAt(1)
items.dragPoints.itemAt(5).upperPoint = items.dragPoints.itemAt(13)
items.dragPoints.itemAt(5).lowerPoint = null
items.dragPoints.itemAt(6).upperPoint = items.dragPoints.itemAt(11)
items.dragPoints.itemAt(6).lowerPoint = null
items.dragPoints.itemAt(7).upperPoint = null
items.dragPoints.itemAt(7).lowerPoint = items.dragPoints.itemAt(4)
items.dragPoints.itemAt(8).upperPoint = items.dragPoints.itemAt(12)
items.dragPoints.itemAt(8).lowerPoint = null
items.dragPoints.itemAt(9).upperPoint = items.dragPoints.itemAt(21)
items.dragPoints.itemAt(9).lowerPoint = items.dragPoints.itemAt(0)
items.dragPoints.itemAt(10).upperPoint = items.dragPoints.itemAt(18)
items.dragPoints.itemAt(10).lowerPoint = items.dragPoints.itemAt(3)
items.dragPoints.itemAt(11).upperPoint = items.dragPoints.itemAt(15)
items.dragPoints.itemAt(11).lowerPoint = items.dragPoints.itemAt(6)
items.dragPoints.itemAt(12).upperPoint = items.dragPoints.itemAt(17)
items.dragPoints.itemAt(12).lowerPoint = items.dragPoints.itemAt(8)
items.dragPoints.itemAt(13).upperPoint = items.dragPoints.itemAt(20)
items.dragPoints.itemAt(13).lowerPoint = items.dragPoints.itemAt(5)
items.dragPoints.itemAt(14).upperPoint = items.dragPoints.itemAt(23)
items.dragPoints.itemAt(14).lowerPoint = items.dragPoints.itemAt(2)
items.dragPoints.itemAt(15).upperPoint = null
items.dragPoints.itemAt(15).lowerPoint = items.dragPoints.itemAt(11)
items.dragPoints.itemAt(16).upperPoint = items.dragPoints.itemAt(19)
items.dragPoints.itemAt(16).lowerPoint = null
items.dragPoints.itemAt(17).upperPoint = null
items.dragPoints.itemAt(17).lowerPoint = items.dragPoints.itemAt(12)
items.dragPoints.itemAt(18).upperPoint = null
items.dragPoints.itemAt(18).lowerPoint = items.dragPoints.itemAt(10)
items.dragPoints.itemAt(19).upperPoint = items.dragPoints.itemAt(22)
items.dragPoints.itemAt(19).lowerPoint = items.dragPoints.itemAt(16)
items.dragPoints.itemAt(20).upperPoint = null
items.dragPoints.itemAt(20).lowerPoint = items.dragPoints.itemAt(13)
items.dragPoints.itemAt(21).upperPoint = null
items.dragPoints.itemAt(21).lowerPoint = items.dragPoints.itemAt(9)
items.dragPoints.itemAt(22).upperPoint = null
items.dragPoints.itemAt(22).lowerPoint = items.dragPoints.itemAt(19)
items.dragPoints.itemAt(23).upperPoint = null
items.dragPoints.itemAt(23).lowerPoint = items.dragPoints.itemAt(14)
// End assigning upper and lower piece
if(twoPlayer) {
items.tutorialSection.visible = false
initLevel()
}
}
function stop() {
}
function initLevel() {
items.bar.level = currentLevel
items.turn = 0
items.gameDone = false
items.firstPhase = true
items.pieceBeingMoved = false
numberOfFirstPieces = 0
numberOfSecondPieces = 0
items.firstPieceNumberCount = numberOfPieces
items.secondPieceNumberCount = numberOfPieces
items.instructionTxt = qsTr("Place a piece")
depthMax = 2
// Clear first and second player pieces, and initialize dragPoints
items.firstPlayerPieces.model.clear()
items.secondPlayerPieces.model.clear()
for (var i = 0 ; i < numberOfDragPoints ; ++i)
items.dragPoints.itemAt(i).state = "AVAILABLE"
// Create first and second player pieces
for (var i = 0 ; i < numberOfPieces ; ++i) {
items.firstPlayerPiecesModel.append({})
items.secondPlayerPiecesModel.append({})
}
currentRepeater = items.firstPlayerPieces
otherRepeater = items.secondPlayerPieces
stopper = false
if(items.playSecond) {
initiatePlayer2()
if(!twoPlayer) {
var rand = Math.floor((Math.random() * numberOfDragPoints))
handleCreate(rand)
}
}
else
initiatePlayer1()
}
function nextLevel() {
if(numberOfLevel <= ++currentLevel) {
currentLevel = 1
}
reset();
}
function previousLevel() {
if(--currentLevel < 1) {
currentLevel = numberOfLevel - 1
}
reset();
}
function reset() {
items.trigTuxMove.stop();
stopper = true;
shouldComputerPlay();
items.player2score.endTurn();
items.player1score.beginTurn();
items.playSecond = !items.playSecond
initLevel()
}
//Initial values at the start of game when its player 1 turn
function initiatePlayer1() {
items.player2score.endTurn();
items.player1score.beginTurn();
items.firstInitial.anchors.right = undefined
items.firstInitial.anchors.top = items.player1score.bottom
items.firstInitial.anchors.left = items.player1score.left
items.secondInitial.anchors.left = undefined
items.secondInitial.anchors.right = items.player2score.right
items.secondInitial.anchors.top = items.player2score.bottom
}
//Initial values at the start of game when its player 1 turn
function initiatePlayer2() {
items.player1score.endTurn();
items.player2score.beginTurn();
items.secondInitial.anchors.right = undefined
items.secondInitial.anchors.top = items.player1score.bottom
items.secondInitial.anchors.left = items.player1score.left
items.firstInitial.anchors.left = undefined
items.firstInitial.anchors.right = items.player2score.right
items.firstInitial.anchors.top = items.player2score.bottom
}
//Change scale of score boxes according to turns
function changeScale() {
if(items.playSecond) {
if(items.turn % 2 == 0){
items.player2score.beginTurn();
items.player1score.endTurn();
}
else {
items.player1score.beginTurn();
items.player2score.endTurn();
}
}
else {
if(items.turn % 2 == 0) {
items.player1score.beginTurn();
items.player2score.endTurn();
}
else {
items.player2score.beginTurn();
items.player1score.endTurn();
}
}
}
//Create the piece at given position
function handleCreate(index) {
items.pieceBeingMoved = true
currentPiece = currentRepeater.itemAt(items.turn/2)
if(currentPiece.state == "2") {
items.secondPieceNumberCount--
numberOfSecondPieces++
}
else {
items.firstPieceNumberCount--
numberOfFirstPieces++
}
currentPiece.move(items.dragPoints.itemAt(index))
}
function secondPhase() {
items.firstPhase = false
for (var i = 0 ; i < numberOfDragPoints ; ++i) {
if(items.dragPoints.itemAt(i).state != "1" && items.dragPoints.itemAt(i).state != "2")
items.dragPoints.itemAt(i).state = "EMPTY"
}
items.instructionTxt = qsTr("Move a piece")
}
function pieceSelected(pieceIndex) {
currentPiece.isSelected = false
currentPiece = currentRepeater.itemAt(pieceIndex)
currentPiece.isSelected = true
if((currentPiece.state == "1" && numberOfFirstPieces > 3) ||
(currentPiece.state == "2" && numberOfSecondPieces > 3)) {
for (var i = 0 ; i < numberOfDragPoints ; ++i) {
if(items.dragPoints.itemAt(i).state == "EMPTY" || items.dragPoints.itemAt(i).state == "AVAILABLE")
items.dragPoints.itemAt(i).state = "UNAVAILABLE"
}
// Now assign values
var index = currentRepeater.itemAt(pieceIndex).parentIndex // Drag Point index
var dragPoint = items.dragPoints.itemAt(index)
if(dragPoint.leftPoint) {
if(dragPoint.leftPoint.state == "UNAVAILABLE")
dragPoint.leftPoint.state = "AVAILABLE"
}
if(dragPoint.upperPoint) {
if(dragPoint.upperPoint.state == "UNAVAILABLE")
dragPoint.upperPoint.state = "AVAILABLE"
}
if(dragPoint.rightPoint) {
if(dragPoint.rightPoint.state == "UNAVAILABLE")
dragPoint.rightPoint.state = "AVAILABLE"
}
if(dragPoint.lowerPoint) {
if(dragPoint.lowerPoint.state == "UNAVAILABLE")
dragPoint.lowerPoint.state = "AVAILABLE"
}
}
else {
for (var i = 0 ; i < numberOfDragPoints ; ++i) {
if(items.dragPoints.itemAt(i).state == "EMPTY" || items.dragPoints.itemAt(i).state == "UNAVAILABLE")
items.dragPoints.itemAt(i).state = "AVAILABLE"
}
}
}
function movePiece(index) {
items.pieceBeingMoved = true
currentPiece.parent.state = "EMPTY"
currentPiece.isSelected = false
for (var i = 0 ; i < numberOfDragPoints ; ++i) {
if(items.dragPoints.itemAt(i).state != "1" && items.dragPoints.itemAt(i).state != "2")
items.dragPoints.itemAt(i).state = "EMPTY"
}
currentPiece.move(items.dragPoints.itemAt(index))
}
function shouldComputerPlay() {
if(!twoPlayer) {
if(items.turn % 2 && items.playSecond == false && stopper == false) {
items.trigTuxMove.start()
}
else if((items.turn % 2 == 0) && items.playSecond && stopper == false) {
items.trigTuxMove.start()
}
else
items.pieceBeingMoved = false
}
else
items.pieceBeingMoved = false
}
function doMove() {
if(items.firstPhase) {
if(currentLevel < 5)
var index = setFirstPhaseMove()
else {
var boardPiecesLeft = items.firstPieceNumberCount + items.secondPieceNumberCount
var board = getBoard()
var index = alphabeta(depthMax, -9000, 9000, 2, board, boardPiecesLeft, false)
}
handleCreate(index)
}
else if(currentLevel < 5 && ((currentPiece.state == "2" && numberOfFirstPieces > 3) ||
(currentPiece.state == "1" && numberOfSecondPieces > 3))) {
var index = setSecondPhaseMove()
currentPiece = currentRepeater.itemAt(index[0])
movePiece(index[1])
}
else if(currentLevel < 5){
var index = setThirdPhaseMove()
currentPiece = currentRepeater.itemAt(index[0])
movePiece(index[1])
}
else {
var noOfPlayerPieces = items.playSecond ? numberOfSecondPieces : numberOfFirstPieces
var noOfComputerPieces = items.playSecond ? numberOfFirstPieces : numberOfSecondPieces
var board = getBoard()
var index = alphabeta(depthMax, -9000, 9000, 2, board, 0, false)
currentPiece = currentRepeater.itemAt(items.dragPoints.itemAt(index[0]).pieceIndex)
movePiece(index[1])
}
}
function setFirstPhaseMove() {
//Assigning States -> State "1" or "2" is used for identifying player and computer
var playerState = items.playSecond ? "2" : "1"
var computerState = items.playSecond ? "1" : "2"
if(currentLevel > 1) {
var value = evaluateBoard(computerState)
if(value != -1)
return value
}
if(currentLevel > 2) {
var value = evaluateBoard(playerState)
if(value != -1)
return value
}
var found = false
while (!found) {
var randno = Math.floor((Math.random() * numberOfDragPoints))
if(items.dragPoints.itemAt(randno).state == "EMPTY" || items.dragPoints.itemAt(randno).state == "AVAILABLE")
found = true
}
return randno
}
function evaluateBoard(state) {
for(var i = 0 ; i < numberOfDragPoints ; ++i) {
if(items.dragPoints.itemAt(i).state == "EMPTY" || items.dragPoints.itemAt(i).state == "AVAILABLE") {
if(checkMill(i,state))
return i
}
}
return -1
}
function setSecondPhaseMove() {
var index = []
var found = false
if(currentLevel > 1) {
for(var i = 0 ; i < numberOfPieces ; ++i) {
var piece = currentRepeater.itemAt(i)
if(piece.visible) {
index[0] = i
if(piece.pieceParent.leftPoint && piece.pieceParent.leftPoint.state == "EMPTY") {
if(checkMill(piece.pieceParent.leftPoint.index, piece.state, "left")) {
index[1] = piece.pieceParent.leftPoint.index
found = true
break
}
}
if(piece.pieceParent.rightPoint && piece.pieceParent.rightPoint.state == "EMPTY") {
if(checkMill(piece.pieceParent.rightPoint.index, piece.state, "right")) {
index[1] = piece.pieceParent.rightPoint.index
found = true
break
}
}
if(piece.pieceParent.upperPoint && piece.pieceParent.upperPoint.state == "EMPTY") {
if(checkMill(piece.pieceParent.upperPoint.index, piece.state, "upper")) {
index[1] = piece.pieceParent.upperPoint.index
found = true
break
}
}
if(piece.pieceParent.lowerPoint && piece.pieceParent.lowerPoint.state == "EMPTY") {
if(checkMill(piece.pieceParent.lowerPoint.index, piece.state, "lower")) {
index[1] = piece.pieceParent.lowerPoint.index
found = true
break
}
}
}
}
if(found)
return index
}
var playerState = items.playSecond ? "2" : "1"
if(currentLevel > 2) {
for(var i = 0 ; i < numberOfPieces ; ++i) {
var piece = currentRepeater.itemAt(i)
if(piece.visible) {
index[0] = i
if(piece.pieceParent.leftPoint && piece.pieceParent.leftPoint.state == "EMPTY") {
if(checkMillPossible(piece.pieceParent.leftPoint.index, playerState)) {
index[1] = piece.pieceParent.leftPoint.index
found = true
break
}
}
if(piece.pieceParent.rightPoint && piece.pieceParent.rightPoint.state == "EMPTY") {
if(checkMillPossible(piece.pieceParent.rightPoint.index, playerState)) {
index[1] = piece.pieceParent.rightPoint.index
found = true
break
}
}
if(piece.pieceParent.upperPoint && piece.pieceParent.upperPoint.state == "EMPTY") {
if(checkMillPossible(piece.pieceParent.upperPoint.index, playerState)) {
index[1] = piece.pieceParent.upperPoint.index
found = true
break
}
}
if(piece.pieceParent.lowerPoint && piece.pieceParent.lowerPoint.state == "EMPTY") {
if(checkMillPossible(piece.pieceParent.lowerPoint.index, playerState)) {
index[1] = piece.pieceParent.lowerPoint.index
found = true
break
}
}
}
}
if(found)
return index
}
var permittedPieceIndex = []
for(var i = 0 ; i < numberOfPieces ; ++i) {
if(currentRepeater.itemAt(i).visible) {
if(!checkMill(currentRepeater.itemAt(i).pieceParent.index, playerState))
permittedPieceIndex.push(i)
}
}
if(!permittedPieceIndex.length) {
for(var i = 0 ; i < numberOfPieces ; ++i) {
if(currentRepeater.itemAt(i).visible)
permittedPieceIndex.push(i)
}
}
var found = false
while (!found) {
var randno = Math.floor((Math.random() * permittedPieceIndex.length))
index[0] = permittedPieceIndex[randno]
var permittedPointIndex = []
var dragPoint = currentRepeater.itemAt(index[0]).pieceParent
if(dragPoint.leftPoint && dragPoint.leftPoint.state == "EMPTY") {
permittedPointIndex.push(dragPoint.leftPoint.index)
}
if(dragPoint.rightPoint && dragPoint.rightPoint.state == "EMPTY") {
permittedPointIndex.push(dragPoint.rightPoint.index)
}
if(dragPoint.upperPoint && dragPoint.upperPoint.state == "EMPTY") {
permittedPointIndex.push(dragPoint.upperPoint.index)
}
if(dragPoint.lowerPoint && dragPoint.lowerPoint.state == "EMPTY") {
permittedPointIndex.push(dragPoint.lowerPoint.index)
}
if(permittedPointIndex.length) {
var randNo = Math.floor((Math.random() * permittedPointIndex.length))
index[1] = permittedPointIndex[randNo]
found = true
}
}
return index
}
function checkMillPossible(index, state) {
// thirdPhase is true if opponent can move its piece anywhere
var thirdPhase = (items.playSecond && numberOfSecondPieces < 4) || (!items.playSecond && numberOfFirstPieces < 4)
var dragPoint = items.dragPoints.itemAt(index)
if(dragPoint.leftPoint && dragPoint.leftPoint.leftPoint) {
if(state == dragPoint.leftPoint.state && state == dragPoint.leftPoint.leftPoint.state) {
if((dragPoint.upperPoint && state == dragPoint.upperPoint.state) ||
(dragPoint.lowerPoint && state == dragPoint.lowerPoint.state) || thirdPhase)
return true
}
}
if(dragPoint.upperPoint && dragPoint.upperPoint.upperPoint) {
if(state == dragPoint.upperPoint.state && state == dragPoint.upperPoint.upperPoint.state) {
if((dragPoint.leftPoint && state == dragPoint.leftPoint.state) ||
(dragPoint.rightPoint && state == dragPoint.rightPoint.state) || thirdPhase)
return true
}
}
if(dragPoint.rightPoint && dragPoint.rightPoint.rightPoint) {
if(state == dragPoint.rightPoint.state && state == dragPoint.rightPoint.rightPoint.state) {
if((dragPoint.upperPoint && state == dragPoint.upperPoint.state) ||
(dragPoint.lowerPoint && state == dragPoint.lowerPoint.state) || thirdPhase)
return true
}
}
if(dragPoint.lowerPoint && dragPoint.lowerPoint.lowerPoint) {
if(state == dragPoint.lowerPoint.state && state == dragPoint.lowerPoint.lowerPoint.state) {
if((dragPoint.leftPoint && state == dragPoint.leftPoint.state) ||
(dragPoint.rightPoint && state == dragPoint.rightPoint.state) || thirdPhase)
return true
}
}
if(dragPoint.lowerPoint && dragPoint.upperPoint) {
if(state == dragPoint.lowerPoint.state && state == dragPoint.upperPoint.state) {
if((dragPoint.leftPoint && state == dragPoint.leftPoint.state) ||
(dragPoint.rightPoint && state == dragPoint.rightPoint.state) || thirdPhase)
return true;
}
}
if(dragPoint.leftPoint && dragPoint.rightPoint) {
if(state == dragPoint.leftPoint.state && state == dragPoint.rightPoint.state) {
if((dragPoint.upperPoint && state == dragPoint.upperPoint.state) ||
(dragPoint.lowerPoint && state == dragPoint.lowerPoint.state) || thirdPhase)
return true;
}
}
}
function setThirdPhaseMove() {
//Assigning States -> State "1" or "2" is used for identifying player and computer
var playerState = items.playSecond ? "2" : "1"
var computerState = items.playSecond ? "1" : "2"
var index = []
if(currentLevel > 2) {
for(var i = 0 ; i < numberOfDragPoints ; ++i) {
if(items.dragPoints.itemAt(i).state == "EMPTY") {
var value = checkMillThirdPhase(i, computerState)
if(value != -1) {
index[0] = value
index[1] = i
return index
}
}
}
}
var permittedPieceIndex = []
for(var i = 0 ; i < numberOfPieces ; ++i) {
if(currentRepeater.itemAt(i).visible) {
if(!checkMillPossible(currentRepeater.itemAt(i).pieceParent.index, playerState)) {
permittedPieceIndex.push(i)
}
}
}
if(!permittedPieceIndex.length) {
for(var i = 0 ; i < numberOfPieces ; ++i) {
if(currentRepeater.itemAt(i).visible)
permittedPieceIndex.push(i)
}
}
var randno = Math.floor((Math.random() * permittedPieceIndex.length))
index[0] = permittedPieceIndex[randno]
if(currentLevel > 3) {
for(var i = 0 ; i < numberOfDragPoints ; ++i) {
if(items.dragPoints.itemAt(i).state == "EMPTY") {
if(checkMillPossible(i,playerState)) {
index[1] = i
return index
}
}
}
}
for(var i = 0 ; i < numberOfDragPoints ; ++i) {
var dragPoint = items.dragPoints.itemAt(i)
if(dragPoint.state == "EMPTY" &&
((dragPoint.leftPoint && dragPoint.leftPoint.state == computerState
&& dragPoint.leftPoint.pieceIndex != index[0]) ||
(dragPoint.rightPoint && dragPoint.rightPoint.state == computerState
&& dragPoint.rightPoint.pieceIndex != index[0]) ||
(dragPoint.upperPoint && dragPoint.upperPoint.state == computerState
&& dragPoint.upperPoint.pieceIndex != index[0]) ||
(dragPoint.lowerPoint && dragPoint.lowerPoint.state == computerState
&& dragPoint.lowerPoint.pieceIndex != index[0]))) {
index[1] = i
return index
}
}
var permittedPointIndex = []
for(var i = 0 ; i < numberOfDragPoints ; ++i) {
if(items.dragPoints.itemAt(i).state == "EMPTY")
permittedPointIndex.push(i)
}
randno = Math.floor((Math.random() * permittedPointIndex.length))
index[1] = permittedPointIndex[randno]
return index
}
function checkMillThirdPhase(index, state) {
var dragPoint = items.dragPoints.itemAt(index)
if(dragPoint.leftPoint && dragPoint.leftPoint.leftPoint) {
if(state == dragPoint.leftPoint.state && state == dragPoint.leftPoint.leftPoint.state) {
for(var i = 0 ; i < numberOfPieces ; ++i) {
if(currentRepeater.itemAt(i).visible && i != dragPoint.leftPoint.pieceIndex
&& i != dragPoint.leftPoint.leftPoint.pieceIndex) {
return i
}
}
}
}
if(dragPoint.upperPoint && dragPoint.upperPoint.upperPoint) {
if(state == dragPoint.upperPoint.state && state == dragPoint.upperPoint.upperPoint.state) {
for(var i = 0 ; i < numberOfPieces ; ++i) {
if(currentRepeater.itemAt(i).visible && i != dragPoint.upperPoint.pieceIndex
&& i != dragPoint.upperPoint.upperPoint.pieceIndex) {
return i
}
}
}
}
if(dragPoint.rightPoint && dragPoint.rightPoint.rightPoint) {
if(state == dragPoint.rightPoint.state && state == dragPoint.rightPoint.rightPoint.state) {
for(var i = 0 ; i < numberOfPieces ; ++i) {
if(currentRepeater.itemAt(i).visible && i != dragPoint.rightPoint.pieceIndex
&& i != dragPoint.rightPoint.rightPoint.pieceIndex) {
return i
}
}
}
}
if(dragPoint.lowerPoint && dragPoint.lowerPoint.lowerPoint) {
if(state == dragPoint.lowerPoint.state && state == dragPoint.lowerPoint.lowerPoint.state) {
for(var i = 0 ; i < numberOfPieces ; ++i) {
if(currentRepeater.itemAt(i).visible && i != dragPoint.lowerPoint.pieceIndex
&& i != dragPoint.lowerPoint.lowerPoint.pieceIndex) {
return i
}
}
}
}
if(dragPoint.lowerPoint && dragPoint.upperPoint) {
if(state == dragPoint.lowerPoint.state && state == dragPoint.upperPoint.state) {
for(var i = 0 ; i < numberOfPieces ; ++i) {
if(currentRepeater.itemAt(i).visible && i != dragPoint.lowerPoint.pieceIndex
&& i != dragPoint.upperPoint.pieceIndex) {
return i
}
}
}
}
if(dragPoint.leftPoint && dragPoint.rightPoint) {
if(state == dragPoint.leftPoint.state && state == dragPoint.rightPoint.state) {
for(var i = 0 ; i < numberOfPieces ; ++i) {
if(currentRepeater.itemAt(i).visible && i != dragPoint.leftPoint.pieceIndex
&& i != dragPoint.rightPoint.pieceIndex) {
return i
}
}
}
}
return -1
}
// continueGame() called by Piece when its animation stops and checkMill(piece) is false or
// called after removePiece(index) has removed a piece
function continueGame() {
items.turn ++
if(items.turn == (2 * numberOfPieces) && items.firstPhase) {
secondPhase()
items.turn --
checkGameWon()
return
}
if(items.turn % 2) {
currentRepeater = items.secondPlayerPieces
otherRepeater = items.firstPlayerPieces
}
else {
currentRepeater = items.firstPlayerPieces
otherRepeater = items.secondPlayerPieces
}
changeScale()
shouldComputerPlay();
}
// position value is only used when checkMill is called by setSecondPhaseMove or getSecondPhaseRemoveIndex function
// Else it is declared as undefined by default
function checkMill(index, state, position) {
var dragPoint = items.dragPoints.itemAt(index)
if(dragPoint.leftPoint && dragPoint.leftPoint.leftPoint && position != "left" && position != "right") {
if(state == dragPoint.leftPoint.state && state == dragPoint.leftPoint.leftPoint.state)
return true;
}
if(dragPoint.upperPoint && dragPoint.upperPoint.upperPoint && position != "upper" && position != "lower") {
if(state == dragPoint.upperPoint.state && state == dragPoint.upperPoint.upperPoint.state)
return true;
}
if(dragPoint.rightPoint && dragPoint.rightPoint.rightPoint && position != "right" && position != "left") {
if(state == dragPoint.rightPoint.state && state == dragPoint.rightPoint.rightPoint.state)
return true;
}
if(dragPoint.lowerPoint && dragPoint.lowerPoint.lowerPoint && position != "lower" && position != "upper") {
if(state == dragPoint.lowerPoint.state && state == dragPoint.lowerPoint.lowerPoint.state)
return true;
}
if(dragPoint.lowerPoint && dragPoint.upperPoint && position != "lower" && position != "upper") {
if(state == dragPoint.lowerPoint.state && state == dragPoint.upperPoint.state)
return true;
}
if(dragPoint.leftPoint && dragPoint.rightPoint && position != "left" && position != "right") {
if(state == dragPoint.leftPoint.state && state == dragPoint.rightPoint.state)
return true;
}
}
// updateRemovablePiece called by Piece when its animation stops and checkMill(piece) is true
function updateRemovablePiece() {
if(twoPlayer || ((items.turn % 2) && items.playSecond) || (!(items.turn % 2) && !items.playSecond)) {
var foundOne = false
for(var i = 0 ; i < numberOfPieces ; ++i) {
var piece = otherRepeater.itemAt(i)
if(piece.parentIndex != -1) {
if(!checkMill(piece.parentIndex, piece.state) && piece.visible) {
foundOne = true
piece.canBeRemoved = true // Mark pieces of other player for removal
}
}
}
if(!foundOne) {
for(var i = 0 ; i < numberOfPieces ; ++i) {
if(otherRepeater.itemAt(i).parentIndex != -1 && otherRepeater.itemAt(i).visible)
otherRepeater.itemAt(i).canBeRemoved = true
}
}
items.instructionTxt = qsTr("Remove a piece")
}
else if(currentLevel < 5) {
if(items.firstPhase)
otherRepeater.itemAt(getFirstPhaseRemoveIndex()).remove()
else
otherRepeater.itemAt(getSecondPhaseRemoveIndex()).remove()
}
else {
var board = getBoard()
var boardPiecesLeft = items.firstPieceNumberCount + items.secondPieceNumberCount
var index = alphabeta(depthMax, -9000, 9000, 2, board, boardPiecesLeft, true)
var pieceIndex = items.dragPoints.itemAt(index).pieceIndex
otherRepeater.itemAt(pieceIndex).remove()
}
}
function getFirstPhaseRemoveIndex() {
var playerState = items.playSecond ? "2" : "1"
var permittedIndex = [];
for(var i = 0 ; i < numberOfPieces ; ++i) {
var piece = otherRepeater.itemAt(i)
if(piece.parentIndex != -1) {
if(!checkMill(piece.parentIndex, piece.state) && piece.visible)
permittedIndex.push(i)
}
}
if(permittedIndex.length == 0) {
for(var i = 0 ; i < numberOfPieces ; ++i) {
if((otherRepeater.itemAt(i).parentIndex != -1) && (otherRepeater.itemAt(i).visible))
permittedIndex.push(i)
}
}
if(currentLevel > 4) {
var index = evaluateBoard(playerState)
if(index != -1) {
var value = -1
var dragPoint = items.dragPoints.itemAt(index)
if(dragPoint.leftPoint)
value = checkRemovedIndex(playerState, dragPoint.leftPoint,
dragPoint.leftPoint.leftPoint, permittedIndex)
if(value != -1)
return value
if(dragPoint.upperPoint)
value = checkRemovedIndex(playerState, dragPoint.upperPoint,
dragPoint.upperPoint.upperPoint, permittedIndex)
if(value != -1)
return value
if(dragPoint.rightPoint)
value = checkRemovedIndex(playerState, dragPoint.rightPoint,
dragPoint.rightPoint.rightPoint, permittedIndex)
if(value != -1)
return value
if(dragPoint.lowerPoint)
value = checkRemovedIndex(playerState, dragPoint.lowerPoint,
dragPoint.lowerPoint.lowerPoint, permittedIndex)
if(value != -1)
return value
if(dragPoint.lowerPoint)
value = checkRemovedIndex(playerState, dragPoint.lowerPoint,
dragPoint.upperPoint, permittedIndex)
if(value != -1)
return value
if(dragPoint.leftPoint)
value = checkRemovedIndex(playerState, dragPoint.leftPoint,
dragPoint.rightPoint, permittedIndex)
if(value != -1)
return value
}
}
var randno = Math.floor((Math.random() * permittedIndex.length))
return permittedIndex[randno]
}
function checkRemovedIndex(state,first,second,permittedIndex) {
if(second) {
if(state == first.state && state == second.state) {
if(Math.floor((Math.random() * 2))) {
for (var i = 0 ; i < permittedIndex.length ; ++ i) {
if(permittedIndex[i] == first.pieceIndex)
return first.pieceIndex
}
for (var i = 0 ; i < permittedIndex.length ; ++ i) {
if(permittedIndex[i] == second.pieceIndex)
return second.pieceIndex
}
}
else {
for (var i = 0 ; i < permittedIndex.length ; ++ i) {
if(permittedIndex[i] == second.pieceIndex)
return second.pieceIndex
}
for (var i = 0 ; i < permittedIndex.length ; ++ i) {
if(permittedIndex[i] == first.pieceIndex)
return first.pieceIndex
}
}
}
}
return -1
}
function getSecondPhaseRemoveIndex() {
var permittedIndex = [];
for(var i = 0 ; i < numberOfPieces ; ++i) {
var piece = otherRepeater.itemAt(i)
if(piece.parentIndex != -1) {
if(piece.visible && !checkMill(piece.parentIndex, piece.state))
permittedIndex.push(i)
}
}
if(permittedIndex.length == 0) {
for(var i = 0 ; i < numberOfPieces ; ++i) {
if((otherRepeater.itemAt(i).parentIndex != -1) && (otherRepeater.itemAt(i).visible))
permittedIndex.push(i)
}
}
for(var index = 0 ; index < permittedIndex.length ; ++index) {
var i = permittedIndex[index]
var piece = otherRepeater.itemAt(i)
if(piece.visible) {
if(piece.pieceParent.leftPoint && piece.pieceParent.leftPoint.state == "EMPTY") {
if(checkMill(piece.pieceParent.leftPoint.index, piece.state, "left")) {
return i
}
}
if(piece.pieceParent.rightPoint && piece.pieceParent.rightPoint.state == "EMPTY") {
if(checkMill(piece.pieceParent.rightPoint.index, piece.state, "right")) {
return i
}
}
if(piece.pieceParent.upperPoint && piece.pieceParent.upperPoint.state == "EMPTY") {
if(checkMill(piece.pieceParent.upperPoint.index, piece.state, "upper")) {
return i
}
}
if(piece.pieceParent.lowerPoint && piece.pieceParent.lowerPoint.state == "EMPTY") {
if(checkMill(piece.pieceParent.lowerPoint.index, piece.state, "lower")) {
return i
}
}
}
}
return getFirstPhaseRemoveIndex()
}
// removePiece(index) called by Piece when items.pieceBeingRemoved is true
function removePiece(index) {
otherRepeater.itemAt(index).visible = false
// Decrease number of pieces of other player by 1
if(items.turn % 2)
numberOfFirstPieces --
else
numberOfSecondPieces --
if(items.firstPhase) {
items.instructionTxt = qsTr("Place a piece")
continueGame()
}
else
checkGameWon()
}
function removePieceSelected(index) {
otherRepeater.itemAt(index).parent.state = items.firstPhase ? "AVAILABLE" : "EMPTY"
for(var i = 0 ; i < numberOfPieces ; ++i)
otherRepeater.itemAt(i).canBeRemoved = false
}
function checkGameWon() {
// Check if other player can mover or not
var flag = true;
for (var i = 0 ; i < numberOfPieces ; ++i) {
var piece = otherRepeater.itemAt(i)
if(piece.visible) {
if((piece.parent.leftPoint && piece.parent.leftPoint.state == "EMPTY") ||
(piece.parent.rightPoint && piece.parent.rightPoint.state == "EMPTY") ||
(piece.parent.upperPoint && piece.parent.upperPoint.state == "EMPTY") ||
(piece.parent.lowerPoint && piece.parent.lowerPoint.state == "EMPTY")) {
flag = false
break
}
}
}
if(((numberOfSecondPieces < 3 && !items.playSecond) || (numberOfFirstPieces < 3 && items.playSecond)) ||
(flag && ((currentPiece.state == "1" && !items.playSecond) || (currentPiece.state == "2" && items.playSecond)))) {
items.gameDone = true
items.player1score.win();
items.player2score.endTurn();
items.instructionTxt = qsTr("Congratulations")
items.bonus.good("flower")
if(twoPlayer) {
items.instructionTxt = qsTr("Congratulations Player 1")
}
}
else if(((numberOfFirstPieces < 3 && !items.playSecond) || (numberOfSecondPieces < 3 && items.playSecond)) ||
(flag && ((currentPiece.state == "2" && !items.playSecond) ||
(currentPiece.state == "1" && items.playSecond)))) {
items.gameDone = true
items.player2score.win();
items.player1score.endTurn();
if(twoPlayer) {
items.bonus.good("flower")
items.instructionTxt = qsTr("Congratulations Player 2")
}
else {
items.instructionTxt = qsTr("Try again")
items.bonus.bad("tux")
}
}
else {
// Continue the game
items.instructionTxt = qsTr("Move a piece")
continueGame()
}
}
function getBoard() {
var board = []
for (var i = 0 ; i < numberOfDragPoints ; ++i) {
if(items.dragPoints.itemAt(i).state == "1") {
if(items.playSecond)
board.push(2)
else
board.push(1)
}
else if(items.dragPoints.itemAt(i).state == "2") {
if(items.playSecond)
board.push(1)
else
board.push(2)
}
else
board.push(0)
}
return board
}
function alphabeta(depth, alpha, beta, player, board, boardPiecesLeft, mill) {
var firstPhase = boardPiecesLeft != 0
var values = getValue(board, firstPhase, player)
var value = values.value
var myToBeMill = 0
var oppToBeMill = 0
if(value != 9000 && value != -9000 && depth == 0) {
var lost = -8500
var win = 8500
var toBeMill = 1.8
var myMillReachable = false
var oppMillReachable = false
var playerPieces = values.playerPieces
var computerPieces = values.computerPieces
for (var i = 0 ; i < numberOfDragPoints ; ++i) {
if (board[i] == 0) {
if(checkMillBoardPossible(board, i, 2, firstPhase, computerPieces)) {
myToBeMill++
if(positionReachable(board, i, 1, firstPhase, playerPieces))
myMillReachable = true
}
if(checkMillBoardPossible(board, i, 1, firstPhase, playerPieces)) {
oppToBeMill++
if(positionReachable(board, i, 2, firstPhase, computerPieces))
oppMillReachable = true
}
}
}
if(myToBeMill > 2 && playerPieces == 4 && !firstPhase && (mill == false || player == 2)){
value: win - 50
}
else if(oppToBeMill > 2 && computerPieces == 4 && !firstPhase && (mill == false || player == 1)) {
value: lost + 50
}
else {
if(myToBeMill > 0 && myMillReachable && player == 1 && ((playerPieces != 3 &&
!firstPhase) || firstPhase))
myToBeMill--
if(oppToBeMill > 0 && oppMillReachable && player == 2 && ((computerPieces != 3 &&
!firstPhase) || firstPhase))
oppToBeMill--
if(myToBeMill > 0 && playerPieces == 3 && player == 2 && !firstPhase){
value = win
}
else if(oppToBeMill > 0 && computerPieces == 3 && player == 1 && !firstPhase){
value = lost
}
else if(myToBeMill > 1 && playerPieces == 3 && player == 1 && !firstPhase &&
!mill){
value = win - 25
}
else if(oppToBeMill > 1 && computerPieces == 3 && player == 2 && !firstPhase &&
!mill){
value = lost + 25
}
else
value += toBeMill * (myToBeMill - oppToBeMill)
}
if(mill && depth == 0){// && value < 8000 && value > -8000) {
if(player == 2 && playerPieces == 3 && !firstPhase)
value = 9000
else if(player == 1 && computerPieces == 3 && !firstPhase)
value = -9000
else if(player == 2) {
if(oppToBeMill == 0)
value += 1.4
else if(oppToBeMill == 1)
value += 3.2
else
value += 4.8
}
else {
if(myToBeMill == 0)
value -= 1.4
else if(myToBeMill == 1)
value -= 3.2
else
value -= 4.8
}
}
if(mill && depth == 1 && !firstPhase && player == 2 && playerPieces == 4
&& oppToBeMill > 0)
return value + 3.2
value = Math.round(value * 1000) / 1000
}
if(depth == 0 || ((value == 9000 || value < -8000) && depth != depthMax)) {
return value
}
if(player == 2) {
var scores = []
if(mill) {
var removableIndex = getRemovableIndexFromBoard(board, 1)
var found = false
for(var i = 0 ; i < removableIndex.length ; ++i) {
board[removableIndex[i]] = 0
var newAlpha = alphabeta(depth - 1, alpha, beta, 1, board, boardPiecesLeft, false)
board[removableIndex[i]] = 1
if(newAlpha >= alpha) {
found = true
alpha = newAlpha
scores[i] = alpha
}
if(beta < alpha) break
}
if(depth == depthMax) {
var max = -9000;
for(var i = 0; i < scores.length; i++) {
if(scores[i] != undefined && scores[i] > max)
max = scores[i]
}
var index = []
for(var i = 0; i < scores.length; i++) {
if(scores[i] != undefined && scores[i] == max)
index.push(i)
}
var randno = Math.floor((Math.random() * index.length))
return removableIndex[index[randno]]
}
if(found)
return alpha
else
return alpha - 1000
}
else if(firstPhase) {
var scores = []
var moves = generateMove(board, 2, 0, true)
for(var i = 0 ; i < moves.length ; ++i) {
var move = moves[i]
board[move] = 2
boardPiecesLeft--
var newAlpha
if(checkMillBoard(board, move) != 0)
newAlpha = alphabeta(depth - 1, alpha, beta, 2, board, boardPiecesLeft, true)
else
newAlpha = alphabeta(depth - 1, alpha, beta, 1, board, boardPiecesLeft, false)
boardPiecesLeft++
board[move] = 0
if(newAlpha >= alpha) {
alpha = newAlpha
scores[i] = alpha
}
if(beta < alpha) break
}
if(depth == depthMax) {
var max = -9000;
for(var i = 0; i < scores.length; i++) {
if(scores[i] != undefined && scores[i] > max)
max = scores[i]
}
var index = []
for(var i = 0; i < scores.length; i++) {
if(scores[i] != undefined && scores[i] == max)
index.push(i)
}
var randno = Math.floor((Math.random() * index.length))
return moves[index[randno]]
}
return alpha
}
else {
var computerPointsIndex = []
for (var i = 0 ; i < numberOfDragPoints ; ++i) {
if(board[i] == 2)
computerPointsIndex.push(i)
}
var scores = []
for (var i = 0 ; i < computerPointsIndex.length ; ++i) {
var computerPoint = computerPointsIndex[i]
var moves = generateMove(board, 2, computerPoint, false)
scores[i] = []
for(var j = 0 ; j < moves.length ; ++j) {
var move = moves[j]
board[computerPoint] = 0
board[move] = 2
var newAlpha
if(checkMillBoard(board, move) != 0)
newAlpha = alphabeta(depth - 1, alpha, beta, 2, board, boardPiecesLeft, true)
else
newAlpha = alphabeta(depth - 1, alpha, beta, 1, board, boardPiecesLeft, false)
board[computerPoint] = 2
board[move] = 0
if(newAlpha >= alpha) {
alpha = newAlpha
scores[i][move] = alpha
}
if(beta < alpha) break
}
if(beta < alpha) break
}
if(depth == depthMax) {
var max = -9000;
for(var i = 0; i < scores.length; i++) {
for(var j = 0 ; j < scores[i].length ; j++) {
if(scores[i][j] != undefined) {
if(scores[i][j] > max) {
max = scores[i][j]
}
}
}
}
var moveIndex = []
for(var i = 0; i < scores.length; i++) {
for(var j = 0 ; j < scores[i].length ; j++) {
if(scores[i][j] != undefined && scores[i][j] == max) {
var index = []
index[0] = computerPointsIndex[i]
index[1] = j
moveIndex.push(index)
}
}
}
var randno = Math.floor((Math.random() * moveIndex.length))
return moveIndex[randno]
}
return alpha
}
}
else {
if(mill) {
var removableIndex = getRemovableIndexFromBoard(board, 2)
for(var i = 0 ; i < removableIndex.length ; ++i) {
board[removableIndex[i]] = 0
if(playerPieces == 3 && computerPieces == 4 && !firstPhase)
beta = Math.min(beta, alphabeta(depth, alpha, beta, 2, board, boardPiecesLeft, false))
board[removableIndex[i]] = 2
if(beta < alpha) break
}
return beta
}
else if(boardPiecesLeft != 0) { // First Phase
var moves = generateMove(board, 1, 0, true)
for(var i = 0 ; i < moves.length ; ++i) {
var move = moves[i]
board[move] = 1
boardPiecesLeft--
if(checkMillBoard(board, move) != 0)
beta = Math.min(beta, alphabeta(depth - 1, alpha, beta, 1, board, boardPiecesLeft, true))
else
beta = Math.min(beta, alphabeta(depth - 1, alpha, beta, 2, board, boardPiecesLeft, false))
boardPiecesLeft++
board[move] = 0
if(beta < alpha) break
}
return beta
}
else {
var playerPointsIndex = []
for (var i = 0 ; i < numberOfDragPoints ; ++i) {
if(board[i] == 1)
playerPointsIndex.push(i)
}
for (var i = 0 ; i < playerPointsIndex.length ; ++i) {
var playerPoint = playerPointsIndex[i]
var moves = generateMove(board, 1, playerPoint, false)
for(var j = 0 ; j < moves.length ; ++j) {
var move = moves[j]
board[playerPoint] = 0
board[move] = 1
if(checkMillBoard(board, move) != 0)
beta = Math.min(beta, alphabeta(depth - 1, alpha, beta, 1, board, boardPiecesLeft, true))
else
beta = Math.min(beta, alphabeta(depth - 1, alpha, beta, 2, board, boardPiecesLeft, false))
board[playerPoint] = 1
board[move] = 0
if(beta < alpha) break
}
if(beta < alpha) break
}
return beta
}
}
}
function getRemovableIndexFromBoard(board, state) {
var index = []
for (var i = 0 ; i < numberOfDragPoints ; ++i) {
if (board[i] == state && checkMillBoard(board, i) == 0)
index.push(i)
}
if(index.length == 0) {
for (var i = 0 ; i < numberOfDragPoints ; ++i) {
if (board[i] == state)
index.push(i)
}
}
return index
}
function getValue(board, firstPhase, player) {
var value = 0.0
var material = 1.0
var freedom = 0.2
var mills = 0.8
var lost = -8500
var win = 8500
var toBeMill = 1.8
// ========== material ==========
var computerPieces = getNumberOfPieces(board, 2)
var playerPieces = getNumberOfPieces(board, 1)
if (computerPieces < 3 && !firstPhase) {
return {value: lost - 500}
}
if (playerPieces < 3 && !firstPhase) {
return {value: win + 500}
}
value += material * (computerPieces - playerPieces)
// ========== mills ==========
var computerMills = 0
var playerMills = 0
var computerMillsIndex = []
var playerMillsIndex = []
for (var i = 0 ; i < numberOfDragPoints ; ++i) {
if(computerMillsIndex.indexOf(i) == -1 && board[i] == 2) {
computerMills += checkMillBoard(board, i, computerMillsIndex)
}
else if(playerMillsIndex.indexOf(i) == -1 && board[i] == 1) {
playerMills += checkMillBoard(board, i, playerMillsIndex)
}
}
value += mills * (computerMills - playerMills)
// ========== freedom ==========
if(playerPieces != 3 || computerPieces != 3 || firstPhase) {
var myFreedom = 0
var oppFreedom = 0
for (var i = 0 ; i < numberOfDragPoints ; ++i) {
if (board[i] == 2)
myFreedom += positionAchievable(board, i, computerPieces, firstPhase)
else if (board[i] == 1)
oppFreedom += positionAchievable(board, i, playerPieces, firstPhase)
}
if (myFreedom == 0 && !firstPhase){
return {value: lost, computerPieces: computerPieces, playerPieces: playerPieces}
}
if (oppFreedom == 0 && !firstPhase){
return {value: win + 500, computerPieces: computerPieces, playerPieces: playerPieces}
}
if(((computerPieces > 3 && playerPieces == 3 && computerPieces < 6) ||
(playerMills > 0 && playerPieces == 4)) && !firstPhase)
freedom = 0
value += freedom * (myFreedom - oppFreedom)
}
value = Math.round(value * 1000) / 1000
return {value: value, computerPieces: computerPieces, playerPieces: playerPieces}
}
function getNumberOfPieces(board, state) {
var no = 0
for (var i = 0 ; i < numberOfDragPoints ; ++ i) {
if (board[i] == state)
no ++
}
return no
}
function positionAchievable(board, index, noOfBoardPieces, firstPhase) {
var positions = 0
if(noOfBoardPieces == 3 && !firstPhase) {
for (var i = 0 ; i < numberOfDragPoints ; ++ i) {
if (board[i] == 0)
positions ++
}
}
else {
var point = items.dragPoints.itemAt(index)
if(point.leftPoint && board[point.leftPoint.index] == 0)
positions ++
if(point.rightPoint && board[point.rightPoint.index] == 0)
positions ++
if(point.upperPoint && board[point.upperPoint.index] == 0)
positions ++
if(point.lowerPoint && board[point.lowerPoint.index] == 0)
positions ++
}
return positions
}
function positionReachable(board, index, state, firstPhase, noOfBoardPieces) {
if(noOfBoardPieces == 3 || firstPhase)
return true
else {
var point = items.dragPoints.itemAt(index)
if(point.leftPoint && board[point.leftPoint.index] == state)
return true
if(point.rightPoint && board[point.rightPoint.index] == state)
return true
if(point.upperPoint && board[point.upperPoint.index] == state)
return true
if(point.lowerPoint && board[point.lowerPoint.index] == state)
return true
return false
}
}
function checkMillBoard(board, index, millsIndex) {
var point = items.dragPoints.itemAt(index)
var state = board[index]
var mills = 0
if (millsIndex == undefined)
millsIndex = []
if(point.leftPoint && point.leftPoint.leftPoint && state == board[point.leftPoint.index]
&& state == board[point.leftPoint.leftPoint.index]) {
mills ++
millsIndex.push(point.leftPoint.index)
millsIndex.push(point.leftPoint.leftPoint.index)
}
if(point.upperPoint && point.upperPoint.upperPoint && state == board[point.upperPoint.index]
&& state == board[point.upperPoint.upperPoint.index]) {
mills ++
millsIndex.push(point.upperPoint.index)
millsIndex.push(point.upperPoint.upperPoint.index)
}
if(point.rightPoint && point.rightPoint.rightPoint && state == board[point.rightPoint.index]
&& state == board[point.rightPoint.rightPoint.index]) {
mills ++
millsIndex.push(point.rightPoint.index)
millsIndex.push(point.rightPoint.rightPoint.index)
}
if(point.lowerPoint && point.lowerPoint.lowerPoint && state == board[point.lowerPoint.index]
&& state == board[point.lowerPoint.lowerPoint.index]) {
mills ++
millsIndex.push(point.lowerPoint.index)
millsIndex.push(point.lowerPoint.lowerPoint.index)
}
if(point.lowerPoint && point.upperPoint && state == board[point.lowerPoint.index]
&& state == board[point.upperPoint.index]) {
mills ++
millsIndex.push(point.lowerPoint.index)
millsIndex.push(point.upperPoint.index)
}
if(point.leftPoint && point.rightPoint && state == board[point.leftPoint.index]
&& state == board[point.rightPoint.index]) {
mills ++
millsIndex.push(point.rightPoint.index)
millsIndex.push(point.leftPoint.index)
}
return mills
}
function checkMillBoardPossible(board, index, state, firstPhase, pieces) {
var freeMove = pieces == 3 || firstPhase
var point = items.dragPoints.itemAt(index)
if(point.leftPoint && point.leftPoint.leftPoint) {
if(state == board[point.leftPoint.index] && state == board[point.leftPoint.leftPoint.index]) {
if((point.upperPoint && state == board[point.upperPoint.index]) ||
(point.lowerPoint && state == board[point.lowerPoint.index]) || freeMove)
return true
}
}
if(point.upperPoint && point.upperPoint.upperPoint) {
if(state == board[point.upperPoint.index] && state == board[point.upperPoint.upperPoint.index]) {
if((point.leftPoint && state == board[point.leftPoint.index]) ||
(point.rightPoint && state == board[point.rightPoint.index]) || freeMove)
return true
}
}
if(point.rightPoint && point.rightPoint.rightPoint) {
if(state == board[point.rightPoint.index] && state == board[point.rightPoint.rightPoint.index]) {
if((point.upperPoint && state == board[point.upperPoint.index]) ||
(point.lowerPoint && state == board[point.lowerPoint.index]) || freeMove)
return true
}
}
if(point.lowerPoint && point.lowerPoint.lowerPoint) {
if(state == board[point.lowerPoint.index] && state == board[point.lowerPoint.lowerPoint.index]) {
if((point.leftPoint && state == board[point.leftPoint.index]) ||
(point.rightPoint && state == board[point.rightPoint.index]) || freeMove)
return true
}
}
if(point.lowerPoint && point.upperPoint) {
if(state == board[point.lowerPoint.index] && state == board[point.upperPoint.index]) {
if((point.leftPoint && state == board[point.leftPoint.index]) ||
(point.rightPoint && state == board[point.rightPoint.index]) || freeMove)
return true;
}
}
if(point.leftPoint && point.rightPoint) {
if(state == board[point.leftPoint.index] && state == board[point.rightPoint.index]) {
if((point.upperPoint && state == board[point.upperPoint.index]) ||
(point.lowerPoint && state == board[point.lowerPoint.index]) || freeMove)
return true;
}
}
}
function generateMove(board, state, index, firstPhase) {
var moves = []
if(firstPhase || getNumberOfPieces(board, state) == 3) {
for (var i = 0 ; i < numberOfDragPoints ; ++i) {
if (board[i] == 0)
moves.push(i)
}
}
else {
var point = items.dragPoints.itemAt(index)
if(point.leftPoint && board[point.leftPoint.index] == 0)
moves.push(point.leftPoint.index)
if(point.rightPoint && board[point.rightPoint.index] == 0)
moves.push(point.rightPoint.index)
if(point.upperPoint && board[point.upperPoint.index] == 0)
moves.push(point.upperPoint.index)
if(point.lowerPoint && board[point.lowerPoint.index] == 0)
moves.push(point.lowerPoint.index)
}
return moves
}
diff --git a/src/activities/nine_men_morris_2players/ActivityInfo.qml b/src/activities/nine_men_morris_2players/ActivityInfo.qml
index a600f7eea..90d47d5e3 100644
--- a/src/activities/nine_men_morris_2players/ActivityInfo.qml
+++ b/src/activities/nine_men_morris_2players/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2016 Pulkit Gupta <pulkitnsit@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "nine_men_morris_2players/NineMenMorris2players.qml"
difficulty: 2
icon: "nine_men_morris_2players/nine_men_morris_2players.svg"
author: "Pulkit Gupta &lt;pulkitnsit@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Nine men's morris (with a friend)")
//: Help title
description: qsTr("Reduce the opponent to two pieces, or by leaving him without a legal move.")
//intro: "Click on the dot where you wish to place your piece and try to take all your friend's pieces."
//: Help goal
goal: qsTr("Form mills (line of 3 pieces) to remove pieces of opponent until opponent has only two pieces, or doesn't have a legal move")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("Play with a friend. First take turns to place nine pieces, and then take turns to move pieces")
credit: ""
section: "strategy"
createdInVersion: 7000
}
diff --git a/src/activities/nine_men_morris_2players/NineMenMorris2players.qml b/src/activities/nine_men_morris_2players/NineMenMorris2players.qml
index 60a8cb8f3..57138cbe2 100644
--- a/src/activities/nine_men_morris_2players/NineMenMorris2players.qml
+++ b/src/activities/nine_men_morris_2players/NineMenMorris2players.qml
@@ -1,28 +1,28 @@
/* GCompris - NineMenMorris2players.qml
*
* Copyright (C) 2016 Pulkit Gupta <pulkitnsit@gmail.com>
*
* Authors:
* Pulkit Gupta <pulkitnsit@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
import "../nine_men_morris"
NineMenMorris {
twoPlayer: true
}
diff --git a/tools/menus/note_names.qml b/src/activities/note_names/ActivityInfo.qml
similarity index 59%
rename from tools/menus/note_names.qml
rename to src/activities/note_names/ActivityInfo.qml
index fd2fd050c..dba16ab19 100644
--- a/tools/menus/note_names.qml
+++ b/src/activities/note_names/ActivityInfo.qml
@@ -1,34 +1,43 @@
/* GCompris - ActivityInfo.qml
*
- * Copyright (C) 2015 Your Name <yy@zz.org>
+ * Copyright (C) 2018 Aman Kumar Gupta <gupta2140@gmail.com>
+ *
+ * Authors:
+ * Aman Kumar Gupta <gupta2140@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "note_names/NoteNames.qml"
difficulty: 4
icon: "note_names/note_names.svg"
- author: "Beth Hadley &lt;bethmhadley@gmail.com&gt;"
+ author: "Aman Kumar Gupta &lt;gupta2140@gmail.com&gt;"
demo: true
- title: qsTr("Name that Note!")
- description: qsTr("Learn the names of the notes, in bass and treble clef, with the help of sounds and colors")
- goal: qsTr("To develop a good understanding of note position and naming convention. To prepare for the piano player and composition activity")
- prerequisite: qsTr("None")
- manual: qsTr("The first level and the eleventh level introduce two different staffs with a C major scale. The following levels then quiz the player on note names. To help learn the names, the note pitches are played when the mouse is rolled over the note, and the pitch names can be color coded.
- ")
+ //: Activity title
+ title: qsTr("Name that Note")
+ //: Help title
+ description: qsTr("Learn the names of the notes, in bass and treble clef.")
+ //intro: "Identify the note and press the correct piano key"
+ //: Help goal
+ goal: qsTr("To develop a good understanding of note position and naming convention. To prepare for the piano player and composition activity.")
+ //: Help prerequisite
+ prerequisite: ""
+ //: Help manual
+ manual: qsTr("Identify the notes correctly and score a 100% to complete a level.")
credit: ""
- section: "/discovery/sound_group"
+ section: "discovery sound"
+ createdInVersion: 9500
}
diff --git a/src/activities/note_names/AdvancedTimer.qml b/src/activities/note_names/AdvancedTimer.qml
new file mode 100644
index 000000000..7a0879cd8
--- /dev/null
+++ b/src/activities/note_names/AdvancedTimer.qml
@@ -0,0 +1,73 @@
+/* GCompris - AdvancedTimer.qml
+ *
+ * Copyright (C) 2018 Aman Kumar Gupta <gupta2140@gmail.com>
+ *
+ * Authors:
+ * Aman Kumar Gupta <gupta2140@gmail.com>
+ *
+ * This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+ */
+import QtQuick 2.6
+import QtQuick.Controls 1.5
+import GCompris 1.0
+import "note_names.js" as Activity
+
+Timer {
+ id: timer
+
+ property double startTime
+ property double pauseTime
+ property int timerNormalInterval: 2700
+ property int remainingInterval
+
+ interval: timerNormalInterval
+
+ signal pause
+ signal resume
+ signal restart
+
+ onPause: {
+ if(timer.running) {
+ pauseTime = new Date().getTime()
+ timer.stop()
+ }
+ }
+
+ onResume: {
+ if(!timer.running) {
+ if(!triggeredOnStart) {
+ remainingInterval = Math.abs(timer.interval - Math.abs(pauseTime - startTime))
+ timer.interval = remainingInterval
+ }
+ timer.start()
+ }
+ }
+
+ onRestart: {
+ timer.stop()
+ timer.interval = 1
+ timer.start()
+ }
+
+ onTriggered:{
+ if(interval != timerNormalInterval) {
+ interval = timerNormalInterval
+ }
+ }
+
+ onRunningChanged: {
+ if(running)
+ startTime = new Date().getTime()
+ }
+}
diff --git a/src/activities/note_names/CMakeLists.txt b/src/activities/note_names/CMakeLists.txt
new file mode 100644
index 000000000..f729ca289
--- /dev/null
+++ b/src/activities/note_names/CMakeLists.txt
@@ -0,0 +1 @@
+GCOMPRIS_ADD_RCC(activities/note_names *.qml *.svg *.js resource/*)
diff --git a/src/activities/note_names/NoteNames.qml b/src/activities/note_names/NoteNames.qml
new file mode 100644
index 000000000..9926f4a90
--- /dev/null
+++ b/src/activities/note_names/NoteNames.qml
@@ -0,0 +1,425 @@
+/* GCompris - NoteNames.qml
+ *
+ * Copyright (C) 2018 Aman Kumar Gupta <gupta2140@gmail.com>
+ *
+ * Authors:
+ * Aman Kumar Gupta <gupta2140@gmail.com>
+ *
+ * This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+ */
+import QtQuick 2.6
+import QtQuick.Controls 1.5
+import GCompris 1.0
+
+import "../../core"
+import "../piano_composition"
+import "note_names.js" as Activity
+
+ActivityBase {
+ id: activity
+
+ onStart: focus = true
+ onStop: {}
+
+ property bool horizontalLayout: width >= height
+
+ pageComponent: Rectangle {
+ id: background
+ anchors.fill: parent
+ color: "#ABCDEF"
+
+ signal start
+ signal stop
+
+ Component.onCompleted: {
+ activity.start.connect(start)
+ activity.stop.connect(stop)
+ }
+
+ Keys.onPressed: {
+ var keyNoteBindings = {}
+ keyNoteBindings[Qt.Key_1] = 'C'
+ keyNoteBindings[Qt.Key_2] = 'D'
+ keyNoteBindings[Qt.Key_3] = 'E'
+ keyNoteBindings[Qt.Key_4] = 'F'
+ keyNoteBindings[Qt.Key_5] = 'G'
+ keyNoteBindings[Qt.Key_6] = 'A'
+ keyNoteBindings[Qt.Key_7] = 'B'
+
+ if(!introMessage.visible && !iAmReady.visible && !messageBox.visible && multipleStaff.musicElementModel.count - 1) {
+ if(keyNoteBindings[event.key]) {
+ // If the key pressed matches the note, pass the correct answer as parameter.
+ isCorrectKey(keyNoteBindings[event.key])
+ }
+ else if(event.key === Qt.Key_Left && shiftKeyboardLeft.visible) {
+ doubleOctave.currentOctaveNb--
+ }
+ else if(event.key === Qt.Key_Right && shiftKeyboardRight.visible) {
+ doubleOctave.currentOctaveNb++
+ }
+ }
+ }
+
+ function isCorrectKey(key) {
+ if(Activity.newNotesSequence[Activity.currentNoteIndex][0] === key)
+ Activity.correctAnswer()
+ else
+ items.displayNoteNameTimer.start()
+ }
+
+ // Add here the QML items you need to access in javascript
+ QtObject {
+ id: items
+ property Item main: activity.main
+ property alias background: background
+ property GCSfx audioEffects: activity.audioEffects
+ property alias bar: bar
+ property alias multipleStaff: multipleStaff
+ property alias doubleOctave: doubleOctave
+ property alias bonus: bonus
+ property alias iAmReady: iAmReady
+ property alias messageBox: messageBox
+ property alias addNoteTimer: addNoteTimer
+ property alias dataset: dataset
+ property alias progressBar: progressBar
+ property alias introMessage: introMessage
+ property bool isTutorialMode: true
+ property alias displayNoteNameTimer: displayNoteNameTimer
+ }
+
+ Loader {
+ id: dataset
+ asynchronous: false
+ source: "qrc:/gcompris/src/activities/note_names/resource/dataset_01.qml"
+ }
+
+ onStart: { Activity.start(items) }
+ onStop: { Activity.stop() }
+
+ property string clefType: "Treble"
+
+ Timer {
+ id: displayNoteNameTimer
+ interval: 2000
+ onRunningChanged: {
+ if(running) {
+ multipleStaff.pauseNoteAnimation()
+ addNoteTimer.pause()
+ messageBox.visible = true
+ }
+ else {
+ messageBox.visible = false
+ if(progressBar.percentage != 100 && Activity.newNotesSequence.length) {
+ Activity.wrongAnswer()
+ addNoteTimer.resume()
+ }
+ }
+ }
+ }
+
+ Rectangle {
+ id: messageBox
+ width: label.width + 20
+ height: label.height + 20
+ border.width: 5
+ border.color: "black"
+ anchors.centerIn: multipleStaff
+ radius: 10
+ z: 11
+ visible: false
+
+ function getTranslatedNoteName(noteName) {
+ for(var i = 0; i < doubleOctave.keyNames.length; i++) {
+ if(doubleOctave.keyNames[i][0] == noteName)
+ return doubleOctave.keyNames[i][1]
+ }
+ return ""
+ }
+
+ onVisibleChanged: {
+ if(Activity.targetNotes[0] === undefined)
+ text = ""
+ else if(items.isTutorialMode)
+ text = qsTr("New note: %1").arg(getTranslatedNoteName(Activity.targetNotes[0]))
+ else
+ text = getTranslatedNoteName(Activity.newNotesSequence[Activity.currentNoteIndex])
+ }
+
+ property string text
+
+ GCText {
+ id: label
+ anchors.centerIn: parent
+ fontSize: mediumSize
+ text: parent.text
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ enabled: items.isTutorialMode
+ onClicked: {
+ items.multipleStaff.pauseNoteAnimation()
+ items.multipleStaff.musicElementModel.remove(1)
+ Activity.showTutorial()
+ }
+ }
+ }
+
+ Rectangle {
+ id: colorLayer
+ anchors.fill: parent
+ color: "black"
+ opacity: 0.3
+ visible: iAmReady.visible
+ z: 10
+ MouseArea {
+ anchors.fill: parent
+ }
+ }
+
+ ReadyButton {
+ id: iAmReady
+ focus: true
+ z: 10
+ visible: !introMessage.visible
+ onVisibleChanged: {
+ messageBox.visible = false
+ }
+ onClicked: {
+ Activity.initLevel()
+ }
+ }
+
+ IntroMessage {
+ id: introMessage
+ anchors {
+ top: parent.top
+ topMargin: 10
+ right: parent.right
+ rightMargin: 5
+ left: parent.left
+ leftMargin: 5
+ }
+ z: 12
+ }
+
+ AdvancedTimer {
+ id: addNoteTimer
+ onTriggered: {
+ Activity.noteIndexToDisplay = (Activity.noteIndexToDisplay + 1) % Activity.newNotesSequence.length
+ Activity.displayNote(Activity.newNotesSequence[Activity.noteIndexToDisplay])
+ }
+ }
+
+ ProgressBar {
+ id: progressBar
+ height: 20 * ApplicationInfo.ratio
+ width: parent.width / 4
+
+ property int percentage: 0
+
+ value: percentage
+ maximumValue: 100
+ visible: !items.isTutorialMode
+ anchors {
+ top: parent.top
+ topMargin: 10
+ right: parent.right
+ rightMargin: 10
+ }
+
+ GCText {
+ anchors.centerIn: parent
+ fontSize: mediumSize
+ font.bold: true
+ color: "black"
+ //: The following translation represents percentage.
+ text: qsTr("%1%").arg(parent.value)
+ z: 2
+ }
+ }
+
+ MultipleStaff {
+ id: multipleStaff
+ width: horizontalLayout ? parent.width * 0.5 : parent.width * 0.78
+ height: horizontalLayout ? parent.height * 0.9 : parent.height * 0.7
+ nbStaves: 1
+ clef: clefType
+ notesColor: "red"
+ softColorOpacity: 0
+ isFlickable: false
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.top: parent.top
+ anchors.topMargin: progressBar.height + 20
+ flickableTopMargin: multipleStaff.height / 14 + distanceBetweenStaff / 2.7
+ noteAnimationEnabled: true
+ onNoteAnimationFinished: {
+ if(!items.isTutorialMode)
+ displayNoteNameTimer.start()
+ }
+ }
+
+ // We present a pair of two joint piano keyboard octaves.
+ Item {
+ id: doubleOctave
+ width: parent.width * 0.95
+ height: horizontalLayout ? parent.height * 0.22 : 2 * parent.height * 0.18
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.bottom: bar.top
+ anchors.bottomMargin: 30
+
+ readonly property int nbJointKeyboards: 2
+ readonly property int maxNbOctaves: 3
+ property int currentOctaveNb: 0
+ property var coloredKeyLabels: []
+ property var keyNames: []
+
+ Repeater {
+ id: octaveRepeater
+ anchors.fill: parent
+ model: doubleOctave.nbJointKeyboards
+ PianoOctaveKeyboard {
+ id: pianoKeyboard
+ width: horizontalLayout ? octaveRepeater.width / 2 : octaveRepeater.width
+ height: horizontalLayout ? octaveRepeater.height : octaveRepeater.height / 2
+ blackLabelsVisible: false
+ blackKeysEnabled: blackLabelsVisible
+ whiteKeysEnabled: !messageBox.visible && multipleStaff.musicElementModel.count > 1
+ onNoteClicked: Activity.checkAnswer(note)
+ currentOctaveNb: doubleOctave.currentOctaveNb
+ anchors.top: (index === 1) ? octaveRepeater.top : undefined
+ anchors.topMargin: horizontalLayout ? 0 : -15
+ anchors.bottom: (index === 0) ? octaveRepeater.bottom : undefined
+ anchors.right: (index === 1) ? octaveRepeater.right : undefined
+ coloredKeyLabels: doubleOctave.coloredKeyLabels
+ labelsColor: "red"
+ // The octaves sets corresponding to respective clef types are in pairs for the joint piano keyboards at a time when displaying.
+ whiteKeyNoteLabelsBass: {
+ if(index === 0) {
+ return [
+ whiteKeyNoteLabelsArray.slice(0, 4), // F1 to B1
+ whiteKeyNoteLabelsArray.slice(4, 11), // C2 to B2
+ whiteKeyNoteLabelsArray.slice(11, 18) // C3 to B3
+ ]
+ }
+ else {
+ return [
+ whiteKeyNoteLabelsArray.slice(4, 11), // C2 to B2
+ whiteKeyNoteLabelsArray.slice(11, 18), // C3 to B3
+ whiteKeyNoteLabelsArray.slice(18, 25) // C4 to B4
+ ]
+ }
+ }
+ whiteKeyNoteLabelsTreble: {
+ if(index === 0) {
+ return [
+ whiteKeyNoteLabelsArray.slice(11, 18), // C3 to B3
+ whiteKeyNoteLabelsArray.slice(18, 25), // C4 to B4
+ whiteKeyNoteLabelsArray.slice(25, 32) // C5 to B5
+ ]
+ }
+ else {
+ return [
+ whiteKeyNoteLabelsArray.slice(18, 25), // C4 to B4
+ whiteKeyNoteLabelsArray.slice(25, 32), // C5 to B5
+ whiteKeyNoteLabelsArray.slice(32, 34) // C6 to D6
+ ]
+ }
+ }
+
+ Component.onCompleted: doubleOctave.keyNames = whiteKeyNoteLabelsArray
+ }
+ }
+ }
+
+ Image {
+ id: shiftKeyboardLeft
+ source: "qrc:/gcompris/src/core/resource/bar_previous.svg"
+ sourceSize.width: horizontalLayout ? doubleOctave.width / 13 : doubleOctave.width / 6
+ width: sourceSize.width
+ height: width
+ fillMode: Image.PreserveAspectFit
+ visible: (doubleOctave.currentOctaveNb > 0) && doubleOctave.visible
+ z: 11
+ anchors {
+ bottom: doubleOctave.top
+ left: doubleOctave.left
+ leftMargin: -37
+ bottomMargin: horizontalLayout ? 10 : 25
+ }
+ MouseArea {
+ enabled: !messageBox.visible
+ anchors.fill: parent
+ onClicked: {
+ doubleOctave.currentOctaveNb--
+ }
+ }
+ }
+
+ Image {
+ id: shiftKeyboardRight
+ source: "qrc:/gcompris/src/core/resource/bar_next.svg"
+ sourceSize.width: horizontalLayout ? doubleOctave.width / 13 : doubleOctave.width / 6
+ width: sourceSize.width
+ height: width
+ fillMode: Image.PreserveAspectFit
+ visible: (doubleOctave.currentOctaveNb < doubleOctave.maxNbOctaves - 1) && doubleOctave.visible
+ z: 11
+ anchors {
+ bottom: doubleOctave.top
+ right: doubleOctave.right
+ rightMargin: -37
+ bottomMargin: horizontalLayout ? 10 : 25
+ }
+ MouseArea {
+ enabled: !messageBox.visible
+ anchors.fill: parent
+ onClicked: {
+ doubleOctave.currentOctaveNb++
+ }
+ }
+ }
+
+ OptionsRow {
+ id: optionsRow
+ iconsWidth: 0
+ visible: false
+ }
+
+ DialogHelp {
+ id: dialogHelp
+ onClose: home()
+ }
+
+ Bar {
+ id: bar
+ content: BarEnumContent { value: help | home | level | reload }
+ onHelpClicked: {
+ displayDialog(dialogHelp)
+ }
+ onPreviousLevelClicked: Activity.previousLevel()
+ onNextLevelClicked: Activity.nextLevel()
+ onHomeClicked: activity.home()
+ onReloadClicked: {
+ iAmReady.visible = true
+ Activity.initLevel()
+ }
+ }
+
+ Bonus {
+ id: bonus
+ Component.onCompleted: win.connect(Activity.nextLevel)
+ }
+ }
+}
diff --git a/src/activities/note_names/note_names.js b/src/activities/note_names/note_names.js
new file mode 100644
index 000000000..5846c4d26
--- /dev/null
+++ b/src/activities/note_names/note_names.js
@@ -0,0 +1,177 @@
+/* GCompris - note_names.js
+ *
+ * Copyright (C) 2018 Aman Kumar Gupta <gupta2140@gmail.com>
+ *
+ * Authors:
+ * Aman Kumar Gupta <gupta2140@gmail.com>
+ *
+ * This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+ */
+.pragma library
+.import QtQuick 2.6 as Quick
+.import "qrc:/gcompris/src/core/core.js" as Core
+
+var currentLevel = 0
+var numberOfLevel
+var dataset
+var items
+var levels
+var targetNotes = []
+var newNotesSequence = []
+var currentNoteIndex
+var noteIndexToDisplay
+var percentageDecreaseValue = 4
+var percentageIncreaseValue = 2
+
+function start(items_) {
+ items = items_
+ currentLevel = 0
+ dataset = items.dataset.item
+ levels = dataset.levels
+ numberOfLevel = levels.length
+ items.doubleOctave.coloredKeyLabels = dataset.referenceNotes[levels[0]["clef"]]
+ items.doubleOctave.currentOctaveNb = 1
+ items.introMessage.intro = [dataset.objective]
+ initLevel()
+}
+
+function stop() {
+ newNotesSequence = []
+ items.multipleStaff.pauseNoteAnimation()
+ items.displayNoteNameTimer.stop()
+ items.addNoteTimer.stop()
+}
+
+function initLevel() {
+ targetNotes = []
+ newNotesSequence = []
+ items.bar.level = currentLevel + 1
+ items.background.clefType = levels[currentLevel]["clef"]
+ items.doubleOctave.coloredKeyLabels = dataset.referenceNotes[items.background.clefType]
+ if(items.background.clefType === "Treble")
+ items.doubleOctave.currentOctaveNb = 1
+ else
+ items.doubleOctave.currentOctaveNb = 2
+
+ items.multipleStaff.pauseNoteAnimation()
+ items.displayNoteNameTimer.stop()
+ items.addNoteTimer.stop()
+ items.multipleStaff.initClefs(items.background.clefType)
+ targetNotes = JSON.parse(JSON.stringify(levels[currentLevel]["sequence"]))
+ items.isTutorialMode = true
+ items.progressBar.percentage = 0
+ items.multipleStaff.coloredNotes = dataset.referenceNotes[items.background.clefType]
+ if(!items.iAmReady.visible && ! items.introMessage.visible)
+ showTutorial()
+}
+
+function showTutorial() {
+ items.messageBox.visible = false
+ if(targetNotes.length) {
+ displayNote(targetNotes[0])
+ items.messageBox.visible = true
+ targetNotes.shift()
+ }
+ else {
+ items.isTutorialMode = false
+ startGame()
+ }
+}
+
+// The principle is to fill half sequence (length 25) with the notes from previous levels and another half with current level's target notes and shuffle them.
+function formNewNotesSequence() {
+ var halfSequenceLength = 25
+ var fullSequenceLength = 50
+ targetNotes = JSON.parse(JSON.stringify(levels[currentLevel]["sequence"]))
+ for(var i = 0; i < currentLevel && newNotesSequence.length < halfSequenceLength; i++) {
+ if(levels[currentLevel]["clef"] === levels[i]["clef"]) {
+ for(var j = 0; j < levels[i]["sequence"].length && newNotesSequence.length < halfSequenceLength; j++)
+ newNotesSequence.push(levels[i]["sequence"][j])
+ }
+ }
+
+ for(var i = 0; newNotesSequence.length && newNotesSequence.length < halfSequenceLength; i++)
+ newNotesSequence.push(newNotesSequence[i % newNotesSequence.length])
+
+ for(var i = 0; newNotesSequence.length < fullSequenceLength; i++)
+ newNotesSequence.push(targetNotes[i % targetNotes.length])
+
+ Core.shuffle(newNotesSequence)
+}
+
+function startGame() {
+ currentNoteIndex = 0
+ noteIndexToDisplay = 0
+ items.progressBar.percentage = 0
+ formNewNotesSequence()
+ displayNote(newNotesSequence[0])
+}
+
+function displayNote(currentNote) {
+ items.multipleStaff.addMusicElement("note", currentNote, "Quarter", false, false, items.background.clefType)
+ items.multipleStaff.playNoteAudio(currentNote, "Quarter", items.background.clefType, 500)
+ if(!items.isTutorialMode) {
+ items.addNoteTimer.interval = items.addNoteTimer.timerNormalInterval
+ items.addNoteTimer.start()
+ }
+}
+
+function wrongAnswer() {
+ if(items.multipleStaff.musicElementRepeater.itemAt(1).x <= items.multipleStaff.clefImageWidth) {
+ items.multipleStaff.musicElementModel.remove(1)
+ currentNoteIndex = (currentNoteIndex + 1) % newNotesSequence.length
+ }
+
+ items.progressBar.percentage = Math.max(0, items.progressBar.percentage - percentageDecreaseValue)
+ items.multipleStaff.resumeNoteAnimation()
+ if(items.multipleStaff.musicElementModel.count <= 1)
+ items.addNoteTimer.restart()
+}
+
+function correctAnswer() {
+ currentNoteIndex = (currentNoteIndex + 1) % newNotesSequence.length
+ items.multipleStaff.pauseNoteAnimation()
+ items.multipleStaff.musicElementModel.remove(1)
+ items.multipleStaff.resumeNoteAnimation()
+ items.progressBar.percentage += percentageIncreaseValue
+ if(items.progressBar.percentage === 100) {
+ items.multipleStaff.pauseNoteAnimation()
+ items.displayNoteNameTimer.stop()
+ items.addNoteTimer.stop()
+ items.bonus.good("flower")
+ }
+ else if(items.multipleStaff.musicElementModel.count <= 1)
+ items.addNoteTimer.restart()
+}
+
+function checkAnswer(noteName) {
+ if(noteName === items.multipleStaff.musicElementModel.get(1).noteName_)
+ correctAnswer()
+ else
+ items.displayNoteNameTimer.start()
+}
+
+function nextLevel() {
+ if(numberOfLevel <= ++ currentLevel) {
+ currentLevel = 0
+ }
+ initLevel()
+}
+
+function previousLevel() {
+ if(--currentLevel < 0) {
+ currentLevel = numberOfLevel - 1
+ }
+ initLevel()
+}
diff --git a/src/activities/note_names/note_names.svg b/src/activities/note_names/note_names.svg
new file mode 100644
index 000000000..4fcf86672
--- /dev/null
+++ b/src/activities/note_names/note_names.svg
@@ -0,0 +1,149 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100"
+ height="100"
+ id="svg2"
+ sodipodi:version="0.32"
+ inkscape:version="0.92.1 r15371"
+ version="1.0"
+ sodipodi:docname="note_names.svg">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="3.1100436"
+ inkscape:cx="47.86201"
+ inkscape:cy="30.458319"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ width="100px"
+ height="100px"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ showgrid="false"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ <dc:date>2018</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Timothée Giet</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Calque 1"
+ inkscape:groupmode="layer"
+ id="layer1">
+ <path
+ inkscape:connector-curvature="0"
+ id="path3"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.39203209;stroke-linecap:round;stroke-linejoin:round"
+ d="m 33.881564,36.514553 c 0.947637,1.398692 1.434824,3.092263 2.655966,4.300236 1.398625,1.842004 3.1861,3.367753 4.57202,5.231727 1.003027,1.302406 2.102471,2.686672 2.387226,4.325052 0.766779,2.101545 0.433848,4.460845 -0.38419,6.518185 -0.922954,1.109437 -1.553941,-0.326373 -1.296318,-1.215319 0.03926,-1.226569 0.02137,-2.449895 -0.449063,-3.608434 -0.417218,-1.737446 -1.180179,-3.38165 -2.457504,-4.656527 -1.109901,-0.972851 -2.369954,-3.11655 -4.062004,-2.378425 -1.117378,0.703912 -0.630582,2.126824 -0.75083,3.223556 -0.06641,6.746623 -0.07086,13.495894 -0.178708,20.241193 -0.08246,2.832921 -2.531026,4.73349 -4.822893,5.949735 -2.041788,1.228686 -4.486389,1.916848 -6.856475,1.369243 -2.203919,-0.226142 -4.483808,-1.835055 -4.529999,-4.215663 -0.146937,-2.760259 1.84657,-5.330594 4.300633,-6.420641 2.409065,-1.373082 5.454806,-1.670675 8.048964,-0.683663 1.267663,0.400688 1.620182,-0.775646 1.778408,-1.90712 0.146401,-8.587634 0.263572,-17.175269 0.293516,-25.764226 0.02422,-0.858499 1.422516,-1.068012 1.751079,-0.308399 z" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect834"
+ width="82"
+ height="1"
+ x="10"
+ y="40"
+ ry="0" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect836"
+ width="2"
+ height="40"
+ x="90"
+ y="40" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect838"
+ width="82"
+ height="1"
+ x="10"
+ y="80" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect834-3"
+ width="82"
+ height="1"
+ x="10"
+ y="50"
+ ry="0" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect834-3-6"
+ width="82"
+ height="1"
+ x="10"
+ y="60"
+ ry="0" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect834-3-6-7"
+ width="82"
+ height="1"
+ x="10"
+ y="70"
+ ry="0" />
+ <g
+ style="display:inline"
+ id="g984"
+ transform="translate(16.04501,-11.844016)">
+ <path
+ inkscape:connector-curvature="0"
+ id="path1992"
+ d="m 39.894707,50.552436 5.712629,-4.536499 8.400923,0.336037 5.376591,3.192351 1.176129,5.712628 -2.016221,4.536498 -3.024332,3.192352 -2.016222,1.344148 -1.008111,2.856313 1.176129,2.856314 -2.520277,3.192351 -5.040554,1.344148 -2.352258,-1.848204 0.168018,-2.352258 0.672074,-2.016221 -0.840092,-1.512167 0.672074,-5.208572 0.168018,-4.872535 -3.528388,1.176129 z"
+ style="display:inline;fill:#faae55;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.81778818px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ id="text1953"
+ d="m 62.041897,53.219932 c -2.4e-5,1.504745 -0.316235,2.965858 -0.948634,4.383345 -0.04364,0.239895 -0.130868,0.567011 -0.261693,0.981345 -0.567021,1.810047 -1.711924,3.303872 -3.43471,4.48148 -0.54521,0.392544 -1.297575,0.774177 -2.257095,1.144903 -0.654247,0.261697 -1.068593,0.556101 -1.243038,0.883211 -1.6e-5,0.239889 -0.02182,0.5561 -0.06542,0.948634 -1.6e-5,0.13085 -0.05453,0.348926 -0.163558,0.654231 -0.109054,0.30531 -0.163572,0.501579 -0.163558,0.588807 -1.4e-5,0.04362 0.141735,0.272599 0.42525,0.686943 0.305292,0.414347 0.501561,0.719654 0.588808,0.915922 0.02179,0.06542 0.03269,0.294404 0.03271,0.686942 -1.6e-5,0.457961 -0.250804,1.199422 -0.752365,2.224384 -0.02182,0.174459 -0.07634,0.40344 -0.163557,0.686942 -0.348938,0.741458 -0.817803,1.37388 -1.406596,1.897269 -0.239898,0.239879 -0.817801,0.523378 -1.733711,0.850499 -1.373895,0.479763 -2.595124,0.719648 -3.663691,0.719654 -1.112199,-6e-6 -2.104448,-0.272602 -2.976749,-0.817788 -1.112196,-0.676044 -1.668292,-1.613773 -1.668288,-2.813191 -4e-6,-0.501579 0.119939,-1.046771 0.359827,-1.635577 0.196265,-0.457962 0.392534,-0.926827 0.588808,-1.406595 -0.174467,-0.08723 -0.414351,-0.261693 -0.719654,-0.523385 -0.152657,-0.196268 -0.228985,-0.795979 -0.228981,-1.799134 -4e-6,-1.766418 0.479765,-4.50328 1.439307,-8.210593 -0.109043,-0.08722 -0.18537,-0.130835 -0.22898,-0.130846 -0.04362,1.1e-5 -0.403447,0.207183 -1.079481,0.621519 -0.806887,0.479779 -1.38479,0.806893 -1.733711,0.981346 -0.218078,-0.174453 -0.348924,-0.33801 -0.392538,-0.490673 -0.348924,-1.635565 -0.915923,-4.06712 -1.700999,-7.294671 -0.04362,-0.174444 -0.152654,-0.490655 -0.327116,-0.948634 -0.196268,-0.457943 -0.294402,-0.719635 -0.294403,-0.785077 1e-6,-0.327096 0.588807,-1.046749 1.766422,-2.15896 1.046767,-0.937709 1.679189,-1.471997 1.897269,-1.602865 0.741457,-0.414324 1.493821,-0.817765 2.257095,-1.210327 1.003147,-0.545168 1.7228,-0.861378 2.158961,-0.948634 0.479761,-0.196245 1.221222,-0.436129 2.224384,-0.719654 1.482911,-0.21805 2.61691,-0.327089 3.401998,-0.327115 1.37387,2.6e-5 2.507869,0.04364 3.401999,0.130846 0.348906,0.130872 0.87229,0.305333 1.570153,0.523385 1.635557,0.436178 2.911305,1.341196 3.827249,2.715056 0.501554,0.785098 0.9159,1.75554 1.243038,2.911326 0.283477,1.003172 0.425226,2.071748 0.42525,3.20573 m -2.976749,1.308461 c -2e-5,-0.915907 -0.01092,-1.428387 -0.03271,-1.537442 -0.85052,-3.620055 -3.827265,-5.430091 -8.930247,-5.430113 -1.177626,2.2e-5 -2.5297,0.283521 -4.05623,0.8505 -0.152661,2.1e-5 -0.348929,0.02183 -0.588807,0.06542 -1.679197,0.763289 -2.889522,1.59198 -3.63098,2.486076 -0.283502,0.327133 -0.425253,0.63244 -0.425249,0.915922 -4e-6,0.588825 0.20717,1.984515 0.621519,4.187076 0.0218,0.152667 0.15265,0.327128 0.392538,0.523384 2.595108,-1.4611 4.350625,-2.191657 5.266556,-2.191672 0.981336,1.5e-5 1.777315,0.250803 2.387941,0.752365 0.63241,0.50159 0.948622,1.232148 0.948634,2.191672 -1.2e-5,0.109051 -0.109051,0.338031 -0.327115,0.686942 -0.196281,0.348934 -0.338031,0.5343 -0.42525,0.556096 -0.174473,0.08724 -0.425261,0.185377 -0.752365,0.294404 -0.109049,1.1e-5 -0.534298,1.1e-5 -1.275749,0 -0.08724,1.1e-5 -0.479779,-0.01089 -1.177615,-0.03271 -0.676046,-0.0436 -1.057681,-0.06541 -1.144904,-0.06542 -0.261699,1e-5 -0.457968,0.501587 -0.588807,1.50473 -0.109046,0.676046 -0.239891,1.591968 -0.392539,2.747768 -0.109044,0.174468 -0.163564,0.283506 -0.163557,0.327115 v 2.649634 c -7e-6,0.152657 0.04361,0.327118 0.130846,0.523384 0.13084,0.283503 0.283493,0.425253 0.457961,0.42525 0.06542,3e-6 0.78507,-0.152651 2.158961,-0.457961 0.04361,3e-6 0.719644,-0.08723 2.028115,-0.261692 0.872295,-0.109035 1.439295,-0.272593 1.700999,-0.490673 0.08722,-0.632419 0.20716,-1.548341 0.359827,-2.747769 0.08722,-0.08722 0.57789,-0.185359 1.472019,-0.294403 1.090368,-0.152647 2.191655,-0.752358 3.303864,-1.799134 1.112173,-1.046759 1.864537,-2.148047 2.257095,-3.303864 0.28348,-0.82868 0.42523,-1.85364 0.42525,-3.074884 m -7.00027,15.145436 c -1.4e-5,-0.436154 -0.207186,-0.817787 -0.621519,-1.144904 -0.39255,-0.348921 -0.828704,-0.523382 -1.308461,-0.523384 -0.894125,2e-6 -1.973605,0.305309 -3.238441,0.915923 -1.548353,0.763268 -2.322524,1.657382 -2.322518,2.682345 -6e-6,0.370728 0.07632,0.599709 0.22898,0.686942 0.436147,0.283497 0.915916,0.479766 1.439308,0.588808 0.414338,0.06542 0.785068,0.09813 1.112191,0.09813 0.654221,-3e-6 1.439297,-0.09814 2.35523,-0.294404 0.588796,-0.130849 1.133988,-0.567002 1.635577,-1.308461 0.479755,-0.654232 0.719639,-1.221231 0.719653,-1.700999"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;line-height:100%;font-family:'Indigo Joker';text-align:start;writing-mode:lr-tb;text-anchor:start;display:inline;fill:#4b4136;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ </g>
+ </g>
+</svg>
diff --git a/src/activities/note_names/resource/dataset_01.qml b/src/activities/note_names/resource/dataset_01.qml
new file mode 100644
index 000000000..bdd829285
--- /dev/null
+++ b/src/activities/note_names/resource/dataset_01.qml
@@ -0,0 +1,105 @@
+/* GCompris - dataset_01.qml
+ *
+ * Copyright (C) 2018 Aman Kumar Gupta <gupta2140@gmail.com>
+ *
+ * Authors:
+ * Beth Hadley <bethmhadley@gmail.com> (GTK+ version)
+ * Johnny Jazeix <jazeix@gmail.com> (Qt Quick port)
+ * Aman Kumar Gupta <gupta2140@gmail.com> (Qt Quick port)
+ *
+ * This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+ */
+import QtQuick 2.6
+
+QtObject {
+ property var levels: [
+ {
+ "clef": "Treble",
+ "sequence": ["C4", "G4"]
+ },
+ {
+ "clef": "Bass",
+ "sequence": ["C3", "F3"]
+ },
+ {
+ "clef": "Treble",
+ "sequence": ["B3", "D4", "F4", "A4"]
+ },
+ {
+ "clef": "Bass",
+ "sequence": ["B2", "D3","E3", "G3"]
+ },
+ {
+ "clef": "Treble",
+ "sequence": ["C5", "G5"]
+ },
+ {
+ "clef": "Bass",
+ "sequence": ["C2", "F2"]
+ },
+ {
+ "clef": "Treble",
+ "sequence": ["B4", "D5", "F5", "A5"]
+ },
+ {
+ "clef": "Bass",
+ "sequence": ["B1", "D2","E2", "G2"]
+ },
+ {
+ "clef": "Treble",
+ "sequence": ["E4", "E5"]
+ },
+ {
+ "clef": "Bass",
+ "sequence": ["B3", "D4"]
+ },
+ {
+ "clef": "Treble",
+ "sequence": ["G3", "C6"]
+ },
+ {
+ "clef": "Bass",
+ "sequence": ["A2", "A3", "C4", "E4"]
+ },
+ {
+ "clef": "Treble",
+ "sequence": ["F3", "A3"]
+ },
+ {
+ "clef": "Bass",
+ "sequence": ["G4", "A4"]
+ },
+ {
+ "clef": "Treble",
+ "sequence": ["B5", "D5"]
+ },
+ {
+ "clef": "Bass",
+ "sequence": ["B4"]
+ },
+ {
+ "clef": "Treble",
+ "sequence": ["D3", "E3"]
+ },
+ {
+ "clef": "Bass",
+ "sequence": ["F1", "G1", "A1"]
+ }
+ ]
+ property string objective: qsTr("This activity will teach you to read notes from F1 in bass clef up to D6 in treble clef.<br>For each level you will learn new notes and train the ones you have already learned.<br>Reference notes are colored in red and will help you to read the notes placed around them.")
+ property var referenceNotes: {
+ "Treble": ["C", "G"],
+ "Bass": ["F", "C"]
+ }
+}
diff --git a/src/activities/number_sequence/ActivityInfo.qml b/src/activities/number_sequence/ActivityInfo.qml
index 05970303f..9e9d31e64 100644
--- a/src/activities/number_sequence/ActivityInfo.qml
+++ b/src/activities/number_sequence/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Emmanuel Charruau <echarruau@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "number_sequence/NumberSequence.qml"
difficulty: 2
icon: "number_sequence/number_sequence.svg"
author: "Emmanuel Charruau &lt;echarruau@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Number sequence")
//: Help title
description: qsTr("Touch the numbers in the right sequence.")
// intro: "Draw the picture by touching the numbers in ascending order."
//: Help goal
goal: qsTr("Can count from 1 to 50.")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("Draw the picture by touching each number in the right sequence, or sliding your finger or dragging the mouse through the numbers in the correct sequence.")
credit: ""
section: "math numeration"
createdInVersion: 0
}
diff --git a/src/activities/number_sequence/NumberSequence.qml b/src/activities/number_sequence/NumberSequence.qml
index df89f1123..016e9f41f 100644
--- a/src/activities/number_sequence/NumberSequence.qml
+++ b/src/activities/number_sequence/NumberSequence.qml
@@ -1,263 +1,263 @@
/* GCompris - NumberSequence.qml
*
* Copyright (C) 2014 Emmanuel Charruau <echarruau@gmail.com>
*
* Authors:
* Olivier Ponchaut <opvg@mailoo.org> (GTK+ version)
* Emmanuel Charruau <echarruau@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "."
import "number_sequence.js" as Activity
import "number_sequence_dataset.js" as Dataset
ActivityBase {
id: activity
property string mode: "number_sequence"
property var dataset: Dataset
property real pointImageOpacity: 1.0
property string url: "qrc:/gcompris/src/activities/number_sequence/resource/"
onStart: focus = true
onStop: {}
pageComponent: Image {
id: background
anchors.fill: parent
source: "qrc:/gcompris/src/activities/checkers/resource/background-wood.svg"
- sourceSize.width: parent.witdh
+ sourceSize.width: parent.width
sourceSize.height: parent.height
signal start
signal stop
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property alias background: background
property alias bar: bar
property alias bonus: bonus
property GCSfx audioEffects: activity.audioEffects
property GCAudio audioVoices: activity.audioVoices
property alias pointImageRepeater: pointImageRepeater
property alias segmentsRepeater: segmentsRepeater
property alias imageBack: imageBack
property alias imageBack2: imageBack2
property int pointIndexToClick
}
onStart: { Activity.start(items,mode,dataset,url) }
onStop: { Activity.stop() }
Image {
id: imageBack
anchors.top: parent.top
anchors.horizontalCenter: background.horizontalCenter
width: Math.min((background.height - bar.height * 1.5), background.width)
height: imageBack.width
sourceSize.width: imageBack.width
sourceSize.height: imageBack.height
}
Image {
id: imageBack2
anchors.centerIn: imageBack
width: imageBack.width
height: imageBack.height
sourceSize.width: imageBack2.width
sourceSize.height: imageBack2.height
}
Repeater {
id: segmentsRepeater
Rectangle {
id: line
opacity: 0
color: "#373737"
transformOrigin: Item.TopLeft
x: imageBack.x + modelData[0] * imageBack.width / 520
y: modelData[1] * imageBack.height / 520
property double x2: imageBack.x + modelData[2] * imageBack.width / 520
property double y2: modelData[3] * imageBack.height / 520
width: Math.sqrt(Math.pow(x - x2, 2) + Math.pow(y- y2, 2))
height: 3 * ApplicationInfo.ratio
rotation: (Math.atan((y2 - y)/(x2-x)) * 180 / Math.PI) + (((y2-y) < 0 && (x2-x) < 0) * 180) + (((y2-y) >= 0 && (x2-x) < 0) * 180)
}
}
Item {
id: playArea
anchors.fill: parent
Repeater {
id: pointImageRepeater
Image {
id: pointImage
source: Activity.url + (highlight ?
(pointImageOpacity ? "bluepoint.svg" : "bluepointHighlight.svg") :
markedAsPointInternal ? "blackpoint.svg" : "greenpoint.svg")
sourceSize.height: bar.height / 4 //to change the size of dots
x: imageBack.x + modelData[0] * imageBack.width / 520 - sourceSize.height/2
y: modelData[1] * imageBack.height / 520 - sourceSize.height/2
z: items.pointIndexToClick == index ? 1000 : index
// only hide last point for clickanddraw and number_sequence
// as the last point is also the first point
visible: (mode=="clickanddraw" || mode=="number_sequence") &&
index == pointImageRepeater.count - 1 &&
items.pointIndexToClick == 0 ? false : true
function drawSegment() {
Activity.drawSegment(index)
}
property bool highlight: false
// draw a point instead of hiding the clicked node if it is
// the first point of the current line to draw
// (helpful to know where the line starts)
property bool markedAsPointInternal: markedAsPoint && items.pointIndexToClick == index+1
property bool markedAsPoint: false
scale: markedAsPointInternal ? 0.2 : 1
opacity: index >= items.pointIndexToClick || markedAsPointInternal ? 1 : 0
GCText {
id: pointNumberText
opacity: pointImageOpacity
text: index + 1
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
fontSize: 11
font.weight: Font.DemiBold
style: Text.Outline
styleColor: "black"
color: "white"
}
ParallelAnimation {
id: anim
running: pointImageOpacity == 0 && items.pointIndexToClick == index
loops: Animation.Infinite
SequentialAnimation {
NumberAnimation {
target: pointImage
property: "rotation"
from: -150; to: 150
duration: 3000
easing.type: Easing.InOutQuad
}
NumberAnimation {
target: pointImage
property: "rotation"
from: 150; to: -150
duration: 3000
easing.type: Easing.InOutQuad
}
}
SequentialAnimation {
NumberAnimation {
target: pointImage
property: "scale"
from: 1; to: 1.5
duration: 1500
easing.type: Easing.InOutQuad
}
NumberAnimation {
target: pointImage
property: "scale"
from: 1.5; to: 1
duration: 1500
easing.type: Easing.InOutQuad
}
NumberAnimation {
target: pointImage
property: "scale"
from: 1; to: 1.5
duration: 1500
easing.type: Easing.InOutQuad
}
NumberAnimation {
target: pointImage
property: "scale"
from: 1.5; to: 1
duration: 1500
easing.type: Easing.InOutQuad
}
}
}
}
}
}
MultiPointTouchArea {
anchors.fill: parent
minimumTouchPoints: 1
maximumTouchPoints: 1
z: 100
function checkPoints(touchPoints) {
for(var i in touchPoints) {
var touch = touchPoints[i]
for(var p = 0; p < pointImageRepeater.count; p++) {
var part = pointImageRepeater.itemAt(p)
// Could not make it work with the item.contains() api
if(touch.x > part.x && touch.x < part.x + part.width &&
touch.y > part.y && touch.y < part.y + part.height) {
part.drawSegment()
}
}
}
}
onPressed: {
checkPoints(touchPoints)
}
onTouchUpdated: {
checkPoints(touchPoints)
}
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level }
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
}
Bonus {
id: bonus
Component.onCompleted: win.connect(Activity.nextLevel)
}
}
}
diff --git a/src/activities/number_sequence/number_sequence.js b/src/activities/number_sequence/number_sequence.js
index a365e1ec6..30a45e653 100644
--- a/src/activities/number_sequence/number_sequence.js
+++ b/src/activities/number_sequence/number_sequence.js
@@ -1,148 +1,148 @@
/* GCompris - number_sequence.js
*
* Copyright (C) 2014 Emmanuel Charruau
*
* Authors:
* Olivier Ponchaut <opvg@mailoo.org> (GTK+ version)
* Emmanuel Charruau <echarruau@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
.import GCompris 1.0 as GCompris //for ApplicationInfo
.import "qrc:/gcompris/src/core/core.js" as Core
var currentLevel = 0
var items
var mode
var dataset
var numberOfLevel
var pointPositions = []
var pointPositions2 = []
var linePropertiesArray = []
var url
function start(_items, _mode,_dataset,_url) {
items = _items
mode = _mode
dataset = _dataset.get()
url = _url
numberOfLevel = dataset.length
currentLevel = 0
initLevel()
}
function stop() {
}
function initLevel() {
items.bar.level = currentLevel + 1
items.pointIndexToClick = 0
loadCoordinates()
loadBackgroundImage()
if(mode == "drawletters" || mode == "drawnumbers") {
//function to play letter sound at start
playLetterSound(dataset[currentLevel].sound)
}
}
function nextLevel() {
if(numberOfLevel <= ++currentLevel) {
currentLevel = 0
}
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
initLevel();
}
-//function to play the sound of chararcter at start & end
+//function to play the sound of character at start & end
function playLetterSound(sound) {
// first we clear the queue in case other voices are there, then we append the new number
// if we play directly, we don't have the bonus sound (or it is truncated)
items.audioVoices.clearQueue()
items.audioVoices.append(sound)
}
function drawSegment(pointIndex) {
if (pointIndex == items.pointIndexToClick) {
var currentPoint = items.pointImageRepeater.itemAt(pointIndex)
// if we need to draw only a point instead of a line
if(mode == "drawletters" || mode == "drawnumbers") {
currentPoint.highlight = false
if(pointIndex == 0 || (pointPositions2 && pointPositions2[pointIndex] != pointPositions2[pointIndex-1])) {
currentPoint.markedAsPoint = true
}
}
if (mode == "clickanddraw" || mode == "drawletters" || mode == "drawnumbers") {
if (pointIndex < items.pointImageRepeater.count-1) {
items.pointImageRepeater.itemAt(pointIndex+1).highlight = true
items.audioEffects.play('qrc:/gcompris/src/core/resource/sounds/audioclick.wav')
}
}
// Draw the line from pointIndex - 1 to pointIndex
if(pointIndex == 0 || (pointPositions2 && pointPositions2[pointIndex] != pointPositions2[pointIndex-1])) {
//do nothing
}
else {
items.segmentsRepeater.itemAt(pointIndex-1).opacity = 1
}
if (pointIndex == items.pointImageRepeater.count-1) {
for (var i = 1; i < dataset[currentLevel].coordinates.length; i++) {
items.segmentsRepeater.itemAt(i-1).opacity = 0
}
items.imageBack2.source = url + dataset[currentLevel].imageName2
won()
}
items.pointIndexToClick++
}
}
function loadCoordinates() {
// prepare points data
pointPositions = dataset[currentLevel].coordinates
pointPositions2 = dataset[currentLevel].coordinates2
items.pointImageRepeater.model = pointPositions
if (mode == "clickanddraw" || mode == "drawletters" || mode == "drawnumbers")
items.pointImageRepeater.itemAt(0).highlight = true
// prepare segments data
linePropertiesArray = []
for (var i = 0; i < (pointPositions.length)-1; i++) {
var lineProperties = [] // properties are x1,y1,x2,y,angle rotation
lineProperties[0] = pointPositions[i][0] // x
lineProperties[1] = pointPositions[i][1] // y
lineProperties[2] = pointPositions[i+1][0] // x2
lineProperties[3] = pointPositions[i+1][1] // y2
linePropertiesArray[i] = lineProperties
}
items.segmentsRepeater.model = linePropertiesArray
}
function loadBackgroundImage() {
items.imageBack.source = url + dataset[currentLevel].imageName1
items.imageBack2.source = url + dataset[currentLevel].imageName1
}
function won() {
items.bonus.good("flower")
}
diff --git a/src/activities/number_sequence/number_sequence_dataset.js b/src/activities/number_sequence/number_sequence_dataset.js
index 0f0561c6f..eb050240f 100644
--- a/src/activities/number_sequence/number_sequence_dataset.js
+++ b/src/activities/number_sequence/number_sequence_dataset.js
@@ -1,70 +1,70 @@
/* GCompris - number_sequence_dataset.js
* Copyright (C) 2014 Emmanuel Charruau <echarruau@gmail.com>
*
* Authors: Emmanuel Charruau <echarruau@gmail.com> (initial set)
* Timothée Giet <animtim@gmail.com> (update set ratio)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
function get() {
return [
{
"imageName1": "dn_fond1.svg",
"imageName2": "dn_fond2.svg",
"coordinates": [[267,121],[349,369],[139,216],[397,214],[190,369],[267,121]]
},
{
"imageName1": "de1.svg",
"imageName2": "de2.svg",
"coordinates": [[104,275],[106,171],[203,133],[288,178],[288,237],[311,211],[427,220],[428,324],[382,386],[260,374],[260,297],[195,323],[104,275]]
},
{
"imageName1": "house1.svg",
"imageName2": "house2.svg",
"coordinates": [[306,360],[412,360],[413,175],[356,120],[355,70],[330,70],[330,96],[272,40],[119,177],[120,361],[253,361],[252,276],[306,276],[306,360]]
},
{
"imageName1": "sapin1.svg",
"imageName2": "sapin2.svg",
"coordinates": [[104,463],[201,361],[127,373],[221,238],[160,251],[237,127],[189,146],[259,52],[324,144],[276,128],[352,251],[295,239],[387,371],[318,362],[417,466],[282,453],[282,504],[234,504],[234,453],[104,463]]
},
{
"imageName1": "epouvantail1.svg",
"imageName2": "epouvantail2.svg",
"coordinates": [[105,449],[190,340],[190,224],[62,233],[58,168],[245,160],[218,135],[217,77],[190,79],[189,68],[213,65],[209,30],[310,30],[314,56],[338,54],[339,66],[313,68],[312,135],[284,161],[462,163],[457,223],[327,221],[327,337],[411,457],[357,487],[263,377],[159,491],[105,449]]
},
{
"imageName1": "plane1.svg",
"imageName2": "plane2.svg",
"coordinates": [[228,296],[106,299],[85,278],[103,253],[142,237],[133,220],[148,213],[103,159],[108,140],[130,138],[247,223],[332,222],[377,214],[351,197],[352,187],[369,188],[395,198],[428,164],[438,216],[470,236],[472,248],[451,247],[428,240],[378,265],[308,280],[394,352],[392,382],[350,370],[266,316],[228,324],[214,310],[228,296]]
},
{
"imageName1": "fish1.svg",
"imageName2": "fish2.svg",
"coordinates": [[21,320],[50,256],[100,212],[209,203],[244,156],[276,146],[294,156],[302,175],[292,204],[314,215],[342,195],[360,207],[355,225],[365,242],[408,258],[446,246],[462,222],[480,215],[494,226],[498,278],[481,349],[469,373],[440,366],[424,335],[362,328],[318,339],[325,357],[322,378],[299,392],[268,388],[226,352],[202,352],[210,360],[206,380],[188,382],[172,360],[52,360],[35,350],[32,322],[21,320]]
},
{
"imageName1": "carnaval1.svg",
"imageName2": "carnaval2.svg",
"coordinates": [[135,204],[192,143],[224,180],[246,118],[265,188],[269,120],[277,179],[312,154],[364,203],[315,188],[286,224],[286,236],[284,296],[279,315],[320,306],[364,262],[384,184],[404,186],[386,279],[313,366],[304,473],[312,518],[208,518],[220,473],[202,365],[177,402],[200,468],[180,483],[148,407],[180,333],[227,317],[219,295],[214,235],[213,223],[183,189],[135,204]]
},
{
"imageName1": "bear1.svg",
"imageName2": "bear2.svg",
"coordinates": [[154,256],[112,240],[66,206],[42,174],[45,159],[66,154],[107,167],[150,188],[184,220],[202,206],[220,200],[192,185],[171,154],[169,117],[187,90],[170,76],[165,55],[185,38],[210,40],[226,52],[227,66],[250,59],[281,60],[300,66],[301,48],[318,37],[340,36],[357,48],[360,70],[351,82],[336,86],[352,110],[356,136],[349,164],[329,189],[308,200],[330,212],[372,180],[428,158],[461,154],[472,164],[468,184],[442,213],[400,236],[365,251],[379,286],[382,329],[376,364],[398,354],[416,360],[426,384],[421,417],[398,455],[370,470],[343,456],[340,419],[311,440],[264,453],[210,441],[180,422],[181,450],[167,471],[134,467],[105,434],[92,402],[98,366],[121,354],[146,364],[138,326],[142,282],[154,256]]
}
]
}
diff --git a/src/activities/numbers-odd-even/ActivityInfo.qml b/src/activities/numbers-odd-even/ActivityInfo.qml
index 1cbcf4493..cd2155cce 100644
--- a/src/activities/numbers-odd-even/ActivityInfo.qml
+++ b/src/activities/numbers-odd-even/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "numbers-odd-even/NumbersOddEven.qml"
difficulty: 2
icon: "numbers-odd-even/numbers-odd-even.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
//: Activity title
title: qsTr("Even and Odd Numbers")
//: Help title
description: qsTr("Move the helicopter to catch the clouds having even or odd numbers")
// intro: "Move the helicopter to catch the clouds having even or odd numbers, in the shown order."
//: Help goal
goal: qsTr("Numeration training")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("Catch the odd or even number clouds. With a keyboard use the arrow keys to move the helicopter. With a pointing device you just click or tap on the target location. To know which number you have to catch you can either remember it or check the bottom right corner.")
credit: ""
section: "math numeration"
createdInVersion: 0
}
diff --git a/src/activities/numbers-odd-even/NumbersOddEven.qml b/src/activities/numbers-odd-even/NumbersOddEven.qml
index 672b5d5b1..fade95cea 100644
--- a/src/activities/numbers-odd-even/NumbersOddEven.qml
+++ b/src/activities/numbers-odd-even/NumbersOddEven.qml
@@ -1,42 +1,42 @@
/* gcompris - NumberOddEven.qml
Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../planegame"
Planegame {
dataset: [
{
data: "0 2 4 6 8 10 12 14 16 18 20".split(" "),
showNext: true
},
{
data: "1 3 5 7 9 11 13 15 17 19 21".split(" "),
showNext: true
},
{
data: "0 2 4 6 8 10 12 14 16 18 20".split(" "),
showNext: false
},
{
data: "1 3 5 7 9 11 13 15 17 19 21".split(" "),
showNext: false
}
]
}
diff --git a/src/activities/paintings/ActivityInfo.qml b/src/activities/paintings/ActivityInfo.qml
index 220916604..ac86f40a8 100644
--- a/src/activities/paintings/ActivityInfo.qml
+++ b/src/activities/paintings/ActivityInfo.qml
@@ -1,44 +1,44 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Bruno Coudoin (bruno.coudoin@gcompris.net) (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "paintings/Paintings.qml"
difficulty: 1
icon: "paintings/paintings.svg"
author: "Pulkit Gupta &lt;pulkitgenius@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Assemble the puzzle")
//: Help title
description: qsTr("Drag and Drop the items to rebuild the original paintings")
// intro: "Catch and drop each piece on the points."
//: Help goal
goal: qsTr("Spatial representation")
//: Help prerequisite
prerequisite: qsTr("Mouse-manipulation: movement, drag and drop")
//: Help manual
manual: qsTr("Drag the image parts from the box on the left to create a painting on the main board.")
section: "puzzle"
createdInVersion: 5000
}
diff --git a/src/activities/paintings/Paintings.qml b/src/activities/paintings/Paintings.qml
index ce60e3473..8ddfd7221 100644
--- a/src/activities/paintings/Paintings.qml
+++ b/src/activities/paintings/Paintings.qml
@@ -1,35 +1,35 @@
/* GCompris - Babyshapes.qml
*
* Copyright (C) 2015 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Bruno Coudoin (bruno.coudoin@gcompris.net) (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../babymatch"
Babymatch {
id: activity
onStart: focus = true
onStop: {}
boardsUrl: "qrc:/gcompris/src/activities/paintings/resource/"
levelCount: 22
answerGlow: false
}
diff --git a/src/activities/paintings/resource/board/board10_0.qml b/src/activities/paintings/resource/board/board10_0.qml
index 95b641a1b..6ea4d7cb5 100644
--- a/src/activities/paintings/resource/board/board10_0.qml
+++ b/src/activities/paintings/resource/board/board10_0.qml
@@ -1,134 +1,134 @@
/* GCompris
*
* Copyright (C) 2015 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Katsushika Hokusai, Viewing Sunset over the Ryogoku Bridge from the Ommaya Embankment - 1830")
property var levels : [
{
"pixmapfile" : "image/bg.svg",
"type" : "SHAPE_BACKGROUND_IMAGE",
"width": 702,
"height": 515
},
{
"pixmapfile" : "image/HokusaiBridge_e4.png",
"x" : "0.869",
"y" : "0.798"
},
{
"pixmapfile" : "image/HokusaiBridge_d4.png",
"x" : "0.687",
"y" : "0.798"
},
{
"pixmapfile" : "image/HokusaiBridge_c4.png",
"x" : "0.497",
"y" : "0.819"
},
{
"pixmapfile" : "image/HokusaiBridge_b4.png",
"x" : "0.311",
"y" : "0.819"
},
{
"pixmapfile" : "image/HokusaiBridge_a4.png",
"x" : "0.125",
"y" : "0.798"
},
{
"pixmapfile" : "image/HokusaiBridge_e3.png",
"x" : "0.869",
"y" : "0.585"
},
{
"pixmapfile" : "image/HokusaiBridge_d3.png",
"x" : "0.687",
"y" : "0.607"
},
{
"pixmapfile" : "image/HokusaiBridge_c3.png",
"x" : "0.479",
"y" : "0.63"
},
{
"pixmapfile" : "image/HokusaiBridge_b3.png",
"x" : "0.309",
"y" : "0.609"
},
{
"pixmapfile" : "image/HokusaiBridge_a3.png",
"x" : "0.145",
"y" : "0.585"
},
{
"pixmapfile" : "image/HokusaiBridge_e2.png",
"x" : "0.869",
"y" : "0.388"
},
{
"pixmapfile" : "image/HokusaiBridge_d2.png",
"x" : "0.687",
"y" : "0.412"
},
{
"pixmapfile" : "image/HokusaiBridge_c2.png",
"x" : "0.479",
"y" : "0.39"
},
{
"pixmapfile" : "image/HokusaiBridge_b2.png",
"x" : "0.291",
"y" : "0.388"
},
{
"pixmapfile" : "image/HokusaiBridge_a2.png",
"x" : "0.125",
"y" : "0.388"
},
{
"pixmapfile" : "image/HokusaiBridge_e1.png",
"x" : "0.869",
"y" : "0.197"
},
{
"pixmapfile" : "image/HokusaiBridge_d1.png",
"x" : "0.705",
"y" : "0.197"
},
{
"pixmapfile" : "image/HokusaiBridge_c1.png",
"x" : "0.517",
"y" : "0.174"
},
{
"pixmapfile" : "image/HokusaiBridge_b1.png",
"x" : "0.311",
"y" : "0.197"
},
{
"pixmapfile" : "image/HokusaiBridge_a1.png",
"x" : "0.125",
"y" : "0.197"
}
]
}
diff --git a/src/activities/paintings/resource/board/board11_0.qml b/src/activities/paintings/resource/board/board11_0.qml
index 0348add88..887c36a30 100644
--- a/src/activities/paintings/resource/board/board11_0.qml
+++ b/src/activities/paintings/resource/board/board11_0.qml
@@ -1,159 +1,159 @@
/* GCompris
*
* Copyright (C) 2015 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Katsushika Hokusa, Poppies - 1833-1834")
property var levels : [
{
"pixmapfile" : "image/bg.svg",
"type" : "SHAPE_BACKGROUND_IMAGE",
"width": 702,
"height": 515
},
{
"pixmapfile" : "image/HokusaiPoppies_e5.png",
"x" : "0.848",
"y" : "0.825"
},
{
"pixmapfile" : "image/HokusaiPoppies_d5.png",
"x" : "0.665",
"y" : "0.825"
},
{
"pixmapfile" : "image/HokusaiPoppies_c5.png",
"x" : "0.496",
"y" : "0.842"
},
{
"pixmapfile" : "image/HokusaiPoppies_b5.png",
"x" : "0.311",
"y" : "0.842"
},
{
"pixmapfile" : "image/HokusaiPoppies_a5.png",
"x" : "0.127",
"y" : "0.825"
},
{
"pixmapfile" : "image/HokusaiPoppies_e4.png",
"x" : "0.865",
"y" : "0.671"
},
{
"pixmapfile" : "image/HokusaiPoppies_d4.png",
"x" : "0.702",
"y" : "0.671"
},
{
"pixmapfile" : "image/HokusaiPoppies_c4.png",
"x" : "0.498",
"y" : "0.673"
},
{
"pixmapfile" : "image/HokusaiPoppies_b4.png",
"x" : "0.31",
"y" : "0.689"
},
{
"pixmapfile" : "image/HokusaiPoppies_a4.png",
"x" : "0.147",
"y" : "0.654"
},
{
"pixmapfile" : "image/HokusaiPoppies_e3.png",
"x" : "0.865",
"y" : "0.515"
},
{
"pixmapfile" : "image/HokusaiPoppies_d3.png",
"x" : "0.702",
"y" : "0.515"
},
{
"pixmapfile" : "image/HokusaiPoppies_c3.png",
"x" : "0.498",
"y" : "0.496"
},
{
"pixmapfile" : "image/HokusaiPoppies_b3.png",
"x" : "0.31",
"y" : "0.498"
},
{
"pixmapfile" : "image/HokusaiPoppies_a3.png",
"x" : "0.147",
"y" : "0.496"
},
{
"pixmapfile" : "image/HokusaiPoppies_e2.png",
"x" : "0.848",
"y" : "0.34"
},
{
"pixmapfile" : "image/HokusaiPoppies_d2.png",
"x" : "0.683",
"y" : "0.34"
},
{
"pixmapfile" : "image/HokusaiPoppies_c2.png",
"x" : "0.516",
"y" : "0.323"
},
{
"pixmapfile" : "image/HokusaiPoppies_b2.png",
"x" : "0.329",
"y" : "0.305"
},
{
"pixmapfile" : "image/HokusaiPoppies_a2.png",
"x" : "0.147",
"y" : "0.34"
},
{
"pixmapfile" : "image/HokusaiPoppies_e1.png",
"x" : "0.865",
"y" : "0.169"
},
{
"pixmapfile" : "image/HokusaiPoppies_d1.png",
"x" : "0.702",
"y" : "0.169"
},
{
"pixmapfile" : "image/HokusaiPoppies_c1.png",
"x" : "0.516",
"y" : "0.15"
},
{
"pixmapfile" : "image/HokusaiPoppies_b1.png",
"x" : "0.311",
"y" : "0.15"
},
{
"pixmapfile" : "image/HokusaiPoppies_a1.png",
"x" : "0.127",
"y" : "0.169"
}
]
}
diff --git a/src/activities/paintings/resource/board/board12_0.qml b/src/activities/paintings/resource/board/board12_0.qml
index 318223b7f..97a2a349b 100644
--- a/src/activities/paintings/resource/board/board12_0.qml
+++ b/src/activities/paintings/resource/board/board12_0.qml
@@ -1,159 +1,159 @@
/* GCompris
*
* Copyright (C) 2015 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Katsushika Hokusai, Kazusa sea Route - 1830.")
property var levels : [
{
"pixmapfile" : "image/bg.svg",
"type" : "SHAPE_BACKGROUND_IMAGE",
"width": 702,
"height": 515
},
{
"pixmapfile" : "image/KazusaSeaRoute_e5.png",
"x" : "0.863",
"y" : "0.842"
},
{
"pixmapfile" : "image/KazusaSeaRoute_d5.png",
"x" : "0.693",
"y" : "0.825"
},
{
"pixmapfile" : "image/KazusaSeaRoute_c5.png",
"x" : "0.519",
"y" : "0.842"
},
{
"pixmapfile" : "image/KazusaSeaRoute_b5.png",
"x" : "0.323",
"y" : "0.825"
},
{
"pixmapfile" : "image/KazusaSeaRoute_a5.png",
"x" : "0.132",
"y" : "0.825"
},
{
"pixmapfile" : "image/KazusaSeaRoute_e4.png",
"x" : "0.863",
"y" : "0.689"
},
{
"pixmapfile" : "image/KazusaSeaRoute_d4.png",
"x" : "0.693",
"y" : "0.671"
},
{
"pixmapfile" : "image/KazusaSeaRoute_c4.png",
"x" : "0.499",
"y" : "0.689"
},
{
"pixmapfile" : "image/KazusaSeaRoute_b4.png",
"x" : "0.303",
"y" : "0.654"
},
{
"pixmapfile" : "image/KazusaSeaRoute_a4.png",
"x" : "0.132",
"y" : "0.654"
},
{
"pixmapfile" : "image/KazusaSeaRoute_e3.png",
"x" : "0.882",
"y" : "0.498"
},
{
"pixmapfile" : "image/KazusaSeaRoute_d3.png",
"x" : "0.713",
"y" : "0.515"
},
{
"pixmapfile" : "image/KazusaSeaRoute_c3.png",
"x" : "0.499",
"y" : "0.515"
},
{
"pixmapfile" : "image/KazusaSeaRoute_b3.png",
"x" : "0.303",
"y" : "0.496"
},
{
"pixmapfile" : "image/KazusaSeaRoute_a3.png",
"x" : "0.132",
"y" : "0.48"
},
{
"pixmapfile" : "image/KazusaSeaRoute_e2.png",
"x" : "0.882",
"y" : "0.321"
},
{
"pixmapfile" : "image/KazusaSeaRoute_d2.png",
"x" : "0.694",
"y" : "0.34"
},
{
"pixmapfile" : "image/KazusaSeaRoute_c2.png",
"x" : "0.499",
"y" : "0.323"
},
{
"pixmapfile" : "image/KazusaSeaRoute_b2.png",
"x" : "0.304",
"y" : "0.323"
},
{
"pixmapfile" : "image/KazusaSeaRoute_a2.png",
"x" : "0.113",
"y" : "0.305"
},
{
"pixmapfile" : "image/KazusaSeaRoute_e1.png",
"x" : "0.882",
"y" : "0.169"
},
{
"pixmapfile" : "image/KazusaSeaRoute_d1.png",
"x" : "0.713",
"y" : "0.169"
},
{
"pixmapfile" : "image/KazusaSeaRoute_c1.png",
"x" : "0.499",
"y" : "0.15"
},
{
"pixmapfile" : "image/KazusaSeaRoute_b1.png",
"x" : "0.303",
"y" : "0.15"
},
{
"pixmapfile" : "image/KazusaSeaRoute_a1.png",
"x" : "0.132",
"y" : "0.15"
}
]
}
diff --git a/src/activities/paintings/resource/board/board13_0.qml b/src/activities/paintings/resource/board/board13_0.qml
index 781e2c6b8..8e3eb0758 100644
--- a/src/activities/paintings/resource/board/board13_0.qml
+++ b/src/activities/paintings/resource/board/board13_0.qml
@@ -1,95 +1,95 @@
/* GCompris
*
* Copyright (C) 2015 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property int numberOfSubLevel: 4
property string instruction: qsTr("Michelangelo, Pieta - 1499")
property var levels : [
{
"pixmapfile" : "image/bg.svg",
"type" : "SHAPE_BACKGROUND_IMAGE",
"width": 702,
"height": 515
},
{
"pixmapfile" : "image/Michelangelo_Pieta_c4.png",
"x" : "0.696",
"y" : "0.854"
},
{
"pixmapfile" : "image/Michelangelo_Pieta_b4.png",
"x" : "0.474",
"y" : "0.854"
},
{
"pixmapfile" : "image/Michelangelo_Pieta_a4.png",
"x" : "0.275",
"y" : "0.831"
},
{
"pixmapfile" : "image/Michelangelo_Pieta_c3.png",
"x" : "0.719",
"y" : "0.619"
},
{
"pixmapfile" : "image/Michelangelo_Pieta_b3.png",
"x" : "0.521",
"y" : "0.619"
},
{
"pixmapfile" : "image/Michelangelo_Pieta_a3.png",
"x" : "0.298",
"y" : "0.617"
},
{
"pixmapfile" : "image/Michelangelo_Pieta_c2.png",
"x" : "0.696",
"y" : "0.352"
},
{
"pixmapfile" : "image/Michelangelo_Pieta_b2.png",
"x" : "0.474",
"y" : "0.352"
},
{
"pixmapfile" : "image/Michelangelo_Pieta_a2.png",
"x" : "0.275",
"y" : "0.377"
},
{
"pixmapfile" : "image/Michelangelo_Pieta_c1.png",
"x" : "0.696",
"y" : "0.138"
},
{
"pixmapfile" : "image/Michelangelo_Pieta_b1.png",
"x" : "0.497",
"y" : "0.138"
},
{
"pixmapfile" : "image/Michelangelo_Pieta_a1.png",
"x" : "0.298",
"y" : "0.138"
}
]
}
diff --git a/src/activities/paintings/resource/board/board14_0.qml b/src/activities/paintings/resource/board/board14_0.qml
index dba96c6df..39f387db7 100644
--- a/src/activities/paintings/resource/board/board14_0.qml
+++ b/src/activities/paintings/resource/board/board14_0.qml
@@ -1,94 +1,94 @@
/* GCompris
*
* Copyright (C) 2015 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Leonardo da Vinci, Mona Lisa - 1503-19")
property var levels : [
{
"pixmapfile" : "image/bg.svg",
"type" : "SHAPE_BACKGROUND_IMAGE",
"width": 702,
"height": 515
},
{
"pixmapfile" : "image/MonaLisa_d3.png",
"x" : "0.667",
"y" : "0.782"
},
{
"pixmapfile" : "image/MonaLisa_c3.png",
"x" : "0.568",
"y" : "0.814"
},
{
"pixmapfile" : "image/MonaLisa_b3.png",
"x" : "0.442",
"y" : "0.814"
},
{
"pixmapfile" : "image/MonaLisa_a3.png",
"x" : "0.328",
"y" : "0.814"
},
{
"pixmapfile" : "image/MonaLisa_d2.png",
"x" : "0.667",
"y" : "0.497"
},
{
"pixmapfile" : "image/MonaLisa_c2.png",
"x" : "0.568",
"y" : "0.499"
},
{
"pixmapfile" : "image/MonaLisa_b2.png",
"x" : "0.453",
"y" : "0.499"
},
{
"pixmapfile" : "image/MonaLisa_a2.png",
"x" : "0.34",
"y" : "0.531"
},
{
"pixmapfile" : "image/MonaLisa_d1.png",
"x" : "0.656",
"y" : "0.214"
},
{
"pixmapfile" : "image/MonaLisa_c1.png",
"x" : "0.556",
"y" : "0.18"
},
{
"pixmapfile" : "image/MonaLisa_b1.png",
"x" : "0.442",
"y" : "0.18"
},
{
"pixmapfile" : "image/MonaLisa_a1.png",
"x" : "0.328",
"y" : "0.214"
}
]
}
diff --git a/src/activities/paintings/resource/board/board15_0.qml b/src/activities/paintings/resource/board/board15_0.qml
index cf82edc30..b58f977d0 100644
--- a/src/activities/paintings/resource/board/board15_0.qml
+++ b/src/activities/paintings/resource/board/board15_0.qml
@@ -1,79 +1,79 @@
/* GCompris
*
* Copyright (C) 2015 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Giovanni Bellini, La Pala di Pesaro - 1475-85")
property var levels : [
{
"pixmapfile" : "image/bg.svg",
"type" : "SHAPE_BACKGROUND_IMAGE",
"width": 702,
"height": 515
},
{
"pixmapfile" : "image/PalaDiPesaro_c3.png",
"x" : "0.814",
"y" : "0.705"
},
{
"pixmapfile" : "image/PalaDiPesaro_b3.png",
"x" : "0.499",
"y" : "0.727"
},
{
"pixmapfile" : "image/PalaDiPesaro_a3.png",
"x" : "0.182",
"y" : "0.705"
},
{
"pixmapfile" : "image/PalaDiPesaro_c2.png",
"x" : "0.814",
"y" : "0.474"
},
{
"pixmapfile" : "image/PalaDiPesaro_b2.png",
"x" : "0.532",
"y" : "0.498"
},
{
"pixmapfile" : "image/PalaDiPesaro_a2.png",
"x" : "0.215",
"y" : "0.474"
},
{
"pixmapfile" : "image/PalaDiPesaro_c1.png",
"x" : "0.781",
"y" : "0.264"
},
{
"pixmapfile" : "image/PalaDiPesaro_b1.png",
"x" : "0.466",
"y" : "0.264"
},
{
"pixmapfile" : "image/PalaDiPesaro_a1.png",
"x" : "0.182",
"y" : "0.264"
}
]
}
diff --git a/src/activities/paintings/resource/board/board16_0.qml b/src/activities/paintings/resource/board/board16_0.qml
index dbdae8b49..5118ae962 100644
--- a/src/activities/paintings/resource/board/board16_0.qml
+++ b/src/activities/paintings/resource/board/board16_0.qml
@@ -1,114 +1,114 @@
/* GCompris
*
* Copyright (C) 2015 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Albrecht Dürer, Lion - 1494")
property var levels : [
{
"pixmapfile" : "image/bg.svg",
"type" : "SHAPE_BACKGROUND_IMAGE",
"width": 702,
"height": 515
},
{
"pixmapfile" : "image/AlbrechtDurer_d4.png",
"x" : "0.864",
"y" : "0.831"
},
{
"pixmapfile" : "image/AlbrechtDurer_c4.png",
"x" : "0.623",
"y" : "0.831"
},
{
"pixmapfile" : "image/AlbrechtDurer_b4.png",
"x" : "0.349",
"y" : "0.854"
},
{
"pixmapfile" : "image/AlbrechtDurer_a4.png",
"x" : "0.13",
"y" : "0.831"
},
{
"pixmapfile" : "image/AlbrechtDurer_d3.png",
"x" : "0.839",
"y" : "0.617"
},
{
"pixmapfile" : "image/AlbrechtDurer_c3.png",
"x" : "0.597",
"y" : "0.594"
},
{
"pixmapfile" : "image/AlbrechtDurer_b3.png",
"x" : "0.349",
"y" : "0.643"
},
{
"pixmapfile" : "image/AlbrechtDurer_a3.png",
"x" : "0.13",
"y" : "0.617"
},
{
"pixmapfile" : "image/AlbrechtDurer_d2.png",
"x" : "0.864",
"y" : "0.4"
},
{
"pixmapfile" : "image/AlbrechtDurer_c2.png",
"x" : "0.623",
"y" : "0.376"
},
{
"pixmapfile" : "image/AlbrechtDurer_b2.png",
"x" : "0.374",
"y" : "0.4"
},
{
"pixmapfile" : "image/AlbrechtDurer_a2.png",
"x" : "0.156",
"y" : "0.377"
},
{
"pixmapfile" : "image/AlbrechtDurer_d1.png",
"x" : "0.864",
"y" : "0.163"
},
{
"pixmapfile" : "image/AlbrechtDurer_c1.png",
"x" : "0.647",
"y" : "0.163"
},
{
"pixmapfile" : "image/AlbrechtDurer_b1.png",
"x" : "0.4",
"y" : "0.163"
},
{
"pixmapfile" : "image/AlbrechtDurer_a1.png",
"x" : "0.156",
"y" : "0.138"
}
]
}
diff --git a/src/activities/paintings/resource/board/board17_0.qml b/src/activities/paintings/resource/board/board17_0.qml
index e2098a757..9adda82fc 100644
--- a/src/activities/paintings/resource/board/board17_0.qml
+++ b/src/activities/paintings/resource/board/board17_0.qml
@@ -1,114 +1,114 @@
/* GCompris
*
* Copyright (C) 2015 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Pieter Brugel, The Harvesters - 1565")
property var levels : [
{
"pixmapfile" : "image/bg.svg",
"type" : "SHAPE_BACKGROUND_IMAGE",
"width": 702,
"height": 515
},
{
"pixmapfile" : "image/PieterBruegel_d4.png",
"x" : "0.859",
"y" : "0.854"
},
{
"pixmapfile" : "image/PieterBruegel_c4.png",
"x" : "0.622",
"y" : "0.854"
},
{
"pixmapfile" : "image/PieterBruegel_b4.png",
"x" : "0.353",
"y" : "0.854"
},
{
"pixmapfile" : "image/PieterBruegel_a4.png",
"x" : "0.137",
"y" : "0.854"
},
{
"pixmapfile" : "image/PieterBruegel_d3.png",
"x" : "0.835",
"y" : "0.643"
},
{
"pixmapfile" : "image/PieterBruegel_c3.png",
"x" : "0.621",
"y" : "0.643"
},
{
"pixmapfile" : "image/PieterBruegel_b3.png",
"x" : "0.402",
"y" : "0.643"
},
{
"pixmapfile" : "image/PieterBruegel_a3.png",
"x" : "0.162",
"y" : "0.643"
},
{
"pixmapfile" : "image/PieterBruegel_d2.png",
"x" : "0.835",
"y" : "0.377"
},
{
"pixmapfile" : "image/PieterBruegel_c2.png",
"x" : "0.621",
"y" : "0.4"
},
{
"pixmapfile" : "image/PieterBruegel_b2.png",
"x" : "0.377",
"y" : "0.377"
},
{
"pixmapfile" : "image/PieterBruegel_a2.png",
"x" : "0.137",
"y" : "0.4"
},
{
"pixmapfile" : "image/PieterBruegel_d1.png",
"x" : "0.835",
"y" : "0.138"
},
{
"pixmapfile" : "image/PieterBruegel_c1.png",
"x" : "0.621",
"y" : "0.163"
},
{
"pixmapfile" : "image/PieterBruegel_b1.png",
"x" : "0.402",
"y" : "0.138"
},
{
"pixmapfile" : "image/PieterBruegel_a1.png",
"x" : "0.162",
"y" : "0.163"
}
]
}
diff --git a/src/activities/paintings/resource/board/board18_0.qml b/src/activities/paintings/resource/board/board18_0.qml
index 40c5eb1c7..bdb3c11c7 100644
--- a/src/activities/paintings/resource/board/board18_0.qml
+++ b/src/activities/paintings/resource/board/board18_0.qml
@@ -1,75 +1,75 @@
/* GCompris
*
* Copyright (C) 2015 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property int numberOfSubLevel: 1
property string instruction: qsTr("Pierre-Auguste Renoir, Girls At The Piano - 1892")
property var levels : [
{
"pixmapfile" : "image/bg.svg",
"type" : "SHAPE_BACKGROUND_IMAGE",
"width": 702,
"height": 515
},
{
"pixmapfile" : "image/renoir-filles_piano-8.png",
"x" : "0.608",
"y" : "0.799"
},
{
"pixmapfile" : "image/renoir-filles_piano-7.png",
"x" : "0.387",
"y" : "0.801"
},
{
"pixmapfile" : "image/renoir-filles_piano-6.png",
"x" : "0.608",
"y" : "0.593"
},
{
"pixmapfile" : "image/renoir-filles_piano-5.png",
"x" : "0.387",
"y" : "0.595"
},
{
"pixmapfile" : "image/renoir-filles_piano-4.png",
"x" : "0.577",
"y" : "0.36"
},
{
"pixmapfile" : "image/renoir-filles_piano-3.png",
"x" : "0.356",
"y" : "0.36"
},
{
"pixmapfile" : "image/renoir-filles_piano-2.png",
"x" : "0.608",
"y" : "0.125"
},
{
"pixmapfile" : "image/renoir-filles_piano-1.png",
"x" : "0.387",
"y" : "0.125"
}
]
}
diff --git a/src/activities/paintings/resource/board/board19_0.qml b/src/activities/paintings/resource/board/board19_0.qml
index b6c7a8bf1..a71d44ff5 100644
--- a/src/activities/paintings/resource/board/board19_0.qml
+++ b/src/activities/paintings/resource/board/board19_0.qml
@@ -1,74 +1,74 @@
/* GCompris
*
* Copyright (C) 2015 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Wassily Kandinsky, Composition VIII - 1923")
property var levels : [
{
"pixmapfile" : "image/bg.svg",
"type" : "SHAPE_BACKGROUND_IMAGE",
"width": 702,
"height": 515
},
{
"pixmapfile" : "image/kandinky_8.png",
"x" : "0.85",
"y" : "0.618"
},
{
"pixmapfile" : "image/kandinky_7.png",
"x" : "0.642",
"y" : "0.618"
},
{
"pixmapfile" : "image/kandinky_6.png",
"x" : "0.376",
"y" : "0.673"
},
{
"pixmapfile" : "image/kandinky_5.png",
"x" : "0.138",
"y" : "0.673"
},
{
"pixmapfile" : "image/kandinky_4.png",
"x" : "0.85",
"y" : "0.228"
},
{
"pixmapfile" : "image/kandinky_3.png",
"x" : "0.642",
"y" : "0.228"
},
{
"pixmapfile" : "image/kandinky_2.png",
"x" : "0.405",
"y" : "0.283"
},
{
"pixmapfile" : "image/kandinky_1.png",
"x" : "0.167",
"y" : "0.283"
}
]
}
diff --git a/src/activities/paintings/resource/board/board1_0.qml b/src/activities/paintings/resource/board/board1_0.qml
index dd39f3f32..c65b6ed9a 100644
--- a/src/activities/paintings/resource/board/board1_0.qml
+++ b/src/activities/paintings/resource/board/board1_0.qml
@@ -1,64 +1,64 @@
/* GCompris
*
* Copyright (C) 2015 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
- property string instruction: qsTr(" Pierre-Auguste Renoir, Le Moulin de la Galette - 1876")
+ property string instruction: qsTr("Pierre-Auguste Renoir, Bal du moulin de la Galette - 1876")
property var levels : [
{
"pixmapfile" : "image/bg.svg",
"type" : "SHAPE_BACKGROUND_IMAGE",
"width": 702,
"height": 515
},
{
"pixmapfile" : "image/renoir-moulin_de_la_galette-4.png",
"x" : "0.226",
"y" : "0.651"
},
{
"pixmapfile" : "image/renoir-moulin_de_la_galette-5.png",
"x" : "0.504",
"y" : "0.651"
},
{
"pixmapfile" : "image/renoir-moulin_de_la_galette-3.png",
"x" : "0.782",
"y" : "0.327"
},
{
"pixmapfile" : "image/renoir-moulin_de_la_galette-1.png",
"x" : "0.255",
"y" : "0.283"
},
{
"pixmapfile" : "image/renoir-moulin_de_la_galette-2.png",
"x" : "0.533",
"y" : "0.283"
},
{
"pixmapfile" : "image/renoir-moulin_de_la_galette-6.png",
"x" : "0.781",
"y" : "0.69"
}
]
}
diff --git a/src/activities/paintings/resource/board/board20_0.qml b/src/activities/paintings/resource/board/board20_0.qml
index 5bd518f6b..573820f6d 100644
--- a/src/activities/paintings/resource/board/board20_0.qml
+++ b/src/activities/paintings/resource/board/board20_0.qml
@@ -1,64 +1,64 @@
/* GCompris
*
* Copyright (C) 2015 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Bazille, The Ramparts at Aigues-Mortes - 1867")
property var levels : [
{
"pixmapfile" : "image/bg.svg",
"type" : "SHAPE_BACKGROUND_IMAGE",
"width": 702,
"height": 515
},
{
"pixmapfile" : "image/bazille_rampart_4.jpg",
"x" : "0.212",
"y" : "0.634"
},
{
"pixmapfile" : "image/bazille_rampart_1.jpg",
"x" : "0.212",
"y" : "0.283"
},
{
"pixmapfile" : "image/bazille_rampart_3.jpg",
"x" : "0.791",
"y" : "0.283"
},
{
"pixmapfile" : "image/bazille_rampart_5.jpg",
"x" : "0.501",
"y" : "0.634"
},
{
"pixmapfile" : "image/bazille_rampart_2.jpg",
"x" : "0.501",
"y" : "0.283"
},
{
"pixmapfile" : "image/bazille_rampart_6.jpg",
"x" : "0.791",
"y" : "0.634"
}
]
}
diff --git a/src/activities/paintings/resource/board/board21_0.qml b/src/activities/paintings/resource/board/board21_0.qml
index 2aa471e30..8fdc26d2b 100644
--- a/src/activities/paintings/resource/board/board21_0.qml
+++ b/src/activities/paintings/resource/board/board21_0.qml
@@ -1,64 +1,64 @@
/* GCompris
*
* Copyright (C) 2015 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Mary Cassatt, Summertime - 1894")
property var levels : [
{
"pixmapfile" : "image/bg.svg",
"type" : "SHAPE_BACKGROUND_IMAGE",
"width": 702,
"height": 515
},
{
"pixmapfile" : "image/cassat_summertime_2.jpg",
"x" : "0.496",
"y" : "0.244"
},
{
"pixmapfile" : "image/cassat_summertime_4.jpg",
"x" : "0.211",
"y" : "0.671"
},
{
"pixmapfile" : "image/cassat_summertime_6.jpg",
"x" : "0.779",
"y" : "0.673"
},
{
"pixmapfile" : "image/cassat_summertime_5.jpg",
"x" : "0.496",
"y" : "0.673"
},
{
"pixmapfile" : "image/cassat_summertime_1.jpg",
"x" : "0.211",
"y" : "0.244"
},
{
"pixmapfile" : "image/cassat_summertime_3.jpg",
"x" : "0.779",
"y" : "0.244"
}
]
}
diff --git a/src/activities/paintings/resource/board/board22_0.qml b/src/activities/paintings/resource/board/board22_0.qml
index f26916873..7935efca0 100644
--- a/src/activities/paintings/resource/board/board22_0.qml
+++ b/src/activities/paintings/resource/board/board22_0.qml
@@ -1,64 +1,64 @@
/* GCompris
*
* Copyright (C) 2015 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Vincent Van Gogh, Village Street in Auvers - 1890")
property var levels : [
{
"pixmapfile" : "image/bg.svg",
"type" : "SHAPE_BACKGROUND_IMAGE",
"width": 702,
"height": 515
},
{
"pixmapfile" : "image/gogh_auvert_2.jpg",
"x" : "0.489",
"y" : "0.224"
},
{
"pixmapfile" : "image/gogh_auvert_6.jpg",
"x" : "0.774",
"y" : "0.681"
},
{
"pixmapfile" : "image/gogh_auvert_5.jpg",
"x" : "0.489",
"y" : "0.681"
},
{
"pixmapfile" : "image/gogh_auvert_1.jpg",
"x" : "0.204",
"y" : "0.224"
},
{
"pixmapfile" : "image/gogh_auvert_4.jpg",
"x" : "0.204",
"y" : "0.681"
},
{
"pixmapfile" : "image/gogh_auvert_3.jpg",
"x" : "0.774",
"y" : "0.224"
}
]
}
diff --git a/src/activities/paintings/resource/board/board2_0.qml b/src/activities/paintings/resource/board/board2_0.qml
index f59342c11..1b5f8842e 100644
--- a/src/activities/paintings/resource/board/board2_0.qml
+++ b/src/activities/paintings/resource/board/board2_0.qml
@@ -1,64 +1,64 @@
/* GCompris
*
* Copyright (C) 2015 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Giuseppe Arcimboldo, Spring - 1573")
property var levels : [
{
"pixmapfile" : "image/bg.svg",
"type" : "SHAPE_BACKGROUND_IMAGE",
"width": 702,
"height": 515
},
{
"pixmapfile" : "image/Arcimboldo_Spring_b3.png",
"x" : "0.615",
"y" : "0.762"
},
{
"pixmapfile" : "image/Arcimboldo_Spring_a3.png",
"x" : "0.405",
"y" : "0.735"
},
{
"pixmapfile" : "image/Arcimboldo_Spring_b2.png",
"x" : "0.59",
"y" : "0.498"
},
{
"pixmapfile" : "image/Arcimboldo_Spring_a2.png",
"x" : "0.379",
"y" : "0.497"
},
{
"pixmapfile" : "image/Arcimboldo_Spring_b1.png",
"x" : "0.59",
"y" : "0.231"
},
{
"pixmapfile" : "image/Arcimboldo_Spring_a1.png",
"x" : "0.379",
"y" : "0.259"
}
]
}
diff --git a/src/activities/paintings/resource/board/board3_0.qml b/src/activities/paintings/resource/board/board3_0.qml
index 827dbdcc8..4b5496ad3 100644
--- a/src/activities/paintings/resource/board/board3_0.qml
+++ b/src/activities/paintings/resource/board/board3_0.qml
@@ -1,79 +1,79 @@
/* GCompris
*
* Copyright (C) 2015 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Giuseppe Arcimboldo, The Librarian - 1566")
property var levels : [
{
"pixmapfile" : "image/bg.svg",
"type" : "SHAPE_BACKGROUND_IMAGE",
"width": 702,
"height": 515
},
{
"pixmapfile" : "image/Arcimboldo_Librarian_c3.png",
"x" : "0.625",
"y" : "0.735"
},
{
"pixmapfile" : "image/Arcimboldo_Librarian_b3.png",
"x" : "0.498",
"y" : "0.735"
},
{
"pixmapfile" : "image/Arcimboldo_Librarian_a3.png",
"x" : "0.372",
"y" : "0.762"
},
{
"pixmapfile" : "image/Arcimboldo_Librarian_c2.png",
"x" : "0.638",
"y" : "0.47"
},
{
"pixmapfile" : "image/Arcimboldo_Librarian_b2.png",
"x" : "0.499",
"y" : "0.497"
},
{
"pixmapfile" : "image/Arcimboldo_Librarian_a2.png",
"x" : "0.357",
"y" : "0.498"
},
{
"pixmapfile" : "image/Arcimboldo_Librarian_c1.png",
"x" : "0.625",
"y" : "0.231"
},
{
"pixmapfile" : "image/Arcimboldo_Librarian_b1.png",
"x" : "0.498",
"y" : "0.259"
},
{
"pixmapfile" : "image/Arcimboldo_Librarian_a1.png",
"x" : "0.373",
"y" : "0.231"
}
]
}
diff --git a/src/activities/paintings/resource/board/board4_0.qml b/src/activities/paintings/resource/board/board4_0.qml
index 3753c5b0e..4f5d232f9 100644
--- a/src/activities/paintings/resource/board/board4_0.qml
+++ b/src/activities/paintings/resource/board/board4_0.qml
@@ -1,64 +1,64 @@
/* GCompris
*
* Copyright (C) 2015 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Katsushika Hokusai, Oiran and Kamuro")
property var levels : [
{
"pixmapfile" : "image/bg.svg",
"type" : "SHAPE_BACKGROUND_IMAGE",
"width": 702,
"height": 515
},
{
"pixmapfile" : "image/HokusaiOiranKamuro_b3.png",
"x" : "0.602",
"y" : "0.752"
},
{
"pixmapfile" : "image/HokusaiOiranKamuro_a3.png",
"x" : "0.416",
"y" : "0.752"
},
{
"pixmapfile" : "image/HokusaiOiranKamuro_b2.png",
"x" : "0.602",
"y" : "0.497"
},
{
"pixmapfile" : "image/HokusaiOiranKamuro_a2.png",
"x" : "0.416",
"y" : "0.497"
},
{
"pixmapfile" : "image/HokusaiOiranKamuro_b1.png",
"x" : "0.602",
"y" : "0.242"
},
{
"pixmapfile" : "image/HokusaiOiranKamuro_a1.png",
"x" : "0.416",
"y" : "0.242"
}
]
}
diff --git a/src/activities/paintings/resource/board/board5_0.qml b/src/activities/paintings/resource/board/board5_0.qml
index 1fd7b924d..b6d847bbb 100644
--- a/src/activities/paintings/resource/board/board5_0.qml
+++ b/src/activities/paintings/resource/board/board5_0.qml
@@ -1,79 +1,79 @@
/* GCompris
*
* Copyright (C) 2015 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Katsushika Hokusai, Woman holding a fan")
property var levels : [
{
"pixmapfile" : "image/bg.svg",
"type" : "SHAPE_BACKGROUND_IMAGE",
"width": 702,
"height": 515
},
{
"pixmapfile" : "image/HokusaiWomanHoldingFan_c3.png",
"x" : "0.627",
"y" : "0.752"
},
{
"pixmapfile" : "image/HokusaiWomanHoldingFan_b3.png",
"x" : "0.484",
"y" : "0.752"
},
{
"pixmapfile" : "image/HokusaiWomanHoldingFan_a3.png",
"x" : "0.355",
"y" : "0.782"
},
{
"pixmapfile" : "image/HokusaiWomanHoldingFan_c2.png",
"x" : "0.64",
"y" : "0.468"
},
{
"pixmapfile" : "image/HokusaiWomanHoldingFan_b2.png",
"x" : "0.499",
"y" : "0.497"
},
{
"pixmapfile" : "image/HokusaiWomanHoldingFan_a2.png",
"x" : "0.355",
"y" : "0.498"
},
{
"pixmapfile" : "image/HokusaiWomanHoldingFan_c1.png",
"x" : "0.64",
"y" : "0.212"
},
{
"pixmapfile" : "image/HokusaiWomanHoldingFan_b1.png",
"x" : "0.499",
"y" : "0.242"
},
{
"pixmapfile" : "image/HokusaiWomanHoldingFan_a1.png",
"x" : "0.355",
"y" : "0.212"
}
]
}
diff --git a/src/activities/paintings/resource/board/board6_0.qml b/src/activities/paintings/resource/board/board6_0.qml
index 1f825029c..1ad1c8916 100644
--- a/src/activities/paintings/resource/board/board6_0.qml
+++ b/src/activities/paintings/resource/board/board6_0.qml
@@ -1,94 +1,94 @@
/* GCompris
*
* Copyright (C) 2015 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Katsushika Hokusai, Ejiri in Suruga Province - 1830-1833")
property var levels : [
{
"pixmapfile" : "image/bg.svg",
"type" : "SHAPE_BACKGROUND_IMAGE",
"width": 702,
"height": 515
},
{
"pixmapfile" : "image/EjiriSuruga_d3.png",
"x" : "0.846",
"y" : "0.752"
},
{
"pixmapfile" : "image/EjiriSuruga_c3.png",
"x" : "0.618",
"y" : "0.752"
},
{
"pixmapfile" : "image/EjiriSuruga_b3.png",
"x" : "0.38",
"y" : "0.752"
},
{
"pixmapfile" : "image/EjiriSuruga_a3.png",
"x" : "0.174",
"y" : "0.782"
},
{
"pixmapfile" : "image/EjiriSuruga_d2.png",
"x" : "0.823",
"y" : "0.497"
},
{
"pixmapfile" : "image/EjiriSuruga_c2.png",
"x" : "0.616",
"y" : "0.468"
},
{
"pixmapfile" : "image/EjiriSuruga_b2.png",
"x" : "0.405",
"y" : "0.468"
},
{
"pixmapfile" : "image/EjiriSuruga_a2.png",
"x" : "0.174",
"y" : "0.498"
},
{
"pixmapfile" : "image/EjiriSuruga_d1.png",
"x" : "0.823",
"y" : "0.242"
},
{
"pixmapfile" : "image/EjiriSuruga_c1.png",
"x" : "0.616",
"y" : "0.212"
},
{
"pixmapfile" : "image/EjiriSuruga_b1.png",
"x" : "0.405",
"y" : "0.212"
},
{
"pixmapfile" : "image/EjiriSuruga_a1.png",
"x" : "0.174",
"y" : "0.212"
}
]
}
diff --git a/src/activities/paintings/resource/board/board7_0.qml b/src/activities/paintings/resource/board/board7_0.qml
index 47bb00748..6ccc93e51 100644
--- a/src/activities/paintings/resource/board/board7_0.qml
+++ b/src/activities/paintings/resource/board/board7_0.qml
@@ -1,94 +1,94 @@
/* GCompris
*
* Copyright (C) 2015 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Katsushika Hokusai, The Great Wave off Kanagawa - 1823-1829")
property var levels : [
{
"pixmapfile" : "image/bg.svg",
"type" : "SHAPE_BACKGROUND_IMAGE",
"width": 702,
"height": 515
},
{
"pixmapfile" : "image/GreatWave_d3.png",
"x" : "0.847",
"y" : "0.752"
},
{
"pixmapfile" : "image/GreatWave_c3.png",
"x" : "0.64",
"y" : "0.752"
},
{
"pixmapfile" : "image/GreatWave_b3.png",
"x" : "0.404",
"y" : "0.752"
},
{
"pixmapfile" : "image/GreatWave_a3.png",
"x" : "0.172",
"y" : "0.782"
},
{
"pixmapfile" : "image/GreatWave_d2.png",
"x" : "0.847",
"y" : "0.468"
},
{
"pixmapfile" : "image/GreatWave_c2.png",
"x" : "0.64",
"y" : "0.497"
},
{
"pixmapfile" : "image/GreatWave_b2.png",
"x" : "0.404",
"y" : "0.468"
},
{
"pixmapfile" : "image/GreatWave_a2.png",
"x" : "0.172",
"y" : "0.527"
},
{
"pixmapfile" : "image/GreatWave_d1.png",
"x" : "0.847",
"y" : "0.212"
},
{
"pixmapfile" : "image/GreatWave_c1.png",
"x" : "0.617",
"y" : "0.242"
},
{
"pixmapfile" : "image/GreatWave_b1.png",
"x" : "0.355",
"y" : "0.212"
},
{
"pixmapfile" : "image/GreatWave_a1.png",
"x" : "0.147",
"y" : "0.242"
}
]
}
diff --git a/src/activities/paintings/resource/board/board8_0.qml b/src/activities/paintings/resource/board/board8_0.qml
index eca14f1c4..a87c8ed0c 100644
--- a/src/activities/paintings/resource/board/board8_0.qml
+++ b/src/activities/paintings/resource/board/board8_0.qml
@@ -1,114 +1,114 @@
/* GCompris
*
* Copyright (C) 2015 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Utagawa Hiroshige, The Benzaiten Shrine at Inokashira in Snow - 1760-70")
property var levels : [
{
"pixmapfile" : "image/bg.svg",
"type" : "SHAPE_BACKGROUND_IMAGE",
"width": 702,
"height": 515
},
{
"pixmapfile" : "image/HiroshigeInokashiraSnow_d4.png",
"x" : "0.841",
"y" : "0.819"
},
{
"pixmapfile" : "image/HiroshigeInokashiraSnow_c4.png",
"x" : "0.623",
"y" : "0.798"
},
{
"pixmapfile" : "image/HiroshigeInokashiraSnow_b4.png",
"x" : "0.374",
"y" : "0.819"
},
{
"pixmapfile" : "image/HiroshigeInokashiraSnow_a4.png",
"x" : "0.129",
"y" : "0.819"
},
{
"pixmapfile" : "image/HiroshigeInokashiraSnow_d3.png",
"x" : "0.866",
"y" : "0.609"
},
{
"pixmapfile" : "image/HiroshigeInokashiraSnow_c3.png",
"x" : "0.623",
"y" : "0.607"
},
{
"pixmapfile" : "image/HiroshigeInokashiraSnow_b3.png",
"x" : "0.373",
"y" : "0.63"
},
{
"pixmapfile" : "image/HiroshigeInokashiraSnow_a3.png",
"x" : "0.155",
"y" : "0.609"
},
{
"pixmapfile" : "image/HiroshigeInokashiraSnow_d2.png",
"x" : "0.866",
"y" : "0.388"
},
{
"pixmapfile" : "image/HiroshigeInokashiraSnow_c2.png",
"x" : "0.623",
"y" : "0.412"
},
{
"pixmapfile" : "image/HiroshigeInokashiraSnow_b2.png",
"x" : "0.348",
"y" : "0.412"
},
{
"pixmapfile" : "image/HiroshigeInokashiraSnow_a2.png",
"x" : "0.129",
"y" : "0.388"
},
{
"pixmapfile" : "image/HiroshigeInokashiraSnow_d1.png",
"x" : "0.841",
"y" : "0.197"
},
{
"pixmapfile" : "image/HiroshigeInokashiraSnow_c1.png",
"x" : "0.598",
"y" : "0.197"
},
{
"pixmapfile" : "image/HiroshigeInokashiraSnow_b1.png",
"x" : "0.348",
"y" : "0.197"
},
{
"pixmapfile" : "image/HiroshigeInokashiraSnow_a1.png",
"x" : "0.129",
"y" : "0.197"
}
]
}
diff --git a/src/activities/paintings/resource/board/board9_0.qml b/src/activities/paintings/resource/board/board9_0.qml
index f2ae77ce4..e2dd7d49f 100644
--- a/src/activities/paintings/resource/board/board9_0.qml
+++ b/src/activities/paintings/resource/board/board9_0.qml
@@ -1,114 +1,114 @@
/* GCompris
*
* Copyright (C) 2015 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Pulkit Gupta <pulkitgenius@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property string instruction: qsTr("Utagawa Hiroshige, Horse-mackerel and Prawn - 1840")
property var levels : [
{
"pixmapfile" : "image/bg.svg",
"type" : "SHAPE_BACKGROUND_IMAGE",
"width": 702,
"height": 515
},
{
"pixmapfile" : "image/HiroshigeHorsePrawns_d4.png",
"x" : "0.853",
"y" : "0.83"
},
{
"pixmapfile" : "image/HiroshigeHorsePrawns_c4.png",
"x" : "0.626",
"y" : "0.853"
},
{
"pixmapfile" : "image/HiroshigeHorsePrawns_b4.png",
"x" : "0.37",
"y" : "0.83"
},
{
"pixmapfile" : "image/HiroshigeHorsePrawns_a4.png",
"x" : "0.115",
"y" : "0.83"
},
{
"pixmapfile" : "image/HiroshigeHorsePrawns_d3.png",
"x" : "0.853",
"y" : "0.594"
},
{
"pixmapfile" : "image/HiroshigeHorsePrawns_c3.png",
"x" : "0.6",
"y" : "0.619"
},
{
"pixmapfile" : "image/HiroshigeHorsePrawns_b3.png",
"x" : "0.343",
"y" : "0.617"
},
{
"pixmapfile" : "image/HiroshigeHorsePrawns_a3.png",
"x" : "0.115",
"y" : "0.594"
},
{
"pixmapfile" : "image/HiroshigeHorsePrawns_d2.png",
"x" : "0.853",
"y" : "0.376"
},
{
"pixmapfile" : "image/HiroshigeHorsePrawns_c2.png",
"x" : "0.6",
"y" : "0.376"
},
{
"pixmapfile" : "image/HiroshigeHorsePrawns_b2.png",
"x" : "0.368",
"y" : "0.4"
},
{
"pixmapfile" : "image/HiroshigeHorsePrawns_a2.png",
"x" : "0.142",
"y" : "0.375"
},
{
"pixmapfile" : "image/HiroshigeHorsePrawns_d1.png",
"x" : "0.878",
"y" : "0.163"
},
{
"pixmapfile" : "image/HiroshigeHorsePrawns_c1.png",
"x" : "0.627",
"y" : "0.163"
},
{
"pixmapfile" : "image/HiroshigeHorsePrawns_b1.png",
"x" : "0.368",
"y" : "0.163"
},
{
"pixmapfile" : "image/HiroshigeHorsePrawns_a1.png",
"x" : "0.142",
"y" : "0.163"
}
]
}
diff --git a/src/activities/penalty/ActivityInfo.qml b/src/activities/penalty/ActivityInfo.qml
index 10e417c35..51b2931fe 100644
--- a/src/activities/penalty/ActivityInfo.qml
+++ b/src/activities/penalty/ActivityInfo.qml
@@ -1,43 +1,43 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Stephane Mankowski <stephane@mankowski.fr>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "penalty/Penalty.qml"
difficulty: 1
icon: "penalty/penalty.svg"
author: "Stephane Mankowski &lt;stephane@mankowski.fr&gt;"
demo: true
//: Activity title
title: qsTr("Penalty kick")
//: Help title
description: qsTr("Double click or double tap on any side of the goal in order to score.")
// intro: "Double click or double tap on the goal, in order to score."
//: Help goal
goal: ""
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("Double click or double tap on a side of the goal to kick the ball. " +
"You can double click the left right or middle mouse button. " +
"If you do not click fast enough, Tux catches the ball. " +
"You must click on it to bring it back to its former position.")
credit: ""
section: "computer mouse"
createdInVersion: 0
}
diff --git a/src/activities/penalty/GoalZone.qml b/src/activities/penalty/GoalZone.qml
index d9995ddfa..b34ca24d7 100644
--- a/src/activities/penalty/GoalZone.qml
+++ b/src/activities/penalty/GoalZone.qml
@@ -1,76 +1,76 @@
/* GCompris - GoalZone.qml
*
* Copyright (C) 2017 Rohit Das <rohit.das950@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import './penalty.js' as Activity
Rectangle {
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
anchors.top: parent.top
anchors.topMargin: parent.height * 0.07
property var progress: undefined
state: "INITIAL"
color: "transparent"
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MidButton
/* enabled if the current zone has been clicked on or if the ball is at the initial position */
enabled: items.saveBallState === parent.state || (items.saveBallState === "INITIAL" && ball.x === items.ballX && ball.y === items.ballY)
onClicked: changeBallState()
}
function changeBallState() {
instruction.text = ""
if(ball.state === "FAIL") {
Activity.resetLevel()
return
}
/* This is a shoot */
if (items.saveBallState === "INITIAL") {
items.saveBallState = state
}
if(progress.ratio > 0) {
/* Second click, stop animation */
progress.anim.running = false;
/* Play sound */
activity.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/brick.wav")
/* Success or not */
if(progress.ratio < 100) {
/* Success */
ball.state = state
} else {
/* failure */
ball.state = "FAIL"
}
timerBonus.start()
} else {
/* First click, start animation*/
progress.anim.running = true;
/* Play sound */
activity.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/flip.wav")
}
}
}
diff --git a/src/activities/penalty/Penalty.qml b/src/activities/penalty/Penalty.qml
index 2af08a2d8..46d1d4c86 100644
--- a/src/activities/penalty/Penalty.qml
+++ b/src/activities/penalty/Penalty.qml
@@ -1,311 +1,311 @@
/* GCompris - Penalty.qml
*
* Copyright (C) 2014 Stephane Mankowski <stephane@mankowski.fr>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Stephane Mankowski <stephane@mankowski.fr> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "penalty.js" as Activity
ActivityBase {
id: activity
onStart: focus = true
onStop: {}
pageComponent: Image {
id: background
source: Activity.url + "penalty_bg.svg"
sourceSize.width: parent.width
fillMode: Image.Stretch
anchors.fill: parent
signal start
signal stop
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
// To enable tapping/clicking on left side of goal
GoalZone {
id: rectLeft
state: "LEFT"
progress: progressLeft
anchors.right: player.left
anchors.leftMargin: parent.width * 0.08
anchors.bottomMargin: parent.height * 0.45
}
// To enable tapping/clicking on top of goal
GoalZone {
id: rectTop
state: "CENTER"
progress: progressTop
anchors.left: player.left
anchors.right: player.right
anchors.bottom: player.top
}
// To enable tapping/clicking on right side of goal
GoalZone {
id: rectRight
state: "RIGHT"
progress: progressRight
anchors.left: player.right
anchors.rightMargin: parent.width * 0.06
anchors.bottomMargin: parent.height * 0.45
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property alias background: background
property alias bar: bar
property alias ball: ball
property alias progressLeft: progressLeft
property alias progressRight: progressRight
property alias progressTop: progressTop
property alias bonus: bonus
- property int duration : 0
- property int progressBarOpacity : 40
+ property int duration: 0
+ property int progressBarOpacity: 40
property string saveBallState: "INITIAL"
property double ballX: ball.parent.width/2 - ball.width/2
property double ballY: ball.parent.height*0.77 - ball.height/2
}
onStart: { Activity.start(items) }
onStop: { Activity.stop() }
/* Instruction */
Item {
id: instruction
z: 99
anchors {
top: parent.top
topMargin: 10
horizontalCenter: parent.horizontalCenter
}
width: parent.width * 0.9
property alias text: instructionTxt.text
visible: bar.level === 1 && text != ""
GCText {
id: instructionTxt
anchors {
horizontalCenter: parent.horizontalCenter
}
fontSize: mediumSize
color: "white"
style: Text.Outline
styleColor: "black"
horizontalAlignment: Text.AlignHCenter
width: parent.width
wrapMode: TextEdit.WordWrap
z: 2
}
Rectangle {
anchors.fill: instructionTxt
z: 1
opacity: 0.8
radius: 10
border.width: 2
border.color: "black"
gradient: Gradient {
GradientStop { position: 0.0; color: "#000" }
GradientStop { position: 0.9; color: "#666" }
GradientStop { position: 1.0; color: "#AAA" }
}
}
}
/* The progress bars */
Progress {
id: progressLeft
anchors.left: parent.left
anchors.leftMargin: parent.width / parent.implicitWidth * 62
}
Progress {
id: progressRight
anchors.right: parent.right
anchors.rightMargin: parent.width/parent.implicitWidth * 50
}
Progress {
id: progressTop
anchors.topMargin: parent.width / parent.implicitWidth * 40
anchors.horizontalCenter: parent.horizontalCenter
width: parent.height / parent.implicitHeight * 20
height: ratio / 100 * parent.width / parent.implicitWidth * 100
}
/* The player */
Image {
id: player
source: Activity.url + "penalty_player.svg"
fillMode: Image.PreserveAspectFit
anchors.centerIn: parent
sourceSize.width: 154 * ApplicationInfo.ratio
}
/* The 2 click icon */
Image {
source: Activity.url + "click_icon.svg"
sourceSize.width: 90 * ApplicationInfo.ratio
anchors.bottom: bar.top
anchors.right: parent.right
anchors.bottomMargin: 10 * ApplicationInfo.ratio
anchors.rightMargin: 10 * ApplicationInfo.ratio
}
/* The spot under the ball */
Rectangle {
radius: 100 * ApplicationInfo.ratio
color: "white"
width: 50 * ApplicationInfo.ratio
height: 33 * ApplicationInfo.ratio
x: parent.width / 2 - width / 2
y: parent.height * 0.77 + width - height / 2
border.width: 1
border.color: "#b4b4b4"
}
/* The ball */
Image {
id: ball
source: Activity.url + "penalty_ball.svg"
fillMode: Image.PreserveAspectFit
sourceSize.width: 100 * ApplicationInfo.ratio
Behavior on x { PropertyAnimation {easing.type: Easing.OutQuad; duration: 1000} }
Behavior on y { PropertyAnimation {easing.type: Easing.OutQuad; duration: 1000} }
Behavior on sourceSize.width { PropertyAnimation {easing.type: Easing.OutQuad; duration: 1000} }
state: "INITIAL"
states: [
State {
name: "INITIAL"
PropertyChanges {
target: ball;
sourceSize.width: 100 * ApplicationInfo.ratio
x: parent.width/2 - width/2;
y: parent.height*0.77 - height/2
}
PropertyChanges {
target: instruction
text: qsTr("Double click or double tap on the side of the goal you want to put the ball in.")
}
},
State {
name: "RIGHT"
PropertyChanges {
target: ball
sourceSize.width: 75 * ApplicationInfo.ratio
x: background.width * 0.7
y: background.height * 0.3
}
},
State {
name: "LEFT"
PropertyChanges {
target: ball
sourceSize.width: 75 * ApplicationInfo.ratio
x: background.width * 0.2
y: background.height * 0.3
}
},
State {
name: "CENTER"
PropertyChanges {
target: ball;
sourceSize.width: 75 * ApplicationInfo.ratio
x: parent.width/2 - width/2;
y: background.height * 0.1
}
},
State {
name: "FAIL"
PropertyChanges {
target: ball
sourceSize.width: 75 * ApplicationInfo.ratio
x: parent.width/2 - width/2
y: player.y + player.height / 2
}
PropertyChanges {
target: instruction
text: qsTr("Click or tap the ball to bring it back to its former position")
}
}
]
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MidButton
onClicked: {
Activity.resetLevel()
}
}
}
Timer {
id: timerBonus
interval: 1500
onTriggered: {
if (ball.state == "FAIL" || ball.state == "INITIAL") {
bonus.bad("tux")
ball.state = "FAIL"
} else {
bonus.good("tux")
}
}
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level }
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
}
Bonus {
id: bonus
winSound: "qrc:/gcompris/src/activities/ballcatch/resource/tuxok.wav"
looseSound: "qrc:/gcompris/src/activities/ballcatch/resource/youcannot.wav"
Component.onCompleted: {
win.connect(Activity.nextLevel)
}
}
}
}
diff --git a/src/activities/penalty/Progress.qml b/src/activities/penalty/Progress.qml
index 23021010f..983c3f7f0 100644
--- a/src/activities/penalty/Progress.qml
+++ b/src/activities/penalty/Progress.qml
@@ -1,51 +1,51 @@
/* GCompris - Progress.qml
*
* Copyright (C) 2017 Rohit Das <rohit.das950@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
Rectangle {
id: progress
property int ratio: 0
property ParallelAnimation anim: animation
opacity: items.progressBarOpacity
anchors.top: parent.top
anchors.topMargin: parent.height / parent.implicitHeight * 100
width: ratio / 100 * parent.width / parent.implicitWidth * 200
height: parent.height / parent.implicitHeight * 20
ParallelAnimation {
id: animation
onRunningChanged: {
if (!animation.running) {
timerBonus.start()
}
}
PropertyAnimation {
target: progress
property: "ratio"
from: 0
to: 100
duration: items.duration
}
PropertyAnimation {
target: progress
property: "color"
from: "#00FF00"
to: "#FF0000"
duration: items.duration
}
}
}
diff --git a/src/activities/penalty/penalty.js b/src/activities/penalty/penalty.js
index 51dd80e01..04362fc99 100644
--- a/src/activities/penalty/penalty.js
+++ b/src/activities/penalty/penalty.js
@@ -1,75 +1,75 @@
/* GCompris - penalty.js
*
* Copyright (C) 2014 Stephane Mankowski <stephane@mankowski.fr>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Stephane Mankowski <stephane@mankowski.fr> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
var currentLevel = 0
var numberOfLevel = 9
var items
var url = "qrc:/gcompris/src/activities/penalty/resource/"
function start(items_) {
items = items_
currentLevel = 0
initLevel()
}
function stop() {
}
function initLevel() {
items.bar.level = currentLevel + 1
if(currentLevel === 0) items.duration = 1000
else if(currentLevel === 1) items.duration = 800
else if(currentLevel === 2) items.duration = 700
else if(currentLevel === 3) items.duration = 600
else if(currentLevel === 4) items.duration = 500
else if(currentLevel === 5) items.duration = 400
else if(currentLevel === 6) items.duration = 350
else if(currentLevel === 7) items.duration = 300
else if(currentLevel === 8) items.duration = 250
resetLevel()
}
function resetLevel() {
items.ball.state = "INITIAL"
items.saveBallState = "INITIAL"
items.progressRight.ratio = 0
items.progressLeft.ratio = 0
items.progressTop.ratio = 0
}
function nextLevel() {
if(numberOfLevel <= ++currentLevel) {
currentLevel = 0
}
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
initLevel();
}
diff --git a/src/activities/photo_hunter/ActivityInfo.qml b/src/activities/photo_hunter/ActivityInfo.qml
index 6b864bad8..6c5feddd2 100644
--- a/src/activities/photo_hunter/ActivityInfo.qml
+++ b/src/activities/photo_hunter/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2016 Stefan Toncu <stefan.toncu29@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "photo_hunter/PhotoHunter.qml"
difficulty: 2
icon: "photo_hunter/photo_hunter.svg"
author: "Stefan Toncu &lt;stefan.toncu29@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Photo Hunter")
//: Help title
description: qsTr("Find the differences between the two pictures!")
//intro: "look at the two pictures carefully and click where you see a difference"
//: Help goal
goal: qsTr("Visual Discrimination")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("Observe the two pictures carefully. There are some slight differences. When you find a difference you must click on it.")
credit: ""
section: "puzzle"
createdInVersion: 6000
}
diff --git a/src/activities/photo_hunter/Observe.qml b/src/activities/photo_hunter/Observe.qml
index 265e9446f..0d45fad31 100644
--- a/src/activities/photo_hunter/Observe.qml
+++ b/src/activities/photo_hunter/Observe.qml
@@ -1,192 +1,192 @@
/* GCompris - Observe.qml
*
* Copyright (C) 2016 Stefan Toncu <stefan.toncu29@gmail.com>
*
* Authors:
* <Marc Le Douarain> (GTK+ version)
* Stefan Toncu <stefan.toncu29@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "photo_hunter.js" as Activity
Image {
id: card
sourceSize.width: background.startedHelp ? background.width :
background.vert ? background.width : (background.width - 30) / 2
sourceSize.height: background.startedHelp ? background.height - background.barHeight * 1.5 - frame.problemTextHeight - slider.height :
background.vert ? (background.height - background.barHeight - 40 - frame.problemTextHeight) / 2 :
background.height - background.barHeight - 30 - frame.problemTextHeight
property GCSfx audioEffects: activity.audioEffects
property alias repeater: repeater
property alias circleRepeater: circleRepeater
property int good: 0
property bool show: false
Behavior on anchors.horizontalCenterOffset {
enabled: !background.vert
NumberAnimation {
duration: 1000
easing.type: Easing.InOutQuad
}
}
Behavior on anchors.verticalCenterOffset {
enabled: background.vert
NumberAnimation {
duration: 1000
easing.type: Easing.InOutQuad
}
}
Image {
id: wrong
source: Activity.url + "wrong.svg"
width: 70
height: 70
opacity: 0
}
NumberAnimation {
id: wrongAnim
target: wrong
property: "opacity"
from: 0
to: 1
duration: 400
}
NumberAnimation {
id: wrongAnim2
target: wrong
property: "opacity"
from: 1
to: 0
duration: 400
}
MouseArea {
id: big
anchors.fill: parent
enabled: !background.startedHelp
onClicked: {
audioEffects.play('qrc:/gcompris/src/core/resource/sounds/brick.wav')
wrongAnim.start()
wrong.x = mouseX - wrong.width/2
wrong.y = mouseY - wrong.height/2
wrongAnim2.start()
}
}
Repeater {
id: repeater
model: items.model
Image {
id: photo
property alias particleLoader: particleLoader
property alias differenceAnimation: differenceAnimation
property double widthScale: Activity.dataset[Activity.currentLevel].coordinates[index].w
property double heightScale: Activity.dataset[Activity.currentLevel].coordinates[index].h
sourceSize.width: Activity.dataset[Activity.currentLevel].coordinates[index].r * 200
sourceSize.height: Activity.dataset[Activity.currentLevel].coordinates[index].r * 200
width: card.width / 10 * widthScale
height: card.height / 10 * heightScale
source: Activity.url + "photo" + (Activity.currentLevel + 1) + "_" + (index + 1) + ".svg"
opacity: card.show ? 1 : 0
x: modelData[0] * card.width / 1200
y: modelData[1] * card.height / 1700
NumberAnimation {
id: differenceAnimation
target: photo
property: "opacity"
from: 0
to: 1
duration: 500
}
// Create a particle only for the strawberry
Loader {
id: particleLoader
anchors.fill: parent
active: true
sourceComponent: particle
}
Component {
id: particle
ParticleSystemStarLoader {
id: particles
clip: false
}
}
MouseArea {
id: mouseArea
anchors.centerIn: parent
width: parent.width * 3
height: parent.height * 3
enabled: !background.startedHelp
onClicked: {
Activity.photoClicked(card,index)
audioEffects.play('qrc:/gcompris/src/core/resource/sounds/bleep.wav')
}
}
}
}
Repeater {
id: circleRepeater
model: card.repeater.model
Rectangle {
id: circle
color: "transparent"
radius: width * 0.5
border.color: card.show ? "blue" : "red"
border.width: 6
opacity: 0
x: itemAt.x - width / 6
y: itemAt.y - height / 6
width: itemAt.width * 1.5
height: itemAt.height * 1.5
property alias scaleAnim: scaleAnim
property var itemAt: card.repeater.itemAt(index) ? card.repeater.itemAt(index) : card
NumberAnimation {
id: scaleAnim
target: circle
property: "scale"
from: 0
to: circle.scale
duration: 700
}
}
}
}
diff --git a/src/activities/photo_hunter/PhotoHunter.qml b/src/activities/photo_hunter/PhotoHunter.qml
index cec83b740..3524c622b 100644
--- a/src/activities/photo_hunter/PhotoHunter.qml
+++ b/src/activities/photo_hunter/PhotoHunter.qml
@@ -1,244 +1,244 @@
/* GCompris - PhotoHunter.qml
*
* Copyright (C) 2016 Stefan Toncu <stefan.toncu29@gmail.com>
*
* Authors:
* <Marc Le Douarain> (GTK+ version)
* Stefan Toncu <stefan.toncu29@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import QtQuick.Controls 1.5
import QtQuick.Controls.Styles 1.4
import "../../core"
import "photo_hunter.js" as Activity
ActivityBase {
id: activity
onStart: focus = true
onStop: {}
pageComponent: Rectangle {
id: background
anchors.fill: parent
color: "white"
signal start
signal stop
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property alias background: background
property alias bar: bar
property alias bonus: bonus
property var model
property bool notShowed: true
property alias img1: img1
property alias img2: img2
property int total
property int totalFound: img1.good + img2.good
property alias problem: problem
property alias frame: frame
}
onStart: { Activity.start(items) }
onStop: { Activity.stop() }
- property bool vert: background.width < background.height
+ property bool vert: background.width <= background.height
property double barHeight: ApplicationSettings.isBarHidden ? bar.height / 2 : bar.height
property bool startedHelp: false
function checkAnswer() {
if (items.totalFound === items.model.length) {
bonus.good("flower")
// after completing a level, mark the problem as shown
if (items.notShowed) {
items.notShowed = false
}
//remove the problem from the board after first level
if (problem.z > 0)
Activity.hideProblem()
}
}
Rectangle {
id: problem
width: parent.width
height: problemText.height
anchors.top: parent.top
anchors.topMargin: 10
border.width: 2
border.color: "black"
color: "red"
z: 5
property alias problemText: problemText
GCText {
id: problemText
anchors.centerIn: parent
width: parent.width * 3 / 4
fontSize: mediumSize
wrapMode: Text.WordWrap
horizontalAlignment: Text.AlignHCenter
text: background.startedHelp ? qsTr("Drag the slider to show the differences!") :
qsTr("Click on the differences between the two images!")
color: "white"
onHeightChanged: {
if (items.problem.z > 0)
frame.problemTextHeight = problemText.height
}
}
MouseArea {
anchors.fill: parent
onClicked: Activity.hideProblem()
}
}
Rectangle {
id: frame
color: "transparent"
width: background.vert ? img1.width : parent.width - 20
height: parent.height - background.barHeight - 30
anchors.top: problem.bottom
anchors.horizontalCenter: parent.horizontalCenter
anchors.margins: 10
property real problemTextHeight: problemText.height
//left/top image
Observe {
id: img1
show: true
anchors {
horizontalCenter: parent.horizontalCenter
horizontalCenterOffset: background.startedHelp ? 0 : background.vert ? 0 : - img1.width / 2 - 5
verticalCenter: parent.verticalCenter
verticalCenterOffset: background.startedHelp ? background.vert ? - frame.problemTextHeight * 0.8 : - frame.problemTextHeight * 1.01 :
background.vert ? - frame.problemTextHeight * 0.5 - img1.height * 0.5 - 5 : - frame.problemTextHeight * 0.5
}
}
//right/bottom image
Observe {
id: img2
opacity: background.startedHelp ? 1 - slider.value : 1
show: false
anchors {
horizontalCenter: parent.horizontalCenter
horizontalCenterOffset: background.startedHelp ? 0 : background.vert ? 0 : img1.width / 2 + 5
verticalCenter: parent.verticalCenter
verticalCenterOffset: background.startedHelp ? background.vert ? - frame.problemTextHeight * 0.8 : - frame.problemTextHeight * 1.01 :
background.vert ? - frame.problemTextHeight * 0.5 + img1.height * 0.5 + 5 : - frame.problemTextHeight * 0.5
}
}
Slider {
id: slider
value: 0
height: 50
width: img1.width * 0.9
z: background.startedHelp ? 5 : -5
opacity: background.startedHelp ? 1 : 0
enabled: background.startedHelp
style: SliderStyle {
handle: Rectangle {
height: background.vert ? 80 : 70
width: height
radius: width / 2
color: "lightblue"
}
groove: Rectangle {
implicitHeight: slider.height
implicitWidth: background.vert ? slider.width * 0.85 : slider.width
radius: height / 2
border.color: "#6699ff"
color: "#99bbff"
Rectangle {
height: parent.height
width: styleData.handlePosition
implicitHeight: 6
implicitWidth: 100
radius: height/2
color: "#4d88ff"
}
}
}
anchors {
top: img1.bottom
topMargin: 20
horizontalCenter: img1.horizontalCenter
}
}
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level | hint }
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
onHintClicked: {
background.startedHelp = !background.startedHelp
slider.value = 0
}
}
Bonus {
id: bonus
Component.onCompleted: win.connect(Activity.nextLevel)
}
Score {
anchors {
bottom: parent.bottom
bottomMargin: 10 * ApplicationInfo.ratio
right: parent.right
rightMargin: 10 * ApplicationInfo.ratio
top: undefined
left: undefined
}
numberOfSubLevels: items.total
currentSubLevel: items.totalFound
}
}
}
diff --git a/src/activities/photo_hunter/photo_hunter.js b/src/activities/photo_hunter/photo_hunter.js
index 966c04dad..7a4381800 100644
--- a/src/activities/photo_hunter/photo_hunter.js
+++ b/src/activities/photo_hunter/photo_hunter.js
@@ -1,183 +1,183 @@
/* GCompris - photo_hunter.js
*
* Copyright (C) 2016 Stefan Toncu <stefan.toncu29@gmail.com>
*
* Authors:
* <Marc Le Douarain> (GTK+ version)
* Stefan Toncu <stefan.toncu29@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
var currentLevel = 0
var items
var url = "qrc:/gcompris/src/activities/photo_hunter/resource/"
var dataset = [
{
"coordinates": [{x: 12, y:5, r: 0.5, w: 1.25, h: 1.25},
{x: 75, y:1170, r: 0.5, w: 0.35, h: 0.4},
{x: 343, y:1375, r: 1, w: 0.9, h: 0.9}]
},
{
"coordinates": [{x: 949.5, y:268.5, r: 0.7, w: 0.85, h: 0.92},
{x: 915, y:1555, r: 0.7, w: 0.75, h: 0.6},
{x: 510, y:1300, r: 1.7, w: 1.25, h: 2}]
},
{
"coordinates": [{x: 800, y:40, r: 1.8, w: 2.6, h: 1},
{x: 593, y:1450, r: 0.5, w: 0.8, h: 0.65}]
},
{
"coordinates": [{x: 975, y:140, r: 0.2, w: 0.3, h: 0.3},
{x: 680, y:720, r: 0.25, w: 0.3, h: 0.4},
{x: 570, y:1580, r: 1.3, w: 1.3, h: 0.6},
{x: 220, y:650, r: 0.7, w: 1, h: 1}]
},
{
"coordinates": [{x: 540, y:200, r: 0.25, w: 0.5, h: 0.5},
{x: 335, y:1228, r: 1, w: 0.25, h: 0.25},
{x: 600, y:1150, r: 0.25, w: 0.5, h: 0.5},
{x: 680, y:1330, r: 1, w: 1.3, h: 0.6}]
},
{
"coordinates": [{x: 130, y: 450, r: 1, w: 1.5, h: 1.5},
{x: 825, y: 234, r: 0.7, w: 0.8, h: 0.8},
{x: 950, y: 1450, r: 0.7, w: 1, h: 1}]
},
{
"coordinates": [{x: 70, y: 600, r: 1, w: 1.6, h: 0.8},
{x: 950, y: 1120, r: 1, w: 1.3, h: 0.45},
{x: 380, y: 815, r: 1, w: 0.3, h: 0.41}]
},
{
"coordinates": [{x: 445, y: 1135, r: 0.5, w: 0.8, h: 0.3},
{x: 17, y: 1300, r: 0.5, w: 0.6, h: 0.6},
{x: 782, y: 670, r: 0.75, w: 0.8, h: 0.8},
{x: 98, y: 1002, r: 0.5, w: 0.85, h: 0.3},
{x: 527, y: 415, r: 0.15, w: 0.178, h: 0.25},
{x: 337, y: 725, r: 0.15, w: 0.25, h: 0.25}]
},
{
"coordinates":
[{x: 275, y: 345, r: 0.15, w: 0.25, h: 0.25},
{x: 1013, y: 1322, r: 0.15, w: 0.25, h: 0.25},
{x: 595, y: 1530, r: 0.7, w: 1, h: 0.15}]
},
{
"coordinates": [{x: 565, y:1120, r: 0.35, w: 0.6, h: 0.55},
{x: 595, y:1500, r: 0.35, w: 0.6, h: 0.55},
{x: 680, y:433, r: 0.5, w: 0.6, h: 0.8},
{x: 760, y:971, r: 0.5, w: 0.35, h: 0.6}]
}
]
var numberOfLevel = dataset.length
function start(items_) {
items = items_
currentLevel = 0
initLevel()
}
function stop() {
}
function initLevel() {
items.bar.level = currentLevel + 1
items.background.startedHelp = false
setUp()
}
function setUp() {
loadCoordinate()
for (var i = 0; i < items.model.length; i++) {
items.img1.circleRepeater.itemAt(i).opacity = 0
items.img2.circleRepeater.itemAt(i).opacity = 0
}
items.img1.good = 0
items.img2.good = 0
items.total = dataset[currentLevel].coordinates.length
items.img1.source = url + "photo" + (currentLevel+1) + ".svg"
items.img2.source = url + "photo" + (currentLevel+1) + ".svg"
}
function loadCoordinate() {
var pointPositions = dataset[currentLevel].coordinates
var linePropertiesArray = []
for (var i = 0; i < (pointPositions.length); i++) {
var lineProperties = []
lineProperties[0] = pointPositions[i].x
lineProperties[1] = pointPositions[i].y
linePropertiesArray[i] = lineProperties
}
items.model = linePropertiesArray
}
function photoClicked(item, index) {
//only if the difference is not yet spotted
if (items.img2.repeater.itemAt(index).opacity === 0) {
//activate the particle loader
items.img1.repeater.itemAt(index).particleLoader.item.burst(40)
items.img2.repeater.itemAt(index).particleLoader.item.burst(40)
// show the actual difference on the second image
items.img2.repeater.itemAt(index).differenceAnimation.start()
// scale animation for the blue circle
items.img1.circleRepeater.itemAt(index).scaleAnim.start()
items.img2.circleRepeater.itemAt(index).scaleAnim.start()
// set opacity of circle differences to 1
items.img1.circleRepeater.itemAt(index).opacity = 1
items.img2.circleRepeater.itemAt(index).opacity = 1
// all good; check if all the differences have been spotted
item.good++
items.background.checkAnswer()
}
}
function hideProblem() {
items.frame.anchors.top = items.background.top
items.frame.problemTextHeight = 0
items.problem.z = -5
}
function nextLevel() {
if(numberOfLevel <= ++currentLevel) {
currentLevel = 0
}
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
initLevel();
}
diff --git a/src/activities/piano_composition/ActivityInfo.qml b/src/activities/piano_composition/ActivityInfo.qml
new file mode 100644
index 000000000..17c9ebbb1
--- /dev/null
+++ b/src/activities/piano_composition/ActivityInfo.qml
@@ -0,0 +1,58 @@
+/* GCompris - ActivityInfo.qml
+ *
+ * Copyright (C) 2016 Johnny Jazeix <jazeix@gmail.com>
+ * Copyright (C) 2018 Aman Kumar Gupta <gupta2140@gmail.com>
+ *
+ * This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+ */
+import GCompris 1.0
+
+ActivityInfo {
+ name: "piano_composition/Piano_composition.qml"
+ difficulty: 2
+ icon: "piano_composition/piano_composition.svg"
+ author: "Aman Kumar Gupta &lt;gupta2140@gmail.com&gt;"
+ demo: true
+ //: Activity title
+ title: qsTr("Piano Composition")
+ //: Help title
+ description: qsTr("An activity to learn how the piano keyboard works, how notes are written on a musical staff and explore music composition by loading and saving your work.")
+ //: Help goal
+ goal: qsTr("Develop an understanding of music composition, and increase interest in making music with a piano keyboard. This activity covers many fundamental aspects of music, but there is much more to explore about music composition. If you enjoy this activity but want a more advanced tool, try downloading Minuet (https://minuet.kde.org/), an open source software for music education or MuseScore (http://musescore.org/en/download), an open source music notation tool.")
+ //: Help prerequisite
+ prerequisite: qsTr("Familiarity with note naming conventions, note-names activity useful to learn this notation.")
+ //: Help manual
+ manual: qsTr("This activity has several levels, each level adds a new functionality to the previous level.
+ Level 1: Basic piano keyboard (white keys only) and students can experiment with clicking the colored rectangle keys to write music.
+ Level 2: The musical staff switches to bass clef, so pitches are lower than in previous level.
+ Level 3: Option to choose between treble and bass clef, addition of black keys (sharp keys).
+ Level 4: Flat notation used for black keys.
+ Level 5: Option to select note duration (whole, half, quarter, eighth notes).
+ Level 6: Addition of rests (whole, half, quarter, eighth rests)
+ Level 7: Load children's melodies from around the world and also save your composition.
+
+The following keyboard bindings work in this game:
+- backspace: undo
+- delete: erase attempt
+- enter/return: OK button
+- space bar: play
+- left/right arrow keys: switch keyboard octave
+- number keys:
+ - 1 to 8: Corresponding white keys in the order on the displayed octave.
+ - F1 to F5: Corresponding black keys in the order on the displayed octave.
+")
+ credit: qsTr("The synthesizer original code is https://github.com/vsr83/miniSynth")
+ section: "discovery sound_group"
+ createdInVersion: 9500
+}
diff --git a/src/activities/piano_composition/BpmMeter.qml b/src/activities/piano_composition/BpmMeter.qml
new file mode 100644
index 000000000..143b82665
--- /dev/null
+++ b/src/activities/piano_composition/BpmMeter.qml
@@ -0,0 +1,189 @@
+/* GCompris - BpmMeter.qml
+*
+* Copyright (C) 2018 Aman Kumar Gupta <gupta2140@gmail.com>
+*
+* Authors:
+* Beth Hadley <bethmhadley@gmail.com> (GTK+ version)
+* Johnny Jazeix <jazeix@gmail.com> (Qt Quick port)
+* Aman Kumar Gupta <gupta2140@gmail.com> (Qt Quick port)
+* Timothée Giet <animtim@gmail.com> (refactoring)
+*
+* This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+*/
+import QtQuick 2.6
+import GCompris 1.0
+
+import "../../core"
+
+Item {
+ id: bpmMeter
+ width: optionsRow.iconsWidth * 2
+ height: optionsRow.iconsWidth
+ visible: bpmVisible
+ Rectangle {
+ id: bpmBg
+ color: "yellow"
+ opacity: 0.1
+ border.width: 2
+ border.color: "black"
+ width: optionsRow.iconsWidth
+ height: optionsRow.iconsWidth
+ anchors.left: parent.left
+ radius: 10
+ }
+ GCText {
+ //: BPM is the abbreviation for Beats Per Minute.
+ text: qsTr("%1 BPM").arg(multipleStaff.bpmValue + "<br>")
+ width: 0.9 * bpmBg.width
+ height: 0.9 * bpmBg.height
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ anchors.centerIn: bpmBg
+ fontSizeMode: Text.Fit
+ }
+
+ Image {
+ id: bpmDown
+ source: "qrc:/gcompris/src/core/resource/bar_down.svg"
+ width: iconsWidth
+ height: iconsWidth * 0.5
+ sourceSize.width: width
+ fillMode: Image.PreserveAspectFit
+ anchors.bottom: parent.bottom
+ anchors.left: bpmBg.right
+ Timer {
+ id: decreaseBpm
+ interval: 500
+ repeat: true
+ onTriggered: {
+ bpmDecreased()
+ interval = 1
+ }
+ onRunningChanged: {
+ if(!running)
+ interval = 500
+ }
+ }
+ MouseArea {
+ id: mouseDown
+ anchors.fill: parent
+ hoverEnabled: true
+ onPressed: {
+ bpmDown.scale = 0.85
+ bpmDecreased()
+ decreaseBpm.start()
+ }
+ onReleased: {
+ decreaseBpm.stop()
+ bpmDown.scale = 1
+ bpmChanged()
+ }
+ }
+ states: [
+ State {
+ name: "notclicked"
+ PropertyChanges {
+ target: bpmDown
+ scale: 1.0
+ }
+ },
+ State {
+ name: "clicked"
+ when: mouseDown.pressed
+ PropertyChanges {
+ target: bpmDown
+ scale: 0.9
+ }
+ },
+ State {
+ name: "hover"
+ when: mouseDown.containsMouse
+ PropertyChanges {
+ target: bpmDown
+ scale: 1.1
+ }
+ }
+ ]
+
+ Behavior on scale { NumberAnimation { duration: 70 } }
+ Behavior on opacity { PropertyAnimation { duration: 200 } }
+ }
+
+ Image {
+ id: bpmUp
+ source: "qrc:/gcompris/src/core/resource/bar_up.svg"
+ width: iconsWidth
+ height: bpmDown.height
+ sourceSize.width: width
+ fillMode: Image.PreserveAspectFit
+ anchors.top: parent.top
+ anchors.left: bpmBg.right
+ Timer {
+ id: increaseBpm
+ interval: 500
+ repeat: true
+ onTriggered: {
+ bpmIncreased()
+ interval = 1
+ }
+ onRunningChanged: {
+ if(!running)
+ interval = 500
+ }
+ }
+ MouseArea {
+ id: mouseUp
+ anchors.fill: parent
+ hoverEnabled: true
+ onPressed: {
+ bpmUp.scale = 0.85
+ bpmIncreased()
+ increaseBpm.start()
+ }
+ onReleased: {
+ increaseBpm.stop()
+ bpmUp.scale = 1
+ bpmChanged()
+ }
+ }
+ states: [
+ State {
+ name: "notclicked"
+ PropertyChanges {
+ target: bpmUp
+ scale: 1.0
+ }
+ },
+ State {
+ name: "clicked"
+ when: mouseUp.pressed
+ PropertyChanges {
+ target: bpmUp
+ scale: 0.9
+ }
+ },
+ State {
+ name: "hover"
+ when: mouseUp.containsMouse
+ PropertyChanges {
+ target: bpmUp
+ scale: 1.1
+ }
+ }
+ ]
+
+ Behavior on scale { NumberAnimation { duration: 70 } }
+ Behavior on opacity { PropertyAnimation { duration: 200 } }
+ }
+}
diff --git a/src/activities/piano_composition/CMakeLists.txt b/src/activities/piano_composition/CMakeLists.txt
new file mode 100644
index 000000000..93807790e
--- /dev/null
+++ b/src/activities/piano_composition/CMakeLists.txt
@@ -0,0 +1 @@
+GCOMPRIS_ADD_RCC(activities/piano_composition *.qml *.svg *.js resource/*.* resource/*/*)
diff --git a/src/activities/piano_composition/KeyOption.qml b/src/activities/piano_composition/KeyOption.qml
new file mode 100644
index 000000000..2d81b4296
--- /dev/null
+++ b/src/activities/piano_composition/KeyOption.qml
@@ -0,0 +1,79 @@
+/* GCompris - KeyOption.qml
+*
+* Copyright (C) 2018 Aman Kumar Gupta <gupta2140@gmail.com>
+*
+* Authors:
+* Beth Hadley <bethmhadley@gmail.com> (GTK+ version)
+* Johnny Jazeix <jazeix@gmail.com> (Qt Quick port)
+* Aman Kumar Gupta <gupta2140@gmail.com> (Qt Quick port)
+* Timothée Giet <animtim@gmail.com> (refactoring)
+*
+* This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+*/
+import QtQuick 2.6
+import GCompris 1.0
+
+import "../../core"
+
+Item {
+ id: clefOption
+
+ property alias clefButtonIndex: clefButton.currentIndex
+ property bool clefButtonVisible: false
+ signal clefAdded
+
+ width: optionsRow.iconsWidth * 2
+ height: optionsRow.iconsWidth
+ visible: clefButtonVisible
+ Rectangle {
+ color: "yellow"
+ opacity: 0.1
+ border.width: 2
+ border.color: "black"
+ anchors.fill: parent
+ radius: 10
+ }
+
+ SwitchableOptions {
+ id: clefButton
+ nbOptions: 2
+ source: "qrc:/gcompris/src/activities/piano_composition/resource/" + (!currentIndex ? "trebbleClefButton.svg"
+ : "bassClefButton.svg")
+ width: optionsRow.iconsWidth * 0.9
+ sourceSize.width: width
+ visible: clefButtonVisible
+ onClicked: {
+ //: Treble clef and Bass clef are the notations to indicate the pitch of the sound written on it.
+ emitOptionMessage(!currentIndex ? qsTr("Treble clef") : qsTr("Bass clef"))
+ }
+ anchors.left: parent.left
+ anchors.verticalCenter: parent.verticalCenter
+ }
+
+ BarButton {
+ id: addClefButton
+ width: clefButton.width
+ sourceSize.width: width
+ source: "qrc:/gcompris/src/activities/piano_composition/resource/add.svg"
+ anchors.right: parent.right
+ anchors.verticalCenter: parent.verticalCenter
+ visible: clefButton.visible
+ onClicked: {
+ background.clefType = !clefButton.currentIndex ? "Treble" : "Bass"
+ emitOptionMessage(!clefButton.currentIndex ? qsTr("Added Treble clef") : qsTr("Added Bass clef"))
+ parent.scale = 1
+ clefAdded()
+ }
+ }
+}
diff --git a/src/activities/piano_composition/LyricsArea.qml b/src/activities/piano_composition/LyricsArea.qml
new file mode 100644
index 000000000..6165f344b
--- /dev/null
+++ b/src/activities/piano_composition/LyricsArea.qml
@@ -0,0 +1,118 @@
+/* GCompris - LyricsArea.qml
+*
+* Copyright (C) 2018 Aman Kumar Gupta <gupta2140@gmail.com>
+*
+* Authors:
+* Beth Hadley <bethmhadley@gmail.com> (GTK+ version)
+* Johnny Jazeix <jazeix@gmail.com> (Qt Quick port)
+* Aman Kumar Gupta <gupta2140@gmail.com> (Qt Quick port)
+*
+* This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+*/
+import QtQuick 2.6
+import GCompris 1.0
+
+import "../../core"
+
+Rectangle {
+ id: lyricsArea
+
+ property string title: ""
+ property string origin: ""
+ property string lyrics: ""
+
+ border.width: 3
+ radius: 5
+ border.color: "black"
+ opacity: 0.8
+ visible: background.isLyricsMode
+ Item {
+ id: melodyTitle
+ width: parent.width
+ height: parent.height / 6
+ GCText {
+ id: titleText
+ fontSizeMode: Text.Fit
+ wrapMode: Text.WordWrap
+ text: qsTr("Title: %1").arg(lyricsArea.title)
+ anchors.fill: parent
+ anchors.rightMargin: parent.width * 0.02
+ anchors.leftMargin: parent.width * 0.02
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ font.bold: true
+ color: "green"
+ }
+ }
+
+ Rectangle {
+ id: titleUnderline
+ width: titleText.contentWidth
+ height: 3
+ color: "black"
+ anchors.top: melodyTitle.bottom
+ anchors.horizontalCenter: melodyTitle.horizontalCenter
+ }
+
+ Item {
+ id: melodyOrigin
+ width: parent.width
+ height: parent.height / 8
+ anchors.top: titleUnderline.bottom
+ GCText {
+ fontSizeMode: Text.Fit
+ wrapMode: Text.WordWrap
+ text: qsTr("Origin: %1").arg(lyricsArea.origin)
+ anchors.fill: parent
+ anchors.rightMargin: parent.width * 0.02
+ anchors.leftMargin: parent.width * 0.02
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ font.italic: true
+ color: "red"
+ }
+ }
+
+ Item {
+ id: melodyLyrics
+ width: parent.width
+ height: parent.height - melodyTitle.height - melodyOrigin.height - 20
+ anchors.top: melodyOrigin.bottom
+ GCText {
+ fontSizeMode: Text.Fit
+ wrapMode: Text.WordWrap
+ text: lyricsArea.lyrics
+ anchors.fill: parent
+ anchors.rightMargin: parent.width * 0.05
+ anchors.leftMargin: parent.width * 0.05
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ }
+ }
+
+ function resetLyricsArea() {
+ lyricsArea.title = ""
+ lyricsArea.origin = ""
+ lyricsArea.lyrics = ""
+ optionsRow.lyricsOrPianoModeIndex = 0
+ }
+
+ function setLyrics(title, origin, lyrics) {
+ resetLyricsArea()
+ lyricsArea.title = title
+ lyricsArea.origin = origin
+ lyricsArea.lyrics = lyrics
+ optionsRow.lyricsOrPianoModeIndex = 1
+ }
+}
diff --git a/src/activities/piano_composition/MelodyList.qml b/src/activities/piano_composition/MelodyList.qml
new file mode 100644
index 000000000..cc1ec6f92
--- /dev/null
+++ b/src/activities/piano_composition/MelodyList.qml
@@ -0,0 +1,174 @@
+/* GCompris - MelodyList.qml
+ *
+ * Copyright (C) 2017 Divyam Madaan <divyam3897@gmail.com>
+ * Copyright (C) 2018 Aman Kumar Gupta <gupta2140@gmail.com>
+ *
+ * Authors:
+ * Beth Hadley <bethmhadley@gmail.com> (GTK+ version)
+ * Divyam Madaan <divyam3897@gmail.com> (Qt Quick port)
+ * Aman Kumar Gupta <gupta2140@gmail.com> (Qt Quick port)
+ *
+ * This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.6
+import GCompris 1.0
+import QtQuick.Controls 1.5
+
+import "../../core"
+import "piano_composition.js" as Activity
+
+Rectangle {
+ id: dialogBackground
+ color: "#696da3"
+ border.color: "black"
+ border.width: 1
+ z: 10000
+ anchors.fill: parent
+ visible: false
+ focus: true
+
+ Keys.onEscapePressed: close()
+
+ signal close
+
+ property alias melodiesModel: melodiesModel
+ property bool horizontalLayout: dialogBackground.width >= dialogBackground.height
+ property int selectedMelodyIndex: -1
+
+ ListModel {
+ id: melodiesModel
+ }
+
+ Row {
+ spacing: 2
+ Item { width: 10; height: 1 }
+
+ Column {
+ spacing: 10
+ anchors.top: parent.top
+ Item { width: 1; height: 10 }
+ Rectangle {
+ id: titleRectangle
+ color: "#e6e6e6"
+ radius: 6.0
+ width: dialogBackground.width - 30
+ height: title.height * 1.2
+ border.color: "black"
+ border.width: 2
+
+ GCText {
+ id: title
+ text: qsTr("Melodies")
+ width: dialogBackground.width - 30
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ color: "black"
+ fontSize: 20
+ font.weight: Font.DemiBold
+ wrapMode: Text.WordWrap
+ }
+ }
+
+ Rectangle {
+ color: "#e6e6e6"
+ radius: 6.0
+ width: dialogBackground.width - 30
+ height: dialogBackground.height - 100
+ border.color: "black"
+ border.width: 2
+ anchors.margins: 100
+
+ Flickable {
+ id: flickableList
+ anchors.fill: parent
+ anchors.topMargin: 10
+ anchors.leftMargin: 20
+ contentWidth: parent.width
+ contentHeight: melodiesGrid.height
+ flickableDirection: Flickable.VerticalFlick
+ clip: true
+
+ Flow {
+ id: melodiesGrid
+ width: parent.width
+ spacing: 40
+ anchors.horizontalCenter: parent.horizontalCenter
+
+ Repeater {
+ id: melodiesRepeater
+ model: melodiesModel
+
+ Item {
+ id: melodiesItem
+ width: dialogBackground.horizontalLayout ? dialogBackground.width / 5 : dialogBackground.width / 4
+ height: dialogBackground.height / 5
+
+ Button {
+ text: title
+ onClicked: {
+ dialogBackground.selectedMelodyIndex = index
+ items.multipleStaff.stopAudios()
+ items.multipleStaff.nbStaves = 2
+ items.multipleStaff.bpmValue = defaultBPM ? defaultBPM : 60
+ items.multipleStaff.loadFromData(melody)
+ lyricsArea.setLyrics(title, _origin, lyrics)
+ }
+ width: parent.width
+ height: parent.height * 0.8
+ style: GCButtonStyle {
+ theme: "dark"
+ }
+
+ Image {
+ source: "qrc:/gcompris/src/core/resource/apply.svg"
+ sourceSize.width: height
+ sourceSize.height: height
+ width: height
+ height: parent.height / 4
+ anchors.bottom: parent.bottom
+ anchors.right: parent.right
+ anchors.margins: 2
+ visible: dialogBackground.selectedMelodyIndex === index
+ }
+ }
+ }
+ }
+ }
+ }
+ // The scroll buttons
+ GCButtonScroll {
+ anchors.right: parent.right
+ anchors.rightMargin: 5 * ApplicationInfo.ratio
+ anchors.bottom: flickableList.bottom
+ anchors.bottomMargin: 30 * ApplicationInfo.ratio
+ width: parent.width / 20
+ height: width * heightRatio
+ onUp: flickableList.flick(0, 1400)
+ onDown: flickableList.flick(0, -1400)
+ upVisible: (flickableList.visibleArea.yPosition <= 0) ? false : true
+ downVisible: ((flickableList.visibleArea.yPosition + flickableList.visibleArea.heightRatio) >= 1) ? false : true
+ }
+ }
+ Item { width: 1; height: 10 }
+ }
+ }
+
+ GCButtonCancel {
+ onClose: {
+ dialogBackground.selectedMelodyIndex = -1
+ parent.close()
+ }
+ }
+}
diff --git a/src/activities/piano_composition/MultipleStaff.qml b/src/activities/piano_composition/MultipleStaff.qml
new file mode 100644
index 000000000..3f1aeb886
--- /dev/null
+++ b/src/activities/piano_composition/MultipleStaff.qml
@@ -0,0 +1,605 @@
+/* GCompris - MultipleStaff.qml
+ *
+ * Copyright (C) 2016 Johnny Jazeix <jazeix@gmail.com>
+ * Copyright (C) 2018 Aman Kumar Gupta <gupta2140@gmail.com>
+ *
+ * Authors:
+ * Beth Hadley <bethmhadley@gmail.com> (GTK+ version)
+ * Johnny Jazeix <jazeix@gmail.com> (Qt Quick port)
+ * Aman Kumar Gupta <gupta2140@gmail.com> (Qt Quick port)
+ *
+ * This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+ */
+import QtQuick 2.6
+import GCompris 1.0
+
+import "../../core"
+import "qrc:/gcompris/src/activities/piano_composition/NoteNotations.js" as NoteNotations
+
+Item {
+ id: multipleStaff
+
+ property int nbStaves
+ property string clef
+ property int distanceBetweenStaff: multipleStaff.height / 3.3
+ readonly property real clefImageWidth: 3 * height / 25
+
+ // Stores the note index which is selected.
+ property int selectedIndex: -1
+
+ // The notes that are to be colored can be assigned to this variable in the activity
+ property var coloredNotes: []
+
+ // When the notesColor is inbuilt, the default color mapping will be done, else assign any color externally in the activity. Example: Reference notes in note_names are red colored.
+ property string notesColor: "inbuilt"
+ property bool noteHoverEnabled: false
+
+ // Stores if the notes are to be centered on the staff. Used in Play_piano and Play_rhythm.
+ property bool centerNotesPosition: false
+ property bool isPulseMarkerDisplayed: false
+ property bool noteAnimationEnabled: false
+ readonly property bool isMusicPlaying: musicTimer.running
+
+ property alias flickableStaves: flickableStaves
+ property alias musicElementModel: musicElementModel
+ property alias musicElementRepeater: musicElementRepeater
+ property double softColorOpacity : 0.8
+ property real flickableTopMargin: multipleStaff.height / 14 + distanceBetweenStaff / 3.5
+ readonly property real pulseMarkerX: pulseMarker.x
+ readonly property bool isPulseMarkerRunning: pulseMarkerAnimation.running
+ property bool isFlickable: true
+ property bool enableNotesSound: true
+ property int currentEnteringStaff: 0
+ property int bpmValue: 120
+
+ // The position where the 1st note in the centered state is to be placed.
+ property real firstCenteredNotePosition: multipleStaff.width / 3.3
+ property real spaceBetweenNotes: 0
+
+ /**
+ * Emitted when a note is clicked.
+ *
+ * It is used for selecting note to play, erase and do other operations on it.
+ */
+ signal noteClicked(int noteIndex)
+
+ /**
+ * Emitted when the animation of the note from the right of the staff to the left is finished.
+ *
+ * It's used in note_names activity.
+ */
+ signal noteAnimationFinished
+
+ /**
+ * Emitted when the pulseMarker's animation is finished.
+ */
+ signal pulseMarkerAnimationFinished
+
+ /**
+ * Used in play_rhythm activity. It tells the instants when pulseMarker reaches a note and the drum sound is to be played.
+ */
+ signal playDrumSound
+
+ ListModel {
+ id: musicElementModel
+ }
+
+ Flickable {
+ id: flickableStaves
+ interactive: multipleStaff.isFlickable
+ flickableDirection: Flickable.VerticalFlick
+ contentWidth: staffColumn.width
+ contentHeight: staffColumn.height + distanceBetweenStaff
+ anchors.fill: parent
+ clip: true
+ Behavior on contentY {
+ NumberAnimation { duration: 250 }
+ }
+
+ Column {
+ id: staffColumn
+ spacing: distanceBetweenStaff
+ anchors.top: parent.top
+ anchors.topMargin: flickableTopMargin
+ Repeater {
+ id: staves
+ model: nbStaves
+ Staff {
+ id: staff
+ height: multipleStaff.height / 5
+ width: multipleStaff.width - 5
+ lastPartition: index == (nbStaves - 1)
+ }
+ }
+ }
+
+ Repeater {
+ id: musicElementRepeater
+ model: musicElementModel
+ MusicElement {
+ id: musicElement
+ noteName: noteName_
+ noteType: noteType_
+ highlightWhenPlayed: highlightWhenPlayed_
+ noteIsColored: multipleStaff.coloredNotes.indexOf(noteName[0]) != -1
+ soundPitch: soundPitch_
+ clefType: clefType_
+ elementType: elementType_
+ isDefaultClef: isDefaultClef_
+
+ property int staffNb: staffNb_
+ property alias noteAnimation: noteAnimation
+ // The shift which the elements experience when a sharp/flat note is added before them.
+ readonly property real sharpShiftDistance: blackType != "" ? width / 6 : 0
+
+ noteDetails: multipleStaff.getNoteDetails(noteName, noteType, clefType)
+
+ MouseArea {
+ id: noteMouseArea
+ anchors.fill: parent
+ hoverEnabled: true
+ onClicked: multipleStaff.noteClicked(index)
+ }
+
+ function highlightNote() {
+ highlightTimer.start()
+ }
+
+ readonly property real defaultXPosition: musicElementRepeater.itemAt(index - 1) ? (musicElementRepeater.itemAt(index - 1).width + musicElementRepeater.itemAt(index - 1).x)
+ : 0
+
+ x: {
+ if(multipleStaff.noteAnimationEnabled)
+ return NaN
+ // !musicElementRepeater.itemAt(index - 1) acts as a fallback condition when there is no previous element present. It happens when Qt clears the model internally.
+ if(isDefaultClef || !musicElementRepeater.itemAt(index - 1))
+ return 0
+ else if(musicElementRepeater.itemAt(index - 1).elementType === "clef") {
+ if(centerNotesPosition)
+ return sharpShiftDistance + defaultXPosition + multipleStaff.firstCenteredNotePosition
+ else
+ return sharpShiftDistance + defaultXPosition + 10
+ }
+ else
+ return sharpShiftDistance + defaultXPosition + multipleStaff.spaceBetweenNotes
+ }
+
+ onYChanged: {
+ if(noteAnimationEnabled && elementType === "note")
+ noteAnimation.start()
+ }
+
+ y: {
+ if(elementType === "clef")
+ return flickableTopMargin + staves.itemAt(staffNb).y
+ else if(noteDetails === undefined || staves.itemAt(staffNb) == undefined)
+ return 0
+
+ var verticalDistanceBetweenLines = staves.itemAt(0).verticalDistanceBetweenLines
+ var shift = -verticalDistanceBetweenLines / 2
+ var relativePosition = noteDetails.positionOnStaff
+ var imageY = flickableTopMargin + staves.itemAt(staffNb).y + 2 * verticalDistanceBetweenLines
+
+ if(rotation === 180) {
+ return imageY - (4 - relativePosition) * verticalDistanceBetweenLines + shift
+ }
+
+ return imageY - (6 - relativePosition) * verticalDistanceBetweenLines + shift
+ }
+
+ NumberAnimation {
+ id: noteAnimation
+ target: musicElement
+ properties: "x"
+ duration: 9000
+ from: multipleStaff.width - 10
+ to: multipleStaff.clefImageWidth
+ onStopped: {
+ noteAnimationFinished()
+ }
+ }
+ }
+ }
+
+ Image {
+ id: secondStaffDefaultClef
+ sourceSize.width: musicElementModel.count ? multipleStaff.clefImageWidth : 0
+ y: staves.count === 2 ? flickableTopMargin + staves.itemAt(1).y : 0
+ visible: (currentEnteringStaff === 0) && (nbStaves === 2)
+ source: background.clefType ? "qrc:/gcompris/src/activities/piano_composition/resource/" + background.clefType.toLowerCase() + "Clef.svg"
+ : ""
+ }
+ }
+
+ Rectangle {
+ id: pulseMarker
+ width: activity.horizontalLayout ? 5 : 3
+ border.width: width / 2
+ height: staves.itemAt(0) == undefined ? 0 : 4 * staves.itemAt(0).verticalDistanceBetweenLines + width
+ opacity: isPulseMarkerDisplayed && pulseMarkerAnimation.running
+ color: "red"
+ y: flickableTopMargin
+
+ property real nextPosition: 0
+
+ NumberAnimation {
+ id: pulseMarkerAnimation
+ target: pulseMarker
+ property: "x"
+ to: pulseMarker.nextPosition
+ onStarted: {
+ if(pulseMarker.height == 0 && staves.count != 0) {
+ pulseMarker.height = Qt.binding(function() {return 4 * staves.itemAt(0).verticalDistanceBetweenLines + pulseMarker.width;})
+ }
+ }
+ onStopped: {
+ if(pulseMarker.x === multipleStaff.width)
+ pulseMarkerAnimationFinished()
+ else
+ playDrumSound()
+ }
+ }
+ }
+
+ /**
+ * Initializes the default clefs on the staves.
+ *
+ * @param clefType: The clef type to be initialized.
+ */
+ function initClefs(clefType) {
+ musicElementModel.clear()
+ musicElementModel.append({ "elementType_": "clef", "clefType_": clefType, "staffNb_": 0, "isDefaultClef_": true,
+ "noteName_": "", "noteType_": "", "soundPitch_": clefType,
+ "highlightWhenPlayed_": false })
+ }
+
+ /**
+ * Pauses the sliding animation of the notes.
+ */
+ function pauseNoteAnimation() {
+ for(var i = 0; i < musicElementModel.count; i++) {
+ if(musicElementRepeater.itemAt(i).noteAnimation.running)
+ musicElementRepeater.itemAt(i).noteAnimation.pause()
+ }
+ }
+
+ function resumeNoteAnimation() {
+ for(var i = 0; i < musicElementModel.count; i++) {
+ musicElementRepeater.itemAt(i).noteAnimation.resume()
+ }
+ }
+
+ /**
+ * Gets all the details of any note like note image, position on staff etc. from NoteNotations.
+ */
+ function getNoteDetails(noteName, noteType, clefType) {
+ var notesDetails = NoteNotations.get()
+ var noteNotation
+ if(noteType === "Rest")
+ noteNotation = noteName + noteType
+ else
+ noteNotation = clefType + noteName
+
+ for(var i = 0; i < notesDetails.length; i++) {
+ if(noteNotation === notesDetails[i].noteName) {
+ return notesDetails[i]
+ }
+ }
+ }
+
+ /**
+ * Adds a note to the staff.
+ */
+ function addMusicElement(elementType, noteName, noteType, highlightWhenPlayed, playAudio, clefType, soundPitch, isUnflicked) {
+ if(soundPitch == undefined || soundPitch === "")
+ soundPitch = clefType
+
+ var isNextStaff = (selectedIndex == -1) && musicElementModel.count && ((staves.itemAt(0).width - musicElementRepeater.itemAt(musicElementModel.count - 1).x - musicElementRepeater.itemAt(musicElementModel.count - 1).width) < multipleStaff.clefImageWidth)
+
+ // If the incoming element is a clef, make sure that there is enough required space to fit one more note too. Else it creates problem when the note is erased and the view is redrawn, else move on to the next staff.
+ if(elementType === "clef" && musicElementModel.count && (selectedIndex == -1)) {
+ if(staves.itemAt(0).width - musicElementRepeater.itemAt(musicElementModel.count - 1).x - musicElementRepeater.itemAt(musicElementModel.count - 1).width - 2 * Math.max(multipleStaff.clefImageWidth, musicElementRepeater.itemAt(0).noteImageWidth) < 0)
+ isNextStaff = true
+ }
+
+ if(isNextStaff && !noteAnimationEnabled) {
+ multipleStaff.currentEnteringStaff++
+ if(multipleStaff.currentEnteringStaff >= multipleStaff.nbStaves)
+ multipleStaff.nbStaves++
+ // When a new staff is added, initialise it with a default clef.
+ musicElementModel.append({"noteName_": "", "noteType_": "", "soundPitch_": soundPitch,
+ "clefType_": clefType, "highlightWhenPlayed_": false,
+ "staffNb_": multipleStaff.currentEnteringStaff,
+ "isDefaultClef_": true, "elementType_": "clef"})
+
+ if(!isUnflicked)
+ flickableStaves.flick(0, - nbStaves * multipleStaff.height)
+
+ if(elementType === "clef")
+ return 0
+
+ isNextStaff = false
+ }
+
+ if(selectedIndex === -1) {
+ var isDefaultClef = false
+ if(!musicElementModel.count)
+ isDefaultClef = true
+ musicElementModel.append({"noteName_": noteName, "noteType_": noteType, "soundPitch_": soundPitch,
+ "clefType_": clefType, "highlightWhenPlayed_": highlightWhenPlayed,
+ "staffNb_": multipleStaff.currentEnteringStaff,
+ "isDefaultClef_": isDefaultClef, "elementType_": elementType})
+
+ }
+ else {
+ var tempModel = createNotesBackup()
+ var insertingIndex = selectedIndex + 1
+ if(elementType === "clef")
+ insertingIndex--
+
+ tempModel.splice(insertingIndex, 0, {"elementType_": elementType, "noteName_": noteName, "noteType_": noteType,
+ "soundPitch_": soundPitch, "clefType_": clefType })
+ if(elementType === "clef") {
+ for(var i = 0; i < musicElementModel.count && tempModel[i]["elementType_"] != "clef"; i++)
+ tempModel[i]["soundPitch_"] = clefType
+ }
+ selectedIndex = -1
+
+ redraw(tempModel)
+ }
+
+ multipleStaff.selectedIndex = -1
+ background.clefType = musicElementModel.get(musicElementModel.count - 1).soundPitch_
+
+ if(playAudio)
+ playNoteAudio(noteName, noteType, soundPitch, musicElementRepeater.itemAt(musicElementModel.count - 1).duration)
+ }
+
+ /**
+ * Creates a backup of the musicElementModel before erasing it.
+ *
+ * This backup data is used to redraw the notes.
+ */
+ function createNotesBackup() {
+ var tempModel = []
+ for(var i = 0; i < musicElementModel.count; i++)
+ tempModel.push(JSON.parse(JSON.stringify(musicElementModel.get(i))))
+
+ return tempModel
+ }
+
+ /**
+ * Redraws all the notes on the staves.
+ */
+ function redraw(notes) {
+ musicElementModel.clear()
+ currentEnteringStaff = 0
+ selectedIndex = -1
+ for(var i = 0; i < notes.length; i++) {
+ var note = notes[i]
+ // On load melody from file, the first "note" is the BPM value
+ if(note.bpm) {
+ bpmValue = note.bpm;
+ }
+ else {
+ addMusicElement(note["elementType_"], note["noteName_"], note["noteType_"], false, false, note["clefType_"], note["soundPitch_"], true)
+ }
+ }
+
+ // Remove the remaining unused staffs.
+ if((multipleStaff.currentEnteringStaff + 1 < multipleStaff.nbStaves) && (multipleStaff.nbStaves > 2)) {
+ nbStaves = multipleStaff.currentEnteringStaff + 1
+ flickableStaves.flick(0, - nbStaves * multipleStaff.height)
+ }
+
+ var lastMusicElement = musicElementModel.get(musicElementModel.count - 1)
+ if(lastMusicElement.isDefaultClef_ && nbStaves > 2) {
+ musicElementModel.remove(musicElementModel.count - 1)
+ lastMusicElement = musicElementModel.get(musicElementModel.count - 1)
+ }
+
+ if(lastMusicElement.staffNb_ < nbStaves - 1 && nbStaves != 2)
+ nbStaves = lastMusicElement.staffNb_ + 1
+
+ currentEnteringStaff = lastMusicElement.staffNb_
+ background.clefType = lastMusicElement.soundPitch_
+ }
+
+ /**
+ * Erases the selected note.
+ *
+ * @param noteIndex: index of the note to be erased
+ */
+ function eraseNote(noteIndex) {
+ musicElementModel.remove(noteIndex)
+ selectedIndex = -1
+ var tempModel = createNotesBackup()
+ redraw(tempModel)
+ }
+
+ /**
+ * Erases all the notes.
+ */
+ function eraseAllNotes() {
+ musicElementModel.clear()
+ selectedIndex = -1
+ multipleStaff.currentEnteringStaff = 0
+ initClefs(background.clefType)
+ }
+
+ readonly property var octave1MidiNumbersTable: {"C":24,"C#":25,"Db":25,"D":26,"D#":27,"Eb":27,"E":28,"F":29,"F#":30,"Gb":30,"G":31,"G#":32,"Ab":32,"A":33,"A#":34,"Bb":34,"B":35}
+ /**
+ * Plays audio for a note.
+ *
+ * @param noteName: name of the note to be played.
+ * @param noteType: note type to be played.
+ */
+ function playNoteAudio(noteName, noteType, soundPitch, duration) {
+ if(noteName) {
+ if(noteType != "Rest") {
+ // We should find a corresponding b type enharmonic notation for # type note to play the audio.
+ if(noteName[1] === "#") {
+ var blackKeysFlat = piano.blackKeyFlatNoteLabelsArray
+ var blackKeysSharp = piano.blackKeySharpNoteLabelsArray
+
+ for(var i = 0; i < blackKeysSharp.length; i++) {
+ if(blackKeysSharp[i][0] === noteName) {
+ noteName = blackKeysFlat[i][0]
+ break
+ }
+ }
+ }
+
+ var octaveNb = ""
+ var noteCharName = ""
+ if(noteName[1] == "#" || noteName[1] == "b") {
+ noteCharName = noteName[0] + noteName[1]
+ octaveNb = noteName[2]
+ }
+ else
+ {
+ noteCharName = noteName[0]
+ octaveNb = noteName[1]
+ }
+ var noteMidiName = (octaveNb-1)*12 + octave1MidiNumbersTable[noteCharName];
+
+ GSynth.generate(noteMidiName, duration)
+ }
+ }
+ }
+
+ /**
+ * Get all the notes from the musicElementModel and returns the melody.
+ */
+ function getAllNotes() {
+ var notes = createNotesBackup()
+ return notes
+ }
+
+ /**
+ * Loads melody from the provided data, to the staffs.
+ *
+ * @param data: melody to be loaded
+ */
+ function loadFromData(data) {
+ if(data != undefined) {
+ var melody = data.split(" ")
+ background.clefType = melody[0]
+ eraseAllNotes()
+ for(var i = 1 ; i < melody.length; ++i) {
+ var noteLength = melody[i].length
+ var noteName = melody[i][0]
+ var noteType
+ if(melody[i].substring(noteLength - 4, noteLength) === "Rest") {
+ noteName = melody[i].substring(0, noteLength - 4)
+ noteType = "Rest"
+ }
+ else if(melody[i][1] === "#" || melody[i][1] === "b") {
+ noteType = melody[i].substring(3, melody[i].length)
+ noteName += melody[i][1] + melody[i][2];
+ }
+ else {
+ noteType = melody[i].substring(2, melody[i].length)
+ noteName += melody[i][1]
+ }
+ addMusicElement("note", noteName, noteType, false, false, melody[0])
+ }
+ var tempModel = createNotesBackup()
+ redraw(tempModel)
+ }
+ }
+
+ /**
+ * Used in the activity play_piano.
+ *
+ * Checks if the answered note is correct
+ */
+ function indicateAnsweredNote(isCorrectAnswer, noteIndexAnswered) {
+ musicElementRepeater.itemAt(noteIndexAnswered).noteAnswered = true
+ musicElementRepeater.itemAt(noteIndexAnswered).isCorrectlyAnswered = isCorrectAnswer
+ }
+
+ /**
+ * Used in the activity play_piano.
+ *
+ * Reverts the previous answer.
+ */
+ function revertAnswer(noteIndexReverting) {
+ musicElementRepeater.itemAt(noteIndexReverting).noteAnswered = false
+ }
+
+ function play() {
+ musicTimer.currentNote = 0
+ selectedIndex = -1
+ musicTimer.interval = 1
+ if(isFlickable)
+ flickableStaves.flick(0, nbStaves * multipleStaff.height)
+
+ pulseMarkerAnimation.stop()
+
+ if(musicElementModel.count > 1)
+ pulseMarker.x = musicElementRepeater.itemAt(1).x + musicElementRepeater.itemAt(1).width / 2
+ else
+ pulseMarker.x = 0
+
+ musicTimer.start()
+ }
+
+ /**
+ * Stops the audios playing.
+ */
+ function stopAudios() {
+ musicElementModel.clear()
+ musicTimer.stop()
+ items.audioEffects.stop()
+ }
+
+ Timer {
+ id: musicTimer
+
+ property int currentNote: 0
+
+ onRunningChanged: {
+ if(!running && musicElementModel.get(currentNote) !== undefined) {
+ var currentElement = musicElementModel.get(currentNote)
+ var currentType = currentElement.noteType_
+ var note = currentElement.noteName_
+ var soundPitch = currentElement.soundPitch_
+ var currentStaff = currentElement.staffNb_
+ background.clefType = currentElement.clefType_
+
+ if(currentElement.isDefaultClef_ && currentStaff > 1) {
+ flickableStaves.contentY = staves.itemAt(currentStaff - 1).y
+ }
+
+ musicTimer.interval = musicElementRepeater.itemAt(currentNote).duration
+ if(multipleStaff.enableNotesSound)
+ playNoteAudio(note, currentType, soundPitch, musicTimer.interval)
+ pulseMarkerAnimation.stop()
+ pulseMarkerAnimation.duration = Math.max(1, musicTimer.interval)
+ if(musicElementRepeater.itemAt(currentNote + 1) != undefined)
+ pulseMarker.nextPosition = musicElementRepeater.itemAt(currentNote + 1).x + musicElementRepeater.itemAt(currentNote + 1).width / 2
+ else
+ pulseMarker.nextPosition = multipleStaff.width
+
+ pulseMarkerAnimation.start()
+
+ if(!isPulseMarkerDisplayed)
+ musicElementRepeater.itemAt(currentNote).highlightNote()
+ currentNote++
+ musicTimer.start()
+ }
+ }
+ }
+}
diff --git a/src/activities/piano_composition/MusicElement.qml b/src/activities/piano_composition/MusicElement.qml
new file mode 100644
index 000000000..615a45a5a
--- /dev/null
+++ b/src/activities/piano_composition/MusicElement.qml
@@ -0,0 +1,204 @@
+/* GCompris - musicElement.qml
+ *
+ * Copyright (C) 2016 Johnny Jazeix <jazeix@gmail.com>
+ * Copyright (C) 2018 Aman Kumar Gupta <gupta2140@gmail.com>
+ *
+ * Authors:
+ * Beth Hadley <bethmhadley@gmail.com> (GTK+ version)
+ * Johnny Jazeix <jazeix@gmail.com> (Qt Quick port)
+ * Aman Kumar Gupta <gupta2140@gmail.com> (Qt Quick port)
+ *
+ * This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+ */
+import QtQuick 2.6
+import QtGraphicalEffects 1.0
+import GCompris 1.0
+
+import "../../core"
+
+Item {
+ id: musicElement
+ width: noteImageWidth
+ height: multipleStaff.height / 5
+
+ property string noteName
+ property string noteType
+ property string soundPitch
+ property string clefType
+ property string elementType
+ property bool noteIsColored: true
+ property bool isDefaultClef: false
+ property string blackType: noteName === "" ? ""
+ : noteName[1] === "#" ? "sharp"
+ : noteName[1] === "b" ? "flat" : ""// empty, "flat" or "sharp"
+
+ /**
+ * Calculates and assign the timer interval for a note.
+ */
+ function calculateTimerDuration(noteType) {
+ noteType = noteType.toLowerCase()
+ if(noteType === "whole")
+ return 240000 / multipleStaff.bpmValue
+ else if(noteType === "half")
+ return 120000 / multipleStaff.bpmValue
+ else if(noteType === "quarter")
+ return 60000 / multipleStaff.bpmValue
+ else
+ return 30000 / multipleStaff.bpmValue
+ }
+
+ readonly property int duration: {
+ if(elementType != "clef") {
+ if(noteType === "Rest")
+ return calculateTimerDuration(noteName)
+ else
+ return calculateTimerDuration(noteType)
+ }
+ return 0
+ }
+
+ readonly property real noteImageWidth: (multipleStaff.width - 15 - clefImageWidth) / 10
+
+ readonly property var noteColorMap: { "1": "#FF0000", "2": "#FF7F00", "3": "#FFFF00",
+ "4": "#32CD32", "5": "#6495ED", "6": "#D02090", "7": "#FF1493", "8": "#FF0000",
+ "-1": "#FF6347", "-2": "#FFD700", "-3": "#20B2AA", "-4": "#8A2BE2",
+ "-5": "#FF00FF" }
+
+ readonly property var whiteNoteName: { "C": "1", "D": "2", "E": "3", "F": "4", "G": "5", "A": "6", "B": "7", "C": "8" }
+
+ readonly property var sharpNoteName: { "C#": "-1", "D#": "-2", "F#": "-3", "G#": "-4", "A#": "-5" }
+ readonly property var flatNoteName: { "Db": "-1", "Eb": "-2", "Gb": "-3", "Ab": "-4", "Bb": "-5" }
+ readonly property var blackNoteName: blackType == "" ? blackType
+ : blackType == "flat" ? flatNoteName : sharpNoteName
+
+ property bool highlightWhenPlayed: false
+ property alias highlightTimer: highlightTimer
+
+ property var noteDetails
+
+ property bool noteAnswered: false
+ property bool isCorrectlyAnswered: false
+
+ rotation: {
+ if((noteDetails === undefined) || elementType === "clef")
+ return 0
+ else if((noteDetails.positionOnStaff < 0) && (noteType === "Whole"))
+ return 180
+ else
+ return noteDetails.rotation
+ }
+
+ Image {
+ id: blackTypeImage
+ source: blackType !== "" ? "qrc:/gcompris/src/activities/piano_composition/resource/black" + blackType + ".svg" : ""
+ sourceSize.width: noteImage.width / 2
+ anchors.right: parent.rotation === 180 ? undefined : noteImage.left
+ anchors.left: parent.rotation === 180 ? noteImage.right : undefined
+ rotation: parent.rotation === 180 ? 180 : 0
+ anchors.rightMargin: -noteImage.width / 4
+ anchors.leftMargin: -noteImage.width / 2.5
+ anchors.bottom: noteImage.bottom
+ anchors.bottomMargin: parent.height / 6
+ fillMode: Image.PreserveAspectFit
+ }
+
+ Rectangle {
+ id: highlightRectangle
+ width: musicElement.width
+ height: musicElement.height * 0.9
+ color: "transparent"
+ opacity: 1
+ border.color: "#373737"
+ border.width: radius * 0.5
+ radius: width * 0.1
+ visible: (multipleStaff.noteHoverEnabled && noteMouseArea.containsMouse) || highlightTimer.running
+ }
+
+ Rectangle {
+ id: selectedNoteIndicator
+ width: musicElement.width
+ height: musicElement.height * 0.9
+ color: "blue"
+ opacity: 0.6
+ border.color: "white"
+ radius: width / 5
+ visible: selectedIndex == index
+ }
+
+ Image {
+ id: noteImage
+ source: (noteDetails === undefined) ? ""
+ : noteType != "Rest" ? "qrc:/gcompris/src/activities/piano_composition/resource/" + noteDetails.imageName + noteType + ".svg"
+ : "qrc:/gcompris/src/activities/piano_composition/resource/" + noteDetails.imageName + ".svg"
+ sourceSize.width: 200
+ width: musicElement.width
+ height: musicElement.height
+ mirror: parent.rotation == 180 && parent.noteType == "Eighth" ? true : false
+ }
+
+ Image {
+ id: clefImage
+ source: (elementType === "clef") ? "qrc:/gcompris/src/activities/piano_composition/resource/" + clefType.toLowerCase() + "Clef.svg" : ""
+ sourceSize.width: multipleStaff.clefImageWidth
+ }
+
+ Image {
+ id: correctOrWrongAnswerIndicator
+ visible: noteAnswered
+ source: isCorrectlyAnswered ? "qrc:/gcompris/src/activities/piano_composition/resource/passed.svg"
+ : "qrc:/gcompris/src/activities/piano_composition/resource/failed.svg"
+ sourceSize.width: noteImage.width / 2.5
+ anchors.right: parent.rotation === 180 ? undefined : noteImage.right
+ anchors.left: parent.rotation === 180 ? noteImage.left : undefined
+ rotation: parent.rotation === 180 ? 180 : 0
+ anchors.rightMargin: 12
+ anchors.bottom: noteImage.bottom
+ anchors.bottomMargin: parent.height / 6
+ fillMode: Image.PreserveAspectFit
+ z: 3
+ }
+
+ Rectangle {
+ id:softColor
+ readonly property int invalidConditionNumber: -6
+ readonly property int noteColorNumber: {
+ if(noteDetails === undefined || noteType === "" || noteType === "Rest" || noteName === "")
+ return invalidConditionNumber
+ else if((blackType === "") && (whiteNoteName[noteName[0]] != undefined))
+ return whiteNoteName[noteName[0]]
+ else if((noteName.length > 2) && (blackNoteName[noteName.substring(0,2)] != undefined))
+ return blackNoteName[noteName.substring(0,2)]
+ else
+ return invalidConditionNumber
+ }
+ color: {
+ if(multipleStaff.notesColor === "inbuilt")
+ return (noteColorNumber > invalidConditionNumber) ? noteColorMap[noteColorNumber] : "white"
+ else
+ return multipleStaff.notesColor
+ }
+ z: -1
+ width: noteImage.width * 0.8
+ height: width
+ radius: width * 0.5
+ anchors.centerIn: noteImage
+ opacity: softColorOpacity
+ visible: noteIsColored && (elementType != "clef")
+ }
+
+ Timer {
+ id: highlightTimer
+ interval: duration
+ }
+}
diff --git a/src/activities/piano_composition/NoteNotations.js b/src/activities/piano_composition/NoteNotations.js
new file mode 100644
index 000000000..1cc04c977
--- /dev/null
+++ b/src/activities/piano_composition/NoteNotations.js
@@ -0,0 +1,621 @@
+/* GCompris - NoteNotations.js
+ *
+ * Copyright (C) 2018 Aman Kumar Gupta <gupta2140@gmail.com>
+ *
+ * Authors:
+ * Beth Hadley <bethmhadley@gmail.com> (GTK+ version)
+ * Johnny Jazeix <jazeix@gmail.com> (Qt Quick port)
+ * Aman Kumar Gupta <gupta2140@gmail.com> (Qt Quick port)
+ *
+ * This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+ **/
+
+function get() {
+ return [
+ {
+ "noteName": "TrebleD3",
+ "imageName": "trebleD3",
+ "rotation": 0,
+ "positionOnStaff": 9
+ },
+ {
+ "noteName": "TrebleE3",
+ "imageName": "trebleE3",
+ "rotation": 0,
+ "positionOnStaff": 8.5
+ },
+ {
+ "noteName": "TrebleF#3",
+ "imageName": "bassG4",
+ "rotation": 0,
+ "positionOnStaff": 8
+ },
+ {
+ "noteName": "TrebleF3",
+ "imageName": "bassG4",
+ "rotation": 0,
+ "positionOnStaff": 8
+ },
+ {
+ "noteName": "TrebleGb3",
+ "imageName": "bassF4",
+ "rotation": 0,
+ "positionOnStaff": 7.5
+ },
+ {
+ "noteName": "TrebleG3",
+ "imageName": "bassF4",
+ "rotation": 0,
+ "positionOnStaff": 7.5
+ },
+ {
+ "noteName": "TrebleG#3",
+ "imageName": "bassF4",
+ "rotation": 0,
+ "positionOnStaff": 7.5
+ },
+ {
+ "noteName": "TrebleA3",
+ "imageName": "trebleA3",
+ "rotation": 0,
+ "positionOnStaff": 7
+ },
+ {
+ "noteName": "TrebleA#3",
+ "imageName": "trebleA3",
+ "rotation": 0,
+ "positionOnStaff": 7
+ },
+ {
+ "noteName": "TrebleAb3",
+ "imageName": "trebleA3",
+ "rotation": 0,
+ "positionOnStaff": 7
+ },
+ {
+ "noteName": "TrebleB3",
+ "imageName": "trebleB3",
+ "rotation": 0,
+ "positionOnStaff": 6.5
+ },
+ {
+ "noteName": "TrebleBb3",
+ "imageName": "trebleB3",
+ "rotation": 0,
+ "positionOnStaff": 6.5
+ },
+ {
+ "noteName": "TrebleC4",
+ "imageName": "trebleC4",
+ "rotation": 0,
+ "positionOnStaff": 6
+ },
+ {
+ "noteName": "TrebleC#4",
+ "imageName": "trebleC4",
+ "rotation": 0,
+ "positionOnStaff": 6
+ },
+ {
+ "noteName": "TrebleDb4",
+ "imageName": "genericNote",
+ "rotation": 0,
+ "positionOnStaff": 5.5
+ },
+ {
+ "noteName": "TrebleD4",
+ "imageName": "genericNote",
+ "rotation": 0,
+ "positionOnStaff": 5.5
+ },
+ {
+ "noteName": "TrebleD#4",
+ "imageName": "genericNote",
+ "rotation": 0,
+ "positionOnStaff": 5.5
+ },
+ {
+ "noteName": "TrebleEb4",
+ "imageName": "genericNote",
+ "rotation": 0,
+ "positionOnStaff": 5
+ },
+ {
+ "noteName": "TrebleE4",
+ "imageName": "genericNote",
+ "rotation": 0,
+ "positionOnStaff": 5
+ },
+ {
+ "noteName": "TrebleF4",
+ "imageName": "genericNote",
+ "rotation": 0,
+ "positionOnStaff": 4.5
+ },
+ {
+ "noteName": "TrebleF#4",
+ "imageName": "genericNote",
+ "rotation": 0,
+ "positionOnStaff": 4.5
+ },
+ {
+ "noteName": "TrebleG4",
+ "imageName": "genericNote",
+ "rotation": 0,
+ "positionOnStaff": 4
+ },
+ {
+ "noteName": "TrebleGb4",
+ "imageName": "genericNote",
+ "rotation": 0,
+ "positionOnStaff": 4
+ },
+ {
+ "noteName": "TrebleG#4",
+ "imageName": "genericNote",
+ "rotation": 0,
+ "positionOnStaff": 4
+ },
+ {
+ "noteName": "TrebleAb4",
+ "imageName": "genericNote",
+ "rotation": 0,
+ "positionOnStaff": 3.5
+ },
+ {
+ "noteName": "TrebleA4",
+ "imageName": "genericNote",
+ "rotation": 0,
+ "positionOnStaff": 3.5
+ },
+ {
+ "noteName": "TrebleA#4",
+ "imageName": "genericNote",
+ "rotation": 0,
+ "positionOnStaff": 3.5
+ },
+ {
+ "noteName": "TrebleBb4",
+ "imageName": "genericNote",
+ "rotation": 0,
+ "positionOnStaff": 3
+ },
+ {
+ "noteName": "TrebleB4",
+ "imageName": "genericNote",
+ "rotation": 0,
+ "positionOnStaff": 3
+ },
+ {
+ "noteName": "TrebleC5",
+ "imageName": "genericNote",
+ "rotation": 180,
+ "positionOnStaff": 2.5
+ },
+ {
+ "noteName": "TrebleC#5",
+ "imageName": "genericNote",
+ "rotation": 180,
+ "positionOnStaff": 2.5
+ },
+ {
+ "noteName": "TrebleDb5",
+ "imageName": "genericNote",
+ "rotation": 180,
+ "positionOnStaff": 2
+ },
+ {
+ "noteName": "TrebleD5",
+ "imageName": "genericNote",
+ "rotation": 180,
+ "positionOnStaff": 2
+ },
+ {
+ "noteName": "TrebleD#5",
+ "imageName": "genericNote",
+ "rotation": 180,
+ "positionOnStaff": 2
+ },
+ {
+ "noteName": "TrebleEb5",
+ "imageName": "genericNote",
+ "rotation": 180,
+ "positionOnStaff": 1.5
+ },
+ {
+ "noteName": "TrebleE5",
+ "imageName": "genericNote",
+ "rotation": 180,
+ "positionOnStaff": 1.5
+ },
+ {
+ "noteName": "TrebleF5",
+ "imageName": "genericNote",
+ "rotation": 180,
+ "positionOnStaff": 1
+ },
+ {
+ "noteName": "TrebleF#5",
+ "imageName": "genericNote",
+ "rotation": 180,
+ "positionOnStaff": 1
+ },
+ {
+ "noteName": "TrebleG5",
+ "imageName": "genericNote",
+ "rotation": 180,
+ "positionOnStaff": 0.5
+ },
+ {
+ "noteName": "TrebleGb5",
+ "imageName": "genericNote",
+ "rotation": 180,
+ "positionOnStaff": 0.5
+ },
+ {
+ "noteName": "TrebleG#5",
+ "imageName": "genericNote",
+ "rotation": 180,
+ "positionOnStaff": 0.5
+ },
+ {
+ "noteName": "TrebleAb5",
+ "imageName": "genericNote",
+ "rotation": 180,
+ "positionOnStaff": 0
+ },
+ {
+ "noteName": "TrebleA5",
+ "imageName": "trebleC4",
+ "rotation": 180,
+ "positionOnStaff": 0
+ },
+ {
+ "noteName": "TrebleA#5",
+ "imageName": "trebleC4",
+ "rotation": 180,
+ "positionOnStaff": 0
+ },
+ {
+ "noteName": "TrebleBb5",
+ "imageName": "trebleB3",
+ "rotation": 180,
+ "positionOnStaff": -0.5
+ },
+ {
+ "noteName": "TrebleB5",
+ "imageName": "trebleB3",
+ "rotation": 180,
+ "positionOnStaff": -0.5
+ },
+ {
+ "noteName": "TrebleC6",
+ "imageName": "trebleA3",
+ "rotation": 180,
+ "positionOnStaff": -1
+ },
+ {
+ "noteName": "TrebleC#6",
+ "imageName": "trebleA3",
+ "rotation": 180,
+ "positionOnStaff": -1
+ },
+ {
+ "noteName": "TrebleDb6",
+ "imageName": "bassF4",
+ "rotation": 180,
+ "positionOnStaff": -1.5
+ },
+ {
+ "noteName": "TrebleD6",
+ "imageName": "bassF4",
+ "rotation": 180,
+ "positionOnStaff": -1.5
+ },
+ {
+ "noteName": "TrebleD#6",
+ "imageName": "bassF4",
+ "rotation": 180,
+ "positionOnStaff": -1.5
+ },
+ {
+ "noteName": "TrebleEb6",
+ "imageName": "bassG4",
+ "rotation": 180,
+ "positionOnStaff": -2
+ },
+ {
+ "noteName": "TrebleE6",
+ "imageName": "bassG4",
+ "rotation": 180,
+ "positionOnStaff": -2
+ },
+ {
+ "noteName": "TrebleF6",
+ "imageName": "trebleE3",
+ "rotation": 180,
+ "positionOnStaff": -2.5
+ },
+ {
+ "noteName": "BassF1",
+ "imageName": "trebleD3",
+ "rotation": 0,
+ "positionOnStaff": 9
+ },
+ {
+ "noteName": "BassG1",
+ "imageName": "trebleE3",
+ "rotation": 0,
+ "positionOnStaff": 8.5
+ },
+ {
+ "noteName": "BassA1",
+ "imageName": "bassG4",
+ "rotation": 0,
+ "positionOnStaff": 8
+ },
+ {
+ "noteName": "BassB1",
+ "imageName": "bassF4",
+ "rotation": 0,
+ "positionOnStaff": 7.5
+ },
+ {
+ "noteName": "BassC2",
+ "imageName": "trebleA3",
+ "rotation": 0,
+ "positionOnStaff": 7
+ },
+ {
+ "noteName": "BassD2",
+ "imageName": "trebleB3",
+ "rotation": 0,
+ "positionOnStaff": 6.5
+ },
+ {
+ "noteName": "BassE2",
+ "imageName": "trebleC4",
+ "rotation": 0,
+ "positionOnStaff": 6
+ },
+ {
+ "noteName": "BassF2",
+ "imageName": "genericNote",
+ "rotation": 0,
+ "positionOnStaff": 5.5
+ },
+ {
+ "noteName": "BassG2",
+ "imageName": "genericNote",
+ "rotation": 0,
+ "positionOnStaff": 5
+ },
+ {
+ "noteName": "BassA2",
+ "imageName": "genericNote",
+ "rotation": 0,
+ "positionOnStaff": 4.5
+ },
+ {
+ "noteName": "BassB2",
+ "imageName": "genericNote",
+ "rotation": 0,
+ "positionOnStaff": 4
+ },
+ {
+ "noteName": "BassC3",
+ "imageName": "genericNote",
+ "rotation": 180,
+ "positionOnStaff": 3.5
+ },
+ {
+ "noteName": "BassC#3",
+ "imageName": "genericNote",
+ "rotation": 180,
+ "positionOnStaff": 3.5
+ },
+ {
+ "noteName": "BassDb3",
+ "imageName": "genericNote",
+ "rotation": 180,
+ "positionOnStaff": 3
+ },
+ {
+ "noteName": "BassD3",
+ "imageName": "genericNote",
+ "rotation": 180,
+ "positionOnStaff": 3
+ },
+ {
+ "noteName": "BassD#3",
+ "imageName": "genericNote",
+ "rotation": 180,
+ "positionOnStaff": 3
+ },
+ {
+ "noteName": "BassEb3",
+ "imageName": "genericNote",
+ "rotation": 180,
+ "positionOnStaff": 2.5
+ },
+ {
+ "noteName": "BassE3",
+ "imageName": "genericNote",
+ "rotation": 180,
+ "positionOnStaff": 2.5
+ },
+ {
+ "noteName": "BassF3",
+ "imageName": "genericNote",
+ "rotation": 180,
+ "positionOnStaff": 2
+ },
+ {
+ "noteName": "BassF#3",
+ "imageName": "genericNote",
+ "rotation": 180,
+ "positionOnStaff": 2
+ },
+ {
+ "noteName": "BassG3",
+ "imageName": "genericNote",
+ "rotation": 180,
+ "positionOnStaff": 1.5
+ },
+ {
+ "noteName": "BassGb3",
+ "imageName": "genericNote",
+ "rotation": 180,
+ "positionOnStaff": 1.5
+ },
+ {
+ "noteName": "BassG#3",
+ "imageName": "genericNote",
+ "rotation": 180,
+ "positionOnStaff": 1.5
+ },
+ {
+ "noteName": "BassAb3",
+ "imageName": "genericNote",
+ "rotation": 180,
+ "positionOnStaff": 1
+ },
+ {
+ "noteName": "BassA3",
+ "imageName": "genericNote",
+ "rotation": 180,
+ "positionOnStaff": 1
+ },
+ {
+ "noteName": "BassA#3",
+ "imageName": "genericNote",
+ "rotation": 180,
+ "positionOnStaff": 1
+ },
+ {
+ "noteName": "BassBb3",
+ "imageName": "genericNote",
+ "rotation": 180,
+ "positionOnStaff": 0.5
+ },
+ {
+ "noteName": "BassB3",
+ "imageName": "genericNote",
+ "rotation": 180,
+ "positionOnStaff": 0.5
+ },
+ {
+ "noteName": "BassC4",
+ "imageName": "trebleC4",
+ "rotation": 180,
+ "positionOnStaff": 0
+ },
+ {
+ "noteName": "BassC#4",
+ "imageName": "trebleC4",
+ "rotation": 180,
+ "positionOnStaff": 0
+ },
+ {
+ "noteName": "BassD4",
+ "imageName": "trebleB3",
+ "rotation": 180,
+ "positionOnStaff": -0.5
+ },
+ {
+ "noteName": "BassD#4",
+ "imageName": "trebleB3",
+ "rotation": 180,
+ "positionOnStaff": -0.5
+ },
+ {
+ "noteName": "BassDb4",
+ "imageName": "trebleB3",
+ "rotation": 180,
+ "positionOnStaff": -0.5
+ },
+ {
+ "noteName": "BassE4",
+ "imageName": "trebleA3",
+ "rotation": 180,
+ "positionOnStaff": -1
+ },
+ {
+ "noteName": "BassEb4",
+ "imageName": "trebleA3",
+ "rotation": 180,
+ "positionOnStaff": -1
+ },
+ {
+ "noteName": "BassF4",
+ "imageName": "bassF4",
+ "rotation": 180,
+ "positionOnStaff": -1.5
+ },
+ {
+ "noteName": "BassF#4",
+ "imageName": "bassF4",
+ "rotation": 180,
+ "positionOnStaff": -1.5
+ },
+ {
+ "noteName": "BassG4",
+ "imageName": "bassG4",
+ "rotation": 180,
+ "positionOnStaff": -2
+ },
+ {
+ "noteName": "BassGb4",
+ "imageName": "bassG4",
+ "rotation": 180,
+ "positionOnStaff": -2
+ },
+ {
+ "noteName": "BassA4",
+ "imageName": "trebleE3",
+ "rotation": 180,
+ "positionOnStaff": -2.5
+ },
+ {
+ "noteName": "BassB4",
+ "imageName": "trebleD3",
+ "rotation": 180,
+ "positionOnStaff": -3
+ },
+ {
+ "noteName": "wholeRest",
+ "imageName": "wholeRest",
+ "rotation": 0,
+ "positionOnStaff": 3.4
+ },
+ {
+ "noteName": "halfRest",
+ "imageName": "halfRest",
+ "rotation": 0,
+ "positionOnStaff": 3.4
+ },
+ {
+ "noteName": "quarterRest",
+ "imageName": "quarterRest",
+ "rotation": 0,
+ "positionOnStaff": 4.5
+ },
+ {
+ "noteName": "eighthRest",
+ "imageName": "eighthRest",
+ "rotation": 0,
+ "positionOnStaff": 4.6
+ }
+ ]
+}
diff --git a/src/activities/piano_composition/OptionsRow.qml b/src/activities/piano_composition/OptionsRow.qml
new file mode 100644
index 000000000..4695d4494
--- /dev/null
+++ b/src/activities/piano_composition/OptionsRow.qml
@@ -0,0 +1,210 @@
+/* GCompris - OptionsRow.qml
+*
+* Copyright (C) 2018 Aman Kumar Gupta <gupta2140@gmail.com>
+*
+* Authors:
+* Beth Hadley <bethmhadley@gmail.com> (GTK+ version)
+* Johnny Jazeix <jazeix@gmail.com> (Qt Quick port)
+* Aman Kumar Gupta <gupta2140@gmail.com> (Qt Quick port)
+* Timothée Giet <animtim@gmail.com> (refactoring)
+*
+* This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+*/
+import QtQuick 2.6
+import GCompris 1.0
+
+import "../../core"
+
+Grid {
+ id: optionsRow
+ columns: 2
+
+ //: Whole note, Half note, Quarter note and Eighth note are the different length notes in the musical notation.
+ readonly property var noteLengthName: [[qsTr("Whole note"), "Whole"], [qsTr("Half note"), "Half"], [qsTr("Quarter note"), "Quarter"], [qsTr("Eighth note"), "Eighth"]]
+
+ //: Whole rest, Half rest, Quarter rest and Eighth rest are the different length rests (silences) in the musical notation.
+ readonly property var restAddedMessage: [qsTr("Added whole rest"), qsTr("Added half rest"), qsTr("Added quarter rest"), qsTr("Added eighth rest")]
+ readonly property var translatedRestNames: [qsTr("Whole rest"), qsTr("Half rest"), qsTr("Quarter rest"), qsTr("Eighth rest")]
+ readonly property var lyricsOrPianoModes: [[qsTr("Piano"), "piano"], [qsTr("Lyrics"), "lyrics"]]
+
+ property real iconsWidth: score.height * 1.2
+ property alias noteOptionsIndex: noteOptions.currentIndex
+ property alias lyricsOrPianoModeIndex: lyricsOrPianoModeOption.currentIndex
+ property alias keyOption: keyOption
+ property alias bpmMeter: bpmMeter
+ property alias restOptionIndex: restOptions.currentIndex
+
+ property bool restOptionsVisible: false
+ property bool noteOptionsVisible: false
+ property bool playButtonVisible: false
+ property bool clearButtonVisible: false
+ property bool undoButtonVisible: false
+ property bool openButtonVisible: false
+ property bool saveButtonVisible: false
+ property bool changeAccidentalStyleButtonVisible: false
+ property bool lyricsOrPianoModeOptionVisible: false
+ property bool bpmVisible: false
+
+ signal undoButtonClicked
+ signal clearButtonClicked
+ signal openButtonClicked
+ signal saveButtonClicked
+ signal playButtonClicked
+ signal bpmIncreased
+ signal bpmDecreased
+ signal bpmChanged
+ signal emitOptionMessage(string message)
+
+
+ BpmMeter {
+ id: bpmMeter
+ }
+
+ BarButton {
+ id: playButton
+ source: "qrc:/gcompris/src/activities/piano_composition/resource/play.svg"
+ sourceSize.width: optionsRow.iconsWidth
+ visible: playButtonVisible
+ onClicked: {
+ optionsRow.playButtonClicked()
+ emitOptionMessage(qsTr("Play melody"))
+ multipleStaff.play()
+ }
+ }
+
+ BarButton {
+ id: clearButton
+ source: "qrc:/gcompris/src/activities/piano_composition/resource/erase.svg"
+ sourceSize.width: optionsRow.iconsWidth
+ visible: clearButtonVisible
+ onClicked: clearButtonClicked()
+ }
+
+ BarButton {
+ id: undoButton
+ source: "qrc:/gcompris/src/activities/piano_composition/resource/undo.svg"
+ sourceSize.width: optionsRow.iconsWidth
+ visible: undoButtonVisible
+ onClicked: {
+ emitOptionMessage(qsTr("Undo"))
+ undoButtonClicked()
+ }
+ }
+
+ KeyOption {
+ id: keyOption
+ }
+
+ Item {
+ id: rests
+ width: optionsRow.iconsWidth * 2
+ height: optionsRow.iconsWidth
+ visible: restOptionsVisible
+ Rectangle {
+ color: "yellow"
+ opacity: 0.1
+ border.width: 2
+ border.color: "black"
+ anchors.fill: parent
+ radius: 10
+ }
+
+ SwitchableOptions {
+ id: restOptions
+
+ readonly property string restTypeImage: (optionsRow.noteLengthName[currentIndex][1]).toLowerCase()
+
+ source: "qrc:/gcompris/src/activities/piano_composition/resource/%1Rest.svg".arg(restTypeImage)
+ nbOptions: optionsRow.noteLengthName.length
+ onClicked: {
+ background.restType = optionsRow.noteLengthName[currentIndex][1]
+ emitOptionMessage(optionsRow.translatedRestNames[currentIndex])
+ }
+ width: optionsRow.iconsWidth * 0.9
+ sourceSize.width: width
+ visible: restOptionsVisible
+ anchors.topMargin: -3
+ anchors.left: parent.left
+ anchors.leftMargin: 5
+ }
+
+ BarButton {
+ id: addRestButton
+ width: restOptions.width
+ sourceSize.width: width
+ source: "qrc:/gcompris/src/activities/piano_composition/resource/add.svg"
+ anchors.right: parent.right
+ anchors.verticalCenter: parent.verticalCenter
+ visible: restOptions.visible
+ onClicked: {
+ emitOptionMessage(optionsRow.restAddedMessage[restOptionIndex])
+ parent.scale = 1
+ pianoLayout.addMusicElementAndPushToStack(restType.toLowerCase(), "Rest")
+ }
+ }
+ }
+
+ BarButton {
+ id: changeAccidentalStyleButton
+ source: changeAccidentalStyleButtonVisible ? (piano.useSharpNotation ? "qrc:/gcompris/src/activities/piano_composition/resource/blacksharp.svg"
+ : "qrc:/gcompris/src/activities/piano_composition/resource/blackflat.svg")
+ : ""
+ sourceSize.width: optionsRow.iconsWidth
+ visible: changeAccidentalStyleButtonVisible
+ onClicked: {
+ piano.useSharpNotation = !piano.useSharpNotation
+ //: Sharp notes and Flat notes represents the accidental style of the notes in the music.
+ emitOptionMessage(piano.useSharpNotation ? qsTr("Sharp notes") : qsTr("Flat notes"))
+ }
+ }
+
+ SwitchableOptions {
+ id: noteOptions
+ source: "qrc:/gcompris/src/activities/piano_composition/resource/genericNote%1.svg".arg(optionsRow.noteLengthName[currentIndex][1])
+ nbOptions: optionsRow.noteLengthName.length
+ sourceSize.width: optionsRow.iconsWidth
+ sourceSize.height: optionsRow.iconsWidth
+ currentIndex: 2
+ onClicked: {
+ background.currentType = optionsRow.noteLengthName[currentIndex][1]
+ emitOptionMessage(optionsRow.noteLengthName[currentIndex][0])
+ }
+ visible: noteOptionsVisible
+ }
+
+ BarButton {
+ id: openButton
+ source: "qrc:/gcompris/src/activities/piano_composition/resource/open.svg"
+ sourceSize.width: optionsRow.iconsWidth
+ visible: openButtonVisible
+ onClicked: openButtonClicked()
+ }
+
+ BarButton {
+ id: saveButton
+ source: "qrc:/gcompris/src/activities/piano_composition/resource/save.svg"
+ sourceSize.width: optionsRow.iconsWidth
+ visible: saveButtonVisible
+ onClicked: saveButtonClicked()
+ }
+
+ SwitchableOptions {
+ id: lyricsOrPianoModeOption
+ nbOptions: optionsRow.lyricsOrPianoModes.length
+ source: "qrc:/gcompris/src/activities/piano_composition/resource/%1.svg".arg(optionsRow.lyricsOrPianoModes[currentIndex][1])
+ visible: lyricsOrPianoModeOptionVisible
+ onClicked: emitOptionMessage(optionsRow.lyricsOrPianoModes[currentIndex][0])
+ }
+
+}
diff --git a/src/activities/piano_composition/PianoKey.qml b/src/activities/piano_composition/PianoKey.qml
new file mode 100644
index 000000000..a3a5dc103
--- /dev/null
+++ b/src/activities/piano_composition/PianoKey.qml
@@ -0,0 +1,87 @@
+/* GCompris - PianoKey.qml
+*
+* Copyright (C) 2018 Aman Kumar Gupta <gupta2140@gmail.com>
+*
+* Authors:
+* Beth Hadley <bethmhadley@gmail.com> (GTK+ version)
+* Johnny Jazeix <jazeix@gmail.com> (Qt Quick port)
+* Aman Kumar Gupta <gupta2140@gmail.com> (Qt Quick port)
+*
+* This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+*/
+import QtQuick 2.6
+import GCompris 1.0
+
+import "../../core"
+
+Rectangle {
+ id: pianoKey
+
+ property string noteColor
+ // keyName is an array of 2 elements. The 1st index has the "actual" key name, while the 2nd index has the translated one.
+ property var keyName
+ property real labelSquareSize
+ property bool labelsVisible
+ property bool isKeyEnabled: true
+
+ signal keyPressed
+
+ SequentialAnimation {
+ id: keyPressAnimation
+ NumberAnimation {
+ target: pianoKey
+ property: "scale"
+ duration: 250
+ to: 0.9
+ }
+ NumberAnimation {
+ target: pianoKey
+ property: "scale"
+ duration: 250
+ to: 1
+ }
+ }
+
+ border.color: "black"
+ Rectangle {
+ width: labelSquareSize
+ height: width
+ anchors.bottom: pianoKey.bottom
+ anchors.horizontalCenter: pianoKey.horizontalCenter
+ color: ((keyName[0] != undefined) && (piano.coloredKeyLabels.indexOf(keyName[0][0]) != -1)) ? (piano.labelsColor === "inbuilt" ? noteColor : labelsColor) : "white"
+ anchors.margins: 4
+ border.color: "black"
+ border.width: 2
+ radius: 5
+ visible: labelsVisible
+ GCText {
+ anchors.fill: parent
+ text: keyName[1] != undefined ? keyName[1] : ""
+ fontSizeMode: Text.Fit
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ }
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onPressed: {
+ if(pianoKey.isKeyEnabled) {
+ keyPressed()
+ pianoKey.scale = 0.95
+ }
+ }
+ onReleased: pianoKey.scale = 1
+ }
+}
diff --git a/src/activities/piano_composition/PianoOctaveKeyboard.qml b/src/activities/piano_composition/PianoOctaveKeyboard.qml
new file mode 100644
index 000000000..e5238b318
--- /dev/null
+++ b/src/activities/piano_composition/PianoOctaveKeyboard.qml
@@ -0,0 +1,213 @@
+/* GCompris - PianoOctaveKeyboard.qml
+*
+* Copyright (C) 2016 Johnny Jazeix <jazeix@gmail.com>
+* Copyright (C) 2018 Aman Kumar Gupta <gupta2140@gmail.com>
+*
+* Authors:
+* Beth Hadley <bethmhadley@gmail.com> (GTK+ version)
+* Johnny Jazeix <jazeix@gmail.com> (Qt Quick port)
+* Aman Kumar Gupta <gupta2140@gmail.com> (Qt Quick port)
+*
+* This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+*/
+import QtQuick 2.6
+import GCompris 1.0
+
+import "../../core"
+
+Item {
+ id: piano
+ z: 3
+
+ property alias keyRepeater: keyRepeater
+
+ property int numberOfWhite: 7
+ property int currentOctaveNb: 0
+ readonly property int maxNbOctaves: whiteKeyNoteLabels.length
+
+ property real whiteWidth: width / numberOfWhite // 23
+ property real whiteHeight: height // 120
+ property real blackWidth: (whiteWidth + 1) / 2 // 13
+ property real blackHeight: 2 * height / 3 // 80
+
+ property bool leftOctaveVisible: false
+
+ property var coloredKeyLabels: ['C', 'D', 'E', 'F', 'G', 'A', 'B']
+ // When the labelsColor is inbuilt, the default color mapping will be done, else assign any color externally in the activity. Example: Reference keys in note_names are red colored and all other are white.
+ property string labelsColor: "inbuilt"
+
+ //: Translators, C, D, E, F, G, A and B are the note notations in English musical notation system. The numbers in the arguments represents the octave number of the note. For instance, C4 is a C note in the 4th octave.
+ readonly property var whiteKeyNoteLabelsArray: [
+ ["F1", qsTr("F%1").arg(1)],
+ ["G1", qsTr("G%1").arg(1)],
+ ["A1", qsTr("A%1").arg(1)],
+ ["B1", qsTr("B%1").arg(1)],
+ ["C2", qsTr("C%1").arg(2)],
+ ["D2", qsTr("D%1").arg(2)],
+ ["E2", qsTr("E%1").arg(2)],
+ ["F2", qsTr("F%1").arg(2)],
+ ["G2", qsTr("G%1").arg(2)],
+ ["A2", qsTr("A%1").arg(2)],
+ ["B2", qsTr("B%1").arg(2)],
+ ["C3", qsTr("C%1").arg(3)],
+ ["D3", qsTr("D%1").arg(3)],
+ ["E3", qsTr("E%1").arg(3)],
+ ["F3", qsTr("F%1").arg(3)],
+ ["G3", qsTr("G%1").arg(3)],
+ ["A3", qsTr("A%1").arg(3)],
+ ["B3", qsTr("B%1").arg(3)],
+ ["C4", qsTr("C%1").arg(4)],
+ ["D4", qsTr("D%1").arg(4)],
+ ["E4", qsTr("E%1").arg(4)],
+ ["F4", qsTr("F%1").arg(4)],
+ ["G4", qsTr("G%1").arg(4)],
+ ["A4", qsTr("A%1").arg(4)],
+ ["B4", qsTr("B%1").arg(4)],
+ ["C5", qsTr("C%1").arg(5)],
+ ["D5", qsTr("D%1").arg(5)],
+ ["E5", qsTr("E%1").arg(5)],
+ ["F5", qsTr("F%1").arg(5)],
+ ["G5", qsTr("G%1").arg(5)],
+ ["A5", qsTr("A%1").arg(5)],
+ ["B5", qsTr("B%1").arg(5)],
+ ["C6", qsTr("C%1").arg(6)],
+ ["D6", qsTr("D%1").arg(6)],
+ ["E6", qsTr("E%1").arg(6)],
+ ["F6", qsTr("F%1").arg(6)]
+ ]
+
+ //: Translators, C♯, D♯, F♯, G♯, and A♯ are the note notations in English musical notation system. The numbers in the arguments represents the octave number of the note. For instance, C♯4 is a C♯ note in the 4th octave.
+ readonly property var blackKeySharpNoteLabelsArray: [
+ ["C#3", qsTr("C♯%1").arg(3)],
+ ["D#3", qsTr("D♯%1").arg(3)],
+ ["F#3", qsTr("F♯%1").arg(3)],
+ ["G#3", qsTr("G♯%1").arg(3)],
+ ["A#3", qsTr("A♯%1").arg(3)],
+ ["C#4", qsTr("C♯%1").arg(4)],
+ ["D#4", qsTr("D♯%1").arg(4)],
+ ["F#4", qsTr("F♯%1").arg(4)],
+ ["G#4", qsTr("G♯%1").arg(4)],
+ ["A#4", qsTr("A♯%1").arg(4)],
+ ["C#5", qsTr("C♯%1").arg(5)],
+ ["D#5", qsTr("D♯%1").arg(5)],
+ ["F#5", qsTr("F♯%1").arg(5)],
+ ["G#5", qsTr("G♯%1").arg(5)],
+ ["A#5", qsTr("A♯%1").arg(5)],
+ ["C#6", qsTr("C♯%1").arg(6)],
+ ["D#6", qsTr("D♯%1").arg(6)]
+ ]
+
+ //: Translators, D♭, E♭, G♭, A♭, B♭ are the note notations in English musical notation system. The numbers in the arguments represents the octave number of the note. For instance, D♭4 is a D♭ note in the 4th octave.
+ readonly property var blackKeyFlatNoteLabelsArray: [
+ ["Db3", qsTr("D♭%1").arg(3)],
+ ["Eb3", qsTr("E♭%1").arg(3)],
+ ["Gb3", qsTr("G♭%1").arg(3)],
+ ["Ab3", qsTr("A♭%1").arg(3)],
+ ["Bb3", qsTr("B♭%1").arg(3)],
+ ["Db4", qsTr("D♭%1").arg(4)],
+ ["Eb4", qsTr("E♭%1").arg(4)],
+ ["Gb4", qsTr("G♭%1").arg(4)],
+ ["Ab4", qsTr("A♭%1").arg(4)],
+ ["Bb4", qsTr("B♭%1").arg(4)],
+ ["Db5", qsTr("D♭%1").arg(5)],
+ ["Eb5", qsTr("E♭%1").arg(5)],
+ ["Gb5", qsTr("G♭%1").arg(5)],
+ ["Ab5", qsTr("A♭%1").arg(5)],
+ ["Bb5", qsTr("B♭%1").arg(5)],
+ ["Db6", qsTr("D♭%1").arg(6)],
+ ["Eb6", qsTr("E♭%1").arg(6)]
+ ]
+ readonly property var blackKeyNoteLabels: useSharpNotation ? blackKeySharpNoteLabelsArray : blackKeyFlatNoteLabelsArray
+
+ readonly property var keyLabelColors: { "C": "#FF0000", "D": "#FF7F00", "E": "#FFFF00", "F": "#32CD32",
+ "G": "#6495ED", "A": "#D02090", "B": "#FF1493",
+ "C#": "#FF6347", "D#": "#FFD700", "F#": "#20B2AA", "G#": "#8A2BE2", "A#": "#FF00FF",
+ "Db": "#FF6347", "Eb": "#FFD700", "Gb": "#20B2AA", "Ab": "#8A2BE2", "Bb": "#FF00FF"}
+
+ // White key notes are from C3 to G4 when the clef is bass
+ property var whiteKeyNoteLabelsBass: [
+ whiteKeyNoteLabelsArray.slice(11, 18),
+ whiteKeyNoteLabelsArray.slice(18, 22)
+ ]
+ // White key notes are from G3 to C6 when the clef is treble
+ property var whiteKeyNoteLabelsTreble: [
+ whiteKeyNoteLabelsArray.slice(13, 18),
+ whiteKeyNoteLabelsArray.slice(18, 25),
+ whiteKeyNoteLabelsArray.slice(25, 32),
+ whiteKeyNoteLabelsArray.slice(32, 36)
+ ]
+ readonly property var whiteKeyNoteLabels: background.clefType === "Treble" ? whiteKeyNoteLabelsTreble : whiteKeyNoteLabelsBass
+
+ signal noteClicked(string note)
+
+ property bool blackLabelsVisible: true
+ property bool whiteLabelsVisible: true
+ property bool blackKeysEnabled: true
+ property bool whiteKeysEnabled: true
+ property bool useSharpNotation: true
+ property int labelSquareSize: whiteWidth - 5
+
+ Repeater {
+ id: keyRepeater
+ model: whiteKeyNoteLabels.length ? whiteKeyNoteLabels[currentOctaveNb % whiteKeyNoteLabels.length].length : 0
+
+ Item {
+ width: whiteWidth
+ height: whiteHeight
+ x: (((currentOctaveNb === 0) ? (piano.numberOfWhite - whiteKeyNoteLabels[0].length + index) : index)) * whiteWidth
+
+ property alias whiteKey: whiteKey
+ property alias blackKey: blackKey
+
+ PianoKey {
+ id: whiteKey
+ color: "white"
+ width: whiteWidth
+ height: whiteHeight
+ labelSquareSize: piano.labelSquareSize
+ noteColor: keyLabelColors[keyName[0][0]]
+ keyName: whiteKeyNoteLabels[currentOctaveNb % whiteKeyNoteLabels.length][index]
+ labelsVisible: whiteLabelsVisible
+ isKeyEnabled: piano.whiteKeysEnabled
+ onKeyPressed: noteClicked(keyName[0])
+ }
+
+ PianoKey {
+ id: blackKey
+ color: "black"
+ width: blackWidth
+ height: Math.min(blackHeight, whiteHeight - labelSquareSize - 10)
+ x: -width / 2
+ visible: {
+ if(index || leftOctaveVisible)
+ return (["D", "E", "G", "A", "B"].indexOf(whiteKeyNoteLabels[currentOctaveNb % whiteKeyNoteLabels.length][index][0][0]) != -1)
+ return false
+ }
+ labelSquareSize: piano.labelSquareSize - 2
+ noteColor: keyName ? keyLabelColors[keyName[0].substr(0, 2)] : "black"
+ keyName: {
+ for(var i = 0; i < blackKeyFlatNoteLabelsArray.length; i++) {
+ if((blackKeyFlatNoteLabelsArray[i][0][0] === whiteKey.keyName[0][0])
+ && (blackKeyFlatNoteLabelsArray[i][0][2] === whiteKey.keyName[0][1]))
+ return blackKeyNoteLabels[i]
+ }
+ return ""
+ }
+ labelsVisible: blackLabelsVisible
+ isKeyEnabled: piano.blackKeysEnabled
+ onKeyPressed: noteClicked(keyName[0])
+ }
+ }
+ }
+}
diff --git a/src/activities/piano_composition/Piano_composition.qml b/src/activities/piano_composition/Piano_composition.qml
new file mode 100644
index 000000000..cefa05337
--- /dev/null
+++ b/src/activities/piano_composition/Piano_composition.qml
@@ -0,0 +1,563 @@
+/* GCompris - Piano_composition.qml
+ *
+ * Copyright (C) 2016 Johnny Jazeix <jazeix@gmail.com>
+ * Copyright (C) 2018 Aman Kumar Gupta <gupta2140@gmail.com>
+ *
+ * Authors:
+ * Beth Hadley <bethmhadley@gmail.com> (GTK+ version)
+ * Johnny Jazeix <jazeix@gmail.com> (Qt Quick port)
+ * Aman Kumar Gupta <gupta2140@gmail.com> (Qt Quick port)
+ * Timothée Giet <animtim@gmail.com> (refactoring)
+ *
+ * This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+ */
+import QtQuick 2.6
+import QtQuick.Controls 1.5
+import GCompris 1.0
+
+import "../../core"
+import "qrc:/gcompris/src/core/core.js" as Core
+import "piano_composition.js" as Activity
+import "melodies.js" as Dataset
+
+ActivityBase {
+ id: activity
+
+ onStart: focus = true
+ onStop: {}
+ isMusicalActivity: true
+
+ property bool horizontalLayout: background.width >= background.height
+
+ pageComponent: Rectangle {
+ id: background
+ anchors.fill: parent
+ color: "#ABCDEF"
+ signal start
+ signal stop
+
+ Component.onCompleted: {
+ activity.start.connect(start)
+ activity.stop.connect(stop)
+ }
+
+ Keys.onPressed: {
+ var keyboardBindings = {}
+ keyboardBindings[Qt.Key_1] = 0
+ keyboardBindings[Qt.Key_2] = 1
+ keyboardBindings[Qt.Key_3] = 2
+ keyboardBindings[Qt.Key_4] = 3
+ keyboardBindings[Qt.Key_5] = 4
+ keyboardBindings[Qt.Key_6] = 5
+ keyboardBindings[Qt.Key_7] = 6
+ keyboardBindings[Qt.Key_F1] = 1
+ keyboardBindings[Qt.Key_F2] = 2
+ keyboardBindings[Qt.Key_F3] = 3
+ keyboardBindings[Qt.Key_F4] = 4
+ keyboardBindings[Qt.Key_F5] = 5
+
+ if(event.key >= Qt.Key_1 && event.key <= Qt.Key_7 && keyboardBindings[event.key] < piano.whiteKeyNoteLabels.length) {
+ piano.keyRepeater.itemAt(keyboardBindings[event.key]).whiteKey.keyPressed()
+ }
+ else if(event.key >= Qt.Key_F1 && event.key <= Qt.Key_F5) {
+ if(piano.blackKeysEnabled)
+ findBlackKey(keyboardBindings[event.key])
+ }
+ if(event.key === Qt.Key_Left && shiftKeyboardLeft.visible) {
+ piano.currentOctaveNb--
+ }
+ if(event.key === Qt.Key_Right && shiftKeyboardRight.visible) {
+ piano.currentOctaveNb++
+ }
+ if(event.key === Qt.Key_Delete) {
+ optionsRow.clearButtonClicked()
+ }
+ if(event.key === Qt.Key_Backspace) {
+ optionsRow.undoButtonClicked()
+ }
+ if(event.key === Qt.Key_Space) {
+ multipleStaff.play()
+ }
+ }
+
+ function findBlackKey(keyNumber) {
+ for(var i = 0; keyNumber; i++) {
+ if(piano.keyRepeater.itemAt(i) === undefined)
+ break
+ if(piano.keyRepeater.itemAt(i).blackKey.visible)
+ keyNumber--
+ if(keyNumber === 0)
+ piano.keyRepeater.itemAt(i).blackKey.keyPressed()
+ }
+ }
+
+ // Add here the QML items you need to access in javascript
+ QtObject {
+ id: items
+ property Item main: activity.main
+ property alias background: background
+ property GCSfx audioEffects: activity.audioEffects
+ property alias bar: bar
+ property alias bonus: bonus
+ property alias multipleStaff: multipleStaff
+ property string staffLength: "short"
+ property alias melodyList: melodyList
+ property alias file: file
+ property alias piano: piano
+ property alias optionsRow: optionsRow
+ property alias lyricsArea: lyricsArea
+ }
+
+ onStart: { Activity.start(items) }
+ onStop: { Activity.stop() }
+
+ property string currentType: "Quarter"
+ property string restType: "Whole"
+ property string clefType: bar.level == 2 ? "Bass" : "Treble"
+ property bool isLyricsMode: (optionsRow.lyricsOrPianoModeIndex === 1) && optionsRow.lyricsOrPianoModeOptionVisible
+ property int layoutMargins: 5 * ApplicationInfo.ratio
+
+ File {
+ id: file
+ onError: console.error("File error: " + msg)
+ }
+
+ Item {
+ id: clickedOptionMessage
+
+ signal show(string message)
+ onShow: {
+ messageText.text = message
+ messageAnimation.stop()
+ messageAnimation.start()
+ }
+
+ height: width * 0.4
+ visible: false
+ anchors.top: optionsRow.bottom
+ anchors.horizontalCenter: optionsRow.horizontalCenter
+ z: 5
+ Rectangle {
+ id: messageRectangle
+ width: messageText.contentWidth + 5
+ height: messageText.height + 5
+ anchors.centerIn: messageText
+ color: "black"
+ opacity: 0.5
+ border.width: 3
+ border.color: "black"
+ radius: 15
+ }
+
+ GCText {
+ id: messageText
+ anchors.fill: parent
+ anchors.rightMargin: parent.width * 0.02
+ anchors.leftMargin: parent.width * 0.02
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ fontSizeMode: Text.Fit
+ color: "white"
+ }
+
+ SequentialAnimation {
+ id: messageAnimation
+ onStarted: clickedOptionMessage.visible = true
+ PauseAnimation {
+ duration: 1000
+ }
+ NumberAnimation {
+ targets: [messageRectangle, messageText]
+ property: "opacity"
+ to: 0
+ duration: 200
+ }
+ onStopped: {
+ clickedOptionMessage.visible = false
+ messageRectangle.opacity = 0.5
+ messageText.opacity = 1
+ }
+ }
+ }
+
+ MelodyList {
+ id: melodyList
+ onClose: {
+ visible = false
+ piano.enabled = true
+ focus = false
+ activity.focus = true
+ }
+ }
+
+ Rectangle {
+ id: instructionBox
+ radius: 10
+ width: background.width * 0.75
+ height: background.height * 0.15
+ anchors.right: parent.right
+ opacity: 0.8
+ border.width: 6
+ color: "white"
+ border.color: "#87A6DD"
+
+ GCText {
+ id: instructionText
+ color: "black"
+ z: 3
+ anchors.fill: parent
+ anchors.rightMargin: parent.width * 0.02
+ anchors.leftMargin: parent.width * 0.02
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ fontSizeMode: Text.Fit
+ wrapMode: Text.WordWrap
+ text: Activity.instructions[bar.level - 1].text
+ }
+ }
+
+ MultipleStaff {
+ id: multipleStaff
+ nbStaves: 2
+ clef: clefType
+ coloredNotes: ['C','D', 'E', 'F', 'G', 'A', 'B']
+ noteHoverEnabled: true
+ anchors.margins: layoutMargins
+
+ onNoteClicked: {
+ if(selectedIndex === noteIndex)
+ selectedIndex = -1
+ else {
+ selectedIndex = noteIndex
+ background.clefType = musicElementModel.get(selectedIndex).soundPitch_
+ playNoteAudio(musicElementModel.get(selectedIndex).noteName_, musicElementModel.get(selectedIndex).noteType_, background.clefType, musicElementRepeater.itemAt(selectedIndex).duration)
+ }
+ }
+ }
+
+ GCButtonScroll {
+ id: multipleStaffFlickButton
+ anchors.left: multipleStaff.right
+ anchors.verticalCenter: multipleStaff.verticalCenter
+ width: bar.height * 0.3
+ height: width * 2
+ onUp: multipleStaff.flickableStaves.flick(0, multipleStaff.height * 1.3)
+ onDown: multipleStaff.flickableStaves.flick(0, -multipleStaff.height * 1.3)
+ upVisible: multipleStaff.flickableStaves.visibleArea.yPosition > 0
+ downVisible: (multipleStaff.flickableStaves.visibleArea.yPosition + multipleStaff.flickableStaves.visibleArea.heightRatio) < 1
+ }
+
+ Item {
+ id: pianoLayout
+ width: multipleStaff.width + multipleStaffFlickButton.width
+ height: multipleStaff.height
+ anchors.margins: layoutMargins
+
+ PianoOctaveKeyboard {
+ id: piano
+ height: parent.height
+ width: parent.width * 0.8
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.verticalCenter: parent.verticalCenter
+ blackLabelsVisible: [3, 4, 5, 6, 7, 8].indexOf(items.bar.level) == -1 ? false : true
+ useSharpNotation: bar.level != 4
+ blackKeysEnabled: bar.level > 2
+ visible: !background.isLyricsMode
+ currentOctaveNb: (background.clefType === "Bass") ? 0 : 1
+
+ onNoteClicked: {
+ parent.addMusicElementAndPushToStack(note, currentType)
+ }
+ }
+
+ function addMusicElementAndPushToStack(noteName, noteType, elementType) {
+ if(noteType === "Rest")
+ elementType = "rest"
+ else if(elementType === undefined)
+ elementType = "note"
+
+ var tempModel = multipleStaff.createNotesBackup()
+ Activity.pushToStack(tempModel)
+ multipleStaff.addMusicElement(elementType, noteName, noteType, false, true, background.clefType)
+ }
+
+ Image {
+ id: shiftKeyboardLeft
+ source: "qrc:/gcompris/src/core/resource/bar_previous.svg"
+ sourceSize.width: parent.width * 0.1
+ width: sourceSize.width
+ height: parent.height
+ fillMode: Image.PreserveAspectFit
+ visible: (piano.currentOctaveNb > 0) && piano.visible
+ anchors.right: piano.left
+ anchors.verticalCenter: parent.verticalCenter
+ MouseArea {
+ anchors.fill: parent
+ onClicked: piano.currentOctaveNb--
+ }
+ }
+
+ Image {
+ id: shiftKeyboardRight
+ source: "qrc:/gcompris/src/core/resource/bar_next.svg"
+ sourceSize.width: parent.width * 0.1
+ width: sourceSize.width
+ height: parent.height
+ fillMode: Image.PreserveAspectFit
+ visible: (piano.currentOctaveNb < piano.maxNbOctaves - 1) && piano.visible
+ anchors.left: piano.right
+ anchors.verticalCenter: parent.verticalCenter
+ MouseArea {
+ anchors.fill: parent
+ onClicked: piano.currentOctaveNb++
+ }
+ }
+
+ LyricsArea {
+ id: lyricsArea
+ width: parent.width
+ height: parent.height
+ anchors.fill: pianoLayout
+ }
+
+ }
+
+ GCCreationHandler {
+ id: creationHandler
+ onFileLoaded: {
+ // We need to draw the notes twice since we first need to count the number of staffs needed for the melody (we get that from
+ // the 1st redraw call), then we redraw the 2nd time to actually display the notes perfectly. This is done because for some reason, the
+ // staves model is updated slower than the addition of notes, so the notes aggregates in their default position instead of
+ // their required position, due to unavailability of the updated staff at that instant. So calculating the number of required staffs first seems the only solution for now.
+ multipleStaff.redraw(data)
+ multipleStaff.redraw(data)
+ lyricsArea.resetLyricsArea()
+ }
+ onClose: {
+ optionsRow.lyricsOrPianoModeIndex = 0
+ }
+ }
+
+ OptionsRow {
+ id: optionsRow
+ anchors.margins: layoutMargins
+ anchors.left: background.left
+ iconsWidth: 0
+ noteOptionsVisible: bar.level > 4
+ playButtonVisible: true
+ keyOption.clefButtonVisible: bar.level > 2
+ clearButtonVisible: true
+ undoButtonVisible: true
+ openButtonVisible: bar.level > 6
+ saveButtonVisible: bar.level > 6
+ changeAccidentalStyleButtonVisible: bar.level >= 4
+ lyricsOrPianoModeOptionVisible: bar.level > 6
+ restOptionsVisible: bar.level > 5
+ bpmVisible: true
+
+ onUndoButtonClicked: {
+ Activity.undoChange()
+ }
+ onClearButtonClicked: {
+ if((multipleStaff.musicElementModel.count > 1) && multipleStaff.selectedIndex === -1) {
+ Core.showMessageDialog(main,
+ qsTr("You have not selected any note. Do you want to erase all the notes?"),
+ qsTr("Yes"), function() {
+ Activity.undoStack = []
+ lyricsArea.resetLyricsArea()
+ multipleStaff.eraseAllNotes()
+ multipleStaff.nbStaves = 2
+ },
+ qsTr("No"), null,
+ null
+ )
+ }
+ else if((multipleStaff.musicElementModel.count > 1) && !multipleStaff.musicElementModel.get(multipleStaff.selectedIndex).isDefaultClef_) {
+ var noteIndex = multipleStaff.selectedIndex
+ var tempModel = multipleStaff.createNotesBackup()
+ Activity.pushToStack(tempModel)
+ multipleStaff.eraseNote(noteIndex)
+ }
+ }
+ onOpenButtonClicked: {
+ dialogActivityConfig.active = true
+ displayDialog(dialogActivityConfig)
+ }
+ onSaveButtonClicked: {
+ var notesToSave = multipleStaff.createNotesBackup()
+ // add bpm at start
+ notesToSave.unshift({"bpm": multipleStaff.bpmValue});
+ creationHandler.saveWindow(notesToSave)
+ }
+ keyOption.onClefAdded: {
+ var insertingIndex = multipleStaff.selectedIndex === -1 ? multipleStaff.musicElementModel.count : multipleStaff.selectedIndex
+ var tempModel = multipleStaff.createNotesBackup()
+ Activity.pushToStack(tempModel)
+ multipleStaff.addMusicElement("clef", "", "", false, false, background.clefType)
+ if(background.clefType === "Bass")
+ piano.currentOctaveNb = 0
+ else
+ piano.currentOctaveNb = 1
+ }
+ onBpmDecreased: {
+ if(multipleStaff.bpmValue - 1 >= 1)
+ multipleStaff.bpmValue--
+ }
+ onBpmIncreased: {
+ multipleStaff.bpmValue++
+ }
+ onEmitOptionMessage: clickedOptionMessage.show(message)
+ }
+
+ DialogActivityConfig {
+ id: dialogActivityConfig
+ content: Component {
+ Column {
+ id: column
+ spacing: 10
+ width: dialogActivityConfig.width
+ height: dialogActivityConfig.height
+
+ GCText {
+ text: qsTr("Select the type of melody to load.")
+ fontSizeMode: mediumSize
+ }
+
+ Button {
+ text: qsTr("Pre-defined melodies")
+ onClicked: {
+ melodyList.melodiesModel.clear()
+ var dataset = Dataset.get()
+ for(var i = 0; i < dataset.length; i++) {
+ melodyList.melodiesModel.append(dataset[i])
+ }
+ melodyList.visible = true
+ piano.enabled = false
+ melodyList.forceActiveFocus()
+ dialogActivityConfig.close()
+ }
+ width: 150 * ApplicationInfo.ratio
+ height: 60 * ApplicationInfo.ratio
+ style: GCButtonStyle {
+ theme: "dark"
+ }
+ }
+
+ Button {
+ text: qsTr("Your saved melodies")
+ onClicked: {
+ creationHandler.loadWindow()
+ dialogActivityConfig.close()
+ }
+ width: 150 * ApplicationInfo.ratio
+ height: 60 * ApplicationInfo.ratio
+ style: GCButtonStyle {
+ theme: "dark"
+ }
+ }
+ }
+ }
+ onClose: home()
+ }
+
+ DialogHelp {
+ id: dialogHelp
+ onClose: home()
+ }
+
+ Bar {
+ id: bar
+ content: BarEnumContent { value: help | home | level }
+ onHelpClicked: {
+ displayDialog(dialogHelp)
+ }
+ onPreviousLevelClicked: Activity.previousLevel()
+ onNextLevelClicked: Activity.nextLevel()
+ onHomeClicked: activity.home()
+ }
+
+ Bonus {
+ id: bonus
+ Component.onCompleted: win.connect(Activity.nextLevel)
+ }
+
+ states: [
+ State {
+ name: "hScreen"
+ when: horizontalLayout
+ PropertyChanges {
+ target: clickedOptionMessage
+ width: background.width / 12
+ }
+ AnchorChanges {
+ target: optionsRow
+ anchors.top: instructionBox.bottom
+ }
+ PropertyChanges {
+ target: optionsRow
+ columns: 11
+ iconsWidth: background.width / 15
+ }
+ AnchorChanges {
+ target: multipleStaff
+ anchors.left: background.horizontalCenter
+ anchors.top: optionsRow.bottom
+ }
+ PropertyChanges {
+ target: multipleStaff
+ width: background.width * 0.5 - multipleStaffFlickButton.width - layoutMargins * 3
+ height: background.height - instructionBox.height - optionsRow.height - bar.height - layoutMargins * 4
+ }
+ AnchorChanges {
+ target: pianoLayout
+ anchors.left: background.left
+ anchors.top: optionsRow.bottom
+ }
+ },
+ State {
+ name: "vScreen"
+ when: !horizontalLayout
+ PropertyChanges {
+ target: clickedOptionMessage
+ width: background.width / 6
+ }
+ AnchorChanges{
+ target: optionsRow
+ anchors.top: background.top
+ }
+ PropertyChanges {
+ target: optionsRow
+ columns: 1
+ iconsWidth: (background.height - bar.height) / 12
+ }
+ AnchorChanges {
+ target: multipleStaff
+ anchors.left: optionsRow.right
+ anchors.top: instructionBox.bottom
+ }
+ PropertyChanges {
+ target: multipleStaff
+ width: background.width - multipleStaffFlickButton.width - optionsRow.width - layoutMargins * 3
+ height: (background.height - instructionBox.height - bar.height - layoutMargins * 4) * 0.5
+ }
+ AnchorChanges {
+ target: pianoLayout
+ anchors.left: optionsRow.right
+ anchors.top: multipleStaff.bottom
+ }
+ }
+
+ ]
+ }
+}
diff --git a/src/activities/piano_composition/README b/src/activities/piano_composition/README
new file mode 100644
index 000000000..87fdabc1f
--- /dev/null
+++ b/src/activities/piano_composition/README
@@ -0,0 +1,8 @@
+1. bassClef.svg: https://openclipart.org/detail/12475/bass-clef
+2. trebleClef.svg : https://openclipart.org/detail/12473/treble-clef
+3. blackflat.svg: https://openclipart.org/detail/198043/mono-music-flat
+4. blacksharp.svg: https://openclipart.org/detail/198039/mono-music-cross
+5. half-note.svg: https://openclipart.org/detail/92971/half-note-stem-facing-up
+6. quarter-note.svg: https://openclipart.org/detail/92875/quarter-note-stem-facing-up
+7. eighth-note.svg: https://openclipart.org/detail/92869/eighth-note-stem-facing-up
+8. whole-note.svg: https://openclipart.org/detail/140893/whole-note
diff --git a/src/activities/piano_composition/Staff.qml b/src/activities/piano_composition/Staff.qml
new file mode 100644
index 000000000..492327624
--- /dev/null
+++ b/src/activities/piano_composition/Staff.qml
@@ -0,0 +1,77 @@
+/* GCompris - Staff.qml
+ *
+ * Copyright (C) 2016 Johnny Jazeix <jazeix@gmail.com>
+ * Copyright (C) 2018 Aman Kumar Gupta <gupta2140@gmail.com>
+ *
+ * Authors:
+ * Beth Hadley <bethmhadley@gmail.com> (GTK+ version)
+ * Johnny Jazeix <jazeix@gmail.com> (Qt Quick port)
+ * Aman Kumar Gupta <gupta2140@gmail.com> (Qt Quick port)
+ *
+ * This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+ */
+import QtQuick 2.6
+import GCompris 1.0
+
+import "../../core"
+
+Item {
+ id: staff
+
+ property Item main: activity.main
+
+ property int verticalDistanceBetweenLines: height / nbLines
+
+ // Stave
+ readonly property int nbLines: 5
+
+ property bool lastPartition: false
+
+ readonly property int yShift: activity.horizontalLayout ? 0 : 1.5
+
+ Repeater {
+ id: staffLines
+ model: nbLines
+ Rectangle {
+ width: staff.width
+ height: activity.horizontalLayout ? 5 : 3
+ border.width: height / 2
+ color: "black"
+ y: index * verticalDistanceBetweenLines + yShift
+ }
+ }
+
+ // Ending vertical line of the staff.
+ Rectangle {
+ id: staffEndLine
+ width: activity.horizontalLayout ? 5 : 3
+ border.width: width / 2
+ height: (nbLines - 1) * verticalDistanceBetweenLines + width
+ color: "black"
+ x: staff.width
+ y: yShift
+ }
+
+ // The 2nd vertical line denoting the end of multiple staves
+ Rectangle {
+ id: multiStaffEndLine
+ width: activity.horizontalLayout ? 5 : 3
+ border.width: width / 2
+ height: (nbLines - 1) * verticalDistanceBetweenLines + width
+ visible: lastPartition
+ color: "black"
+ x: staff.width - 10
+ y: yShift
+ }
+}
diff --git a/src/activities/color_mix/ColorButton.qml b/src/activities/piano_composition/SwitchableOptions.qml
similarity index 55%
copy from src/activities/color_mix/ColorButton.qml
copy to src/activities/piano_composition/SwitchableOptions.qml
index ba5990caf..7cde85aa5 100644
--- a/src/activities/color_mix/ColorButton.qml
+++ b/src/activities/piano_composition/SwitchableOptions.qml
@@ -1,78 +1,78 @@
-/* GCompris - ColorButton.qml
+/* GCompris - SwitchableOptions.qml
*
-* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
+* Copyright (C) 2018 Aman Kumar Gupta <gupta2140@gmail.com>
*
* Authors:
-* Bruno Coudoin <bruno.coudoin@gcompris.net>
+* Beth Hadley <bethmhadley@gmail.com> (GTK+ version)
+* Johnny Jazeix <jazeix@gmail.com> (Qt Quick port)
+* Aman Kumar Gupta <gupta2140@gmail.com> (Qt Quick port)
+* Timothée Giet <animtim@gmail.com> (refactoring)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
+import GCompris 1.0
import "../../core"
-Item {
- id: button
- height: parent.height / 4
- width: height
- z: 3
-
- property alias source: buttonImage.source
+Image {
+ id: switchableOptions
+ property int currentIndex: 0
+ property int nbOptions: 1
+
signal clicked
- Image {
- id: buttonImage
- anchors.centerIn: parent
- sourceSize.width: parent.width
- horizontalAlignment: Text.AlignHCenter
- verticalAlignment: Text.AlignVCenter
- }
+ sourceSize.width: optionsRow.iconsWidth
MouseArea {
id: mouseArea
- anchors.centerIn: parent
- height: 3 * parent.height
- width: 3 * parent.width
+ anchors.fill: parent
hoverEnabled: true
+ onClicked: {
+ parent.currentIndex = (parent.currentIndex + 1) % nbOptions
+ //clickAnimation.start()
+ parent.clicked()
+ }
}
-
+
states: [
State {
name: "notclicked"
PropertyChanges {
- target: button
+ target: switchableOptions
scale: 1.0
}
},
State {
name: "clicked"
when: mouseArea.pressed
PropertyChanges {
- target: button
+ target: switchableOptions
scale: 0.9
}
},
State {
name: "hover"
when: mouseArea.containsMouse
PropertyChanges {
- target: button
- scale: 1.2
+ target: switchableOptions
+ scale: 1.1
}
}
]
-
+
Behavior on scale { NumberAnimation { duration: 70 } }
+ Behavior on opacity { PropertyAnimation { duration: 200 } }
}
diff --git a/src/activities/piano_composition/melodies.js b/src/activities/piano_composition/melodies.js
new file mode 100644
index 000000000..7c238d47d
--- /dev/null
+++ b/src/activities/piano_composition/melodies.js
@@ -0,0 +1,266 @@
+/* GCompris - melodies.js
+ *
+ * Copyright (C) 2016 Johnny Jazeix <jazeix@gmail.com>
+ * Copyright (C) 2018 Aman Kumar Gupta <gupta2140@gmail.com>
+ *
+ * Authors:
+ * Beth Hadley <bethmhadley@gmail.com> (GTK+ version)
+ * Johnny Jazeix <jazeix@gmail.com> (Qt Quick port)
+ * Aman Kumar Gupta <gupta2140@gmail.com> (Qt Quick port)
+ *
+ * This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+ **/
+
+function get() {
+ return [
+ {
+ "title": "Twinkle Twinkle Little Star",
+ "_origin": qsTr("America: English Lullaby"),
+ "lyrics": "Twinkle, twinkle, little star, how I wonder what you are; Up above the world so high, like a diamond in the sky. Twinkle, twinkle, little star, how I wonder what you are.",
+ "defaultBPM": 120,
+ "melody": "Treble C4Quarter C4Quarter G4Quarter G4Quarter A4Quarter A4Quarter G4Half F4Quarter F4Quarter E4Quarter E4Quarter D4Quarter D4Quarter C4Half G4Quarter G4Quarter F4Quarter F4Quarter E4Quarter E4Quarter D4Half G4Quarter G4Quarter F4Quarter F4Quarter E4Quarter E4Quarter D4Half C4Quarter C4Quarter G4Quarter G4Quarter A4Quarter A4Quarter G4Half F4Quarter F4Quarter E4Quarter E4Quarter D4Quarter D4Quarter C4Whole"
+ },
+ {
+ "title": "Yankee Doodle",
+ "_origin": qsTr("America: Patriotic"),
+ "lyrics": "Yankee Doodle went to town, Riding on a pony; He stuck a feather in his hat, And called it macaroni",
+ "defaultBPM": 120,
+ "melody": "Treble G4Eighth G4Eighth A4Eighth B4Eighth G4Eighth B4Eighth A4Quarter G4Eighth G4Eighth A4Eighth B4Eighth G4Quarter F#4Quarter G4Eighth G4Eighth A4Eighth B4Eighth C5Eighth B4Eighth A4Eighth G4Eighth F#4Eighth D4Eighth E4Eighth F#4Eighth G4Quarter G4Quarter"
+ },
+ {
+ "title": "Simple Gifts",
+ "_origin": qsTr("America: Shaker Tune"),
+ "lyrics": "Tis the gift to be simple, 'tis the gift to be free, 'tis the gift to come down where we ought to be. And when we find ourselves in the place just right, 'Twill be in the valley of love and delight.",
+ "defaultBPM": 116,
+ "melody": "Treble C4Eighth C4Eighth F4Quarter F4Eighth G4Eighth A4Eighth F4Eighth A4Eighth Bb4Eighth C5Quarter C5Eighth Bb4Eighth A4Quarter G4Eighth F4Eighth G4Quarter C4Quarter G4Quarter F4Quarter G4Eighth A4Eighth G4Eighth E4Eighth C4Quarter C4Quarter F4Eighth E4Eighth F4Eighth G4Eighth A4Quarter G4Eighth G4Eighth A4Quarter Bb4Quarter C5Quarter A4Quarter G4Quarter G4Eighth G4Eighth A4Quarter A4Eighth G4Eighth F4Quarter F4Eighth F4Eighth F4Half"
+ },
+ {
+ "title": "Old MacDonald Had a Farm",
+ "_origin": qsTr("America: Nursery Rhyme"),
+ "lyrics": "Old MacDonald had a farm, EE-I-EE-I-O, And on that farm he had a [animal name], EE-I-EE-I-O",
+ "defaultBPM": 152,
+ "melody": "Bass G3Quarter G3Quarter G3Quarter D3Quarter E3Quarter E3Quarter D3Half B3Quarter B3Quarter A3Quarter A3Quarter G3Half D3Half G3Quarter G3Quarter G3Quarter D3Quarter E3Quarter E3Quarter D3Half B3Quarter B3Quarter A3Quarter A3Quarter G3Whole"
+ },
+ {
+ "title": "Un elefante se balanceaba",
+ "_origin": qsTr("Mexico"),
+ "lyrics": "Un elefante se columpiaba sobre la tela de una araña. Como veia que resistía fue a llamar a otro elefante",
+ "defaultBPM": 122,
+ "melody": "Treble G4Quarter G4Eighth G4Eighth E4Quarter E4Quarter G4Quarter G4Eighth G4Eighth E4Quarter E4Quarter G4Quarter G4Eighth G4Eighth A4Eighth G4Eighth F4Eighth E4Eighth F4Half D4Half F4Quarter F4Eighth F4Eighth D4Quarter D4Quarter F4Quarter F4Eighth F4Eighth D4Quarter D4Quarter F4Quarter F4Eighth F4Eighth G4Eighth F4Eighth E4Eighth D4Eighth E4Half C4Half"
+ },
+ {
+ "title": "Piove, Piove",
+ "_origin": qsTr("Italy"),
+ "lyrics": "Piove, piove. La gatta non si muove. La fiamma traballa. La mucca è nella stalla. La mucca ha il vitello. La pecora ha l’agnello. [La chioccia ha il pulcino.] Ognuno ha il suo bambino. Ognuno ha la sua mamma. E tutti fanno nanna!",
+ "defaultBPM": 116,
+ "melody": "Treble E4Eighth G4Quarter G4Eighth A4Eighth G4Quarter G4Eighth E4Eighth G4Eighth G4Eighth G4Eighth A4Eighth G4Quarter G4Eighth E4Eighth G4Eighth G4Eighth G4Eighth A4Eighth G4Quarter G4Eighth E4Eighth G4Eighth G4Eighth G4Eighth A4Eighth G4Quarter G4Eighth E4Eighth G4Half E4Eighth G4Half E4Eighth G4Eighth A4Eighth G4Eighth E4Eighth G4Half"
+ },
+ {
+ "title": "Que llueva, que llueva",
+ "_origin": qsTr("Spain"),
+ "lyrics": "Que llueva, que llueva. La Virgen de la Cueva. Los pajaritos cantan, Las nubes se levantan. ¡Que sí, que no, que caiga un chaparrón! Que siga lloviendo, Los pájaros corriendo. Florezca la pradera. Al sol de la primavera....",
+ "defaultBPM": 116,
+ "melody": "Treble E4Eighth G4Quarter G4Eighth A4Eighth G4Quarter G4Eighth E4Eighth G4Eighth G4Eighth G4Eighth A4Eighth G4Quarter G4Eighth E4Eighth G4Eighth G4Eighth G4Eighth A4Eighth G4Quarter G4Eighth E4Eighth G4Eighth G4Eighth G4Eighth A4Eighth G4Quarter G4Eighth E4Eighth G4Half E4Eighth G4Half E4Eighth G4Eighth A4Eighth G4Eighth E4Eighth G4Half"
+ },
+ {
+ "title": "Backe, backe Kuchen",
+ "_origin": qsTr("German Kid's Song"),
+ "lyrics": "Backe, backe, Kuchen Der Bäcker hat gerufen! Wer will guten Kuchen backen Der muß haben sieben Sachen: Eier und Schmalz Butter und Salz Milch und Mehl/Safran macht den Kuchen gehl!Schieb, schieb in´n Ofen ´nein.",
+ "defaultBPM": 92,
+ "melody": "Treble A4Quarter A4Quarter B4Quarter B4Quarter A4Half F#4Quarter D4Quarter A4Quarter A4Quarter B4Quarter B4Quarter A4Half F#4Half A4Quarter A4Quarter B4Quarter B4Quarter A4Quarter A4Quarter F#4Quarter D4Quarter A4Quarter A4Quarter B4Quarter B4Quarter A4Quarter A4Quarter F#4Quarter F#4Quarter A4Eighth A4Eighth A4Quarter F#4Half A4Eighth A4Eighth A4Quarter F#4Half A4Quarter A4Quarter F#4Half"
+ },
+ {
+ "title": "Se essa rua fosse minha",
+ "_origin": qsTr("Children's Song from Brazil"),
+ "lyrics": "Se essa rua Se essa rua fosse minha Eu mandava Eu mandava ladrilhar Com pedrinhas Com pedrinhas de brilhante Só pra ver Só pra ver meu bem passar Nessa rua Nessa rua tem um bosque Que se chama Que se chama solidão...",
+ "defaultBPM": 120,
+ "melody": "Treble E4Eighth E4Eighth A4Eighth A4Eighth E4Eighth C4Eighth A4Eighth C4Eighth F4Eighth E4Eighth E4Quarter D4Quarter E4Eighth E4Eighth B4Eighth B4Eighth F4Eighth E4Eighth G#4Eighth E4Eighth C4Eighth B4Eighth A4Half A4Eighth A4Eighth Bb4Eighth A4Eighth E4Eighth C#4Eighth A4Eighth G4Eighth F4Eighth E4Eighth G4Eighth F4Eighth E4Eighth D4Eighth E4Quarter B4Eighth G#4Eighth E4Eighth D4Eighth C4Eighth B4Eighth A4Half"
+ },
+ {
+ "title": "Fuchs du hast die Gans gestohlen",
+ "_origin": qsTr("Germany"),
+ "lyrics": "Fuchs, du hast die Gans gestohlen, gib sie wieder her, gib sie wieder her! Sonst wird dich der Jäger holen, mit dem Schießgewehr! Sonst wird dich der Jäger holen, mit dem Schießgewehr!",
+ "defaultBPM": 100,
+ "melody": "Treble D4Quarter E4Quarter F#4Quarter G4Quarter A4Quarter A4Quarter A4Quarter A4Quarter B4Quarter G4Quarter D5Quarter B4Quarter A4Whole B4Quarter G4Quarter D5Quarter B4Quarter A4Whole A4Quarter G4Quarter G4Quarter G4Quarter G4Quarter F#4Quarter F#4Quarter F#4Quarter F#4Quarter E4Quarter F#4Quarter E4Quarter D4Quarter F#4Quarter A4Half"
+ },
+ {
+ "title": "Un éléphant qui se balançait",
+ "_origin": qsTr("France"),
+ "lyrics": "Un éléphant qui se balançait\nSur une toile toile toile\nToile d'araignée\nIl trouvait ça tellement amusant\nQu'il alla chercher un\nDeuxième éléphant.",
+ "defaultBPM": 122,
+ "melody": "Treble G4Quarter G4Eighth G4Eighth E4Quarter E4Quarter G4Quarter G4Eighth G4Eighth E4Quarter E4Quarter G4Quarter G4Eighth G4Eighth A4Eighth G4Eighth F4Eighth E4Eighth F4Half D4Half F4Quarter F4Eighth F4Eighth D4Quarter D4Quarter F4Quarter F4Eighth F4Eighth D4Quarter D4Quarter F4Quarter F4Eighth F4Eighth G4Eighth F4Eighth E4Eighth D4Eighth E4Half C4Half"
+ },
+ {
+ "title": "Alle Meine Entchen",
+ "_origin": qsTr("Germany"),
+ "lyrics": "Alle meine Entchen schwimmen auf dem See, schwimmen auf dem See, Köpfchen in das Wasser, Schwänzchen in die Höh'.",
+ "defaultBPM": 100,
+ "melody": "Treble C4Eighth D4Eighth E4Eighth F4Eighth G4Quarter G4Quarter A4Eighth A4Eighth A4Eighth A4Eighth G4Half A4Eighth A4Eighth A4Eighth A4Eighth G4Half F4Eighth F4Eighth F4Eighth F4Eighth E4Quarter E4Quarter D4Eighth D4Eighth D4Eighth G4Eighth C4Half"
+ },
+ {
+ "title": "À la claire fontaine",
+ "_origin": qsTr("France"),
+ "lyrics": "À la claire fontaine\nM'en allant promener\nJ'ai trouvé l'eau si belle\nQue je m'y suis baigné\nIl y a longtemps que je t'aime\nJamais je ne t'oublierai.",
+ "defaultBPM": 77,
+ "melody": "Treble G4Quarter G4Eighth B4Eighth B4Eighth A4Eighth B4Eighth B4Eighth G4Quarter G4Eighth B4Eighth B4Eighth A4Eighth B4Quarter B4Quarter B4Eighth A4Eighth G4Eighth B4Eighth D5Eighth B4Eighth D5Quarter D5Eighth B4Eighth G4Eighth B4Eighth A4Half G4Half G4Quarter B4Quarter B4Quarter A4Eighth G4Eighth B4Quarter G4Quarter B4Half B4Quarter A4Eighth G4Eighth B4Quarter A4Quarter G4Whole"
+ },
+ {
+ "title": "O Cravo e a Rosa",
+ "_origin": qsTr("Brazil"),
+ "lyrics": "O Cravo brigou com a Rosa Debaixo de uma sacada O Cravo ficou ferido E a Rosa despedaçada O Cravo ficou doente A Rosa foi visitar O Cravo teve um desmaio A Rosa pôs-se a chorar",
+ "defaultBPM": 120,
+ "melody": "Treble G4Quarter G4Quarter E4Quarter C5Eighth B4Eighth A4Eighth G4Quarter F4Half A4Quarter A4Quarter F4Quarter C5Eighth B4Eighth A4Eighth G4Quarter G4Half G4Quarter C5Quarter C5Quarter C5Eighth D5Eighth C5Eighth B4Quarter A4Half A4Quarter G4Quarter B4Half A4Eighth F4Eighth D4Eighth C4Quarter"
+ },
+ {
+ "title": "Marcha Soldado",
+ "_origin": qsTr("Brazil"),
+ "lyrics": "Marcha soldado Cabeça de papel Se não marchar direito Vai preso pro quartel O quartel pegou fogo A polícia deu sinal Acode acode acode A bandeira nacional",
+ "defaultBPM": 120,
+ "melody": "Treble G4Quarter G4Eighth E4Eighth C4Quarter C4Eighth E4Eighth G4Eighth G4Eighth G4Eighth E4Eighth D4Half E4Eighth F4Eighth F4Eighth F4Eighth D4Eighth G4Quarter G4Eighth A4Eighth G4Eighth F4Eighth E4Eighth D4Eighth C4Half"
+ },
+ {
+ "title": "Frère jacques",
+ "_origin": qsTr("France"),
+ "lyrics": "Frère Jacques\nFrère Jacques\nDormez-vous ?\nDormez-vous ?\nSonnez les matines\nSonnez les matines\nDing ding dong\nDing ding dong",
+ "defaultBPM": 120,
+ "melody": "Treble F4Quarter G4Quarter A4Quarter F4Quarter F4Quarter G4Quarter A4Quarter F4Quarter A4Quarter Bb4Quarter C5Half A4Quarter Bb4Quarter C5Half C5Eighth D5Eighth C5Eighth Bb4Eighth A4Quarter F4Quarter C5Eighth D5Eighth C5Eighth Bb4Eighth A4Quarter F4Quarter F4Quarter C4Quarter F4Half F4Quarter C4Quarter F4Half"
+ },
+ {
+ "title": "Au clair de la lune",
+ "_origin": qsTr("France"),
+ "lyrics": "Au clair de la lune\nMon ami Pierrot\nPrête-moi ta plume\nPour écrire un mot\nMa chandelle est morte\nJe n'ai plus de feu\nOuvre-moi ta porte\nPour l'amour de Dieu.",
+ "defaultBPM": 85,
+ "melody": "Treble G4Quarter G4Quarter G4Quarter A4Quarter B4Half A4Half G4Quarter B4Quarter A4Quarter A4Quarter G4Whole G4Quarter G4Quarter G4Quarter A4Quarter B4Half A4Half G4Quarter B4Quarter A4Quarter A4Quarter G4Whole A4Quarter A4Quarter A4Quarter A4Quarter E4Half E4Half A4Quarter G4Quarter F#4Quarter E4Quarter D4Whole G4Quarter G4Quarter G4Quarter A4Quarter B4Half A4Half G4Quarter B4Quarter A4Quarter A4Quarter G4Whole"
+ },
+ {
+ "title": "Boci, boci tarka",
+ "_origin": qsTr("Hungary, Nursery Rhyme"),
+ "lyrics": "Boci, boci tarka, Se füle, se farka, Oda megyünk lakni, Ahol tejet kapni.",
+ "defaultBPM": 120,
+ "melody": "Treble D4Eighth F#4Eighth D4Eighth F#4Eighth A4Quarter A4Quarter D4Eighth F#4Eighth D4Eighth F#4Eighth A4Quarter A4Quarter D5Eighth C#5Eighth B4Eighth A4Eighth G4Quarter B4Quarter A4Eighth G4Eighth F#4Eighth E4Eighth D4Quarter D4Quarter"
+ },
+ {
+ "title": "Nyuszi ül a fűben",
+ "_origin": qsTr("Hungary, Nursery Rhyme"),
+ "lyrics": "Nyuszi ül a fűben, ülve szundikálva. Nyuszi talán beteg vagy, hogy már nem is ugorhatsz? Nyuszi hopp! Nyuszi hopp! Máris egyet elkapott.",
+ "defaultBPM": 120,
+ "melody": "Treble A4Eighth A4Eighth A4Eighth B4Eighth A4Quarter F#4Quarter A4Eighth A4Eighth A4Eighth B4Eighth A4Eighth G4Eighth F#4Quarter F#4Eighth E4Eighth F#4Eighth E4Eighth D4Eighth D4Eighth D4Quarter A4Eighth A4Eighth D5Quarter A4Eighth A4Eighth D5Quarter F#4Eighth E4Eighth F#4Eighth E4Eighth D4Eighth D4Eighth D4Quarter"
+ },
+ {
+ "title": "Lánc, lánc, eszterlánc",
+ "_origin": qsTr("Hungary, Children's Song"),
+ "lyrics": "Lánc, lánc, eszterlánc,/ eszterlánci cérna,/ cérna volna, selyem volna,/ mégis kifordulna. / Pénz volna karika, karika,/ forduljon ki Marika,/ Marikának lánca.",
+ "defaultBPM": 120,
+ "melody": "Treble A4Quarter B4Quarter A4Eighth A4Eighth F#4Quarter A4Eighth A4Eighth A4Eighth B4Eighth A4Quarter F#4Quarter A4Eighth A4Eighth A4Eighth B4Eighth A4Eighth G4Eighth F#4Eighth E4Eighth F#4Eighth E4Eighth F#4Eighth E4Eighth D4Quarter D4Quarter A4Quarter A4Eighth A4Eighth A4Eighth D5Eighth A4Quarter A4Eighth G4Eighth F#4Eighth E4Eighth D4Eighth D5Eighth A4Quarter A4Eighth G4Eighth F#4Eighth E4Eighth D4Quarter D4Quarter"
+ },
+ {
+ "title": "Tavaszi szél vizet áraszt",
+ "_origin": qsTr("Hungary, Children's Song"),
+ "lyrics": "Tavaszi szél vizet áraszt, virágom, virágom. / Minden madár társat választ virágom, virágom. / Hát én immár kit válasszak? Virágom, virágom. / Te engemet, én tégedet, virágom, virágom.",
+ "defaultBPM": 120,
+ "melody": "Treble F4Quarter G4Quarter A4Quarter A4Quarter G4Quarter G4Eighth A4Eighth F4Quarter G4Quarter A4Eighth A4Quarter G4Quarter G4Eighth A4Eighth F4Half C4Half F4Quarter G4Quarter A4Eighth A4Quarter G4Quarter G4Eighth A4Eighth F4Eighth E4Eighth D4Quarter G4Eighth G4Quarter A4Eighth F4Quarter E4Quarter D4Half D4Half"
+ },
+ {
+ "title": "Zec kopa repu",
+ "_origin": qsTr("Serbia"),
+ "lyrics": "Zec kopa repu, a lisica cveklu / Vuk im se prikrade, zeca da ukrade / Zec spazi repu, a lisica cveklu / Vuka nije bilo, u snu im se snilo",
+ "defaultBPM": 180,
+ "melody": "Treble A4Half A4Quarter F#4Quarter G4Half E4Half D4Quarter E4Quarter E4Quarter E4Quarter E4Half D4Half F4Quarter F4Quarter E4Quarter F4Quarter G4Half E4Half F4Quarter F4Quarter E4Quarter D4Quarter E4Half D4Half"
+ },
+ {
+ "title": "Jack and Jill",
+ "_origin": qsTr("Britain"),
+ "lyrics": "Jack and Jill went up the hill / To fetch a pail of water. / Jack fell down and broke his crown,/ And Jill came tumbling after",
+ "defaultBPM": 101,
+ "melody": "Treble C4Quarter C4Eighth D4Quarter D4Eighth E4Quarter E4Eighth F4Quarter F4Eighth G4Quarter G4Eighth A4Quarter A4Eighth B4Half C5Half C5Quarter C5Eighth B4Quarter B4Eighth A4Quarter A4Eighth G4Quarter G4Eighth F4Quarter F4Eighth E4Quarter E4Eighth D4Half C4Half"
+ },
+ {
+ "title": "Wlazł kotek na płotek",
+ "_origin": qsTr("Poland"),
+ "lyrics": "Wlazł kotek na płotek i mruga,/ Ładna to piosenka nie długa. / Nie długa, nie krótka, lecz w sam raz,/ Zaśpiewaj koteczku jeszcze raz.",
+ "defaultBPM": 120,
+ "melody": "Treble G4Quarter E4Quarter E4Quarter F4Quarter D4Quarter D4Quarter C4Eighth E4Eighth G4Half G4Quarter E4Quarter E4Quarter F4Quarter D4Quarter D4Quarter C4Eighth E4Eighth C4Half"
+ },
+ {
+ "title": "Φεγγαράκι μου λαμπρό",
+ "_origin": qsTr("Greece"),
+ "lyrics": "Φεγγαράκι μου λαμπρό,/ Φέγγε μου να περπατώ,/ Να πηγαίνω στο σχολειό / Να μαθαίνω γράμματα,/ Γράμματα σπουδάματα / Του Θεού τα πράματα.",
+ "defaultBPM": 120,
+ "melody": "Treble C4Quarter C4Quarter G4Quarter G4Quarter A4Quarter A4Quarter G4Half F4Quarter F4Quarter E4Quarter E4Quarter D4Quarter D4Quarter C4Half G4Quarter G4Quarter F4Quarter F4Quarter E4Quarter E4Quarter D4Half G4Quarter G4Quarter F4Quarter F4Quarter E4Quarter E4Quarter D4Half C4Quarter C4Quarter G4Quarter G4Quarter A4Quarter A4Quarter G4Half F4Quarter F4Quarter E4Quarter E4Quarter D4Quarter D4Quarter C4Whole"
+ },
+ {
+ "title": "Βρέχει, χιονίζει",
+ "_origin": qsTr("Greece"),
+ "lyrics": "Βρέχει, χιονίζει,/ Τα μάρμαρα ποτίζει,/ Κι' ο γέρος πα στα ξύλα / Κ' η γριά του μαγειρεύει / Κουρκούτι με το μέλι. / \"'Ελα γέρο μου να φας / Πού να φας την / κουτσουλιά,/ Και του σκύλλου την οριά.\"",
+ "defaultBPM": 120,
+ "melody": "Treble D4Eighth G4Eighth G4Eighth G4Eighth A4Eighth A4Eighth G4Eighth G4Eighth D4Eighth G4Eighth G4Eighth G4Eighth A4Eighth A4Eighth G4Eighth G4Eighth D4Eighth G4Eighth G4Eighth G4Eighth A4Eighth A4Eighth G4Eighth G4Eighth D4Eighth G4Eighth G4Eighth G4Eighth A4Eighth A4Eighth G4Eighth G4Eighth"
+ },
+ {
+ "title": "Котику сіренький",
+ "_origin": qsTr("Ukraine"),
+ "lyrics": "Котику сіренький,/ Котику біленький,/ Котку волохатий,/ Не ходи по хаті! / Не ходи по хаті,/ Не буди дитяти! / Дитя буде спати,/ Котик воркотати. / Ой на кота воркота,/ На дитину дрімота. / А-а, люлі!",
+ "defaultBPM": 120,
+ "melody": "Treble C4Quarter F4Quarter G4Quarter Bb4Eighth Ab4Eighth G4Quarter F4Quarter C4Quarter F4Quarter G4Quarter Bb4Eighth Ab4Eighth G4Half F4Half Bb4Quarter Bb4Quarter Bb4Quarter Ab4Quarter G4Half F4Half Bb4Quarter Bb4Quarter Bb4Quarter Ab4Quarter G4Half F4Half C4Quarter F4Quarter G4Quarter Bb4Eighth Ab4Eighth G4Eighth F4Eighth G4Quarter F4Half"
+ },
+ {
+ "title": "Baa, Baa, Blacksheep",
+ "_origin": qsTr("Britain"),
+ "lyrics": "Baa, baa, black sheep, / Have you any wool? / Yes, sir, yes, sir, / Three bags full; / One for the master, / And one for the dame, / And one for the little boy / Who lives down the lane",
+ "defaultBPM": 105,
+ "melody": "Treble G4Quarter G4Quarter D5Quarter D5Quarter E5Eighth E5Eighth E5Eighth E5Eighth D5Half C5Quarter C5Quarter B4Quarter B4Quarter A4Quarter A4Quarter G4Half D5Quarter D5Eighth D5Eighth C5Quarter C5Quarter B4Quarter B4Eighth B4Eighth A4Half D5Quarter D5Eighth D5Eighth C5Eighth C5Eighth C5Eighth C5Eighth B4Quarter B4Eighth B4Eighth A4Half"
+ },
+ {
+ "title": "A la rueda de San Miguel",
+ "_origin": qsTr("Mexico"),
+ "lyrics": "A la rueda, a la rueda de San Miguel / Todos traen su caja de miel. / A lo maduro, a lo maduro / Que se voltee (nombre del niño) de burro.",
+ "defaultBPM": 120,
+ "melody": "Treble G4Quarter G4Quarter C5Quarter G4Quarter C5Quarter G4Eighth G4Eighth C5Quarter D5Quarter E5Half C5Quarter D5Quarter E5Half C5Quarter C5Quarter D5Quarter D5Eighth D5Eighth G4Quarter G4Eighth G4Eighth C5Half"
+ },
+ {
+ "title": "Arroz con leche",
+ "_origin": qsTr("Mexico"),
+ "lyrics": "Arroz con leche / me quiero casar / con una mexicana / de la capital.",
+ "defaultBPM": 120,
+ "melody": "Treble C4Eighth F4Half A4Eighth F4Quarter F4Eighth C4Eighth F4Quarter F4Eighth A4Eighth G4Half A4Eighth Bb4Eighth A4Eighth G4Eighth F4Eighth E4Quarter E4Eighth C4Eighth D4Quarter E4Eighth E4Eighth F4Quarter"
+ },
+ {
+ "title": "Los pollitos dicen",
+ "_origin": qsTr("Mexico"),
+ "lyrics": "Los pollitos dicen / pío pío pío / cuando tienen hambre / cuando tienen frío",
+ "defaultBPM": 117,
+ "melody": "Treble A4Eighth E4Eighth A4Eighth B4Eighth C#5Quarter C#5Quarter B4Eighth D5Eighth C#5Eighth B4Eighth A4Quarter A4Quarter A4Eighth G#4Eighth F#4Eighth E4Eighth B4Quarter B4Quarter E4Eighth E4Eighth F#4Eighth G#4Eighth A4Quarter A4Quarter"
+ },
+ {
+ "title": "Dale dale dale",
+ "_origin": qsTr("Mexican song to break a piñata"),
+ "lyrics": "Dale dale dale / no pierdas el tino / porque si lo pierdes / pierdes el camino",
+ "defaultBPM": 120,
+ "melody": "Treble G4Eighth G4Eighth G4Eighth E4Eighth A4Quarter A4Quarter B4Eighth B4Eighth B4Eighth G4Eighth C5Quarter C5Quarter G4Eighth G4Eighth G4Eighth E4Eighth A4Quarter A4Quarter B4Eighth B4Eighth B4Eighth G4Eighth C5Half"
+ },
+ {
+ "title": "Kolme varista",
+ "_origin": qsTr("Finland"),
+ "lyrics": "Kolme varista istui aidalla. Silivati seilaa, silivati seilaa, yksi lensi pois. Kaksi varista istui aidalla. Silivati seilaa, silivati seilaa, yksi lensi pois. Yksi varis vain istui aidalla. Silivati seilaa, silivati seilaa, sekin lensi pois.",
+ "defaultBPM": 120,
+ "melody": "Treble A4Quarter Bb4Quarter A4Eighth F4Half D4Whole A4Quarter D4Quarter C5Quarter Bb4Quarter G4Whole A4Eighth A4Eighth A4Eighth G4Eighth E4Quarter G4Quarter A4Eighth A4Eighth A4Eighth G4Eighth E4Quarter G4Quarter A4Half G4Eighth F4Quarter E4Quarter D4Quarter"
+ },
+ {
+ "title": "Humpty Dumpty",
+ "_origin": qsTr("Britain"),
+ "lyrics": "Humpty Dumpty sat on a wall, / Humpty Dumpty had a great fall. / All the king's horses and all the king's men / Couldn't put Humpty together again",
+ "defaultBPM": 120,
+ "melody": "Treble E4Quarter G4Eighth F4Quarter A4Eighth G4Eighth A4Eighth B4Eighth C5Half E4Quarter G4Eighth F4Quarter A4Eighth G4Eighth F4Eighth E4Eighth D4Half E4Eighth E4Eighth G4Eighth F4Eighth F4Eighth A4Eighth G4Eighth A4Eighth B4Eighth C5Quarter C5Eighth E5Eighth E5Eighth C5Eighth F5Quarter E5Eighth D5Eighth C5Eighth B4Eighth C5Half"
+ }
+ ];
+}
diff --git a/src/activities/piano_composition/piano_composition.js b/src/activities/piano_composition/piano_composition.js
new file mode 100644
index 000000000..ce7af4cb6
--- /dev/null
+++ b/src/activities/piano_composition/piano_composition.js
@@ -0,0 +1,148 @@
+/* GCompris - piano_composition.js
+ *
+ * Copyright (C) 2016 Johnny Jazeix <jazeix@gmail.com>
+ * Copyright (C) 2018 Aman Kumar Gupta <gupta2140@gmail.com>
+ *
+ * Authors:
+ * Beth Hadley <bethmhadley@gmail.com> (GTK+ version)
+ * Johnny Jazeix <jazeix@gmail.com> (Qt Quick port)
+ * Aman Kumar Gupta <gupta2140@gmail.com> (Qt Quick port)
+ *
+ * This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+ */
+.pragma library
+.import QtQuick 2.6 as Quick
+.import GCompris 1.0 as GCompris
+.import "qrc:/gcompris/src/core/core.js" as Core
+
+var currentLevel = 0
+var numberOfLevel = 7
+var items
+var userDir = "file://" + GCompris.ApplicationSettings.userDataPath + "/" + "piano_composition"
+var userFile = userDir + "/melodies.json"
+var undoStack = []
+var instructions = [{
+ "text": qsTr("This is the treble clef staff for high pitched notes.")
+ },
+ {
+ "text": qsTr("This is the bass clef staff for low pitched notes.")
+ },
+ {
+ "text": qsTr("The black keys are sharp and flat keys. Sharp notes have a ♯ sign.")
+ },
+ {
+ "text": qsTr("Each black key has two names: flat and sharp. Flat notes have ♭ sign.")
+ },
+ {
+ "text": qsTr("Click on the note symbol to write different length notes such as whole notes, half notes, quarter notes and eighth notes.")
+ },
+ {
+ "text": qsTr("Rests are equivalent to notes during which silence is maintained. Click on the rest symbol to select the rest length and then click on the add button to enter it to the staff.")
+ },
+ {
+ "text": qsTr("Now you can load music and also save your composed one.")
+ }
+]
+
+function start(items_) {
+ items = items_
+ currentLevel = 0
+ initLevel()
+}
+
+function saveMelody() {
+ var notes = items.multipleStaff.getAllNotes()
+ if (!items.file.exists(userDir)) {
+ if (!items.file.mkpath(userDir))
+ console.error("Could not create directory " + userDir);
+ else
+ console.debug("Created directory " + userDir);
+ }
+
+ if(items.file.exists(userFile))
+ var data = items.file.read(userFile)
+ if (!items.file.append(JSON.stringify(notes), userFile)) {
+ Core.showMessageDialog(items.background,
+ qsTr("Error saving melody to your file (%1)")
+ .arg(userFile),
+ "", null, "", null, null);
+ } else {
+ Core.showMessageDialog(items.background,
+ qsTr("Saved melody to your file (%1)")
+ .arg(userFile),
+ "", null, "", null, null);
+ }
+}
+
+function stop() {
+ items.multipleStaff.stopAudios()
+}
+
+function initLevel() {
+ items.bar.level = currentLevel + 1
+ items.multipleStaff.bpmValue = 120
+
+ if(items.bar.level === 2) {
+ items.background.clefType = "Bass"
+ items.piano.currentOctaveNb = 0
+ }
+ else {
+ items.background.clefType = "Treble"
+ items.piano.currentOctaveNb = 1
+ }
+
+ items.multipleStaff.initClefs(items.background.clefType)
+
+ if(items.bar.level === 4)
+ items.piano.useSharpNotation = false
+ else
+ items.piano.useSharpNotation = true
+
+ items.multipleStaff.nbStaves = 2
+ items.optionsRow.noteOptionsIndex = 2
+ items.background.currentType = "Quarter"
+ items.lyricsArea.resetLyricsArea()
+ undoStack = []
+}
+
+function pushToStack(data) {
+ undoStack.push(data)
+ // Maintain most recent 5 changes. Remove older ones (stack behaves as queue here).
+ if(undoStack.length > 5)
+ undoStack.shift()
+}
+
+function undoChange() {
+ if(undoStack.length > 0) {
+ var undoState = undoStack[undoStack.length - 1]
+ undoStack.pop()
+ items.multipleStaff.redraw(undoState)
+ }
+}
+
+function nextLevel() {
+ items.multipleStaff.eraseAllNotes()
+ if(numberOfLevel <= ++currentLevel) {
+ currentLevel = 0
+ }
+ initLevel()
+}
+
+function previousLevel() {
+ items.multipleStaff.eraseAllNotes()
+ if(--currentLevel < 0) {
+ currentLevel = numberOfLevel - 1
+ }
+ initLevel()
+}
diff --git a/src/activities/piano_composition/piano_composition.svg b/src/activities/piano_composition/piano_composition.svg
new file mode 100644
index 000000000..86072c4c2
--- /dev/null
+++ b/src/activities/piano_composition/piano_composition.svg
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100"
+ height="100"
+ id="svg2"
+ sodipodi:version="0.32"
+ inkscape:version="0.92.1 r15371"
+ version="1.0"
+ sodipodi:docname="piano_composition.svg">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1.5550218"
+ inkscape:cx="-92.349125"
+ inkscape:cy="43.300017"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ width="100px"
+ height="100px"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ showgrid="true"
+ inkscape:window-maximized="1">
+ <inkscape:grid
+ type="xygrid"
+ id="grid832" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ <dc:date>2018</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Timothée Giet</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Calque 1"
+ inkscape:groupmode="layer"
+ id="layer1">
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#000000;stroke:none;stroke-width:0.48204404"
+ d="m 22.727477,27.361774 c -0.751056,-0.0195 -1.487457,0.405625 -2.167315,1.095897 -0.679858,0.690272 -1.314172,1.658409 -1.862272,2.80094 -1.0962,2.28506 -1.843351,5.267481 -1.79166,8.098717 0.02412,1.724359 0.555552,5.116636 1.323739,9.375379 -4.901589,5.065371 -10.6316336,10.319077 -10.6332147,17.28015 -7.7e-6,6.27e-4 7.7e-6,0.0013 0,0.0019 v 9.64e-4 c -0.039335,3.196722 0.9129797,6.819593 3.0438447,9.652183 2.131474,2.833392 5.459601,4.864311 10.093739,4.825145 1.318523,-0.0091 2.504282,-0.17409 3.582378,-0.439677 0.80598,4.442388 1.344826,7.986892 1.341627,9.568387 v 9.64e-4 9.64e-4 c 0.01423,3.181953 -2.038751,4.878503 -4.158572,5.370269 -1.05991,0.245886 -2.13229,0.177123 -2.941222,-0.165702 -0.735852,-0.311854 -1.204131,-0.856038 -1.361397,-1.589237 1.787391,-0.219802 3.188834,-1.657735 3.188834,-3.466576 0,-1.959987 -1.625809,-3.5579 -3.630394,-3.5579 -1.09703,0 -2.078774,0.480448 -2.746334,1.232413 -0.005,0.005 -0.02249,0.01972 -0.04802,0.04613 l -9.64e-4,9.64e-4 -9.64e-4,0.0019 c -0.159591,0.169428 -0.287211,0.362757 -0.408608,0.572427 0,0 -9.64e-4,9.64e-4 -9.64e-4,9.64e-4 0,0 0,9.65e-4 0,9.65e-4 -0.412331,0.698395 -0.66692,1.676019 -0.680699,3.039138 v 0.0019 9.64e-4 c 0,1.477803 0.929142,2.795716 2.275587,3.762205 1.346444,0.966483 3.123062,1.598359 4.909882,1.709749 1.786821,0.11138 3.592499,-0.30113 4.956016,-1.459313 1.36285,-1.157619 2.258706,-3.053325 2.259581,-5.816541 v -0.0019 c 0.02214,-1.513118 -0.599334,-5.128901 -1.492265,-9.701138 4.920054,-1.885018 6.798613,-6.514083 6.269465,-10.693666 -0.536337,-4.236374 -3.541187,-8.057377 -8.23994,-8.093068 h -0.0019 -0.0019 c -0.639111,0.0065 -1.252998,0.09938 -1.85474,0.232549 -0.495415,-2.384808 -0.973399,-4.701691 -1.393415,-6.837117 3.454483,-3.42021 6.480786,-7.905151 6.413446,-16.021374 0.0052,-2.946227 -0.480687,-5.601283 -1.239004,-7.547003 -0.379201,-0.97297 -0.825184,-1.769203 -1.325621,-2.339608 -0.500437,-0.570405 -1.06755,-0.924392 -1.674915,-0.944317 h -9.64e-4 z m 0.634566,6.130057 c 0.512326,-0.04944 0.940164,0.143476 1.283254,0.647746 0.34309,0.504271 0.576193,1.338134 0.576193,2.516609 v 0.0028 0.0028 c 0.08994,3.895673 -2.57721,7.365746 -5.86738,10.873294 -0.269231,-1.688908 -0.484148,-3.201981 -0.504639,-4.027703 0.04956,-3.210004 0.732851,-5.689246 1.633489,-7.375651 0.901289,-1.687624 2.025641,-2.557602 2.879083,-2.639944 z m -3.898719,21.761652 c 0.389738,2.00026 0.803016,4.08172 1.22394,6.189371 -3.002853,1.149185 -5.224346,3.779834 -5.639539,6.664824 -0.424539,2.949931 1.079826,6.123172 5.437118,8.040341 l 0.253261,-0.4039 c -2.562797,-2.181792 -3.177497,-4.507935 -2.73786,-6.404028 0.419216,-1.808013 1.830273,-3.210283 3.514591,-3.717953 0.911267,4.55187 1.79691,9.027787 2.522258,12.929511 -0.945945,0.30833 -2.028782,0.50028 -3.304638,0.509347 -1.67965,0 -4.235476,-0.543094 -6.344716,-2.097643 -2.109241,-1.554551 -3.793273,-4.10178 -3.793273,-8.206046 0,-3.437682 1.178816,-5.824173 2.917684,-7.895354 1.655143,-1.971455 3.829109,-3.657845 5.951174,-5.60847 z m 3.38843,10.129516 c 0.05534,9.16e-4 0.107015,-0.0019 0.161937,0 h 0.0038 0.0047 c 5.937509,0 8.235682,9.280943 2.419635,12.540672 -0.767221,-3.843065 -1.676631,-8.182617 -2.590056,-12.540672 z"
+ id="path26" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path3"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.39203209;stroke-linecap:round;stroke-linejoin:round"
+ d="m 67.881564,36.514553 c 0.947637,1.398692 1.434824,3.092263 2.655966,4.300236 1.398625,1.842004 3.1861,3.367753 4.57202,5.231727 1.003027,1.302406 2.102471,2.686672 2.387226,4.325052 0.766779,2.101545 0.433848,4.460845 -0.38419,6.518185 -0.922954,1.109437 -1.553941,-0.326373 -1.296318,-1.215319 0.03926,-1.226569 0.02137,-2.449895 -0.449063,-3.608434 -0.417218,-1.737446 -1.180179,-3.38165 -2.457504,-4.656527 -1.109901,-0.972851 -2.369954,-3.11655 -4.062004,-2.378425 -1.117378,0.703912 -0.630582,2.126824 -0.75083,3.223556 -0.06641,6.746623 -0.07086,13.495894 -0.178708,20.241193 -0.08246,2.832921 -2.531026,4.73349 -4.822893,5.949735 -2.041788,1.228686 -4.486389,1.916848 -6.856475,1.369243 -2.203919,-0.226142 -4.483808,-1.835055 -4.529999,-4.215663 -0.146937,-2.760259 1.84657,-5.330594 4.300633,-6.420641 2.409065,-1.373082 5.454806,-1.670675 8.048964,-0.683663 1.267663,0.400688 1.620182,-0.775646 1.778408,-1.90712 0.146401,-8.587634 0.263572,-17.175269 0.293516,-25.764226 0.02422,-0.858499 1.422516,-1.068012 1.751079,-0.308399 z" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect834"
+ width="82"
+ height="1"
+ x="10"
+ y="40"
+ ry="0" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect836"
+ width="2"
+ height="40"
+ x="90"
+ y="40" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect838"
+ width="82"
+ height="1"
+ x="10"
+ y="80" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect834-3"
+ width="82"
+ height="1"
+ x="10"
+ y="50"
+ ry="0" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect834-3-6"
+ width="82"
+ height="1"
+ x="10"
+ y="60"
+ ry="0" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect834-3-6-7"
+ width="82"
+ height="1"
+ x="10"
+ y="70"
+ ry="0" />
+ </g>
+</svg>
diff --git a/src/activities/piano_composition/resource/README b/src/activities/piano_composition/resource/README
new file mode 100644
index 000000000..b18deaa83
--- /dev/null
+++ b/src/activities/piano_composition/resource/README
@@ -0,0 +1,13 @@
+Copyright: 2018, Timothee Giet
+License: CC-BY-SA 4.0
+Files:
+add.svg
+bassClefButton.svg
+erase.svg
+lyrics.svg
+open.svg
+piano.svg
+play.svg
+save.svg
+trebleClefButton.svg
+undo.svg
diff --git a/src/activities/piano_composition/resource/add.svg b/src/activities/piano_composition/resource/add.svg
new file mode 100644
index 000000000..a208dc3c1
--- /dev/null
+++ b/src/activities/piano_composition/resource/add.svg
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 12.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ height="42"
+ id="Layer_1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="add.svg"
+ sodipodi:version="0.32"
+ space="preserve"
+ style="overflow:visible"
+ version="1.1"
+ viewBox="0 0 42.000002 42"
+ width="42"
+ inkscape:export-filename="D:\GR8DAN\My Pictures\Graphics\Buttons\large_round_blue_play_button_pressed.png"
+ inkscape:export-xdpi="39.369999"
+ inkscape:export-ydpi="39.369999">
+ <metadata
+ id="metadata3001">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:title></dc:title>
+ <dc:description />
+ <dc:subject>
+ <rdf:Bag />
+ </dc:subject>
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://www.openclipart.org/">
+ <dc:title />
+ </cc:Agent>
+ </dc:publisher>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Timothée Giet</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:rights>
+ <cc:Agent>
+ <dc:title />
+ </cc:Agent>
+ </dc:rights>
+ <dc:date>2018</dc:date>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
+ <dc:language />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs23" />
+ <sodipodi:namedview
+ bordercolor="#666666"
+ borderopacity="1.0"
+ id="base"
+ inkscape:current-layer="g3"
+ inkscape:cx="15.328017"
+ inkscape:cy="18.088295"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:window-height="1051"
+ inkscape:window-width="1884"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:zoom="10.502363"
+ pagecolor="#ffffff"
+ showgrid="true"
+ inkscape:window-maximized="1"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0">
+ <inkscape:grid
+ type="xygrid"
+ id="grid855" />
+ </sodipodi:namedview>
+ <g
+ id="g3"
+ transform="translate(3.0415638e-8,-98.453992)">
+ <radialGradient
+ cx="68.590797"
+ cy="68.5327"
+ gradientUnits="userSpaceOnUse"
+ id="XMLID_2_"
+ r="63.7393"
+ gradientTransform="matrix(-0.24216096,0,0,0.24216096,36.716755,100.51532)">
+ <stop
+ id="stop8"
+ offset="0"
+ style="stop-color:#D4E4F7" />
+ <stop
+ id="stop10"
+ offset="1"
+ style="stop-color:#7FB5F7" />
+ </radialGradient>
+ <circle
+ style="opacity:1;vector-effect:none;fill:#eef1f7;fill-opacity:1;stroke:none;stroke-width:9;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path826"
+ cx="21"
+ cy="119.45399"
+ r="18" />
+ <path
+ style="opacity:1;vector-effect:none;fill:#5471af;fill-opacity:1;stroke:none;stroke-width:11.42506504;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ d="M 21 1 A 20 20 0 0 0 1 21 A 20 20 0 0 0 21 41 A 20 20 0 0 0 41 21 A 20 20 0 0 0 21 1 z M 21 4 A 17 17 0 0 1 38 21 A 17 17 0 0 1 21 38 A 17 17 0 0 1 4 21 A 17 17 0 0 1 21 4 z "
+ transform="translate(-3.0415638e-8,98.453992)"
+ id="path837" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#5471af;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect867"
+ width="6"
+ height="19.999998"
+ x="18"
+ y="109.45399"
+ ry="0" />
+ <rect
+ style="overflow:visible;opacity:1;vector-effect:none;fill:#5471af;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect867-3"
+ width="5.9999952"
+ height="20"
+ x="-122.45399"
+ y="11"
+ ry="0"
+ transform="rotate(-90)" />
+ </g>
+</svg>
diff --git a/src/activities/piano_composition/resource/bassClef.svg b/src/activities/piano_composition/resource/bassClef.svg
new file mode 100644
index 000000000..41324d5cd
--- /dev/null
+++ b/src/activities/piano_composition/resource/bassClef.svg
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg2"
+ sodipodi:docname="bassClef.svg"
+ viewBox="0 0 95.116 153.12"
+ sodipodi:version="0.32"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ inkscape:version="0.91 r13725"
+ version="1.1">
+ <defs
+ id="defs7" />
+ <sodipodi:namedview
+ id="base"
+ bordercolor="#666666"
+ inkscape:pageshadow="2"
+ guidetolerance="10.0"
+ pagecolor="#ffffff"
+ gridtolerance="10.0"
+ inkscape:zoom="1.7353499"
+ objecttolerance="10.0"
+ borderopacity="1.0"
+ inkscape:current-layer="svg2"
+ inkscape:cx="45.535866"
+ inkscape:cy="99.748538"
+ inkscape:window-y="75"
+ inkscape:window-x="661"
+ inkscape:window-height="643"
+ showgrid="false"
+ inkscape:pageopacity="0.0"
+ inkscape:window-width="823"
+ inkscape:window-maximized="0" />
+ <metadata
+ id="metadata5">
+ <rdf:RDF>
+ <cc:Work>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/publicdomain/" />
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://openclipart.org/">
+ <dc:title>Openclipart</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:title>Treble clef</dc:title>
+ <dc:date>2006-12-03T12:59:04</dc:date>
+ <dc:description>Hollow treble clef for use at drawings</dc:description>
+ <dc:source>https://openclipart.org/detail/12473/treble-clef-by-rickvanderzwet-12473</dc:source>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>rickvanderzwet</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>clef</rdf:li>
+ <rdf:li>line art</rdf:li>
+ <rdf:li>music</rdf:li>
+ <rdf:li>sign</rdf:li>
+ <rdf:li>silhouette</rdf:li>
+ <rdf:li>treble</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/publicdomain/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <path
+ inkscape:connector-curvature="0"
+ id="path861"
+ style="fill:#000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.81543082"
+ d="M 38.267774,6.649897 C 23.341767,7.0455894 11.907282,18.633721 15.612871,36.402184 c 0.0032,0.01879 0.02208,0.0377 0.02718,0.05649 0.434952,6.123816 5.029135,10.947484 10.663129,10.947484 5.921126,0 10.719199,-5.313573 10.719199,-11.870761 0,-5.803483 -3.722588,-10.627163 -8.661674,-11.682339 -1.967477,-0.772542 -4.920393,-2.5249 -4.791266,-5.351271 0.06118,-1.39434 1.534223,-3.938085 3.897578,-5.219365 2.873056,-1.48856 5.834475,-2.298794 8.824767,-1.620458 4.531323,0.923285 16.122125,10.156096 17.022612,26.153364 0.526705,12.134567 -5.623791,28.546369 -11.636668,36.30947 -9.681089,12.26646 -25.232338,19.878824 -23.71,21.235483 C 19.332042,96.716947 37.69349,87.408754 47.253946,75.726413 58.921204,61.707608 64.697909,50.02527 64.137232,35.836879 63.814412,21.629643 53.892064,6.2541718 38.267766,6.6498642 Z" />
+ <ellipse
+ ry="8.7999544"
+ rx="8.4639387"
+ cy="24.160589"
+ cx="75.6045"
+ id="path1877"
+ style="fill:#000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.81543666;stroke-linecap:round;stroke-linejoin:round" />
+ <ellipse
+ ry="8.7999544"
+ rx="8.4639387"
+ cy="48.750023"
+ cx="75.6045"
+ id="path2766"
+ style="fill:#000000;fill-rule:evenodd;stroke:#000000;stroke-width:0.81543666;stroke-linecap:round;stroke-linejoin:round" />
+</svg>
diff --git a/src/activities/piano_composition/resource/bassClefButton.svg b/src/activities/piano_composition/resource/bassClefButton.svg
new file mode 100644
index 000000000..694352605
--- /dev/null
+++ b/src/activities/piano_composition/resource/bassClefButton.svg
@@ -0,0 +1,153 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 12.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ height="42"
+ id="Layer_1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="bassClefButton.svg"
+ sodipodi:version="0.32"
+ space="preserve"
+ style="overflow:visible"
+ version="1.1"
+ viewBox="0 0 42.000002 42"
+ width="42"
+ inkscape:export-filename="D:\GR8DAN\My Pictures\Graphics\Buttons\large_round_blue_play_button_pressed.png"
+ inkscape:export-xdpi="39.369999"
+ inkscape:export-ydpi="39.369999">
+ <metadata
+ id="metadata3001">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:title></dc:title>
+ <dc:description />
+ <dc:subject>
+ <rdf:Bag />
+ </dc:subject>
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://www.openclipart.org/">
+ <dc:title />
+ </cc:Agent>
+ </dc:publisher>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Timothée Giet</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:rights>
+ <cc:Agent>
+ <dc:title />
+ </cc:Agent>
+ </dc:rights>
+ <dc:date>2018</dc:date>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
+ <dc:language />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs23" />
+ <sodipodi:namedview
+ bordercolor="#666666"
+ borderopacity="1.0"
+ id="base"
+ inkscape:current-layer="g3"
+ inkscape:cx="39.956846"
+ inkscape:cy="18.564378"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:window-height="1051"
+ inkscape:window-width="1884"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:zoom="10.502363"
+ pagecolor="#ffffff"
+ showgrid="true"
+ inkscape:window-maximized="1"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0">
+ <inkscape:grid
+ type="xygrid"
+ id="grid855" />
+ </sodipodi:namedview>
+ <g
+ id="g3"
+ transform="translate(3.0415638e-8,-98.453992)">
+ <radialGradient
+ cx="68.590797"
+ cy="68.5327"
+ gradientUnits="userSpaceOnUse"
+ id="XMLID_2_"
+ r="63.7393"
+ gradientTransform="matrix(-0.24216096,0,0,0.24216096,36.716755,100.51532)">
+ <stop
+ id="stop8"
+ offset="0"
+ style="stop-color:#D4E4F7" />
+ <stop
+ id="stop10"
+ offset="1"
+ style="stop-color:#7FB5F7" />
+ </radialGradient>
+ <circle
+ style="opacity:1;vector-effect:none;fill:#eef1f7;fill-opacity:1;stroke:none;stroke-width:9;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path826"
+ cx="21"
+ cy="119.45399"
+ r="18" />
+ <path
+ style="opacity:1;vector-effect:none;fill:#5471af;fill-opacity:1;stroke:none;stroke-width:11.42506504;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ d="M 21 1 A 20 20 0 0 0 1 21 A 20 20 0 0 0 21 41 A 20 20 0 0 0 41 21 A 20 20 0 0 0 21 1 z M 21 4 A 17 17 0 0 1 38 21 A 17 17 0 0 1 21 38 A 17 17 0 0 1 4 21 A 17 17 0 0 1 21 4 z "
+ transform="translate(-3.0415638e-8,98.453992)"
+ id="path837" />
+ <path
+ inkscape:connector-curvature="0"
+ style="fill:#37496f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.22089595;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 17.798396,108.02959 c -4.257961,0.10079 -7.520005,3.08367 -6.462874,7.65199 0.0013,0.006 0.0065,0.0101 0.0077,0.0154 0.124104,1.57552 1.435035,2.81834 3.042262,2.81834 1.689103,0 3.057704,-1.3686 3.057704,-3.05771 0,-1.48868 -1.061821,-2.72999 -2.470873,-3.00365 -0.561509,-0.19868 -1.403655,-0.65042 -1.366701,-1.37442 0.01703,-0.36034 0.437695,-1.01393 1.111892,-1.34354 0.819401,-0.38454 1.664333,-0.59262 2.517201,-0.41696 1.292838,0.23601 4.599082,2.61004 4.856809,6.72541 0.147933,3.1246 -1.607198,7.34323 -3.320235,9.34297 -2.7616,3.15214 -7.197992,5.11013 -6.764012,5.45908 0.389515,0.34897 5.627302,-2.04504 8.354634,-5.04984 3.328324,-3.60404 4.976002,-6.60819 4.8182,-10.26184 -0.09491,-3.65364 -2.923534,-7.60931 -7.381729,-7.50527 z"
+ id="path861" />
+ <ellipse
+ ry="2.263649"
+ rx="2.4145589"
+ cy="112.53559"
+ cx="28.449829"
+ style="fill:#37496f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.22089569;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path1877" />
+ <ellipse
+ ry="2.263649"
+ rx="2.4145589"
+ cy="118.85842"
+ cx="28.449829"
+ style="fill:#37496f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.22089569;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path2766" />
+ </g>
+</svg>
diff --git a/src/activities/piano_composition/resource/bassF4Eighth.svg b/src/activities/piano_composition/resource/bassF4Eighth.svg
new file mode 100644
index 000000000..c6371f9d4
--- /dev/null
+++ b/src/activities/piano_composition/resource/bassF4Eighth.svg
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg2"
+ viewBox="0 0 744 1052"
+ version="1.1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="bassF4Eighth.svg">
+ <defs
+ id="defs9" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ id="namedview7"
+ showgrid="false"
+ inkscape:zoom="0.43502872"
+ inkscape:cx="20.290616"
+ inkscape:cy="369.23983"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <metadata
+ id="metadata5">
+ <rdf:RDF>
+ <cc:Work>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://openclipart.org/">
+ <dc:title>Openclipart</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:title />
+ <dc:date>2011-05-27T21:51:50</dc:date>
+ <dc:description>There didn't seem to be a whole note on openclipart already. Here is a big one!</dc:description>
+ <dc:source>https://openclipart.org/detail/140893/whole-note-by-10binary</dc:source>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>10binary</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>music</rdf:li>
+ <rdf:li>notation</rdf:li>
+ <rdf:li>note</rdf:li>
+ <rdf:li>whole</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Edited by Timothée Giet for GCompris</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 617.23751,634.95686 v 24.47802 C 434.0785,659.53773 250.9142,659.53773 67.773721,656.72476 v -23.60302 c 196.843069,0.89738 363.774909,1.31393 549.463789,1.83589 z"
+ id="path3287-6"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 617.23751,446.89625 c 0,8.15815 0,16.31606 0,24.47422 -183.15901,0.4499 -366.32066,-0.41649 -549.463789,-2.70971 0,-7.86636 0,-15.73298 0,-23.59935 183.153709,0.8561 366.310069,1.32657 549.463789,1.83561 z"
+ id="path3287-6-5"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path3"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5.92409992;stroke-linecap:round;stroke-linejoin:round"
+ d="m 421.77949,233.27846 c 14.32,21.136 21.682,46.728 40.135,64.982 21.135,27.835 48.146,50.891 69.089,79.058 15.157,19.681 31.771,40.599 36.074,65.357 11.587,31.757 6.556,67.409 -5.8056,98.498 -13.947,16.765 -23.482,-4.9319 -19.589,-18.365 0.59324,-18.535 0.32293,-37.021 -6.7859,-54.528 -6.3047,-26.255 -17.834,-51.101 -37.136,-70.366 -16.772,-14.701 -35.813,-47.095 -61.382,-35.941 -16.885,10.637 -9.5289,32.139 -11.346,48.712 -1.0035,101.95 -1.0707,203.94 -2.7005,305.87 -1.2461,42.809 -38.247,71.529 -72.88,89.908 -30.854,18.567 -67.795,28.966 -103.61,20.691 -33.304,-3.4173 -67.756,-27.73 -68.454,-63.704 -2.2204,-41.711 27.904,-80.552 64.988,-97.024 36.404,-20.749 82.429,-25.246 121.63,-10.331 19.156,6.0549 24.483,-11.721 26.874,-28.819 2.2123,-129.77 3.9829,-259.54 4.4354,-389.33 0.36593,-12.973 21.496,-16.139 26.461,-4.6603 z" />
+</svg>
diff --git a/src/activities/piano_composition/resource/bassF4Half.svg b/src/activities/piano_composition/resource/bassF4Half.svg
new file mode 100644
index 000000000..cd0a58390
--- /dev/null
+++ b/src/activities/piano_composition/resource/bassF4Half.svg
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg2"
+ viewBox="0 0 744 1052"
+ version="1.1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="bassF4Half.svg">
+ <defs
+ id="defs9">
+ <linearGradient
+ id="linearGradient3019"
+ y2="333.89001"
+ gradientUnits="userSpaceOnUse"
+ x2="490.53"
+ gradientTransform="matrix(2.0779,0,0,2.0779,-518.08,-481.7868)"
+ y1="489.14001"
+ x1="382.34">
+ <stop
+ id="stop3015"
+ style="stop-color:#000000;stop-opacity:.82639"
+ offset="0" />
+ <stop
+ id="stop3017"
+ style="stop-color:#000000"
+ offset="1" />
+ </linearGradient>
+ <inkscape:perspective
+ id="perspective3348"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 0.5 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="1 : 0.5 : 1"
+ inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+ id="perspective2844" />
+ <inkscape:perspective
+ id="perspective3348-6"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 0.5 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="1 : 0.5 : 1"
+ inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+ id="perspective2844-7" />
+ <inkscape:perspective
+ id="perspective3348-3"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 0.5 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="1 : 0.5 : 1"
+ inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+ id="perspective2844-6" />
+ </defs>
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ id="namedview7"
+ showgrid="false"
+ inkscape:zoom="0.43502872"
+ inkscape:cx="20.290616"
+ inkscape:cy="369.23983"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <metadata
+ id="metadata5">
+ <rdf:RDF>
+ <cc:Work>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://openclipart.org/">
+ <dc:title>Openclipart</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:title />
+ <dc:date>2011-05-27T21:51:50</dc:date>
+ <dc:description>There didn't seem to be a whole note on openclipart already. Here is a big one!</dc:description>
+ <dc:source>https://openclipart.org/detail/140893/whole-note-by-10binary</dc:source>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>10binary</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>music</rdf:li>
+ <rdf:li>notation</rdf:li>
+ <rdf:li>note</rdf:li>
+ <rdf:li>whole</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Edited by Timothée Giet for GCompris</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 617.23751,634.95686 v 24.47802 C 434.0785,659.53773 250.9142,659.53773 67.773721,656.72476 v -23.60302 c 196.843069,0.89738 363.774909,1.31393 549.463789,1.83589 z"
+ id="path3287-6"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path3"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5.92409992;stroke-linecap:round;stroke-linejoin:round"
+ d="m 411.08132,225.77655 c -7.2475,0.33178 -15.544,4.8587 -15.75,12.156 -0.45246,129.79 -2.2252,259.57 -4.4375,389.34 -2.3903,17.098 -7.7188,34.867 -26.875,28.812 -39.21,-14.91 -85.23,-10.4 -121.63,10.35 -37.084,16.471 -67.22,55.289 -65,97 0.69789,35.974 35.134,60.301 68.438,63.719 35.814,8.2749 72.771,-2.12 103.62,-20.688 34.633,-18.379 71.629,-47.097 72.875,-89.906 2.4559,-167.09 4.7446,-319.48 -0.5625,-483.28 -0.073,-5.4712 -5.0506,-7.758 -10.688,-7.5 z m -99.28,436.04 c 30.478,-0.002 56.713,13.001 67.312,36.562 16.152,35.904 -10.092,82.712 -58.594,104.53 -48.502,21.819 -100.91,10.404 -117.06,-25.5 -16.152,-35.904 10.092,-82.712 58.594,-104.53 16.672,-7.5002 33.785,-11.062 49.75,-11.062 z" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 617.23656,446.89642 c 0,8.15818 0,16.3161 0,24.47427 -183.15556,0.44991 -366.31289,-0.41648 -549.463097,-2.70971 1.194462,-7.22957 -2.579681,-21.64219 2.265912,-23.58886 182.397875,0.85097 364.799305,1.31887 547.197185,1.82533 z"
+ id="path3287-6-5"
+ inkscape:connector-curvature="0" />
+</svg>
diff --git a/src/activities/piano_composition/resource/bassF4Quarter.svg b/src/activities/piano_composition/resource/bassF4Quarter.svg
new file mode 100644
index 000000000..491062f47
--- /dev/null
+++ b/src/activities/piano_composition/resource/bassF4Quarter.svg
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg2"
+ viewBox="0 0 744 1052"
+ version="1.1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="bassF4Quarter.svg">
+ <defs
+ id="defs9" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ id="namedview7"
+ showgrid="false"
+ inkscape:zoom="0.43502872"
+ inkscape:cx="20.290616"
+ inkscape:cy="369.23983"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <metadata
+ id="metadata5">
+ <rdf:RDF>
+ <cc:Work>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://openclipart.org/">
+ <dc:title>Openclipart</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:title />
+ <dc:date>2011-05-27T21:51:50</dc:date>
+ <dc:description>There didn't seem to be a whole note on openclipart already. Here is a big one!</dc:description>
+ <dc:source>https://openclipart.org/detail/140893/whole-note-by-10binary</dc:source>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>10binary</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>music</rdf:li>
+ <rdf:li>notation</rdf:li>
+ <rdf:li>note</rdf:li>
+ <rdf:li>whole</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Edited by Timothée Giet for GCompris</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 617.23751,634.95686 c 0,8.15943 0,16.31859 0,24.47802 -183.15901,0.44997 -366.32066,-0.41655 -549.463789,-2.71012 0,-7.86759 0,-15.73543 0,-23.60302 183.153709,0.85624 366.310069,1.32678 549.463789,1.83589 z"
+ id="path3287-6"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 617.23751,446.89625 c 0,8.15815 0,16.31606 0,24.47422 -183.15901,0.4499 -366.32066,-0.41649 -549.463789,-2.70971 0,-7.86636 0,-15.73298 0,-23.59935 183.153709,0.8561 366.310069,1.32657 549.463789,1.83561 z"
+ id="path3287-6-5"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path3-5"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5.92409992;stroke-linecap:round;stroke-linejoin:round"
+ d="m 421.77912,233.28546 c 5.3071,163.8 3.0093,316.18 0.55337,483.27 -1.2461,42.809 -38.247,71.529 -72.88,89.908 -30.854,18.567 -67.795,28.966 -103.61,20.691 -33.304,-3.4173 -67.756,-27.73 -68.454,-63.704 -2.2204,-41.711 27.904,-80.552 64.988,-97.024 36.404,-20.749 82.429,-25.246 121.63,-10.331 19.156,6.0549 24.483,-11.721 26.874,-28.819 2.2123,-129.77 3.9829,-259.54 4.4354,-389.33 0.36593,-12.973 26.294,-17.166 26.461,-4.6603 z" />
+</svg>
diff --git a/src/activities/piano_composition/resource/bassF4Whole.svg b/src/activities/piano_composition/resource/bassF4Whole.svg
new file mode 100644
index 000000000..2f425d5d6
--- /dev/null
+++ b/src/activities/piano_composition/resource/bassF4Whole.svg
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg2"
+ viewBox="0 0 744 1052"
+ version="1.1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="bassF4Whole.svg">
+ <defs
+ id="defs9" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ id="namedview7"
+ showgrid="false"
+ inkscape:zoom="0.43502872"
+ inkscape:cx="20.290616"
+ inkscape:cy="691.72367"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 289.29484,644.77518 c 66.94384,0.69882 130.26832,30.04918 135.09143,95.04169 3.61532,47.53718 -50.66281,90.84313 -117.60261,90.84313 -67.54773,-0.69977 -130.26832,-29.34803 -135.69532,-94.31861 -3.61814,-48.26027 51.22644,-91.56621 118.2065,-91.56621 z m 16.2456,169.81361 c 28.94793,0 47.64333,-32.1676 44.62788,-58.00095 -6.634,-51.01266 -21.71125,-92.26597 -61.5128,-92.26597 -28.94793,0 -45.83567,32.8445 -42.21632,58.70071 6.67143,51.03599 19.33633,91.56621 59.10124,91.56621 z"
+ style="fill:#000000;stroke:none;stroke-width:0.43337601"
+ id="path270" />
+ <metadata
+ id="metadata5">
+ <rdf:RDF>
+ <cc:Work>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://openclipart.org/">
+ <dc:title>Openclipart</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:title />
+ <dc:date>2011-05-27T21:51:50</dc:date>
+ <dc:description>There didn't seem to be a whole note on openclipart already. Here is a big one!</dc:description>
+ <dc:source>https://openclipart.org/detail/140893/whole-note-by-10binary</dc:source>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>10binary</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>music</rdf:li>
+ <rdf:li>notation</rdf:li>
+ <rdf:li>note</rdf:li>
+ <rdf:li>whole</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Edited by Timothée Giet for GCompris</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 538.23906,446.89281 c 0,8.15943 0,16.3186 0,24.47804 -160.15845,0.44997 -320.31922,-0.41655 -480.463788,-2.71013 0,-7.86759 0,-15.73544 0,-23.60303 160.153828,0.85623 320.309968,1.32678 480.463788,1.83589 z"
+ id="path3287-6"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 538.24006,625.76432 c 0,8.15838 0,16.3165 0,24.47488 -160.15845,0.44992 -320.31922,-0.41649 -480.463788,-2.70977 0,-7.86658 0,-15.73342 0,-23.59999 160.153828,0.85612 320.309968,1.3266 480.463788,1.83565 z"
+ id="path3287-6-3"
+ inkscape:connector-curvature="0" />
+</svg>
diff --git a/src/activities/piano_composition/resource/bassG4Eighth.svg b/src/activities/piano_composition/resource/bassG4Eighth.svg
new file mode 100644
index 000000000..dfa73d175
--- /dev/null
+++ b/src/activities/piano_composition/resource/bassG4Eighth.svg
@@ -0,0 +1,199 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg2"
+ viewBox="0 0 744 1052"
+ version="1.1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="bassG4Eighth.svg">
+ <defs
+ id="defs9">
+ <linearGradient
+ id="linearGradient3019"
+ y2="333.89001"
+ gradientUnits="userSpaceOnUse"
+ x2="490.53"
+ gradientTransform="matrix(2.0779,0,0,2.0779,-518.08,-481.7868)"
+ y1="489.14001"
+ x1="382.34">
+ <stop
+ id="stop3015"
+ style="stop-color:#000000;stop-opacity:.82639"
+ offset="0" />
+ <stop
+ id="stop3017"
+ style="stop-color:#000000"
+ offset="1" />
+ </linearGradient>
+ <inkscape:perspective
+ id="perspective3348"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 0.5 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="1 : 0.5 : 1"
+ inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+ id="perspective2844" />
+ <inkscape:perspective
+ id="perspective3348-6"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 0.5 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="1 : 0.5 : 1"
+ inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+ id="perspective2844-7" />
+ <inkscape:perspective
+ id="perspective3348-3"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 0.5 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="1 : 0.5 : 1"
+ inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+ id="perspective2844-6" />
+ <inkscape:perspective
+ id="perspective3348-36"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 0.5 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="1 : 0.5 : 1"
+ inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+ id="perspective2844-75" />
+ <linearGradient
+ x1="382.34"
+ y1="489.14"
+ gradientTransform="matrix(2.0779,0,0,2.0779,-518.08,-281.8)"
+ x2="490.53"
+ gradientUnits="userSpaceOnUse"
+ y2="333.89"
+ id="linearGradient3019-3">
+ <stop
+ offset="0"
+ style="stop-color:#000000;stop-opacity:.82639"
+ id="stop3015-6" />
+ <stop
+ offset="1"
+ style="stop-color:#000000"
+ id="stop3017-7" />
+ </linearGradient>
+ </defs>
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ id="namedview7"
+ showgrid="false"
+ inkscape:zoom="0.43502872"
+ inkscape:cx="20.290616"
+ inkscape:cy="369.23983"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <metadata
+ id="metadata5">
+ <rdf:RDF>
+ <cc:Work>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://openclipart.org/">
+ <dc:title>Openclipart</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:title />
+ <dc:date>2011-05-27T21:51:50</dc:date>
+ <dc:description>There didn't seem to be a whole note on openclipart already. Here is a big one!</dc:description>
+ <dc:source>https://openclipart.org/detail/140893/whole-note-by-10binary</dc:source>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>10binary</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>music</rdf:li>
+ <rdf:li>notation</rdf:li>
+ <rdf:li>note</rdf:li>
+ <rdf:li>whole</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Edited by Timothée Giet for GCompris</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 617.23751,729.20386 c 0,8.15943 0,16.31859 0,24.47802 -183.15901,0.44997 -366.32066,-0.41655 -549.463789,-2.71012 0,-7.86759 0,-15.73543 0,-23.60302 183.153709,0.85624 366.310069,1.32678 549.463789,1.83589 z"
+ id="path3287-6"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 617.23751,367.18125 c 0,8.15815 0,16.31606 0,24.47422 -183.15901,0.4499 -366.32066,-0.41649 -549.463789,-2.70971 0,-7.86636 0,-15.73298 0,-23.59935 183.153709,0.8561 366.310069,1.32657 549.463789,1.83561 z"
+ id="path3287-6-5"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 617.23751,547.23326 c 0,8.15835 0,16.31645 0,24.4748 -183.15901,0.44991 -366.32066,-0.41649 -549.463789,-2.70977 0,-7.86655 0,-15.73335 0,-23.5999 183.153709,0.85612 366.310069,1.32917 549.463789,1.83564 z"
+ id="path3287-6-6"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path3"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5.92409992;stroke-linecap:round;stroke-linejoin:round"
+ d="m 421.77949,233.27846 c 14.32,21.136 21.682,46.728 40.135,64.982 21.135,27.835 48.146,50.891 69.089,79.058 15.157,19.681 31.771,40.599 36.074,65.357 11.587,31.757 6.556,67.409 -5.8056,98.498 -13.947,16.765 -23.482,-4.9319 -19.589,-18.365 0.59324,-18.535 0.32293,-37.021 -6.7859,-54.528 -6.3047,-26.255 -17.834,-51.101 -37.136,-70.366 -16.772,-14.701 -35.813,-47.095 -61.382,-35.941 -16.885,10.637 -9.5289,32.139 -11.346,48.712 -1.0035,101.95 -1.0707,203.94 -2.7005,305.87 -1.2461,42.809 -38.247,71.529 -72.88,89.908 -30.854,18.567 -67.795,28.966 -103.61,20.691 -33.304,-3.4173 -67.756,-27.73 -68.454,-63.704 -2.2204,-41.711 27.904,-80.552 64.988,-97.024 36.404,-20.749 82.429,-25.246 121.63,-10.331 19.156,6.0549 24.483,-11.721 26.874,-28.819 2.2123,-129.77 3.9829,-259.54 4.4354,-389.33 0.36593,-12.973 21.496,-16.139 26.461,-4.6603 z" />
+</svg>
diff --git a/src/activities/piano_composition/resource/bassG4Half.svg b/src/activities/piano_composition/resource/bassG4Half.svg
new file mode 100644
index 000000000..b0a4c1188
--- /dev/null
+++ b/src/activities/piano_composition/resource/bassG4Half.svg
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg2"
+ viewBox="0 0 744 1052"
+ version="1.1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="bassG4Half.svg">
+ <defs
+ id="defs9" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ id="namedview7"
+ showgrid="false"
+ inkscape:zoom="0.43502872"
+ inkscape:cx="20.290616"
+ inkscape:cy="369.23983"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <metadata
+ id="metadata5">
+ <rdf:RDF>
+ <cc:Work>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://openclipart.org/">
+ <dc:title>Openclipart</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:title />
+ <dc:date>2011-05-27T21:51:50</dc:date>
+ <dc:description>There didn't seem to be a whole note on openclipart already. Here is a big one!</dc:description>
+ <dc:source>https://openclipart.org/detail/140893/whole-note-by-10binary</dc:source>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>10binary</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>music</rdf:li>
+ <rdf:li>notation</rdf:li>
+ <rdf:li>note</rdf:li>
+ <rdf:li>whole</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Edited by Timothée Giet for GCompris</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 617.23751,729.20386 c 0,8.15943 0,16.31859 0,24.47802 -183.15901,0.44997 -366.32066,-0.41655 -549.463789,-2.71012 0,-7.86759 0,-15.73543 0,-23.60302 183.153709,0.85624 366.310069,1.32678 549.463789,1.83589 z"
+ id="path3287-6"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path3"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5.92409992;stroke-linecap:round;stroke-linejoin:round"
+ d="m 411.08132,225.77655 c -7.2475,0.33178 -15.544,4.8587 -15.75,12.156 -0.45246,129.79 -2.2252,259.57 -4.4375,389.34 -2.3903,17.098 -7.7188,34.867 -26.875,28.812 -39.21,-14.91 -85.23,-10.4 -121.63,10.35 -37.084,16.471 -67.22,55.289 -65,97 0.69789,35.974 35.134,60.301 68.438,63.719 35.814,8.2749 72.771,-2.12 103.62,-20.688 34.633,-18.379 71.629,-47.097 72.875,-89.906 2.4559,-167.09 4.7446,-319.48 -0.5625,-483.28 -0.073,-5.4712 -5.0506,-7.758 -10.688,-7.5 z m -99.28,436.04 c 30.478,-0.002 56.713,13.001 67.312,36.562 16.152,35.904 -10.092,82.712 -58.594,104.53 -48.502,21.819 -100.91,10.404 -117.06,-25.5 -16.152,-35.904 10.092,-82.712 58.594,-104.53 16.672,-7.5002 33.785,-11.062 49.75,-11.062 z" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 617.23751,547.18125 c 0,8.15815 0,16.31606 0,24.47422 -183.15901,0.4499 -366.32066,-0.41649 -549.463789,-2.70971 0,-7.86636 0,-15.73298 0,-23.59935 183.153709,0.8561 366.310069,1.32914 549.463789,1.83561 z"
+ id="path3287-6-5"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 617.23751,367.23326 c 0,8.15835 0,16.31645 0,24.4748 -183.15901,0.44991 -366.32066,-0.41649 -549.463789,-2.70977 0,-7.86655 0,-15.73335 0,-23.5999 183.153709,0.85612 366.310069,1.32917 549.463789,1.83564 z"
+ id="path3287-6-6"
+ inkscape:connector-curvature="0" />
+</svg>
diff --git a/src/activities/piano_composition/resource/bassG4Quarter.svg b/src/activities/piano_composition/resource/bassG4Quarter.svg
new file mode 100644
index 000000000..ac9022691
--- /dev/null
+++ b/src/activities/piano_composition/resource/bassG4Quarter.svg
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg2"
+ viewBox="0 0 744 1052"
+ version="1.1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="bassG4Quarter.svg">
+ <defs
+ id="defs9" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ id="namedview7"
+ showgrid="false"
+ inkscape:zoom="0.43502872"
+ inkscape:cx="513.36151"
+ inkscape:cy="369.23983"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="g3336-5" />
+ <metadata
+ id="metadata5">
+ <rdf:RDF>
+ <cc:Work>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://openclipart.org/">
+ <dc:title>Openclipart</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:title></dc:title>
+ <dc:date>2011-05-27T21:51:50</dc:date>
+ <dc:description>There didn't seem to be a whole note on openclipart already. Here is a big one!</dc:description>
+ <dc:source>https://openclipart.org/detail/140893/whole-note-by-10binary</dc:source>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>10binary</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>music</rdf:li>
+ <rdf:li>notation</rdf:li>
+ <rdf:li>note</rdf:li>
+ <rdf:li>whole</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Edited by Timothée Giet for GCompris</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 617.23751,729.20386 c 0,8.15943 0,16.31859 0,24.47802 -183.15901,0.44997 -366.32066,-0.41655 -549.463789,-2.71012 0,-7.86759 0,-15.73543 0,-23.60302 183.153709,0.85624 366.310069,1.32678 549.463789,1.83589 z"
+ id="path3287-6"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 617.23751,547.18125 c 0,8.15815 0,16.31606 0,24.47422 -183.15901,0.4499 -366.32066,-0.41649 -549.463789,-2.70971 0,-7.86636 0,-15.73298 0,-23.59935 183.153709,0.8561 366.310069,1.32914 549.463789,1.83561 z"
+ id="path3287-6-5"
+ inkscape:connector-curvature="0" />
+ <g
+ transform="matrix(26.463093,0,0,25.709358,-8651.9314,-12769.499)"
+ id="layer1-3"
+ inkscape:label="Layer 1">
+ <g
+ style="fill:#000000"
+ transform="matrix(-1,0,0,-1,1577.821,844.41268)"
+ id="g3336-5">
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 1227.5532,333.44184 c 0,-0.31733 0,-0.63465 0,-0.95198 6.9213,-0.0175 13.8427,0.0162 20.7634,0.1054 0,0.30598 0,0.61197 0,0.91795 -6.9211,-0.0333 -13.8423,-0.0517 -20.7634,-0.0714 z"
+ id="path3287-6-6"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ id="path3"
+ style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5.92409992;stroke-linecap:round;stroke-linejoin:round"
+ d="m 421.77912,233.28546 c 5.3071,163.8 3.0093,316.18 0.55337,483.27 -1.2461,42.809 -38.247,71.529 -72.88,89.908 -30.854,18.567 -67.795,28.966 -103.61,20.691 -33.304,-3.4173 -67.756,-27.73 -68.454,-63.704 -2.2204,-41.711 27.904,-80.552 64.988,-97.024 36.404,-20.749 82.429,-25.246 121.63,-10.331 19.156,6.0549 24.483,-11.721 26.874,-28.819 2.2123,-129.77 3.9829,-259.54 4.4354,-389.33 0.36593,-12.973 26.294,-17.166 26.461,-4.6603 z" />
+</svg>
diff --git a/src/activities/piano_composition/resource/bassG4Whole.svg b/src/activities/piano_composition/resource/bassG4Whole.svg
new file mode 100644
index 000000000..1e90dbf05
--- /dev/null
+++ b/src/activities/piano_composition/resource/bassG4Whole.svg
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg2"
+ viewBox="0 0 744 1052"
+ version="1.1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="bassG4Whole.svg"
+ width="744"
+ height="1052">
+ <defs
+ id="defs9" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ id="namedview7"
+ showgrid="false"
+ inkscape:zoom="0.43502872"
+ inkscape:cx="513.36151"
+ inkscape:cy="691.72367"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 289.29484,644.77518 c 66.94384,0.69882 130.26832,30.04918 135.09143,95.04169 3.61532,47.53718 -50.66281,90.84313 -117.60261,90.84313 -67.54773,-0.69977 -130.26832,-29.34803 -135.69532,-94.31861 -3.61814,-48.26027 51.22644,-91.56621 118.2065,-91.56621 z m 16.2456,169.81361 c 28.94793,0 47.64333,-32.1676 44.62788,-58.00095 -6.634,-51.01266 -21.71125,-92.26597 -61.5128,-92.26597 -28.94793,0 -45.83567,32.8445 -42.21632,58.70071 6.67143,51.03599 19.33633,91.56621 59.10124,91.56621 z"
+ style="fill:#000000;stroke-width:0.43337601;stroke:none"
+ id="path270" />
+ <metadata
+ id="metadata5">
+ <rdf:RDF>
+ <cc:Work>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://openclipart.org/">
+ <dc:title>Openclipart</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:title></dc:title>
+ <dc:date>2011-05-27T21:51:50</dc:date>
+ <dc:description>There didn't seem to be a whole note on openclipart already. Here is a big one!</dc:description>
+ <dc:source>https://openclipart.org/detail/140893/whole-note-by-10binary</dc:source>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>10binary</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>music</rdf:li>
+ <rdf:li>notation</rdf:li>
+ <rdf:li>note</rdf:li>
+ <rdf:li>whole</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Edited by Timothée Giet for GCompris</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 538.23806,367.23021 c 0,8.15935 0,16.31869 0,24.47804 -160.15837,0.44943 -320.321,-0.41706 -480.463788,-2.71013 0,-7.86768 0,-15.73535 0,-23.60303 160.153578,0.85584 320.308828,1.32618 480.463788,1.83512 z"
+ id="path3287-6"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 538.23806,547.19132 c 0,8.15829 0,16.31659 0,24.47488 -160.15837,0.44936 -320.321,-0.41698 -480.463788,-2.70977 0,-7.86666 0,-15.73333 0,-23.59999 160.153578,0.85571 320.308828,1.32601 480.463788,1.83488 z"
+ id="path3287-6-3"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 538.23806,745.21709 c 0,8.15935 0,16.31869 0,24.47804 -160.15837,0.44942 -320.321,-0.41704 -480.463788,-2.71013 0,-7.86768 0,-15.73535 0,-23.60303 160.153578,0.85591 320.308828,1.32619 480.463788,1.83512 z"
+ id="path3287-6-6"
+ inkscape:connector-curvature="0" />
+</svg>
diff --git a/src/activities/piano_composition/resource/blackflat.svg b/src/activities/piano_composition/resource/blackflat.svg
new file mode 100644
index 000000000..264bcf97f
--- /dev/null
+++ b/src/activities/piano_composition/resource/blackflat.svg
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg1"
+ sodipodi:docname="blackflat.svg"
+ viewBox="0 0 60 60"
+ sodipodi:version="0.32"
+ _SVGFile__filename="oldscale/actions/music_flat.svg"
+ version="1.0"
+ y="0"
+ x="0"
+ inkscape:version="0.92.1 r15371">
+ <defs
+ id="defs12" />
+ <sodipodi:namedview
+ id="base"
+ bordercolor="#666666"
+ inkscape:pageshadow="2"
+ inkscape:window-y="0"
+ pagecolor="#7b7b7b"
+ inkscape:window-height="1051"
+ inkscape:zoom="5.2958333"
+ inkscape:window-x="0"
+ borderopacity="1.0"
+ inkscape:current-layer="g1091"
+ inkscape:cx="30"
+ inkscape:cy="20.176541"
+ inkscape:window-width="1884"
+ inkscape:pageopacity="0"
+ showgrid="false"
+ inkscape:window-maximized="1" />
+ <g
+ id="g1091">
+ <g
+ id="g1709"
+ transform="matrix(1.0946,0,0,1.0946,-4.7351,-2.6665)">
+ <path
+ style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5.00013256;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ d="M 12.523438 3.0917969 A 2.5003163 2.5003163 0 0 0 10.060547 5.6269531 L 10.060547 26.71875 A 2.5003163 2.5003163 0 0 0 10.035156 27.074219 L 10.035156 54.375 A 2.5003163 2.5003163 0 0 0 13.533203 56.667969 C 23.143625 52.489167 33.920332 47.837878 41.269531 42.865234 C 44.944131 40.378912 47.862733 37.873777 49.257812 34.695312 C 49.955352 33.10608 50.189736 31.26249 49.691406 29.513672 C 49.19626 27.776021 48.058106 26.246613 46.484375 24.914062 C 41.053574 20.075889 34.917744 18.76088 29.302734 19.052734 C 23.566123 19.350911 18.395259 21.317731 15.0625 22.898438 L 15.0625 5.6269531 A 2.5003163 2.5003163 0 0 0 12.523438 3.0917969 z M 31.044922 23.892578 C 35.099841 23.983751 39.349751 25.234346 43.183594 28.660156 A 2.5003163 2.5003163 0 0 0 43.238281 28.710938 C 44.294947 29.600743 44.72508 30.331222 44.882812 30.884766 C 45.040547 31.43831 45.011769 31.926454 44.677734 32.6875 C 44.009664 34.209589 41.790933 36.475418 38.466797 38.724609 C 32.616129 42.683312 23.651655 46.733166 15.035156 50.507812 L 15.035156 44.453125 A 2.5003163 2.5003163 0 0 0 15.0625 44.068359 L 15.0625 28.546875 C 17.365264 27.210513 22.722672 24.285493 29.320312 23.921875 C 29.889881 23.890484 30.465648 23.879553 31.044922 23.892578 z "
+ transform="matrix(0.91357574,0,0,0.91357574,4.3258725,2.4360497)"
+ id="path839" />
+ </g>
+ </g>
+ <metadata
+ id="metadata9">
+ <rdf:RDF>
+ <cc:Work>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://openclipart.org/">
+ <dc:title>Openclipart</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:title></dc:title>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Edited by Timothée Giet for GCompris</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+</svg>
diff --git a/src/activities/piano_composition/resource/blacksharp.svg b/src/activities/piano_composition/resource/blacksharp.svg
new file mode 100644
index 000000000..1297481fb
--- /dev/null
+++ b/src/activities/piano_composition/resource/blacksharp.svg
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg1"
+ sodipodi:docname="blacksharp.svg"
+ viewBox="0 0 60 60"
+ sodipodi:version="0.32"
+ _SVGFile__filename="oldscale/actions/music_cross.svg"
+ version="1.0"
+ y="0"
+ x="0"
+ inkscape:version="0.92.1 r15371">
+ <defs
+ id="defs11" />
+ <sodipodi:namedview
+ id="base"
+ bordercolor="#666666"
+ inkscape:pageshadow="2"
+ inkscape:window-y="0"
+ pagecolor="#aeaeae"
+ inkscape:window-height="1051"
+ inkscape:zoom="8.6748326"
+ inkscape:window-x="0"
+ borderopacity="1.0"
+ inkscape:current-layer="svg1"
+ inkscape:cx="9.1771171"
+ inkscape:cy="21.795312"
+ inkscape:window-width="1884"
+ inkscape:pageopacity="0"
+ showgrid="false"
+ inkscape:window-maximized="1" />
+ <g
+ id="g1088"
+ transform="matrix(1.051 0 0 1.051 -.96118 -1.6077)">
+ <path
+ style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.74983358;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ d="M 20.558594 3.0996094 A 1.8751042 1.8751042 0 0 0 18.712891 5 L 18.712891 22.052734 L 12.535156 23.708984 A 2.5001584 2.5001584 0 1 0 13.828125 28.537109 L 18.712891 27.228516 L 18.712891 38.822266 L 12.537109 40.470703 A 2.5005687 2.5005687 0 0 0 13.826172 45.302734 L 18.712891 43.998047 L 18.712891 54.996094 A 1.8757218 1.8757218 0 1 0 22.462891 54.996094 L 22.462891 42.998047 L 37.535156 38.974609 L 37.535156 54.996094 A 1.8751042 1.8751042 0 1 0 41.283203 54.996094 L 41.283203 37.972656 L 47.460938 36.324219 A 2.5001584 2.5001584 0 0 0 46.835938 31.400391 A 2.5001584 2.5001584 0 0 0 46.171875 31.492188 L 41.283203 32.796875 L 41.283203 21.181641 L 47.462891 19.525391 A 2.5001584 2.5001584 0 0 0 46.833984 14.601562 A 2.5001584 2.5001584 0 0 0 46.169922 14.695312 L 41.283203 16.005859 L 41.283203 5 A 1.8751042 1.8751042 0 0 0 39.380859 3.0996094 A 1.8751042 1.8751042 0 0 0 37.535156 5 L 37.535156 17.009766 L 22.462891 21.048828 L 22.462891 5 A 1.8751042 1.8751042 0 0 0 20.558594 3.0996094 z M 37.535156 22.185547 L 37.535156 33.796875 L 22.462891 37.820312 L 22.462891 26.222656 L 37.535156 22.185547 z "
+ transform="matrix(0.95147479,0,0,0.95147479,0.91453853,1.529686)"
+ id="path836" />
+ </g>
+ <metadata
+ id="metadata8">
+ <rdf:RDF>
+ <cc:Work>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://openclipart.org/">
+ <dc:title>Openclipart</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:title></dc:title>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Edited by Timothée Giet for GCompris</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+</svg>
diff --git a/src/activities/piano_composition/resource/eighthRest.svg b/src/activities/piano_composition/resource/eighthRest.svg
new file mode 100644
index 000000000..062bc078c
--- /dev/null
+++ b/src/activities/piano_composition/resource/eighthRest.svg
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="744"
+ height="1052"
+ viewBox="0 0 744 1052"
+ id="svg2"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="eighthRest.svg">
+ <metadata
+ id="metadata10">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ <dc:date>2018</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Timothée Giet</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs8" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ id="namedview6"
+ showgrid="false"
+ inkscape:zoom="0.98333333"
+ inkscape:cx="428.64407"
+ inkscape:cy="690.50848"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <path
+ style="fill:#000000;stroke-width:0.10965671"
+ d="m 374.07042,585.30932 c -12.94796,-0.73241 -26.14241,-7.80174 -15.07051,-20.97632 28.89045,-80.67771 58.32522,-161.1597 87.70449,-241.6591 -31.46324,10.18132 -64.82045,20.95619 -98.21832,15.32117 -28.3125,-5.71929 -54.42066,-31.47492 -51.9348,-61.73597 -1.88167,-31.24039 29.60542,-56.06479 59.4046,-54.17213 20.61994,0.4731 39.26079,16.02919 43.30793,36.31383 4.6056,12.72806 3.42486,29.9327 16.00904,38.0489 16.94704,7.86459 28.84074,-11.70666 39.12624,-21.82079 12.32788,-8.95744 15.57954,-32.00962 32.64493,-32.06754 14.30311,2.21829 5.41558,15.38059 3.78447,23.52121 -28.66995,99.19268 -58.61738,198.00555 -88.05551,296.97032 -0.10516,15.30249 -14.61581,23.64461 -28.70195,22.25641 z"
+ id="path812"
+ inkscape:connector-curvature="0" />
+</svg>
diff --git a/src/activities/piano_composition/resource/erase.svg b/src/activities/piano_composition/resource/erase.svg
new file mode 100644
index 000000000..1865a1146
--- /dev/null
+++ b/src/activities/piano_composition/resource/erase.svg
@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 12.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ height="42"
+ id="Layer_1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="erase.svg"
+ sodipodi:version="0.32"
+ space="preserve"
+ style="overflow:visible"
+ version="1.1"
+ viewBox="0 0 42.000002 42"
+ width="42"
+ inkscape:export-filename="D:\GR8DAN\My Pictures\Graphics\Buttons\large_round_blue_play_button_pressed.png"
+ inkscape:export-xdpi="39.369999"
+ inkscape:export-ydpi="39.369999">
+ <metadata
+ id="metadata3001">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:title />
+ <dc:description />
+ <dc:subject>
+ <rdf:Bag />
+ </dc:subject>
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://www.openclipart.org/">
+ <dc:title />
+ </cc:Agent>
+ </dc:publisher>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Timothée Giet</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:rights>
+ <cc:Agent>
+ <dc:title />
+ </cc:Agent>
+ </dc:rights>
+ <dc:date>2018</dc:date>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
+ <dc:language />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs23" />
+ <sodipodi:namedview
+ bordercolor="#666666"
+ borderopacity="1.0"
+ id="base"
+ inkscape:current-layer="g3"
+ inkscape:cx="1.5369209"
+ inkscape:cy="19.040462"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:window-height="1051"
+ inkscape:window-width="1884"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:zoom="10.502363"
+ pagecolor="#ffffff"
+ showgrid="true"
+ inkscape:window-maximized="1"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0">
+ <inkscape:grid
+ type="xygrid"
+ id="grid855" />
+ </sodipodi:namedview>
+ <g
+ id="g3"
+ transform="translate(3.0415638e-8,-98.453992)">
+ <radialGradient
+ cx="68.590797"
+ cy="68.5327"
+ gradientUnits="userSpaceOnUse"
+ id="XMLID_2_"
+ r="63.7393"
+ gradientTransform="matrix(-0.24216096,0,0,0.24216096,36.716755,100.51532)">
+ <stop
+ id="stop8"
+ offset="0"
+ style="stop-color:#D4E4F7" />
+ <stop
+ id="stop10"
+ offset="1"
+ style="stop-color:#7FB5F7" />
+ </radialGradient>
+ <circle
+ style="opacity:1;vector-effect:none;fill:#eef1f7;fill-opacity:1;stroke:none;stroke-width:9;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path826"
+ cx="21"
+ cy="119.45399"
+ r="18" />
+ <path
+ style="opacity:1;vector-effect:none;fill:#df543d;fill-opacity:1;stroke:none;stroke-width:11.42506504;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ d="M 21 1 A 20 20 0 0 0 1 21 A 20 20 0 0 0 21 41 A 20 20 0 0 0 41 21 A 20 20 0 0 0 21 1 z M 21 4 A 17 17 0 0 1 38 21 A 17 17 0 0 1 21 38 A 17 17 0 0 1 4 21 A 17 17 0 0 1 21 4 z "
+ transform="translate(-3.0415638e-8,98.453992)"
+ id="path837" />
+ <rect
+ style="overflow:visible;opacity:1;vector-effect:none;fill:#df543d;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect867"
+ width="6"
+ height="19.999998"
+ x="-72.617485"
+ y="89.315964"
+ ry="0"
+ transform="rotate(-45)" />
+ <rect
+ style="overflow:visible;opacity:1;vector-effect:none;fill:#df543d;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect867-3"
+ width="5.9999952"
+ height="20"
+ x="-102.31596"
+ y="-79.617485"
+ ry="0"
+ transform="rotate(-135)" />
+ </g>
+</svg>
diff --git a/src/activities/piano_composition/resource/failed.svg b/src/activities/piano_composition/resource/failed.svg
new file mode 100644
index 000000000..771af1080
--- /dev/null
+++ b/src/activities/piano_composition/resource/failed.svg
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="20"
+ height="20"
+ id="svg4191"
+ version="1.1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="failed.svg">
+ <defs
+ id="defs4193" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="7.919596"
+ inkscape:cx="-3.2898115"
+ inkscape:cy="6.5593514"
+ inkscape:document-units="px"
+ inkscape:current-layer="g3"
+ showgrid="true"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0">
+ <inkscape:grid
+ type="xygrid"
+ id="grid827" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata4196">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ <dc:date>2018</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Timothée Giet</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Calque 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-289.43692,-378.10224)">
+ <circle
+ style="opacity:1;vector-effect:none;fill:#df543d;fill-opacity:1;stroke:none;stroke-width:9;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path829"
+ cx="299.43692"
+ cy="388.10223"
+ r="9" />
+ <g
+ style="overflow:visible"
+ id="g836"
+ transform="translate(242.36236,374.00865)">
+ <g
+ transform="translate(3.0415638e-8,-98.453992)"
+ id="g3">
+ <radialGradient
+ gradientTransform="matrix(-0.24216096,0,0,0.24216096,36.716755,100.51532)"
+ r="63.7393"
+ id="XMLID_2_"
+ gradientUnits="userSpaceOnUse"
+ cy="68.5327"
+ cx="68.590797">
+ <stop
+ style="stop-color:#D4E4F7"
+ offset="0"
+ id="stop8" />
+ <stop
+ style="stop-color:#7FB5F7"
+ offset="1"
+ id="stop10" />
+ </radialGradient>
+ <path
+ style="fill:#eef1f7;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
+ d="m 53.07456,106.54758 -2,2 10,10 2,-2 z"
+ id="path840"
+ inkscape:connector-curvature="0" />
+ <path
+ style="overflow:visible;fill:#eef1f7;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 53.07456,118.54758 -2,-2 10,-10 2,2 z"
+ id="path840-6"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+ </g>
+</svg>
diff --git a/src/activities/piano_composition/resource/genericNoteEighth.svg b/src/activities/piano_composition/resource/genericNoteEighth.svg
new file mode 100644
index 000000000..4cf77d436
--- /dev/null
+++ b/src/activities/piano_composition/resource/genericNoteEighth.svg
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg2986"
+ viewBox="0 0 744.09 1052.4"
+ version="1.1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="genericNoteEighth.svg">
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ id="namedview12"
+ showgrid="false"
+ inkscape:zoom="0.22424933"
+ inkscape:cx="-118.48042"
+ inkscape:cy="526.20001"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="layer1" />
+ <title
+ id="title3044">eighth note</title>
+ <defs
+ id="defs2988" />
+ <g
+ id="layer1">
+ <path
+ id="path3"
+ style="stroke-linejoin:round;fill-rule:evenodd;stroke:none;stroke-linecap:round;stroke-width:5.9241;fill:#000000;fill-opacity:1"
+ d="m418.39 231.34c14.32 21.136 21.682 46.728 40.135 64.982 21.135 27.835 48.146 50.891 69.089 79.058 15.157 19.681 31.771 40.599 36.074 65.357 11.587 31.757 6.556 67.409-5.8056 98.498-13.947 16.765-23.482-4.9319-19.589-18.365 0.59324-18.535 0.32293-37.021-6.7859-54.528-6.3047-26.255-17.834-51.101-37.136-70.366-16.772-14.701-35.813-47.095-61.382-35.941-16.885 10.637-9.5289 32.139-11.346 48.712-1.0035 101.95-1.0707 203.94-2.7005 305.87-1.2461 42.809-38.247 71.529-72.88 89.908-30.854 18.567-67.795 28.966-103.61 20.691-33.304-3.4173-67.756-27.73-68.454-63.704-2.2204-41.711 27.904-80.552 64.988-97.024 36.404-20.749 82.429-25.246 121.63-10.331 19.156 6.0549 24.483-11.721 26.874-28.819 2.2123-129.77 3.9829-259.54 4.4354-389.33 0.36593-12.973 21.496-16.139 26.461-4.6603z" />
+ </g>
+ <metadata
+ id="metadata9">
+ <rdf:RDF>
+ <cc:Work>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://openclipart.org/">
+ <dc:title>Openclipart</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:title>Eighth Note (Stem Facing Up)</dc:title>
+ <dc:date>2010-10-27T16:06:43</dc:date>
+ <dc:description>a single stem facing up eighth note</dc:description>
+ <dc:source>https://openclipart.org/detail/92869/eighth-note-(stem-facing-up)-by-jaschon</dc:source>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>jaschon</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>black and white</rdf:li>
+ <rdf:li>eighth</rdf:li>
+ <rdf:li>flag</rdf:li>
+ <rdf:li>music</rdf:li>
+ <rdf:li>music note</rdf:li>
+ <rdf:li>musical notation</rdf:li>
+ <rdf:li>quaver</rdf:li>
+ <rdf:li>sound</rdf:li>
+ <rdf:li>staff</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Edited by Timothee Giet for GCompris</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+</svg>
diff --git a/src/activities/piano_composition/resource/genericNoteHalf.svg b/src/activities/piano_composition/resource/genericNoteHalf.svg
new file mode 100644
index 000000000..ddf93e7bf
--- /dev/null
+++ b/src/activities/piano_composition/resource/genericNoteHalf.svg
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg2986"
+ viewBox="0 0 744.09 1052.4"
+ version="1.1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="genericNoteHalf.svg">
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ id="namedview12"
+ showgrid="false"
+ inkscape:zoom="0.22424933"
+ inkscape:cx="-118.48042"
+ inkscape:cy="526.20001"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="layer1" />
+ <title
+ id="title3044">half note</title>
+ <defs
+ id="defs2988" />
+ <g
+ id="layer1">
+ <path
+ id="path3"
+ style="stroke-linejoin:round;fill-rule:evenodd;stroke:#000000;stroke-linecap:round;stroke-width:5.9241;fill:#000000;fill-opacity:1"
+ d="m407.69 223.84c-7.2475 0.33178-15.544 4.8587-15.75 12.156-0.45246 129.79-2.2252 259.57-4.4375 389.34-2.3903 17.098-7.7188 34.867-26.875 28.812-39.21-14.91-85.23-10.4-121.63 10.35-37.084 16.471-67.22 55.289-65 97 0.69789 35.974 35.134 60.301 68.438 63.719 35.814 8.2749 72.771-2.12 103.62-20.688 34.633-18.379 71.629-47.097 72.875-89.906 2.4559-167.09 4.7446-319.48-0.5625-483.28-0.073-5.4712-5.0506-7.758-10.688-7.5zm-99.28 436.04c30.478-0.002 56.713 13.001 67.312 36.562 16.152 35.904-10.092 82.712-58.594 104.53-48.502 21.819-100.91 10.404-117.06-25.5-16.152-35.904 10.092-82.712 58.594-104.53 16.672-7.5002 33.785-11.062 49.75-11.062z" />
+ </g>
+ <metadata
+ id="metadata9">
+ <rdf:RDF>
+ <cc:Work>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://openclipart.org/">
+ <dc:title>Openclipart</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:title>Half Note (Stem Facing Up)</dc:title>
+ <dc:date>2010-10-28T16:56:55</dc:date>
+ <dc:description>A single half note with stem facing up.</dc:description>
+ <dc:source>https://openclipart.org/detail/92971/half-note-(stem-facing-up)-by-jaschon</dc:source>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>jaschon</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>black and white</rdf:li>
+ <rdf:li>half</rdf:li>
+ <rdf:li>half note</rdf:li>
+ <rdf:li>music</rdf:li>
+ <rdf:li>music note</rdf:li>
+ <rdf:li>musical notation</rdf:li>
+ <rdf:li>note</rdf:li>
+ <rdf:li>quaver</rdf:li>
+ <rdf:li>sound</rdf:li>
+ <rdf:li>staff</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Edited by Timothée Giet for GCompris</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+</svg>
diff --git a/src/activities/piano_composition/resource/genericNoteQuarter.svg b/src/activities/piano_composition/resource/genericNoteQuarter.svg
new file mode 100644
index 000000000..d23aea2fc
--- /dev/null
+++ b/src/activities/piano_composition/resource/genericNoteQuarter.svg
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg2986"
+ viewBox="0 0 744.09 1052.4"
+ version="1.1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="genericNoteQuarter.svg">
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ id="namedview12"
+ showgrid="false"
+ inkscape:zoom="0.22424933"
+ inkscape:cx="-118.48042"
+ inkscape:cy="526.20001"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="layer1" />
+ <title
+ id="title3044">quarter note</title>
+ <defs
+ id="defs2988" />
+ <g
+ id="layer1">
+ <path
+ id="path3"
+ style="stroke-linejoin:round;fill-rule:evenodd;stroke:none;stroke-linecap:round;stroke-width:5.9241;fill:#000000;fill-opacity:1"
+ d="m418.39 231.34c5.3071 163.8 3.0093 316.18 0.55337 483.27-1.2461 42.809-38.247 71.529-72.88 89.908-30.854 18.567-67.795 28.966-103.61 20.691-33.304-3.4173-67.756-27.73-68.454-63.704-2.2204-41.711 27.904-80.552 64.988-97.024 36.404-20.749 82.429-25.246 121.63-10.331 19.156 6.0549 24.483-11.721 26.874-28.819 2.2123-129.77 3.9829-259.54 4.4354-389.33 0.36593-12.973 26.294-17.166 26.461-4.6603z" />
+ </g>
+ <metadata
+ id="metadata9">
+ <rdf:RDF>
+ <cc:Work>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://openclipart.org/">
+ <dc:title>Openclipart</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:title>Quarter Note (Stem Facing Up)</dc:title>
+ <dc:date>2010-10-27T16:29:09</dc:date>
+ <dc:description>A single quarter note with stem facing up.</dc:description>
+ <dc:source>https://openclipart.org/detail/92875/quarter-note-(stem-facing-up)-by-jaschon</dc:source>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>jaschon</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>black and white</rdf:li>
+ <rdf:li>crotchet</rdf:li>
+ <rdf:li>music</rdf:li>
+ <rdf:li>music note</rdf:li>
+ <rdf:li>musical notation</rdf:li>
+ <rdf:li>note</rdf:li>
+ <rdf:li>quarter</rdf:li>
+ <rdf:li>quaver</rdf:li>
+ <rdf:li>sound</rdf:li>
+ <rdf:li>staff</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Edited by Timothée Giet for GCompris</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+</svg>
diff --git a/src/activities/piano_composition/resource/genericNoteWhole.svg b/src/activities/piano_composition/resource/genericNoteWhole.svg
new file mode 100644
index 000000000..a2276cffc
--- /dev/null
+++ b/src/activities/piano_composition/resource/genericNoteWhole.svg
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg2"
+ viewBox="0 0 744 1052"
+ version="1.1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="genericNoteWhole.svg">
+ <defs
+ id="defs9" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ id="namedview7"
+ showgrid="false"
+ inkscape:zoom="0.21751436"
+ inkscape:cx="-410.74465"
+ inkscape:cy="371.73958"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <g
+ id="layer1"
+ transform="matrix(0.40259701,0,0,0.46650811,152.80238,414.36682)"
+ style="fill:#000000;fill-opacity:1;stroke:none">
+ <path
+ id="path270"
+ style="fill:#000000;fill-opacity:1;stroke:none"
+ d="m 339.03,493.9 c 166.28,1.498 323.57,64.413 335.55,203.73 8.98,101.9 -125.84,194.73 -292.11,194.73 C 214.69,890.86 58.9,829.45 45.42,690.18 36.433,586.73 172.66,493.9 339.03,493.9 Z m 40.352,364.01 c 71.903,0 118.34,-68.954 110.85,-124.33 C 473.754,624.23 436.304,535.8 337.442,535.8 c -71.903,0 -113.85,70.405 -104.86,125.83 16.571,109.4 48.029,196.28 146.8,196.28 z"
+ inkscape:connector-curvature="0" />
+ </g>
+ <metadata
+ id="metadata5">
+ <rdf:RDF>
+ <cc:Work>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://openclipart.org/">
+ <dc:title>Openclipart</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:title>whole note</dc:title>
+ <dc:date>2011-05-27T21:51:50</dc:date>
+ <dc:description>There didn't seem to be a whole note on openclipart already. Here is a big one!</dc:description>
+ <dc:source>https://openclipart.org/detail/140893/whole-note-by-10binary</dc:source>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>10binary</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>music</rdf:li>
+ <rdf:li>notation</rdf:li>
+ <rdf:li>note</rdf:li>
+ <rdf:li>whole</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Edited by Timothée Giet for GCompris</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+</svg>
diff --git a/src/activities/piano_composition/resource/halfRest.svg b/src/activities/piano_composition/resource/halfRest.svg
new file mode 100644
index 000000000..dcc65e091
--- /dev/null
+++ b/src/activities/piano_composition/resource/halfRest.svg
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="774"
+ height="1052"
+ viewBox="0 0 774 1052"
+ id="svg2"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="halfRest.svg">
+ <metadata
+ id="metadata10">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ <dc:date>2018</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Timothée Giet</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs8" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ id="namedview6"
+ showgrid="false"
+ inkscape:zoom="0.34766084"
+ inkscape:cx="425.32236"
+ inkscape:cy="577.49046"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <path
+ style="fill:#000000;stroke-width:0.56839144"
+ d="m 484.79984,575.52382 c 0.20677,0.21207 0.37594,17.82721 0.37594,39.14477 v 38.75919 h 27.50088 27.50087 v 10.36137 10.36137 H 399.30569 258.43385 v -10.36137 -10.36137 h 26.93571 26.93572 l 0.14423,-38.99904 0.14424,-38.99903 85.91507,-0.14574 c 47.25329,-0.0802 86.08425,0.0277 86.29102,0.23985 z"
+ id="path812-3"
+ inkscape:connector-curvature="0" />
+</svg>
diff --git a/src/activities/piano_composition/resource/lyrics.svg b/src/activities/piano_composition/resource/lyrics.svg
new file mode 100644
index 000000000..71b0a2237
--- /dev/null
+++ b/src/activities/piano_composition/resource/lyrics.svg
@@ -0,0 +1,179 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 12.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ height="42"
+ id="Layer_1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="lyrics.svg"
+ sodipodi:version="0.32"
+ space="preserve"
+ style="overflow:visible"
+ version="1.1"
+ viewBox="0 0 42.000002 42"
+ width="42"
+ inkscape:export-filename="D:\GR8DAN\My Pictures\Graphics\Buttons\large_round_blue_play_button_pressed.png"
+ inkscape:export-xdpi="39.369999"
+ inkscape:export-ydpi="39.369999">
+ <metadata
+ id="metadata3001">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:title></dc:title>
+ <dc:description />
+ <dc:subject>
+ <rdf:Bag />
+ </dc:subject>
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://www.openclipart.org/">
+ <dc:title />
+ </cc:Agent>
+ </dc:publisher>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Timothée Giet</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:rights>
+ <cc:Agent>
+ <dc:title />
+ </cc:Agent>
+ </dc:rights>
+ <dc:date>2018</dc:date>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
+ <dc:language />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs23" />
+ <sodipodi:namedview
+ bordercolor="#666666"
+ borderopacity="1.0"
+ id="base"
+ inkscape:current-layer="g3"
+ inkscape:cx="25.028188"
+ inkscape:cy="16.876385"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:window-height="1051"
+ inkscape:window-width="1884"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:zoom="14.852584"
+ pagecolor="#ffffff"
+ showgrid="true"
+ inkscape:window-maximized="1"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0">
+ <inkscape:grid
+ type="xygrid"
+ id="grid855" />
+ </sodipodi:namedview>
+ <g
+ id="g3"
+ transform="translate(3.0415638e-8,-98.453992)">
+ <radialGradient
+ cx="68.590797"
+ cy="68.5327"
+ gradientUnits="userSpaceOnUse"
+ id="XMLID_2_"
+ r="63.7393"
+ gradientTransform="matrix(-0.24216096,0,0,0.24216096,36.716755,100.51532)">
+ <stop
+ id="stop8"
+ offset="0"
+ style="stop-color:#D4E4F7" />
+ <stop
+ id="stop10"
+ offset="1"
+ style="stop-color:#7FB5F7" />
+ </radialGradient>
+ <circle
+ style="opacity:1;vector-effect:none;fill:#eef1f7;fill-opacity:1;stroke:none;stroke-width:9;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path826"
+ cx="21"
+ cy="119.45399"
+ r="18" />
+ <path
+ style="opacity:1;vector-effect:none;fill:#5471af;fill-opacity:1;stroke:none;stroke-width:11.42506504;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ d="M 21 1 A 20 20 0 0 0 1 21 A 20 20 0 0 0 21 41 A 20 20 0 0 0 41 21 A 20 20 0 0 0 21 1 z M 21 4 A 17 17 0 0 1 38 21 A 17 17 0 0 1 21 38 A 17 17 0 0 1 4 21 A 17 17 0 0 1 21 4 z "
+ transform="translate(-3.0415638e-8,98.453992)"
+ id="path837" />
+ <g
+ id="layer1"
+ transform="matrix(0.02957639,0,0,0.02957639,17.087771,104.61156)"
+ style="fill:#5471af;fill-opacity:1">
+ <path
+ d="m 418.39,231.34 c 14.32,21.136 21.682,46.728 40.135,64.982 21.135,27.835 48.146,50.891 69.089,79.058 15.157,19.681 31.771,40.599 36.074,65.357 11.587,31.757 6.556,67.409 -5.8056,98.498 -13.947,16.765 -23.482,-4.9319 -19.589,-18.365 0.59324,-18.535 0.32293,-37.021 -6.7859,-54.528 -6.3047,-26.255 -17.834,-51.101 -37.136,-70.366 -16.772,-14.701 -35.813,-47.095 -61.382,-35.941 -16.885,10.637 -9.5289,32.139 -11.346,48.712 -1.0035,101.95 -1.0707,203.94 -2.7005,305.87 -1.2461,42.809 -38.247,71.529 -72.88,89.908 -30.854,18.567 -67.795,28.966 -103.61,20.691 -33.304,-3.4173 -67.756,-27.73 -68.454,-63.704 -2.2204,-41.711 27.904,-80.552 64.988,-97.024 36.404,-20.749 82.429,-25.246 121.63,-10.331 19.156,6.0549 24.483,-11.721 26.874,-28.819 2.2123,-129.77 3.9829,-259.54 4.4354,-389.33 0.36593,-12.973 21.496,-16.139 26.461,-4.6603 z"
+ style="fill:#5471af;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5.92409992;stroke-linecap:round;stroke-linejoin:round"
+ id="path3"
+ inkscape:connector-curvature="0" />
+ </g>
+ <rect
+ style="opacity:1;vector-effect:none;fill:#5471af;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect852"
+ width="10"
+ height="2"
+ x="10"
+ y="126.45399" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#5471af;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect854"
+ width="10"
+ height="2"
+ x="10"
+ y="122.45399" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#5471af;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect856"
+ width="15"
+ height="2"
+ x="10"
+ y="118.45399" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#5471af;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect858"
+ width="15"
+ height="2"
+ x="10"
+ y="114.45399" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#5471af;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect860"
+ width="15"
+ height="2"
+ x="10"
+ y="110.45399" />
+ </g>
+</svg>
diff --git a/src/activities/piano_composition/resource/open.svg b/src/activities/piano_composition/resource/open.svg
new file mode 100644
index 000000000..41a019d1e
--- /dev/null
+++ b/src/activities/piano_composition/resource/open.svg
@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 12.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ height="42"
+ id="Layer_1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="open.svg"
+ sodipodi:version="0.32"
+ space="preserve"
+ style="overflow:visible"
+ version="1.1"
+ viewBox="0 0 42.000002 42"
+ width="42"
+ inkscape:export-filename="D:\GR8DAN\My Pictures\Graphics\Buttons\large_round_blue_play_button_pressed.png"
+ inkscape:export-xdpi="39.369999"
+ inkscape:export-ydpi="39.369999">
+ <metadata
+ id="metadata3001">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:title></dc:title>
+ <dc:description />
+ <dc:subject>
+ <rdf:Bag />
+ </dc:subject>
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://www.openclipart.org/">
+ <dc:title />
+ </cc:Agent>
+ </dc:publisher>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Timothée Giet</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:rights>
+ <cc:Agent>
+ <dc:title />
+ </cc:Agent>
+ </dc:rights>
+ <dc:date>2018</dc:date>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
+ <dc:language />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs23" />
+ <sodipodi:namedview
+ bordercolor="#666666"
+ borderopacity="1.0"
+ id="base"
+ inkscape:current-layer="g3"
+ inkscape:cx="18.152229"
+ inkscape:cy="20.468712"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:window-height="1051"
+ inkscape:window-width="1884"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:zoom="10.502363"
+ pagecolor="#ffffff"
+ showgrid="true"
+ inkscape:window-maximized="1"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0">
+ <inkscape:grid
+ type="xygrid"
+ id="grid855" />
+ </sodipodi:namedview>
+ <g
+ id="g3"
+ transform="translate(3.0415638e-8,-98.453992)">
+ <radialGradient
+ cx="68.590797"
+ cy="68.5327"
+ gradientUnits="userSpaceOnUse"
+ id="XMLID_2_"
+ r="63.7393"
+ gradientTransform="matrix(-0.24216096,0,0,0.24216096,36.716755,100.51532)">
+ <stop
+ id="stop8"
+ offset="0"
+ style="stop-color:#D4E4F7" />
+ <stop
+ id="stop10"
+ offset="1"
+ style="stop-color:#7FB5F7" />
+ </radialGradient>
+ <path
+ style="opacity:1;vector-effect:none;fill:#5471af;fill-opacity:1;stroke:none;stroke-width:11.42506504;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ d="M 21,1 C 9.954305,1 1,9.954305 1,21 1,32.045695 9.954305,41 21,41 32.045695,41 41,32.045695 41,21 41,9.954305 32.045695,1 21,1 Z"
+ transform="translate(-3.0415638e-8,98.453992)"
+ id="path837"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="sssss" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 8,112.45399 v 5 h 2 v -5 z m 24,0 v 3 h 2 v -3 z"
+ id="path4360"
+ style="display:inline;fill:#ffffff;fill-opacity:1;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 11,108.45399 v 9 h 12 v -2 h 12 v -7 z"
+ id="rect4354"
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 5,118.45399 c 1.06451,0 19,0 19,0 v -2 h 13 l -3,14 H 8 Z"
+ id="path4356-7"
+ style="display:inline;fill:#ffffff;fill-opacity:1;stroke:none" />
+ </g>
+</svg>
diff --git a/src/activities/piano_composition/resource/passed.svg b/src/activities/piano_composition/resource/passed.svg
new file mode 100644
index 000000000..57378cdb9
--- /dev/null
+++ b/src/activities/piano_composition/resource/passed.svg
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="20"
+ height="20"
+ id="svg4191"
+ version="1.1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="passed.svg">
+ <defs
+ id="defs4193" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="15.839192"
+ inkscape:cx="10.252546"
+ inkscape:cy="6.5593514"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0">
+ <inkscape:grid
+ type="xygrid"
+ id="grid827" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata4196">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ <dc:date>2018</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Timothée Giet</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Calque 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-289.43692,-378.10224)">
+ <circle
+ style="opacity:1;vector-effect:none;fill:#5cc067;fill-opacity:1;stroke:none;stroke-width:9;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path829"
+ cx="299.43692"
+ cy="388.10223"
+ r="9" />
+ <path
+ style="fill:#eef1f7;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 298.43692,395.10224 7,-12 h -3 l -4,7 -2,-5 h -3 z"
+ id="path831"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc" />
+ </g>
+</svg>
diff --git a/src/activities/piano_composition/resource/piano.svg b/src/activities/piano_composition/resource/piano.svg
new file mode 100644
index 000000000..e2a0bc430
--- /dev/null
+++ b/src/activities/piano_composition/resource/piano.svg
@@ -0,0 +1,240 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 12.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ height="42"
+ id="Layer_1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="piano.svg"
+ sodipodi:version="0.32"
+ space="preserve"
+ style="overflow:visible"
+ version="1.1"
+ viewBox="0 0 42.000002 42"
+ width="42"
+ inkscape:export-filename="D:\GR8DAN\My Pictures\Graphics\Buttons\large_round_blue_play_button_pressed.png"
+ inkscape:export-xdpi="39.369999"
+ inkscape:export-ydpi="39.369999">
+ <metadata
+ id="metadata3001">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:title></dc:title>
+ <dc:description />
+ <dc:subject>
+ <rdf:Bag />
+ </dc:subject>
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://www.openclipart.org/">
+ <dc:title />
+ </cc:Agent>
+ </dc:publisher>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Timothée Giet</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:rights>
+ <cc:Agent>
+ <dc:title />
+ </cc:Agent>
+ </dc:rights>
+ <dc:date>2018</dc:date>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
+ <dc:language />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs23" />
+ <sodipodi:namedview
+ bordercolor="#666666"
+ borderopacity="1.0"
+ id="base"
+ inkscape:current-layer="g3"
+ inkscape:cx="7.8931225"
+ inkscape:cy="24.955787"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-height="1051"
+ inkscape:window-width="1884"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:zoom="2.6255907"
+ pagecolor="#d1d1d1"
+ showgrid="false"
+ inkscape:window-maximized="1"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0">
+ <inkscape:grid
+ type="xygrid"
+ id="grid855" />
+ </sodipodi:namedview>
+ <g
+ id="g3"
+ transform="translate(3.0415638e-8,-98.453992)">
+ <radialGradient
+ cx="68.590797"
+ cy="68.5327"
+ gradientUnits="userSpaceOnUse"
+ id="XMLID_2_"
+ r="63.7393"
+ gradientTransform="matrix(-0.24216096,0,0,0.24216096,36.716755,100.51532)">
+ <stop
+ id="stop8"
+ offset="0"
+ style="stop-color:#D4E4F7" />
+ <stop
+ id="stop10"
+ offset="1"
+ style="stop-color:#7FB5F7" />
+ </radialGradient>
+ <circle
+ style="opacity:1;vector-effect:none;fill:#eef1f7;fill-opacity:1;stroke:none;stroke-width:9;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path826"
+ cx="21"
+ cy="119.45399"
+ r="18" />
+ <path
+ style="opacity:1;vector-effect:none;fill:#5471af;fill-opacity:1;stroke:none;stroke-width:11.42506504;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ d="M 21 1 A 20 20 0 0 0 1 21 A 20 20 0 0 0 21 41 A 20 20 0 0 0 41 21 A 20 20 0 0 0 21 1 z M 21 4 A 17 17 0 0 1 38 21 A 17 17 0 0 1 21 38 A 17 17 0 0 1 4 21 A 17 17 0 0 1 21 4 z "
+ transform="translate(-3.0415638e-8,98.453992)"
+ id="path837" />
+ <g
+ id="g5"
+ transform="matrix(0.07786013,0,0,0.07891947,4.7739485,99.874072)"
+ style="fill:none;fill-opacity:1;stroke:#5471af;stroke-opacity:1;stroke-width:12.75705294;stroke-miterlimit:4;stroke-dasharray:none">
+ <rect
+ x="288.70001"
+ y="172.7"
+ style="fill:none;fill-opacity:1;stroke:#5471af;stroke-opacity:1;stroke-width:12.75705294;stroke-miterlimit:4;stroke-dasharray:none"
+ width="38.099998"
+ height="150.8"
+ id="rect7" />
+ <rect
+ x="249"
+ y="172.7"
+ style="fill:none;fill-opacity:1;stroke:#5471af;stroke-opacity:1;stroke-width:12.75705294;stroke-miterlimit:4;stroke-dasharray:none"
+ width="38.099998"
+ height="150.8"
+ id="rect9" />
+ <rect
+ x="209.3"
+ y="172.7"
+ style="fill:none;fill-opacity:1;stroke:#5471af;stroke-opacity:1;stroke-width:12.75705294;stroke-miterlimit:4;stroke-dasharray:none"
+ width="38.099998"
+ height="150.8"
+ id="rect11" />
+ <rect
+ x="169.60001"
+ y="172.7"
+ style="fill:none;fill-opacity:1;stroke:#5471af;stroke-opacity:1;stroke-width:12.75705294;stroke-miterlimit:4;stroke-dasharray:none"
+ width="38.099998"
+ height="150.8"
+ id="rect13" />
+ </g>
+ <rect
+ x="23.320234"
+ y="113.51136"
+ style="fill:#5471af;fill-opacity:1;stroke:#5471af;stroke-opacity:1"
+ width="1.5649889"
+ height="7.8919468"
+ id="rect15" />
+ <rect
+ x="20.213614"
+ y="113.51136"
+ style="fill:#5471af;fill-opacity:1;stroke:#5471af;stroke-opacity:1"
+ width="1.5649889"
+ height="7.8919468"
+ id="rect23" />
+ <rect
+ x="26.419067"
+ y="113.51136"
+ style="fill:#5471af;fill-opacity:1;stroke:#5471af;stroke-opacity:1"
+ width="1.5649889"
+ height="7.8919468"
+ id="rect31" />
+ <g
+ id="g39"
+ transform="matrix(0.07786013,0,0,0.07891947,4.7739485,99.874072)"
+ style="fill:none;fill-opacity:1;stroke:#5471af;stroke-opacity:1;stroke-width:12.75705294;stroke-miterlimit:4;stroke-dasharray:none">
+ <rect
+ x="129.89999"
+ y="172.7"
+ style="fill:none;fill-opacity:1;stroke:#5471af;stroke-opacity:1;stroke-width:12.75705294;stroke-miterlimit:4;stroke-dasharray:none"
+ width="38.099998"
+ height="150.8"
+ id="rect41" />
+ <rect
+ x="90.199997"
+ y="172.7"
+ style="fill:none;fill-opacity:1;stroke:#5471af;stroke-opacity:1;stroke-width:12.75705294;stroke-miterlimit:4;stroke-dasharray:none"
+ width="38.099998"
+ height="150.8"
+ id="rect43" />
+ <rect
+ x="50.5"
+ y="172.7"
+ style="fill:none;fill-opacity:1;stroke:#5471af;stroke-opacity:1;stroke-width:12.75705294;stroke-miterlimit:4;stroke-dasharray:none"
+ width="38.099998"
+ height="150.8"
+ id="rect45" />
+ </g>
+ <rect
+ x="10.956045"
+ y="113.51136"
+ style="fill:#5471af;fill-opacity:1;stroke:#5471af;stroke-opacity:1"
+ width="1.5649889"
+ height="7.8919468"
+ id="rect47" />
+ <rect
+ x="14.054878"
+ y="113.51136"
+ style="fill:#5471af;fill-opacity:1;stroke:#5471af;stroke-opacity:1"
+ width="1.5649889"
+ height="7.8919468"
+ id="rect55" />
+ <g
+ id="g63"
+ transform="matrix(0.07786013,0,0,0.07891947,0.7884533,101.29414)"
+ style="fill:none;fill-opacity:1;stroke:#5471af;stroke-opacity:1;stroke-width:12.75705294;stroke-miterlimit:4;stroke-dasharray:none">
+ <rect
+ x="379.38791"
+ y="154.7061"
+ style="fill:none;fill-opacity:1;stroke:#5471af;stroke-opacity:1;stroke-width:12.75705294;stroke-miterlimit:4;stroke-dasharray:none"
+ width="38.099998"
+ height="150.8"
+ id="rect69" />
+ </g>
+ </g>
+</svg>
diff --git a/src/activities/piano_composition/resource/play.svg b/src/activities/piano_composition/resource/play.svg
new file mode 100644
index 000000000..f8154c168
--- /dev/null
+++ b/src/activities/piano_composition/resource/play.svg
@@ -0,0 +1,140 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 12.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ height="42"
+ id="Layer_1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="play.svg"
+ sodipodi:version="0.32"
+ space="preserve"
+ style="overflow:visible"
+ version="1.1"
+ viewBox="0 0 42.000002 42"
+ width="42"
+ inkscape:export-filename="D:\GR8DAN\My Pictures\Graphics\Buttons\large_round_blue_play_button_pressed.png"
+ inkscape:export-xdpi="39.369999"
+ inkscape:export-ydpi="39.369999">
+ <metadata
+ id="metadata3001">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:title />
+ <dc:description />
+ <dc:subject>
+ <rdf:Bag />
+ </dc:subject>
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://www.openclipart.org/">
+ <dc:title />
+ </cc:Agent>
+ </dc:publisher>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Timothée Giet</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:rights>
+ <cc:Agent>
+ <dc:title />
+ </cc:Agent>
+ </dc:rights>
+ <dc:date>2018</dc:date>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
+ <dc:language />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs23" />
+ <sodipodi:namedview
+ bordercolor="#666666"
+ borderopacity="1.0"
+ id="base"
+ inkscape:current-layer="g3"
+ inkscape:cx="4.5838539"
+ inkscape:cy="18.088295"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:window-height="1051"
+ inkscape:window-width="1884"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:zoom="10.502363"
+ pagecolor="#ffffff"
+ showgrid="true"
+ inkscape:window-maximized="1"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0">
+ <inkscape:grid
+ type="xygrid"
+ id="grid855" />
+ </sodipodi:namedview>
+ <g
+ id="g3"
+ transform="translate(3.0415638e-8,-98.453992)">
+ <radialGradient
+ cx="68.590797"
+ cy="68.5327"
+ gradientUnits="userSpaceOnUse"
+ id="XMLID_2_"
+ r="63.7393"
+ gradientTransform="matrix(-0.24216096,0,0,0.24216096,36.716755,100.51532)">
+ <stop
+ id="stop8"
+ offset="0"
+ style="stop-color:#D4E4F7" />
+ <stop
+ id="stop10"
+ offset="1"
+ style="stop-color:#7FB5F7" />
+ </radialGradient>
+ <circle
+ style="opacity:1;vector-effect:none;fill:#eef1f7;fill-opacity:1;stroke:none;stroke-width:9;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path826"
+ cx="21"
+ cy="119.45399"
+ r="18" />
+ <path
+ style="opacity:1;vector-effect:none;fill:#5471af;fill-opacity:1;stroke:none;stroke-width:11.42506504;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ d="M 21 1 A 20 20 0 0 0 1 21 A 20 20 0 0 0 21 41 A 20 20 0 0 0 41 21 A 20 20 0 0 0 21 1 z M 21 4 A 17 17 0 0 1 38 21 A 17 17 0 0 1 21 38 A 17 17 0 0 1 4 21 A 17 17 0 0 1 21 4 z "
+ transform="translate(-3.0415638e-8,98.453992)"
+ id="path837" />
+ <path
+ style="fill:#5471af;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 17,110.45399 v 18 l 12,-9 z"
+ id="path857"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc" />
+ </g>
+</svg>
diff --git a/src/activities/piano_composition/resource/quarterRest.svg b/src/activities/piano_composition/resource/quarterRest.svg
new file mode 100644
index 000000000..350926d30
--- /dev/null
+++ b/src/activities/piano_composition/resource/quarterRest.svg
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="744"
+ height="1052"
+ viewBox="0 0 744 1052"
+ id="svg2"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="quarterRest.svg">
+ <metadata
+ id="metadata10">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ <dc:date>2018</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Timothée Giet</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs8" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ id="namedview6"
+ showgrid="false"
+ inkscape:zoom="0.98333333"
+ inkscape:cx="436.77966"
+ inkscape:cy="665.08474"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <path
+ style="fill:#000000;stroke-width:0.13448758"
+ d="m 333.7686,734.3469 c -25.69298,-25.81812 -43.43836,-58.86702 -59.70312,-91.31819 -13.59746,-30.8995 -29.37634,-64.55433 -23.88378,-99.14787 5.03092,-27.83029 39.0092,-24.58201 59.95674,-21.11428 27.64745,4.50032 54.85193,12.33997 80.48245,23.6508 -40.91758,-45.60495 -80.03796,-92.85423 -119.6464,-139.59686 -16.25819,-18.87392 -1.35403,-44.20433 14.3869,-57.81053 27.3097,-29.79103 69.31119,-48.55318 82.26281,-89.56777 13.97793,-36.28996 -0.27527,-77.14236 -27.55677,-103.01613 -13.81702,-11.19521 -38.61279,-46.24034 -4.95399,-45.75598 23.96597,22.52895 43.88242,49.68841 66.04957,74.20744 26.32425,31.33528 53.34602,62.2571 78.55306,94.41511 11.96745,23.02644 -9.26627,44.95161 -24.96023,59.49006 -26.68396,25.81364 -63.78554,44.74819 -75.2554,82.60844 -13.27286,34.03859 -2.2259,73.34439 23.16398,98.67463 22.46654,27.70666 47.51947,53.44068 68.71035,82.09086 3.40601,28.83546 -28.47699,15.07999 -38.72637,1.01207 -26.93401,-15.14756 -60.05751,-24.85143 -90.6407,-16.40864 -25.2707,11.16309 -26.60556,44.19993 -25.08311,68.01865 2.0628,25.81434 9.82709,51.53381 24.87033,72.70339 1.23116,4.76106 -3.84291,7.87499 -8.02632,6.8648 z"
+ id="path812"
+ inkscape:connector-curvature="0" />
+</svg>
diff --git a/src/activities/piano_composition/resource/save.svg b/src/activities/piano_composition/resource/save.svg
new file mode 100644
index 000000000..f4fc608b7
--- /dev/null
+++ b/src/activities/piano_composition/resource/save.svg
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 12.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ height="42"
+ id="Layer_1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="save.svg"
+ sodipodi:version="0.32"
+ space="preserve"
+ style="overflow:visible"
+ version="1.1"
+ viewBox="0 0 42.000002 42"
+ width="42"
+ inkscape:export-filename="D:\GR8DAN\My Pictures\Graphics\Buttons\large_round_blue_play_button_pressed.png"
+ inkscape:export-xdpi="39.369999"
+ inkscape:export-ydpi="39.369999">
+ <metadata
+ id="metadata3001">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:title></dc:title>
+ <dc:description />
+ <dc:subject>
+ <rdf:Bag />
+ </dc:subject>
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://www.openclipart.org/">
+ <dc:title />
+ </cc:Agent>
+ </dc:publisher>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Timothée Giet</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:rights>
+ <cc:Agent>
+ <dc:title />
+ </cc:Agent>
+ </dc:rights>
+ <dc:date>2018</dc:date>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
+ <dc:language />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs23" />
+ <sodipodi:namedview
+ bordercolor="#666666"
+ borderopacity="1.0"
+ id="base"
+ inkscape:current-layer="g3"
+ inkscape:cx="18.152229"
+ inkscape:cy="20.468712"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:window-height="1051"
+ inkscape:window-width="1884"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:zoom="10.502363"
+ pagecolor="#ffffff"
+ showgrid="true"
+ inkscape:window-maximized="1"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0">
+ <inkscape:grid
+ type="xygrid"
+ id="grid855" />
+ </sodipodi:namedview>
+ <g
+ id="g3"
+ transform="translate(3.0415638e-8,-98.453992)">
+ <radialGradient
+ cx="68.590797"
+ cy="68.5327"
+ gradientUnits="userSpaceOnUse"
+ id="XMLID_2_"
+ r="63.7393"
+ gradientTransform="matrix(-0.24216096,0,0,0.24216096,36.716755,100.51532)">
+ <stop
+ id="stop8"
+ offset="0"
+ style="stop-color:#D4E4F7" />
+ <stop
+ id="stop10"
+ offset="1"
+ style="stop-color:#7FB5F7" />
+ </radialGradient>
+ <path
+ style="opacity:1;vector-effect:none;fill:#5471af;fill-opacity:1;stroke:none;stroke-width:11.42506504;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ d="M 21,1 C 9.954305,1 1,9.954305 1,21 1,32.045695 9.954305,41 21,41 32.045695,41 41,32.045695 41,21 41,9.954305 32.045695,1 21,1 Z"
+ transform="translate(-3.0415638e-8,98.453992)"
+ id="path837"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="sssss" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 9.0029559,107.45695 v 24 h 4.0000001 v -6 h 12.9375 l 7.0625,-7.09375 v -10.90625 z m 5.0000001,4 h 14 c 0.554,0 1,0.446 1,1 v 6 c 0,0.554 -0.446,1 -1,1 h -14 c -0.554,0 -1,-0.446 -1,-1 v -6 c 0,-0.554 0.446,-1 1,-1 z m 19,17.09375 -2.9375,2.90625 h 2.9375 z"
+ id="rect4434-6"
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;enable-background:accumulate" />
+ <rect
+ width="3"
+ height="5"
+ x="14.002956"
+ y="126.45695"
+ id="rect4439-9"
+ style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3;marker:none;enable-background:accumulate" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 32.699696,119.98897 c 0,0 -0.75425,0.75425 1.13137,2.63987 1.88562,1.88561 2.63987,1.13137 2.63987,1.13137 l -9.42809,9.42808 c 0,0 -0.75425,0.75425 -2.63987,-1.13137 -1.88561,-1.88561 -1.13137,-2.63986 -1.13137,-2.63986 z"
+ id="path3921"
+ style="display:inline;fill:#ffffff;fill-opacity:1;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 33.076816,119.61185 c 0,0 -0.75424,0.75424 1.13137,2.63986 1.88562,1.88562 2.63987,1.13137 2.63987,1.13137 0,0 0.75425,-0.75424 -1.13137,-2.63986 -1.88562,-1.88562 -2.63987,-1.13137 -2.63987,-1.13137 z"
+ id="path3930"
+ style="display:inline;fill:#ffffff;fill-opacity:1;stroke:none" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 22.894486,129.79418 c 0,0 -0.75425,0.75425 1.13137,2.63987 1.88562,1.88561 2.63986,1.13137 2.63986,1.13137 -0.75424,0.75424 -5.65685,1.88561 -5.65685,1.88561 0,0 1.13137,-4.9026 1.88562,-5.65685 z"
+ id="path3932"
+ style="display:inline;fill:#ffffff;fill-opacity:1;stroke:none" />
+ </g>
+</svg>
diff --git a/src/activities/piano_composition/resource/trebbleClefButton.svg b/src/activities/piano_composition/resource/trebbleClefButton.svg
new file mode 100644
index 000000000..326d14a36
--- /dev/null
+++ b/src/activities/piano_composition/resource/trebbleClefButton.svg
@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 12.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 51448) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ height="42"
+ id="Layer_1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="trebbleClefButton.svg"
+ sodipodi:version="0.32"
+ space="preserve"
+ style="overflow:visible"
+ version="1.1"
+ viewBox="0 0 42.000002 42"
+ width="42"
+ inkscape:export-filename="D:\GR8DAN\My Pictures\Graphics\Buttons\large_round_blue_play_button_pressed.png"
+ inkscape:export-xdpi="39.369999"
+ inkscape:export-ydpi="39.369999">
+ <metadata
+ id="metadata3001">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:title></dc:title>
+ <dc:description />
+ <dc:subject>
+ <rdf:Bag />
+ </dc:subject>
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://www.openclipart.org/">
+ <dc:title />
+ </cc:Agent>
+ </dc:publisher>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Timothée Giet</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:rights>
+ <cc:Agent>
+ <dc:title />
+ </cc:Agent>
+ </dc:rights>
+ <dc:date>2018</dc:date>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
+ <dc:language />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs23" />
+ <sodipodi:namedview
+ bordercolor="#666666"
+ borderopacity="1.0"
+ id="base"
+ inkscape:current-layer="g3"
+ inkscape:cx="39.956846"
+ inkscape:cy="18.564378"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:window-height="1051"
+ inkscape:window-width="1884"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:zoom="10.502363"
+ pagecolor="#ffffff"
+ showgrid="true"
+ inkscape:window-maximized="1"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0">
+ <inkscape:grid
+ type="xygrid"
+ id="grid855" />
+ </sodipodi:namedview>
+ <g
+ id="g3"
+ transform="translate(3.0415638e-8,-98.453992)">
+ <radialGradient
+ cx="68.590797"
+ cy="68.5327"
+ gradientUnits="userSpaceOnUse"
+ id="XMLID_2_"
+ r="63.7393"
+ gradientTransform="matrix(-0.24216096,0,0,0.24216096,36.716755,100.51532)">
+ <stop
+ id="stop8"
+ offset="0"
+ style="stop-color:#D4E4F7" />
+ <stop
+ id="stop10"
+ offset="1"
+ style="stop-color:#7FB5F7" />
+ </radialGradient>
+ <circle
+ style="opacity:1;vector-effect:none;fill:#eef1f7;fill-opacity:1;stroke:none;stroke-width:9;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path826"
+ cx="21"
+ cy="119.45399"
+ r="18" />
+ <path
+ style="opacity:1;vector-effect:none;fill:#5471af;fill-opacity:1;stroke:none;stroke-width:11.42506504;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ d="M 21 1 A 20 20 0 0 0 1 21 A 20 20 0 0 0 21 41 A 20 20 0 0 0 41 21 A 20 20 0 0 0 21 1 z M 21 4 A 17 17 0 0 1 38 21 A 17 17 0 0 1 21 38 A 17 17 0 0 1 4 21 A 17 17 0 0 1 21 4 z "
+ transform="translate(-3.0415638e-8,98.453992)"
+ id="path837" />
+ <path
+ style="fill:#37496f;fill-opacity:1;stroke:none;stroke-width:0.18228871"
+ d="m 22.005859,106.36024 -0.0098,0.0469 c -0.253011,0.0242 -0.502273,0.1374 -0.732422,0.37109 -0.257081,0.26103 -0.497807,0.62653 -0.705078,1.05859 -0.414543,0.86412 -0.697316,1.99187 -0.677735,3.0625 0.009,0.65135 0.211917,1.94092 0.501953,3.54883 -1.853324,1.915 -4.020391,3.89984 -4.021484,6.53125 -0.01512,1.20917 0.344365,2.58083 1.150391,3.65235 0.806026,1.07151 2.06391,1.8394 3.816406,1.82422 0.499729,-0.002 0.943714,-0.0715 1.351563,-0.17188 0.303049,1.67247 0.512806,3.02757 0.511718,3.62305 0.0054,1.20332 -0.770628,1.84514 -1.572265,2.03125 -0.400819,0.0931 -0.807382,0.067 -1.113282,-0.0625 -0.284797,-0.12057 -0.453474,-0.33948 -0.507812,-0.62696 0.666001,-0.092 1.199219,-0.60856 1.199219,-1.28515 0,-0.74119 -0.615192,-1.34375 -1.373047,-1.34375 -0.416987,0 -0.790435,0.18219 -1.042969,0.46875 7.39e-4,-0.001 -0.005,0.006 -0.01367,0.0156 -0.06167,0.0642 -0.110539,0.13732 -0.15625,0.21485 -0.155974,0.26458 -0.250708,0.63451 -0.255859,1.15039 v 0.002 c 0,0.55906 0.350205,1.05824 0.859375,1.42383 0.50917,0.36559 1.181717,0.60437 1.857422,0.64648 0.675705,0.0421 1.357426,-0.11464 1.873046,-0.55273 0.515255,-0.43777 0.854986,-1.15449 0.855469,-2.19922 v -0.002 c 0.0083,-0.57048 -0.231807,-1.95032 -0.568359,-3.67383 1.858146,-0.71407 2.574993,-2.4594 2.375,-4.03906 -0.202826,-1.60203 -1.340283,-3.04514 -3.117188,-3.0586 -0.241727,0.002 -0.473854,0.0376 -0.701172,0.0879 -0.187692,-0.90407 -0.370177,-1.78267 -0.529296,-2.59179 1.30582,-1.2934 2.45135,-2.98621 2.425781,-6.05469 0.0018,-1.11336 -0.180171,-2.11618 -0.466797,-2.85156 -0.143409,-0.36794 -0.312688,-0.66906 -0.501953,-0.88477 -0.189266,-0.2157 -0.40311,-0.34989 -0.632813,-0.35742 h -0.002 z m 0.316407,2.32227 c 0.19372,-0.0187 0.356571,0.0534 0.486328,0.24414 0.129757,0.19073 0.216797,0.50553 0.216797,0.95117 v 0.002 c 0.03386,1.46834 -0.980211,2.77765 -2.21875,4.09961 -0.100185,-0.63041 -0.18359,-1.19795 -0.191407,-1.50781 v -0.004 c 0.01903,-1.21277 0.278774,-2.14975 0.619141,-2.78711 0.340822,-0.6382 0.765229,-0.96688 1.087891,-0.99804 z m -1.47461,8.23437 c 0.147697,0.75806 0.305347,1.54706 0.464844,2.34571 -1.132426,0.4359 -1.978045,1.42078 -2.134766,2.50976 -0.159369,1.1074 0.411166,2.29494 2.03125,3.02149 0.0016,7.1e-4 0.0023,9.5e-4 0.0039,0.002 0,0 0,0.002 0,0.002 0.0099,0.004 0.01151,0.0112 0.02148,0.0156 l 0.0957,-0.1543 c -0.969152,-0.82506 -1.201432,-1.7029 -1.035156,-2.41992 0.158148,-0.68197 0.697248,-1.19924 1.332031,-1.39258 0.342856,1.71321 0.67597,3.39706 0.949219,4.86719 -0.359073,0.11659 -0.763799,0.19793 -1.248047,0.20117 -0.635222,0 -1.600811,-0.20698 -2.398437,-0.79492 -0.797627,-0.58794 -1.435547,-1.54979 -1.435547,-3.10156 0,-1.29998 0.445968,-2.20311 1.103515,-2.98633 0.624039,-0.74331 1.449758,-1.38038 2.25,-2.11524 z m 1.283203,3.82422 c 0.02141,4.3e-4 0.0405,-3.8e-4 0.0625,0 2.238301,0 3.083864,3.47355 0.910157,4.7168 -0.289126,-1.44718 -0.629087,-3.07811 -0.972657,-4.7168 z m -1.832031,2.67774 c 0.119836,0.26909 0.27396,0.54255 0.488281,0.8125 -0.0025,-0.002 -0.0034,-0.004 -0.0059,-0.006 -0.221707,-0.26878 -0.382669,-0.53955 -0.482422,-0.80664 z"
+ id="path26"
+ inkscape:connector-curvature="0" />
+ </g>
+</svg>
diff --git a/src/activities/piano_composition/resource/trebleA3Eighth.svg b/src/activities/piano_composition/resource/trebleA3Eighth.svg
new file mode 100644
index 000000000..994b42fad
--- /dev/null
+++ b/src/activities/piano_composition/resource/trebleA3Eighth.svg
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg2"
+ viewBox="0 0 744 1052"
+ version="1.1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="trebleA3Eighth.svg">
+ <defs
+ id="defs9" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ id="namedview7"
+ showgrid="false"
+ inkscape:zoom="0.43502872"
+ inkscape:cx="513.36151"
+ inkscape:cy="369.23983"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <metadata
+ id="metadata5">
+ <rdf:RDF>
+ <cc:Work>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://openclipart.org/">
+ <dc:title>Openclipart</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:title></dc:title>
+ <dc:date>2011-05-27T21:51:50</dc:date>
+ <dc:description>There didn't seem to be a whole note on openclipart already. Here is a big one!</dc:description>
+ <dc:source>https://openclipart.org/detail/140893/whole-note-by-10binary</dc:source>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>10binary</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>music</rdf:li>
+ <rdf:li>notation</rdf:li>
+ <rdf:li>note</rdf:li>
+ <rdf:li>whole</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Edited by Timothée Giet for GCompris
+</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 617.23751,729.20386 c 0,8.15934 0,16.31868 0,24.47802 -183.1579,0.44944 -366.31952,-0.41701 -549.463789,-2.71012 0,-7.86767 0,-15.73535 0,-23.60302 183.153709,0.85591 366.308879,1.32619 549.463789,1.83512 z"
+ id="path3287-6"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 617.23751,530.47825 c 0,8.15807 0,16.31615 0,24.47422 -183.15789,0.44938 -366.31952,-0.41696 -549.463789,-2.70971 0,-7.86645 0,-15.7329 0,-23.59935 183.153709,0.85573 366.308879,1.32597 549.463789,1.83484 z"
+ id="path3287-6-5"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path3-5"
+ style="fill:#000000;fill-rule:evenodd;stroke:none;stroke-width:5.92409992;stroke-linecap:round;stroke-linejoin:round;fill-opacity:1"
+ d="m 421.77949,233.27846 c 14.32,21.136 21.682,46.728 40.135,64.982 21.135,27.835 48.146,50.891 69.089,79.058 15.157,19.681 31.771,40.599 36.074,65.357 11.587,31.757 6.556,67.409 -5.8056,98.498 -13.947,16.765 -23.482,-4.9319 -19.589,-18.365 0.59324,-18.535 0.32293,-37.021 -6.7859,-54.528 -6.3047,-26.255 -17.834,-51.101 -37.136,-70.366 -16.772,-14.701 -35.813,-47.095 -61.382,-35.941 -16.885,10.637 -9.5289,32.139 -11.346,48.712 -1.0035,101.95 -1.0707,203.94 -2.7005,305.87 -1.2461,42.809 -38.247,71.529 -72.88,89.908 -30.854,18.567 -67.795,28.966 -103.61,20.691 -33.304,-3.4173 -67.756,-27.73 -68.454,-63.704 -2.2204,-41.711 27.904,-80.552 64.988,-97.024 36.404,-20.749 82.429,-25.246 121.63,-10.331 19.156,6.0549 24.483,-11.721 26.874,-28.819 2.2123,-129.77 3.9829,-259.54 4.4354,-389.33 0.36593,-12.973 21.496,-16.139 26.461,-4.6603 z" />
+</svg>
diff --git a/src/activities/piano_composition/resource/trebleA3Half.svg b/src/activities/piano_composition/resource/trebleA3Half.svg
new file mode 100644
index 000000000..863a92526
--- /dev/null
+++ b/src/activities/piano_composition/resource/trebleA3Half.svg
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg2"
+ viewBox="0 0 744 1052"
+ version="1.1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="trebleA3Half.svg">
+ <defs
+ id="defs9" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ id="namedview7"
+ showgrid="false"
+ inkscape:zoom="0.43502872"
+ inkscape:cx="513.36151"
+ inkscape:cy="369.23983"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <metadata
+ id="metadata5">
+ <rdf:RDF>
+ <cc:Work>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://openclipart.org/">
+ <dc:title>Openclipart</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:title></dc:title>
+ <dc:date>2011-05-27T21:51:50</dc:date>
+ <dc:description>There didn't seem to be a whole note on openclipart already. Here is a big one!</dc:description>
+ <dc:source>https://openclipart.org/detail/140893/whole-note-by-10binary</dc:source>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>10binary</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>music</rdf:li>
+ <rdf:li>notation</rdf:li>
+ <rdf:li>note</rdf:li>
+ <rdf:li>whole</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Edited by Timothée Giet for GCompris</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 617.23751,729.20386 c 0,8.15934 0,16.31868 0,24.47802 -183.1579,0.44944 -366.31952,-0.41701 -549.463789,-2.71012 0,-7.86767 0,-15.73535 0,-23.60302 183.153709,0.85591 366.308879,1.32619 549.463789,1.83512 z"
+ id="path3287-6"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path3"
+ style="fill:#000000;fill-rule:evenodd;stroke:none;stroke-width:5.92409992;stroke-linecap:round;stroke-linejoin:round;fill-opacity:1"
+ d="m 411.08132,225.77655 c -7.2475,0.33178 -15.544,4.8587 -15.75,12.156 -0.45246,129.79 -2.2252,259.57 -4.4375,389.34 -2.3903,17.098 -7.7188,34.867 -26.875,28.812 -39.21,-14.91 -85.23,-10.4 -121.63,10.35 -37.084,16.471 -67.22,55.289 -65,97 0.69789,35.974 35.134,60.301 68.438,63.719 35.814,8.2749 72.771,-2.12 103.62,-20.688 34.633,-18.379 71.629,-47.097 72.875,-89.906 2.4559,-167.09 4.7446,-319.48 -0.5625,-483.28 -0.073,-5.4712 -5.0506,-7.758 -10.688,-7.5 z m -99.28,436.04 c 30.478,-0.002 56.713,13.001 67.312,36.562 16.152,35.904 -10.092,82.712 -58.594,104.53 -48.502,21.819 -100.91,10.404 -117.06,-25.5 -16.152,-35.904 10.092,-82.712 58.594,-104.53 16.672,-7.5002 33.785,-11.062 49.75,-11.062 z" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 617.23751,537.18125 c 0,8.15807 0,16.31615 0,24.47422 -183.15789,0.44938 -366.31952,-0.41696 -549.463789,-2.70971 0,-7.86645 0,-15.7329 0,-23.59935 183.153709,0.85571 366.308879,1.32598 549.463789,1.83484 z"
+ id="path3287-6-5"
+ inkscape:connector-curvature="0" />
+</svg>
diff --git a/src/activities/piano_composition/resource/trebleA3Quarter.svg b/src/activities/piano_composition/resource/trebleA3Quarter.svg
new file mode 100644
index 000000000..314953d3e
--- /dev/null
+++ b/src/activities/piano_composition/resource/trebleA3Quarter.svg
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg2"
+ viewBox="0 0 744 1052"
+ version="1.1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="trebleA3Quarter.svg">
+ <defs
+ id="defs9" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ id="namedview7"
+ showgrid="false"
+ inkscape:zoom="0.43502872"
+ inkscape:cx="513.36151"
+ inkscape:cy="369.23983"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <metadata
+ id="metadata5">
+ <rdf:RDF>
+ <cc:Work>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://openclipart.org/">
+ <dc:title>Openclipart</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:title></dc:title>
+ <dc:date>2011-05-27T21:51:50</dc:date>
+ <dc:description>There didn't seem to be a whole note on openclipart already. Here is a big one!</dc:description>
+ <dc:source>https://openclipart.org/detail/140893/whole-note-by-10binary</dc:source>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>10binary</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>music</rdf:li>
+ <rdf:li>notation</rdf:li>
+ <rdf:li>note</rdf:li>
+ <rdf:li>whole</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Edited by Timothée Giet for GCompris</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 617.23751,729.20386 c 0,8.15934 0,16.31868 0,24.47802 -183.1579,0.44944 -366.31952,-0.41701 -549.463789,-2.71012 0,-7.86767 0,-15.73535 0,-23.60302 183.153709,0.85591 366.308879,1.32619 549.463789,1.83512 z"
+ id="path3287-6"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 617.23751,537.18125 c 0,8.15807 0,16.31615 0,24.47422 -183.15789,0.44938 -366.31952,-0.41696 -549.463789,-2.70971 0,-7.86645 0,-15.7329 0,-23.59935 183.153709,0.85571 366.308879,1.32598 549.463789,1.83484 z"
+ id="path3287-6-5"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path3"
+ style="fill:#000000;fill-rule:evenodd;stroke:none;stroke-width:5.92409992;stroke-linecap:round;stroke-linejoin:round;fill-opacity:1"
+ d="m 421.77912,233.28546 c 5.3071,163.8 3.0093,316.18 0.55337,483.27 -1.2461,42.809 -38.247,71.529 -72.88,89.908 -30.854,18.567 -67.795,28.966 -103.61,20.691 -33.304,-3.4173 -67.756,-27.73 -68.454,-63.704 -2.2204,-41.711 27.904,-80.552 64.988,-97.024 36.404,-20.749 82.429,-25.246 121.63,-10.331 19.156,6.0549 24.483,-11.721 26.874,-28.819 2.2123,-129.77 3.9829,-259.54 4.4354,-389.33 0.36593,-12.973 26.294,-17.166 26.461,-4.6603 z" />
+</svg>
diff --git a/src/activities/piano_composition/resource/trebleA3Whole.svg b/src/activities/piano_composition/resource/trebleA3Whole.svg
new file mode 100644
index 000000000..99fb3f095
--- /dev/null
+++ b/src/activities/piano_composition/resource/trebleA3Whole.svg
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg2"
+ viewBox="0 0 744 1052"
+ version="1.1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="trebleA3Whole.svg">
+ <defs
+ id="defs9" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ id="namedview7"
+ showgrid="false"
+ inkscape:zoom="0.43502872"
+ inkscape:cx="513.36151"
+ inkscape:cy="691.72367"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 289.29484,644.77518 c 66.94384,0.69882 130.26832,30.04918 135.09143,95.04169 3.61532,47.53718 -50.66281,90.84313 -117.60261,90.84313 -67.54773,-0.69977 -130.26832,-29.34803 -135.69532,-94.31861 -3.61814,-48.26027 51.22644,-91.56621 118.2065,-91.56621 z m 16.2456,169.81361 c 28.94793,0 47.64333,-32.1676 44.62788,-58.00095 -6.634,-51.01266 -21.71125,-92.26597 -61.5128,-92.26597 -28.94793,0 -45.83567,32.8445 -42.21632,58.70071 6.67143,51.03599 19.33633,91.56621 59.10124,91.56621 z"
+ style="fill:#000000;stroke-width:0.43337601;stroke:none"
+ id="path270" />
+ <metadata
+ id="metadata5">
+ <rdf:RDF>
+ <cc:Work>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://openclipart.org/">
+ <dc:title>Openclipart</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:title></dc:title>
+ <dc:date>2011-05-27T21:51:50</dc:date>
+ <dc:description>There didn't seem to be a whole note on openclipart already. Here is a big one!</dc:description>
+ <dc:source>https://openclipart.org/detail/140893/whole-note-by-10binary</dc:source>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>10binary</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>music</rdf:li>
+ <rdf:li>notation</rdf:li>
+ <rdf:li>note</rdf:li>
+ <rdf:li>whole</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Edited by Timothée Giet for GCompris</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 538.23806,537.17809 c 0,8.15935 0,16.31869 0,24.47804 -160.15837,0.44942 -320.321,-0.41704 -480.463788,-2.71013 0,-7.86768 0,-15.73535 0,-23.60303 160.153578,0.85583 320.308828,1.32618 480.463788,1.83512 z"
+ id="path3287-6"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 538.23806,731.50432 c 0,8.15829 0,16.31659 0,24.47488 -160.15837,0.44936 -320.321,-0.41698 -480.463788,-2.70977 0,-7.86666 0,-15.73333 0,-23.59999 160.153578,0.85571 320.308828,1.32601 480.463788,1.83488 z"
+ id="path3287-6-3"
+ inkscape:connector-curvature="0" />
+</svg>
diff --git a/src/activities/piano_composition/resource/trebleB3Eighth.svg b/src/activities/piano_composition/resource/trebleB3Eighth.svg
new file mode 100644
index 000000000..a88e1255e
--- /dev/null
+++ b/src/activities/piano_composition/resource/trebleB3Eighth.svg
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg2"
+ viewBox="0 0 744 1052"
+ version="1.1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="trebleB3Eighth.svg">
+ <defs
+ id="defs9" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ id="namedview7"
+ showgrid="false"
+ inkscape:zoom="0.43502872"
+ inkscape:cx="513.36151"
+ inkscape:cy="369.23983"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <metadata
+ id="metadata5">
+ <rdf:RDF>
+ <cc:Work>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://openclipart.org/">
+ <dc:title>Openclipart</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:title></dc:title>
+ <dc:date>2011-05-27T21:51:50</dc:date>
+ <dc:description>There didn't seem to be a whole note on openclipart already. Here is a big one!</dc:description>
+ <dc:source>https://openclipart.org/detail/140893/whole-note-by-10binary</dc:source>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>10binary</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>music</rdf:li>
+ <rdf:li>notation</rdf:li>
+ <rdf:li>note</rdf:li>
+ <rdf:li>whole</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Edited by Timothée Giet for GCompris</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 617.23751,634.95686 c 0,8.15934 0,16.31868 0,24.47802 -183.1579,0.44944 -366.31952,-0.41701 -549.463789,-2.71012 0,-7.86767 0,-15.73535 0,-23.60302 183.153709,0.8559 366.308879,1.32616 549.463789,1.83512 z"
+ id="path3287-6"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path3"
+ style="fill:#000000;fill-rule:evenodd;stroke:none;stroke-width:5.92409992;stroke-linecap:round;stroke-linejoin:round;fill-opacity:1"
+ d="m 421.77949,233.27846 c 14.32,21.136 21.682,46.728 40.135,64.982 21.135,27.835 48.146,50.891 69.089,79.058 15.157,19.681 31.771,40.599 36.074,65.357 11.587,31.757 6.556,67.409 -5.8056,98.498 -13.947,16.765 -23.482,-4.9319 -19.589,-18.365 0.59324,-18.535 0.32293,-37.021 -6.7859,-54.528 -6.3047,-26.255 -17.834,-51.101 -37.136,-70.366 -16.772,-14.701 -35.813,-47.095 -61.382,-35.941 -16.885,10.637 -9.5289,32.139 -11.346,48.712 -1.0035,101.95 -1.0707,203.94 -2.7005,305.87 -1.2461,42.809 -38.247,71.529 -72.88,89.908 -30.854,18.567 -67.795,28.966 -103.61,20.691 -33.304,-3.4173 -67.756,-27.73 -68.454,-63.704 -2.2204,-41.711 27.904,-80.552 64.988,-97.024 36.404,-20.749 82.429,-25.246 121.63,-10.331 19.156,6.0549 24.483,-11.721 26.874,-28.819 2.2123,-129.77 3.9829,-259.54 4.4354,-389.33 0.36593,-12.973 21.496,-16.139 26.461,-4.6603 z" />
+</svg>
diff --git a/src/activities/piano_composition/resource/trebleB3Half.svg b/src/activities/piano_composition/resource/trebleB3Half.svg
new file mode 100644
index 000000000..546734e26
--- /dev/null
+++ b/src/activities/piano_composition/resource/trebleB3Half.svg
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg2"
+ viewBox="0 0 744 1052"
+ version="1.1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="trebleB3Half.svg">
+ <defs
+ id="defs9" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ id="namedview7"
+ showgrid="false"
+ inkscape:zoom="0.43502872"
+ inkscape:cx="513.36151"
+ inkscape:cy="369.23983"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <metadata
+ id="metadata5">
+ <rdf:RDF>
+ <cc:Work>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://openclipart.org/">
+ <dc:title>Openclipart</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:title></dc:title>
+ <dc:date>2011-05-27T21:51:50</dc:date>
+ <dc:description>There didn't seem to be a whole note on openclipart already. Here is a big one!</dc:description>
+ <dc:source>https://openclipart.org/detail/140893/whole-note-by-10binary</dc:source>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>10binary</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>music</rdf:li>
+ <rdf:li>notation</rdf:li>
+ <rdf:li>note</rdf:li>
+ <rdf:li>whole</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Edited by Timothée Giet for GCompris</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 617.23751,634.95686 c 0,8.15934 0,16.31868 0,24.47802 -183.1579,0.44944 -366.31952,-0.41701 -549.463789,-2.71012 0,-7.86767 0,-15.73535 0,-23.60302 183.153709,0.8559 366.308879,1.32616 549.463789,1.83512 z"
+ id="path3287-6"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path3"
+ style="fill:#000000;fill-rule:evenodd;stroke:none;stroke-width:5.92409992;stroke-linecap:round;stroke-linejoin:round;fill-opacity:1"
+ d="m 411.08132,225.77655 c -7.2475,0.33178 -15.544,4.8587 -15.75,12.156 -0.45246,129.79 -2.2252,259.57 -4.4375,389.34 -2.3903,17.098 -7.7188,34.867 -26.875,28.812 -39.21,-14.91 -85.23,-10.4 -121.63,10.35 -37.084,16.471 -67.22,55.289 -65,97 0.69789,35.974 35.134,60.301 68.438,63.719 35.814,8.2749 72.771,-2.12 103.62,-20.688 34.633,-18.379 71.629,-47.097 72.875,-89.906 2.4559,-167.09 4.7446,-319.48 -0.5625,-483.28 -0.073,-5.4712 -5.0506,-7.758 -10.688,-7.5 z m -99.28,436.04 c 30.478,-0.002 56.713,13.001 67.312,36.562 16.152,35.904 -10.092,82.712 -58.594,104.53 -48.502,21.819 -100.91,10.404 -117.06,-25.5 -16.152,-35.904 10.092,-82.712 58.594,-104.53 16.672,-7.5002 33.785,-11.062 49.75,-11.062 z" />
+</svg>
diff --git a/src/activities/piano_composition/resource/trebleB3Quarter.svg b/src/activities/piano_composition/resource/trebleB3Quarter.svg
new file mode 100644
index 000000000..0caf31ae1
--- /dev/null
+++ b/src/activities/piano_composition/resource/trebleB3Quarter.svg
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg2"
+ viewBox="0 0 744 1052"
+ version="1.1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="trebleB3Quarter.svg">
+ <defs
+ id="defs9" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ id="namedview7"
+ showgrid="false"
+ inkscape:zoom="0.43502872"
+ inkscape:cx="513.36151"
+ inkscape:cy="369.23983"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <metadata
+ id="metadata5">
+ <rdf:RDF>
+ <cc:Work>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://openclipart.org/">
+ <dc:title>Openclipart</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:title></dc:title>
+ <dc:date>2011-05-27T21:51:50</dc:date>
+ <dc:description>There didn't seem to be a whole note on openclipart already. Here is a big one!</dc:description>
+ <dc:source>https://openclipart.org/detail/140893/whole-note-by-10binary</dc:source>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>10binary</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>music</rdf:li>
+ <rdf:li>notation</rdf:li>
+ <rdf:li>note</rdf:li>
+ <rdf:li>whole</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Edited by Timothée Giet for GCompris</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 617.23751,634.95686 c 0,8.15934 0,16.31868 0,24.47802 -183.1579,0.44944 -366.31952,-0.41701 -549.463789,-2.71012 0,-7.86767 0,-15.73535 0,-23.60302 183.153709,0.8559 366.308879,1.32616 549.463789,1.83512 z"
+ id="path3287-6"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path3-5"
+ style="fill:#000000;fill-rule:evenodd;stroke:none;stroke-width:5.92409992;stroke-linecap:round;stroke-linejoin:round;fill-opacity:1"
+ d="m 421.77912,233.28546 c 5.3071,163.8 3.0093,316.18 0.55337,483.27 -1.2461,42.809 -38.247,71.529 -72.88,89.908 -30.854,18.567 -67.795,28.966 -103.61,20.691 -33.304,-3.4173 -67.756,-27.73 -68.454,-63.704 -2.2204,-41.711 27.904,-80.552 64.988,-97.024 36.404,-20.749 82.429,-25.246 121.63,-10.331 19.156,6.0549 24.483,-11.721 26.874,-28.819 2.2123,-129.77 3.9829,-259.54 4.4354,-389.33 0.36593,-12.973 26.294,-17.166 26.461,-4.6603 z" />
+</svg>
diff --git a/src/activities/piano_composition/resource/trebleB3Whole.svg b/src/activities/piano_composition/resource/trebleB3Whole.svg
new file mode 100644
index 000000000..749bc7112
--- /dev/null
+++ b/src/activities/piano_composition/resource/trebleB3Whole.svg
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg2"
+ viewBox="0 0 744 1052"
+ version="1.1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="trebleB3Whole.svg">
+ <defs
+ id="defs9" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ id="namedview7"
+ showgrid="false"
+ inkscape:zoom="0.43502872"
+ inkscape:cx="513.36151"
+ inkscape:cy="323.93186"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 289.29484,644.77518 c 66.94384,0.69882 130.26832,30.04918 135.09143,95.04169 3.61532,47.53718 -50.66281,90.84313 -117.60261,90.84313 -67.54773,-0.69977 -130.26832,-29.34803 -135.69532,-94.31861 -3.61814,-48.26027 51.22644,-91.56621 118.2065,-91.56621 z m 16.2456,169.81361 c 28.94793,0 47.64333,-32.1676 44.62788,-58.00095 -6.634,-51.01266 -21.71125,-92.26597 -61.5128,-92.26597 -28.94793,0 -45.83567,32.8445 -42.21632,58.70071 6.67143,51.03599 19.33633,91.56621 59.10124,91.56621 z"
+ style="fill:#000000;stroke-width:0.43337601;stroke:none"
+ id="path270" />
+ <metadata
+ id="metadata5">
+ <rdf:RDF>
+ <cc:Work>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://openclipart.org/">
+ <dc:title>Openclipart</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:title></dc:title>
+ <dc:date>2011-05-27T21:51:50</dc:date>
+ <dc:description>There didn't seem to be a whole note on openclipart already. Here is a big one!</dc:description>
+ <dc:source>https://openclipart.org/detail/140893/whole-note-by-10binary</dc:source>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>10binary</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>music</rdf:li>
+ <rdf:li>notation</rdf:li>
+ <rdf:li>note</rdf:li>
+ <rdf:li>whole</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Edited by Timothée Giet for GCompris</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 538.23806,625.76309 c 0,8.15935 0,16.31869 0,24.47804 -160.15837,0.44942 -320.321,-0.41704 -480.463788,-2.71013 0,-7.86768 0,-15.73535 0,-23.60303 160.153578,0.85585 320.308828,1.32618 480.463788,1.83512 z"
+ id="path3287-6"
+ inkscape:connector-curvature="0" />
+</svg>
diff --git a/src/activities/piano_composition/resource/trebleC4Eighth.svg b/src/activities/piano_composition/resource/trebleC4Eighth.svg
new file mode 100644
index 000000000..2fc09d30c
--- /dev/null
+++ b/src/activities/piano_composition/resource/trebleC4Eighth.svg
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg2"
+ viewBox="0 0 744 1052"
+ version="1.1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="trebleC4Eighth.svg">
+ <defs
+ id="defs9" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ id="namedview7"
+ showgrid="false"
+ inkscape:zoom="0.43502872"
+ inkscape:cx="513.36151"
+ inkscape:cy="323.93186"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <metadata
+ id="metadata5">
+ <rdf:RDF>
+ <cc:Work>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://openclipart.org/">
+ <dc:title>Openclipart</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:title></dc:title>
+ <dc:date>2011-05-27T21:51:50</dc:date>
+ <dc:description>There didn't seem to be a whole note on openclipart already. Here is a big one!</dc:description>
+ <dc:source>https://openclipart.org/detail/140893/whole-note-by-10binary</dc:source>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>10binary</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>music</rdf:li>
+ <rdf:li>notation</rdf:li>
+ <rdf:li>note</rdf:li>
+ <rdf:li>whole</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Edited by Timothée Giet for GCompris</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 617.23823,729.20503 c 0,8.15934 0,16.31868 0,24.47802 -183.15796,0.44944 -366.31965,-0.41701 -549.463992,-2.71012 0,-7.86767 0,-15.73535 0,-23.60302 183.153772,0.85586 366.309012,1.32618 549.463992,1.83512 z"
+ id="path3287-6"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path3"
+ style="fill:#000000;fill-rule:evenodd;stroke:none;stroke-width:5.92409992;stroke-linecap:round;stroke-linejoin:round;fill-opacity:1"
+ d="m 421.77949,233.27846 c 14.32,21.136 21.682,46.728 40.135,64.982 21.135,27.835 48.146,50.891 69.089,79.058 15.157,19.681 31.771,40.599 36.074,65.357 11.587,31.757 6.556,67.409 -5.8056,98.498 -13.947,16.765 -23.482,-4.9319 -19.589,-18.365 0.59324,-18.535 0.32293,-37.021 -6.7859,-54.528 -6.3047,-26.255 -17.834,-51.101 -37.136,-70.366 -16.772,-14.701 -35.813,-47.095 -61.382,-35.941 -16.885,10.637 -9.5289,32.139 -11.346,48.712 -1.0035,101.95 -1.0707,203.94 -2.7005,305.87 -1.2461,42.809 -38.247,71.529 -72.88,89.908 -30.854,18.567 -67.795,28.966 -103.61,20.691 -33.304,-3.4173 -67.756,-27.73 -68.454,-63.704 -2.2204,-41.711 27.904,-80.552 64.988,-97.024 36.404,-20.749 82.429,-25.246 121.63,-10.331 19.156,6.0549 24.483,-11.721 26.874,-28.819 2.2123,-129.77 3.9829,-259.54 4.4354,-389.33 0.36593,-12.973 21.496,-16.139 26.461,-4.6603 z" />
+</svg>
diff --git a/src/activities/piano_composition/resource/trebleC4Half.svg b/src/activities/piano_composition/resource/trebleC4Half.svg
new file mode 100644
index 000000000..3c32304e5
--- /dev/null
+++ b/src/activities/piano_composition/resource/trebleC4Half.svg
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg2"
+ viewBox="0 0 744 1052"
+ version="1.1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="trebleC4Half.svg">
+ <defs
+ id="defs9" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ id="namedview7"
+ showgrid="false"
+ inkscape:zoom="0.43502872"
+ inkscape:cx="513.36151"
+ inkscape:cy="323.93186"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <metadata
+ id="metadata5">
+ <rdf:RDF>
+ <cc:Work>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://openclipart.org/">
+ <dc:title>Openclipart</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:title></dc:title>
+ <dc:date>2011-05-27T21:51:50</dc:date>
+ <dc:description>There didn't seem to be a whole note on openclipart already. Here is a big one!</dc:description>
+ <dc:source>https://openclipart.org/detail/140893/whole-note-by-10binary</dc:source>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>10binary</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>music</rdf:li>
+ <rdf:li>notation</rdf:li>
+ <rdf:li>note</rdf:li>
+ <rdf:li>whole</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Edited by Timothée Giet for GCompris</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 617.23751,729.20386 c 0,8.15934 0,16.31868 0,24.47802 -183.1579,0.44944 -366.31952,-0.41701 -549.463789,-2.71012 0,-7.86767 0,-15.73535 0,-23.60302 183.153709,0.85591 366.308879,1.32619 549.463789,1.83512 z"
+ id="path3287-6"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path3"
+ style="fill:#000000;fill-rule:evenodd;stroke:none;stroke-width:5.92409992;stroke-linecap:round;stroke-linejoin:round;fill-opacity:1"
+ d="m 411.08132,225.77655 c -7.2475,0.33178 -15.544,4.8587 -15.75,12.156 -0.45246,129.79 -2.2252,259.57 -4.4375,389.34 -2.3903,17.098 -7.7188,34.867 -26.875,28.812 -39.21,-14.91 -85.23,-10.4 -121.63,10.35 -37.084,16.471 -67.22,55.289 -65,97 0.69789,35.974 35.134,60.301 68.438,63.719 35.814,8.2749 72.771,-2.12 103.62,-20.688 34.633,-18.379 71.629,-47.097 72.875,-89.906 2.4559,-167.09 4.7446,-319.48 -0.5625,-483.28 -0.073,-5.4712 -5.0506,-7.758 -10.688,-7.5 z m -99.28,436.04 c 30.478,-0.002 56.713,13.001 67.312,36.562 16.152,35.904 -10.092,82.712 -58.594,104.53 -48.502,21.819 -100.91,10.404 -117.06,-25.5 -16.152,-35.904 10.092,-82.712 58.594,-104.53 16.672,-7.5002 33.785,-11.062 49.75,-11.062 z" />
+</svg>
diff --git a/src/activities/piano_composition/resource/trebleC4Quarter.svg b/src/activities/piano_composition/resource/trebleC4Quarter.svg
new file mode 100644
index 000000000..79cbefdbb
--- /dev/null
+++ b/src/activities/piano_composition/resource/trebleC4Quarter.svg
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg2"
+ viewBox="0 0 744 1052"
+ version="1.1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="trebleC4Quarter.svg">
+ <defs
+ id="defs9" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ id="namedview7"
+ showgrid="false"
+ inkscape:zoom="0.43502872"
+ inkscape:cx="513.36151"
+ inkscape:cy="323.93186"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <metadata
+ id="metadata5">
+ <rdf:RDF>
+ <cc:Work>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://openclipart.org/">
+ <dc:title>Openclipart</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:title></dc:title>
+ <dc:date>2011-05-27T21:51:50</dc:date>
+ <dc:description>There didn't seem to be a whole note on openclipart already. Here is a big one!</dc:description>
+ <dc:source>https://openclipart.org/detail/140893/whole-note-by-10binary</dc:source>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>10binary</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>music</rdf:li>
+ <rdf:li>notation</rdf:li>
+ <rdf:li>note</rdf:li>
+ <rdf:li>whole</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Edited by Timothée Giet for GCompris</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 617.23751,729.20386 c 0,8.15934 0,16.31868 0,24.47802 -183.1579,0.44944 -366.31952,-0.41701 -549.463789,-2.71012 0,-7.86767 0,-15.73535 0,-23.60302 183.153709,0.85591 366.308879,1.32619 549.463789,1.83512 z"
+ id="path3287-6"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path3-5"
+ style="fill:#000000;fill-rule:evenodd;stroke:none;stroke-width:5.92409992;stroke-linecap:round;stroke-linejoin:round;fill-opacity:1"
+ d="m 421.77912,233.28546 c 5.3071,163.8 3.0093,316.18 0.55337,483.27 -1.2461,42.809 -38.247,71.529 -72.88,89.908 -30.854,18.567 -67.795,28.966 -103.61,20.691 -33.304,-3.4173 -67.756,-27.73 -68.454,-63.704 -2.2204,-41.711 27.904,-80.552 64.988,-97.024 36.404,-20.749 82.429,-25.246 121.63,-10.331 19.156,6.0549 24.483,-11.721 26.874,-28.819 2.2123,-129.77 3.9829,-259.54 4.4354,-389.33 0.36593,-12.973 26.294,-17.166 26.461,-4.6603 z" />
+</svg>
diff --git a/src/activities/piano_composition/resource/trebleC4Whole.svg b/src/activities/piano_composition/resource/trebleC4Whole.svg
new file mode 100644
index 000000000..0560d3840
--- /dev/null
+++ b/src/activities/piano_composition/resource/trebleC4Whole.svg
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg2"
+ viewBox="0 0 744 1052"
+ version="1.1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="trebleC4Whole.svg">
+ <defs
+ id="defs9" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ id="namedview7"
+ showgrid="false"
+ inkscape:zoom="0.43502872"
+ inkscape:cx="513.36151"
+ inkscape:cy="323.93186"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 289.29484,644.77518 c 66.94384,0.69882 130.26832,30.04918 135.09143,95.04169 3.61532,47.53718 -50.66281,90.84313 -117.60261,90.84313 -67.54773,-0.69977 -130.26832,-29.34803 -135.69532,-94.31861 -3.61814,-48.26027 51.22644,-91.56621 118.2065,-91.56621 z m 16.2456,169.81361 c 28.94793,0 47.64333,-32.1676 44.62788,-58.00095 -6.634,-51.01266 -21.71125,-92.26597 -61.5128,-92.26597 -28.94793,0 -45.83567,32.8445 -42.21632,58.70071 6.67143,51.03599 19.33633,91.56621 59.10124,91.56621 z"
+ style="fill:#000000;stroke-width:0.43337601;stroke:none"
+ id="path270" />
+ <metadata
+ id="metadata5">
+ <rdf:RDF>
+ <cc:Work>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://openclipart.org/">
+ <dc:title>Openclipart</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:title>whole note</dc:title>
+ <dc:date>2011-05-27T21:51:50</dc:date>
+ <dc:description>There didn't seem to be a whole note on openclipart already. Here is a big one!</dc:description>
+ <dc:source>https://openclipart.org/detail/140893/whole-note-by-10binary</dc:source>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>10binary</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>music</rdf:li>
+ <rdf:li>notation</rdf:li>
+ <rdf:li>note</rdf:li>
+ <rdf:li>whole</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Edited by Timothée Giet for GCompris</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 538.23829,729.20303 c 0,8.15934 0,16.31869 0,24.47803 -160.15836,0.44942 -320.32099,-0.41705 -480.46377,-2.71012 0,-7.86768 0,-15.73535 0,-23.60303 160.15357,0.85587 320.30882,1.3262 480.46377,1.83512 z"
+ id="path3287-6"
+ inkscape:connector-curvature="0" />
+</svg>
diff --git a/src/activities/piano_composition/resource/trebleClef.svg b/src/activities/piano_composition/resource/trebleClef.svg
new file mode 100644
index 000000000..4795b3f7e
--- /dev/null
+++ b/src/activities/piano_composition/resource/trebleClef.svg
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg2"
+ sodipodi:docname="trebleClef.svg"
+ viewBox="0 0 95.116 153.12"
+ sodipodi:version="0.32"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ inkscape:version="0.92.1 r15371"
+ version="1.1">
+ <defs
+ id="defs7" />
+ <sodipodi:namedview
+ id="base"
+ bordercolor="#666666"
+ inkscape:pageshadow="2"
+ guidetolerance="10.0"
+ pagecolor="#ffffff"
+ gridtolerance="10.0"
+ inkscape:zoom="2.4686199"
+ objecttolerance="10.0"
+ borderopacity="1.0"
+ inkscape:current-layer="svg2"
+ inkscape:cx="-34.066656"
+ inkscape:cy="80.611843"
+ inkscape:window-y="0"
+ inkscape:window-x="0"
+ inkscape:window-height="1051"
+ showgrid="false"
+ inkscape:pageopacity="0.0"
+ inkscape:window-width="1884"
+ inkscape:window-maximized="1" />
+ <path
+ style="stroke:none;fill:#000000"
+ d="M 51.701172 4.75 C 50.143107 4.709548 48.615442 5.5914695 47.205078 7.0234375 C 45.794714 8.4554055 44.47883 10.463806 43.341797 12.833984 C 41.06773 17.574341 39.517767 23.761369 39.625 29.634766 C 39.67504 33.211948 40.777491 40.249223 42.371094 49.083984 C 32.202752 59.59209 20.31578 70.490899 20.3125 84.931641 C 20.312484 84.932941 20.312516 84.934247 20.3125 84.935547 L 20.3125 84.9375 C 20.2309 91.569097 22.206476 99.08474 26.626953 104.96094 C 31.048694 110.83881 37.952891 115.05195 47.566406 114.9707 C 50.30168 114.9519 52.761537 114.60955 54.998047 114.05859 C 56.670052 123.27432 57.787887 130.62739 57.78125 133.9082 L 57.78125 133.91016 L 57.78125 133.91211 C 57.81077 140.51307 53.551864 144.03256 49.154297 145.05273 C 46.955513 145.56282 44.730862 145.42017 43.052734 144.70898 C 41.526209 144.06204 40.554765 142.93313 40.228516 141.41211 C 43.936458 140.95613 46.84375 137.97314 46.84375 134.2207 C 46.84375 130.15471 43.47101 126.83984 39.3125 126.83984 C 37.036713 126.83984 35.000085 127.83653 33.615234 129.39648 C 33.604874 129.40688 33.568575 129.43739 33.515625 129.49219 L 33.513672 129.49414 L 33.511719 129.49805 C 33.180649 129.84953 32.915901 130.25059 32.664062 130.68555 C 32.664062 130.68555 32.662109 130.6875 32.662109 130.6875 C 32.662109 130.6875 32.662109 130.68945 32.662109 130.68945 C 31.806729 132.13827 31.278584 134.16635 31.25 136.99414 L 31.25 136.99805 L 31.25 137 C 31.25 140.0657 33.177505 142.79971 35.970703 144.80469 C 38.763901 146.80966 42.449492 148.12049 46.15625 148.35156 C 49.863008 148.58263 53.608886 147.72687 56.4375 145.32422 C 59.264732 142.92274 61.123184 138.9901 61.125 133.25781 L 61.125 133.25391 C 61.17092 130.11495 59.881681 122.61401 58.029297 113.12891 C 68.235803 109.21885 72.132873 99.615855 71.035156 90.945312 C 69.922524 82.156959 63.688965 74.23029 53.941406 74.15625 L 53.9375 74.15625 L 53.933594 74.15625 C 52.607758 74.16978 51.334251 74.362416 50.085938 74.638672 C 49.058212 69.69139 48.066635 64.885018 47.195312 60.455078 C 54.361633 53.359855 60.639697 44.055849 60.5 27.21875 C 60.51087 21.106805 59.502814 15.598894 57.929688 11.5625 C 57.143034 9.5440754 56.217843 7.8922892 55.179688 6.7089844 C 54.141531 5.5256796 52.965055 4.7913347 51.705078 4.75 L 51.703125 4.75 L 51.701172 4.75 z M 53.017578 17.466797 C 54.080398 17.364236 54.967948 17.764438 55.679688 18.810547 C 56.391427 19.856656 56.875 21.586504 56.875 24.03125 L 56.875 24.037109 L 56.875 24.042969 C 57.06157 32.124539 51.52858 39.323202 44.703125 46.599609 C 44.144604 43.095969 43.69876 39.9571 43.65625 38.244141 C 43.759065 31.584991 45.176549 26.441805 47.044922 22.943359 C 48.914645 19.442385 51.247114 17.637616 53.017578 17.466797 z M 44.929688 62.611328 C 45.738199 66.760865 46.595545 71.078852 47.46875 75.451172 C 41.239334 77.835157 36.630849 83.292435 35.769531 89.277344 C 34.888826 95.396974 38.009629 101.97986 47.048828 105.95703 L 47.574219 105.11914 C 42.257699 100.59301 40.982503 95.767428 41.894531 91.833984 C 42.764193 88.083263 45.69143 85.174254 49.185547 84.121094 C 51.075969 93.563945 52.913235 102.84923 54.417969 110.94336 C 52.455606 111.58299 50.209261 111.98119 47.5625 112 C 44.078067 112 38.776008 110.87335 34.400391 107.64844 C 30.024773 104.42352 26.53125 99.139297 26.53125 90.625 C 26.53125 83.493531 28.976704 78.542758 32.583984 74.246094 C 36.017575 70.156312 40.527467 66.657898 44.929688 62.611328 z M 51.958984 83.625 C 52.073794 83.6269 52.180986 83.621 52.294922 83.625 L 52.302734 83.625 L 52.3125 83.625 C 64.629857 83.625 69.397415 102.87831 57.332031 109.64062 C 55.740454 101.66818 53.853883 92.665781 51.958984 83.625 z "
+ id="path26" />
+ <metadata
+ id="metadata4">
+ <rdf:RDF>
+ <cc:Work>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://openclipart.org/">
+ <dc:title>Openclipart</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:title>Treble clef</dc:title>
+ <dc:date>2006-12-03T12:59:04</dc:date>
+ <dc:description>Hollow treble clef for use at drawings</dc:description>
+ <dc:source>https://openclipart.org/detail/12473/treble-clef-by-rickvanderzwet-12473</dc:source>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>rickvanderzwet</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>clef</rdf:li>
+ <rdf:li>line art</rdf:li>
+ <rdf:li>music</rdf:li>
+ <rdf:li>sign</rdf:li>
+ <rdf:li>silhouette</rdf:li>
+ <rdf:li>treble</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Edited by Timothée Giet for GCompris</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+</svg>
diff --git a/src/activities/piano_composition/resource/trebleD3Quarter.svg b/src/activities/piano_composition/resource/trebleD3Quarter.svg
new file mode 100644
index 000000000..e206de8e8
--- /dev/null
+++ b/src/activities/piano_composition/resource/trebleD3Quarter.svg
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg2"
+ viewBox="0 0 744 1052"
+ version="1.1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="trebleD3Quarter.svg">
+ <defs
+ id="defs9" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ id="namedview7"
+ showgrid="false"
+ inkscape:zoom="0.43502872"
+ inkscape:cx="513.36151"
+ inkscape:cy="369.23983"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <metadata
+ id="metadata5">
+ <rdf:RDF>
+ <cc:Work>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://openclipart.org/">
+ <dc:title>Openclipart</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:title></dc:title>
+ <dc:date>2011-05-27T21:51:50</dc:date>
+ <dc:description>There didn't seem to be a whole note on openclipart already. Here is a big one!</dc:description>
+ <dc:source>https://openclipart.org/detail/140893/whole-note-by-10binary</dc:source>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>10binary</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>music</rdf:li>
+ <rdf:li>notation</rdf:li>
+ <rdf:li>note</rdf:li>
+ <rdf:li>whole</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Edited by Timothée Giet for GCompris</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 617.23751,729.20386 c 0,8.15934 0,16.31868 0,24.47802 -183.1579,0.44944 -366.31952,-0.41701 -549.463789,-2.71012 0,-7.86767 0,-15.73535 0,-23.60302 183.153709,0.85591 366.308879,1.32619 549.463789,1.83512 z"
+ id="path3287-6"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 617.23751,547.18125 c 0,8.15807 0,16.31615 0,24.47422 -183.15789,0.44938 -366.31952,-0.41696 -549.463789,-2.70971 0,-7.86645 0,-15.7329 0,-23.59935 183.153709,0.85577 366.308879,1.32599 549.463789,1.83484 z"
+ id="path3287-6-5"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 617.23751,367.23326 c 0,8.15827 0,16.31653 0,24.4748 -183.15789,0.44939 -366.31952,-0.41697 -549.463789,-2.70977 0,-7.86663 0,-15.73327 0,-23.5999 183.153709,0.85571 366.308879,1.326 549.463789,1.83487 z"
+ id="path3287-6-6"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path3"
+ style="fill:#000000;fill-rule:evenodd;stroke:none;stroke-width:5.92409992;stroke-linecap:round;stroke-linejoin:round;fill-opacity:1"
+ d="m 421.77912,233.28546 c 5.3071,163.8 3.0093,316.18 0.55337,483.27 -1.2461,42.809 -38.247,71.529 -72.88,89.908 -30.854,18.567 -67.795,28.966 -103.61,20.691 -33.304,-3.4173 -67.756,-27.73 -68.454,-63.704 -2.2204,-41.711 27.904,-80.552 64.988,-97.024 36.404,-20.749 82.429,-25.246 121.63,-10.331 19.156,6.0549 24.483,-11.721 26.874,-28.819 2.2123,-129.77 3.9829,-259.54 4.4354,-389.33 0.36593,-12.973 26.294,-17.166 26.461,-4.6603 z" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 617.23751,202.28525 c 0,8.15807 0,16.31615 0,24.47422 -183.15789,0.44938 -366.31952,-0.41696 -549.463789,-2.70971 0,-7.86645 0,-15.7329 0,-23.59935 183.153709,0.85574 366.308879,1.326 549.463789,1.83484 z"
+ id="path3287-6-5-5"
+ inkscape:connector-curvature="0" />
+</svg>
diff --git a/src/activities/piano_composition/resource/trebleE3Eighth.svg b/src/activities/piano_composition/resource/trebleE3Eighth.svg
new file mode 100644
index 000000000..62df1b0df
--- /dev/null
+++ b/src/activities/piano_composition/resource/trebleE3Eighth.svg
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg2"
+ viewBox="0 0 744 1052"
+ version="1.1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="trebleE3Eighth.svg">
+ <defs
+ id="defs9" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ id="namedview7"
+ showgrid="false"
+ inkscape:zoom="0.43502872"
+ inkscape:cx="513.36151"
+ inkscape:cy="369.23983"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <metadata
+ id="metadata5">
+ <rdf:RDF>
+ <cc:Work>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://openclipart.org/">
+ <dc:title>Openclipart</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:title></dc:title>
+ <dc:date>2011-05-27T21:51:50</dc:date>
+ <dc:description>There didn't seem to be a whole note on openclipart already. Here is a big one!</dc:description>
+ <dc:source>https://openclipart.org/detail/140893/whole-note-by-10binary</dc:source>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>10binary</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>music</rdf:li>
+ <rdf:li>notation</rdf:li>
+ <rdf:li>note</rdf:li>
+ <rdf:li>whole</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Edited by Timothée Giet for GCompris</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 617.23751,629.20386 c 0,8.15934 0,16.31868 0,24.47802 -183.1579,0.44944 -366.31952,-0.41701 -549.463789,-2.71012 0,-7.86767 0,-15.73535 0,-23.60302 183.153709,0.85593 366.308879,1.32618 549.463789,1.83512 z"
+ id="path3287-6"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 617.23751,267.18125 c 0,8.15807 0,16.31615 0,24.47422 -183.15789,0.44938 -366.31952,-0.41696 -549.463789,-2.70971 0,-7.86645 0,-15.7329 0,-23.59935 183.153709,0.85577 366.308879,1.32599 549.463789,1.83484 z"
+ id="path3287-6-5"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 617.23751,447.23326 c 0,8.15827 0,16.31653 0,24.4748 -183.15789,0.44939 -366.31952,-0.41697 -549.463789,-2.70977 0,-7.86663 0,-15.73327 0,-23.5999 183.153709,0.85576 366.308879,1.32599 549.463789,1.83487 z"
+ id="path3287-6-6"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path3"
+ style="fill:#000000;fill-rule:evenodd;stroke:none;stroke-width:5.92409992;stroke-linecap:round;stroke-linejoin:round;fill-opacity:1"
+ d="m 421.77949,233.27846 c 14.32,21.136 21.682,46.728 40.135,64.982 21.135,27.835 48.146,50.891 69.089,79.058 15.157,19.681 31.771,40.599 36.074,65.357 11.587,31.757 6.556,67.409 -5.8056,98.498 -13.947,16.765 -23.482,-4.9319 -19.589,-18.365 0.59324,-18.535 0.32293,-37.021 -6.7859,-54.528 -6.3047,-26.255 -17.834,-51.101 -37.136,-70.366 -16.772,-14.701 -35.813,-47.095 -61.382,-35.941 -16.885,10.637 -9.5289,32.139 -11.346,48.712 -1.0035,101.95 -1.0707,203.94 -2.7005,305.87 -1.2461,42.809 -38.247,71.529 -72.88,89.908 -30.854,18.567 -67.795,28.966 -103.61,20.691 -33.304,-3.4173 -67.756,-27.73 -68.454,-63.704 -2.2204,-41.711 27.904,-80.552 64.988,-97.024 36.404,-20.749 82.429,-25.246 121.63,-10.331 19.156,6.0549 24.483,-11.721 26.874,-28.819 2.2123,-129.77 3.9829,-259.54 4.4354,-389.33 0.36593,-12.973 21.496,-16.139 26.461,-4.6603 z" />
+</svg>
diff --git a/src/activities/piano_composition/resource/trebleE3Half.svg b/src/activities/piano_composition/resource/trebleE3Half.svg
new file mode 100644
index 000000000..c53c7804c
--- /dev/null
+++ b/src/activities/piano_composition/resource/trebleE3Half.svg
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg2"
+ viewBox="0 0 744 1052"
+ version="1.1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="trebleE3Half.svg">
+ <defs
+ id="defs9" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ id="namedview7"
+ showgrid="false"
+ inkscape:zoom="0.43502872"
+ inkscape:cx="513.36151"
+ inkscape:cy="369.23983"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <metadata
+ id="metadata5">
+ <rdf:RDF>
+ <cc:Work>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://openclipart.org/">
+ <dc:title>Openclipart</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:title></dc:title>
+ <dc:date>2011-05-27T21:51:50</dc:date>
+ <dc:description>There didn't seem to be a whole note on openclipart already. Here is a big one!</dc:description>
+ <dc:source>https://openclipart.org/detail/140893/whole-note-by-10binary</dc:source>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>10binary</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>music</rdf:li>
+ <rdf:li>notation</rdf:li>
+ <rdf:li>note</rdf:li>
+ <rdf:li>whole</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Edited by Timothée Giet for GCompris</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 617.23751,629.20386 c 0,8.15934 0,16.31868 0,24.47802 -183.1579,0.44944 -366.31952,-0.41701 -549.463789,-2.71012 0,-7.86767 0,-15.73535 0,-23.60302 183.153709,0.85593 366.308879,1.32618 549.463789,1.83512 z"
+ id="path3287-6"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path3"
+ style="fill:#000000;fill-rule:evenodd;stroke:none;stroke-width:5.92409992;stroke-linecap:round;stroke-linejoin:round;fill-opacity:1"
+ d="m 411.08132,225.77655 c -7.2475,0.33178 -15.544,4.8587 -15.75,12.156 -0.45246,129.79 -2.2252,259.57 -4.4375,389.34 -2.3903,17.098 -7.7188,34.867 -26.875,28.812 -39.21,-14.91 -85.23,-10.4 -121.63,10.35 -37.084,16.471 -67.22,55.289 -65,97 0.69789,35.974 35.134,60.301 68.438,63.719 35.814,8.2749 72.771,-2.12 103.62,-20.688 34.633,-18.379 71.629,-47.097 72.875,-89.906 2.4559,-167.09 4.7446,-319.48 -0.5625,-483.28 -0.073,-5.4712 -5.0506,-7.758 -10.688,-7.5 z m -99.28,436.04 c 30.478,-0.002 56.713,13.001 67.312,36.562 16.152,35.904 -10.092,82.712 -58.594,104.53 -48.502,21.819 -100.91,10.404 -117.06,-25.5 -16.152,-35.904 10.092,-82.712 58.594,-104.53 16.672,-7.5002 33.785,-11.062 49.75,-11.062 z" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 617.23751,447.18125 c 0,8.15807 0,16.31615 0,24.47422 -183.15789,0.44938 -366.31952,-0.41696 -549.463789,-2.70971 0,-7.86645 0,-15.7329 0,-23.59935 183.153709,0.85574 366.308879,1.326 549.463789,1.83484 z"
+ id="path3287-6-5"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 617.23751,267.23326 c 0,8.15827 0,16.31653 0,24.4748 -183.15789,0.44939 -366.31952,-0.41697 -549.463789,-2.70977 0,-7.86663 0,-15.73327 0,-23.5999 183.153709,0.85574 366.308879,1.32599 549.463789,1.83487 z"
+ id="path3287-6-6"
+ inkscape:connector-curvature="0" />
+</svg>
diff --git a/src/activities/piano_composition/resource/trebleE3Quarter.svg b/src/activities/piano_composition/resource/trebleE3Quarter.svg
new file mode 100644
index 000000000..2d22a0fa4
--- /dev/null
+++ b/src/activities/piano_composition/resource/trebleE3Quarter.svg
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg2"
+ viewBox="0 0 744 1052"
+ version="1.1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="trebleE3Quarter.svg">
+ <defs
+ id="defs9" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ id="namedview7"
+ showgrid="false"
+ inkscape:zoom="0.43502872"
+ inkscape:cx="513.36151"
+ inkscape:cy="369.23983"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <metadata
+ id="metadata5">
+ <rdf:RDF>
+ <cc:Work>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://openclipart.org/">
+ <dc:title>Openclipart</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:title></dc:title>
+ <dc:date>2011-05-27T21:51:50</dc:date>
+ <dc:description>There didn't seem to be a whole note on openclipart already. Here is a big one!</dc:description>
+ <dc:source>https://openclipart.org/detail/140893/whole-note-by-10binary</dc:source>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>10binary</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>music</rdf:li>
+ <rdf:li>notation</rdf:li>
+ <rdf:li>note</rdf:li>
+ <rdf:li>whole</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Edited by Timothée Giet for GCompris</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 617.23751,629.20386 c 0,8.15934 0,16.31868 0,24.47802 -183.1579,0.44944 -366.31952,-0.41701 -549.463789,-2.71012 0,-7.86767 0,-15.73535 0,-23.60302 183.153709,0.85593 366.308879,1.32618 549.463789,1.83512 z"
+ id="path3287-6"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 617.23751,447.18125 c 0,8.15807 0,16.31615 0,24.47422 -183.15789,0.44938 -366.31952,-0.41696 -549.463789,-2.70971 0,-7.86645 0,-15.7329 0,-23.59935 183.153709,0.85574 366.308879,1.326 549.463789,1.83484 z"
+ id="path3287-6-5"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 617.23751,267.23326 c 0,8.15827 0,16.31653 0,24.4748 -183.15789,0.44939 -366.31952,-0.41697 -549.463789,-2.70977 0,-7.86663 0,-15.73327 0,-23.5999 183.153709,0.85574 366.308879,1.32599 549.463789,1.83487 z"
+ id="path3287-6-6"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path3"
+ style="fill:#000000;fill-rule:evenodd;stroke:none;stroke-width:5.92409992;stroke-linecap:round;stroke-linejoin:round;fill-opacity:1"
+ d="m 421.77912,233.28546 c 5.3071,163.8 3.0093,316.18 0.55337,483.27 -1.2461,42.809 -38.247,71.529 -72.88,89.908 -30.854,18.567 -67.795,28.966 -103.61,20.691 -33.304,-3.4173 -67.756,-27.73 -68.454,-63.704 -2.2204,-41.711 27.904,-80.552 64.988,-97.024 36.404,-20.749 82.429,-25.246 121.63,-10.331 19.156,6.0549 24.483,-11.721 26.874,-28.819 2.2123,-129.77 3.9829,-259.54 4.4354,-389.33 0.36593,-12.973 26.294,-17.166 26.461,-4.6603 z" />
+</svg>
diff --git a/src/activities/piano_composition/resource/trebleE3Whole.svg b/src/activities/piano_composition/resource/trebleE3Whole.svg
new file mode 100644
index 000000000..aa5a7d5df
--- /dev/null
+++ b/src/activities/piano_composition/resource/trebleE3Whole.svg
@@ -0,0 +1,198 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg2"
+ viewBox="0 0 744 1052"
+ version="1.1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="trebleE3Whole.svg"
+ width="744"
+ height="1052">
+ <defs
+ id="defs9">
+ <linearGradient
+ id="linearGradient3019"
+ y2="333.89001"
+ gradientUnits="userSpaceOnUse"
+ x2="490.53"
+ gradientTransform="matrix(2.0779,0,0,2.0779,-518.08,-281.8)"
+ y1="489.14001"
+ x1="382.34">
+ <stop
+ id="stop3015"
+ style="stop-color:#000000;stop-opacity:.82639"
+ offset="0" />
+ <stop
+ id="stop3017"
+ style="stop-color:#000000"
+ offset="1" />
+ </linearGradient>
+ <inkscape:perspective
+ id="perspective3348"
+ inkscape:persp3d-origin="0.50006349 : 0.33344809 : 1"
+ inkscape:vp_z="1.000127 : 0.50017214 : 1"
+ inkscape:vp_y="0 : 0.95057034 : 0"
+ inkscape:vp_x="0 : 0.50017214 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 0.00047528517 : 1"
+ inkscape:vp_y="0 : 0.95057034 : 0"
+ inkscape:vp_z="0.001344086 : 0.00047528517 : 1"
+ inkscape:persp3d-origin="0.00067204301 : 0.00031685678 : 1"
+ id="perspective2844" />
+ <inkscape:perspective
+ id="perspective3348-6"
+ inkscape:persp3d-origin="0.50006349 : 0.33344809 : 1"
+ inkscape:vp_z="1.000127 : 0.50017214 : 1"
+ inkscape:vp_y="0 : 0.95057034 : 0"
+ inkscape:vp_x="0 : 0.50017214 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 0.00047528517 : 1"
+ inkscape:vp_y="0 : 0.95057034 : 0"
+ inkscape:vp_z="0.001344086 : 0.00047528517 : 1"
+ inkscape:persp3d-origin="0.00067204301 : 0.00031685678 : 1"
+ id="perspective2844-7" />
+ <inkscape:perspective
+ id="perspective3348-3"
+ inkscape:persp3d-origin="0.50006349 : 0.33344809 : 1"
+ inkscape:vp_z="1.000127 : 0.50017214 : 1"
+ inkscape:vp_y="0 : 0.95057034 : 0"
+ inkscape:vp_x="0 : 0.50017214 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 0.00047528517 : 1"
+ inkscape:vp_y="0 : 0.95057034 : 0"
+ inkscape:vp_z="0.001344086 : 0.00047528517 : 1"
+ inkscape:persp3d-origin="0.00067204301 : 0.00031685678 : 1"
+ id="perspective2844-6" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 0.50017214 : 1"
+ inkscape:vp_y="0 : 0.95057034 : 0"
+ inkscape:vp_z="1.000127 : 0.50017214 : 1"
+ inkscape:persp3d-origin="0.50006349 : 0.33344809 : 1"
+ id="perspective3348-35" />
+ <inkscape:perspective
+ id="perspective2844-62"
+ inkscape:persp3d-origin="0.00067204301 : 0.00031685678 : 1"
+ inkscape:vp_z="0.001344086 : 0.00047528517 : 1"
+ inkscape:vp_y="0 : 0.95057034 : 0"
+ inkscape:vp_x="0 : 0.00047528517 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 0.50017214 : 1"
+ inkscape:vp_y="0 : 0.95057034 : 0"
+ inkscape:vp_z="1.000127 : 0.50017214 : 1"
+ inkscape:persp3d-origin="0.50006349 : 0.33344809 : 1"
+ id="perspective3348-6-9" />
+ <inkscape:perspective
+ id="perspective2844-7-1"
+ inkscape:persp3d-origin="0.00067204301 : 0.00031685678 : 1"
+ inkscape:vp_z="0.001344086 : 0.00047528517 : 1"
+ inkscape:vp_y="0 : 0.95057034 : 0"
+ inkscape:vp_x="0 : 0.00047528517 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ </defs>
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ id="namedview7"
+ showgrid="false"
+ inkscape:zoom="0.43502872"
+ inkscape:cx="513.36151"
+ inkscape:cy="691.72367"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 289.29484,644.77518 c 66.94384,0.69882 130.26832,30.04918 135.09143,95.04169 3.61532,47.53718 -50.66281,90.84313 -117.60261,90.84313 -67.54773,-0.69977 -130.26832,-29.34803 -135.69532,-94.31861 -3.61814,-48.26027 51.22644,-91.56621 118.2065,-91.56621 z m 16.2456,169.81361 c 28.94793,0 47.64333,-32.1676 44.62788,-58.00095 -6.634,-51.01266 -21.71125,-92.26597 -61.5128,-92.26597 -28.94793,0 -45.83567,32.8445 -42.21632,58.70071 6.67143,51.03599 19.33633,91.56621 59.10124,91.56621 z"
+ style="fill:#000000;stroke-width:0.43337601;stroke:none"
+ id="path270" />
+ <metadata
+ id="metadata5">
+ <rdf:RDF>
+ <cc:Work>
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <cc:license
+ rdf:resource="http://creativecommons.org/publicdomain/zero/1.0/" />
+ <dc:publisher>
+ <cc:Agent
+ rdf:about="http://openclipart.org/">
+ <dc:title>Openclipart</dc:title>
+ </cc:Agent>
+ </dc:publisher>
+ <dc:title></dc:title>
+ <dc:date>2011-05-27T21:51:50</dc:date>
+ <dc:description>There didn't seem to be a whole note on openclipart already. Here is a big one!</dc:description>
+ <dc:source>https://openclipart.org/detail/140893/whole-note-by-10binary</dc:source>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>10binary</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:subject>
+ <rdf:Bag>
+ <rdf:li>music</rdf:li>
+ <rdf:li>notation</rdf:li>
+ <rdf:li>note</rdf:li>
+ <rdf:li>whole</rdf:li>
+ </rdf:Bag>
+ </dc:subject>
+ <dc:contributor>
+ <cc:Agent>
+ <dc:title>Edited by Timothée Giet for GCompris</dc:title>
+ </cc:Agent>
+ </dc:contributor>
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/publicdomain/zero/1.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 538.23806,267.23021 c 0,8.15935 0,16.31869 0,24.47804 -160.15837,0.44943 -320.321,-0.41706 -480.463788,-2.71013 0,-7.86768 0,-15.73535 0,-23.60303 160.153578,0.85584 320.308828,1.32618 480.463788,1.83512 z"
+ id="path3287-6"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 538.23806,447.18132 c 0,8.15829 0,16.31659 0,24.47488 -160.15837,0.44936 -320.321,-0.41698 -480.463788,-2.70977 0,-7.86666 0,-15.73333 0,-23.59999 160.153578,0.85571 320.308828,1.32601 480.463788,1.83488 z"
+ id="path3287-6-3"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:0;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 538.23806,627.98309 c 0,8.15935 0,16.31869 0,24.47804 -160.15837,0.44942 -320.321,-0.41704 -480.463788,-2.71013 0,-7.86768 0,-15.73535 0,-23.60303 160.153578,0.85589 320.308828,1.3262 480.463788,1.83512 z"
+ id="path3287-6-6"
+ inkscape:connector-curvature="0" />
+</svg>
diff --git a/src/activities/piano_composition/resource/undo.svg b/src/activities/piano_composition/resource/undo.svg
new file mode 100644
index 000000000..f066b1b2e
--- /dev/null
+++ b/src/activities/piano_composition/resource/undo.svg
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="42"
+ height="42"
+ id="svg3930"
+ sodipodi:docname="undo.svg"
+ inkscape:version="0.92.1 r15371">
+ <sodipodi:namedview
+ pagecolor="#a5a5a5"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ id="namedview10"
+ showgrid="false"
+ inkscape:zoom="4.9166667"
+ inkscape:cx="-60.406779"
+ inkscape:cy="24"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg3930" />
+ <defs
+ id="defs3932" />
+ <metadata
+ id="metadata3935">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ <dc:date>2018</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Timothée Giet</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <circle
+ style="overflow:visible;opacity:1;vector-effect:none;fill:#eef1f7;fill-opacity:1;stroke:none;stroke-width:9;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path826"
+ cx="21"
+ cy="21"
+ r="18" />
+ <path
+ style="overflow:visible;opacity:1;vector-effect:none;fill:#df543d;fill-opacity:1;stroke:none;stroke-width:11.42506504;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ d="M 21 1 A 20 20 0 0 0 1 21 A 20 20 0 0 0 21 41 A 20 20 0 0 0 41 21 A 20 20 0 0 0 21 1 z M 21 4 A 17 17 0 0 1 38 21 A 17 17 0 0 1 21 38 A 17 17 0 0 1 4 21 A 17 17 0 0 1 21 4 z "
+ id="path837" />
+ <g
+ transform="matrix(0.83333333,0,0,0.83333333,1.0000001,-835.9685)"
+ id="layer1"
+ style="fill:#df543d;fill-opacity:1">
+ <g
+ transform="translate(-792,300.3622)"
+ id="g4784"
+ style="display:inline;fill:#df543d;fill-opacity:1">
+ <path
+ d="m 804,718 12,12 h -12 z"
+ id="path4564"
+ style="fill:#df543d;fill-opacity:1;stroke:none"
+ inkscape:connector-curvature="0" />
+ <path
+ d="m 819.53125,715.3125 c -2.67562,0.0197 -5.34109,1.02859 -7.375,3.0625 l -0.0625,0.0625 -5.3125,5.3125 3.53125,3.5625 5.3125,-5.3125 0.0625,-0.0625 c 2.19996,-2.19996 5.56652,-2.21479 7.6875,-0.0937 L 823.53125,722 c 2.12096,2.12097 2.13749,5.48751 -0.0625,7.6875 l -6.53125,6.5 3.5625,3.5625 6.5,-6.5 c 4.06779,-4.06779 4.14248,-10.73256 0.0937,-14.78125 l -0.1875,-0.15625 c -2.02434,-2.02436 -4.69938,-3.01973 -7.375,-3 z m -3.0625,21.375 -2.1875,2.1875 3.53125,3.5625 L 820,740.25 Z m -3.21875,3.25 -1.09375,1.0625 3.53125,3.5625 1.09375,-1.09375 z"
+ id="path4594"
+ style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#df543d;fill-opacity:1;stroke:none;stroke-width:5;marker:none;enable-background:accumulate"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+</svg>
diff --git a/src/activities/piano_composition/resource/wholeRest.svg b/src/activities/piano_composition/resource/wholeRest.svg
new file mode 100644
index 000000000..7e26a3783
--- /dev/null
+++ b/src/activities/piano_composition/resource/wholeRest.svg
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ width="774"
+ height="1052"
+ viewBox="0 0 774 1052"
+ id="svg2"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="wholeRest.svg">
+ <metadata
+ id="metadata10">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ <dc:date>2018</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Timothée Giet</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <defs
+ id="defs8" />
+ <sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ id="namedview6"
+ showgrid="false"
+ inkscape:zoom="0.49166667"
+ inkscape:cx="-35.389833"
+ inkscape:cy="544.80296"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2" />
+ <path
+ style="fill:#000000;stroke-width:0.56839144"
+ d="m 313.81154,553.88415 c -0.20677,-0.21207 -0.37594,-17.82721 -0.37594,-39.14477 v -38.75919 h -27.50088 -27.50087 v -10.36137 -10.36137 h 140.87184 140.87184 v 10.36137 10.36137 H 513.24182 486.3061 l -0.14423,38.99904 -0.14424,38.99903 -85.91507,0.14574 c -47.25329,0.0802 -86.08425,-0.0277 -86.29102,-0.23985 z"
+ id="path812"
+ inkscape:connector-curvature="0" />
+</svg>
diff --git a/src/activities/planegame/ActivityInfo.qml b/src/activities/planegame/ActivityInfo.qml
index 413072f08..aa6e82b54 100644
--- a/src/activities/planegame/ActivityInfo.qml
+++ b/src/activities/planegame/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Johnny Jazeix <jazeix@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "planegame/Sequence.qml"
difficulty: 2
icon: "planegame/planegame.svg"
author: "Johnny Jazeix &lt;jazeix@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Numbers in Order")
//: Help title
description: qsTr("Move the helicopter to catch the clouds in the correct order")
// intro: "Move the helicopter with the arrow keys and catch the numbers in the clouds, in ascending order."
//: Help goal
goal: qsTr("Numeration training")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("Catch the clouds in increasing order. With a keyboard use the arrow keys to move the helicopter. With a pointing device you just click or tap on the target location. To know which number you have to catch you can either remember it or check the bottom right corner.")
credit: ""
section: "math numeration"
createdInVersion: 0
}
diff --git a/src/activities/planegame/Cloud.qml b/src/activities/planegame/Cloud.qml
index 4b37f9bfe..8d85bf781 100644
--- a/src/activities/planegame/Cloud.qml
+++ b/src/activities/planegame/Cloud.qml
@@ -1,115 +1,115 @@
/* gcompris - Cloud.qml
Copyright (C) 2014 Johnny Jazeix <jazeix@gmail.com>
2003, 2014: Bruno Coudoin: initial version
2014: Johnny Jazeix: Qt port
This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "planegame.js" as Activity
import "../../core"
import GCompris 1.0
Image {
id: cloud
property Item background
property alias text: number.text
property double heightRatio: 1
/* An helper property to remember if a cloud has been wrongly touched */
property bool touched: false
sourceSize.height: 60 * ApplicationInfo.ratio
height: sourceSize.height * heightRatio
state: "normal"
fillMode: Image.PreserveAspectFit
z: 5
signal done
signal touch
onDone: {
particles.burst(50)
opacityTimer.start()
}
onTouch: {
touched = true
state = "storm"
}
GCText {
id: number
anchors.horizontalCenter: cloud.horizontalCenter
anchors.verticalCenter: cloud.verticalCenter
color: "black"
font.bold: true
fontSize: 18
}
Component.onCompleted: {
x = -cloud.width - 1
y = Activity.getRandomInt(0, background.height - (cloud.height + Activity.items.bar.height))
}
Behavior on x { PropertyAnimation { duration: 20000 } }
Behavior on opacity { PropertyAnimation { duration: 400 } }
Timer {
id: stormy
interval: 2000;
running: false;
repeat: false
onTriggered: cloud.state = "normal"
}
states: [
State {
name: "normal"
PropertyChanges {
target: cloud
source: Activity.url + "resource/cloud.svg"
}
},
State {
name: "storm"
PropertyChanges {
target: cloud
source: Activity.url + "resource/cloud_storm.svg"
}
StateChangeScript {
script: stormy.start()
}
}
]
Timer {
id: opacityTimer
running: false
repeat: false
interval: 500
onTriggered: opacity = 0
}
ParticleSystemStarLoader {
id: particles
anchors.fill: parent
clip: false
}
}
diff --git a/src/activities/planegame/Plane.qml b/src/activities/planegame/Plane.qml
index 091a08ce5..32db36a90 100644
--- a/src/activities/planegame/Plane.qml
+++ b/src/activities/planegame/Plane.qml
@@ -1,78 +1,78 @@
/* gcompris - Plane.qml
Copyright (C) 2014 Johnny Jazeix <jazeix@gmail.com>
2003, 2014: Bruno Coudoin: initial version
2014: Johnny Jazeix: Qt port
This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "planegame.js" as Activity
import GCompris 1.0
Image {
id: plane
property Item background
property real velocityX
property real velocityY
source: Activity.url + "resource/tuxhelico.svg"
fillMode: Image.PreserveAspectFit
sourceSize.height: 80 * ApplicationInfo.ratio
z: 10
states: [
State {
name: "init"
PropertyChanges {
target: plane
x: 20
y: parent.height / 2 - plane.height / 2
velocityX: 700
velocityY: 700
height: sourceSize.height * (1.0 - 0.5 * Activity.currentLevel / 10)
}
},
State {
name: "play"
PropertyChanges {
target: plane
x: 20
y: parent.height / 2 - plane.height / 2
velocityX: 200
velocityY: 200
height: sourceSize.height * (1.0 - 0.5 * Activity.currentLevel / 10)
}
}
]
Behavior on x {
SmoothedAnimation {
velocity: velocityX * ApplicationInfo.ratio
reversingMode: SmoothedAnimation.Immediate
}
}
Behavior on y {
SmoothedAnimation {
velocity: velocityY * ApplicationInfo.ratio
reversingMode: SmoothedAnimation.Immediate
}
}
Behavior on height { PropertyAnimation { duration: 100 } }
Behavior on rotation { PropertyAnimation { duration: 100 } }
}
diff --git a/src/activities/planegame/Planegame.qml b/src/activities/planegame/Planegame.qml
index 38795ab31..c30d2b425 100644
--- a/src/activities/planegame/Planegame.qml
+++ b/src/activities/planegame/Planegame.qml
@@ -1,150 +1,150 @@
/* gcompris - Planegame.qml
Copyright (C) 2014 Johnny Jazeix <jazeix@gmail.com>
2003, 2014: Bruno Coudoin: initial version
2014: Johnny Jazeix: Qt port
This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "planegame.js" as Activity
ActivityBase {
id: activity
focus: true
onStart: { focus = true; }
onStop: { }
Keys.onPressed: Activity.processPressedKey(event)
Keys.onReleased: Activity.processReleasedKey(event)
property var dataset
property int oldWidth: width
onWidthChanged: {
// Reposition helico and clouds, same for height
Activity.repositionObjectsOnWidthChanged(width / oldWidth)
oldWidth = width
}
property int oldHeight: height
onHeightChanged: {
// Reposition helico and clouds, same for height
Activity.repositionObjectsOnHeightChanged(height / oldHeight)
oldHeight = height
}
pageComponent: Image {
id: background
anchors.fill: parent
signal start
signal stop
source: Activity.url + "../algorithm/resource/desert_scene.svg"
sourceSize.width: parent.width
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
QtObject {
id: items
property alias background: background
property alias bar: bar
property alias bonus: bonus
property alias score: score
property alias plane: plane
property GCAudio audioVoices: activity.audioVoices
property GCSfx audioEffects: activity.audioEffects
property alias movePlaneTimer: movePlaneTimer
property alias cloudCreation: cloudCreation
}
onStart: Activity.start(items, dataset)
onStop: Activity.stop();
MultiPointTouchArea {
anchors.fill: parent
touchPoints: [ TouchPoint { id: point1 } ]
onReleased: {
plane.x = point1.x - plane.width / 2
plane.y = point1.y - plane.height / 2
}
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level }
onHelpClicked: displayDialog(dialogHelp)
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
}
Bonus {
id: bonus
Component.onCompleted: win.connect(Activity.nextLevel)
}
Score {
id: score
visible: false
- fontSize: background.width > background.height ? internalTextComponent.largeSize : internalTextComponent.mediumSize
+ fontSize: background.width >= background.height ? internalTextComponent.largeSize : internalTextComponent.mediumSize
height: internalTextComponent.height + 10
anchors.bottom: bar.top
anchors.margins: 10
}
property int movePlaneTimerCounter: 0
Timer {
id: movePlaneTimer
running: false
repeat: true
onTriggered: {
plane.state = "play"
interval = 50
if(movePlaneTimerCounter++ % 3 == 0) {
/* Do not call this too often or plane commands are too hard */
Activity.handleCollisionsWithCloud();
}
Activity.computeVelocity();
Activity.planeMove();
}
}
Timer {
id: cloudCreation
running: false
repeat: true
interval: 10200 - (bar.level * 200)
onTriggered: Activity.createCloud()
}
Plane {
id: plane
background: background
}
}
}
diff --git a/src/activities/planegame/Sequence.qml b/src/activities/planegame/Sequence.qml
index 3100697de..21fe0299a 100644
--- a/src/activities/planegame/Sequence.qml
+++ b/src/activities/planegame/Sequence.qml
@@ -1,43 +1,43 @@
-/* GCompris - Score.qml
+/* GCompris - Sequence.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
Planegame {
dataset: [
{
data: "0 1 2 3 4 5 6 7 8 9 10".split(" "),
showNext: true
},
{
data: "10 11 12 13 14 15 16 17 18 19 20".split(" "),
showNext: true
},
{
data: "0 1 2 3 4 5 6 7 8 9 10".split(" "),
showNext: false
},
{
data: "10 11 12 13 14 15 16 17 18 19 20".split(" "),
showNext: false
}
]
}
diff --git a/src/activities/planegame/planegame.js b/src/activities/planegame/planegame.js
index d43e261f3..67c280079 100644
--- a/src/activities/planegame/planegame.js
+++ b/src/activities/planegame/planegame.js
@@ -1,333 +1,333 @@
/*
gcompris - planegame.js
Copyright (C)
2003, 2014: Bruno Coudoin: initial version
2014: Johnny Jazeix: Qt port
2014: Bruno Coudoin: Added support for dataset, smooth plane anim
This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
.import GCompris 1.0 as GCompris //for ApplicationInfo
.import "qrc:/gcompris/src/core/core.js" as Core
var url = "qrc:/gcompris/src/activities/planegame/"
var max_velocity = 500 * GCompris.ApplicationInfo.ratio
var currentLevel
var numberOfLevel
var currentSubLevel
var numberOfSubLevels
var upPressed
var downPressed
var leftPressed
var rightPressed
var items
var dataset
var cloudComponent = Qt.createComponent(url + "Cloud.qml");
var clouds = new Array;
var cloudsErased = new Array;
function start(items_, dataset_) {
Core.checkForVoices(items_.background);
items = items_
dataset = dataset_
numberOfLevel = dataset.length
currentLevel = 0
initLevel()
}
function stop() {
cloudDestroy(clouds)
cloudDestroy(cloudsErased)
items.movePlaneTimer.stop()
items.cloudCreation.stop()
}
function cloudDestroy(clouds) {
for(var i = clouds.length - 1; i >= 0 ; --i) {
var cloud = clouds[i];
// Remove the cloud
cloud.destroy()
// Remove the element from the list
clouds.splice(i, 1)
}
}
function initLevel() {
items.bar.level = currentLevel + 1;
currentSubLevel = 0
numberOfSubLevels = dataset[currentLevel].data.length
items.movePlaneTimer.stop();
items.cloudCreation.stop()
items.score.visible = dataset[currentLevel].showNext
items.score.message = dataset[currentLevel].data[currentSubLevel]
upPressed = false
downPressed = false
leftPressed = false
rightPressed = false
cloudDestroy(clouds)
cloudDestroy(cloudsErased)
// Tend towards 0.5 ratio
items.plane.state = "init"
items.movePlaneTimer.interval = 1000
items.movePlaneTimer.start();
items.cloudCreation.start()
// Inject the first cloud now
createCloud()
}
function nextLevel() {
if(numberOfLevel <= ++currentLevel) {
currentLevel = 0
}
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
initLevel();
}
function repositionObjectsOnWidthChanged(factor) {
if(items && items.plane) {
items.movePlaneTimer.interval = 1000
items.plane.state = "init"
}
for(var i = clouds.length - 1; i >= 0 ; --i) {
var cloud = clouds[i];
}
}
function repositionObjectsOnHeightChanged(factor) {
if(items && items.plane) {
items.movePlaneTimer.interval = 1000
items.plane.state = "init"
}
for(var i = clouds.length - 1; i >= 0 ; --i) {
var cloud = clouds[i];
cloud.y *= factor
}
}
var cloudCounter = 1
function createCloud() {
var cloud = cloudComponent.createObject(
items.background, {
"background": items.background,
"x": items.background.width,
"heightRatio": 1.0 - 0.5 * currentLevel / 10
});
/* Random cloud number but at least one in 3 */
if(cloudCounter++ % 3 == 0 || getRandomInt(0, 1) === 0) {
/* Put the target */
cloud.text = dataset[currentLevel].data[currentSubLevel];
cloudCounter = 1
} else {
var min = Math.max(1, currentSubLevel - 1);
var index = Math.min(min + getRandomInt(0, currentSubLevel - min + 3),
numberOfSubLevels - 1)
cloud.text = dataset[currentLevel].data[index]
}
clouds.push(cloud);
}
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
function processPressedKey(event) {
switch(event.key) {
case Qt.Key_Right:
rightPressed = true;
event.accepted = true;
break;
case Qt.Key_Left:
leftPressed = true;
event.accepted = true;
break;
case Qt.Key_Up:
upPressed = true;
event.accepted = true;
break;
case Qt.Key_Down:
downPressed = true;
event.accepted = true;
}
}
function processReleasedKey(event) {
switch(event.key) {
case Qt.Key_Right:
rightPressed = false;
event.accepted = true;
break;
case Qt.Key_Left:
leftPressed = false;
event.accepted = true;
break;
case Qt.Key_Up:
upPressed = false;
event.accepted = true;
break;
case Qt.Key_Down:
downPressed = false;
event.accepted = true;
}
}
var speedX = 0
var speedY = 0
var speedFactor = 20
function computeVelocity() {
if(rightPressed && speedX < 300)
speedX += speedFactor
if(leftPressed && speedX > -300)
speedX -= speedFactor
if(!rightPressed && speedX > 0)
speedX = 0
else if(!leftPressed && speedX < 0)
speedX = 0
else if(leftPressed || rightPressed)
items.plane.x += speedX
if(upPressed && speedY > -300)
speedY -= speedFactor
if(downPressed && speedY < 300)
speedY += speedFactor
if(!upPressed && speedY < 0)
speedY = 0
else if(!downPressed && speedY > 0)
speedY = 0
else if(upPressed || downPressed)
items.plane.y += speedY
items.plane.rotation = speedX * 10 / max_velocity
}
/* We move x/y of the plane to let its smooth animation track it */
function planeMove() {
if(items.plane.x + items.plane.width > items.background.width) {
items.plane.x = items.background.width - items.plane.width;
}
if(items.plane.x < 0) {
items.plane.x = 0;
}
if(items.plane.y < 0) {
items.plane.y = 0;
}
if(items.plane.y + items.plane.height > items.background.height - items.bar.height) {
items.plane.y = items.background.height - (items.plane.height + items.bar.height);
}
}
function isIn(x1, y1, px1, py1, px2, py2) {
return (x1>px1 && x1<px2 && y1>py1 && y1<py2)
}
function handleCollisionsWithCloud() {
var planeX1 = items.plane.x
var planeX2 = items.plane.x + items.plane.width
var planeY1 = items.plane.y
var planeY2 = items.plane.y + items.plane.height
var gotOne = false
if(clouds !== undefined) {
for(var i = clouds.length - 1; i >= 0 ; --i) {
var cloud = clouds[i];
var x1 = cloud.x
var x2 = cloud.x + cloud.width
var y1 = cloud.y
var y2 = cloud.y + cloud.height
if(x2 < 0) {
// Remove the cloud
cloud.destroy()
clouds.splice(i, 1)
}
else if(isIn(x1, y1, planeX1, planeY1, planeX2, planeY2) ||
isIn(x2, y1, planeX1, planeY1, planeX2, planeY2) ||
isIn(x1, y2, planeX1, planeY1, planeX2, planeY2) ||
isIn(x2, y2, planeX1, planeY1, planeX2, planeY2)) {
gotOne = true
// Collision, look for id
if(cloud.text === dataset[currentLevel].data[currentSubLevel]) {
playLetterSound(cloud.text)
// Move the cloud to the erased list
cloud.done()
cloudsErased.push(cloud)
clouds.splice(i, 1)
currentSubLevel++
if(currentSubLevel === numberOfSubLevels) {
/* Try the next level */
items.bonus.good("flower")
} else {
items.score.message = dataset[currentLevel].data[currentSubLevel]
}
} else {
/* Touched the wrong cloud */
if(!cloud.touched)
items.audioEffects.play("qrc:/gcompris/src/core/resource/sounds/crash.wav")
cloud.touch()
}
break;
}
}
// Reset the touched state on the clouds
if(!gotOne) {
for(var i = clouds.length - 1; i >= 0 ; --i) {
clouds[i].touched = false
}
}
}
}
function playLetterSound(number) {
if(number > 9)
items.audioVoices.play(GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/"
+ number + ".$CA"))
else
items.audioVoices.play(
GCompris.ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/alphabet/"
+ Core.getSoundFilenamForChar(number)))
}
diff --git a/tools/menus/play_piano.qml b/src/activities/play_piano/ActivityInfo.qml
similarity index 50%
rename from tools/menus/play_piano.qml
rename to src/activities/play_piano/ActivityInfo.qml
index 610d1f6db..723aeca1a 100644
--- a/tools/menus/play_piano.qml
+++ b/src/activities/play_piano/ActivityInfo.qml
@@ -1,55 +1,44 @@
/* GCompris - ActivityInfo.qml
*
- * Copyright (C) 2015 Your Name <yy@zz.org>
+ * Copyright (C) 2018 Aman Kumar Gupta <gupta2140@gmail.com>
+ *
+ * Authors:
+ * Beth Hadley <bethmhadley@gmail.com> (GTK+ version)
+ * Aman Kumar Gupta <gupta2140@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "play_piano/PlayPiano.qml"
- difficulty: 2
+ difficulty: 1
icon: "play_piano/play_piano.svg"
- author: "Beth Hadley &lt;bethmhadley@gmail.com&gt;"
+ author: "Aman Kumar Gupta &lt;gupta2140@gmail.com&gt;"
demo: true
- title: qsTr("Play Piano!")
- description: qsTr("Learn to play melodies on the piano keyboard!")
+ //: Activity title
+ title: qsTr("Play piano")
+ //: Help title
+ description: ""
+ //intro: "Click on the keyboard keys that match the notes that you see and hear"
+ //: Help goal
goal: qsTr("Understand how the piano keyboard can play music as written on the musical staff.")
+ //: Help prerequisite
prerequisite: qsTr("Knowledge of musical notation and musical staff. Play the activity named 'Piano Composition' first.")
- manual: qsTr("The notes you see will be played to you. Click on the corresponding keys on the keyboard that match the notes you hear and see. All levels except for the last have the notes colored so you can match the notes to the keyboard colors. Each level increases in difficulty by adding more notes. Levels 1-6 test the treble clef, levels 7-12 test the bass clef. When you get five points, you move onto the next level (incorrect answers deduct points, correct answers add points).
-
-The following keyboard bindings work in this game:
-- backspace: erase attempt
-- delete: erase attempt
-- enter/return: OK button
-- space bar: play
-- number keys:
- - 1: C
- - 2: D
- - 3: E
- - 4: F
- - 5: G
- - 6: A
- - 7: B
- - 8: C (higher octave)
- - etc.
- - F1: C# / Db
- - F2: D# / Eb
- - F3: F# / Gb
- - F4: G# / Ab
- - F5: A# / Bb
-")
- credit: qsTr("Bruno Coudoin for his mentorship.")
- section: "/discovery/sound_group"
+ //: Help manual
+ manual: qsTr("The notes you see will be played to you. Click on the corresponding keys on the keyboard that match the notes you hear and see.<br>Levels 1-5 will offer treble clef to practice and levels 6-10 will offer bass clef.")
+ credit: qsTr("The synthesizer original code is https://github.com/vsr83/miniSynth")
+ section: "discovery sound_group"
+ createdInVersion: 9500
}
diff --git a/src/activities/play_piano/CMakeLists.txt b/src/activities/play_piano/CMakeLists.txt
new file mode 100644
index 000000000..6c4f577ae
--- /dev/null
+++ b/src/activities/play_piano/CMakeLists.txt
@@ -0,0 +1 @@
+GCOMPRIS_ADD_RCC(activities/play_piano *.qml *.svg *.js *.json resource/*)
diff --git a/src/activities/play_piano/PlayPiano.qml b/src/activities/play_piano/PlayPiano.qml
new file mode 100644
index 000000000..ffb41c7e8
--- /dev/null
+++ b/src/activities/play_piano/PlayPiano.qml
@@ -0,0 +1,331 @@
+/* GCompris - PlayPiano.qml
+ *
+ * Copyright (C) 2018 Aman Kumar Gupta <gupta2140@gmail.com>
+ *
+ * Authors:
+ * Beth Hadley <bethmhadley@gmail.com> (GTK+ version)
+ * Aman Kumar Gupta <gupta2140@gmail.com> (Qt Quick port)
+ *
+ * This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+ */
+import QtQuick 2.6
+import QtQuick.Controls 1.5
+import GCompris 1.0
+
+import "../../core"
+import "../piano_composition"
+import "play_piano.js" as Activity
+
+ActivityBase {
+ id: activity
+
+ onStart: focus = true
+ onStop: {}
+ isMusicalActivity: true
+
+ property bool horizontalLayout: width >= height * 1.2
+
+ pageComponent: Rectangle {
+ id: background
+ anchors.fill: parent
+ color: "#ABCDEF"
+ signal start
+ signal stop
+
+ Component.onCompleted: {
+ activity.start.connect(start)
+ activity.stop.connect(stop)
+ }
+
+ Keys.onPressed: {
+ var keyboardBindings = {}
+ keyboardBindings[Qt.Key_1] = 0
+ keyboardBindings[Qt.Key_2] = 1
+ keyboardBindings[Qt.Key_3] = 2
+ keyboardBindings[Qt.Key_4] = 3
+ keyboardBindings[Qt.Key_5] = 4
+ keyboardBindings[Qt.Key_6] = 5
+ keyboardBindings[Qt.Key_7] = 6
+ keyboardBindings[Qt.Key_8] = 7
+ keyboardBindings[Qt.Key_F1] = 1
+ keyboardBindings[Qt.Key_F2] = 2
+ keyboardBindings[Qt.Key_F3] = 3
+ keyboardBindings[Qt.Key_F4] = 4
+ keyboardBindings[Qt.Key_F5] = 5
+
+ if(piano.whiteKeysEnabled && !iAmReady.visible) {
+ if(event.key >= Qt.Key_1 && event.key <= Qt.Key_8) {
+ piano.keyRepeater.itemAt(keyboardBindings[event.key]).whiteKey.keyPressed()
+ }
+ else if(event.key >= Qt.Key_F1 && event.key <= Qt.Key_F5) {
+ if(piano.blackKeysEnabled)
+ findBlackKey(keyboardBindings[event.key])
+ }
+ else if(event.key === Qt.Key_Space) {
+ multipleStaff.play()
+ }
+ else if(event.key === Qt.Key_Backspace || event.key === Qt.Key_Delete) {
+ Activity.undoPreviousAnswer()
+ }
+ }
+ }
+
+ function findBlackKey(keyNumber) {
+ for(var i = 0; keyNumber; i++) {
+ if(piano.keyRepeater.itemAt(i) === undefined)
+ break
+ if(piano.keyRepeater.itemAt(i).blackKey.visible)
+ keyNumber--
+ if(keyNumber === 0)
+ piano.keyRepeater.itemAt(i).blackKey.keyPressed()
+ }
+ }
+
+ // Add here the QML items you need to access in javascript
+ QtObject {
+ id: items
+ property Item main: activity.main
+ property alias background: background
+ property GCSfx audioEffects: activity.audioEffects
+ property alias multipleStaff: multipleStaff
+ property alias piano: piano
+ property alias bar: bar
+ property alias bonus: bonus
+ property alias score: score
+ property alias iAmReady: iAmReady
+ property alias introductoryAudioTimer: introductoryAudioTimer
+ property alias parser: parser
+ property string mode: "coloredNotes"
+ }
+
+ onStart: {
+ dialogActivityConfig.getInitialConfiguration()
+ Activity.start(items)
+ }
+ onStop: { Activity.stop() }
+
+ property string clefType: (items.bar.level <= 5) ? "Treble" : "Bass"
+
+ Timer {
+ id: introductoryAudioTimer
+ interval: 4000
+ onRunningChanged: {
+ if(running)
+ Activity.isIntroductoryAudioPlaying = true
+ else {
+ Activity.isIntroductoryAudioPlaying = false
+ Activity.initSubLevel()
+ }
+ }
+ }
+
+ JsonParser {
+ id: parser
+ }
+
+ Rectangle {
+ anchors.fill: parent
+ color: "black"
+ opacity: 0.3
+ visible: iAmReady.visible
+ z: 10
+ MouseArea {
+ anchors.fill: parent
+ }
+ }
+
+ ReadyButton {
+ id: iAmReady
+ focus: true
+ z: 10
+ onClicked: {
+ Activity.initLevel()
+ }
+ }
+
+ Score {
+ id: score
+ anchors.top: background.top
+ anchors.bottom: undefined
+ numberOfSubLevels: 5
+ width: horizontalLayout ? parent.width / 10 : (parent.width - instruction.x - instruction.width - 1.5 * anchors.rightMargin)
+ }
+
+ Rectangle {
+ id: instruction
+ radius: 10
+ width: background.width * 0.6
+ height: background.height / 9
+ anchors.horizontalCenter: parent.horizontalCenter
+ opacity: 0.8
+ border.width: 6
+ color: "white"
+ border.color: "#87A6DD"
+
+ GCText {
+ color: "black"
+ z: 3
+ anchors.fill: parent
+ anchors.rightMargin: parent.width * 0.02
+ anchors.leftMargin: parent.width * 0.02
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ fontSizeMode: Text.Fit
+ wrapMode: Text.WordWrap
+ text: qsTr("Click on the piano keys that match the given notes.")
+ }
+ }
+
+ MultipleStaff {
+ id: multipleStaff
+ width: horizontalLayout ? parent.width * 0.5 : parent.width * 0.8
+ height: horizontalLayout ? parent.height * 0.85 : parent.height * 0.58
+ nbStaves: 1
+ clef: clefType
+ coloredNotes: (items.mode === "coloredNotes") ? ['C', 'D', 'E', 'F', 'G', 'A', 'B'] : []
+ isFlickable: false
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.top: instruction.bottom
+ anchors.topMargin: horizontalLayout ? parent.height * 0.02 : parent.height * 0.15
+ onNoteClicked: {
+ playNoteAudio(musicElementModel.get(noteIndex).noteName_, musicElementModel.get(noteIndex).noteType_, musicElementModel.get(noteIndex).soundPitch_)
+ }
+ centerNotesPosition: true
+ }
+
+ PianoOctaveKeyboard {
+ id: piano
+ width: horizontalLayout ? parent.width * 0.5 : parent.width * 0.7
+ height: parent.height * 0.3
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.bottom: bar.top
+ anchors.bottomMargin: 20
+ blackLabelsVisible: ([4, 5, 9, 10].indexOf(items.bar.level) != -1)
+ blackKeysEnabled: blackLabelsVisible && !multipleStaff.isMusicPlaying && !introductoryAudioTimer.running
+ whiteKeysEnabled: !multipleStaff.isMusicPlaying && !introductoryAudioTimer.running
+ whiteKeyNoteLabelsTreble: [ whiteKeyNoteLabelsArray.slice(18, 26) ]
+ whiteKeyNoteLabelsBass: [ whiteKeyNoteLabelsArray.slice(11, 19)]
+ onNoteClicked: {
+ multipleStaff.playNoteAudio(note, "Quarter", clefType, 500)
+ Activity.checkAnswer(note)
+ }
+ useSharpNotation: true
+ }
+
+ Rectangle {
+ id: optionDeck
+ width: optionsRow.changeAccidentalStyleButtonVisible ? optionsRow.iconsWidth * 3.3 : optionsRow.iconsWidth * 2.2
+ height: optionsRow.iconsWidth * 1.1
+ color: "white"
+ opacity: 0.5
+ radius: 10
+ y: horizontalLayout ? piano.y : multipleStaff.y / 2 + instruction.height - height / 2
+ x: horizontalLayout ? multipleStaff.x + multipleStaff.width + 25 : background.width / 2 - width / 2
+ }
+
+ OptionsRow {
+ id: optionsRow
+ anchors.centerIn: optionDeck
+
+ playButtonVisible: true
+ undoButtonVisible: true
+
+ onUndoButtonClicked: Activity.undoPreviousAnswer()
+ }
+
+ ExclusiveGroup {
+ id: configOptions
+ }
+
+ DialogActivityConfig {
+ id: dialogActivityConfig
+ content: Component {
+ Column {
+ id: column
+ spacing: 5
+ width: dialogActivityConfig.width
+ height: dialogActivityConfig.height
+
+ property alias coloredNotesModeBox: coloredNotesModeBox
+ property alias colorlessNotesModeBox: colorlessNotesModeBox
+
+ GCDialogCheckBox {
+ id: coloredNotesModeBox
+ width: column.width - 50
+ text: qsTr("Display colored notes.")
+ checked: items.mode === "coloredNotes"
+ exclusiveGroup: configOptions
+ onCheckedChanged: {
+ if(coloredNotesModeBox.checked) {
+ items.mode = "coloredNotes"
+ }
+ }
+ }
+
+ GCDialogCheckBox {
+ id: colorlessNotesModeBox
+ width: coloredNotesModeBox.width
+ text: qsTr("Display colorless notes.")
+ checked: items.mode === "colorlessNotes"
+ exclusiveGroup: configOptions
+ onCheckedChanged: {
+ if(colorlessNotesModeBox.checked) {
+ items.mode = "colorlessNotes"
+ }
+ }
+ }
+ }
+ }
+ onLoadData: {
+ if(dataToSave && dataToSave["mode"])
+ items.mode = dataToSave["mode"]
+ }
+ onSaveData: dataToSave["mode"] = items.mode
+ onClose: {
+ home()
+ }
+ onVisibleChanged: {
+ multipleStaff.eraseAllNotes()
+ iAmReady.visible = true
+ }
+ }
+
+ DialogHelp {
+ id: dialogHelp
+ onClose: home()
+ }
+
+ Bar {
+ id: bar
+ content: BarEnumContent { value: help | home | level | config | reload }
+ onHelpClicked: displayDialog(dialogHelp)
+ onPreviousLevelClicked: Activity.previousLevel()
+ onNextLevelClicked: Activity.nextLevel()
+ onHomeClicked: activity.home()
+ onConfigClicked: {
+ dialogActivityConfig.active = true
+ displayDialog(dialogActivityConfig)
+ }
+ onReloadClicked: {
+ multipleStaff.eraseAllNotes()
+ iAmReady.visible = true
+ }
+ }
+
+ Bonus {
+ id: bonus
+ Component.onCompleted: win.connect(Activity.nextSubLevel)
+ }
+ }
+}
diff --git a/src/activities/play_piano/dataset.json b/src/activities/play_piano/dataset.json
new file mode 100644
index 000000000..7f5d9232b
--- /dev/null
+++ b/src/activities/play_piano/dataset.json
@@ -0,0 +1,74 @@
+{
+ "levels": [
+ [
+ "Treble E4Quarter C4Quarter E4Quarter",
+ "Treble D4Quarter D4Quarter C4Quarter",
+ "Treble D4Quarter C4Quarter D4Quarter",
+ "Treble D4Quarter E4Quarter E4Quarter",
+ "Treble D4Quarter C4Quarter C4Quarter"
+ ],
+ [
+ "Treble G4Quarter F4Quarter D4Quarter",
+ "Treble E4Quarter A4Quarter A4Quarter",
+ "Treble G4Quarter G4Quarter C4Quarter",
+ "Treble C4Quarter E4Quarter E4Quarter",
+ "Treble E4Quarter C4Quarter C4Quarter"
+ ],
+ [
+ "Treble F4Quarter C4Quarter C4Quarter D4Quarter",
+ "Treble E4Quarter A4Quarter E4Quarter G4Quarter",
+ "Treble G4Quarter F4Quarter A4Quarter B4Quarter",
+ "Treble B4Quarter G4Quarter G4Quarter B4Quarter",
+ "Treble B4Quarter C4Quarter G4Quarter E4Quarter"
+ ],
+ [
+ "Treble D4Quarter C5Quarter C#4Quarter E4Quarter",
+ "Treble G4Quarter A4Quarter A4Quarter B4Quarter",
+ "Treble B4Quarter C4Quarter D4Quarter D4Quarter",
+ "Treble F4Quarter D#4Quarter C#4Quarter A4Quarter",
+ "Treble C#4Quarter B4Quarter B4Quarter E4Quarter"
+ ],
+ [
+ "Treble F#4Quarter D#4Quarter D#4Quarter A#4Quarter",
+ "Treble D4Quarter G4Quarter G4Quarter G4Quarter",
+ "Treble C#4Quarter C5Quarter E4Quarter F4Quarter",
+ "Treble C4Quarter D#4Quarter B4Quarter G#4Quarter",
+ "Treble G#4Quarter G4Quarter A4Quarter C5Quarter"
+ ],
+ [
+ "Bass C3Quarter D3Quarter D3Quarter",
+ "Bass C3Quarter C3Quarter D3Quarter",
+ "Bass D3Quarter D3Quarter D3Quarter",
+ "Bass C3Quarter D3Quarter C3Quarter",
+ "Bass E3Quarter E3Quarter D3Quarter"
+ ],
+ [
+ "Bass D3Quarter A3Quarter F3Quarter",
+ "Bass E3Quarter C3Quarter G3Quarter",
+ "Bass F3Quarter D3Quarter C3Quarter",
+ "Bass F3Quarter G3Quarter D3Quarter",
+ "Bass F3Quarter F3Quarter G3Quarter"
+ ],
+ [
+ "Bass F3Quarter A3Quarter D3Quarter A3Quarter",
+ "Bass E3Quarter G3Quarter A3Quarter A3Quarter",
+ "Bass C3Quarter B3Quarter G3Quarter G3Quarter",
+ "Bass C3Quarter F3Quarter C4Quarter C4Quarter",
+ "Bass F3Quarter C3Quarter B3Quarter E3Quarter"
+ ],
+ [
+ "Bass E3Quarter C4Quarter C#3Quarter B3Quarter",
+ "Bass G3Quarter G3Quarter B3Quarter B3Quarter",
+ "Bass F3Quarter A3Quarter F3Quarter D#3Quarter",
+ "Bass E3Quarter C3Quarter D#3Quarter B3Quarter",
+ "Bass E3Quarter E3Quarter B3Quarter E3Quarter"
+ ],
+ [
+ "Bass G#3Quarter A#3Quarter E3Quarter F3Quarter",
+ "Bass F3Quarter D3Quarter F#3Quarter A#3Quarter",
+ "Bass G#3Quarter G3Quarter C3Quarter G#3Quarter",
+ "Bass C3Quarter C4Quarter C4Quarter D3Quarter",
+ "Bass D#3Quarter C3Quarter C#3Quarter C4Quarter"
+ ]
+ ]
+}
diff --git a/src/activities/play_piano/play_piano.js b/src/activities/play_piano/play_piano.js
new file mode 100644
index 000000000..49fe81c12
--- /dev/null
+++ b/src/activities/play_piano/play_piano.js
@@ -0,0 +1,116 @@
+/* GCompris - play_piano.js
+ *
+ * Copyright (C) 2018 Aman Kumar Gupta <gupta2140@gmail.com>
+ *
+ * Authors:
+ * Beth Hadley <bethmhadley@gmail.com> (GTK+ version)
+ * Aman Kumar Gupta <gupta2140@gmail.com> (Qt Quick port)
+ *
+ * This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+ */
+.pragma library
+.import QtQuick 2.6 as Quick
+.import "qrc:/gcompris/src/core/core.js" as Core
+
+var currentLevel = 0
+var currentSubLevel = 0
+var numberOfLevel = 10
+var noteIndexAnswered
+var items
+var levels
+var incorrectAnswers = []
+var isIntroductoryAudioPlaying = false
+
+function start(items_) {
+ items = items_
+ currentLevel = 0
+ levels = items.parser.parseFromUrl("qrc:/gcompris/src/activities/play_piano/dataset.json").levels
+ items.introductoryAudioTimer.start()
+ initLevel()
+}
+
+function stop() {
+ items.multipleStaff.stopAudios()
+}
+
+function initLevel() {
+ items.bar.level = currentLevel + 1
+ currentSubLevel = 0
+ Core.shuffle(levels[currentLevel])
+ nextSubLevel()
+}
+
+function initSubLevel() {
+ var currentSubLevelMelody = levels[currentLevel][currentSubLevel - 1]
+ noteIndexAnswered = -1
+ items.multipleStaff.loadFromData(currentSubLevelMelody)
+
+ if(!isIntroductoryAudioPlaying && !items.iAmReady.visible)
+ items.multipleStaff.play()
+}
+
+function nextSubLevel() {
+ currentSubLevel++
+ incorrectAnswers = []
+ items.score.currentSubLevel = currentSubLevel
+ if(currentSubLevel > levels[currentLevel].length)
+ nextLevel()
+ else
+ initSubLevel()
+}
+
+function undoPreviousAnswer() {
+ if(noteIndexAnswered >= 0) {
+ items.multipleStaff.revertAnswer(noteIndexAnswered + 1)
+ if(incorrectAnswers.indexOf(noteIndexAnswered) != -1)
+ incorrectAnswers.pop()
+
+ noteIndexAnswered--
+ }
+}
+
+function checkAnswer(noteName) {
+ var currentSubLevelNotes = levels[currentLevel][currentSubLevel - 1].split(' ')
+ if(noteIndexAnswered < (currentSubLevelNotes.length - 2)) {
+ noteIndexAnswered++
+ var currentNote = currentSubLevelNotes[noteIndexAnswered + 1]
+ if((noteName + "Quarter") === currentNote)
+ items.multipleStaff.indicateAnsweredNote(true, noteIndexAnswered + 1)
+ else {
+ incorrectAnswers.push(noteIndexAnswered)
+ items.multipleStaff.indicateAnsweredNote(false, noteIndexAnswered + 1)
+ }
+
+ if(noteIndexAnswered === (currentSubLevelNotes.length - 2)) {
+ if(incorrectAnswers.length === 0)
+ items.bonus.good("flower")
+ else
+ items.bonus.bad("flower")
+ }
+ }
+}
+
+function nextLevel() {
+ if(numberOfLevel <= ++currentLevel) {
+ currentLevel = 0
+ }
+ initLevel()
+}
+
+function previousLevel() {
+ if(--currentLevel < 0) {
+ currentLevel = numberOfLevel - 1
+ }
+ initLevel()
+}
diff --git a/src/activities/play_piano/play_piano.svg b/src/activities/play_piano/play_piano.svg
new file mode 100644
index 000000000..00af7fae3
--- /dev/null
+++ b/src/activities/play_piano/play_piano.svg
@@ -0,0 +1,186 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100"
+ height="100"
+ id="svg2"
+ sodipodi:version="0.32"
+ inkscape:version="0.92.1 r15371"
+ version="1.0"
+ sodipodi:docname="play_piano.svg">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="3.1100436"
+ inkscape:cx="38.064122"
+ inkscape:cy="32.862914"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ width="100px"
+ height="100px"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ showgrid="true"
+ inkscape:window-maximized="1">
+ <inkscape:grid
+ type="xygrid"
+ id="grid904" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ <dc:date>2018</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Timothée Giet</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Calque 1"
+ inkscape:groupmode="layer"
+ id="layer1">
+ <rect
+ style="opacity:1;vector-effect:none;fill:#f2f2f2;fill-opacity:1;stroke:#1e1e1e;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect906-3"
+ width="10"
+ height="50"
+ x="10"
+ y="45"
+ ry="0" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#f2f2f2;fill-opacity:1;stroke:#1e1e1e;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect906-3-5"
+ width="10"
+ height="50"
+ x="20"
+ y="45"
+ ry="0" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#f2f2f2;fill-opacity:1;stroke:#1e1e1e;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect906-3-6"
+ width="10"
+ height="50"
+ x="30"
+ y="45"
+ ry="0" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#f2f2f2;fill-opacity:1;stroke:#1e1e1e;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect906-3-5-2"
+ width="10"
+ height="50"
+ x="40"
+ y="45"
+ ry="0" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#f2f2f2;fill-opacity:1;stroke:#1e1e1e;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect906-3-9"
+ width="10"
+ height="50"
+ x="50"
+ y="45"
+ ry="0" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#f2f2f2;fill-opacity:1;stroke:#1e1e1e;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect906-3-5-1"
+ width="10"
+ height="50"
+ x="60"
+ y="45"
+ ry="0" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#f2f2f2;fill-opacity:1;stroke:#1e1e1e;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect906-3-6-2"
+ width="10"
+ height="50"
+ x="70"
+ y="45"
+ ry="0" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#1e1e1e;fill-opacity:1;stroke:#1e1e1e;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect1010"
+ width="4"
+ height="30"
+ x="18"
+ y="45" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#1e1e1e;fill-opacity:1;stroke:#1e1e1e;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect1010-0"
+ width="4"
+ height="30"
+ x="28"
+ y="45" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#1e1e1e;fill-opacity:1;stroke:#1e1e1e;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect1010-9"
+ width="4"
+ height="30"
+ x="48"
+ y="45" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#1e1e1e;fill-opacity:1;stroke:#1e1e1e;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect1010-0-3"
+ width="4"
+ height="30"
+ x="58"
+ y="45" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#1e1e1e;fill-opacity:1;stroke:#1e1e1e;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect1010-0-3-6"
+ width="4"
+ height="30"
+ x="68"
+ y="45" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:#f2f2f2;fill-opacity:1;stroke:#1e1e1e;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect906-3-0"
+ width="10"
+ height="50"
+ x="80"
+ y="45"
+ ry="0" />
+ </g>
+</svg>
diff --git a/src/activities/play_rhythm/ActivityInfo.qml b/src/activities/play_rhythm/ActivityInfo.qml
new file mode 100644
index 000000000..9e66f147f
--- /dev/null
+++ b/src/activities/play_rhythm/ActivityInfo.qml
@@ -0,0 +1,44 @@
+/* GCompris - ActivityInfo.qml
+ *
+ * Copyright (C) 2018 Aman Kumar Gupta <gupta2140@gmail.com>
+ *
+ * Authors:
+ * Beth Hadley <bethmhadley@gmail.com> (GTK+ version)
+ * Aman Kumar Gupta <gupta2140@gmail.com> (Qt Quick port)
+ *
+ * This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+ */
+import GCompris 1.0
+
+ActivityInfo {
+ name: "play_rhythm/PlayRhythm.qml"
+ difficulty: 1
+ icon: "play_rhythm/play_rhythm.svg"
+ author: "Aman Kumar Gupta &lt;gupta2140@gmail.com&gt;"
+ demo: true
+ //: Activity title
+ title: qsTr("Play rhythm")
+ //: Help title
+ description: ""
+ //intro: "Click the drum to recreate the rhythm"
+ //: Help goal
+ goal: qsTr("Learn to beat rhythms precisely and accurately based on what you see and hear.")
+ //: Help prerequisite
+ prerequisite: qsTr("Simple understanding of musical rhythm and beat.")
+ //: Help manual
+ manual: qsTr("Listen to the rhythm played, and follow along with the music. When you're ready to perform the identical rhythm, click the drum to the rhythm. If you clicked tempo at correct times, another rhythm is displayed. If not, you must try again.<br>Odd levels display a vertical playing line when you click the drum, which helps you see when to click, to follow the rhythm. Click on the drum when the line is in the middle of the notes.<br>Even levels are harder, because there is no vertical playing line. You must read the rhythm, and click it back in tempo. Click the metronome to hear the quarter note tempos.<br>Click on the reload button to replay the rhythm.")
+ credit: ""
+ section: "discovery sound_group"
+ createdInVersion: 9500
+}
diff --git a/src/activities/play_rhythm/CMakeLists.txt b/src/activities/play_rhythm/CMakeLists.txt
new file mode 100644
index 000000000..49a68c23a
--- /dev/null
+++ b/src/activities/play_rhythm/CMakeLists.txt
@@ -0,0 +1 @@
+GCOMPRIS_ADD_RCC(activities/play_rhythm *.qml *.svg *.js resource/*)
diff --git a/src/activities/play_rhythm/PlayRhythm.qml b/src/activities/play_rhythm/PlayRhythm.qml
new file mode 100644
index 000000000..df1a1b14a
--- /dev/null
+++ b/src/activities/play_rhythm/PlayRhythm.qml
@@ -0,0 +1,334 @@
+/* GCompris - PlayRhythm.qml
+ *
+ * Copyright (C) 2018 Aman Kumar Gupta <gupta2140@gmail.com>
+ *
+ * Authors:
+ * Beth Hadley <bethmhadley@gmail.com> (GTK+ version)
+ * Aman Kumar Gupta <gupta2140@gmail.com> (Qt Quick port)
+ *
+ * This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+ */
+import QtQuick 2.6
+import GCompris 1.0
+
+import "../../core"
+import "../piano_composition"
+import "play_rhythm.js" as Activity
+
+ActivityBase {
+ id: activity
+
+ onStart: focus = true
+ onStop: {}
+ isMusicalActivity: true
+
+ property bool horizontalLayout: width >= height
+
+ pageComponent: Rectangle {
+ id: background
+ anchors.fill: parent
+ color: "#ABCDEF"
+
+ signal start
+ signal stop
+
+ Component.onCompleted: {
+ activity.start.connect(start)
+ activity.stop.connect(stop)
+ }
+
+ // Add here the QML items you need to access in javascript
+ QtObject {
+ id: items
+ property Item main: activity.main
+ property GCSfx audioEffects: activity.audioEffects
+ property alias background: background
+ property alias bar: bar
+ property alias bonus: bonus
+ property alias parser: parser
+ property alias score: score
+ property alias multipleStaff: multipleStaff
+ property alias iAmReady: iAmReady
+ property alias introductoryAudioTimer: introductoryAudioTimer
+ property alias metronomeOscillation: metronomeOscillation
+ property bool isMetronomeVisible: false
+ property bool isWrongRhythm: false
+ }
+
+ onStart: { Activity.start(items) }
+ onStop: { Activity.stop() }
+
+ property string clefType: "Treble"
+ property bool isRhythmPlaying: false
+ property int metronomeSpeed: 60000 / multipleStaff.bpmValue - 53
+ property real weightOffset: metronome.height * multipleStaff.bpmValue * 0.004
+
+ Keys.onSpacePressed: if (!background.isRhythmPlaying && !bonus.isPlaying)
+ tempo.tempoPressed()
+
+ Rectangle {
+ id: instructionBox
+ radius: 10
+ width: background.width * 0.7
+ height: background.height / 9
+ anchors.horizontalCenter: parent.horizontalCenter
+ opacity: 0.8
+ border.width: 6
+ color: "white"
+ border.color: "#87A6DD"
+
+ GCText {
+ id: instructionText
+ color: "black"
+ z: 3
+ anchors.fill: parent
+ anchors.rightMargin: parent.width * 0.02
+ anchors.leftMargin: parent.width * 0.02
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ fontSizeMode: Text.Fit
+ wrapMode: Text.WordWrap
+ text: items.isMetronomeVisible ? qsTr("Use the metronome to estimate the time intervals and play the rhythm correctly.")
+ : qsTr("Follow the vertical line and click on the tempo or press space key and play the rhythm correctly.")
+ }
+ }
+
+ Timer {
+ id: introductoryAudioTimer
+ interval: 3500
+ onRunningChanged: {
+ if(running)
+ Activity.isIntroductoryAudioPlaying = true
+ else {
+ Activity.isIntroductoryAudioPlaying = false
+ Activity.initSubLevel()
+ }
+ }
+ }
+
+ JsonParser {
+ id: parser
+ }
+
+ Rectangle {
+ anchors.fill: parent
+ color: "black"
+ opacity: 0.3
+ visible: iAmReady.visible
+ z: 10
+ MouseArea {
+ anchors.fill: parent
+ }
+ }
+
+ ReadyButton {
+ id: iAmReady
+ focus: true
+ z: 10
+ onClicked: {
+ Activity.initLevel()
+ }
+ }
+
+ Score {
+ id: score
+ anchors.top: background.top
+ anchors.bottom: undefined
+ numberOfSubLevels: 3
+ width: horizontalLayout ? parent.width / 10 : (parent.width - instructionBox.x - instructionBox.width - 1.5 * anchors.rightMargin)
+ }
+
+ MultipleStaff {
+ id: multipleStaff
+ width: horizontalLayout ? parent.width * 0.6 : parent.width * 0.9
+ height: horizontalLayout ? parent.height * 1.1 : parent.height * 0.76
+ bpmValue: 90
+ nbStaves: 1
+ clef: clefType
+ isFlickable: false
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.top: parent.top
+ anchors.topMargin: horizontalLayout ? 0 : parent.height * 0.1
+ centerNotesPosition: true
+ firstCenteredNotePosition: width / (2 * (musicElementModel.count - 1))
+ spaceBetweenNotes: width / (2.5 * (musicElementModel.count - 1))
+ enableNotesSound: false
+ onPulseMarkerAnimationFinished: background.isRhythmPlaying = false
+ onPlayDrumSound: {
+ if(background.isRhythmPlaying && !metronomeOscillation.running)
+ GSynth.generate(60, 100)
+ }
+ }
+
+ Image {
+ id: tempo
+ source: "qrc:/gcompris/src/activities/play_rhythm/resource/drumhead.svg"
+ width: horizontalLayout ? parent.width / 7 : parent.width / 4
+ sourceSize.width: width
+ fillMode: Image.PreserveAspectFit
+ anchors.top: metronome.top
+ anchors.horizontalCenter: parent.horizontalCenter
+ transform: Scale {
+ id: tempoScale
+ origin.y: tempo.height
+ yScale: 1
+ SequentialAnimation on yScale {
+ id: tempoAnim
+ PropertyAnimation { to: 0.5; duration: 50 }
+ PropertyAnimation { to: 1; duration: 50 }
+ }
+ }
+ MouseArea {
+ anchors.fill: parent
+ enabled: !background.isRhythmPlaying && !bonus.isPlaying
+ onPressed: tempo.tempoPressed()
+ }
+
+ function tempoPressed() {
+ tempoAnim.start()
+ if(!multipleStaff.isMusicPlaying && Activity.currentNote == 0) {
+ multipleStaff.play()
+ } else if (!multipleStaff.isMusicPlaying && Activity.currentNote > 0){
+ items.bonus.bad("flower")
+ }
+ GSynth.generate(60, 100)
+ Activity.checkAnswer(multipleStaff.pulseMarkerX)
+ }
+ }
+
+ Image {
+ id: metronome
+ source: "qrc:/gcompris/src/activities/play_rhythm/resource/metronome_stand.svg"
+ fillMode: Image.PreserveAspectFit
+ sourceSize.width: parent.width / 3
+ sourceSize.height: parent.height / 4
+ width: sourceSize.width
+ height: sourceSize.height
+ anchors.bottom: bar.top
+ anchors.bottomMargin: 20
+ visible: items.isMetronomeVisible
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ if(metronomeOscillation.running)
+ metronomeOscillation.stop()
+ else
+ metronomeOscillation.start()
+ }
+ }
+
+ Image {
+ id: metronomeNeedle
+ source: "qrc:/gcompris/src/activities/play_rhythm/resource/metronome_needle.svg"
+ fillMode: Image.PreserveAspectFit
+ width: parent.height
+ height: parent.height
+ anchors.centerIn: parent
+ transformOrigin: Item.Bottom
+ SequentialAnimation {
+ id: metronomeOscillation
+ loops: Animation.Infinite
+ onStarted: metronomeNeedle.rotation = 12
+ onStopped: metronomeNeedle.rotation = 0
+ ScriptAction {
+ script: items.audioEffects.play("qrc:/gcompris/src/activities/play_rhythm/resource/click.wav")
+ }
+ RotationAnimator {
+ target: metronomeNeedle
+ from: 12
+ to: 348
+ direction: RotationAnimator.Shortest
+ duration: metronomeSpeed
+ }
+ ScriptAction {
+ script: items.audioEffects.play("qrc:/gcompris/src/activities/play_rhythm/resource/click.wav")
+ }
+ RotationAnimator {
+ target: metronomeNeedle
+ from: 348
+ to: 12
+ direction: RotationAnimator.Shortest
+ duration: metronomeSpeed
+ }
+ }
+ Image {
+ id: metronomeWeight
+ source: "qrc:/gcompris/src/activities/play_rhythm/resource/metronome_weight.svg"
+ fillMode: Image.PreserveAspectFit
+ width: parent.height
+ height: parent.height
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.verticalCenterOffset: weightOffset
+ }
+
+ }
+ Image {
+ id: metronomeFront
+ source: "qrc:/gcompris/src/activities/play_rhythm/resource/metronome_front.svg"
+ fillMode: Image.PreserveAspectFit
+ width: parent.height
+ height: parent.height
+ anchors.centerIn: parent
+ }
+ }
+
+ OptionsRow {
+ id: optionsRow
+ anchors.verticalCenter: tempo.verticalCenter
+ anchors.left: tempo.right
+
+ bpmVisible: true
+ onBpmDecreased: {
+ if(multipleStaff.bpmValue >= 51)
+ multipleStaff.bpmValue--
+ }
+ onBpmIncreased: {
+ if(multipleStaff.bpmValue <= 179)
+ multipleStaff.bpmValue++
+ }
+ onBpmChanged: {
+ Activity.initSubLevel()
+ background.isRhythmPlaying = true
+ }
+ }
+
+ DialogHelp {
+ id: dialogHelp
+ onClose: home()
+ }
+
+ Bar {
+ id: bar
+ content: BarEnumContent { value: help | home | level | reload }
+ onHelpClicked: {
+ displayDialog(dialogHelp)
+ }
+ onPreviousLevelClicked: Activity.previousLevel()
+ onNextLevelClicked: Activity.nextLevel()
+ onHomeClicked: activity.home()
+ onReloadClicked: {
+ Activity.initSubLevel()
+ }
+ }
+
+ Bonus {
+ id: bonus
+ Component.onCompleted: {
+ win.connect(Activity.nextSubLevel)
+ loose.connect(Activity.initSubLevel)
+ }
+ }
+ }
+}
diff --git a/src/activities/play_rhythm/play_rhythm.js b/src/activities/play_rhythm/play_rhythm.js
new file mode 100644
index 000000000..47cbe45d6
--- /dev/null
+++ b/src/activities/play_rhythm/play_rhythm.js
@@ -0,0 +1,112 @@
+/* GCompris - play_rhythm.js
+ *
+ * Copyright (C) 2018 Aman Kumar Gupta <gupta2140@gmail.com>
+ *
+ * Authors:
+ * Beth Hadley <bethmhadley@gmail.com> (GTK+ version)
+ * Aman Kumar Gupta <gupta2140@gmail.com> (Qt Quick port)
+ *
+ * This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+ */
+.pragma library
+.import QtQuick 2.6 as Quick
+.import "qrc:/gcompris/src/core/core.js" as Core
+
+var currentLevel = 0
+var numberOfLevel
+var currentSubLevel = 0
+var currentNote = 0
+var items
+var levels
+var isIntroductoryAudioPlaying = false
+
+function start(items_) {
+ items = items_
+ currentLevel = 0
+ levels = items.parser.parseFromUrl("qrc:/gcompris/src/activities/play_rhythm/resource/dataset.json").levels
+ numberOfLevel = levels.length
+ items.introductoryAudioTimer.start()
+ initLevel()
+}
+
+function stop() {
+ items.metronomeOscillation.stop()
+ items.multipleStaff.stopAudios()
+}
+
+function initLevel() {
+ items.bar.level = currentLevel + 1
+ currentSubLevel = 0
+ Core.shuffle(levels[currentLevel].melodies)
+ items.multipleStaff.isPulseMarkerDisplayed = levels[currentLevel].pulseMarkerVisible
+ items.isMetronomeVisible = levels[currentLevel].metronomeVisible
+ nextSubLevel()
+ currentNote = 0
+}
+
+function nextSubLevel() {
+ currentSubLevel++
+ items.score.currentSubLevel = currentSubLevel
+ if(currentSubLevel > items.score.numberOfSubLevels)
+ nextLevel()
+ else
+ initSubLevel()
+}
+
+function checkAnswer(pulseMarkerX) {
+ currentNote++
+ if(currentNote < items.multipleStaff.musicElementModel.count) {
+ var accuracyLowerLimit = items.multipleStaff.musicElementRepeater.itemAt(currentNote).x
+ var accuracyUpperLimit = accuracyLowerLimit + items.multipleStaff.musicElementRepeater.itemAt(currentNote).width
+ if(pulseMarkerX >= accuracyLowerLimit && pulseMarkerX <= accuracyUpperLimit)
+ items.multipleStaff.indicateAnsweredNote(true, currentNote)
+ else {
+ items.multipleStaff.indicateAnsweredNote(false, currentNote)
+ items.isWrongRhythm = true
+ }
+ }
+ if((currentNote >= items.multipleStaff.musicElementModel.count - 1)) {
+ if(!items.isWrongRhythm)
+ items.bonus.good("flower")
+ else
+ items.bonus.bad("flower")
+ }
+}
+
+function initSubLevel() {
+ items.metronomeOscillation.stop()
+ items.multipleStaff.stopAudios()
+ currentNote = 0
+ var currentSubLevelMelody = levels[currentLevel].melodies[currentSubLevel - 1]
+ items.multipleStaff.loadFromData(currentSubLevelMelody)
+ items.background.isRhythmPlaying = true
+ items.isWrongRhythm = false
+
+ if(!isIntroductoryAudioPlaying && !items.iAmReady.visible)
+ items.multipleStaff.play()
+}
+
+function nextLevel() {
+ if(numberOfLevel <= ++currentLevel) {
+ currentLevel = 0
+ }
+ initLevel()
+}
+
+function previousLevel() {
+ if(--currentLevel < 0) {
+ currentLevel = numberOfLevel - 1
+ }
+ initLevel()
+}
diff --git a/src/activities/play_rhythm/play_rhythm.svg b/src/activities/play_rhythm/play_rhythm.svg
new file mode 100644
index 000000000..db13f949e
--- /dev/null
+++ b/src/activities/play_rhythm/play_rhythm.svg
@@ -0,0 +1,280 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="100"
+ height="100"
+ id="svg2"
+ sodipodi:version="0.32"
+ inkscape:version="0.92.1 r15371"
+ version="1.0"
+ sodipodi:docname="play_rhythm.svg">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="8.7965317"
+ inkscape:cx="69.040063"
+ inkscape:cy="39.415993"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ width="100px"
+ height="100px"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ showgrid="false"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ <dc:date>2018</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Timothée Giet</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Calque 1"
+ inkscape:groupmode="layer"
+ id="layer1">
+ <path
+ style="fill:#53290f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.26285145px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 49.999999,18 39.29104,23.161427 25.904465,98 h 48.19107 L 60.709452,23.161427 Z"
+ id="path3338-3"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#843d0e;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.24012738px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 40.693099,24.18693 h 18.613963 l 11.63373,71.86748 H 29.059368 Z"
+ id="path3338"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ style="fill:#a37251;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.24012738px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 42.089145,25.673839 H 57.911014 L 69.544745,94.56749 H 30.455416 Z"
+ id="path3348"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ <g
+ id="g3394"
+ style="stroke:#794d2b;stroke-width:1.88532007;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ transform="matrix(0.25108353,0,0,0.25108353,102.72754,-49.220402)">
+ <path
+ inkscape:connector-curvature="0"
+ id="path3352"
+ d="m -218.82976,316.82918 h 18.8532 v 216.8118 h -18.8532 z"
+ style="fill:#dec9a6;fill-opacity:1;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532007;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path3354"
+ d="m -199.97656,524.21438 h -18.8532"
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532007;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:nodetypes="cc" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532007;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m -204.68986,514.78778 h -9.4266"
+ id="path3356"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532007;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m -199.97656,505.36118 h -18.8532"
+ id="path3358"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path3360"
+ d="m -204.68986,495.93458 h -9.4266"
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532007;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path3362"
+ d="m -199.97656,486.50798 h -18.8532"
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532007;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:nodetypes="cc" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532007;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m -204.68986,477.08138 h -9.4266"
+ id="path3364"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532007;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m -199.97656,467.65478 h -18.8532"
+ id="path3366"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532019;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m -204.68986,458.22818 h -9.4266"
+ id="path3356-3"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532019;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m -199.97656,448.80158 h -18.8532"
+ id="path3358-5"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path3360-6"
+ d="m -204.68986,439.37498 h -9.4266"
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532019;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path3362-2"
+ d="m -199.97656,429.94838 h -18.8532"
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532019;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:nodetypes="cc" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532019;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m -204.68986,420.52178 h -9.4266"
+ id="path3364-9"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532019;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m -199.97656,411.09518 h -18.8532"
+ id="path3366-1"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532019;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m -204.68986,401.66858 h -9.4266"
+ id="path3356-3-2"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532019;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m -199.97656,392.24198 h -18.8532"
+ id="path3358-5-7"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path3360-6-0"
+ d="m -204.68986,382.81538 h -9.4266"
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532019;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path3362-2-9"
+ d="m -199.97656,373.38878 h -18.8532"
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532019;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:nodetypes="cc" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532019;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m -204.68986,363.96218 h -9.4266"
+ id="path3364-9-3"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532019;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m -199.97656,354.53558 h -18.8532"
+ id="path3366-1-6"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532019;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m -204.68986,345.10898 h -9.4266"
+ id="path3356-3-0"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532019;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m -199.97656,335.68238 h -18.8532"
+ id="path3358-5-6"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path3360-6-2"
+ d="m -204.68986,326.25578 h -9.4266"
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532019;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:nodetypes="cc" />
+ </g>
+ <rect
+ style="opacity:1;vector-effect:none;fill:#cccccc;fill-opacity:1;stroke:#727272;stroke-width:0.47337279;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect1023"
+ width="2.3668587"
+ height="60.355026"
+ x="74.915436"
+ y="13.602678"
+ ry="1.1834289"
+ inkscape:transform-center-x="-9.0440816"
+ inkscape:transform-center-y="-28.26902"
+ transform="rotate(17.740987)" />
+ <path
+ style="fill:#727272;fill-opacity:1;stroke:none;stroke-width:0.23668639px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 58.850339,56.469203 5.410333,1.730923 3.119763,-1.983948 0.865462,-2.705166 -9.91894,-3.173359 -0.865462,2.705167 z"
+ id="path1047"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc"
+ inkscape:transform-center-y="-38.886725"
+ inkscape:transform-center-x="-12.758356" />
+ <path
+ style="fill:#cccccc;fill-opacity:1;stroke:none;stroke-width:0.23668639px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 59.445443,56.162586 4.508613,1.442435 2.975518,-1.533087 0.721217,-2.254305 -9.017216,-2.88487 -0.721217,2.254305 z"
+ id="path1047-9"
+ inkscape:connector-curvature="0"
+ inkscape:transform-center-y="-38.886725"
+ inkscape:transform-center-x="-12.686234" />
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:1;vector-effect:none;fill:#76582d;fill-opacity:1;stroke:none;stroke-width:0.47337279;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ d="m 50.149779,87.571695 c -4.733649,0.09573 -8.283942,4.503428 -8.283942,8.424978 h 16.568046 c 0,-3.92155 -3.550296,-8.520715 -8.284104,-8.424978 z"
+ id="path1025-7"
+ sodipodi:nodetypes="sccs" />
+ <path
+ style="opacity:1;vector-effect:none;fill:#caa66e;fill-opacity:1;stroke:none;stroke-width:0.47337279;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ d="m 50.149779,88.186179 a 7.100592,7.100592 0 0 0 -7.100591,7.100594 h 14.201183 a 7.100592,7.100592 0 0 0 -7.100592,-7.100594 z"
+ id="path1025"
+ inkscape:connector-curvature="0" />
+ </g>
+</svg>
diff --git a/src/activities/play_rhythm/resource/README b/src/activities/play_rhythm/resource/README
new file mode 100644
index 000000000..11025bf48
--- /dev/null
+++ b/src/activities/play_rhythm/resource/README
@@ -0,0 +1,7 @@
+Copyright: 2018, Timothee Giet
+License: CC-BY-SA 4.0
+Files:
+metronome_front.svg
+metronome_needle.svg
+metronome_stand.svg
+metronome_weight.svg
diff --git a/src/activities/play_rhythm/resource/click.wav b/src/activities/play_rhythm/resource/click.wav
new file mode 100644
index 000000000..d92340213
Binary files /dev/null and b/src/activities/play_rhythm/resource/click.wav differ
diff --git a/src/activities/play_rhythm/resource/dataset.json b/src/activities/play_rhythm/resource/dataset.json
new file mode 100644
index 000000000..26e7cd06e
--- /dev/null
+++ b/src/activities/play_rhythm/resource/dataset.json
@@ -0,0 +1,85 @@
+{
+ "levels": [
+ {
+ "pulseMarkerVisible": true,
+ "metronomeVisible": false,
+ "melodies": [
+ "Treble C4Quarter C4Eighth C4Half",
+ "Treble C4Quarter C4Eighth C4Eighth",
+ "Treble C4Quarter C4Quarter C4Half"
+ ]
+ },
+ {
+ "pulseMarkerVisible": false,
+ "metronomeVisible": true,
+ "melodies": [
+ "Treble C4Quarter C4Half C4Eighth",
+ "Treble C4Quarter C4Quarter C4Quarter",
+ "Treble C4Eighth C4Quarter C4Quarter"
+ ]
+ },
+ {
+ "pulseMarkerVisible": true,
+ "metronomeVisible": false,
+ "melodies": [
+ "Treble C4Quarter C4Eighth C4Half",
+ "Treble C4Quarter C4Half C4Quarter",
+ "Treble C4Quarter C4Quarter C4Eighth"
+ ]
+ },
+ {
+ "pulseMarkerVisible": false,
+ "metronomeVisible": true,
+ "melodies": [
+ "Treble C4Eighth C4Quarter C4Eighth",
+ "Treble C4Quarter C4Eighth C4Half",
+ "Treble C4Eighth C4Quarter C4Half"
+ ]
+ },
+ {
+ "pulseMarkerVisible": true,
+ "metronomeVisible": false,
+ "melodies": [
+ "Treble C4Eighth C4Eighth C4Quarter C4Eighth",
+ "Treble C4Quarter C4Quarter C4Half C4Eighth",
+ "Treble C4Half C4Eighth C4Eighth C4Quarter"
+ ]
+ },
+ {
+ "pulseMarkerVisible": false,
+ "metronomeVisible": true,
+ "melodies": [
+ "Treble C4Quarter C4Quarter C4Quarter C4Quarter",
+ "Treble C4Eighth C4Quarter C4Half C4Eighth",
+ "Treble C4Eighth C4Half C4Eighth C4Eighth"
+ ]
+ },
+ {
+ "pulseMarkerVisible": true,
+ "metronomeVisible": false,
+ "melodies": [
+ "Treble C4Eighth C4Quarter C4Quarter C4Quarter",
+ "Treble C4Eighth C4Eighth C4Eighth C4Eighth",
+ "Treble C4Quarter C4Half C4Quarter C4Eighth"
+ ]
+ },
+ {
+ "pulseMarkerVisible": false,
+ "metronomeVisible": true,
+ "melodies": [
+ "Treble C4Eighth C4Quarter C4Eighth C4Quarter",
+ "Treble C4Quarter C4Half C4Eighth C4Eighth",
+ "Treble C4Quarter C4Eighth C4Quarter C4Eighth"
+ ]
+ },
+ {
+ "pulseMarkerVisible": true,
+ "metronomeVisible": false,
+ "melodies": [
+ "Treble C4Quarter C4Quarter C4Half C4Eighth",
+ "Treble C4Eighth C4Eighth C4Eighth C4Quarter",
+ "Treble C4Quarter C4Eighth C4Quarter C4Eighth"
+ ]
+ }
+ ]
+}
diff --git a/src/activities/play_rhythm/resource/drumhead.svg b/src/activities/play_rhythm/resource/drumhead.svg
new file mode 100644
index 000000000..3e316656b
--- /dev/null
+++ b/src/activities/play_rhythm/resource/drumhead.svg
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="180"
+ height="90"
+ viewBox="0 0 180 90"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="drumhead.svg"
+ inkscape:export-filename="/home/algot/Documents/runeman.org/clipart/metronome.png"
+ inkscape:export-xdpi="86.098335"
+ inkscape:export-ydpi="86.098335">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="4.0000001"
+ inkscape:cx="24.303832"
+ inkscape:cy="38.442177"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0"
+ units="px">
+ <inkscape:grid
+ type="xygrid"
+ id="grid3336"
+ originx="0"
+ originy="0" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ <dc:date>2018</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Timothée Giet</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:rights>
+ <cc:Agent>
+ <dc:title />
+ </cc:Agent>
+ </dc:rights>
+ <dc:publisher>
+ <cc:Agent>
+ <dc:title />
+ </cc:Agent>
+ </dc:publisher>
+ <dc:identifier />
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(300.59358,-500.39808)">
+ <path
+ style="opacity:1;vector-effect:none;fill:#623f19;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ d="m -283.09358,527.89808 v 35 a 72.5,15 0 0 0 72.5,15 72.5,15 0 0 0 72.5,-15 v -35 z"
+ id="path834-3"
+ inkscape:connector-curvature="0" />
+ <path
+ style="opacity:1;vector-effect:none;fill:#885a33;fill-opacity:1;stroke:none;stroke-width:9.5147419;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ d="m -281.09358,527.89808 v 33.43165 a 70.628677,13.93934 0 0 0 -0.12891,0.50781 70.628677,13.93934 0 0 0 0.12891,0.71484 v 0.3457 h 0.0937 a 70.628677,13.93934 0 0 0 70.40625,12.87891 70.628677,13.93934 0 0 0 70.35938,-12.87891 h 0.14062 v -0.55273 a 70.628677,13.93934 0 0 0 0.12891,-0.50781 70.628677,13.93934 0 0 0 -0.12891,-0.71485 v -33.22461 z"
+ id="path834-3-5"
+ inkscape:connector-curvature="0" />
+ <ellipse
+ style="opacity:1;vector-effect:none;fill:#623f19;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path834"
+ cx="-210.59358"
+ cy="527.89807"
+ rx="72.5"
+ ry="15" />
+ <ellipse
+ style="opacity:1;vector-effect:none;fill:#e1ba91;fill-opacity:1;stroke:none;stroke-width:9.2078495;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path834-6"
+ cx="-210.59358"
+ cy="527.52307"
+ rx="70.25"
+ ry="13.125" />
+ </g>
+</svg>
diff --git a/src/activities/play_rhythm/resource/metronome_front.svg b/src/activities/play_rhythm/resource/metronome_front.svg
new file mode 100644
index 000000000..5390bf437
--- /dev/null
+++ b/src/activities/play_rhythm/resource/metronome_front.svg
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="220"
+ height="340"
+ viewBox="0 0 206.24999 318.75"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="metronome_front.svg"
+ inkscape:export-filename="/home/algot/Documents/runeman.org/clipart/metronome.png"
+ inkscape:export-xdpi="86.098335"
+ inkscape:export-ydpi="86.098335">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1.4142136"
+ inkscape:cx="-165.25363"
+ inkscape:cy="128.92987"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0"
+ units="px">
+ <inkscape:grid
+ type="xygrid"
+ id="grid3336"
+ originx="300.59357"
+ originy="-466.96407" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ <dc:date>2018</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Timothée Giet</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:rights>
+ <cc:Agent>
+ <dc:title />
+ </cc:Agent>
+ </dc:rights>
+ <dc:publisher>
+ <cc:Agent>
+ <dc:title />
+ </cc:Agent>
+ </dc:publisher>
+ <dc:identifier />
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(300.59358,-266.64809)">
+ <path
+ inkscape:connector-curvature="0"
+ style="opacity:1;vector-effect:none;fill:#76582d;fill-opacity:1;stroke:none;stroke-width:1.875;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ d="m -196.87532,543.12969 c -18.74969,0.37919 -32.81218,17.83779 -32.81218,33.37079 h 65.62499 c 0,-15.533 -14.0625,-33.75 -32.81281,-33.37079 z"
+ id="path1025-7"
+ sodipodi:nodetypes="sccs" />
+ <path
+ style="opacity:1;vector-effect:none;fill:#caa66e;fill-opacity:1;stroke:none;stroke-width:1.875;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ d="m -196.87532,545.56362 a 28.125,28.125 0 0 0 -28.125,28.125 h 56.25 a 28.125,28.125 0 0 0 -28.125,-28.125 z"
+ id="path1025"
+ inkscape:connector-curvature="0" />
+ </g>
+</svg>
diff --git a/src/activities/play_rhythm/resource/metronome_needle.svg b/src/activities/play_rhythm/resource/metronome_needle.svg
new file mode 100644
index 000000000..911ca55c9
--- /dev/null
+++ b/src/activities/play_rhythm/resource/metronome_needle.svg
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="220"
+ height="340"
+ viewBox="0 0 206.24999 318.75"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="metronome_needle.svg"
+ inkscape:export-filename="/home/algot/Documents/runeman.org/clipart/metronome.png"
+ inkscape:export-xdpi="86.098335"
+ inkscape:export-ydpi="86.098335">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1.4142136"
+ inkscape:cx="-22.064511"
+ inkscape:cy="93.574532"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0"
+ units="px">
+ <inkscape:grid
+ type="xygrid"
+ id="grid3336"
+ originx="300.59357"
+ originy="-466.96407" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ <dc:date>2018</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Timothée Giet</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:rights>
+ <cc:Agent>
+ <dc:title />
+ </cc:Agent>
+ </dc:rights>
+ <dc:publisher>
+ <cc:Agent>
+ <dc:title />
+ </cc:Agent>
+ </dc:publisher>
+ <dc:identifier />
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(300.59358,-266.64809)">
+ <rect
+ style="opacity:1;vector-effect:none;fill:#cccccc;fill-opacity:1;stroke:#727272;stroke-width:1.875;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect1023"
+ width="9.374979"
+ height="239.06248"
+ x="-201.56248"
+ y="321.11218"
+ ry="4.6874876" />
+ </g>
+</svg>
diff --git a/src/activities/play_rhythm/resource/metronome_stand.svg b/src/activities/play_rhythm/resource/metronome_stand.svg
new file mode 100644
index 000000000..8f0d0c4b2
--- /dev/null
+++ b/src/activities/play_rhythm/resource/metronome_stand.svg
@@ -0,0 +1,265 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="220"
+ height="340"
+ viewBox="0 0 206.24999 318.75"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="metronome_stand.svg"
+ inkscape:export-filename="/home/algot/Documents/runeman.org/clipart/metronome.png"
+ inkscape:export-xdpi="86.098335"
+ inkscape:export-ydpi="86.098335">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="2.0000001"
+ inkscape:cx="-127.32922"
+ inkscape:cy="154.42987"
+ inkscape:document-units="px"
+ inkscape:current-layer="g3394"
+ showgrid="false"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0"
+ units="px">
+ <inkscape:grid
+ type="xygrid"
+ id="grid3336"
+ originx="300.59357"
+ originy="-466.96407" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ <dc:date>2018</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Timothée Giet</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:rights>
+ <cc:Agent>
+ <dc:title />
+ </cc:Agent>
+ </dc:rights>
+ <dc:publisher>
+ <cc:Agent>
+ <dc:title />
+ </cc:Agent>
+ </dc:publisher>
+ <dc:identifier />
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(300.59358,-266.64809)">
+ <path
+ style="fill:#53290f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1.04113817px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -197.46859,267.58559 -42.41752,20.44409 -53.02338,296.4309 h 190.88181 l -53.02144,-296.4309 z"
+ id="path3338-3"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#843d0e;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9511295px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -234.33264,292.09163 h 73.72874 l 46.08048,284.66257 h -165.8897 z"
+ id="path3338"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ style="fill:#a37251;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.9511295px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -228.80299,297.98119 h 62.66944 l 46.08047,272.88344 h -154.83038 z"
+ id="path3348"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccc" />
+ <g
+ id="g3394"
+ style="stroke:#794d2b;stroke-opacity:1;stroke-width:1.88532001;stroke-miterlimit:4;stroke-dasharray:none"
+ transform="matrix(0.9945261,0,0,0.9945261,11.381898,1.3297833)">
+ <path
+ inkscape:connector-curvature="0"
+ id="path3352"
+ d="m -218.82976,316.82918 h 18.8532 l 0,216.8118 h -18.8532 z"
+ style="fill:#dec9a6;fill-opacity:1;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532007;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path3354"
+ d="m -199.97656,524.21438 h -18.8532"
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532007;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:nodetypes="cc" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532007;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m -204.68986,514.78778 h -9.4266"
+ id="path3356"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532007;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m -199.97656,505.36118 h -18.8532"
+ id="path3358"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path3360"
+ d="m -204.68986,495.93458 h -9.4266"
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532007;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path3362"
+ d="m -199.97656,486.50798 h -18.8532"
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532007;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:nodetypes="cc" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532007;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m -204.68986,477.08138 h -9.4266"
+ id="path3364"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532007;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m -199.97656,467.65478 h -18.8532"
+ id="path3366"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532019;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m -204.68986,458.22818 h -9.4266"
+ id="path3356-3"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532019;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m -199.97656,448.80158 h -18.8532"
+ id="path3358-5"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path3360-6"
+ d="m -204.68986,439.37498 h -9.4266"
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532019;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path3362-2"
+ d="m -199.97656,429.94838 h -18.8532"
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532019;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:nodetypes="cc" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532019;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m -204.68986,420.52178 h -9.4266"
+ id="path3364-9"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532019;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m -199.97656,411.09518 h -18.8532"
+ id="path3366-1"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532019;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m -204.68986,401.66858 h -9.4266"
+ id="path3356-3-2"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532019;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m -199.97656,392.24198 h -18.8532"
+ id="path3358-5-7"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path3360-6-0"
+ d="m -204.68986,382.81538 h -9.4266"
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532019;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path3362-2-9"
+ d="m -199.97656,373.38878 h -18.8532"
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532019;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:nodetypes="cc" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532019;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m -204.68986,363.96218 h -9.4266"
+ id="path3364-9-3"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532019;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m -199.97656,354.53558 h -18.8532"
+ id="path3366-1-6"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ sodipodi:nodetypes="cc"
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532019;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m -204.68986,345.10898 h -9.4266"
+ id="path3356-3-0"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532019;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m -199.97656,335.68238 h -18.8532"
+ id="path3358-5-6"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path3360-6-2"
+ d="m -204.68986,326.25578 h -9.4266"
+ style="fill:none;fill-rule:evenodd;stroke:#76582d;stroke-width:1.88532019;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ sodipodi:nodetypes="cc" />
+ </g>
+ </g>
+</svg>
diff --git a/src/activities/play_rhythm/resource/metronome_weight.svg b/src/activities/play_rhythm/resource/metronome_weight.svg
new file mode 100644
index 000000000..0e70d2385
--- /dev/null
+++ b/src/activities/play_rhythm/resource/metronome_weight.svg
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="220"
+ height="340"
+ viewBox="0 0 206.24999 318.75"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="metronome_weight.svg"
+ inkscape:export-filename="/home/algot/Documents/runeman.org/clipart/metronome.png"
+ inkscape:export-xdpi="86.098335"
+ inkscape:export-ydpi="86.098335">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="1.4142136"
+ inkscape:cx="47.370589"
+ inkscape:cy="153.67861"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0"
+ units="px">
+ <inkscape:grid
+ type="xygrid"
+ id="grid3336"
+ originx="300.59357"
+ originy="-466.96407" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ <dc:date>2018</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Timothée Giet</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <dc:rights>
+ <cc:Agent>
+ <dc:title />
+ </cc:Agent>
+ </dc:rights>
+ <dc:publisher>
+ <cc:Agent>
+ <dc:title />
+ </cc:Agent>
+ </dc:publisher>
+ <dc:identifier />
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(300.59358,-266.64809)">
+ <path
+ style="fill:#727272;fill-opacity:1;stroke:none;stroke-width:0.9375px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -208.125,296.73714 h 22.5 l 9.375,-11.25 v -11.25 h -41.25 v 11.25 z"
+ id="path1047"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccccccc" />
+ <path
+ style="fill:#cccccc;fill-opacity:1;stroke:none;stroke-width:0.9375px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -206.25,294.86214 h 18.75 l 9.375,-9.375 v -9.375 h -37.5 v 9.375 z"
+ id="path1047-9"
+ inkscape:connector-curvature="0" />
+ </g>
+</svg>
diff --git a/src/activities/railroad/ActivityInfo.qml b/src/activities/railroad/ActivityInfo.qml
index 1ddc06660..c01c72203 100644
--- a/src/activities/railroad/ActivityInfo.qml
+++ b/src/activities/railroad/ActivityInfo.qml
@@ -1,42 +1,47 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2017 Utkarsh Tiwari <iamutkarshtiwari@kde.org>
* Copyright (C) 2018 Amit Sagtani <asagtani06@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "railroad/Railroad.qml"
difficulty: 1
icon: "railroad/railroad.svg"
author: "Utkarsh Tiwari &lt;iamutkarshtiwari@kde.org&gt;"
demo: true
+ //: Activity title
title: qsTr("Railroad activity")
+ //: Help title
description: qsTr("Rebuild the displayed train at the top of the screen by dragging the appropriate carriages and locomotive. Deselect an item by dragging it down.")
//intro: "Observe the train and then click on the items to set up a similar train"
+ //: Help goal
goal: qsTr("Memory training")
+ //: Help prerequisite
prerequisite: ""
+ //: Help manual
manual: qsTr("A train - a locomotive and carriage(s) - is displayed at the top of the main area for a few seconds. Rebuild it at the top of the screen by dragging the appropriate carriages and locomotive. Deselect an item by dragging it down.<br><br>") +
qsTr("<b>Keyboard Controls:</b><br><br>") +
qsTr("1. Use arrow keys to move in the answer or sample zone.<br>") +
qsTr("2. Use Enter or Return key to submit the answers.<br>") +
qsTr("3. Use Space key to swap two wagons or locomotives in answer zone.<br>") +
qsTr("4. Use Space key to add a wagon or locomotive from samples to answer list.<br>") +
qsTr("5. Use Delete key to remove a wagon or locomotive from answer zone.<br>")
credit: ""
section: "discovery memory"
createdInVersion: 9500
}
diff --git a/src/activities/railroad/Loco.qml b/src/activities/railroad/Loco.qml
index 9c97a8254..9b16a9aa0 100644
--- a/src/activities/railroad/Loco.qml
+++ b/src/activities/railroad/Loco.qml
@@ -1,45 +1,45 @@
/* GCompris - Loco.qml
*
* Copyright (C) 2017 Utkarsh Tiwari <iamutkarshtiwari@kde.org>
* Copyright (C) 2018 Amit Sagtani <asagtani06@gmail.com>
*
* Authors:
* <Pascal Georges> (GTK+ version)
* Utkarsh Tiwari <iamutkarshtiwari@kde.org> (Qt Quick port)
* Amit Sagtani <asagtani06@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "railroad.js" as Activity
Item {
id: draggedItem
property string imageURL
Image {
id: img
source: imageURL
height: background.height / 8.0
- width: ((background.width > background.height) ? background.width : background.height) / 5.66
+ width: ((background.width >= background.height) ? background.width : background.height) / 5.66
Drag.hotSpot.x: width / 2
Drag.hotSpot.y: height / 2
}
function destroy() {
// Destroy this copy object on drop
draggedItem.destroy();
}
}
diff --git a/src/activities/railroad/Railroad.qml b/src/activities/railroad/Railroad.qml
index d277a2c35..676be86c6 100644
--- a/src/activities/railroad/Railroad.qml
+++ b/src/activities/railroad/Railroad.qml
@@ -1,594 +1,596 @@
/* GCompris - railroad.qml
*
* Copyright (C) 2016 Utkarsh Tiwari <iamutkarshtiwari@kde.org>
* Copyright (C) 2018 Amit Sagtani <asagtani06@gmail.com>
*
* Authors:
* Pascal Georges (GTK+ version)
* Utkarsh Tiwari <iamutkarshtiwari@kde.org> (Qt Quick port)
* Amit Sagtani <asagtani06@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "railroad.js" as Activity
ActivityBase {
id: activity
onStart: focus = true
onStop: {}
- property bool isHorizontal: background.width > background.height
+ property bool isHorizontal: background.width >= background.height
pageComponent: Image {
id: background
source: Activity.resourceURL + "railroad-bg.svg"
sourceSize.height: background.height
fillMode: Image.PreserveAspectCrop
anchors.horizontalCenter: parent.horizontalCenter
signal start
signal stop
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property alias background: background
property alias bar: bar
property alias bonus: bonus
property alias score: score
property alias trainAnimationTimer: trainAnimationTimer
property alias sampleList: sampleList
property alias listModel: listModel
property alias answerZone: answerZone
property alias animateFlow: animateFlow
property alias introMessage: introMessage
property bool memoryMode: false
property bool mouseEnabled: true
property var currentKeyZone: sampleList
property bool keyNavigationMode: false
// stores height of sampleGrid images to set rail bar support position
property int sampleImageHeight: 0
+ property int sampleModel: Activity.dataset["noOfLocos"][bar.level - 1] + Activity.dataset["noOfWagons"][bar.level - 1]
}
onStart: { Activity.start(items) }
onStop: { Activity.stop() }
Keys.enabled: !trainAnimationTimer.running && !animateFlow.running && !introMessage.visible
Keys.onPressed: {
items.keyNavigationMode = true;
items.currentKeyZone.handleKeys(event);
activity.audioEffects.play('qrc:/gcompris/src/core/resource/sounds/smudge.wav');
}
// Countdown timer
Timer {
id: trainAnimationTimer
repeat: false
interval: 4000
onTriggered: {
items.animateFlow.start()
activity.audioEffects.play(Activity.resourceURL + 'sounds/train.wav')
}
}
// Intro message
IntroMessage {
id: introMessage
y: background.height / 4.7
anchors {
right: parent.right
rightMargin: 5
left: parent.left
leftMargin: 5
}
z: score.z + 1
onIntroDone: {
trainAnimationTimer.start()
}
intro: [
qsTr("Observe and remember the train before the timer ends and then drag the items to set up a similar train."),
qsTr("If you forget the positions, you can click on the Hint button to view them again.")
]
}
// Top Display Area
Rectangle {
id: topDisplayArea
width: background.width
height: background.height * 0.2
anchors.bottom: sampleList.top
color: 'transparent'
z: 1
GridView {
id: answerZone
readonly property int levelCellWidth: isHorizontal ? background.width / (listModel.count > 5 ? 7.2 : 5.66) :
background.width / ((listModel.count > 5) ? 7.1 : 5)
readonly property int levelCellHeight: levelCellWidth * 0.42
width: parent.width
height: levelCellHeight
cellWidth: levelCellWidth
cellHeight: levelCellHeight
anchors.bottom: parent.bottom
interactive: false
model: listModel
delegate: Image {
id: wagon
source: Activity.resourceURL + modelData + ".svg"
fillMode: Image.PreserveAspectFit
width: answerZone.cellWidth
sourceSize.width: wagon.width
function checkDrop(dragItem) {
// Checks the drop location of this wagon
var globalCoordinates = dragItem.mapToItem(answerZone, 0, 0)
if(globalCoordinates.y <= ((background.height / 12.5) + (background.height / 8))) {
var dropIndex = Activity.getDropIndex(globalCoordinates.x)
if(dropIndex > (listModel.count - 1)) {
// Handles index overflow
dropIndex = listModel.count - 1
}
listModel.move(listModel.count - 1, dropIndex, 1)
opacity = 1
}
if(globalCoordinates.y > (background.height / 8)) {
// Remove it if dropped in the lower section
activity.audioEffects.play('qrc:/gcompris/src/core/resource/sounds/smudge.wav')
listModel.remove(listModel.count - 1)
}
}
function createNewItem() {
var component = Qt.createComponent("Loco.qml");
if(component.status === Component.Ready) {
var newItem = component.createObject(parent, {"x": x, "y": y, "z": 10, "imageURL": source});
}
return newItem
}
MouseArea {
id: displayWagonMouseArea
hoverEnabled: true
enabled: !introMessage.visible && items.mouseEnabled
anchors.fill: parent
onPressed: {
if(items.memoryMode) {
drag.target = parent.createNewItem();
parent.opacity = 0
listModel.move(index, listModel.count - 1, 1)
}
answerZone.selectedSwapIndex = -1;
}
onReleased: {
if(items.memoryMode) {
var dragItem = drag.target
parent.checkDrop(dragItem)
dragItem.destroy();
parent.Drag.cancel()
}
}
onClicked: {
// skips memorization time
if(!items.memoryMode) {
bar.hintClicked()
}
else {
items.currentKeyZone = answerZone
if(items.keyNavigationMode) {
answerZone.currentIndex = index
}
}
answerZone.selectedSwapIndex = -1;
}
}
states: State {
name: "wagonHover"
when: displayWagonMouseArea.containsMouse && (items.memoryMode === true)
PropertyChanges {
target: wagon
scale: 1.1
}
}
}
onXChanged: {
if(answerZone.x >= background.width) {
trainAnimationTimer.stop()
animateFlow.stop();
listModel.clear();
items.memoryMode = true;
}
}
PropertyAnimation {
id: animateFlow
target: answerZone
properties: "x"
from: answerZone.x
to: background.width
duration: 4000
easing.type: Easing.InExpo
loops: 1
onStopped: answerZone.x = 2;
}
function handleKeys(event) {
// Switch zones via tab key.
if(event.key === Qt.Key_Tab) {
items.currentKeyZone = sampleList
sampleList.currentIndex = 0
answerZone.currentIndex = -1
}
if(event.key === Qt.Key_Down) {
items.currentKeyZone = sampleList
answerZone.currentIndex = -1
sampleList.currentIndex = 0
}
if(event.key === Qt.Key_Up) {
items.currentKeyZone = sampleList
answerZone.currentIndex = -1
sampleList.currentIndex = 0
}
if(event.key === Qt.Key_Left) {
items.currentKeyZone = answerZone
answerZone.moveCurrentIndexLeft()
}
if(event.key === Qt.Key_Right) {
items.currentKeyZone = answerZone
answerZone.moveCurrentIndexRight()
}
// Remove a wagon via Delete/Return key.
if(event.key === Qt.Key_Delete && listModel.count > 0) {
activity.audioEffects.play('qrc:/gcompris/src/core/resource/sounds/smudge.wav')
listModel.remove(answerZone.currentIndex)
if(listModel.count < 2) {
answerZone.selectedSwapIndex = -1;
}
}
// Checks answer.
if((event.key === Qt.Key_Return || event.key === Qt.Key_Enter) && items.mouseEnabled) {
items.currentKeyZone = answerZone
Activity.checkAnswer();
}
// Swaps two wagons with help of Space/Enter keys.
if(event.key === Qt.Key_Space) {
if(selectedSwapIndex === -1 && listModel.count > 1) {
answerZone.selectedSwapIndex = answerZone.currentIndex;
swapHighlight.x = answerZone.currentItem.x;
swapHighlight.anchors.top = answerZone.top;
}
else if(answerZone.currentIndex != selectedSwapIndex && listModel.count > 1){
var min = Math.min(selectedSwapIndex, answerZone.currentIndex);
var max = Math.max(selectedSwapIndex, answerZone.currentIndex);
listModel.move(min, max, 1);
listModel.move(max-1, min, 1);
answerZone.selectedSwapIndex = -1;
}
}
}
// variable for storing the index of wagons to be swapped via key navigations.
property int selectedSwapIndex: -1
Keys.enabled: true
focus: true
keyNavigationWraps: true
highlightRangeMode: GridView.ApplyRange
highlight: Rectangle {
width: answerZone.cellWidth
height: answerZone.cellHeight
color: "blue"
opacity: 0.3
radius: 5
visible: (items.currentKeyZone === answerZone) && (!trainAnimationTimer.running && !animateFlow.running) && items.keyNavigationMode
- x: visible ? answerZone.currentItem.x : 0
- y: visible ? answerZone.currentItem.y : 0
+ x: (visible && answerZone.currentItem) ? answerZone.currentItem.x : 0
+ y: (visible && answerZone.currentItem) ? answerZone.currentItem.y : 0
Behavior on x {
SpringAnimation {
spring: 3
damping: 0.2
}
}
Behavior on y {
SpringAnimation {
spring: 3
damping: 0.2
}
}
}
highlightFollowsCurrentItem: false
}
// Used to highlight a wagon selected for swaping via key navigations
Rectangle {
id: swapHighlight
width: answerZone.cellWidth
height: answerZone.cellHeight
visible: answerZone.selectedSwapIndex != -1 ? true : false
color: "#AA41AAC4"
opacity: 0.8
radius: 5
}
ListModel {
id: listModel
}
}
// Lower Sample Wagon Display Area
GridView {
id: sampleList
visible: items.memoryMode
y: background.height * 0.2
z: 5
width: background.width
height: background.height * 0.8
anchors.margins: 20
cellWidth: width / columnCount
cellHeight: isHorizontal ? background.height / 7 : background.height / 7.5
- model: Activity.dataset["noOfLocos"][bar.level - 1] + Activity.dataset["noOfWagons"][bar.level - 1]
+ model: Math.max(0, items.sampleModel)
interactive: false
// No. of wagons in a row
readonly property int columnCount: isHorizontal ? Activity.dataset["columnsInHorizontalMode"][bar.level - 1] :
Activity.dataset["columsInVerticalMode"][bar.level - 1]
readonly property int rowCount: columnCount > 0 ? model / columnCount : 0
delegate: Image {
id: loco
readonly property string uniqueID: Activity.uniqueId[index]
property real originX
property real originY
source: Activity.resourceURL + uniqueID + ".svg"
width: isHorizontal ? background.width / 5.66 : background.width / 4.2
sourceSize.width: width
fillMode: Image.PreserveAspectFit
visible: true
onHeightChanged: items.sampleImageHeight = height
onVisibleChanged: items.sampleImageHeight = height
function initDrag() {
originX = x
originY = y
}
function replace() {
x = originX
y = originY
}
function checkDrop() {
// Checks the drop location of this wagon
var globalCoordinates = loco.mapToItem(answerZone, 0, 0)
// checks if the wagon is dropped in correct zone and no. of wagons in answer row are less than
// total no. of wagons in correct answer + 2, before dropping the wagon
if(globalCoordinates.y <= (background.height / 12.5) &&
listModel.count < Activity.dataset["WagonsInCorrectAnswers"][bar.level - 1] + 2) {
activity.audioEffects.play('qrc:/gcompris/src/core/resource/sounds/smudge.wav')
var dropIndex = Activity.getDropIndex(globalCoordinates.x)
Activity.addWagon(uniqueID, dropIndex);
}
}
MouseArea {
id: mouseArea
hoverEnabled: true
anchors.fill: parent
drag.target: parent
enabled: items.mouseEnabled
onClicked: {
items.currentKeyZone = sampleList
if(items.keyNavigationMode) {
sampleList.currentIndex = index
}
}
onPressed: {
parent.initDrag()
}
onReleased: {
parent.Drag.cancel()
parent.checkDrop()
parent.replace()
}
}
Component.onCompleted: initDrag();
states: State {
name: "carHover"
when: mouseArea.containsMouse
PropertyChanges {
target: loco
scale: 1.1
}
}
}
function handleKeys(event) {
if(event.key === Qt.Key_Tab) {
if(listModel.count > 0) {
items.currentKeyZone = answerZone
sampleList.currentIndex = -1
answerZone.currentIndex = 0
}
}
if(event.key === Qt.Key_Up) {
items.currentKeyZone = sampleList
// Checks if current highlighted element is in first row of the grid.
if(sampleList.currentIndex < columnCount && listModel.count > 0) {
items.currentKeyZone = answerZone
answerZone.currentIndex = 0
sampleList.currentIndex = -1
}
else {
sampleList.moveCurrentIndexUp()
}
}
if(event.key === Qt.Key_Down) {
items.currentKeyZone = sampleList
sampleList.moveCurrentIndexDown()
}
if(event.key === Qt.Key_Left) {
items.currentKeyZone = sampleList
sampleList.moveCurrentIndexLeft()
}
if(event.key === Qt.Key_Right) {
items.currentKeyZone = sampleList
sampleList.moveCurrentIndexRight()
}
if(event.key === Qt.Key_Space) {
var imageId = Activity.uniqueId[sampleList.currentIndex]
// At most (current level + 2) wagons are allowed in answer row at a time.
if(listModel.count < Activity.dataset["WagonsInCorrectAnswers"][bar.level - 1] + 2) {
activity.audioEffects.play('qrc:/gcompris/src/core/resource/sounds/smudge.wav')
Activity.addWagon(imageId, listModel.count);
}
}
if((event.key === Qt.Key_Enter || event.key === Qt.Key_Return) && listModel.count > 0 && items.mouseEnabled) {
items.currentKeyZone = sampleList
Activity.checkAnswer()
}
}
Keys.enabled: true
focus: true
keyNavigationWraps: true
highlightRangeMode: GridView.ApplyRange
highlight: Rectangle {
width: isHorizontal ? background.width / 5.66 : background.width / 4.2
height: isHorizontal ? sampleList.cellHeight : sampleList.cellHeight / 1.65
color: "#AA41AAC4"
opacity: 0.8
radius: 5
visible: items.currentKeyZone === sampleList && items.keyNavigationMode
- x: (sampleList.currentIndex >= 0) ? sampleList.currentItem.x : 0
- y: (sampleList.currentIndex >= 0) ? sampleList.currentItem.y : 0
+ x: (sampleList.currentIndex >= 0 && sampleList.currentItem) ? sampleList.currentItem.x : 0
+ y: (sampleList.currentIndex >= 0 && sampleList.currentItem) ? sampleList.currentItem.y : 0
Behavior on x {
SpringAnimation {
spring: 3
damping: 0.2
}
}
Behavior on y {
SpringAnimation {
spring: 3
damping: 0.2
}
}
}
highlightFollowsCurrentItem: false
}
// Lower level wagons shelves
Repeater {
id: railSupporter
model: sampleList.rowCount
Rectangle {
x: 0
y: sampleList.y + (sampleList.cellHeight * (index + 1)) - (sampleList.cellHeight - items.sampleImageHeight)
z: 1
width: background.width
height: isHorizontal ? 6 : 3
border.color: "#808180"
color: "transparent"
border.width: 4
}
}
// Answer Submission button
BarButton {
id: okButton
source: "qrc:/gcompris/src/core/resource/bar_ok.svg"
- width: height
height: score.height
+ width: height
sourceSize.width: width
sourceSize.height: height
anchors.top: score.top
z: score.z
anchors {
right: score.left
rightMargin: 10
}
ParticleSystemStarLoader {
id: okButtonParticles
clip: false
}
MouseArea {
id: okButtonMouseArea
anchors.fill: parent
enabled: !trainAnimationTimer.running && !animateFlow.running && listModel.count > 0 && items.mouseEnabled
onClicked: Activity.checkAnswer()
}
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Score {
id: score
- fontSize: isHorizontal ? internalTextComponent.smallSize : internalTextComponent.tinySize
+ height: bar.height * 0.8
+ width: height
anchors.top: parent.top
anchors.topMargin: 10 * ApplicationInfo.ratio
anchors.right: parent.right
anchors.leftMargin: 10 * ApplicationInfo.ratio
anchors.bottom: undefined
anchors.left: undefined
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level | hint }
onHelpClicked: {
displayDialog(dialogHelp)
}
z: introMessage.z
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
onHintClicked: {
if(!introMessage.visible && items.mouseEnabled) {
if(items.memoryMode == false) {
trainAnimationTimer.stop()
animateFlow.stop();
listModel.clear();
for(var index = 0; index < Activity.backupListModel.length; index++) {
Activity.addWagon(Activity.backupListModel[index], index);
}
items.memoryMode = true;
okButton.visible = true;
} else {
Activity.restoreLevel();
okButton.visible = false;
}
}
}
}
Bonus {
id: bonus
Component.onCompleted: win.connect(Activity.nextSubLevel)
}
}
}
diff --git a/src/activities/railroad/railroad.js b/src/activities/railroad/railroad.js
index bcce1ae3f..203f663ca 100644
--- a/src/activities/railroad/railroad.js
+++ b/src/activities/railroad/railroad.js
@@ -1,204 +1,204 @@
/* GCompris - railroad.js
*
* Copyright (C) 2016 Utkarsh Tiwari <iamutkarshtiwari@kde.org>
* Copyright (C) 2018 Amit Sagtani <asagtani06@gmail.com>
*
* Authors:
* <Pascal Georges> (GTK+ version)
* Utkarsh Tiwari <iamutkarshtiwari@kde.org> (Qt Quick port)
* Amit Sagtani <asagtani06@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
.import GCompris 1.0 as GCompris
var currentLevel = 0
var numberOfLevel = 10
var solutionArray = []
var backupListModel = []
var isNewLevel = true
var resourceURL = "qrc:/gcompris/src/activities/railroad/resource/"
var items
var uniqueId = []
/**
* Stores configuration for each level.
* 'WagonsInCorrectAnswers' contains no. of wagons in correct answer.
* 'memoryTime' contains time(in seconds) for memorizing the wagons.
* 'numberOfSubLevels' contains no. of sublevels in each level.
* 'columnsInHorizontalMode' contains no. of columns in a row of sampleZone in horizontal mode.
* 'columnsInVerticalMode' contains no. of columns in a row of sampleZone in vertical mode.
* 'noOfLocos' stores no. of locos to be displayed in sampleZone.
* 'noOfWagons' stores no. of wagons to be displayed in sampleZone.
*/
var dataset = {
"WagonsInCorrectAnswers": [1, 1, 2, 2, 3, 3, 4, 4, 5, 5],
"memoryTime": [4, 4, 6, 6, 7, 7, 8, 8, 10, 10],
"numberOfSubLevels": 3,
"columnsInHorizontalMode": [3, 5, 3, 5, 3, 5, 3, 5, 3, 5],
"columsInVerticalMode": [3, 4, 3, 4, 3, 4, 3, 4, 3, 4],
"noOfLocos": [8, 9, 4, 9, 4, 9, 4, 9, 4, 9],
"noOfWagons": [4, 11, 8, 11, 8, 11, 8, 11, 8, 11]
}
function start(items_) {
items = items_
currentLevel = 0
items.score.numberOfSubLevels = dataset["numberOfSubLevels"];
items.score.currentSubLevel = 1;
initLevel()
}
function stop() {
}
function initLevel() {
generateUniqueId();
items.mouseEnabled = true;
items.memoryMode = false;
items.trainAnimationTimer.stop();
items.animateFlow.stop(); // Stops any previous animations
items.listModel.clear();
items.answerZone.currentIndex = 0;
items.sampleList.currentIndex = 0;
items.answerZone.selectedSwapIndex = -1;
if(isNewLevel) {
// Initiates a new level
backupListModel = [];
solutionArray = [];
//Adds wagons to display in answerZone
var identifier;
var idLoco;
// Adds a loco at the beginning
idLoco = "loco" + Math.floor(Math.random() * dataset["noOfLocos"][currentLevel])
addWagon(idLoco, items.listModel.length);
for(var i = 0; i < dataset["WagonsInCorrectAnswers"][currentLevel] - 1; i++) {
do {
identifier = "wagon" + Math.floor(Math.random() * dataset["noOfWagons"][currentLevel])
} while (solutionArray.indexOf(identifier) != -1)
solutionArray.push(identifier);
addWagon(identifier, i);
}
solutionArray.push(idLoco);
} else {
// Re-setup the same level
for(var i = 0; i < solutionArray.length; i++) {
addWagon(solutionArray[i], i);
}
}
if(items.introMessage.visible === false && isNewLevel) {
items.trainAnimationTimer.start()
}
items.bar.level = currentLevel + 1;
items.trainAnimationTimer.interval = dataset["memoryTime"][currentLevel] * 1000
}
function nextLevel() {
if(numberOfLevel <= ++currentLevel) {
currentLevel = 0
}
items.score.currentSubLevel = 1;
isNewLevel = true;
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
items.score.currentSubLevel = 1;
isNewLevel = true;
initLevel();
}
function restoreLevel() {
backupListModel = [];
for (var index = 0; index < items.listModel.count; index++) {
backupListModel.push(items.listModel.get(index).id);
}
isNewLevel = false;
initLevel();
}
function nextSubLevel() {
/* Sets up the next sublevel */
items.score.currentSubLevel ++;
if(items.score.currentSubLevel > dataset["numberOfSubLevels"]) {
nextLevel();
}
else {
isNewLevel = true;
initLevel();
}
}
function checkAnswer() {
/* Checks if the top level setup equals the solutions */
if(items.listModel.count === solutionArray.length) {
var isSolution = true;
for (var index = 0; index < items.listModel.count; index++) {
if(items.listModel.get(index).id !== solutionArray[index]) {
isSolution = false;
break;
}
}
if(isSolution == true) {
items.mouseEnabled = false; // Disables the touch
items.bonus.good("flower");
}
else {
items.bonus.bad("flower");
}
}
else {
items.bonus.bad("flower");
}
}
function addWagon(uniqueID, dropIndex) {
/* Appends wagons to the display area */
items.listModel.insert(dropIndex, {"id": uniqueID});
}
function getDropIndex(x) {
var count = items.listModel.count;
for (var index = 0; index < count; index++) {
var xVal = items.answerZone.cellWidth * index
var itemWidth = items.answerZone.cellWidth
if(x < xVal && index == 0) {
return 0;
}
else if((xVal + itemWidth + items.background.width * 0.0025) <= x && index == (count - 1)) {
return count;
}
else if(xVal <= x && x < (xVal + itemWidth + items.background.width * 0.0025)) {
return index + 1;
}
}
return 0;
}
function generateUniqueId() {
uniqueId = [];
var index;
for(index = 0; index < dataset["noOfLocos"][currentLevel]; index++) {
uniqueId.push("loco" + index)
}
for(index = 0; index < dataset["noOfWagons"][currentLevel]; index++) {
uniqueId.push("wagon" + index)
}
}
diff --git a/src/activities/readingh/ActivityInfo.qml b/src/activities/readingh/ActivityInfo.qml
index f5141d341..9fc125c85 100644
--- a/src/activities/readingh/ActivityInfo.qml
+++ b/src/activities/readingh/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Johnny Jazeix <jazeix@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "readingh/Readingh.qml"
difficulty: 2
icon: "readingh/readingh.svg"
author: "Johnny Jazeix &lt;jazeix@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Horizontal reading practice")
//: Help title
description: qsTr("Read a list of words and work out if a given word is in it.")
// intro: "Read a list of words and say if a given word is in it."
//: Help goal
goal: qsTr("Reading training in a limited time")
//: Help prerequisite
prerequisite: qsTr("Reading")
//: Help manual
manual: qsTr("A word is shown on the board. A list of words, displayed horizontally, will appear and disappear. Does the given word belong to the list?")
credit: ""
section: "reading"
createdInVersion: 5000
}
diff --git a/src/activities/readingh/Readingh.qml b/src/activities/readingh/Readingh.qml
index 6d4a648c9..7eb3640cd 100644
--- a/src/activities/readingh/Readingh.qml
+++ b/src/activities/readingh/Readingh.qml
@@ -1,302 +1,302 @@
/* GCompris - readingh.qml
*
* Copyright (C) 2015 Johnny Jazeix <jazeix@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Johnny Jazeix <jazeix@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "readingh.js" as Activity
import "qrc:/gcompris/src/core/core.js" as Core
ActivityBase {
id: activity
onStart: focus = true
onStop: {}
/* mode of the activity, "readingh" (horizontal) or "readingv" (vertical):*/
property string mode: "readingh"
pageComponent: Image {
id: background
anchors.fill: parent
source: Activity.url + "reading-bg.svg"
signal start
signal stop
sourceSize.width: parent.width
fillMode: Image.Stretch
Component.onCompleted: {
dialogActivityConfig.getInitialConfiguration()
activity.start.connect(start)
activity.stop.connect(stop)
}
// system locale by default
property string locale: "system"
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property alias background: background
property alias bar: bar
property alias bonus: bonus
property alias wordlist: wordlist
property alias wordDropTimer: wordDropTimer
property alias locale: background.locale
property alias iAmReady: iAmReady
property alias answerButtonFound: answerButtonFound
property alias answerButtonNotFound: answerButtonNotFound
property alias answerButtonsFlow: answerButtonsFlow
property alias wordDisplayRepeater: wordDisplayRepeater
property string textToFind
property int currentIndex
property bool buttonsBlocked: false
}
onStart: { Activity.start(items, mode) }
onStop: { Activity.stop() }
DialogActivityConfig {
id: dialogActivityConfig
currentActivity: activity
content: Component {
Item {
property alias localeBox: localeBox
height: column.height
property alias availableLangs: langs.languages
LanguageList {
id: langs
}
Column {
id: column
spacing: 10
width: parent.width
Flow {
spacing: 5
width: dialogActivityConfig.width
GCComboBox {
id: localeBox
model: langs.languages
background: dialogActivityConfig
width: dialogActivityConfig.width
label: qsTr("Select your locale")
}
}
}
}
}
onClose: home()
onLoadData: {
if(dataToSave) {
if(dataToSave["locale"]) {
background.locale = dataToSave["locale"];
}
}
}
onSaveData: {
var oldLocale = background.locale;
var newLocale = dialogActivityConfig.configItem.availableLangs[dialogActivityConfig.loader.item.localeBox.currentIndex].locale;
// Remove .UTF-8
- if(newLocale.indexOf('.') != -1) {
+ if(newLocale.indexOf('.') !== -1) {
newLocale = newLocale.substring(0, newLocale.indexOf('.'))
}
dataToSave = {
"locale": newLocale,
}
background.locale = newLocale;
// Restart the activity with new information
if(oldLocale !== newLocale) {
background.stop();
wordDisplayList.layoutDirection = Core.isLeftToRightLocale(background.locale) ? Qt.LeftToRight : Qt.RightToLeft;
background.start();
}
}
function setDefaultValues() {
var localeUtf8 = background.locale;
if(background.locale != "system") {
localeUtf8 += ".UTF-8";
}
for(var i = 0 ; i < dialogActivityConfig.configItem.availableLangs.length ; i ++) {
if(dialogActivityConfig.configItem.availableLangs[i].locale === localeUtf8) {
dialogActivityConfig.loader.item.localeBox.currentIndex = i;
break;
}
}
}
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level | config }
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
onConfigClicked: {
dialogActivityConfig.active = true
dialogActivityConfig.setDefaultValues()
displayDialog(dialogActivityConfig)
}
}
Bonus {
id: bonus
// Do not pass automatically at next level, allowing the child to do more than one try, or add sublevels?
Component.onCompleted: {
win.connect(resetClickInProgress)
loose.connect(resetClickInProgress)
}
}
function resetClickInProgress() {
items.buttonsBlocked = false
Activity.initLevel()
}
Flow {
id: wordDisplayList
spacing: 20
x: 70/800*parent.width
- y: 100/600*parent.height
+ y: 100/600*parent.height - 40 * ApplicationInfo.ratio
width: 350/800*parent.width-x
- height: 520/600*parent.height-y
+ height: 520/600*parent.height-y - 40 * ApplicationInfo.ratio
flow: mode == "readingh" ? Flow.LeftToRight : Flow.TopToBottom
layoutDirection: Core.isLeftToRightLocale(locale) ? Qt.LeftToRight : Qt.RightToLeft
Repeater {
id: wordDisplayRepeater
model: Activity.words
property int idToHideBecauseOverflow: 0
delegate: GCText {
text: modelData
color: "#373737"
opacity: iAmReady.visible ? false : (index == items.currentIndex ? 1 : 0)
onOpacityChanged: {
/* Handle case where we go over the image
On these cases, we hide all above items to restart to 0
As we don't replay the same level and always replace the model,
we do not care about restoring visible to true */
if((x+width > wordDisplayList.width) ||
(y+height > wordDisplayList.height)) {
var i = wordDisplayRepeater.idToHideBecauseOverflow;
for(; i < index; ++i) {
wordDisplayRepeater.itemAt(i).visible=false
}
wordDisplayRepeater.idToHideBecauseOverflow = i
}
}
}
}
}
GCText {
id: wordToFindBox
x: 430/800*parent.width
y: 90/600*parent.height
- text: qsTr("<font color=\"#373737\">Check if the word<br/><b><font color=\"#315AAA\">%1</font></b><br/><font color=\"#373737\">is displayed").arg(items.textToFind)
+ text: qsTr("<font color=\"#373737\">Check if the word<br/></font><b><font color=\"#315AAA\">%1</font></b><br/><font color=\"#373737\">is displayed</font>").arg(items.textToFind)
color: "#373737"
horizontalAlignment: Text.AlignHCenter
width: background.width/3
height: background.height/5
fontSizeMode: Text.Fit
}
ReadyButton {
id: iAmReady
onClicked: Activity.run()
x: background.width / 2
y: background.height / 2.2
anchors.verticalCenter: undefined
anchors.horizontalCenter: undefined
theme: "light"
}
Flow {
id: answerButtonsFlow
x: iAmReady.x
y: iAmReady.y
width: wordToFindBox.width
AnswerButton {
id : answerButtonFound
width: Math.min(250 * ApplicationInfo.ratio, background.width/2-10)
height: 60 * ApplicationInfo.ratio
textLabel: qsTr("Yes, I saw it!")
isCorrectAnswer: Activity.words ? Activity.words.indexOf(items.textToFind) != -1 : false
onCorrectlyPressed: bonus.good("flower")
onIncorrectlyPressed: bonus.bad("flower")
blockAllButtonClicks: items.buttonsBlocked
onPressed: {
items.buttonsBlocked = true
}
}
AnswerButton {
id : answerButtonNotFound
width: Math.min(250 * ApplicationInfo.ratio, background.width/2-10)
height: 60 * ApplicationInfo.ratio
textLabel: qsTr("No, it was not there!")
isCorrectAnswer: !answerButtonFound.isCorrectAnswer
onCorrectlyPressed: bonus.good("flower")
onIncorrectlyPressed: bonus.bad("flower")
blockAllButtonClicks: items.buttonsBlocked
onPressed: {
items.buttonsBlocked = true
}
}
}
Wordlist {
id: wordlist
defaultFilename: Activity.dataSetUrl + "default-en.json"
// To switch between locales: xx_XX stored in configuration and
// possibly correct xx if available (ie fr_FR for french but dataset is fr.)
useDefault: false
filename: ""
onError: console.log("Reading: Wordlist error: " + msg);
}
Timer {
id: wordDropTimer
repeat: true
interval: 1000
onTriggered: Activity.dropWord();
}
}
}
diff --git a/src/activities/readingh/readingh.js b/src/activities/readingh/readingh.js
index a953392ca..a3548a1dd 100644
--- a/src/activities/readingh/readingh.js
+++ b/src/activities/readingh/readingh.js
@@ -1,118 +1,118 @@
/* GCompris - readingh.js
*
* Copyright (C) 2015 Johnny Jazeix <jazeix@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Johnny Jazeix <jazeix@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
.import GCompris 1.0 as GCompris //for ApplicationInfo
.import "qrc:/gcompris/src/core/core.js" as Core
var currentLevel = 0
var items
var maxLevel
var url = "qrc:/gcompris/src/activities/readingh/resource/"
var dataSetUrl= "qrc:/gcompris/src/activities/wordsgame/resource/"
//
var level
// words to display
var words
function start(items_) {
items = items_
currentLevel = 0
var locale = items.locale == "system" ? "$LOCALE" : items.locale
items.wordlist.loadFromFile(GCompris.ApplicationInfo.getLocaleFilePath(
dataSetUrl + "default-"+locale+".json"));
// If wordlist is empty, we try to load from short locale and if not present again, we switch to default one
var localeUnderscoreIndex = locale.indexOf('_')
// probably exist a better way to see if the list is empty
if(items.wordlist.maxLevel == 0) {
var localeShort;
// We will first look again for locale xx (without _XX if exist)
if(localeUnderscoreIndex > 0) {
localeShort = locale.substring(0, localeUnderscoreIndex)
}
else {
localeShort = locale;
}
// If not found, we will use the default file
items.wordlist.useDefault = true
items.wordlist.loadFromFile(GCompris.ApplicationInfo.getLocaleFilePath(
dataSetUrl + "default-"+localeShort+".json"));
// We remove the using of default file for next time we enter this function
items.wordlist.useDefault = false
}
maxLevel = items.wordlist.maxLevel;
initLevel();
}
function stop() {
items.wordDropTimer.stop();
}
function initLevel() {
items.bar.level = currentLevel + 1;
items.wordDropTimer.stop();
items.answerButtonsFlow.visible = false;
// initialize level
level = items.wordlist.getLevelWordList(currentLevel + 1);
items.wordlist.initRandomWord(currentLevel + 1)
items.textToFind = items.wordlist.getRandomWord()
Core.shuffle(level.words)
words = level.words.slice(0, 15)
items.currentIndex = -1
items.wordDisplayRepeater.model = words
items.wordDisplayRepeater.idToHideBecauseOverflow = 0
items.answerButtonFound.isCorrectAnswer = words.indexOf(items.textToFind) != -1
items.iAmReady.visible = true
}
function nextLevel() {
if(maxLevel <= ++currentLevel) {
currentLevel = 0
}
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = maxLevel - 1
}
initLevel();
}
function run() {
items.wordDropTimer.start();
}
function dropWord() {
if(++items.currentIndex < words.length) {
// Display next word
}
else {
items.wordDropTimer.stop();
items.answerButtonsFlow.visible = true
}
}
diff --git a/src/activities/readingh/resource/reading-bg.svg b/src/activities/readingh/resource/reading-bg.svg
index 52e0d1f54..063ad7888 100644
--- a/src/activities/readingh/resource/reading-bg.svg
+++ b/src/activities/readingh/resource/reading-bg.svg
@@ -1,224 +1,224 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="800"
height="520"
id="svg2"
sodipodi:version="0.32"
inkscape:version="0.91 r13725"
version="1.0"
sodipodi:docname="reading-bg.svg"
inkscape:output_extension="org.inkscape.output.svgz.inkscape">
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.979899"
inkscape:cx="502.02276"
inkscape:cy="314.53198"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
showguides="false"
inkscape:guide-bbox="true"
inkscape:window-width="1878"
inkscape:window-height="1051"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1">
<sodipodi:guide
id="guide3244"
position="-244.45692,789.93929"
orientation="0,1" />
<inkscape:grid
id="grid4151"
type="xygrid" />
</sodipodi:namedview>
<defs
id="defs4">
<linearGradient
id="linearGradient4223"
inkscape:collect="always">
<stop
id="stop4225"
offset="0"
style="stop-color:#87a6dd;stop-opacity:1" />
<stop
id="stop4227"
offset="1"
style="stop-color:#9fb8e3;stop-opacity:1" />
</linearGradient>
<linearGradient
inkscape:collect="always"
id="linearGradient4193">
<stop
style="stop-color:#dcdcdc;stop-opacity:1"
offset="0"
id="stop4195" />
<stop
style="stop-color:#f2f2f2;stop-opacity:1"
offset="1"
id="stop4197" />
</linearGradient>
<linearGradient
id="linearGradient4177"
inkscape:collect="always">
<stop
id="stop4179"
offset="0"
style="stop-color:#ebf1f8;stop-opacity:1" />
<stop
id="stop4181"
offset="1"
style="stop-color:#f2f2f2;stop-opacity:1" />
</linearGradient>
<linearGradient
gradientUnits="userSpaceOnUse"
y2="133.57382"
x2="207.08554"
y1="467.14526"
x1="207.08554"
id="linearGradient4183"
xlink:href="#linearGradient4177"
inkscape:collect="always" />
<linearGradient
gradientUnits="userSpaceOnUse"
y2="57.461983"
x2="581.93799"
y1="188.17625"
x1="581.93799"
id="linearGradient4191"
xlink:href="#linearGradient4193"
inkscape:collect="always"
gradientTransform="matrix(1.09932,0,0,1.2352842,-62.226815,-8.1085626)" />
<linearGradient
gradientUnits="userSpaceOnUse"
y2="69.604843"
x2="565.34314"
y1="178.17627"
x1="565.34314"
id="linearGradient4229"
xlink:href="#linearGradient4223"
inkscape:collect="always"
gradientTransform="matrix(1.09932,0,0,1.2352842,-62.226815,-8.1085626)" />
</defs>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
<dc:date>2016</dc:date>
<dc:creator>
<cc:Agent>
<dc:title>Timothée Giet</dc:title>
</cc:Agent>
</dc:creator>
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Notice" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
<g
transform="translate(-6.0141234,-15.002437)"
id="layer1"
inkscape:groupmode="layer"
inkscape:label="Calque 1">
<rect
ry="11.100569"
rx="10.181538"
y="15.002437"
x="6.0141234"
height="520"
width="800"
id="rect2433"
style="opacity:1;fill:#e8e7e2;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
<g
inkscape:label="Calque 1"
id="layer1-7"
transform="matrix(1.0529823,0,0,1.0529823,-120.02203,-559.23209)">
<rect
transform="matrix(0,1,-1,0,0,0)"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#87491d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
id="rect5232"
width="499.99985"
height="1072.3112"
x="552.36224"
y="-1036.1866"
rx="2.2577578e-06" />
<path
inkscape:connector-curvature="0"
id="rect5232-3"
d="m 1037.4251,530.72906 c -30.8324,0.85466 -61.905,3.10987 -92.1944,3.24906 -26.71474,-3.20568 -52.72766,-0.34334 -78.98747,-2.91797 -26.51487,-0.4957 -48.94697,1.86092 -74.64377,1.91028 -25.92905,-2.80495 -49.18689,1.36183 -74.96305,-0.71356 -27.35497,8.19226 -52.34231,-7.42092 -79.03467,1.14304 -27.75437,-3.3168 -53.94949,-2.34604 -82.15296,-2.12676 -31.66761,0.21455 -64.34662,-2.09974 -95.78702,2.22766 -22.5882,-3.87911 -40.63767,-1.22437 -61.82261,0.005 -28.58727,-5.71549 -56.85461,3.8133 -83.22828,-3.45477 -22.01595,6.02752 -40.51131,1.28418 -62.36962,0.99646 -24.26492,2.78843 -49.37459,-1.5781 -71.96748,2.1728 -28.61537,-3.82935 -59.10806,-1.83893 -86.99626,1.02417 -30.6828,0.37896 -60.051302,-6.9351 -90.96298,-1.91757 -28.845214,-2.6913 -50.515879,-3.45788 -38.739926,29.89011 -9.703043,26.69679 30.103408,23.36773 49.573938,18.01703 20.146944,4.57241 39.425268,2.70723 59.141168,4.41111 24.08814,-4.29081 49.96209,-2.05677 74.2253,-2.58617 24.70129,-3.8168 48.8227,1.84029 74.24947,-0.98522 27.20848,0.34499 54.49348,2.9656 81.5114,-0.68194 27.12522,-0.10656 51.62328,1.61784 78.20092,0.11837 31.78055,-2.80829 62.37443,8.04168 93.21847,0.92374 23.88805,5.58779 45.17461,-2.27508 69.458,3.58659 23.65194,3.29067 51.00979,-2.85102 74.50206,0.33591 23.42596,4.17903 52.44451,-3.84007 75.24339,3.78504 30.47783,-4.00552 58.20132,3.42568 88.46219,-1.88994 22.8104,-1.94062 43.59733,6.75469 64.17532,1.67881 28.40905,10.42346 58.68374,0.30001 88.33475,2.29001 29.16862,1.241 57.44822,4.49175 85.37932,6.04625 32.883,6.11713 13.3829,-35.87712 16.6119,-53.73305 2.6627,-1.84158 -1.7253,-14.74145 -1.7827,-10.79991 m 2.2624,73.17152 c -33.1296,-8.21597 -67.484,-2.78837 -101.09245,-5.46425 -29.09238,-4.72158 -59.51786,2.16635 -88.96286,-4.04643 -31.13044,5.18492 -60.42617,-2.46975 -92.76266,2.36595 -27.28128,-7.82226 -55.15805,-5.81526 -83.73765,-3.60609 -21.92767,-5.08115 -44.91262,1.2389 -67.27333,-1.16093 -27.37321,-3.72091 -52.748,-2.90851 -82.2766,-1.10033 -20.59989,-3.30858 -45.21027,-1.17715 -66.89758,-0.7525 -29.30488,-8.35085 -62.80058,-1.31602 -95.10944,-1.2383 -22.81822,-4.31326 -46.06559,-1.58447 -67.53223,-0.66139 -25.25554,-3.47473 -47.80749,-2.0194 -72.8084,0.47998 -26.18604,-3.67169 -59.0859,-1.02622 -85.18097,0.0671 -26.99849,-3.21053 -55.12604,-0.17926 -82.00235,-0.15157 -28.851456,1.27889 -56.410525,-0.0622 -84.827184,-0.47218 -2.551433,12.19966 10.380377,51.99228 2.432177,51.12872 20.262079,1.33086 41.780037,-2.41169 64.086177,-1.97678 23.2462,3.86265 45.22375,-4.78629 67.0351,1.23029 24.98699,-0.52869 46.79516,-2.5411 70.07156,-0.25221 30.08093,1.41369 59.00075,-8.52283 88.12189,0.58586 23.69342,-4.17155 49.74635,-0.8234 73.75883,-2.42997 24.76302,2.63366 51.77358,1.35451 77.08966,-0.0233 24.40994,0.0967 46.22512,2.01644 70.74407,4.58514 31.04293,-0.84663 60.86069,-2.99327 91.13825,1.06308 23.73872,0.57124 50.28382,-6.49974 74.48717,2.32159 26.04813,3.15909 51.85507,-8.51272 76.56365,1.24074 25.30877,-6.602 49.72997,5.16584 75.94866,1.10522 31.66,0.12323 63.96471,-0.93803 95.63343,3.31994 24.20068,-5.52457 47.48128,3.93291 72.40268,1.16044 23.7149,-2.59769 47.3705,5.47306 68.971,1.98979 5.4923,-11.06238 0.5581,-36.39032 0.6781,-49.8163 0.2765,-0.21716 -1.4767,-3.99793 0.3672,-3.34877 m 1.1001,59.47126 c -30.6314,5.47136 -63.0612,-3.29417 -94.9517,0.21147 -21.65893,-3.07763 -46.9423,-7.55125 -69.81811,-2.41379 -18.83594,-5.08766 -41.06628,3.61977 -59.56765,-5.20352 -23.17845,-0.98492 -49.55779,2.54982 -70.18441,-2.33645 -26.0831,1.62482 -52.89885,1.04294 -78.56172,-1.65447 -19.40964,7.91241 -40.09448,-6.42217 -60.85284,1.5553 -27.95635,-5.1417 -56.02074,-3.66679 -84.36014,-2.79275 -27.54445,-5.76107 -53.2959,4.23047 -79.16745,-3.43176 -25.67218,6.76449 -51.98651,-4.39207 -77.65994,3.1722 -29.69317,-2.26443 -59.39768,-3.60168 -89.75484,-4.52692 -26.84977,-2.14378 -54.34843,7.58269 -81.38749,2.19076 -24.38036,-2.71734 -49.03075,3.40701 -75.21522,1.25524 -21.99774,-2.68779 -45.19236,-0.98806 -66.87422,-2.52199 -29.410703,6.51528 -55.879088,-1.21349 -85.362073,5.01749 16.148604,8.4841 50.391223,2.45174 74.593041,5.86385 28.686952,-7.17488 56.705242,1.71996 86.686122,-0.87554 23.84552,-1.69142 47.37189,-0.74715 71.11321,-1.26875 27.1762,-4.97781 52.31096,0.20587 78.76484,-1.04188 23.94025,1.08364 51.67667,-2.7986 77.1577,-0.51996 25.96386,3.24892 54.25032,4.50106 79.12609,0.36405 27.06065,8.01687 57.38459,0.86518 83.7868,2.50212 31.97626,5.25919 61.22224,-1.44759 93.05028,2.59712 24.60424,1.34078 52.87699,0.69203 76.96174,2.41814 27.39068,3.83138 53.93859,-5.65569 81.37869,-0.0963 19.69197,6.62772 46.75697,-4.55804 67.62693,4.7519 28.54422,-0.82106 56.2317,-0.45038 83.8193,3.60142 31.29006,-0.37243 64.07926,-0.44779 95.96826,1.19656 14.9329,4.45763 20.3195,2.27895 24.0325,-7.9368 m 1.3179,16.84391 c -34.236,-3.0674 -68.2496,-1.6607 -100.9822,-5.04372 -24.28312,1.50802 -48.87003,-2.25778 -74.08536,-2.35556 -27.96354,4.99599 -56.26791,-6.85119 -83.60563,-1.29846 -23.21441,-4.7783 -41.39572,2.06876 -63.92918,-2.91204 -32.96967,-4.73319 -64.5559,5.99875 -96.90918,-3.9123 -19.64946,8.9335 -41.42282,-5.80884 -62.9562,-1.12897 -27.66796,-0.78945 -60.51051,0.10772 -87.78791,-0.47455 -22.93493,-4.9702 -44.50106,5.21529 -66.71668,-0.93617 -28.60131,2.33796 -57.31843,2.4204 -85.79319,1.84106 -25.2564,-6.06318 -55.37537,2.76093 -79.35979,-2.02221 -28.6399,-1.80279 -59.40573,-1.03615 -87.45242,1.8394 -22.70356,-7.46815 -46.25627,4.99722 -69.30075,-1.79722 -27.15765,2.71717 -51.916181,-1.91787 -78.765524,4.36139 -20.965561,0.66354 -44.162504,-13.98995 -37.009518,13.86926 24.186701,-9.88901 53.047252,-0.44888 78.050552,-3.88153 26.46972,-2.11286 49.1277,2.43755 75.12901,-1.8142 32.9496,5.87608 64.37143,-0.71018 97.43473,0.29785 23.9546,-0.5483 47.68062,-0.31312 70.46216,1.25384 27.29591,4.07458 52.47371,-2.79411 78.64411,-0.14452 24.19246,3.18226 49.68721,1.90859 71.52799,0.3085 30.64106,1.91691 61.07634,1.29473 91.60835,0.48124 27.27928,4.88604 54.63667,-0.009 80.22957,4.24458 30.15262,-0.0817 56.72413,2.45604 86.44196,1.20114 26.37855,1.93878 52.7444,0.51807 78.79023,1.5976 22.7218,-0.47239 46.53511,4.57225 69.02695,4.87027 23.4778,-1.60718 44.72576,-3.58188 67.87783,0.96628 23.93971,1.67206 47.36629,1.12659 68.27649,0.35008 18.2627,-6.78372 70.7974,19.27465 60.4409,-12.12407 -1.8439,1.12149 2.7971,1.17407 0.8696,1.54577 m -0.4639,36.89008 c -22.6843,-0.35879 -50.2564,-6.31914 -74.0368,-3.18506 -30.36573,-1.80079 -58.88572,-4.04018 -88.58573,-2.97213 -23.76553,-2.01926 -48.03448,-4.52809 -71.98687,-1.80287 -31.58606,-4.50834 -63.35533,-3.86873 -93.95966,-3.691 -27.4649,-1.52848 -56.77673,-0.0683 -82.7321,-3.73334 -25.13189,0.55105 -47.56723,-0.41552 -72.13218,0.7047 -32.67824,-3.02968 -65.90296,0.43848 -98.28865,-3.24587 -25.98503,4.25808 -50.76827,1.19385 -76.05682,0.61015 -25.95557,1.97709 -51.13452,-5.7287 -78.4429,-0.57406 -27.88184,-3.80304 -57.40849,-2.33787 -85.76516,-2.53867 -27.86946,5.59084 -58.80709,-3.00972 -87.54615,0.76224 -29.01316,5.15145 -59.32561,-2.15201 -89.693455,3.93282 -23.512937,-7.3753 -55.333169,-2.33398 -75.99288,2.74298 25.317682,9.28292 56.399729,4.79355 83.489875,3.36059 22.49396,3.15401 47.96831,-0.31256 72.10899,0.85892 24.88932,1.73716 47.36389,-2.88243 72.85931,-3.37537 26.49753,4.53189 60.61194,1.18589 87.51166,2.65602 28.98088,-2.31339 58.0255,4.52292 86.20503,-2.26182 29.62498,6.28482 59.36676,-2.77632 89.15917,4.57253 28.70976,-5.02253 56.36125,3.23132 83.42361,-1.96069 27.89446,6.46415 60.57352,-1.91394 89.2433,4.48748 22.95977,-0.86761 47.08577,-0.9058 68.80927,2.66181 29.54641,-4.87141 55.92588,0.88827 83.93005,0.17291 27.58514,2.71017 54.07771,-0.57487 81.38551,4.86794 29.09761,-4.71838 55.52542,-0.0664 84.47038,-0.30964 16.7827,4.28496 36.0519,4.57824 54.2029,2.01328 16.6707,1.46443 41.4633,8.07698 37.5843,-4.67771 l 0.6416,0.54222 -0.6962,-5.5e-4 m -2.3122,12.5105 c -28.5443,1.95929 -56.3473,-1.49555 -84.8247,-3.27267 -29.13826,2.55961 -57.94131,-0.69695 -87.9681,-2.0373 -28.25703,3.72937 -54.93229,-4.62231 -83.91033,-0.81518 -28.69502,-6.02686 -55.4076,-0.0419 -84.199,-4.45465 -32.0743,-0.33472 -61.16078,-2.58124 -93.56642,-3.05616 -26.42333,1.04336 -52.26444,0.18901 -78.52388,-0.44029 -23.51627,-4.75255 -43.90868,5.04832 -67.07771,-0.22738 -31.09709,-2.4377 -61.72844,-0.42754 -93.77326,1.82223 -25.36826,-8.41525 -52.6827,-3.80506 -79.00526,-2.89824 -21.74837,-0.007 -45.50088,1.59851 -68.09883,-0.13748 -24.84134,-0.12504 -48.46537,-0.0637 -73.27737,1.73838 -27.85939,-4.47185 -53.93367,-2.07071 -80.3074,0.37892 -25.989127,-0.0689 -52.627687,-0.61826 -77.081779,-0.23807 -25.757222,-12.06339 -24.956034,42.37315 1.832564,21.00298 31.850564,5.31352 60.727275,-2.59609 93.665345,0.26047 28.86061,-0.48483 57.73248,-3.04594 85.35883,0.73315 27.87073,-5.67352 54.49772,1.253 82.13608,-0.92911 22.05912,0.22142 46.15112,-1.81431 66.55174,1.83113 24.49018,2.76549 48.19971,-5.75576 71.1158,-1.33967 23.29576,2.0199 44.7639,0.13577 67.39214,2.73194 22.86889,-1.54307 50.10508,-6.6593 73.10909,0.94138 27.11769,-3.13574 53.27818,1.96227 81.50297,1.77899 30.67534,-6.50086 56.90728,6.70741 87.65861,0.48942 21.91872,1.83901 42.14409,2.06736 63.82505,0.0404 24.64978,3.87043 50.03345,0.58074 75.30922,5.58247 30.89706,1.889 57.67572,-0.84877 89.06918,2.27655 21.22712,0.58795 40.35652,7.65706 59.85332,1.0396 26.3612,0.52594 62.3437,13.8307 56.0898,-21.94934 -0.3481,-0.24211 1.3114,-2.07122 0.02,-0.99703 m 0.7347,42.26185 c -26.0459,-8.92368 -52.5924,2.59029 -78.4512,-3.30052 -22.77314,0.0895 -46.37986,-6.075 -69.83062,-0.78347 -26.53488,-5.5813 -54.08204,1.461 -82.43149,-5.25995 -28.67054,-5.1039 -57.71858,0.20083 -85.25267,-3.42954 -29.35204,4.12919 -58.34193,-7.73069 -88.31594,-0.26004 -28.61449,-6.05919 -60.20749,1.09266 -88.67013,-5.70077 -28.28543,2.31546 -56.24358,-0.13957 -84.43144,0.10928 -25.61888,-3.17762 -55.82974,7.09663 -81.08448,-2.03401 -24.34158,1.37628 -48.02778,-2.82068 -71.4193,0.2916 -30.7463,-1.92155 -64.31696,-1.9958 -93.52576,-0.21073 -25.93026,-1.87251 -48.38591,-1.43087 -75.49559,1.06289 -26.98451,-4.16562 -54.29999,2.06316 -81.8533,0.81605 -24.017785,-0.68378 -46.624082,-1.25268 -70.299779,-0.0117 -37.699053,-10.46689 -16.131491,31.17707 -24.43676,53.00281 9.015811,21.7408 50.020402,2.92441 71.139628,7.65803 33.205341,2.18817 63.623881,-2.08637 96.039891,1.22082 24.43522,-4.46189 50.55735,1.78154 73.54552,-2.46908 25.05509,4.05752 49.1157,-4.43679 73.19767,2.4929 24.80966,-3.34111 47.93232,0.39191 73.48444,-0.41851 22.67079,1.61132 49.2761,1.83062 73.87169,1.90018 22.5602,-1.50546 51.08277,-0.4963 76.09792,0.0885 28.85745,5.65884 56.84812,-2.01341 86.68693,3.78376 24.59554,-0.0808 48.02248,0.0881 72.05143,2.48241 23.97063,3.09169 44.95192,-0.94158 67.89269,2.5163 26.69183,1.5059 50.21815,-0.40618 77.00749,3.77096 22.88382,-8.56512 45.29018,5.74482 67.94351,0.28871 31.27991,2.94318 62.55356,5.84828 92.36835,5.81697 18.9779,-4.63127 72.4188,17.75049 70.5354,-6.91943 0.4142,-17.20475 -2.7628,-45.74212 3.4884,-56.32151 l 0.5293,0.47851 -0.5954,-0.14686 m 0.1826,71.3569 c -25.4711,-1.71211 -48.0264,-2.68304 -72.7031,-5.31808 -29.53927,5.10201 -59.7279,-7.73866 -88.56153,-1.87218 -22.70593,-8.60919 -47.61973,2.00505 -71.13709,-6.02024 -27.29647,-0.77912 -52.14686,-3.80136 -78.28826,-0.79448 -16.96816,-8.09763 -38.41183,1.72242 -57.94977,-4.99141 -26.61253,-0.34643 -53.55299,-3.23265 -81.12246,-2.17485 -27.52635,-2.78965 -55.08706,0.36294 -82.84373,-3.78881 -19.98685,3.47505 -41.71123,0.66987 -63.20279,-1.34658 -22.75629,7.11164 -45.62935,-5.84971 -67.42889,2.68101 -26.74717,-4.79619 -51.07449,-1.47334 -76.58315,-1.87857 -25.12908,-0.49293 -50.58718,-1.09909 -74.08451,-3.27616 -25.1682,-4.05202 -48.27809,6.4056 -72.39412,1.79842 -27.94608,-0.55023 -54.74775,3.43279 -83.52779,0.0107 -24.68492,2.61336 -53.101516,5.54986 -78.945437,1.48351 -30.627595,-2.19293 -36.256308,29.61345 0.142666,19.04975 25.829793,0.96089 55.074821,1.9673 81.634031,-3.38621 24.57213,4.04938 50.21968,-3.53973 77.67303,1.15064 24.35446,-1.28532 47.80674,1.13155 72.0062,-0.79655 22.8594,-0.38638 43.69749,2.58803 66.72885,-1.50455 31.14954,3.55265 64.80161,-0.74897 95.83018,4.28973 28.07949,-1.918 52.38272,-1.4692 81.11368,-1.18673 22.85679,5.11777 40.75505,1.45607 64.37402,3.08268 25.32366,-1.24984 53.53656,4.51385 81.55957,0.57888 24.42294,3.65487 48.0672,3.50756 73.68987,5.28993 28.81546,-5.33412 56.31627,4.50686 84.66829,2.00851 27.25531,4.48137 56.48991,-0.66449 83.50174,1.54305 26.77699,8.18071 54.69636,0.32722 82.13876,7.99105 28.39334,-0.3292 56.41264,1.45481 84.41594,1.5817 32.6622,12.45922 3.9955,-15.23699 19.3561,-14.45073 m -3.5209,19.36182 c -22.1863,0.60563 -50.3595,3.33994 -69.5268,-4.43767 -32.61977,2.68528 -62.84319,-5.96242 -95.43645,-3.10666 -25.2948,3.57981 -50.86075,-5.45848 -75.80942,-2.38711 -28.08744,0.71746 -55.74551,-5.21612 -83.08815,-3.5241 -27.27736,-4.26867 -57.12832,0.0212 -86.42012,-4.45269 -28.27844,-0.61274 -56.8785,-2.0869 -86.23912,-0.29661 -26.23052,-7.38685 -53.2196,-2.23273 -80.73239,-1.11517 -25.4841,-1.50802 -47.91363,-4.83178 -71.65884,-3.84526 -27.31898,1.89962 -53.48574,-3.10795 -82.9876,0.28024 -24.77892,-4.73798 -49.10931,0.7005 -75.34834,-0.82336 -28.92064,-5.1627 -59.17507,3.49424 -88.74628,-0.0461 -27.33607,1.06373 -54.02091,-3.09143 -80.08707,0.52451 -28.268705,1.61135 -52.107301,-2.13234 -79.822269,3.39839 -22.429474,-9.54631 -12.633518,34.03957 -10.905917,33.97972 29.949195,-1.73522 61.24122,-1.37344 89.441316,-3.11665 26.23528,5.74446 51.71214,-3.56331 77.79231,1.18903 24.98243,-4.98791 55.01319,-0.986 81.44082,-4.0552 27.81393,3.8956 54.5161,3.05237 83.55479,3.95767 26.00214,-2.43072 52.35323,-5.31322 78.64598,1.38718 19.46903,-9.94699 40.70743,2.60151 58.4067,-1.37475 28.36614,3.07268 57.9216,0.26816 88.69726,0.70778 27.48919,4.74809 53.18669,4.32316 79.30653,2.73201 25.79196,2.71954 52.20469,5.0246 78.87459,3.28559 27.00522,3.65092 53.25856,-0.66246 80.7946,5.83697 26.15704,-2.02288 51.47883,1.68246 77.1056,-0.91141 20.97435,4.62498 39.13627,6.23494 60.95678,4.37492 24.83029,1.87071 53.20859,4.88127 80.20459,3.30668 22.7211,-2.04499 64.9095,18.93611 52.6742,-14.43171 1.5141,-3.72848 5.6721,-22.88109 -1.6772,-14.78775 m 0.7031,43.71758 c -28.8564,4.82074 -57.2701,-3.2315 -86.232,-5.81077 -23.58572,1.12624 -46.43696,2.3217 -69.56046,-1.93977 -26.25699,0.8752 -54.3815,-1.16335 -81.38686,-3.30886 -32.64609,0.41172 -64.57987,-5.65668 -96.02399,-1.22666 -26.38483,-8.05244 -54.07745,-1.04934 -79.8835,-7.08144 -24.75237,0.48328 -49.70194,-0.30944 -75.81147,0.21898 -28.2932,1.57494 -56.45582,-7.3673 -84.49571,-1.28828 -26.76485,-3.84529 -53.82526,-0.82968 -82.29426,-4.60873 -25.14068,0.95452 -49.88476,4.60669 -74.91879,-1.08989 -22.2881,8.81456 -47.02928,-1.59709 -67.66383,2.44449 -24.4423,-6.872 -51.49245,3.32691 -76.47421,-1.261 -24.49518,4.44205 -45.27634,-1.25912 -67.19969,2.39102 -24.17714,-1.46994 -46.43943,-0.99087 -70.712616,-0.96201 -24.789819,3.70951 -68.485459,-10.18756 -60.968004,23.89831 15.515001,12.98493 49.71915,4.4007 72.351227,3.35564 21.788243,0.39713 48.383253,-0.64829 72.628883,-1.08138 24.68974,2.07252 49.23301,-2.05757 73.87508,1.80473 26.35988,-2.5016 57.38548,2.00883 83.67126,-3.05089 29.87851,0.39684 56.61133,0.51799 85.46787,3.94727 23.11758,-1.10472 43.20605,-3.16436 65.14899,-1.48848 25.73747,3.05512 53.05037,4.61025 76.96163,0.7556 23.25628,3.68882 47.80572,2.06172 71.84689,2.74593 26.1629,0.51905 48.31475,3.84883 74.67784,0.99343 25.99744,4.33365 56.29822,1.04378 85.30895,5.79285 29.70937,-0.97563 55.5061,4.14261 86.41348,3.36383 31.60383,-1.42833 66.51782,3.80456 97.17878,4.32402 26.89626,-3.25386 52.20571,6.8889 80.06871,4.92254 26.4489,0.0368 59.2773,9.29265 50.5151,-22.8508 l 0.1606,-0.7654 -1.1576,-3.53822 m -2.3288,32.42212 c -27.4389,-3.39093 -56.1183,0.43523 -84.8291,-4.28958 -32.42609,-5.6997 -62.61389,-1.49765 -95.48364,-5.02953 -30.84469,0.17842 -57.99561,-1.67672 -87.93046,-3.59788 -23.92386,-0.4274 -51.26566,-5.31951 -74.88251,-2.0962 -23.62015,-1.4268 -48.23264,-5.4599 -74.15532,-6.4302 -25.68131,1.1843 -49.41533,2.58774 -76.11865,-0.84666 -20.5265,6.26454 -43.92652,-4.71346 -65.57032,-0.44052 -30.8459,-1.228 -63.39812,2.16395 -93.47385,-4.22541 -24.61197,2.01208 -52.04566,-1.86006 -74.49906,2.93157 -24.81934,1.83801 -49.88634,-5.0183 -73.66263,-0.19535 -22.1346,0.11907 -44.89763,-4.8438 -64.39683,0.19158 -27.42429,-3.12099 -56.05046,1.56909 -84.81358,-2.08894 -24.72475,2.40182 -48.04008,0.0297 -72.856341,1.83091 -22.982428,3.88715 -57.805453,-11.28446 -47.572642,23.62979 -15.497197,36.30793 37.767701,24.20353 58.425031,20.73427 25.448562,3.08546 51.990422,2.38786 78.435372,1.72036 24.19382,-4.76336 47.48591,-1.08166 72.01278,-0.5321 29.82241,-6.16586 60.03455,-2.39506 88.2265,0.2765 20.71002,-7.69686 40.96067,0.1462 62.21832,-0.79986 27.50193,3.15076 55.89646,-5.0073 82.31032,1.89016 29.71055,-1.48346 60.96561,-1.41866 89.67559,2.8359 27.18047,-5.87076 55.2208,4.48 83.71839,2.2768 26.0345,-3.3006 54.5416,3.3736 82.02983,2.6458 24.63417,-5.7692 53.20347,6.8751 76.80269,0.6982 25.49736,4.2022 52.34823,4.0541 76.0792,3.0016 26.83311,5.7232 52.26808,7.0905 78.92378,5.2714 24.5277,0.5259 49.78703,5.3372 73.83823,4.3 18.5875,-3.7068 76.1731,19.2319 66.0733,-8.5167 3.5635,-10.115 5.4438,-32.06916 3.5037,-36.88754 m -2.0454,58.56574 c -25.0228,-0.089 -49.1202,-5.1291 -73.2304,-3.1823 -25.28846,-4.0434 -52.56098,-6.4117 -78.22651,-5.0655 -31.45595,-7.501 -61.10116,0.3262 -91.68637,-7.658 -28.95955,2.6158 -55.66151,-5.6152 -83.97629,-0.5044 -26.62958,-0.3828 -52.07193,-10.4169 -77.87626,-3.1809 -27.68325,-3.084 -54.84062,-3.0117 -82.98643,-4.3014 -27.56155,-3.63 -56.64396,-4.0266 -84.849,-2.059 -20.95236,-3.9039 -43.32172,0.423 -63.93341,-2.9607 -30.53201,0.9584 -60.64044,-3.3326 -89.19288,0.7582 -28.77822,-2.2802 -58.4402,-4.6404 -85.55747,-0.9599 -24.61633,5.2056 -49.97357,-3.6524 -75.01166,-1.9892 -24.28569,3.9281 -47.01097,-1.6911 -72.13663,1.4737 -27.01922,3.4698 -57.076499,-1.0083 -83.620846,3.6783 -27.329576,-11.42126 -31.994396,14.6903 -27.019226,31.6263 -14.72987,37.1278 20.140727,31.2281 45.974836,32.2959 23.444333,-3.5122 50.036156,4.8874 75.664656,-1.6211 28.23267,-0.4937 58.49047,2.4953 85.83694,-1.0566 25.45096,2.2212 49.57106,3.8382 75.73681,-1.4275 23.72812,7.2853 45.34424,1.6161 68.45727,1.3697 31.86311,9.0618 66.96374,-3.8783 96.68957,3.2639 25.30347,-3.498 53.63893,-3.4122 77.49041,-0.09 25.27541,-0.5037 50.42079,1.0847 75.92495,-1.6065 20.90265,-1.9232 43.07842,4.6891 62.22971,-1.9958 24.13279,6.161 49.46082,-0.6719 74.73896,3.9815 27.37747,-0.5489 56.12485,-2.3312 81.04969,-1.5728 23.98679,-1.0009 46.31681,0.9408 70.3106,1.385 25.85939,-1.8204 48.79291,-1.0187 73.61967,0.1519 25.06801,-5.6262 47.70411,-0.6233 73.73651,-0.8847 29.9225,10.8273 41.7083,-14.3468 33.2334,-36.2773 l 0.306,-0.6237 -1.3626,-2.0519"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#844617;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
<path
inkscape:connector-curvature="0"
id="rect5232-3-0"
d="m 1037.094,550.5498 c -26.946,9.86379 -59.4223,-8.22074 -86.6842,3.81226 -18.4249,-4.07202 -40.55865,0.91147 -57.64094,-2.1144 -23.57948,-3.84597 -46.25123,3.50591 -69.51205,-1.42527 -23.52241,6.90507 -46.47402,-1.79942 -70.36663,-0.49343 -31.67078,5.10744 -62.89307,0.60077 -95.12391,0.6984 -27.08937,1.67431 -54.27098,0.81044 -83.0619,3.301 -29.20541,-1.73318 -57.69533,1.1704 -87.08099,-0.73064 -28.58931,-0.99817 -51.03294,0.39239 -78.58778,-2.58902 -33.94323,1.88562 -65.81363,-0.78295 -99.97576,0.75655 -26.5182,-1.87241 -49.14782,1.61748 -75.36271,1.7577 -27.5279,-2.27602 -54.01315,-4.94401 -81.2373,-0.14978 -16.71052,-1.86352 -38.91132,1.99926 -58.7788,0.91691 -20.18182,-3.23022 -42.53091,-1.38264 -63.96622,-3.84159 -22.625285,11.39121 -65.553424,-10.87766 -66.58979,12.35304 -5.674299,27.51057 36.245749,7.38817 51.761669,13.93854 27.810241,-0.16948 51.390241,0.39075 81.267951,-0.35104 25.58606,-4.05474 55.71105,2.48055 80.53419,-2.27758 23.55256,0.38588 48.34203,5.85174 71.04891,-0.10163 27.04388,4.84275 52.96961,-1.13284 80.5333,0.94834 31.81671,5.7484 62.29194,-4.39005 94.0141,3.28403 24.82694,-0.19956 50.68764,0.18191 76.17439,0.51839 23.24118,-1.82453 45.12518,0.56132 68.42624,0.91168 29.53375,-1.52051 58.30042,1.22908 89.19315,1.76449 22.10964,-1.46108 47.81225,1.54636 70.15565,0.86269 27.6465,0.39771 55.91651,2.2087 82.91278,0.61191 28.37452,1.52757 57.87786,4.21155 84.55863,3.04988 29.27702,1.33629 57.15612,3.19191 85.89242,2.87394 23.4868,1.56105 69.0973,13.44871 55.7076,-21.95955 -3.3219,-0.41107 3.2696,-14.77426 1.0836,-12.52229 m -2.3034,128.74131 c -24.0915,1.24769 -48.4122,0.40799 -70.5428,-3.72378 -27.0389,1.70234 -53.35438,0.32865 -80.27531,-3.02752 -34.88894,0.52927 -63.00459,1.70872 -97.62511,0.0795 -26.30261,-1.07915 -52.69525,0.30859 -79.27459,-5.5082 -25.34142,8.27472 -52.71969,-1.71391 -78.01813,-0.26815 -25.77727,1.04849 -51.97816,-1.33995 -79.34518,-3.11977 -28.70503,5.09838 -56.57864,-5.74611 -84.52046,1.76558 -25.04914,-2.22056 -53.89336,-1.53749 -76.69429,-0.52071 -19.58778,-2.00877 -42.02507,-1.77884 -60.83869,-1.71632 -23.75073,3.666 -45.6607,-2.28027 -69.47916,-1.7591 -29.32555,1.64617 -54.99529,2.02977 -83.03666,0.38886 -27.29945,2.26394 -54.60684,-0.68574 -82.16712,2.57225 -29.92726,0.4339 -60.62503,-2.95984 -90.283701,-1.5917 -12.205379,1.17229 -62.08651,-0.12582 -25.46364,9.08542 29.631032,-0.70277 54.299031,-1.43029 83.386471,-0.0103 32.33395,-1.77151 61.09381,-5.30861 92.28631,-1.08659 24.79688,-4.42626 49.31163,-0.0911 73.21616,-1.95486 24.57594,4.99217 54.28701,-2.67095 80.42408,0.58308 27.45935,-3.26568 56.50784,2.08939 85.25204,-0.48197 28.49876,-2.22241 61.29266,1.95392 91.39201,3.49433 25.73982,-1.6451 47.83848,0.42259 71.06388,-0.45128 27.99485,1.81893 56.24149,1.18457 87.35348,0.85514 26.62158,4.75811 49.79436,2.13101 76.20288,5.1838 25.67741,-1.39486 53.72837,3.05023 80.2359,0.20222 22.63854,2.36881 45.29165,1.5695 67.28307,3.36632 23.9702,-2.39535 45.89732,1.16711 69.30336,-0.5749 31.6109,2.60442 62.5032,1.72469 93.395,6.33062 12.0782,-2.04139 11.7153,2.2493 7.8845,-9.48629 m -0.3815,14.42621 c -22.9724,2.20938 -46.2195,-3.05353 -69.7986,1.46441 -27.5151,-6.08516 -57.89193,-3.36694 -85.95365,-5.14043 -24.92583,-3.60099 -51.52413,1.88674 -77.14401,-4.73553 -28.03919,7.01684 -57.69719,-2.44443 -86.19768,0.023 -31.81584,-0.0923 -60.33224,-1.44855 -91.30602,-2.13814 -21.85259,-6.89496 -43.92858,3.23995 -64.87644,-3.74517 -21.66584,9.66812 -43.8433,-5.58361 -65.5529,1.91182 -24.52695,-4.25746 -47.24012,2.03445 -71.94255,-3.68665 -28.10403,6.35333 -56.07076,-7.69209 -84.43804,1.11585 -25.43347,1.56744 -52.44559,-5.30208 -76.56556,1.02002 -26.36063,-0.93353 -54.11009,1.46966 -79.1192,-2.42135 -24.44102,-1.13877 -50.08469,2.25834 -75.05972,-0.37512 -29.09076,1.1689 -62.23129,1.09485 -94.69044,1.92245 -12.88219,8.59991 -53.836317,-12.03616 -45.152856,13.0755 16.844999,3.0274 45.383015,0.35712 68.294126,2.24048 20.55707,-6.44341 46.38819,4.35309 67.77597,-4.50323 27.50743,5.90754 51.75218,-4.89782 77.81618,4.17525 27.89788,-5.30065 52.74924,0.51995 79.38988,-3.41336 28.55519,4.65091 55.24367,-3.36789 84.19029,2.44214 29.7582,-4.1622 58.24608,4.8461 87.74049,-1.58258 25.72374,4.37229 48.87667,0.622 75.30336,3.30034 23.93922,-0.43023 49.26929,-0.8157 74.34024,1.29477 22.89976,1.60274 43.6079,-0.50163 66.97945,-0.95341 25.58927,7.95038 52.69197,0.48568 77.97645,5.31821 28.23349,-5.70262 56.87975,3.70857 85.15012,-0.48715 28.53026,0.87 55.58085,6.97672 84.18615,4.77723 24.02026,-2.57247 46.13926,6.38225 69.32756,-0.2877 21.3338,-6.59333 64.9911,14.46018 70.5504,-0.11747 -4.3167,-3.45772 3.6971,-7.51495 0.9448,-10.80941 m 1.1661,36.6398 c -29.5851,6.47593 -59.3748,-9.98739 -88.1216,-0.80079 -28.4755,2.02689 -57.12876,-7.22076 -85.1558,-2.70083 -35.12601,-6.55796 -71.5416,-2.59522 -107.76282,-3.86381 -28.0254,-6.17013 -58.52127,-0.38476 -87.43374,-2.61039 -25.92559,-1.70762 -51.96802,-1.09341 -75.5265,-3.05341 -20.90458,2.46449 -43.92985,-1.11094 -65.47701,-0.0101 -29.63234,3.87956 -59.78835,-6.2843 -87.36463,-0.099 -19.77921,0.29758 -43.78387,-10.5942 -63.7538,-0.75053 -21.38095,-7.82059 -46.51071,3.37801 -69.39197,-3.51517 -26.62859,2.39912 -52.67346,-1.37411 -78.58008,2.69174 -29.79179,-5.82527 -64.64818,1.75824 -96.15011,-3.78196 -24.25183,3.16435 -48.88746,2.70283 -73.5465,0.63032 -28.95315,4.13731 -55.292217,3.24543 -83.524342,4.2302 -36.69501,2.73067 26.03367,9.62019 40.690843,9.19622 29.475519,-4.04838 60.229759,-2.03307 90.078489,0.10207 28.71393,-4.03014 55.99951,-1.65498 84.97472,0.0356 26.88505,-5.4769 53.85413,1.59608 80.74911,-0.29532 24.08601,6.30096 47.40339,-4.51666 68.08625,0.99597 22.77258,-3.52551 52.21101,-1.95293 74.21264,-0.2547 26.604,-3.99417 53.37567,4.78593 80.24392,-1.19654 19.00488,6.95787 39.9301,-3.76387 59.32993,4.20093 25.9783,-4.191 49.53173,3.57423 75.49071,-3.38604 21.99298,9.29588 46.16776,-4.33305 69.14133,5.47337 23.82157,-3.99198 49.82745,-1.82207 74.70891,-2.01867 27.12368,3.91751 54.92777,-1.92254 82.14728,3.11879 24.7683,-8.30955 51.66766,3.28897 78.85127,-3.64077 22.5825,3.42493 42.8722,1.09939 65.5191,4.08815 11.8019,1.40718 29.8468,-8.78024 37.2324,-0.69018 m 0.4363,54.21228 c -28.3247,-0.83041 -55.8351,-2.03997 -83.9204,-3.24996 -24.7212,1.04926 -49.9712,-4.30223 -75.60223,-1.60382 -22.16794,-6.1288 -45.07116,-2.28292 -67.279,-4.43301 -20.81892,2.51179 -43.30009,1.58095 -64.34888,-3.13617 -30.37927,3.45475 -62.5368,0.78421 -94.51613,0.59233 -24.84964,-7.32508 -51.53328,1.46594 -78.06239,-1.61225 -25.14026,-1.8141 -45.0676,-2.23392 -70.12181,-4.8803 -25.44791,2.4328 -54.10346,-2.01946 -81.74517,0.0933 -37.39148,1.81541 -73.28981,-5.74375 -109.44142,0.81214 -23.78854,-8.6953 -53.86345,4.72796 -78.81558,-2.86325 -25.35126,1.32317 -53.87359,2.33751 -79.90279,-1.0647 -31.03797,4.11336 -61.47101,1.91036 -93.09718,1.94651 -24.9849,-1.1136 -45.8881,3.41714 -71.167714,3.77093 -36.542122,-17.22759 -26.688691,28.9954 -21.742297,46.11622 28.906457,-0.62825 53.773271,-1.3742 82.386121,-2.83157 26.2476,1.63517 53.29017,-6.13268 78.77166,1.43007 27.20819,-4.63276 52.88423,-0.92452 80.08696,-0.91804 24.39457,0.61568 45.90978,-2.39825 67.41943,-1.963 22.81687,1.84784 44.66253,3.01461 67.65115,2.89302 29.48652,-2.40935 58.80626,-0.99511 88.58572,-0.19258 24.8391,1.10153 49.78713,0.0237 73.7418,3.41286 23.71101,-4.57352 48.20821,-0.94251 73.60017,2.13598 24.82411,-7.68452 50.60234,2.45407 75.27655,1.67634 23.15091,-2.48895 43.81108,0.79963 67.11318,2.0854 25.84601,0.54357 44.5253,2.55045 71.01773,1.31587 21.49112,3.26944 41.35602,1.66276 63.35054,2.47295 22.98048,1.59865 45.13285,3.07233 68.07648,3.3162 26.8472,6.75499 55.0332,1.82908 81.7164,4.95844 25.4468,5.37152 34.9446,8.27766 28.6184,-18.73422 8.5051,-10.24241 -9.3217,-22.35745 2.4191,-30.87136 m -2.237,79.31833 c -18.6442,3.04126 -37.8138,0.38424 -57.0808,-0.40021 -26.4928,-3.97637 -54.3575,-1.91629 -79.53332,-6.85333 -24.51254,2.18739 -48.34293,-1.42837 -72.18362,-2.20428 -26.55196,-1.2865 -52.80814,1.62297 -76.64349,-4.72536 -25.74963,-3.01727 -52.60022,7.33951 -77.74298,-2.71261 -25.62299,2.46443 -49.96364,-1.44986 -75.62498,0.94895 -20.67942,-7.15707 -45.02065,0.30622 -66.54505,-5.51266 -28.34704,3.03036 -57.83655,-3.25632 -84.4869,-0.93726 -25.16245,-1.09192 -52.4278,-0.7899 -78.22181,-2.62031 -26.07654,4.69666 -52.00725,-1.11809 -79.47376,0.61711 -19.58865,-0.73042 -44.86356,4.13667 -67.67159,-0.27741 -26.99977,-1.37245 -57.65416,5.79377 -82.85602,-0.37499 -24.88114,6.12643 -47.16136,-4.39118 -71.91086,2.41947 -28.17139,3.48581 -57.741566,-0.0636 -86.292701,1.22808 -45.561545,6.70433 27.316084,6.52195 41.694521,6.51736 24.8004,-2.08135 49.72024,1.16668 74.50755,-1.87962 20.96664,2.95366 39.19104,-0.88708 60.88192,1.68297 28.56814,-1.10788 56.02597,-1.62784 85.20589,-1.63048 22.70114,2.75567 44.46542,-0.15609 68.26833,0.13534 23.95617,0.0874 54.21935,2.72104 80.53901,2.06362 22.41774,4.7076 45.7592,-5.48518 68.89236,1.97624 31.02857,-0.84797 58.26659,3.09631 90.27723,2.3394 21.85465,0.57 45.31835,-1.58246 67.9039,1.32197 20.52061,1.30023 39.93176,-0.19461 62.73166,3.61355 27.46951,-1.55825 55.92292,0.6945 84.64648,1.82301 21.8081,-2.17191 44.07928,3.70663 65.23916,2.47223 27.2071,3.45609 52.77106,1.61732 79.7837,6.87146 28.38427,1.4897 60.91267,-3.85006 90.31857,4.70087 7.9557,-7.58206 49.7062,10.41715 33.3368,-8.46559 m 4.2072,26.44346 c -32.3927,1.68666 -64.4036,-6.3897 -98.0288,-6.77546 -24.48025,4.45714 -44.30336,-4.95722 -69.09817,0.65337 -20.49597,-4.2489 -40.04481,-3.57604 -62.53283,-5.48716 -25.88953,-4.74187 -51.48881,1.5226 -78.67182,-1.5303 -26.44484,-5.48982 -55.28453,1.301 -81.94767,-6.12595 -27.93075,-1.60889 -53.29989,2.86737 -78.10769,-2.81352 -26.5022,4.48249 -58.38059,2.58045 -83.86444,-1.55934 -22.19957,1.05473 -43.54914,-0.91401 -66.25974,-1.95198 -32.84948,4.56076 -65.72444,-4.56621 -98.96209,0.62501 -27.63581,-1.4559 -52.03445,-2.7149 -78.76197,0.12079 -28.44566,3.56559 -56.78343,-4.82804 -84.90467,-1.22012 -27.2879,2.39733 -55.53309,4.35864 -83.71329,0.50026 -23.88245,3.43761 -50.80088,3.73635 -76.758118,0.70532 -20.496039,0.68048 -41.733452,2.92405 -29.256501,20.09453 26.84975,-2.74729 54.479779,7.28486 82.311219,-1.82894 21.02875,6.6319 44.87388,0.76798 66.51092,-0.93894 27.75452,2.50567 55.88508,-0.18297 83.47852,1.13562 27.57685,-1.7981 51.97933,0.34866 80.30554,0.10387 20.80388,2.57705 39.5431,-1.16355 61.85453,1.4571 31.09262,-3.82816 64.31997,4.36658 96.71118,0.0709 29.53105,5.22288 60.83865,4.04863 90.29314,0.77487 29.42558,3.77452 59.95433,0.57986 88.09927,5.82578 18.14957,-3.14688 34.82695,3.00359 53.18919,0.0981 30.917,-2.47171 60.78081,9.28942 91.96364,2.87723 22.06162,7.71226 46.65348,-1.67635 70.48628,3.95151 27.27257,1.67366 53.39314,0.72578 81.63885,4.56734 31.14392,2.4376 60.49262,4.49094 91.71282,6.09873 21.4592,-10.2764 29.5476,15.28399 31.0665,-20.74554 m -2.2338,51.32568 c -26.8456,2.34373 -54.5473,-2.12018 -83.1762,-5.28586 -23.5997,2.70784 -49.08528,-2.60161 -72.35701,-1.99561 -23.79767,0.82252 -48.38837,-2.10271 -70.62256,-3.33405 -26.73537,4.38656 -52.12722,-6.23717 -77.76646,-0.38647 -27.92575,-3.6014 -56.93386,-6.03388 -83.55072,-3.70861 -26.8518,-7.81232 -53.6831,0.39068 -78.91282,-6.11667 -25.28719,3.41313 -55.22646,-1.82806 -80.27438,-1.66801 -25.92858,0.58694 -52.87598,-0.6007 -78.59358,1.5571 -26.24168,-5.94606 -58.14389,-1.04767 -86.49034,-3.87062 -26.7495,6.53761 -53.8011,-3.58563 -80.86028,-0.11284 -31.66872,-0.22709 -62.37563,1.11966 -93.15849,-0.33487 -28.9905,4.79704 -55.95335,-1.76865 -84.30516,1.84844 -25.0173,0.89616 -50.777544,3.81128 -75.551319,-0.3684 -22.176179,2.44414 -35.751595,12.64941 -5.144989,6.73569 30.524006,3.22576 62.362358,0.61269 94.852718,0.7578 28.28165,-2.16224 53.99343,-1.65871 81.86978,-1.66561 28.15827,-2.94166 59.96426,2.18988 88.2549,-1.46135 23.84065,1.30927 45.26664,1.64119 68.82659,1.29317 30.04422,0.38366 60.04824,2.20031 87.81248,2.53307 24.8633,-0.49985 48.03734,-1.81522 72.80764,2.66198 26.8837,-6.59744 56.36941,1.6949 84.51034,-1.66006 25.40009,1.64255 50.18357,4.53162 75.68531,3.99018 24.91244,3.74634 50.25025,-1.99676 73.73928,3.60683 22.36844,1.17373 47.59922,-1.16641 71.36115,3.42406 29.39388,-0.0913 57.87051,-1.10115 87.33633,2.93479 24.11061,2.25418 46.10168,1.81714 70.79819,1.43498 27.2582,3.61127 56.6944,5.35329 83.5397,4.51412 10.238,1.13195 16.0024,10.04619 9.0513,-4.99943 m 2.4094,13.20642 c -25.8637,-2.30859 -48.7415,-6.01058 -73.5163,-7.64818 -29.0559,4.55369 -53.49842,-1.92238 -80.898,-4.3174 -24.92502,3.70073 -49.25336,2.03853 -71.72556,-3.5687 -22.75408,4.22353 -46.10586,-1.10963 -70.3222,0.48273 -27.13324,-3.80622 -54.65752,-5.46497 -82.38993,-5.82208 -27.76904,3.87715 -57.38244,-2.34523 -85.1703,-0.57454 -30.31474,-3.46165 -59.52357,-6.23458 -88.9624,-1.39664 -31.89287,-2.65619 -64.18547,-0.53965 -95.9979,-1.82661 -30.99843,-0.32759 -61.107,-1.75348 -90.14403,-2.33073 -27.94603,-4.50419 -54.72511,3.90794 -83.10585,-2.78859 -25.7567,5.60714 -49.71579,0.65814 -76.50531,2.6668 -24.68743,3.84704 -49.3453,-7.18978 -73.44408,2.67683 -30.77492,-0.71045 -57.948444,-3.20802 -87.169814,-1.32538 -20.620762,-9.03674 -21.689713,41.33799 2.778601,24.3797 18.299973,-2.77378 36.634868,1.86019 55.798613,-1.82435 33.71331,-1.60197 65.19981,1.27666 98.90733,-3.4768 24.51021,2.62749 46.31553,-0.88624 68.69547,3.61154 26.0141,-5.72577 47.91776,2.4088 74.91381,-2.48674 26.47894,3.16189 54.5024,0.53889 80.47849,1.04844 21.79038,1.48711 40.53397,-2.32763 62.28374,1.44448 25.53808,4.01662 50.78468,-1.47886 76.7708,3.53322 20.56929,-2.6359 44.20643,-1.89106 67.59891,-0.8632 23.89926,0.6211 48.85522,3.4256 72.63592,4.7735 22.59514,5.9609 45.92929,-3.8747 66.05127,2.4473 22.69101,-0.5243 46.07223,-1.685 70.06095,2.8948 22.83186,-0.1202 47.1641,4.5263 70.44824,5.1708 22.4195,-3.3937 47.94662,0.081 71.36979,2.8347 26.70774,1.9072 56.97444,0.267 85.00324,2.5592 20.1389,5.6388 45.212,8.3271 34.1729,-20.2819 m 2.3854,85.656 c -24.1523,-3.5244 -50.5549,-2.1256 -75.8556,-4.078 -20.2407,-9.8247 -45.74276,3.311 -64.7033,-8.1173 -27.44284,1.3448 -52.52623,0.8281 -79.79039,-4.151 -22.42882,4.5589 -44.53066,-2.0597 -67.62131,-3.3151 -28.71468,4.8874 -49.859,-6.0933 -79.53682,-0.3826 -24.86427,-1.3755 -47.79172,-6.2205 -73.76541,-2.8501 -27.89016,-4.604 -54.08038,1.1419 -81.56716,-5.2778 -26.14624,2.4492 -52.8506,1.75 -78.80524,-1.6299 -23.2118,-2.9512 -45.0201,4.1792 -68.73943,1.8842 -29.99815,-4.2203 -59.73981,-1.0321 -91.58188,-4.1355 -23.51435,-1.3621 -43.51316,4.5892 -66.32405,-0.6958 -29.47813,5.3079 -56.6962,4.3006 -86.62981,0 -24.31307,4.8783 -49.12226,-3.6497 -72.45389,5.0058 -28.88032,0.2136 -62.041476,-2.7016 -85.318308,4.1093 -16.897384,31.46 14.184183,34.21 39.448441,29.4893 26.630767,3.6848 52.739477,-7.3404 78.012837,1.8204 32.16254,-9.3279 62.34177,3.327 93.57358,-2.0984 31.28436,-2.8219 63.10887,2.1628 94.20069,2.1039 23.93248,-5.3694 43.55901,-0.066 67.43769,-3.4253 30.01157,5.6449 56.65539,1.077 85.32525,0.4685 24.45307,2.7256 47.71324,-2.5439 72.26174,2.7789 26.01911,-4.0094 51.98226,-1.9671 77.76141,-2.6146 26.29205,1.8595 52.5164,1.1262 78.40758,2.4107 23.32097,-4.7968 50.04401,3.4258 75.64247,-2.1301 28.48869,5.4039 55.92561,-7.7868 84.39879,2.5614 28.78043,-3.3129 55.06127,-2.8142 83.31636,0.1964 20.10508,-4.6307 41.57306,-3.5106 61.07996,-0.4714 27.2821,0.423 52.2167,-0.3951 78.7492,-3.1514 l 3.1524,-3.5257 0.3883,-2.0344"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#7e4314;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
</g>
<path
inkscape:connector-curvature="0"
id="rect4153-5"
d="m 424.5349,60.980262 c -5.78084,0 -10.44164,6.256987 -10.44164,14.038287 l 0,141.634861 c 0,7.78152 4.6608,14.03829 10.44164,14.03829 l 292.18123,0 c 5.78079,0 10.43965,-6.25701 10.43965,-14.03829 l 0,-141.634861 c 0,-7.781287 -4.65886,-14.038287 -10.43965,-14.038287 l -292.18123,0 z"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#63350f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
<path
inkscape:connector-curvature="0"
id="rect4153"
d="m 424.44337,60.981094 c -5.73063,0 -10.35096,6.125168 -10.35096,13.742537 l 0,138.650999 c 0,7.61758 4.62033,13.74254 10.35096,13.74254 l 289.64386,0 c 5.73059,0 10.34897,-6.12521 10.34897,-13.74254 l 0,-138.650999 c 0,-7.617357 -4.61838,-13.742537 -10.34897,-13.742537 l -289.64386,0 z"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#linearGradient4191);fill-opacity:1;fill-rule:evenodd;stroke:#373737;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
<rect
ry="0"
rx="0"
- y="75.71521"
+ y="35.71521"
x="68.871262"
height="396.43152"
width="294.28571"
id="rect4175-0"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#63350f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
<rect
ry="0"
rx="0"
- y="72.859581"
+ y="32.859581"
x="66.014122"
height="397.14279"
width="294.28571"
id="rect4175"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:url(#linearGradient4183);fill-opacity:1;fill-rule:evenodd;stroke:#373737;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
<path
inkscape:connector-curvature="0"
id="rect4153-9"
d="m 441.28491,78.628012 c -5.0642,0 -9.14722,4.823942 -9.14722,10.823082 l 0,109.196066 c 0,5.99931 4.08302,10.82309 9.14722,10.82309 l 255.96057,0 c 5.06416,0 9.14547,-4.82398 9.14547,-10.82309 l 0,-109.196066 c 0,-5.99913 -4.08131,-10.823082 -9.14547,-10.823082 l -255.96057,0 z"
style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient4229);stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
</g>
</svg>
diff --git a/src/activities/readingv/ActivityInfo.qml b/src/activities/readingv/ActivityInfo.qml
index ddbab17bf..64c463b27 100644
--- a/src/activities/readingv/ActivityInfo.qml
+++ b/src/activities/readingv/ActivityInfo.qml
@@ -1,41 +1,41 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Johnny Jazeix <jazeix@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "readingv/Readingv.qml"
difficulty: 2
icon: "readingv/readingv.svg"
author: "Johnny Jazeix &lt;jazeix@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Vertical-reading practice")
//: Help title
description: qsTr("Read a vertical list of words and work out if a given word is in it.")
// intro: "Read a list of words and say if a given word is in it."
//: Help goal
goal: qsTr("Reading training in a limited time")
//: Help prerequisite
prerequisite: qsTr("Reading")
//: Help manual
manual: qsTr("A word is shown on the board. A list of words, displayed vertically, will appear and disappear. Does the given word belong to the list?")
credit: ""
section: "reading"
createdInVersion: 5000
}
diff --git a/src/activities/readingv/Readingv.qml b/src/activities/readingv/Readingv.qml
index 5b93a9e9f..ff4138d15 100644
--- a/src/activities/readingv/Readingv.qml
+++ b/src/activities/readingv/Readingv.qml
@@ -1,28 +1,28 @@
/* GCompris - readingv.qml
*
* Copyright (C) 2015 Johnny Jazeix <jazeix@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Johnny Jazeix <jazeix@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../readingh"
Readingh {
mode: "readingv"
}
diff --git a/src/activities/redraw/ActivityInfo.qml b/src/activities/redraw/ActivityInfo.qml
index 1659c0e00..63d699d27 100644
--- a/src/activities/redraw/ActivityInfo.qml
+++ b/src/activities/redraw/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "redraw/Redraw.qml"
difficulty: 3
icon: "redraw/redraw.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
//: Activity title
title: qsTr("Redraw the given image")
//: Help title
description: qsTr("Draw perfectly the given image on the empty grid.")
//intro: "Use the drawing tools to build an identical pattern on the right."
//: Help goal
goal: ""
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("First, select the proper color from the toolbar. Then click on the grid and drag to paint, then release the click to stop painting.")
credit: ""
section: "math geometry puzzle"
createdInVersion: 0
}
diff --git a/src/activities/redraw/Redraw.qml b/src/activities/redraw/Redraw.qml
index ed03cf825..5c411c637 100644
--- a/src/activities/redraw/Redraw.qml
+++ b/src/activities/redraw/Redraw.qml
@@ -1,440 +1,440 @@
/* GCompris - redraw.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import QtGraphicalEffects 1.0
import "../../core"
import "redraw.js" as Activity
ActivityBase {
id: activity
onStart: focus = true
onStop: {}
property bool symmetry: false
pageComponent: Image {
id: background
anchors.fill: parent
source: Activity.url + "background.svg"
fillMode: Image.PreserveAspectCrop
sourceSize.width: Math.max(parent.width, parent.height)
- property bool landscape: width > height
+ property bool landscape: width >= height
signal start
signal stop
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property alias background: background
property alias bar: bar
property alias bonus: bonus
property int colorSelector: 0
property alias userModel: userModel
property int numberOfColumn
property int numberOfColor
property int numberOfLine: targetModelData.length / numberOfColumn
property alias targetModel: targetModel
property var targetModelData
}
onStart: { Activity.start(items) }
onStop: { Activity.stop() }
Keys.onPressed: {
if(event.key >= Qt.Key_0 && event.key < Qt.Key_0 + items.numberOfColor)
items.colorSelector = event.key - Qt.Key_0
- if(event.key == Qt.Key_Backspace)
+ if(event.key === Qt.Key_Backspace)
userModel.clearCurrentItem()
}
Keys.onEnterPressed: userModel.paintCurrentItem()
Keys.onReturnPressed: userModel.paintCurrentItem()
Keys.onSpacePressed: userModel.paintCurrentItem()
Keys.onDeletePressed: userModel.clearCurrentItem()
Keys.onRightPressed: userModel.moveCurrentIndexRight()
Keys.onLeftPressed: userModel.moveCurrentIndexLeft()
Keys.onDownPressed: userModel.moveCurrentIndexDown()
Keys.onUpPressed: userModel.moveCurrentIndexUp()
// For creating new content, dump the drawing on the console
Keys.onTabPressed: Activity.dump()
Row {
anchors {
top: parent.top
right: parent.right
left: parent.left
bottom: bar.top
}
anchors.margins: 10
spacing: 20
// The color selector
Flickable {
id: flickable
interactive: true
width: 70 * ApplicationInfo.ratio
height: background.height
boundsBehavior: Flickable.StopAtBounds
contentHeight: items.numberOfColor * width
bottomMargin: bar.height
Column {
id: colorSelector
Repeater {
model: items.numberOfColor
Item {
width: flickable.width
height: width
Image {
id: img
source: Activity.url + Activity.colorShortcut[modelData] + ".svg"
sourceSize.width: parent.width
z: iAmSelected ? 10 : 1
property bool iAmSelected: modelData == items.colorSelector
states: [
State {
name: "notclicked"
when: !img.iAmSelected && !mouseArea.containsMouse
PropertyChanges {
target: img
scale: 0.8
}
},
State {
name: "clicked"
when: mouseArea.pressed
PropertyChanges {
target: img
scale: 0.7
}
},
State {
name: "hover"
when: mouseArea.containsMouse
PropertyChanges {
target: img
scale: 1.1
}
},
State {
name: "selected"
when: img.iAmSelected
PropertyChanges {
target: img
scale: 1
}
}
]
SequentialAnimation {
id: anim
running: img.iAmSelected
loops: Animation.Infinite
alwaysRunToEnd: true
NumberAnimation {
target: img
property: "rotation"
from: 0; to: 10
duration: 200
easing.type: Easing.OutQuad
}
NumberAnimation {
target: img
property: "rotation"
from: 10; to: -10
duration: 400
easing.type: Easing.InOutQuad
}
NumberAnimation {
target: img
property: "rotation"
from: -10; to: 0
duration: 200
easing.type: Easing.InQuad
}
}
Behavior on scale { NumberAnimation { duration: 70 } }
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: {
activity.audioEffects.play('qrc:/gcompris/src/core/resource/sounds/scroll.wav')
items.colorSelector = modelData
}
}
}
GCText {
id: text1
anchors.fill: parent
text: modelData
fontSize: regularSize
z: modelData == items.colorSelector ? 12 : 2
font.bold: true
style: Text.Outline
styleColor: "black"
color: "white"
}
DropShadow {
anchors.fill: text1
cached: false
horizontalOffset: 1
verticalOffset: 1
radius: 8.0
samples: 16
color: "#80000000"
source: text1
}
}
}
}
}
Grid {
id: drawAndExampleArea
columns: background.landscape ? 2 : 1
width: gridWidth
height: parent.height
spacing: 10
property int gridWidth: parent.width - colorSelector.width
// The drawing area
Grid {
id: drawingArea
width: background.landscape ? parent.gridWidth / 2 - parent.spacing * 2 : parent.gridWidth
height: background.landscape ? parent.height : parent.height / 2
columns: items.numberOfColumn
Repeater {
id: userModel
model: items.targetModelData.length
property int currentItem: 0
property bool keyNavigation: false
function reset() {
for(var i=0; i < items.userModel.count; ++i)
userModel.itemAt(i).paint(items.colorSelector)
currentItem = 0
keyNavigation = false
}
function clearCurrentItem() {
userModel.itemAt(currentItem).paint(0)
}
function paintCurrentItem() {
userModel.itemAt(currentItem).playEffect(items.colorSelector)
userModel.itemAt(currentItem).paint(items.colorSelector)
}
function moveCurrentIndexRight() {
keyNavigation = true
if(currentItem++ >= items.targetModelData.length - 1)
currentItem = 0
}
function moveCurrentIndexLeft() {
keyNavigation = true
if(currentItem-- <= 0)
currentItem = items.targetModelData.length - 1
}
function moveCurrentIndexUp() {
keyNavigation = true
currentItem -= items.numberOfColumn
if(currentItem < 0)
currentItem += items.targetModelData.length
}
function moveCurrentIndexDown() {
keyNavigation = true
currentItem += items.numberOfColumn
if(currentItem > items.targetModelData.length - 1)
currentItem -= items.targetModelData.length
}
Item {
id: userItem
width: Math.min(drawingArea.width / items.numberOfColumn,
drawingArea.height / items.numberOfLine)
height: width
property color color: Activity.colors[colorIndex]
property int colorIndex
function paint(color) {
colorIndex = color
}
function playEffect(color) {
if(color === 0)
activity.audioEffects.play(Activity.url + 'eraser.wav')
else
activity.audioEffects.play(Activity.url + 'brush.wav')
}
Rectangle {
id: userRect
anchors.fill: parent
border.width: userModel.keyNavigation && userModel.currentItem == modelData ? 3 : 1
border.color: 'black'
color: parent.color
Behavior on color {
ColorAnimation {
duration: 200
onRunningChanged: {
if(!running && Activity.checkModel()) bonus.good("flower")
}
}
}
}
GCText {
id: text2
anchors.fill: parent
anchors.margins: 4
text: parent.colorIndex == 0 ? "" : parent.colorIndex
fontSize: regularSize
font.bold: true
style: Text.Outline
styleColor: "black"
color: "white"
}
DropShadow {
anchors.fill: text2
cached: false
horizontalOffset: 1
verticalOffset: 1
radius: 8.0
samples: 16
color: "#80000000"
source: text2
}
}
}
}
// The painting to reproduce
Grid {
id: imageArea
width: drawingArea.width
height: drawingArea.height
columns: items.numberOfColumn
LayoutMirroring.enabled: activity.symmetry
LayoutMirroring.childrenInherit: true
Repeater {
id: targetModel
model: items.targetModelData
Item {
width: Math.min(imageArea.width / items.numberOfColumn,
imageArea.height / items.numberOfLine)
height: width
property alias color: targetRect.color
Rectangle {
id: targetRect
anchors.fill: parent
color: Activity.colors[modelData]
border.width: 1
border.color: 'black'
}
GCText {
id: text3
anchors.fill: parent
anchors.margins: 4
text: modelData == 0 ? "" : modelData
fontSize: regularSize
font.bold: true
style: Text.Outline
styleColor: "black"
color: "white"
}
DropShadow {
anchors.fill: text3
cached: false
horizontalOffset: 1
verticalOffset: 1
radius: 8.0
samples: 16
color: "#80000000"
source: text3
}
}
}
}
}
}
MultiPointTouchArea {
x: drawAndExampleArea.x
y: drawAndExampleArea.y
width: drawAndExampleArea.width
height: drawAndExampleArea.height
onPressed: checkTouchPoint(touchPoints)
onTouchUpdated: checkTouchPoint(touchPoints)
function checkTouchPoint(touchPoints) {
for(var i in touchPoints) {
var touch = touchPoints[i]
var block = drawingArea.childAt(touch.x, touch.y)
if(block) {
block.playEffect(items.colorSelector)
block.paint(items.colorSelector)
}
}
}
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level }
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
}
Bonus {
id: bonus
Component.onCompleted: win.connect(Activity.nextLevel)
}
}
}
diff --git a/src/activities/redraw/redraw.js b/src/activities/redraw/redraw.js
index c1665e0a0..3d594c833 100644
--- a/src/activities/redraw/redraw.js
+++ b/src/activities/redraw/redraw.js
@@ -1,538 +1,538 @@
/* GCompris - redraw.js
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
var url = "qrc:/gcompris/src/activities/redraw/resource/"
var colorShortcut = {
0: 'white',
1: 'red',
2: 'orange',
3: 'green',
4: 'blue',
5: 'yellow',
6: 'black'
}
var colors = {
0: '#33FFFFFF',
1: '#FFCC0000',
2: '#FFFCAE3D',
3: '#FF73D216',
4: '#FF3465A4',
5: '#FFEDD400',
6: '#FF2E3436'
}
var dataset = [
{
"columns": 4,
"image":
[
2,0,0,0,
0,1,0,0,
0,0,1,0,
0,1,0,0,
0,0,0,0
]
},
{
"columns": 4,
"image":
[
1,1,0,0,
0,2,2,0,
0,0,1,1,
0,2,2,0,
1,1,0,0
]
},
{
"columns": 4,
"image":
[
1,0,0,0,
0,1,0,0,
0,0,2,3,
0,1,0,0,
1,0,0,0
]
},
{
"columns": 4,
"image":
[
4,4,4,4,
0,2,2,2,
0,3,3,0,
2,2,2,0,
4,4,4,4
]
},
{
"columns": 6,
"image":
[
1,1,1,1,1,1,
1,2,0,0,0,1,
1,0,2,3,0,1,
1,0,2,3,0,1,
1,2,0,0,0,1,
1,1,1,1,1,1
]
},
{
"columns": 6,
"image":
[
1,2,2,2,2,2,
3,1,0,0,0,2,
3,0,1,4,0,2,
3,0,4,1,0,2,
3,0,0,0,1,2,
3,3,3,3,3,1
]
},
{
"columns": 6,
"image":
[
1,2,2,2,2,3,
4,0,0,0,0,4,
4,0,0,0,0,4,
4,0,0,0,0,4,
4,0,0,0,0,4,
3,2,2,2,2,1
]
},
{
"columns": 7,
"image":
[
0,1,1,1,1,1,0,
1,0,0,0,0,0,1,
1,0,3,0,2,0,1,
1,0,0,0,0,0,1,
1,0,2,1,3,0,1,
1,0,0,0,0,0,1,
0,1,1,1,1,1,0
]
},
{
"columns": 7,
"image":
[
1,0,1,0,1,0,1,
0,2,0,2,0,2,0,
3,0,3,0,3,0,3,
0,4,0,4,0,4,0,
5,0,5,0,5,0,5,
0,6,0,6,0,6,0,
1,0,1,0,1,0,1
]
},
{ // A
"columns": 6,
"image":
[
0,2,2,0,1,2,
2,0,0,2,3,2,
2,1,3,2,0,1,
2,0,0,2,4,0,
2,0,0,2,0,4
]
},
{ // B
"columns": 7,
"image":
[
2,2,2,2,1,1,1,
2,0,0,2,3,0,1,
2,1,1,0,1,0,2,
2,0,0,2,3,4,1,
2,2,2,2,4,3,1
]
},
{ // C
"columns": 6,
"image":
[
2,3,3,3,4,5,
2,0,0,0,0,6,
2,0,2,0,3,2,
2,0,1,0,2,1,
2,3,3,3,2,5
]
},
{ // D
"columns": 6,
"image":
[
1,1,1,0,1,0,
1,0,0,2,3,4,
1,0,4,2,4,3,
1,0,0,2,5,0,
1,1,1,0,3,1
]
},
{ // E
"columns": 6,
"image":
[
1,1,1,1,1,1,
1,0,2,0,1,0,
1,2,2,0,3,3,
1,0,3,0,4,0,
1,1,1,1,0,0
]
},
{ // F
"columns": 6,
"image":
[
1,2,1,3,1,4,
1,0,2,0,3,0,
4,2,2,0,4,4,
1,0,3,0,3,0,
1,2,0,0,2,1,
2,5,0,0,1,2
]
},
{ // G
"columns": 7,
"image":
[
1,2,1,3,1,4,1,
1,0,2,0,3,0,5,
1,0,2,2,0,3,3,
1,0,0,2,2,0,3,
1,6,1,0,4,2,1
]
},
{ // H
"columns": 6,
"image":
[
4,0,2,1,3,5,
1,2,0,3,4,1,
1,2,3,1,2,1,
1,0,5,5,0,1,
1,0,6,1,6,0
]
},
{ // I
"columns": 7,
"image":
[
0,2,2,2,2,0,5,
2,0,1,0,3,1,4,
4,0,1,0,5,6,0,
4,0,1,2,3,4,6,
0,2,2,2,0,0,5
]
},
{ // J
"columns": 7,
"image":
[
0,3,2,4,0,1,1,
0,3,2,0,1,4,2,
0,0,2,0,4,5,1,
1,0,2,0,0,0,1,
1,2,1,0,4,1,3
]
},
{ // K
"columns": 7,
"image":
[
1,4,0,1,2,0,0,
1,0,5,0,0,3,0,
1,3,0,0,0,0,4,
1,0,5,0,0,3,0,
1,4,0,1,2,0,0
]
},
{ // L
"columns": 7,
"image":
[
1,0,0,0,3,0,0,
1,0,0,3,0,3,0,
1,0,3,0,4,0,3,
1,3,0,0,0,3,4,
2,2,2,2,2,2,2
]
},
{ // M
"columns": 7,
"image":
[
1,0,0,0,1,4,0,
1,2,0,2,1,0,5,
1,0,2,0,1,4,0,
1,0,3,0,1,0,5,
1,3,0,3,1,4,0,
0,1,0,5,0,1,0
]
},
{ // N
"columns": 7,
"image":
[
1,0,5,0,1,0,0,
1,2,0,4,0,5,0,
1,0,2,0,1,0,1,
1,4,0,2,0,4,0,
1,0,5,0,1,0,1,
0,0,1,0,5,0,1
]
},
{ // O
"columns": 7,
"image":
[
0,2,3,0,3,2,0,
1,5,0,1,0,1,1,
1,0,5,1,1,0,1,
1,5,0,1,0,1,1,
0,3,2,0,2,3,0,
1,2,0,1,0,5,1,
0,3,2,0,2,3,0
]
},
{ // P
"columns": 8,
"image":
[
1,3,3,1,1,2,2,1,
2,0,5,1,5,0,0,2,
1,2,2,1,4,5,5,4,
1,0,4,0,5,0,4,2,
1,5,0,4,4,0,5,1,
0,1,1,0,0,1,1,0,
3,4,0,2,2,0,4,3
]
},
{ // Q
"columns": 8,
"image":
[
0,3,3,0,0,2,2,0,
4,0,0,4,4,0,0,4,
1,0,0,4,4,0,0,4,
2,4,0,0,3,0,4,2,
1,5,0,3,1,0,5,1,
0,0,0,4,4,0,0,0,
4,3,5,1,1,5,4,3
]
},
{ // R
"columns": 8,
"image":
[
5,0,0,0,5,0,0,0,
0,4,0,4,0,4,0,4,
0,0,3,0,0,0,3,0,
0,0,1,0,0,0,1,0,
0,1,0,1,0,1,0,1,
1,0,0,0,1,0,0,0,
2,0,2,0,2,0,2,0
]
},
{ // S
"columns": 8,
"image":
[
1,0,2,3,0,2,0,1,
0,2,0,4,4,0,2,0,
0,0,3,0,0,3,0,0,
0,0,0,4,4,0,0,0,
0,0,3,0,0,3,0,0,
0,2,0,4,4,0,2,0,
1,0,2,0,3,2,0,1
]
},
{ // T
"columns": 8,
"image":
[
4,0,4,0,4,0,4,0,
0,5,0,5,0,5,0,5,
4,0,4,0,4,0,4,0,
0,5,0,5,0,5,0,5,
4,0,4,0,4,0,4,0,
0,5,0,5,0,5,0,5,
4,0,4,0,4,0,4,0
]
},
{ // U
"columns": 8,
"image":
[
4,0,1,0,4,0,1,0,
0,5,0,3,3,0,0,5,
4,0,2,0,0,0,3,0,
0,5,0,3,0,3,0,5,
4,0,3,4,4,0,2,0,
0,5,0,1,3,2,0,5,
4,0,1,2,4,0,1,0
]
},
{ // V
"columns": 8,
"image":
[
0,3,3,0,0,3,3,0,
5,0,0,5,5,0,0,5,
4,0,0,4,4,0,0,4,
0,5,5,0,0,5,5,0,
3,0,4,0,3,0,4,0,
0,2,0,2,0,2,0,2,
4,0,1,0,4,0,1,0
]
},
{ // W
"columns": 8,
"image":
[
1,0,2,0,5,2,0,3,
0,2,0,1,0,4,0,0,
0,0,3,0,1,0,3,0,
0,5,0,4,0,5,0,1,
0,1,1,0,5,0,4,0,
0,1,0,2,0,4,0,3,
0,2,0,1,0,3,0,4
]
},
{ // X
"columns": 8,
"image":
[
0,1,3,0,2,1,0,3,
0,4,1,0,0,4,1,0,
5,3,0,0,1,0,3,5,
4,1,0,4,1,0,4,1,
0,1,1,0,5,0,4,0,
0,1,0,2,0,4,0,3,
0,2,0,1,1,0,0,4
]
},
{ // Y
"columns": 8,
"image":
[
1,0,1,0,1,0,1,0,
0,2,0,2,0,2,0,2,
3,0,3,0,3,0,3,0,
0,4,0,4,0,4,0,4,
1,0,1,0,1,0,1,0,
0,2,0,2,0,2,0,2,
3,0,3,0,3,0,3,0
]
},
{ // Z
"columns": 8,
"image":
[
1,5,1,0,1,5,1,0,
0,2,0,2,0,2,0,2,
3,0,3,1,3,1,3,0,
0,4,0,5,5,0,0,4,
1,0,1,4,4,0,1,0,
0,2,0,2,2,0,0,2,
3,0,3,0,3,0,3,0
]
},
]
var currentLevel = 0
var numberOfLevel = dataset.length
var items
function start(items_) {
items = items_
currentLevel = 0
initLevel()
}
function stop() {
}
function initLevel() {
items.bar.level = currentLevel + 1
items.numberOfColumn = dataset[currentLevel].columns
items.targetModelData = dataset[currentLevel].image
items.numberOfColor = getNumberOfColors(items.targetModelData)
items.colorSelector = 0
items.userModel.reset()
if(currentLevel == 0) {
// To help determine the puzzle mirroring type set a color
// at first level
items.userModel.itemAt(0).paint(items.targetModelData[0])
}
}
function nextLevel() {
if(numberOfLevel <= ++currentLevel ) {
currentLevel = 0
}
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
initLevel();
}
function getNumberOfColors(model) {
var nbColor = 0
for(var i=0; i < model.length; ++i) {
nbColor = Math.max(nbColor, model[i])
}
return nbColor + 1
}
function checkModel() {
for(var i=0; i < items.userModel.count; ++i) {
if(items.userModel.itemAt(i).color !== items.targetModel.itemAt(i).color)
return false
}
return true
}
// Dump the user drawing in the format we use for drawing definition
// Can be used to create content
function dump() {
var line = "["
for(var i=0; i < items.userModel.count; ++i) {
if(i % items.numberOfColumn == 0) {
print(line)
line = " "
}
line += items.userModel.itemAt(i).colorIndex + ","
}
print(line)
print("]")
}
diff --git a/src/activities/redraw_symmetrical/ActivityInfo.qml b/src/activities/redraw_symmetrical/ActivityInfo.qml
index 93456fbdf..ee400e6ca 100644
--- a/src/activities/redraw_symmetrical/ActivityInfo.qml
+++ b/src/activities/redraw_symmetrical/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "redraw_symmetrical/RedrawSymmetrical.qml"
difficulty: 4
icon: "redraw_symmetrical/redraw_symmetrical.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
//: Activity title
title: qsTr("Mirror the given image")
//: Help title
description: qsTr("Draw the image on the empty grid as if you see it in a mirror.")
//intro: "Use the drawing tools to reproduce symmetrically the pattern on the right."
//: Help goal
goal: ""
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("First, select the proper color from the toolbar. Then click on the grid and drag to paint, then release the click to stop painting.")
credit: ""
section: "math geometry symmetry puzzle"
createdInVersion: 0
}
diff --git a/src/activities/redraw_symmetrical/RedrawSymmetrical.qml b/src/activities/redraw_symmetrical/RedrawSymmetrical.qml
index 698286eb4..5460c6e31 100644
--- a/src/activities/redraw_symmetrical/RedrawSymmetrical.qml
+++ b/src/activities/redraw_symmetrical/RedrawSymmetrical.qml
@@ -1,27 +1,27 @@
/* GCompris - redraw_symmetrical.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import "../redraw"
Redraw {
symmetry: true
}
diff --git a/src/activities/renewable_energy/ActivityInfo.qml b/src/activities/renewable_energy/ActivityInfo.qml
index f9110ccf2..b1d757dd7 100644
--- a/src/activities/renewable_energy/ActivityInfo.qml
+++ b/src/activities/renewable_energy/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Sagar Chand Agarwal <atomsagar@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "renewable_energy/RenewableEnergy.qml"
difficulty: 4
icon: "renewable_energy/renewable_energy.svg"
author: "Sagar Chand Agarwal &lt;atomsagar@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Renewable Energy")
//: Help title
description: qsTr("Tux has come back from fishing on his boat. Bring the electrical system back up so he can have light in his home. ")
//intro: "Click on the different stages that go to make up the power supply."
//: Help goal
goal: qsTr("Learn about an electrical system based on renewable energy")
//: Help manual
- manual: qsTr("Click on different active elements : sun, cloud, dam, solar array, wind farm and transformers, in order to reactivate the entire electrical system. When the system is back up and Tux is in his home, push the light button for him. To win you must switch on all the consumers while all the producers are up. ")
+ manual: qsTr("Click on different active elements: sun, cloud, dam, solar array, wind farm and transformers, in order to reactivate the entire electrical system. When the system is back up and Tux is in his home, push the light button for him. To win you must switch on all the consumers while all the producers are up. ")
//: Help prerequisite
prerequisite: ""
credit: qsTr("Drawing by Stephane Cabaraux")
section: "experiment"
createdInVersion: 5000
}
diff --git a/src/activities/renewable_energy/Hydro.qml b/src/activities/renewable_energy/Hydro.qml
index 696068493..f3d4137ee 100644
--- a/src/activities/renewable_energy/Hydro.qml
+++ b/src/activities/renewable_energy/Hydro.qml
@@ -1,501 +1,501 @@
/* GCompris - hydro.qml
*
* Copyright (C) 2015 Sagar Chand Agarwal <atomsagar@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Sagar Chand Agarwal <atomsagar@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
Item {
id: hydro
property alias power: stepupwire1.power
function start() {
anim.running = true
}
function stop() {
anim.running = false
dam.started = false
river.level = 0
sun.down()
rain.down()
cloud.down()
stepup1.started = false
}
Image {
id: sky
anchors.top: parent.top
sourceSize.width: parent.width
source: activity.url + "sky.svg"
height: (background.height - landscape.paintedHeight) / 2 + landscape.paintedHeight * 0.3
visible: true
z: 27
}
Image {
id: landscape
anchors.fill: parent
sourceSize.width: parent.width
sourceSize.height: parent.height
source: activity.url + "landscape.svg"
z: 30
}
Image {
id: tuxboat
source: activity.url + "boat.svg"
sourceSize.width: parent.width * 0.15
sourceSize.height: parent.height * 0.15
anchors {
bottom: parent.bottom
bottomMargin: 15
}
x: 0
z: 51
Behavior on opacity { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 200 } }
NumberAnimation on x {
id: anim
running: false
to: background.width - tuxboat.width
duration: 15000
easing.type: Easing.InOutSine
onRunningChanged: {
if(!anim.running)
{
items.audioEffects.play('qrc:/gcompris/src/activities/watercycle/resource/harbor2.wav')
if(!anim.running)
{
tuxboat.opacity = 0
boatparked.opacity = 1
tux.visible = true
}
} else {
items.audioEffects.play('qrc:/gcompris/src/activities/watercycle/resource/harbor1.wav')
}
}
}
}
Image {
id: boatparked
source: activity.url + "boat_parked.svg"
sourceSize.width: parent.width*0.15
sourceSize.height: parent.height*0.15
opacity: 0
anchors {
right: parent.right
bottom: parent.bottom
bottomMargin: 20
}
z: 51
Behavior on opacity { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 200 } }
}
Image {
id: sun
source: activity.url + "sun.svg"
sourceSize.width: parent.width * 0.06
anchors {
left: parent.left
top: parent.top
leftMargin: parent.width * 0.05
topMargin: sun.downPosition
onTopMarginChanged: items.sunIsUp = (anchors.topMargin != sun.downPosition)
}
z: 28
property double upPosition: parent.height * 0.05
property double downPosition: parent.height * 0.28
MouseArea {
id: sun_area
anchors.fill: sun
onClicked: {
if(cloud.opacity == 0)
sun.up()
}
}
Behavior on anchors.topMargin { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 5000 } }
function up() {
items.audioEffects.play('qrc:/gcompris/src/core/resource/sounds/bleep.wav')
sun.anchors.topMargin = upPosition
vapor.up()
}
function down() {
sun.anchors.topMargin = downPosition
}
}
Image {
id: sea
anchors {
left: parent.left
bottom: parent.bottom
}
sourceSize.width: parent.width
source: activity.url + "sea.svg"
height : (background.height - landscape.paintedHeight) / 2 + landscape.paintedHeight * 0.7
z: 29
}
Image {
id: vapor
opacity: 0
source: activity.url + "vapor.svg"
sourceSize.width: parent.width*0.05
anchors {
left: sun.left
}
y: background.height * 0.28
z: 31
SequentialAnimation {
id: vaporAnim
loops: 2
NumberAnimation {
target: vapor
property: "opacity"
duration: 200
from: 0
to: 1
}
NumberAnimation {
target: vapor
property: "y"
duration: 5000
from: background.height * 0.28
to: background.height * 0.1
}
NumberAnimation {
target: vapor
property: "opacity"
duration: 200
from: 1
to: 0
}
NumberAnimation {
target: vapor
property: "y"
duration: 0
to: background.height * 0.28
}
onRunningChanged: {
}
}
function up() {
vaporAnim.start()
cloud.up()
}
function down() {
}
}
Image {
id: cloud
opacity: 0
source: activity.url + "cloud.svg"
sourceSize.width: parent.width * 0.20
fillMode: Image.PreserveAspectFit
width: 0
anchors {
top: parent.top
topMargin: parent.height * 0.05
}
x: parent.width * 0.05
z: 32
MouseArea {
id: cloud_area
anchors.fill: cloud
onClicked: {
sun.down()
rain.up()
}
}
ParallelAnimation {
id: cloudanimOn
running: false
PropertyAnimation {
target: cloud
property: 'opacity'
easing.type: Easing.InOutQuad
duration: 5000
from: 0
to: 1
}
PropertyAnimation {
target: cloud
property: 'width'
easing.type: Easing.InOutQuad
duration: 15000
from: 0
to: cloud.sourceSize.width
}
PropertyAnimation {
target: cloud
property: 'x'
easing.type: Easing.InOutQuad
duration: 15000
from: background.width * 0.05
to: background.width * 0.4
}
}
function up() {
cloudanimOn.start()
}
function down() {
opacity = 0
width = 0
x = parent.width * 0.05
}
}
Image {
id: rain
source: activity.url + "rain.svg"
sourceSize.height: cloud.height * 2
opacity: 0
anchors {
top: cloud.bottom
}
x: cloud.x
z: 35
Behavior on opacity { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 300 } }
SequentialAnimation{
id: rainAnim
running: false
loops: 10
NumberAnimation {
target: rain
property: "scale"
duration: 500
to: 0.95
}
NumberAnimation {
target: rain
property: "scale"
duration: 500
to: 1
}
onRunningChanged: {
if(!running) {
rain.down()
cloud.down()
}
}
}
function up() {
items.audioEffects.play('qrc:/gcompris/src/core/resource/sounds/water.wav')
opacity = 1
rainAnim.start()
}
function down() {
opacity = 0
}
}
Image {
id: river
source: activity.url + "river.svg"
sourceSize.width: parent.width * 0.415
sourceSize.height: parent.height * 0.74
width: parent.width * 0.415
height: parent.height * 0.74
opacity: level > 0 ? 1 : 0
anchors {
top: parent.top
left: parent.left
topMargin: parent.height * 0.1775
leftMargin: parent.width * 0.293
}
z: 40
Behavior on opacity { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 5000 } }
property double level: 0
}
Image {
id: reservoir1
source: activity.url + "hydroelectric/reservoir1.svg"
sourceSize.width: parent.width * 0.06
width: parent.width * 0.06
height: parent.height * 0.15
anchors {
top: parent.top
left: parent.left
topMargin: parent.height * 0.2925
leftMargin: parent.width * 0.3225
}
opacity: river.level > 0.2 ? 1 : 0
z: 40
Behavior on opacity { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 5000 } }
}
Image {
id: reservoir2
source: activity.url + "hydroelectric/reservoir2.svg"
sourceSize.width: parent.width*0.12
width: parent.width * 0.12
height: parent.height * 0.155
anchors {
top: parent.top
left: parent.left
topMargin: parent.height * 0.2925
leftMargin: parent.width * 0.285
}
opacity: river.level > 0.5 ? 1 : 0
z: 40
Behavior on opacity { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 5000 } }
}
Image {
id: reservoir3
source: activity.url + "hydroelectric/reservoir3.svg"
sourceSize.width: parent.width * 0.2
width: parent.width * 0.2
height: parent.height * 0.17
anchors {
top: parent.top
left: parent.left
topMargin: parent.height * 0.29
leftMargin: parent.width * 0.25
}
opacity: river.level > 0.8 ? 1 : 0
z: 40
Behavior on opacity { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 5000 } }
}
Image {
source: activity.url + "left.svg"
width: dam.width / 2
height: dam.height * 0.5
z: 30
anchors {
left: dam.left
leftMargin: parent.width * 0.05
top: dam.top
}
Rectangle {
width: dam_power.width * 1.1
height: dam_power.height * 1.1
border.color: "black"
radius: 5
color: items.produceColor
anchors {
left: parent.right
}
GCText {
fontSize: smallSize * 0.5
id: dam_power
anchors.centerIn: parent
text: dam.power.toString() + "W"
}
}
}
Image {
id: dam
source: activity.url + "hydroelectric/" + (started ? "dam.svg" : "dam_off.svg")
width: river.width * 0.12
sourceSize.height: parent.height * 0.08
z: 45
anchors {
left: parent.left
top: parent.top
leftMargin: parent.width * 0.33
topMargin: parent.height * 0.42
}
MouseArea {
id: dam_area
anchors.centerIn: parent
// Size the area for a touch screen
width: 70 * ApplicationInfo.ratio
height: width
onClicked: parent.started = !parent.started
}
property bool started: false
property int power: started && river.level > 0.1 ? 1000 : 0
}
Image {
id: damwire
source: activity.url + "hydroelectric/damwire.svg"
sourceSize.width: parent.width
sourceSize.height: parent.height
anchors.fill: parent
z: 44
visible: power > 0
property int power: dam.power
}
Image {
id: stepup1
source: activity.url + (started ? "transformer.svg" : "transformer_off.svg")
sourceSize.width: parent.width * 0.06
height: parent.height * 0.09
z: 34
anchors {
top: parent.top
left: parent.left
topMargin: parent.height*0.435
leftMargin: parent.width*0.44
}
property bool started: false
property int power: started && damwire.power ? damwire.power : 0
MouseArea {
id: stepup1_area
anchors.centerIn: parent
// Size the area for a touch screen
width: 70 * ApplicationInfo.ratio
height: width
onClicked: {
parent.started = !parent.started
}
}
}
Image {
id: stepupwire1
source: activity.url + "hydroelectric/stepupwire.svg"
sourceSize.width: parent.width
sourceSize.height: parent.height
anchors.fill: parent
z: 34
visible: power > 0
property int power: stepup1.power
}
// Manage stuff that changes periodically
Timer {
id: timer
interval: 100
running: true
repeat: true
onTriggered: {
if(rain.opacity > 0.2 && river.level < 1) {
river.level += 0.01
} else if(river.level > 0) {
- // Make the river level dependant on whether the dam runs
+ // Make the river level dependent on whether the dam runs
river.level -= (dam.power > 0 ? 0.001 : 0.0005)
} else {
dam.started = false
}
}
}
}
diff --git a/src/activities/renewable_energy/RenewableEnergy.qml b/src/activities/renewable_energy/RenewableEnergy.qml
index 42130a321..0ee1889c9 100644
--- a/src/activities/renewable_energy/RenewableEnergy.qml
+++ b/src/activities/renewable_energy/RenewableEnergy.qml
@@ -1,574 +1,574 @@
/* GCompris - renewable_energy.qml
*
* Copyright (C) 2015 Sagar Chand Agarwal <atomsagar@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Sagar Chand Agarwal <atomsagar@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
ActivityBase {
id: activity
onStart: focus = true
onStop: {}
property string url: "qrc:/gcompris/src/activities/renewable_energy/resource/"
property var barAtStart
property int oldWidth: width
onWidthChanged: {
oldWidth: width
}
property int oldHeight: height
onHeightChanged: {
oldHeight: height
}
pageComponent: Item {
id: background
anchors.fill: parent
signal start
signal stop
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property alias background: background
property alias bar: bar
property alias bonus: bonus
property GCSfx audioEffects: activity.audioEffects
property int currentLevel
property int numberOfLevel: 3
property bool sunIsUp
property color consumeColor: '#ffff8100'
property color produceColor: '#ffffec00'
property bool hasWon: false
}
onStart: {
barAtStart = ApplicationSettings.isBarHidden;
ApplicationSettings.isBarHidden = true;
}
onStop: {
ApplicationSettings.isBarHidden = barAtStart;
initLevel()
}
function initLevel() {
residentSmallSwitch.on = false
residentBigSwitch.on = false
tuxSwitch.on = false
stepDown.started = false
hydro.item.stop()
if(wind.item)
wind.item.stop()
if(solar.item)
solar.item.stop()
}
function nextLevel() {
if(items.numberOfLevel <= ++items.currentLevel) {
// Stay on the last level
items.currentLevel = items.numberOfLevel - 1
}
}
function previousLevel() {
if(--items.currentLevel < 0) {
items.currentLevel = items.numberOfLevel - 1
}
}
function checkForNextLevel() {
switch(items.currentLevel) {
case 0:
if(tuxSwitch.on)
win()
break
case 1:
if(tuxSwitch.on && residentSmallSwitch.on)
win()
break
case 2:
if(!items.hasWon &&
tuxSwitch.on && residentSmallSwitch.on && residentBigSwitch.on) {
items.hasWon = true
win()
}
break
}
}
Loader {
id: hydro
anchors.fill: parent
source: "Hydro.qml"
}
Loader {
id: wind
anchors.fill: parent
source: items.currentLevel > 0 ? "Wind.qml" : ""
}
Loader {
id: solar
anchors.fill: parent
source: items.currentLevel > 1 ? "Solar.qml" : ""
}
IntroMessage {
id: message
opacity: items.currentLevel == 0 ? 1 : start()
z: 100
anchors {
top: parent.top
topMargin: 10
right: parent.right
rightMargin: 5
left: parent.left
leftMargin: 5
}
onIntroDone: {
hydro.item.start()
message.opacity = 0
}
intro: [
qsTr("Tux has come back from fishing on his boat. " +
"Bring the electrical system back up so he can have light in his home."),
- qsTr("Click on different active elements : sun, cloud, dam, solar array, " +
+ qsTr("Click on different active elements: sun, cloud, dam, solar array, " +
"wind farm and transformers, in order to reactivate the entire electrical system."),
qsTr("When the system is back up and Tux is in his home, push the light button for him. " +
"To win you must switch on all the consumers while all the producers are up."),
qsTr("Learn about an electrical system based on renewable energy. Enjoy.")
]
Behavior on opacity { PropertyAnimation { duration: 200 } }
}
Rectangle {
id: check
opacity: 0
width: 400 * ApplicationInfo.ratio
height: 200 * ApplicationInfo.ratio
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
z: 100
border.width: 2
radius: 5
color: "#d0f0f0"
property bool shown: false
GCText {
id: warning
anchors.fill: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
text: qsTr( "It is not possible to consume more electricity " +
- "than what is produced. This is a key limitation in the " +
+ "than what is produced. There is a key limitation in the " +
"distribution of electricity, with minor exceptions, " +
"electrical energy cannot be stored, and therefore it " +
"must be generated as it is needed. A sophisticated " +
"system of control is therefore required to ensure electric " +
"generation very closely matches the demand. If supply and demand " +
"are not in balance, generation plants and transmission equipment " +
"can shut down which, in the worst cases, can lead to a major " +
"regional blackout.")
fontSizeMode: Text.Fit
minimumPointSize: 10
wrapMode: Text.WordWrap
fontSize: smallSize
}
Behavior on opacity {
NumberAnimation {
duration: 200
}
}
MouseArea {
anchors.fill: parent
enabled: check.opacity > 0
onClicked: check.opacity = 0
}
}
Image {
id: stepDown
source: activity.url + (started ? "transformer.svg" : "transformer_off.svg")
sourceSize.width: parent.width * 0.06
height: parent.height * 0.09
anchors {
top: parent.top
left: parent.left
topMargin: parent.height * 0.41
leftMargin: parent.width * 0.72
}
MouseArea {
anchors.centerIn: parent
// Size the area for a touch screen
width: 70 * ApplicationInfo.ratio
height: width
onClicked: {
onClicked: parent.started = !parent.started
}
}
property bool started: false
property int powerIn:
started ? (hydro.item.power +
(wind.item ? wind.item.power : 0) +
(solar.item ? solar.item.power : 0)) : 0
property int powerOut:
started ? (tux.powerConsumed +
residentSmallLights.powerConsumed +
residentBigLights.powerConsumed) : 0
onPowerInChanged: checkPower()
// Check powerOut does not exceed powerIn. Cut some consumers in case.
function checkPower() {
if(powerOut > powerIn && residentBigSwitch.on) {
residentBigSwitch.on = false
if(!check.shown && powerIn) check.opacity = 1
}
if(powerOut > powerIn && residentSmallSwitch.on) {
residentSmallSwitch.on = false
if(!check.shown && powerIn) check.opacity = 1
}
if(powerOut > powerIn && tuxSwitch.on) {
tuxSwitch.on = false
if(!check.shown && powerIn) check.opacity = 1
}
}
}
Image {
source: activity.url + "right.svg"
sourceSize.width: stepDown.width / 2
sourceSize.height: stepDown.height / 2
anchors {
right: stepDown.left
bottom: stepDown.bottom
bottomMargin: parent.height * 0.03
}
Rectangle {
id: produceMeter
width: pow.width * 1.1
height: pow.height * 1.1
border.color: "black"
radius: 5
color: items.produceColor
anchors {
top: parent.top
right: parent.left
}
GCText {
id: pow
anchors.centerIn: parent
fontSize: smallSize * 0.5
text: stepDown.powerIn.toString() + "W"
}
}
}
Image {
source: activity.url + "down.svg"
sourceSize.width: stepDown.width / 2
sourceSize.height: stepDown.height / 2
anchors {
left: stepDown.left
top: stepDown.top
topMargin: stepDown.height * 0.8
leftMargin: parent.width * 0.05
}
Rectangle {
id: consumeMeter
width: stepdown_info.width * 1.1
height: stepdown_info.height * 1.1
border.color: "black"
radius: 5
color: items.consumeColor
anchors {
top: parent.top
topMargin: parent.height * 0.1
left: parent.right
}
GCText {
id: stepdown_info
anchors.centerIn: parent
fontSize: smallSize * 0.5
text: stepDown.powerOut.toString() + "W"
}
}
}
Image {
id: stepDownWire
source: activity.url + "hydroelectric/stepdown.svg"
sourceSize.width: parent.width
anchors.fill: parent
visible: power > 0
property int power: stepDown.powerIn
}
Image {
id: residentSmallSwitch
visible: items.currentLevel > 0
source: activity.url + (on ? "on.svg" : "off.svg")
sourceSize.height: parent.height * 0.03
sourceSize.width: parent.height * 0.03
anchors {
left: parent.left
top: parent.top
leftMargin: parent.width * 0.55
topMargin: parent.height * 0.65
}
property bool on: false
MouseArea {
id: small_area
visible: parent.visible
anchors.centerIn: parent
// Size the area for a touch screen
width: 70 * ApplicationInfo.ratio
height: width
onClicked: {
if(stepDown.powerIn - stepDown.powerOut >= residentSmallLights.power)
parent.on = !parent.on
else
parent.on = false
checkForNextLevel()
}
}
}
Image {
id: tuxHouseOn
source: activity.url + "tux_house_on.svg"
sourceSize.width: parent.width
sourceSize.height: parent.height
anchors.fill: parent
visible: tuxSwitch.on
}
Image {
id: residentSmallLights
source: activity.url + "resident_smallon.svg"
sourceSize.width: parent.width
sourceSize.height: parent.height
anchors.fill: parent
visible: items.currentLevel > 0 && powerConsumed
property int power: 1000
property int powerConsumed: on ? power : 0
property bool on: residentSmallSwitch.on
}
Rectangle {
id: smallConsumeRect
width: small_consume.width * 1.1
height: small_consume.height * 1.1
border.color: "black"
radius: 5
color: items.consumeColor
anchors {
top: residentSmallSwitch.bottom
left:residentSmallSwitch.left
}
GCText {
id: small_consume
anchors.centerIn: parent
text: residentSmallLights.powerConsumed.toString() + "W"
fontSize: smallSize * 0.5
}
visible: items.currentLevel > 0
}
Image {
id: residentBigSwitch
visible: items.currentLevel > 1
source: activity.url + (on ? "on.svg" : "off.svg")
sourceSize.height: parent.height * 0.03
sourceSize.width: parent.height * 0.03
anchors {
left: parent.left
top: parent.top
leftMargin: parent.width * 0.60
topMargin: parent.height * 0.65
}
property bool on: false
MouseArea {
id: big_area
visible: parent.visible
anchors.centerIn: parent
// Size the area for a touch screen
width: 70 * ApplicationInfo.ratio
height: width
onClicked: {
if(stepDown.powerIn - stepDown.powerOut >= residentBigLights.power)
parent.on = !parent.on
else
parent.on = false
checkForNextLevel()
}
}
}
Image {
id: residentBigLights
source: activity.url + "resident_bigon.svg"
sourceSize.width: parent.width
sourceSize.height: parent.height
anchors.fill: parent
visible: items.currentLevel > 0 && powerConsumed
property int power: 2000
property int powerConsumed: on ? power : 0
property bool on: residentBigSwitch.on
}
Rectangle {
id: bigConsumeRect
width: bigConsume.width * 1.1
height: bigConsume.height * 1.1
border.color: "black"
radius : 5
color: items.consumeColor
anchors {
top: residentBigSwitch.bottom
left: residentBigSwitch.left
}
GCText {
id: bigConsume
anchors.centerIn: parent
text: residentBigLights.powerConsumed.toString() + "W"
fontSize: smallSize * 0.5
}
visible: items.currentLevel > 1
}
// Tux is visible when tuxboat animation stops
// It's light can be activated after stepdown is on
Image {
id: tux
source: activity.url + (on ? "lightson.svg" : "lightsoff.svg")
sourceSize.height: parent.height * 0.2
sourceSize.width: parent.width * 0.15
anchors {
bottom: parent.bottom
right: parent.right
bottomMargin: parent.height * 0.3
rightMargin: parent.width * 0.02
}
visible: false
property int power: 100
property int powerConsumed: on ? power : 0
property bool on: tuxSwitch.on
Image {
id: tuxSwitch
source: activity.url + (on ? "on.svg" : "off.svg")
sourceSize.height: parent.height*0.20
sourceSize.width: parent.height*0.20
property bool on: false
anchors {
right: tux.right
top: tux.top
rightMargin: tux.width * 0.20
topMargin: tux.height * 0.30
}
MouseArea {
id: off_area
anchors.centerIn: parent
// Size the area for a touch screen
width: 70 * ApplicationInfo.ratio
height: width
onClicked: {
if(stepDown.powerIn - stepDown.powerOut >= tux.power)
parent.on = !parent.on
else
parent.on = false
checkForNextLevel()
}
}
}
Rectangle {
id: tuxMeter
width: tuxConsume.width * 1.1
height: tuxConsume.height * 1.1
border.color: "black"
radius : 5
color: items.consumeColor
anchors {
bottom: tuxSwitch.top
left: tuxSwitch.left
}
GCText {
id: tuxConsume
anchors.centerIn: parent
fontSize: smallSize * 0.5
text: tux.powerConsumed.toString() + "W"
}
visible: tux.visible
}
}
function win() {
items.bonus.good("flower")
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level | reload }
onHelpClicked: displayDialog(dialogHelp)
onPreviousLevelClicked: previousLevel()
onNextLevelClicked: nextLevel()
onHomeClicked: activity.home()
onReloadClicked: initLevel()
level: items.currentLevel + 1
}
Bonus {
id: bonus
Component.onCompleted: win.connect(nextLevel)
}
}
}
diff --git a/src/activities/renewable_energy/Solar.qml b/src/activities/renewable_energy/Solar.qml
index e9f75e44b..1b7ae68f2 100644
--- a/src/activities/renewable_energy/Solar.qml
+++ b/src/activities/renewable_energy/Solar.qml
@@ -1,117 +1,117 @@
/* GCompris - solar.qml
*
* Copyright (C) 2015 Sagar Chand Agarwal <atomsagar@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Sagar Chand Agarwal <atomsagar@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
Item {
id: solar
property alias power: solarTransformer.power
function stop() {
solarTransformer.started = false
solarPanel.started = false
}
Image {
id: solarTransformer
source: activity.url + (started ? "transformer.svg" : "transformer_off.svg")
sourceSize.width: parent.width * 0.05
height: parent.height * 0.08
anchors {
top: parent.top
right: parent.right
topMargin: parent.height * 0.38
rightMargin: parent.width * 0.11
}
property bool started: false
property int power: started ? solarPanel.power : 0
MouseArea {
anchors.centerIn: parent
// Size the area for a touch screen
width: parent.width * 1.2
height: parent.height * 1.2
onClicked: parent.started = !parent.started
}
}
Image {
source: activity.url + "left.svg"
sourceSize.width: solarTransformer.width / 2
sourceSize.height: solarTransformer.height / 2
anchors {
top: solarPanel.top
left:solarTransformer.left
leftMargin: solarTransformer.width
topMargin: solarTransformer.height
}
Rectangle {
width: solar_info.width * 1.1
height: solar_info.height * 1.1
border.color: "black"
radius: 5
color: items.produceColor
anchors {
left: parent.right
}
GCText {
id: solar_info
fontSize: smallSize * 0.5
anchors.centerIn: parent
text: solar.power.toString() + "W"
}
}
}
Image {
id: solarPower
source: activity.url + "solar/" + (solarTransformer.power ? "solarpoweron.svg" : "solarpoweroff.svg")
sourceSize.width: parent.width
anchors.fill: parent
}
Image {
id: solarPanel
source: activity.url + "solar/" + (power ? "solarpanelon.svg" : "solarpaneloff.svg")
sourceSize.width: parent.width * 0.07
height: parent.height * 0.09
anchors {
top: parent.top
right: parent.right
topMargin: parent.height * 0.31
rightMargin: parent.width * 0.14
}
property bool started: false
property int power: started && items.sunIsUp ? 1000 : 0
MouseArea {
anchors.fill: parent
onClicked: parent.started = !parent.started
}
}
Image {
id: panelPower
source: activity.url + "solar/" + (solarPanel.power ? "panelpoweron.svg" : "panelpoweroff.svg")
sourceSize.width: parent.width
anchors.fill: parent
}
}
diff --git a/src/activities/renewable_energy/Wind.qml b/src/activities/renewable_energy/Wind.qml
index 94a0f90ad..842586156 100644
--- a/src/activities/renewable_energy/Wind.qml
+++ b/src/activities/renewable_energy/Wind.qml
@@ -1,168 +1,168 @@
/* GCompris - wind.qml
*
* Copyright (C) 2015 Sagar Chand Agarwal <atomsagar@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Sagar Chand Agarwal <atomsagar@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
Item {
id: wind
property alias power: windTransformer.power
function stop() {
cloud.started = false
windTransformer.started = false
}
Image {
id: cloud
opacity: 1
source: activity.url + "wind/" + (started ? "cloud_fury.svg" :"cloud_quiet.svg")
sourceSize.width: parent.width * 0.20
sourceSize.height: parent.height * 0.10
anchors {
right: parent.right
top: parent.top
topMargin: 0.02 * parent.height
rightMargin: 0.05 * parent.width
}
property bool started: false
MouseArea {
anchors.fill: parent
onClicked: {
cloud.started = true
windTimer.restart()
}
}
}
Timer {
id: windTimer
interval: 30000
running: false
repeat: false
onTriggered: cloud.started = false
}
Image {
id: windTransformer
source: activity.url + (started ? "transformer.svg" : "transformer_off.svg")
sourceSize.width: parent.width * 0.035
height: parent.height * 0.06
anchors {
top: parent.top
right: parent.right
topMargin: parent.height * 0.2
rightMargin: parent.width * 0.18
}
property bool started: false
property int power: started ? windTurbine.power : 0
MouseArea {
anchors.centerIn: parent
// Size the area for a touch screen
width: 70 * ApplicationInfo.ratio
height: width
onClicked: {
parent.started = !parent.started
}
}
}
Image {
sourceSize.width: windTransformer.width / 2
sourceSize.height: windTransformer.height / 2
source: activity.url + "down.svg"
anchors {
bottom: windTransformer.top
right: parent.right
rightMargin: parent.width*0.20
}
Rectangle {
width: windvoltage.width * 1.1
height: windvoltage.height * 1.1
border.color: "black"
radius: 5
color: items.produceColor
anchors {
bottom: parent.top
right: parent.right
}
GCText {
id: windvoltage
anchors.centerIn: parent
text: wind.power.toString() + "W"
fontSize: smallSize * 0.5
}
}
}
Image {
source: activity.url + (windTurbine.power ? "wind/windturbineon.svg" : "wind/windturbineoff.svg")
sourceSize.width: parent.width
sourceSize.height: parent.height
anchors.fill: parent
}
Image {
source: activity.url + (windTransformer.power ? "wind/windpoweron.svg" : "wind/windpoweroff.svg")
sourceSize.width: parent.width
sourceSize.height: parent.height
anchors.fill: parent
}
// Wind turbines
WindTurbine {
id: windTurbine
anchors {
top: parent.top
right: parent.right
topMargin: parent.height * 0.17
rightMargin: parent.width * 0.05
}
z: 55
duration: 3200
property int power: cloud.started ? 1500 : 0
}
WindTurbine {
id: windTurbine2
anchors {
top: parent.top
right: parent.right
topMargin: parent.height * 0.15
rightMargin: parent.width * 0.1
}
z: 54
duration: 3500
}
WindTurbine {
id: windTurbine3
anchors {
top: parent.top
right: parent.right
topMargin: parent.height * 0.12
rightMargin: parent.width * 0.15
}
z: 53
duration: 3100
}
}
diff --git a/src/activities/renewable_energy/WindTurbine.qml b/src/activities/renewable_energy/WindTurbine.qml
index 1d5b9b004..26bf67362 100644
--- a/src/activities/renewable_energy/WindTurbine.qml
+++ b/src/activities/renewable_energy/WindTurbine.qml
@@ -1,51 +1,51 @@
/* GCompris - wind.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
Image {
id: windTurbine
source: activity.url + "wind/mast.svg"
sourceSize.width: parent.width * 0.01
property int duration
Image {
id: blade
source: activity.url + "wind/blade.svg"
sourceSize.height: parent.height * 1.3
anchors {
horizontalCenter: parent.horizontalCenter
verticalCenter: parent.top
verticalCenterOffset: parent.height * 0.06
}
SequentialAnimation on rotation {
id: anim
loops: Animation.Infinite
running: cloud.started
NumberAnimation {
from: 0; to: 360
duration: windTurbine.duration
}
}
}
}
diff --git a/src/activities/reversecount/ActivityInfo.qml b/src/activities/reversecount/ActivityInfo.qml
index a238db0a4..be0114db6 100644
--- a/src/activities/reversecount/ActivityInfo.qml
+++ b/src/activities/reversecount/ActivityInfo.qml
@@ -1,41 +1,41 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "reversecount/Reversecount.qml"
difficulty: 2
icon: "reversecount/reversecount.svg"
author: "Emmanuel Charruau &lt;echarruau@gmail.com&gt;"
demo: false
//: Activity title
title: qsTr("Practice subtraction with a fun game")
//: Help title
description: qsTr("Tux is hungry. Help him find fish by counting to the correct ice spot.")
// intro: "Click on the domino and validate your choice with the OK button to indicate the number of ice blocks Tux will have to follow to eat a fish."
//: Help goal
goal: qsTr("Tux is hungry. Help him find fish by counting to the correct ice spot.")
//: Help prerequisite
- prerequisite: qsTr("Can read numbers on a dice, and count intervals up to 10 for the first level")
+ prerequisite: qsTr("Can read numbers on a domino, and count intervals up to 10 for the first level")
//: Help manual
- manual: qsTr("Click on the dice to show how many ice spots there are between Tux and the fish. Click the dice with the right mouse button to count backwards. When done, click on the OK button or hit the Enter key.")
+ manual: qsTr("Click on the domino to show how many ice spots there are between Tux and the fish. Click the domino with the right mouse button to count backwards. When done, click on the OK button or hit the Enter key.")
credit: ""
section: "math numeration"
createdInVersion: 0
levels: "1,2"
}
diff --git a/src/activities/reversecount/ChooseDiceBar.qml b/src/activities/reversecount/ChooseDiceBar.qml
index 52fa82786..f9f4de542 100644
--- a/src/activities/reversecount/ChooseDiceBar.qml
+++ b/src/activities/reversecount/ChooseDiceBar.qml
@@ -1,65 +1,66 @@
/* GCompris - ChooseDiceBar.qml
*
* Copyright (C) 2014 Emmanuel Charruau <echarruau@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Emmanuel Charruau <echarruau@gmail.com> (Qt Quick port)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Major rework)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "reversecount.js" as Activity
Item {
id: chooseDiceBar
z: 1000
property alias value1: domino.value1
property alias value2: domino.value2
property alias valueMax: domino.valueMax
+ property alias mode: domino.mode
property GCSfx audioEffects
Row {
id: barRow
spacing: 8
BarButton {
id: ok
source: "qrc:/gcompris/src/core/resource/bar_ok.svg";
sourceSize.width: 75 * ApplicationInfo.ratio
visible: true
anchors {
right: undefined
rightMargin: undefined
top: undefined
topMargin: undefined
}
onClicked: Activity.moveTux()
}
Domino {
id: domino
height: ok.height
width: height * 2
isClickable: true
audioEffects: activity.audioEffects
}
}
}
diff --git a/src/activities/reversecount/Reversecount.qml b/src/activities/reversecount/Reversecount.qml
index e686f1a83..e26df510c 100644
--- a/src/activities/reversecount/Reversecount.qml
+++ b/src/activities/reversecount/Reversecount.qml
@@ -1,232 +1,289 @@
/* GCompris - ReverseCount.qml
*
* Copyright (C) 2014 Emmanuel Charruau <echarruau@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Emmanuel Charruau <echarruau@gmail.com> (Qt Quick port)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Major rework)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "reversecount.js" as Activity
ActivityBase {
id: activity
onStart: focus = true
onStop: {}
pageComponent: Rectangle {
id: background
anchors.fill: parent
color: "#ff00a4b0"
signal start
signal stop
Component.onCompleted: {
+ dialogActivityConfig.getInitialConfiguration()
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property GCSfx audioEffects: activity.audioEffects
readonly property string resourceUrl: activity.resourceUrl
property var levels: activity.datasetLoader.item.data
property alias background: background
property alias backgroundImg: backgroundImg
property alias bar: bar
property alias bonus: bonus
property alias chooseDiceBar: chooseDiceBar
property alias tux: tux
property alias fishToReach: fishToReach
property int clockPosition: 4
+ property string mode: "dot"
}
onStart: { Activity.start(items) }
onStop: { Activity.stop() }
Keys.onEnterPressed: Activity.moveTux()
Keys.onReturnPressed: Activity.moveTux()
onWidthChanged: {
if(Activity.fishIndex > 0) {
// set x
fishToReach.x = Activity.iceBlocksLayout[Activity.fishIndex % Activity.iceBlocksLayout.length][0] *
background.width / 5 + (background.width / 5 - tux.width) / 2
// set y
fishToReach.y = Activity.iceBlocksLayout[Activity.fishIndex % Activity.iceBlocksLayout.length][1] *
(background.height - background.height/5) / 5 +
(background.height / 5 - tux.height) / 2
// Move Tux
Activity.moveTuxToIceBlock()
}
}
onHeightChanged: {
if(Activity.fishIndex > 0) {
// set x
fishToReach.x = Activity.iceBlocksLayout[Activity.fishIndex % Activity.iceBlocksLayout.length][0] *
background.width / 5 + (background.width / 5 - tux.width) / 2
// set y
fishToReach.y = Activity.iceBlocksLayout[Activity.fishIndex % Activity.iceBlocksLayout.length][1] *
(background.height - background.height/5) / 5 +
(background.height / 5 - tux.height) / 2
// Move Tux
Activity.moveTuxToIceBlock()
}
}
Image {
id: backgroundImg
source: activity.resourceUrl + Activity.backgrounds[0]
sourceSize.height: parent.height * 0.5
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
}
// === The ice blocks ===
Repeater {
model: Activity.iceBlocksLayout
Image {
x: modelData[0] * background.width / 5
y: modelData[1] * (background.height- background.height/5) / 5
width: background.width / 5
height: background.height / 5
source: activity.resourceUrl + "iceblock.svg"
}
}
Tux {
id: tux
sourceSize.width: Math.min(background.width / 6, background.height / 6)
z: 11
}
Image {
id: fishToReach
sourceSize.width: Math.min(background.width / 6, background.height / 6)
z: 10
property string nextSource
property int nextX
property int nextY
function showParticles() {
particles.burst(40)
}
ParticleSystemStarLoader {
id: particles
clip: false
}
onOpacityChanged: { if(opacity == 0) { source = ""; source = nextSource; } }
onSourceChanged: {
if(source != "") {
x = nextX
y = nextY
opacity = 1
}
}
Behavior on opacity { NumberAnimation { duration: 500 } }
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
- content: BarEnumContent { value: help | home | level }
+ content: BarEnumContent { value: help | home | level | config }
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
+ onConfigClicked: {
+ dialogActivityConfig.active = true
+ dialogActivityConfig.setDefaultValues()
+ displayDialog(dialogActivityConfig)
+ }
}
Image {
id: clock
anchors {
right: parent.right
bottom: parent.bottom
margins: 10
}
sourceSize.width: 66 * bar.barZoom
property int remainingLife: items.clockPosition
onRemainingLifeChanged: if(remainingLife >= 0) clockAnim.restart()
SequentialAnimation {
id: clockAnim
alwaysRunToEnd: true
ParallelAnimation {
NumberAnimation {
target: clock; properties: "opacity";
to: 0; duration: 800; easing.type: Easing.OutCubic
}
NumberAnimation {
target: clock; properties: "rotation"; from: 0; to: 180;
duration: 800; easing.type: Easing.OutCubic
}
}
PropertyAction {
target: clock; property: 'source';
value: activity.resourceUrl + "flower" + items.clockPosition + ".svg"
}
ParallelAnimation {
NumberAnimation {
target: clock; properties: "opacity";
to: 1; duration: 800; easing.type: Easing.OutCubic
}
NumberAnimation {
target: clock; properties: "rotation"; from: 180; to: 0;
duration: 800; easing.type: Easing.OutCubic
}
}
}
}
+ DialogActivityConfig {
+ id: dialogActivityConfig
+ currentActivity: activity
+ content: Component {
+ Item {
+ property alias modeBox: modeBox
+ property var availableModes: [
+ { "text": qsTr("Dots"), "value": "dot" },
+ { "text": qsTr("Arabic numbers"), "value": "number" },
+ { "text": qsTr("Roman numbers"), "value": "roman" },
+ { "text": qsTr("Images"), "value": "image" }
+ ]
+ Flow {
+ id: flow
+ spacing: 5
+ width: dialogActivityConfig.width
+ GCComboBox {
+ id: modeBox
+ model: availableModes
+ background: dialogActivityConfig
+ label: qsTr("Select Domino Representation")
+ }
+ }
+ }
+ }
+ onClose: home()
+ onLoadData: {
+ if(dataToSave && dataToSave["mode"]) {
+ items.mode = dataToSave["mode"];
+ }
+ }
+ onSaveData: {
+ var newMode = dialogActivityConfig.configItem.availableModes[dialogActivityConfig.configItem.modeBox.currentIndex].value;
+ if (newMode !== items.mode) {
+ items.mode = newMode;
+ dataToSave = {"mode": items.mode};
+ }
+ Activity.initLevel();
+ }
+ function setDefaultValues() {
+ for(var i = 0 ; i < dialogActivityConfig.configItem.availableModes.length ; i++) {
+ if(dialogActivityConfig.configItem.availableModes[i].value === items.mode) {
+ dialogActivityConfig.configItem.modeBox.currentIndex = i;
+ break;
+ }
+ }
+ }
+ }
+
ChooseDiceBar {
id: chooseDiceBar
+ mode: items.mode
x: background.width / 5 + 20
y: (background.height - background.height/5) * 3 / 5
audioEffects: activity.audioEffects
}
Bonus {
id: bonus
winSound: "qrc:/gcompris/src/activities/ballcatch/resource/tuxok.wav"
looseSound: "qrc:/gcompris/src/activities/ballcatch/resource/youcannot.wav"
onWin: Activity.nextLevel()
onLoose: Activity.initLevel()
}
}
}
diff --git a/src/activities/reversecount/Tux.qml b/src/activities/reversecount/Tux.qml
index a5ad55f7f..9b356fe1b 100644
--- a/src/activities/reversecount/Tux.qml
+++ b/src/activities/reversecount/Tux.qml
@@ -1,64 +1,64 @@
/* GCompris - Tux.qml
*
* Copyright (C) 2014 Emmanuel Charruau <echarruau@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Emmanuel Charruau <echarruau@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "reversecount.js" as Activity
import GCompris 1.0
Image {
id: tux
source: activity.resourceUrl + "tux_top_south.svg"
fillMode: Image.PreserveAspectFit
z: 10
property int duration: 1000
signal init
onInit: {
tux.rotation = -90
Activity.moveTuxToIceBlock()
}
Behavior on x {
SmoothedAnimation {
reversingMode: SmoothedAnimation.Immediate
onRunningChanged: Activity.tuxRunningChanged()
duration: tux.duration
}
}
Behavior on y {
SmoothedAnimation {
reversingMode: SmoothedAnimation.Immediate
onRunningChanged: Activity.tuxRunningChanged()
duration: tux.duration
}
}
Behavior on rotation {
RotationAnimation {
duration: tux.duration / 2
direction: RotationAnimation.Shortest
}
}
}
diff --git a/src/activities/reversecount/reversecount.js b/src/activities/reversecount/reversecount.js
index 79622083c..cfdc12bbb 100644
--- a/src/activities/reversecount/reversecount.js
+++ b/src/activities/reversecount/reversecount.js
@@ -1,245 +1,245 @@
/* GCompris - reversecount.js
*
* Copyright (C) 2014 Emmanuel Charruau
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Emmanuel Charruau <echarruau@gmail.com> (Qt Quick port)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Major rework)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
.import GCompris 1.0 as GCompris //for ApplicationInfo
var iceBlocksLayout = [[0, 0],[1, 0],[2, 0],[3, 0],[4, 0],
[4, 1],[4, 2],[4, 3],[4, 4],[3, 4],
[2, 4],[1, 4],[0, 4],[0, 3],[0, 2],
[0, 1]]
var backgrounds = [
"baleine.svg",
"phoque.svg",
"ourspolaire.svg",
"morse.svg",
"elephant_mer.svg",
"epaulard.svg",
"narval.svg"
]
var tuxIceBlockNumber = 0
var tuxIceBlockNumberGoal = 0
var tuxIsMoving = false;
var placeFishToReachBool = false
var level = null;
var fishes = [
"Benzfish.svg",
"blue-fish.svg",
"drunken_duck_cartoon_globefish_kugelfisch.svg",
"Fish02.svg",
"molumen_Codfish.svg",
"mystica_Aquarium_fish_-_Amphiprion_percula.svg",
"pepinux_Pez_dorado.svg",
"The_Whale-Fish.svg",
"Benzfish.svg",
"blue-fish.svg",
"drunken_duck_cartoon_globefish_kugelfisch.svg",
"Fish02.svg"
]
var numberOfFish
var fishIndex = -1
var currentLevel = 0
var numberOfLevel = 0
var items
function start(items_) {
items = items_
currentLevel = 0
numberOfLevel = items.levels.length
initLevel()
}
function stop() {
fishIndex = -1
}
function initLevel() {
items.bar.level = currentLevel + 1
items.chooseDiceBar.value1 = 0
items.chooseDiceBar.value2 = 0
items.chooseDiceBar.valueMax = items.levels[currentLevel].maxNumber
numberOfFish = items.levels[currentLevel].numberOfFish
fishIndex = 0
tuxIceBlockNumber = 0
items.tux.init()
calculateNextPlaceFishToReach()
placeFishToReach()
moveTuxToIceBlock()
items.backgroundImg.source = items.resourceUrl + backgrounds[currentLevel % backgrounds.length]
items.clockPosition = 4
}
function moveTux() {
calculateTuxIceBlockNextPos()
if (tuxIceBlockNumberGoal > fishIndex)
{
items.clockPosition--
if (items.clockPosition === 0) {
lost()
return
}
}
else if (items.chooseDiceBar.value1 != 0 || items.chooseDiceBar.value2 != 0 ) {
moveTuxToNextIceBlock()
}
}
function moveTuxToNextIceBlock() {
tuxIsMoving = false
tuxIceBlockNumber++
tuxIceBlockNumber = tuxIceBlockNumber % iceBlocksLayout.length
if (tuxIceBlockNumber > 0 && tuxIceBlockNumber <= 4)
items.tux.rotation = -90
else if (tuxIceBlockNumber >= 5 && tuxIceBlockNumber <= 8)
items.tux.rotation = 0
else if (tuxIceBlockNumber >= 9 && tuxIceBlockNumber <= 12)
items.tux.rotation = 90
else if (tuxIceBlockNumber >= 13 && tuxIceBlockNumber <= 15)
items.tux.rotation = 180
moveTuxToIceBlock()
var fishPos = fishIndex % iceBlocksLayout.length
//if tux reaches its position + dice number
if (tuxIceBlockNumber == fishPos) {
tuxIsMoving = false;
// if last fish reached
if (--numberOfFish == 0) {
won()
items.fishToReach.showParticles()
items.clockPosition++
return
}
items.audioEffects.play('qrc:/gcompris/src/activities/gnumch-equality/resource/eat.wav')
calculateNextPlaceFishToReach()
placeFishToReachBool = true
return
}
items.audioEffects.play(items.resourceUrl + 'icy_walk.wav')
//if tux reaches its position + dice number before reaching the fish, calculation was wrong
if (tuxIceBlockNumber == tuxIceBlockNumberGoal) {
items.clockPosition--
if (items.clockPosition === 0) {
lost()
return
}
tuxIsMoving = false;
return
}
tuxIsMoving = true
}
function moveTuxToIceBlock() {
items.tux.x = iceBlocksLayout[tuxIceBlockNumber % iceBlocksLayout.length][0] *
items.background.width / 5 +
(items.background.width / 5 - items.tux.width) / 2
items.tux.y = iceBlocksLayout[tuxIceBlockNumber % iceBlocksLayout.length][1] *
(items.background.height - items.background.height/5) / 5 +
(items.background.height / 5 - items.tux.height) / 2
}
function tuxRunningChanged() {
if (tuxIsMoving) {
moveTuxToNextIceBlock()
} else {
if (placeFishToReachBool == true) {
placeFishToReach(fishIndex)
placeFishToReachBool = false
}
}
}
function calculateTuxIceBlockNextPos() {
tuxIceBlockNumberGoal = tuxIceBlockNumber +
items.chooseDiceBar.value1 + items.chooseDiceBar.value2
// Increase Tux's speed depending on the number of blocks to move
items.tux.duration = 1000 -
(items.chooseDiceBar.value1 + items.chooseDiceBar.value2) * 40
}
var previousFishIndex = 0
function calculateNextPlaceFishToReach() {
var newFishIndex
do {
newFishIndex = Math.floor(Math.random() *
(items.levels[currentLevel].maxNumber * 2 -
items.levels[currentLevel].minNumber + 1)) +
items.levels[currentLevel].minNumber
} while((previousFishIndex === newFishIndex) || (newFishIndex >= iceBlocksLayout.length))
previousFishIndex = newFishIndex
fishIndex = tuxIceBlockNumber + newFishIndex
}
function placeFishToReach() {
// placeFishToReach can be called when the opacity is 0.
// In this case, this does not trigger the onOpacityChanged of the fish Image (meaning the fish will not be displayed) so we directly set the opacity to 1.
if(items.fishToReach.opacity == 0)
items.fishToReach.opacity = 1
else
items.fishToReach.opacity = 0
items.fishToReach.nextSource = items.resourceUrl + fishes[fishIndex % fishes.length]
items.fishToReach.nextX = iceBlocksLayout[fishIndex % iceBlocksLayout.length][0] *
items.background.width / 5 +
(items.background.width / 5 - items.tux.width) / 2
items.fishToReach.nextY = iceBlocksLayout[fishIndex % iceBlocksLayout.length][1] *
(items.background.height - items.background.height/5) / 5 +
(items.background.height / 5 - items.tux.height) / 2
}
function nextLevel() {
if(numberOfLevel <= ++currentLevel) {
currentLevel = 0
}
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
initLevel();
}
function lost() {
items.bonus.bad("tux")
}
function won() {
items.bonus.good("flower")
}
diff --git a/src/activities/reversecount/reversecount.svg b/src/activities/reversecount/reversecount.svg
index 6d3a2ed80..62e1e807a 100644
--- a/src/activities/reversecount/reversecount.svg
+++ b/src/activities/reversecount/reversecount.svg
@@ -1,514 +1,465 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="100"
height="100"
id="svg2"
sodipodi:version="0.32"
- inkscape:version="0.91 r13725"
+ inkscape:version="0.92.1 r15371"
version="1.0"
sodipodi:docname="reversecount.svg">
<defs
id="defs4">
<linearGradient
gradientTransform="matrix(1,0,0,1.0859179,0,-53.897354)"
gradientUnits="userSpaceOnUse"
y2="650.04968"
x2="945.6795"
y1="637.41199"
x1="940.9632"
id="linearGradient4503"
xlink:href="#linearGradient4497"
inkscape:collect="always" />
<linearGradient
id="linearGradient4497"
inkscape:collect="always">
<stop
id="stop4499"
offset="0"
style="stop-color:#275eb1;stop-opacity:1" />
<stop
id="stop4501"
offset="1"
style="stop-color:#e6ecf9;stop-opacity:1" />
</linearGradient>
<linearGradient
gradientTransform="matrix(-1,0,0,1.0859179,1919.9978,-53.897354)"
gradientUnits="userSpaceOnUse"
y2="650.04968"
x2="945.6795"
y1="637.41199"
x1="940.9632"
id="linearGradient4503-2"
xlink:href="#linearGradient4497"
inkscape:collect="always" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="2.8634092"
- inkscape:cx="38.740885"
+ inkscape:cx="-36.169819"
inkscape:cy="51.353514"
inkscape:document-units="px"
inkscape:current-layer="layer1"
width="100px"
height="100px"
- inkscape:window-width="1880"
- inkscape:window-height="1060"
- inkscape:window-x="-3"
- inkscape:window-y="-3"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
showgrid="false"
inkscape:window-maximized="1" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
<dc:date>2015</dc:date>
<dc:creator>
<cc:Agent>
<dc:title>Timothée Giet</dc:title>
</cc:Agent>
</dc:creator>
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Notice" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
<g
inkscape:label="Calque 1"
inkscape:groupmode="layer"
id="layer1">
<g
transform="matrix(0.17306643,0,0,0.17306643,-36.673612,-30.052924)"
id="layer1-6"
inkscape:label="Calque 1">
<path
sodipodi:nodetypes="csszszcc"
inkscape:connector-curvature="0"
id="path3775-3"
d="m 402.557,627.34124 c 15.45599,-0.1269 60.59179,16.71024 59.13369,23.10393 -0.3799,1.66622 -16.1722,7.30674 -22.2907,10.18897 -3.4918,1.64489 1.6432,6.65255 -1.6045,7.05293 -3.2477,0.40038 -12.1021,-3.21282 -19.2145,-3.70297 -9.1385,-0.62978 -26.50988,1.9625 -30.38541,1.57616 -3.87552,-0.38633 -8.97404,-28.10646 -6.81057,-29.11119 6.42101,-2.95779 16.60439,-8.77075 21.17199,-9.10783 z"
style="display:inline;opacity:0.98999999;fill:#a78014;fill-opacity:1;stroke:none" />
<path
sodipodi:nodetypes="csszszcc"
inkscape:connector-curvature="0"
id="path3775"
d="m 329.45449,627.34203 c -15.45599,-0.1269 -60.59178,16.71024 -59.13375,23.10393 0.37997,1.66622 16.17224,7.30674 22.29073,10.18897 3.49182,1.64489 -1.64324,6.65255 1.60449,7.05293 3.24772,0.40038 12.10216,-3.21282 19.2145,-3.70297 9.13848,-0.62978 26.50991,1.9625 30.38544,1.57616 3.87552,-0.38633 8.97404,-28.10646 6.81057,-29.11119 -6.42101,-2.95779 -16.60435,-8.77075 -21.17198,-9.10783 z"
style="display:inline;fill:#a78014;fill-opacity:1;stroke:none" />
<g
transform="translate(-594.61442,-196.85364)"
id="g4667"
style="display:inline">
<path
style="display:inline;fill:#e2a70e;fill-opacity:1;stroke:none"
d="m 921.34614,828.77469 c -13.48149,-0.11069 -52.85117,12.57551 -51.57941,18.1524 0.33143,1.45336 14.10624,4.3733 19.44309,6.88733 3.04574,1.43475 0.31118,5.80268 3.14402,6.15192 2.83282,0.34923 8.8116,-2.80239 15.01534,-3.22992 7.97104,-0.54933 25.12326,1.9673 28.5037,1.63031 3.38042,-0.33698 3.8276,-22.77136 1.94051,-23.64774 -5.60072,-2.57993 -12.48314,-5.65028 -16.46725,-5.9443 z"
id="path3775-9"
inkscape:connector-curvature="0"
sodipodi:nodetypes="csszszcc" />
<path
style="display:inline;fill:#e2a70e;fill-opacity:1;stroke:none"
d="m 999.3113,828.77469 c 13.4815,-0.11069 52.8512,12.57551 51.5794,18.1524 -0.3314,1.45336 -14.1062,4.3733 -19.4431,6.88733 -3.0457,1.43475 -0.3112,5.80268 -3.144,6.15192 -2.8328,0.34923 -8.8116,-2.80239 -15.0153,-3.22992 -7.9711,-0.54933 -25.12331,1.9673 -28.50375,1.63031 -3.38042,-0.33698 -3.8276,-22.77136 -1.94051,-23.64774 5.60072,-2.57993 12.48316,-5.65028 16.46726,-5.9443 z"
id="path3775-9-3"
inkscape:connector-curvature="0"
sodipodi:nodetypes="csszszcc" />
</g>
<g
transform="translate(-594.28572,-196.85364)"
style="display:inline;fill:#2a2a2a;fill-opacity:1"
id="g4602">
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#2a2a2a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.5;marker:none;enable-background:accumulate"
d="m 1047.5807,761.80244 c 0,48.36946 -39.2113,87.58066 -87.58072,87.58066 -48.36945,0 -87.58065,-39.2112 -87.58065,-87.58066 0,-24.18473 13.8028,-71.40879 29.65178,-112.58666 15.84898,-41.17788 25.49178,-72.49935 59.03328,-72.49935 33.54151,0 40.97541,31.32147 56.82441,72.49935 15.849,41.17787 29.6519,88.40193 29.6519,112.58666 z"
id="path2992"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ssszzzs" />
<path
style="fill:#2a2a2a;fill-opacity:1;stroke:none"
d="m 1037.6216,728.00614 c 23.716,-0.38105 55.6572,10.63018 59.7453,12.83874 10.9697,-19.99218 -50.0446,-46.77657 -71.2956,-65.89171 -12.1316,-10.91225 6.4731,51.31353 11.5503,53.05297 z"
id="path3807"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccsc" />
<path
style="display:inline;fill:#2a2a2a;fill-opacity:1;stroke:none"
d="m 882.37842,728.00614 c -23.716,-0.38105 -55.6572,10.63018 -59.7453,12.83874 -10.9697,-19.99218 50.0446,-46.77657 71.2956,-65.89171 12.1316,-10.91225 -6.4731,51.31353 -11.5503,53.05297 z"
id="path3807-7"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccsc" />
</g>
<path
sodipodi:nodetypes="sssss"
inkscape:connector-curvature="0"
id="path3829"
d="m 426.85729,547.62604 c 0,38.44108 -26.2701,67.60375 -61.14303,67.60375 -34.8729,0 -61.14297,-29.16267 -61.14297,-67.60375 0,-38.44109 26.27007,-75.60375 61.14297,-75.60375 34.87293,0 61.14303,37.16266 61.14303,75.60375 z"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#f2f2f2;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.5;marker:none;enable-background:accumulate" />
<path
sodipodi:nodetypes="szszs"
inkscape:connector-curvature="0"
id="path3792"
d="m 404.38759,489.32906 c 0,7.97791 -22.81369,28.56754 -38.67333,28.56754 -15.85964,0 -38.67338,-21.38032 -38.67338,-28.56754 0,-6.377 17.31467,-23.90146 38.67338,-23.90146 21.35873,0 38.67333,17.00327 38.67333,23.90146 z"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#b28b16;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.5;marker:none;enable-background:accumulate" />
<path
sodipodi:nodetypes="szszs"
inkscape:connector-curvature="0"
id="path3792-7"
d="m 399.06482,489.65017 c 0,6.87987 -19.67375,24.63567 -33.35056,24.63567 -13.67682,0 -33.35061,-18.43766 -33.35061,-24.63567 0,-5.49931 11.32081,-22.61181 33.35061,-22.61181 22.0298,0 33.35056,16.66304 33.35056,22.61181 z"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#f1c43c;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.5;marker:none;enable-background:accumulate" />
<path
sodipodi:nodetypes="ccsccsc"
inkscape:connector-curvature="0"
id="path3803"
d="m 328.43301,490.14636 -0.0625,0.71875 c 0,0 16.04366,16.65625 37.34375,16.65625 21.30009,0 37.34375,-16.65625 37.34375,-16.65625 l -0.0625,-0.71875 c 0,0 -16.50458,15.32236 -37.28125,15.32236 -20.77667,0 -37.28125,-15.32236 -37.28125,-15.32236 z"
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:Sans;-inkscape-font-specification:Sans;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;display:inline;overflow:visible;visibility:visible;fill:#b28b16;fill-opacity:1;stroke:none;stroke-width:1px;marker:none;enable-background:accumulate" />
<g
transform="translate(-594.25403,-196.85364)"
id="g4625"
style="display:inline">
<path
style="fill:#f2f2f5;fill-opacity:1;stroke:none"
d="m 939.0157,625.16734 c 8.22345,-3.27448 13.36227,12.73386 11.8014,21.21012 -1.56086,8.47625 -9.50431,12.46262 -16.2504,5.30623 -6.7461,-7.15639 -3.77445,-23.24187 4.449,-26.51635 z"
id="path2999"
inkscape:connector-curvature="0"
sodipodi:nodetypes="zzzz" />
<path
style="display:inline;fill:url(#linearGradient4503);fill-opacity:1;stroke:none"
d="m 942.97212,636.2935 c 6.98855,-0.19342 7.86724,17.20381 1.52621,16.26008 -6.34105,-0.94375 -8.51478,-16.06661 -1.52621,-16.26008 z"
id="path3769-9"
inkscape:connector-curvature="0"
sodipodi:nodetypes="zzz" />
<path
style="fill:#171717;fill-opacity:1;stroke:none"
d="m 943.91329,641.70876 c 2.94998,-0.0863 3.32089,7.67564 0.64424,7.25458 -2.67665,-0.42106 -3.59422,-7.16827 -0.64424,-7.25458 z"
id="path3769"
inkscape:connector-curvature="0"
sodipodi:nodetypes="zzz" />
<path
style="display:inline;fill:#f2f2f5;fill-opacity:1;stroke:none"
d="m 980.92095,625.16734 c -8.22345,-3.27448 -13.36227,12.73386 -11.8014,21.21012 1.56086,8.47625 9.50431,12.46262 16.2504,5.30623 6.7461,-7.15639 3.77445,-23.24187 -4.449,-26.51635 z"
id="path2999-2"
inkscape:connector-curvature="0"
sodipodi:nodetypes="zzzz" />
<path
style="display:inline;fill:url(#linearGradient4503-2);fill-opacity:1;stroke:none"
d="m 977.02571,636.2935 c -6.98855,-0.19342 -7.86724,17.20381 -1.52621,16.26008 6.34105,-0.94375 8.51478,-16.06661 1.52621,-16.26008 z"
id="path3769-9-5"
inkscape:connector-curvature="0"
sodipodi:nodetypes="zzz" />
<path
style="display:inline;fill:#171717;fill-opacity:1;stroke:none"
d="m 976.08665,641.70876 c -2.94998,-0.0863 -3.32089,7.67564 -0.64424,7.25458 2.67665,-0.42106 3.59422,-7.16827 0.64424,-7.25458 z"
id="path3769-6"
inkscape:connector-curvature="0"
sodipodi:nodetypes="zzz" />
<path
style="display:inline;fill:#ffffff;fill-opacity:0.90232556;stroke:none"
d="m 941.32961,639.49936 c 2.59421,-0.0649 2.92038,5.77001 0.56654,5.45349 -2.35384,-0.31653 -3.16075,-5.38861 -0.56654,-5.45349 z"
id="path3769-2"
inkscape:connector-curvature="0"
sodipodi:nodetypes="zzz" />
<path
style="display:inline;fill:#ffffff;fill-opacity:0.76744187;stroke:none"
d="m 942.09935,645.81792 c 1.70477,-0.0343 1.91911,3.04768 0.3723,2.88049 -1.54682,-0.16719 -2.07708,-2.84622 -0.3723,-2.88049 z"
id="path3769-2-0"
inkscape:connector-curvature="0"
sodipodi:nodetypes="zzz" />
<path
style="display:inline;fill:#ffffff;fill-opacity:0.90232556;stroke:none"
d="m 974.66822,639.49936 c -2.59421,-0.0649 -2.92038,5.77001 -0.56654,5.45349 2.35384,-0.31653 3.16075,-5.38861 0.56654,-5.45349 z"
id="path3769-2-9"
inkscape:connector-curvature="0"
sodipodi:nodetypes="zzz" />
<path
style="display:inline;fill:#ffffff;fill-opacity:0.76744187;stroke:none"
d="m 973.89848,645.81792 c -1.70477,-0.0343 -1.91911,3.04768 -0.3723,2.88049 1.54682,-0.16719 2.07708,-2.84622 0.3723,-2.88049 z"
id="path3769-2-0-2"
inkscape:connector-curvature="0"
sodipodi:nodetypes="zzz" />
</g>
</g>
- <g
- id="g4420"
- transform="translate(-4.0161917,8.2070004)">
- <path
- sodipodi:nodetypes="zzzzzsz"
- id="path18961-3-3"
- d="m 77.472418,30.353957 c -0.12646,-1.060839 -7.581598,-11.519713 -8.66971,-12.026284 -1.088112,-0.506573 -15.73154,1.510681 -16.606769,2.26237 -0.875229,0.751689 -6.921838,12.935146 -6.715973,14.169583 0.205866,1.234436 7.995299,11.24996 9.158145,11.78814 1.162848,0.53818 15.766424,-0.411633 16.850986,-0.952576 1.227345,-0.61216 6.10978,-14.180394 5.983321,-15.241233 z"
- style="fill:#94441a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="zzzzzzz"
- id="path19848-6-5"
- d="m 75.518681,30.324062 c -0.133708,-1.105913 -6.817734,-9.888655 -7.815408,-10.388916 -0.997674,-0.50026 -13.394182,1.323252 -14.171942,2.014178 -0.777761,0.690926 -6.570051,12.167746 -6.08009,13.487087 0.489961,1.319341 6.962947,9.189219 8.164198,9.622953 1.201251,0.433734 13.152228,-0.01951 14.380354,-0.848074 1.228125,-0.82856 5.656595,-12.781313 5.522888,-13.887228 z"
- style="fill:#df773f;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- inkscape:connector-curvature="0" />
- <path
- style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#a4572e;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.18700004;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
- d="m 56.152521,45.287383 c -0.64397,-0.058 -1.40475,-0.211255 -1.688493,-0.418397 -3.218356,-3.330416 -4.295051,-4.682563 -7.229067,-8.6712 -0.6946,-0.919554 3.875301,-0.730809 3.934166,-0.762255 0.09158,-0.04893 2.640778,-0.310122 4.57639,-0.468911 1.289702,-0.105801 5.758548,-0.194923 6.121854,-0.126766 0.538675,0.101056 1.565733,1.442629 3.970907,4.732013 0.749941,1.025642 1.861309,2.535826 2.469706,3.355964 0.608397,0.820138 1.092559,1.663485 1.075917,1.680127 -0.12269,0.12269 -3.416948,0.461721 -5.790261,0.595909 -2.005283,0.11338 -6.569721,0.162004 -7.441119,0.08352 z"
- id="path4274"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="scccsssssss" />
- <path
- sodipodi:nodetypes="czcczzczcc"
- id="path19850-5-2"
- d="M 70.756446,43.690036 C 68.239689,40.138423 62.850725,34.836238 62.57517,33.568904 62.299614,32.30157 66.645043,24.360275 68.990096,19.677907 l -2.141125,-0.640044 c -1.536485,5.118849 -4.674045,13.345082 -5.739104,14.173825 -1.065061,0.828743 -14.068366,1.674238 -14.998929,1.026905 -0.930562,-0.647333 1.288018,1.918023 1.288018,1.918023 4.565769,-0.948532 13.24642,-1.473477 14.321454,-1.158846 1.075034,0.314631 5.43376,6.960778 7.81495,9.882987 z"
- style="fill:#94441a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- inkscape:connector-curvature="0" />
- <path
- sodipodi:nodetypes="zzz"
- inkscape:connector-curvature="0"
- id="path4146-9"
- d="m 57.603017,38.910418 c 2.292489,0.187697 3.629311,2.975564 1.336574,2.791065 -2.292738,-0.184498 -3.629062,-2.978762 -1.336574,-2.791065 z"
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#dfae97;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
- <path
- sodipodi:nodetypes="zzz"
- inkscape:connector-curvature="0"
- id="path4146-3-1"
- d="m 69.444927,38.859988 c -0.189812,-2.292314 2.341842,-4.067142 2.53485,-1.775105 0.193009,2.292036 -2.345039,4.067419 -2.53485,1.775105 z"
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#ebcec0;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
- <path
- sodipodi:nodetypes="zzz"
- inkscape:connector-curvature="0"
- id="path4146-3-6-2"
- d="m 71.954902,32.693625 c -0.189813,-2.292314 2.341843,-4.067142 2.534851,-1.775105 0.193009,2.292037 -2.345039,4.06742 -2.534851,1.775105 z"
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#ebcec0;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
- <path
- sodipodi:nodetypes="zzz"
- inkscape:connector-curvature="0"
- id="path4146-3-7-7"
- d="m 64.757531,33.116105 c -0.189812,-2.292314 2.341843,-4.067142 2.534851,-1.775105 0.193008,2.292037 -2.34504,4.06742 -2.534851,1.775105 z"
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#ebcec0;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
- <path
- sodipodi:nodetypes="zzz"
- inkscape:connector-curvature="0"
- id="path4146-3-5-0"
- d="m 67.646875,26.72941 c -0.189811,-2.292315 2.341843,-4.067143 2.534852,-1.775106 0.193008,2.292037 -2.34504,4.067419 -2.534852,1.775106 z"
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#ebcec0;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
- <path
- sodipodi:nodetypes="zzz"
- inkscape:connector-curvature="0"
- id="path4146-3-56-93"
- d="m 53.174633,24.79324 c 0.201997,-2.291273 2.99815,-3.610673 2.79935,-1.319131 -0.198803,2.291542 -3.00135,3.610404 -2.79935,1.319131 z"
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#ebcec0;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
- <path
- sodipodi:nodetypes="zzz"
- inkscape:connector-curvature="0"
- id="path4146-3-56-9-6"
- d="m 58.2667,31.325174 c 0.334527,-2.275703 3.202487,-3.430734 2.871135,-1.154578 -0.331353,2.276157 -3.205664,3.430282 -2.871135,1.154578 z"
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#ebcec0;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
- <path
- sodipodi:nodetypes="zzz"
- inkscape:connector-curvature="0"
- id="path4146-3-56-9-6-0"
- d="m 55.635244,28.132155 c 0.334526,-2.275703 3.202486,-3.430734 2.871134,-1.154579 -0.331352,2.276158 -3.205664,3.430283 -2.871134,1.154579 z"
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#ebcec0;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
- <path
- sodipodi:nodetypes="zzz"
- inkscape:connector-curvature="0"
- id="path4146-3-6-2-6"
- d="m 68.578889,32.727425 c -0.189813,-2.292313 2.341843,-4.067141 2.534851,-1.775104 0.193009,2.292037 -2.345039,4.06742 -2.534851,1.775104 z"
- style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#ebcec0;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
- </g>
<g
transform="matrix(0.44773562,0,0,0.44773562,46.002778,53.531599)"
inkscape:label="Calque 1"
id="layer1-1">
<path
style="fill:#193e76;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.8419742px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 63.726064,29.937747 C 58.6456,30.725204 51.403169,33.599916 46.564095,36.936301 41.725021,40.272687 41.507385,48.333091 36.695168,48.243086 31.88295,48.15308 32.761783,41.52088 29.520142,38.749571 26.278501,35.978261 20.057337,33.62974 15.792119,32.877138 9.1015754,32.227362 0.2722508,34.416024 3.3351054,41.569676 c 1.090021,2.536319 7.0255276,2.598526 10.2673906,5.733032 3.241863,3.134506 6.729106,4.791005 7.464818,10.454291 0.735713,5.663286 -1.167327,11.680527 -4.537971,16.27533 -3.633567,5.371758 -15.83409816,6.845353 -11.7301259,13.655012 1.0788342,3.162513 14.9003079,0.698728 20.5408799,-2.340519 5.640573,-3.039247 5.214643,-14.528996 11.715061,-14.161741 6.500419,0.367255 6.340635,8.280168 10.634312,11.766714 4.293676,3.486545 8.439228,6.410984 14.348533,7.138525 5.909304,0.727541 13.904546,-1.494467 19.236878,-4.234125 5.332332,-2.739658 9.240122,-5.601067 12.097784,-10.882752 2.857662,-5.281686 3.43355,-13.898204 3.024445,-19.525966 C 95.988004,49.819715 95.588543,46.500436 92.24729,41.975259 88.906038,37.450083 81.024841,32.6873 75.999685,30.917544 70.97453,29.147787 68.806529,29.150289 63.726064,29.937747 Z"
id="path49949-6"
sodipodi:nodetypes="zzzzcczzcczzzzzzzzzz"
inkscape:connector-curvature="0" />
<path
style="fill:#193e76;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 79.158338,34.055655 C 78.879842,29.236503 71.709396,17.964698 68.642477,18.136811 c -1.375933,0.07722 -29.60136,11.88731 -28.886911,13.769007 0.532796,1.403263 3.778816,11.737218 0.154587,15.262304 -2.880564,2.801763 30.701761,-16.038381 39.248185,-13.112467 z"
id="path4205-7"
inkscape:connector-curvature="0"
sodipodi:nodetypes="csssc" />
<path
style="fill:#3f86f1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 76.839528,34.522852 C 76.587657,30.194408 70.801765,20.764582 68.028051,20.91917 66.78366,20.988523 41.25665,31.59606 41.902796,33.286154 c 0.481859,1.260377 3.277744,8.737077 0,11.903223 -2.605175,2.516475 27.207366,-13.294509 34.936732,-10.666525 z"
id="path4205"
inkscape:connector-curvature="0"
sodipodi:nodetypes="csssc" />
<path
style="fill:#193e76;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 60.366032,89.207426 c -2.899707,2.550811 -3.173054,7.727965 -9.372263,6.979297 L 30.853375,83.42458 c -4.074231,-3.62359 9.777502,-3.195918 12.164,-9.172788"
id="path4173-3"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<path
style="fill:#3f86f1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 58.897765,85.845839 c -2.247923,1.977463 -3.541939,7.845993 -8.347715,7.265604 L 34.936732,83.217855 c -3.158442,-2.809114 8.661866,-3.559681 10.511937,-8.193126"
id="path4173"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<path
style="fill:#3f86f1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.8419742px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 62.616968,32.218036 c -4.692925,0.72739 -11.382902,3.382818 -15.85285,6.464703 -4.469948,3.081885 -6.098936,11.384212 -10.544076,11.301072 -4.44514,-0.08314 -4.347322,-5.923844 -7.34169,-8.483757 C 25.883984,38.940141 22.279303,35.628403 18.339437,34.93321 14.399571,34.238017 8.827595,35.570503 7.002049,37.325151 5.176504,39.079799 5.111797,38.4779 6.118671,40.820748 c 1.006874,2.342848 7.203595,2.828696 10.198168,5.724101 2.994573,2.895405 6.215808,6.13909 6.8954,11.370379 0.679592,5.231289 -2.077851,13.35985 -5.191381,17.60416 -3.11353,4.24431 -10.295262,4.648993 -10.980049,7.379588 -0.684788,2.730595 -1.13743,1.884154 1.715449,3.234681 2.85288,1.350527 9.765439,-0.211344 14.975747,-3.018756 5.210308,-2.807412 8.243956,-14.705878 14.248521,-14.366637 6.004565,0.339241 5.856969,9.219303 9.823123,12.439894 3.966154,3.220591 7.795482,5.921953 13.254023,6.593997 5.458541,0.672044 12.843904,-1.380469 17.769484,-3.911145 4.92558,-2.530676 8.535283,-5.173816 11.174962,-10.052613 C 92.641797,68.9396 93.173756,60.980352 92.795857,55.781877 92.417958,50.583402 92.048968,47.517319 88.962587,43.337324 85.876206,39.157329 78.596189,34.757853 73.954354,33.123094 69.312519,31.488335 67.309893,31.490646 62.616968,32.218036 Z"
id="path49949-2"
sodipodi:nodetypes="zzzzzzzzzzzzzzzzzzzzzz"
inkscape:connector-curvature="0" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#eaeef3;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
id="path4222"
sodipodi:type="arc"
sodipodi:cx="86.578522"
sodipodi:cy="54.310028"
sodipodi:rx="4.7922068"
sodipodi:ry="7.8839526"
sodipodi:start="0.14344896"
sodipodi:end="0.14048923"
sodipodi:open="true"
d="m 91.321507,55.437098 a 4.7922068,7.8839526 0 0 1 -5.424557,6.676737 4.7922068,7.8839526 0 0 1 -4.062422,-8.919328 4.7922068,7.8839526 0 0 1 5.418545,-6.689937 4.7922068,7.8839526 0 0 1 4.070441,8.909429" />
<g
id="g4260"
transform="translate(0,18)">
<path
sodipodi:nodetypes="cccccc"
id="path54402-7"
d="m 49.65685,13.293398 3.406083,3.032647 -3.530452,5.04186 -4.21996,1.454291 -1.140036,-6.44692 5.484365,-3.081878 z"
style="fill:#f0cb38;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0" />
<path
sodipodi:nodetypes="cccccc"
id="path54404-0"
d="m 64.039825,8.8520949 2.665115,3.7007451 -4.542344,4.153499 -4.43522,0.501842 0.289154,-6.540554 6.023295,-1.8155321 z"
style="fill:#f0cb38;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccc"
id="path54408-9"
d="m 42.521663,68.662191 -1.971685,-2.39521 2.584894,-5.346975 4.067247,-1.838621 1.731828,6.313733 -6.412284,3.267073 z"
style="fill:#f0cb38;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccc"
id="path54410-3"
d="m 51.421497,72.327068 -3.672145,-2.240622 3.048656,-6.119912 4.067247,-1.838621 2.19559,5.386209 -5.639348,4.812946 z"
style="fill:#f0cb38;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<path
sodipodi:nodetypes="ccccsccccccccc"
id="path50840-6"
d="m 54.642546,19.043977 0.219483,3.926793 -5.195237,8.57014 3.296086,10.299103 c 0,0 -1.924109,4.009031 -2.721468,9.492381 -0.797359,5.48335 -1.474778,10.928897 -0.99502,10.77769 l 5.199252,2.638837 1.631096,-10.407208 -1.245633,-3.962216 4.089698,-7.63952 -2.957937,-13.583951 2.991125,-2.222447 -0.0017,-9.377463 -4.309752,1.487861 z"
style="fill:#f0cb38;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0" />
<path
sodipodi:nodetypes="ccccsccccccccc"
id="path54390-0"
d="m 66.870433,15.60753 -1.122931,6.446994 -3.685022,9.242193 3.296086,10.299103 c 0,0 -1.924108,4.009031 -2.721467,9.49238 -0.797359,5.48335 -0.971373,17.313405 -0.491615,17.162198 l 5.534855,-1.393484 0.792087,-12.759394 1.439195,-4.130229 1.404871,-7.471508 -2.957937,-13.583951 1.480909,-2.8945 2.011928,-10.049516 -4.980959,-0.360286 z"
style="fill:#f0cb38;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0" />
<path
sodipodi:nodetypes="cccccccccccc"
id="path54392-6"
d="m 79.341384,19.626574 -2.129742,5.438914 -3.349418,22.011208 0.611259,10.803143 c 0,0 3.445546,1.824857 4.494005,6.97218 l 4.157311,-4.719295 -4.937271,-5.138309 0.398061,-9.319655 2.243916,-12.743884 0.138496,-5.078674 4.193351,-4.337061 -5.819968,-3.888567 z"
style="fill:#f0cb38;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0" />
<path
sodipodi:nodetypes="cccccccccc"
id="path54394-2"
d="m 45.107658,25.016137 2.633146,6.278981 -3.530452,5.04186 2.073568,9.291023 c 0,0 -0.592916,6.361217 -1.641375,11.50854 l -4.828518,-6.063401 1.077831,-6.482417 -0.901466,-6.799454 -0.367099,-7.374444 5.484365,-5.400688 z"
style="fill:#f0cb38;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0" />
<path
sodipodi:nodetypes="ccccccccccc"
id="path54396-6"
d="m 19.433996,19.471695 9.009612,5.102888 6.705452,17.810874 -3.296086,12.14725 c 0,0 -3.445546,3.168965 -6.507626,6.46814 l 1.283365,-9.017537 2.790172,-9.487668 -2.915123,-10.05567 -2.655521,-7.598875 -10.234213,-5.177128 5.819968,-0.192274 z"
style="fill:#f0cb38;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0" />
<path
sodipodi:nodetypes="cccccc"
id="path54412-1"
d="m 10.146685,67.071099 -1.5079226,-2.395209 4.5945296,-2.873578 3.912659,-2.766145 1.886416,6.777495 -8.885682,1.257437 z"
style="fill:#f0cb38;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0" />
<path
sodipodi:nodetypes="ccccc"
id="path54414-8"
d="M 8.9872804,19.461816 8.0977067,23.093723 12.073887,25.039777 11.225708,19.637141 8.9872804,19.461816 Z"
style="fill:#f0cb38;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
inkscape:connector-curvature="0" />
</g>
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#214f8a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
id="path4224-5"
sodipodi:type="arc"
sodipodi:cx="88.433578"
sodipodi:cy="54.068512"
sodipodi:rx="2.4476323"
sodipodi:ry="4.0965638"
sodipodi:start="0.14344896"
sodipodi:end="0.14048923"
sodipodi:open="true"
d="m 90.856071,54.654146 a 2.4476323,4.0965638 0 0 1 -2.770607,3.469285 2.4476323,4.0965638 0 0 1 -2.074893,-4.634553 2.4476323,4.0965638 0 0 1 2.767537,-3.476143 2.4476323,4.0965638 0 0 1 2.078988,4.629409" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#1f2a38;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
id="path4224"
sodipodi:type="arc"
sodipodi:cx="88.356285"
sodipodi:cy="54.454979"
sodipodi:rx="1.7777541"
sodipodi:ry="2.7825716"
sodipodi:start="0.14344896"
sodipodi:end="0.14048923"
sodipodi:open="true"
d="m 90.11578,54.852768 a 1.7777541,2.7825716 0 0 1 -2.012336,2.356496 1.7777541,2.7825716 0 0 1 -1.507028,-3.147999 1.7777541,2.7825716 0 0 1 2.010106,-2.361154 1.7777541,2.7825716 0 0 1 1.510002,3.144505" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
id="path4241"
sodipodi:type="arc"
sodipodi:cx="87.096687"
sodipodi:cy="55.946457"
sodipodi:rx="1.2366985"
sodipodi:ry="1.3912858"
sodipodi:start="0.14344896"
sodipodi:end="0.14048923"
sodipodi:open="true"
d="m 88.320683,56.145352 a 1.2366985,1.3912858 0 0 1 -1.399885,1.178247 1.2366985,1.3912858 0 0 1 -1.048367,-1.573999 1.2366985,1.3912858 0 0 1 1.398334,-1.180577 1.2366985,1.3912858 0 0 1 1.050436,1.572252" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
id="path4241-3"
sodipodi:type="arc"
sodipodi:cx="86.901237"
sodipodi:cy="59.409981"
sodipodi:rx="0.58084011"
sodipodi:ry="0.73542732"
sodipodi:start="0.14344896"
sodipodi:end="0.14048923"
sodipodi:open="true"
d="m 87.476112,59.515116 a 0.58084011,0.73542732 0 0 1 -0.657485,0.622816 0.58084011,0.73542732 0 0 1 -0.492386,-0.832009 0.58084011,0.73542732 0 0 1 0.656756,-0.624047 0.58084011,0.73542732 0 0 1 0.493358,0.831085" />
</g>
+ <g
+ id="g902">
+ <path
+ sodipodi:nodetypes="ccccc"
+ inkscape:connector-curvature="0"
+ id="rect4896-3"
+ d="M 61.052611,23.682225 71.566766,26.801812 56.93899,52.922698 46.384752,47.980873 Z"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#ebd9c0;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.31647754;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="ccccscccc"
+ inkscape:connector-curvature="0"
+ id="path4894-4"
+ d="M 73.070209,26.687147 57.805576,53.702838 56.942928,53.622193 45.020249,47.750477 c -0.0282,0.687332 0.526852,2.395783 0.783553,2.939199 0.308298,0.652646 9.420884,4.462315 11.228493,4.830857 0.310863,0.06809 0.732256,0.128516 1.270184,-0.280643 5.493217,-8.022274 9.995332,-17.002599 14.764988,-25.566956 0.116165,-0.764197 0.233392,-2.384408 0.0028,-2.985787 z"
+ style="fill:#a4572e;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.55274624px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+ <path
+ sodipodi:nodetypes="ccccccccscccscccccccccccccccccccccccscc"
+ style="fill:#df773f;fill-opacity:1;stroke-width:0.55274624"
+ inkscape:connector-curvature="0"
+ d="m 52.679499,35.067008 c -3.689428,6.012324 -6.881533,11.218372 -7.047487,11.56665 -0.366957,0.775384 -0.158869,1.256648 0.863255,2.055403 1.002036,0.756513 9.643605,4.615299 10.546292,4.683432 0.346753,0.032 0.835217,-0.117356 1.077926,-0.325992 0.501897,-0.404396 14.464121,-24.862916 14.712078,-25.757849 0.210826,-0.711518 -0.463445,-1.955394 -1.2682,-2.31875 -0.725926,-0.328305 -10.122594,-2.201467 -10.585294,-2.085086 -0.189097,0.0381 -0.613698,0.343578 -0.946586,0.667618 -0.332889,0.324039 -3.633192,5.498644 -7.351984,11.514574 z m 8.376926,-8.748631 c 0.754864,-0.286368 1.442143,0.0914 1.328701,0.746251 -0.150564,0.838271 -1.544893,1.501191 -2.138386,1.037394 -0.313232,-0.244783 -0.304379,-0.901711 -0.02454,-1.293768 0.103068,-0.131885 0.479735,-0.34205 0.834241,-0.489877 z m 1.992989,3.682537 c 1.294319,-0.26311 1.377062,1.262007 0.06562,1.750792 -0.725494,0.282765 -1.119628,0.10753 -1.211769,-0.522105 -0.06636,-0.662604 0.301561,-1.065471 1.14606,-1.228683 z m 1.765789,3.531536 c 0.416848,-0.125661 0.616751,-0.07566 0.816109,0.212907 0.545016,0.797667 -0.03528,1.778085 -1.112655,1.865526 -0.574501,0.05556 -0.732155,-0.01454 -0.896463,-0.381914 -0.248269,-0.565767 0.388691,-1.448798 1.193009,-1.696519 z m -10.65429,4.497903 c 2.509912,0.400097 -1.238185,3.740816 -1.311465,1.338407 0.0089,-0.656928 0.619492,-1.268431 1.311465,-1.338407 z m -2.931192,7.454582 c -0.581269,0.607902 -1.339192,0.626345 -1.695654,0.02915 -0.447742,-3.082292 3.36677,-1.882508 1.695654,-0.02915 z m 8.254404,-5.737587 c 1.077379,-0.08745 1.436895,0.777689 0.715432,1.700896 -2.149011,1.826887 -2.569766,-1.422834 -0.715432,-1.700896 z m -3.505457,5.810892 c 0.789365,-0.126643 1.066023,0.06301 1.159689,0.826599 0.154915,1.262873 -1.625363,2.181813 -2.384694,1.216669 -0.530602,-0.680191 0.200691,-1.887809 1.225005,-2.043268 z"
+ id="objDomino_6-6_matblack_p0001-4" />
+ <path
+ sodipodi:nodetypes="cssssscsssccscccsssscccsssssssscscssssssccccssssscscccsssssscccccssssccsccssscssscscccc"
+ inkscape:connector-curvature="0"
+ id="objDomino_6-6_matblack_p0001-0-5"
+ d="m 60.846833,22.994702 c -0.171188,0.03539 -0.317502,0.131687 -0.498071,0.259833 -0.181771,0.128998 -0.377607,0.292209 -0.55255,0.462502 -0.08027,0.07813 -0.153726,0.183851 -0.284975,0.370789 -0.131249,0.18694 -0.302382,0.440354 -0.510148,0.753616 -0.415541,0.62652 -0.976284,1.492976 -1.642459,2.53668 -1.332341,2.087411 -3.087241,4.88552 -4.947096,7.894228 -1.844723,3.006181 -3.565257,5.811139 -4.845418,7.908077 -0.640078,1.048467 -1.170105,1.92006 -1.550764,2.551728 -0.190328,0.315835 -0.343694,0.571398 -0.454728,0.759949 -0.111034,0.18855 -0.173839,0.296797 -0.20735,0.367118 l -7.74e-4,8.85e-4 c -0.197487,0.41729 -0.252258,0.815551 -0.09274,1.19325 0.159523,0.377702 0.495658,0.713912 1.017592,1.121789 l 0.0018,0.0017 0.0018,7.74e-4 c 0.298719,0.225529 1.010432,0.592558 1.978718,1.063293 0.968298,0.470729 2.172157,1.026212 3.373222,1.560913 1.201067,0.534701 2.398674,1.048135 3.355166,1.432808 0.478241,0.192334 0.896364,0.352493 1.226175,0.467812 0.329459,0.115197 0.549235,0.187615 0.724767,0.200982 1.85e-4,1.5e-5 4.27e-4,-3.6e-5 8.29e-4,-3e-5 0.423778,0.03813 0.919101,-0.109103 1.230523,-0.375201 0.06767,-0.05528 0.07995,-0.08609 0.123386,-0.147491 0.04424,-0.06253 0.09901,-0.144554 0.164913,-0.246835 0.131818,-0.204559 0.308697,-0.48892 0.524391,-0.844438 0.431392,-0.711044 1.018788,-1.70373 1.710808,-2.886188 1.384041,-2.364913 3.184751,-5.488784 4.977182,-8.627802 1.792426,-3.139023 3.576428,-6.293502 4.928674,-8.71969 0.676123,-1.213098 1.244027,-2.244168 1.651427,-3.001083 0.203699,-0.37846 0.367501,-0.687996 0.484872,-0.919089 0.116953,-0.230263 0.181936,-0.350697 0.215289,-0.47026 0.131913,-0.447536 -0.01089,-0.97346 -0.271195,-1.450887 -0.260678,-0.478027 -0.64925,-0.911501 -1.114647,-1.12163 -0.134883,-0.061 -0.34903,-0.117725 -0.679613,-0.200957 -0.330583,-0.08324 -0.76028,-0.18337 -1.256606,-0.293617 -0.992655,-0.220494 -2.251568,-0.482438 -3.501764,-0.730091 -1.250198,-0.247652 -2.491593,-0.480911 -3.451861,-0.645786 -0.480134,-0.08244 -0.889518,-0.14743 -1.196759,-0.188771 -0.153618,-0.02067 -0.281723,-0.03579 -0.382887,-0.04372 -0.09852,-0.0077 -0.150917,-0.01846 -0.248998,0.0049 z m 0.09794,0.415345 c -0.04552,0.01145 0.03047,-2.83e-4 0.118139,0.0066 0.08767,0.0069 0.209499,0.02038 0.358518,0.04043 0.298043,0.0401 0.704422,0.104879 1.181635,0.186815 0.954425,0.163871 2.194229,0.397353 3.441781,0.64448 1.24755,0.24713 2.502941,0.507723 3.490784,0.727145 0.493925,0.109713 0.921578,0.209083 1.245632,0.290674 0.32405,0.08159 0.561869,0.154887 0.608464,0.175963 0.339358,0.153221 0.689667,0.523896 0.914671,0.936565 0.225003,0.412675 0.314077,0.863263 0.235961,1.126907 l 6.3e-5,0.0017 -7.74e-4,0.0018 c 0.0023,-0.0081 -0.07086,0.167378 -0.185498,0.393079 -0.114635,0.225705 -0.276574,0.532922 -0.479367,0.909691 -0.40558,0.753535 -0.973555,1.78392 -1.649104,2.995981 -1.351094,2.424118 -3.134458,5.577395 -4.926322,8.715422 -1.791858,3.13803 -3.592045,6.260776 -4.974824,8.623541 -0.691391,1.181377 -1.278479,2.172781 -1.707683,2.880218 -0.214599,0.353714 -0.390078,0.636422 -0.518047,0.83501 -0.06453,0.101117 -0.134661,0.198548 -0.202354,0.297573 -0.321881,0.31618 -0.547982,0.360086 -0.92137,0.277851 l -0.0017,6.2e-5 0.09129,0.01234 c -0.05005,-0.0038 -0.39042,-0.07959 -0.709893,-0.19129 -0.319471,-0.111705 -0.732194,-0.270169 -1.20669,-0.461001 C 54.199084,52.455908 53.00394,51.944028 51.806523,51.410949 50.609106,50.877874 49.408941,50.323918 48.446906,49.85623 47.485194,49.388698 46.74177,48.98918 46.539175,48.836335 l -8.29e-4,3e-5 c -0.497625,-0.389345 -0.776177,-0.693617 -0.884199,-0.949383 -0.108213,-0.256218 -0.08358,-0.485976 0.08544,-0.843467 l -3.1e-5,-8.29e-4 c 0.0082,-0.01712 0.08069,-0.147088 0.190198,-0.333049 0.109712,-0.186301 0.262427,-0.441365 0.452345,-0.756513 0.379835,-0.630303 0.909315,-1.501046 1.549183,-2.549166 1.279644,-2.096084 3.0001,-4.900488 4.844645,-7.906376 1.858937,-3.007227 3.613211,-5.804212 4.94394,-7.889095 0.665364,-1.042442 1.224585,-1.906971 1.637691,-2.529819 0.206554,-0.311427 0.376321,-0.562615 0.503802,-0.744185 0.12748,-0.18157 0.230683,-0.308347 0.233639,-0.311221 0.157946,-0.153746 0.340406,-0.305388 0.501433,-0.419664 0.161023,-0.114275 0.321928,-0.187979 0.338355,-0.19129 l 0.005,-9.95e-4 0.005,-9.95e-4 z"
+ style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#94441a;fill-opacity:1;fill-rule:nonzero;stroke:#94441a;stroke-width:0.42783314;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ inkscape:connector-curvature="0"
+ id="path4964-7"
+ d="m 54.162878,34.722723 c 1.251582,0.05525 3.986082,1.017229 4.53286,1.298527 2.181054,1.073456 5.10109,1.844176 6.899006,2.793226 -0.08313,0.364692 -0.05785,0.243839 -0.303594,0.353702 -0.649402,-0.214416 -3.948298,-1.41482 -4.573303,-1.68553 -2.178817,-0.755427 -4.506409,-1.662448 -6.765813,-2.324381 -0.141945,-0.07016 0.07247,-0.29266 0.210844,-0.435544 z"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#94441a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:3.31647754;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ </g>
</g>
</svg>
diff --git a/src/activities/roman_numerals/ActivityInfo.qml b/src/activities/roman_numerals/ActivityInfo.qml
index a6f9df4af..4bb6ae6e8 100644
--- a/src/activities/roman_numerals/ActivityInfo.qml
+++ b/src/activities/roman_numerals/ActivityInfo.qml
@@ -1,40 +1,44 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2016 Bruno Coudoin < bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "roman_numerals/RomanNumerals.qml"
difficulty: 4
icon: "roman_numerals/roman_numerals.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: true
//: Activity title
title: qsTr("Roman numerals")
//: Help title
description: ""
//intro: "Learn and practice roman to arabic numerals conversion"
//: Help goal
goal: ""
//: Help prerequisite
prerequisite: ""
//: Help manual
- manual: qsTr("A Roman numeral is the name for a number when it is written in the way the Romans used to write numbers. Roman numerals are not used very often today in the west. They are used to write the names of kings and queens, or popes. For example: Queen Elizabeth II. They may be used to write the year a book or movie was made.")
+ manual: qsTr("A Roman numeral is the name for a number when it is written in the way the Romans used to write numbers. Roman numerals are not used very often today in the west. They are used to write the names of kings and queens, or popes. For example: Queen Elizabeth II. They may be used to write the year a book or movie was made.\n
+ The building of the roman numbers is made up by an agglutination of numbers (the thousands, joined with the hundreds, joined with the tens, joined with the units → just like the arab decimal system). This agglutination of numbers is interpreted as the sum of these particular numbers (again → just like the arab decimal system: you add up thousands+hundreds+tens+units, and you write the respective figures combined).\n
+ Examples:\n
+ 2394: we got a sum of 2000 (MM), 300 (CCC), 90 (XC) and 4 units (IV), so we write this combined: MMCCCXCIV\n
+ MMMCMXLIX: we got first thousands (MMM=3000), then we got hundreds (CM=1000–100=900), then we got tens (XL=50–10=40), and at last we got units (IX=10–1=9), so we write this in the decimal system: 3949.")
credit: ""
section: "math"
createdInVersion: 7000
}
diff --git a/src/activities/roman_numerals/RomanNumerals.qml b/src/activities/roman_numerals/RomanNumerals.qml
index 879480116..0470096b7 100644
--- a/src/activities/roman_numerals/RomanNumerals.qml
+++ b/src/activities/roman_numerals/RomanNumerals.qml
@@ -1,530 +1,530 @@
/* GCompris - roman_numerals.qml
*
* Copyright (C) 2016 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
ActivityBase {
id: activity
onStart: focus = true
onStop: {}
pageComponent: Image {
id: background
source: items.toArabic ?
"qrc:/gcompris/src/activities/roman_numerals/resource/arcs.svg" :
"qrc:/gcompris/src/activities/roman_numerals/resource/torrazzo-crema.svg"
fillMode: Image.PreserveAspectCrop
sourceSize.width: Math.max(parent.width, parent.height)
signal start
signal stop
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property alias background: background
property alias bar: bar
property alias bonus: bonus
property alias score: score
property alias textInput: textInput
property bool toArabic: dataset[currentLevel].toArabic
property string questionText: dataset[currentLevel].question
property string instruction: dataset[currentLevel].instruction
property string questionValue
property int currentLevel: 0
property int numberOfLevel: dataset.length
property var dataset: [
{
values: ['I', 'V', 'X', 'L', 'C', 'D', 'M'],
- instruction: qsTr("Roman numerals, are based on seven symbols: \nI = 1, V = 5\nX = 10, L = 50\nC = 100, D = 500\nM = 1000"),
+ instruction: qsTr("The roman numbers are all built out of these 7 numbers:\nI and V (units, 1 and 5)\nX and L (tens, 10 and 50)\nC and D (hundreds, 100 and 500)\n and M (1000).\n An interesting observation here is that the roman numeric system lacks the number 0."),
question: qsTr("Convert the roman number %1 in arabic."),
toArabic: true
},
{
values: [1, 5, 10, 50, 100, 500, 1000],
- instruction: qsTr("Roman numerals, are based on seven symbols: \nI = 1, V = 5\nX = 10, L = 50\nC = 100, D = 500\nM = 1000"),
+ instruction: qsTr("The roman numbers are all built out of these 7 numbers:\nI and V (units, 1 and 5)\nX and L (tens, 10 and 50)\nC and D (hundreds, 100 and 500)\n and M (1000).\n An interesting observation here is that the roman numeric system lacks the number 0."),
question: qsTr("Convert the arabic number %1 in roman."),
toArabic: false
},
{
- values: ['II', 'III', 'VI', 'XX', 'XXII', 'XXX', 'LX', 'CC', 'CCL', 'MM', 'CLX', 'DCCLI', 'CCCLXVI'],
- instruction: qsTr("Several symbols create a larger number like:\nII = 2\nXX = 20\nXI = 11"),
+ values: ['II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX'],
+ instruction: qsTr("All the units except 4 and 9 are built using sums of I and V:\nI, II, III, V, VI, VII, VIII.\n The 4 and the 9 units are built using differences:\nIV (5 – 1) and IX (10 – 1)"),
question: qsTr("Convert the roman number %1 in arabic."),
toArabic: true
},
{
- values: [2, 3, 6, 20, 22, 30, 60, 200, 250, 2000, 160, 651, 361],
- instruction: qsTr("Several symbols create a larger number like:\nII = 2\nXX = 20\nXI = 11"),
+ values: [2, 3, 4, 5, 6, 7, 8, 9],
+ instruction: qsTr("All the units except 4 and 9 are built using sums of I and V:\nI, II, III, V, VI, VII, VIII.\n The 4 and the 9 units are built using differences:\nIV (5 – 1) and IX (10 – 1)"),
question: qsTr("Convert the arabic number %1 in roman."),
toArabic: false
},
{
- values: ['IV', 'IX', 'XL', 'XC', 'CD', 'CM'],
- instruction: qsTr("If a lower value symbol is before a higher value one, it is subtracted. Otherwise it is added. So:\n'IV' is '4'\n'VI' is '6'\n'IX' is '9'"),
+ values: ['XX', 'XXX', 'XL', 'LX', 'LXX', 'LXXX', 'XC'],
+ instruction: qsTr("All the tens except 40 and 90 are built using sums of X and L:\nX, XX, XXX, L, LX, LXX, LXXX.\nThe 40 and the 90 tens are built using differences:\nXL (10 taken from 50) and XC (10 taken from 100)\n "),
question: qsTr("Convert the roman number %1 in arabic."),
toArabic: true
},
{
- values: [4, 9, 40, 90, 400, 900],
- instruction: qsTr("If a lower value symbol is before a higher value one, it is subtracted. Otherwise it is added. So:\n'IV' is '4'\n'VI' is '6'\n'IX' is '9'"),
+ values: [20, 30, 40, 60, 70, 80, 90],
+ instruction: qsTr("All the tens except 40 and 90 are built using sums of X and L:\nX, XX, XXX, L, LX, LXX, LXXX.\nThe 40 and the 90 tens are built using differences:\nXL (10 taken from 50) and XC (10 taken from 100)\n "),
question: qsTr("Convert the arabic number %1 in roman."),
toArabic: false
},
{
- values: ['VIII', 'LXXX', 'CCCCLXXX', 'DCCC', 'MCCC'],
- instruction: qsTr("Only one number is subtracted, not two. So 8 is always VIII and never IIX."),
+ values: ['CC', 'CCC', 'CD', 'DC', 'DCC', 'DCCC', 'CM', ],
+ instruction: qsTr("All the hundreds except 400 and 900 are built using sums of C and D:\nC, CC, CCC, D, DC, DCC, DCCC.\nThe 400 and the 900 hundreds are built using differences:\nCD (100 taken from 500) and CM (100 taken from 1000)"),
question: qsTr("Convert the roman number %1 in arabic."),
toArabic: true
},
{
- values: [8, 70, 480, 800, 1300],
- instruction: qsTr("Only one number is subtracted, not two. So 8 is always VIII and never IIX."),
+ values: [200, 300, 400, 600, 700, 800, 900],
+ instruction: qsTr("All the hundreds except 400 and 900 are built using sums of C and D:\nC, CC, CCC, D, DC, DCC, DCCC.\nThe 400 and the 900 hundreds are built using differences:\nCD (100 taken from 500) and CM (100 taken from 1000)"),
question: qsTr("Convert the arabic number %1 in roman."),
toArabic: false
},
{
- values: ['XLIX', 'CMXC', 'XCV', 'XLVIII', 'CMXCIX', 'XLVI', 'CXCII', 'CDLXXV'],
- instruction: qsTr("Proper form is to subtract only a value with the next lower power of 10. Thus, 900 is written CM, but 990 would not be XM - properly, it is CM for the 900 portion and XC for the 90 portion, or CMXC. Similarly, 999 would not be IM but rather CMXCIX - CM for the 900 portion, XC for the 90 portion, and IX for the 9 portion. Only values starting in 1's are ever used to subtract; 45 is properly XLV, not VL."),
+ values: ['MM', 'MMM'],
+ instruction: qsTr("Sums of M are used for building thousands: M, MM, MMM.\nNotice that you cannot join more than three identical symbols. The first implication of this rule is that you cannot use just sums for building all possible units, tens or hundreds, you must use differences too. On the other hand, it limits the maximum roman number to 3999 (MMMCMXCIX).\n"),
question: qsTr("Convert the roman number %1 in arabic."),
toArabic: true
},
{
- values: [48, 991, 96, 49, 998, 47, 193, 472, 1092],
- instruction: qsTr("Proper form is to subtract only a value with the next lower power of 10. Thus, 900 is written CM, but 990 would not be XM - properly, it is CM for the 900 portion and XC for the 90 portion, or CMXC. Similarly, 999 would not be IM but rather CMXCIX - CM for the 900 portion, XC for the 90 portion, and IX for the 9 portion. Only values starting in 1's are ever used to subtract; 45 is properly XLV, not VL."),
+ values: [2000, 3000],
+ instruction: qsTr("Sums of M are used for building thousands: M, MM, MMM.\nNotice that you cannot join more than three identical symbols. The first implication of this rule is that you cannot use just sums for building all possible units, tens or hundreds, you must use differences too. On the other hand, it limits the maximum roman number to 3999 (MMMCMXCIX).\n"),
question: qsTr("Convert the arabic number %1 in roman."),
toArabic: false
},
{
values: ['_random_', 50 /* up to this number */ , 10 /* sublevels */],
- instruction: qsTr("Now you know the rules, you can read and write any numbers in roman numerals."),
+ instruction: qsTr("Now you know the rules, you can read and write numbers in roman numerals."),
question: qsTr("Convert the arabic number %1 in roman."),
toArabic: false
},
{
values: ['_random_', 100, 10],
instruction: '',
question: qsTr("Convert the arabic number %1 in roman."),
toArabic: false
},
{
values: ['_random_', 500, 10],
instruction: '',
question: qsTr("Convert the arabic number %1 in roman."),
toArabic: false
},
{
values: ['_random_', 1000, 10],
instruction: '',
question: qsTr("Convert the arabic number %1 in roman."),
toArabic: false
}
]
onQuestionValueChanged: {
textInput.text = ''
romanConverter.arabic = 0
if(toArabic)
keyboard.populateArabic()
else
keyboard.populateRoman()
}
function start() {
if (!ApplicationInfo.isMobile)
textInput.forceActiveFocus();
items.currentLevel = 0
initLevel()
}
function initLevel() {
score.currentSubLevel = 1
initSubLevel()
}
function initSubLevel() {
- if(dataset[currentLevel].values[0] == '_random_') {
+ if(dataset[currentLevel].values[0] === '_random_') {
questionValue = Math.round(Math.random() * dataset[currentLevel].values[1] + 1)
score.numberOfSubLevels = dataset[currentLevel].values[2]
} else {
questionValue = dataset[currentLevel].values[score.currentSubLevel - 1]
score.numberOfSubLevels = dataset[currentLevel].values.length
}
}
function nextLevel() {
if(numberOfLevel - 1 == currentLevel ) {
currentLevel = 0
} else {
currentLevel++
}
initLevel();
}
function previousLevel() {
if(currentLevel == 0) {
currentLevel = numberOfLevel - 1
} else {
currentLevel--
}
initLevel();
}
function nextSubLevel() {
if(++score.currentSubLevel > score.numberOfSubLevels) {
nextLevel()
} else {
initSubLevel();
}
}
property bool isChecking: false
function check() {
if(isChecking) {
return
}
isChecking = true
if(feedback.value == items.questionValue) {
bonus.good('tux')
} else {
bonus.bad('tux')
}
}
}
onStart: {
items.start()
}
onStop: { }
Keys.onPressed: {
if ((event.key === Qt.Key_Enter) || (event.key === Qt.Key_Return)) {
items.check()
}
}
QtObject {
id: romanConverter
property int arabic
property string roman
// conversion code copied from:
// http://blog.stevenlevithan.com/archives/javascript-roman-numeral-converter
function arabic2Roman(num) {
if (!+num)
return '';
var digits = String(+num).split(""),
key = ["","C","CC","CCC","CD","D","DC","DCC","DCCC","CM",
"","X","XX","XXX","XL","L","LX","LXX","LXXX","XC",
"","I","II","III","IV","V","VI","VII","VIII","IX"],
roman = "",
i = 3;
while (i--)
roman = (key[+digits.pop() + (i * 10)] || "") + roman;
return new Array(+digits.join("") + 1).join("M") + roman;
}
function roman2Arabic(str) {
var str = str.toUpperCase(),
validator = /^M*(?:D?C{0,3}|C[MD])(?:L?X{0,3}|X[CL])(?:V?I{0,3}|I[XV])$/,
token = /[MDLV]|C[MD]?|X[CL]?|I[XV]?/g,
key = {M:1000,CM:900,D:500,CD:400,C:100,XC:90,L:50,XL:40,X:10,IX:9,V:5,IV:4,I:1},
num = 0, m;
if (!(str && validator.test(str)))
return false;
while (m = token.exec(str))
num += key[m[0]];
return num;
}
onArabicChanged: roman = arabic2Roman(arabic)
onRomanChanged: arabic = roman2Arabic(roman)
}
Column {
id: column
anchors.fill: parent
anchors.topMargin: 10
GCText {
id: questionLabel
anchors.horizontalCenter: parent.horizontalCenter
wrapMode: TextEdit.WordWrap
text: items.questionValue ? items.questionText.arg(items.questionValue) : ''
color: 'white'
width: parent.width * 0.9
horizontalAlignment: Text.AlignHCenter
Rectangle {
z: -1
border.color: 'black'
border.width: 1
anchors.centerIn: parent
width: parent.width * 1.1
height: parent.height
opacity: 0.8
gradient: Gradient {
GradientStop { position: 0.0; color: "#000" }
GradientStop { position: 0.9; color: "#666" }
GradientStop { position: 1.0; color: "#AAA" }
}
radius: 10
}
}
Item { // Just a margin
width: 1
height: 5 * ApplicationInfo.ratio
}
TextInput {
id: textInput
x: parent.width / 2
width: 60 * ApplicationInfo.ratio
color: 'white'
text: ''
maximumLength: items.toArabic ?
('' + romanConverter.roman2Arabic(items.questionValue)).length + 1 :
romanConverter.arabic2Roman(items.questionValue).length + 1
horizontalAlignment: Text.AlignHCenter
verticalAlignment: TextInput.AlignVCenter
anchors.horizontalCenter: parent.horizontalCenter
font.pointSize: questionLabel.pointSize
font.weight: Font.DemiBold
font.family: GCSingletonFontLoader.fontLoader.name
font.capitalization: ApplicationSettings.fontCapitalization
font.letterSpacing: ApplicationSettings.fontLetterSpacing
cursorVisible: true
validator: RegExpValidator{regExp: items.toArabic ?
/[0-9]+/ :
/[ivxlcdmIVXLCDM]*/}
onTextChanged: if(text) {
text = text.toUpperCase();
if(items.toArabic)
romanConverter.arabic = parseInt(text)
else
romanConverter.roman = text
}
Rectangle {
z: -1
opacity: 0.8
gradient: Gradient {
GradientStop { position: 0.0; color: "#000" }
GradientStop { position: 0.9; color: "#666" }
GradientStop { position: 1.0; color: "#AAA" }
}
radius: 10
border.color: 'black'
border.width: 1
anchors.horizontalCenter: parent.horizontalCenter
width: column.width * 0.7
height: parent.height
}
function appendText(car) {
if(car === keyboard.backspace) {
if(text && cursorPosition > 0) {
var oldPos = cursorPosition
text = text.substring(0, cursorPosition - 1) + text.substring(cursorPosition)
cursorPosition = oldPos - 1
}
return
}
var oldPos = cursorPosition
text = text.substring(0, cursorPosition) + car + text.substring(cursorPosition)
cursorPosition = oldPos + 1
}
}
Item { // Just a margin
width: 1
height: 5 * ApplicationInfo.ratio
}
GCText {
id: feedback
anchors.horizontalCenter: parent.horizontalCenter
text: items.toArabic ?
qsTr("Roman value: %1").arg(value) :
qsTr('Arabic value: %1').arg(value)
color: 'white'
Rectangle {
z: -1
opacity: 0.8
gradient: Gradient {
GradientStop { position: 0.0; color: "#000" }
GradientStop { position: 0.9; color: "#666" }
GradientStop { position: 1.0; color: "#AAA" }
}
radius: 10
border.color: 'black'
border.width: 1
anchors.centerIn: parent
width: parent.width * 1.1
height: parent.height
}
property string value: items.toArabic ?
romanConverter.roman :
romanConverter.arabic ? romanConverter.arabic : ''
}
Item { // Just a margin
width: 1
height: 5 * ApplicationInfo.ratio
}
Rectangle {
color: "transparent"
width: parent.width
height: (background.height - (y + bar.height + okButton.height + keyboard.height) * 1.1 )
Flickable {
width: parent.width
height: parent.height
contentWidth: parent.width
contentHeight: instructionContainer.height
anchors.fill: parent
flickableDirection: Flickable.VerticalFlick
clip: true
GCText {
id: instruction
visible: items.instruction != ''
wrapMode: TextEdit.WordWrap
fontSize: tinySize
anchors.horizontalCenter: parent.horizontalCenter
width: parent.width * 0.95
text: items.instruction
horizontalAlignment: Text.AlignHCenter
color: 'white'
Rectangle {
id: instructionContainer
z: -1
opacity: 0.8
gradient: Gradient {
GradientStop { position: 0.0; color: "#000" }
GradientStop { position: 0.9; color: "#666" }
GradientStop { position: 1.0; color: "#AAA" }
}
radius: 10
border.color: 'black'
border.width: 1
anchors.centerIn: parent
width: parent.width
height: parent.contentHeight
}
}
}
}
}
Score {
id: score
anchors.bottom: bar.top
currentSubLevel: 0
numberOfSubLevels: 1
}
DialogHelp {
id: dialogHelp
onClose: home()
}
VirtualKeyboard {
id: keyboard
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
function populateArabic() {
layout = [ [
{ label: "0" },
{ label: "1" },
{ label: "2" },
{ label: "3" },
{ label: "4" },
{ label: "5" },
{ label: "6" },
{ label: "7" },
{ label: "8" },
{ label: "9" },
{ label: keyboard.backspace }
] ]
}
function populateRoman() {
layout = [ [
{ label: "I" },
{ label: "V" },
{ label: "X" },
{ label: "L" },
{ label: "C" },
{ label: "D" },
{ label: "M" },
{ label: keyboard.backspace }
] ]
}
onKeypress: textInput.appendText(text)
onError: console.log("VirtualKeyboard error: " + msg);
}
Bar {
id: bar
anchors.bottom: keyboard.top
content: BarEnumContent { value: help | home | level | hint }
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: items.previousLevel()
onNextLevelClicked: items.nextLevel()
onHomeClicked: activity.home()
level: items.currentLevel + 1
onHintClicked: feedback.visible = !feedback.visible
}
BarButton {
id: okButton
source: "qrc:/gcompris/src/core/resource/bar_ok.svg";
sourceSize.width: 60 * ApplicationInfo.ratio
visible: true
anchors {
verticalCenter: score.verticalCenter
right: score.left
rightMargin: 10 * ApplicationInfo.ratio
bottomMargin: 10 * ApplicationInfo.ratio
}
onClicked: items.check()
}
Bonus {
id: bonus
Component.onCompleted: win.connect(items.nextSubLevel)
onWin: items.isChecking = false
onLoose: items.isChecking = false
}
}
}
diff --git a/src/activities/scalesboard/ActivityInfo.qml b/src/activities/scalesboard/ActivityInfo.qml
index f89113696..dfd5f6954 100644
--- a/src/activities/scalesboard/ActivityInfo.qml
+++ b/src/activities/scalesboard/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "scalesboard/ScaleNumber.qml"
difficulty: 2
icon: "scalesboard/scalesboard.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
//: Activity title
title: qsTr("Balance the scales properly")
//: Help title
description: qsTr("Drag and Drop weights to balance the scales")
// intro: "Drag the weights up to balance the scales."
//: Help goal
goal: qsTr("Mental calculation, arithmetic equality")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("To balance the scales, move the weights to the left or the right side (on higher levels). The weights can be arranged in any order.")
credit:""
section: "math"
createdInVersion: 0
}
diff --git a/src/activities/scalesboard/MasseArea.qml b/src/activities/scalesboard/MasseArea.qml
index 57f5f50db..52d7ef336 100644
--- a/src/activities/scalesboard/MasseArea.qml
+++ b/src/activities/scalesboard/MasseArea.qml
@@ -1,285 +1,285 @@
/* GCompris - MasseArea.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import QtGraphicalEffects 1.0
import "../../core"
import "scalesboard.js" as Activity
Rectangle {
id: masseArea
height: itemHeight
color: dropArea.containsDrag ? "#33333333" : "#00000000"
border.width: 2
border.color: dropArea.containsDrag ? "#33666666" : "#00000000"
property bool dropEnabled: true
property bool dropEnabledForThisLevel: true
property int nbColumns
property int itemWidth: (width - masseFlow.spacing * nbColumns) / nbColumns
property int itemHeight: itemWidth * 1.2
property Item masseAreaCenter
property Item masseAreaLeft
property Item masseAreaRight
property alias masseModel: masseModel
property alias dropArea: dropArea
property int weight: 0
property GCSfx audioEffects
function init() {
weight = 0
masseModel.clear()
}
function removeWeight(value) {
weight -= value
}
function removeMasse(masseArea, index, weight) {
masseArea.removeWeight(weight)
masseArea.masseModel.remove(index)
}
/* weight is the absolute weight
* text is the text being displayed on the masseAreaCenter
*/
function addMasse(img, weight, text, index, dragEnabled) {
masseModel.append( {
img: img,
weight: weight,
text: text,
masseIndex: index,
opacity: 1.0,
dragEnabled: dragEnabled
} )
masseArea.weight += weight
}
function setAllZonesDropEnabled(enabled) {
masseAreaCenter.dropEnabled = enabled
masseAreaLeft.dropEnabled = enabled
masseAreaRight.dropEnabled = enabled
}
function showMasseInMasseArea(index) {
masseAreaCenter.masseModel.get(index).opacity = 1.0
}
function hideMasseInMasseArea(index) {
masseAreaCenter.masseModel.get(index).opacity = 0.0
}
ListModel {
id: masseModel
function contains(masseIndex) {
for(var i = 0; i < masseModel.count; i++) {
if(masseModel.get(i).masseIndex == masseIndex) {
return masseModel.get(i).opacity == 1
}
}
return false;
}
}
DropArea {
id: dropArea
anchors {
left: parent.left
right: parent.right
verticalCenter: parent.verticalCenter
}
height: parent.height * 2
enabled: dropEnabledForThisLevel && dropEnabled
}
Flow {
id: masseFlow
anchors.topMargin: 4
anchors.bottomMargin: 4
anchors.fill: parent
spacing: 10
flow: Flow.TopToBottom
add: Transition {
NumberAnimation {
properties: "x"
from: parent.width * 0.05
easing.type: Easing.InOutQuad
}
}
move: Transition {
NumberAnimation {
properties: "x,y"
easing.type: Easing.InOutQuad
}
}
Repeater {
id: answer
model: masseModel
Image {
source: Activity.url + img
sourceSize.height: masseArea.itemHeight
height: masseArea.itemHeight
opacity: model.opacity
property string img: model.img
property int masseIndex: model.masseIndex
property int modelIndex: index
property int weight: model.weight
property string text: model.text
property int masseOriginX
property int masseOriginY
property int originX
property int originY
property Item currentMasseArea: masseArea
Drag.active: dragArea.drag.active
Drag.hotSpot.x: width / 2
Drag.hotSpot.y: height / 2
function initDrag() {
originX = x
originY = y
if(currentMasseArea == masseArea) {
masseOriginX = x
masseOriginY = y
}
z = 111
}
function replace() {
x = originX
y = originY
}
function replaceInMasse() {
x = masseOriginX
y = masseOriginY
}
onOpacityChanged: opacity == 1.0 ? currentMasseArea = masseAreaCenter : null
MouseArea {
id: dragArea
anchors.fill: parent
drag.target: parent
enabled: model.dragEnabled
onPressed: {
if(masseModel.contains(parent.masseIndex)) {
parent.initDrag()
}
else {
setAllZonesDropEnabled(false)
}
}
function dropOnPlate(masseArea) {
parent.Drag.cancel()
if(parent.currentMasseArea == masseAreaCenter) {
masseArea.hideMasseInMasseArea(parent.masseIndex)
parent.replaceInMasse()
}
masseArea.addMasse(parent.img,
parent.weight,
parent.text,
parent.masseIndex,
/* dragEnabled */ true)
if(parent.currentMasseArea != masseAreaCenter) {
removeMasse(parent.currentMasseArea,
parent.modelIndex, parent.weight)
}
parent.currentMasseArea = masseArea
}
onReleased: {
setAllZonesDropEnabled(true)
if(masseArea.audioEffects)
masseArea.audioEffects.play(Activity.url + 'metal_hit.wav')
if(masseAreaLeft.dropArea.containsDrag &&
parent.currentMasseArea != masseAreaLeft) {
dropOnPlate(masseAreaLeft)
} else if (masseAreaRight.dropArea.containsDrag &&
parent.currentMasseArea != masseAreaRight) {
dropOnPlate(masseAreaRight)
} else if (masseAreaCenter.dropArea.containsDrag &&
parent.dropArea != masseAreaCenter) {
parent.Drag.cancel()
masseAreaCenter.showMasseInMasseArea(parent.masseIndex)
parent.replaceInMasse()
if(parent.currentMasseArea != masseAreaCenter) {
removeMasse(parent.currentMasseArea,
parent.modelIndex, parent.weight)
}
} else {
parent.Drag.cancel()
parent.replace()
}
}
}
GCText {
id: text
anchors.fill: parent
text: model.text.replace(" ", "\n")
color: "white"
fontSizeMode: Text.Fit
minimumPointSize: 10
fontSize: largeSize
font.bold : true
style: Text.Outline
styleColor: "black"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
DropShadow {
anchors.fill: text
cached: false
horizontalOffset: 3
verticalOffset: 3
radius: 8.0
samples: 16
color: "#80000000"
source: text
}
}
}
}
Behavior on y {
NumberAnimation {
duration: 500
easing.type: Easing.InOutQuad
}
}
}
diff --git a/src/activities/scalesboard/Message.qml b/src/activities/scalesboard/Message.qml
index 9dabfa712..34fb72909 100644
--- a/src/activities/scalesboard/Message.qml
+++ b/src/activities/scalesboard/Message.qml
@@ -1,65 +1,65 @@
/* GCompris - Message.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
Item {
id: message
property alias text: messageText.text
property bool displayed: messageText.text != "" ? true : false
Rectangle {
id: messageBg
x: messageText.x - 4
y: messageText.y - 4
width: messageText.width + 8
height: messageText.height + 8
color: "#ddd6e598"
border.color: "black"
border.width: 2
radius: 8
opacity: message.displayed ? 1 : 0
MouseArea {
anchors.fill: parent
onClicked: message.text = ""
}
Behavior on opacity { NumberAnimation { duration: 100 } }
}
GCText {
id: messageText
anchors {
top: parent.top
right: parent.right
left: parent.left
}
color: "black"
fontSize: 18
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
wrapMode: TextEdit.WordWrap
opacity: message.displayed ? 1 : 0
Behavior on opacity { NumberAnimation { duration: 100 } }
}
}
diff --git a/src/activities/scalesboard/Question.qml b/src/activities/scalesboard/Question.qml
index 3eb971fa6..ff06548ee 100644
--- a/src/activities/scalesboard/Question.qml
+++ b/src/activities/scalesboard/Question.qml
@@ -1,71 +1,71 @@
/* GCompris - Question.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
Item {
id: question
property string text
property bool displayed: text != "" ? true : false
property string answer
property string userEntry
Rectangle {
id: questionBg
x: questionText.x - 4
y: questionText.y - 4
width: questionText.width + 8
height: questionText.height + 8
border.color: "black"
border.width: 2
radius: 8
opacity: question.displayed ? 1 : 0
gradient: Gradient {
GradientStop { position: 0.0; color: "#F0FFFFFF" }
GradientStop { position: 0.9; color: "#F0F0F0F0" }
GradientStop { position: 1.0; color: "#F0CECECE" }
}
Behavior on opacity { NumberAnimation { duration: 100 } }
}
GCText {
id: questionText
color: "black"
fontSize: largeSize
width: parent.width
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
wrapMode: TextEdit.WordWrap
opacity: question.displayed ? 1 : 0
text: question.text != "" ? question.text.arg(question.userEntry) : ""
Behavior on opacity { NumberAnimation { duration: 100 } }
}
onUserEntryChanged: {
if(userEntry === question.answer)
bonus.good("flower")
}
}
diff --git a/src/activities/scalesboard/ScaleNumber.qml b/src/activities/scalesboard/ScaleNumber.qml
index c8285b59a..fe7b45411 100644
--- a/src/activities/scalesboard/ScaleNumber.qml
+++ b/src/activities/scalesboard/ScaleNumber.qml
@@ -1,99 +1,99 @@
/* GCompris - Scalesboard.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* miguel DE IZARRA <miguel2i@free.fr> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
Scalesboard {
dataset: [
{
"masses": [[1, "1"], [2, "2"], [2, "2"], [5, "5"], [5, "5"], [10, "10"], [10, "10"]],
"targets": [[3, "3"], [4, "4"], [6, "6"], [7, "7"], [8, "8"], [9, "9"]],
"rightDrop": false
},
{
"masses": [[1, "1"], [2, "2"], [2, "2"], [5, "5"], [5, "5"], [10, "10"], [10, "10"]],
"targets": [[3, "3"], [4, "4"], [6, "6"], [7, "7"], [8, "8"], [9, "9"]],
"rightDrop": false
},
{
"masses": [[1, "1"], [2, "2"], [2, "2"], [5, "5"], [5, "5"], [10, "10"], [10, "10"]],
"targets": [[12, "12"], [13, "13"], [14, "14"], [15, "15"], [16, "16"]],
"rightDrop": false
},
{
"masses": [[2, "2"], [2, "2"], [5, "5"], [5, "5"], [5, "5"]],
"targets": [[8, "8"], [11, "11"], [13, "13"]],
"rightDrop": true,
"message": qsTr("Take care, you can drop weights on both sides of the scale.")
},
{
"masses": [[2, "2"], [5, "5"], [10, "10"], [10, "10"], [12, "12"]],
"targets": [[3, "3"], [8, "8"], [13, "13"]],
"rightDrop": true
},
{
"masses": [[2, "2"], [4, "4"], [7, "7"], [10, "10"], [12, "12"]],
"targets": [[3, "3"], [5, "5"], [8, "8"], [9, "9"]],
"rightDrop": true
},
{
"masses": [[5, "5"], [8, "8"], [9, "9"], [10, "10"], [11, "11"], [12, "12"]],
"targets": [[6, "6"], [7, "7"], [13, "13"], [14, "14"], [15, "15"], [16, "16"],
[17, "17"], [18, "18"]],
"rightDrop": true
},
{
"masses": [[1, "1"], [2, "2"], [2, "2"], [5, "5"], [5, "5"], [10, "10"], [10, "10"]],
"targets": [[3, "3"], [4, "4"], [6, "6"], [7, "7"], [8, "8"], [9, "9"]],
"rightDrop": false,
"message": qsTr("Now you have to guess the weight of the gift."),
"question": qsTr("Enter the weight of the gift: %1")
},
{
"masses": [[2, "2"], [2, "2"], [5, "5"], [5, "5"], [5, "5"]],
"targets": [[8, "8"], [11, "11"], [13, "13"]],
"rightDrop": true,
"message": qsTr("Take care, you can drop weights on both sides of the scale."),
"question": qsTr("Enter the weight of the gift: %1")
},
{
"masses": [[2, "2"], [5, "5"], [10, "10"], [10, "10"], [12, "12"]],
"targets": [[3, "3"], [8, "8"], [13, "13"]],
"rightDrop": true,
"question": qsTr("Enter the weight of the gift: %1")
},
{
"masses": [[2, "2"], [4, "4"], [7, "7"], [10, "10"], [12, "12"]],
"targets": [[3, "3"], [5, "5"], [8, "8"], [9, "9"]],
"rightDrop": true,
"question": qsTr("Enter the weight of the gift: %1")
},
{
"masses": [[5, "5"], [8, "8"], [9, "9"], [10, "10"], [11, "11"], [12, "12"]],
"targets": [[6, "6"], [7, "7"], [13, "13"], [14, "14"], [15, "15"], [16, "16"],
[17, "17"], [18, "18"]],
"rightDrop": true,
"question": qsTr("Enter the weight of the gift: %1")
},
]
}
diff --git a/src/activities/scalesboard/Scalesboard.qml b/src/activities/scalesboard/Scalesboard.qml
index fbb073318..9dbf1cf0b 100644
--- a/src/activities/scalesboard/Scalesboard.qml
+++ b/src/activities/scalesboard/Scalesboard.qml
@@ -1,308 +1,308 @@
/* GCompris - Scalesboard.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* miguel DE IZARRA <miguel2i@free.fr> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "scalesboard.js" as Activity
import "."
ActivityBase {
id: activity
property var dataset
onStart: focus = true
onStop: {}
pageComponent: Image {
id: background
anchors.fill: parent
source: Activity.url + "background.svg"
sourceSize.width: Math.max(parent.width, parent.height)
fillMode: Image.PreserveAspectCrop
signal start
signal stop
property int scaleHeight: items.masseAreaLeft.weight == items.masseAreaRight.weight ? 0 :
items.masseAreaLeft.weight > items.masseAreaRight.weight ? 20 : -20
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property alias background: background
property alias bar: bar
property alias bonus: bonus
property int numberOfSubLevels
property int currentSubLevel
property int giftWeight
property var dataset: activity.dataset
property alias masseAreaCenter: masseAreaCenter
property alias masseAreaLeft: masseAreaLeft
property alias masseAreaRight: masseAreaRight
property alias masseCenterModel: masseAreaCenter.masseModel
property alias masseRightModel: masseAreaRight.masseModel
property alias question: question
property alias numpad: numpad
}
onStart: { Activity.start(items) }
onStop: { Activity.stop() }
property bool vert: background.width > background.height
onScaleHeightChanged: Activity.initCompleted && scaleHeight == 0 && question.hasText == "" ?
bonus.good("flower") :
activity.audioEffects.play('qrc:/gcompris/src/activities/erase/resource/eraser2.wav')
Image {
id: scale
source: Activity.url + "scale.svg"
sourceSize.width: Math.min(parent.width - 10 * ApplicationInfo.ratio,
(parent.height - bar.height - 10 * ApplicationInfo.ratio) * 2)
anchors.centerIn: parent
}
Image {
id: needle
parent: scale
source: Activity.url + "needle.svg"
sourceSize.width: parent.width * 0.75
z: -10
property int angle: - background.scaleHeight * 0.35
anchors {
horizontalCenter: parent.horizontalCenter
verticalCenter: parent.verticalCenter
verticalCenterOffset: - parent.paintedHeight * 0.15
}
transform: Rotation {
origin.x: needle.width / 2
origin.y: needle.height * 0.9
angle: needle.angle
}
Behavior on angle {
NumberAnimation {
duration: 500
easing.type: Easing.InOutQuad
}
}
}
// === The Left plate ===
Image {
id: plateLeft
parent: scale
source: Activity.url + "plate.svg"
sourceSize.width: parent.width * 0.35
z: -1
anchors {
horizontalCenter: parent.horizontalCenter
horizontalCenterOffset: - parent.paintedWidth * 0.3
verticalCenter: parent.verticalCenter
verticalCenterOffset: - parent.paintedHeight * 0.03 + background.scaleHeight
}
Behavior on anchors.verticalCenterOffset {
NumberAnimation {
duration: 500
easing.type: Easing.InOutQuad
}
}
// The Left Drop Area
MasseArea {
id: masseAreaLeft
parent: scale
width: plateLeft.width
anchors {
horizontalCenter: parent.horizontalCenter
horizontalCenterOffset: - parent.paintedWidth * 0.3
verticalCenter: parent.verticalCenter
verticalCenterOffset: - parent.paintedHeight * 0.44 + background.scaleHeight
}
masseAreaCenter: masseAreaCenter
masseAreaLeft: masseAreaLeft
masseAreaRight: masseAreaRight
nbColumns: 3
audioEffects: activity.audioEffects
Behavior on anchors.verticalCenterOffset {
NumberAnimation {
duration: 500
easing.type: Easing.InOutQuad
}
}
}
}
// === The Right plate ===
Image {
id: plateRight
parent: scale
source: Activity.url + "plate.svg"
sourceSize.width: parent.width * 0.35
z: -1
anchors {
horizontalCenter: parent.horizontalCenter
horizontalCenterOffset: parent.paintedWidth * 0.3
verticalCenter: parent.verticalCenter
verticalCenterOffset: - parent.paintedHeight * 0.03 - background.scaleHeight
}
Behavior on anchors.verticalCenterOffset {
NumberAnimation {
duration: 500
easing.type: Easing.InOutQuad
}
}
// The Right Drop Area
MasseArea {
id: masseAreaRight
parent: scale
width: plateRight.width
anchors {
horizontalCenter: parent.horizontalCenter
horizontalCenterOffset: parent.paintedWidth * 0.3
verticalCenter: parent.verticalCenter
verticalCenterOffset: - parent.paintedHeight * 0.44 - background.scaleHeight
}
masseAreaCenter: masseAreaCenter
masseAreaLeft: masseAreaLeft
masseAreaRight: masseAreaRight
nbColumns: 3
dropEnabledForThisLevel: items.dataset[bar.level - 1].rightDrop
audioEffects: activity.audioEffects
Behavior on anchors.verticalCenterOffset {
NumberAnimation {
duration: 500
easing.type: Easing.InOutQuad
}
}
}
}
// === The Initial Masses List ===
MasseArea {
id: masseAreaCenter
parent: scale
x: parent.width * 0.05
y: parent.height * 0.84 - height
width: parent.width
masseAreaCenter: masseAreaCenter
masseAreaLeft: masseAreaLeft
masseAreaRight: masseAreaRight
nbColumns: masseModel.count
audioEffects: activity.audioEffects
}
Message {
id: message
anchors {
top: parent.top
topMargin: 10
right: parent.right
rightMargin: 10
left: parent.left
leftMargin: 10
}
}
Question {
id: question
parent: scale
anchors.horizontalCenter: parent.horizontalCenter
y: parent.height * 0.45
z: 1000
width: parent.width - y
text: items.dataset[bar.level - 1].question && background.scaleHeight == 0 ?
items.dataset[bar.level - 1].question : ""
answer: items.giftWeight
property bool hasText: items.dataset[bar.level - 1].question ? true : false
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level }
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
onLevelChanged: message.text = items.dataset[bar.level - 1].message ? items.dataset[bar.level - 1].message : ""
}
Score {
id: score
anchors {
bottom: background.vert ? background.bottom : bar.top
right: parent.right
bottomMargin: 10 * ApplicationInfo.ratio
}
numberOfSubLevels: items.numberOfSubLevels
currentSubLevel: items.currentSubLevel
opacity: question.displayed ? 0 : 1
}
NumPad {
id: numpad
onAnswerChanged: question.userEntry = answer
maxDigit: ('' + items.giftWeight).length + 1
opacity: question.displayed ? 1 : 0
columnWidth: 60 * ApplicationInfo.ratio
}
Keys.onPressed: {
if(question.displayed) {
numpad.updateAnswer(event.key, true);
}
}
Keys.onReleased: {
if(question.displayed) {
numpad.updateAnswer(event.key, false);
}
}
Bonus {
id: bonus
Component.onCompleted: win.connect(Activity.nextSubLevel)
}
}
}
diff --git a/src/activities/scalesboard/scalesboard.js b/src/activities/scalesboard/scalesboard.js
index 0705c0296..acd497116 100644
--- a/src/activities/scalesboard/scalesboard.js
+++ b/src/activities/scalesboard/scalesboard.js
@@ -1,97 +1,97 @@
/* GCompris - scalesboard.js
*
* Copyright (C) 2014 Bruno Coudoin
*
* Authors:
* miguel DE IZARRA <miguel2i@free.fr> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
.import "qrc:/gcompris/src/core/core.js" as Core
var url = "qrc:/gcompris/src/activities/scalesboard/resource/"
var currentLevel = 0
var numberOfLevel
var items
var currentTargets = []
var initCompleted = false
function start(items_) {
items = items_
currentLevel = 0
numberOfLevel = items.dataset.length
initLevel()
}
function stop() {
}
function initLevel() {
items.bar.level = currentLevel + 1
currentTargets = Core.shuffle(items.dataset[currentLevel].targets)
items.currentSubLevel = 1
items.numberOfSubLevels = currentTargets.length
displayLevel()
}
function displayLevel()
{
initCompleted = false
items.numpad.answer = ""
items.masseAreaLeft.init()
items.masseAreaRight.init()
items.masseAreaCenter.init()
var data = items.dataset[currentLevel]
for(var i=0; i < data.masses.length; i++)
items.masseAreaCenter.addMasse("masse" + (i % 5 + 1) + ".svg",
data.masses[i][0],
data.masses[i][1],
i,
/* dragEnabled */ true)
items.giftWeight = currentTargets[items.currentSubLevel - 1][0]
items.masseAreaRight.addMasse("gift.svg",
currentTargets[items.currentSubLevel - 1][0],
data.question ? "" : currentTargets[items.currentSubLevel - 1][1],
0,
/* dragEnabled */ false)
initCompleted = true
}
function nextSubLevel() {
if(items.numberOfSubLevels < ++items.currentSubLevel ) {
nextLevel();
}
displayLevel()
}
function nextLevel() {
if(numberOfLevel <= ++currentLevel ) {
currentLevel = 0
}
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
initLevel();
}
diff --git a/src/activities/scalesboard_weight/ActivityInfo.qml b/src/activities/scalesboard_weight/ActivityInfo.qml
index 740f4c167..5979cb629 100644
--- a/src/activities/scalesboard_weight/ActivityInfo.qml
+++ b/src/activities/scalesboard_weight/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "scalesboard_weight/ScalesboardWeight.qml"
difficulty: 4
icon: "scalesboard_weight/scalesboard_weight.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
//: Activity title
title: qsTr("Balance the scales properly")
//: Help title
description: qsTr("Drag and Drop masses to balance the scales and calculate the weight")
// intro: "Drag the weights up to balance the scales."
//: Help goal
goal: qsTr("Mental calculation, arithmetic equality, unit conversion")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("To balance the scales, move the masses to the left or the right side (on higher levels). They can be arranged in any order. Take care of the weight and the unit of the masses, remember that a kilogram (kg) is 1000 grams (g).")
credit: ""
section: "math"
createdInVersion: 0
}
diff --git a/src/activities/scalesboard_weight/ScalesboardWeight.qml b/src/activities/scalesboard_weight/ScalesboardWeight.qml
index 9959c2afb..9136fa6dd 100644
--- a/src/activities/scalesboard_weight/ScalesboardWeight.qml
+++ b/src/activities/scalesboard_weight/ScalesboardWeight.qml
@@ -1,134 +1,134 @@
/* GCompris - Scalesboard.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* miguel DE IZARRA <miguel2i@free.fr> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import "../scalesboard"
Scalesboard {
function g(value) {
/* g == gram */
return qsTr("%1 g").arg(value)
}
function kg(value) {
/* kg == kilogram */
return qsTr("%1 kg").arg(value)
}
dataset: [
{
"masses": [[1, kg(1)], [2, kg(2)], [2, kg(2)], [5, kg(5)],
[5, kg(5)], [10, kg(10)], [10, kg(10)]],
"targets": [[3, kg(3)], [4, kg(4)], [6, kg(6)], [7, kg(7)], [8, kg(8)], [9, kg(9)]],
"rightDrop": false,
"message": qsTr('The "kg" symbol at the end of a number means kilogram.') + " " +
qsTr('The kilogram is a unit of mass, a property which corresponds to the ' +
'common perception of how "heavy" an object is.')
},
{
"masses": [[100, g(100)], [200, g(200)], [200, g(200)], [500, g(500)],
[500, g(500)], [1000, g(1000)], [1000, g(1000)]],
"targets": [[300, g(300)], [400, g(400)], [600, g(600)], [700, g(700)],
[800, g(800)], [900, g(900)]],
"rightDrop": false,
"message": qsTr('The "g" symbol at the end of a number means gram. One kilogram equals 1000 grams')
},
{
"masses": [[100, g(100)], [200, g(200)], [200, g(200)], [500, g(500)],
[500, g(500)], [1000, kg(1)], [1000, kg(1)]],
"targets": [[1200, kg(1.2)], [1300, kg(1.3)], [1400, kg(1.4)],
[1500, kg(1.5)], [1600, kg(1.6)]],
"rightDrop": false,
"message": qsTr('Remember, one kilogram ("kg") equals 1000 grams ("g").')
},
{
"masses": [[200, g(200)], [500, g(500)], [1000, kg(1)], [1000, kg(1)], [1200, kg(1.2)]],
"targets": [[300, g(300)], [800, g(800)], [1300, kg(1.3)]],
"rightDrop": true,
"message": qsTr("Take care, you can drop weights on both sides of the scale.")
},
{
"masses": [[200, g(200)], [400, g(400)], [700, g(700)], [1000, kg(1)], [1200, kg(1.2)]],
"targets": [[300, g(300)], [500, g(500)], [800, g(800)], [900, g(900)]],
"rightDrop": true
},
{
"masses": [[500, g(500)], [800, g(800)], [900, g(900)], [1000, kg(1)],
[1100, kg(1.1)], [1200, kg(1.2)]],
"targets": [[600, g(600)], [700, g(700)], [1300, kg(1.3)], [1400, kg(1.4)],
[1500, kg(1.5)], [1600, kg(1.6)], [1700, kg(1.7)], [1800, kg(1.8)]],
"rightDrop": true
},
{
"masses": [[1, kg(1)], [2, kg(2)], [2, kg(2)], [5, kg(5)],
[5, kg(5)], [1, kg(10)], [1, kg(10)]],
"targets": [[3, kg(3)], [4, kg(4)], [6, kg(6)], [7, kg(7)], [8, kg(8)], [9, kg(9)]],
"rightDrop": false,
"message": qsTr("Now you have to guess the weight of the gift."),
"question": qsTr("Enter the weight of the gift in kilogram: %1")
},
{
"masses": [[100, g(100)], [200, g(200)], [200, g(200)], [500, g(500)],
[500, g(500)], [1000, g(1000)], [1000, g(1000)]],
"targets": [[300, g(300)], [400, g(400)], [600, g(600)], [700, g(700)],
[800, g(800)], [900, g(900)]],
"rightDrop": false,
"question": qsTr("Enter the weight of the gift in gram: %1")
},
{
"masses": [[2, kg(2)], [2, kg(2)], [5, kg(5)], [5, kg(5)], [5, kg(5)]],
"targets": [[8, kg(8)], [11, kg(11)], [13, kg(13)]],
"rightDrop": true,
"message": qsTr("Take care, you can drop weights on both sides of the scale."),
"question": qsTr("Enter the weight of the gift in gram: %1")
},
{
"masses": [[100, g(100)], [200, g(200)], [200, g(200)], [500, g(500)],
[500, g(500)], [1000, kg(1)], [1000, kg(1)]],
"targets": [[1200, kg(1.2)], [1300, kg(1.3)], [1400, kg(1.4)],
[1500, kg(1.5)], [1600, kg(1.6)]],
"rightDrop": false,
- "message": qsTr("Remember, one kilo ('kg') equals 1000 grams ('g')."),
+ "message": qsTr("Remember, one kilogram ('kg') equals 1000 grams ('g')."),
"question": qsTr("Enter the weight of the gift in gram: %1")
},
{
"masses": [[200, g(200)], [500, g(500)], [1000, kg(1)], [1000, kg(1)], [1200, kg(1.2)]],
"targets": [[300, g(300)], [800, g(800)], [1300, kg(1.3)]],
"rightDrop": true,
"question": qsTr("Enter the weight of the gift in gram: %1")
},
{
"masses": [[200, g(200)], [400, g(400)], [700, g(700)], [1000, kg(1)], [1200, kg(1.2)]],
"targets": [[300, g(300)], [500, g(500)], [800, g(800)], [900, g(900)]],
"rightDrop": true,
"question": qsTr("Enter the weight of the gift in gram: %1")
},
{
"masses": [[500, g(500)], [800, g(800)], [900, g(900)], [1000, kg(1)],
[1100, kg(1.1)], [1200, kg(1.2)]],
"targets": [[600, g(600)], [700, g(700)], [1300, kg(1.3)], [1400, kg(1.4)],
[1500, kg(1.5)], [1600, kg(1.6)], [1700, kg(1.7)], [1800, kg(1.8)]],
"rightDrop": true,
"question": qsTr("Enter the weight of the gift in gram: %1")
}
]
}
diff --git a/src/activities/scalesboard_weight_avoirdupois/ActivityInfo.qml b/src/activities/scalesboard_weight_avoirdupois/ActivityInfo.qml
index 035896ddf..a4e63d06b 100644
--- a/src/activities/scalesboard_weight_avoirdupois/ActivityInfo.qml
+++ b/src/activities/scalesboard_weight_avoirdupois/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "scalesboard_weight_avoirdupois/ScalesboardWeight.qml"
difficulty: 4
icon: "scalesboard_weight_avoirdupois/scalesboard_weight_avoirdupois.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
//: Activity title
title: qsTr("Balance the scales properly")
//: Help title
description: qsTr("Drag and Drop masses to balance the scales and calculate the weight in the avoirdupois unit")
// intro: "Drag the weights up to balance the scales."
//: Help goal
goal: qsTr("Mental calculation, arithmetic equality, unit conversion")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("To balance the scales, move the masses to the left or the right side (on higher levels). They can be arranged in any order. Take care of the weight and the unit of the masses, remember that a pound (lb) is 16 ounce (oz).")
credit: ""
section: "math"
createdInVersion: 0
}
diff --git a/src/activities/scalesboard_weight_avoirdupois/ScalesboardWeight.qml b/src/activities/scalesboard_weight_avoirdupois/ScalesboardWeight.qml
index 182eaa1c6..2dc7ea042 100644
--- a/src/activities/scalesboard_weight_avoirdupois/ScalesboardWeight.qml
+++ b/src/activities/scalesboard_weight_avoirdupois/ScalesboardWeight.qml
@@ -1,87 +1,87 @@
/* GCompris - ScalesboardWeight.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import "../scalesboard"
Scalesboard {
function oz(value) {
/* oz == ounce */
return qsTr("%1 oz").arg(value)
}
function lb(value) {
/* lb == pound */
return qsTr("%1 lb").arg(value)
}
dataset: [
{
"masses": [[1, lb(1)], [2, lb(2)], [2, lb(2)], [5, lb(5)],
[5, lb(5)], [10, lb(10)], [10, lb(10)]],
"targets": [[3, lb(3)], [4, lb(4)], [6, lb(6)], [7, lb(7)], [8, lb(8)], [9, lb(9)]],
"rightDrop": false,
"message": qsTr('The "lb" symbol at the end of a number means pound.') + " " +
qsTr('The pound is a unit of mass, a property which corresponds to the ' +
'common perception of how "heavy" an object is. This unit is used in the USA.')
},
{
"masses": [[1, oz(1)], [2, oz(2)], [2, oz(2)], [4, oz(4)],
[8, oz(8)], [16, oz(16)]],
"targets": [[3, oz(3)], [4, oz(4)], [6, oz(6)], [7, oz(7)],
[16, oz(16)], [24, oz(24)], [28, oz(28)]],
"rightDrop": false,
"message": qsTr('The "oz" symbol at the end of a number means ounce. One pound equals sixteen ounces')
},
{
"masses": [[4, oz(4)], [4, oz(4)], [8, oz(8)], [8, oz(8)],
[8, oz(8)], [16, lb(1)]],
"targets": [[16, lb(1)], [20, oz(20)], [32, lb(2)],
[28, oz(28)]],
"rightDrop": false,
"message": qsTr('Remember, one pound ("lb") equals sixteen ounces ("oz").')
},
{
"masses": [[1, oz(1)], [4, oz(4)], [6, oz(6)], [8, oz(8)],
[10, oz(10)], [16, lb(1)]],
"targets": [[3, oz(3)], [9, oz(9)], [11, oz(11)], [32, lb(2)]],
"rightDrop": true,
"message": qsTr("Take care, you can drop weights on both sides of the scale.")
},
{
"masses": [[4, oz(4)], [4, oz(4)], [8, oz(8)], [8, oz(8)],
[8, oz(8)], [16, lb(1)]],
"targets": [[16, lb(1)], [20, oz(20)], [32, lb(2)],
[28, oz(28)]],
"rightDrop": false,
"message": qsTr("Now you have to guess the weight of the gift."),
"question": qsTr("Enter the weight of the gift in ounce: %1")
},
{
"masses": [[1, oz(1)], [4, oz(4)], [6, oz(6)], [8, oz(8)],
[10, oz(10)], [16, lb(1)]],
"targets": [[3, oz(3)], [9, oz(9)], [11, oz(11)], [32, lb(2)]],
"rightDrop": true,
"message": qsTr("Take care, you can drop weights on both sides of the scale."),
"question": qsTr("Enter the weight of the gift in ounce: %1")
}
]
}
diff --git a/src/activities/share/ActivityInfo.qml b/src/activities/share/ActivityInfo.qml
index 71b3fca2d..8caaf4096 100644
--- a/src/activities/share/ActivityInfo.qml
+++ b/src/activities/share/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2016 Stefan Toncu <stefan.toncu29@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "share/Share.qml"
difficulty: 2
icon: "share/share.svg"
author: "Stefan Toncu &lt;stefan.toncu29@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Share pieces of candy")
//: Help title
description: qsTr("Try to split the pieces of candy to a given number of children")
//intro: "Share the candies equally among the specified number of children and notice that there may be a rest left"
//: Help goal
goal: qsTr("Learn the division of numbers")
//: Help prerequisite
prerequisite: qsTr("Know how to count")
//: Help manual
manual: qsTr("Follow the instructions shown on the screen: first, drag the given number of boys/girls to the middle, then drag pieces of candy to each child's rectangle.")
credit: ""
section: "math"
createdInVersion: 7000
}
diff --git a/src/activities/share/BasketWidget.qml b/src/activities/share/BasketWidget.qml
index 67e789eb4..bde642f88 100644
--- a/src/activities/share/BasketWidget.qml
+++ b/src/activities/share/BasketWidget.qml
@@ -1,46 +1,45 @@
/* GCompris - BasketWidget.qml
*
* Copyright (C) 2016 Stefan Toncu <stefan.toncu29@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
WidgetOption {
id: widget
src: "resource/images/basket.svg"
name: "basket"
availableItems: ""
releaseElement: function() {
var newCoordinate = widget.mapToItem(background, element.x, element.y)
if (background.contains(newCoordinate.x, newCoordinate.y, grid)) {
if (widget.canDrag) {
widget.canDrag = false
- widget.element.opacity = 0
+ widget.element.opacity = 0.6
listModel.append({countS: 0, nameS: "basket"});
}
}
}
element {
opacity: 0
- Behavior on opacity { PropertyAnimation { duration: 500 } }
}
}
diff --git a/src/activities/share/CandyWidget.qml b/src/activities/share/CandyWidget.qml
index 1948b5e8a..808728151 100644
--- a/src/activities/share/CandyWidget.qml
+++ b/src/activities/share/CandyWidget.qml
@@ -1,124 +1,124 @@
/* GCompris - CandyWidget.qml
*
* Copyright (C) 2016 Stefan Toncu <stefan.toncu29@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
WidgetOption {
id: widget
src: "resource/images/candy.svg"
name: "candy"
availableItems: (background.showCount && background.easyMode) ?
widget.total - widget.current : ""
property int placedInChild
releaseElement: function() {
var newCoordinate = widget.mapToItem(background, element.x, element.y)
// Easy mode
if (background.easyMode) {
if (background.currentCandies < items.totalCandies) {
items.acceptCandy = true
for (var i = 0; i < listModel.count; i++) {
var currentChild = repeaterDropAreas.itemAt(i)
var childCoordinate = dropAreas.mapToItem(background, currentChild.x, currentChild.y)
//coordinates of "boy/girl rectangle" in background coordinates
if ((listModel.get(i).countS + 1) > items.maxNumberOfCandiesPerWidget) {
continue
}
var currentElement = element.parent.mapToItem(background, element.x, element.y)
if (currentElement.x > childCoordinate.x && currentElement.x < childCoordinate.x + currentChild.area.width &&
currentElement.y > childCoordinate.y + currentChild.childImage.height &&
currentElement.y < childCoordinate.y + currentChild.childImage.height + currentChild.area.height) {
repeaterDropAreas.itemAt(i).candyCount.text = listModel.get(i).countS + 1
listModel.setProperty(i, "countS", listModel.get(i).countS + 1)
background.currentCandies ++
}
if (background.currentCandies == items.totalCandies) {
widget.canDrag = false
background.resetCandy()
candyWidget.element.opacity = 0.6
}
}
}
else {
widget.canDrag = false
background.resetCandy()
element.opacity = 0.6
}
}
else {
// Hard mode
if (background.currentCandies < widget.total) {
items.acceptCandy = true
for (i = 0; i < listModel.count; i++) {
currentChild = repeaterDropAreas.itemAt(i)
childCoordinate = dropAreas.mapToItem(background, currentChild.x, currentChild.y)
//coordinates of "boy/girl rectangle" in background coordinates
currentElement = element.parent.mapToItem(background, element.x, element.y)
if (currentElement.x > childCoordinate.x && currentElement.x < childCoordinate.x + currentChild.area.width &&
currentElement.y > childCoordinate.y + currentChild.childImage.height &&
currentElement.y < childCoordinate.y + currentChild.childImage.height + currentChild.area.height) {
if ((listModel.get(i).countS + 1) > items.maxNumberOfCandiesPerWidget) {
background.wrongMove.visible = true
continue
}
repeaterDropAreas.itemAt(i).candyCount.text = listModel.get(i).countS + 1
listModel.setProperty(i, "countS", listModel.get(i).countS + 1)
background.currentCandies ++
}
}
// if all the "dropAreas" are full with items.maxNumberOfCandiesPerWidget candies,
// then stop the "swing" effect of the candy in leftWidget
if (background.currentCandies + 1 == widget.total)
background.resetCandy()
}
}
}
//swing animation for candies
SequentialAnimation {
id: anim
running: items.acceptCandy ? true : false
loops: Animation.Infinite
NumberAnimation {
target: candyWidget.element
property: "rotation"
from: -10; to: 10
duration: 700
easing.type: Easing.InOutQuad
}
NumberAnimation {
target: candyWidget.element
property: "rotation"
from: 10; to: -10
duration: 700
easing.type: Easing.InOutQuad
}
}
}
diff --git a/src/activities/share/ChildWidget.qml b/src/activities/share/ChildWidget.qml
index d4459e09c..3325ec21d 100644
--- a/src/activities/share/ChildWidget.qml
+++ b/src/activities/share/ChildWidget.qml
@@ -1,54 +1,54 @@
/* GCompris - ChildWidget.qml
*
* Copyright (C) 2016 Stefan Toncu <stefan.toncu29@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
WidgetOption {
id: widget
src: "resource/images/" + name + ".svg"
availableItems: (background.showCount && background.easyMode) ?
widget.total - widget.current : ""
property int placedInChild
releaseElement: function() {
var newCoordinate = widget.mapToItem(background, element.x, element.y)
if (background.contains(newCoordinate.x, newCoordinate.y, grid)) {
if (widget.current < widget.total) {
if (widget.canDrag) {
widget.current ++
listModel.append({countS: 0, nameS: widget.name});
// set the candies already "present"
repeaterDropAreas.itemAt(listModel.count-1).candyCount.text = placedInChild
listModel.setProperty(listModel.count-1, "countS", placedInChild)
if (widget.current === widget.total) {
widget.canDrag = false
element.opacity = 0.6
}
}
}
else {
widget.canDrag = false
}
}
}
}
diff --git a/src/activities/share/DropChild.qml b/src/activities/share/DropChild.qml
index ffa782a47..605e8339e 100644
--- a/src/activities/share/DropChild.qml
+++ b/src/activities/share/DropChild.qml
@@ -1,227 +1,231 @@
/* GCompris - DropChild.qml
*
* Copyright (C) 2016 Stefan Toncu <stefan.toncu29@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
Rectangle {
id: dropChild
width: items.cellSize * 3
height: items.cellSize * 4.5
color: "transparent"
radius: 0.2
z: 5
property string name
property alias childImage: childImage
property alias area: area
property int indexS: index
property alias candyCount: candyCount
Image {
id: childImage
- sourceSize.width: items.cellSize * 1.5 * 0.7
- sourceSize.height: items.cellSize * 1.5 - 5
+ width: items.cellSize
+ sourceSize.width: width
anchors.bottom: area.top
anchors.left: parent.left
anchors.leftMargin: 20
source: "resource/images/" + name + ".svg"
+ fillMode: Image.PreserveAspectFit
+ mipmap: true
}
//displays the number of candies each child has
GCText {
id: candyCount
+ color: "#373737"
anchors.bottom: area.top
anchors.right: parent.right
anchors.rightMargin: 20
//"listModel.get(index) ? ... " because of an error received at startup of each level
text: (listModel.get(index) && background.showCount) ? listModel.get(index).countS : ""
}
Rectangle {
id: area
width: items.cellSize * 3
height: items.cellSize * 3
anchors.bottom: parent.bottom
radius: width * 0.07
- color: "#cfecf0"
+ color: "#f2f2f2"
property var childCoordinate: repeaterDropAreas.mapToItem(background, dropChild.x, dropChild.y)
property var candyCoord: candyWidget.mapToItem(background, candyWidget.element.x, candyWidget.element.y)
opacity: candyCoord.x > childCoordinate.x &&
candyCoord.y > childCoordinate.y + childImage.height &&
candyCoord.x < childCoordinate.x + childCoordinate.width &&
candyCoord.y < childCoordinate.y + childCoordinate.height ? 0.5 : 1
MouseArea {
anchors.fill: parent
onClicked: {
if (items.acceptCandy) {
// Easy mode
if (background.easyMode) {
if (background.currentCandies < items.candyWidget.total) {
if (listModel.get(index).countS + 1 <= items.maxNumberOfCandiesPerWidget) {
//add candies in the first rectangle
repeaterDropAreas.itemAt(index).candyCount.text = listModel.get(index).countS + 1
listModel.setProperty(index, "countS", listModel.get(index).countS + 1)
//the current number of candies increases
background.currentCandies ++
//on the last one, the candy image from top goes away (destroy)
if (background.currentCandies === items.candyWidget.total) {
background.resetCandy()
candyWidget.element.opacity = 0.6
}
}
}
else {
background.resetCandy()
candyWidget.element.opacity = 0.6
}
}
// Hard mode
else {
if (background.currentCandies < items.candyWidget.total) {
if (listModel.get(index).countS + 1 <= items.maxNumberOfCandiesPerWidget) {
//add candies in the first rectangle
repeaterDropAreas.itemAt(index).candyCount.text = listModel.get(index).countS + 1
listModel.setProperty(index, "countS", listModel.get(index).countS + 1)
//the current number of candies increases
background.currentCandies ++
if (background.currentCandies + 1 === items.candyWidget.total) {
background.resetCandy()
}
}
else {
background.wrongMove.visible = true
}
}
}
}
}
}
Flow {
id: candyDropArea
spacing: 5
width: parent.width
height: parent.height
Repeater {
id: repeaterCandyDropArea
model: countS
Image {
id: candyArea
sourceSize.width: items.cellSize * 0.6
sourceSize.height: items.cellSize * 1.2
source: "resource/images/candy.svg"
+ fillMode: Image.PreserveAspectFit
property int lastX
property int lastY
MouseArea {
anchors.fill: parent
//enables dragging the candy after placed
drag.target: parent
onPressed: {
instruction.hide()
//set the initial position
candyArea.lastX = candyArea.x
candyArea.lastY = candyArea.y
//move this rectangle/grid on top of everything
dropChild.z++
}
function childContainsCandy(currentChild, candy) {
//coordinates of "boy/girl rectangle" in background coordinates
var child = dropAreas.mapToItem(items.background, currentChild.x, currentChild.y)
return (candy.x > child.x &&
candy.x < child.x + currentChild.area.width &&
candy.y > child.y + currentChild.childImage.height &&
candy.y < child.y + currentChild.childImage.height + currentChild.area.height)
}
onReleased: {
//move this rectangle/grid to its previous state
dropChild.z--
var candyCoordinate = candyArea.parent.mapToItem(background, candyArea.x, candyArea.y)
//check where the candy is being dropped
for (var i = 0 ; i < listModel.count ; i++) {
var currentChild = repeaterDropAreas.itemAt(i)
if (currentChild !== dropChild) {
//check if the user wants to put a candy to another rectangle
if (childContainsCandy(currentChild, candyCoordinate)) {
// don't drop more than the maximum of allowed candies per widget
if(listModel.get(currentChild.indexS).countS >= items.maxNumberOfCandiesPerWidget) {
background.wrongMove.visible = true
break;
}
//add the candy to the i-th rectangle
repeaterDropAreas.itemAt(i).candyCount.text = listModel.get(i).countS + 1
listModel.setProperty(i, "countS", listModel.get(i).countS + 1)
//remove the candy from current rectangle
repeaterDropAreas.itemAt(rect2.indexS).candyCount.text = listModel.get(rect2.indexS).countS - 1
listModel.setProperty(rect2.indexS, "countS", listModel.get(rect2.indexS).countS - 1);
break;
}
}
else if (childContainsCandy(currentChild, candyCoordinate)) {
//check if the user wants to put back the candy
repeaterDropAreas.itemAt(rect2.indexS).candyCount.text = listModel.get(rect2.indexS).countS - 1
//restore the candy to the leftWidget
background.currentCandies --
candyWidget.element.opacity = 1
items.candyWidget.canDrag = true
//remove the candy from current rectangle
listModel.setProperty(rect2.indexS, "countS", listModel.get(rect2.indexS).countS - 1);
break;
}
}
//restore the candy to its initial position
candyArea.x = candyArea.lastX
candyArea.y = candyArea.lastY
}
//when clicked, it will restore the candy
onClicked: {
repeaterDropAreas.itemAt(rect2.indexS).candyCount.text = listModel.get(rect2.indexS).countS - 1
background.currentCandies--
candyWidget.element.opacity = 1
items.candyWidget.canDrag = true
listModel.setProperty(rect2.indexS, "countS", listModel.get(rect2.indexS).countS - 1);
}
}
}
}
}
}
}
diff --git a/src/activities/share/Share.qml b/src/activities/share/Share.qml
index 10b57ed34..45e6de940 100644
--- a/src/activities/share/Share.qml
+++ b/src/activities/share/Share.qml
@@ -1,433 +1,427 @@
/* GCompris - Share.qml
*
* Copyright (C) 2016 Stefan Toncu <stefan.toncu29@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "share.js" as Activity
ActivityBase {
id: activity
onStart: focus = true
onStop: {}
pageComponent: Rectangle {
id: background
anchors.fill: parent
- color: "#ffffb3"
+ color: "#abcdef"
signal start
signal stop
Component.onCompleted: {
dialogActivityConfig.getInitialConfiguration()
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property alias background: background
property alias bar: bar
property alias bonus: bonus
property alias instruction: instruction
property int currentSubLevel: 0
property int nbSubLevel
property alias listModel: listModel
property bool acceptCandy: false
property alias dataset: dataset
property alias girlWidget: girlWidget
property alias boyWidget: boyWidget
property alias candyWidget: candyWidget
property alias basketWidget: basketWidget
property alias leftWidget: leftWidget
property int totalBoys
property int totalGirls
property int totalCandies
property int totalChildren: totalBoys + totalGirls
property int barHeightAddon: ApplicationSettings.isBarHidden ? 1 : 3
- property int cellSize: Math.min(background.width / 11, background.height / (9 + barHeightAddon))
+ property int cellSize: Math.round(Math.min(background.width / 11, background.height / (9 + barHeightAddon)))
property alias repeaterDropAreas: repeaterDropAreas
property int maxNumberOfCandiesPerWidget: 8
}
Loader {
id: dataset
asynchronous: false
}
onStart: { Activity.start(items) }
onStop: { Activity.stop() }
- property bool vert: background.width > background.height
+ property bool vert: background.width >= background.height
property int currentBoys: 0
property int currentGirls: 0
property int currentCandies: 0
property int rest
property int placedInGirls
property int placedInBoys
property bool showCount: true
property bool easyMode: true
property alias wrongMove: wrongMove
property bool finished: false
//returns true if the x and y is in the "dest" area
function contains(x, y, dest) {
return (x > dest.x && x < dest.x + dest.width &&
y > dest.y && y < dest.y + dest.height)
}
//stop the candy rotation
function resetCandy() {
items.acceptCandy = false;
candyWidget.element.rotation = 0
}
//check if the answer is correct
function check() {
background.resetCandy()
background.finished = true
var ok = 0
var okRest = 0
if (listModel.count >= items.totalChildren) {
for (var i = 0 ; i < listModel.count ; i++) {
if (listModel.get(i).nameS === "basket")
okRest = listModel.get(i).countS
else if (listModel.get(i).countS === Math.floor(items.totalCandies/items.totalChildren))
ok ++
}
//condition without rest
if (rest == 0 && ok == items.totalChildren) {
bonus.good("flower")
return
}
//condition with rest
else if (rest == okRest && ok == items.totalChildren) {
bonus.good("tux")
return
}
}
//else => bad
bonus.bad("flower")
}
//center zone
Rectangle {
id: grid
z: 4
//map the coordinates from widgets to grid
property var boy: leftWidget.mapFromItem(boyWidget, boyWidget.element.x, boyWidget.element.y)
property var girl: leftWidget.mapFromItem(girlWidget, girlWidget.element.x, girlWidget.element.y)
property var basket: leftWidget.mapFromItem(basketWidget, basketWidget.element.x, basketWidget.element.y)
//show that the widget can be dropped here
color: background.contains(boy.x, boy.y, grid) ||
background.contains(girl.x, girl.y, grid) ||
- background.contains(basket.x, basket.y, grid) ? "pink" : "transparent"
+ background.contains(basket.x, basket.y, grid) ? "#d5e6f7" : "transparent"
anchors {
top: background.vert ? parent.top : leftWidget.bottom
left: background.vert ? leftWidget.right : parent.left
topMargin: 20
leftMargin: 20
}
width: background.vert ?
background.width - leftWidget.width - 40 : background.width - 40
height: ApplicationSettings.isBarHidden ?
background.height : background.vert ?
background.height - (bar.height * 1.1) :
background.height - (bar.height * 1.1) - leftWidget.height
//shows/hides the Instruction
MouseArea {
anchors.fill: parent
// first hide the wrong move if visible, then show/hide instruction
onClicked: wrongMove.visible ? wrongMove.visible = false :
(instruction.opacity === 0) ?
instruction.show() : instruction.hide()
}
ListModel {
id: listModel
}
Flow {
id: dropAreas
spacing: 10
width: parent.width
height: parent.height
Repeater {
id: repeaterDropAreas
model: listModel
DropChild {
id: rect2
//"nameS" from listModel
name: nameS
}
}
}
}
//instruction rectangle
Rectangle {
id: instruction
anchors.fill: instructionTxt
opacity: 0.8
radius: 10
border.width: 2
z: 10
- border.color: "black"
- gradient: Gradient {
- GradientStop { position: 0.0; color: "#000" }
- GradientStop { position: 0.9; color: "#666" }
- GradientStop { position: 1.0; color: "#AAA" }
- }
-
+ border.color: "#DDD"
+ color: "#373737"
+
property alias text: instructionTxt.text
Behavior on opacity { PropertyAnimation { duration: 200 } }
//shows/hides the Instruction
MouseArea {
anchors.fill: parent
onClicked: instruction.hide()
enabled: instruction.opacity !== 0
}
function show() {
if(text)
opacity = 1
}
function hide() {
opacity = 0
}
}
//instruction for playing the game
GCText {
id: instructionTxt
anchors {
top: background.vert ? parent.top : leftWidget.bottom
topMargin: -10
horizontalCenter: grid.horizontalCenter
}
opacity: instruction.opacity
z: instruction.z
fontSize: background.vert ? regularSize : smallSize
color: "white"
- style: Text.Outline
- styleColor: "black"
horizontalAlignment: Text.AlignHCenter
width: Math.max(Math.min(parent.width * 0.8, text.length * 8), parent.width * 0.3)
wrapMode: TextEdit.WordWrap
}
//left widget, with girl/boy/candy/basket widgets in a grid
Rectangle {
id: leftWidget
width: background.vert ?
items.cellSize * 1.74 : background.width
height: background.vert ?
background.height : items.cellSize * 1.74
- color: "#FFFF42"
- border.color: "#FFD85F"
+ color: "#5a9de0"
+ border.color: "#3f81c4"
border.width: 4
z: 4
//grid with ok button and images of a boy, a girl, a candy and a basket
Grid {
id: view
x: 10
y: 10
width: background.vert ? leftWidget.width : 3 * bar.height
height: background.vert ? background.height - 2 * bar.height : bar.height
spacing: 10
columns: background.vert ? 1 : 5
//ok button
Image {
id: okButton
source:"qrc:/gcompris/src/core/resource/bar_ok.svg"
sourceSize.width: items.cellSize * 1.5
fillMode: Image.PreserveAspectFit
MouseArea {
id: mouseArea
anchors.fill: parent
enabled: background.finished ? false : true
onPressed: okButton.opacity = 0.6
onReleased: okButton.opacity = 1
onClicked: background.check()
}
}
ChildWidget {
id: girlWidget
name: "girl"
total: items.totalGirls
current: background.currentGirls
placedInChild: background.placedInGirls
}
ChildWidget {
id: boyWidget
name: "boy"
total: items.totalBoys
current: background.currentBoys
placedInChild: background.placedInBoys
}
+
+ BasketWidget {
+ id: basketWidget
+ }
CandyWidget {
id: candyWidget
total: background.easyMode ? items.totalCandies : 8 * items.totalChildren + 1
current: background.currentCandies
element.opacity: background.easyMode ? 1 : 0
}
-
- BasketWidget {
- id: basketWidget
- }
}
}
// show message warning for placing too many candies in one area
Rectangle {
id: wrongMove
z: 5
color: "orange"
radius: width / height * 10
visible: false
width: grid.width
height: grid.height / 3
anchors.centerIn: grid
MouseArea {
anchors.fill: parent
onClicked: parent.visible = false
}
GCText {
id: wrongMoveText
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
width: parent.width - 2 // -2 for margin
height: parent.height
fontSizeMode: Text.Fit
wrapMode: Text.WordWrap
color: "#404040"
text: qsTr("You can't put more than %1 pieces of candy in the same rectangle").arg(items.maxNumberOfCandiesPerWidget)
}
}
DialogActivityConfig {
id: dialogActivityConfig
currentActivity: activity
content: Component {
Item {
height: column.height
Column {
id: column
spacing: 10
width: parent.width
GCDialogCheckBox {
id: easyModeBox
width: dialogActivityConfig.width
text: qsTr("Display candy counter")
checked: background.easyMode
onCheckedChanged: {
background.easyMode = checked
Activity.reloadRandom()
}
}
}
}
}
onLoadData: {
if(dataToSave && dataToSave["mode"]) {
background.easyMode = (dataToSave["mode"] === "true");
}
}
onSaveData: {
dataToSave = { "mode": "" + background.easyMode }
}
onClose: home()
}
//bar buttons
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level | reload | config}
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
onReloadClicked: Activity.reloadRandom()
onConfigClicked: {
dialogActivityConfig.active = true
displayDialog(dialogActivityConfig)
}
}
Bonus {
id: bonus
Component.onCompleted: {
win.connect(Activity.nextSubLevel)
}
onStop: background.finished = false
}
Score {
anchors {
left: undefined
right: leftWidget.right
bottom: background.vert ? bar.top : leftWidget.bottom
margins: 3 * ApplicationInfo.ratio
}
- width: basketWidget.width
- height: background.vert ? (basketWidget.height * 0.8) : basketWidget.height
+ width: girlWidget.width
+ height: background.vert ? (girlWidget.height * 0.8) : girlWidget.height
numberOfSubLevels: items.nbSubLevel
currentSubLevel: items.currentSubLevel + 1
}
}
}
diff --git a/src/activities/share/WidgetOption.qml b/src/activities/share/WidgetOption.qml
index ef56ec1c4..7aab25472 100644
--- a/src/activities/share/WidgetOption.qml
+++ b/src/activities/share/WidgetOption.qml
@@ -1,85 +1,87 @@
/* GCompris - WidgetOption.qml
*
* Copyright (C) 2016 Stefan Toncu <stefan.toncu29@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
Rectangle {
id: widget
- width: items.cellSize * 1.5
- height: items.cellSize * 1.5
+ width: element.opacity > 0 ? items.cellSize * 1.5 : 0
+ height: width
color: "transparent"
//initial position of the element
//(these vars are assigned to element after release of click mouse)
property int lastX
property int lastY
property string src
property int current: 0
property int total: 0
property string name
property bool canDrag: true
property alias element: element
property string availableItems
// callback defined in each widget called when we release the element in background
property var releaseElement: null
Image {
id: element
- sourceSize.width: items.cellSize * 1.5
- sourceSize.height: items.cellSize * 1.5
+ fillMode: Image.PreserveAspectFit
+ width: items.cellSize
+ sourceSize.width: width
source: widget.src
-
- //number of available items
- GCText {
- id: elementText
- anchors.left: parent.left
- anchors.bottom: parent.bottom
- text: availableItems
- }
-
- property alias dragAreaElement: dragAreaElement
-
- MouseArea {
- id: dragAreaElement
- anchors.fill: parent
- drag.target: (widget.canDrag) ? parent : null
- enabled: element.opacity > 0
- onPressed: {
- instruction.hide()
- if (widget.name !== "candy")
- background.resetCandy()
+ mipmap: true
+ }
+ //number of available items
+ GCText {
+ id: elementText
+ anchors.left: element.right
+ anchors.bottom: element.bottom
+ text: availableItems
+ color: "#f2f2f2"
+ }
+
+ property alias dragAreaElement: dragAreaElement
+
+ MouseArea {
+ id: dragAreaElement
+ anchors.fill: parent
+ drag.target: (widget.canDrag) ? element : null
+ enabled: element.opacity > 0
+ onPressed: {
+ instruction.hide()
+ if (widget.name !== "candy")
+ background.resetCandy()
//set the initial position
widget.lastX = element.x
widget.lastY = element.y
- }
-
- onReleased: {
- widget.releaseElement()
- //set the widget to its initial coordinates
- element.x = widget.lastX
- element.y = widget.lastY
- }
+ }
+
+ onReleased: {
+ widget.releaseElement()
+ //set the widget to its initial coordinates
+ element.x = widget.lastX
+ element.y = widget.lastY
}
}
}
diff --git a/src/activities/share/resource/README b/src/activities/share/resource/README
index 8b3c88668..6564d3150 100644
--- a/src/activities/share/resource/README
+++ b/src/activities/share/resource/README
@@ -1,10 +1,7 @@
-License: Public domain
-Files: basket.svg
-Source: https://openclipart.org/detail/215766/basket-02
-
-Copyright: Timothée Giet, 2017
+Copyright: Timothée Giet, 2017 - 2019
License: CC-BY-SA 4.0
Files:
+basket.svg
boy.svg
girl.svg
candy.svg
diff --git a/src/activities/share/resource/board/board0.qml b/src/activities/share/resource/board/board0.qml
index ccbe76565..2ebff42e5 100644
--- a/src/activities/share/resource/board/board0.qml
+++ b/src/activities/share/resource/board/board0.qml
@@ -1,69 +1,69 @@
/* GCompris
*
* Copyright (C) 2016 Stefan Toncu <stefan.toncu29@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
/*
Numbers of kids are given in the left widget which eases kid work.
No rest (basket).
*/
QtObject {
property var levels : [
{
"instruction": qsTr("Paul wants to equally share 2 pieces of candy between 2 of his friends: one girl and one boy. Can you help him? First, place the children in center, then drag the pieces of candy to each of them."),
"totalBoys": 1,
"totalGirls": 1,
"totalCandies": 2,
"showCount": true,
"forceShowBasket": "false",
"placedInGirls": 0,
"placedInBoys": 0
},
{
"instruction": qsTr("Now he wants to give 4 pieces of candy to his friends."),
"totalBoys": 1,
"totalGirls": 1,
"totalCandies": 4,
"showCount": true,
"forceShowBasket": false,
"placedInGirls": 0,
"placedInBoys": 0
},
{
"instruction": qsTr("Can you now give 6 of Paul's pieces of candy to his friends?"),
"totalBoys": 1,
"totalGirls": 1,
"totalCandies": 6,
"showCount": true,
"forceShowBasket": false,
"placedInGirls": 0,
"placedInBoys": 0
},
{
"instruction": qsTr("Paul has only 10 pieces of candy left. He eats 2 pieces of candy and he gives the rest to his friends. Can you help him equally split the 8 remaining pieces of candy?"),
"totalBoys": 1,
"totalGirls": 1,
"totalCandies": 8,
"showCount": true,
"forceShowBasket": false,
"placedInGirls": 0,
"placedInBoys": 0
}
]
}
diff --git a/src/activities/share/resource/board/board1.qml b/src/activities/share/resource/board/board1.qml
index f09a2eee9..62ebce22f 100644
--- a/src/activities/share/resource/board/board1.qml
+++ b/src/activities/share/resource/board/board1.qml
@@ -1,58 +1,58 @@
/* GCompris
*
* Copyright (C) 2016 Stefan Toncu <stefan.toncu29@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
/*
Numbers of kids are given in the left widget which eases kid work.
There is a rest (basket)
*/
QtObject {
property var levels : [
{
"instruction": qsTr("George wants to equally share 3 pieces of candy between 2 of his friends: one girl and one boy. Can he equally split the pieces of candy between his friends? First, place the children in center, then drag the pieces of candy to each of them. Be careful, a rest will remain!"),
"totalBoys": 1,
"totalGirls": 1,
"totalCandies": 3,
"showCount": true,
"forceShowBasket": false,
"placedInGirls": 0,
"placedInBoys": 0
},
{
"instruction": qsTr("Maria wants to equally share 5 pieces of candy between 3 of her friends: one girl and two boys. Can she equally split the pieces of candy between her friends? First, place the children in center, then drag the pieces of candy to each of them. Be careful, a rest will remain!"),
"totalBoys": 2,
"totalGirls": 1,
"totalCandies": 5,
"showCount": true,
"forceShowBasket": false,
"placedInGirls": 0,
"placedInBoys": 0
},
{
"instruction": qsTr("John wants to equally share 10 pieces of candy between 3 of his friends: one boy and two girls. Can he equally split the pieces of candy between his friends? First, place the children in center, then drag the pieces of candy to each of them."),
"totalBoys": 1,
"totalGirls": 2,
"totalCandies": 10,
"showCount": true,
"forceShowBasket": false,
"placedInGirls": 0,
"placedInBoys": 0
}
]
}
diff --git a/src/activities/share/resource/board/board2.qml b/src/activities/share/resource/board/board2.qml
index 39c2d76c2..4519a2d9e 100644
--- a/src/activities/share/resource/board/board2.qml
+++ b/src/activities/share/resource/board/board2.qml
@@ -1,68 +1,68 @@
/* GCompris
*
* Copyright (C) 2016 Stefan Toncu <stefan.toncu29@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
/*
Numbers of kids are not given anymore in the left widget which forces kids to understand this part.
No rest (basket).
*/
QtObject {
property var levels : [
{
"instruction": qsTr("Alice wants to equally share 3 pieces of candy between 3 of her friends: one girl and two boys. Can you help her? First, place the children in the center, then drag the pieces of candy to each of them."),
"totalBoys": 2,
"totalGirls": 1,
"totalCandies": 3,
"showCount": false,
"forceShowBasket": false,
"placedInGirls": 0,
"placedInBoys": 0
},
{
"instruction": qsTr("Now, Alice wants to give 6 pieces of candy to her friends"),
"totalBoys": 2,
"totalGirls": 1,
"totalCandies": 6,
"showCount": false,
"forceShowBasket": false,
"placedInGirls": 0,
"placedInBoys": 0
},
{
"instruction": qsTr("Can you help Alice give 9 pieces of candy to her friends: one girl and two boys?"),
"totalBoys": 2,
"totalGirls": 1,
"totalCandies": 9,
"showCount": false,
"forceShowBasket": false,
"placedInGirls": 0,
"placedInBoys": 0
},
{
"instruction": qsTr("Alice has 12 pieces of candy left. She wants to give them all to her friends. Can you help her split the pieces of candy equally?"),
"totalBoys": 2,
"totalGirls": 1,
"totalCandies": 12,
"showCount": false,
"forceShowBasket": false,
"placedInGirls": 0,
"placedInBoys": 0
}
]
}
diff --git a/src/activities/share/resource/board/board3.qml b/src/activities/share/resource/board/board3.qml
index 3f8c6939c..f2abbb1a9 100644
--- a/src/activities/share/resource/board/board3.qml
+++ b/src/activities/share/resource/board/board3.qml
@@ -1,68 +1,68 @@
/* GCompris
*
* Copyright (C) 2016 Stefan Toncu <stefan.toncu29@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
/*
Numbers of kids are not given anymore in the left widget.
There is a rest (basket).
*/
QtObject {
property var levels : [
{
"instruction": qsTr("Michael wants to equally share 5 pieces of candy between 2 of his friends: one girl and one boy. Can you help him? First, place the children in center, then drag the pieces of candy to each of them!"),
"totalBoys": 1,
"totalGirls": 1,
"totalCandies": 5,
"showCount": false,
"forceShowBasket": false,
"placedInGirls": 0,
"placedInBoys": 0
},
{
"instruction": qsTr("Helen has 3 friends: one boy and two girls. She wants to give them 7 pieces of candy. Help her split the pieces of candy between her friends!"),
"totalBoys": 1,
"totalGirls": 2,
"totalCandies": 7,
"showCount": false,
"forceShowBasket": false,
"placedInGirls": 0,
"placedInBoys": 0
},
{
"instruction": qsTr("Michelle has 9 pieces of candy and wants to split them with two brothers and two sisters. Help her share the pieces of candy!"),
"totalBoys": 2,
"totalGirls": 2,
"totalCandies": 9,
"showCount": false,
"forceShowBasket": false,
"placedInGirls": 0,
"placedInBoys": 0
},
{
"instruction": qsTr("Thomas wants to share his 11 pieces of candy with his friends: three boys and one girl. Can you help him?"),
"totalBoys": 3,
"totalGirls": 1,
"totalCandies": 11,
"showCount": false,
"forceShowBasket": false,
"placedInGirls": 0,
"placedInBoys": 0
}
]
}
diff --git a/src/activities/share/resource/board/board4.qml b/src/activities/share/resource/board/board4.qml
index 71a19b678..707bc6e58 100644
--- a/src/activities/share/resource/board/board4.qml
+++ b/src/activities/share/resource/board/board4.qml
@@ -1,58 +1,58 @@
/* GCompris
*
* Copyright (C) 2016 Stefan Toncu <stefan.toncu29@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
/*
Numbers of kids are not given anymore in the left widget.
There is always a basket even if the rest can be equal to 0
*/
QtObject {
property var levels : [
{
"instruction": qsTr("Charles wants to share his 8 pieces of candy with 3 of his friends: one boy and two girls. Can he split the pieces of candy equally?"),
"totalBoys": 1,
"totalGirls": 2,
"totalCandies": 8,
"showCount": true,
"forceShowBasket": true,
"placedInGirls": 0,
"placedInBoys": 0
},
{
"instruction": qsTr("For her birthday, Elizabeth has 12 pieces of candy to share with 4 of her friends: two girls and two boys. How should she split the pieces of candy to her friends?"),
"totalBoys": 2,
"totalGirls": 2,
"totalCandies": 12,
"showCount": true,
"forceShowBasket": true,
"placedInGirls": 0,
"placedInBoys": 0
},
{
"instruction": qsTr("Jason's father gave him 14 pieces of candy to share with his friends: two boys and three girls. Help him give the pieces of candy to his friends!"),
"totalBoys": 2,
"totalGirls": 3,
"totalCandies": 14,
"showCount": true,
"forceShowBasket": true,
"placedInGirls": 0,
"placedInBoys": 0
}
]
}
diff --git a/src/activities/share/resource/board/board5.qml b/src/activities/share/resource/board/board5.qml
index 5950461cc..c962537c4 100644
--- a/src/activities/share/resource/board/board5.qml
+++ b/src/activities/share/resource/board/board5.qml
@@ -1,59 +1,59 @@
/* GCompris
*
* Copyright (C) 2016 Stefan Toncu <stefan.toncu29@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
/*
Numbers of kids are not given anymore in the left widget.
No rest (basket).
Boy or Girl rectangles already contain a given number of pieces of candy.
*/
QtObject {
property var levels : [
{
"instruction": qsTr("Bob wants to give 5 pieces of candy to his friends: two boys and one girl, his girlfriend already has one candy. Can you help him equally split the pieces of candy so that each friend will have the same amount of pieces of candy?"),
"totalBoys": 2,
"totalGirls": 1,
"totalCandies": 6,
"showCount": true,
"forceShowBasket": false,
"placedInGirls": 1,
"placedInBoys": 0
},
{
"instruction": qsTr("Harry wants to equally share 8 pieces of candy between his friends: one boy and two girls. Place the children in center, then drag the pieces of candy to each of them so that each of them has an equal number of pieces of candy."),
"totalBoys": 1,
"totalGirls": 2,
"totalCandies": 9,
"showCount": true,
"forceShowBasket": false,
"placedInGirls": 0,
"placedInBoys": 1
},
{
"instruction": qsTr("Can you now give 6 of Harry's pieces of candy to his friends?"),
"totalBoys": 1,
"totalGirls": 2,
"totalCandies": 8,
"showCount": true,
"forceShowBasket": false,
"placedInGirls": 0,
"placedInBoys": 2
}
]
}
diff --git a/src/activities/share/resource/board/board6.qml b/src/activities/share/resource/board/board6.qml
index a793a6684..d522105ad 100644
--- a/src/activities/share/resource/board/board6.qml
+++ b/src/activities/share/resource/board/board6.qml
@@ -1,59 +1,59 @@
/* GCompris
*
* Copyright (C) 2016 Stefan Toncu <stefan.toncu29@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
/*
Numbers of kids are not given anymore in the left widget.
No rest (basket).
Boy or Girl rectangles already contain a given number of pieces of candies.
*/
QtObject {
property var levels : [
{
"instruction": qsTr("Help Jon split 9 pieces of candies between three boys and two girls. The rest will remain to Jon."),
"totalBoys": 3,
"totalGirls": 2,
"totalCandies": 9,
"showCount": false,
"forceShowBasket": true,
"placedInGirls": 0,
"placedInBoys": 0
},
{
"instruction": qsTr("Jon wants to share the rest of his pieces of candies with his brother and his sister. Can you split them equally, knowing that his brother already has two pieces of candies?"),
"totalBoys": 1,
"totalGirls": 1,
"totalCandies": 6,
"showCount": false,
"forceShowBasket": true,
"placedInGirls": 0,
"placedInBoys": 2
},
{
"instruction": qsTr("Help Tux split some pieces of candies to his friends: 9 pieces of candies to one boy and two girls."),
"totalBoys": 1,
"totalGirls": 2,
"totalCandies": 13,
"showCount": false,
"forceShowBasket": true,
"placedInGirls": 2,
"placedInBoys": 0
}
]
}
diff --git a/src/activities/share/resource/board/board7.qml b/src/activities/share/resource/board/board7.qml
index b6d22c4c8..273cf24a8 100644
--- a/src/activities/share/resource/board/board7.qml
+++ b/src/activities/share/resource/board/board7.qml
@@ -1,29 +1,29 @@
/* GCompris
*
* Copyright (C) 2016 Stefan Toncu <stefan.toncu29@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property var levels : [
{
"maxBoys": 2,
"maxGirls": 2,
"maxCandies": 16,
"alreadyPlaced": false
}
]
}
diff --git a/src/activities/share/resource/board/board8.qml b/src/activities/share/resource/board/board8.qml
index 973165dc0..94bc38f2b 100644
--- a/src/activities/share/resource/board/board8.qml
+++ b/src/activities/share/resource/board/board8.qml
@@ -1,29 +1,29 @@
/* GCompris
*
* Copyright (C) 2016 Stefan Toncu <stefan.toncu29@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property var levels : [
{
"maxBoys": 3,
"maxGirls": 3,
"maxCandies": 24,
"alreadyPlaced": true
}
]
}
diff --git a/src/activities/share/resource/board/board9.qml b/src/activities/share/resource/board/board9.qml
index 973165dc0..94bc38f2b 100644
--- a/src/activities/share/resource/board/board9.qml
+++ b/src/activities/share/resource/board/board9.qml
@@ -1,29 +1,29 @@
/* GCompris
*
* Copyright (C) 2016 Stefan Toncu <stefan.toncu29@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
QtObject {
property var levels : [
{
"maxBoys": 3,
"maxGirls": 3,
"maxCandies": 24,
"alreadyPlaced": true
}
]
}
diff --git a/src/activities/share/resource/images/basket.svg b/src/activities/share/resource/images/basket.svg
index c3af3dcdf..be426a2a9 100644
--- a/src/activities/share/resource/images/basket.svg
+++ b/src/activities/share/resource/images/basket.svg
@@ -1,92 +1,196 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- id="svg2"
version="1.1"
- inkscape:version="0.91 r13725"
- width="600"
- height="600"
+ id="svg2"
+ viewBox="0 0 42 60"
+ height="60"
+ width="42"
+ inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
sodipodi:docname="basket.svg">
+ <sodipodi:namedview
+ pagecolor="#abcdef"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ id="namedview32"
+ showgrid="false"
+ units="px"
+ inkscape:zoom="6.7277216"
+ inkscape:cx="22.242932"
+ inkscape:cy="30.165103"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="svg2"
+ scale-x="1" />
+ <defs
+ id="defs4">
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1458"
+ id="linearGradient1501"
+ x1="38.590771"
+ y1="60.980442"
+ x2="38.590771"
+ y2="48.519623"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.88101766,0,0,0.84913951,-7.1925659,4.9643561)" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient1458">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.81395346"
+ offset="0"
+ id="stop1454" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.14617941"
+ offset="1"
+ id="stop1456" />
+ </linearGradient>
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1458"
+ id="radialGradient1154"
+ cx="33.166317"
+ cy="4.5757427"
+ fx="33.166317"
+ fy="4.5757427"
+ r="2.5"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.98529961,0.03516151,-0.04119243,1.1542991,-10.323625,-4.0722544)" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1458"
+ id="radialGradient1146-2"
+ cx="36"
+ cy="11.379496"
+ fx="36"
+ fy="11.379496"
+ r="8.5"
+ gradientTransform="matrix(1.2081346,-1.9026703e-8,0,0.91491787,-18.492847,-0.58689372)"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1458"
+ id="radialGradient1138-1"
+ cx="38"
+ cy="20"
+ fx="38"
+ fy="20"
+ r="10.5"
+ gradientTransform="matrix(1.2417417,0,0,0.0952381,-20.186186,15.919643)"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1458"
+ id="radialGradient930-5"
+ cx="40.25"
+ cy="33.787296"
+ fx="40.25"
+ fy="33.787296"
+ r="16.5"
+ gradientTransform="matrix(0.78787881,-5.2513019e-8,1.3129095e-7,1.9393939,-2.7121288,-36.222699)"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient1458"
+ id="radialGradient971"
+ cx="35.641792"
+ cy="21.71756"
+ fx="35.641792"
+ fy="21.71756"
+ r="8.7091942"
+ gradientTransform="matrix(1.4926754,2.1403857e-6,-1.6464505e-7,0.11482119,-26.201624,17.810461)"
+ gradientUnits="userSpaceOnUse" />
+ </defs>
<metadata
- id="metadata8">
+ id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
+ <dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
- <defs
- id="defs6" />
- <sodipodi:namedview
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1"
- objecttolerance="10"
- gridtolerance="10"
- guidetolerance="10"
- inkscape:pageopacity="0"
- inkscape:pageshadow="2"
- inkscape:window-width="1664"
- inkscape:window-height="985"
- id="namedview4"
- showgrid="false"
- borderlayer="true"
- inkscape:zoom="0.69644045"
- inkscape:cx="-70.880883"
- inkscape:cy="80.98044"
- inkscape:window-x="131"
- inkscape:window-y="-2"
- inkscape:window-maximized="0"
- inkscape:current-layer="svg2" />
+ <ellipse
+ style="opacity:1;vector-effect:none;fill:url(#radialGradient971);fill-opacity:1;stroke:#505050;stroke-width:0.99999994;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.70764118"
+ id="path941"
+ cx="21.000002"
+ cy="20.014935"
+ rx="8.2731085"
+ ry="1.1133742" />
+ <path
+ style="opacity:1;vector-effect:none;fill:url(#radialGradient930-5);fill-opacity:1;stroke:#505050;stroke-width:0.99999994;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.70764118"
+ d="m 37,33.304173 c 0,4.418278 -3.790861,15.418277 -6.686292,21.313708 -2.89543,5.89543 -4.89543,2.686292 -9.313708,2.686292 -4.418279,0 -6.418278,3.209138 -9.313707,-2.686292 C 8.7908616,48.72245 4.9999999,37.722451 4.9999999,33.304173 c 0,-4.418278 1.7908618,-8.418278 4.686292,-11.313709 C 11.134007,20.54275 10.911528,19.941348 12.772079,20.561533 15,21.304174 18.79086,21.304174 21,21.304174 c 2.20914,0 6,0 8.227922,-0.742641 1.770799,-0.590267 1.63807,-0.01878 3.085787,1.428931 C 35.209139,24.885895 37,28.885895 37,33.304173 Z"
+ id="path919"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="sssssssssss" />
+ <rect
+ style="opacity:1;vector-effect:none;fill:url(#radialGradient1138-1);fill-opacity:1;stroke:#505050;stroke-width:0.99999994;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.70764118"
+ id="rect1112"
+ width="15.999999"
+ height="1.9999999"
+ x="13.000001"
+ y="16.824417"
+ ry="0.95512903" />
+ <path
+ style="opacity:1;vector-effect:none;fill:url(#radialGradient1146-2);fill-opacity:1;stroke:#505050;stroke-width:0.99999994;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.70764118"
+ d="m 29,13.824406 c 9.6e-5,3.257358 -3.673756,2.934618 -8.089741,2.792281 -3.91369,-0.126147 -7.910258,0.465077 -7.910258,-2.792281 0,-3.999999 3.58172,-7.9999963 7.999999,-7.9999963 4.418278,0 7.999881,3.9999973 8,7.9999963 z"
+ id="path1071"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="sssss" />
+ <circle
+ style="opacity:1;vector-effect:none;fill:url(#radialGradient1154);fill-opacity:1;stroke:#505050;stroke-width:0.99999994;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.70764118"
+ id="path1114"
+ cx="21.000002"
+ cy="3.8244102"
+ r="1.9999999" />
+ <path
+ style="opacity:1;vector-effect:none;fill:url(#linearGradient1501);fill-opacity:1;stroke:none;stroke-width:0.8649317;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.71760798"
+ d="m 35.096284,35.533379 c 0,3.751735 -3.339817,13.09227 -5.890744,18.098314 C 26.654616,58.637736 24.892582,55.91273 21,55.91273 c -3.892582,0 -5.654617,2.725006 -8.205541,-2.281037 -2.550925,-5.006044 -5.8907419,-14.346579 -5.8907419,-18.098314 0,-3.751735 1.5777803,-7.148292 4.1287039,-9.606917 1.275466,-1.229312 1.079458,-1.739984 2.718635,-1.213362 1.962839,0.630606 5.302652,0.630606 7.248944,0.630606 1.946292,0 5.286105,0 7.248945,-0.630606 1.560105,-0.501221 1.443169,-0.01596 2.718633,1.213362 2.550923,2.458625 4.128706,5.855182 4.128706,9.606917 z"
+ id="path919-8"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="sssssssssss" />
+ <circle
+ style="opacity:1;vector-effect:none;fill:#eaeaea;fill-opacity:1;stroke:#ab3c3c;stroke-width:0.99999994;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="path1452"
+ cx="21.000002"
+ cy="33.304176"
+ r="7.9999995" />
<g
- transform="matrix(1.9609414,0,0,1.9081327,-825.28981,78.51064)"
- id="g3774">
- <path
- inkscape:connector-curvature="0"
- id="path3776"
- d="m 553,222.98747 c -4.675,-0.48537 -11.425,-1.39649 -15,-2.02471 -3.575,-0.62822 -7.90032,-1.32341 -9.61182,-1.54487 -5.08152,-0.6575 -20.47519,-5.34058 -26.35866,-8.01885 -8.12547,-3.69888 -28.23414,-19.44158 -37.96464,-29.72181 -6.12925,-6.47553 -9.45101,-12.38916 -13.10967,-23.33878 -7.60897,-22.77207 -9.55098,-41.32811 -5.95914,-56.93967 2.52226,-10.962677 4.1934,-15.300459 8.40654,-21.820822 C 455.20723,76.785081 457.95408,72.25 459.50672,69.5 465.03081,59.71584 474.58223,46.417276 480,40.966924 485.93595,34.995275 494.56003,30.324366 514.34352,22.36604 533.86108,14.514692 546.30961,12.4962 581,11.557895 c 18.7821,-0.508018 32.56898,2.204122 55.5,10.9179 22.23293,8.448505 38.99819,22.50089 53.11979,44.524205 7.81867,12.19358 13.02354,23.306183 15.47097,33.03113 1.99304,7.91938 2.05144,9.21503 0.90009,19.96887 -1.69589,15.84003 -9.18305,37.82361 -16.4093,48.18054 -2.43477,3.4896 -20.85885,22.18026 -25.37339,25.74052 -14.89638,11.7476 -41.94688,22.52577 -69.20816,27.57574 -10.51979,1.94872 -30.69216,2.66468 -42,1.49067 z m 102.12756,-32.65119 c 1.24448,-1.5086 1.16266,-1.55194 -0.87756,-0.46482 -2.32696,1.23991 -2.89993,2.12854 -1.37244,2.12854 0.48265,0 1.49515,-0.74867 2.25,-1.66372 z m 3.79855,-16.74725 c 0.75526,-0.91003 0.81654,-1.63004 0.17262,-2.02801 -0.54911,-0.33937 -1.48679,0.29557 -2.08374,1.41097 -1.23454,2.30676 0.14037,2.75067 1.91112,0.61704 z M 672,171.80968 c 0,-1.31439 -2.27278,-0.49134 -2.77106,1.0035 -0.24358,0.73075 0.21359,0.95424 1.1875,0.58051 C 671.2874,173.05947 672,172.34667 672,171.80968 z m -3,-15.43212 c 0,-1.64087 -0.13551,-1.65674 -3.4349,-0.40231 -2.96083,1.12571 -3.35304,2.70045 -0.8151,3.27267 2.1064,0.47493 4.25,-0.97281 4.25,-2.87036 z M 680.8,156.8 c 1.37094,-1.37094 1.62454,-4.8 0.35499,-4.8 -1.49912,0 -4.37207,3.83974 -3.69393,4.93699 0.85619,1.38535 1.85769,1.34426 3.33894,-0.13699 z m -8.27611,-20.60945 c -0.89036,-0.89035 -2.49812,1.91641 -2.46854,4.30945 0.0204,1.64913 0.29458,1.50204 1.56295,-0.83841 0.84602,-1.56112 1.25353,-3.12309 0.90559,-3.47104 z m 14.86912,-0.77234 c 0.90904,-2.36891 0.73147,-6.22324 -0.31654,-6.87095 -1.31351,-0.81179 -5.37669,5.228 -4.70122,6.98823 0.7499,1.95421 4.25429,1.8723 5.01776,-0.11728 z m -13.57659,-12.74533 c 0.34258,-2.89378 -1.22132,-3.66608 -2.20943,-1.09109 -0.99905,2.60348 -0.68967,4.61202 0.64301,4.17442 0.6875,-0.22574 1.39239,-1.61324 1.56642,-3.08333 z m 13.99194,-9.68151 c 0.27674,-4.03074 0.15083,-4.33616 -1.22768,-2.97798 -0.84482,0.83237 -1.83645,3.01545 -2.20362,4.8513 -0.58255,2.91277 -0.42619,3.29207 1.22768,2.97798 1.466,-0.2784 1.9651,-1.37719 2.20362,-4.8513 z M 672,107.05902 c 0,-1.06754 -0.35899,-2.16285 -0.79775,-2.43402 -1.4249,-0.88064 -3.51067,1.12888 -2.87935,2.77408 0.86709,2.2596 3.6771,1.99973 3.6771,-0.34006 z m 13.25,-9.045365 c 1.21283,-0.02208 0.85965,-3.48144 -0.55261,-5.412825 -1.07441,-1.469335 -1.49831,-1.545638 -2.41961,-0.435535 -0.61435,0.740241 -1.44448,2.6507 -1.84474,4.245464 -0.67646,2.695234 -0.5588,2.854362 1.66961,2.25806 1.31854,-0.35283 2.73485,-0.647654 3.14735,-0.655164 z m -18.8326,-6.147302 c -0.70379,-1.138753 -3.14799,-1.11128 -3.86163,0.0434 -0.30924,0.500367 -0.2802,1.644794 0.0645,2.543172 0.57717,1.504074 0.77352,1.500637 2.47966,-0.0434 1.01908,-0.92225 1.61192,-2.066678 1.31743,-2.543172 z m 11.49218,-8.789307 c 1.19204,-0.754618 1.20397,-1.388706 0.0773,-4.108741 -1.23704,-2.98649 -1.42716,-3.086656 -2.65958,-1.401229 -2.90956,3.979071 -1.09972,7.84085 2.58229,5.50997 z M 656,80.559017 c 0,-2.823717 -1.15159,-3.821812 -3.40976,-2.955273 -1.88858,0.724716 -2.05647,2.530029 -0.39024,4.196256 1.96654,1.966538 3.8,1.367777 3.8,-1.240983 z M 644,70.5 c 0,-0.825 -0.675,-1.5 -1.5,-1.5 -0.825,0 -1.5,0.675 -1.5,1.5 0,0.825 0.675,1.5 1.5,1.5 0.825,0 1.5,-0.675 1.5,-1.5 z m 23.35576,-1.602525 c 1.74371,-2.036511 1.72952,-2.177799 -0.45208,-4.5 -2.81151,-2.992722 -4.50047,-3.047348 -5.25294,-0.169895 -0.56184,2.148484 1.5889,6.77242 3.15007,6.77242 0.41509,0 1.56482,-0.946136 2.55495,-2.102525 z M 529.45729,62.069098 c 0.73955,-1.196602 -1.14162,-2.382227 -2.4736,-1.559017 C 525.86533,61.201265 526.59952,63 528,63 c 0.48508,0 1.14086,-0.418906 1.45729,-0.930902 z m 100.36226,-1.24077 C 629.44383,58.274921 628.08888,57.638846 626,59.035259 c -1.29825,0.867876 -1.23892,1.201944 0.44113,2.483744 2.70446,2.063384 3.75215,1.849197 3.37842,-0.690675 z M 501,57 c 0,-0.55 -0.45,-1 -1,-1 -0.55,0 -1,0.45 -1,1 0,0.55 0.45,1 1,1 0.55,0 1,-0.45 1,-1 z m 45.8041,-2.877747 c -0.32589,-2.810181 -1.73629,-3.176863 -3.21325,-0.835396 -1.30449,2.068046 -0.007,4.810019 1.92539,4.068537 1.02218,-0.392246 1.48311,-1.549416 1.28786,-3.233141 z m 107.59504,1.616238 c 0.90591,-1.44956 0.56958,-2.195832 -1.89914,-4.214037 -1.65,-1.348891 -3.28504,-2.468711 -3.63342,-2.488491 -0.9359,-0.05314 -1.70648,4.860273 -1.11623,7.117373 0.63989,2.446945 5.03155,2.172931 6.64879,-0.414845 z M 615.40804,53.5 c 1.55077,-2.366768 1.53595,-2.5 -0.278,-2.5 -1.98592,0 -3.55821,2.498196 -2.57427,4.090242 0.80963,1.310008 1.03387,1.184986 2.85227,-1.590242 z M 562,51.567388 c 0,-1.583799 -0.72416,-2.662451 -2.07536,-3.091306 C 557.27842,47.636204 557.06251,47.90602 557.70488,51.25 558.4025,54.881541 562,55.147378 562,51.567388 z M 581.5,50 c 0,-1.832728 -0.60174,-2.585447 -2.25447,-2.820137 -1.35228,-0.192025 -2.49559,0.308199 -2.85699,1.25 -0.99567,2.594671 0.39988,4.739185 2.85699,4.390274 C 580.89826,52.585447 581.5,51.832728 581.5,50 z m 18.5,1.122445 c 0,-1.032656 -0.64623,-2.413883 -1.43608,-3.069394 C 596.62172,46.44117 593,48.38233 593,51.035184 593,52.614021 593.68756,53 596.5,53 c 2.75725,0 3.5,-0.398444 3.5,-1.877555 z m -75.18733,-3.39673 c 0.5905,-0.71151 0.81187,-3.106126 0.50123,-5.422099 -0.61701,-4.600121 -1.21646,-4.661775 -7.02583,-0.722605 -2.9806,2.021063 -3.08863,2.284552 -1.5,3.658471 1.89822,1.641659 5.36759,3.683015 6.33949,3.730109 0.34515,0.01673 1.10345,-0.543019 1.68511,-1.243876 z M 637.60795,46.25 c 1.90464,-2.509039 1.74038,-2.932922 -1.58585,-4.09245 -3.47901,-1.212791 -4.51018,-0.238354 -3.59719,3.399285 0.71595,2.85258 3.28319,3.195914 5.18304,0.693165 z M 542,36.752555 c 0,-2.840029 -0.17197,-2.96816 -3.17708,-2.367138 -4.27802,0.855602 -4.33483,1.003173 -1.73833,4.515131 C 539.76972,42.532373 542,41.557758 542,36.752555 z m 79.20084,2.139958 c 1.65978,-0.888289 1.79522,-1.281105 0.68426,-1.984687 -0.76181,-0.48246 -2.41343,-0.884091 -3.67028,-0.892513 C 616.23824,36.002068 616.07418,36.270098 617,38 c 1.24356,2.323604 1.44633,2.366685 4.20084,0.892513 z m -59.90252,-5.925272 c 0.41684,-1.594008 0.0105,-1.964336 -2.14194,-1.951928 -1.46101,0.0084 -3.33138,0.467564 -4.15638,1.020315 -1.27943,0.857218 -1.15012,1.298326 0.87939,2.99975 2.61058,2.188575 4.49371,1.469877 5.41893,-2.068137 z m 18.76365,1.750956 C 583.17223,32.292475 583.0687,30.26374 579.8013,29.610261 574.61729,28.573457 574,28.818869 574,31.916667 c 0,3.835689 2.9738,5.210025 6.06197,2.80153 z M 599,35.5651 C 599,33.601563 596.75092,30 595.52475,30 c -1.77876,0 -1.94162,1.35255 -0.48957,4.065741 C 595.91558,35.710768 599,36.877192 599,35.5651 z M 604.8,34.8 c 1.84019,-1.840188 1.4276,-3.8 -0.8,-3.8 -1.46667,0 -2,0.666667 -2,2.5 0,2.729605 0.93588,3.164121 2.8,1.3 z"
- style="fill:#ca9858" />
- <path
- inkscape:connector-curvature="0"
- id="path3778"
- d="m 552,221.94603 c -4.675,-0.42631 -14.00586,-1.70655 -20.73526,-2.84497 -21.97294,-3.71722 -31.6807,-8.01052 -48.26474,-21.3453 -21.16102,-17.015 -27.03316,-24.38233 -31.8312,-39.93622 -6.79496,-22.02735 -8.80213,-41.50515 -5.71533,-55.46198 2.32022,-10.490737 4.50043,-15.846835 9.77754,-24.020378 2.42787,-3.76045 6.16658,-9.762182 8.30825,-13.337182 6.139,-10.247591 12.42337,-18.88734 16.8672,-23.189022 4.86298,-4.707426 11.48895,-9.342399 14.74968,-10.317642 1.28912,-0.385559 4.14386,-1.71778 6.34386,-2.960492 2.2,-1.242711 6.44389,-3.059182 9.43087,-4.036603 2.98698,-0.97742 6.81198,-2.554191 8.5,-3.503937 2.97671,-1.674812 4.54133,-2.13189 18.75664,-5.479464 7.65721,-1.803202 27.57458,-3.290766 45.81249,-3.421589 20.12923,-0.14439 40.17133,4.897198 63.51818,15.977992 15.45916,7.337169 30.6426,21.705424 41.66788,39.430757 18.95294,30.470612 21.26814,48.98625 9.79183,78.30935 -6.69569,17.10815 -9.07871,20.94801 -20.59815,33.19065 -18.06339,19.19743 -32.50657,27.86188 -59.87974,35.92179 -25.39499,7.47745 -42.13703,9.24587 -66.5,7.02424 z M 596.5,197 c 0.33992,-0.55 -0.057,-1 -0.88197,-1 -0.825,0 -1.77811,0.45 -2.11803,1 -0.33992,0.55 0.057,1 0.88197,1 0.825,0 1.77811,-0.45 2.11803,-1 z m 60.14219,-6.57732 c 2.94679,-2.51753 5.35781,-4.99901 5.35781,-5.5144 0,-1.89399 -11.60035,4.91917 -12.77862,7.50518 -1.88738,4.14236 1.21657,3.30966 7.42081,-1.99078 z M 494,193 c 0,-0.55 -0.70156,-1 -1.55902,-1 -0.85746,0 -1.2809,0.45 -0.94098,1 0.33992,0.55 1.04148,1 1.55902,1 0.51754,0 0.94098,-0.45 0.94098,-1 z m 7.5,0 c -0.33992,-0.55 -1.15398,-0.99311 -1.80902,-0.98469 -0.71561,0.009 -0.59227,0.40223 0.30902,0.98469 1.92112,1.24153 2.2673,1.24153 1.5,0 z m 136.10577,-3.47735 C 640.24539,187.79311 640.76528,186 638.62712,186 636.28155,186 628,190.03485 628,191.17764 c 0,1.47828 6.54472,0.35069 9.60577,-1.65499 z m 8.56549,-1.17764 c 2.61079,-2.36273 2.2585,-3.49795 -0.67126,-2.16306 -1.375,0.6265 -2.5,1.74185 -2.5,2.47857 0,1.78407 0.95639,1.68892 3.17126,-0.31551 z M 493,187.15499 c 0,-0.46476 -0.9,-1.6595 -2,-2.65499 -2.20097,-1.99185 -2.55837,-1.41184 -0.96482,1.56574 1.04351,1.94982 2.96482,2.65569 2.96482,1.08925 z M 524.5,186 c -0.33992,-0.55 -1.06803,-1 -1.61803,-1 -0.55,0 -0.72189,0.45 -0.38197,1 0.33992,0.55 1.06803,1 1.61803,1 0.55,0 0.72189,-0.45 0.38197,-1 z m 66.47664,0.25 c -0.0509,-1.63339 -5.53862,-10.7358 -6.47664,-10.74267 -0.55,-0.004 -1.1438,1.00517 -1.31955,2.24267 -0.21973,1.54713 0.19181,2.25 1.31739,2.25 1.19465,0 1.46131,0.55335 0.98693,2.04799 -0.3575,1.12639 -0.10773,2.70139 0.55506,3.5 1.2445,1.49954 4.97819,2.03047 4.93681,0.70201 z M 622,184.94098 c 0,-0.58246 -0.45,-0.7809 -1,-0.44098 -0.55,0.33992 -1,0.81648 -1,1.05902 0,0.24254 0.45,0.44098 1,0.44098 0.55,0 1,-0.47656 1,-1.05902 z M 489.5,178 c -0.33992,-0.55 -1.06803,-1 -1.61803,-1 -0.55,0 -0.72189,0.45 -0.38197,1 0.33992,0.55 1.06803,1 1.61803,1 0.55,0 0.72189,-0.45 0.38197,-1 z m 169.43045,-3.42597 c 2.23492,-2.37896 2.11758,-4.6048 -0.23947,-4.54261 -1.63857,0.0432 -4.93946,4.75751 -4.18543,5.97757 0.94422,1.52777 1.94709,1.20255 4.4249,-1.43496 z m 12.15621,0.14417 c 2.16781,-1.6644 4.10353,-5.48262 3.09539,-6.10569 -1.52248,-0.94094 -7.18205,3.2929 -7.18205,5.37279 0,2.25822 1.70235,2.56351 4.08666,0.7329 z M 553,170.93632 c -1.21988,-0.80622 -0.0681,-2.3401 6.16759,-8.21383 4.21718,-3.97237 8.17549,-8.24429 8.79625,-9.49316 2.07519,-4.17496 -1.21569,-5.81849 -4.46384,-2.22933 -0.99549,1.1 -2.34549,2 -3,2 -0.65451,0 -1.99986,0.89486 -2.98966,1.98857 -0.9898,1.09372 -3.98454,3.39063 -6.65499,5.10425 -5.48817,3.52175 -6.09864,5.78405 -2.35535,8.72852 1.38339,1.08818 2.5,3.00288 2.5,4.28687 0,2.21004 0.0832,2.23714 1.75,0.56991 1.53287,-1.53327 1.56389,-1.87345 0.25,-2.7418 z m 28.29172,0.47922 c -0.37644,-5.26955 -1.22917,-10.81349 -1.90389,-12.37794 -1.71599,-3.97887 -2.44858,9.52215 -0.80284,14.79556 0.76669,2.45665 2.91769,0.5354 2.70673,-2.41762 z m 46.73052,0.33446 c 0.0122,-0.6875 0.90222,-2.375 1.97776,-3.75 2.3457,-2.99881 2.48504,-4 0.5567,-4 -1.92429,0 -4.5567,3.88359 -4.5567,6.72251 0,2.31364 1.98145,3.32041 2.02224,1.02749 z m -149.88302,-3.78327 c -1.29844,-1.0817 -3.09844,-1.95176 -4,-1.93346 -1.28503,0.0261 -1.12912,0.45822 0.72156,2 1.29844,1.0817 3.09844,1.95176 4,1.93346 1.28503,-0.0261 1.12912,-0.45822 -0.72156,-2 z M 598.25,167.79989 c 3.40365,-1.23217 3.4654,-2.28504 0.25729,-4.38707 -3.33229,-2.1834 -6.82127,-1.18498 -9.62662,2.75477 l -2.25212,3.16281 2.18473,-0.57132 c 1.2016,-0.31423 2.45569,-0.13289 2.78687,0.40297 0.33119,0.53587 1.34413,0.67259 2.251,0.30384 0.90687,-0.36875 2.88635,-1.11845 4.39885,-1.666 z m 26,-1.60688 c 2.34782,-2.01642 2.21679,-2.8559 -0.89602,-5.74076 -3.26031,-3.02155 -4.038,-3.04609 -6.41042,-0.20225 -1.74156,2.08762 -1.87942,2.11135 -1.91029,0.32874 -0.0183,-1.05669 -0.77967,-2.74602 -1.69193,-3.75406 -1.36137,-1.50429 -1.45099,-2.28861 -0.5,-4.3758 1.39075,-3.05237 1.52168,-8.10649 0.23066,-8.90438 -0.51041,-0.31545 -1.21573,0.33299 -1.56739,1.44098 -0.86976,2.74037 -5.14806,2.71328 -6.02132,-0.0381 -0.48433,-1.526 -0.97803,-1.78164 -1.92423,-0.99637 -0.70001,0.58096 -2.68604,0.77362 -4.41342,0.42815 -6.01637,-1.20328 -8.37634,3.87195 -3.2175,6.91935 2.83054,1.67204 2.94945,1.66256 3.56739,-0.28439 0.99026,-3.12003 2.75341,-2.42399 2.0438,0.80683 -0.5427,2.47092 -0.18317,3.05594 2.89771,4.71511 1.98801,1.07061 3.93938,3.10502 4.4881,4.67907 0.53395,1.5317 1.61413,2.7849 2.4004,2.7849 0.78626,0 2.03155,0.72534 2.7673,1.61186 2.82446,3.40327 6.61848,3.62035 10.15716,0.58115 z m 17.1933,-2.41552 c 1.92508,-2.74843 1.99791,-4.16077 0.17856,-3.46262 -0.75798,0.29086 -1.86391,0.0431 -2.45762,-0.55063 -1.40636,-1.40636 -4.16424,0.76915 -4.16424,3.28488 0,1.55057 1.14537,2.3249 4.1933,2.83488 0.38131,0.0638 1.39381,-0.88413 2.25,-2.10651 z M 652.75632,162.25 c 0.277,-0.84379 -0.75414,-1.25 -3.17299,-1.25 -2.58306,0 -3.58333,0.4364 -3.58333,1.56336 0,1.92159 6.11576,1.63794 6.75632,-0.31336 z M 500.65016,158.25269 500.5,154.5 493,153.36217 c -4.125,-0.6258 -7.66809,-0.98271 -7.87354,-0.79312 -0.20544,0.18958 -0.0782,1.11435 0.28278,2.05504 0.50024,1.30358 0.93392,1.43275 1.82354,0.54313 C 489.26655,153.13345 490,153.88428 490,158 c 0,2.5415 0.45578,3.99442 1.25,3.98469 1.79893,-0.022 3.29928,-1.22285 4.04156,-3.23469 0.99594,-2.69935 2.69341,-2.07516 3.35519,1.23377 0.81482,4.07406 2.18821,2.88735 2.00341,-1.73108 z m 7.16626,1.07443 c -0.17403,-1.47009 -0.80276,-2.8322 -1.39718,-3.02692 -0.67532,-0.22122 -0.9141,0.78149 -0.6365,2.67288 0.54749,3.73031 2.47306,4.06552 2.03368,0.35404 z M 592,161 c 0,-0.55 -0.92656,-1 -2.05902,-1 -1.13246,0 -1.7809,0.45 -1.44098,1 0.33992,0.55 1.26648,1 2.05902,1 0.79254,0 1.44098,-0.45 1.44098,-1 z m 76.94897,-2.40465 c 1.71264,-3.20009 0.52779,-4.93183 -2.80247,-4.09598 -3.23224,0.81124 -5.1465,2.31896 -5.1465,4.05352 0,1.14118 1.61986,1.81192 5.58102,2.31093 0.59456,0.0749 1.66014,-0.94591 2.36795,-2.26847 z m 11.85009,-0.85323 c 1.35836,-1.63672 4.24787,-10.02852 3.65665,-10.61974 -0.55063,-0.55064 -6.12147,4.70415 -7.47952,7.05518 -1.96185,3.39633 1.37797,6.51048 3.82287,3.56456 z m -206.23639,-2.34843 c -0.456,-1.81688 -0.1665,-2.96289 0.95579,-3.78353 1.45288,-1.06237 1.38491,-1.46328 -0.69677,-4.10971 l -2.3067,-2.9325 -0.6995,4.89013 c -0.70169,4.9054 0.28945,8.54192 2.3281,8.54192 0.6571,0 0.81959,-1.01055 0.41908,-2.60631 z m 70.0415,-2.12286 c -1.01652,-1.01651 -1.85525,0.51389 -1.02122,1.86338 0.63003,1.01942 0.86558,1.02021 1.2043,0.004 0.2316,-0.69479 0.14921,-1.53513 -0.18308,-1.86742 z M 483.5,153 c 0.33992,-0.55 -0.0835,-1 -0.94098,-1 -0.85746,0 -1.55902,0.45 -1.55902,1 0,0.55 0.42344,1 0.94098,1 0.51754,0 1.2191,-0.45 1.55902,-1 z m 41.5,-0.55902 c 0,-0.85746 -0.45,-1.2809 -1,-0.94098 -0.55,0.33992 -1,1.04148 -1,1.55902 0,0.51754 0.45,0.94098 1,0.94098 0.55,0 1,-0.70156 1,-1.55902 z m -17.33583,-3.87376 C 507.3334,147.70525 506.14865,147 505.03138,147 c -2.47005,0 -2.55495,0.76398 -0.35501,3.19489 1.88459,2.08245 3.97459,0.94387 2.9878,-1.62767 z M 463.1038,146.7038 c -1.28349,-1.28349 -2.58505,-0.2915 -1.63484,1.24598 0.36808,0.59556 1.12735,0.79971 1.68727,0.45366 0.683,-0.42212 0.66575,-0.98146 -0.0524,-1.69964 z m 209.40573,-6.38085 c 1.04722,-2.50636 1.21069,-4.00273 0.51342,-4.7 -1.50474,-1.50474 -2.98861,0.39062 -3.6901,4.71336 -0.7867,4.84787 1.14893,4.83973 3.17668,-0.0134 z m -202.31887,-2.37324 c -1.653,-2.93865 -5.58724,-4.89621 -6.98723,-3.47663 -0.83573,0.84741 6.89153,7.58626 7.94933,6.93251 0.40071,-0.24765 -0.0322,-1.8028 -0.9621,-3.45588 z m 37.60021,0.008 c 2.22506,-4.49726 1.94578,-8.46953 -0.49928,-7.10121 -3.7589,2.10359 -10.62186,-2.54889 -8.15124,-5.5258 0.59587,-0.71798 0.79631,-2.05356 0.44543,-2.96795 -0.57013,-1.48574 -0.88131,-1.43393 -2.92633,0.48726 -2.68617,2.52353 -4.65945,2.78015 -4.65945,0.60596 0,-0.88558 -0.70192,-1.41855 -1.64626,-1.25 -2.49847,0.44595 -2.75144,-1.88521 -0.42111,-3.88051 1.13705,-0.97357 2.06737,-2.34953 2.06737,-3.05768 0,-0.70815 0.9,-2.05815 2,-3 1.12015,-0.9591 2,-2.94994 2,-4.52539 0,-2.58916 -0.1752,-2.71918 -2.2022,-1.63437 -1.64065,0.87806 -2.29939,0.88703 -2.58333,0.0352 -0.4616,-1.38461 -3.21447,-1.53755 -3.21447,-0.1784 0,0.53065 0.9,1.44648 2,2.03518 1.1,0.5887 2,1.85007 2,2.80305 0,2.51548 -4.6362,8.94671 -6.98758,9.69301 -2.78496,0.88391 -2.56205,4.34447 0.3512,5.45209 1.29998,0.49425 2.65378,1.6548 3.00842,2.579 0.36237,0.94431 1.27575,1.43825 2.0852,1.12763 0.87055,-0.33406 1.68841,0.22876 2.06735,1.42268 0.35558,1.12035 1.35166,1.85575 2.30119,1.69898 1.30218,-0.21501 1.64145,0.44576 1.52677,2.97356 -0.0811,1.7875 0.25641,3.25 0.75,3.25 0.4936,0 0.89745,-0.91412 0.89745,-2.03138 0,-2.58242 2.22209,-3.45531 5.00482,-1.96604 2.03656,1.08993 2.06423,1.26364 0.48018,3.01399 -0.92451,1.02157 -1.38528,2.33576 -1.02394,2.92042 1.31392,2.12597 3.37362,0.9747 5.32981,-2.97909 z m 39.72572,2.02833 c 1.14726,-0.95214 1.80751,-0.96214 2.91362,-0.0442 0.78662,0.65283 3.14912,1.04543 5.25,0.87245 3.04713,-0.25091 3.88275,-0.75687 4.13106,-2.50133 0.37159,-2.61059 -3.84498,-5.79915 -6.68627,-5.05614 -1.40031,0.36619 -1.75652,0.0499 -1.41492,-1.25641 0.47954,-1.83377 -4.34009,-6.02633 -6.86445,-5.97134 -2.13364,0.0465 -7.84563,5.75011 -7.84563,7.83415 0,1.04041 -0.66554,2.444 -1.47899,3.1191 -1.08587,0.9012 -1.21433,1.72196 -0.48329,3.08792 0.81214,1.51749 1.91743,1.79469 5.99558,1.50367 2.74994,-0.19624 5.66742,-0.91081 6.48329,-1.58792 z m 31.87642,0.43198 c 1.05872,-2.75898 0.6972,-3.73796 -0.89301,-2.41821 -1.63697,1.35856 -2.0378,4 -0.60699,4 0.49116,0 1.16616,-0.7118 1.5,-1.58179 z m -51.54223,-1.51604 C 532.08462,137.42625 532.26369,134 528.10699,134 525.29798,134 524,135.44803 524,138.58179 c 0,1.70155 -0.0898,1.69408 3.85078,0.32038 z m 159.95401,-6.16116 c 0.36401,-5.66209 -1.27896,-6.29607 -4.61673,-1.7815 -2.64553,3.57827 -2.72235,4.62581 -0.43806,5.97383 3.34341,1.97303 4.7325,0.82096 5.05479,-4.19233 z m -228.52387,0.94817 c -0.245,-1.28163 0.19983,-2.84328 0.99878,-3.50635 1.68509,-1.3985 1.1619,-5.57145 -0.91461,-7.29479 -2.01516,-1.67244 -2.74874,-0.48294 -3.34462,5.42332 -0.3922,3.8874 -0.14692,5.49415 0.97803,6.40684 2.21873,1.80009 2.77527,1.54918 2.28242,-1.02902 z m 76.37912,-8.33249 c 0.21887,-3.72777 -0.12869,-5.50075 -1.26285,-6.44202 -2.6548,-2.20329 -4.84266,0.11143 -4.89545,5.17929 -0.0539,5.17702 1.05657,7.11595 3.83979,6.7043 1.67406,-0.24761 2.06782,-1.17178 2.31851,-5.44157 z m -63.64481,1.62808 c 1.46891,-1.46891 1.83677,-2.72628 1.35692,-4.63813 -0.64001,-2.55 -0.55746,-2.60399 2.96969,-1.94229 2.99971,0.56275 3.52712,0.41775 3.04552,-0.83729 -0.32036,-0.83485 -1.99391,-2.22203 -3.71899,-3.08261 -2.83887,-1.41622 -3.24459,-1.4169 -4.27539,-0.007 -0.65306,0.89312 -1.83292,1.29117 -2.76592,0.93314 -1.27279,-0.48841 -1.62706,0.009 -1.62706,2.28263 0,1.59885 0.5625,3.50324 1.25,4.23199 1,1.06 1,1.41667 0,1.78333 -1.76155,0.6459 -1.5606,3.29167 0.25,3.29167 0.825,0 2.40685,-0.90685 3.51523,-2.01523 z M 527,126 c 0,-0.55 -0.9,-1 -2,-1 -1.1,0 -2,0.45 -2,1 0,0.55 0.9,1 2,1 1.1,0 2,-0.45 2,-1 z m 51.11158,-6.94172 c -0.70226,-2.74004 -1.0196,-5.39809 -0.70521,-5.90678 0.76988,-1.2457 -2.04844,-3.49075 -3.36257,-2.67857 -0.57409,0.35481 -1.0438,3.74619 -1.0438,7.5364 0,5.51815 0.3487,7.08917 1.75,7.88436 1.256,0.71275 2.15768,0.5913 3.1942,-0.43022 1.22342,-1.20572 1.24901,-2.18487 0.16738,-6.40519 z m 96.31186,5.6322 c 1.10815,-1.75677 0.0129,-4.67623 -1.88244,-5.0177 -1.05919,-0.19083 -2.6045,5.93038 -1.72035,6.81454 0.85415,0.85415 2.42467,0.0709 3.60279,-1.79684 z M 516,122.61735 c 0,-1.9851 -10.87158,-7.14577 -12.21769,-5.79966 C 502.2991,118.3009 503.5867,121 505.77749,121 c 1.01214,0 2.71376,0.66069 3.78138,1.4682 2.47618,1.87288 6.44113,1.9647 6.44113,0.14915 z m 11,-2.67637 C 527,119.42344 526.55,119 526,119 c -0.55,0 -1,0.70156 -1,1.55902 0,0.85746 0.45,1.2809 1,0.94098 0.55,-0.33992 1,-1.04148 1,-1.55902 z m 29.80075,-1.90911 c 0.1639,-2.15106 -0.40828,-3.38383 -2.07853,-4.47822 -1.26758,-0.83055 -2.88725,-3.12113 -3.59927,-5.09018 -1.01098,-2.79582 -1.76643,-3.51254 -3.44855,-3.27178 -3.16015,0.45233 -3.32603,3.55428 -0.26466,4.94914 1.99072,0.90703 2.42486,1.66998 1.97353,3.46823 -0.4245,1.69135 0.15217,2.98267 2.16508,4.84817 3.58579,3.3232 4.97534,3.21067 5.2524,-0.42536 z m -98.36373,-2.41177 c 0.68077,-3.76072 0.62341,-3.86481 -1.86734,-3.38867 -2.01514,0.38522 -2.56968,0.0896 -2.56968,-1.3701 0,-2.25835 -1.55677,-2.45876 -2.38258,-0.30673 -0.5498,1.43277 2.58697,7.01726 4.85362,8.64103 1.21964,0.87372 1.13159,1.03387 1.96598,-3.57553 z M 688,112.94098 c 0,-5.75669 -1.03345,-5.7559 -3.97144,0.003 C 681.89301,117.13005 682.17487,118 685.66667,118 687.80363,118 688,117.57424 688,112.94098 z m -32,3.11804 c 0,-0.51754 -0.45,-1.2191 -1,-1.55902 -0.55,-0.33992 -1,0.0835 -1,0.94098 0,0.85746 0.45,1.55902 1,1.55902 0.55,0 1,-0.42344 1,-0.94098 z m -189,-4.03597 c 0,-2.22151 -4.34857,-5.54369 -5.95602,-4.55023 -1.80925,1.11818 -1.13479,4.00795 1.20602,5.16727 3.4574,1.71232 4.75,1.54441 4.75,-0.61704 z M 476.95846,107.5 c 0.0737,-2.42543 -2.15063,-8.5 -3.11245,-8.5 -0.62307,0 -0.75678,0.721339 -0.3244,1.75 1.86779,4.44359 1.67432,6.07551 -0.92193,7.77664 -2.77531,1.81846 -3.39885,4.01725 -1.34968,4.75942 1.27599,0.46214 5.65342,-3.9748 5.70846,-5.78606 z M 498,112 c 0,-0.55 -0.45,-1 -1,-1 -0.55,0 -1,0.45 -1,1 0,0.55 0.45,1 1,1 0.55,0 1,-0.45 1,-1 z m 22.9963,-3.49606 c 1.2897,-1.37283 2.04137,-2.7996 1.67037,-3.17061 -0.73062,-0.73061 -5.66667,3.48621 -5.66667,4.84098 0,1.52683 1.63451,0.84364 3.9963,-1.67037 z M 672.07431,109.25 c 0.0409,-0.4125 0.25959,-1.73983 0.48604,-2.94961 0.51846,-2.76985 -0.9236,-3.71153 -3.53968,-2.31145 -1.96131,1.04966 -2.70668,3.99172 -1.354,5.34439 0.90996,0.90996 4.3156,0.84558 4.40764,-0.0833 z M 651.5,107 c -0.33992,-0.55 -0.81648,-1 -1.05902,-1 -0.24254,0 -0.44098,0.45 -0.44098,1 0,0.55 0.47656,1 1.05902,1 0.58246,0 0.7809,-0.45 0.44098,-1 z m -137.95013,-1.84287 c -0.3419,-1.07722 0.2397,-2.89118 1.39986,-4.36609 3.00819,-3.824303 1.29262,-4.102835 -3.053,-0.49567 -4.48971,3.72677 -4.69868,4.44674 -1.64673,5.67347 3.36958,1.3544 3.94263,1.21344 3.29987,-0.81171 z m -50.2275,-5.246873 C 464.79507,97.660898 466,94.987456 466,93.969274 c 0,-2.782342 1.74891,-3.306957 3.03199,-0.909496 0.85164,1.591296 1.73171,1.965361 3.55018,1.508956 1.81461,-0.45544 2.41783,-0.201161 2.41783,1.019203 0,1.071894 0.53907,1.419182 1.58179,1.019052 0.86998,-0.333844 1.99498,-0.606989 2.5,-0.606989 1.01874,0 1.26405,-3.320826 0.31539,-4.269489 -0.33156,-0.331553 -1.69499,-0.187584 -3.02985,0.31993 -2.03079,0.772107 -2.58502,0.557612 -3.39479,-1.313844 -0.53227,-1.230128 -1.51744,-3.005712 -2.18927,-3.945742 -0.9966,-1.394469 -0.81293,-2.550102 0.99762,-6.276751 C 473.0014,78.00192 474,75.733535 474,75.473249 c 0,-1.167247 -2.40137,-0.3066 -3.558,1.275179 -0.70316,0.961635 -1.61251,1.414394 -2.02077,1.006131 -0.40827,-0.408264 0.0357,-1.60195 0.98653,-2.652636 1.43842,-1.58943 1.51926,-2.245923 0.48125,-3.908035 -1.03472,-1.65686 -0.94519,-2.459209 0.5248,-4.702694 1.78082,-2.717866 0.93846,-5.444976 -1.26182,-4.085126 C 467.84089,63.216371 462,73.967583 462,75.570593 c 0,0.668486 -0.675,1.474451 -1.5,1.791033 -1.823,0.69955 -1.96003,4.918156 -0.25,7.696232 1.07487,1.746208 0.9419,2.269699 -0.94908,3.736432 -1.54813,1.200806 -2.40192,3.272045 -2.88434,6.997236 -0.58333,4.504404 -0.40496,5.503744 1.19908,6.718194 2.64045,1.99914 2.71949,1.96313 5.70671,-2.599463 z m 70.62026,1.983563 c 2.95992,-1.80444 3.20716,-2.230492 1.76325,-3.038542 -1.0634,-0.595111 -2.36492,-0.572937 -3.54843,0.06046 -1.02797,0.550156 -3.17143,0.906679 -4.76325,0.792275 -3.23748,-0.23268 -4.20571,2.408847 -1.05257,2.871637 1.0129,0.14866 2.1004,0.52906 2.41667,0.84532 0.89478,0.89478 1.49642,0.71709 5.18433,-1.53114 z M 510.25,98.553399 c 3.67159,-4.601556 3.51088,-6.65655 -0.23957,-3.063393 -3.44824,3.303626 -5.04945,2.744684 -2.64589,-0.923614 2.36222,-3.6052 1.95375,-5.57793 -0.47963,-2.316392 -2.46613,3.30544 -5.5736,3.905353 -3.88491,0.75 0.88406,-1.651889 0.75965,-2.002377 -0.71482,-2.013655 -0.98185,-0.0075 -2.79768,-0.284994 -4.03518,-0.616631 -1.76519,-0.473052 -2.25,-0.186549 -2.25,1.329656 0,1.8727 6.26977,8.30063 8.09639,8.30063 0.49698,0 0.90361,0.45 0.90361,1 0,2.08354 2.60346,0.87028 5.25,-2.446601 z M 481.36163,99.5 c -0.31659,-0.825 -1.03256,-1.5 -1.59106,-1.5 -0.58531,0 -0.48812,0.635407 0.22943,1.5 0.68469,0.825 1.40067,1.5 1.59106,1.5 0.19039,0 0.0871,-0.675 -0.22943,-1.5 z M 542,100 c 0,-0.55 -0.45,-1 -1,-1 -0.55,0 -1,0.45 -1,1 0,0.55 0.45,1 1,1 0.55,0 1,-0.45 1,-1 z m 142.29283,-1.25 c 3.14583,-1.460964 3.22166,-1.854414 1.13508,-5.889407 -1.4845,-2.870699 -1.6745,-2.947408 -3.41006,-1.376744 C 679.07554,94.146596 678.27948,100 680.85965,100 c 0.40789,0 1.95282,-0.5625 3.43318,-1.25 z m -18.34386,-4.154647 c 2.07096,-3.869633 -1.14322,-6.476076 -3.89592,-3.159275 -0.88467,1.06596 -0.90716,1.968009 -0.0873,3.5 1.43845,2.687778 2.4067,2.604953 3.98318,-0.340725 z m -178.5852,-3.374926 c 0.69634,-1.126696 -6.36369,-9.338513 -7.45096,-8.666538 -1.75386,1.083942 -0.88861,3.666299 2.19295,6.544901 3.19388,2.983535 4.41964,3.478138 5.25801,2.121637 z M 543.5,90 c 0.33992,-0.55 0.16803,-1 -0.38197,-1 -0.55,0 -1.27811,0.45 -1.61803,1 -0.33992,0.55 -0.16803,1 0.38197,1 0.55,0 1.27811,-0.45 1.61803,-1 z m 135.93999,-7.102382 c 1.00139,-0.934918 -1.80196,-7.903786 -3.17381,-7.889816 -1.92395,0.01959 -4.09059,7.834458 -2.58851,9.33653 0.77029,0.770294 4.35044,-0.128555 5.76232,-1.446714 z M 511.81955,81.171672 C 511.9953,79.977252 511.67364,79 511.10473,79 c -1.32634,0 -3.2418,3.529592 -2.38205,4.38935 1.16132,1.161312 2.76908,0.01 3.09687,-2.217678 z m 144.98101,-0.265818 c 0.4159,-3.566048 -1.96613,-5.443911 -4.7222,-3.722718 -2.51966,1.573552 -2.59813,2.585042 -0.38987,5.025147 2.26241,2.499935 4.74229,1.868122 5.11207,-1.302429 z M 494.97073,75.9453 c -0.84881,-1.586002 -1.43695,-1.766156 -3.01272,-0.922829 -2.20391,1.179499 -2.6029,3.579627 -0.70801,4.259068 0.6875,0.246513 2.04322,0.04012 3.01271,-0.458654 1.3992,-0.719843 1.54521,-1.313273 0.70802,-2.877585 z M 482,75.622445 c 0,-2.66362 -2.35825,-5.137104 -3.9562,-4.149518 -1.50423,0.929668 -1.2868,2.601074 0.61119,4.698332 C 480.89859,78.650417 482,78.46971 482,75.622445 z M 644.5,70.5 c 0,-3.35612 -1.35002,-4.061372 -4.02716,-2.103797 -1.91769,1.402249 -1.91817,1.454231 -0.0326,3.53781 C 642.90016,74.65215 644.5,74.08704 644.5,70.5 z M 668.07569,69.418641 670.5,66.837282 667.23422,63.918641 C 665.43805,62.313388 663.59778,61 663.14474,61 c -1.43647,0 -2.9561,4.535953 -2.43424,7.265929 0.43192,2.259443 1.33425,3.007332 4.36519,3.61807 0.31662,0.0638 1.66662,-1.045611 3,-2.465358 z M 516.1875,67.316886 c -0.72187,-0.288871 -1.58438,-0.253344 -1.91667,0.07895 -0.33229,0.332292 0.25834,0.568641 1.3125,0.52522 1.16495,-0.04798 1.4019,-0.284941 0.60417,-0.604167 z m 16.61239,-5.219769 c -0.20576,-1.756686 -1.16798,-2.863817 -3.06561,-3.527281 -3.91327,-1.368192 -5.87699,0.775898 -5.09938,5.567763 l 0.58656,3.614519 3.93916,-1.547348 c 3.32376,-1.305611 3.89232,-1.947336 3.63927,-4.107653 z M 486,65 c -0.5887,-1.1 -1.20979,-2 -1.3802,-2 -0.1704,0 -1.12431,0.9 -2.1198,2 -1.77404,1.96029 -1.74663,2 1.3802,2 2.88029,0 3.0862,-0.19427 2.1198,-2 z m 18.85573,0.25 c 1.33291,-2.518721 1.89588,-18.257335 0.65168,-18.21879 -0.55407,0.01716 -2.80741,1.139859 -5.00741,2.494876 -4.57722,2.819184 -8.76899,3.338469 -7.86163,0.973914 0.354,-0.922491 -0.002,-1.5 -0.92439,-1.5 -2.11089,0 -3.02777,2.942359 -1.14233,3.665868 0.96858,0.371679 1.4251,1.560834 1.23314,3.212146 -0.2301,1.979473 0.18531,2.699384 1.69521,2.937834 1.1,0.173716 3.23322,2.086216 4.7405,4.25 2.95462,4.241541 5.14393,4.964386 6.61523,2.184152 z m 125.94253,-3.915833 c 0.43509,-2.930947 -2.13499,-4.759504 -4.73434,-3.368377 -2.7006,1.44532 -2.62266,3.460081 0.18608,4.809812 2.94272,1.414114 4.18269,1.02114 4.54826,-1.441435 z M 549.3184,58.026243 C 550.50842,56.916713 547.36095,50 545.66604,50 c -2.2958,0 -4.79444,4.640246 -4.06456,7.548323 0.56773,2.261988 1.00291,2.481191 3.77016,1.899062 1.7206,-0.36195 3.49664,-1.001464 3.94676,-1.421142 z m 105.26269,-1.115844 c 1.87273,-2.069349 1.85292,-2.12455 -2.04389,-5.695717 l -3.93496,-3.606117 -1.28969,3.160679 c -2.69175,6.596743 2.71904,11.168295 7.26854,6.141155 z m -93.16482,-0.878564 c 2.23412,-0.84941 2.46674,-1.370714 1.89654,-4.25 -0.90453,-4.567512 -4.08036,-6.853657 -6.9681,-5.016041 C 554.73345,47.791124 555.83144,57 557.56495,57 c 0.71767,0 2.45076,-0.435674 3.85132,-0.968165 z M 616,55 c 0,-1.1 0.45,-2 1,-2 0.55,0 1,-0.675 1,-1.5 0,-1.565377 -2.7213,-2.002581 -4.57294,-0.734687 -1.74595,1.195526 -2.35516,3.906585 -1.14892,5.112832 C 614.049,57.649 616,57.188676 616,55 z m -33.5,-4.391014 c 0,-6.237073 -6.69809,-5.956734 -7.31816,0.306292 -0.31269,3.158271 -0.25245,3.208168 3.5,2.899151 3.47124,-0.28586 3.81816,-0.577108 3.81816,-3.205443 z m 18.31642,0.741876 c -0.39798,-3.331957 -2.7327,-4.839674 -6.16164,-3.979064 C 592.52448,47.906469 592,48.627019 592,51.019052 592,53.891784 592.16577,54 596.56642,54 c 4.35237,0 4.55159,-0.124181 4.25,-2.649138 z M 526.3666,49.563247 c 1.25306,-1.912414 1.41133,-3.428611 0.73549,-7.046191 -0.47363,-2.535191 -1.09171,-4.840013 -1.37353,-5.121828 -0.58598,-0.585979 -7.18574,2.025418 -10.35141,4.095851 -3.31991,2.171315 -2.03067,5.783155 2.95982,8.291994 5.39956,2.71449 6.11992,2.694769 8.02963,-0.219826 z m 112.01839,-3.028064 c 2.13061,-3.251721 2.15054,-3.203338 -1.86544,-4.528731 C 632.58158,40.706805 631,41.271515 631,43.97723 c 0,5.396111 4.50332,6.955935 7.38499,2.557953 z m -95.56942,-5.029751 c 0.62513,-1.372013 0.86422,-3.856495 0.5313,-5.521073 -0.5699,-2.849497 -0.81706,-2.991472 -4.22608,-2.427518 -1.99144,0.329442 -4.14836,0.761397 -4.79317,0.959901 C 531.53528,35.376361 536.71151,44 540.01982,44 c 0.91253,0 2.17062,-1.122556 2.79575,-2.494568 z M 621.55887,39.5 c 1.92151,-1.484836 1.92151,-1.515164 0,-3 -1.99093,-1.538487 -4.75924,-1.966295 -5.82531,-0.90023 -0.88678,0.886784 1.39979,5.40023 2.73583,5.40023 0.63159,0 2.02186,-0.675 3.08948,-1.5 z M 561.4433,35.777494 C 562.29948,34.555115 563,32.704021 563,31.66395 c 0,-1.683414 -0.52152,-1.817421 -4.75,-1.220533 -9.36644,1.322154 -9.92335,1.90783 -4.98689,5.244431 4.17206,2.819937 6.25185,2.842729 8.18019,0.08965 z m 18.65233,0.154412 C 581.93834,34.619782 583,32.974854 583,31.431906 583,29.180286 582.62933,29 578,29 c -4.75215,0 -5,0.132415 -5,2.671259 C 573,33.962548 575.39272,38 576.75062,38 c 0.24235,0 1.74761,-0.930642 3.34501,-2.068094 z m 21.77626,0.96291 c 3.18441,-1.110091 5.67976,-4.193211 4.68999,-5.794694 -0.29184,-0.472199 -3.35015,-0.800399 -6.79625,-0.729333 -5.6666,0.116858 -6.23631,0.320422 -5.959,2.129211 0.16865,1.1 1.23101,2.7875 2.36079,3.75 2.43293,2.072697 1.81033,2.00232 5.70447,0.644816 z"
- style="fill:#b38959" />
- <path
- inkscape:connector-curvature="0"
- id="path3780"
- d="m 561.9733,222.64309 c -0.28968,-0.2914 -4.34674,-0.74602 -9.01568,-1.01027 -4.66894,-0.26425 -11.54735,-1.18973 -15.28535,-2.05664 C 533.93426,218.70928 529.60416,218 528.04981,218 c -4.19357,0 -18.85419,-4.47178 -26.26285,-8.01069 -6.58913,-3.14745 -27.01819,-18.95224 -36.48569,-28.22689 -8.14433,-7.97843 -11.91773,-16.37171 -17.73417,-39.44661 -4.74701,-18.83231 -3.07809,-41.87128 4.05428,-55.968163 C 454.80793,80.049531 457,77.729503 457,80.655049 c 0,1.044966 0.73482,2.949039 1.63293,4.231273 1.36862,1.953972 1.40908,2.473105 0.25,3.207193 -0.76061,0.481723 -1.88625,0.88275 -2.50142,0.891172 -0.67644,0.0093 -1.30435,2.880715 -1.58875,7.265313 -0.25865,3.9875 -1.16082,8.6 -2.00483,10.25 -2.59037,5.06406 -2.94963,7.19544 -1.46336,8.68171 0.76585,0.76585 1.60565,3.96327 1.86622,7.10537 0.41831,5.04431 0.25931,5.71292 -1.35852,5.71292 -2.13069,0 -2.273,0.93861 -0.67429,4.44738 1.44428,3.16985 7.02872,6.55262 10.81739,6.55262 4.10005,0 6.02463,0.95342 6.02463,2.98454 0,2.63519 -2.4414,4.19376 -5.40435,3.45011 C 460.4218,144.88905 460,145.12271 460,146.87254 c 0,1.45557 0.83418,2.28588 2.75,2.73722 3.16693,0.74609 8.25,5.1265 8.25,7.10956 0,0.73982 -1.0125,1.73556 -2.25,2.21274 -1.92931,0.74396 -2.01171,0.96414 -0.57814,1.54478 0.91952,0.37244 2.62402,0.16759 3.78777,-0.45524 1.16375,-0.62282 2.99461,-0.85351 4.06856,-0.51265 1.89098,0.60017 1.89872,0.52579 0.24534,-2.35508 -1.47798,-2.57523 -1.52534,-3.31484 -0.35258,-5.50617 1.23022,-2.29868 1.11612,-2.81493 -1.24133,-5.6166 -1.42784,-1.69689 -2.35031,-3.72568 -2.04995,-4.50843 0.85553,-2.22946 -7.22043,-9.86295 -9.73809,-9.20457 -1.53271,0.40081 -1.90355,0.15548 -1.47057,-0.97285 0.31844,-0.82985 0.57899,-2.37202 0.57899,-3.42704 0,-2.26587 2.53175,-2.58083 3.36163,-0.41821 0.33442,0.8715 1.831,1.5 3.5718,1.5 3.19433,0 5.53984,-2.7434 5.55728,-6.5 0.01,-2.05114 0.61088,-2.19186 3.90084,-0.91278 1.71158,0.66542 1.82597,0.38581 1.20228,-2.93874 -0.4893,-2.6082 -0.24025,-4.3152 0.85845,-5.88381 2.3212,-3.31398 2.04777,-7.76467 -0.47703,-7.76467 -2.63815,0 -4.55651,-4.5947 -2.80134,-6.70955 1.0459,-1.260234 1.32544,-1.172881 1.98927,0.621637 1.40185,3.789563 2.82903,2.310233 2.19984,-2.280234 -0.57223,-4.174869 0.70045,-6.956208 2.1269,-4.648165 C 484.44596,93.5306 488,93.19595 488,91.559017 488,90.766476 487.55,89.839919 487,89.5 c -1.90912,-1.1799 -0.98605,-3.368884 1.55332,-3.683578 2.37395,-0.294193 2.44848,-0.456925 1.06091,-2.316422 -1.26415,-1.694087 -1.80056,-1.811937 -3.50697,-0.770479 -1.26775,0.773742 -2.23895,0.866416 -2.61992,0.25 -1.06045,-1.715852 -3.91191,-1.024486 -6.3423,1.537756 -4.97137,5.241083 -7.48713,2.048097 -3.91865,-4.973519 l 2.36481,-4.653163 2.76857,2.177764 c 2.15448,1.694713 3.64155,2.060674 6.70422,1.649884 2.16459,-0.290333 4.18727,-0.120711 4.49484,0.376939 C 490.27825,80.259242 500,80.284626 500,79.122445 500,78.639789 499.325,77.684689 498.5,77 497.675,76.315311 497,75.170854 497,74.456762 497,73.089967 489.45527,65 488.18059,65 486.77956,65 485.30708,59.402179 486.12588,57.188744 487.19966,54.286042 488.82779,54.41685 490,57.5 c 0.52277,1.375 1.61424,2.5 2.42548,2.5 0.81124,0 3.16767,2.025 5.23651,4.5 2.06884,2.475 4.32969,4.5 5.02409,4.5 1.69433,0 4.10682,-4.852702 4.91022,-9.876851 0.35943,-2.247738 1.0473,-3.843418 1.5286,-3.545956 C 509.60621,55.874656 510,55.641476 510,55.059017 510,54.476558 509.55,54 509,54 c -0.55,0 -1,-1.773442 -1,-3.940983 0,-2.167541 -0.43457,-4.20956 -0.9657,-4.537821 -0.53114,-0.32826 -2.76321,0.320182 -4.96017,1.440983 -4.81887,2.458404 -5.18632,2.49375 -4.39147,0.422422 0.4922,-1.28267 0.17894,-1.47545 -1.52089,-0.935944 -1.2916,0.409938 -2.9864,0.08716 -4.27259,-0.813725 -2.53587,-1.776189 -4.9571,-1.060321 -11.39502,3.369083 C 476.42344,51.804748 474,52.721068 474,51.459507 474,48.597521 492.64276,32 495.85742,32 c 0.92307,0 3.3535,-1.138322 5.40096,-2.529605 2.04745,-1.391282 6.6329,-3.428491 10.18988,-4.52713 3.55698,-1.09864 6.71209,-2.393698 7.01135,-2.877907 0.66107,-1.069646 7.98592,-3.265084 20.04039,-6.006602 12.91069,-2.936246 53.01683,-4.456869 63.01185,-2.389093 3.84348,0.795143 9.01315,1.841818 11.48815,2.325945 11.73814,2.296061 35.07636,11.912929 44.855,18.483187 19.66927,13.215765 39.70748,41.876368 45.70666,65.374145 1.80927,7.0866 1.81179,7.40082 0.0694,8.67485 -2.73419,1.99933 -6.05815,16.47221 -3.7831,16.47221 1.1079,0 3.12588,-6.06329 3.16178,-9.5 0.0115,-1.1 0.4571,-2.675 0.99026,-3.5 2.50962,-3.88336 0.0395,18.44577 -3.01775,27.2801 -3.58501,10.35917 -10.70284,24.51015 -15.30977,30.43743 -6.78828,8.73376 -22.85019,23.83166 -31.29232,29.41418 -14.80821,9.79222 -43.73253,19.45631 -65.88016,22.01166 -11.27835,1.30127 -25.90207,2.12804 -26.5267,1.49972 z M 587.5,215 c 1.66816,-1.8433 1.67642,-2 0.10533,-2 -1.77882,0 -7.60533,2.70106 -7.60533,3.52568 0,1.39693 5.95055,0.18645 7.5,-1.52568 z m -26,0 c 0.33992,-0.55 -0.30852,-1 -1.44098,-1 -1.13246,0 -2.05902,0.45 -2.05902,1 0,0.55 0.64844,1 1.44098,1 0.79254,0 1.7191,-0.45 2.05902,-1 z m -12.06476,-0.89522 c 0.66883,-1.08219 -2.23752,-2.34501 -3.54179,-1.53893 -0.50934,0.31479 -0.66718,0.99125 -0.35074,1.50325 0.73258,1.18535 3.1682,1.20768 3.89253,0.0357 z m -11.97795,-2.03568 c 0.31644,-0.512 0.11397,-1.21604 -0.44993,-1.56455 -1.42561,-0.88108 -5.16454,0.43211 -4.46286,1.56745 0.74349,1.203 4.16876,1.20098 4.91279,-0.003 z M 524,208 c 0,-0.55 -0.92656,-1 -2.05902,-1 -1.13246,0 -1.7809,0.45 -1.44098,1 0.33992,0.55 1.26648,1 2.05902,1 0.79254,0 1.44098,-0.45 1.44098,-1 z m 106,-2.5 c 0,-0.825 -0.3949,-1.5 -0.87756,-1.5 -0.48265,0 -1.43775,0.675 -2.12244,1.5 -1.04007,1.2532 -0.89568,1.5 0.87756,1.5 1.21995,0 2.12244,-0.63782 2.12244,-1.5 z m -28.5,-1.5137 c 0,-0.81746 -1.0125,-1.6301 -2.25,-1.80585 -2.18881,-0.31086 -3.12347,1.61274 -1.54876,3.18745 1.16503,1.16503 3.79876,0.20716 3.79876,-1.3816 z m -4.95669,-6.05638 c 0.36374,-0.58854 1.6278,-1.46002 2.80902,-1.93661 1.9754,-0.79703 1.92181,-0.87162 -0.66807,-0.92992 -3.89594,-0.0877 -7.44376,1.84171 -5.56936,3.02878 1.83703,1.16342 2.63237,1.12578 3.42841,-0.16225 z M 503,196.19113 c 0,-2.53427 -2.05712,-4.86811 -5,-5.6726 -2.4208,-0.66177 -2.40496,-0.60275 0.5,1.86306 2.21836,1.88301 2.56265,2.55585 1.32143,2.58245 -0.92322,0.0198 -2.2942,-0.57967 -3.04664,-1.33211 C 494.48471,191.34185 491,190.61814 491,192.43261 c 0,0.88484 0.84524,1.56739 1.94098,1.56739 1.06754,0 2.23859,0.48153 2.60233,1.07008 0.71616,1.15877 4.19272,2.76441 6.20669,2.86653 0.6875,0.0349 1.25,-0.7506 1.25,-1.74548 z m 150.59996,-2.03429 c 12.18116,-8.88018 13.38543,-13.43723 2.21216,-8.37103 -4.94397,2.2417 -6.74764,3.64431 -7.72708,6.00889 -1.22182,2.94972 -0.86479,5.2053 0.82394,5.2053 0.43502,0 2.54596,-1.27942 4.69098,-2.84316 z m -18.70218,-2.12752 c 1.96162,-0.56259 4.03884,-0.60454 4.94077,-0.0998 2.07141,1.15922 6.14088,-0.46176 8.10024,-3.22655 2.37706,-3.35419 1.92291,-4.14761 -2.43879,-4.26064 -2.2,-0.057 -5.35,-0.40726 -7,-0.77835 -2.56624,-0.57715 -3.62659,-0.10135 -7.33367,3.29077 -5.88378,5.38391 -4.39705,7.40579 3.73145,5.07457 z M 494,188.96967 c 1.25727,-0.83793 0.97152,-1.48275 -1.76578,-3.98469 C 490.43805,183.34324 487.85055,182 486.48422,182 484.92006,182 484,181.43283 484,180.46862 c 0,-0.84227 -0.64021,-1.77706 -1.42268,-2.07732 -0.78248,-0.30027 -1.66282,-1.17173 -1.95633,-1.93659 -0.97436,-2.53915 1.20207,-2.5232 3.95592,0.029 2.60682,2.41592 5.43057,3.33677 5.41626,1.7663 -0.004,-0.4125 -1.62891,-1.85487 -3.61144,-3.20526 -1.98254,-1.3504 -4.28449,-3.4929 -5.11546,-4.76112 -1.67855,-2.56179 -7.94955,-5.93367 -9.0286,-4.85462 -0.37995,0.37995 1.07877,2.17647 3.2416,3.99228 3.86232,3.24261 3.90294,3.34645 2.27862,5.82547 C 475.9563,177.99633 476.33302,179 479.16667,179 480.175,179 481,179.44085 481,179.97968 c 0,0.53882 1.81813,1.90721 4.04029,3.04088 2.22216,1.13366 4.46103,3.1678 4.97525,4.52032 1.0226,2.68964 1.7183,2.93912 3.98446,1.42879 z M 525,186.5 c 0,-0.825 -0.675,-1.5 -1.5,-1.5 -2.60246,0 -1.75909,1.97081 1.25,2.92105 0.1375,0.0434 0.25,-0.59605 0.25,-1.42105 z m 65.62469,0.0357 c 0.95188,-2.48056 -3.82713,-10.99339 -6.37469,-11.3552 -1.39389,-0.19797 -2.25,-1.01336 -2.25,-2.14301 0,-2.22957 2.33512,-3.24242 5.59124,-2.42518 2.90984,0.73032 13.40876,-3.2523 13.40876,-5.08643 0,-0.68304 -2.31203,-2.44141 -5.13785,-3.90749 -6.05348,-3.14066 -9.36781,-2.7692 -8.4355,0.94543 0.4534,1.80649 0.005,2.76229 -1.87128,3.99191 -2.78787,1.82668 -4.55537,1.22544 -4.55537,-1.5496 0,-2.66586 -1.93159,-7.40782 -2.70319,-6.63622 -0.35598,0.35598 -0.68089,4.03812 -0.72203,8.18253 -0.0696,7.01014 0.082,7.57463 2.17522,8.09986 1.30943,0.32856 2.25,1.33064 2.25,2.39714 0,1.00792 0.45,2.11069 1,2.45061 0.55,0.33992 1,1.56854 1,2.73028 0,4.1684 5.34441,7.64173 6.62469,4.30537 z m 32.80207,-2.68929 c 2.20632,-4.42267 1.99366,-4.62333 -1.42676,-1.34636 -3.29063,3.15262 -3.76168,4.5 -1.57324,4.5 0.78472,0 2.13472,-1.41914 3,-3.15364 z M 497,177.94098 C 497,177.42344 496.55,177 496,177 c -0.55,0 -1,0.70156 -1,1.55902 0,0.85746 0.45,1.2809 1,0.94098 0.55,-0.33992 1,-1.04148 1,-1.55902 z M 671.07237,176.75 c 3.97241,-2.25216 6.5942,-7.20118 4.8443,-9.14437 -0.92213,-1.02399 -6.34826,0.96882 -8.50184,3.1224 -1.33157,1.33156 -2.0556,8.27197 -0.86295,8.27197 0.30354,0 2.33776,-1.0125 4.52049,-2.25 z m -10.68738,-2.21482 c 2.14896,-3.27972 2.03804,-4.26614 -0.57292,-5.09483 -1.55384,-0.49317 -2.64852,-0.1256 -3.77723,1.2683 -0.87412,1.07949 -2.81456,2.27023 -4.31208,2.64608 -1.49752,0.37586 -2.72276,1.3498 -2.72276,2.16432 0,1.10582 1.23737,1.48095 4.88499,1.48095 4.08858,0 5.14829,-0.40185 6.5,-2.46482 z m -107.12371,-3.21275 c -0.20021,-2.59986 0.49879,-3.70432 4.33268,-6.84591 2.51428,-2.06026 6.1092,-5.32934 7.98872,-7.26462 3.64784,-3.75606 4.61659,-8.2119 1.78535,-8.2119 -2.23512,0 -8.03528,3.60624 -12.97245,8.06561 -2.25744,2.03896 -5.02837,4.00045 -6.15762,4.35887 -3.52547,1.11893 -3.67424,3.79651 -0.37476,6.7446 2.18507,1.95236 2.83738,3.25989 2.42089,4.85255 -0.45711,1.74799 -0.1949,2.10287 1.3229,1.79045 1.43505,-0.29539 1.83526,-1.13961 1.65429,-3.48965 z m 76.69193,-1.94955 c 2.4648,-5.5721 2.55568,-6.78214 0.44863,-5.97359 -0.97252,0.37319 -3.1348,-0.60376 -5.52338,-2.49555 -2.81018,-2.2257 -4.58197,-2.94399 -6.23718,-2.52856 -1.54354,0.38741 -3.03268,-0.0912 -4.48036,-1.43989 -1.96351,-1.82928 -2.03967,-2.27599 -0.80605,-4.72773 1.59353,-3.16703 1.01999,-10.12648 -0.8951,-10.86137 -0.71692,-0.27511 -2.27671,0.0207 -3.46621,0.65726 -1.1895,0.6366 -4.77637,1.14495 -7.97082,1.12967 -4.47083,-0.0214 -6.2061,0.41201 -7.5367,1.88231 -2.28475,2.52461 -1.39951,4.44625 3.21524,6.97953 5.60607,3.07747 10.66326,6.90035 11.79872,8.919 1.70272,3.02714 8.15733,8.08604 10.31692,8.08604 1.12908,0 3.22599,-0.44601 4.65978,-0.99114 1.95262,-0.74239 2.56668,-0.67964 2.44662,0.25 -0.37124,2.8746 0.14298,5.74114 1.02989,5.74114 0.52426,0 1.87426,-2.0822 3,-4.62712 z M 608,145 c 0,-0.55 0.45,-1 1,-1 0.55,0 1,0.45 1,1 0,0.55 -0.45,1 -1,1 -0.55,0 -1,-0.45 -1,-1 z m 26,26 c 0,-0.55 -0.675,-1 -1.5,-1 -0.825,0 -1.5,0.45 -1.5,1 0,0.55 0.675,1 1.5,1 0.825,0 1.5,-0.45 1.5,-1 z m 13,-0.55902 C 647,170.19844 646.55,170 646,170 c -0.55,0 -1,0.47656 -1,1.05902 0,0.58246 0.45,0.7809 1,0.44098 0.55,-0.33992 1,-0.81648 1,-1.05902 z M 640.5,166 c 0.33992,-0.55 2.96635,-1 5.83651,-1 7.75151,0 12.90416,-4.18774 6.91349,-5.61884 -1.5125,-0.36131 -3.3612,-1.1404 -4.10821,-1.7313 -1.01531,-0.80312 -1.70171,-0.60461 -2.71875,0.78627 -0.97845,1.33811 -1.72035,1.57322 -2.64178,0.8372 -2.50997,-2.00491 -8.3023,-0.21286 -9.0937,2.81344 -0.85747,3.27898 4.12942,6.63641 5.81244,3.91323 z m -147.0651,-3.97525 c 1.41081,-0.53639 2.5651,-1.66139 2.5651,-2.5 0,-2.34602 1.81948,-1.8062 2.18045,0.64692 0.17575,1.19442 0.88205,2.35692 1.56955,2.58334 0.87515,0.28821 1.25,-0.93073 1.25,-4.06469 0,-4.95221 -0.35583,-5.23956 -6.89448,-5.56779 -2.41697,-0.12133 -5.68353,-0.88719 -7.25903,-1.70192 -2.14206,-1.1077 -3.36671,-1.21256 -4.85552,-0.41578 -2.61589,1.39999 -2.52916,2.77757 0.19992,3.17562 1.52883,0.22298 2.45088,1.32806 3.05123,3.65688 0.57015,2.21172 1.32105,3.16054 2.22634,2.81315 0.75131,-0.28831 1.61414,0.12239 1.9174,0.91266 0.65429,1.70506 0.74986,1.71596 4.04904,0.46161 z M 488.01531,157.25 C 488.00689,156.0125 488.45,155 489,155 c 1.25292,0 1.25292,1.06124 0,3 -0.78387,1.21296 -0.9723,1.06944 -0.98469,-0.75 z m 19.55419,0.17091 c -0.85009,-3.38705 -2.75094,-3.07506 -2.00503,0.32909 0.33142,1.5125 0.85963,3.425 1.17381,4.25 0.88025,2.31144 1.58552,-1.57376 0.83122,-4.57909 z m 161.89774,1.64244 c 2.27795,-4.40507 1.08048,-6.38806 -3.35688,-5.55896 -4.56219,0.85243 -6.11036,2.13313 -6.11036,5.0547 0,1.86149 0.63577,2.39309 3.25,2.71751 1.7875,0.22183 3.57594,0.47534 3.97432,0.56336 0.39838,0.088 1.40769,-1.16145 2.24292,-2.77661 z M 681.29406,158.75 c 2.19559,-1.63721 4.98522,-10.87072 3.67893,-12.17701 -0.62546,-0.62546 -2.23998,0.25357 -4.55312,2.47896 -4.82558,4.6425 -5.73682,6.48731 -4.41987,8.94805 1.23026,2.29876 2.89989,2.53529 5.29406,0.75 z m -136.68989,-5.47917 c -1.01652,-1.01651 -1.85525,0.51389 -1.02122,1.86338 0.63003,1.01942 0.86558,1.02021 1.2043,0.004 0.2316,-0.69479 0.14921,-1.53513 -0.18308,-1.86742 z M 525.8125,152.0625 c 0.25,-0.75 -0.125,-1.125 -0.875,-0.875 -0.72187,0.24062 -1.50937,1.02812 -1.75,1.75 -0.25,0.75 0.125,1.125 0.875,0.875 0.72187,-0.24063 1.50937,-1.02813 1.75,-1.75 z M 508,149.54797 C 508,147.43428 506.34992,146 503.91821,146 c -1.4931,0 -1.04857,3.19848 0.71544,5.14768 1.98716,2.19579 3.36635,1.54039 3.36635,-1.59971 z m 36.1038,0.15583 c -1.28349,-1.28349 -2.58505,-0.2915 -1.63484,1.24598 0.36808,0.59556 1.12735,0.79971 1.68727,0.45366 0.683,-0.42212 0.66575,-0.98146 -0.0524,-1.69964 z m 100.14318,-1.19215 C 643.70735,145.68875 642,146.10466 642,149.05902 c 0,1.06754 0.6126,1.94098 1.36133,1.94098 0.91116,0 1.20403,-0.82286 0.88565,-2.48835 z M 580,138.81835 c 0,-2.89123 -1.43656,-2.13632 -4.32237,2.27139 -3.9627,6.05253 -3.43866,8.2671 0.82315,3.47861 1.92457,-2.16241 3.49922,-4.74991 3.49922,-5.75 z m 9,6.68165 c -0.68469,-0.825 -2.20229,-1.48405 -3.37244,-1.46456 -2.00407,0.0334 -1.98245,0.11838 0.37244,1.46456 3.27489,1.87209 4.5537,1.87209 3,0 z m 61.1038,-0.7962 c -1.28349,-1.28349 -2.58505,-0.2915 -1.63484,1.24598 0.36808,0.59556 1.12735,0.79971 1.68727,0.45366 0.683,-0.42212 0.66575,-0.98146 -0.0524,-1.69964 z m 21.09404,-0.56619 c 0.38381,-0.35069 1.4066,-2.33528 2.27287,-4.41022 1.45027,-3.47379 1.44363,-3.82303 -0.0838,-4.40915 -0.91233,-0.35009 -2.38512,-0.10185 -3.27286,0.55165 -0.88775,0.65349 -2.40158,1.45259 -3.36408,1.77577 -0.9625,0.32318 -1.75,1.26522 -1.75,2.09342 0,1.22511 0.27961,1.27375 1.5,0.26092 1.26313,-1.0483 1.5,-0.86235 1.5,1.17756 0,1.33234 -0.5625,3.01302 -1.25,3.73483 -1.02189,1.07291 -0.79379,1.18014 1.25,0.58761 1.375,-0.39863 2.81403,-1.01171 3.19784,-1.36239 z m -8.53965,-3.81275 c -1.03181,-1.03181 -2.5595,0.76876 -1.96552,2.31662 0.54064,1.40891 0.70603,1.39748 1.54799,-0.10702 0.51847,-0.92646 0.70636,-1.92078 0.41753,-2.2096 z M 507.21402,140.25 c 0.64413,-1.5125 2.09698,-3.54302 3.22856,-4.51226 1.92655,-1.65017 1.9461,-1.82826 0.30742,-2.7997 -0.9625,-0.57058 -1.75,-2.00107 -1.75,-3.17886 0,-2.03268 -0.0679,-2.04856 -1.3372,-0.31271 -1.0973,1.50064 -1.85978,1.65344 -4.25,0.85169 -2.6161,-0.87752 -2.9128,-1.41658 -2.9128,-5.29213 0,-5.01223 -1.48643,-6.0196 -4.47397,-3.03206 -2.20634,2.20634 -4.02603,1.93876 -4.02603,-0.592 0,-0.825 -0.45,-1.22189 -1,-0.88197 -1.37824,0.8518 -1.28809,0.47194 1.02334,-4.31217 2.02433,-4.18988 3.4652,-5.2222 4.20234,-3.01078 0.5135,1.5405 2.77432,0.12576 2.77432,-1.73607 C 499,110.64844 498.28545,110 497.4121,110 c -1.29851,0 -1.46474,-0.72897 -0.9121,-4 0.73339,-4.34091 -0.26989,-5.19936 -2.29213,-1.96125 -1.13034,1.80997 -1.44113,1.87084 -2.76948,0.54249 -1.6314,-1.63139 -4.43839,-1.09672 -4.43839,0.84541 0,0.66698 1.13689,2.20119 2.52643,3.40938 3.01949,2.62542 2.58627,3.81597 -3.66234,10.06458 -4.5866,4.58661 -4.58043,6.53109 0.0273,8.59939 1.88049,0.84411 2.13735,1.54562 1.64765,4.5 -0.50102,3.02266 -0.41852,3.22723 0.60495,1.5 2.18928,-3.6947 3.32798,-3.61533 3.97313,0.27693 0.54326,3.27751 0.70681,3.4538 1.36663,1.47307 1.1296,-3.39095 2.51626,-2.7021 2.51626,1.25 0,2.44444 0.45238,3.5 1.5,3.5 0.92366,0 1.5,-0.93789 1.5,-2.44098 0,-1.34254 0.45318,-2.72107 1.00706,-3.06339 1.46608,-0.90608 2.46308,2.43423 1.12572,3.77159 -0.62303,0.62303 -1.13278,1.68648 -1.13278,2.36323 0,1.05897 0.98661,1.47697 5.27144,2.23337 0.42429,0.0749 1.29845,-1.10132 1.94258,-2.61382 z M 558.25,141.31044 C 561.63861,140.44835 559.0858,133 555.40172,133 c -0.70857,0 -1.87633,-0.79993 -2.59502,-1.77763 C 551.25224,129.1077 546.06027,125 544.94187,125 c -0.43363,0 -2.12541,1.125 -3.7595,2.5 C 536.97784,131.03788 536,130.67594 536,125.58179 536,118.99004 535.3438,118 530.9748,118 525.7994,118 524,118.83762 524,121.24675 c 0,1.11802 -0.74375,2.57661 -1.65278,3.2413 -2.0593,1.50581 -0.95636,3.50019 1.9618,3.54739 1.20504,0.0195 3.31598,0.67854 4.69098,1.46456 1.375,0.78602 3.46436,1.44508 4.64301,1.46456 1.17866,0.0195 2.41616,0.74724 2.75,1.61723 0.81234,2.11691 0.82798,2.05436 -0.96137,3.84371 -0.95922,0.95922 -1.31957,2.35225 -0.92779,3.58662 0.5936,1.87027 1.42353,2.00819 11.31836,1.8809 5.87278,-0.0756 11.46529,-0.33771 12.42779,-0.58258 z m -32.67997,-17.19713 c -0.30141,-0.48768 0.0695,-1.39917 0.8242,-2.02553 1.04729,-0.86917 1.50193,-0.80076 1.92009,0.28893 0.85481,2.22762 -1.51428,3.7268 -2.74429,1.7366 z m 2.87281,14.78791 c 4.19998,-2.47805 4.42909,-3.54682 1.08677,-5.06968 -3.21906,-1.4667 -5.52961,0.32625 -5.52961,4.2909 0,3.43729 -0.0486,3.42878 4.44284,0.77878 z M 481,137.41667 c 0,-0.87084 -0.53438,-1.40521 -1.1875,-1.1875 C 477.95828,136.84724 477.65074,139 479.41667,139 480.2875,139 481,138.2875 481,137.41667 z M 624.64733,134.314 c -0.28285,-0.28285 -0.99542,-0.2169 -1.5835,0.14655 -0.74504,0.46046 -0.69608,1.32463 0.16149,2.85014 l 1.23072,2.18931 0.35278,-2.33586 c 0.19403,-1.28473 0.12136,-2.56729 -0.16149,-2.85014 z m 63.09208,3.436 c 0.54136,-0.6875 1.26285,-3.3875 1.60331,-6 0.58654,-4.5008 0.49509,-4.75 -1.74316,-4.75 -2.78475,0 -8.08245,6.29922 -7.20994,8.57296 0.31133,0.8113 1.58852,1.88575 2.83821,2.38768 3.08606,1.23948 3.38053,1.22573 4.51158,-0.21064 z m -68.2922,-1.83541 c -0.32197,-0.52097 -1.01165,-0.68378 -1.53262,-0.3618 -0.52097,0.32197 -0.68378,1.01165 -0.3618,1.53262 0.32197,0.52097 1.01165,0.68378 1.53262,0.3618 0.52097,-0.32197 0.68378,-1.01165 0.3618,-1.53262 z m -99.0542,-3.49638 c 0.93873,-2.44628 0.7352,-2.7695 -0.89301,-1.41821 -1.66238,1.37965 -1.99022,3 -0.60699,3 0.49116,0 1.16616,-0.7118 1.5,-1.58179 z m 67.63174,-0.98331 c 1.45698,-3.83214 1.22062,-3.99171 -1.52475,-1.0294 -2.91405,3.14431 -3.03619,3.5945 -0.97525,3.5945 0.83861,0 1.96361,-1.15429 2.5,-2.5651 z m -9.95972,-1.85654 c -0.90842,-1.09458 -0.8971,-1.87439 0.0492,-3.38964 0.9081,-1.4541 0.98838,-3.75945 0.30742,-8.82836 -0.86011,-6.40245 -1.08827,-6.86036 -3.41822,-6.86036 -2.40627,0 -2.49376,0.22796 -2.41837,6.30169 0.0599,4.82381 0.64538,7.22133 2.49659,10.2231 1.3301,2.15678 2.81097,3.93352 3.29081,3.94831 0.47985,0.0148 0.34151,-0.61284 -0.30741,-1.39474 z m 96.68419,-4.741 C 676.27671,121.65037 675.45648,119 672.9427,119 c -2.44134,0 -3.68266,2.41172 -3.14096,6.10251 0.54392,3.70597 3.11009,3.56844 4.94748,-0.26515 z m -79.24516,-1.55095 c 1.87115,-2.04247 3.22731,-3.88837 3.01369,-4.102 -0.62517,-0.62517 -4.26845,2.22893 -6.55356,5.13399 -3.1796,4.0422 -0.35406,3.21847 3.53987,-1.03199 z M 666,124.44098 C 666,123.64844 665.59814,123 665.10699,123 c -1.10376,0 -2.17899,2.59467 -1.39861,3.37505 0.87532,0.87532 2.29162,-0.32 2.29162,-1.93407 z m -148.97994,-0.96515 c 1.52272,-1.83477 1.77271,-1.5856 -5.01085,-4.99439 -7.71054,-3.87461 -10.9838,-4.71122 -11.64913,-2.9774 -0.70933,1.84848 3.60603,6.41169 6.61065,6.99032 1.31035,0.25235 2.84299,0.91936 3.40586,1.48223 1.51756,1.51756 5.19869,1.24009 6.64347,-0.50076 z M 557.8,120.8 c 1.9916,-1.9916 1.36562,-4.30144 -1.8,-6.64188 -1.65,-1.2199 -3.00224,-2.76702 -3.00497,-3.43806 -0.0101,-2.49027 -4.4425,-6.86932 -6.25065,-6.17546 -2.31985,0.89021 -2.23787,5.12092 0.12372,6.38481 1.21224,0.64877 1.73464,1.80213 1.48797,3.28518 -0.28325,1.70299 0.55593,2.98622 3.29293,5.03541 4.16956,3.12173 4.49681,3.20419 6.151,1.55 z M 657,118.08179 C 657,116.0303 655.70327,114 654.39301,114 c -1.70962,0 -1.81999,2.17302 -0.19301,3.8 1.42624,1.42624 2.8,1.56449 2.8,0.28179 z m 31.79737,-5.81858 c 0.24846,-5.21084 0.0504,-6.14202 -1.20405,-5.66065 -2.02485,0.77701 -5.9402,9.05109 -5.19813,10.9849 0.38416,1.00112 1.56523,1.4347 3.34912,1.22951 2.64169,-0.30386 2.76799,-0.57498 3.05306,-6.55376 z M 524,105.30383 c 0,-1.96265 -2.08731,-1.57044 -4.69879,0.88293 -3.10372,2.91579 -4.62463,1.42772 -3.29154,-3.22049 1.86049,-6.487128 0.57635,-7.804885 -3.69522,-3.791956 C 511.0415,100.37019 510,100.88993 510,100.3293 c 0,-0.560628 0.9,-1.833814 2,-2.8293 2.81172,-2.54457 2.61602,-4.850914 -0.36328,-4.281384 -1.90188,0.363567 -2.26959,0.09347 -1.88337,-1.383423 0.67723,-2.589717 -2.38729,-2.387695 -3.79919,0.250453 -0.61391,1.147106 -1.33592,1.865926 -1.60447,1.597379 -0.26855,-0.268547 0.0884,-1.411623 0.79317,-2.540168 1.512,-2.421097 0.51371,-3.932651 -1.49582,-2.264888 -0.77071,0.639633 -2.91909,1.041259 -4.77417,0.892501 -2.97206,-0.23833 -3.40876,0.0386 -3.6749,2.330426 -0.22467,1.934687 0.41569,3.070285 2.5,4.433405 1.54111,1.00788 3.43314,2.356364 4.2045,2.996631 2.52763,2.098058 7.52374,6.355208 11.59753,9.882188 l 4,3.46309 3.25,-3.13427 c 1.7875,-1.72385 3.25,-3.721 3.25,-4.43811 z m 148.82284,1.81901 c 0.41803,-4.37288 -0.80139,-5.54537 -4.17071,-4.0102 -2.78167,1.26741 -3.01527,1.92958 -2.00777,5.69117 0.47652,1.77914 1.21356,2.23462 3.23634,2 2.17031,-0.25173 2.67464,-0.88271 2.94214,-3.68097 z M 652,107.62244 c 0,-0.75765 -0.675,-1.93775 -1.5,-2.62244 -1.24637,-1.0344 -1.5,-0.9142 -1.5,0.71089 0,1.07568 0.3,2.25578 0.66667,2.62244 1.11681,1.11682 2.33333,0.74619 2.33333,-0.71089 z m -117.84264,-5.20382 c 1.69984,-0.87901 4.09335,-1.32153 5.38906,-0.99633 2.13424,0.53566 4.32586,-0.88335 3.16194,-2.047264 -0.27055,-0.270551 -4.59061,-0.660624 -9.60014,-0.866829 C 524.0904,98.136999 524,98.15677 524,100.50022 c 0,1.81445 0.64189,2.46417 2.75,2.78353 1.5125,0.22912 3.10985,0.48401 3.54966,0.56642 0.43981,0.0824 2.17578,-0.56179 3.8577,-1.43155 z M 488.25,100.26992 c 0.9625,-0.276753 1.75,-1.125699 1.75,-1.886551 0,-2.125627 -4.76806,-1.685265 -5.96482,0.55089 -1.46927,2.745351 -1.29064,3.384891 0.71482,2.559281 0.9625,-0.39625 2.5375,-0.94688 3.5,-1.22362 z m 196.59636,-0.843162 c 3.65071,-1.821211 3.72365,-2.163589 1.46843,-6.892831 -2.01246,-4.220158 -2.55217,-4.318894 -5.20099,-0.951465 -2.79956,3.559059 -3.49961,6.247742 -2.07397,7.965526 1.51071,1.820292 1.9323,1.811492 5.80653,-0.12123 z m -18.44174,-4.101279 c 1.36417,-1.870591 1.62766,-3.050752 0.92856,-4.159056 -1.62202,-2.57143 -3.00891,-2.415999 -6.19012,0.693736 l -3.03551,2.967305 2.19622,1.533816 c 3.03374,2.118725 3.90867,1.97018 6.10085,-1.035801 z m -19.69268,-6.068082 c -1.37282,-1.372818 -3.06941,-2.304908 -3.7702,-2.071309 -0.83738,0.279126 -0.29777,1.330099 1.57412,3.065807 3.57222,3.312355 5.58944,2.398857 2.19608,-0.994498 z M 544,90 c 0,-0.55 -0.64844,-1 -1.44098,-1 -0.79254,0 -1.7191,0.45 -2.05902,1 -0.33992,0.55 0.30852,1 1.44098,1 C 543.07344,91 544,90.55 544,90 z m 73.52134,-5.976419 c -0.98375,-1.08703 -2.24666,-1.693341 -2.80648,-1.347356 -0.60598,0.374516 -0.27224,1.174259 0.82478,1.976418 2.76303,2.020379 4.01869,1.621788 1.9817,-0.629062 z m 63.15548,-1.623759 c 0.52129,-1.358464 -3.26374,-8.405272 -4.50838,-8.393499 C 675.1395,74.016055 672,79.946965 672,81.88104 c 0,2.98837 1.89831,4.05037 5.1893,2.903126 1.63341,-0.56941 3.20279,-1.642365 3.48752,-2.384344 z M 656.8,83.8 c 1.57641,-1.576405 1.52095,-3.978812 -0.14441,-6.256329 -0.99818,-1.365093 -2.03934,-1.664173 -4.04282,-1.161331 -3.72553,0.935049 -4.31155,3.244937 -1.56497,6.168541 2.55977,2.724754 3.97027,3.03105 5.7522,1.249119 z M 512.37034,81.777524 c 0.80432,-1.277228 0.75,-2.052708 -0.21014,-3 -1.05254,-1.038463 -1.56294,-0.914283 -2.72752,0.663606 C 508.64471,80.508751 508,82.004247 508,82.764454 c 0,1.850983 3.01146,1.170921 4.37034,-0.98693 z M 537,78.5 c 1.01247,-1.219951 0.96484,-1.5 -0.25511,-1.5 -0.825,0 -2.0602,0.675 -2.74489,1.5 -1.01247,1.219951 -0.96484,1.5 0.25511,1.5 0.825,0 2.0602,-0.675 2.74489,-1.5 z m -1.75,-3.486345 C 535.6625,75.006145 536,74.325 536,73.5 c 0,-2.179219 -2.39224,-1.837179 -4.59501,0.656992 -1.89731,2.148294 -1.89491,2.154398 0.59501,1.513654 1.375,-0.353835 2.8375,-0.649481 3.25,-0.656991 z M 620.5,74 c -0.33992,-0.55 -1.04148,-1 -1.55902,-1 C 618.42344,73 618,73.45 618,74 c 0,0.55 0.70156,1 1.55902,1 0.85746,0 1.2809,-0.45 0.94098,-1 z m 24.78204,-2.346122 c 0.62348,-1.870434 0.52658,-3.179548 -0.30994,-4.1875 -1.63364,-1.968406 -2.58757,-1.850906 -5.06198,0.6235 l -2.08988,2.089878 2.28225,2.429334 c 2.73257,2.908697 3.9675,2.680953 5.17955,-0.955212 z m -129.24155,0.158064 c 3.62483,-2.679949 3.75529,-4.492237 0.43238,-6.006255 -3.09673,-1.410968 -4.09287,-0.526664 -5.00634,4.444313 -0.8121,4.419307 0.22852,4.774665 4.57396,1.561942 z m 17.9238,-1.412382 C 535.18049,69.237119 535.19251,69 534.03528,69 531.72861,69 526,71.338662 526,72.280344 c 0,1.255604 6.21953,-0.213151 7.96429,-1.880784 z m 135.39782,-1.017714 c 1.86126,-2.554156 1.86061,-2.556839 -1.44617,-5.968576 -3.77024,-3.889898 -5.4027,-4.240793 -6.88076,-1.479011 -1.15595,2.159926 -1.39937,8.36822 -0.36851,9.399074 1.68666,1.686667 6.89623,0.517501 8.69544,-1.951487 z M 529.32186,67.405998 C 533.37275,66.025721 534,65.443139 534,63.060985 c 0,-3.107421 -2.30214,-5.609742 -6,-6.521723 -3.56947,-0.880319 -5.30314,2.256453 -4.43751,8.028912 C 523.92802,67.005678 524.32083,69 524.4354,69 c 0.11458,0 2.31348,-0.717301 4.88646,-1.594002 z m 102.06052,-4.650416 c 0.72895,-1.155631 0.62851,-2.366717 -0.34754,-4.190481 -1.60759,-3.003812 -2.26461,-3.115881 -5.57002,-0.950091 -3.21124,2.104085 -3.11985,3.966325 0.28518,5.810638 3.16753,1.715677 4.20537,1.592209 5.63238,-0.670066 z M 547.53212,59.551027 C 549.43945,58.754091 551,57.909047 551,57.673151 c 0,-0.235897 -0.68922,-2.078439 -1.5316,-4.094538 -2.09551,-5.015259 -4.22953,-5.613511 -7.12333,-1.996961 -2.66952,3.336251 -2.68243,3.400824 -1.36982,6.853248 1.12798,2.96682 1.8382,3.087714 6.55687,1.116127 z M 654.36514,57.92742 C 655.81431,56.787501 657,55.308801 657,54.641419 c 0,-1.808706 -8.22567,-7.815746 -9.271,-6.770419 -0.48776,0.487757 -1.13499,2.737014 -1.4383,4.998347 -0.91401,6.814466 2.84665,9.170256 8.07444,5.058073 z m -90.14131,-1.822543 c 0.39811,-0.358897 0.44661,-2.360877 0.10778,-4.448844 -0.79593,-4.9047 -4.26626,-7.462467 -7.88678,-5.812848 -2.22983,1.015979 -2.41444,1.546643 -1.87567,5.391851 0.9645,6.883618 1.00457,6.931634 5.16778,6.191435 2.06968,-0.367979 4.08878,-0.962696 4.48689,-1.321594 z M 616.35434,56.25 c 0.32318,-0.9625 1.15305,-2.525114 1.84415,-3.472476 1.73946,-2.384439 -0.23342,-4.236558 -3.61004,-3.389078 C 610.31697,50.460518 609.67219,58 613.85198,58 c 1.05312,0 2.17918,-0.7875 2.50236,-1.75 z M 531.55385,52.087132 C 530.77866,50.832851 528,50.60835 528,51.8 c 0,0.44 0.54,1.34 1.2,2 1.39799,1.397992 3.38351,-0.04684 2.35385,-1.712868 z m 50.32115,1.926523 c 2.12974,-0.01225 2.30985,-0.339429 1.74406,-3.168347 -1.15449,-5.772465 -4.22003,-7.421384 -7.79032,-4.19032 -1.81766,1.644959 -2.48935,6.351072 -1.10417,7.73625 0.39852,0.398514 1.63602,0.479659 2.75,0.180321 1.11399,-0.299337 3.09418,-0.550394 4.40043,-0.557904 z m 19.82355,-0.670478 c 0.89799,-2.340127 -1.85304,-6.783603 -4.43038,-7.155968 C 593.7553,45.679682 591,47.737444 591,50.868517 591,54.587526 591.56888,55 596.69805,55 c 3.14088,0 4.54299,-0.464565 5.0005,-1.656823 z m -74.02226,-3.29652 c 1.30265,-3.451115 0.57602,-11.592371 -1.16351,-13.036048 -1.33904,-1.11131 -8.14151,0.860879 -12.24641,3.550515 -2.47705,1.623023 -3.03101,5.562056 -1.01637,7.227038 2.48946,2.057389 11.12133,6.006574 12.21309,5.58763 0.61524,-0.23609 1.61118,-1.734201 2.2132,-3.329135 z M 638.93191,47.09563 C 640.06936,45.498226 641,43.929265 641,43.60905 641,42.969981 634.29845,40 632.85644,40 c -0.49463,0 -1.4035,1.106566 -2.01973,2.459036 -0.89722,1.969188 -0.78876,2.965204 0.54449,5 2.1958,3.351204 5.00183,3.216153 7.55071,-0.363406 z m -95.53089,-5.198066 c 0.76948,-1.830038 1.03084,-4.393342 0.63728,-6.25 -0.63813,-3.010459 -0.85805,-3.134924 -5.04871,-2.857378 -5.29886,0.350942 -6.96888,1.559128 -6.21542,4.496582 1.89194,7.375988 8.29589,10.154539 10.62685,4.610796 z M 565,41 c 0,-0.55 -0.47656,-1 -1.05902,-1 -0.58246,0 -0.7809,0.45 -0.44098,1 0.33992,0.55 0.81648,1 1.05902,1 C 564.80156,42 565,41.55 565,41 z m 56.77749,-0.556704 C 622.99987,39.587109 624,38.28113 624,37.541121 624,36.246977 619.14628,34 616.35078,34 c -1.8644,0 -1.71002,4.497903 0.22065,6.428571 1.95218,1.952181 2.438,1.953555 5.20606,0.01472 z M 561.92742,36.365141 C 563.06734,34.915969 564,32.614119 564,31.249918 c 0,-2.435968 -0.10292,-2.467542 -5.75,-1.76397 -5.80226,0.722906 -9.25,1.962525 -9.25,3.325796 0,0.99576 8.0784,6.188256 9.62759,6.188256 0.67499,0 2.15991,-1.185686 3.29983,-2.634859 z m 42.68911,0.09514 c 2.84178,-1.787721 3.68448,-5.242622 1.54327,-6.327144 -0.91289,-0.46238 -4.2473,-0.892104 -7.4098,-0.954942 -5.70239,-0.113304 -5.75,-0.09028 -5.75,2.781199 0,1.943072 0.87399,3.582929 2.65713,4.985547 2.75888,2.17014 4.92561,2.052931 8.9594,-0.48466 z m -23.00432,-0.981582 c 1.54031,-1.54031 2.39806,-3.388449 2.20455,-4.75 -0.27965,-1.967588 -0.99041,-2.263831 -6.06676,-2.528599 l -5.75,-0.299904 0,3.221163 C 572,34.798445 574.42046,38 577.20044,38 c 1.03976,0 3.02506,-1.134587 4.41177,-2.521305 z M 469,148.5 c 0,-1.68889 0.45833,-2.51389 1.25,-2.25 0.6875,0.22917 1.25,1.24167 1.25,2.25 0,1.00833 -0.5625,2.02083 -1.25,2.25 -0.79167,0.26389 -1.25,-0.56111 -1.25,-2.25 z m -8.8,-27.7 c -1.39396,-1.39396 -1.54785,-4.70269 -0.30961,-6.65689 0.58569,-0.92434 1.82561,-1.14476 3.88949,-0.69146 1.83632,0.40333 3.29924,0.22935 3.71395,-0.44166 0.49557,-0.80185 1.07326,-0.78423 2.0952,0.0639 C 471.71981,114.84228 471.28894,116 468.5,116 c -1.42752,0 -2.5,0.577 -2.5,1.34501 0,1.23608 -3.0324,4.65499 -4.12874,4.65499 -0.25919,0 -1.01126,-0.54 -1.67126,-1.2 z m 6.16163,-12.3 c -0.31659,-0.825 -1.15432,-1.5 -1.86163,-1.5 -3.76718,0 -1.90211,-6.17464 2.71544,-8.989942 4.39176,-2.677639 5.48909,-2.53113 5.54204,0.739942 0.0245,1.5125 0.3598,3.9523 0.74514,5.42177 0.60118,2.29256 0.26746,2.89577 -2.35134,4.25 -3.76017,1.94446 -4.07156,1.94954 -4.78965,0.0782 z M 474,89.5 c 0,-0.833333 0.88889,-1.5 2,-1.5 2.38425,0 2.65261,1.535591 0.41821,2.393011 C 474.18315,91.250687 474,91.183053 474,89.5 z m -2.2979,-17.831899 c -0.97904,-1.494204 -1.2102,-2.841328 -0.64348,-3.75 1.30098,-2.085967 4.36246,0.122896 4.7578,3.432761 0.40325,3.37603 -1.98925,3.560506 -4.11432,0.317239 z M 481,62.059017 C 481,61.476558 481.45,61 482,61 c 0.55,0 1,0.198442 1,0.440983 0,0.242541 -0.45,0.719098 -1,1.059017 -0.55,0.339919 -1,0.141476 -1,-0.440983 z m -5.82332,-4.701834 c 0.38654,-1.96404 3.43474,-4.079099 4.43589,-3.077944 C 480.40403,55.070701 477.2071,59 475.77169,59 c -0.50509,0 -0.77284,-0.739268 -0.59501,-1.642817 z M 483.75,50.805556 c 2.31279,-2.312792 3.90534,-1.955725 2.90492,0.651316 C 486.32924,52.305592 485.04865,53 483.80916,53 l -2.2536,0 2.19444,-2.194444 z"
- style="fill:#9a6e4f" />
- <path
- inkscape:connector-curvature="0"
- id="path3782"
- d="m 551.5,220.87969 c -4.95,-0.46752 -11.25,-1.32763 -14,-1.91136 -2.75,-0.58374 -6.95762,-1.29308 -9.35027,-1.57631 -6.65862,-0.78822 -20.58574,-5.07744 -26.94632,-8.29881 -3.13687,-1.5887 -9.26153,-5.7471 -13.61035,-9.24088 -4.34881,-3.49378 -9.74881,-7.76468 -12,-9.4909 -12.62389,-9.68001 -19.1657,-19.37968 -23.92584,-35.47526 -5.89387,-19.92908 -6.94903,-27.76446 -5.68328,-42.20294 1.07354,-12.24598 2.93104,-19.023726 5.99626,-21.879407 1.06023,-0.987756 2.22443,-3.377669 2.58711,-5.310917 0.89875,-4.790766 1.80861,-5.024822 3.74534,-0.963467 1.61685,3.390584 1.60591,3.452898 -0.70862,4.033808 -2.13456,0.535738 -2.39396,1.250032 -2.81935,7.763389 -0.30074,4.604574 -1.24132,8.681024 -2.62659,11.383524 -2.5303,4.93631 -2.61103,5.69405 -0.79958,7.5055 0.74719,0.74718 1.57171,3.92932 1.83228,7.07142 C 453.6091,127.33139 453.4501,128 451.83227,128 450.82452,128 450,128.47235 450,129.04966 c 0,1.78539 2.99649,6.95034 4.03229,6.95034 0.53952,0 1.95911,1.125 3.15466,2.5 1.62869,1.87316 3.15827,2.5 6.10037,2.5 3.16976,0 3.80965,0.30491 3.31967,1.58179 -0.33385,0.86998 -0.60699,1.99498 -0.60699,2.5 0,1.56017 -3.02708,1.01122 -3.67055,-0.66564 -0.48935,-1.27522 -0.77253,-1.32393 -1.4533,-0.25 -1.76812,2.78927 -0.93405,4.87227 2.20207,5.49949 1.90949,0.3819 3.39912,1.45967 3.9234,2.83862 0.46484,1.22263 1.55464,2.49522 2.42178,2.82797 2.26413,0.86883 1.94191,2.59135 -0.6734,3.59983 -1.92931,0.74396 -2.01171,0.96414 -0.57814,1.54478 0.91952,0.37244 2.62402,0.16759 3.78777,-0.45524 1.16375,-0.62282 2.99461,-0.85351 4.06856,-0.51265 1.89806,0.60242 1.904,0.53472 0.21223,-2.42163 -1.4397,-2.51587 -1.52444,-3.38858 -0.49042,-5.05078 1.71958,-2.76427 1.60673,-3.35958 -1.21382,-6.403 -1.35511,-1.46218 -2.22795,-3.27321 -1.93965,-4.0245 0.58635,-1.52799 -4.87791,-7.77015 -8.34653,-9.53476 -1.41517,-0.71994 -2.25,-2.05918 -2.25,-3.60946 0,-2.71477 2.42322,-3.41026 3.36163,-0.96482 0.33442,0.8715 1.831,1.5 3.5718,1.5 3.19433,0 5.53984,-2.7434 5.55728,-6.5 0.01,-2.05359 0.60944,-2.19236 3.91786,-0.90625 1.70907,0.66437 1.84007,0.39945 1.25327,-2.53456 -0.54695,-2.73474 -0.24248,-3.60122 1.84143,-5.24042 1.3732,-1.08016 2.48242,-2.71877 2.46493,-3.64135 C 483.92299,107.79313 481.57452,105 479.61501,105 c -2.3047,0 -4.04338,-4.77892 -2.4411,-6.70955 1.0459,-1.260234 1.32544,-1.172881 1.98927,0.621637 1.30263,3.521343 2.99958,2.472403 2.27225,-1.404557 -0.92479,-4.929567 -0.0347,-6.898738 2.42416,-5.363142 1.90717,1.191046 1.83712,2.6871 -0.38192,8.156412 -0.62059,1.52956 -0.35147,1.70563 1.78675,1.16897 2.5522,-0.64056 5.27794,1.51611 2.91263,2.30455 -1.90904,0.63634 -1.35651,2.70897 1.34938,5.06171 3.01071,2.61778 2.58035,3.8219 -3.56086,9.96311 -3.94907,3.94907 -4.09103,4.29613 -2.87812,7.03629 0.94424,2.1332 1.78483,2.74922 3.23424,2.3702 1.77325,-0.46372 1.89594,-0.14313 1.29779,3.39112 -0.55724,3.29259 -0.47519,3.59035 0.5245,1.90325 2.18928,-3.6947 3.32798,-3.61533 3.97313,0.27693 0.54326,3.27751 0.70681,3.4538 1.36663,1.47307 1.1296,-3.39095 2.51626,-2.7021 2.51626,1.25 0,2.44444 0.45238,3.5 1.5,3.5 0.92366,0 1.5,-0.93789 1.5,-2.44098 0,-2.73002 1.4952,-4.18482 2.54885,-2.47998 0.37788,0.61142 0.10829,2.19308 -0.59907,3.51481 -1.47984,2.7651 -1.39937,2.89695 2.31167,3.7874 2.36142,0.56662 2.93255,0.26106 3.94258,-2.10932 0.64963,-1.52456 2.10697,-3.56495 3.23855,-4.53419 1.92655,-1.65017 1.9461,-1.82826 0.30742,-2.7997 -0.9625,-0.57058 -1.75,-2.00107 -1.75,-3.17886 0,-2.03268 -0.0679,-2.04856 -1.3372,-0.31271 -1.0973,1.50064 -1.85978,1.65344 -4.25,0.85169 -2.6161,-0.87752 -2.9128,-1.41658 -2.9128,-5.29213 0,-5.01223 -1.48643,-6.0196 -4.47397,-3.03206 -2.20634,2.20634 -4.02603,1.93876 -4.02603,-0.592 0,-0.825 -0.45,-1.22189 -1,-0.88197 -1.37824,0.8518 -1.28809,0.47194 1.02334,-4.31217 2.02433,-4.18988 3.4652,-5.2222 4.20234,-3.01078 0.5135,1.5405 2.77432,0.12576 2.77432,-1.73607 C 499,110.64844 498.28545,110 497.4121,110 c -1.29851,0 -1.46474,-0.72897 -0.9121,-4 0.76833,-4.5477 0.13765,-4.97942 -2.55644,-1.75 -1.49007,1.78616 -1.88388,1.91448 -1.91029,0.62244 -0.0183,-0.89515 0.60813,-2.15987 1.39206,-2.81047 1.98477,-1.64721 1.3122,-6.471971 -0.96462,-6.91982 -2.02523,-0.398364 -3.35342,-1.651752 -5.21071,-4.91725 -1.81539,-3.191835 -1.56063,-4.05356 1.30332,-4.408478 2.3748,-0.294298 2.44881,-0.45626 1.05857,-2.316422 -1.18012,-1.579016 -1.8642,-1.77366 -3.2499,-0.924711 -1.29381,0.792654 -2.48234,0.712518 -4.52176,-0.304881 -2.03278,-1.014083 -3.28944,-1.100365 -4.73768,-0.325289 -2.96883,1.588867 -3.38845,1.313744 -2.58543,-1.695119 0.40366,-1.5125 0.75245,-3.289738 0.77507,-3.949417 0.0259,-0.754499 1.07888,-0.460481 2.8387,0.792621 1.61284,1.148443 4.40077,1.990599 6.58334,1.988641 2.08217,-0.0019 6.37327,0.2456 9.53577,0.549929 5.83281,0.561295 7.12973,-0.24181 4.25,-2.631774 -0.825,-0.684689 -1.5,-1.981543 -1.5,-2.881898 0,-0.900355 -0.86952,-2.180035 -1.93227,-2.843733 -2.58649,-1.615288 -9.30823,-13.205244 -8.65135,-14.917065 0.82086,-2.139108 2.54489,-1.589372 3.58362,1.142696 0.52277,1.375 1.60985,2.5 2.41572,2.5 0.80588,0 3.34975,2.234933 5.65306,4.966518 3.50925,4.161769 4.49111,4.804207 6.05952,3.964816 1.02944,-0.550936 1.87447,-1.773369 1.87786,-2.716518 0.003,-0.943149 0.6089,-2.869809 1.34558,-4.281467 3.19698,-6.12622 2.94664,-15.162579 -0.52324,-18.887061 -1.77692,-1.907297 -2.12075,-1.946522 -4.82128,-0.550024 -3.36538,1.740307 -6.37046,1.914886 -8.97429,0.521359 -2.65231,-1.419473 -7.87503,0.628289 -11.83107,4.638815 C 479.38789,49.495397 477.47539,51 476.95186,51 c -1.86904,0 -0.90031,-1.86343 2.29814,-4.420653 3.60889,-2.885378 4.07533,-3.30335 6.53658,-5.857289 2.28307,-2.369046 8.11286,-6.407697 11.20899,-7.765143 1.37256,-0.601777 3.84756,-2.120354 5.5,-3.374615 1.65243,-1.25426 4.60467,-2.577404 6.56051,-2.94032 1.95585,-0.362916 5.33085,-1.580931 7.5,-2.7067 10.40587,-5.400538 25.80686,-8.870123 43.37807,-9.772353 30.55851,-1.56909 45.35355,-0.563253 58.56585,3.981586 1.65,0.567576 4.67963,1.44275 6.73251,1.94483 6.67104,1.63156 25.03362,10.200723 32.36177,15.102086 9.93796,6.646916 20.80874,17.623307 27.43791,27.704471 9.53177,14.495249 15.54217,26.935824 16.92648,35.035137 0.42951,2.512933 1.11266,5.356463 1.51811,6.318963 0.49813,1.18247 0.28496,1.75 -0.6573,1.75 -0.94436,0 -1.44847,1.3535 -1.5617,4.19311 -0.0998,2.50159 -1.03314,5.36434 -2.31374,7.09645 -2.04948,2.77207 -2.07957,3.13633 -0.66569,8.05689 1.46858,5.1109 1.4899,5.13079 2.57649,2.40355 3.24321,-8.14016 2.38854,3.40733 -0.90673,12.2508 -1.12701,3.02456 -2.86769,7.2992 -3.86816,9.4992 -1.00048,2.2 -2.1522,5.07277 -2.55939,6.38393 -2.55649,8.23194 -17.57041,25.89455 -31.94793,37.58407 -8.91586,7.24896 -26.31566,15.5071 -43.12252,20.46642 -24.66437,7.2779 -43.1376,9.19427 -66.95011,6.94527 z m 16.22146,-6.06385 c 2.06903,0.0778 3.27854,-0.35118 3.27854,-1.16276 0,-0.98527 -1.41841,-1.11877 -6.06537,-0.57085 -6.58858,0.77686 -8.16023,1.54227 -5.95955,2.90237 0.84756,0.52382 2.2312,0.44019 3.4425,-0.20808 1.11393,-0.59616 3.50068,-1.02846 5.30388,-0.96068 z m 21.2583,0.57558 c 4.42156,-1.76916 5.28033,-3.40372 1.77024,-3.36946 -2.35711,0.023 -10.75,3.48099 -10.75,4.42915 0,1.10422 5.06563,0.50644 8.97976,-1.05969 z m -39.54452,-1.28664 c 0.66883,-1.08219 -2.23752,-2.34501 -3.54179,-1.53893 -0.50934,0.31479 -0.66718,0.99125 -0.35074,1.50325 0.73258,1.18535 3.1682,1.20768 3.89253,0.0357 z m -11.97795,-2.03568 c 0.31644,-0.512 0.11397,-1.21604 -0.44993,-1.56455 -1.42561,-0.88108 -5.16454,0.43211 -4.46286,1.56745 0.74349,1.203 4.16876,1.20098 4.91279,-0.003 z m 76.29754,-2.81857 c 0.59712,-1.81315 -2.77994,-2.82109 -3.84044,-1.14625 -0.48607,0.76765 -0.89066,1.76452 -0.89908,2.21527 -0.0242,1.29297 4.28148,0.32181 4.73952,-1.06902 z m -89.2496,-1.25899 c 0.8456,-1.36822 -3.71831,-3.05374 -4.99687,-1.84542 -0.64774,0.61215 -0.47434,1.26421 0.5,1.88021 1.95188,1.23402 3.72116,1.22033 4.49687,-0.0348 z m 105.39049,-0.90593 C 631.5953,206.00945 630.63381,203 628.5904,203 c -1.88014,0 -2.92704,1.68036 -2.2104,3.54789 0.63721,1.66054 1.52742,1.7967 3.51572,0.53772 z M 601.5,203.9863 c 0,-0.81746 -1.0125,-1.6301 -2.25,-1.80585 -2.18881,-0.31086 -3.12347,1.61274 -1.54876,3.18745 1.16503,1.16503 3.79876,0.20716 3.79876,-1.3816 z m 38.21765,-1.63786 c 0.21086,-0.63335 -1.07133,-1.87726 -2.84931,-2.76424 -2.55335,-1.27377 -3.39925,-1.347 -4.0252,-0.34844 -0.50575,0.8068 -0.078,1.5909 1.18218,2.16705 1.08607,0.49655 1.97468,1.31705 1.97468,1.82333 0,1.29112 3.25113,0.52356 3.71765,-0.8777 z M 502.66284,197.43623 C 503.38747,195.54788 501.47542,191 499.95688,191 c -0.5973,0 -2.23555,-1.36616 -3.64056,-3.03592 C 493.41984,184.52181 489.07876,182 486.04966,182 484.87574,182 484,181.3457 484,180.46862 c 0,-0.84227 -0.64021,-1.77706 -1.42268,-2.07732 -0.78248,-0.30027 -1.66282,-1.17173 -1.95633,-1.93659 -0.97436,-2.53915 1.20207,-2.5232 3.95592,0.029 2.3784,2.20422 5.42309,3.36516 5.42309,2.06782 C 490,177.5637 485.19783,173 484.15838,173 c -0.61175,0 -1.84245,-1.11439 -2.73489,-2.47643 C 479.93742,168.25554 474.88214,165 472.84636,165 c -2.1785,0 -0.48113,3.28294 2.65364,5.1325 3.95982,2.33635 4.06368,2.61772 2.03531,5.51363 -1.51128,2.15765 -1.1352,3.35387 1.05443,3.35387 1.17594,0 4.20253,2.44208 10.60461,8.5566 2.23819,2.13766 3.04238,2.38707 4.75,1.47318 1.13061,-0.60508 2.1119,-0.85931 2.18065,-0.56496 0.0688,0.29435 0.18125,0.93445 0.25,1.42245 0.0688,0.488 1.25,1.82303 2.625,2.96673 1.96493,1.6344 2.14074,2.08658 0.82143,2.11273 -0.92322,0.0183 -2.2942,-0.58236 -3.04664,-1.3348 C 494.48471,191.34185 491,190.61814 491,192.43261 c 0,0.9088 0.85356,1.56739 2.03138,1.56739 1.11727,0 2.30486,0.71266 2.6391,1.58368 0.54234,1.4133 3.50188,3.18185 5.6109,3.35293 0.42977,0.0349 1.05142,-0.64031 1.38146,-1.50038 z m 93.88047,0.49369 c 0.36374,-0.58854 1.6278,-1.46002 2.80902,-1.93661 1.9754,-0.79703 1.92181,-0.87162 -0.66807,-0.92992 -3.89594,-0.0877 -7.44376,1.84171 -5.56936,3.02878 1.83703,1.16342 2.63237,1.12578 3.42841,-0.16225 z m 56.9238,-1.87671 C 654.23832,194.80537 662.86095,189 663.94314,189 c 1.30506,0 2.17133,-3.06396 1.48112,-5.23864 -0.44207,-1.39284 -1.24126,-1.81013 -2.77268,-1.44774 -1.18337,0.28002 -3.13488,0.74256 -4.33668,1.02784 -1.20181,0.28529 -3.19119,1.05715 -4.42084,1.71524 -1.79546,0.9609 -2.44824,0.92039 -3.31489,-0.20573 -0.74902,-0.97325 -3.2357,-1.39441 -8.12814,-1.37661 -6.66063,0.0242 -7.28596,0.2285 -11.35087,3.70791 -5.36661,4.59362 -4.73726,6.23056 2.03725,5.29883 3.25507,-0.44769 5.40579,-0.27517 6.3512,0.50945 0.83951,0.69673 2.63088,0.92248 4.34048,0.54699 2.38772,-0.52443 3.00743,-0.27069 3.44734,1.41155 0.56217,2.14973 5.0498,2.95011 6.19068,1.10412 z M 525,186.5 c 0,-0.825 -0.675,-1.5 -1.5,-1.5 -2.60246,0 -1.75909,1.97081 1.25,2.92105 0.1375,0.0434 0.25,-0.59605 0.25,-1.42105 z m 65.62469,0.0357 c 0.95188,-2.48056 -3.82713,-10.99339 -6.37469,-11.3552 -1.39389,-0.19797 -2.25,-1.01336 -2.25,-2.14301 0,-2.22957 2.33512,-3.24242 5.59124,-2.42518 2.90984,0.73032 13.40876,-3.2523 13.40876,-5.08643 0,-0.68304 -2.31203,-2.44141 -5.13785,-3.90749 -6.05348,-3.14066 -9.36781,-2.7692 -8.4355,0.94543 0.4534,1.80649 0.005,2.76229 -1.87128,3.99191 -2.78787,1.82668 -4.55537,1.22544 -4.55537,-1.5496 0,-2.66586 -1.93159,-7.40782 -2.70319,-6.63622 -0.35598,0.35598 -0.68089,4.03812 -0.72203,8.18253 -0.0696,7.01014 0.082,7.57463 2.17522,8.09986 1.30943,0.32856 2.25,1.33064 2.25,2.39714 0,1.00792 0.45,2.11069 1,2.45061 0.55,0.33992 1,1.56854 1,2.73028 0,4.1684 5.34441,7.64173 6.62469,4.30537 z m 32.80207,-2.68929 c 2.20632,-4.42267 1.99366,-4.62333 -1.42676,-1.34636 -3.29063,3.15262 -3.76168,4.5 -1.57324,4.5 0.78472,0 2.13472,-1.41914 3,-3.15364 z M 497,177.94098 C 497,177.42344 496.55,177 496,177 c -0.55,0 -1,0.70156 -1,1.55902 0,0.85746 0.45,1.2809 1,0.94098 0.55,-0.33992 1,-1.04148 1,-1.55902 z M 675.54621,176.25 c 1.89433,-2.0625 3.51388,-4.7625 3.59901,-6 0.0851,-1.2375 0.19978,-2.8125 0.25478,-3.5 0.18161,-2.27008 -8.99441,-0.0434 -12.65,3.06968 -1.72862,1.47209 -2.48475,8.11224 -1.08333,9.51365 1.94296,1.94297 6.59718,0.49042 9.87954,-3.08333 z m -13.99214,-0.69218 c 2.43137,-3.71074 1.55851,-6.98798 -1.96828,-7.39009 -1.86239,-0.21234 -3.22671,0.22614 -3.78003,1.21488 -0.69324,1.23875 -1.34346,1.32952 -3.26205,0.45535 -1.31793,-0.60049 -3.47941,-0.81993 -4.8033,-0.48765 -1.87249,0.46996 -2.40708,1.26929 -2.40708,3.59913 0,3.55351 2.57895,4.84945 9.89362,4.97161 3.95598,0.0661 4.98793,-0.31937 6.32712,-2.36323 z m -108.29279,-4.23539 c -0.20021,-2.59986 0.49879,-3.70432 4.33268,-6.84591 2.51428,-2.06026 6.1092,-5.32934 7.98872,-7.26462 3.64784,-3.75606 4.61659,-8.2119 1.78535,-8.2119 -2.23512,0 -8.03528,3.60624 -12.97245,8.06561 -2.25744,2.03896 -5.02837,4.00045 -6.15762,4.35887 -3.52547,1.11893 -3.67424,3.79651 -0.37476,6.7446 2.18507,1.95236 2.83738,3.25989 2.42089,4.85255 -0.45711,1.74799 -0.1949,2.10287 1.3229,1.79045 1.43505,-0.29539 1.83526,-1.13961 1.65429,-3.48965 z m 76.69193,-1.94955 c 2.4648,-5.5721 2.55568,-6.78214 0.44863,-5.97359 -0.97252,0.37319 -3.1348,-0.60376 -5.52338,-2.49555 -2.81018,-2.2257 -4.58197,-2.94399 -6.23718,-2.52856 -1.54354,0.38741 -3.03268,-0.0912 -4.48036,-1.43989 -1.96351,-1.82928 -2.03967,-2.27599 -0.80605,-4.72773 1.59353,-3.16703 1.01999,-10.12648 -0.8951,-10.86137 -0.71692,-0.27511 -2.27671,0.0207 -3.46621,0.65726 -1.1895,0.6366 -4.77637,1.14495 -7.97082,1.12967 -4.47083,-0.0214 -6.2061,0.41201 -7.5367,1.88231 -2.28475,2.52461 -1.39951,4.44625 3.21524,6.97953 5.60607,3.07747 10.66326,6.90035 11.79872,8.919 1.70272,3.02714 8.15733,8.08604 10.31692,8.08604 1.12908,0 3.22599,-0.44601 4.65978,-0.99114 1.95262,-0.74239 2.56668,-0.67964 2.44662,0.25 -0.37124,2.8746 0.14298,5.74114 1.02989,5.74114 0.52426,0 1.87426,-2.0822 3,-4.62712 z M 608,145 c 0,-0.55 0.45,-1 1,-1 0.55,0 1,0.45 1,1 0,0.55 -0.45,1 -1,1 -0.55,0 -1,-0.45 -1,-1 z m 26,26 c 0,-0.55 -0.675,-1 -1.5,-1 -0.825,0 -1.5,0.45 -1.5,1 0,0.55 0.675,1 1.5,1 0.825,0 1.5,-0.45 1.5,-1 z m 6.55,-4.89125 c 0.5225,-0.49019 3.77613,-1.08239 7.23029,-1.316 7.25848,-0.49091 9.75012,-2.18469 8.43672,-5.73516 -0.66344,-1.79345 -1.72087,-2.3595 -4.78434,-2.56113 -2.16297,-0.14236 -4.40208,0.11554 -4.9758,0.57311 -0.57372,0.45757 -2.59872,1.01894 -4.5,1.24749 -4.86982,0.58539 -6.6824,1.52535 -7.26931,3.76971 -0.86261,3.29861 3.46719,6.26911 5.86244,4.02198 z m -147.1151,-4.084 c 1.41081,-0.53639 2.5651,-1.66139 2.5651,-2.5 0,-2.34602 1.81948,-1.8062 2.18045,0.64692 0.17575,1.19442 0.88205,2.35692 1.56955,2.58334 0.87515,0.28821 1.25,-0.93073 1.25,-4.06469 0,-4.95221 -0.35583,-5.23956 -6.89448,-5.56779 -2.41697,-0.12133 -5.68353,-0.88719 -7.25903,-1.70192 -2.14206,-1.1077 -3.36671,-1.21256 -4.85552,-0.41578 -2.63555,1.41051 -2.52381,2.78039 0.25903,3.17562 1.74072,0.24722 2.32259,1.0774 2.57068,3.6677 0.25901,2.7043 0.67927,3.25437 2.18542,2.86051 1.04749,-0.27393 2.09842,0.12132 2.39793,0.90185 0.6347,1.654 0.74126,1.66495 4.03087,0.41424 z M 488.01531,157.25 C 488.00689,156.0125 488.45,155 489,155 c 1.25292,0 1.25292,1.06124 0,3 -0.78387,1.21296 -0.9723,1.06944 -0.98469,-0.75 z m 19.55419,0.17091 c -0.85009,-3.38705 -2.75094,-3.07506 -2.00503,0.32909 0.33142,1.5125 0.85963,3.425 1.17381,4.25 0.88025,2.31144 1.58552,-1.57376 0.83122,-4.57909 z m 161.8738,3.35658 c 2.07235,-2.95869 2.00672,-7.39082 -0.12153,-8.20751 -2.29137,-0.87928 -12.53417,2.4274 -11.85654,3.82764 0.29342,0.60631 0.81254,1.8948 1.15362,2.86332 0.34107,0.96851 1.80386,2.02038 3.25064,2.33747 1.44678,0.31709 3.08051,0.72664 3.63051,0.91011 1.96615,0.65587 2.40699,0.46235 3.9433,-1.73103 z m 13.8067,-2.58448 c 0.9625,-0.82664 1.75,-2.29644 1.75,-3.26621 0,-3.28647 1.23279,-4.99722 4.62129,-6.41303 2.2812,-0.95315 3.37871,-2.07795 3.37871,-3.46274 0,-2.3991 -2.21321,-2.70398 -4,-0.55103 -0.68469,0.825 -2.48743,1.5 -4.00608,1.5 -3.45688,0 -9.99392,6.83745 -9.99392,10.45319 0,4.32134 4.21038,5.20925 8.25,1.73982 z m -138.64583,-4.92218 c -1.01652,-1.01651 -1.85525,0.51389 -1.02122,1.86338 0.63003,1.01942 0.86558,1.02021 1.2043,0.004 0.2316,-0.69479 0.14921,-1.53513 -0.18308,-1.86742 z M 525.8125,152.0625 c 0.25,-0.75 -0.125,-1.125 -0.875,-0.875 -0.72187,0.24062 -1.50937,1.02812 -1.75,1.75 -0.25,0.75 0.125,1.125 0.875,0.875 0.72187,-0.24063 1.50937,-1.02813 1.75,-1.75 z M 508,149.54797 C 508,147.43428 506.34992,146 503.91821,146 c -1.4931,0 -1.04857,3.19848 0.71544,5.14768 1.98716,2.19579 3.36635,1.54039 3.36635,-1.59971 z m 36.1038,0.15583 c -1.28349,-1.28349 -2.58505,-0.2915 -1.63484,1.24598 0.36808,0.59556 1.12735,0.79971 1.68727,0.45366 0.683,-0.42212 0.66575,-0.98146 -0.0524,-1.69964 z m 101.28921,-0.28559 c 1.50054,-3.91035 -0.0279,-5.56938 -3.25002,-3.52774 -0.85139,0.53946 -1.10573,1.65155 -0.68261,2.98468 0.79169,2.49441 3.06345,2.80812 3.93263,0.54306 z m 8.27112,-1.02836 c 1.6049,-2.44939 1.75467,-2.49002 2.43172,-0.65979 0.56022,1.51443 1.41244,1.84895 3.81282,1.49665 1.70023,-0.24954 3.09133,-0.90078 3.09133,-1.4472 0,-0.54642 0.70351,-0.72353 1.56335,-0.39358 C 668.63327,148.94771 675,142.02148 675,136.03212 c 0,-2.77832 -2.33269,-2.59698 -9.21588,0.7164 -4.41506,2.1253 -5.85593,3.37926 -6.33132,5.50998 -0.60081,2.69289 -0.67897,2.72097 -3.28656,1.18063 -2.07406,-1.22518 -3.28527,-1.34437 -5.41868,-0.53325 -3.06394,1.16491 -3.26442,1.86563 -1.58704,5.54707 1.4656,3.21665 2.36287,3.20407 4.50361,-0.0631 z M 580,138.81835 c 0,-2.89123 -1.43656,-2.13632 -4.32237,2.27139 -3.9627,6.05253 -3.43866,8.2671 0.82315,3.47861 1.92457,-2.16241 3.49922,-4.74991 3.49922,-5.75 z m 9,6.68165 c -0.68469,-0.825 -2.20229,-1.48405 -3.37244,-1.46456 -2.00407,0.0334 -1.98245,0.11838 0.37244,1.46456 3.27489,1.87209 4.5537,1.87209 3,0 z m 89.5,-3.5 c -0.33992,-0.55 -0.81648,-1 -1.05902,-1 -0.24254,0 -0.44098,0.45 -0.44098,1 0,0.55 0.47656,1 1.05902,1 0.58246,0 0.7809,-0.45 0.44098,-1 z M 558.25,141.31044 C 561.63861,140.44835 559.0858,133 555.40172,133 c -0.70857,0 -1.87633,-0.79993 -2.59502,-1.77763 C 551.25224,129.1077 546.06027,125 544.94187,125 c -0.43363,0 -2.12541,1.125 -3.7595,2.5 C 536.97784,131.03788 536,130.67594 536,125.58179 536,118.99004 535.3438,118 530.9748,118 525.7994,118 524,118.83762 524,121.24675 c 0,1.11802 -0.74375,2.57661 -1.65278,3.2413 -2.0593,1.50581 -0.95636,3.50019 1.9618,3.54739 1.20504,0.0195 3.31598,0.67854 4.69098,1.46456 1.375,0.78602 3.46436,1.44508 4.64301,1.46456 1.17866,0.0195 2.41616,0.74724 2.75,1.61723 0.81234,2.11691 0.82798,2.05436 -0.96137,3.84371 -0.95922,0.95922 -1.31957,2.35225 -0.92779,3.58662 0.5936,1.87027 1.42353,2.00819 11.31836,1.8809 5.87278,-0.0756 11.46529,-0.33771 12.42779,-0.58258 z m -32.67997,-17.19713 c -0.30141,-0.48768 0.0695,-1.39917 0.8242,-2.02553 1.04729,-0.86917 1.50193,-0.80076 1.92009,0.28893 0.85481,2.22762 -1.51428,3.7268 -2.74429,1.7366 z m 2.87281,14.78791 c 4.19998,-2.47805 4.42909,-3.54682 1.08677,-5.06968 -3.21906,-1.4667 -5.52961,0.32625 -5.52961,4.2909 0,3.43729 -0.0486,3.42878 4.44284,0.77878 z M 481,137.41667 c 0,-0.87084 -0.53438,-1.40521 -1.1875,-1.1875 C 477.95828,136.84724 477.65074,139 479.41667,139 480.2875,139 481,138.2875 481,137.41667 z M 624.64733,134.314 c -0.28285,-0.28285 -0.99542,-0.2169 -1.5835,0.14655 -0.74504,0.46046 -0.69608,1.32463 0.16149,2.85014 l 1.23072,2.18931 0.35278,-2.33586 c 0.19403,-1.28473 0.12136,-2.56729 -0.16149,-2.85014 z m 19.79988,2.60059 c -0.32197,-0.52097 -1.01165,-0.68378 -1.53262,-0.3618 -0.52097,0.32197 -0.68378,1.01165 -0.3618,1.53262 0.32197,0.52097 1.01165,0.68378 1.53262,0.3618 0.52097,-0.32197 0.68378,-1.01165 0.3618,-1.53262 z M 689,138.01342 c 0,-0.54262 1.53878,-1.62952 3.41951,-2.41534 1.88073,-0.78582 3.92156,-2.36686 4.53518,-3.51342 C 697.95077,130.22347 697.79523,130 695.5038,130 c -1.41161,0 -2.82559,0.675 -3.14217,1.5 -0.31659,0.825 -0.95015,1.5 -1.40792,1.5 -0.45777,0 -0.14475,-2.01788 0.6956,-4.48417 1.92467,-5.64859 1.393,-7.75603 -1.19435,-4.73422 -1.04469,1.22011 -2.64602,2.21839 -3.55851,2.21839 -1.40966,0 -4.87535,3.66441 -7.1756,7.58703 -1.27015,2.16599 2.2305,5.41297 5.83585,5.41297 1.89382,0 3.4433,-0.44396 3.4433,-0.98658 z m -69.55279,-2.09883 c -0.32197,-0.52097 -1.01165,-0.68378 -1.53262,-0.3618 -0.52097,0.32197 -0.68378,1.01165 -0.3618,1.53262 0.32197,0.52097 1.01165,0.68378 1.53262,0.3618 0.52097,-0.32197 0.68378,-1.01165 0.3618,-1.53262 z m 31.32362,0.89791 C 650.15276,134.95828 648,134.65074 648,136.41667 648,137.2875 648.7125,138 649.58333,138 c 0.87084,0 1.40521,-0.53438 1.1875,-1.1875 z M 657.5,135 c 1.95846,-1.1 4.22215,-2 5.03042,-2 0.80827,0 1.46958,-0.45 1.46958,-1 0,-0.55 0.9,-1 2,-1 1.1,0 2,-0.45 2,-1 0,-0.55 1.0125,-1.01431 2.25,-1.0318 3.70057,-0.0523 5.75,-2.3191 5.75,-6.35983 0,-4.08077 -2.16102,-5.73824 -4.88592,-3.74741 -0.88775,0.64858 -3.07658,1.85124 -4.86408,2.67256 -1.7875,0.82133 -3.25,1.93728 -3.25,2.4799 0,0.54262 -0.86278,0.98658 -1.91729,0.98658 -1.35398,0 -2.42743,1.33577 -3.65359,4.54642 -1.20887,3.16538 -2.05415,4.22855 -2.7827,3.5 C 652.93219,131.33219 652,131.84421 652,134.5 c 0,3.02254 0.86829,3.10148 5.5,0.5 z m 1.57895,-4.41667 c -0.0434,-1.05416 0.19293,-1.64479 0.52522,-1.3125 0.33229,0.33229 0.36781,1.19479 0.0789,1.91667 -0.31922,0.79773 -0.55618,0.56078 -0.60416,-0.60417 z m -138.68594,1.83488 c 0.93873,-2.44628 0.7352,-2.7695 -0.89301,-1.41821 -1.66238,1.37965 -1.99022,3 -0.60699,3 0.49116,0 1.16616,-0.7118 1.5,-1.58179 z m 67.63174,-0.98331 c 1.45698,-3.83214 1.22062,-3.99171 -1.52475,-1.0294 -2.91405,3.14431 -3.03619,3.5945 -0.97525,3.5945 0.83861,0 1.96361,-1.15429 2.5,-2.5651 z m -9.95972,-1.85654 c -0.90842,-1.09458 -0.8971,-1.87439 0.0492,-3.38964 0.9081,-1.4541 0.98838,-3.75945 0.30742,-8.82836 -0.86011,-6.40245 -1.08827,-6.86036 -3.41822,-6.86036 -2.40627,0 -2.49376,0.22796 -2.41837,6.30169 0.0599,4.82381 0.64538,7.22133 2.49659,10.2231 1.3301,2.15678 2.81097,3.93352 3.29081,3.94831 0.47985,0.0148 0.34151,-0.61284 -0.30741,-1.39474 z m 17.43903,-6.29195 c 1.87115,-2.04247 3.22731,-3.88837 3.01369,-4.102 -0.62517,-0.62517 -4.26845,2.22893 -6.55356,5.13399 -3.1796,4.0422 -0.35406,3.21847 3.53987,-1.03199 z m -78.484,0.18942 c 1.52272,-1.83477 1.77271,-1.5856 -5.01085,-4.99439 -7.71054,-3.87461 -10.9838,-4.71122 -11.64913,-2.9774 -0.70933,1.84848 3.60603,6.41169 6.61065,6.99032 1.31035,0.25235 2.84299,0.91936 3.40586,1.48223 1.51756,1.51756 5.19869,1.24009 6.64347,-0.50076 z M 557.8,120.8 c 1.9916,-1.9916 1.36562,-4.30144 -1.8,-6.64188 -1.65,-1.2199 -3.00224,-2.76702 -3.00497,-3.43806 -0.0101,-2.49027 -4.4425,-6.86932 -6.25065,-6.17546 -2.31985,0.89021 -2.23787,5.12092 0.12372,6.38481 1.21224,0.64877 1.73464,1.80213 1.48797,3.28518 -0.28325,1.70299 0.55593,2.98622 3.29293,5.03541 4.16956,3.12173 4.49681,3.20419 6.151,1.55 z m 99.54505,-3.72552 c -0.14411,-2.98762 -0.0336,-3.10262 1.57874,-1.64345 2.11456,1.91365 5.07621,2.05559 5.07621,0.24328 0,-0.72912 -1.16127,-2.41662 -2.58059,-3.75 -2.41678,-2.27042 -2.66182,-2.31322 -3.86024,-0.67431 -0.70381,0.9625 -1.98005,1.75 -2.83608,1.75 -2.25399,0 -2.65741,2.08682 -1.02722,5.31378 1.82052,3.60373 3.84954,2.91465 3.64918,-1.2393 z m 31.21382,1.5033 c 1.57632,-1.15494 1.90408,-2.49187 1.74398,-7.11382 -0.10843,-3.13038 -0.42653,-5.92097 -0.70687,-6.20132 -1.24063,-1.24063 -3.46132,0.94846 -6.12697,6.03978 -2.44396,4.66791 -2.67838,5.74037 -1.55153,7.09815 1.64234,1.9789 4.09309,2.04429 6.64139,0.17721 z M 524,105.30383 c 0,-1.96265 -2.08731,-1.57044 -4.69879,0.88293 -3.10372,2.91579 -4.62463,1.42772 -3.29154,-3.22049 C 517.41791,98.056045 517.25576,97 515.09362,97 c -1.45733,0 -1.77418,-0.505532 -1.34514,-2.14618 0.48438,-1.852288 0.21641,-2.080262 -1.9569,-1.664807 -2.06046,0.393881 -2.43092,0.14782 -2.03823,-1.35382 0.68836,-2.632295 -2.15509,-2.34313 -4.07893,0.414807 -0.86323,1.2375 -1.59312,1.714058 -1.62197,1.059017 C 504.0236,92.653976 504.45,91.839919 505,91.5 c 0.55,-0.339919 1,-1.448656 1,-2.46386 0,-1.589584 -0.59,-1.770877 -4.25,-1.305931 -2.3375,0.296942 -4.8125,0.984222 -5.5,1.527288 -2.17842,1.720767 -1.42378,5.398835 1.5,7.310898 1.5125,0.989128 3.38111,2.32227 4.15247,2.962537 2.52763,2.098058 7.52374,6.355208 11.59753,9.882188 l 4,3.46309 3.25,-3.13427 c 1.7875,-1.72385 3.25,-3.721 3.25,-4.43811 z m 148.96743,5.2163 C 673.53534,110.16914 674,108.15667 674,106.04797 c 0,-4.6446 -1.86169,-5.68797 -6.17197,-3.45904 -2.65978,1.37543 -2.96824,1.96002 -2.43666,4.61792 0.33475,1.67373 0.60863,3.63049 0.60863,4.34834 0,0.97157 0.75853,1.08766 2.96743,0.45415 1.63209,-0.46807 3.43209,-1.13822 4,-1.48921 z m -20.225,-2.603 c 0.13333,-0.77942 -0.62625,-2.53919 -1.68796,-3.9106 -1.75745,-2.2701 -1.99251,-2.33158 -2.62388,-0.68623 -0.87696,2.2853 1.19026,6.9726 2.83376,6.42538 0.67961,-0.22628 1.34474,-1.04912 1.47808,-1.82855 z m 3.46972,-5.27202 c -0.3089,-2.83853 0.65575,-3.377209 2.58785,-1.44511 0.93333,0.93333 1.2,0.74193 1.2,-0.86133 0,-1.601072 0.50455,-1.964875 2.25971,-1.629355 1.6545,0.316277 2.87697,-0.402906 4.56436,-2.685228 2.93978,-3.976259 2.51173,-6.426291 -1.19705,-6.851551 -3.68081,-0.422054 -8.94693,4.244148 -8.03444,7.119158 0.49566,1.561688 0.23696,1.788979 -1.43296,1.258969 -2.89727,-0.91956 -4.58567,2.420148 -2.99191,5.918087 1.47386,3.23476 3.42854,2.70594 3.04444,-0.82364 z m 38.20606,1.7479 c 0.86999,-0.33384 1.58179,-1.45884 1.58179,-2.5 0,-2.327556 -0.79631,-2.387324 -3.17126,-0.23802 -3.00251,2.71724 -2.15607,4.17532 1.58947,2.73802 z m -160.26085,-1.97439 c 1.69984,-0.87901 4.09335,-1.32153 5.38906,-0.99633 2.13424,0.53566 4.32586,-0.88335 3.16194,-2.047264 -0.27055,-0.270551 -4.59061,-0.660624 -9.60014,-0.866829 C 524.0904,98.136999 524,98.15677 524,100.50022 c 0,1.81445 0.64189,2.46417 2.75,2.78353 1.5125,0.22912 3.10985,0.48401 3.54966,0.56642 0.43981,0.0824 2.17578,-0.56179 3.8577,-1.43155 z m 150.62782,-2.1425 C 689.3633,97.36908 693,93.595997 693,91.753247 c 0,-2.370459 -1.68131,-2.217238 -3.01499,0.274761 C 688.48008,94.839999 687,93.557257 687,89.440983 687,87.548442 686.63828,86 686.19617,86 c -1.3911,0 -7.02927,6.382614 -8.06396,9.128683 -0.74401,1.974611 -0.62075,3.156511 0.49537,4.75 1.80017,2.570107 2.64967,2.624937 6.1576,0.397437 z M 645,96.11501 C 645,95.270658 640.6565,92 639.53518,92 c -1.21203,0 -0.41338,2.371976 1.21482,3.607954 2.01805,1.531915 4.25,1.798204 4.25,0.507056 z M 628.5,93 c -0.33992,-0.55 -1.06803,-1 -1.61803,-1 -0.55,0 -0.72189,0.45 -0.38197,1 0.33992,0.55 1.06803,1 1.61803,1 0.55,0 0.72189,-0.45 0.38197,-1 z m 21.42667,-0.411645 c 0.94088,-1.133687 0.50337,-1.921303 -2.22194,-4 -5.67738,-4.33035 -8.42113,-2.781631 -4.12252,2.326973 2.84502,3.381115 4.55307,3.831525 6.34446,1.673027 z M 544,90 c 0,-0.55 -0.64844,-1 -1.44098,-1 -0.79254,0 -1.7191,0.45 -2.05902,1 -0.33992,0.55 0.30852,1 1.44098,1 C 543.07344,91 544,90.55 544,90 z M 658.27939,79.338167 c -1.31693,-3.950794 -3.58427,-5.048143 -6.83539,-3.308198 -3.66745,1.962762 -4.08485,3.658978 -1.56137,6.345099 1.17462,1.250318 1.84242,2.566547 1.48402,2.924953 -0.35841,0.358406 -0.10252,1.31331 0.56864,2.122009 1.0423,1.255894 1.6595,0.970135 4.23141,-1.959109 2.538,-2.890617 2.86995,-3.852968 2.11269,-6.124754 z M 619.96858,85.75 c -0.0173,-0.6875 -1.14699,-2.062054 -2.51045,-3.054565 -2.31281,-1.683569 -2.52274,-1.690636 -3.13106,-0.105392 -0.41068,1.070214 0.0341,2.200878 1.20158,3.054565 2.321,1.697159 4.48123,1.748437 4.43993,0.105392 z M 501.45295,84.839485 c 2.93983,-1.339478 3.22983,-2.363501 0.9203,-3.249749 C 500.49808,80.870164 498,82.602499 498,84.622445 c 0,1.673034 0.22618,1.687251 3.45295,0.21704 z M 679.77749,84.443296 C 680.99987,83.587109 682,82.268312 682,81.512637 682,79.466724 677.68726,73.091098 676.27032,73.042326 674.97914,72.997883 671,79.957434 671,82.260162 c 0,3.635002 4.94774,4.865601 8.77749,2.183134 z M 595,83.5 c 0,-0.933333 -0.94444,-1.5 -2.5,-1.5 -1.55556,0 -2.5,0.566667 -2.5,1.5 0,0.933333 0.94444,1.5 2.5,1.5 1.55556,0 2.5,-0.566667 2.5,-1.5 z M 512.48713,81.244158 C 513.03005,80.009871 514.18154,79 515.046,79 c 0.86446,0 2.44525,-0.647177 3.51287,-1.438171 1.91883,-1.421649 1.91831,-1.455075 -0.0456,-2.909681 -1.8918,-1.401197 -1.90374,-1.56321 -0.25,-3.39057 C 519.21847,70.206095 520,68.606285 520,67.706443 c 0,-2.112969 -3.52329,-3.99252 -6.00665,-3.204333 -2.22245,0.70538 -4.22509,6.726394 -3.37018,10.132618 0.32555,1.297091 -0.11172,3.224692 -1.0284,4.533434 C 508.71765,80.42043 508,82.052881 508,82.79583 c 0,2.11655 3.38911,0.944576 4.48713,-1.551672 z M 637.12868,79.436461 C 635.55821,77.439929 635,77.167225 635,78.396526 c 0,0.916434 -0.675,1.925265 -1.5,2.241848 -2.37402,0.910996 -1.75059,2.196928 1.25,2.578349 4.01837,0.510796 4.78974,-0.715091 2.37868,-3.780262 z M 609,79.5 c 0,-0.833333 -0.88889,-1.5 -2,-1.5 -1.11111,0 -2,0.666667 -2,1.5 0,0.833333 0.88889,1.5 2,1.5 1.11111,0 2,-0.666667 2,-1.5 z m -72,-1 c 1.01247,-1.219951 0.96484,-1.5 -0.25511,-1.5 -0.825,0 -2.0602,0.675 -2.74489,1.5 -1.01247,1.219951 -0.96484,1.5 0.25511,1.5 0.825,0 2.0602,-0.675 2.74489,-1.5 z m 126.77106,-0.31318 c 0.24358,-0.73075 -0.21359,-0.954237 -1.1875,-0.580511 C 661.7126,77.940527 661,78.653333 661,79.190322 c 0,1.314392 2.27278,0.491335 2.77106,-1.003502 z M 623,76.328741 C 623,75.072959 619.69544,72 618.34501,72 c -1.93726,0 -1.65631,2.719304 0.40499,3.919901 2.0164,1.174444 4.25,1.389311 4.25,0.40884 z M 535.25,75.013655 C 535.6625,75.006145 536,74.325 536,73.5 c 0,-2.179219 -2.39224,-1.837179 -4.59501,0.656992 -1.89731,2.148294 -1.89491,2.154398 0.59501,1.513654 1.375,-0.353835 2.8375,-0.649481 3.25,-0.656991 z M 646.03355,71.5 c 0.56364,-5.729211 -1.62198,-7.654914 -5.67445,-4.999633 -3.21727,2.108037 -3.03931,5.62093 0.3909,7.71609 3.06654,1.873036 4.92609,0.916979 5.28355,-2.716457 z M 533.96429,70.39956 C 535.18049,69.237119 535.19251,69 534.03528,69 531.72861,69 526,71.338662 526,72.280344 c 0,1.255604 6.21953,-0.213151 7.96429,-1.880784 z m 18.80677,0.78726 c 0.24358,-0.73075 -0.21359,-0.954237 -1.1875,-0.580511 C 550.7126,70.940527 550,71.653333 550,72.190322 c 0,1.314392 2.27278,0.491335 2.77106,-1.003502 z m 117.14275,-1.284112 2.28993,-3.097291 -2.97019,-3.152709 c -1.63361,-1.733989 -3.38818,-3.946184 -3.89905,-4.915988 -0.87458,-1.660231 -1.05491,-1.645852 -3.08563,0.246049 -2.66934,2.486873 -3.8788,8.339276 -2.39596,11.593757 1.70374,3.739304 7.06353,3.380338 10.0609,-0.673818 z m -57.18405,0.407999 c 0.49435,-1.483026 -2.11636,-2.315474 -3.82044,-1.218187 -1.20138,0.773587 -1.188,1.052626 0.0907,1.891224 1.72585,1.131861 3.21788,0.862623 3.72976,-0.673037 z M 680,71 c 0,-0.55 -0.45,-1 -1,-1 -0.55,0 -1,0.45 -1,1 0,0.55 0.45,1 1,1 0.55,0 1,-0.45 1,-1 z M 531.17814,66.841395 c 3.23662,-1.23815 4.06906,-3.061014 2.85549,-6.25294 -1.06524,-2.801792 -1.53367,-3.139186 -5.55309,-3.999677 -1.90776,-0.408423 -3.70618,-0.144268 -4.88468,0.717469 -1.71886,1.256862 -1.76121,1.769716 -0.53974,6.53565 1.42597,5.563841 1.42224,5.562464 8.12202,2.999498 z M 631.96482,64.065741 C 633.50101,61.195336 633.23307,59.233066 631,57 c -2.55549,-2.555485 -2.95893,-2.520654 -6.26022,0.540469 -3.51006,3.254715 -3.44673,4.057892 0.51022,6.470491 4.07315,2.483446 5.4092,2.494345 6.71482,0.05478 z m 42.43144,-1.655983 c 0.92761,-2.417322 -0.3327,-3.616179 -2.02378,-1.9251 -0.825,0.825 -1.21975,1.953452 -0.87722,2.507671 0.91806,1.485459 2.20672,1.226673 2.901,-0.582571 z M 550.72058,59.612756 c 1.08605,-1.086053 -2.03437,-9.710326 -3.86855,-10.691947 -1.46768,-0.785478 -2.39702,-0.466729 -4.35872,1.494972 -2.7459,2.745898 -2.99588,4.132162 -1.46923,8.147558 0.93571,2.461105 1.3743,2.646565 5.08259,2.149179 2.23218,-0.299398 4.30844,-0.794291 4.61391,-1.099762 z m 64.52942,-0.0048 c 0.9625,-0.730642 1.75,-1.918397 1.75,-2.639456 0,-0.721059 0.72958,-2.11719 1.62128,-3.102512 3.05758,-3.378582 -0.6303,-7.094169 -5.04485,-5.082763 -2.9059,1.324016 -5.49352,10.018825 -3.3805,11.359028 1.80236,1.143168 3.01287,1.015198 5.05407,-0.534297 z m 39.67327,-1.196848 c 3.79753,-3.195403 3.88978,-5.393072 0.32041,-7.63246 -1.50903,-0.946745 -3.47001,-2.255862 -4.35776,-2.909148 -2.57679,-1.896251 -4.63192,-0.332369 -5.37971,4.09377 -0.5091,3.013292 -0.26393,4.757547 0.92339,6.569628 2.07179,3.161954 4.63484,3.125203 8.49367,-0.12179 z m -89.09662,-1.949221 c 0.17966,-0.155019 -0.0508,-2.19035 -0.51207,-4.522958 -1.1221,-5.67408 -5.06886,-8.827546 -8.87677,-7.092547 -2.49194,1.135408 -2.5855,1.449298 -1.91456,6.42368 0.38798,2.876467 0.91886,5.589029 1.17975,6.027916 0.40748,0.6855 9.20198,-0.04082 10.12365,-0.836091 z M 602.4,52.549738 C 602.4,48.533037 599.6547,45 596.53357,45 c -3.19583,0 -6.70737,3.705664 -6.34106,6.691629 0.24756,2.018047 1.28201,2.838279 5.30749,4.208407 2.75,0.936 5.4275,1.341401 5.95,0.900891 0.5225,-0.44051 0.95,-2.353545 0.95,-4.251189 z m -18.57036,1.865833 C 586.85787,53.472873 582.61038,44 579.15946,44 c -4.28087,0 -7.95289,7.80657 -5.04148,10.717983 0.99817,0.998165 6.03794,0.841231 9.71166,-0.302412 z M 532,52.440983 C 532,51.648442 531.32527,51 530.5006,51 c -1.05537,0 -1.4555,-0.96245 -1.35117,-3.25 0.20461,-4.486367 -0.84226,-10.842825 -1.97177,-11.972345 -0.58383,-0.583828 -2.37367,-0.541427 -4.74135,0.11232 -2.39023,0.659972 -4.22505,0.700319 -4.93805,0.108585 -1.74958,-1.452023 -5.14227,1.471492 -5.85746,5.047427 -0.78084,3.904204 0.43021,6.216745 4.60769,8.798573 5.61543,3.470527 8.50921,4.254887 10.04216,2.721935 1.14438,-1.144382 1.54856,-1.053608 2.56652,0.576412 C 530.15314,55.218084 532,54.805604 532,52.440983 z M 639.05637,47.777139 C 640.67537,46.004565 642,44.213711 642,43.797463 642,42.828104 634.5367,39 632.64683,39 c -2.94871,0 -3.65372,7.229913 -0.99184,10.171259 2.35444,2.601625 4.04219,2.28372 7.40138,-1.39412 z M 543.4433,42.777494 c 1.97513,-2.819906 2.04063,-10.13098 0.10514,-11.737293 -1.132,-0.939472 -2.2878,-0.939561 -5.25,-4.03e-4 -8.11215,2.571937 -8.30445,2.982328 -4.33231,9.245741 3.41071,5.378134 6.82651,6.276295 9.47717,2.491955 z M 606,43 c 0,-1.1 -0.42344,-2 -0.94098,-2 -1.34235,0 -2.28822,1.820126 -1.55902,3 1.04512,1.691037 2.5,1.109085 2.5,-1 z M 566,40.440983 C 566,39.648442 565.325,39 564.5,39 c -1.50623,0 -2.05568,2.110991 -0.86052,3.306147 C 564.57272,43.239389 566,42.111627 566,40.440983 z m 56.77749,0.0023 C 623.99987,39.587109 625,38.243148 625,37.456716 625,36.071687 619.10385,33 616.44526,33 c -1.99296,0 -2.81529,3.940068 -1.38149,6.61916 1.47391,2.754028 4.49725,3.077042 7.71372,0.824136 z m -61.25631,-2.707857 c 1.80079,-1.548977 2.68739,-3.365933 2.80577,-5.75 L 564.5,28.5 559,28.755531 c -3.025,0.140541 -6.5125,0.486615 -7.75,0.769052 -4.03168,0.920157 -2.49178,4.596963 3.65157,8.718828 3.30504,2.217506 3.46536,2.205203 6.61961,-0.507972 z m 40.18177,1.0712 C 606.13834,36.914278 608,34.897509 608,31.984915 c 0,-2.556487 -0.31469,-2.737588 -5.72777,-3.296268 -3.44662,-0.355722 -6.1788,-1.207964 -6.86025,-2.139902 -1.93188,-2.642007 -2.90147,-1.720319 -3.176,3.019094 -0.22566,3.895677 0.16275,4.984733 2.67307,7.495062 3.37671,3.376705 3.12057,3.310962 6.7939,1.743738 z m -19.73903,-2.772935 c 2.37259,-2.216334 3.09461,-3.670092 2.85575,-5.75 C 584.50655,27.557061 584.36676,27.5 578,27.5 l -6.5,0 -0.30499,3.659815 c -0.22998,2.759708 0.2468,4.173882 1.93856,5.75 3.04094,2.833065 5.07579,2.631176 8.83035,-0.876111 z M 524.45,32.929237 c 0.5987,-0.585617 0.52356,-1.355674 -0.2032,-2.082433 -0.82935,-0.829351 -0.85594,-1.708623 -0.0947,-3.131049 0.99412,-1.857528 0.8251,-1.934063 -2.77839,-1.258044 -2.1103,0.395895 -4.7452,1.242367 -5.85532,1.881049 -1.78932,1.029442 -1.52299,1.196778 2.34661,1.474358 l 4.36502,0.313118 -2.36502,2.577906 -2.36502,2.577906 3,-0.711787 c 1.65,-0.391482 3.4275,-1.129943 3.95,-1.641024 z M 534,30 c 0,-0.55 0.675,-1 1.5,-1 3.19356,0 1.29291,-1.859192 -2.56738,-2.511385 -5.06416,-0.855584 -5.91252,-0.118719 -2.82428,2.453112 C 532.77496,31.162446 534,31.495574 534,30 z m -65,118.5 c 0,-1.68889 0.45833,-2.51389 1.25,-2.25 0.6875,0.22917 1.25,1.24167 1.25,2.25 0,1.00833 -0.5625,2.02083 -1.25,2.25 -0.79167,0.26389 -1.25,-0.56111 -1.25,-2.25 z m -8.90082,-30.75 c -1.35363,-3.64149 -0.2588,-5.00253 3.46248,-4.30441 1.93382,0.36279 3.55642,0.17237 3.94939,-0.46346 0.47055,-0.76138 1.08257,-0.73436 2.07798,0.0918 2.09359,1.73752 1.71418,2.92611 -0.93404,2.92611 -1.28976,0 -3.1595,0.9 -4.15499,2 -2.33717,2.58255 -3.36971,2.52389 -4.40082,-0.25 z m 4.5847,-10.67723 -2.81611,-2.87167 2.25468,-2.10055 c 2.90686,-2.708158 4.01664,-2.645844 6.86438,0.38543 l 2.33546,2.48599 -2.71267,2.51401 c -1.49196,1.38271 -2.80198,2.50152 -2.91114,2.48624 -0.10916,-0.0153 -1.46573,-1.32003 -3.0146,-2.89945 z m 7.01822,-35.404669 c -0.97904,-1.494204 -1.2102,-2.841328 -0.64348,-3.75 1.30098,-2.085967 4.36246,0.122896 4.7578,3.432761 0.40325,3.37603 -1.98925,3.560506 -4.11432,0.317239 z M 483,52.122445 c 0,-1.260517 2.93548,-3.520303 3.6477,-2.808074 C 487.67176,50.338428 486.14346,53 484.53138,53 483.68912,53 483,52.6051 483,52.122445 z"
- style="fill:#ac712e" />
+ id="g3527"
+ transform="matrix(0.09921748,0.09921748,-0.09921748,0.09921748,78.504775,-51.508188)">
<path
- inkscape:connector-curvature="0"
- id="path3784"
- d="m 551.5,220.87969 c -4.95,-0.46752 -11.25,-1.35186 -14,-1.96521 -2.75,-0.61335 -6.86266,-1.29517 -9.13923,-1.51515 -6.19644,-0.59875 -20.69482,-5.03311 -27.15736,-8.30612 -3.13687,-1.5887 -9.26153,-5.7471 -13.61035,-9.24088 -4.34881,-3.49378 -9.74881,-7.7521 -12,-9.46293 -7.00384,-5.32271 -16.17686,-15.66343 -18.5305,-20.8894 -4.64971,-10.32408 -10.1488,-30.01373 -11.45082,-41 -0.78905,-6.65795 0.9162,-25.44854 2.43858,-26.87121 1.22315,-1.14304 1.13813,-0.35628 -0.66302,6.13607 -0.47018,1.69478 -0.27313,2.12856 0.78283,1.72335 1.19245,-0.45759 1.26794,0.89624 0.4871,8.73514 -0.64606,6.48582 -0.58307,10.55956 0.20936,13.541 0.62337,2.34539 1.13341,5.59879 1.13341,7.22976 0,1.63098 0.63665,4.66202 1.41477,6.73565 0.77813,2.07363 1.70901,5.12024 2.06862,6.77024 1.48856,6.82986 13.49423,27.98517 13.51164,23.80902 0.003,-0.65504 -0.44503,-1.4691 -0.99503,-1.80902 -1.72758,-1.0677 -1.08964,-2.5 1.1135,-2.5 2.107,0 2.27328,-1.47629 0.78577,-6.97626 -0.24684,-0.91264 0.42993,-1.60341 1.77262,-1.80931 1.71897,-0.26361 2.067,0.068 1.66892,1.59032 -0.34901,1.3346 0.48567,2.69711 2.72667,4.45096 3.53183,2.76407 3.5131,5.74429 -0.0361,5.74429 -2.31707,0 -2.43791,0.37188 -0.9962,3.06574 0.66611,1.24464 2.09223,1.93426 4,1.93426 1.63065,0 2.96482,0.46599 2.96482,1.03554 0,0.56954 2.025,1.90355 4.5,2.96446 2.54216,1.0897 4.5,2.597 4.5,3.46446 0,2.37869 -3.06194,1.81818 -8,-1.46446 -4.47674,-2.97597 -7,-3.75688 -7,-2.16639 0,1.42885 7.26004,8.59226 12.63398,12.4658 5.31761,3.83295 7.66648,4.6272 7.15986,2.42104 -0.45743,-1.99195 0.40615,-2.13958 4.5383,-0.77585 3.27013,1.07924 3.74833,1.59863 3.2607,3.54152 -0.49439,1.96981 0.10223,2.5666 4.42495,4.42619 2.74801,1.18216 6.56196,2.04395 8.47543,1.91509 2.41916,-0.16293 4.05225,0.38097 5.36063,1.78536 2.16815,2.32723 14.72055,4.96186 18.78274,3.94231 1.43695,-0.36065 3.16893,-0.13144 3.95852,0.52387 0.77209,0.64078 4.32964,1.77835 7.90565,2.52795 5.89969,1.23668 6.94163,1.19399 11.25054,-0.4609 5.86261,-2.25162 9.86251,-1.535 9.50568,1.70302 -0.23522,2.13448 -0.0266,2.18473 6.5,1.56572 4.80826,-0.45604 7.82671,-1.36897 10.51987,-3.18174 3.29002,-2.21452 4.07861,-2.38072 6.11787,-1.28934 1.92604,1.03079 3.64957,0.9429 9.72314,-0.49584 4.06018,-0.9618 9.15416,-2.58101 11.31997,-3.59826 C 617.60364,209.8323 620.88059,209 622.71995,209 627.25282,209 633,206.47508 633,204.48364 c 0,-1.16334 0.56237,-1.43993 2,-0.98364 3.20386,1.01687 6.26256,-0.38796 5.68162,-2.60949 -0.56367,-2.15548 2.73168,-4.64883 3.81898,-2.88954 0.80796,1.3073 5.12979,0.26495 9.302,-2.2435 4.0086,-2.41007 5.64832,-1.39755 2.18246,1.34766 -6.51326,5.15897 -22.81743,12.4762 -37.35023,16.76261 -24.9646,7.36323 -43.22347,9.27029 -67.13483,7.01195 z m 6.16326,-8.69054 c -1.0102,-0.42689 -5.01291,-0.65717 -8.8949,-0.51172 -4.55384,0.17062 -7.98249,-0.22596 -9.66326,-1.11772 -4.41312,-2.34143 -8.93753,-3.78131 -9.93826,-3.16282 -1.3326,0.82359 -9.19228,-2.08514 -11.63837,-4.30714 -1.11566,-1.01346 -3.82847,-2.16352 -6.02847,-2.55569 -4.89922,-0.87333 -6.5,-2.10507 -6.5,-5.00152 0,-2.4733 -2.36286,-4.94985 -5.68841,-5.9621 -2.10366,-0.64032 -8.31139,-6.88051 -8.31178,-8.35524 -1e-4,-0.39336 2.5874,-0.68075 5.75,-0.63864 5.68302,0.0757 5.7538,0.11291 6.05892,3.18799 0.35825,3.61045 2.78527,4.64987 5.49658,2.35403 1.6553,-1.40164 2.05658,-1.25981 4.82916,1.70684 2.67709,2.86448 3.44479,3.16181 6.69469,2.5928 2.01896,-0.35349 4.75835,-1.32672 6.08753,-2.16274 2.18086,-1.37169 2.53317,-1.36074 3.61025,0.11224 1.90448,2.60454 2.35126,1.94498 2.02171,-2.98454 -0.36684,-5.48732 -2.29367,-7.2785 -4.70894,-4.37742 -2.01992,2.4262 -6.83971,2.71691 -6.83971,0.41254 0,-0.86994 -1.62585,-3.56584 -3.613,-5.9909 -3.07642,-3.75436 -3.51975,-4.90626 -2.9851,-7.75619 0.51367,-2.73808 0.14833,-3.86447 -2.0081,-6.1913 -2.36062,-2.54715 -2.57847,-3.40173 -2.08529,-8.18018 C 509.84028,148.14737 513.195,141 515.08156,141 515.5867,141 516,142.32344 516,143.94098 c 0,1.61754 0.40285,3.18996 0.89522,3.49426 1.08344,0.6696 2.10478,-1.73626 2.10478,-4.95801 0,-3.58918 1.7341,-3.8921 3.43637,-0.60027 0.83685,1.61829 2.02726,3.11092 2.64534,3.31694 0.62606,0.20869 -0.29665,1.89519 -2.08334,3.80784 -2.94015,3.14745 -3.31235,3.28935 -4.4711,1.70466 -1.12502,-1.53854 -1.40297,-1.5611 -2.5283,-0.20516 -0.87481,1.05408 -1.6369,1.21421 -2.47366,0.51977 -2.93105,-2.43256 -3.53607,3.75429 -0.62479,6.38896 1.80496,1.63347 2.00122,1.61188 3.90304,-0.42949 1.91094,-2.05116 2.04959,-2.06556 3.0322,-0.31496 0.96588,1.72078 1.20432,1.73378 3.84697,0.20969 1.5495,-0.89363 4.90559,-1.92633 7.45797,-2.29488 4.51661,-0.65218 4.6997,-0.57463 6.84725,2.90017 2.36038,3.81918 2.11662,6.5195 -0.58853,6.5195 -2.46336,0 -8.39942,3.94462 -8.39942,5.58156 0,2.51822 4.4486,1.53928 7.18709,-1.58156 4.58035,-5.21987 8.9075,-3.35182 9.32373,4.02509 0.15826,2.80482 -0.17829,3.97491 -1.14327,3.97491 -1.72758,0 -1.8588,6.10875 -0.16755,7.8 1.58496,1.58496 3.8,1.53271 3.8,-0.0897 0,-1.82893 7.06067,-9.71035 8.69914,-9.71035 0.75017,0 4.11831,0.92788 7.48474,2.06195 5.45125,1.83639 6.28552,1.89722 7.62663,0.55611 1.33026,-1.33026 1.83744,-1.33435 4.34987,-0.0351 2.76731,1.43103 2.80625,1.56116 1.44333,4.82309 -1.3054,3.12426 -1.24548,3.51372 0.88043,5.72318 l 2.28115,2.37079 -2.04711,2.23952 c -1.91688,2.09704 -1.94123,2.35653 -0.38265,4.07874 0.91546,1.01157 1.66447,2.58625 1.66447,3.49928 0,1.18782 0.76027,1.59714 2.67254,1.43887 1.46989,-0.12165 2.86656,0.3609 3.10371,1.07233 0.32808,0.98426 0.88006,0.88728 2.3087,-0.40562 1.53308,-1.38742 2.15617,-1.4679 3.39629,-0.43869 0.83532,0.69325 1.51876,1.92073 1.51876,2.72772 0,1.55806 3.81952,5.20286 5.5,5.24842 0.55,0.0149 2.28894,-0.64512 3.86431,-1.46673 1.57537,-0.82161 3.48787,-1.49384 4.25,-1.49384 1.77774,0 1.74375,-0.52389 -0.22932,-3.53518 C 605.47183,201.07116 603.80594,200 602.55166,200 c -3.27006,0 -3.7386,-1.02804 -1.35003,-2.96219 C 603.94277,194.81817 602.77197,193 598.6015,193 c -2.52458,0 -3.54169,-0.57332 -4.41415,-2.48815 -0.62352,-1.36848 -0.90027,-3.09639 -0.615,-3.83979 0.28527,-0.7434 -0.17681,-1.92883 -1.02684,-2.63429 -0.85003,-0.70546 -1.54551,-2.101 -1.54551,-3.1012 0,-1.00019 -0.45,-2.09665 -1,-2.43657 -2.62718,-1.62369 -0.79751,-4.2159 4.53608,-6.42655 l 5.53608,-2.29457 2.99927,3.13845 c 1.64961,1.72616 3.42224,4.25091 3.93918,5.61057 1.48692,3.91091 6.0426,2.74057 6.49303,-1.66804 0.13261,-1.29792 0.29854,-2.6449 0.36874,-2.99328 0.31462,-1.56155 5.26354,-1.51433 6.41327,0.0612 0.83227,1.14048 2.63022,1.64961 5.71435,1.61814 2.67403,-0.0273 5.86612,0.73221 7.86673,1.87173 2.66414,1.51746 3.74791,1.6796 5.19331,0.77693 2.20524,-1.3772 18.09039,-0.42731 19.11374,1.14295 0.45274,0.69468 1.14737,0.64083 2.11733,-0.16416 1.13925,-0.9455 1.71233,-0.87415 2.71871,0.33846 1.43713,1.73164 1.49255,1.6524 -2.29354,3.27961 -2.32875,1.00087 -2.88011,0.94519 -3.37355,-0.34069 -0.51771,-1.34912 -0.78874,-1.35887 -2.21629,-0.0798 -1.93919,1.73754 -10.57543,1.52947 -14.0665,-0.33889 -2.16296,-1.15758 -4.11922,-1.05924 -10.42825,0.52422 -2.17354,0.54553 -2.76457,0.22439 -3.59191,-1.95166 C 626.49513,179.17209 625.68377,178 625.23675,178 c -0.44701,0 -3.20929,2.25 -6.13841,5 -3.16866,2.9749 -6.24731,5 -7.60122,5 -1.25155,0 -3.28337,0.81609 -4.51516,1.81352 l -2.2396,1.81353 4.07928,-0.0635 c 2.24361,-0.0349 4.64158,-0.62602 5.32882,-1.31352 1.83786,-1.83854 5.29303,-1.52241 7.27301,0.66544 1.60047,1.7685 1.61063,2.10288 0.13246,4.35886 -1.44859,2.21082 -1.45261,2.56656 -0.0423,3.73701 1.30886,1.08626 1.99365,0.8987 4.27253,-1.17021 C 630.14032,193.88811 638,191.36371 638,193.91821 638,196.13189 636.65149,198 635.05353,198 c -0.95288,0 -2.24508,1.125 -2.87158,2.5 -0.62649,1.375 -1.81089,2.5 -2.632,2.5 -0.82111,0 -4.05244,1.13194 -7.18075,2.51543 -4.04711,1.78982 -6.62352,2.33988 -8.93157,1.90689 -2.65287,-0.49768 -3.35744,-0.25034 -3.86785,1.35782 -0.52301,1.64786 -1.88321,2.07618 -8.39795,2.64447 -4.27562,0.37297 -12.47589,0.67088 -18.22284,0.66204 -5.74694,-0.009 -13.37399,0.18524 -16.94899,0.4313 -3.575,0.24606 -7.32653,0.0981 -8.33674,-0.3288 z m 2.91293,-3.31243 c 0.4396,-0.71129 2.42837,-0.91789 5.42232,-0.5633 C 571.69312,208.98786 573,207.95874 573,202.8 c 0,-3.26954 -0.31409,-3.80214 -2.25,-3.81531 -2.98451,-0.0203 -5.34361,-1.49978 -3.85676,-2.41871 0.60872,-0.37621 1.10676,-1.11384 1.10676,-1.63919 0,-0.52534 -1.82009,0.24931 -4.04466,1.72146 -2.68357,1.7759 -3.8509,3.18153 -3.4689,4.17701 0.33323,0.8684 -0.5883,2.7154 -2.18778,4.38489 -2.31553,2.4169 -2.52321,3.03647 -1.2811,3.82187 1.95273,1.23472 2.72025,1.20123 3.55863,-0.1553 z M 582,207.08179 C 582,203.84073 580.87458,202 578.89301,202 c -2.14475,0 -2.30658,0.78202 -0.91776,4.4349 1.13651,2.98925 4.02475,3.45347 4.02475,0.64689 z M 589.5,207 c 0.33992,-0.55 -0.0835,-1 -0.94098,-1 -0.85746,0 -1.55902,0.45 -1.55902,1 0,0.55 0.42344,1 0.94098,1 0.51754,0 1.2191,-0.45 1.55902,-1 z m -52.75,-5.63029 C 539.25336,200.69884 539.85404,198 537.5,198 c -0.98767,0 -1.5,-0.98811 -1.5,-2.89301 0,-3.28294 -2.25934,-4.70435 -4.04933,-2.54755 -0.65756,0.79231 -2.15296,1.45487 -3.32311,1.47236 -1.17016,0.0175 -3.00107,0.6925 -4.06869,1.5 -1.06762,0.80751 -3.30512,1.4682 -4.97222,1.4682 l -3.03109,0 2.21053,2.21053 c 2.04828,2.04828 2.54273,2.12168 6.73657,1 6.0873,-1.6281 7.84421,-1.55683 7.13571,0.28947 -0.61541,1.60375 0.49564,1.83876 4.11163,0.86971 z M 542,187.55448 c 0,-0.73011 -1.35606,-1.52651 -3.01346,-1.76976 l -3.01347,-0.44229 2.15883,2.29797 c 2.19958,2.34135 3.8681,2.30429 3.8681,-0.0859 z m 27.66813,-1.13202 c 0.72462,-1.88834 -2.01618,-4.94342 -3.57217,-3.98177 -1.20758,0.74633 -1.47926,3.84268 -0.42929,4.89264 1.19819,1.19819 3.38298,0.70086 4.00146,-0.91087 z M 522.5,173 c -0.33992,-0.55 -1.04148,-1 -1.55902,-1 -0.51754,0 -0.94098,0.45 -0.94098,1 0,0.55 0.70156,1 1.55902,1 0.85746,0 1.2809,-0.45 0.94098,-1 z m 63.77083,22.39583 c 0.33229,-0.33229 1.1948,-0.36781 1.91667,-0.0789 0.79773,0.31922 0.56078,0.55618 -0.60417,0.60416 -1.05416,0.0434 -1.64479,-0.19293 -1.3125,-0.52522 z m -74.03194,-12.84102 c -2.12128,-4.36624 -2.12498,-4.45619 -0.20821,-5.06455 1.07328,-0.34064 2.43321,-0.3216 3.02205,0.0423 1.64484,1.01657 3.0678,5.51229 2.40535,7.59949 -0.98095,3.0907 -2.93404,2.12625 -5.21919,-2.57727 z M 625,184.55902 c 0,-0.24254 0.45,-0.7191 1,-1.05902 0.55,-0.33992 1,-0.14148 1,0.44098 0,0.58246 -0.45,1.05902 -1,1.05902 -0.55,0 -1,-0.19844 -1,-0.44098 z m 50,-6.76226 c 0,-1.87261 2.50697,-4.12777 4.02584,-3.62148 0.6012,0.2004 -0.0587,1.44638 -1.46638,2.76886 C 675.61264,178.77308 675,178.97717 675,177.79676 z m -186.5,-2.63844 c -4.6345,-2.83354 -5.76494,-4.67555 -5.00178,-8.15022 0.57397,-2.61324 0.13261,-3.67433 -2.94553,-7.08146 -3.99695,-4.42415 -3.95062,-6.12754 0.13693,-5.03436 1.76206,0.47125 3.0095,1.72568 3.64185,3.66224 0.52899,1.62001 1.57081,3.30534 2.31516,3.74517 0.74435,0.43983 1.35337,1.90233 1.35337,3.25 0,1.66979 0.55914,2.45031 1.75531,2.45031 1.15082,0 2.15668,1.28234 2.92079,3.72365 1.75986,5.62263 0.75467,6.44935 -4.1761,3.43467 z m 174.3719,1.1507 c -0.0705,-0.44496 -0.18296,-2.38402 -0.25,-4.30902 -0.10677,-3.06562 -0.47377,-3.54029 -2.95708,-3.82464 -1.78767,-0.2047 -3.28498,0.2905 -4.05261,1.3403 -1.10583,1.51231 -1.33746,1.52032 -2.5267,0.0874 -1.85633,-2.23674 -0.83864,-4.01777 3.4619,-6.05851 2.46923,-1.17172 5.03985,-1.59496 7.60093,-1.25145 3.16419,0.42441 4.14171,0.13092 5.36075,-1.60951 2.107,-3.00816 1.92299,-7.41165 -0.3397,-8.1298 -1.00684,-0.31956 -5.16934,0.48578 -9.25,1.78963 -10.06127,3.21477 -20.48459,2.73672 -15.75379,-0.72253 0.91435,-0.66859 1.83932,-2.54429 2.0555,-4.16824 l 0.39305,-2.95262 1.18348,2.79024 c 1.00986,2.38093 1.47488,2.63428 3.17,1.72708 1.09259,-0.58473 2.51397,-2.04867 3.1586,-3.25319 1.16563,-2.178 1.17625,-2.17875 1.93159,-0.13687 0.60027,1.62269 1.40766,1.95804 3.85085,1.59945 1.70023,-0.24954 3.09133,-0.90078 3.09133,-1.4472 0,-0.54642 0.70351,-0.72353 1.56335,-0.39358 C 668.63327,148.94771 675,142.02148 675,136.03212 c 0,-2.77832 -2.33269,-2.59698 -9.21588,0.7164 -4.45323,2.14368 -5.85408,3.37111 -6.34154,5.55651 -0.59625,2.67316 -0.73395,2.73408 -2.92902,1.29581 -2.29992,-1.50696 -9.51356,-1.19987 -9.51356,0.405 0,0.40929 -1.35,1.01416 -3,1.34416 -2.56025,0.51205 -3,1.05506 -3,3.70446 0,2.98042 -0.12984,3.07628 -3.25,2.39936 -1.7875,-0.38779 -3.475,-1.05318 -3.75,-1.47864 -0.275,-0.42545 -1.625,-0.93142 -3,-1.12436 -1.72937,-0.24268 -2.60227,-1.07316 -2.83178,-2.69416 -0.27247,-1.92442 0.0151,-2.23324 1.60881,-1.72743 2.51348,0.79775 4.59488,-1.68209 3.72149,-4.43389 -0.54528,-1.71802 -0.93454,-1.87836 -2.13714,-0.88029 -2.15835,1.79126 -4.993,-1.53567 -6.06225,-7.11505 -0.94539,-4.9331 -3.74685,-6.41527 -3.78023,-2 -0.0141,1.86193 -0.62354,2.58554 -2.3879,2.83515 -1.51532,0.21437 -2.75377,1.35451 -3.43674,3.1639 -1.1325,3.00033 -1.29305,3.06338 -13.30036,5.22291 -3.90835,0.70292 -7.78723,1.84699 -8.61972,2.54236 -1.23462,1.03128 -2.32102,0.91808 -5.8939,-0.61409 L 583.5,141.2718 l 3.77884,-1.59692 c 3.31081,-1.39914 3.69991,-1.91138 3.14159,-4.1359 -0.78861,-3.14207 0.74444,-3.35272 2.10314,-0.28898 0.62408,1.40725 1.74292,2.1619 2.98712,2.01478 7.61615,-0.90055 14.39478,-2.24616 16.73931,-3.32288 C 615.33421,132.52549 615.95285,130 613.21561,130 611.02097,130 608,125.11775 608,121.57096 c 0,-1.87503 0.71117,-2.89085 2.5,-3.57096 3.00592,-1.14285 3.12976,-2.1201 0.56301,-4.44297 C 608.70844,111.42617 607,112.26798 607,115.55902 607,117.06211 606.42366,118 605.5,118 c -0.825,0 -1.5,0.675 -1.5,1.5 0,2.16336 -1.75536,1.84615 -2.48376,-0.44885 -0.3402,-1.07186 -1.60803,-2.25877 -2.81739,-2.63756 -1.20937,-0.37879 -3.257,-1.51498 -4.5503,-2.52487 -1.29329,-1.00989 -3.92724,-2.13178 -5.85321,-2.49309 -4.38262,-0.82219 -6.33654,-4.70175 -5.27945,-10.48253 0.47794,-2.613672 0.29,-4.480093 -0.5695,-5.655529 -1.69785,-2.321953 -2.25618,-1.576081 -2.82817,3.778196 C 579.02266,104.61065 578.01324,108 576.94847,108 c -0.45005,0 -2.08507,0.53109 -3.63337,1.1802 -1.54831,0.64911 -4.56968,1.28662 -6.71417,1.41668 -2.14449,0.13006 -5.41015,0.51995 -7.25702,0.86643 -2.8779,0.53989 -3.48406,0.30163 -4.24006,-1.66668 C 553.74335,106.25449 549.32808,102 547.01257,102 c -1.75133,0 -1.9177,-0.30874 -1.04505,-1.93931 1.365,-2.550535 -0.0489,-3.394023 -5.68932,-3.394023 -3.8023,0 -4.18578,-0.187663 -2.93643,-1.437011 0.79036,-0.790356 2.94929,-1.744519 4.79762,-2.120362 4.42395,-0.899572 5.28275,-4.618099 1.40689,-6.0917 -2.1352,-0.811801 -2.48104,-1.429355 -1.96094,-3.501612 0.7169,-2.856337 -1.19217,-3.402982 -4.55343,-1.303837 -1.06752,0.66668 -2.29892,0.830073 -2.73643,0.363095 -0.43751,-0.466977 -0.239,-1.047936 0.44114,-1.291018 0.68014,-0.243083 2.25514,-1.274534 3.5,-2.292113 1.81565,-1.484158 2.01611,-2.101563 1.01338,-3.121126 -0.6875,-0.699041 -1.25277,-1.968483 -1.25616,-2.820983 -0.003,-0.8525 -0.67839,-2.838938 -1.5,-4.414307 C 535.67223,67.060324 535,64.558833 535,63.076823 c 0,-1.48201 -0.64854,-3.568072 -1.4412,-4.635693 -0.80188,-1.080048 -1.19291,-2.957101 -0.88148,-4.231425 0.34167,-1.398034 -0.0829,-3.000333 -1.08967,-4.112854 -0.90717,-1.002407 -1.92235,-4.246774 -2.25596,-7.209705 -0.91103,-8.091218 -1.70643,-8.611897 -9.58169,-6.272271 -0.9625,0.285945 -1.75,0.07533 -1.75,-0.468032 0,-0.543363 1.34484,-1.283309 2.98853,-1.644324 3.4585,-0.759615 4.69498,-2.219009 3.17114,-3.742847 -0.75143,-0.751437 -0.75366,-1.649787 -0.008,-3.043917 0.9938,-1.856924 0.82472,-1.933992 -2.76537,-1.260488 -2.10313,0.394551 -5.18803,1.316815 -6.85532,2.049475 -3.01418,1.324529 -3.00067,1.332574 2.37356,1.413684 L 522.30998,30 520.40735,32.102379 C 517.73279,35.057729 513.6252,37 510.04966,37 c -3.51428,0 -3.98119,1.431092 -0.98933,3.032288 1.13318,0.60646 1.91452,1.859793 1.73631,2.785184 C 510.39525,44.901701 507.5,45.062005 507.5,43 c 0,-2.618162 -1.76244,-2.906762 -5.64746,-0.924772 -5.17712,2.64117 -7.28883,2.601375 -5.61101,-0.105741 1.03724,-1.673566 1.00068,-2.190884 -0.20799,-2.942797 -0.90955,-0.565831 -1.93653,-0.522164 -2.70425,0.114985 -2.05447,1.70506 -8.32929,4.6913 -8.32929,3.963981 0,-1.852307 10.04363,-7.834663 15,-8.934548 7.25395,-1.609751 9.71647,-3.135012 5.09501,-3.155795 -3.26865,-0.0147 -3.33688,-0.09057 -1.70402,-1.894857 0.93553,-1.033749 3.36777,-2.147794 5.40499,-2.475655 2.03721,-0.327862 5.50402,-1.532171 7.70402,-2.676243 5.35427,-2.784397 13.39181,-5.404811 22.5,-7.335496 11.12382,-2.357943 14.56594,-2.644436 37,-3.079574 15.94207,-0.309218 22.05637,-0.0551 27.5,1.142909 3.85,0.847294 8.8,1.888984 11,2.314869 2.2,0.425884 5.575,1.334166 7.5,2.018405 1.925,0.684239 5.525,1.925999 8,2.759466 17.03389,5.736235 38.01468,19.050886 44.71422,28.376153 1.91036,2.65909 3.84662,4.83471 4.30279,4.83471 0.92125,0 7.74917,10.132534 13.3015,19.739227 4.90427,8.485397 9.90078,21.237639 9.29527,23.723641 -0.2729,1.120423 0.15236,2.910642 0.94502,3.978262 1.82427,2.45708 1.82835,3.55887 0.0132,3.55887 -0.98006,0 -1.64245,1.71601 -2.11149,5.47008 -0.37589,3.00854 -1.30595,5.98672 -2.0668,6.61817 -1.02275,0.8488 -1.21848,2.55104 -0.75084,6.52992 0.6256,5.32285 0.60328,5.38183 -2.03653,5.38183 -1.46799,0 -2.92809,0.675 -3.24467,1.5 -0.31659,0.825 -0.95015,1.5 -1.40792,1.5 -0.45777,0 -0.14475,-2.01788 0.6956,-4.48417 1.92467,-5.64859 1.393,-7.75603 -1.19435,-4.73422 -1.04469,1.22011 -2.6605,2.21839 -3.59069,2.21839 -0.93019,0 -3.07809,1.88581 -4.77312,4.19069 -2.7487,3.73766 -2.93497,4.41331 -1.72302,6.25 1.73293,2.62624 7.59414,3.37811 8.84935,1.13518 0.48504,-0.86673 1.53363,-1.57587 2.33019,-1.57587 1.5898,0 8.50477,-6.32403 10.38771,-9.5 0.98478,-1.66104 1.0905,-1.15247 0.62379,3.0008 -1.02446,9.11677 -5.57665,19.29111 -15.3441,34.29472 -4.35241,6.68568 -5.66788,8.07357 -6.77856,7.15179 -0.75797,-0.62906 -1.27876,-2.11205 -1.15732,-3.29553 0.17991,-1.7532 -0.24227,-2.09663 -2.27919,-1.85407 -6.70341,0.79829 -12,4.2403 -12,7.79826 0,2.1358 -1.84671,4.49011 -2.1281,2.71305 z M 683.25,158.19301 c 0.9625,-0.82664 1.75,-2.29644 1.75,-3.26621 0,-3.28647 1.23279,-4.99722 4.62129,-6.41303 2.2812,-0.95315 3.37871,-2.07795 3.37871,-3.46274 0,-2.3991 -2.21321,-2.70398 -4,-0.55103 -0.68469,0.825 -2.48743,1.5 -4.00608,1.5 -3.45688,0 -9.99392,6.83745 -9.99392,10.45319 0,4.32134 4.21038,5.20925 8.25,1.73982 z M 678.5,142 c -0.33992,-0.55 -0.81648,-1 -1.05902,-1 -0.24254,0 -0.44098,0.45 -0.44098,1 0,0.55 0.47656,1 1.05902,1 0.58246,0 0.7809,-0.45 0.44098,-1 z M 645,138.12244 c 0,-0.48265 -0.675,-1.43775 -1.5,-2.12244 -1.2532,-1.04007 -1.5,-0.89568 -1.5,0.87756 0,1.21995 0.63782,2.12244 1.5,2.12244 0.825,0 1.5,-0.3949 1.5,-0.87756 z m 5.72976,-1.43315 C 650.06001,134.68002 648,134.82792 648,136.88528 c 0,1.43811 0.46137,1.87491 1.54226,1.46013 0.84825,-0.3255 1.38262,-1.07076 1.1875,-1.65612 z M 632,136.58179 c 0,-0.23002 -0.27314,-1.13002 -0.60699,-2 C 630.53559,132.34739 629,132.61575 629,135 c 0,1.11111 0.66667,2 1.5,2 0.825,0 1.5,-0.1882 1.5,-0.41821 z M 657.5,135 c 1.95846,-1.1 4.22215,-2 5.03042,-2 0.80827,0 1.46958,-0.45 1.46958,-1 0,-0.55 0.9,-1 2,-1 1.1,0 2,-0.45 2,-1 0,-0.55 1.0125,-1.01431 2.25,-1.0318 3.70057,-0.0523 5.75,-2.3191 5.75,-6.35983 0,-4.08077 -2.16102,-5.73824 -4.88592,-3.74741 -0.88775,0.64858 -3.07658,1.85124 -4.86408,2.67256 -1.7875,0.82133 -3.25,1.93728 -3.25,2.4799 0,0.54262 -0.86278,0.98658 -1.91729,0.98658 -1.35398,0 -2.42743,1.33577 -3.65359,4.54642 -1.20887,3.16538 -2.05415,4.22855 -2.7827,3.5 C 652.93219,131.33219 652,131.84421 652,134.5 c 0,3.02254 0.86829,3.10148 5.5,0.5 z m 1.57895,-4.41667 c -0.0434,-1.05416 0.19293,-1.64479 0.52522,-1.3125 0.33229,0.33229 0.36781,1.19479 0.0789,1.91667 -0.31922,0.79773 -0.55618,0.56078 -0.60416,-0.60417 z m -1.7339,-13.50885 c -0.14411,-2.98762 -0.0336,-3.10262 1.57874,-1.64345 2.11456,1.91365 5.07621,2.05559 5.07621,0.24328 0,-0.72912 -1.16127,-2.41662 -2.58059,-3.75 -2.41678,-2.27042 -2.66182,-2.31322 -3.86024,-0.67431 -0.70381,0.9625 -1.98005,1.75 -2.83608,1.75 -2.25399,0 -2.65741,2.08682 -1.02722,5.31378 1.82052,3.60373 3.84954,2.91465 3.64918,-1.2393 z m 31.21382,1.5033 c 1.57632,-1.15494 1.90408,-2.49187 1.74398,-7.11382 -0.10843,-3.13038 -0.42653,-5.92097 -0.70687,-6.20132 -1.24063,-1.24063 -3.46132,0.94846 -6.12697,6.03978 -2.44396,4.66791 -2.67838,5.74037 -1.55153,7.09815 1.64234,1.9789 4.09309,2.04429 6.64139,0.17721 z m -70.91561,-6.09051 C 618.38833,110.54565 616.28551,108 613.93657,108 c -2.94108,0 -3.45303,2.16338 -0.9849,4.16195 2.7588,2.23394 3.92807,2.31502 4.69159,0.32532 z m 55.32417,-1.96714 C 673.53534,110.16914 674,108.15667 674,106.04797 c 0,-4.6446 -1.86169,-5.68797 -6.17197,-3.45904 -2.65978,1.37543 -2.96824,1.96002 -2.43666,4.61792 0.33475,1.67373 0.60863,3.63049 0.60863,4.34834 0,0.97157 0.75853,1.08766 2.96743,0.45415 1.63209,-0.46807 3.43209,-1.13822 4,-1.48921 z m -20.225,-2.603 c 0.13333,-0.77942 -0.62625,-2.53919 -1.68796,-3.9106 -1.75745,-2.2701 -1.99251,-2.33158 -2.62388,-0.68623 -0.87696,2.2853 1.19026,6.9726 2.83376,6.42538 0.67961,-0.22628 1.34474,-1.04912 1.47808,-1.82855 z m 3.46972,-5.27202 c -0.3089,-2.83853 0.65575,-3.377209 2.58785,-1.44511 0.93333,0.93333 1.2,0.74193 1.2,-0.86133 0,-1.601072 0.50455,-1.964875 2.25971,-1.629355 1.6545,0.316277 2.87697,-0.402906 4.56436,-2.685228 2.93978,-3.976259 2.51173,-6.426291 -1.19705,-6.851551 -3.68081,-0.422054 -8.94693,4.244148 -8.03444,7.119158 0.49566,1.561688 0.23696,1.788979 -1.43296,1.258969 -2.89727,-0.91956 -4.58567,2.420148 -2.99191,5.918087 1.47386,3.23476 3.42854,2.70594 3.04444,-0.82364 z m -49.60516,0.7731 C 606.27314,102.54823 606,101.62167 606,101.3592 c 0,-0.26248 -0.45,-0.19912 -1,0.1408 -1.59337,0.98476 -1.15716,3.5 0.60699,3.5 1.05452,0 1.39831,-0.5438 1,-1.58179 z m 87.81122,0.9748 c 0.86999,-0.33384 1.58179,-1.45884 1.58179,-2.5 0,-2.327556 -0.79631,-2.387324 -3.17126,-0.23802 -3.00251,2.71724 -2.15607,4.17532 1.58947,2.73802 z M 556,102.5 c 0,-0.825 -0.7301,-1.5 -1.62244,-1.5 -1.3288,0 -1.39713,0.27149 -0.37756,1.5 0.68469,0.825 1.41479,1.5 1.62244,1.5 C 555.8301,104 556,103.325 556,102.5 z m 128.78518,-2.22388 C 689.3633,97.36908 693,93.595997 693,91.753247 c 0,-2.370459 -1.68131,-2.217238 -3.01499,0.274761 C 688.48008,94.839999 687,93.557257 687,89.440983 687,87.548442 686.63828,86 686.19617,86 c -1.3911,0 -7.02927,6.382614 -8.06396,9.128683 -0.74401,1.974611 -0.62075,3.156511 0.49537,4.75 1.80017,2.570107 2.64967,2.624937 6.1576,0.397437 z M 645,96.11501 C 645,95.270658 640.6565,92 639.53518,92 c -1.21203,0 -0.41338,2.371976 1.21482,3.607954 2.01805,1.531915 4.25,1.798204 4.25,0.507056 z M 628.5,93 c -0.33992,-0.55 -1.06803,-1 -1.61803,-1 -0.55,0 -0.72189,0.45 -0.38197,1 0.33992,0.55 1.06803,1 1.61803,1 0.55,0 0.72189,-0.45 0.38197,-1 z m 21.42667,-0.411645 c 0.94088,-1.133687 0.50337,-1.921303 -2.22194,-4 -5.67738,-4.33035 -8.42113,-2.781631 -4.12252,2.326973 2.84502,3.381115 4.55307,3.831525 6.34446,1.673027 z M 553.42974,88.11369 c 0.30127,-0.48747 -0.45967,-1.156326 -1.69099,-1.486345 C 548.44191,85.743717 548,85.846861 548,87.5 c 0,1.631194 4.48743,2.138381 5.42974,0.61369 z m 104.84965,-8.775523 c -1.31693,-3.950794 -3.58427,-5.048143 -6.83539,-3.308198 -3.66745,1.962762 -4.08485,3.658978 -1.56137,6.345099 1.17462,1.250318 1.84242,2.566547 1.48402,2.924953 -0.35841,0.358406 -0.10252,1.31331 0.56864,2.122009 1.0423,1.255894 1.6595,0.970135 4.23141,-1.959109 2.538,-2.890617 2.86995,-3.852968 2.11269,-6.124754 z M 619.96858,85.75 c -0.0173,-0.6875 -1.14699,-2.062054 -2.51045,-3.054565 -2.31281,-1.683569 -2.52274,-1.690636 -3.13106,-0.105392 -0.41068,1.070214 0.0341,2.200878 1.20158,3.054565 2.321,1.697159 4.48123,1.748437 4.43993,0.105392 z m 59.80891,-1.306704 C 680.99987,83.587109 682,82.268312 682,81.512637 682,79.466724 677.68726,73.091098 676.27032,73.042326 674.97914,72.997883 671,79.957434 671,82.260162 c 0,3.635002 4.94774,4.865601 8.77749,2.183134 z M 595,83.5 c 0,-0.933333 -0.94444,-1.5 -2.5,-1.5 -1.55556,0 -2.5,0.566667 -2.5,1.5 0,0.933333 0.94444,1.5 2.5,1.5 1.55556,0 2.5,-0.566667 2.5,-1.5 z m 42.12868,-4.063539 C 635.55821,77.439929 635,77.167225 635,78.396526 c 0,0.916434 -0.675,1.925265 -1.5,2.241848 -2.37402,0.910996 -1.75059,2.196928 1.25,2.578349 4.01837,0.510796 4.78974,-0.715091 2.37868,-3.780262 z M 552.12895,82.25 c 0.69897,-4.065406 0.2727,-6.17321 -1.33337,-6.593206 -2.58858,-0.676929 -2.20744,-2.336607 0.70442,-3.067438 1.375,-0.345103 2.5,-1.068887 2.5,-1.608408 0,-1.250516 -1.18927,-1.239684 -4.55911,0.04153 -2.45541,0.933543 -2.63546,1.359294 -2.07009,4.894924 0.49815,3.115266 0.27803,4.011748 -1.12578,4.58486 -1.59865,0.652655 -1.57726,0.781393 0.25498,1.534791 2.58222,1.061784 5.46426,1.170815 5.62895,0.21295 z m 14.29903,-5.329585 C 565.4721,75.864187 565.07477,75 565.54501,75 c 0.47025,0 0.34794,-0.507053 -0.27179,-1.126784 C 563.99438,72.594377 559,73.506627 559,75.019052 c 0,0.539521 1.2375,1.011404 2.75,1.048628 2.70054,0.06646 2.70953,0.0872 0.5,1.152815 -1.2375,0.596823 -2.25,1.435069 -2.25,1.862768 0,1.197052 4.27838,1.629556 6.33296,0.640204 1.74326,-0.839437 1.74791,-0.97663 0.095,-2.803052 z M 609,79.5 c 0,-0.833333 -0.88889,-1.5 -2,-1.5 -1.11111,0 -2,0.666667 -2,1.5 0,0.833333 0.88889,1.5 2,1.5 1.11111,0 2,-0.666667 2,-1.5 z m 54.77106,-1.31318 c 0.24358,-0.73075 -0.21359,-0.954237 -1.1875,-0.580511 C 661.7126,77.940527 661,78.653333 661,79.190322 c 0,1.314392 2.27278,0.491335 2.77106,-1.003502 z M 579,77 c 0,-0.55 -0.70156,-1 -1.55902,-1 -0.85746,0 -1.2809,0.45 -0.94098,1 0.33992,0.55 1.04148,1 1.55902,1 C 578.57656,78 579,77.55 579,77 z m 44,-0.671259 C 623,75.072959 619.69544,72 618.34501,72 c -1.93726,0 -1.65631,2.719304 0.40499,3.919901 2.0164,1.174444 4.25,1.389311 4.25,0.40884 z M 646.03355,71.5 c 0.56364,-5.729211 -1.62198,-7.654914 -5.67445,-4.999633 -3.21727,2.108037 -3.03931,5.62093 0.3909,7.71609 3.06654,1.873036 4.92609,0.916979 5.28355,-2.716457 z m 23.88026,-1.597292 2.28993,-3.097291 -2.97019,-3.152709 c -1.63361,-1.733989 -3.38818,-3.946184 -3.89905,-4.915988 -0.87458,-1.660231 -1.05491,-1.645852 -3.08563,0.246049 -2.66934,2.486873 -3.8788,8.339276 -2.39596,11.593757 1.70374,3.739304 7.06353,3.380338 10.0609,-0.673818 z m -57.18405,0.407999 c 0.49435,-1.483026 -2.11636,-2.315474 -3.82044,-1.218187 -1.20138,0.773587 -1.188,1.052626 0.0907,1.891224 1.72585,1.131861 3.21788,0.862623 3.72976,-0.673037 z M 680,71 c 0,-0.55 -0.45,-1 -1,-1 -0.55,0 -1,0.45 -1,1 0,0.55 0.45,1 1,1 0.55,0 1,-0.45 1,-1 z M 564.58288,70.134109 C 564.08502,69.328543 559,69.767985 559,70.616577 559,70.82746 560.37656,71 562.05902,71 c 1.68246,0 2.8182,-0.389651 2.52386,-0.865891 z M 548,67 c 1.17323,-0.758201 0.91378,-0.97271 -1.19098,-0.984687 C 545.32898,66.006891 543.83992,66.45 543.5,67 c -0.78917,1.276897 2.52414,1.276897 4.5,0 z m 83.96482,-2.934259 C 633.50101,61.195336 633.23307,59.233066 631,57 c -2.55549,-2.555485 -2.95893,-2.520654 -6.26022,0.540469 -3.51006,3.254715 -3.44673,4.057892 0.51022,6.470491 4.07315,2.483446 5.4092,2.494345 6.71482,0.05478 z m 42.43144,-1.655983 c 0.92761,-2.417322 -0.3327,-3.616179 -2.02378,-1.9251 -0.825,0.825 -1.21975,1.953452 -0.87722,2.507671 0.91806,1.485459 2.20672,1.226673 2.901,-0.582571 z M 547.30397,61.099944 c 2.04976,-1.045031 6.87169,-2.21588 10.71539,-2.601888 3.8437,-0.386008 7.22145,-1.078681 7.50611,-1.539272 1.12322,-1.817399 -0.85127,-8.678808 -3.36723,-11.70126 C 559.55371,42.128668 553,39.787353 553,41.985738 553,42.543582 553.675,43 554.5,43 c 1.94185,0 1.94449,1.892204 0.004,2.636964 -1.18733,0.455624 -1.3654,1.688141 -0.86232,5.968615 0.73798,6.279004 -0.90493,7.401168 -3.10982,2.124119 -1.97666,-4.730815 -4.61422,-6.887981 -6.60667,-5.403366 -3.00504,2.239114 -4.88883,6.207548 -4.48003,9.437702 0.74216,5.864292 1.91959,6.364064 7.85914,3.33591 z M 559.5,62 c 0.33992,-0.55 -0.28197,-1 -1.38197,-1 -1.1,0 -2.27811,0.45 -2.61803,1 -0.33992,0.55 0.28197,1 1.38197,1 1.1,0 2.27811,-0.45 2.61803,-1 z m 55.75,-2.392046 c 0.9625,-0.730642 1.75,-1.918397 1.75,-2.639456 0,-0.721059 0.72958,-2.11719 1.62128,-3.102512 3.05758,-3.378582 -0.6303,-7.094169 -5.04485,-5.082763 -2.9059,1.324016 -5.49352,10.018825 -3.3805,11.359028 1.80236,1.143168 3.01287,1.015198 5.05407,-0.534297 z m 39.67327,-1.196848 c 3.79753,-3.195403 3.88978,-5.393072 0.32041,-7.63246 -1.50903,-0.946745 -3.47001,-2.255862 -4.35776,-2.909148 -2.57679,-1.896251 -4.63192,-0.332369 -5.37971,4.09377 -0.5091,3.013292 -0.26393,4.757547 0.92339,6.569628 2.07179,3.161954 4.63484,3.125203 8.49367,-0.12179 z M 602.4,52.549738 C 602.4,48.533037 599.6547,45 596.53357,45 c -3.19583,0 -6.70737,3.705664 -6.34106,6.691629 0.24756,2.018047 1.28201,2.838279 5.30749,4.208407 2.75,0.936 5.4275,1.341401 5.95,0.900891 0.5225,-0.44051 0.95,-2.353545 0.95,-4.251189 z m -18.57036,1.867715 c 1.67402,-0.523498 0.64153,-6.130983 -1.59592,-8.667453 -2.0576,-2.332586 -4.11926,-2.206158 -6.91927,0.424314 -2.21781,2.083528 -3.21744,7.589361 -1.66057,9.146231 0.61133,0.611332 7.20397,0.02624 10.17576,-0.903092 z m 55.22673,-6.640314 C 640.67537,46.004565 642,44.213711 642,43.797463 642,42.828104 634.5367,39 632.64683,39 c -2.94871,0 -3.65372,7.229913 -0.99184,10.171259 2.35444,2.601625 4.04219,2.28372 7.40138,-1.39412 z m -99.36421,0.292036 c 0.59921,-2.291394 2.86928,-3.343145 5.44872,-2.524462 1.93745,0.614922 2.60228,-0.967381 0.85912,-2.044713 -0.55,-0.339919 -1,-3.011376 -1,-5.936572 0,-6.817466 -1.41874,-8.198536 -6.70156,-6.52363 -6.08755,1.930043 -6.78133,2.490834 -7.10684,5.744611 -0.22519,2.250908 0.22508,3.368222 1.66871,4.140834 1.08742,0.581967 2.29162,2.524366 2.67601,4.31644 0.38438,1.792074 0.89751,3.595817 1.14029,4.008317 0.82992,1.410072 2.51006,0.752162 3.01555,-1.180825 z M 606,43 c 0,-1.1 -0.42344,-2 -0.94098,-2 -1.34235,0 -2.28822,1.820126 -1.55902,3 1.04512,1.691037 2.5,1.109085 2.5,-1 z M 565.81184,40.738516 C 566.03534,39.577971 565.51278,39 564.23999,39 c -2.44821,0 -3.24357,0.827103 -2.54526,2.646858 0.74244,1.934782 3.69503,1.283366 4.11711,-0.908342 z M 574,40.5 c 0,-0.825 -0.45,-1.5 -1,-1.5 -0.55,0 -1,0.675 -1,1.5 0,0.825 0.45,1.5 1,1.5 0.55,0 1,-0.675 1,-1.5 z m 48.77749,-0.0567 C 623.99987,39.587109 625,38.243148 625,37.456716 625,36.071687 619.10385,33 616.44526,33 c -1.99296,0 -2.81529,3.940068 -1.38149,6.61916 1.47391,2.754028 4.49725,3.077042 7.71372,0.824136 z m -60.27413,-3.088775 c 0.95337,-1.455013 1.79262,-4.042513 1.86501,-5.75 L 564.5,28.5 l -6.49572,0.34632 c -11.01899,0.587479 -12.65255,2.840216 -5.75428,7.935349 5.25509,3.881466 7.98552,4.034014 10.25336,0.572852 z m 39.19959,1.452118 C 606.13834,36.914278 608,34.897509 608,31.984915 c 0,-2.556487 -0.31469,-2.737588 -5.72777,-3.296268 -3.44662,-0.355722 -6.1788,-1.207964 -6.86025,-2.139902 -1.93188,-2.642007 -2.90147,-1.720319 -3.176,3.019094 -0.22566,3.895677 0.16275,4.984733 2.67307,7.495062 3.37671,3.376705 3.12057,3.310962 6.7939,1.743738 z m -19.73903,-2.772935 c 2.37259,-2.216334 3.09461,-3.670092 2.85575,-5.75 C 584.50655,27.557061 584.36676,27.5 578,27.5 l -6.5,0 -0.31864,3.320774 C 570.77399,35.066353 573.29211,39 576.4173,39 c 1.30415,0 3.80013,-1.334833 5.54662,-2.966296 z M 535.06574,29.96482 c 2.99783,-1.60439 2.30984,-2.725567 -2.13312,-3.476201 -5.06416,-0.855584 -5.91252,-0.118719 -2.82428,2.453112 2.84982,2.373286 2.55011,2.311432 4.9574,1.023089 z M 496.50227,174.00367 C 496.1611,173.45165 496.78197,173 497.88197,173 c 1.1,0 2.30234,-0.48921 2.67188,-1.08713 0.47741,-0.77247 0.98173,-0.77729 1.74235,-0.0167 1.30419,1.30419 0.96616,1.63975 -2.48491,2.46679 -1.4788,0.35439 -2.96786,0.1927 -3.30902,-0.35932 z m 8.86972,-1.47666 c -0.8298,-2.16242 -0.37251,-2.44654 2.91982,-1.81414 3.1976,0.61422 3.11675,2.63042 -0.12461,3.10727 -1.30233,0.19159 -2.42472,-0.32766 -2.79521,-1.29313 z m -7.64282,-4.13118 C 497.32812,167.99479 497,166.97667 497,166.13333 c 0,-1.12559 0.29583,-1.2375 1.1125,-0.42083 0.61187,0.61187 0.94,1.63 0.72917,2.2625 -0.21084,0.6325 -0.71146,0.82187 -1.1125,0.42083 z m 107.65561,-0.16114 c -0.61337,-0.40408 -1.45431,-1.85969 -1.86876,-3.23469 -0.7526,-2.49687 -0.74964,-2.49633 2.36522,0.43709 1.71532,1.6154 3.11876,3.0779 3.11876,3.25 0,0.5936 -2.50288,0.28039 -3.61522,-0.4524 z M 592.75,158.24177 C 590.21513,156.67015 589.12393,155 590.63197,155 c 0.85037,0 7.36803,4.05279 7.36803,4.58156 0,0.94122 -2.66994,0.25986 -5.25,-1.33979 z m 32.42372,-0.2471 c -3.26257,-2.71913 -1.86417,-4.40308 1.99793,-2.4059 2.19866,1.13696 3.36312,1.27646 4.14325,0.49633 1.55671,-1.55671 3.6851,-1.3374 3.6851,0.37972 0,1.68607 -3.0265,3.55061 -5.68426,3.50191 -0.99866,-0.0183 -2.86257,-0.90573 -4.14202,-1.97206 z M 465.75,155.33936 c -1.5125,-0.79667 -2.75,-2.09894 -2.75,-2.89393 0,-2.02361 1.06758,-1.76282 4.25,1.03821 4.21854,3.71298 3.56383,4.52295 -1.5,1.85572 z M 583,153.07673 c 0,-0.50781 -1.165,-2.30781 -2.58889,-4 L 577.82221,146 l 2.50711,0 c 1.37891,0 3.21891,0.27314 4.08889,0.60699 1.87444,0.71929 2.12843,3.36529 0.33179,3.4564 -0.6875,0.0349 -0.2375,0.47036 1,0.96777 3.00939,1.20963 2.86125,2.96884 -0.25,2.96884 -1.375,0 -2.5,-0.41547 -2.5,-0.92327 z m -8,-1.51771 c 0,-1.05548 1.91911,-1.49891 2.48992,-0.57533 C 577.83538,151.54266 577.41648,152 576.55902,152 575.70156,152 575,151.80156 575,151.55902 z M 477.99274,148.4809 C 477.47396,147.1164 476.61869,146 476.09214,146 c -1.51455,0 -2.37012,-3.96012 -1.16841,-5.4081 0.60698,-0.73136 2.19524,-1.10065 3.58837,-0.83434 1.37466,0.26279 3.14042,-0.0542 3.92391,-0.70445 1.13519,-0.94213 1.64365,-0.77278 2.50348,0.83382 0.84499,1.57888 0.63101,2.8755 -0.98676,5.97926 -2.60716,5.00194 -4.70282,5.92132 -5.95999,2.61471 z M 495,150 c 0,-0.55 0.45,-1 1,-1 0.55,0 1,0.45 1,1 0,0.55 -0.45,1 -1,1 -0.55,0 -1,-0.45 -1,-1 z m 64.653,-1.40683 c -1.72178,-2.62778 -0.7805,-4.23981 1.87963,-3.21902 0.81333,0.3121 1.88571,-0.28731 2.47118,-1.38126 0.88344,-1.65074 1.39997,-1.76604 3.54115,-0.79045 2.82334,1.2864 2.75906,3.1206 -0.12783,3.64739 -1.05442,0.19241 -2.86578,1.22337 -4.02524,2.29102 -2.0947,1.92883 -2.1185,1.92534 -3.73889,-0.54768 z m 62.72669,-1.04611 c -0.44593,-1.16206 -0.93514,-1.21713 -2.44366,-0.27504 -1.45817,0.91064 -2.16567,0.89834 -3.11821,-0.0542 -1.79593,-1.79593 1.47091,-5.05301 3.43403,-3.42377 0.74372,0.61724 2.34131,0.8636 3.55019,0.54747 2.24352,-0.5867 2.67589,0.24944 1.59097,3.07669 -0.75942,1.97901 -2.27843,2.04396 -3.01332,0.12885 z m -94.20557,-0.83726 c -0.96202,-1.15916 -0.79907,-1.92962 0.81015,-3.83041 1.99451,-2.3559 2.02955,-2.35977 3.54897,-0.39188 1.39065,1.80109 2.5162,1.95624 12.00067,1.65419 6.91903,-0.22035 10.46609,0.0262 10.46609,0.72731 0,2.06745 -3.59432,2.85726 -11,2.41714 -8.92822,-0.5306 -8.8131,-0.53303 -12.06082,0.25406 -1.65661,0.40148 -2.98603,0.10827 -3.76506,-0.83041 z m -40.52493,-2.18162 c -0.31064,-0.80951 -0.0449,-2.94701 0.59044,-4.75 l 1.15524,-3.27818 0.70926,3.41135 C 490.83684,143.43543 490.37177,146 489,146 c -0.43231,0 -1.04018,-0.66232 -1.35081,-1.47182 z m -26.42401,-1.02212 c -1.80114,-0.6177 -2.96364,-1.43426 -2.58333,-1.81458 1.01026,-1.01026 8.35815,-0.84668 8.35815,0.18608 0,1.99621 -2.58062,2.72395 -5.77482,1.6285 z M 476,133.95731 c 0,-1.14884 -0.49517,-3.01403 -1.10039,-4.14489 -0.89444,-1.67127 -0.71521,-2.44126 0.95761,-4.11408 1.75321,-1.75322 2.43451,-1.88645 4.60039,-0.89961 1.64686,0.75036 2.537,1.95849 2.52708,3.42983 -0.019,2.81093 -0.73961,3.84351 -4.23469,6.06759 -2.68082,1.70593 -2.75,1.69741 -2.75,-0.33884 z m 94.20872,-3.19622 c -1.58845,-0.76505 -2.0678,-1.58783 -1.56272,-2.68232 0.40071,-0.86833 0.75679,-3.22781 0.79128,-5.2433 0.0345,-2.01549 0.40022,-4.00299 0.81272,-4.41666 0.4125,-0.41368 0.75,0.58685 0.75,2.22339 0,1.63655 0.66069,3.84905 1.4682,4.91667 1.53317,2.02704 2.0807,6.49066 0.7818,6.37345 -0.4125,-0.0372 -1.78108,-0.56428 -3.04128,-1.17123 z m 10.33092,-2.10845 c -1.25173,-0.91529 -1.47999,-1.57147 -0.7118,-2.04624 1.45227,-0.89755 5.41624,1.18966 4.64115,2.44377 -0.79799,1.29117 -1.7519,1.19467 -3.92935,-0.39753 z M 540.22251,122.4433 C 538.04187,120.91592 537.1072,117 538.92327,117 c 0.50781,0 2.33928,1.19149 4.06995,2.64775 2.37746,2.0005 2.82401,2.85235 1.82673,3.48469 -1.79119,1.13573 -2.04676,1.09742 -4.59744,-0.68914 z m 40.2718,-0.28232 c -1.96535,-1.96536 2.5656,-3.04293 5.357,-1.27404 0.95827,0.60726 0.44762,0.98896 -1.75569,1.31233 -1.70885,0.25081 -3.32944,0.23358 -3.60131,-0.0383 z m -119.82764,-2.82765 c -1.04997,-1.04996 -0.77829,-4.14631 0.42929,-4.89264 0.60278,-0.37254 1.80162,0.0283 2.6641,0.8908 1.29182,1.29182 1.34144,1.84128 0.28159,3.11832 -1.39413,1.67983 -2.33292,1.92559 -3.37498,0.88352 z m 20.3446,-1.81976 c -1.09355,-1.31763 -0.98134,-1.93177 0.69294,-3.79289 1.09877,-1.22137 2.2757,-3.00818 2.61539,-3.97068 0.76096,-2.15612 2.03601,-2.23137 3.70634,-0.21874 1.04121,1.25458 0.98577,1.75146 -0.30681,2.75 -0.86771,0.67031 -1.72198,2.33914 -1.89839,3.70852 -0.37818,2.93566 -2.95909,3.75337 -4.80947,1.52379 z m 49.75766,-2.78052 C 528.93664,113.29123 527.44572,109 528.77707,109 c 0.50152,0 2.13234,1.04874 3.62406,2.33053 2.25027,1.9336 2.47568,2.52682 1.32349,3.48305 -1.05267,0.87364 -1.76789,0.85416 -2.95569,-0.0805 z M 580.002,114.75 c -0.003,-1.07943 4.22881,-0.89531 5.998,0.26097 1.09776,0.71746 0.49493,0.91447 -2.248,0.73469 -2.06139,-0.13511 -3.74889,-0.58316 -3.75,-0.99566 z m -73.44623,-0.65976 c -0.30924,-0.50036 -0.28833,-1.62361 0.0465,-2.4961 0.50275,-1.31014 0.068,-1.4782 -2.49676,-0.96524 C 501.4919,111.15162 501,110.94509 501,109.325 c 0,-1.05875 0.54,-2.465 1.2,-3.125 0.93333,-0.93333 0.93333,-1.2 0,-1.2 -0.66,0 -1.2,-0.675 -1.2,-1.5 0,-1.94318 0.58791,-1.89146 2.84219,0.25 1.0132,0.9625 3.97503,3.49068 6.58183,5.61817 3.50701,2.86219 4.44746,4.16035 3.61617,4.99164 C 513.2089,115.1911 512.67831,115.09753 512,114 c -0.73008,-1.1813 -1.1695,-1.2305 -2.15836,-0.24164 -1.4726,1.4726 -2.51575,1.57796 -3.28587,0.33188 z M 467,107 c 0,-0.55 -0.7063,-1 -1.56955,-1 -2.09532,0 -1.50428,-3.93604 0.80875,-5.38595 1.40482,-0.880593 2.26999,-0.55311 4.5,1.70336 2.69188,2.72381 2.71234,2.82961 0.81967,4.23807 C 469.3147,108.22551 467,108.45121 467,107 z m 58,-0.5 c 0,-0.825 0.45,-1.5 1,-1.5 0.55,0 1,0.675 1,1.5 0,0.825 -0.45,1.5 -1,1.5 -0.55,0 -1,-0.675 -1,-1.5 z m -6.31775,-4.75 c 0.74858,-3.847994 2.67784,-5.558727 3.13054,-2.775939 C 522.17192,101.1817 520.38317,105 518.98982,105 c -0.52333,0 -0.65964,-1.44026 -0.30757,-3.25 z M 494,98.059017 C 494,97.476558 494.45,97 495,97 c 0.55,0 1,0.198442 1,0.440983 0,0.242541 -0.45,0.719098 -1,1.059017 -0.55,0.339919 -1,0.141476 -1,-0.440983 z m -4,-5.027632 c 0,-1.339038 0.47971,-1.784533 1.5,-1.393011 0.825,0.316582 1.5,1.202459 1.5,1.968615 C 493,94.373145 492.325,95 491.5,95 490.67464,95 490,94.114598 490,93.031385 z M 523.19875,90.25 c 2.4509,-5.030285 3.32163,-6.25 4.46177,-6.25 1.9832,0 1.62455,2.714931 -0.66052,5 -1.92748,1.927481 -4.5518,2.790462 -3.80125,1.25 z m -25.57828,-2.962865 c -0.33639,-0.336385 1.27224,-1.455034 3.57472,-2.485886 l 4.18633,-1.874276 2.32243,2.322435 2.32244,2.322436 -5.89716,0.163451 c -3.24343,0.0899 -6.17238,-0.111774 -6.50876,-0.44816 z m 21.93051,-1.230802 c -1.63932,-1.811429 -1.59824,-1.979262 0.88231,-3.604579 2.14042,-1.402459 2.38366,-1.967392 1.37194,-3.186434 -0.99688,-1.201173 -0.87762,-1.739218 0.62984,-2.8415 C 524.51114,74.905764 526,75.379869 526,77.559017 526,78.351558 526.45,79 527,79 c 1.76289,0 1.0832,1.518332 -2.36482,5.282694 -3.27598,3.576533 -3.41022,3.623364 -5.0842,1.773639 z M 474,81.69113 c 0,-0.719879 0.58618,-2.110514 1.30261,-3.0903 1.22295,-1.672482 1.38883,-1.677553 2.71226,-0.08292 1.23115,1.483454 1.16864,1.874734 -0.49375,3.0903 C 475.13846,83.350462 474,83.377271 474,81.69113 z m 19,0.367887 C 493,81.476558 493.45,81 494,81 c 0.55,0 1,0.198442 1,0.440983 0,0.242541 -0.45,0.719098 -1,1.059017 -0.55,0.339919 -1,0.141476 -1,-0.440983 z m 21,-0.377555 c 0,-1.866903 1.63099,-3.087556 2.41989,-1.811081 0.30695,0.496653 -0.11196,1.459094 -0.9309,2.138757 C 514.27832,83.013904 514,82.952655 514,81.681462 z m -6.2716,-8.286393 C 506.66136,72.328026 506.83847,67 507.94098,67 c 0.51754,0 1.1734,0.376056 1.45747,0.835681 0.75324,1.218776 -0.80926,6.420174 -1.67005,5.559388 z M 520,67.031937 c 0,-0.532434 -1.15811,-1.574857 -2.57357,-2.316494 -2.25821,-1.183192 -2.3853,-1.504687 -1.03716,-2.623548 1.28627,-1.067504 1.94647,-0.832671 4.05484,1.442301 1.38513,1.494579 2.27529,3.110804 1.97814,3.591611 C 521.69403,68.304094 520,68.238445 520,67.031937 z m -7,-11.563322 c 0,-0.842261 -0.64021,-1.777055 -1.42268,-2.077319 -1.62555,-0.62378 -2.83032,-3.172918 -2.07624,-4.393042 0.27916,-0.451694 1.87991,-0.303261 3.55722,0.329852 2.35888,0.890381 2.92726,1.606476 2.50933,3.161504 -0.29718,1.105714 -0.54647,2.57289 -0.55398,3.26039 C 515.00614,56.4375 514.55,57 514,57 c -0.55,0 -1,-0.689123 -1,-1.531385 z m -33,-8.933431 c 0,-0.255649 1.0125,-1.004323 2.25,-1.66372 2.04022,-1.087124 2.12204,-1.043787 0.87756,0.464816 C 481.84973,46.885299 480,47.594367 480,46.535184 z"
- style="fill:#914e15" />
+ style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#6d1e1e;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.37690854;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ d="m 132.02811,679.84788 c -8.04553,-0.25046 -15.95524,4.50231 -19.292,11.86311 -2.59537,5.37625 -3.07538,11.6434 -2.05839,17.46758 0.57967,3.65038 4.41695,5.85396 7.92046,4.98797 3.36839,-0.19947 5.94772,-3.12367 6.13926,-6.41619 0.76465,-4.06045 -0.93689,-8.80985 1.84107,-12.32994 2.25228,-2.20936 6.2761,-2.21667 8.89754,-0.78363 1.74778,2.91763 1.09226,6.56962 1.24283,9.83823 -0.005,16.76895 -0.0427,33.54176 0.0498,50.30834 0.2483,4.26937 5.20633,6.28248 8.87931,5.01663 4.27691,-0.7914 5.63523,-5.40692 5.06709,-9.18845 -0.0232,-16.60727 1.19769,-33.20689 0.69832,-49.81303 -0.2394,-5.15461 -0.59604,-10.90499 -4.58899,-14.69697 -3.79679,-4.00462 -9.29092,-6.27512 -14.79625,-6.25365 z"
+ id="path3549-3"
+ inkscape:connector-curvature="0" />
<path
- inkscape:connector-curvature="0"
- id="path3786"
- d="m 556.5,221.3241 c -9.68382,-0.82238 -21.00903,-2.52399 -21.48318,-3.22784 -0.28425,-0.42195 -1.41682,-1.27754 -2.51682,-1.90131 -1.76331,-0.99991 -1.55204,-1.13773 1.78518,-1.16454 2.08185,-0.0167 4.78185,0.60212 6,1.37521 1.21815,0.77309 5.48537,1.71957 9.48271,2.10329 5.87833,0.56428 7.74363,0.38595 9.75617,-0.93272 4.05117,-2.65443 6.82279,-3.37805 9.34008,-2.43854 2.01055,0.75038 2.16974,1.11661 1.06431,2.44857 -1.85018,2.22932 0.56216,3.63778 5.07155,2.96104 1.925,-0.28889 4.94684,-0.5302 6.7152,-0.53625 2.15377,-0.007 4.37231,-1.02696 6.72021,-3.08844 3.45879,-3.03686 5.56459,-3.17444 5.56459,-0.36355 0,1.7692 4.24872,1.91906 7.31574,0.25804 2.01538,-1.09148 6.23875,-2.39882 20.61502,-6.38137 2.98692,-0.82744 8.71056,-2.95147 12.7192,-4.72006 5.78602,-2.55277 7.17783,-3.57637 6.75185,-4.96563 -0.35278,-1.15056 3.1e-4,-1.75 1.0308,-1.75 0.86207,0 1.56739,0.45 1.56739,1 0,0.55 1.2375,1.00542 2.75,1.01205 2.63542,0.0115 2.58335,0.10613 -1.25,2.27027 -9.53278,5.38181 -28.71432,11.90151 -44.54989,15.14226 -14.94703,3.05892 -30.57167,4.07812 -44.45011,2.89952 z m -37.40793,-5.85292 c -12.20054,-3.15193 -20.70068,-7.19363 -29.82181,-14.17985 -8.766,-6.71421 -10.66077,-8.96888 -3.25768,-3.87645 2.88945,1.9876 6.43117,3.89279 7.87049,4.23377 1.43931,0.34098 3.35393,1.25858 4.25472,2.0391 2.39992,2.0795 11.42374,5.31225 14.82853,5.31225 1.61967,0 4.60264,1.125 6.62882,2.5 2.02617,1.375 4.45141,2.5 5.38942,2.5 0.93801,0 2.51995,0.9 3.51544,2 2.22884,2.46284 2.15644,2.45877 -9.40793,-0.52882 z m 41.58327,-3.12917 c -2.48583,-2.48583 6.87038,-4.59428 10.32466,-2.3267 1.33333,0.87528 1.33333,1.0941 0,1.96938 -1.68598,1.10677 -9.3113,1.37068 -10.32466,0.35732 z m 24.81392,-1.35938 c -0.84644,-1.36958 -0.87702,-1.34811 3.91367,-2.74845 4.18659,-1.22376 8.05615,-0.12374 7.32923,2.08352 -0.51151,1.55319 -10.33486,2.13416 -11.2429,0.66493 z m -45.27313,-0.80328 c -3.52437,-2.30383 3.84251,-7.35655 12.53387,-8.59661 3.41574,-0.48734 4.25,-0.3054 4.25,0.92688 0,0.84329 -1.10825,2.03821 -2.46277,2.65537 -1.62609,0.7409 -2.39049,1.83775 -2.25,3.22856 0.19044,1.88536 -0.3645,2.13366 -5.28723,2.36575 -3.025,0.14261 -6.07774,-0.11837 -6.78387,-0.57995 z m 66.24275,-1.24588 c -0.36254,-0.5866 0.13402,-1.64653 1.10346,-2.3554 1.06341,-0.77758 1.51227,-1.94125 1.13152,-2.93346 -0.40031,-1.0432 -0.11947,-1.64461 0.76797,-1.64461 1.96012,0 2.33558,4.14648 0.56593,6.25 -1.69317,2.0126 -2.63585,2.19314 -3.56888,0.68347 z M 522.25,205.98078 c -2.96659,-1.20817 -2.85677,-2.79039 0.24776,-3.56957 3.35469,-0.84198 5.72481,0.19456 5.31466,2.32428 -0.39625,2.05756 -2.44287,2.51574 -5.56242,1.24529 z m 102.10674,-3.49351 c -0.76938,-2.00498 1.17235,-4.20638 5.78652,-6.56036 C 634.82732,193.53728 635,193.53988 635,196 c 0,1.1 -0.41968,2 -0.93261,2 -0.51294,0 -1.20633,0.86239 -1.54086,1.91642 -0.33454,1.05403 -2.00701,2.40403 -3.71661,3 -3.90433,1.36105 -3.76091,1.37488 -4.45318,-0.42915 z m -127.79995,-1.82209 c -2.47116,-1.80695 -1.19981,-3.8386 1.72504,-2.75663 2.29021,0.84721 3.01243,3.16003 1.17773,3.7716 -0.57224,0.19074 -1.87849,-0.26599 -2.90277,-1.01497 z m 10.57133,-1.56484 c -2.13829,-1.35451 -0.90192,-3.19216 3.0653,-4.55602 3.56685,-1.22623 3.62986,-1.20177 4.03617,1.56664 0.53128,3.61983 -3.45634,5.29843 -7.10147,2.98938 z M 615,197.46862 c 0,-1.51309 2.63652,-3.16543 3.56667,-2.23529 0.26422,0.26423 0.19667,1.21982 -0.15012,2.12354 C 617.62094,199.4302 615,199.51592 615,197.46862 z m -139.59996,-7.3274 c -2.14502,-1.57233 -6.64179,-5.73483 -9.99282,-9.25 C 457.3426,172.43159 454.006,165.11848 449.03184,145 c -3.36252,-13.60006 -4.40386,-21.50005 -3.48185,-26.41475 1.26357,-6.73543 2.14133,-3.59058 2.74878,9.84841 0.47918,10.60107 1.14452,15.03423 3.15538,21.02449 5.18679,15.45118 16.7193,35.02882 22.34924,37.94018 2.51914,1.3027 7.12506,5.60167 6.00164,5.60167 -0.27773,0 -2.25997,-1.28645 -4.40499,-2.85878 z M 526.5,191 c -1.08086,-1.74886 0.52195,-3.22667 2.08903,-1.92611 0.77603,0.64405 1.41097,1.5659 1.41097,2.04855 0,1.20559 -2.73844,1.10978 -3.5,-0.12244 z m 19.5,-2 c 0,-0.55 0.45,-1 1,-1 0.55,0 1,0.45 1,1 0,0.55 -0.45,1 -1,1 -0.55,0 -1,-0.45 -1,-1 z m 10.71025,-1 c 0.28947,-1.10692 1.36402,-2 2.40638,-2 2.15931,0 2.41906,1.06431 0.68337,2.8 -1.89766,1.89766 -3.67487,1.43751 -3.08975,-0.8 z m -61.53594,-1.31445 C 492.19852,183.51796 492.44764,182 495.9433,182 c 2.92982,0 6.0567,2.95434 6.0567,5.72251 0,2.11997 -4.50251,1.43594 -6.82569,-1.03696 z m -12.67986,-0.69168 c -0.99854,-1.10337 -1.63078,-2.1806 -1.40499,-2.39384 0.79077,-0.74678 7.26434,1.91225 7.66876,3.14997 0.67043,2.05176 -4.26144,1.45641 -6.26377,-0.75613 z m 176.73174,-3.56753 c 0.94941,-0.99401 2.00045,-1.53304 2.33565,-1.19784 0.3352,0.3352 -0.44159,1.14849 -1.72619,1.80729 -2.23286,1.14512 -2.25968,1.1183 -0.60946,-0.60945 z m -146.78004,-1.51347 c -0.36954,-0.59793 -0.15236,-1.60666 0.48262,-2.24164 0.87268,-0.87268 1.37235,-0.80204 2.04689,0.28938 C 515.92877,180.50279 515.44816,182 514,182 c -0.48508,0 -1.18431,-0.48921 -1.55385,-1.08713 z M 651.24379,179.75 c 0.22574,-0.6875 1.72574,-1.3693 3.33333,-1.51512 l 2.92288,-0.26512 -2.5,1.47969 c -3.09616,1.83253 -4.29064,1.92811 -3.75621,0.30055 z M 486.22251,173.4433 C 483.45718,171.50639 483.33167,169 486,169 c 2.08345,0 6,3.26379 6,5 0,1.51323 -3.27243,1.19791 -5.77749,-0.5567 z m 176.52516,-0.90367 C 663.01469,171.14284 663.84119,170 664.58435,170 c 0.97182,0 1.12285,0.61729 0.53792,2.1985 -1.16552,3.15072 -2.96099,3.40866 -2.3746,0.34113 z m -192.15742,0.27734 c -0.21911,-0.72433 -0.6469,-2.09006 -0.95064,-3.03494 -0.30375,-0.94489 -0.20634,-1.93177 0.21645,-2.19307 1.12604,-0.69593 6.64394,3.16184 6.64394,4.64503 0,1.7322 -5.40095,2.26499 -5.90975,0.58298 z m 183.00631,-2.66074 c -0.34605,-0.55992 -0.1419,-1.31919 0.45366,-1.68727 1.53748,-0.95021 2.52947,0.35135 1.24598,1.63484 -0.71818,0.71818 -1.27752,0.73543 -1.69964,0.0524 z m 25.66216,-2.38889 c 0.20977,-1.97127 -0.15046,-2.2214 -2.75872,-1.91554 -1.65,0.1935 -3.82604,0.79245 -4.83565,1.33102 -2.42276,1.29241 -3.08779,0.4769 -1.71019,-2.09717 C 670.56808,163.93854 671.95453,163 673.03518,163 674.11583,163 675,162.325 675,161.5 c 0,-2.12309 -2.24745,-1.8598 -4.26797,0.5 -1.86145,2.17401 -8.73203,2.86249 -8.73203,0.875 0,-0.71377 1.08405,-0.90819 2.96562,-0.53188 3.4856,0.69712 6.03438,-2.04758 6.03438,-6.49824 0,-3.53901 -2.51494,-4.30717 -8.12935,-2.48305 -9.47303,3.07779 -16.23309,2.84371 -12.2937,-0.42569 0.85521,-0.70976 2.26486,-2.66335 3.13257,-4.34131 1.47865,-2.85939 1.62566,-2.92105 2.34273,-0.98262 0.60614,1.63854 1.40732,1.97395 3.85642,1.6145 1.70023,-0.24954 3.09133,-0.90078 3.09133,-1.4472 0,-0.54642 0.70351,-0.72353 1.56335,-0.39358 C 668.63327,148.94771 675,142.02148 675,136.03212 c 0,-2.77832 -2.33269,-2.59698 -9.21588,0.7164 -4.45323,2.14368 -5.85408,3.37111 -6.34154,5.55651 -0.60141,2.69631 -0.71739,2.74493 -2.99226,1.25437 -1.30163,-0.85286 -3.3795,-1.44012 -4.61747,-1.30503 -2.52347,0.27538 -3.89676,-2.97881 -1.80313,-4.27274 0.67458,-0.41691 0.9173,-1.25833 0.53938,-1.86983 C 649.57728,134.50701 648,134.74534 648,136.5 c 0,2.59216 -2.88036,1.63204 -4.5,-1.5 -1.9796,-3.82813 -3.96568,-3.99216 -3.02702,-0.25 l 0.6898,2.75 -2.39584,-2.25 c -1.31771,-1.2375 -3.10946,-2.25 -3.98165,-2.25 -1.07725,0 -1.97208,-1.61016 -2.7903,-5.02088 -0.69993,-2.91764 -1.97087,-5.43103 -3.034,-6 -3.27112,-1.75065 -7.06254,-1.11974 -9.13965,1.52088 -2.23832,2.84556 -6.84976,3.37561 -8.81077,1.01273 -1.81461,-2.18647 -0.48597,-4.46765 3.00928,-5.1667 1.96162,-0.39232 3.57728,-1.60007 4.48267,-3.3509 1.27791,-2.47121 1.20073,-3.16342 -0.79346,-7.11631 -1.48369,-2.94098 -2.95676,-4.48491 -4.48611,-4.70192 -1.46404,-0.20773 -2.17813,-0.90949 -2,-1.96545 0.31849,-1.888 -4.67643,-4.567567 -10.47997,-5.622064 -3.41464,-0.620436 -3.84752,-0.444634 -4.75,1.929083 C 595.44684,99.954921 595,103.14003 595,105.59648 c 0,2.92046 -0.48793,4.65353 -1.40974,5.00726 -2.09308,0.80319 -7.81784,-2.43048 -6.89791,-3.89633 0.41675,-0.66407 0.62554,-2.01048 0.46397,-2.99201 -0.16318,-0.99132 1.12151,-3.10665 2.89012,-4.758779 2.56547,-2.396514 2.95317,-3.252161 1.9961,-4.405368 -0.65328,-0.787151 -2.1676,-1.571156 -3.36516,-1.742234 -1.7074,-0.243911 -2.1346,-0.920093 -1.97917,-3.132699 0.16681,-2.374524 -0.37536,-3.061304 -3.42141,-4.334027 -2.76833,-1.156682 -3.28533,-1.723964 -2.19822,-2.412022 2.24504,-1.420933 4.69285,-1.085223 6.63246,0.909624 2.43348,2.502765 4.81849,3.230577 6.1671,1.88196 1.80452,-1.804518 1.29766,-3.557786 -1.12814,-3.902304 -1.60252,-0.227593 -2.22715,-0.967036 -2.1706,-2.569551 0.0697,-1.976241 -0.41694,-2.251863 -4,-2.265313 -2.24367,-0.0084 -4.74137,-0.433954 -5.55044,-0.945627 -1.59971,-1.011687 -1.50854,-1.189906 1.47104,-2.875598 1.95196,-1.104321 1.94412,-1.147174 -0.32672,-1.784174 -2.80242,-0.786117 -4.71952,-5.016182 -3.13736,-6.922564 1.31528,-1.58482 -0.89271,-5.725657 -2.6861,-5.037469 -2.01864,0.774626 -2.41347,-0.691437 -0.69701,-2.588103 C 576.60596,55.777927 578.67902,55 580.53254,55 583.92701,55 587.634,52.056426 585.25,51.254045 584.5625,51.022654 584,50.040578 584,49.071654 584,47.052875 580.99026,44 579,44 c -0.73839,0 -2.16545,0.744744 -3.17126,1.654988 C 574.18454,47.14297 574,47.149539 574,45.720087 574,42.8389 575.92485,39 577.36949,39 c 0.78045,0 2.84794,-1.334833 4.59443,-2.966296 2.37259,-2.216334 3.09461,-3.670092 2.85575,-5.75 C 584.50655,27.557061 584.36676,27.5 578,27.5 l -6.5,0 -7.1e-4,4.899153 c -5.9e-4,4.073311 -0.36914,5.063549 -2.18631,5.874394 -1.20208,0.536383 -3.31171,0.692604 -4.68807,0.347159 -2.38269,-0.598017 -2.4339,-0.759538 -1.06985,-3.374394 1.77494,-3.402539 1.84674,-6.154895 0.17728,-6.79553 -0.69722,-0.267547 -4.18472,-0.01312 -7.75,0.565396 -3.56529,0.578514 -7.45043,1.045255 -8.63366,1.037202 -3.11769,-0.02122 -1.86566,3.825795 1.73832,5.341152 2.98588,1.255468 2.77278,2.590702 -0.70552,4.42058 C 545.65154,41.251295 545,40.507684 545,35.955778 c 0,-5.110168 -1.83791,-6.458187 -6.70156,-4.915266 -2.08914,0.662749 -4.58594,1.603572 -5.54844,2.090717 -1.2847,0.650219 -1.75,0.484637 -1.75,-0.622755 0,-1.70633 -0.86039,-1.882848 -2.89572,-0.594086 -0.79074,0.500697 -1.12079,1.600192 -0.76145,2.536625 0.36727,0.957099 0.22379,1.39918 -0.34085,1.050211 -0.53631,-0.331458 -2.64335,-0.142027 -4.68232,0.420958 -4.94241,1.364666 -5.54295,0.486888 -0.9732,-1.422475 3.65947,-1.529025 4.52855,-2.840885 2.65084,-4.001378 -0.6647,-0.410807 -0.64525,-1.287627 0.0577,-2.601116 1.01405,-1.894779 0.82835,-1.950758 -4.2473,-1.28034 -2.91924,0.385589 -6.75576,1.304534 -8.52559,2.042099 C 509.51228,29.396537 506.86968,30 505.40967,30 c -5.14294,0 -0.55498,-2.884247 5.71666,-3.593802 4.03138,-0.4561 6.35253,-1.251773 7.2059,-2.470141 1.36809,-1.953213 8.87866,-4.673825 20.66777,-7.486643 7.19525,-1.716749 11.01107,-1.927946 49,-2.71205 11.04206,-0.227912 21.50595,1.281341 30.5,4.399149 1.65,0.571976 4.8,1.469 7,1.993387 2.2,0.524387 7.6,2.6581 12,4.741585 4.4,2.083485 10.03769,4.710396 12.5282,5.837579 6.96564,3.152588 20.8148,14.067772 24.68602,19.456226 1.91036,2.65909 3.84662,4.83471 4.30279,4.83471 0.91436,0 7.75964,10.145042 13.15745,19.5 C 696.11124,81.322828 698,86.23452 698,89.649223 698,91.077731 698.59166,92 699.50808,92 c 1.14147,0 1.4675,1.07267 1.34117,4.4126 -0.11176,2.954613 0.38119,4.9607 1.49192,6.07143 2.0466,2.0466 2.13191,3.51597 0.20414,3.51597 -1.30885,0 -3.32728,6.12001 -2.73428,8.29051 0.11879,0.43478 -0.3526,1.78478 -1.04753,3 -0.69492,1.21522 -1.2635,4.45949 -1.2635,7.20949 0,4.46323 -0.24811,5.03517 -2.31115,5.32756 -1.27113,0.18016 -2.55678,0.96766 -2.85699,1.75 -0.30021,0.78234 -0.92038,1.42244 -1.37815,1.42244 -0.45777,0 -0.14475,-2.01788 0.6956,-4.48417 1.92467,-5.64859 1.393,-7.75603 -1.19435,-4.73422 -1.04469,1.22011 -2.6605,2.21839 -3.59069,2.21839 -0.93019,0 -3.07809,1.88581 -4.77312,4.19069 -2.74901,3.73808 -2.93505,4.41311 -1.72255,6.25 1.44961,2.19609 8.6314,3.55491 8.6314,1.6331 0,-0.57582 1.52904,-1.68583 3.39787,-2.46667 1.86883,-0.78085 3.78133,-2.10492 4.25,-2.94239 0.46867,-0.83746 1.30213,-1.54173 1.85213,-1.56503 0.55,-0.0233 1.83192,-1.51777 2.84871,-3.32103 l 1.84871,-3.27867 -0.60041,4.902 c -0.72566,5.92454 -4.21292,15.94548 -7.03572,20.21773 -8.81625,13.34322 -11.74907,17.27329 -13.98209,18.73642 -2.49615,1.63554 -2.55559,1.62046 -2.32048,-0.58881 z m 3.99128,-9.57433 c 0.9625,-0.82664 1.75,-2.29644 1.75,-3.26621 0,-3.28647 1.23279,-4.99722 4.62129,-6.41303 2.2812,-0.95315 3.37871,-2.07795 3.37871,-3.46274 0,-2.3991 -2.21321,-2.70398 -4,-0.55103 -0.68469,0.825 -2.48743,1.5 -4.00608,1.5 -3.45688,0 -9.99392,6.83745 -9.99392,10.45319 0,4.32134 4.21038,5.20925 8.25,1.73982 z M 678.5,142 c -0.33992,-0.55 -0.81648,-1 -1.05902,-1 -0.24254,0 -0.44098,0.45 -0.44098,1 0,0.55 0.47656,1 1.05902,1 0.58246,0 0.7809,-0.45 0.44098,-1 z m -21,-7 c 1.95846,-1.1 4.22215,-2 5.03042,-2 0.80827,0 1.46958,-0.45 1.46958,-1 0,-0.55 0.9,-1 2,-1 1.1,0 2,-0.45 2,-1 0,-0.55 1.0125,-1.01431 2.25,-1.0318 3.70057,-0.0523 5.75,-2.3191 5.75,-6.35983 0,-4.08077 -2.16102,-5.73824 -4.88592,-3.74741 -0.88775,0.64858 -3.07658,1.85124 -4.86408,2.67256 -1.7875,0.82133 -3.25,1.93728 -3.25,2.4799 0,0.54262 -0.86278,0.98658 -1.91729,0.98658 -1.35398,0 -2.42743,1.33577 -3.65359,4.54642 -1.20887,3.16538 -2.05415,4.22855 -2.7827,3.5 C 652.93219,131.33219 652,131.84421 652,134.5 c 0,3.02254 0.86829,3.10148 5.5,0.5 z m 1.57895,-4.41667 c -0.0434,-1.05416 0.19293,-1.64479 0.52522,-1.3125 0.33229,0.33229 0.36781,1.19479 0.0789,1.91667 -0.31922,0.79773 -0.55618,0.56078 -0.60416,-0.60417 z m -1.7339,-13.50885 c -0.14411,-2.98762 -0.0336,-3.10262 1.57874,-1.64345 2.11456,1.91365 5.07621,2.05559 5.07621,0.24328 0,-0.72912 -1.16127,-2.41662 -2.58059,-3.75 -2.41678,-2.27042 -2.66182,-2.31322 -3.86024,-0.67431 -0.70381,0.9625 -1.98005,1.75 -2.83608,1.75 -2.25399,0 -2.65741,2.08682 -1.02722,5.31378 1.82052,3.60373 3.84954,2.91465 3.64918,-1.2393 z m 31.21382,1.5033 c 1.57632,-1.15494 1.90408,-2.49187 1.74398,-7.11382 -0.10843,-3.13038 -0.42653,-5.92097 -0.70687,-6.20132 -1.24063,-1.24063 -3.46132,0.94846 -6.12697,6.03978 -2.44396,4.66791 -2.67838,5.74037 -1.55153,7.09815 1.64234,1.9789 4.09309,2.04429 6.64139,0.17721 z m -15.59144,-8.05765 C 673.53534,110.16914 674,108.15667 674,106.04797 c 0,-4.6446 -1.86169,-5.68797 -6.17197,-3.45904 -2.65978,1.37543 -2.96824,1.96002 -2.43666,4.61792 0.33475,1.67373 0.60863,3.63049 0.60863,4.34834 0,0.97157 0.75853,1.08766 2.96743,0.45415 1.63209,-0.46807 3.43209,-1.13822 4,-1.48921 z m -20.225,-2.603 c 0.13333,-0.77942 -0.62625,-2.53919 -1.68796,-3.9106 -1.75745,-2.2701 -1.99251,-2.33158 -2.62388,-0.68623 -0.87696,2.2853 1.19026,6.9726 2.83376,6.42538 0.67961,-0.22628 1.34474,-1.04912 1.47808,-1.82855 z m 3.46972,-5.27202 c -0.3089,-2.83853 0.65575,-3.377209 2.58785,-1.44511 0.93333,0.93333 1.2,0.74193 1.2,-0.86133 0,-1.601072 0.50455,-1.964875 2.25971,-1.629355 1.6545,0.316277 2.87697,-0.402906 4.56436,-2.685228 2.93978,-3.976259 2.51173,-6.426291 -1.19705,-6.851551 -3.68081,-0.422054 -8.94693,4.244148 -8.03444,7.119158 0.49566,1.561688 0.23696,1.788979 -1.43296,1.258969 -2.89727,-0.91956 -4.58567,2.420148 -2.99191,5.918087 1.47386,3.23476 3.42854,2.70594 3.04444,-0.82364 z m 38.20606,1.7479 c 0.86999,-0.33384 1.58179,-1.45884 1.58179,-2.5 0,-2.327556 -0.79631,-2.387324 -3.17126,-0.23802 -3.00251,2.71724 -2.15607,4.17532 1.58947,2.73802 z m -9.63303,-4.11689 C 689.3633,97.36908 693,93.595997 693,91.753247 c 0,-2.370459 -1.68131,-2.217238 -3.01499,0.274761 C 688.48008,94.839999 687,93.557257 687,89.440983 687,87.548442 686.63828,86 686.19617,86 c -1.3911,0 -7.02927,6.382614 -8.06396,9.128683 -0.74401,1.974611 -0.62075,3.156511 0.49537,4.75 1.80017,2.570107 2.64967,2.624937 6.1576,0.397437 z M 645,96.11501 c 0,-1.261629 -4.90691,-4.312706 -6.22782,-3.872405 -0.62142,0.207141 -0.074,1.3299 1.24954,2.563007 C 642.41871,97.038748 645,97.717684 645,96.11501 z M 628.5,93 c -0.33992,-0.55 -1.06803,-1 -1.61803,-1 -0.55,0 -0.72189,0.45 -0.38197,1 0.33992,0.55 1.06803,1 1.61803,1 0.55,0 0.72189,-0.45 0.38197,-1 z m 21.42667,-0.411645 c 0.94088,-1.133687 0.50337,-1.921303 -2.22194,-4 -5.67738,-4.33035 -8.42113,-2.781631 -4.12252,2.326973 2.84502,3.381115 4.55307,3.831525 6.34446,1.673027 z m 8.35272,-13.250188 c -1.31693,-3.950794 -3.58427,-5.048143 -6.83539,-3.308198 -3.66745,1.962762 -4.08485,3.658978 -1.56137,6.345099 1.17462,1.250318 1.84242,2.566547 1.48402,2.924953 -0.35841,0.358406 -0.10252,1.31331 0.56864,2.122009 1.0423,1.255894 1.6595,0.970135 4.23141,-1.959109 2.538,-2.890617 2.86995,-3.852968 2.11269,-6.124754 z M 619.96858,85.75 c -0.0173,-0.6875 -1.14699,-2.062054 -2.51045,-3.054565 -2.31281,-1.683569 -2.52274,-1.690636 -3.13106,-0.105392 -0.41068,1.070214 0.0341,2.200878 1.20158,3.054565 2.321,1.697159 4.48123,1.748437 4.43993,0.105392 z m 59.80891,-1.306704 C 680.99987,83.587109 682,82.268312 682,81.512637 682,79.466724 677.68726,73.091098 676.27032,73.042326 674.97914,72.997883 671,79.957434 671,82.260162 c 0,3.635002 4.94774,4.865601 8.77749,2.183134 z M 637.12868,79.436461 C 635.55821,77.439929 635,77.167225 635,78.396526 c 0,0.916434 -0.675,1.925265 -1.5,2.241848 -2.37402,0.910996 -1.75059,2.196928 1.25,2.578349 4.01837,0.510796 4.78974,-0.715091 2.37868,-3.780262 z M 609,79.5 c 0,-0.833333 -0.88889,-1.5 -2,-1.5 -1.11111,0 -2,0.666667 -2,1.5 0,0.833333 0.88889,1.5 2,1.5 1.11111,0 2,-0.666667 2,-1.5 z m 54.77106,-1.31318 c 0.24358,-0.73075 -0.21359,-0.954237 -1.1875,-0.580511 C 661.7126,77.940527 661,78.653333 661,79.190322 c 0,1.314392 2.27278,0.491335 2.77106,-1.003502 z M 623,76.328741 C 623,75.072959 619.69544,72 618.34501,72 c -1.93726,0 -1.65631,2.719304 0.40499,3.919901 2.0164,1.174444 4.25,1.389311 4.25,0.40884 z M 646.03355,71.5 c 0.56364,-5.729211 -1.62198,-7.654914 -5.67445,-4.999633 -3.21727,2.108037 -3.03931,5.62093 0.3909,7.71609 3.06654,1.873036 4.92609,0.916979 5.28355,-2.716457 z m 23.88026,-1.597292 2.28993,-3.097291 -2.97019,-3.152709 c -1.63361,-1.733989 -3.38818,-3.946184 -3.89905,-4.915988 -0.87458,-1.660231 -1.05491,-1.645852 -3.08563,0.246049 -2.66934,2.486873 -3.8788,8.339276 -2.39596,11.593757 1.70374,3.739304 7.06353,3.380338 10.0609,-0.673818 z m -57.18405,0.407999 c 0.49435,-1.483026 -2.11636,-2.315474 -3.82044,-1.218187 -1.20138,0.773587 -1.188,1.052626 0.0907,1.891224 1.72585,1.131861 3.21788,0.862623 3.72976,-0.673037 z M 680,71 c 0,-0.55 -0.45,-1 -1,-1 -0.55,0 -1,0.45 -1,1 0,0.55 0.45,1 1,1 0.55,0 1,-0.45 1,-1 z M 631.96482,64.065741 C 633.50101,61.195336 633.23307,59.233066 631,57 c -2.55549,-2.555485 -2.95893,-2.520654 -6.26022,0.540469 -3.51006,3.254715 -3.44673,4.057892 0.51022,6.470491 4.07315,2.483446 5.4092,2.494345 6.71482,0.05478 z m 42.43144,-1.655983 c 0.92761,-2.417322 -0.3327,-3.616179 -2.02378,-1.9251 -0.825,0.825 -1.21975,1.953452 -0.87722,2.507671 0.91806,1.485459 2.20672,1.226673 2.901,-0.582571 z M 615.25,59.607954 c 0.9625,-0.730642 1.75,-1.918397 1.75,-2.639456 0,-0.721059 0.72958,-2.11719 1.62128,-3.102512 3.05758,-3.378582 -0.6303,-7.094169 -5.04485,-5.082763 -2.9059,1.324016 -5.49352,10.018825 -3.3805,11.359028 1.80236,1.143168 3.01287,1.015198 5.05407,-0.534297 z m 39.67327,-1.196848 c 3.79753,-3.195403 3.88978,-5.393072 0.32041,-7.63246 -1.50903,-0.946745 -3.47001,-2.255862 -4.35776,-2.909148 -2.57679,-1.896251 -4.63192,-0.332369 -5.37971,4.09377 -0.5091,3.013292 -0.26393,4.757547 0.92339,6.569628 2.07179,3.161954 4.63484,3.125203 8.49367,-0.12179 z M 602.4,52.549738 C 602.4,48.533037 599.6547,45 596.53357,45 c -3.19583,0 -6.70737,3.705664 -6.34106,6.691629 0.24756,2.018047 1.28201,2.838279 5.30749,4.208407 2.75,0.936 5.4275,1.341401 5.95,0.900891 0.5225,-0.44051 0.95,-2.353545 0.95,-4.251189 z m 36.65637,-4.772599 C 640.67537,46.004565 642,44.213711 642,43.797463 642,42.828104 634.5367,39 632.64683,39 c -2.94871,0 -3.65372,7.229913 -0.99184,10.171259 2.35444,2.601625 4.04219,2.28372 7.40138,-1.39412 z M 606,43 c 0,-1.1 -0.42344,-2 -0.94098,-2 -1.34235,0 -2.28822,1.820126 -1.55902,3 1.04512,1.691037 2.5,1.109085 2.5,-1 z m -22,-2 c 0,-0.55 -0.45,-1 -1,-1 -0.55,0 -1,0.45 -1,1 0,0.55 0.45,1 1,1 0.55,0 1,-0.45 1,-1 z m 38.77749,-0.556704 C 623.99987,39.587109 625,38.243148 625,37.456716 625,36.071687 619.10385,33 616.44526,33 c -1.99296,0 -2.81529,3.940068 -1.38149,6.61916 1.47391,2.754028 4.49725,3.077042 7.71372,0.824136 z M 601.70295,38.806639 C 606.13834,36.914278 608,34.897509 608,31.984915 c 0,-2.556487 -0.31469,-2.737588 -5.72777,-3.296268 -3.44662,-0.355722 -6.1788,-1.207964 -6.86025,-2.139902 -1.93188,-2.642007 -2.90147,-1.720319 -3.176,3.019094 -0.22566,3.895677 0.16275,4.984733 2.67307,7.495062 3.37671,3.376705 3.12057,3.310962 6.7939,1.743738 z m -63.85281,-9.356924 c 1.02738,-0.92914 -1.34718,-2.357893 -4.92276,-2.961985 -4.92256,-0.831661 -5.67218,-0.28933 -3.26071,2.359071 1.35121,1.483971 2.62226,1.869632 4.83333,1.466517 1.65,-0.300822 3.15756,-0.689443 3.35014,-0.863603 z M 518,166 c 0,-0.55 0.19844,-1 0.44098,-1 0.24254,0 0.7191,0.45 1.05902,1 0.33992,0.55 0.14148,1 -0.44098,1 C 518.47656,167 518,166.55 518,166 z m -37.34501,-6.82874 C 478.39246,156.67119 478.5713,156 481.5,156 c 2,0 2.5,0.5 2.5,2.5 0,2.96346 -1.07531,3.17925 -3.34501,0.67126 z m -15.21229,-4.5895 c -1.06675,-0.78003 -1.59026,-1.76753 -1.16335,-2.19444 0.42691,-0.42692 1.76371,0.21129 2.97065,1.41824 2.4462,2.4462 1.20537,2.97911 -1.8073,0.7762 z m 171.54991,-6.09066 c -1.03152,-1.24291 -0.75941,-2.2201 1.54356,-5.54329 1.74223,-2.51405 3.32936,-3.82965 4.21162,-3.4911 0.77868,0.29881 1.82898,0.54329 2.334,0.54329 0.50501,0 0.91821,1.07622 0.91821,2.39159 0,1.69958 -0.7041,2.56831 -2.43335,3.00233 -1.33834,0.3359 -2.71867,1.50968 -3.06739,2.6084 -0.75716,2.38563 -1.81055,2.53245 -3.50665,0.48878 z m -159.827,-2.08766 c -2.53402,-1.77489 -2.64025,-5.71474 -0.16561,-6.14197 2.3298,-0.40222 3.62907,0.94843 4.31775,4.48853 0.72213,3.71201 -0.51167,4.20333 -4.15214,1.65344 z m -16.67287,-3.8339 c -1.87504,-1.41699 -1.73679,-1.50781 2.34059,-1.53774 3.02988,-0.0222 4.20951,0.3442 3.92168,1.2182 -0.6128,1.86073 -3.99454,2.03329 -6.26227,0.31954 z M 590.5,143 c -0.33992,-0.55 0.0835,-1 0.94098,-1 0.85746,0 1.55902,0.45 1.55902,1 0,0.55 -0.42344,1 -0.94098,1 -0.51754,0 -1.2191,-0.45 -1.55902,-1 z M 476.57143,130.42857 c -1.96597,-1.96597 -1.97427,-2.84936 -0.0418,-4.45315 1.16961,-0.97068 2.11105,-1.00455 4,-0.14388 1.35872,0.61907 2.47039,1.55309 2.47039,2.07559 0,1.18363 -2.84323,4.09287 -4,4.09287 -0.47143,0 -1.56429,-0.70714 -2.42857,-1.57143 z M 460.66667,119.33333 C 459.20152,117.86818 460.04497,115 461.94098,115 c 2.55258,0 3.5351,1.72143 2.02267,3.5438 -1.32017,1.59071 -2.26867,1.81785 -3.29698,0.78953 z m 20.70902,-2.79667 c -0.34004,-0.88613 0.11132,-2.41732 1.00303,-3.40265 C 483.27042,112.14869 484,110.81545 484,110.17126 484,109.52707 484.40186,109 484.89301,109 c 2.60021,0 1.51373,8.29799 -1.15374,8.8117 -0.95992,0.18486 -2.02353,-0.38891 -2.36358,-1.27504 z M 446.15789,108 c 0,-1.375 0.22698,-1.9375 0.50439,-1.25 0.27741,0.6875 0.27741,1.8125 0,2.5 -0.27741,0.6875 -0.50439,0.125 -0.50439,-1.25 z m 19.93602,-1.89428 c -1.56356,-1.20207 -2.18429,-2.4278 -1.77268,-3.50044 1.13685,-2.962595 3.70296,-3.03748 6.5157,-0.19015 2.60003,2.63202 2.61712,2.73002 0.72194,4.14035 -2.42837,1.80711 -2.5415,1.7978 -5.46496,-0.44976 z M 567,96 c 0,-0.55 0.70156,-1 1.55902,-1 0.85746,0 1.2809,0.45 0.94098,1 -0.33992,0.55 -1.04148,1 -1.55902,1 C 567.42344,97 567,96.55 567,96 z m -77,-2 c 0,-0.55 0.42344,-1 0.94098,-1 0.51754,0 1.2191,0.45 1.55902,1 0.33992,0.55 -0.0835,1 -0.94098,1 C 490.70156,95 490,94.55 490,94 z m 77,-3.940983 c 0,-0.517541 0.45,-1.219098 1,-1.559017 0.55,-0.339919 1,0.08352 1,0.940983 C 569,90.298442 568.55,91 568,91 c -0.55,0 -1,-0.423442 -1,-0.940983 z m 8.54271,-0.989919 c -0.31644,-0.511996 -0.0964,-1.226871 0.48887,-1.588613 1.35919,-0.840031 3.96842,0.138409 3.96842,1.48813 0,1.284813 -3.67415,1.367641 -4.45729,0.100483 z M 498,87.160515 C 498,86.162612 502.47988,84 504.54705,84 c 1.95564,0 1.85572,2.631467 -0.12884,3.393011 C 502.10158,88.281986 498,88.133409 498,87.160515 z M 474.01531,81.75 c 0.008,-0.6875 0.42413,-1.896064 0.92379,-2.685698 0.77519,-1.225065 1.15297,-1.232784 2.57498,-0.05261 1.55067,1.286941 1.54268,1.473635 -0.11491,2.685698 -2.24265,1.639863 -3.40352,1.657912 -3.38386,0.05261 z M 551,74 c 0,-0.55 0.9,-1 2,-1 1.1,0 2,0.45 2,1 0,0.55 -0.9,1 -2,1 -1.1,0 -2,-0.45 -2,-1 z m -1.72917,-4.604167 c 0.33229,-0.332291 1.1948,-0.367818 1.91667,-0.07895 0.79773,0.319226 0.56078,0.556183 -0.60417,0.604167 -1.05416,0.04342 -1.64479,-0.192928 -1.3125,-0.52522 z M 568,68 c 0,-0.55 0.45,-1 1,-1 0.55,0 1,0.45 1,1 0,0.55 -0.45,1 -1,1 -0.55,0 -1,-0.45 -1,-1 z m -20.50437,-6.007063 c -0.34231,-0.553884 0.10054,-1.284477 0.98412,-1.623538 1.91464,-0.73472 2.98171,0.07492 2.06137,1.56407 -0.83038,1.343581 -2.23491,1.371006 -3.04549,0.05947 z M 565.5,60 c 0.33992,-0.55 1.26648,-1 2.05902,-1 C 568.35156,59 569,58.55 569,58 c 0,-0.55 -0.61875,-1 -1.375,-1 -2.28809,0 -3.67091,-11.801271 -1.73986,-14.848393 1.21692,-1.920258 4.53331,-1.000799 4.90492,1.359877 0.17217,1.093684 0.77967,2.93336 1.35,4.088169 0.71758,1.452948 0.71325,3.272078 -0.014,5.906154 -0.57807,2.093575 -0.78525,4.236543 -0.4604,4.76215 0.32484,0.525607 -0.0295,1.348448 -0.78749,1.828534 C 568.97012,61.304993 564.74037,61.229105 565.5,60 z M 509.66667,51.333333 C 509.3,50.966667 509,50.201667 509,49.633333 c 0,-0.626604 0.46577,-0.567562 1.18333,0.15 0.65084,0.650834 0.95084,1.415834 0.66667,1.7 -0.28417,0.284167 -0.81667,0.216667 -1.18333,-0.15 z M 529,43.573324 C 529,42.645689 529.855,42 531.08333,42 c 2.43705,0 2.09257,2.336773 -0.4162,2.823324 C 529.68037,45.014697 529,44.504563 529,43.573324 z m -31.37888,-4.999615 -2.87888,-2.354366 4.37888,-0.694736 c 2.40838,-0.382105 6.16144,-1.598782 8.34012,-2.703727 2.17868,-1.104944 6.45368,-2.226123 9.5,-2.491507 L 522.5,29.846855 519.23422,32.923428 C 516.60584,35.39953 515.10821,36 511.56095,36 c -3.24238,0 -5.1929,0.660875 -7.37858,2.5 -1.6341,1.375 -3.13112,2.483817 -3.32673,2.464037 -0.1956,-0.01978 -1.65114,-1.095427 -3.23452,-2.390328 z"
- style="fill:#784727" />
+ style="fill:#f0f0f0;fill-opacity:1;stroke-width:1.18845427"
+ d="m 132.03149,682.22559 c -6.83372,-0.23737 -13.61239,3.55889 -16.72277,9.69133 -2.74628,5.04652 -3.22178,11.07775 -2.32756,16.66882 0.43314,3.38858 4.39762,3.98337 7.02482,2.81616 2.90003,-1.58575 2.44803,-5.44614 2.55528,-8.25473 -0.34319,-4.14905 0.4717,-9.43463 4.87532,-11.13306 2.8893,-0.96223 6.3723,-1.09021 9.08503,0.43047 3.01656,2.35206 2.46472,6.63064 2.58101,10.0397 -0.0332,17.35038 -0.0228,34.70225 0.0241,52.05177 0.20114,3.22404 4.34757,3.86953 6.73893,2.66559 2.64207,-0.80035 2.62465,-3.6798 2.47047,-5.91805 -0.0235,-16.53569 1.12153,-33.06091 0.73502,-49.59608 -0.31198,-4.79776 -0.17963,-10.32165 -3.96719,-13.8849 -3.37928,-3.49951 -8.20043,-5.58808 -13.07254,-5.57702 z"
+ id="path3529"
+ inkscape:connector-curvature="0" />
<path
- inkscape:connector-curvature="0"
- id="path3788"
- d="m 557.5,220.3475 c -10.55768,-0.83482 -22.24808,-2.70495 -24.5,-3.9193 -2.47699,-1.33571 -2.46515,-1.34849 1.28518,-1.38816 2.08185,-0.022 4.94029,0.71681 6.35208,1.64185 1.92089,1.25862 4.93108,1.69904 11.96101,1.75 5.16677,0.0375 9.39583,0.37572 9.39793,0.75169 0.002,0.37597 1.2413,0.87104 2.7538,1.10017 2.67579,0.40534 2.66904,0.41609 -0.25,0.39831 -1.65,-0.01 -4.8,-0.1606 -7,-0.33456 z m 6,-3.3475 c 0.33992,-0.55 1.74303,-1 3.11803,-1 1.41203,0 2.23104,0.43519 1.88197,1 -0.33992,0.55 -1.74303,1 -3.11803,1 -1.41203,0 -2.23104,-0.43519 -1.88197,-1 z m 40.5,-0.90218 c 0.825,-0.46275 3.3,-1.11071 5.5,-1.43991 l 4,-0.59855 -3.5,1.39424 c -3.97319,1.58274 -8.54914,2.07406 -6,0.64422 z m -86.5,-1.7096 C 510.77812,212.7692 493,204.4893 493,202.9777 c 0,-1.42052 0.67652,-1.24314 5.32193,1.39538 2.29794,1.30519 6.65307,3.168 9.67807,4.13957 3.025,0.97157 7.60842,2.60369 10.18538,3.62692 2.57696,1.02324 5.5879,1.86043 6.69098,1.86043 1.10309,0 2.28372,0.45 2.62364,1 0.83686,1.35407 -2.74899,1.13469 -10,-0.61178 z M 617.5,212 c 2.77822,-1.19384 4.73784,-1.19384 4,0 -0.33992,0.55 -1.82898,0.96837 -3.30902,0.92971 C 615.78816,212.86696 615.71417,212.7674 617.5,212 z M 561,211.10699 c 0,-1.36875 2.32661,-1.95837 5.40533,-1.36984 2.00759,0.38378 2.40622,0.76716 1.43662,1.38169 C 566.06054,212.2479 561,212.23914 561,211.10699 z m -16.31228,-0.91432 c -3.70906,-0.23688 -4.74069,-0.66132 -4.5,-1.8514 0.49915,-2.46805 8.39213,-6.34127 12.92245,-6.34127 6.07023,0 4.49691,2.47691 -1.64356,2.58749 -5.55287,0.10001 -7.2364,2.10855 -2.55255,3.04532 3.15991,0.63198 4.06749,1.87289 1.83594,2.5102 -0.6875,0.19635 -3.41553,0.21869 -6.06228,0.0497 z M 589,210.01905 c 0,-1.88395 5.07906,-2.36856 6.79892,-0.6487 1.5062,1.5062 1.31041,1.62965 -2.58463,1.62965 C 590.89643,211 589,210.55857 589,210.01905 z m -65.75,-5.10424 c -2.7632,-1.04432 -2.82675,-1.53072 -0.28677,-2.19494 1.07978,-0.28237 2.45163,0.0751 3.04856,0.79434 1.44392,1.73982 0.0313,2.45622 -2.76179,1.4006 z M 626.5,200 c 1.8932,-2.09196 4.5,-2.69163 4.5,-1.03518 0,1.09604 -3.25146,3.03518 -5.08925,3.03518 -0.76455,0 -0.54436,-0.74738 0.58925,-2 z m -129,0 c -0.33992,-0.55 -0.16803,-1 0.38197,-1 0.55,0 1.27811,0.45 1.61803,1 0.33992,0.55 0.16803,1 -0.38197,1 -0.55,0 -1.27811,-0.45 -1.61803,-1 z m 9.95888,-2.06653 c -0.36253,-0.58659 -0.50159,-1.14909 -0.30902,-1.25 0.19258,-0.10091 1.7622,-0.96662 3.48806,-1.9238 l 3.13792,-1.74033 0.43889,2.99033 c 0.41094,2.79992 0.2308,2.99033 -2.82891,2.99033 -1.79728,0 -3.5644,-0.47994 -3.92694,-1.06653 z m 19.08383,-6.86437 c -0.31644,-0.512 -0.11799,-1.21356 0.44098,-1.55902 1.19337,-0.73755 3.01631,0.19857 3.01631,1.54894 0,1.2168 -2.70662,1.22469 -3.45729,0.0101 z M 546,189 c 0,-0.55 0.45,-1 1,-1 0.55,0 1,0.45 1,1 0,0.55 -0.45,1 -1,1 -0.55,0 -1,-0.45 -1,-1 z m 10.71025,-1 c 0.28947,-1.10692 1.36402,-2 2.40638,-2 2.15931,0 2.41906,1.06431 0.68337,2.8 -1.89766,1.89766 -3.67487,1.43751 -3.08975,-0.8 z M 485,187 c -1.2819,-0.82843 -1.24555,-0.9716 0.25,-0.98469 0.9625,-0.008 1.75,0.43469 1.75,0.98469 0,1.21961 -0.11279,1.21961 -2,0 z m 10.55703,-0.93699 C 493.87609,184.2056 494.12745,182 496.02006,182 c 1.09197,0 4.97994,4.05085 4.97994,5.18856 0,1.56063 -3.70546,0.79438 -5.44297,-1.12555 z M 513,180.5 c -1.01957,-1.22851 -0.95124,-1.5 0.37756,-1.5 0.89234,0 1.62244,0.675 1.62244,1.5 0,0.825 -0.1699,1.5 -0.37756,1.5 -0.20765,0 -0.93775,-0.675 -1.62244,-1.5 z m 138,0.059 c 0,-0.24254 0.45,-0.7191 1,-1.05902 0.55,-0.33992 1,-0.14148 1,0.44098 0,0.58246 -0.45,1.05902 -1,1.05902 -0.55,0 -1,-0.19844 -1,-0.44098 z m -189.92768,-5.45746 c -2.65786,-3.73261 -6.41549,-12.09173 -5.73944,-12.76778 0.275,-0.275 1.42106,1.58219 2.54679,4.1271 1.12573,2.5449 3.01242,5.98321 4.19265,7.64068 1.18022,1.65748 1.92086,3.23859 1.64586,3.51359 -0.275,0.275 -1.46564,-0.85611 -2.64586,-2.51359 z M 489,173 c 0,-0.55 0.45,-1 1,-1 0.55,0 1,0.45 1,1 0,0.55 -0.45,1 -1,1 -0.55,0 -1,-0.45 -1,-1 z m -18,-2.00847 c 0,-1.75815 0.24927,-1.85281 2,-0.75946 1.1,0.68696 2,1.59078 2,2.00848 0,0.4177 -0.9,0.75945 -2,0.75945 -1.33615,0 -2,-0.66667 -2,-2.00847 z M 518,166 c 0,-0.55 0.19844,-1 0.44098,-1 0.24254,0 0.7191,0.45 1.05902,1 0.33992,0.55 0.14148,1 -0.44098,1 C 518.47656,167 518,166.55 518,166 z m 161.8985,-1.81937 -2.60151,-1.52431 4.93275,-2.4581 c 4.90386,-2.44369 7.20521,-5.2199 4.95017,-5.97158 -2.15812,-0.71938 -1.22219,-2.16442 2.69676,-4.16372 3.92689,-2.00335 5.12333,-3.67184 5.12333,-7.14471 0,-2.44376 -1.58774,-2.42302 -6.26118,0.0818 -2.05237,1.1 -4.56346,2 -5.58021,2 -1.01675,0 -2.66312,0.9 -3.65861,2 -0.99549,1.1 -2.44179,2 -3.214,2 -0.77222,0 -1.15486,0.40316 -0.85032,0.89592 0.30454,0.49276 -0.0783,2.11408 -0.85071,3.60294 -1.36217,2.62559 -1.43719,2.64579 -2.49363,0.6718 -1.61523,-3.01807 -4.27684,-3.43647 -10.91629,-1.71602 -6.7454,1.74791 -9.54809,1.95796 -8.74297,0.65526 0.30256,-0.48955 3.81662,-1.68519 7.80901,-2.65696 7.28539,-1.77331 11.56595,-3.80034 13.0623,-6.18554 0.52883,-0.84297 1.38321,-0.98279 2.5,-0.40914 2.34367,1.20385 4.19661,0.34657 4.19661,-1.9416 0,-1.2291 -0.69473,-1.91667 -1.93664,-1.91667 -1.45282,0 -2.01493,-0.80989 -2.25,-3.24181 -0.39849,-4.12251 -2.51461,-4.58893 -8.358,-1.84221 -2.43846,1.14621 -4.87809,2.08402 -5.42141,2.08402 -0.54331,0 -1.73251,1.13651 -2.64266,2.52557 -1.25614,1.91712 -2.16513,2.35765 -3.77305,1.82858 -1.16503,-0.38334 -2.91026,-0.64748 -3.87828,-0.58696 -3.75692,0.23486 2.90148,-4.09025 8.0314,-5.21697 1.76314,-0.38725 3.45715,-1.11094 3.76447,-1.6082 0.30733,-0.49726 3.46249,-2.24811 7.01147,-3.89077 3.54899,-1.64267 6.4527,-3.4512 6.4527,-4.01896 0,-0.56776 1.125,-1.03229 2.5,-1.03229 1.63572,0 2.5,-0.55889 2.5,-1.61663 0,-1.1387 -0.6075,-1.45777 -2.05489,-1.07927 -1.52678,0.39926 -2.29392,-0.0914 -2.98499,-1.90899 -1.6869,-4.43689 -2.79937,-4.21491 -16.00554,3.19367 -3.15976,1.77261 -5.95458,4.6238 -5.95458,6.07468 0,1.08685 -0.38025,1.11602 -1.93021,0.14805 -1.63994,-1.02416 -2.23648,-0.83745 -3.96674,1.24152 -1.12008,1.34584 -2.05148,3.00947 -2.06978,3.69697 C 646.99474,136.19746 645,136.48094 645,135.03896 645,133.90253 640.9816,130 639.81144,130 639.36515,130 639,130.59706 639,131.32681 c 0,0.90685 -0.95421,1.18676 -3.01473,0.88434 -2.61227,-0.3834 -3.16348,-1.03324 -4.12905,-4.86787 -1.83052,-7.26964 -7.87862,-9.0805 -12.1788,-3.64644 -2.10093,2.65491 -6.77539,3.09496 -8.66685,0.81589 -1.81323,-2.1848 -0.48682,-4.46748 3.00134,-5.16511 1.68252,-0.33651 3.57541,-1.56488 4.20644,-2.72972 C 620.82522,111.80571 617.76901,104 613.278,104 c -1.67264,0 -2.32282,-0.44081 -1.97751,-1.34068 0.90814,-2.36657 -0.73501,-3.555833 -7.20196,-5.212589 -4.49954,-1.15273 -6.63425,-1.311007 -7.39683,-0.548434 -0.58956,0.589561 -1.27031,3.814503 -1.51277,7.166533 -0.26666,3.68658 -0.94808,6.28925 -1.72463,6.58724 -2.00071,0.76775 -7.66038,-2.52901 -6.77195,-3.94466 0.41675,-0.66407 0.62554,-2.01048 0.46397,-2.99201 -0.16318,-0.99132 1.12151,-3.10665 2.89012,-4.758779 2.56547,-2.396514 2.95317,-3.252161 1.9961,-4.405368 -0.65328,-0.787151 -2.1676,-1.571156 -3.36516,-1.742234 -1.7074,-0.243911 -2.1346,-0.920093 -1.97917,-3.132699 0.16681,-2.374524 -0.37536,-3.061304 -3.42141,-4.334027 -2.76833,-1.156682 -3.28533,-1.723964 -2.19822,-2.412022 2.5127,-1.590342 4.93506,-0.994441 6.06833,1.492812 1.46075,3.205992 5.50162,4.204968 7.97068,1.970496 2.40585,-2.177262 2.36655,-2.864623 -0.30615,-5.354624 C 593.10939,79.453257 592.97102,79 594.18899,79 c 0.86137,0 2.13727,-0.688192 2.83534,-1.529315 1.05173,-1.26726 0.88518,-1.938099 -0.97195,-3.914924 -1.49781,-1.59435 -2.03015,-3.050438 -1.60498,-4.390034 0.47224,-1.487889 0.0841,-2.179656 -1.50627,-2.684413 -1.17835,-0.373993 -2.61965,-0.202796 -3.20288,0.380438 -1.79429,1.794286 -1.74554,6.034787 0.0811,7.057065 1.4533,0.813328 1.30983,1.081523 -1.0607,1.982812 -3.99083,1.517341 -7.84807,-0.492284 -4.69051,-2.443763 0.5875,-0.363092 0.84766,-1.234815 0.57815,-1.937162 -0.26952,-0.702346 0.003,-1.770481 0.60661,-2.373632 0.79552,-0.795518 0.16476,-1.488463 -2.29713,-2.523608 -3.22666,-1.356712 -3.2722,-1.444117 -0.92478,-1.775217 1.87225,-0.264078 2.5483,-1.042344 2.79716,-3.220069 0.49106,-4.297204 -1.02283,-5.167574 -5.71958,-3.288307 -2.2121,0.885105 -4.25237,1.236524 -4.53394,0.780933 C 573.91282,58.049927 578.41227,56 581.42461,56 c 3.69736,0 5.08646,-2.428149 3.79549,-6.634513 -0.7923,-2.581542 -0.78755,-4.220716 0.0173,-5.987246 0.84288,-1.849925 0.80459,-2.725363 -0.15991,-3.655367 -1.0064,-0.970411 -1.5834,-0.758361 -2.79485,1.027126 -1.79958,2.65231 -7.62669,3.310066 -6.6443,0.75 0.31659,-0.825 1.16794,-1.5 1.89189,-1.5 2.34479,0 7.30505,-4.973669 7.96729,-7.988836 1.11152,-5.060746 -0.47629,-6.421881 -7.14204,-6.122416 -4.12804,0.185456 -6.46456,0.830702 -7.91996,2.187158 -2.46757,2.299803 -3.78214,2.416329 -5.39093,0.477862 -0.92554,-1.115216 -3.07073,-1.349371 -9.37244,-1.023037 -12.7445,0.659972 -14.9171,0.538808 -17.20371,-0.959433 -1.17408,-0.769284 -4.24607,-1.71532 -6.82667,-2.102304 -3.78791,-0.568033 -4.47588,-0.963988 -3.57046,-2.054948 0.61683,-0.743238 3.76954,-1.872309 7.00601,-2.509046 3.23648,-0.636738 5.67539,-1.496058 5.41981,-1.909599 -1.33727,-2.163743 26.31095,-4.239322 37.90286,-2.845405 5.40402,0.64983 8.23175,0.618231 8.95,-0.100012 2.18148,-2.181486 19.21855,0.04406 31.14998,4.069105 1.65,0.556625 5.25,1.627501 8,2.379725 6.00109,1.641514 14.19053,5.191436 15.0008,6.502483 0.32101,0.519394 2.27998,1.40113 4.35329,1.959412 2.0733,0.558283 6.2168,2.813753 9.20777,5.012156 2.99098,2.198404 7.76245,5.568252 10.60327,7.488552 2.84082,1.9203 6.19013,4.964558 7.44292,6.765019 1.25278,1.80046 4.33693,5.558487 6.85366,8.351171 C 685.65169,63.891479 691,73.756547 691,77.937943 c 0,2.055389 0.83812,3.92682 2.40048,5.360023 1.92663,1.767351 2.5114,3.534487 2.96238,8.952034 0.49229,5.913958 0.3498,6.755281 -1.15049,6.792637 -2.04821,0.051 -9.24629,6.337903 -11.716,10.232933 -1.30291,2.05485 -2.27573,2.61185 -3.74645,2.14506 -1.41501,-0.44911 -1.84462,-0.24069 -1.49323,0.72443 0.27132,0.74522 1.03814,1.22958 1.70404,1.07636 0.84519,-0.19447 1.01451,0.61482 0.56082,2.68047 -0.51737,2.35555 -0.23311,3.18211 1.39375,4.05278 3.06283,1.63918 6.51239,0.31666 10.54643,-4.04336 1.99038,-2.15122 4.27574,-3.91131 5.07858,-3.91131 2.55653,0 1.57044,3.76416 -1.61738,6.17394 -1.69239,1.27933 -4.18784,3.33856 -5.54545,4.57606 -1.35762,1.2375 -3.10232,2.25 -3.87713,2.25 -0.7748,0 -2.9933,2.07524 -4.92998,4.61164 -3.00686,3.93796 -3.35689,4.924 -2.3961,6.75 0.61882,1.1761 1.62027,2.46897 2.22543,2.87305 1.91401,1.27801 6.32397,0.8277 9.64307,-0.98469 2.42344,-1.32331 3.3169,-1.44522 3.66438,-0.5 0.25273,0.6875 1.09702,1.25 1.87618,1.25 3.68218,0 0.46498,7.83288 -7.66829,18.66992 -6.5212,8.68904 -5.97364,8.29366 -9.01654,6.51071 z m -29.08514,-44.00764 c 0.32152,-3.25564 -1.39496,-4.42691 -2.45173,-1.67299 -0.31659,0.825 -1.20246,1.5 -1.96862,1.5 -1.88963,0 -1.75158,1.00774 0.35699,2.6059 2.51351,1.90509 3.70542,1.19144 4.06336,-2.43291 z M 659.27287,120 c 1.39842,-1.1 3.04823,-2 3.66624,-2 0.61801,0 1.38268,-0.675 1.69926,-1.5 0.31659,-0.825 1.20246,-1.5 1.96862,-1.5 0.76615,0 1.39301,-0.44143 1.39301,-0.98095 0,-0.53952 1.1355,-1.26594 2.52333,-1.61426 1.38783,-0.34832 3.08005,-1.42815 3.76048,-2.3996 0.68044,-0.97146 2.12727,-1.93771 3.21519,-2.14722 1.08792,-0.20952 2.14024,-1.22323 2.3385,-2.25271 0.30113,-1.56363 -0.0674,-1.76438 -2.23851,-1.21946 -1.92405,0.48291 -2.59899,0.26696 -2.59899,-0.83156 0,-3.802904 -9.13364,-2.97551 -10.64551,0.96434 C 664.04184,105.33336 663.20731,106 662.5,106 c -0.70731,0 -1.54504,0.675 -1.86163,1.5 -0.31658,0.825 -1.05795,1.5 -1.64748,1.5 -2.0034,0 -6.99089,4.36828 -6.99089,6.12296 0,2.99428 1.88597,6.87704 3.34039,6.87704 0.76444,0 2.53406,-0.9 3.93248,-2 z M 641.5,116 c 0.33992,-0.55 -0.0835,-1 -0.94098,-1 -0.85746,0 -1.55902,0.45 -1.55902,1 0,0.55 0.42344,1 0.94098,1 0.51754,0 1.2191,-0.45 1.55902,-1 z m -4.5,-1 c 0,-0.55 -0.45,-1 -1,-1 -0.55,0 -1,0.45 -1,1 0,0.55 0.45,1 1,1 0.55,0 1,-0.45 1,-1 z m 8.41367,-5.49141 c -0.89784,-1.37028 -2.09443,-2.20589 -2.65909,-1.85691 -0.59759,0.36933 -0.0295,1.40124 1.35939,2.46917 3.12197,2.40056 3.23797,2.34592 1.2997,-0.61226 z M 653.71025,109 c 0.28766,-1.1 0.97989,-2 1.5383,-2 0.55841,0 2.50071,-1.575 4.31622,-3.5 1.81551,-1.925 3.66864,-3.500013 4.11808,-3.500029 1.2654,-4.6e-5 6.31715,-6.709298 6.31715,-8.389838 0,-2.055662 -3.86652,-4.59437 -5.8648,-3.850759 -2.73141,1.016423 -8.13514,5.659899 -8.13517,6.990626 -2e-5,0.6875 -0.41439,1.25 -0.92082,1.25 -0.50644,0 -2.7607,1.821613 -5.00948,4.04803 -3.61197,3.57605 -3.95552,4.30476 -2.94653,6.25 2.66088,5.12988 5.63329,6.34915 6.58705,2.70197 z m 33.89643,-9.61459 c 7.25827,-4.81777 8.63041,-7.311335 6.00153,-10.906534 -1.19172,-1.629774 -1.62644,-1.708639 -3.02416,-0.548628 -2.19988,1.825738 -2.85399,0.909956 -1.63678,-2.29156 1.63161,-4.291468 -1.37816,-3.305486 -6.44492,2.111312 -6.01521,6.430768 -7.23574,9.481765 -5.09817,12.7441 2.18879,3.34052 3.75607,3.17021 10.2025,-1.10869 z m -52.31955,-0.498278 c -1.6878,-1.687805 -3.69343,-0.08162 -2.17807,1.744278 0.83681,1.0083 1.52538,1.13415 2.24856,0.41097 0.72317,-0.72317 0.70159,-1.383171 -0.0705,-2.155248 z M 648.25,95.546205 C 650.3125,93.651873 652,91.629023 652,91.050983 652,90.472942 652.64468,90 653.43261,90 c 0.78794,0 1.69974,-0.7875 2.02623,-1.75 0.91245,-2.689941 5.2686,-7.25 6.92581,-7.25 1.52805,0 3.25275,-3.695934 2.21088,-4.737801 -0.32289,-0.322894 -1.64798,-0.103701 -2.94464,0.487096 -1.93127,0.879945 -2.65354,0.728498 -3.99444,-0.837559 C 656.75617,74.860281 655.29714,74 654.41416,74 651.8401,74 647,77.961367 647,80.068094 647,81.130642 646.55,82 646,82 c -0.55,0 -1,0.675 -1,1.5 0,0.833333 -0.88889,1.5 -2,1.5 -1.99934,0 -2.40309,0.865414 -2.03378,4.359311 0.10809,1.022621 -0.19907,1.614813 -0.68259,1.315983 -1.5949,-0.985702 -3.35791,0.942745 -3.57251,3.90775 -0.17279,2.387336 0.181,2.916956 1.94852,2.916956 1.18781,0 2.50031,0.3375 2.91667,0.75 1.38979,1.376897 2.89446,0.767293 6.67369,-2.703795 z M 613,96.468615 c 0,-1.612079 -2.66157,-3.140377 -3.68563,-2.11632 C 608.60214,95.064525 610.86193,98 612.12244,98 612.6051,98 613,97.310877 613,96.468615 z m 17.30698,-1.108931 C 631.06545,94.601212 627.93534,89 626.75301,89 c -1.76243,0 -1.90084,3.179168 -0.2193,5.037245 1.87489,2.071731 2.72577,2.369943 3.77327,1.322439 z M 615.41655,89.643128 C 614.77363,87.967711 613,87.348895 613,88.8 c 0,0.972866 2.23095,3.302381 2.70687,2.826461 0.18711,-0.187112 0.0565,-1.079612 -0.29032,-1.983333 z m -9.74452,-1.585193 C 606.94581,84.683311 606.56335,84 603.40072,84 c -2.69433,0 -4.14198,3.401911 -2.36089,5.547988 1.85733,2.237946 3.41405,1.737191 4.6322,-1.490053 z M 636,87.535184 c 0,-0.805649 0.94485,-1.970482 2.09966,-2.588518 1.50195,-0.803822 1.96843,-1.81017 1.63867,-3.535184 C 639.48479,80.085167 639.69708,79 640.2101,79 c 0.51302,0 1.56758,-0.634821 2.34347,-1.410714 0.77589,-0.775893 1.89256,-1.571329 2.48148,-1.767635 0.58892,-0.196306 1.45828,-2.075153 1.93192,-4.175216 0.7133,-3.162685 0.53252,-4.146947 -1.0529,-5.732365 C 644.86133,64.861331 643.40344,64 642.67431,64 c -1.80227,0 -5.28059,3.941346 -6.17766,7 -0.40326,1.375 -1.24248,3.175 -1.86493,4 -2.06369,2.735252 -3.36933,5.528862 -4.0656,8.698974 -0.53694,2.444653 -0.29015,3.364864 1.12284,4.186768 C 634.26111,89.381903 636,89.240503 636,87.535184 z m -15,-1.674941 c 0,-1.176867 -0.7875,-2.729485 -1.75,-3.450264 -1.60657,-1.203097 -1.57539,-1.266606 0.38039,-0.77489 1.4934,0.375466 2.91365,-0.3091 4.75,-2.289519 C 625.82117,77.791747 627,76.008438 627,75.382663 c 0,-0.625775 0.67005,-1.693862 1.48899,-2.373525 0.81894,-0.679663 1.25273,-1.618024 0.96397,-2.085246 -0.28876,-0.467222 0.64309,-2.699885 2.07076,-4.961474 3.08472,-4.886512 2.91108,-7.566531 -0.66247,-10.224281 l -2.63875,-1.962516 -3.11743,2.30482 c -1.79505,1.327134 -3.54195,3.813827 -4.11819,5.862189 -0.85832,3.051057 -0.72116,3.788775 0.96366,5.183228 1.08043,0.894222 1.6498,1.940473 1.26527,2.325003 -0.38453,0.38453 0.0846,1.137754 1.04252,1.673832 2.47586,1.385563 2.15748,3.073463 -0.50833,2.694858 -1.45613,-0.206803 -2.26648,-1.025216 -2.29671,-2.319551 -0.0285,-1.219386 -0.61259,-1.870344 -1.49657,-1.66781 -2.53822,0.581553 -4.11095,2.470042 -3.62012,4.346958 0.2616,1.000373 0.0679,2.070866 -0.43048,2.378873 C 615.40775,76.866028 615,77.991476 615,79.059017 615,80.126558 614.55,81 614,81 c -1.87732,0 -1.00527,3.882904 1.22251,5.443296 C 618.43722,88.694968 621,88.436338 621,85.860243 z M 625.5,68 c -0.33992,-0.55 -0.16803,-1 0.38197,-1 0.55,0 1.27811,0.45 1.61803,1 0.33992,0.55 0.16803,1 -0.38197,1 -0.55,0 -1.27811,-0.45 -1.61803,-1 z m 53.05224,17.967714 C 681.58703,84.09211 686,78.152142 686,75.94284 c 0,-1.400079 -2.76012,-1.14252 -3.29167,0.30716 -0.36316,0.990446 -0.7421,0.9818 -1.82497,-0.04164 -0.99912,-0.94429 -1.05742,-1.48275 -0.21678,-2.002292 1.52694,-0.943703 2.77812,-7.813192 1.56016,-8.565933 -1.36553,-0.843943 -7.43012,6.038717 -10.1853,11.559213 -1.28995,2.584641 -2.78322,4.609641 -3.3184,4.5 -0.53517,-0.109641 -1.18952,0.39384 -1.4541,1.118846 -0.27359,0.749669 0.10617,1.18334 0.88051,1.00552 0.74888,-0.171971 2.3716,0.697342 3.60607,1.931806 2.73267,2.73267 2.71919,2.732249 6.79672,0.212195 z m -68.11677,-8.385945 c 0.3644,-2.430027 1.3155,-4.960127 2.11354,-5.622444 3.52954,-2.929259 0.69159,-5.761696 -3.98965,-3.981893 -2.83318,1.077173 -3.05573,2.574479 -1.08097,7.272568 0.56176,1.336449 0.25162,1.75 -1.31238,1.75 -1.12639,0 -2.33827,0.469712 -2.69308,1.043805 C 602.50345,79.612459 604.93913,82 607.5089,82 c 1.91043,0 2.36749,-0.690024 2.92657,-4.418231 z m 59.64145,-6.504846 C 671.68462,69.469231 673,67.810734 673,67.391374 c 0,-0.419359 0.98169,-1.807437 2.18154,-3.084618 2.10713,-2.242932 2.12474,-2.441276 0.51618,-5.814451 -1.83527,-3.848607 -4.5928,-4.609533 -5.40797,-1.492305 -0.28766,1.1 -0.9047,2 -1.3712,2 -0.4665,0 -1.32985,-0.9 -1.91855,-2 -1.87118,-3.49634 -4.33351,-2.373021 -6.75,3.079365 -2.6521,5.984011 -2.81152,8.673934 -0.6933,11.698129 2.27497,3.247969 6.87823,2.941425 10.52022,-0.700571 z m -18.5358,-5.143454 c 1.07627,-1.741443 -0.14952,-2.110241 -1.52106,-0.457635 C 649.23131,66.426218 649.15544,67 649.81854,67 c 0.58488,0 1.36004,-0.479939 1.72258,-1.066531 z M 614.13814,64.25 c 0.79647,-0.9625 2.04603,-3.1 2.77681,-4.75 0.73078,-1.65 1.94887,-4.194431 2.70687,-5.654292 1.80161,-3.469794 1.78966,-3.529988 -1.07286,-5.405583 -4.75657,-3.116628 -9.17436,1.101824 -10.01624,9.564301 -0.21681,2.179332 -0.67927,4.423687 -1.0277,4.987456 -0.34843,0.563769 0.4079,1.442705 1.68074,1.95319 3.21131,1.287937 3.32461,1.272036 4.95238,-0.695072 z M 594.5,64 c 0.33992,-0.55 2.07761,-1 3.86154,-1 3.10501,0 3.28892,-0.221712 4.30719,-5.192603 C 604.39904,49.360615 601.59756,44 595.45295,44 594.65383,44 594,43.351558 594,42.559017 c 0,-1.985062 -1.9459,-3.013119 -3.24475,-1.714266 -0.76065,0.760648 -0.69999,1.516908 0.20958,2.612867 1.00972,1.216644 1.02254,1.852676 0.0607,3.011636 -0.67066,0.80809 -1.37941,4.569047 -1.57501,8.357683 -0.1956,3.788636 -0.43027,7.289972 -0.52149,7.780746 -0.0912,0.490774 -0.11257,1.229817 -0.0474,1.642317 0.17642,1.11736 4.90334,0.907029 5.61842,-0.25 z m 61.1,-5.4 c 3.9109,-3.910895 4.70642,-8.6 1.45902,-8.6 -2.22483,0 -3.62866,-1.771211 -3.24714,-4.096912 0.33964,-2.070376 -2.35435,-4.292635 -4.29915,-3.546348 C 648.68073,42.67601 648,43.626354 648,44.468615 648,45.310877 647.62123,46 647.15829,46 646.18731,46 644,52.758748 644,55.759031 c 0,1.114845 -0.675,2.286013 -1.5,2.602595 -2.4318,0.93317 -1.77226,2.923522 0.75831,2.288391 1.24207,-0.31174 2.92957,-0.142414 3.75,0.376279 2.70361,1.70928 5.14578,1.019609 8.59169,-2.426296 z M 637.81184,54.738516 C 638.01532,53.681957 637.52949,53 636.57332,53 635.708,53 635,53.188196 635,53.418213 c 0,0.230016 -0.29066,1.175657 -0.64591,2.101423 -0.48611,1.266792 -0.17971,1.59343 1.23852,1.320304 1.03643,-0.199599 2.03509,-1.145239 2.21923,-2.101424 z m 1.82584,-6.458554 c 1.87408,-2.046022 3.16451,-4.353058 2.86762,-5.126749 -0.29689,-0.77369 -0.0433,-2.004961 0.56354,-2.736156 C 644.48829,38.706716 643.4255,37 640.94098,37 639.79252,37 639,37.683636 639,38.674314 c 0,1.421729 -0.34915,1.3463 -2.31445,-0.5 -3.16641,-2.974683 -4.18468,-2.749597 -6.13273,1.355627 -2.32186,4.892941 -1.71375,9.591857 1.44718,11.182513 3.55984,1.791402 3.85479,1.697466 7.63768,-2.432492 z m 21.35396,-4.30629 c -2.42527,-1.533309 -3.13796,-1.115584 -1.93418,1.133687 0.84938,1.587092 1.41149,1.823693 2.27682,0.95836 0.86533,-0.865334 0.78074,-1.381821 -0.34264,-2.092047 z m -54.17828,-1.731861 c 0.20861,-2.158175 -0.12566,-3.252442 -1,-3.273614 -0.85966,-0.02082 -0.69148,-0.503392 0.48685,-1.396957 2.66596,-2.021675 4.45006,-14.249543 2.38097,-16.318636 -1.02152,-1.021514 -2.39006,-1.291503 -4.2193,-0.832394 -2.44438,0.613503 -2.65299,1.01466 -2.1475,4.129651 0.65413,4.030948 -1.10934,4.655175 -4.25748,1.507043 -1.0687,-1.068702 -2.5312,-2.02202 -3.25,-2.118482 -3.37479,-0.452899 -3.71175,0.100024 -3.40712,5.590938 0.41342,7.452008 3.40081,10.880925 8.85022,10.158256 3.85661,-0.511441 4.59603,0.06636 2.61722,2.045167 -1.57989,1.579889 -0.24241,4.484962 1.87976,4.082934 1.15582,-0.218961 1.85977,-1.436478 2.06638,-3.573906 z M 614,43 c 0,-0.55 -0.45,-1 -1,-1 -0.55,0 -1,0.45 -1,1 0,0.55 0.45,1 1,1 0.55,0 1,-0.45 1,-1 z m 9.41957,-2.115394 c 4.03965,-3.177587 3.10329,-5.830021 -2.71075,-7.678757 -5.54885,-1.764411 -7.04215,-0.97822 -7.04215,3.707533 0,5.991046 4.73437,7.918804 9.7529,3.971224 z M 618.77083,28.8125 C 618.15276,26.958277 616,26.65074 616,28.416667 616,29.2875 616.7125,30 617.58333,30 c 0.87084,0 1.40521,-0.534375 1.1875,-1.1875 z M 563.17889,24.5 c -0.26321,-1.471364 -2.43977,-1.217369 -2.96072,0.345503 -0.28754,0.862613 0.19537,1.221505 1.34555,1 C 562.55045,25.655477 563.27728,25.05 563.17889,24.5 z M 563,20.440983 C 563,20.198442 562.55,20 562,20 c -0.55,0 -1,0.476558 -1,1.059017 0,0.582459 0.45,0.780902 1,0.440983 0.55,-0.339919 1,-0.816476 1,-1.059017 z M 481,158.5 c -1.01957,-1.22851 -0.95124,-1.5 0.37756,-1.5 0.89234,0 1.62244,0.675 1.62244,1.5 0,0.825 -0.1699,1.5 -0.37756,1.5 -0.20765,0 -0.93775,-0.675 -1.62244,-1.5 z M 672,158 c 0,-0.55 0.45,-1 1,-1 0.55,0 1,0.45 1,1 0,0.55 -0.45,1 -1,1 -0.55,0 -1,-0.45 -1,-1 z M 638,145.87431 C 638,142.79933 639.7132,141 642.64098,141 c 2.88513,0 4.03165,1.82089 1.6724,2.65608 -0.99736,0.35307 -2.82588,1.55333 -4.06338,2.66725 l -2.25,2.0253 0,-2.47432 z m -162,-3.4813 c 0,-1.05452 0.5438,-1.39831 1.58179,-1 0.86998,0.33385 1.88248,0.61388 2.25,0.6223 0.8947,0.0205 -2.12442,1.94983 -3.08179,1.96938 -0.4125,0.008 -0.75,-0.70783 -0.75,-1.59168 z m 0,-14.30968 c 0,-1.22373 2.08856,-1.86453 4.25,-1.30394 2.83712,0.73583 2.00133,2.22061 -1.25,2.22061 -1.65,0 -3,-0.4125 -3,-0.91667 z m 218,-2 C 694,124.855 694.64569,124 695.57332,124 c 0.93124,0 1.44138,0.68037 1.25,1.66713 C 696.33677,128.1759 694,128.52038 694,126.08333 z m -0.49445,-18.08946 c 1.98964,-2.19852 3.08052,-1.96353 2.14937,0.463 C 695.32924,109.30559 694.3039,110 693.3764,110 c -1.53891,0 -1.52762,-0.17542 0.12915,-2.00613 z m 4.28826,-5.04238 c 0.29391,-2.00253 0.79893,-2.75875 1.42454,-2.13314 1.19411,1.19411 0.67092,4.38633 -0.79911,4.8757 -0.68008,0.2264 -0.91195,-0.79037 -0.62543,-2.74256 z M 567,96 c 0,-0.55 0.70156,-1 1.55902,-1 0.85746,0 1.2809,0.45 0.94098,1 -0.33992,0.55 -1.04148,1 -1.55902,1 C 567.42344,97 567,96.55 567,96 z m 0,-5.940983 c 0,-0.517541 0.45,-1.219098 1,-1.559017 0.55,-0.339919 1,0.08352 1,0.940983 C 569,90.298442 568.55,91 568,91 c -0.55,0 -1,-0.423442 -1,-0.940983 z m 8.54271,-0.989919 c -0.31644,-0.511996 -0.1586,-1.188456 0.35074,-1.503244 C 577.0757,86.835178 580,87.932627 580,89.106989 c 0,1.183506 -3.72198,1.151866 -4.45729,-0.03789 z M 568,68 c 0,-0.55 0.45,-1 1,-1 0.55,0 1,0.45 1,1 0,0.55 -0.45,1 -1,1 -0.55,0 -1,-0.45 -1,-1 z m -2.5,-8 c 0.33992,-0.55 1.26648,-1 2.05902,-1 1.6682,0 1.87398,-1.166999 0.45584,-2.585137 -0.54182,-0.541825 -1.44207,-3.394537 -2.00054,-6.339359 -0.88608,-4.672295 -0.79245,-5.519733 0.73514,-6.653745 1.45158,-1.077591 2.00671,-1.047853 3.25054,0.174131 1.85769,1.82506 2.38104,15.510696 0.63629,16.638797 C 568.92649,61.340184 564.78857,61.151114 565.5,60 z M 530.63948,44.306147 C 529.5133,43.179963 529.95359,42 531.5,42 c 0.825,0 1.5,0.423442 1.5,0.940983 0,1.260978 -1.56159,2.164095 -2.36052,1.365164 z M 546,37.5 c 0,-2.809298 0.29862,-2.945737 3.13031,-1.430261 1.59618,0.854252 1.75971,1.357848 0.81181,2.5 C 548.06274,40.834251 546,40.274502 546,37.5 z m 20.03987,0.04804 c -1.73684,-2.092757 -0.86908,-4.997921 1.59849,-5.351621 1.58784,-0.2276 2.28808,0.374374 2.79777,2.405143 0.95457,3.803302 -2.02681,5.801493 -4.39626,2.946478 z M 498.5,37 c 0.33992,-0.55 1.26648,-1 2.05902,-1 0.79254,0 1.44098,0.45 1.44098,1 0,0.55 -0.92656,1 -2.05902,1 -1.13246,0 -1.7809,-0.45 -1.44098,-1 z m 9,-3 c 3.58281,-1.658548 10.61187,-2.778533 9.31804,-1.484703 -0.57169,0.57169 -11.50762,3.527855 -12.61683,3.410539 C 503.81554,35.885046 505.3,35.01842 507.5,34 z"
- style="fill:#652710" />
+ style="color:#000000;fill:#dc3f3f;fill-opacity:1;stroke-width:0.15989453"
+ d="m 134.97779,682.49412 c -2.78583,1.68294 -3.87593,5.47975 -3.52065,8.83893 1.77112,-0.0432 3.5383,0.25575 5.06467,1.11139 0.34516,0.26913 0.62955,0.57224 0.88762,0.88762 0.16835,-3.06065 1.92342,-7.00511 4.52762,-8.08557 -1.86438,-1.21459 -3.92982,-2.11016 -6.10147,-2.58827 -0.23141,-0.0392 -0.46504,-0.10335 -0.69369,-0.14173 -0.0542,-0.01 -0.10979,-0.0132 -0.1641,-0.0224 z m -12.09106,1.88713 c -3.04994,1.6056 -5.63612,4.04127 -7.30983,7.10098 0.79341,3.36035 4.27905,6.4628 7.30983,6.39983 0.53142,-2.31118 1.70876,-4.36699 3.85631,-5.49729 -3.64257,-2.20893 -4.04968,-5.44914 -3.85631,-8.00352 z m 25.98721,13.97073 c -3.45652,0.84076 -7.03487,3.54051 -9.77131,5.7882 -0.005,2.96882 0.0102,5.93717 0.007,8.90606 2.6517,-2.65236 6.19094,-6.04826 9.97271,-6.68328 -0.0115,-1.5584 0.0215,-3.11824 -0.0149,-4.6768 -0.0704,-1.08311 -0.11858,-2.20797 -0.19393,-3.33418 z m -36.26573,6.27303 c 0.0483,1.33181 0.1647,2.65868 0.37295,3.96074 0.43314,3.38858 4.39919,3.98671 7.02639,2.8195 0.73049,-0.39943 1.24351,-0.94639 1.61115,-1.58131 -3.00071,0.47579 -6.97816,-1.1442 -9.01049,-5.19893 z m 36.37015,15.44016 c -3.52688,0.86537 -7.29772,3.46109 -9.86828,6.04926 7.6e-4,2.65063 0.005,5.3007 0.007,7.95131 2.66442,-2.38739 6.24799,-5.07094 9.67434,-6.09402 0.0763,-2.63573 0.12625,-5.27078 0.18648,-7.90655 z m -0.49975,20.25122 c -3.19336,0.80673 -6.7218,2.95008 -9.36107,4.93041 0.005,2.49637 0.001,4.99257 0.007,7.48885 2.4386,-2.29924 5.86157,-5.29746 9.27156,-6.01942 0.0218,-2.1339 0.0354,-4.26618 0.082,-6.39984 z"
+ id="path3533"
+ inkscape:connector-curvature="0" />
</g>
</svg>
diff --git a/src/activities/share/resource/images/boy.svg b/src/activities/share/resource/images/boy.svg
index 092433301..e8bda262b 100644
--- a/src/activities/share/resource/images/boy.svg
+++ b/src/activities/share/resource/images/boy.svg
@@ -1,370 +1,393 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="svg2"
- viewBox="0 0 39.374999 56.250001"
+ viewBox="0 0 42 60"
height="60"
width="42"
- inkscape:version="0.92.1 r15371"
+ inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
sodipodi:docname="boy.svg">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1884"
inkscape:window-height="1051"
id="namedview32"
showgrid="false"
units="px"
inkscape:zoom="1.6819304"
- inkscape:cx="23.574402"
+ inkscape:cx="-230.30055"
inkscape:cy="64.777487"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<defs
id="defs4">
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient1200"
id="linearGradient1296"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-0.96958036,0.09974415,0.09719467,0.99501312,-9.4686467,-2.137586)"
x1="38.396049"
y1="28.53743"
x2="38.269402"
y2="30.051884" />
<linearGradient
id="linearGradient1200"
inkscape:collect="always">
<stop
id="stop1196"
offset="0"
style="stop-color:#a16f29;stop-opacity:1" />
<stop
id="stop1198"
offset="1"
style="stop-color:#cb9544;stop-opacity:1" />
</linearGradient>
<linearGradient
gradientTransform="matrix(-0.9815442,0.09747867,0.09839397,0.97241342,-9.1837067,-1.454476)"
gradientUnits="userSpaceOnUse"
y2="29.458378"
x2="47.31078"
y1="27.521519"
x1="47.416126"
id="linearGradient5862-805-5"
xlink:href="#linearGradient1200"
inkscape:collect="always" />
</defs>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
+ <dc:date>2017</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Timothée Giet</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
</cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
</rdf:RDF>
</metadata>
<g
id="g1294"
- transform="matrix(-0.66639908,0,0,0.66639908,-6.3336488,-8.5067547)">
+ transform="matrix(-0.71082569,0,0,0.71082569,-6.7558918,-9.0738718)">
<path
style="display:inline;overflow:visible;fill:#76533a;fill-opacity:0.98277061;fill-rule:evenodd;stroke:none;stroke-width:5.53261995px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -62.035286,61.419072 c -2.182705,1.622582 -6.180776,6.064833 -4.901251,8.09035 0.445858,0.70581 4.00709,-2.507051 5.084139,-2.191615 1.077159,0.315482 1.333803,0.984759 0.08574,2.756347 -0.6025,0.855259 0.121559,2.327448 1.113285,1.797624 0.991613,-0.529874 3.045803,-3.238199 3.703089,-5.058446 0.657397,-1.820193 1.901041,-5.270053 0.936983,-5.689663 -1.416288,-0.616449 -6.021981,0.295403 -6.021981,0.295403 z"
id="path6085-2"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cssssssc" />
<path
style="display:inline;overflow:visible;fill:#dbb191;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5.53261995px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -66.446763,68.307525 c 0.213202,0.805373 4.01164,-1.978261 5.088802,-1.66278 1.077161,0.315484 1.720517,1.251604 0.472333,3.023143 -0.6025,0.855259 -0.507083,1.40923 0.485215,0.879649 0.991612,-0.529874 1.930014,-2.803935 2.587414,-4.624132 0.657285,-1.820241 2.763749,-4.380125 1.799691,-4.799735 -1.416289,-0.616449 -5.996076,1.066738 -5.996076,1.066738 -1.091351,0.811291 -4.847278,4.56823 -4.437379,6.117117 z"
id="path6085-3-9"
inkscape:connector-curvature="0"
sodipodi:nodetypes="sssssscs" />
<path
style="display:inline;overflow:visible;fill:#2d6374;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -41.889561,50.103927 c -3.626559,5.303174 -7.314396,12.161329 -9.68619,15.057606 -1.87333,2.287712 -6.46725,1.433374 -7.925272,-1.781266 -1.855737,-4.091532 2.835426,-7.310991 5.887926,-9.847323 2.612933,-2.171075 7.089033,-8.231592 9.552281,-8.503428 2.618534,-0.288973 3.647094,1.429686 2.171255,5.074411 z"
id="path5890-2-1"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cssssc" />
<path
style="display:inline;overflow:visible;fill:#59b1ce;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -41.585728,48.854903 c -3.626603,5.303084 -8.252032,12.307391 -10.623827,15.203668 -1.87333,2.287712 -5.018155,1.988471 -6.476179,-1.226172 -1.855703,-4.091437 2.604529,-5.855636 5.657019,-8.391985 2.612938,-2.171066 7.563748,-8.724641 10.02699,-8.996485 2.618534,-0.288973 2.891812,-0.233795 1.415997,3.410974 z"
id="path5890-6-6-2"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cssssc" />
<path
inkscape:transform-center-y="7.1524113"
inkscape:transform-center-x="1.958253"
style="display:inline;overflow:visible;fill:#254957;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -52.034017,84.39286 c -3.146529,1.690934 -5.03486,4.619565 -5.200051,5.022522 -0.165128,0.403036 -0.520699,1.823816 0.0061,2.236653 0.526805,0.412837 4.549626,2.101123 9.054384,1.93953 4.504824,-0.161517 8.256273,-1.742898 8.610904,-2.518255 0.354627,-0.775356 1.067014,-4.137534 0.137283,-4.669109 -0.929669,-0.531496 -10.613808,-2.829602 -12.608625,-2.011341 z"
id="path5960-2-7"
inkscape:connector-curvature="0" />
<path
inkscape:transform-center-y="6.6430871"
inkscape:transform-center-x="1.8743967"
style="display:inline;overflow:visible;fill:#30718c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -51.479625,85.052177 c -2.678562,1.33217 -4.27452,3.661045 -4.412982,3.982378 -0.138653,0.321103 -0.322485,0.903133 0.130169,1.236243 0.452715,0.333189 3.900608,1.70695 7.749143,1.605316 3.848473,-0.101713 7.044572,-1.342702 7.342942,-1.960154 0.298302,-0.617525 0.775162,-2.749028 -0.02253,-3.179491 -0.797694,-0.430463 -9.087066,-2.326069 -10.786742,-1.684292 z"
id="path5960-9-0-0"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccssssc" />
<path
style="display:inline;overflow:visible;fill:#274a6d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -48.616197,67.945772 c -1.687327,4.583043 -3.663708,9.640761 -3.684391,10.156964 -0.02068,0.516203 1.590381,4.513859 1.405507,4.836245 -0.184874,0.322386 -1.913392,-0.18513 -2.01497,0.776261 -0.0407,0.385266 2.761513,2.788771 5.575777,3.504063 2.814266,0.715291 8.286609,1.930491 9.144512,0.760364 0.857838,-1.170204 -1.129069,-6.795459 -1.213997,-7.53895 -0.08493,-0.743493 -0.623378,-1.150576 -0.912489,-1.408157 -0.289176,-0.257658 2.14177,-6.3856 2.537135,-7.40067 0.395365,-1.015072 -9.430942,-3.927431 -10.837084,-3.68612 z"
id="path5925-8-9"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cssssssssc"
inkscape:transform-center-x="-0.93862069"
inkscape:transform-center-y="-3.5589168" />
<path
style="display:inline;overflow:visible;fill:#3576b9;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -47.927086,69.349532 c -1.454764,3.951418 -3.235287,8.419869 -3.253144,8.864903 -0.01785,0.445033 1.943112,4.530817 1.626222,5.038422 -0.169634,0.27184 -1.47348,0.424369 -1.365055,0.740361 0.108355,0.315916 1.643365,1.418937 4.069745,2.035623 2.426446,0.616762 7.010696,1.745476 7.750266,0.736504 0.739636,-1.008895 -1.414532,-5.602496 -1.487735,-6.243499 -0.0732,-0.641001 -0.537474,-0.99202 -0.78678,-1.214143 -0.249305,-0.222125 1.494969,-6.288385 2.471848,-7.23113 0.675864,-0.652176 -7.813002,-2.935068 -9.025367,-2.727041 z"
id="path5925-1-7-3"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cssssssssc"
inkscape:transform-center-x="-1.2557077"
inkscape:transform-center-y="-3.5057264" />
<path
style="display:inline;overflow:visible;fill:#254957;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -42.126902,86.85689 c -2.945201,2.0214 -4.505642,5.1371 -4.626205,5.5557 -0.120565,0.4185 -0.320357,1.8694 0.248017,2.2228 0.568372,0.3534 4.750214,1.5966 9.211076,0.9487 4.460863,-0.648 8.019218,-2.6259 8.287904,-3.4351 0.268684,-0.8091 0.613152,-4.2287 -0.368582,-4.6565 -0.981733,-0.4278 -10.857634,-1.6648 -12.75221,-0.6356 z"
id="path5960-6"
inkscape:connector-curvature="0" />
<path
style="display:inline;overflow:visible;fill:#30718c;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -41.504463,87.42359 c -2.518724,1.468 -3.853207,3.7309 -3.956311,4.0349 -0.103108,0.304 -0.273968,1.3577 0.212102,1.6144 0.486069,0.2567 4.062364,1.1596 7.877278,0.689 3.814911,-0.4706 6.858003,-1.9071 7.087782,-2.4948 0.229777,-0.5877 0.524366,-3.0712 -0.315211,-3.382 -0.839573,-0.3107 -9.285405,-1.2091 -10.90564,-0.4615 z"
id="path5960-9-06"
inkscape:connector-curvature="0" />
<path
style="display:inline;overflow:visible;fill:#274a6d;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -43.51419,71.24639 c -0.837057,4.8115 -1.467433,9.2727 -1.395095,9.7843 0.07234,0.5115 2.084032,4.5449 1.960023,4.8952 -0.124008,0.3503 -2.032361,0.7875 -1.842903,1.1254 0.189457,0.3379 3.217331,2.2476 6.114308,2.446 2.896978,0.1985 9.348865,-0.341 9.982685,-1.6462 0.633821,-1.3052 -2.890087,-6.1198 -3.107101,-6.8359 -0.217017,-0.7162 -0.819835,-1.02 -1.150524,-1.2215 -0.33069,-0.2015 2.193554,-7.010965 2.400235,-8.080465 0.206681,-1.0696 -11.621646,-0.956635 -12.961628,-0.466835 z"
id="path5925-2"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cssssssssc" />
<path
style="display:inline;overflow:visible;fill:#3576b9;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -42.584277,72.50359 c -0.721692,4.1484 -1.26519,7.9947 -1.202821,8.4358 0.06237,0.441 2.434073,4.4982 2.21348,5.0545 -0.118113,0.2979 -1.373342,0.682 -1.209996,0.9734 0.163347,0.2913 1.871408,1.1008 4.369117,1.2719 2.497713,0.171 8.06039,-0.294 8.606856,-1.4194 0.546467,-1.1253 -2.956801,-4.895 -3.143906,-5.5125 -0.187108,-0.6174 -0.706842,-0.8794 -0.991956,-1.0531 -0.285116,-0.1737 1.989105,-7.351683 2.780793,-8.454483 0.547709,-0.763 -10.266263,0.281583 -11.421567,0.703883 z"
id="path5925-1-6"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cssssssssc" />
<path
style="display:inline;overflow:visible;fill:#2d6374;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -45.475284,46.976592 c -2.408674,3.429343 -7.13384,18.546403 -7.638735,22.603151 0.78036,1.465242 0.817366,0.735536 6.788267,4.641325 2.108112,1.378939 17.957933,0.152571 16.923335,-2.879752 -0.639064,-1.873085 0.646049,-0.729792 -0.947049,-6.332954 -1.593091,-5.603164 -2.41006,-20.188538 -3.820324,-20.920761 -2.094365,-1.08741 -9.136355,-0.425387 -11.305494,2.888991 z"
id="path5873-0-1"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccssssc" />
<path
style="display:inline;overflow:visible;fill:#59b1ce;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -45.350113,48.5369 c -2.182841,3.107789 -6.065083,16.783047 -6.522637,20.459428 0.707192,1.327859 0.77426,0.242305 6.18532,3.781858 1.910468,1.24972 15.920099,0.956293 14.982495,-1.791772 -0.579145,-1.697459 1.214271,0.03155 -0.229461,-5.046279 -1.443727,-5.077828 -2.892201,-19.357781 -4.170236,-20.021351 -1.897995,-0.985451 -8.279723,-0.385503 -10.245481,2.618116 z"
id="path5873-8"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccssssc" />
<path
style="display:inline;overflow:visible;fill:#2d6374;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -35.401114,49.367185 c 2.837751,5.763913 5.515629,13.075758 7.452612,16.279242 1.529973,2.530175 6.19859,2.336117 8.097834,-0.639303 2.41726,-3.786909 -1.769853,-7.639193 -4.431746,-10.582884 -2.278616,-2.519654 -5.849886,-9.153793 -8.249681,-9.772237 -2.551076,-0.657444 -3.812999,0.897966 -2.869019,4.715182 z"
id="path5890-7"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cssssc" />
<path
style="display:inline;overflow:visible;fill:#59b1ce;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -35.800949,47.811374 c 2.837751,5.763913 6.699299,13.629633 8.636282,16.833117 1.529938,2.530269 -1.116398,-1.559457 1.971682,-3.269287 4.380938,-2.425672 6.539752,0.399165 0.640248,-5.857447 -2.330626,-2.471664 -5.927019,-9.503832 -8.326811,-10.122286 -2.551076,-0.657444 -3.865388,-1.401294 -2.921401,2.415903 z"
id="path5890-6-9"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cssssc" />
<path
style="display:inline;overflow:visible;fill:#76533a;fill-opacity:0.98277061;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -21.656633,60.39321 c 3.2684,-0.293551 8.479377,-1.532785 9.108849,-1.134338 0.629719,0.398135 0.60697,1.615233 -0.232046,2.159763 -0.838957,0.544452 -4.135754,1.06713 -4.601096,1.513012 1.518397,0.97982 6.430766,1.956254 6.467672,2.639643 0.03684,0.683467 -0.397541,1.693057 -1.443137,1.839028 -1.045655,0.146057 -3.874337,-0.958126 -4.667758,-0.896494 1.101718,1.618918 3.721015,4.030724 3.554169,4.599474 -0.166788,0.56867 -1.295268,1.023228 -2.045013,0.632011 -0.749743,-0.391215 -1.80209,-1.342389 -2.085291,-1.661352 -0.396057,1.337394 -0.211972,3.386686 -0.48172,3.667222 -0.218857,0.227618 -1.421156,-0.190315 -1.757774,-1.308361 -0.336553,-1.118125 0.06147,-3.266478 -0.378912,-3.223913 -0.410409,0.03972 -2.121751,-0.941159 -2.64681,-1.736012 -0.524998,-0.794931 -2.204669,-1.179826 -2.846792,-3.068804 -0.28361,-0.834165 0.380162,-1.762263 0.09782,-3.472132 -0.288784,-1.749263 -0.849512,-3.724518 -0.522524,-4.110068 0.654032,-0.771178 1.680693,-0.575516 2.361309,0.325367 0.710317,0.940403 0.938847,3.451379 2.117993,3.237282 z"
id="path5995-20"
inkscape:connector-curvature="0"
sodipodi:nodetypes="csscsscsscssssssssc" />
<path
style="display:inline;overflow:visible;fill:#dbb191;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -21.886534,60.786811 c 3.268402,-0.293553 8.165867,-1.542829 8.79534,-1.144381 0.629719,0.398134 0.325143,0.828004 -0.51387,1.372535 -0.838955,0.544452 -4.767373,1.432065 -5.232653,1.877869 1.518397,0.979821 7.356192,2.100926 7.393099,2.784314 0.03684,0.683468 -0.43401,0.867201 -1.479605,1.013173 -1.045656,0.146057 -4.729538,-1.151437 -5.522896,-1.089882 1.101655,1.618995 4.403597,4.637443 4.236812,5.206114 -0.166845,0.568751 -0.387799,0.868344 -1.137541,0.477129 -0.749743,-0.391215 -2.222191,-1.911573 -2.504459,-2.231708 -0.396056,1.337392 -0.280257,3.624307 -0.550006,3.904843 -0.218856,0.227618 -0.613833,0.290371 -0.950514,-0.827596 -0.336553,-1.118125 -0.0055,-3.45194 -0.445983,-3.409297 -0.410348,0.03964 -1.91459,-0.735839 -2.439648,-1.530691 -0.524998,-0.794931 -1.831708,-0.857372 -2.473832,-2.74635 -0.283545,-0.834244 0.0491,-1.902255 -0.233238,-3.612123 -0.288849,-1.749185 -0.938825,-3.214437 -0.611838,-3.599986 0.654033,-0.771179 0.851871,-0.689252 1.532424,0.21171 0.710381,0.940323 0.959142,3.558581 2.138288,3.344484 z"
id="path5995-2-2"
inkscape:connector-curvature="0"
sodipodi:nodetypes="csscsscsscssssssssc" />
<path
style="display:inline;overflow:visible;fill:#2d6374;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -36.40073,45.888628 c -2.218295,2.52089 -5.165097,4.2231 -6.800373,3.7005 -1.635282,-0.52265 -2.243615,-2.40467 -1.35251,-3.70902 2.717407,-0.29388 9.48213,-1.96184 8.152883,0.009 z"
id="path6030-5-3"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cscc" />
<path
style="display:inline;overflow:visible;fill:#dbb191;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -37.91293,45.980718 c -1.612113,1.77952 -3.613471,2.79949 -4.801886,2.43056 -1.188417,-0.36892 -1.532883,-1.4633 -0.885284,-2.38406 0.647601,-0.92076 6.982369,-1.53151 5.68717,-0.0465 z"
id="path6030-7"
inkscape:connector-curvature="0" />
<path
style="display:inline;overflow:visible;fill:#76533a;fill-opacity:0.98277061;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -48.863286,20.387787 c -5.04856,3.449004 -11.098802,13.425273 -5.948421,21.706801 5.150375,8.281529 19.004702,3.98451 25.421587,-1.966011 6.416884,-5.950521 5.271399,-15.299913 2.485393,-18.363564 -2.786007,-3.06366 -10.152373,-7.984665 -21.958559,-1.377226 z"
id="path4285-3-2"
inkscape:connector-curvature="0"
sodipodi:nodetypes="csssc" />
<path
style="display:inline;overflow:visible;fill:#dbb191;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -48.785494,20.861346 c -4.67148,3.191408 -10.258272,13.113846 -5.492578,20.77682 4.765692,7.662975 18.304763,3.663028 24.242367,-1.843042 5.937604,-5.506069 4.643675,-14.457819 2.065757,-17.292653 -2.577918,-2.834825 -9.891173,-7.755047 -20.815546,-1.641125 z"
id="path4285-2"
inkscape:connector-curvature="0"
sodipodi:nodetypes="csssc" />
<path
style="display:inline;overflow:visible;fill:#8d5336;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -46.441024,21.121395 c 4.969154,-0.794606 10.99264,-2.084426 13.426539,-0.356145 2.433903,1.728292 6.620652,7.68411 5.467503,9.994753 -1.153151,2.310643 -4.468498,8.347051 -3.455536,10.778679 0.913167,2.192068 3.60755,0.263591 4.774688,-1.389478 1.16714,-1.653059 3.694396,-16.251576 1.772327,-18.088813 -1.922069,-1.837237 -4.374127,-5.598012 -7.821485,-5.316316 -4.626086,0.378014 -10.363593,-0.840177 -10.493347,-2.572833 -1.234783,0.06308 -7.945844,3.659075 -6.749975,6.101924 1.301738,2.659114 1.569263,1.066584 3.079286,0.848229 z"
id="path5169-8"
inkscape:connector-curvature="0"
sodipodi:nodetypes="csssssscsc" />
<path
style="display:inline;overflow:visible;fill:#c06e46;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -33.277221,21.134197 c 2.3301,1.612738 5.282872,5.239654 4.188178,7.433162 -1.094693,2.193508 -0.568243,2.931858 -1.007736,5.142878 -0.709945,3.57161 -0.637355,6.305469 0.09307,7.681667 0.730426,1.376198 2.60705,-1.144744 3.161036,-1.929379 1.107967,-1.569263 3.545353,-15.345993 1.720721,-17.090094 -1.824632,-1.744101 -3.658895,-5.463128 -6.912023,-5.017503 -3.404972,0.466425 -10.76542,-0.160355 -10.934052,-2.505902 -1.155794,0.07076 -6.092169,2.391301 -5.920529,5.423638 0.158287,2.796441 1.679933,1.295765 4.767089,0.685983 3.087156,-0.609781 8.328014,-1.566016 10.844246,0.17555 z"
id="path5169-6-9"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ssssssscscs" />
<path
style="display:inline;overflow:visible;fill:#6c4e30;fill-opacity:0.97846327;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -31.21757,34.539218 c 2.267966,-2.430517 5.921235,-3.102726 6.718114,-0.794368 0.796878,2.308347 -1.476493,6.356615 -3.151276,6.607888 -1.770181,0.26559 -4.24933,-0.338533 -4.364748,-1.245684"
id="path5003-7"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cssc" />
<path
style="display:inline;overflow:visible;fill:#dbb191;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -31.832858,34.481923 c 2.789854,-0.93621 5.644083,-2.221584 6.440961,0.08676 0.796877,2.308358 -1.148656,4.589139 -2.823439,4.840412 -1.77018,0.26559 -3.997496,0.220064 -4.112913,-0.687087"
id="path5003-6-3"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cssc" />
<path
style="display:inline;overflow:visible;fill:#6c4e30;fill-opacity:0.97846327;fill-rule:evenodd;stroke:none;stroke-width:7.01484632px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -51.899466,32.798227 c -1.422854,2.532979 -0.420064,3.551605 1.202776,3.708933 0.34424,0.03337 -1.2152,0.100292 -2.052716,-0.382361 -1.455913,-0.838888 -0.409649,-2.274026 0.849932,-3.326647 z"
id="path5097-6"
inkscape:connector-curvature="0"
sodipodi:nodetypes="csscc" />
<path
style="display:inline;overflow:visible;fill:#8e6235;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5.33853054px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -52.279044,38.484227 c 3.214749,3.385037 9.674508,-0.418469 8.931651,-0.0099 -1.286897,2.560555 -3.480092,3.553677 -5.281449,2.93032 -1.281398,-0.443426 -2.071083,-0.918303 -3.650202,-2.920391 z"
id="path5099-1"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccscc" />
<path
style="display:inline;overflow:visible;fill:#76533a;fill-opacity:0.98277061;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -26.342983,36.430478 c -0.946711,-2.036266 -3.755335,-0.617701 -4.038312,-0.107944 -0.28298,0.509748 -0.469124,2.352899 0.766544,1.953296 0.926548,-0.299642 0.305419,-1.339232 0.114998,-1.477488 -0.190418,-0.138267 1.670118,-1.591321 3.156766,-0.367904 z"
id="path5101-2"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cssscc" />
<path
style="display:inline;overflow:visible;fill:#76533a;fill-opacity:0.98277061;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -27.390723,36.624497 c 0.79341,1.302226 -0.284006,1.801446 -1.118505,1.749262 -0.996042,-0.06229 1.296791,-0.402438 1.118505,-1.749262 z"
id="path5103-9"
inkscape:connector-curvature="0"
sodipodi:nodetypes="csc" />
<path
style="display:inline;overflow:visible;fill:#6c4e30;fill-opacity:0.97846327;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -42.237903,25.865446 c 2.864352,0.488967 1.430976,6.536184 -1.642845,6.364021 -3.578027,-0.200412 -1.990502,-6.984269 1.642845,-6.364021 z"
id="path5105-5-3"
inkscape:connector-curvature="0"
sodipodi:nodetypes="sss" />
<path
style="display:inline;overflow:visible;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -42.348932,26.819901 c 2.818886,0.361797 1.832041,5.61582 -1.730549,5.437317 -3.562593,-0.178502 -1.909867,-5.904547 1.730549,-5.437317 z"
id="path5105-1"
inkscape:connector-curvature="0"
sodipodi:nodetypes="sss" />
<path
style="display:inline;overflow:visible;fill:#6c4e30;fill-opacity:0.97846327;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -51.428122,26.15282 c 2.459392,0.532224 0.981052,6.110679 -1.552652,5.973628 -3.033573,-0.164077 -1.499885,-6.634209 1.552652,-5.973628 z"
id="path5105-7-3-9"
inkscape:connector-curvature="0"
sodipodi:nodetypes="sss" />
<path
style="display:inline;overflow:visible;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -51.583414,26.959281 c 2.413146,0.409877 1.427341,5.555124 -1.583422,5.321314 -3.01077,-0.233819 -1.478764,-5.841422 1.583422,-5.321314 z"
id="path5105-7-4"
inkscape:connector-curvature="0"
sodipodi:nodetypes="sss" />
<path
style="display:inline;overflow:visible;fill:#8d5336;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -44.783723,24.442275 c 2.714919,-0.510503 6.413286,0.451247 7.002291,2.113648 0.172181,-1.419624 -1.630858,-4.858519 -7.002291,-2.113648 z"
id="path5150-7"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<path
style="display:inline;overflow:visible;fill:#8d5336;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -49.519862,24.396245 c -2.412139,0.0035 -4.63565,1.15779 -4.829503,2.898678 -0.01486,-1.46299 1.769777,-4.91825 4.829503,-2.898678 z"
id="path5150-5-8"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#linearGradient1296);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.98713714;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
d="m -42.349809,29.866265 c 0.104073,1.06542 -0.649923,2.155164 -1.750975,2.380552 -2.271645,-0.03104 -2.522032,-2.704983 -1.008177,-4.108028 1.198809,-1.111062 2.641596,0.524008 2.759152,1.727476 z"
id="path5784-4"
inkscape:connector-curvature="0"
sodipodi:nodetypes="scss" />
<ellipse
transform="matrix(-0.99501312,0.09974415,0.09974415,0.99501312,0,0)"
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#3a3a3a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
id="path5767-5"
cx="47.857407"
cy="25.590271"
rx="0.84886146"
ry="0.90317881" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#linearGradient5862-805-5);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.98186457;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
d="m -51.263292,29.843948 c 0.108681,1.074079 -0.811225,2.240193 -1.994834,2.294731 -2.10929,0.09718 -1.840845,-3.150925 -0.571894,-3.951148 1.268953,-0.800213 2.447721,0.480283 2.566728,1.656417 z"
id="path5784-7-0"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ssss" />
<ellipse
transform="matrix(-0.99501312,0.09974415,0.09974415,0.99501312,0,0)"
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#3a3a3a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
id="path5767-2-3"
ry="0.90782917"
rx="0.8273322"
cy="24.745483"
cx="56.505615" />
<ellipse
transform="matrix(-0.99501312,0.09974415,0.09974415,0.99501312,0,0)"
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#fdfcfa;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
id="path5834-6"
cx="47.149242"
cy="25.117126"
rx="0.4353216"
ry="0.41891629" />
<ellipse
transform="matrix(-0.99501312,0.09974415,0.09974415,0.99501312,0,0)"
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#fdfcfa;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
id="path5836-1"
cx="47.177975"
cy="26.287109"
rx="0.27901918"
ry="0.25034222" />
<ellipse
transform="matrix(-0.99501312,0.09974415,0.09974415,0.99501312,0,0)"
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#fdfcfa;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
id="path5834-3-0"
cx="55.650879"
cy="24.544434"
rx="0.4353216"
ry="0.41891629" />
<ellipse
transform="matrix(-0.99501312,0.09974415,0.09974415,0.99501312,0,0)"
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#fdfcfa;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
id="path5836-6-6"
cx="55.691788"
cy="25.727539"
rx="0.27901918"
ry="0.25034222" />
</g>
</svg>
diff --git a/src/activities/share/resource/images/candy.svg b/src/activities/share/resource/images/candy.svg
index 4f9f7eb83..1650d8ee3 100644
--- a/src/activities/share/resource/images/candy.svg
+++ b/src/activities/share/resource/images/candy.svg
@@ -1,71 +1,94 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="svg2"
- viewBox="0 0 39.374999 56.250001"
+ viewBox="0 0 42 60"
height="60"
width="42"
- inkscape:version="0.92.1 r15371"
+ inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
sodipodi:docname="candy.svg">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1884"
inkscape:window-height="1051"
id="namedview32"
showgrid="false"
units="px"
inkscape:zoom="4.7572176"
- inkscape:cx="17.731924"
+ inkscape:cx="-72.026426"
inkscape:cy="63.383296"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<defs
id="defs4" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
+ <dc:date>2017</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Timothée Giet</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
</cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
</rdf:RDF>
</metadata>
<g
id="g3527"
- transform="matrix(0.67684674,0,0,0.67684674,-68.882985,-459.20893)">
+ transform="matrix(0.72196986,0,0,0.72196986,-73.475185,-489.82286)">
<path
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#6d1e1e;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.37690854;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
d="m 132.02811,679.84788 c -8.04553,-0.25046 -15.95524,4.50231 -19.292,11.86311 -2.59537,5.37625 -3.07538,11.6434 -2.05839,17.46758 0.57967,3.65038 4.41695,5.85396 7.92046,4.98797 3.36839,-0.19947 5.94772,-3.12367 6.13926,-6.41619 0.76465,-4.06045 -0.93689,-8.80985 1.84107,-12.32994 2.25228,-2.20936 6.2761,-2.21667 8.89754,-0.78363 1.74778,2.91763 1.09226,6.56962 1.24283,9.83823 -0.005,16.76895 -0.0427,33.54176 0.0498,50.30834 0.2483,4.26937 5.20633,6.28248 8.87931,5.01663 4.27691,-0.7914 5.63523,-5.40692 5.06709,-9.18845 -0.0232,-16.60727 1.19769,-33.20689 0.69832,-49.81303 -0.2394,-5.15461 -0.59604,-10.90499 -4.58899,-14.69697 -3.79679,-4.00462 -9.29092,-6.27512 -14.79625,-6.25365 z"
id="path3549-3"
inkscape:connector-curvature="0" />
<path
style="fill:#f0f0f0;fill-opacity:1;stroke-width:1.18845427"
d="m 132.03149,682.22559 c -6.83372,-0.23737 -13.61239,3.55889 -16.72277,9.69133 -2.74628,5.04652 -3.22178,11.07775 -2.32756,16.66882 0.43314,3.38858 4.39762,3.98337 7.02482,2.81616 2.90003,-1.58575 2.44803,-5.44614 2.55528,-8.25473 -0.34319,-4.14905 0.4717,-9.43463 4.87532,-11.13306 2.8893,-0.96223 6.3723,-1.09021 9.08503,0.43047 3.01656,2.35206 2.46472,6.63064 2.58101,10.0397 -0.0332,17.35038 -0.0228,34.70225 0.0241,52.05177 0.20114,3.22404 4.34757,3.86953 6.73893,2.66559 2.64207,-0.80035 2.62465,-3.6798 2.47047,-5.91805 -0.0235,-16.53569 1.12153,-33.06091 0.73502,-49.59608 -0.31198,-4.79776 -0.17963,-10.32165 -3.96719,-13.8849 -3.37928,-3.49951 -8.20043,-5.58808 -13.07254,-5.57702 z"
id="path3529"
inkscape:connector-curvature="0" />
<path
style="color:#000000;fill:#dc3f3f;fill-opacity:1;stroke-width:0.15989453"
d="m 134.97779,682.49412 c -2.78583,1.68294 -3.87593,5.47975 -3.52065,8.83893 1.77112,-0.0432 3.5383,0.25575 5.06467,1.11139 0.34516,0.26913 0.62955,0.57224 0.88762,0.88762 0.16835,-3.06065 1.92342,-7.00511 4.52762,-8.08557 -1.86438,-1.21459 -3.92982,-2.11016 -6.10147,-2.58827 -0.23141,-0.0392 -0.46504,-0.10335 -0.69369,-0.14173 -0.0542,-0.01 -0.10979,-0.0132 -0.1641,-0.0224 z m -12.09106,1.88713 c -3.04994,1.6056 -5.63612,4.04127 -7.30983,7.10098 0.79341,3.36035 4.27905,6.4628 7.30983,6.39983 0.53142,-2.31118 1.70876,-4.36699 3.85631,-5.49729 -3.64257,-2.20893 -4.04968,-5.44914 -3.85631,-8.00352 z m 25.98721,13.97073 c -3.45652,0.84076 -7.03487,3.54051 -9.77131,5.7882 -0.005,2.96882 0.0102,5.93717 0.007,8.90606 2.6517,-2.65236 6.19094,-6.04826 9.97271,-6.68328 -0.0115,-1.5584 0.0215,-3.11824 -0.0149,-4.6768 -0.0704,-1.08311 -0.11858,-2.20797 -0.19393,-3.33418 z m -36.26573,6.27303 c 0.0483,1.33181 0.1647,2.65868 0.37295,3.96074 0.43314,3.38858 4.39919,3.98671 7.02639,2.8195 0.73049,-0.39943 1.24351,-0.94639 1.61115,-1.58131 -3.00071,0.47579 -6.97816,-1.1442 -9.01049,-5.19893 z m 36.37015,15.44016 c -3.52688,0.86537 -7.29772,3.46109 -9.86828,6.04926 7.6e-4,2.65063 0.005,5.3007 0.007,7.95131 2.66442,-2.38739 6.24799,-5.07094 9.67434,-6.09402 0.0763,-2.63573 0.12625,-5.27078 0.18648,-7.90655 z m -0.49975,20.25122 c -3.19336,0.80673 -6.7218,2.95008 -9.36107,4.93041 0.005,2.49637 0.001,4.99257 0.007,7.48885 2.4386,-2.29924 5.86157,-5.29746 9.27156,-6.01942 0.0218,-2.1339 0.0354,-4.26618 0.082,-6.39984 z"
id="path3533"
inkscape:connector-curvature="0" />
</g>
</svg>
diff --git a/src/activities/share/resource/images/girl.svg b/src/activities/share/resource/images/girl.svg
index 91fb8525b..d9f4a4f4d 100644
--- a/src/activities/share/resource/images/girl.svg
+++ b/src/activities/share/resource/images/girl.svg
@@ -1,382 +1,405 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="svg2"
- viewBox="0 0 39.374999 56.250001"
+ viewBox="0 0 42 60"
height="60"
width="42"
- inkscape:version="0.92.1 r15371"
+ inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
sodipodi:docname="girl.svg">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1884"
inkscape:window-height="1051"
id="namedview32"
showgrid="false"
units="px"
inkscape:zoom="1.6819304"
- inkscape:cx="23.574402"
+ inkscape:cx="-230.30055"
inkscape:cy="64.777487"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg2" />
<defs
id="defs4">
<linearGradient
gradientTransform="matrix(0.96958036,0.09974415,-0.09719467,0.99501312,-128.43025,-2.1375864)"
gradientUnits="userSpaceOnUse"
y2="30.051884"
x2="38.269402"
y1="28.53743"
x1="38.396049"
id="linearGradient5870-39"
xlink:href="#linearGradient1005"
inkscape:collect="always" />
<linearGradient
inkscape:collect="always"
id="linearGradient1005">
<stop
style="stop-color:#5d9cd6;stop-opacity:1"
offset="0"
id="stop1001" />
<stop
style="stop-color:#85bbe0;stop-opacity:1"
offset="1"
id="stop1003" />
</linearGradient>
<linearGradient
gradientTransform="matrix(0.9815442,0.09747867,-0.09839397,0.97241342,-128.71519,-1.4544761)"
gradientUnits="userSpaceOnUse"
y2="29.458378"
x2="47.31078"
y1="27.521519"
x1="47.416126"
id="linearGradient5862-805"
xlink:href="#linearGradient1005"
inkscape:collect="always" />
</defs>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
+ <dc:date>2017</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Timothée Giet</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
</cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
</rdf:RDF>
</metadata>
<g
id="g1248"
- transform="matrix(0.69449136,0,0,0.69449136,88.361984,-10.740054)">
+ transform="matrix(0.74079078,0,0,0.74079078,94.252783,-11.456058)">
<path
style="display:inline;overflow:visible;fill:#6d4d30;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -78.18476,62.085172 c 2.138617,0.481263 6.546924,2.458243 6.287382,4.39412 -0.09044,0.674573 -3.768599,-0.532013 -4.451146,0.06213 -0.682613,0.59422 -0.646835,1.178482 0.857829,2.0824 0.726381,0.436386 0.688382,1.774762 -0.214043,1.710641 -0.90236,-0.0642 -3.309572,-1.397321 -4.398312,-2.534473 -1.088803,-1.137075 -3.15073,-3.292985 -2.585631,-3.927083 0.830181,-0.931548 4.503921,-1.78774 4.503921,-1.78774 z"
id="path6085"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cssssssc" />
<path
style="display:inline;overflow:visible;fill:#c79968;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -78.38057,62.758312 c 2.138617,0.481263 4.963492,1.573394 5.180927,2.864172 0.113018,0.671185 -3.052747,-0.01193 -3.735362,0.582285 -0.682614,0.594222 -0.840609,1.506253 0.664122,2.410097 0.726381,0.436385 0.841592,0.880976 -0.06117,0.817225 -0.902359,-0.0642 -2.348306,-1.445767 -3.437114,-2.582845 -1.088736,-1.137149 -3.484613,-2.342236 -2.919514,-2.976334 0.830181,-0.931548 4.308111,-1.1146 4.308111,-1.1146 z"
id="path6085-3"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cssssssc" />
<path
style="display:inline;overflow:visible;fill:#864a25;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -96.009335,50.103927 c 3.626559,5.303174 7.314396,12.161329 9.68619,15.057606 1.87333,2.287712 6.46725,1.433374 7.925272,-1.781266 1.855737,-4.091532 -2.835426,-7.310991 -5.887926,-9.847323 -2.612933,-2.171075 -7.089033,-8.231592 -9.552281,-8.503428 -2.618534,-0.288973 -3.647094,1.429686 -2.171255,5.074411 z"
id="path5890-2"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cssssc" />
<path
style="display:inline;overflow:visible;fill:#d38254;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -96.313168,48.854903 c 3.626603,5.303084 8.252032,12.307391 10.623827,15.203668 1.87333,2.287712 5.018155,1.988471 6.476179,-1.226172 1.855703,-4.091437 -2.604529,-5.855636 -5.657019,-8.391985 -2.612938,-2.171066 -7.563748,-8.724641 -10.02699,-8.996485 -2.618534,-0.288973 -2.891812,-0.233795 -1.415997,3.410974 z"
id="path5890-6-6"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cssssc" />
<path
inkscape:transform-center-y="6.4827357"
inkscape:transform-center-x="-3.3593108"
style="display:inline;overflow:visible;fill:#785333;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -84.222199,83.649957 c 3.413168,1.053655 5.829904,3.564045 6.06957,3.92767 0.239618,0.363714 0.862018,1.689484 0.42453,2.196002 -0.437488,0.506519 -4.060113,2.937566 -8.511736,3.646093 -4.451673,0.708614 -8.437361,-0.121098 -8.934605,-0.813695 -0.49724,-0.692596 -1.843474,-3.854778 -1.033449,-4.555371 0.809979,-0.700505 9.870674,-4.819686 11.98569,-4.400699 z"
id="path5960-2"
inkscape:connector-curvature="0" />
<path
inkscape:transform-center-y="6.0417536"
inkscape:transform-center-x="-3.1733939"
style="display:inline;overflow:visible;fill:#d9bc7e;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -84.639315,84.403657 c 2.884895,0.791676 4.899282,2.769803 5.097006,3.058475 0.197868,0.28841 0.490294,0.824171 0.110224,1.238181 -0.380116,0.414099 -3.499105,2.425838 -7.295235,3.066889 -3.796084,0.640962 -7.171288,0.03838 -7.582928,-0.510094 -0.411588,-0.548558 -1.289813,-2.548414 -0.589895,-3.124371 0.69992,-0.575957 8.469405,-4.031694 10.260828,-3.72908 z"
id="path5960-9-0"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccssssc" />
<path
style="display:inline;overflow:visible;fill:#7c4523;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -90.741921,68.168309 c 2.53794,4.172555 5.450897,8.75527 5.570555,9.257839 0.119656,0.502569 -0.691791,4.735574 -0.44832,5.016346 0.243471,0.280772 1.841977,-0.549967 2.126708,0.373893 0.114101,0.370227 -2.173076,3.268171 -4.79703,4.51179 -2.623957,1.243619 -7.760059,3.489438 -8.827151,2.506325 -1.067043,-0.9832 -0.200068,-6.885712 -0.259839,-7.631647 -0.05977,-0.745937 0.390253,-1.249051 0.624377,-1.557465 0.234173,-0.308501 -3.330849,-5.85393 -3.914209,-6.773917 -0.58336,-0.919988 8.498613,-5.669301 9.924909,-5.703164 z"
id="path5925-8"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cssssssssc"
inkscape:transform-center-x="1.7131945"
inkscape:transform-center-y="-3.0499145" />
<path
style="display:inline;overflow:visible;fill:#c76f3a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -91.147943,69.678462 c 2.188148,3.597507 4.795485,7.639674 4.89867,8.072948 0.103183,0.433274 -1.034662,4.82011 -0.625992,5.257227 0.218787,0.234104 1.527611,0.13281 1.482037,0.463763 -0.04552,0.330865 -1.33951,1.708726 -3.601814,2.780921 -2.262354,1.072283 -6.543618,3.062289 -7.46357,2.214541 -0.920001,-0.84766 0.309685,-5.770005 0.258136,-6.413112 -0.05155,-0.643105 0.336474,-1.076925 0.538362,-1.342882 0.201888,-0.265958 -2.677431,-5.883033 -3.817507,-6.620114 -0.788759,-0.509887 7.101942,-4.384066 8.331678,-4.413292 z"
id="path5925-1-7"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cssssssssc"
inkscape:transform-center-x="2.0853772"
inkscape:transform-center-y="-2.9968831" />
<path
style="display:inline;overflow:visible;fill:#785333;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -95.771994,86.85689 c 2.945201,2.0214 4.505642,5.1371 4.626205,5.5557 0.120565,0.4185 0.320357,1.8694 -0.248017,2.2228 -0.568372,0.3534 -4.750214,1.5966 -9.211074,0.9487 -4.46087,-0.648 -8.01922,-2.6259 -8.28791,-3.4351 -0.26868,-0.8091 -0.61315,-4.2287 0.36859,-4.6565 0.98173,-0.4278 10.85763,-1.6648 12.752206,-0.6356 z"
id="path5960"
inkscape:connector-curvature="0" />
<path
style="display:inline;overflow:visible;fill:#d9bc7e;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -96.394433,87.42359 c 2.518724,1.468 3.853207,3.7309 3.956311,4.0349 0.103108,0.304 0.273968,1.3577 -0.212102,1.6144 -0.486069,0.2567 -4.062364,1.1596 -7.877276,0.689 -3.81491,-0.4706 -6.85801,-1.9071 -7.08778,-2.4948 -0.22978,-0.5877 -0.52437,-3.0712 0.31521,-3.382 0.83957,-0.3107 9.285402,-1.2091 10.905637,-0.4615 z"
id="path5960-9"
inkscape:connector-curvature="0" />
<path
style="display:inline;overflow:visible;fill:#7c4523;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -94.384706,71.24639 c 0.837057,4.8115 1.467433,9.2727 1.395095,9.7843 -0.07234,0.5115 -2.084032,4.5449 -1.960023,4.8952 0.124008,0.3503 2.032361,0.7875 1.842903,1.1254 -0.189457,0.3379 -3.217331,2.2476 -6.114308,2.446 -2.896981,0.1985 -9.348861,-0.341 -9.982681,-1.6462 -0.63382,-1.3052 2.89008,-6.1198 3.1071,-6.8359 0.21701,-0.7162 0.81983,-1.02 1.15052,-1.2215 0.33069,-0.2015 -1.08852,-3.4196 -1.2952,-4.4891 -0.20668,-1.0696 10.516612,-4.548 11.856594,-4.0582 z"
id="path5925"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cssssssssc" />
<path
style="display:inline;overflow:visible;fill:#c76f3a;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -95.314619,72.50359 c 0.721692,4.1484 1.26519,7.9947 1.202821,8.4358 -0.06237,0.441 -2.434073,4.4982 -2.21348,5.0545 0.118113,0.2979 1.373342,0.682 1.209996,0.9734 -0.163347,0.2913 -1.871408,1.1008 -4.369117,1.2719 -2.497711,0.171 -8.060391,-0.294 -8.606851,-1.4194 -0.54647,-1.1253 2.9568,-4.895 3.1439,-5.5125 0.18711,-0.6174 0.70684,-0.8794 0.99196,-1.0531 0.28511,-0.1737 -0.46968,-3.2078 -1.26137,-4.3106 -0.54771,-0.763 8.746837,-3.8623 9.902141,-3.44 z"
id="path5925-1"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cssssssssc" />
<path
style="display:inline;overflow:visible;fill:#864a25;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -92.423612,46.976592 c 2.408674,3.429343 10.357024,20.890537 10.861919,24.947285 -0.78036,1.465242 -4.626584,0.05183 -10.597485,3.957619 -2.108112,1.378939 -20.692752,2.887395 -19.658162,-0.144928 0.63907,-1.873085 1.89343,-3.952977 3.48653,-9.556139 1.59309,-5.603164 3.19144,-21.360605 4.6017,-22.092828 2.09437,-1.08741 9.136359,-0.425387 11.305498,2.888991 z"
id="path5873-0"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccssssc" />
<path
style="display:inline;overflow:visible;fill:#d38254;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -92.548783,48.5369 c 2.182841,3.107789 9.38594,18.931837 9.843494,22.608218 -0.707192,1.327859 -4.192789,0.04696 -9.603849,3.586513 -1.910468,1.24972 -18.752592,2.616722 -17.814992,-0.131343 0.57915,-1.697459 1.7159,-3.582326 3.15963,-8.660153 1.44373,-5.077828 2.8922,-19.357781 4.17024,-20.021351 1.89799,-0.985451 8.279719,-0.385503 10.245477,2.618116 z"
id="path5873"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccssssc" />
<path
style="display:inline;overflow:visible;fill:#864a25;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -102.49778,49.367185 c -2.83775,5.763913 -5.51563,13.075758 -7.45261,16.279242 -1.52998,2.530175 -6.19859,2.336117 -8.09784,-0.639303 -2.41726,-3.786909 1.76985,-7.639193 4.43175,-10.582884 2.27861,-2.519654 5.84988,-9.153793 8.24968,-9.772237 2.55107,-0.657444 3.813,0.897966 2.86902,4.715182 z"
id="path5890"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cssssc" />
<path
style="display:inline;overflow:visible;fill:#d38254;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -102.09795,47.811374 c -2.83775,5.763913 -6.6993,13.629633 -8.63628,16.833117 -1.52994,2.530269 1.1164,-1.559457 -1.97168,-3.269287 -4.38094,-2.425672 -6.53975,0.399165 -0.64025,-5.857447 2.33063,-2.471664 5.92702,-9.503832 8.32681,-10.122286 2.55108,-0.657444 3.86539,-1.401294 2.9214,2.415903 z"
id="path5890-6"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cssssc" />
<path
style="display:inline;overflow:visible;fill:#6c4e30;fill-opacity:0.97846327;fill-rule:evenodd;stroke:none;stroke-width:4.16854429px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -115.52463,60.944509 c -3.15056,-0.263358 -8.17367,-1.375133 -8.78045,-1.017667 -0.60702,0.357185 -0.58509,1.4491 0.22368,1.937623 0.80871,0.488453 3.98665,0.957372 4.43521,1.357393 -1.46365,0.879042 -6.19892,1.755047 -6.23449,2.368147 -0.0355,0.61317 0.38321,1.51892 1.3911,1.649877 1.00796,0.131035 3.73466,-0.859579 4.49948,-0.804286 -1.062,1.452406 -3.58686,3.616149 -3.42604,4.126401 0.16078,0.51018 1.24858,0.917986 1.97129,0.567007 0.72271,-0.350978 1.73712,-1.20432 2.01011,-1.490476 0.38179,1.199838 0.20433,3.038353 0.46436,3.290035 0.21097,0.204206 1.36991,-0.170741 1.69439,-1.173792 0.32442,-1.003122 -0.0593,-2.930509 0.36525,-2.892322 0.39562,0.03563 2.04527,-0.844357 2.55139,-1.557457 0.50607,-0.713169 2.12518,-1.058476 2.74416,-2.753166 0.27339,-0.748368 -0.36646,-1.581008 -0.0943,-3.115011 0.27837,-1.569345 0.81888,-3.341438 0.50368,-3.687332 -0.63045,-0.69186 -1.6201,-0.516323 -2.27618,0.291901 -0.68471,0.84368 -0.905,3.096393 -2.04163,2.904316 z"
id="path5995"
inkscape:connector-curvature="0"
sodipodi:nodetypes="csscsscsscssssssssc" />
<path
style="display:inline;overflow:visible;fill:#c79968;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.16854429px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -115.30302,61.297627 c -3.15056,-0.26336 -7.87146,-1.384144 -8.47824,-1.026678 -0.60702,0.357185 -0.31342,0.742841 0.49534,1.231365 0.80871,0.488453 4.5955,1.284772 5.044,1.684724 -1.46366,0.879042 -7.09098,1.884838 -7.12656,2.497937 -0.0355,0.613171 0.41837,0.778006 1.42627,0.908964 1.00795,0.131035 4.55903,-1.033007 5.32377,-0.977783 -1.06193,1.452475 -4.24482,4.160465 -4.08406,4.670646 0.16084,0.510253 0.37382,0.779032 1.09653,0.428055 0.72271,-0.350978 2.14207,-1.714961 2.41417,-2.002169 0.38178,1.199836 0.27015,3.251534 0.53018,3.503216 0.21096,0.204206 0.5917,0.260505 0.91624,-0.742475 0.32442,-1.003122 0.005,-3.096896 0.4299,-3.058639 0.39556,0.03556 1.84557,-0.660155 2.3517,-1.373254 0.50607,-0.713169 1.76567,-0.769188 2.38464,-2.463878 0.27332,-0.748439 -0.0473,-1.706601 0.22483,-3.240603 0.27843,-1.569275 0.90498,-2.88382 0.58978,-3.229714 -0.63045,-0.691861 -0.82116,-0.61836 -1.47717,0.189935 -0.68478,0.843607 -0.92457,3.192568 -2.0612,3.000491 z"
id="path5995-2"
inkscape:connector-curvature="0"
sodipodi:nodetypes="csscsscsscssssssssc" />
<path
style="display:inline;overflow:visible;fill:#864a25;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -101.49817,45.888628 c 2.218299,2.52089 5.165101,4.2231 6.800377,3.7005 1.635282,-0.52265 2.243615,-2.40467 1.35251,-3.70902 -2.717407,-0.29388 -9.482127,-1.96184 -8.152887,0.009 z"
id="path6030-5"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cscc" />
<path
style="display:inline;overflow:visible;fill:#c79968;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -99.985966,45.980718 c 1.612113,1.77952 3.613471,2.79949 4.801886,2.43056 1.188417,-0.36892 1.532883,-1.4633 0.885284,-2.38406 -0.647601,-0.92076 -6.982374,-1.53151 -5.68717,-0.0465 z"
id="path6030"
inkscape:connector-curvature="0" />
<path
style="display:inline;overflow:visible;fill:#4e3a32;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5.27144384px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -107.4031,25.79871 c -0.66816,-1.287859 -0.23611,-0.825604 -1.2572,-1.918745 -0.92819,0.02834 -2.21452,-1.41602 -2.61364,-2.2676 -0.74651,-1.010917 -0.0922,0.03142 -1.26003,-0.295602 -1.15912,0.372927 -1.80464,0.964341 -2.82378,0.836145 -0.6732,-0.422716 -2.16869,0.473181 -2.49582,1.066495 -1.12266,0.7971 -0.19811,1.257245 -1.14979,1.372225 -0.42803,0.07714 -0.91792,1.995833 -1.934,2.632194 -0.3099,0.356461 -1.46838,0.388746 -1.40378,1.846501 -0.0982,0.219209 -0.92805,2.538068 -0.93139,4.446775 -0.24812,0.414493 0.38987,0.822433 0.34251,2.630845 -0.0584,0.499116 -0.40812,2.411895 -0.18131,2.773127 0.48675,1.904961 0.72802,2.282001 0.97198,3.491971 0.79908,0.691553 -0.48037,2.098743 0.29753,2.317081 0.16713,0.02594 1.96206,0.968796 2.22905,2.183456 0.33861,1.26263 0.77317,1.311033 0.81542,1.6886 0.22625,-0.04536 2.16095,0.770596 2.28903,0.488429 1.08457,-1.038313 1.99616,0.397098 2.26552,0.192322 0.35109,0.677567 1.29711,0.0835 2.63658,-0.293024 0.27205,-0.986421 0.69881,-1.110332 1.76611,-1.381419 0.12162,-0.196529 1.41996,-0.468816 1.67215,-1.861057 -0.0758,-0.47749 1.27409,-2.416529 1.22179,-3.748699 0.22867,-1.534417 0.45208,-0.01258 1.16441,-1.174405 0.21292,-0.169583 -0.13842,-3.131595 0.39511,-3.26015 -0.0722,-0.433667 1.57435,-0.892247 1.2874,-1.431468 -0.24261,-1.276562 -0.92708,-1.728876 -0.60299,-2.947793 -0.37988,-1.559963 0.86623,-1.650346 0.24131,-2.96954 -0.79157,-0.893007 -0.75419,-3.235865 -1.22333,-3.301653 -1.01292,-1.889939 -2.38969,-1.992296 -1.96537,-1.643069"
id="path5186-2"
inkscape:connector-curvature="0"
sodipodi:nodetypes="csssssssccccccccccccccccccccc" />
<path
style="display:inline;overflow:visible;fill:#6a4739;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:5.27144384px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -108.01169,26.708689 c -0.60375,-1.163694 -0.21335,-0.746006 -1.136,-1.733752 -0.8387,0.0256 -2.00102,-1.279514 -2.36166,-2.048996 -0.67454,-0.913461 -0.0833,0.02835 -1.13856,-0.267086 -1.04737,0.336965 -1.63065,0.871376 -2.55155,0.755537 -0.60829,-0.381959 -1.9596,0.427558 -2.2552,0.963671 -1.01442,0.720262 -0.179,1.136028 -1.03893,1.239946 -0.38677,0.06966 -0.82943,1.803399 -1.74755,2.378426 -0.28003,0.322089 -1.32681,0.351261 -1.26845,1.668484 -0.0887,0.198059 -0.83857,2.293372 -0.84159,4.018061 -0.2242,0.374527 0.35229,0.74314 0.30949,2.377213 -0.0528,0.451 -0.36877,2.179374 -0.16384,2.505762 0.43983,1.721314 0.65784,2.061994 0.87828,3.155329 0.72204,0.624876 -0.43406,1.896404 0.26884,2.093685 0.151,0.02372 1.77291,0.8754 2.01416,1.972953 0.30596,1.140894 0.69863,1.184644 0.7368,1.525814 0.20444,-0.04102 1.95262,0.696306 2.06835,0.441339 0.98001,-0.938214 1.80371,0.358881 2.0471,0.173855 0.31724,0.612247 1.17205,0.07548 2.38239,-0.264773 0.24582,-0.891319 0.63145,-1.003297 1.59584,-1.248245 0.1099,-0.177584 1.28307,-0.423611 1.51095,-1.681636 -0.0685,-0.431446 1.15125,-2.183547 1.104,-3.387288 0.20662,-1.386491 0.40849,-0.01134 1.05215,-1.06118 0.19239,-0.153235 -0.12508,-2.829684 0.35701,-2.945856 -0.0653,-0.391851 1.42257,-0.806225 1.16328,-1.293453 -0.21921,-1.153511 -0.8377,-1.562206 -0.54485,-2.663605 -0.34325,-1.409575 0.78272,-1.491245 0.21805,-2.683254 -0.71526,-0.806901 -0.68148,-2.923887 -1.10539,-2.983336 -0.91527,-1.707725 -2.15931,-1.800229 -1.77589,-1.484664"
id="path5186"
inkscape:connector-curvature="0"
sodipodi:nodetypes="csssssssccccccccccccccccccccc" />
<path
style="display:inline;overflow:visible;fill:#6c4e30;fill-opacity:0.97846327;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -88.621222,20.318722 c 5.04856,3.449004 11.075103,13.005976 5.924722,21.287504 -5.150375,8.281529 -19.68841,4.472872 -26.10529,-1.477649 -6.41689,-5.950521 -4.97839,-15.299913 -2.19238,-18.363564 2.78601,-3.06366 10.56676,-8.05373 22.372948,-1.446291 z"
id="path4285-3"
inkscape:connector-curvature="0"
sodipodi:nodetypes="csssc" />
<path
style="display:inline;overflow:visible;fill:#c79968;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -89.113402,20.861346 c 4.67148,3.191408 10.648961,12.475505 5.883267,20.138479 -4.765692,7.662975 -18.695455,4.301369 -24.633055,-1.204701 -5.9376,-5.506069 -4.64368,-14.457819 -2.06576,-17.292653 2.57792,-2.834825 9.89118,-7.755047 20.815548,-1.641125 z"
id="path4285"
inkscape:connector-curvature="0"
sodipodi:nodetypes="csssc" />
<path
style="display:inline;overflow:visible;fill:#4e3a32;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -91.457872,21.121395 c -4.969154,-0.794606 -10.992638,-2.084426 -13.426538,-0.356145 -2.4339,1.728292 -5.15557,6.023682 -4.00242,8.334325 1.15315,2.310643 2.21397,2.178685 0.62304,3.941621 -1.59093,1.762945 -3.02152,2.80307 -4.18865,1.150001 -1.16714,-1.653059 -2.91302,-10.293569 -0.99095,-12.130806 1.92207,-1.837237 7.19995,-5.205958 10.65398,-5.023299 3.454016,0.182669 2.75666,-0.941916 3.991445,-0.878889 1.234783,0.06308 9.075769,1.476769 10.419379,4.114963 1.34361,2.638204 -1.569263,1.066584 -3.079286,0.848229 z"
id="path5169"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cssssssssc" />
<path
style="display:inline;overflow:visible;fill:#6a4739;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -91.622844,21.28776 c -4.75338,-0.938894 -10.482596,-1.895129 -12.998826,-0.153563 -2.3301,1.612738 -5.28288,5.239654 -4.18818,7.433162 1.09469,2.193508 2.71336,2.88328 1.20308,4.556844 -1.51028,1.673575 -2.73217,2.144929 -3.84014,0.575659 -1.10798,-1.569259 -3.15467,-9.58333 -1.33004,-11.327431 1.82464,-1.744101 6.78722,-5.052783 10.06615,-4.879374 3.27892,0.173408 2.970408,-0.656211 4.142602,-0.596383 1.172196,0.05982 8.380028,1.018045 9.655528,3.522498 1.275498,2.504453 -1.289244,1.149257 -2.710174,0.868588 z"
id="path5169-6"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ssssssssss" />
<path
style="display:inline;overflow:visible;fill:#6c4e30;fill-opacity:0.97846327;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -106.68133,34.539218 c -2.26796,-2.430517 -5.82356,-2.41902 -6.62044,-0.110662 -0.79688,2.308347 1.37882,5.672909 3.05361,5.924182 1.77018,0.26559 4.24933,-0.338533 4.36474,-1.245684"
id="path5003"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cssc" />
<path
style="display:inline;overflow:visible;fill:#c79968;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -106.06604,34.481923 c -2.78985,-0.93621 -5.25339,-1.830895 -6.05027,0.477452 -0.79688,2.308358 0.75797,4.19845 2.43275,4.449723 1.77018,0.26559 3.9975,0.220064 4.11291,-0.687087"
id="path5003-6"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cssc" />
<path
style="display:inline;overflow:visible;fill:#6c4e30;fill-opacity:0.97846327;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -86.564288,32.798202 c 0.413356,1.113322 -0.06693,1.801616 -0.860219,2.158794 -0.195203,0.08789 0.867799,0.390697 1.378765,0.06766 0.888249,-0.561462 0.249926,-1.521991 -0.518541,-2.226504 z"
id="path5097"
inkscape:connector-curvature="0"
sodipodi:nodetypes="csscc" />
<path
style="display:inline;overflow:visible;fill:#8e6235;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -85.619852,38.472105 c -3.214749,2.386559 -9.674508,-0.295034 -8.931651,-0.007 1.286897,1.805273 4.274782,2.118521 6.062827,1.652796 1.788044,-0.465716 2.060459,-0.467148 2.868824,-1.645796 z"
id="path5099"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccsc" />
<path
style="display:inline;overflow:visible;fill:#6c4e30;fill-opacity:0.97846327;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -111.55591,36.430478 c 0.94671,-2.036266 4.04835,-0.617701 4.33133,-0.107944 0.28298,0.509748 0.1761,2.352899 -1.05957,1.953296 -0.92654,-0.299642 -0.30541,-1.339232 -0.11499,-1.477488 0.19041,-0.138267 -1.67012,-1.591321 -3.15677,-0.367904 z"
id="path5101"
inkscape:connector-curvature="0"
sodipodi:nodetypes="csssc" />
<path
style="display:inline;overflow:visible;fill:#6c4e30;fill-opacity:0.97846327;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -110.01981,36.526825 c -0.79341,1.302226 -0.20436,1.899118 0.63014,1.846934 0.99604,-0.06229 -0.80843,-0.50011 -0.63014,-1.846934 z"
id="path5103"
inkscape:connector-curvature="0"
sodipodi:nodetypes="csc" />
<path
style="display:inline;overflow:visible;fill:#6c4e30;fill-opacity:0.97846327;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -95.660993,25.865446 c -2.864352,0.488967 -1.430976,6.536184 1.642845,6.364021 3.578027,-0.200412 1.990502,-6.984269 -1.642845,-6.364021 z"
id="path5105-5"
inkscape:connector-curvature="0"
sodipodi:nodetypes="sss" />
<path
style="display:inline;overflow:visible;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -95.549964,26.819901 c -2.818886,0.361797 -1.832041,5.61582 1.730549,5.437317 3.562593,-0.178502 1.909867,-5.904547 -1.730549,-5.437317 z"
id="path5105"
inkscape:connector-curvature="0"
sodipodi:nodetypes="sss" />
<path
style="display:inline;overflow:visible;fill:#6c4e30;fill-opacity:0.97846327;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -86.470774,26.15282 c -2.459392,0.532224 -0.981052,6.110679 1.552652,5.973628 3.033573,-0.164077 1.499885,-6.634209 -1.552652,-5.973628 z"
id="path5105-7-3"
inkscape:connector-curvature="0"
sodipodi:nodetypes="sss" />
<path
style="display:inline;overflow:visible;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -86.315482,26.959281 c -2.413146,0.409877 -1.427341,5.555124 1.583422,5.321314 3.01077,-0.233819 1.478764,-5.841422 -1.583422,-5.321314 z"
id="path5105-7"
inkscape:connector-curvature="0"
sodipodi:nodetypes="sss" />
<path
style="display:inline;overflow:visible;fill:#6c4e30;fill-opacity:0.97846327;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -93.115173,24.442275 c -2.714919,-0.510503 -6.413286,0.451247 -7.002287,2.113648 0.004,-1.217817 2.624945,-3.722415 7.002287,-2.113648 z"
id="path5150"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<path
style="display:inline;overflow:visible;fill:#6c4e30;fill-opacity:0.97846327;fill-rule:evenodd;stroke:none;stroke-width:4.48256016px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m -88.379034,24.396245 c 2.412139,0.0035 4.63565,1.15779 4.829503,2.898678 0.222549,-1.195957 -0.79436,-3.664143 -4.829503,-2.898678 z"
id="path5150-5"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#linearGradient5870-39);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.98713714;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
d="m -95.549087,29.866265 c -0.104073,1.06542 0.649923,2.155164 1.750975,2.380552 2.271645,-0.03104 2.522032,-2.704983 1.008177,-4.108028 -1.198809,-1.111062 -2.641596,0.524008 -2.759152,1.727476 z"
id="path5784"
inkscape:connector-curvature="0"
sodipodi:nodetypes="scss" />
<ellipse
transform="rotate(5.7244379)"
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#3a3a3a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
id="path5767"
cx="-89.353798"
cy="39.344883"
rx="0.84886146"
ry="0.90317881" />
<path
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:url(#linearGradient5862-805);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.98186457;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
d="m -86.635604,29.843948 c -0.108681,1.074079 0.811225,2.240193 1.994834,2.294731 2.10929,0.09718 1.840845,-3.150925 0.571894,-3.951148 -1.268953,-0.800213 -2.447721,0.480283 -2.566728,1.656417 z"
id="path5784-7"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ssss" />
<ellipse
transform="rotate(5.7244379)"
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#3a3a3a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
id="path5767-2"
ry="0.90782917"
rx="0.8273322"
cy="38.500095"
cx="-80.705589" />
<ellipse
transform="rotate(5.7244379)"
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#fdfcfa;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
id="path5834"
cx="-90.061966"
cy="38.871738"
rx="0.4353216"
ry="0.41891629" />
<ellipse
transform="rotate(5.7244379)"
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#fdfcfa;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
id="path5836"
cx="-90.033234"
cy="40.041721"
rx="0.27901918"
ry="0.25034222" />
<ellipse
transform="rotate(5.7244379)"
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#fdfcfa;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
id="path5834-3"
cx="-81.560326"
cy="38.299046"
rx="0.4353216"
ry="0.41891629" />
<ellipse
transform="rotate(5.7244379)"
style="color:#000000;display:inline;overflow:visible;visibility:visible;opacity:1;fill:#fdfcfa;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate"
id="path5836-6"
cx="-81.519417"
cy="39.482151"
rx="0.27901918"
ry="0.25034222" />
</g>
</svg>
diff --git a/src/activities/share/share.js b/src/activities/share/share.js
index e45e47440..e673149ae 100644
--- a/src/activities/share/share.js
+++ b/src/activities/share/share.js
@@ -1,220 +1,220 @@
/* GCompris - share.js
*
* Copyright (C) 2016 Stefan Toncu <stefan.toncu29@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
var currentLevel = 0
var numberOfLevel = 10
var items
var savedTotalBoys
var savedTotalGirls
var savedTotalCandies
var savedPlacedInGirls
var savedPlacedInBoys
var savedCurrentCandies
function start(items_) {
items = items_
currentLevel = 0
initLevel()
}
function stop() {
}
function initLevel() {
items.bar.level = currentLevel + 1
var filename = "resource/board/"+ "board" + currentLevel + ".qml"
items.dataset.source = filename
setUp()
}
function setUp() {
var levelData = items.dataset.item
// use board levels
if (currentLevel < 7) {
var subLevelData = levelData.levels[items.currentSubLevel];
items.totalBoys = subLevelData.totalBoys
items.totalGirls = subLevelData.totalGirls
items.totalCandies = subLevelData.totalCandies
items.instruction.text = subLevelData.instruction
items.nbSubLevel = levelData.levels.length
items.background.currentCandies = items.totalGirls * subLevelData.placedInGirls +
items.totalBoys * subLevelData.placedInBoys
items.background.placedInGirls = subLevelData.placedInGirls
items.background.placedInBoys = subLevelData.placedInBoys
items.background.showCount = subLevelData.showCount
items.background.rest = items.totalCandies -
Math.floor(items.totalCandies / items.totalChildren) * (items.totalBoys+items.totalGirls)
items.basketWidget.element.opacity = (subLevelData.forceShowBasket === true ||
items.background.rest !== 0) ? 1 : 0
items.background.wrongMove.visible = false
}
else {
// create random (guided) levels
// get a random number between 1 and max for boys, girls and candies
var maxBoys = levelData.levels[0].maxBoys
var maxGirls = levelData.levels[0].maxGirls
var maxCandies = levelData.levels[0].maxCandies
items.totalBoys = Math.floor(Math.random() * maxBoys) + 1
items.totalGirls = Math.floor(Math.random() * maxGirls) + 1
var sum = items.totalBoys + items.totalGirls
// use sum * 4 as top margin (max 4 candies per rectangle)
items.totalCandies = Math.floor(Math.random() * (4 * sum - sum + 1)) + sum
// stay within the max margin
if (items.totalCandies > maxCandies)
items.totalCandies = maxCandies
//~ singular Place %n boy
//~ plural Place %n boys
items.instruction.text = qsTr("Place %n boy(s) ", "First part of Place %n boy(s) and %n girl(s) in the center. Then equally split %n pieces of candy between them.", items.totalBoys);
//~ singular and %n girl in the center.
//~ plural and %n girls in the center.
items.instruction.text += qsTr("and %n girl(s) in the center. ", "Second part of Place %n boy(s) and %n girl(s) in the center. Then equally split %n pieces of candy between them.", items.totalGirls);
//~ singular Then equally split %n candy between them.
//~ plural Then equally split %n candies between them.
items.instruction.text += qsTr("Then equally split %n pieces of candy between them.", "Third part of Place %n boy(s) and %n girl(s) in the center. Then equally split %n pieces of candy between them.", items.totalCandies);
items.background.showCount = false
items.nbSubLevel = 5
// depending on the levels configuration, add candies from start in a child rectangle
if (levelData.levels[0].alreadyPlaced == false) {
items.background.placedInGirls = 0
items.background.placedInBoys = 0
items.background.currentCandies = 0
}
else {
items.background.currentCandies = items.totalCandies * 2
// Place randomly between 0 and 3 candies for each child
while (items.background.currentCandies > items.totalCandies / 3) {
items.background.placedInGirls = Math.floor(Math.random() * 3)
items.background.placedInBoys = Math.floor(Math.random() * 3)
items.background.currentCandies = items.totalGirls * items.background.placedInGirls
+ items.totalBoys * items.background.placedInBoys
}
}
items.background.rest = items.totalCandies -
Math.floor(items.totalCandies / items.totalChildren) * (items.totalBoys+items.totalGirls)
items.basketWidget.element.opacity = 1
items.background.wrongMove.visible = false;
saveVariables()
}
resetBoard()
}
function resetBoard() {
items.background.currentGirls = 0
items.background.currentBoys = 0
items.background.resetCandy()
items.background.finished = false
items.acceptCandy = false
items.instruction.opacity = 1
items.listModel.clear()
items.girlWidget.current = 0
items.girlWidget.canDrag = true
items.girlWidget.element.opacity = 1
items.boyWidget.current = 0
items.boyWidget.canDrag = true
items.boyWidget.element.opacity = 1
items.candyWidget.canDrag = true
items.candyWidget.element.opacity = 1
if (items.totalCandies - items.background.currentCandies == 0)
items.candyWidget.element.opacity = 0.6
items.basketWidget.canDrag = true
}
function saveVariables() {
savedTotalBoys = items.totalBoys
savedTotalGirls = items.totalGirls
savedTotalCandies = items.totalCandies
savedPlacedInGirls = items.background.placedInGirls
savedPlacedInBoys = items.background.placedInBoys
savedCurrentCandies = items.background.currentCandies
}
function loadVariables() {
items.totalBoys = savedTotalBoys
items.totalGirls = savedTotalGirls
items.totalCandies = savedTotalCandies
items.background.placedInGirls = savedPlacedInGirls
items.background.placedInBoys = savedPlacedInBoys
items.background.currentCandies = savedCurrentCandies
}
function reloadRandom() {
if (currentLevel < 7) {
initLevel()
}
else {
loadVariables()
resetBoard()
items.background.rest = items.totalCandies -
Math.floor(items.totalCandies / items.totalChildren) * (items.totalBoys+items.totalGirls)
items.background.showCount = false
items.basketWidget.element.opacity = 1
}
}
function nextSubLevel() {
items.currentSubLevel ++
if (items.currentSubLevel === items.nbSubLevel) {
nextLevel()
}
else {
setUp()
}
}
function nextLevel() {
if(numberOfLevel <= ++currentLevel) {
currentLevel = 0
}
items.currentSubLevel = 0;
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
items.currentSubLevel = 0;
initLevel();
}
diff --git a/src/activities/simplepaint/ActivityInfo.qml b/src/activities/simplepaint/ActivityInfo.qml
index 53ef8904c..125b4ab04 100644
--- a/src/activities/simplepaint/ActivityInfo.qml
+++ b/src/activities/simplepaint/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "simplepaint/Simplepaint.qml"
difficulty: 1
icon: "simplepaint/simplepaint.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: true
//: Activity title
title: qsTr("A simple drawing activity")
//: Help title
description: qsTr("Create your own drawing")
// intro: "Select a color and paint the rectangles as you like to create a drawing."
//: Help goal
goal: qsTr("Enhance creative skills")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("Select a color and paint the rectangles as you like to create a drawing.")
credit: ""
section: "fun"
createdInVersion: 4000
}
diff --git a/src/activities/simplepaint/PaintItem.qml b/src/activities/simplepaint/PaintItem.qml
index cf4f70053..32f93938d 100644
--- a/src/activities/simplepaint/PaintItem.qml
+++ b/src/activities/simplepaint/PaintItem.qml
@@ -1,53 +1,53 @@
/* GCompris - PaintItem.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Christof Petig and Ingo Konrad (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "simplepaint.js" as Activity
import GCompris 1.0
Item {
id: paint
property alias color: rectangle.color
property double ix
property double iy
property int nbx
property int nby
property int initialX
// Warning testing parent here, just to avoid an error at deletion time
property double r: parent ? Math.min((parent.width - initialX) / nbx / 2, (parent.height - bar.height) / nby / 2) : 0
property double offsetX: parent ? (initialX + parent.width % (width * nbx)) / 2 : 0
property double offsetY: parent ? 10 : 0
x: width * ix + offsetX
y: height * iy + offsetY
width: r * 2
height: r * 2
Rectangle {
id: rectangle
anchors.fill: parent
border.width: bar.level == 1 ? 1 : 0
border.color: "black"
}
function touched() {
paint.color = Activity.getColor()
}
}
diff --git a/src/activities/simplepaint/Simplepaint.qml b/src/activities/simplepaint/Simplepaint.qml
index c1d979041..156f7c8fc 100644
--- a/src/activities/simplepaint/Simplepaint.qml
+++ b/src/activities/simplepaint/Simplepaint.qml
@@ -1,260 +1,260 @@
/* GCompris - Simplepaint.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Christof Petig and Ingo Konrad (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "simplepaint.js" as Activity
ActivityBase {
id: activity
onStart: focus = true
pageComponent: Image {
id: background
source: items.backgroundImg
sourceSize.width: Math.max(parent.width, parent.height)
fillMode: Image.PreserveAspectCrop
signal start
signal stop
focus: true
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
QtObject {
id: items
property alias background: background
property alias bar: bar
property alias paintModel: paintModel
property var colors: bar.level < 10 ? Activity.colorsSimple : Activity.colorsAdvanced
property string colorSelector: colors[0]
property string backgroundImg: Activity.backgrounds[bar.level - 1]
}
onStart: Activity.start(main, items)
onStop: Activity.stop()
MultiPointTouchArea {
anchors.fill: parent
onPressed: checkTouchPoint(touchPoints)
onTouchUpdated: checkTouchPoint(touchPoints)
}
function checkTouchPoint(touchPoints) {
for(var i in touchPoints) {
var touch = touchPoints[i]
var block = rootItem.childAt(touch.x, touch.y)
if(block)
block.touched()
}
}
Item {
id: rootItem
anchors.fill: parent
}
ListModel {
id: paintModel
}
Column {
id: colorSelectorColumn
spacing: 2
anchors {
left: background.left
top: background.top
bottom: bar.top
}
// The color selector
GridView {
id: colorSelector
clip: true
width: cellWidth + 10 * ApplicationInfo.ratio
height: colorSelectorColumn.height - (2 + colorSelectorButton.height)
model: items.colors
cellWidth: 60 * ApplicationInfo.ratio
cellHeight: cellWidth
delegate: Item {
width: colorSelector.cellWidth
height: width
Rectangle {
id: rect
width: parent.width
height: width
radius: width * 0.1
z: iAmSelected ? 10 : 1
color: modelData
border.color: "#373737"
border.width: modelData == "#00FFFFFF" ? 0 : 1
Image {
scale: 0.9
width: rect.height
height: rect.height
sourceSize.width: rect.height
sourceSize.height: rect.height
source: Activity.url + "eraser.svg"
visible: modelData == "#00FFFFFF" ? 1 : 0
anchors.centerIn: parent
}
property bool iAmSelected: modelData == items.colorSelector
states: [
State {
name: "notclicked"
when: !rect.iAmSelected && !mouseArea.containsMouse
PropertyChanges {
target: rect
scale: 0.8
}
},
State {
name: "clicked"
when: mouseArea.pressed
PropertyChanges {
target: rect
scale: 0.7
}
},
State {
name: "hover"
when: mouseArea.containsMouse
PropertyChanges {
target: rect
scale: 1.1
}
},
State {
name: "selected"
when: rect.iAmSelected
PropertyChanges {
target: rect
scale: 1
}
}
]
SequentialAnimation {
id: anim
running: rect.iAmSelected
loops: Animation.Infinite
alwaysRunToEnd: true
NumberAnimation {
target: rect
property: "rotation"
from: 0; to: 10
duration: 200
easing.type: Easing.OutQuad
}
NumberAnimation {
target: rect
property: "rotation"
from: 10; to: -10
duration: 400
easing.type: Easing.InOutQuad
}
NumberAnimation {
target: rect
property: "rotation"
from: -10; to: 0
duration: 200
easing.type: Easing.InQuad
}
}
Behavior on scale { NumberAnimation { duration: 70 } }
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: {
activity.audioEffects.play('qrc:/gcompris/src/core/resource/sounds/scroll.wav')
items.colorSelector = modelData
}
}
}
}
}
// Scroll buttons
GCButtonScroll {
id: colorSelectorButton
isHorizontal: true
width: colorSelectorColumn.width - 10 * ApplicationInfo.ratio
height: width * heightRatio
onUp: colorSelector.flick(0, 1400)
onDown: colorSelector.flick(0, -1400)
upVisible: colorSelector.visibleArea.yPosition <= 0 ? 0 : 1
downVisible: colorSelector.visibleArea.yPosition + colorSelector.visibleArea.heightRatio >= 1 ? 0 : 1
}
}
Item {
anchors {
top: parent.top
left: colorSelectorColumn.right
right: parent.right
bottom: parent.bottom
}
Repeater {
model: paintModel
parent: rootItem
PaintItem {
initialX: colorSelector.width + 20 * ApplicationInfo.ratio
ix: m_ix
iy: m_iy
nbx: m_nbx
nby: m_nby
color: items.colors[0]
}
}
}
DialogHelp {
id: dialogHelpLeftRight
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | reload | level }
onHelpClicked: {
displayDialog(dialogHelpLeftRight)
}
onReloadClicked: Activity.initLevel()
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: home()
}
}
}
diff --git a/src/activities/simplepaint/simplepaint.js b/src/activities/simplepaint/simplepaint.js
index b8e570b75..ca29adb53 100644
--- a/src/activities/simplepaint/simplepaint.js
+++ b/src/activities/simplepaint/simplepaint.js
@@ -1,176 +1,176 @@
/* GCompris - simplepaint.js
*
* Copyright (C) 2014 Bruno Coudoin
*
* Authors:
* Christof Petig and Ingo Konrad (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
var url = "qrc:/gcompris/src/activities/simplepaint/resource/"
var colorsSimple = [
'#00FFFFFF',
'#FF550000',
'#FFaa0000',
'#FFffaaaa',
'#FFffdd55',
'#FF918a6f',
'#FFccff00',
'#FFe5ff80',
'#FF330080',
'#FF9955ff',
'#FFe9afdd',
'#FFff2a7f'
]
var colorsAdvanced = [
'#00FFFFFF',
'#FF550000',
'#FF800000',
'#FFaa0000',
'#FFd40000',
'#FFff0000',
'#FFff2a2a',
'#FFff8080',
'#FFffaaaa',
'#FFffd5d5',
'#FFc83737',
'#FFd35f5f',
'#FFde8787',
'#FFaa4400',
'#FFd45500',
'#FFff7f2a',
'#FFff9955',
'#FFffccaa',
'#FFaa8800',
'#FFffcc00',
'#FFffdd55',
'#FFffe680',
'#FFc8ab37',
'#FFd3bc5f',
'#FF918a6f',
'#FFaca793',
'#FFaad400',
'#FFccff00',
'#FFe5ff80',
'#FFf6ffd5',
'#FF00d455',
'#FF80ffb3',
'#FF00ffcc',
'#FF80ffe6',
'#FF2ad4ff',
'#FFaaeeff',
'#FF0066ff',
'#FF5555ff',
'#FF87aade',
'#FF80b3ff',
'#FF0000ff',
'#FF330080',
'#FF9955ff',
'#FFdd55ff',
'#FFff2ad4',
'#FFe9afdd',
'#FFff2a7f',
'#FFff80b2',
'#FFd35f8d'
]
var backgrounds = [
'qrc:/gcompris/src/activities/menu/resource/background.svg',
'qrc:/gcompris/src/activities/colors/resource/background.svg',
'qrc:/gcompris/src/activities/wordsgame/resource/background.svg',
'qrc:/gcompris/src/activities/sudoku/resource/background.svg',
'qrc:/gcompris/src/activities/mosaic/resource/background.svg',
'qrc:/gcompris/src/activities/algebra_by/resource/background.svg',
'qrc:/gcompris/src/activities/scalesboard/resource/background.svg',
'qrc:/gcompris/src/activities/redraw/resource/background.svg',
'qrc:/gcompris/src/activities/color_mix/resource/background.svg',
'qrc:/gcompris/src/activities/missing-letter/resource/background.svg',
'qrc:/gcompris/src/activities/enumerate/resource/background.svg',
'qrc:/gcompris/src/activities/football/resource/background.svg',
'qrc:/gcompris/src/activities/hanoi_real/resource/background.svg',
'qrc:/gcompris/src/activities/intro_gravity/resource/background.svg',
'qrc:/gcompris/src/activities/instruments/resource/background.svg',
'qrc:/gcompris/src/activities/gletters/resource/background.svg',
'qrc:/gcompris/src/activities/braille_alphabets/resource/background.svg',
'qrc:/gcompris/src/activities/followline/resource/background.svg',
'qrc:/gcompris/src/activities/money/resource/background.svg',
'qrc:/gcompris/src/activities/menu/resource/background.svg',
'qrc:/gcompris/src/activities/smallnumbers2/resource/background.svg',
'qrc:/gcompris/src/activities/align4-2players/resource/background.svg',
'qrc:/gcompris/src/activities/smallnumbers/resource/background.svg',
'qrc:/gcompris/src/activities/magic-hat-minus/resource/background.svg',
'qrc:/gcompris/src/activities/tic_tac_toe/resource/background.svg',
'qrc:/gcompris/src/activities/click_on_letter/resource/background.svg',
'qrc:/gcompris/src/activities/fifteen/resource/background.svg'
]
var main
var items
// The size of the array
var nbx
var nby
var currentLevel = 0
var numberOfLevel = backgrounds.length
function start(main_, items_) {
main = main_
items = items_
currentLevel = 0
initLevel()
}
function stop() {
}
function initLevel() {
items.bar.level = currentLevel + 1
items.paintModel.clear()
nbx = 20 + currentLevel
nby = Math.floor(nbx * (main.height / main.width))
var model = []
for(var ix = 0; ix < nbx; ++ix) {
for(var iy = 0; iy < nby; ++iy) {
items.paintModel.append( {
"m_ix": ix, "m_iy": iy, "m_nbx": nbx, "m_nby": nby,
} )
}
}
}
function nextLevel() {
if(numberOfLevel <= ++currentLevel ) {
currentLevel = 0
}
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
initLevel();
}
function getColor() {
return items.colorSelector
}
diff --git a/src/activities/smallnumbers/ActivityInfo.qml b/src/activities/smallnumbers/ActivityInfo.qml
index c20bc2149..4f1d2e651 100644
--- a/src/activities/smallnumbers/ActivityInfo.qml
+++ b/src/activities/smallnumbers/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "smallnumbers/Smallnumbers.qml"
difficulty: 2
icon: "smallnumbers/smallnumbers.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
//: Activity title
title: qsTr("Numbers With Dice")
//: Help title
description: qsTr("Count the number of dots on dice before they reach the ground")
// intro: "Count the number on your dice and type it on your keyboard before it reaches the ground."
//: Help goal
goal: qsTr("In a limited time, count the number of dots")
//: Help prerequisite
prerequisite: qsTr("Counting skills")
//: Help manual
manual: qsTr("With the keyboard, type the number of dots you see on the falling dice.")
credit: ""
section: "computer keyboard math numeration"
createdInVersion: 0
}
diff --git a/src/activities/smallnumbers/Smallnumbers.qml b/src/activities/smallnumbers/Smallnumbers.qml
index 98f43372d..6cc3bcde9 100644
--- a/src/activities/smallnumbers/Smallnumbers.qml
+++ b/src/activities/smallnumbers/Smallnumbers.qml
@@ -1,38 +1,38 @@
/* GCompris - smallnumbers.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "../gletters"
Gletters {
id: activity
mode: "letter"
dataSetUrl: "qrc:/gcompris/src/activities/smallnumbers/resource/"
configurationButtonVisible: false
function getImage(key) {
return dataSetUrl + "dice" + key + ".svg"
}
}
diff --git a/src/activities/smallnumbers2/ActivityInfo.qml b/src/activities/smallnumbers2/ActivityInfo.qml
index a165b07c0..bee3fbc0c 100644
--- a/src/activities/smallnumbers2/ActivityInfo.qml
+++ b/src/activities/smallnumbers2/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "smallnumbers2/Smallnumbers2.qml"
difficulty: 2
icon: "smallnumbers2/smallnumbers2.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
//: Activity title
title: qsTr("Numbers with dominoes")
//: Help title
description: qsTr("Count the number of dots on the dominoes before they reach the ground")
// intro: "Count the number of the points on the dominoes then type the result on your keyboard."
//: Help goal
goal: qsTr("In a limited time, count the number of dots")
//: Help prerequisite
prerequisite: qsTr("Counting skills")
//: Help manual
manual: qsTr("With the keyboard, type the number of dots you see on the falling dominoes.")
credit: ""
section: "math numeration"
createdInVersion: 0
}
diff --git a/src/activities/smallnumbers2/Smallnumbers2.qml b/src/activities/smallnumbers2/Smallnumbers2.qml
index b0a29f3d3..849e267c8 100644
--- a/src/activities/smallnumbers2/Smallnumbers2.qml
+++ b/src/activities/smallnumbers2/Smallnumbers2.qml
@@ -1,39 +1,43 @@
/* GCompris - smallnumbers2.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "../gletters"
Gletters {
id: activity
-
- mode: "letter"
dataSetUrl: "qrc:/gcompris/src/activities/smallnumbers2/resource/"
- configurationButtonVisible: false
+ configurationButtonVisible: true
+ activityName: "smallnumbers2"
+ property string dominoMode: "dot"
+
+ function getMode() {
+ return activity.dominoMode;
+ }
function getDominoValues(key) {
var val1 = Math.floor(Math.random() * key)
return [val1, key - val1]
}
}
diff --git a/src/activities/solar_system/ActivityInfo.qml b/src/activities/solar_system/ActivityInfo.qml
index f68b98fbf..8409fc6a6 100644
--- a/src/activities/solar_system/ActivityInfo.qml
+++ b/src/activities/solar_system/ActivityInfo.qml
@@ -1,43 +1,43 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2018 Aman Kumar Gupta <gupta2140@gmail.com>
*
* Authors:
* Aman Kumar Gupta <gupta2140@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "solar_system/SolarSystem.qml"
difficulty: 5
icon: "solar_system/solar_system.svg"
author: "Aman Kumar Gupta &lt;gupta2140@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Solar System")
//: Help title
- description: qsTr("Answer the questions presented and get a 100% correctness among the options.")
+ description: qsTr("Answer the questions with a correctness of 100%.")
//intro: "Answer the questions presented and get a 100% correctness among the options."
//: Help goal
- goal: ""
+ goal: qsTr("Learn information about the solar system. If you want to learn more about astronomy, try downloading KStars (https://edu.kde.org/kstars/) or Stellarium (http://stellarium.org/) which are open source astronomy softwares.")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("Click on a planet or the Sun to reveal questions. Each question contains 4 options. One of those is 100% correct. Try to answer the questions until you get a 100% closeness in the closeness meter.")
credit: ""
- section: "fun"
+ section: "experiment"
createdInVersion: 9500
}
diff --git a/src/activities/solar_system/Dataset.js b/src/activities/solar_system/Dataset.js
index 79300bfae..4941db615 100644
--- a/src/activities/solar_system/Dataset.js
+++ b/src/activities/solar_system/Dataset.js
@@ -1,374 +1,383 @@
/* GCompris - Dataset.js
*
* Copyright (C) 2018 Aman Kumar Gupta <gupta2140@gmail.com>
*
* Authors:
* Aman Kumar Gupta <gupta2140@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
function get() {
return [
{
"realImg": "qrc:/gcompris/src/activities/solar_system/resource/sun.png",
"bodyName": qsTr("Sun"),
+ "bodySize": 1.3,
"levels": [
{ // sub-level 1
- "question": qsTr("How large is the Sun compared to other planets in our Solar System?"),
+ "question": qsTr("How large is the Sun compared to the planets in our Solar System?"),
"options": [qsTr("Sixth largest"), qsTr("Third largest"), qsTr("Largest"), qsTr("Seventh largest")],
"closeness": [17.5, 67, 100, 1]
},
{ // sub-level 2
"question": qsTr("The temperature of the Sun is around:"),
- "options": [qsTr("1000 degrees celsius"), qsTr("4500 degrees celsius"), qsTr("5505 degrees celsius"), qsTr("3638 degrees celsius")],
+ "options": [qsTr("1000 °C"), qsTr("4500 °C"), qsTr("5505 °C"), qsTr("3638 °C")],
"closeness": [1, 78, 100, 60]
},
{ // sub-level 3
"question": qsTr("How old is the Sun?"),
"options": [qsTr("1.2 billion years"), qsTr("3 billion years"), qsTr("7 billion years"), qsTr("4.5 billion years")],
"closeness": [1, 55, 25, 100]
},
{ // sub-level 4
"question": qsTr("How long does it take for the Sun’s light to reach the Earth?"),
"options": [qsTr("8 minutes"), qsTr("30 minutes"), qsTr("60 minutes"), qsTr("15 minutes")],
"closeness": [100, 58, 1, 86.6]
},
{ // sub-level 5
"question": qsTr("The Sun is as big as:"),
"options": [qsTr("1 million Earths"), qsTr("2.6 million Earths"), qsTr("1.3 million Earths"), qsTr("5 million Earths")],
"closeness": [92, 65, 100, 1]
}
]
},
{
"realImg": "qrc:/gcompris/src/activities/solar_system/resource/mercury.png",
"bodyName": qsTr("Mercury"),
- "temperatureHint": qsTr("The maximum temperature on Earth is 58 degrees celsius."),
+ "bodySize": 0.12,
+ "temperatureHint": qsTr("The maximum temperature on Earth is 58 °C."),
"lengthOfYearHint": qsTr("The length of a year on Venus is 225 days."),
"levels": [
{ // sub-level 1
"question": qsTr("At which position is Mercury in the Solar System?"),
"options": [qsTr("Seventh"), qsTr("Sixth"), qsTr("First"), qsTr("Fourth")],
"closeness": [1, 17.5, 100, 50.5]
},
{ // sub-level 2
"question": qsTr("How small is Mercury compared to other planets in our Solar System?"),
"options": [qsTr("Smallest"), qsTr("Second smallest"), qsTr("Third smallest"), qsTr("Fifth smallest")],
"closeness": [100, 75.3, 50.5, 1]
},
{ // sub-level 3
"question": qsTr("How many moons has Mercury?"),
"options": ["5", "200", "0", "10"],
"closeness": [97.5, 1, 100, 95]
},
{ // sub-level 4
"question": qsTr("The maximum temperature on Mercury is:"),
- "options": [qsTr("50 degrees celsius"), qsTr("35 degrees celsius"), qsTr("427 degrees celsius"), qsTr("273 degrees celsius")],
+ "options": [qsTr("50 °C"), qsTr("35 °C"), qsTr("427 °C"), qsTr("273 °C")],
"closeness": [4.8, 1, 100, 61]
},
{ // sub-level 5
"question": qsTr("How many days make a year on Mercury?"),
"options": [qsTr("365 days"), qsTr("433 days"), qsTr("88 days"), qsTr("107 days")],
"closeness": [20.5, 1, 100, 94.5]
},
{ // sub-level 6
"question": qsTr("How long is a day on Mercury?"),
"options": [qsTr("50 Earth days"), qsTr("365 Earth days"), qsTr("59 Earth days"), qsTr("107 Earth days")],
"closeness": [97, 1, 100, 84.4]
}
]
},
{
"realImg": "qrc:/gcompris/src/activities/solar_system/resource/venus.png",
"bodyName": qsTr("Venus"),
- "temperatureHint": qsTr("The maximum temperature on Earth is 58 degrees celsius."),
+ "bodySize": 0.22,
+ "temperatureHint": qsTr("The maximum temperature on Earth is 58 °C."),
"lengthOfYearHint": qsTr("The length of a year on Earth is 365 days."),
"levels": [
{ // sub-level 1
"question": qsTr("At which position is Venus in the Solar System?"),
"options": [qsTr("Seventh"), qsTr("Sixth"), qsTr("Second"), qsTr("Fourth")],
"closeness": [1, 20.8, 100, 60.4]
},
{ // sub-level 2
"question": qsTr("Venus is as heavy as:"),
"options": [qsTr("0.7 Earths"), qsTr("0.8 Earths"), qsTr("1.3 Earths"), qsTr("2.5 Earths")],
"closeness": [94, 100, 71, 1]
},
{ // sub-level 3
"question": qsTr("How large is Venus compared to other planets in our Solar System?"),
"options": [qsTr("Seventh largest"), qsTr("Sixth largest"), qsTr("Fifth largest"), qsTr("Fourth largest")],
"closeness": [50.5, 100, 50.5, 1]
},
{ // sub-level 4
"question": qsTr("How long is a year on Venus?"),
"options": [qsTr("225 days"), qsTr("365 days"), qsTr("116 days"), qsTr("100 days")],
"closeness": [100, 1, 23, 11.6]
},
{ // sub-level 5
"question": qsTr("How long is a day on Venus?"),
"options": [qsTr("117 Earth days"), qsTr("365 Earth days"), qsTr("88 Earth days"), qsTr("107 Earth days")],
"closeness": [100, 1, 88.8, 96.4]
},
{ // sub-level 6
"question": qsTr("The maximum temperature on Venus is:"),
- "options": [qsTr("100 degrees celsius"), qsTr("20 degrees celsius"), qsTr("467 degrees celsius"), qsTr("45 degrees celsius")],
+ "options": [qsTr("100 °C"), qsTr("20 °C"), qsTr("467 °C"), qsTr("45 °C")],
"closeness": [18.7, 1, 100, 6.5]
},
{ // sub-level 7
"question": qsTr("How many moons has Venus?"),
"options": ["5", "10", "2", "0"],
"closeness": [63, 1, 100, 75.3]
}
]
},
{
"realImg": "qrc:/gcompris/src/activities/solar_system/resource/earth.png",
"bodyName": qsTr("Earth"),
- "temperatureHint": qsTr("The maximum temperature on Mars is 20 degrees celsius."),
+ "bodySize": 0.3,
+ "temperatureHint": qsTr("The maximum temperature on Mars is 20 °C."),
"lengthOfYearHint": qsTr("The length of a year on Venus is 225 days."),
"levels": [
{ // sub-level 1
"question": qsTr("At which position is Earth in the Solar System?"),
"options": [qsTr("Sixth"), qsTr("Third"), qsTr("First"), qsTr("Fifth")],
"closeness": [1, 100, 35, 35]
},
{ // sub-level 2
"question": qsTr("How long does it take for Earth to complete one year?"),
"options": [qsTr("200 days"), qsTr("30 days"), qsTr("7 days"), qsTr("365 days")],
"closeness": [54.3, 7.3, 1, 100]
},
{ // sub-level 3
"question": qsTr("How many moons has Earth?"),
"options": ["1", "5", "2", "3"],
"closeness": [100, 15, 75, 50.5]
},
{ // sub-level 4
"question": qsTr("How long is a day on Earth?"),
"options": [qsTr("12 hours"), qsTr("24 hours"), qsTr("365 hours"), qsTr("48 hours")],
"closeness": [96.5, 100, 1, 93]
},
{ // sub-level 5
"question": qsTr("How many seasons has Earth?"),
"options": ["2", "4", "6", "1"],
"closeness": [34, 100, 34, 1]
},
{ // sub-level 6
"question": qsTr("Maximum temperature on Earth is:"),
- "options": [qsTr("100 degrees celsius"), qsTr("58 degrees celsius"), qsTr("30 degrees celsius"), qsTr("45 degrees celsius")],
+ "options": [qsTr("100 °C"), qsTr("58 °C"), qsTr("30 °C"), qsTr("45 °C")],
"closeness": [1, 100, 33, 69.3]
},
{ // sub-level 7
"question": qsTr("How large is Earth compared to other planets in our Solar System?"),
"options": [qsTr("Seventh largest"), qsTr("Sixth largest"), qsTr("Fifth largest"), qsTr("Fourth largest")],
"closeness": [1, 50.5, 100, 50.5]
}
]
},
{
"realImg": "qrc:/gcompris/src/activities/solar_system/resource/mars.png",
"bodyName": qsTr("Mars"),
- "temperatureHint": qsTr("The maximum temperature on Earth is 58 degrees celsius."),
+ "bodySize": 0.15,
+ "temperatureHint": qsTr("The maximum temperature on Earth is 58 °C."),
"lengthOfYearHint": qsTr("The length of a year on Earth is 365 days."),
"levels": [
{ // sub-level 1
"question": qsTr("At which position is Mars in the Solar System?"),
"options": [qsTr("Sixth"), qsTr("Fourth"), qsTr("First"), qsTr("Fifth")],
"closeness": [34, 100, 1, 67]
},
{ // sub-level 2
"question": qsTr("The maximum temperature on Mars is:"),
- "options": [qsTr("20 degrees celsius"), qsTr("35 degrees celsius"), qsTr("100 degrees celsius"), qsTr("60 degrees celsius")],
+ "options": [qsTr("20 °C"), qsTr("35 °C"), qsTr("100 °C"), qsTr("60 °C")],
"closeness": [100, 81.4, 1, 51.5]
},
{ // sub-level 3
"question": qsTr("How big is the size of Mars compared to Earth?"),
"options": [qsTr("The same"), qsTr("Half"), qsTr("Two times"), qsTr("Three times")],
"closeness": [80, 100, 40.6, 1]
},
{ // sub-level 4
"question": qsTr("How many moons has Mars?"),
"options": ["1", "5", "2", "3"],
"closeness": [67, 1, 100, 50.5]
},
{ // sub-level 5
"question": qsTr("How long is a day on Mars?"),
"options": [qsTr("12 hours"), qsTr("24 hours"), qsTr("24.5 hours"), qsTr("48 hours")],
"closeness": [47.3, 91, 100, 1]
},
{ // sub-level 6
"question": qsTr("How long does it take for Mars to complete one year?"),
"options": [qsTr("687 days"), qsTr("30 days"), qsTr("7 days"), qsTr("365 days")],
"closeness": [100, 4.3, 1, 53]
},
{ // sub-level 7
"question": qsTr("How small is Mars compared to other planets in our Solar System?"),
"options": [qsTr("Smallest"), qsTr("Second smallest"), qsTr("Third smallest"), qsTr("Fifth smallest")],
"closeness": [67, 100, 67, 1]
}
]
},
{
"realImg": "qrc:/gcompris/src/activities/solar_system/resource/jupiter.png",
"bodyName": qsTr("Jupiter"),
- "temperatureHint": qsTr("The maximum temperature on Mars is 20 degrees celsius."),
+ "bodySize": 1,
+ "temperatureHint": qsTr("The maximum temperature on Mars is 20 °C."),
"lengthOfYearHint": qsTr("The length of a year on Saturn is 29.5 Earth years."),
"levels": [
{ // sub-level 1
"question": qsTr("At which position is Jupiter in the Solar System?"),
"options": [qsTr("Sixth"), qsTr("Fifth"), qsTr("First"), qsTr("Fourth")],
"closeness": [75, 100, 1, 75]
},
{ // sub-level 2
"question": qsTr("How large is Jupiter compared to other planets in the Solar System?"),
"options": [qsTr("Third largest"), qsTr("Largest"), qsTr("Fifth largest"), qsTr("Second largest")],
"closeness": [50.5, 100, 1, 75]
},
{ // sub-level 3
"question": qsTr("The minimum temperature on Jupiter is:"),
- "options": [qsTr("-145 degrees celsius"), qsTr("100 degrees celsius"), qsTr("50 degrees celsius"), qsTr("-180 degrees celsius")],
+ "options": [qsTr("-145 °C"), qsTr("100 °C"), qsTr("50 °C"), qsTr("-180 °C")],
"closeness": [100, 63, 24.7, 1]
},
{ // sub-level 4
"question": qsTr("How many moons has Jupiter?"),
"options": ["1", "20", "25", "53"],
"closeness": [1, 37, 46.7, 100]
},
{ // sub-level 5
"question": qsTr("How long is one day on Jupiter?"),
"options": [qsTr("10 hours"), qsTr("24 hours"), qsTr("12 hours"), qsTr("48 hours")],
"closeness": [100, 63.5, 94.8, 1]
},
{ // sub-level 6
"question": qsTr("How long does it take for Jupiter to complete one year?"),
"options": [qsTr("5 Earth years"), qsTr("12 Earth years"), qsTr("30 Earth years"), qsTr("1 Earth year")],
"closeness": [61.5, 100, 1, 39.5]
}
]
},
{
"realImg": "qrc:/gcompris/src/activities/solar_system/resource/saturn.png",
"bodyName": qsTr("Saturn"),
- "temperatureHint": qsTr("The minimum temperature on Jupiter is -145 degrees celsius."),
+ "bodySize": 1.2,
+ "temperatureHint": qsTr("The minimum temperature on Jupiter is -145 °C."),
"lengthOfYearHint": qsTr("The length of a year on Jupiter is 12 Earth years."),
"levels": [
{ // sub-level 1
"question": qsTr("At which position is Saturn in the Solar System?"),
"options": [qsTr("Sixth"), qsTr("Fourth"), qsTr("First"), qsTr("Fifth")],
"closeness": [100, 60.4, 1, 80]
},
{ // sub-level 2
"question": qsTr("How large is Saturn compared to other planets in the Solar System?"),
"options": [qsTr("Third largest"), qsTr("Largest"), qsTr("Fifth largest"), qsTr("Second largest")],
"closeness": [67, 67, 1, 100]
},
{ // sub-level 3
"question": qsTr("How many moons has Saturn?"),
"options": ["120", "1", "150", "200"],
"closeness": [80, 1, 100, 60.8]
},
{ // sub-level 4
"question": qsTr("How long is one day on Saturn?"),
"options": [qsTr("10.5 hours"), qsTr("24 hours"), qsTr("12 hours"), qsTr("48 hours")],
"closeness": [100, 64.3, 96, 1]
},
{ // sub-level 5
"question": qsTr("The minimum temperature on Saturn is:"),
- "options": [qsTr("0 degrees celsius"), qsTr("100 degrees celsius"), qsTr("-178 degrees celsius"), qsTr("-100 degrees celsius")],
+ "options": [qsTr("0 °C"), qsTr("100 °C"), qsTr("-178 °C"), qsTr("-100 °C")],
"closeness": [36.6, 1, 100, 72]
},
{ // sub-level 6
"question": qsTr("How long does it take for Saturn to complete one year?"),
"options": [qsTr("29.5 Earth years"), qsTr("20 Earth years"), qsTr("10 Earth years"), qsTr("1 Earth year")],
"closeness": [100, 67, 32, 1]
}
]
},
{
"realImg": "qrc:/gcompris/src/activities/solar_system/resource/uranus.png",
"bodyName": qsTr("Uranus"),
- "temperatureHint": qsTr("The temperature on Saturn is -178 degrees celsius."),
+ "bodySize": 0.5,
+ "temperatureHint": qsTr("The temperature on Saturn is -178 °C."),
"lengthOfYearHint": qsTr("The length of a year on Saturn is 29.5 Earth years."),
"levels": [
{ // sub-level 1
"question": qsTr("At which position is Uranus in the Solar System?"),
"options": [qsTr("Seventh"), qsTr("Fourth"), qsTr("Eighth"), qsTr("Fifth")],
"closeness": [100, 1, 67, 34]
},
{ // sub-level 2
"question": qsTr("How many years does it take for Uranus to go once around the Sun?"),
"options": [qsTr("1 year"), qsTr("24 years"), qsTr("68 years"), qsTr("84 years")],
"closeness": [1, 28.4, 81, 100]
},
{ // sub-level 3
"question": qsTr("How many moons has Uranus?"),
"options": ["120", "87", "27", "50"],
"closeness": [1, 36, 100, 75.5]
},
{ // sub-level 4
"question": qsTr("How long is one day on Uranus?"),
"options": [qsTr("10 hours"), qsTr("27 hours"), qsTr("17 hours"), qsTr("48 hours")],
"closeness": [77.6, 68, 100, 1]
},
{ // sub-level 5
"question": qsTr("How large is Uranus compared to other planets in the Solar System?"),
"options": [qsTr("Third largest"), qsTr("Largest"), qsTr("Seventh largest"), qsTr("Second largest")],
"closeness": [100, 50.5, 1, 75]
},
{ // sub-level 6
"question": qsTr("The maximum temperature on Uranus is:"),
- "options": [qsTr("100 degrees celsius"), qsTr("-216 degrees celsius"), qsTr("0 degrees celsius"), qsTr("-100 degrees celsius")],
+ "options": [qsTr("100 °C"), qsTr("-216 °C"), qsTr("0 °C"), qsTr("-100 °C")],
"closeness": [1, 100, 32.3, 63.6]
}
]
},
{
"realImg": "qrc:/gcompris/src/activities/solar_system/resource/neptune.png",
"bodyName": qsTr("Neptune"),
- "temperatureHint": qsTr("The maximum temperature on Saturn is -178 degrees celsius."),
+ "bodySize": 0.4,
+ "temperatureHint": qsTr("The maximum temperature on Saturn is -178 °C."),
"lengthOfYearHint": qsTr("The length of a year on Uranus is 84 years."),
"levels": [
{ // sub-level 1
"question": qsTr("At which position is Neptune in the Solar System?"),
"options": [qsTr("Seventh"), qsTr("Fourth"), qsTr("Eighth"), qsTr("Fifth")],
"closeness": [75, 1, 100, 25.7]
},
{ // sub-level 2
"question": qsTr("How long does it take for Neptune to make one revolution around the Sun?"),
"options": [qsTr("165 years"), qsTr("3 years"), qsTr("100 years"), qsTr("1 year")],
"closeness": [100, 2, 60.7, 1]
},
{ // sub-level 3
"question": qsTr("How many moons has Neptune?"),
"options": ["120", "87", "14", "50"],
"closeness": [1, 31.8, 100, 66.3]
},
{ // sub-level 4
"question": qsTr("How long is one day on Neptune?"),
"options": [qsTr("16 hours"), qsTr("27 hours"), qsTr("17 hours"), qsTr("48 hours")],
"closeness": [100, 66, 97, 1]
},
{ // sub-level 5
"question": qsTr("The average temperature on Neptune is:"),
- "options": [qsTr("100 degrees celsius"), qsTr("30 degrees celsius"), qsTr("-210 degrees celsius"), qsTr("-100 degrees celsius")],
+ "options": [qsTr("100 °C"), qsTr("30 °C"), qsTr("-210 °C"), qsTr("-100 °C")],
"closeness": [1, 23, 100, 64]
},
{ // sub-level 6
"question": qsTr("How large is Neptune compared to other planets in the Solar System?"),
"options": [qsTr("Fourth largest"), qsTr("Largest"), qsTr("Third largest"), qsTr("Second largest")],
"closeness": [100, 1, 67, 34]
}
]
}
];
}
diff --git a/src/activities/solar_system/PlanetInSolarModel.qml b/src/activities/solar_system/PlanetInSolarModel.qml
index 18047230f..5851faf0a 100644
--- a/src/activities/solar_system/PlanetInSolarModel.qml
+++ b/src/activities/solar_system/PlanetInSolarModel.qml
@@ -1,89 +1,137 @@
/* GCompris - PlanetInSolarModel.qml
*
* Copyright (C) 2018 Aman Kumar Gupta <gupta2140@gmail.com>
*
* Authors:
* Aman Kumar Gupta <gupta2140@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "solar_system.js" as Activity
Item {
id: planetItem
width: background.itemWidth
height: width
property string planetImageSource
property string planetName
+ property double planetSize
+ property bool planetHovered
+ property bool hintMode
// Name of the planet which hovers over the top of each planet
GCText {
id: planetNameText
- anchors.horizontalCenter: background.horizontalLayout ? parent.horizontalCenter : undefined
- anchors.leftMargin: background.horizontalLayout ? 0 : 10 * ApplicationInfo.ratio
- anchors.left: !background.horizontalLayout ? planetImage.right : undefined
- horizontalAlignment: background.horizontalLayout ? Text.AlignHCenter : undefined
- y: !background.horizontalLayout ? 5 * ApplicationInfo.ratio : 0
width: parent.width
fontSizeMode: Text.Fit
font.pointSize: NaN // need to clear font.pointSize explicitly
font.pixelSize: parent.width * 0.18
color: "white"
text: planetName
+
+ states: [
+ State {
+ name: "hScreen"
+ when: background.horizontalLayout
+ AnchorChanges {
+ target: planetNameText
+ anchors.bottom: planetItem.top
+ anchors.horizontalCenter: planetItem.horizontalCenter
+ anchors.left: undefined
+ anchors.verticalCenter: undefined
+ }
+ PropertyChanges {
+ target: planetNameText
+ anchors.bottomMargin: 20 * ApplicationInfo.ratio
+ anchors.leftMargin: 0
+ horizontalAlignment: Text.AlignHCenter
+ }
+ },
+ State {
+ name: "vScreen"
+ when: !background.horizontalLayout
+ AnchorChanges {
+ target: planetNameText
+ anchors.bottom: undefined
+ anchors.horizontalCenter: undefined
+ anchors.left: planetItem.right
+ anchors.verticalCenter: planetItem.verticalCenter
+ }
+ PropertyChanges {
+ target: planetNameText
+ anchors.bottomMargin: 0
+ anchors.leftMargin: 20 * ApplicationInfo.ratio
+ horizontalAlignment: Text.AlignLeft
+ }
+ }
+
+ ]
+
+ MouseArea {
+ id: mouseAreaText
+ anchors.fill: planetNameText
+ enabled: !message.visible && !hintMode
+ hoverEnabled: ApplicationInfo.isMobile ? false : true
+ onEntered: planetHovered = true
+ onExited: planetHovered = false
+ onClicked: {
+ Activity.showQuizScreen(index)
+ }
+ }
}
Image {
id: planetImage
- anchors.top: background.horizontalLayout ? planetNameText.bottom : planetItem.top
- anchors.topMargin: parent.width * 0.05
+ z: -10
anchors.horizontalCenter: parent.horizontalCenter
- width: parent.width / 1.3
+ anchors.verticalCenter: parent.verticalCenter
+ width: parent.width * planetSize
height: planetImage.width
fillMode: Image.PreserveAspectFit
source: planetImageSource
-
- states: [
+ }
+
+ states: [
State {
- name: "clicked"
- when: mouseArea.pressed
+ name: "hover"
+ when: planetHovered
PropertyChanges {
- target: planetImage
- scale: 0.7
+ target: planetNameText
+ scale: 1.2
}
- },
- State {
- name: "hover"
- when: mouseArea.containsMouse
PropertyChanges {
target: planetImage
scale: 1.2
}
}
]
Behavior on scale { NumberAnimation { duration: 70 } }
MouseArea {
id: mouseArea
- anchors.fill: planetImage
- enabled: !message.visible
+ anchors.fill: planetItem
+ enabled: !message.visible && !hintMode
hoverEnabled: ApplicationInfo.isMobile ? false : true
- onClicked: Activity.showQuizScreen(index)
+ onEntered: planetHovered = true
+ onExited: planetHovered = false
+ onClicked: {
+ Activity.showQuizScreen(index)
+ }
}
- }
}
diff --git a/src/activities/solar_system/QuizScreen.qml b/src/activities/solar_system/QuizScreen.qml
index 7c6894c71..084460ae0 100644
--- a/src/activities/solar_system/QuizScreen.qml
+++ b/src/activities/solar_system/QuizScreen.qml
@@ -1,307 +1,307 @@
/* GCompris - QuizScreen.qml
*
* Copyright (C) 2018 Aman Kumar Gupta <gupta2140@gmail.com>
*
* Authors:
* Aman Kumar Gupta <gupta2140@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import QtGraphicalEffects 1.0
import QtQuick.Controls 1.5
import "../../core"
import "solar_system.js" as Activity
Item {
id: mainQuizScreen
width: parent.width
height: parent.height
focus: true
property alias score: score
property alias optionListModel: optionListModel
property alias restartAssessmentMessage: restartAssessmentMessage
property alias blockAnswerButtons: optionListView.blockAnswerButtons
property alias closenessMeter: closenessMeter
property string planetRealImage
property string question
property string closenessMeterValue
property int numberOfCorrectAnswers: 0
Rectangle {
id: questionArea
anchors.right: score.left
anchors.top: parent.top
anchors.left: parent.left
anchors.margins: 10 * ApplicationInfo.ratio
height: questionText.height + 10 * ApplicationInfo.ratio
color: 'white'
radius: 10
border.width: 3
opacity: 0.8
border.color: "black"
GCText {
id: questionText
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
anchors.centerIn: parent.Center
color: "black"
width: parent.width
wrapMode: Text.Wrap
text: mainQuizScreen.question
}
}
// Model of options for a question
ListModel {
id: optionListModel
}
// This grid has image of the planet in its first column/row (row in case of vertical screen) and the options on the 2nd column/row
Grid {
id: imageAndOptionGrid
columns: (background.horizontalLayout && !items.assessmentMode && items.bar.level != 2) ? 2 : 1
spacing: 10 * ApplicationInfo.ratio
anchors.top: (questionArea.y + questionArea.height) > (score.y + score.height) ? questionArea.bottom : score.bottom
anchors.left: parent.left
anchors.right: parent.right
// An item to hold image of the planet
Item {
width: background.horizontalLayout ? background.width * 0.40
: background.width - imageAndOptionGrid.anchors.margins * 2
height: background.horizontalLayout ? background.height - bar.height - questionArea.height - 10 * ApplicationInfo.ratio
: (background.height - bar.height - questionArea.height - 10 * ApplicationInfo.ratio) * 0.37
visible: !items.assessmentMode && (items.bar.level != 2)
Image {
id: planetImageMain
sourceSize.width: Math.min(parent.width, parent.height) * 0.9
anchors.centerIn: parent
source: mainQuizScreen.planetRealImage
fillMode: Image.PreserveAspectCrop
}
}
// An item to hold the list view of options
Item {
width: ( items.assessmentMode || items.bar.level == 2 ) ? mainQuizScreen.width
: background.horizontalLayout ? background.width * 0.55
: background.width - imageAndOptionGrid.anchors.margins * 2
height: background.horizontalLayout ? itemHeightHorizontal
: itemHeightVertical
readonly property real itemHeightHorizontal: background.height - bar.height - closenessMeter.height - questionArea.height - 10 * ApplicationInfo.ratio
readonly property real itemHeightVertical: (items.bar.level != 2 && !items.assessmentMode) ? itemHeightHorizontal * 0.39
: itemHeightHorizontal * 0.8
ListView {
id: optionListView
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
width: background.horizontalLayout ? background.width * 0.40
: background.width - imageAndOptionGrid.anchors.margins * 2
height: background.horizontalLayout ? background.height - bar.height - closenessMeter.height * 1.5 - questionArea.height - 50 * ApplicationInfo.ratio
: parent.itemHeightVertical
spacing: background.horizontalLayout ? 10 * ApplicationInfo.ratio : 7.5 * ApplicationInfo.ratio
orientation: Qt.Vertical
verticalLayoutDirection: ListView.TopToBottom
interactive: false
model: optionListModel
readonly property real buttonHeight: (height - 3 * spacing) / 4
add: Transition {
NumberAnimation { properties: "y"; from: parent.y; duration: 500 }
onRunningChanged: {
optionListView.blockAnswerButtons = running
}
}
property bool blockAnswerButtons: false
delegate: AnswerButton {
id: optionButton
width: parent.width
height: optionListView.buttonHeight
textLabel: optionValue
anchors.right: parent.right
anchors.left: parent.left
blockAllButtonClicks: optionListView.blockAnswerButtons
isCorrectAnswer: closeness === 100
onPressed: optionListView.blockAnswerButtons = true
onIncorrectlyPressed: {
if(!items.assessmentMode) {
closenessMeter.stopAnimations()
closenessMeterIncorrectAnswerAnimation.start()
mainQuizScreen.closenessMeterValue = closeness
}
else {
optionListView.blockAnswerButtons = false
Activity.appendAndAddQuestion()
}
}
onCorrectlyPressed: {
if(!items.assessmentMode) {
closenessMeter.stopAnimations()
particles.burst(30)
closenessMeterCorrectAnswerAnimation.start()
mainQuizScreen.closenessMeterValue = closeness
}
else {
Activity.assessmentModeQuestions.shift()
mainQuizScreen.numberOfCorrectAnswers++
Activity.nextSubLevel(true)
}
}
}
}
}
}
Rectangle {
id: closenessMeter
x: ((background.width - items.bar.barZoom * items.bar.fullButton * 5.6) < (width + 10 * ApplicationInfo.ratio) && background.horizontalLayout) ? background.width - width - 42 * ApplicationInfo.ratio : background.width - width - 10 * ApplicationInfo.ratio
y: (background.width - items.bar.barZoom * items.bar.fullButton * 5.6) < (width + 10 * ApplicationInfo.ratio) ? background.height - bar.height - height - 10 * ApplicationInfo.ratio : background.height - height - 10 * ApplicationInfo.ratio
height: 40 * ApplicationInfo.ratio
width: 150 * ApplicationInfo.ratio
radius: width * 0.06
border.width: 2
border.color: "black"
opacity: 0.78
visible: !items.assessmentMode
Item {
width: parent.width - 3 * ApplicationInfo.ratio
height: parent.height
anchors.centerIn: parent
GCText {
id: closenessText
color: "black"
anchors.fill: parent
fontSizeMode: Text.Fit
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
- text: qsTr("Closeness: %1%").arg(closenessMeterValue)
+ text: qsTr("Accuracy: %1%").arg(closenessMeterValue)
}
}
SequentialAnimation {
id: closenessMeterIncorrectAnswerAnimation
onStarted: optionListView.blockAnswerButtons = true
NumberAnimation { target: closenessMeter; property: "scale"; to: 1.1; duration: 450 }
NumberAnimation { target: closenessMeter; property: "scale"; to: 1.0; duration: 450 }
onStopped: optionListView.blockAnswerButtons = false
}
SequentialAnimation {
id: closenessMeterCorrectAnswerAnimation
onStarted: optionListView.blockAnswerButtons = true
NumberAnimation { target: closenessMeter; property: "scale"; to: 1.1; duration: 450 }
NumberAnimation { target: closenessMeter; property: "scale"; to: 1.0; duration: 450 }
NumberAnimation { target: closenessMeter; property: "scale"; to: 1.1; duration: 450 }
NumberAnimation { target: closenessMeter; property: "scale"; to: 1.0; duration: 450 }
ScriptAction { script: { Activity.nextSubLevel() } }
}
ParticleSystemStarLoader {
id: particles
clip: false
}
function stopAnimations() {
optionListView.blockAnswerButtons = false
closenessMeterCorrectAnswerAnimation.stop()
closenessMeterIncorrectAnswerAnimation.stop()
}
}
ProgressBar {
id: progressBar
height: bar.height * 0.35
width: parent.width * 0.35
readonly property real percentage: (mainQuizScreen.numberOfCorrectAnswers / score.numberOfSubLevels) * 100
readonly property string message: qsTr("%1%").arg(value)
value: Math.round(percentage * 10) / 10
maximumValue: 100
visible: items.assessmentMode
y: parent.height - bar.height - height - 10 * ApplicationInfo.ratio
x: parent.width - width * 1.1
GCText {
id: progressbarText
anchors.centerIn: parent
fontSize: mediumSize
font.bold: true
color: "black"
text: parent.message
z: 2
}
}
Rectangle {
id: restartAssessmentMessage
width: parent.width
height: parent.height - bar.height * 1.25
anchors.top: parent.top
anchors.margins: 10 * ApplicationInfo.ratio
anchors.horizontalCenter: parent.horizontalCenter
radius: 4 * ApplicationInfo.ratio
visible: items.assessmentMode && (score.currentSubLevel >= score.numberOfSubLevels)
z: 4
GCText {
anchors.fill: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
wrapMode: Text.WordWrap
fontSizeMode: mediumSize
- text: qsTr("Your final score is: <font color=\"#3bb0de\">%1%</font>.<br><br>%2").arg(progressBar.value).arg(progressBar.value <= 90 ? qsTr("You should score above 90% to become a Solar System expert!<br>Retry to test your skills more or train in normal mode to explore more about the Solar System.") : qsTr("Great! You can replay the assessment to test your knowledge on more questions."))
+ text: qsTr("Your final score is: <font color=\"#3bb0de\">%1%</font>.<br><br>%2").arg(progressBar.value).arg(progressBar.value <= 90 ? qsTr("You should score above 90% to become a Solar System expert!<br>Retry to test your skills again or train in normal mode to explore more about the Solar System.") : qsTr("Great! You can replay the assessment to test your knowledge on more questions."))
}
// To prevent clicking on options under it
MouseArea {
anchors.fill: parent
}
onVisibleChanged: scaleAnimation.start()
NumberAnimation {
id: scaleAnimation
target: restartAssessmentMessage
properties: "scale"
from: 0
to: 1
duration: 1500
easing.type: Easing.OutBounce
}
}
Score {
id: score
anchors.bottom: undefined
anchors.right: parent.right
anchors.rightMargin: 10 * ApplicationInfo.ratio
anchors.top: parent.top
z: 0
}
}
diff --git a/src/activities/solar_system/SolarSystem.qml b/src/activities/solar_system/SolarSystem.qml
index 8237bc77b..4e4825ea9 100644
--- a/src/activities/solar_system/SolarSystem.qml
+++ b/src/activities/solar_system/SolarSystem.qml
@@ -1,337 +1,402 @@
/* GCompris - SolarSystem.qml
*
* Copyright (C) 2018 Aman Kumar Gupta <gupta2140@gmail.com>
*
* Authors:
* Aman Kumar Gupta <gupta2140@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "solar_system.js" as Activity
ActivityBase {
id: activity
onStart: {
focus = true;
}
onStop: {}
pageComponent: Rectangle {
id: background
anchors.fill: parent
- property bool horizontalLayout: background.width > background.height
+ property bool horizontalLayout: background.width >= background.height
Image {
id: stars
fillMode: Image.PreserveAspectCrop
source: "qrc:/gcompris/src/activities/solar_system/resource/background.svg"
width: horizontalLayout ? parent.width * 2.5 : parent.height * 2.5
height: stars.width
sourceSize.width: stars.width
sourceSize.height: stars.width
- x: horizontalLayout ? -stars.width * 0.48 : -stars.width * 0.5 + parent.width * 0.5
- y: horizontalLayout ? -stars.height * 0.5 + parent.height * 0.5 : -stars.height * 0.5 + parent.height * 0.9
+
transform: Rotation {
origin.x: stars.width / 2; origin.y: stars.height / 2; angle: 0;
NumberAnimation on angle{
loops: Animation.Infinite
from: 0
to: 360
duration: 108000
}
}
}
signal start
signal stop
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property alias background: background
property alias bar: bar
property alias bonus: bonus
property alias planetsModel: planetsModel
property alias mainQuizScreen: mainQuizScreen
property alias dialogActivityConfig: dialogActivityConfig
property bool assessmentMode: false
property bool solarSystemVisible: true
property bool quizScreenVisible: false
property string temperatureHint
property string lengthOfYearHint
}
onStart: {
dialogActivityConfig.getInitialConfiguration()
Activity.start(items)
}
onStop: Activity.stop()
IntroMessage {
id: message
anchors {
top: parent.top
topMargin: 10
right: parent.right
rightMargin: 5
left: parent.left
leftMargin: 5
}
z: 10
readonly property string commonInstruction: qsTr("Mode: <font color=\"#3bb0de\">%1</font><br><br>There are two modes in the activity which you can switch from the configuration window:<br><b>1. Normal mode</b> - In this mode you can play and learn about the Solar System.<br><b>2. Assessment mode</b> - In this mode you can test your knowledge about the Solar System.").arg(items.assessmentMode ? qsTr("Assessment") : qsTr("Normal"))
readonly property var normalModeInstructions: [
commonInstruction,
qsTr("Click on the Sun or any planet to reveal questions. Each question will have 4 options, out of which one is correct."),
qsTr("After a planet is clicked, the Closeness meter at the bottom-right corner of the screen represents the degree of correctness of your selected answer. The least correct answer is represented by 1%. Try again until you reach a 100% closeness by following the closeness meter, or hint which indicates the correct answer.")
]
readonly property var assessmentModeInstructions: [
commonInstruction,
qsTr("There are 20 questions initially with 4 options each. The progress bar at the bottom right of the screen shows your percentage score."),
qsTr("If your answer is correct, your score will increase.<br>If your answer is wrong, your score decreases and one more question will be asked in the end along with the incorrectly answered question.<br>Maximum 25 questions will be asked after which no more question will be added."),
qsTr("You should score above 90% to pass the assessment and become a Solar System expert!")
]
intro: items.assessmentMode ? assessmentModeInstructions : normalModeInstructions
onIntroChanged: index = 0
}
ListModel {
id: planetsModel
}
- readonly property int itemWidth: horizontalLayout ? background.width / 9 : (background.height - bar.height) / 9
+ readonly property int itemWidth: horizontalLayout ? background.width * 0.11 : (background.height - bar.height) * 0.11
// Arrangement of all the planets in the solar system
GridView {
id: planetView
- y: horizontalLayout ? (parent.height - bar.height) / 2 - cellHeight/2 : 0
- x: horizontalLayout ? 0 : parent.width / 2 - cellHeight / 2
layoutDirection: Qt.LeftToRight
verticalLayoutDirection: GridView.BottomToTop
- width: horizontalLayout ? parent.width : cellWidth
- height: horizontalLayout ? cellHeight : parent.height - bar.height
clip: false
interactive: false
visible: items.solarSystemVisible
cellWidth: background.itemWidth
cellHeight: cellWidth
model: planetsModel
delegate: PlanetInSolarModel {
planetImageSource: realImg
planetName: bodyName
+ planetSize: bodySize
}
}
+ states: [
+ State {
+ name: "hGrid"
+ when: background.horizontalLayout
+ AnchorChanges {
+ target: planetView
+ anchors.horizontalCenter: background.horizontalCenter
+ anchors.verticalCenter: background.verticalCenter
+ anchors.top: undefined
+ }
+ PropertyChanges {
+ target: planetView
+ width: background.width
+ height: cellHeight
+
+ }
+ PropertyChanges {
+ target: stars
+ x: -stars.width * 0.48
+ y: -stars.height * 0.5 + background.height * 0.5
+ }
+ },
+ State {
+ name: "vGrid"
+ when: !background.horizontalLayout
+ AnchorChanges {
+ target: planetView
+ anchors.horizontalCenter: background.horizontalCenter
+ anchors.verticalCenter: undefined
+ anchors.top: background.top
+ }
+ PropertyChanges {
+ target: planetView
+ width: cellWidth
+ height: background.height - bar.height * 1.5
+ }
+ PropertyChanges {
+ target: stars
+ x: -stars.width * 0.5 + background.width * 0.5
+ y: -stars.height * 0.5 + background.height * 0.9
+ }
+ }
+ ]
QuizScreen {
id: mainQuizScreen
visible: items.quizScreenVisible
}
Rectangle {
id: solarSystemImageHint
radius: 30
border.width: 5
border.color: "black"
width: parent.width
height: parent.height
visible: false
z: 2000
parent: items.assessmentMode ? background : hintDialog
onVisibleChanged: {
if(visible) {
hintCloseAnimation.stop()
hintAppearAnimation.start()
}
else {
solarSystemImageHint.x = 0
solarSystemImageHint.y = 0
}
}
Image {
id: solarSystemImage
- source: "qrc:/gcompris/src/activities/solar_system/resource/hint_solar_model.png"
- width: parent.width - 6 * ApplicationInfo.ratio
fillMode: Image.PreserveAspectCrop
- anchors.centerIn: parent
+ source: "qrc:/gcompris/src/activities/solar_system/resource/background.svg"
+ width: horizontalLayout ? parent.width * 2.5 : parent.height * 2.5
+ height: stars.width
+ sourceSize.width: stars.width
+ sourceSize.height: stars.width
+ x: horizontalLayout ? -stars.width * 0.48 : -stars.width * 0.5 + parent.width * 0.5
+ y: horizontalLayout ? -stars.height * 0.5 + parent.height * 0.5 : -stars.height * 0.5 + parent.height * 0.9
}
+ GridView {
+ id: planetViewHint
+ y: horizontalLayout ? (parent.height - bar.height) / 2 - cellHeight/2 : 0
+ x: horizontalLayout ? 0 : parent.width / 2 - cellHeight / 2
+ layoutDirection: Qt.LeftToRight
+ verticalLayoutDirection: GridView.BottomToTop
+ width: horizontalLayout ? parent.width : cellWidth
+ height: horizontalLayout ? cellHeight : parent.height - bar.height
+ clip: false
+ interactive: false
+ cellWidth: background.itemWidth
+ cellHeight: cellWidth
+ model: items.planetsModel
+
+ delegate: PlanetInSolarModel {
+ hintMode: true
+ planetImageSource: realImg
+ planetName: bodyName
+ planetSize: bodySize
+ }
+ }
+
NumberAnimation {
id: hintAppearAnimation
target: solarSystemImageHint
property: horizontalLayout ? "x" : "y"
from: horizontalLayout ? -width : -height
to: 0
duration: 1200
easing.type: Easing.OutBack
}
GCButtonCancel {
id: cancelButton
onClose: hintCloseAnimation.start()
}
SequentialAnimation {
id: hintCloseAnimation
NumberAnimation {
target: solarSystemImageHint
property: horizontalLayout ? "x" : "y"
to: horizontalLayout ? -width : -height
duration: 1200
easing.type: Easing.InSine
}
onStopped: solarSystemImageHint.visible = false
}
}
// Hint dialog while playing the quiz
DialogBackground {
id: hintDialog
visible: false
readonly property string hint1: qsTr("1. The <b>farther</b> a planet from the Sun, the <b>lower</b> is its temperature.<br><font color=\"#3bb0de\">%1</font>").arg(items.temperatureHint)
readonly property string hint2: qsTr("2. The duration of a year on a planet <b>increases as we go away from the Sun</b>.<br><font color=\"#3bb0de\">%1</font>").arg(items.lengthOfYearHint)
title: qsTr("Hint")
content: "%1<br>%2".arg(hint1).arg(hint2)
onClose: {
solarSystemImageHint.visible = false
home()
}
button0Text: qsTr("View solar system")
onButton0Hit: solarSystemImageHint.visible = true
}
DialogActivityConfig {
id: dialogActivityConfig
currentActivity: activity
content: Component {
Item {
width: dialogActivityConfig.width
height: dialogActivityConfig.height
property alias assessmentModeBox: assessmentModeBox
property bool initialCheckStatus
GCDialogCheckBox {
id: assessmentModeBox
width: dialogActivityConfig.width
text: qsTr("Assessment mode")
checked: items.assessmentMode
}
}
}
onLoadData: {
if(dataToSave && dataToSave["assessmentMode"])
items.assessmentMode = dataToSave["assessmentMode"] === "true" ? true : false
Activity.numberOfLevel = items.assessmentMode ? 1 : 2
}
onSaveData: {
if(!dialogActivityConfig.configItem) {
return
}
dialogActivityConfig.configItem.initialCheckStatus = items.assessmentMode
if(dialogActivityConfig.configItem.assessmentModeBox.checked != items.assessmentMode) {
items.assessmentMode = !items.assessmentMode
dataToSave["assessmentMode"] = items.assessmentMode ? "true" : "false"
Activity.numberOfLevel = items.assessmentMode ? 1 : 2
}
}
onClose: {
if(items.assessmentMode != dialogActivityConfig.configItem.initialCheckStatus) {
if(items.assessmentMode)
Activity.startAssessmentMode()
else {
Activity.showSolarModel()
}
}
home()
}
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: items.mainQuizScreen.restartAssessmentMessage.visible ? withConfigWithRestart :
items.solarSystemVisible ? withConfig :
items.assessmentMode ? withConfigWithHint :
Activity.indexOfSelectedPlanet == 0 ? withoutConfigWithoutHint :
withoutConfigWithHint
property BarEnumContent withConfig: BarEnumContent { value: help | home | config }
property BarEnumContent withoutConfigWithHint: BarEnumContent { value: help | home | level | hint }
property BarEnumContent withoutConfigWithoutHint: BarEnumContent { value: help | home | level }
property BarEnumContent withConfigWithRestart: BarEnumContent { value: help | home | config | reload }
property BarEnumContent withConfigWithHint: BarEnumContent { value: help | home | config | hint }
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: {
mainQuizScreen.closenessMeter.stopAnimations()
if(items.solarSystemVisible || items.assessmentMode)
activity.home()
else
Activity.showSolarModel()
}
onHintClicked: {
if(items.assessmentMode)
solarSystemImageHint.visible = true
else
displayDialog(hintDialog)
}
onConfigClicked: {
dialogActivityConfig.active = true
displayDialog(dialogActivityConfig)
}
onReloadClicked: Activity.startAssessmentMode()
}
Bonus {
id: bonus
Component.onCompleted: win.connect(Activity.nextLevel)
}
}
}
diff --git a/src/activities/solar_system/resource/background.svg b/src/activities/solar_system/resource/background.svg
index 8895e2209..4af2cd857 100644
--- a/src/activities/solar_system/resource/background.svg
+++ b/src/activities/solar_system/resource/background.svg
@@ -1,1250 +1,4719 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- inkscape:version="0.92.1 r15371"
- sodipodi:docname="background.svg"
- id="svg8"
- version="1.1"
- viewBox="0 0 285.74999 285.75002"
+ width="1080"
height="1080"
- width="1080">
+ viewBox="0 0 285.74999 285.75002"
+ version="1.1"
+ id="svg8"
+ sodipodi:docname="background.svg"
+ inkscape:version="0.92.1 r15371">
<sodipodi:namedview
- inkscape:current-layer="svg8"
- inkscape:window-maximized="1"
- inkscape:window-y="0"
- inkscape:window-x="0"
- inkscape:cy="587.69778"
- inkscape:cx="599.02784"
- inkscape:zoom="0.86000002"
- showgrid="false"
- id="namedview685"
- inkscape:window-height="1051"
- inkscape:window-width="1884"
- inkscape:pageshadow="2"
- inkscape:pageopacity="0"
- guidetolerance="10"
- gridtolerance="10"
- objecttolerance="10"
- borderopacity="1"
+ pagecolor="#ffffff"
bordercolor="#666666"
- pagecolor="#ffffff" />
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ id="namedview685"
+ showgrid="false"
+ inkscape:zoom="2.4324474"
+ inkscape:cx="652.46944"
+ inkscape:cy="511.73458"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="layer2" />
<defs
id="defs2" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- <dc:date>2017</dc:date>
+ <dc:title></dc:title>
+ <dc:date>2018</dc:date>
<dc:creator>
<cc:Agent>
<dc:title>Timothée Giet</dc:title>
</cc:Agent>
</dc:creator>
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Notice" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
- <rect
- style="opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.64583349;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
- id="rect931"
- width="285.75"
- height="285.75"
- x="0"
- y="4.999999e-06" />
- <circle
- style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#d6d6d6;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.26458335;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
- id="path5194"
- cx="280.49277"
- cy="38.075737"
- r="1.0186579" />
- <use
- style="stroke-width:0.66666657"
- id="use5570"
- inkscape:spray-origin="#path5194"
- xlink:href="#path5194"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-184.36902,14.379512)" />
- <use
- style="stroke-width:0.66666657"
- id="use5572"
- inkscape:spray-origin="#path5194"
- xlink:href="#path5194"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-42.339302,70.125621)" />
- <use
- style="stroke-width:0.66666657"
- id="use5586"
- inkscape:spray-origin="#path5194"
- xlink:href="#path5194"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-24.648355,209.03186)" />
- <use
- style="stroke-width:0.66666657"
- id="use5588"
- inkscape:spray-origin="#path5194"
- xlink:href="#path5194"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-53.793863,163.00021)" />
- <use
- style="stroke-width:0.66666657"
- id="use5590"
- inkscape:spray-origin="#path5194"
- xlink:href="#path5194"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-76.592441,166.75316)" />
- <use
- style="stroke-width:0.66666657"
- id="use5592"
- inkscape:spray-origin="#path5194"
- xlink:href="#path5194"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-250.32179,50.008135)" />
- <use
- style="stroke-width:0.66666657"
- id="use5594"
- inkscape:spray-origin="#path5194"
- xlink:href="#path5194"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-220.782,76.144619)" />
- <use
- style="stroke-width:0.66666657"
- id="use5596"
- inkscape:spray-origin="#path5194"
- xlink:href="#path5194"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-266.48486,31.00733)" />
- <use
- style="stroke-width:0.66666657"
- id="use5598"
- inkscape:spray-origin="#path5194"
- xlink:href="#path5194"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-251.52089,28.270884)" />
- <use
- style="stroke-width:0.66666657"
- id="use5600"
- inkscape:spray-origin="#path5194"
- xlink:href="#path5194"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-245.692,24.858505)" />
- <use
- style="stroke-width:0.66666657"
- id="use5604"
- inkscape:spray-origin="#path5194"
- xlink:href="#path5194"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-264.59341,74.292134)" />
- <use
- style="stroke-width:0.66666657"
- id="use5608"
- inkscape:spray-origin="#path5194"
- xlink:href="#path5194"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-261.80248,76.097428)" />
- <use
- style="stroke-width:0.66666657"
- id="use5610"
- inkscape:spray-origin="#path5194"
- xlink:href="#path5194"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-267.06965,-13.88682)" />
- <use
- style="stroke-width:0.66666657"
- id="use5618"
- inkscape:spray-origin="#path5194"
- xlink:href="#path5194"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-173.29908,0.4979964)" />
- <use
- style="stroke-width:0.66666657"
- id="use5620"
- inkscape:spray-origin="#path5194"
- xlink:href="#path5194"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-3.712039,-30.457127)" />
- <circle
- style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#d6d6d6;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.26458335;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
- id="path5194-3"
- cx="-245.78827"
- cy="-35.668034"
- transform="scale(-1)"
- r="0.5953126" />
- <use
- style="stroke-width:0.66666657"
- id="use5651"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-157.56904,27.031126)" />
- <use
- style="stroke-width:0.66666657"
- id="use5655"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-149.29546,12.588592)" />
- <use
- style="stroke-width:0.66666657"
- id="use5659"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-156.42845,22.298573)" />
- <use
- style="stroke-width:0.66666657"
- id="use5661"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-113.22206,9.0470197)" />
- <use
- style="stroke-width:0.66666657"
- id="use5665"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-105.67584,1.9096002)" />
- <use
- style="stroke-width:0.66666657"
- id="use5667"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-65.158208,-6.7015722)" />
- <use
- style="stroke-width:0.66666657"
- id="use5669"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(12.285481,-6.8626452)" />
- <use
- style="stroke-width:0.66666657"
- id="use5673"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(2.7172695,-9.5908192)" />
- <use
- style="stroke-width:0.66666657"
- id="use5691"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(36.4865,234.6402)" />
- <use
- style="stroke-width:0.66666657"
- id="use5693"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(13.859829,209.88521)" />
- <use
- style="stroke-width:0.66666657"
- id="use5695"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-9.6539412,132.80505)" />
- <use
- style="stroke-width:0.66666657"
- id="use5697"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-5.2823882,144.7338)" />
- <use
- style="stroke-width:0.66666657"
- id="use5699"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-38.124022,154.8128)" />
- <use
- style="stroke-width:0.66666657"
- id="use5701"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(21.621735,134.28832)" />
- <use
- style="stroke-width:0.66666657"
- id="use5703"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-11.408995,124.83134)" />
- <use
- style="stroke-width:0.66666657"
- id="use5705"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(30.887522,112.55865)" />
- <use
- style="stroke-width:0.66666657"
- id="use5709"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-10.033204,44.717297)" />
- <use
- style="stroke-width:0.66666657"
- id="use5711"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-27.587545,76.923713)" />
- <use
- style="stroke-width:0.66666657"
- id="use5713"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-34.722331,66.287669)" />
- <use
- style="stroke-width:0.66666657"
- id="use5715"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-54.578491,118.70052)" />
- <use
- style="stroke-width:0.66666657"
- id="use5717"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-68.42172,88.093449)" />
- <use
- style="stroke-width:0.66666657"
- id="use5719"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-49.321797,47.953404)" />
- <use
- style="stroke-width:0.66666657"
- id="use5721"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-67.345837,86.982601)" />
- <use
- style="stroke-width:0.66666657"
- id="use5723"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-14.973612,69.651136)" />
- <use
- style="stroke-width:0.66666657"
- id="use5725"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-15.957985,71.04917)" />
- <use
- style="stroke-width:0.66666657"
- id="use5727"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-46.343882,142.12381)" />
- <use
- style="stroke-width:0.66666657"
- id="use5729"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-17.778142,146.64303)" />
- <use
- style="stroke-width:0.66666657"
- id="use5731"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(1.1460965,153.05578)" />
- <use
- style="stroke-width:0.66666657"
- id="use5733"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-71.988414,176.2827)" />
- <use
- style="stroke-width:0.66666657"
- id="use5735"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-12.619238,144.53697)" />
- <use
- style="stroke-width:0.66666657"
- id="use5737"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-52.518824,157.7711)" />
- <use
- style="stroke-width:0.66666657"
- id="use5739"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-42.521552,163.11946)" />
- <use
- style="stroke-width:0.66666657"
- id="use5741"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-94.325284,209.6186)" />
- <use
- style="stroke-width:0.66666657"
- id="use5743"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-104.00009,171.00966)" />
- <use
- style="stroke-width:0.66666657"
- id="use5745"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-82.639845,153.11273)" />
- <use
- style="stroke-width:0.66666657"
- id="use5747"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-152.59132,157.29497)" />
- <use
- style="stroke-width:0.66666657"
- id="use5749"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-104.03007,181.32615)" />
- <use
- style="stroke-width:0.66666657"
- id="use5751"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-158.56189,177.74341)" />
- <use
- style="stroke-width:0.66666657"
- id="use5753"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-127.17454,222.94368)" />
- <use
- style="stroke-width:0.66666657"
- id="use5755"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-107.4452,204.55739)" />
- <use
- style="stroke-width:0.66666657"
- id="use5757"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-106.80825,230.44794)" />
- <use
- style="stroke-width:0.66666657"
- id="use5759"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-177.47887,205.92515)" />
- <use
- style="stroke-width:0.66666657"
- id="use5761"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-172.45047,221.3648)" />
- <use
- style="stroke-width:0.66666657"
- id="use5763"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-106.69754,191.67516)" />
<g
id="g4590" />
- <circle
- style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#d6d6d6;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.26458335;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
- id="path5194-4"
- cx="-51.383812"
- cy="-254.54085"
- r="1.0186579"
- transform="scale(-1)" />
- <use
- style="stroke-width:0.66666657"
- id="use5570-3"
- inkscape:spray-origin="#path5194"
- xlink:href="#path5194-4"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(184.36902,-14.37952)" />
- <use
- style="stroke-width:0.66666657"
- id="use5572-1"
- inkscape:spray-origin="#path5194"
- xlink:href="#path5194-4"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(42.3393,-70.12562)" />
- <use
- style="stroke-width:0.66666657"
- id="use5586-0"
- inkscape:spray-origin="#path5194"
- xlink:href="#path5194-4"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(24.64836,-209.03186)" />
- <use
- style="stroke-width:0.66666657"
- id="use5588-6"
- inkscape:spray-origin="#path5194"
- xlink:href="#path5194-4"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(53.79386,-163.0002)" />
- <use
- style="stroke-width:0.66666657"
- id="use5590-8"
- inkscape:spray-origin="#path5194"
- xlink:href="#path5194-4"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(76.59244,-166.75316)" />
- <use
- style="stroke-width:0.66666657"
- id="use5594-2"
- inkscape:spray-origin="#path5194"
- xlink:href="#path5194-4"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(220.782,-76.14462)" />
- <use
- style="stroke-width:0.66666657"
- id="use5618-7"
- inkscape:spray-origin="#path5194"
- xlink:href="#path5194-4"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(173.29908,-0.498)" />
- <use
- style="stroke-width:0.66666657"
- id="use5620-2"
- inkscape:spray-origin="#path5194"
- xlink:href="#path5194-4"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(3.71204,30.45712)" />
- <use
- style="stroke-width:0.66666657"
- id="use5624-2"
- inkscape:spray-origin="#path5194"
- xlink:href="#path5194-4"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-37.12218,13.58174)" />
- <use
- style="stroke-width:0.66666657"
- id="use5628-6"
- inkscape:spray-origin="#path5194"
- xlink:href="#path5194-4"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-24.1189,-30.6407)" />
- <circle
- style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#d6d6d6;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.26458335;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
- id="path5194-3-1"
- cx="86.08831"
- cy="256.94855"
- r="0.5953126" />
- <use
- style="stroke-width:0.66666657"
- id="use5651-5"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(157.56904,-27.03112)" />
- <use
- style="stroke-width:0.66666657"
- id="use5655-9"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(149.29546,-12.5886)" />
- <use
- style="stroke-width:0.66666657"
- id="use5659-4"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(156.42845,-22.29858)" />
- <use
- style="stroke-width:0.66666657"
- id="use5661-9"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(113.22206,-9.04702)" />
- <use
- style="stroke-width:0.66666657"
- id="use5665-0"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(105.67584,-1.9096)" />
- <use
- style="stroke-width:0.66666657"
- id="use5667-9"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(65.1582,6.70158)" />
- <use
- style="stroke-width:0.66666657"
- id="use5669-1"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-12.28548,6.86264)" />
- <use
- style="stroke-width:0.66666657"
- id="use5673-7"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-2.71726,9.59082)" />
- <use
- style="stroke-width:0.66666657"
- id="use5677-7"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-45.97284,-25.66372)" />
- <use
- style="stroke-width:0.66666657"
- id="use5691-6"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-36.4865,-234.6402)" />
- <use
- style="stroke-width:0.66666657"
- id="use5693-7"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-13.85982,-209.8852)" />
- <use
- style="stroke-width:0.66666657"
- id="use5695-3"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(9.65394,-132.80504)" />
- <use
- style="stroke-width:0.66666657"
- id="use5697-6"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(5.28238,-144.7338)" />
- <use
- style="stroke-width:0.66666657"
- id="use5699-5"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(38.12402,-154.8128)" />
- <use
- style="stroke-width:0.66666657"
- id="use5701-6"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-21.62174,-134.28832)" />
- <use
- style="stroke-width:0.66666657"
- id="use5703-3"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(11.409,-124.83134)" />
- <use
- style="stroke-width:0.66666657"
- id="use5705-9"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-30.88752,-112.55864)" />
- <use
- style="stroke-width:0.66666657"
- id="use5707-4"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-61.06228,-94.27746)" />
- <use
- style="stroke-width:0.66666657"
- id="use5709-8"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(10.0332,-44.7173)" />
- <use
- style="stroke-width:0.66666657"
- id="use5711-1"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(27.58754,-76.92372)" />
- <use
- style="stroke-width:0.66666657"
- id="use5713-2"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(34.72234,-66.28766)" />
- <use
- style="stroke-width:0.66666657"
- id="use5717-3"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(68.42172,-88.09344)" />
- <use
- style="stroke-width:0.66666657"
- id="use5719-9"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(49.3218,-47.9534)" />
- <use
- style="stroke-width:0.66666657"
- id="use5721-0"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(67.34584,-86.9826)" />
- <use
- style="stroke-width:0.66666657"
- id="use5723-8"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(14.97362,-69.65114)" />
- <use
- style="stroke-width:0.66666657"
- id="use5725-8"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(15.95798,-71.04916)" />
- <use
- style="stroke-width:0.66666657"
- id="use5727-5"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(46.34388,-142.1238)" />
- <use
- style="stroke-width:0.66666657"
- id="use5729-0"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(17.77814,-146.64302)" />
- <use
- style="stroke-width:0.66666657"
- id="use5731-9"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(-1.1461,-153.05578)" />
- <use
- style="stroke-width:0.66666657"
- id="use5733-6"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(71.98842,-176.2827)" />
- <use
- style="stroke-width:0.66666657"
- id="use5735-3"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(12.61924,-144.53696)" />
- <use
- style="stroke-width:0.66666657"
- id="use5737-8"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(52.51882,-157.7711)" />
- <use
- style="stroke-width:0.66666657"
- id="use5739-5"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(42.52156,-163.11946)" />
- <use
- style="stroke-width:0.66666657"
- id="use5741-6"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(94.32528,-209.6186)" />
- <use
- style="stroke-width:0.66666657"
- id="use5743-1"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(104.00008,-171.00966)" />
- <use
- style="stroke-width:0.66666657"
- id="use5745-1"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(82.63984,-153.11272)" />
- <use
- style="stroke-width:0.66666657"
- id="use5747-5"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(152.59132,-157.29496)" />
- <use
- style="stroke-width:0.66666657"
- id="use5749-9"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(104.03006,-181.32614)" />
- <use
- style="stroke-width:0.66666657"
- id="use5751-8"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(158.56189,-177.7434)" />
- <use
- style="stroke-width:0.66666657"
- id="use5753-4"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(127.17454,-222.94368)" />
- <use
- style="stroke-width:0.66666657"
- id="use5755-8"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(107.4452,-204.55738)" />
- <use
- style="stroke-width:0.66666657"
- id="use5757-1"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(106.80824,-230.44794)" />
- <use
- style="stroke-width:0.66666657"
- id="use5759-0"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(177.47887,-205.92514)" />
- <use
- style="stroke-width:0.66666657"
- id="use5761-3"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(172.45047,-221.3648)" />
- <use
- style="stroke-width:0.66666657"
- id="use5763-0"
- inkscape:spray-origin="#path5194-3"
- xlink:href="#path5194-3-1"
- x="0"
- y="0"
- width="100%"
- height="100%"
- transform="translate(106.69754,-191.67516)" />
+ <g
+ inkscape:label="Layer 1"
+ id="layer1"
+ inkscape:groupmode="layer"
+ sodipodi:insensitive="true">
+ <rect
+ y="2.7509037e-14"
+ x="0"
+ height="285.75"
+ width="285.75"
+ id="rect931"
+ style="opacity:1;vector-effect:none;fill:#000000;fill-opacity:1;stroke:none;stroke-width:2.64583349;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886" />
+ </g>
+ <g
+ inkscape:label="Layer 2"
+ id="layer2"
+ inkscape:groupmode="layer">
+ <circle
+ r="0.25312728"
+ cy="249.34361"
+ cx="80.75869"
+ id="path5194"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.37882553;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#f8ddbd;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.06574658;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ <use
+ transform="translate(73.753485,-235.10118)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194"
+ inkscape:spray-origin="#path5194"
+ id="use5570"
+ style="opacity:0.34737854;fill:#fae5d3;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-31.505791,-198.54799)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194"
+ inkscape:spray-origin="#path5194"
+ id="use5572"
+ style="opacity:0.2163673;fill:#f9e6ca;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-18.951514,-216.0058)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194"
+ inkscape:spray-origin="#path5194"
+ id="use5586"
+ style="opacity:0.21844201;fill:#fae5d3;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-40.908482,-89.435447)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194"
+ inkscape:spray-origin="#path5194"
+ id="use5588"
+ style="opacity:0.2860914;fill:#f9e3c6;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(118.02615,-10.503365)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194"
+ inkscape:spray-origin="#path5194"
+ id="use5590"
+ style="opacity:0.1163299;fill:#f7dcba;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(18.36774,-53.144275)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194"
+ inkscape:spray-origin="#path5194"
+ id="use5592"
+ style="opacity:0.35941683;fill:#f7d9b6;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(144.7366,14.576265)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194"
+ inkscape:spray-origin="#path5194"
+ id="use5594"
+ style="opacity:0.20896176;fill:#fbebde;fill-opacity:1;stroke-width:0.66666657;image-rendering:auto" />
+ <use
+ transform="translate(62.371487,-9.8317452)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194"
+ inkscape:spray-origin="#path5194"
+ id="use5596"
+ style="opacity:0.34067185;fill:#f8e6b9;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-14.998175,-98.024182)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194"
+ inkscape:spray-origin="#path5194"
+ id="use5598"
+ style="opacity:0.17423054;fill:#faedcd;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(149.30836,-147.84076)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194"
+ inkscape:spray-origin="#path5194"
+ id="use5600"
+ style="opacity:0.25922893;fill:#f8d7b1;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-65.739922,-55.142965)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194"
+ inkscape:spray-origin="#path5194"
+ id="use5604"
+ style="opacity:0.12921274;fill:#fbe7d0;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-34.949043,-48.858595)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194"
+ inkscape:spray-origin="#path5194"
+ id="use5608"
+ style="opacity:0.10575651;fill:#fbeed6;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(46.839228,-146.53232)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194"
+ inkscape:spray-origin="#path5194"
+ id="use5610"
+ style="opacity:0.33048634;fill:#fbeeda;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(190.68996,-161.30717)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194"
+ inkscape:spray-origin="#path5194"
+ id="use5618"
+ style="opacity:0.38239638;fill:#fbe9d0;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(58.334767,-99.118783)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194"
+ inkscape:spray-origin="#path5194"
+ id="use5620"
+ style="opacity:0.34486658;fill:#f8e6bb;fill-opacity:1;stroke-width:0.66666657" />
+ <circle
+ transform="scale(-1)"
+ r="0.1479298"
+ cy="-273.15582"
+ cx="-9.7274399"
+ id="path5194-3"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.30502954;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#f7dbb6;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.06574658;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ <use
+ transform="translate(182.59039,-204.1717)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5651"
+ style="opacity:0.10923959;fill:#f7deb6;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(28.112741,-212.25741)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5655"
+ style="opacity:0.27390873;fill:#f8e6bb;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(141.29438,-242.1348)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5659"
+ style="opacity:0.36945825;fill:#fae7d1;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(93.27051,-205.78546)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5661"
+ style="opacity:0.32420355;fill:#f8d7bd;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(28.529455,-240.21833)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5665"
+ style="opacity:0.09485444;fill:#fae8d1;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(97.75322,-192.22959)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5667"
+ style="opacity:0.19350682;fill:#fbeeda;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(96.961922,-37.318977)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5669"
+ style="opacity:0.2194604;fill:#fbecd0;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(106.54166,-89.147797)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5673"
+ style="opacity:0.26716739;fill:#f8e7bd;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(20.931287,-224.57232)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5691"
+ style="opacity:0.34555347;fill:#fae9d7;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(50.511409,-209.27941)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5693"
+ style="opacity:0.23542349;fill:#f6e2b5;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(127.01631,-142.57299)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5695"
+ style="opacity:0.24349706;fill:#f9d8ba;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(56.073984,-19.820077)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5697"
+ style="opacity:0.18551414;fill:#faecd1;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-4.0255425,-103.91758)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5699"
+ style="opacity:0.35154856;fill:#f9d7b8;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(92.635409,-261.85353)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5701"
+ style="opacity:0.24899657;fill:#f7e5b4;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(163.101,-202.33271)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5703"
+ style="opacity:0.39109569;fill:#f7d2b4;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(4.3046975,-17.511277)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5705"
+ style="opacity:0.27577443;fill:#f8dab7;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(233.37744,-190.8946)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5709"
+ style="opacity:0.2855902;fill:#fae7cf;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(88.350613,-226.96484)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5711"
+ style="opacity:0.37664681;fill:#fbe8d2;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(199.64298,-126.44013)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5713"
+ style="opacity:0.37406963;fill:#faead9;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(266.56086,-239.98365)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5715"
+ style="opacity:0.15749326;fill:#f7deb4;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(125.34134,-100.74394)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5717"
+ style="opacity:0.12360481;fill:#fbeede;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(218.58666,-203.8316)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5719"
+ style="opacity:0.33607447;fill:#fae6cd;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(5.7254975,-63.994977)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5721"
+ style="opacity:0.29799344;fill:#fae5c9;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(162.51204,-226.87001)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5723"
+ style="opacity:0.2122616;fill:#f8d1b1;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(247.03947,-253.59739)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5725"
+ style="opacity:0.1554639;fill:#f9e4c6;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(15.867807,-27.490987)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5727"
+ style="opacity:0.09227702;fill:#fae9d3;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(174.645,5.0645633)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5729"
+ style="opacity:0.37342236;fill:#f9d5b8;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(133.84555,-80.413387)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5731"
+ style="opacity:0.21767841;fill:#fbefdc;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(246.89221,-229.74221)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5733"
+ style="opacity:0.24955127;fill:#fbead8;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(127.24828,-211.64817)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5735"
+ style="opacity:0.29087441;fill:#fae4d3;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(181.8506,-32.631947)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5737"
+ style="opacity:0.35162784;fill:#f8e7c1;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(60.963009,-14.071997)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5739"
+ style="opacity:0.35031218;fill:#fae9d5;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(150.0218,-240.34389)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5741"
+ style="opacity:0.11176423;fill:#f9e4cc;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(31.823448,-138.59981)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5743"
+ style="opacity:0.2098327;fill:#f9e6c2;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(236.28029,-86.638527)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5745"
+ style="opacity:0.21802703;fill:#fae7d5;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(19.081317,-207.97587)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5747"
+ style="opacity:0.16708649;fill:#f9eaca;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(199.66073,-171.20713)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5749"
+ style="opacity:0.31327545;fill:#fbf3de;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(216.02735,-62.122137)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5751"
+ style="opacity:0.15563067;fill:#f7d6b2;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(248.90594,-201.1423)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5753"
+ style="opacity:0.20818063;fill:#f8dab7;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(31.72583,-13.791987)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5755"
+ style="opacity:0.3700029;fill:#f8d9bd;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(247.37913,-204.72312)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5757"
+ style="opacity:0.11860681;fill:#f8ddbf;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(91.902103,-97.716109)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5759"
+ style="opacity:0.25909573;fill:#f8e5c1;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(26.091699,-205.98804)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5761"
+ style="opacity:0.36942061;fill:#fbe8d6;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(70.998984,-41.105547)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3"
+ inkscape:spray-origin="#path5194-3"
+ id="use5763"
+ style="opacity:0.30347302;fill:#f7d7ba;fill-opacity:1;stroke-width:0.66666657" />
+ <circle
+ transform="scale(-1)"
+ r="0.25312728"
+ cy="-15.791413"
+ cx="-173.15376"
+ id="path5194-4"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.23884433;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#faeed3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.06574658;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ <use
+ transform="translate(-12.892016,183.90957)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-4"
+ inkscape:spray-origin="#path5194"
+ id="use5570-3"
+ style="opacity:0.3389503;fill:#f9e1ca;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-125.49601,107.64683)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-4"
+ inkscape:spray-origin="#path5194"
+ id="use5572-1"
+ style="opacity:0.22675039;fill:#fbebdc;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-157.39791,52.66529)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-4"
+ inkscape:spray-origin="#path5194"
+ id="use5586-0"
+ style="opacity:0.22325529;fill:#f9e6c6;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(64.058942,73.474455)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-4"
+ inkscape:spray-origin="#path5194"
+ id="use5588-6"
+ style="opacity:0.35207621;fill:#fae6cf;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-106.96269,186.46164)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-4"
+ inkscape:spray-origin="#path5194"
+ id="use5590-8"
+ style="opacity:0.32048609;fill:#f9ebca;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-101.06551,174.85169)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-4"
+ inkscape:spray-origin="#path5194"
+ id="use5594-2"
+ style="opacity:0.24935698;fill:#fbecd6;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-124.56638,239.42714)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-4"
+ inkscape:spray-origin="#path5194"
+ id="use5618-7"
+ style="opacity:0.27712935;fill:#fbf0d6;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-145.94852,84.240139)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-4"
+ inkscape:spray-origin="#path5194"
+ id="use5620-2"
+ style="opacity:0.3508652;fill:#faead7;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(31.428832,152.24033)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-4"
+ inkscape:spray-origin="#path5194"
+ id="use5624-2"
+ style="opacity:0.38755314;fill:#f9e6ce;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-91.197781,202.10912)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-4"
+ inkscape:spray-origin="#path5194"
+ id="use5628-6"
+ style="opacity:0.19130399;fill:#fbeada;fill-opacity:1;stroke-width:0.66666657" />
+ <circle
+ r="0.1479298"
+ cy="96.067619"
+ cx="160.88298"
+ id="path5194-3-1"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.31897356;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#f9e3c4;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.06574658;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ <use
+ transform="translate(-60.946867,179.40875)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5651-5"
+ style="opacity:0.18001392;fill:#fbedda;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-142.02755,3.090068)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5655-9"
+ style="opacity:0.21193734;fill:#fae9d1;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-107.84391,-6.720733)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5659-4"
+ style="opacity:0.22169722;fill:#fbedd6;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-121.99599,-39.440348)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5661-9"
+ style="opacity:0.2191703;fill:#faebd1;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(107.52977,-1.71762)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5665-0"
+ style="opacity:0.13866727;fill:#f7d9b2;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(83.012712,105.88898)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5667-9"
+ style="opacity:0.08427776;fill:#f9dec6;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(0.35959465,150.34697)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5669-1"
+ style="opacity:0.26808202;fill:#fae8cf;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-32.78589,124.06327)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5673-7"
+ style="opacity:0.2804146;fill:#fbebdc;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(74.234622,-12.968449)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5677-7"
+ style="opacity:0.26791029;fill:#f9e8ca;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(92.038112,-66.71707)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5691-6"
+ style="opacity:0.25806227;fill:#f8ddb7;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-13.647035,80.336086)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5693-7"
+ style="opacity:0.38200319;fill:#f8e5bd;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-138.08273,9.209386)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5695-3"
+ style="opacity:0.29042897;fill:#f9e6c8;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-138.29512,-56.185838)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5697-6"
+ style="opacity:0.08609158;fill:#f9e2c6;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(82.152402,-60.62896)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5699-5"
+ style="opacity:0.15146604;fill:#fae5d3;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-5.5303013,-84.89374)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5701-6"
+ style="opacity:0.38620851;fill:#fbf1d8;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(21.060608,-65.50837)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5703-3"
+ style="opacity:0.28061775;fill:#faebcf;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-48.542945,150.39458)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5705-9"
+ style="opacity:0.29215878;fill:#f8d7b7;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-63.328918,-66.33936)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5707-4"
+ style="opacity:0.14132666;fill:#f9e9c2;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-50.066227,-38.941172)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5709-8"
+ style="opacity:0.23284493;fill:#fae7cf;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-94.892809,7.682733)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5711-1"
+ style="opacity:0.29652943;fill:#f7d7b4;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(64.169892,124.11098)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5713-2"
+ style="opacity:0.0997327;fill:#f9ebca;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-134.63022,15.290422)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5717-3"
+ style="opacity:0.14362368;fill:#fae4cf;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-107.44732,-0.75659802)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5719-9"
+ style="opacity:0.2375727;fill:#f9e7cc;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(16.264656,46.544497)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5721-0"
+ style="opacity:0.31532204;fill:#f8e7b9;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-33.793495,50.354664)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5723-8"
+ style="opacity:0.16239678;fill:#fbebd2;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-7.2703133,6.833616)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5725-8"
+ style="opacity:0.38412924;fill:#f7dbb4;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-17.482791,110.39646)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5727-5"
+ style="opacity:0.28565363;fill:#faddc5;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-102.53359,24.93811)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5729-0"
+ style="opacity:0.08405385;fill:#f9d9bc;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(14.417684,165.09815)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5731-9"
+ style="opacity:0.29316287;fill:#faeacd;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-21.312874,182.28092)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5733-6"
+ style="opacity:0.18351411;fill:#f7e0b4;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-17.115598,113.66005)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5735-3"
+ style="opacity:0.16418224;fill:#f8d6b1;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(67.407462,47.943189)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5737-8"
+ style="opacity:0.18169867;fill:#f9e2cc;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(80.272742,-67.66415)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5739-5"
+ style="opacity:0.35956726;fill:#f8e4b9;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-118.06778,174.35311)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5741-6"
+ style="opacity:0.38857206;fill:#f8d3b5;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-71.813972,-91.113)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5743-1"
+ style="opacity:0.24204873;fill:#f8debf;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(88.407692,-63.7581)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5745-1"
+ style="opacity:0.27657393;fill:#f7d6b8;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(17.797564,135.89181)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5747-5"
+ style="opacity:0.15578984;fill:#f6d7b5;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(20.680883,-47.132675)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5749-9"
+ style="opacity:0.34398876;fill:#fbf0d6;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-62.793917,88.018846)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5751-8"
+ style="opacity:0.29799727;fill:#f9e3ca;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(8.6792537,120.9687)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5753-4"
+ style="opacity:0.18539979;fill:#fbecd4;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(75.373572,134.79958)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5755-8"
+ style="opacity:0.26514534;fill:#fae3d1;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-125.86054,109.39803)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5757-1"
+ style="opacity:0.11811745;fill:#fcebdd;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-113.80822,27.318489)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5759-0"
+ style="opacity:0.15232023;fill:#f8e1bf;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-52.111665,77.745017)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5761-3"
+ style="opacity:0.3282567;fill:#f9dcc2;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(28.536449,-13.51654)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1"
+ inkscape:spray-origin="#path5194-3"
+ id="use5763-0"
+ style="opacity:0.25946811;fill:#f9dbc0;fill-opacity:1;stroke-width:0.66666657" />
+ <circle
+ r="0.25312728"
+ cy="-234.94048"
+ cx="-169.68172"
+ id="path5194-6"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.40152947;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#f7d4b2;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.06574658;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ transform="scale(-1)" />
+ <use
+ transform="translate(34.590753,-75.247883)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-6"
+ inkscape:spray-origin="#path5194"
+ id="use5570-7"
+ style="opacity:0.15950473;fill:#f9e0bc;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-33.381416,38.203297)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-6"
+ inkscape:spray-origin="#path5194"
+ id="use5572-5"
+ style="opacity:0.17732843;fill:#f9ddc6;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-87.331081,-161.37138)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-6"
+ inkscape:spray-origin="#path5194"
+ id="use5586-3"
+ style="opacity:0.30685365;fill:#f7e2ba;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-60.831062,-132.47258)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-6"
+ inkscape:spray-origin="#path5194"
+ id="use5588-5"
+ style="opacity:0.1140981;fill:#faebcf;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-125.80311,-190.34498)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-6"
+ inkscape:spray-origin="#path5194"
+ id="use5590-6"
+ style="opacity:0.21713873;fill:#f8dbbf;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-19.705784,-109.62163)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-6"
+ inkscape:spray-origin="#path5194"
+ id="use5592-2"
+ style="opacity:0.20464448;fill:#fbedd6;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-13.778828,-63.72692)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-6"
+ inkscape:spray-origin="#path5194"
+ id="use5594-9"
+ style="opacity:0.27012814;fill:#fbe7d6;fill-opacity:1;stroke-width:0.66666657;image-rendering:auto" />
+ <use
+ transform="translate(-88.212742,-208.80353)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-6"
+ inkscape:spray-origin="#path5194"
+ id="use5596-1"
+ style="opacity:0.32416675;fill:#f7d8bc;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-24.956125,-105.76829)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-6"
+ inkscape:spray-origin="#path5194"
+ id="use5598-2"
+ style="opacity:0.45679351;fill:#f8dcc3;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-117.42305,25.127576)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-6"
+ inkscape:spray-origin="#path5194"
+ id="use5600-7"
+ style="opacity:0.38709801;fill:#f9dabc;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-10.503943,-36.715019)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-6"
+ inkscape:spray-origin="#path5194"
+ id="use5604-0"
+ style="opacity:0.32712301;fill:#f9dbc0;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-69.922076,-15.425538)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-6"
+ inkscape:spray-origin="#path5194"
+ id="use5608-9"
+ style="opacity:0.42997431;fill:#fbe9da;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-1.098173,-120.2385)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-6"
+ inkscape:spray-origin="#path5194"
+ id="use5610-3"
+ style="opacity:0.3303471;fill:#fbe8d8;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(71.875121,-156.46046)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-6"
+ inkscape:spray-origin="#path5194"
+ id="use5618-6"
+ style="opacity:0.44419783;fill:#f8dfbf;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-51.811776,-9.6523335)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-6"
+ inkscape:spray-origin="#path5194"
+ id="use5620-0"
+ style="opacity:0.34411029;fill:#fae1c9;fill-opacity:1;stroke-width:0.66666657" />
+ <circle
+ r="0.1479298"
+ cy="244.43372"
+ cx="31.440466"
+ id="path5194-3-6"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.16155874;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#fae2cf;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.06574658;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ <use
+ transform="translate(49.842002,-228.03646)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5651-2"
+ style="opacity:0.35058899;fill:#f8e0b7;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(83.289804,-69.598764)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5655-6"
+ style="opacity:0.14766535;fill:#f9e7c8;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(15.904832,-198.30952)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5659-1"
+ style="opacity:0.18419554;fill:#f8ddbb;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(93.572164,-95.030129)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5661-8"
+ style="opacity:0.34176043;fill:#f9e0c0;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(175.93366,-82.884548)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5665-7"
+ style="opacity:0.45861033;fill:#f9e0ca;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(75.255849,-36.720151)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5667-92"
+ style="opacity:0.11718642;fill:#faeed3;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(222.46525,-15.839213)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5669-0"
+ style="opacity:0.20870176;fill:#fbecda;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(69.431678,-204.82421)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5673-2"
+ style="opacity:0.17447264;fill:#f9e4c0;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(0.00878162,-216.32775)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5691-3"
+ style="opacity:0.45480239;fill:#f9e4c2;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(150.49195,-187.69345)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5693-75"
+ style="opacity:0.3559462;fill:#f7d7b8;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-17.287288,-219.3005)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5695-9"
+ style="opacity:0.22754762;fill:#f7e3b2;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(140.25145,-36.808519)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5697-2"
+ style="opacity:0.20226309;fill:#fbf1de;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(135.28694,-235.01998)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5699-2"
+ style="opacity:0.14754507;fill:#f8dabd;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(201.60054,-236.5589)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5701-8"
+ style="opacity:0.46274025;fill:#f9e9ca;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-6.5918684,-218.10297)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5703-9"
+ style="opacity:0.37956405;fill:#fceedd;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(132.69156,-201.75535)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5705-7"
+ style="opacity:0.41557886;fill:#f9dabc;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(122.33168,-208.80831)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5709-3"
+ style="opacity:0.28055994;fill:#f9e5c0;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(246.76719,-119.00663)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5711-6"
+ style="opacity:0.11201938;fill:#f7ddb4;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(178.74943,-36.565678)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5713-1"
+ style="opacity:0.32658907;fill:#f8d8b5;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(126.41108,-94.599604)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5715-2"
+ style="opacity:0.25440913;fill:#fbeada;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(147.7145,30.00909)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5717-9"
+ style="opacity:0.23606454;fill:#f9e2ca;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(182.68104,-239.92046)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5719-3"
+ style="opacity:0.17671539;fill:#f9dec6;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(51.834891,-208.27495)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5721-1"
+ style="opacity:0.40776547;fill:#fae0c7;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(5.9448016,-193.36667)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5723-9"
+ style="opacity:0.18377141;fill:#f8debd;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(145.18889,24.587483)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5725-4"
+ style="opacity:0.23516894;fill:#fbedd2;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(82.465469,-125.26469)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5727-7"
+ style="opacity:0.11561022;fill:#f7dab8;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(114.74518,-106.85158)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5729-8"
+ style="opacity:0.22803405;fill:#fae5d1;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(144.05326,-48.48075)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5731-4"
+ style="opacity:0.28497883;fill:#f9edce;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(25.683801,-18.452687)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5733-5"
+ style="opacity:0.38718154;fill:#f7e1b6;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(219.09358,-135.72975)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5735-0"
+ style="opacity:0.34509732;fill:#f9e5ce;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(115.61202,-111.59629)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5737-3"
+ style="opacity:0.20517381;fill:#f8eac3;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(172.73345,-206.24816)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5739-6"
+ style="opacity:0.12408788;fill:#fae1c7;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(34.361227,-207.8513)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5741-1"
+ style="opacity:0.33758036;fill:#fbf3dc;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(46.314236,-91.547406)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5743-0"
+ style="opacity:0.39320768;fill:#fbeed8;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(149.91301,-8.1534231)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5745-6"
+ style="opacity:0.15570786;fill:#f9dec4;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(181.17971,-49.974434)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5747-3"
+ style="opacity:0.09475463;fill:#fbe9d6;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(135.88842,-224.57686)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5749-2"
+ style="opacity:0.33540458;fill:#fbe9d8;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(217.63058,-28.461015)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5751-0"
+ style="opacity:0.24990707;fill:#faebc9;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(200.06231,-136.4552)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5753-6"
+ style="opacity:0.26755198;fill:#fbefde;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(27.811525,-119.45149)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5755-1"
+ style="opacity:0.13445512;fill:#f8debd;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(83.691915,-144.49659)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5757-5"
+ style="opacity:0.16362125;fill:#f8ddb7;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-5.3078784,-209.16202)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5759-5"
+ style="opacity:0.17024967;fill:#fbeedc;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(133.66484,-163.75413)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5761-4"
+ style="opacity:0.28822416;fill:#f8e6bb;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(223.49256,-189.47282)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6"
+ inkscape:spray-origin="#path5194-3"
+ id="use5763-7"
+ style="opacity:0.3141218;fill:#f9e9c0;fill-opacity:1;stroke-width:0.66666657" />
+ <circle
+ r="0.25312728"
+ cy="167.88055"
+ cx="235.86465"
+ id="path5194-4-6"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.47193699;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#fbf1d8;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.06574658;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ <use
+ transform="translate(-54.017643,102.12629)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-4-6"
+ inkscape:spray-origin="#path5194"
+ id="use5570-3-5"
+ style="opacity:0.34689164;fill:#f7dab4;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-53.445242,36.646723)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-4-6"
+ inkscape:spray-origin="#path5194"
+ id="use5572-1-6"
+ style="opacity:0.37107981;fill:#fae4c5;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-11.456465,91.973832)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-4-6"
+ inkscape:spray-origin="#path5194"
+ id="use5586-0-9"
+ style="opacity:0.19326465;fill:#f7e2b8;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-53.973405,104.53393)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-4-6"
+ inkscape:spray-origin="#path5194"
+ id="use5588-6-3"
+ style="opacity:0.37584552;fill:#fbefd6;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-41.366799,-126.83928)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-4-6"
+ inkscape:spray-origin="#path5194"
+ id="use5590-8-7"
+ style="opacity:0.10650599;fill:#faecd5;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-2.4395375,-139.13187)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-4-6"
+ inkscape:spray-origin="#path5194"
+ id="use5594-2-4"
+ style="opacity:0.34622952;fill:#fbebd8;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-218.71315,79.589576)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-4-6"
+ inkscape:spray-origin="#path5194"
+ id="use5618-7-5"
+ style="opacity:0.43808612;fill:#faead5;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-79.674251,-42.265875)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-4-6"
+ inkscape:spray-origin="#path5194"
+ id="use5620-2-2"
+ style="opacity:0.45931247;fill:#f7e7ba;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-141.3452,-123.10367)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-4-6"
+ inkscape:spray-origin="#path5194"
+ id="use5624-2-5"
+ style="opacity:0.29187119;fill:#fbf3de;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-43.362941,82.576772)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-4-6"
+ inkscape:spray-origin="#path5194"
+ id="use5628-6-4"
+ style="opacity:0.40407745;fill:#f8e3b1;fill-opacity:1;stroke-width:0.66666657" />
+ <circle
+ r="0.1479298"
+ cy="-73.099571"
+ cx="-240.34644"
+ id="path5194-3-1-7"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.27740903;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#faeccf;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.06574658;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ transform="scale(-1)" />
+ <use
+ transform="translate(-24.134015,202.56106)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5651-5-4"
+ style="opacity:0.09849441;fill:#faead1;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-133.1539,98.471821)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5655-9-4"
+ style="opacity:0.43412123;fill:#f6deb3;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-22.606149,190.55632)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5659-4-3"
+ style="opacity:0.30043718;fill:#f8dcbf;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(10.925717,147.48953)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5661-9-0"
+ style="opacity:0.3166325;fill:#fae7d7;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-54.348257,77.323034)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5665-0-7"
+ style="opacity:0.29930857;fill:#f9e6c6;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-57.938576,-53.171057)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5667-9-8"
+ style="opacity:0.26747514;fill:#f7d9be;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-143.29009,20.899391)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5669-1-6"
+ style="opacity:0.44730183;fill:#faf0d5;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-91.831913,25.342266)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5673-7-8"
+ style="opacity:0.11735008;fill:#f8e6bf;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-179.08435,156.72785)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5677-7-8"
+ style="opacity:0.12444159;fill:#f7e4b8;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(20.191683,91.403989)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5691-6-4"
+ style="opacity:0.27283146;fill:#f8e6b7;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-142.83556,96.614363)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5693-7-3"
+ style="opacity:0.17850234;fill:#f9dec8;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-11.428215,15.950598)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5695-3-1"
+ style="opacity:0.43440438;fill:#fae9cb;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-230.68237,5.1982161)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5697-6-4"
+ style="opacity:0.25443564;fill:#f8dbb9;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-227.25506,-42.558847)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5699-5-9"
+ style="opacity:0.45607509;fill:#f9e3c6;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(2.8464998,171.61194)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5701-6-2"
+ style="opacity:0.3002682;fill:#f7deb6;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-100.04391,-55.185227)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5703-3-0"
+ style="opacity:0.15587541;fill:#fbe8d2;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-76.052795,103.57261)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5705-9-6"
+ style="opacity:0.33783515;fill:#f8e1bf;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-113.8556,123.71803)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5707-4-8"
+ style="opacity:0.41550754;fill:#f8e4b9;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(26.894594,44.506321)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5709-8-9"
+ style="opacity:0.40654399;fill:#fae7cf;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-216.78379,119.82905)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5711-1-2"
+ style="opacity:0.17151184;fill:#fbebda;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-173.82573,61.049613)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5713-2-6"
+ style="opacity:0.34290975;fill:#faf0d5;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-61.573269,26.004584)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5717-3-6"
+ style="opacity:0.10002172;fill:#f9e1c8;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-6.5569942,107.2634)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5719-9-4"
+ style="opacity:0.37177256;fill:#f9e5c4;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-126.83398,78.006228)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5721-0-9"
+ style="opacity:0.22286132;fill:#f9e9ca;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-234.25911,145.51777)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5723-8-5"
+ style="opacity:0.20556736;fill:#f6d3b3;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-44.731793,186.09067)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5725-8-0"
+ style="opacity:0.22347753;fill:#f7e3b8;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(40.744931,-53.300907)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5727-5-4"
+ style="opacity:0.45382056;fill:#f8e0c3;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-172.40618,200.23126)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5729-0-8"
+ style="opacity:0.42608098;fill:#fcf2db;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-119.33693,43.085275)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5731-9-7"
+ style="opacity:0.39113225;fill:#f8e6c3;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-31.823349,-63.626087)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5733-6-1"
+ style="opacity:0.44527049;fill:#faeccf;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-19.893713,145.91477)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5735-3-7"
+ style="opacity:0.46135332;fill:#faefd1;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-140.65002,150.52865)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5737-8-2"
+ style="opacity:0.45352658;fill:#faead3;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-233.79907,-35.559267)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5739-5-7"
+ style="opacity:0.28864722;fill:#faedd1;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(16.71047,-64.836367)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5741-6-2"
+ style="opacity:0.35075636;fill:#fae6cb;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-194.47128,-35.799347)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5743-1-2"
+ style="opacity:0.10159188;fill:#f7e0b4;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-223.75546,58.97719)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5745-1-6"
+ style="opacity:0.23191899;fill:#f7e2b4;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(6.6907918,-25.727387)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5747-5-1"
+ style="opacity:0.38868378;fill:#faebd1;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-141.17938,190.60446)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5749-9-0"
+ style="opacity:0.36886393;fill:#fbeedc;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(34.70308,16.583617)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5751-8-6"
+ style="opacity:0.33468191;fill:#f9ecc8;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-31.727971,106.29743)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5753-4-1"
+ style="opacity:0.45519451;fill:#fae1cd;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-70.199707,-5.1656839)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5755-8-5"
+ style="opacity:0.44989744;fill:#f8e2bf;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-41.699593,-68.784557)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5757-1-9"
+ style="opacity:0.44653201;fill:#f8ddbb;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-67.169984,147.10597)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5759-0-4"
+ style="opacity:0.21319245;fill:#f8e1b1;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-174.1182,110.75656)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5761-3-9"
+ style="opacity:0.4163959;fill:#fcebdd;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-184.52653,24.713228)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7"
+ inkscape:spray-origin="#path5194-3"
+ id="use5763-0-0"
+ style="opacity:0.27020844;fill:#f8e2b7;fill-opacity:1;stroke-width:0.66666657" />
+ <circle
+ r="0.25312728"
+ cy="265.35706"
+ cx="264.64709"
+ id="path5194-1"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.08015609;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#f8d5b3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.06574658;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ <use
+ transform="translate(-124.80271,-27.899577)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-1"
+ inkscape:spray-origin="#path5194"
+ id="use5570-77"
+ style="opacity:0.07507019;fill:#fbf0d8;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-129.1893,-88.530975)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-1"
+ inkscape:spray-origin="#path5194"
+ id="use5572-11"
+ style="opacity:0.29440134;fill:#f8d2b3;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-9.9619644,-29.398244)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-1"
+ inkscape:spray-origin="#path5194"
+ id="use5586-5"
+ style="opacity:0.15655494;fill:#fae9c7;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-246.38395,-33.003737)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-1"
+ inkscape:spray-origin="#path5194"
+ id="use5588-9"
+ style="opacity:0.25387621;fill:#faf1d7;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-181.7964,-37.795742)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-1"
+ inkscape:spray-origin="#path5194"
+ id="use5590-7"
+ style="opacity:0.07079312;fill:#fbefd4;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-43.950569,-109.94839)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-1"
+ inkscape:spray-origin="#path5194"
+ id="use5592-7"
+ style="opacity:0.211317;fill:#f8d5b9;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-177.58601,-180.1109)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-1"
+ inkscape:spray-origin="#path5194"
+ id="use5594-6"
+ style="opacity:0.0863316;fill:#f9e2ce;fill-opacity:1;stroke-width:0.66666657;image-rendering:auto" />
+ <use
+ transform="translate(-98.065872,-88.417728)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-1"
+ inkscape:spray-origin="#path5194"
+ id="use5596-7"
+ style="opacity:0.30857263;fill:#f6e2b3;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-20.367574,-113.86828)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-1"
+ inkscape:spray-origin="#path5194"
+ id="use5598-3"
+ style="opacity:0.22730491;fill:#fae2cd;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-37.658558,-159.83626)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-1"
+ inkscape:spray-origin="#path5194"
+ id="use5600-6"
+ style="opacity:0.22131647;fill:#f9dcc0;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-75.92828,-84.98691)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-1"
+ inkscape:spray-origin="#path5194"
+ id="use5604-5"
+ style="opacity:0.14236115;fill:#faecd7;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-35.615067,-3.2967124)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-1"
+ inkscape:spray-origin="#path5194"
+ id="use5608-6"
+ style="opacity:0.20771371;fill:#f9e3c6;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-9.1807344,-205.60505)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-1"
+ inkscape:spray-origin="#path5194"
+ id="use5610-39"
+ style="opacity:0.19363559;fill:#fbedd8;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-214.76505,-184.27294)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-1"
+ inkscape:spray-origin="#path5194"
+ id="use5618-4"
+ style="opacity:0.18251881;fill:#fae4cb;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-174.30589,-195.23516)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-1"
+ inkscape:spray-origin="#path5194"
+ id="use5620-8"
+ style="opacity:0.08325854;fill:#fbeeda;fill-opacity:1;stroke-width:0.66666657" />
+ <circle
+ transform="scale(-1)"
+ r="0.1479298"
+ cy="-70.141876"
+ cx="-186.26796"
+ id="path5194-3-12"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.1081443;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#f8dab3;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.06574658;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ <use
+ transform="translate(-73.184941,78.803828)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5651-9"
+ style="opacity:0.28136549;fill:#f8e4b9;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-116.29482,-25.893743)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5655-3"
+ style="opacity:0.23385375;fill:#fbf0d4;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-16.798326,-45.898303)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5659-9"
+ style="opacity:0.17726889;fill:#fae6d3;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-145.97215,110.53046)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5661-0"
+ style="opacity:0.33516247;fill:#fceedd;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(71.029767,11.810949)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5665-8"
+ style="opacity:0.28160759;fill:#fbebda;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-93.126401,22.406231)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5667-8"
+ style="opacity:0.17934905;fill:#f9ebc4;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(34.666573,51.61249)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5669-5"
+ style="opacity:0.23877899;fill:#f8e8c1;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(49.509597,144.08602)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5673-0"
+ style="opacity:0.26488462;fill:#fbeada;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-4.5637453,76.723557)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5691-9"
+ style="opacity:0.13737159;fill:#fae1cb;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-24.780491,131.04802)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5693-6"
+ style="opacity:0.1477776;fill:#fae9d1;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-163.78139,57.017622)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5695-38"
+ style="opacity:0.19992197;fill:#fbecd8;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(4.8860177,51.277095)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5697-5"
+ style="opacity:0.32979371;fill:#f9dcc4;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-17.328404,5.4484102)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5699-6"
+ style="opacity:0.34010524;fill:#f9dcc2;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-169.10099,140.27296)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5701-1"
+ style="opacity:0.18159024;fill:#fbf0d4;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-30.019554,197.93088)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5703-1"
+ style="opacity:0.23960266;fill:#fbf1da;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-143.14343,61.523919)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5705-5"
+ style="opacity:0.08070631;fill:#f9dec8;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-25.110392,-22.248153)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5709-9"
+ style="opacity:0.11915415;fill:#fae8cf;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(17.571284,152.25673)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5711-8"
+ style="opacity:0.24354493;fill:#f7dcb6;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-52.687542,174.34157)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5713-4"
+ style="opacity:0.09688009;fill:#f8deb5;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(40.977532,58.41466)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5715-8"
+ style="opacity:0.34218373;fill:#f8dfbf;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-39.512551,-60.205323)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5717-1"
+ style="opacity:0.20607192;fill:#fae6d5;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(10.107018,99.089202)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5719-0"
+ style="opacity:0.20768989;fill:#faefd3;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(51.049397,-2.7063418)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5721-3"
+ style="opacity:0.15390469;fill:#faeacf;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-153.84026,-38.705833)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5723-0"
+ style="opacity:0.3065444;fill:#f7d7b8;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(13.462525,192.24649)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5725-44"
+ style="opacity:0.21492214;fill:#fbe9d8;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-6.6929813,-22.547223)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5727-4"
+ style="opacity:0.24965689;fill:#fae6d5;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-59.786917,-2.7167258)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5729-4"
+ style="opacity:0.26535579;fill:#fcf0db;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(78.172857,-20.056986)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5731-7"
+ style="opacity:0.08500755;fill:#f7d7b2;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-137.83255,183.54127)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5733-63"
+ style="opacity:0.29806824;fill:#faedcf;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-19.177105,19.491059)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5735-1"
+ style="opacity:0.15891604;fill:#fbf0d2;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-20.594096,94.152502)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5737-7"
+ style="opacity:0.26192184;fill:#f7e6b8;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(40.717655,2.9905472)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5739-59"
+ style="opacity:0.15258903;fill:#f7e3b4;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(9.3837997,153.70016)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5741-62"
+ style="opacity:0.07475424;fill:#faeed3;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-147.4449,-48.585463)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5743-17"
+ style="opacity:0.1513317;fill:#f8d4b1;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-40.858847,153.79187)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5745-8"
+ style="opacity:0.13639449;fill:#fae8d3;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(76.442247,112.41505)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5747-57"
+ style="opacity:0.11789485;fill:#faeed7;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-49.488142,157.51115)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5749-4"
+ style="opacity:0.23962205;fill:#f7dbb6;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-148.5333,-6.6329298)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5751-1"
+ style="opacity:0.23700705;fill:#f7e2b4;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-85.986366,120.5255)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5753-8"
+ style="opacity:0.32795225;fill:#f7d6b2;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(73.945247,54.311491)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5755-5"
+ style="opacity:0.12126273;fill:#fbeadc;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-173.01228,-41.266503)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5757-9"
+ style="opacity:0.24595205;fill:#fbf1da;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(44.11154,-18.464277)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5759-7"
+ style="opacity:0.333189;fill:#faeccf;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-128.72484,76.437459)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5761-5"
+ style="opacity:0.23551845;fill:#fae6d3;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-93.721355,-30.303483)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-12"
+ inkscape:spray-origin="#path5194-3"
+ id="use5763-3"
+ style="opacity:0.23842809;fill:#f9e6c0;fill-opacity:1;stroke-width:0.66666657" />
+ <circle
+ transform="scale(-1)"
+ r="0.25312728"
+ cy="-63.524544"
+ cx="-154.8483"
+ id="path5194-4-8"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.31767387;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#faecc7;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.06574658;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ <use
+ transform="translate(-57.860029,54.416646)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-4-8"
+ inkscape:spray-origin="#path5194"
+ id="use5570-3-8"
+ style="opacity:0.11063579;fill:#f9dfc4;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-68.050896,21.267207)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-4-8"
+ inkscape:spray-origin="#path5194"
+ id="use5572-1-3"
+ style="opacity:0.17487135;fill:#fbefdc;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(100.76253,171.3119)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-4-8"
+ inkscape:spray-origin="#path5194"
+ id="use5586-0-1"
+ style="opacity:0.19322073;fill:#f9e4c6;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-81.887966,34.109657)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-4-8"
+ inkscape:spray-origin="#path5194"
+ id="use5588-6-8"
+ style="opacity:0.29832267;fill:#faefcf;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-10.363486,8.6762574)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-4-8"
+ inkscape:spray-origin="#path5194"
+ id="use5590-8-9"
+ style="opacity:0.13140217;fill:#fbeede;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-27.392967,11.173767)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-4-8"
+ inkscape:spray-origin="#path5194"
+ id="use5594-2-6"
+ style="opacity:0.21644078;fill:#f8d9bd;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(94.176616,94.319039)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-4-8"
+ inkscape:spray-origin="#path5194"
+ id="use5618-7-4"
+ style="opacity:0.30873461;fill:#f7e0b4;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-71.762705,61.734919)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-4-8"
+ inkscape:spray-origin="#path5194"
+ id="use5620-2-3"
+ style="opacity:0.32380598;fill:#f7dab4;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(65.184216,79.858294)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-4-8"
+ inkscape:spray-origin="#path5194"
+ id="use5624-2-3"
+ style="opacity:0.19354266;fill:#fbead4;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(49.528416,48.309007)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-4-8"
+ inkscape:spray-origin="#path5194"
+ id="use5628-6-3"
+ style="opacity:0.11780485;fill:#f9dfc4;fill-opacity:1;stroke-width:0.66666657" />
+ <circle
+ r="0.1479298"
+ cy="153.43832"
+ cx="193.50865"
+ id="path5194-3-1-8"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.08652045;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#fbe9d2;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.06574658;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ <use
+ transform="translate(-10.553312,66.042051)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5651-5-6"
+ style="opacity:0.24966389;fill:#fceedb;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-135.66474,-109.49474)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5655-9-0"
+ style="opacity:0.2389424;fill:#f7e1b6;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-32.939467,-28.875081)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5659-4-4"
+ style="opacity:0.18344936;fill:#fcf2dd;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(65.857311,-129.1469)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5661-9-8"
+ style="opacity:0.31991368;fill:#faedd5;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-46.701205,-138.52056)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5665-0-8"
+ style="opacity:0.3154611;fill:#faeacb;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-79.445875,59.23379)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5667-9-89"
+ style="opacity:0.24326327;fill:#f9e7ca;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-152.63399,105.31337)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5669-1-7"
+ style="opacity:0.31576843;fill:#f9e8c8;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(78.944331,-81.208644)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5673-7-7"
+ style="opacity:0.14731709;fill:#faebcd;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-158.8044,-44.848473)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5677-7-6"
+ style="opacity:0.30101013;fill:#f9e8c2;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-132.06362,-81.618154)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5691-6-43"
+ style="opacity:0.17967763;fill:#fae7cd;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(66.241751,-93.383174)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5693-7-0"
+ style="opacity:0.0756155;fill:#fae2cb;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-129.81533,-40.901118)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5695-3-3"
+ style="opacity:0.32683171;fill:#f9dcbc;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-102.31706,-105.79546)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5697-6-0"
+ style="opacity:0.11648871;fill:#f7d2b4;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-172.60652,10.442458)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5699-5-92"
+ style="opacity:0.2559106;fill:#f9e5c2;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-160.04672,-149.07199)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5701-6-5"
+ style="opacity:0.28690245;fill:#f9dac0;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-134.35216,34.148991)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5703-3-4"
+ style="opacity:0.14594176;fill:#f8dfc1;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(34.241631,-45.759301)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5705-9-0"
+ style="opacity:0.32747109;fill:#f9eac8;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(35.866571,91.966172)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5707-4-5"
+ style="opacity:0.28055958;fill:#f9e8ca;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-121.02048,-34.156541)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5709-8-94"
+ style="opacity:0.24800116;fill:#fbf0dc;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-87.336758,119.72419)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5711-1-6"
+ style="opacity:0.18202652;fill:#fbedd8;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-145.54668,107.72671)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5713-2-9"
+ style="opacity:0.21777523;fill:#fbefd2;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-107.21652,-72.090314)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5717-3-2"
+ style="opacity:0.23078703;fill:#fae6cf;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-29.540328,126.13106)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5719-9-2"
+ style="opacity:0.33665299;fill:#f8debd;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(8.5109011,-13.042768)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5721-0-4"
+ style="opacity:0.1894414;fill:#f7e5ba;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-71.913884,103.19665)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5723-8-7"
+ style="opacity:0.23370595;fill:#f9d8be;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-121.30233,-62.016134)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5725-8-7"
+ style="opacity:0.3190541;fill:#faefd1;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(55.239331,-46.099953)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5727-5-5"
+ style="opacity:0.20732811;fill:#f9e9c2;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(82.680541,43.320611)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5729-0-4"
+ style="opacity:0.23948825;fill:#faecd1;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-0.8940599,6.0168561)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5731-9-8"
+ style="opacity:0.27675326;fill:#f8d5b9;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(57.481581,-85.211064)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5733-6-12"
+ style="opacity:0.2914108;fill:#fbeada;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(23.351141,31.067964)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5735-3-8"
+ style="opacity:0.10228577;fill:#f7d8b4;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-3.5855029,79.762949)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5737-8-9"
+ style="opacity:0.17642852;fill:#f9e3c0;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-11.078518,-134.6003)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5739-5-3"
+ style="opacity:0.3398012;fill:#f8e1c1;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-76.323462,-50.465264)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5741-6-6"
+ style="opacity:0.06983684;fill:#f8e8bb;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-140.84662,-10.487952)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5743-1-8"
+ style="opacity:0.2852931;fill:#fae3cf;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-165.31021,-122.54031)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5745-1-0"
+ style="opacity:0.20735623;fill:#fae9cd;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-128.33597,45.448235)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5747-5-2"
+ style="opacity:0.30067605;fill:#fbf1da;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-7.0432549,-122.08308)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5749-9-1"
+ style="opacity:0.28081701;fill:#f8e5b3;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-159.84149,-27.364964)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5751-8-0"
+ style="opacity:0.19461921;fill:#f6d5b5;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-149.29571,-25.99044)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5753-4-5"
+ style="opacity:0.16186535;fill:#fbf3dc;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(32.814771,-121.33432)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5755-8-1"
+ style="opacity:0.24777012;fill:#f9e1c8;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-76.46653,120.73255)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5757-1-1"
+ style="opacity:0.17030227;fill:#f8d6b7;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-121.01417,-10.936342)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5759-0-0"
+ style="opacity:0.28682897;fill:#fbead6;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-66.281839,76.526652)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5761-3-8"
+ style="opacity:0.17808299;fill:#faeecf;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(25.253611,-28.570759)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-8"
+ inkscape:spray-origin="#path5194-3"
+ id="use5763-0-5"
+ style="opacity:0.12767968;fill:#faebcb;fill-opacity:1;stroke-width:0.66666657" />
+ <circle
+ r="0.25312728"
+ cy="-219.72015"
+ cx="-238.0349"
+ id="path5194-6-6"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.51509615;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#f9e6c4;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.06574658;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ transform="scale(-1)" />
+ <use
+ transform="translate(-27.410777,-114.81119)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-6-6"
+ inkscape:spray-origin="#path5194"
+ id="use5570-7-4"
+ style="opacity:0.53443095;fill:#fbf0dc;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(6.7608272,-15.715112)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-6-6"
+ inkscape:spray-origin="#path5194"
+ id="use5572-5-6"
+ style="opacity:0.67620161;fill:#f8d7bd;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-205.93552,-178.23894)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-6-6"
+ inkscape:spray-origin="#path5194"
+ id="use5586-3-2"
+ style="opacity:0.63853718;fill:#f9dfca;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-7.1334118,-140.58057)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-6-6"
+ inkscape:spray-origin="#path5194"
+ id="use5588-5-5"
+ style="opacity:0.3600282;fill:#fcf0dd;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-47.608172,-139.49829)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-6-6"
+ inkscape:spray-origin="#path5194"
+ id="use5590-6-8"
+ style="opacity:0.2480887;fill:#f8dcb5;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-141.95602,16.984541)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-6-6"
+ inkscape:spray-origin="#path5194"
+ id="use5592-2-6"
+ style="opacity:0.48100059;fill:#f9edca;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-34.148381,-101.919)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-6-6"
+ inkscape:spray-origin="#path5194"
+ id="use5594-9-2"
+ style="opacity:0.51265905;fill:#f7e2b4;fill-opacity:1;stroke-width:0.66666657;image-rendering:auto" />
+ <use
+ transform="translate(-124.2428,0.15069991)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-6-6"
+ inkscape:spray-origin="#path5194"
+ id="use5596-1-8"
+ style="opacity:0.48157989;fill:#f9ebcc;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-112.69182,-196.54499)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-6-6"
+ inkscape:spray-origin="#path5194"
+ id="use5598-2-4"
+ style="opacity:0.39424319;fill:#f7d7b8;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-136.56311,-48.560836)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-6-6"
+ inkscape:spray-origin="#path5194"
+ id="use5604-0-2"
+ style="opacity:0.77640872;fill:#f8dab7;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-124.39041,-87.606332)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-6-6"
+ inkscape:spray-origin="#path5194"
+ id="use5608-9-4"
+ style="opacity:0.55152337;fill:#fbf3dc;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-226.47993,-97.042717)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-6-6"
+ inkscape:spray-origin="#path5194"
+ id="use5610-3-0"
+ style="opacity:0.24128789;fill:#f8dfb7;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(19.223677,-149.79314)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-6-6"
+ inkscape:spray-origin="#path5194"
+ id="use5618-6-6"
+ style="opacity:0.86759428;fill:#f8e1b9;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-184.70295,-95.661669)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-6-6"
+ inkscape:spray-origin="#path5194"
+ id="use5620-0-2"
+ style="opacity:0.51509615;fill:#fbe8d4;fill-opacity:1;stroke-width:0.66666657" />
+ <circle
+ r="0.1479298"
+ cy="119.42557"
+ cx="135.48605"
+ id="path5194-3-6-9"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.31796324;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#fae7d1;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.06574658;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ <use
+ transform="translate(2.5218899,113.74492)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6-9"
+ inkscape:spray-origin="#path5194-3"
+ id="use5651-2-9"
+ style="opacity:0.62974818;fill:#f8e0c7;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(93.92397,-73.186297)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6-9"
+ inkscape:spray-origin="#path5194-3"
+ id="use5655-6-0"
+ style="opacity:0.68632801;fill:#f9e0c6;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(16.948667,104.89718)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6-9"
+ inkscape:spray-origin="#path5194-3"
+ id="use5659-1-8"
+ style="opacity:0.56376929;fill:#fbf1d8;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(81.400594,36.88804)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6-9"
+ inkscape:spray-origin="#path5194-3"
+ id="use5661-8-1"
+ style="opacity:0.51856139;fill:#fbeedc;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(47.698531,108.27264)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6-9"
+ inkscape:spray-origin="#path5194-3"
+ id="use5665-7-3"
+ style="opacity:0.76440017;fill:#fae5d1;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-17.25647,-99.470747)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6-9"
+ inkscape:spray-origin="#path5194-3"
+ id="use5669-0-1"
+ style="opacity:0.58378649;fill:#f8e4c5;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-105.1643,3.9166552)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6-9"
+ inkscape:spray-origin="#path5194-3"
+ id="use5673-2-0"
+ style="opacity:0.89318913;fill:#f9e9be;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(62.699899,-28.419919)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6-9"
+ inkscape:spray-origin="#path5194-3"
+ id="use5691-3-3"
+ style="opacity:0.44984945;fill:#f7dab8;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-13.757635,15.435852)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6-9"
+ inkscape:spray-origin="#path5194-3"
+ id="use5693-75-4"
+ style="opacity:0.77417656;fill:#fbecde;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(120.55838,-61.971371)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6-9"
+ inkscape:spray-origin="#path5194-3"
+ id="use5695-9-0"
+ style="opacity:0.41255619;fill:#fbecd0;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-116.74061,-98.646957)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6-9"
+ inkscape:spray-origin="#path5194-3"
+ id="use5697-2-3"
+ style="opacity:0.57635749;fill:#f8e6bf;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-26.931769,-82.834297)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6-9"
+ inkscape:spray-origin="#path5194-3"
+ id="use5699-2-9"
+ style="opacity:0.82897393;fill:#fbefdc;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(7.7407641,-0.70351679)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6-9"
+ inkscape:spray-origin="#path5194-3"
+ id="use5701-8-1"
+ style="opacity:0.83640747;fill:#f9edcc;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(138.17835,54.374246)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6-9"
+ inkscape:spray-origin="#path5194-3"
+ id="use5703-9-9"
+ style="opacity:0.92765928;fill:#fae3d1;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-11.2503,61.746352)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6-9"
+ inkscape:spray-origin="#path5194-3"
+ id="use5705-7-6"
+ style="opacity:0.67521231;fill:#f8e5b1;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-121.62408,81.590553)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6-9"
+ inkscape:spray-origin="#path5194-3"
+ id="use5709-3-9"
+ style="opacity:0.68766258;fill:#f8dfb7;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(115.79477,129.40854)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6-9"
+ inkscape:spray-origin="#path5194-3"
+ id="use5711-6-3"
+ style="opacity:0.73717035;fill:#faf0d5;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-9.1129241,-44.237418)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6-9"
+ inkscape:spray-origin="#path5194-3"
+ id="use5713-1-3"
+ style="opacity:0.91648972;fill:#fae3cf;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-116.94119,50.586066)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6-9"
+ inkscape:spray-origin="#path5194-3"
+ id="use5715-2-8"
+ style="opacity:0.52133412;fill:#f9e9c2;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(140.89978,34.062795)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6-9"
+ inkscape:spray-origin="#path5194-3"
+ id="use5717-9-0"
+ style="opacity:0.5185572;fill:#f9e5c8;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-9.6183221,47.358886)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6-9"
+ inkscape:spray-origin="#path5194-3"
+ id="use5719-3-5"
+ style="opacity:0.76549557;fill:#f8deb9;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(8.7933143,-74.586671)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6-9"
+ inkscape:spray-origin="#path5194-3"
+ id="use5721-1-6"
+ style="opacity:0.37841635;fill:#f9dfba;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-40.357254,-85.847197)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6-9"
+ inkscape:spray-origin="#path5194-3"
+ id="use5723-9-6"
+ style="opacity:0.69219265;fill:#f8e2bb;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(47.800237,90.533807)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6-9"
+ inkscape:spray-origin="#path5194-3"
+ id="use5725-4-4"
+ style="opacity:0.90878565;fill:#f9e1c8;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(97.916987,-28.933372)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6-9"
+ inkscape:spray-origin="#path5194-3"
+ id="use5727-7-0"
+ style="opacity:0.70991426;fill:#f7deba;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-120.50666,63.092216)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6-9"
+ inkscape:spray-origin="#path5194-3"
+ id="use5729-8-0"
+ style="opacity:0.33191139;fill:#f9e4c4;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(141.91725,34.963473)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6-9"
+ inkscape:spray-origin="#path5194-3"
+ id="use5731-4-4"
+ style="opacity:0.35514927;fill:#f9e1c2;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-33.726039,-107.14963)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6-9"
+ inkscape:spray-origin="#path5194-3"
+ id="use5733-5-6"
+ style="opacity:0.66832084;fill:#f8e4b3;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(60.104683,43.737324)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6-9"
+ inkscape:spray-origin="#path5194-3"
+ id="use5735-0-2"
+ style="opacity:0.62969875;fill:#f9e5c6;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(130.56753,42.924699)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6-9"
+ inkscape:spray-origin="#path5194-3"
+ id="use5739-6-7"
+ style="opacity:0.58305933;fill:#fae4c9;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-64.352607,76.806655)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6-9"
+ inkscape:spray-origin="#path5194-3"
+ id="use5741-1-5"
+ style="opacity:0.68933937;fill:#f7e6bc;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(8.96092,66.116784)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6-9"
+ inkscape:spray-origin="#path5194-3"
+ id="use5743-0-6"
+ style="opacity:0.78866966;fill:#fae6d1;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(68.349474,-50.511099)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6-9"
+ inkscape:spray-origin="#path5194-3"
+ id="use5745-6-9"
+ style="opacity:0.82571238;fill:#f8dfc1;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(13.576969,65.810801)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6-9"
+ inkscape:spray-origin="#path5194-3"
+ id="use5747-3-8"
+ style="opacity:0.91943383;fill:#f7e8be;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-114.90976,135.3077)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6-9"
+ inkscape:spray-origin="#path5194-3"
+ id="use5749-2-7"
+ style="opacity:0.76528362;fill:#f9dfc8;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-72.105877,92.606443)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6-9"
+ inkscape:spray-origin="#path5194-3"
+ id="use5751-0-2"
+ style="opacity:0.82425393;fill:#f8e0bb;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-69.763433,19.19353)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6-9"
+ inkscape:spray-origin="#path5194-3"
+ id="use5753-6-8"
+ style="opacity:0.33226282;fill:#f8e8c1;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-99.204039,162.08)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6-9"
+ inkscape:spray-origin="#path5194-3"
+ id="use5755-1-2"
+ style="opacity:0.88268421;fill:#fbeede;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-69.287037,101.28454)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6-9"
+ inkscape:spray-origin="#path5194-3"
+ id="use5757-5-9"
+ style="opacity:0.74581813;fill:#f7d3b6;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-44.494608,-111.5988)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6-9"
+ inkscape:spray-origin="#path5194-3"
+ id="use5759-5-9"
+ style="opacity:0.42326086;fill:#fadec5;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-113.45252,122.33129)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6-9"
+ inkscape:spray-origin="#path5194-3"
+ id="use5761-4-6"
+ style="opacity:0.25995998;fill:#f9e2ca;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(44.373914,-51.03748)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-6-9"
+ inkscape:spray-origin="#path5194-3"
+ id="use5763-7-0"
+ style="opacity:0.70086347;fill:#fae1cb;fill-opacity:1;stroke-width:0.66666657" />
+ <circle
+ r="0.25312728"
+ cy="143.93597"
+ cx="272.92487"
+ id="path5194-4-6-2"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.2133135;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#f8dfb7;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.06574658;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" />
+ <use
+ transform="translate(-97.523311,-54.169334)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-4-6-2"
+ inkscape:spray-origin="#path5194"
+ id="use5570-3-5-7"
+ style="opacity:0.55776331;fill:#fae6d3;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-97.247262,-4.9516969)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-4-6-2"
+ inkscape:spray-origin="#path5194"
+ id="use5572-1-6-6"
+ style="opacity:0.91566018;fill:#fcecdd;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-116.2253,-32.490818)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-4-6-2"
+ inkscape:spray-origin="#path5194"
+ id="use5586-0-9-1"
+ style="opacity:0.8011562;fill:#fae4d1;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-116.48577,33.070747)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-4-6-2"
+ inkscape:spray-origin="#path5194"
+ id="use5588-6-3-3"
+ style="opacity:0.47066459;fill:#fae4d1;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-24.903199,64.054893)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-4-6-2"
+ inkscape:spray-origin="#path5194"
+ id="use5590-8-7-2"
+ style="opacity:0.76212009;fill:#f8d2b1;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-165.01706,-120.27187)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-4-6-2"
+ inkscape:spray-origin="#path5194"
+ id="use5594-2-4-1"
+ style="opacity:0.36166603;fill:#f7dab4;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-26.314207,60.386023)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-4-6-2"
+ inkscape:spray-origin="#path5194"
+ id="use5618-7-5-5"
+ style="opacity:0.44323348;fill:#fae8d7;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-239.95689,-105.13436)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-4-6-2"
+ inkscape:spray-origin="#path5194"
+ id="use5620-2-2-9"
+ style="opacity:0.73318452;fill:#f8e4b9;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-82.267372,132.32929)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-4-6-2"
+ inkscape:spray-origin="#path5194"
+ id="use5624-2-5-9"
+ style="opacity:0.64640311;fill:#fcecdd;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-229.84689,-10.785491)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-4-6-2"
+ inkscape:spray-origin="#path5194"
+ id="use5628-6-4-1"
+ style="opacity:0.64930761;fill:#fbedd8;fill-opacity:1;stroke-width:0.66666657" />
+ <circle
+ r="0.1479298"
+ cy="-125.81341"
+ cx="-173.59578"
+ id="path5194-3-1-7-4"
+ style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.25005906;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#f8dcbd;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.06574658;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ transform="scale(-1)" />
+ <use
+ transform="translate(81.099342,-25.388459)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5651-5-4-9"
+ style="opacity:0.29960902;fill:#faeecd;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-132.35348,-18.505611)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5655-9-4-1"
+ style="opacity:0.25559734;fill:#f9e4c6;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-93.902683,116.36654)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5659-4-3-0"
+ style="opacity:0.59912738;fill:#f8e1c1;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-38.79418,14.217548)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5661-9-0-7"
+ style="opacity:0.69609477;fill:#f8deb5;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(39.774696,-17.954239)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5665-0-7-5"
+ style="opacity:0.81515383;fill:#f9dfc4;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(41.092181,28.671033)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5667-9-8-8"
+ style="opacity:0.2158333;fill:#f7e1b2;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(40.639705,28.923161)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5669-1-6-7"
+ style="opacity:0.66778582;fill:#f9e6c4;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-86.899733,-40.142331)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5673-7-8-0"
+ style="opacity:0.46030435;fill:#f7d4b4;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-91.548473,-120.21226)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5677-7-8-4"
+ style="opacity:0.20230701;fill:#fbebdc;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-67.555223,83.401183)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5691-6-4-8"
+ style="opacity:0.76295034;fill:#f8e8c1;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(75.919845,118.63064)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5693-7-3-0"
+ style="opacity:0.72270532;fill:#f7dfb6;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(24.6633,83.808973)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5695-3-1-4"
+ style="opacity:0.77621197;fill:#f9dfc8;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-37.885655,-93.139609)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5697-6-4-2"
+ style="opacity:0.26322823;fill:#fae1cd;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(90.387031,-92.464151)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5699-5-9-9"
+ style="opacity:0.23636277;fill:#fbebd8;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-38.11219,93.568273)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5701-6-2-6"
+ style="opacity:0.60334856;fill:#fbeada;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-91.984813,110.26065)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5703-3-0-1"
+ style="opacity:0.9079019;fill:#faeccd;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-165.33763,22.797193)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5705-9-6-0"
+ style="opacity:0.92221907;fill:#fbebd6;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(67.131509,37.737303)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5707-4-8-4"
+ style="opacity:0.48834145;fill:#fbf2de;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-76.568753,101.19569)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5709-8-9-2"
+ style="opacity:0.9233943;fill:#fbeada;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-160.82053,63.487813)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5711-1-2-2"
+ style="opacity:0.5106431;fill:#f9e6cc;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(50.173243,21.66012)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5713-2-6-2"
+ style="opacity:0.39269768;fill:#f9dfc6;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-157.01817,-111.95559)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5717-3-6-0"
+ style="opacity:0.20113029;fill:#faedcf;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-161.23954,130.09889)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5719-9-4-5"
+ style="opacity:0.69594864;fill:#f8d5b5;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-124.54393,-76.530169)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5721-0-9-5"
+ style="opacity:0.85233633;fill:#f9e1c8;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(90.458454,-10.403051)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5723-8-5-2"
+ style="opacity:0.89217882;fill:#f8eac5;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(39.416306,67.409543)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5725-8-0-9"
+ style="opacity:0.23113631;fill:#f7d4b4;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-95.517443,86.352803)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5727-5-4-0"
+ style="opacity:0.35710198;fill:#fae6c9;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-43.126314,-61.882436)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5729-0-8-2"
+ style="opacity:0.85987926;fill:#fbedd6;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(57.729271,-113.27735)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5733-6-1-3"
+ style="opacity:0.61046352;fill:#fbebdc;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(6.4475156,30.979527)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5735-3-7-8"
+ style="opacity:0.1969547;fill:#fae0cb;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(79.651412,-15.565871)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5737-8-2-0"
+ style="opacity:0.709767;fill:#fae9d5;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(49.109193,85.407703)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5739-5-7-4"
+ style="opacity:0.55372596;fill:#f8d9bd;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(16.295686,149.12405)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5741-6-2-0"
+ style="opacity:0.85252727;fill:#f7e1b2;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(1.9250996,34.722262)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5743-1-2-9"
+ style="opacity:0.60519768;fill:#fbefd4;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-155.79307,43.494474)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5745-1-6-1"
+ style="opacity:0.54519923;fill:#fae2cb;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-103.13173,-120.9874)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5747-5-1-9"
+ style="opacity:0.57890098;fill:#f9ebc8;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(53.826922,153.42762)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5749-9-0-6"
+ style="opacity:0.48293146;fill:#f9eac2;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-42.101843,-63.886566)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5751-8-6-2"
+ style="opacity:0.91748167;fill:#f8e7b9;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(106.70781,-69.399448)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5753-4-1-5"
+ style="opacity:0.39435431;fill:#f7e4be;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-151.41241,153.18697)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5755-8-5-4"
+ style="opacity:0.64421129;fill:#f9e7bc;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(102.8252,-114.7773)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5757-1-9-4"
+ style="opacity:0.3557327;fill:#fae8d3;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(81.780355,-63.537791)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5759-0-4-9"
+ style="opacity:0.69628679;fill:#fae8d5;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-118.94333,-95.459212)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5761-3-9-9"
+ style="opacity:0.74780656;fill:#fbead4;fill-opacity:1;stroke-width:0.66666657" />
+ <use
+ transform="translate(-161.96878,18.777813)"
+ height="100%"
+ width="100%"
+ y="0"
+ x="0"
+ xlink:href="#path5194-3-1-7-4"
+ inkscape:spray-origin="#path5194-3"
+ id="use5763-0-0-3"
+ style="opacity:0.84120531;fill:#f8d4b1;fill-opacity:1;stroke-width:0.66666657" />
+ </g>
</svg>
diff --git a/src/activities/solar_system/resource/earth.png b/src/activities/solar_system/resource/earth.png
index 2b7b0b88f..5af534861 100644
Binary files a/src/activities/solar_system/resource/earth.png and b/src/activities/solar_system/resource/earth.png differ
diff --git a/src/activities/solar_system/resource/hint_solar_model.png b/src/activities/solar_system/resource/hint_solar_model.png
deleted file mode 100644
index b613be404..000000000
Binary files a/src/activities/solar_system/resource/hint_solar_model.png and /dev/null differ
diff --git a/src/activities/solar_system/solar_system.js b/src/activities/solar_system/solar_system.js
index 069b6407b..77f160509 100644
--- a/src/activities/solar_system/solar_system.js
+++ b/src/activities/solar_system/solar_system.js
@@ -1,180 +1,181 @@
/* GCompris - solar_system.js
*
* Copyright (C) 2018 Aman Kumar Gupta <gupta2140@gmail.com>
*
* Authors:
* Aman Kumar Gupta <gupta2140@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
.import "Dataset.js" as Dataset
.import "qrc:/gcompris/src/core/core.js" as Core
var currentLevel = 0
var numberOfLevel
var items
var dataset
var currentPlanetLevels
var currentSubLevel
var indexOfSelectedPlanet
var assessmentModeQuestions = []
var allQuestions = []
function start(items_) {
items = items_
currentLevel = 0
dataset = Dataset.get()
for(var i = 0; i < dataset.length; ++i) {
items.planetsModel.append({
"realImg": dataset[i].realImg,
- "bodyName": dataset[i].bodyName
+ "bodyName": dataset[i].bodyName,
+ "bodySize": dataset[i].bodySize
});
}
if(items.assessmentMode)
startAssessmentMode()
}
function stop() {
}
function initLevel() {
currentSubLevel = 0
items.bar.level = currentLevel + 1
items.mainQuizScreen.score.numberOfSubLevels = currentPlanetLevels.length
Core.shuffle(currentPlanetLevels)
nextSubLevel(false)
}
function nextSubLevel(isAssessmentMode) {
items.mainQuizScreen.score.currentSubLevel = currentSubLevel
var optionListShuffle = []
if(!isAssessmentMode) {
items.mainQuizScreen.closenessMeterValue = 0
if(currentSubLevel+1 > items.mainQuizScreen.score.numberOfSubLevels) {
items.bonus.good("flower")
return
}
else {
items.mainQuizScreen.question = currentPlanetLevels[currentSubLevel].question
for(var i = 0 ; i < 4 ; i ++) {
optionListShuffle.push({
"optionValue": currentPlanetLevels[currentSubLevel].options[i],
"closeness": currentPlanetLevels[currentSubLevel].closeness[i]
});
}
}
}
else if(!items.mainQuizScreen.restartAssessmentMessage.visible) {
items.mainQuizScreen.question = assessmentModeQuestions[0].question
for(var i = 0 ; i < 4 ; i ++) {
optionListShuffle.push({
"optionValue": assessmentModeQuestions[0].options[i],
"closeness": assessmentModeQuestions[0].closeness[i]
});
}
}
items.mainQuizScreen.closenessMeter.stopAnimations()
if((currentSubLevel + 1) <= items.mainQuizScreen.score.numberOfSubLevels) {
items.mainQuizScreen.optionListModel.clear()
Core.shuffle(optionListShuffle)
for(var i = 0 ; i < optionListShuffle.length ; i ++)
items.mainQuizScreen.optionListModel.append(optionListShuffle[i])
currentSubLevel++
}
}
function showSolarModel() {
items.quizScreenVisible = false
items.solarSystemVisible = true
}
function startAssessmentMode() {
items.solarSystemVisible = false
items.quizScreenVisible = true
items.mainQuizScreen.numberOfCorrectAnswers = 0
items.mainQuizScreen.score.numberOfSubLevels = 20
currentSubLevel = 0
assessmentModeQuestions = []
allQuestions = []
for(var i = 0; i < dataset.length; i++) {
for(var j = 0; j < dataset[i].levels.length; j++)
allQuestions.push(dataset[i].levels[j])
}
Core.shuffle(allQuestions)
assessmentModeQuestions = allQuestions.slice(0, 20)
nextSubLevel(true)
}
function appendAndAddQuestion() {
var incorrectAnsweredQuestion = assessmentModeQuestions.shift()
assessmentModeQuestions.push(incorrectAnsweredQuestion)
if(items.mainQuizScreen.score.numberOfSubLevels == 24)
items.mainQuizScreen.score.numberOfSubLevels++
else if(items.mainQuizScreen.score.numberOfSubLevels < 24) {
assessmentModeQuestions.push(allQuestions[items.mainQuizScreen.score.numberOfSubLevels])
items.mainQuizScreen.score.numberOfSubLevels += 2
}
else if(items.mainQuizScreen.numberOfCorrectAnswers)
items.mainQuizScreen.numberOfCorrectAnswers--
nextSubLevel(true)
}
function showQuizScreen(index) {
currentLevel = 0
indexOfSelectedPlanet = index
items.solarSystemVisible = false
items.quizScreenVisible = true
currentPlanetLevels = dataset[indexOfSelectedPlanet].levels
items.mainQuizScreen.planetRealImage = dataset[indexOfSelectedPlanet].realImg
if(indexOfSelectedPlanet != 0) {
items.temperatureHint = dataset[indexOfSelectedPlanet].temperatureHint
items.lengthOfYearHint = dataset[indexOfSelectedPlanet].lengthOfYearHint
}
initLevel()
}
function nextLevel() {
if(numberOfLevel <= ++currentLevel) {
currentLevel = 0
}
if(!items.assessmentMode)
initLevel()
else
startAssessmentMode()
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
initLevel();
}
diff --git a/src/activities/solar_system/solar_system.svg b/src/activities/solar_system/solar_system.svg
index 5b8a8483c..8e01655a2 100644
--- a/src/activities/solar_system/solar_system.svg
+++ b/src/activities/solar_system/solar_system.svg
@@ -1,112 +1,114 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
id="svg5406"
sodipodi:docname="solar_system.svg"
- viewBox="0 0 217.82 217.82"
+ viewBox="0 0 99.999997 99.999997"
version="1.1"
- inkscape:version="0.92.1 r15371">
+ inkscape:version="0.92.1 r15371"
+ width="100"
+ height="100">
<defs
id="defs5408" />
<sodipodi:namedview
id="base"
bordercolor="#666666"
inkscape:pageshadow="2"
inkscape:window-y="0"
fit-margin-left="0"
pagecolor="#ffffff"
fit-margin-top="0"
inkscape:window-maximized="1"
inkscape:zoom="1.979899"
inkscape:window-x="0"
inkscape:window-height="1051"
showgrid="false"
borderopacity="1.0"
inkscape:current-layer="g4119"
- inkscape:cx="-78.811055"
- inkscape:cy="178.2521"
+ inkscape:cx="120.90306"
+ inkscape:cy="143.40184"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:window-width="1884"
inkscape:pageopacity="0.0"
inkscape:document-units="px" />
<g
id="layer1"
inkscape:label="Layer 1"
inkscape:groupmode="layer"
- transform="translate(-579.66 -629.17)">
+ transform="translate(-579.66,-746.99001)">
<g
id="g4119"
- transform="matrix(.80211 0 0 .80211 4567.3 1423.6)">
+ transform="matrix(0.80211,0,0,0.80211,4567.3,1423.6)">
<path
- style="color:#000000;fill:#ffeb38;fill-opacity:1;stroke-width:0.62435251"
- d="m -4815.0339,-929.37048 c -5.7859,4.87876 -9.6588,9.73047 -12.6059,14.64887 a 68.080063,68.080063 0 0 1 14.0304,3.22148 c -1.5363,-6.11305 -2.2792,-12.09649 -1.4245,-17.87035 z m -43.8809,0.67449 c -2.5807,7.1438 -3.5058,13.30187 -3.594,19.05375 a 68.080063,68.080063 0 0 1 13.7747,-4.27339 c -4.3922,-4.53023 -8.0322,-9.34774 -10.1807,-14.78036 z m 82.2246,20.68032 c -7.4551,1.33297 -13.2386,3.60044 -18.2527,6.3894 a 68.080063,68.080063 0 0 1 10.5508,9.79351 c 1.7273,-6.05939 4.0759,-11.61164 7.7019,-16.18291 z m -119.8889,1.85303 c 1.3394,7.49117 3.622,13.29221 6.4284,18.32325 a 68.080063,68.080063 0 0 1 9.8349,-10.60192 c -6.0902,-1.72932 -11.6721,-4.0796 -16.2633,-7.72133 z m 123.4294,32.21727 a 68.080063,68.080063 0 0 1 4.249,13.73818 c 4.5179,-4.37575 9.3194,-8.00169 14.7365,-10.14414 -7.1163,-2.57077 -13.2535,-3.49977 -18.9855,-3.59404 z m -126.8238,4.6776 c -6.1441,1.55201 -12.1585,2.30782 -17.9604,1.44882 4.902,5.81348 9.777,9.69508 14.7195,12.6473 a 68.080063,68.080063 0 0 1 3.2409,-14.09612 z m 131.8569,30.20111 a 68.080063,68.080063 0 0 1 -3.2337,14.0182 c 6.1115,-1.53537 12.0963,-2.27649 17.8679,-1.42202 -4.8731,-5.77965 -9.7207,-9.65009 -14.6342,-12.59618 z m -134.3113,4.89432 c -4.5458,4.41521 -9.3781,8.07739 -14.8315,10.23424 7.168,2.58947 13.3436,3.51372 19.1122,3.59646 a 68.080063,68.080063 0 0 1 -4.2807,-13.8307 z m 121.1891,27.77586 a 68.080063,68.080063 0 0 1 -9.8203,10.55809 c 6.0744,1.72824 11.641,4.07796 16.2219,7.71159 -1.3346,-7.46408 -3.6079,-13.25145 -6.4016,-18.26968 z m -105.7538,3.82049 c -1.7303,6.10536 -4.084,11.70127 -7.7335,16.30221 7.5001,-1.34101 13.3054,-3.62836 18.3403,-6.44052 a 68.080063,68.080063 0 0 1 -10.6068,-9.86169 z m 78.0851,17.93122 a 68.080063,68.080063 0 0 1 -13.7917,4.25636 c 4.3992,4.53504 8.0467,9.35384 10.1977,14.79252 2.5801,-7.14214 3.5055,-13.29813 3.594,-19.04888 z m -48.9237,1.7678 c 1.5493,6.14263 2.3026,12.15773 1.444,17.95801 5.8067,-4.89609 9.6877,-9.76618 12.64,-14.70244 a 68.080063,68.080063 0 0 1 -14.084,-3.25557 z"
+ style="color:#000000;fill:#ffeb38;fill-opacity:1;stroke-width:0.27546149"
+ d="m -4899.983,-809.9973 c -2.5527,2.15249 -4.2614,4.29304 -5.5617,6.46302 a 30.036616,30.036616 0 0 1 6.1902,1.4213 c -0.6778,-2.69705 -1.0056,-5.33691 -0.6285,-7.88432 z m -19.3601,0.29759 c -1.1386,3.15181 -1.5467,5.86872 -1.5856,8.40642 a 30.036616,30.036616 0 0 1 6.0773,-1.8854 c -1.9378,-1.99871 -3.5438,-4.12418 -4.4917,-6.52102 z m 36.2771,9.12406 c -3.2891,0.5881 -5.8408,1.5885 -8.053,2.81897 a 30.036616,30.036616 0 0 1 4.655,4.32086 c 0.7621,-2.67338 1.7983,-5.12301 3.398,-7.13983 z m -52.8944,0.81755 c 0.5909,3.30507 1.598,5.86446 2.8362,8.08413 a 30.036616,30.036616 0 0 1 4.3391,-4.67752 c -2.687,-0.76296 -5.1497,-1.7999 -7.1753,-3.40661 z m 54.4565,14.21411 a 30.036616,30.036616 0 0 1 1.8746,6.06123 c 1.9933,-1.93057 4.1117,-3.53031 6.5017,-4.47555 -3.1397,-1.13422 -5.8474,-1.54409 -8.3763,-1.58568 z m -55.9541,2.06374 c -2.7107,0.68474 -5.3643,1.0182 -7.924,0.63921 2.1627,2.56488 4.3135,4.27743 6.4941,5.57993 a 30.036616,30.036616 0 0 1 1.4299,-6.21914 z m 58.1747,13.32459 a 30.036616,30.036616 0 0 1 -1.4267,6.18477 c 2.6964,-0.6774 5.3368,-1.00438 7.8832,-0.62739 -2.15,-2.54996 -4.2887,-4.25758 -6.4565,-5.55738 z m -59.2576,2.15935 c -2.0055,1.94797 -4.1375,3.56371 -6.5436,4.5153 3.1625,1.14247 5.8872,1.55024 8.4323,1.58675 a 30.036616,30.036616 0 0 1 -1.8887,-6.10205 z m 53.4681,12.25459 a 30.036616,30.036616 0 0 1 -4.3326,4.65818 c 2.6799,0.76249 5.1359,1.79918 7.157,3.40232 -0.5888,-3.29312 -1.5918,-5.84648 -2.8244,-8.0605 z m -46.6581,1.68558 c -0.7634,2.69366 -1.8018,5.16255 -3.412,7.19246 3.309,-0.59165 5.8703,-1.60081 8.0917,-2.84153 a 30.036616,30.036616 0 0 1 -4.6797,-4.35093 z m 34.4508,7.91117 a 30.036616,30.036616 0 0 1 -6.0848,1.87789 c 1.9409,2.00084 3.5501,4.12687 4.4992,6.52639 1.1383,-3.15108 1.5466,-5.86707 1.5856,-8.40428 z m -21.5849,0.77995 c 0.6835,2.7101 1.0159,5.36393 0.6371,7.92299 2.5619,-2.16013 4.2742,-4.30879 5.5767,-6.48665 a 30.036616,30.036616 0 0 1 -6.2138,-1.43634 z"
id="path4113"
inkscape:connector-curvature="0" />
<path
- style="color:#000000;fill:#ffd429;fill-opacity:1;stroke-width:0.62435251"
- d="m -4837.0121,-931.92477 c -4.3354,6.22339 -6.8222,11.92451 -8.3958,17.44909 a 68.080063,68.080063 0 0 1 9.7497,-0.76945 68.080063,68.080063 0 0 1 4.6605,0.23132 c -3.0709,-5.51247 -5.3428,-11.10727 -6.0119,-16.91096 z m 42.5635,10.70175 c -6.8515,3.21495 -11.8464,6.90077 -15.9661,10.88925 a 68.080063,68.080063 0 0 1 12.7179,6.68403 c 0.1033,-6.28062 0.9355,-12.23447 3.2482,-17.57328 z m -84.7764,1.31246 c -0.6415,7.54084 0.053,13.71031 1.4464,19.27289 a 68.080063,68.080063 0 0 1 12.2115,-7.63611 c -5.4139,-3.23896 -10.1771,-6.94609 -13.6579,-11.63678 z m 111.0889,28.99822 c -5.2452,-0.0305 -9.8048,0.62056 -14.0182,1.67283 a 68.080063,68.080063 0 0 1 7.6069,12.17492 c 3.2322,-5.39421 6.933,-10.13618 11.61,-13.60669 -1.8077,-0.15377 -3.5376,-0.23141 -5.1987,-0.24106 z m -141.6382,2.5129 c 3.2281,6.87955 6.9307,11.88799 10.938,16.01733 a 68.080063,68.080063 0 0 1 6.7084,-12.76906 c -6.3075,-0.0979 -12.2872,-0.92663 -17.6464,-3.24827 z m 141.4336,31.55253 a 68.080063,68.080063 0 0 1 0.7622,9.6815 68.080063,68.080063 0 0 1 -0.2362,4.70438 c 5.5043,-3.06477 11.0881,-5.33149 16.8842,-5.9998 -6.2099,-4.32616 -11.8974,-6.81185 -17.4102,-8.38608 z m -135.161,4.96006 c -5.5338,3.08937 -11.148,5.37912 -16.9743,6.05093 6.2454,4.35073 11.9646,6.83782 17.5075,8.41044 a 68.080063,68.080063 0 0 1 -0.7694,-9.73993 68.080063,68.080063 0 0 1 0.2362,-4.72144 z m 130.9899,30.02578 a 68.080063,68.080063 0 0 1 -6.6962,12.71306 c 6.2845,0.10261 12.2393,0.93693 17.5806,3.2507 -3.2138,-6.84906 -6.8969,-11.84438 -10.8844,-15.96376 z m -124.2864,4.53152 c -3.2455,5.43269 -6.9597,10.21363 -11.6636,13.70408 7.5567,0.64285 13.7357,-0.0553 19.307,-1.45611 a 68.080063,68.080063 0 0 1 -7.6434,-12.24797 z m 103.18,23.69238 a 68.080063,68.080063 0 0 1 -12.209,7.61419 c 5.4112,3.23806 10.1709,6.94552 13.6505,11.63437 0.6406,-7.53018 -0.051,-13.69245 -1.4415,-19.24856 z m -80.0866,2.90251 c -0.098,6.31282 -0.9298,12.29497 -3.2532,17.6585 6.8783,-3.22762 11.887,-6.92906 16.0173,-10.93551 a 68.080063,68.080063 0 0 1 -12.7641,-6.72299 z m 47.7183,10.88924 a 68.080063,68.080063 0 0 1 -9.6717,0.75972 68.080063,68.080063 0 0 1 -4.7677,-0.23863 c 3.0827,5.5261 5.3654,11.13193 6.0363,16.94993 4.3418,-6.23219 6.8299,-11.93877 8.4031,-17.47102 z"
+ style="color:#000000;fill:#ffd429;fill-opacity:1;stroke-width:0.27546149"
+ d="m -4909.6797,-811.12424 c -1.9128,2.74574 -3.0099,5.26104 -3.7042,7.69846 a 30.036616,30.036616 0 0 1 4.3015,-0.33947 30.036616,30.036616 0 0 1 2.0562,0.10205 c -1.3548,-2.43207 -2.3572,-4.90047 -2.6524,-7.46104 z m 18.7788,4.72157 c -3.0228,1.41842 -5.2266,3.04459 -7.0442,4.80429 a 30.036616,30.036616 0 0 1 5.6111,2.94896 c 0.046,-2.77098 0.4128,-5.39779 1.4331,-7.75325 z m -37.4029,0.57905 c -0.2831,3.32698 0.023,6.04893 0.6381,8.50311 a 30.036616,30.036616 0 0 1 5.3877,-3.36902 c -2.3886,-1.42901 -4.4901,-3.06458 -6.0258,-5.13409 z m 49.0119,12.79388 c -2.3142,-0.0135 -4.3259,0.27379 -6.1848,0.73805 a 30.036616,30.036616 0 0 1 3.3561,5.37152 c 1.4261,-2.3799 3.0588,-4.47204 5.1223,-6.00321 -0.7975,-0.0679 -1.5608,-0.1021 -2.2936,-0.10636 z m -62.4902,1.10868 c 1.4243,3.03523 3.0578,5.24493 4.8258,7.06678 a 30.036616,30.036616 0 0 1 2.9598,-5.63366 c -2.7829,-0.0432 -5.4211,-0.40882 -7.7856,-1.43312 z m 62.3999,13.92084 a 30.036616,30.036616 0 0 1 0.3363,4.27143 30.036616,30.036616 0 0 1 -0.1042,2.07555 c 2.4284,-1.35216 4.892,-2.35223 7.4492,-2.64708 -2.7398,-1.90869 -5.2491,-3.00536 -7.6813,-3.6999 z m -59.6324,2.18835 c -2.4415,1.36302 -4.9185,2.37325 -7.489,2.66964 2.7554,1.91953 5.2787,3.01682 7.7242,3.71065 a 30.036616,30.036616 0 0 1 -0.3394,-4.29721 30.036616,30.036616 0 0 1 0.1042,-2.08308 z m 57.7921,13.24724 a 30.036616,30.036616 0 0 1 -2.9543,5.60894 c 2.7727,0.0453 5.3999,0.41337 7.7565,1.4342 -1.4179,-3.02178 -3.0429,-5.22569 -4.8022,-7.04314 z m -54.8346,1.99929 c -1.4319,2.39687 -3.0705,4.5062 -5.1459,6.04617 3.334,0.28363 6.0601,-0.0244 8.5182,-0.64242 a 30.036616,30.036616 0 0 1 -3.3723,-5.40375 z m 45.5226,10.45297 a 30.036616,30.036616 0 0 1 -5.3866,3.35934 c 2.3874,1.42862 4.4874,3.06434 6.0226,5.13303 0.2826,-3.32228 -0.023,-6.04104 -0.636,-8.49237 z m -35.3339,1.28057 c -0.043,2.78519 -0.4102,5.42449 -1.4353,7.79085 3.0347,-1.42401 5.2445,-3.05707 7.0668,-4.8247 a 30.036616,30.036616 0 0 1 -5.6315,-2.96615 z m 21.0531,4.80428 a 30.036616,30.036616 0 0 1 -4.2671,0.33519 30.036616,30.036616 0 0 1 -2.1035,-0.10528 c 1.3601,2.43809 2.3672,4.91135 2.6632,7.47823 1.9156,-2.74961 3.0134,-5.26733 3.7074,-7.70814 z"
id="path4115"
inkscape:connector-curvature="0" />
<circle
- style="opacity:1;vector-effect:none;fill:#ffd429;fill-opacity:1;stroke:#fdf075;stroke-width:13.53555298;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
+ style="opacity:1;vector-effect:none;fill:#ffd429;fill-opacity:1;stroke:#fdf075;stroke-width:5.97182465;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.50162886"
id="path848"
- cx="-4835.6582"
- cy="-847.16565"
- r="65.027107" />
+ cx="-4909.0825"
+ cy="-773.72894"
+ r="28.689665" />
</g>
</g>
<metadata
id="metadata16">
<rdf:RDF>
<cc:Work>
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
<dc:publisher>
<cc:Agent
rdf:about="http://openclipart.org/">
<dc:title />
</cc:Agent>
</dc:publisher>
- <dc:title />
+ <dc:title></dc:title>
<dc:date />
<dc:description />
<dc:source />
<dc:creator>
<cc:Agent>
<dc:title>Timothée Giet</dc:title>
</cc:Agent>
</dc:creator>
<dc:subject>
<rdf:Bag />
</dc:subject>
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Notice" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
</svg>
diff --git a/src/activities/submarine/ActivityInfo.qml b/src/activities/submarine/ActivityInfo.qml
index ecb73d1b0..21273db53 100644
--- a/src/activities/submarine/ActivityInfo.qml
+++ b/src/activities/submarine/ActivityInfo.qml
@@ -1,59 +1,60 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2017 Rudra Nil Basu <rudra.nil.basu.1996@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "submarine/Submarine.qml"
difficulty: 5
icon: "submarine/submarine.svg"
author: "Rudra Nil Basu &lt;rudra.nil.basu.1996@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Pilot a Submarine")
//: Help title
description: qsTr("Drive the submarine to the end point.")
//intro: "Drive the submarine to the right end of the screen without colliding with any objects"
//: Help goal
goal: qsTr("Learn how to control a submarine")
//: Help prerequisite
prerequisite: qsTr("Move and click using the mouse, physics basics")
//: Help manual
manual: qsTr("Control the various parts of the submarine (the engine, rudders and ballast tanks) to reach the end point.
Controls:
Engine:
D / Right arrow: Increase velocity
A / Left arrow: Decrease velocity
Ballast tanks:
Switch filling of Ballast tanks:
W / Up arrow: Central ballast tank
R: Left ballast tank
- T: Right ballast tanks
+ T: Right ballast tank
Switch flush ballast tanks:
S / Down arrow: Central ballast tank
F: Left ballast tank
- G: Right ballast tanks
+ G: Right ballast tank
Diving planes:
+ : Increase diving plane angle
- : Decrease diving plane angle")
credit: ""
section: "experimental"
+ enabled: ApplicationInfo.isBox2DInstalled
createdInVersion: 9000
}
diff --git a/src/activities/submarine/BallastTank.qml b/src/activities/submarine/BallastTank.qml
index ef37fa201..c8e124b1d 100644
--- a/src/activities/submarine/BallastTank.qml
+++ b/src/activities/submarine/BallastTank.qml
@@ -1,86 +1,86 @@
/* GCompris - BallastTank.qml
*
* Copyright (C) 2017 RUDRA NIL BASU <rudra.nil.basu.1996@gmail.com>
*
* Authors:
* Pascal Georges <pascal.georges1@free.fr> (GTK+ version)
* Rudra Nil Basu <rudra.nil.basu.1996@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
Item {
property int initialWaterLevel: 0
property int waterLevel: 0
property int maxWaterLevel: 500
property int waterRate: 100
property bool waterFilling: false
property bool waterFlushing: false
function fillBallastTanks() {
waterFilling = !waterFilling
}
function flushBallastTanks() {
waterFlushing = !waterFlushing
}
function updateWaterLevel(isInflow) {
if (isInflow) {
if (waterLevel < maxWaterLevel) {
waterLevel += waterRate
}
} else {
if (waterLevel > 0) {
waterLevel -= waterRate
}
}
if (waterLevel > maxWaterLevel) {
waterLevel = maxWaterLevel
}
if (waterLevel < 0) {
waterLevel = 0
}
}
function resetBallastTanks() {
waterFilling = false
waterFlushing = false
waterLevel = initialWaterLevel
}
Timer {
id: fillBallastTanks
interval: 500
running: waterFilling && !waterFlushing
repeat: true
onTriggered: updateWaterLevel(true)
}
Timer {
id: flushBallastTanks
interval: 500
running: waterFlushing && !waterFilling
repeat: true
onTriggered: updateWaterLevel(false)
}
}
diff --git a/src/activities/submarine/Controls.qml b/src/activities/submarine/Controls.qml
index 82a0e9eb3..1637fca69 100644
--- a/src/activities/submarine/Controls.qml
+++ b/src/activities/submarine/Controls.qml
@@ -1,575 +1,575 @@
/* GCompris - Controls.qml
*
* Copyright (C) 2017 RUDRA NIL BASU <rudra.nil.basu.1996@gmail.com>
*
* Authors:
* Pascal Georges <pascal.georges1@free.fr> (GTK+ version)
* Rudra Nil Basu <rudra.nil.basu.1996@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
Item {
id: controls
/* Engine Controller Properties */
property point enginePosition
property alias engineWidth : engine.width
property alias engineHeight : engine.height
property alias submarineHorizontalSpeed : engineValues.text
/* Ballast tanks Controller Properties */
property alias leftTankVisible : leftBallastTankController.visible
property point leftBallastTankPosition
property alias leftBallastTankWidth : leftBallastTankDisplay.width
property alias leftBallastTankHeight : leftBallastTankDisplay.height
property alias rotateLeftFill: rotateLeftFill
property alias rotateLeftFlush: rotateLeftFlush
property alias centralTankVisible : centralBallastTankController.visible
property point centralBallastTankPosition
property alias centralBallastTankWidth : centralBallastTankDisplay.width
property alias centralBallastTankHeight : centralBallastTankDisplay.height
property alias rotateCentralFill: rotateCentralFill
property alias rotateCentralFlush: rotateCentralFlush
property alias rightTankVisible : rightBallastTankController.visible
property point rightBallastTankPosition
property alias rightBallastTankWidth : rightBallastTankDisplay.width
property alias rightBallastTankHeight : rightBallastTankDisplay.height
property alias rotateRightFill: rotateRightFill
property alias rotateRightFlush: rotateRightFlush
/* Diving Plane Controller properties */
property bool divingPlaneVisible
property point divingPlanePosition
property int divingPlaneWidth
property int divingPlaneHeight
property int buttonSize
property int buttonPlusY
property int buttonMinusY
property string fillColor : "#0DA5CB"
Image {
id: controlBackground
source: url + "board.svg"
width: background.width
height: background.height * 0.40
sourceSize.width: controlBackground.width
sourceSize.height: controlBackground.height
y: background.height - controlBackground.height
}
Item {
Rectangle {
id: engine
x: enginePosition.x
y: enginePosition.y
radius: 10
color: "#323232"
border.width: 4
border.color: "#AEC6DD"
GCText {
id: engineValues
anchors {
horizontalCenter: parent.horizontalCenter
verticalCenter: parent.verticalCenter
}
color: "#D3E1EB"
}
}
Image {
id: incSpeed
source: url + "up.svg"
width: buttonSize
height: buttonSize
sourceSize.width: incSpeed.width
sourceSize.height: incSpeed.height
anchors {
right: engine.left
leftMargin: incSpeed.width / 2
}
y: buttonPlusY
MouseArea {
anchors.fill: parent
enabled: !tutorial.visible
onClicked: submarine.increaseHorizontalVelocity(1)
}
}
Image {
id: downSpeed
source: url + "down.svg"
width: buttonSize
height: buttonSize
sourceSize.width: downSpeed.width
sourceSize.height: downSpeed.height
anchors {
right: engine.left
leftMargin: downSpeed.width / 2
}
y: buttonMinusY
MouseArea {
anchors.fill: parent
enabled: !tutorial.visible
onClicked: submarine.decreaseHorizontalVelocity(1)
}
}
}
// 3 Ballast Tanks
Item {
id: leftBallastTankController
Rectangle {
id: leftBallastTankDisplay
x: leftBallastTankPosition.x
y: leftBallastTankPosition.y
radius: 2
color: "#323232"
border.width: 4
border.color: "#AEC6DD"
Rectangle {
width: leftBallastTankWidth * 0.85
height: (leftBallastTank.waterLevel / leftBallastTank.maxWaterLevel) * (leftBallastTankHeight - 8)
anchors {
bottom: parent.bottom
horizontalCenter: parent.horizontalCenter
margins: 4
}
color: fillColor
Behavior on height {
NumberAnimation {
duration: 1000
}
}
}
GCText {
id: leftBallastTankLabel
text: qsTr("Left Ballast Tank")
wrapMode: Text.WordWrap
anchors.fill: leftBallastTankDisplay
anchors.margins: 4
horizontalAlignment: Text.AlignHCenter
fontSizeMode: Text.Fit
minimumPixelSize: 8
font.pixelSize: 70
color: "#B8D3E1EB"
}
}
Image {
id: leftBallastFill
source: url + "vanne.svg"
x: leftBallastTankDisplay.x - buttonSize * 1.1
y: buttonPlusY
width: buttonSize
height: buttonSize
sourceSize.width: buttonSize
sourceSize.height: buttonSize
rotation: 0
transform: Rotation {
id: rotateLeftFill;
origin.x: leftBallastFill.width / 2;
origin.y: leftBallastFill.height / 2
axis { x: 0; y: 0; z: 1 } angle: 0
}
MouseArea {
anchors.fill: parent
enabled: !tutorial.visible
onClicked: {
leftBallastTank.fillBallastTanks()
updateVannes(leftBallastTank.waterFilling, rotateLeftFill)
}
}
}
Image {
id: leftBallastFlush
source: url + "vanne.svg"
x: leftBallastTankDisplay.x - buttonSize * 1.1
y: buttonMinusY
width: buttonSize
height: buttonSize
sourceSize.width: buttonSize
sourceSize.height: buttonSize
rotation: 0
transform: Rotation {
id: rotateLeftFlush;
origin.x: leftBallastFill.width / 2;
origin.y: leftBallastFill.height / 2
axis { x: 0; y: 0; z: 1 } angle: 0
}
MouseArea {
anchors.fill: parent
enabled: !tutorial.visible
onClicked: {
leftBallastTank.flushBallastTanks()
updateVannes(leftBallastTank.waterFlushing, rotateLeftFlush)
}
}
}
}
Item {
id: centralBallastTankController
Rectangle {
id: centralBallastTankDisplay
x: centralBallastTankPosition.x
y: centralBallastTankPosition.y
radius: 2
color: "#323232"
border.width: 4
border.color: "#AEC6DD"
Rectangle {
width: centralBallastTankWidth * 0.85
height: (centralBallastTank.waterLevel / centralBallastTank.maxWaterLevel) * (centralBallastTankHeight - 8)
anchors {
bottom: parent.bottom
horizontalCenter: parent.horizontalCenter
margins: 4
}
color: fillColor
Behavior on height {
NumberAnimation {
duration: 1000
}
}
}
GCText {
id: centralBallastTankLabel
text: qsTr("Central Ballast Tank")
wrapMode: Text.WordWrap
anchors.fill: centralBallastTankDisplay
anchors.margins: 4
horizontalAlignment: Text.AlignHCenter
fontSizeMode: Text.Fit
minimumPixelSize: 8
font.pixelSize: 70
color: "#B8D3E1EB"
}
}
Image {
id: centralBallastFill
source: url + "vanne.svg"
x: centralBallastTankDisplay.x - buttonSize * 1.1
y: buttonPlusY
width: buttonSize
height: buttonSize
sourceSize.width: buttonSize
sourceSize.height: buttonSize
rotation: 0
transform: Rotation {
id: rotateCentralFill;
origin.x: centralBallastFill.width / 2;
origin.y: centralBallastFill.height / 2
axis { x: 0; y: 0; z: 1 } angle: 0
}
MouseArea {
anchors.fill: parent
enabled: !tutorial.visible
onClicked: {
centralBallastTank.fillBallastTanks()
updateVannes(centralBallastTank.waterFilling, rotateCentralFill)
}
}
}
Image {
id: centralBallastFlush
source: url + "vanne.svg"
x: centralBallastTankDisplay.x - buttonSize * 1.1
y: buttonMinusY
width: buttonSize
height: buttonSize
sourceSize.width: buttonSize
sourceSize.height: buttonSize
rotation: 0
transform: Rotation {
id: rotateCentralFlush;
origin.x: centralBallastFill.width / 2;
origin.y: centralBallastFill.height / 2
axis { x: 0; y: 0; z: 1 } angle: 0
}
MouseArea {
anchors.fill: parent
enabled: !tutorial.visible
onClicked: {
centralBallastTank.flushBallastTanks()
updateVannes(centralBallastTank.waterFlushing, rotateCentralFlush)
}
}
}
}
Item {
id: rightBallastTankController
Rectangle {
id: rightBallastTankDisplay
x: rightBallastTankPosition.x
y: rightBallastTankPosition.y
radius: 2
color: "#323232"
border.width: 4
border.color: "#AEC6DD"
Rectangle {
width: rightBallastTankWidth * 0.85
height: (rightBallastTank.waterLevel / rightBallastTank.maxWaterLevel) * (rightBallastTankHeight - 8)
anchors {
bottom: parent.bottom
horizontalCenter: parent.horizontalCenter
margins: 4
}
color: fillColor
Behavior on height {
NumberAnimation {
duration: 1000
}
}
}
GCText {
id: rightBallastTankLabel
text: qsTr("Right Ballast Tank")
wrapMode: Text.WordWrap
anchors.fill: rightBallastTankDisplay
anchors.margins: 4
horizontalAlignment: Text.AlignHCenter
fontSizeMode: Text.Fit
minimumPixelSize: 8
font.pixelSize: 70
color: "#B8D3E1EB"
}
}
Image {
id: rightBallastFill
source: url + "vanne.svg"
x: rightBallastTankDisplay.x - buttonSize * 1.1
y: buttonPlusY
width: buttonSize
height: buttonSize
sourceSize.width: buttonSize
sourceSize.height: buttonSize
rotation: 0
transform: Rotation {
id: rotateRightFill;
origin.x: rightBallastFill.width / 2;
origin.y: rightBallastFill.height / 2
axis { x: 0; y: 0; z: 1 } angle: 0
}
MouseArea {
anchors.fill: parent
enabled: !tutorial.visible
onClicked: {
rightBallastTank.fillBallastTanks()
updateVannes(rightBallastTank.waterFilling, rotateRightFill)
}
}
}
Image {
id: rightBallastFlush
source: url + "vanne.svg"
x: rightBallastTankDisplay.x - buttonSize * 1.1
y: buttonMinusY
width: buttonSize
height: buttonSize
sourceSize.width: buttonSize
sourceSize.height: buttonSize
rotation: 0
transform: Rotation {
id: rotateRightFlush;
origin.x: rightBallastFill.width / 2;
origin.y: rightBallastFill.height / 2
axis { x: 0; y: 0; z: 1 } angle: 0
}
MouseArea {
anchors.fill: parent
enabled: !tutorial.visible
onClicked: {
rightBallastTank.flushBallastTanks()
updateVannes(rightBallastTank.waterFlushing, rotateRightFlush)
}
}
}
}
PropertyAnimation {
id: ballastTankOnAnim
properties: "angle"
from: 0
to: 90
duration: 200
}
PropertyAnimation {
id: ballastTankOffAnim
properties: "angle"
from: 90
to: 0
duration: 200
}
function updateVannes(vanneOnCondition, animationTarget) {
if (vanneOnCondition) {
ballastTankOnAnim.target = animationTarget
ballastTankOnAnim.start()
} else {
ballastTankOffAnim.target = animationTarget
ballastTankOffAnim.start()
}
}
function resetVannes() {
if (leftTankVisible) {
rotateLeftFill.angle = 0
rotateLeftFlush.angle = 0
}
if (centralTankVisible) {
rotateCentralFill.angle = 0
rotateCentralFlush.angle = 0
}
if (rightTankVisible) {
rotateRightFill.angle = 0
rotateRightFlush.angle = 0
}
}
Item {
id: divingPlaneController
visible: divingPlaneVisible
property int maxRotationAngle: 30
Image {
id: divingPlanesImage
source: url + "rudder.svg"
width: divingPlaneWidth
height: divingPlaneHeight
sourceSize.width: divingPlaneWidth
sourceSize.height: divingPlaneHeight
x: divingPlanePosition.x
y: divingPlanePosition.y
transform: Rotation {
id: rotateDivingPlanes;
origin.x: divingPlanesImage.width;
origin.y: divingPlanesImage.height / 2
axis { x: 0; y: 0; z: 1 } angle: (submarine.wingsAngle / submarine.maxWingsAngle) * divingPlaneController.maxRotationAngle
}
}
Image {
id: divingPlanesRotateUp
source: url + "up.svg"
width: buttonSize
height: buttonSize
sourceSize.width: buttonSize
sourceSize.height: buttonSize
anchors {
left: divingPlanesImage.right
// bottom: divingPlanesImage.top
}
y: buttonPlusY
MouseArea {
anchors.fill: parent
enabled: !tutorial.visible
onClicked: submarine.increaseWingsAngle(1)
}
}
Image {
id: divingPlanesRotateDown
source: url + "down.svg"
width: buttonSize
height: buttonSize
sourceSize.width: buttonSize
sourceSize.height: buttonSize
anchors {
left: divingPlanesImage.right
// top: divingPlanesImage.bottom
}
y: buttonMinusY
MouseArea {
anchors.fill: parent
enabled: !tutorial.visible
onClicked: submarine.decreaseWingsAngle(1)
}
}
}
}
diff --git a/src/activities/submarine/Submarine.qml b/src/activities/submarine/Submarine.qml
index db5a36e97..53cc64d1f 100644
--- a/src/activities/submarine/Submarine.qml
+++ b/src/activities/submarine/Submarine.qml
@@ -1,980 +1,980 @@
/* GCompris - submarine.qml
*
* Copyright (C) 2017 RUDRA NIL BASU <rudra.nil.basu.1996@gmail.com>
*
* Authors:
* Pascal Georges <pascal.georges1@free.fr> (GTK+ version)
* Rudra Nil Basu <rudra.nil.basu.1996@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import QtQuick.Particles 2.0
import Box2D 2.0
import QtGraphicalEffects 1.0
import GCompris 1.0
import "../../core"
import "submarine.js" as Activity
ActivityBase {
id: activity
onStart: focus = true
onStop: {}
property string url: "qrc:/gcompris/src/activities/submarine/resource/"
pageComponent: Image {
id: background
source: url + "background.svg"
anchors.fill: parent
sourceSize.height: parent.height
sourceSize.width: parent.width
onWidthChanged: updateOnWidthReset.start()
onHeightChanged: Activity.resetUpperGate()
- property bool hori: background.width > background.height
+ property bool hori: background.width >= background.height
signal start
signal stop
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
/* Testing purposes, A / Left Key => Reduces velocity, D / Right Key => Increases velocity */
Keys.onPressed: {
- if ((event.key == Qt.Key_D || event.key == Qt.Key_Right) && !tutorial.visible) {
+ if ((event.key === Qt.Key_D || event.key === Qt.Key_Right) && !tutorial.visible) {
submarine.increaseHorizontalVelocity(1)
}
- if ((event.key == Qt.Key_A || event.key == Qt.Key_Left) && !tutorial.visible) {
+ if ((event.key === Qt.Key_A || event.key === Qt.Key_Left) && !tutorial.visible) {
submarine.decreaseHorizontalVelocity(1)
}
- if ((event.key == Qt.Key_W || event.key == Qt.Key_Up) && !tutorial.visible) {
+ if ((event.key === Qt.Key_W || event.key === Qt.Key_Up) && !tutorial.visible) {
centralBallastTank.fillBallastTanks()
controls.updateVannes(centralBallastTank.waterFilling, controls.rotateCentralFill)
}
- if ((event.key == Qt.Key_S || event.key == Qt.Key_Down) && !tutorial.visible) {
+ if ((event.key === Qt.Key_S || event.key === Qt.Key_Down) && !tutorial.visible) {
centralBallastTank.flushBallastTanks()
controls.updateVannes(centralBallastTank.waterFlushing, controls.rotateCentralFlush)
}
- if ((event.key == Qt.Key_Plus) && !tutorial.visible) {
+ if ((event.key === Qt.Key_Plus) && !tutorial.visible) {
submarine.increaseWingsAngle(1)
}
- if ((event.key == Qt.Key_Minus) && !tutorial.visible) {
+ if ((event.key === Qt.Key_Minus) && !tutorial.visible) {
submarine.decreaseWingsAngle(1)
}
- if ((event.key == Qt.Key_R) && !tutorial.visible) {
+ if ((event.key === Qt.Key_R) && !tutorial.visible) {
leftBallastTank.fillBallastTanks()
controls.updateVannes(leftBallastTank.waterFilling, controls.rotateLeftFill)
}
- if ((event.key == Qt.Key_F) && !tutorial.visible) {
+ if ((event.key === Qt.Key_F) && !tutorial.visible) {
leftBallastTank.flushBallastTanks()
controls.updateVannes(leftBallastTank.waterFlushing, controls.rotateLeftFlush)
}
- if ((event.key == Qt.Key_T) && !tutorial.visible) {
+ if ((event.key === Qt.Key_T) && !tutorial.visible) {
rightBallastTank.fillBallastTanks()
controls.updateVannes(rightBallastTank.waterFilling, controls.rotateRightFill)
}
- if ((event.key == Qt.Key_G) && !tutorial.visible) {
+ if ((event.key === Qt.Key_G) && !tutorial.visible) {
rightBallastTank.flushBallastTanks()
controls.updateVannes(rightBallastTank.waterFlushing, controls.rotateRightFlush)
}
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property alias background: background
property alias bar: bar
property alias bonus: bonus
property alias crown: crown
property alias whale: whale
property var submarineCategory: Fixture.Category1
property var crownCategory: Fixture.Category2
property var whaleCategory: Fixture.Category3
property var upperGatefixerCategory: Fixture.Category4
property var lowerGatefixerCategory: Fixture.Category5
property var shipCategory: Fixture.Category6
property var rockCategory: Fixture.Category7
property var maxDepthCategory: Fixture.Category8
property alias submarine: submarine
property alias tutorial: tutorial
property alias upperGate: upperGate
property alias ship: ship
property alias controls: controls
property alias physicalWorld: physicalWorld
property bool processingAnswer: false
}
IntroMessage {
id: tutorial
textContainerHeight: 0.5 * parent.height
z: 100
onIntroDone: {
tutorial.visible = false
}
}
onStart: { Activity.start(items) }
onStop: { Activity.stop() }
World {
id: physicalWorld
running: !tutorial.visible && !items.processingAnswer
gravity: Qt.point(0,0)
autoClearForces: false
}
Item {
id: waterLevel
x: 0
y: background.height / 15
}
Rectangle {
id: maximumWaterDepth
width: background.width
height: 10
color: "transparent"
y: background.height * 0.65
Body {
id: maxDepthBody
target: maximumWaterDepth
bodyType: Body.Static
sleepingAllowed: true
linearDamping: 0
fixtures: Box {
categories: items.maxDepthCategory
collidesWith: items.submarineCategory
width: maximumWaterDepth.width
height: maximumWaterDepth.height
density: 1
friction: 0
restitution: 0
}
}
}
Item {
id: submarine
z: 1
property point initialPosition: Qt.point(0,waterLevel.y - submarineImage.height/2)
property bool isHit: false
property int terminalVelocityIndex: 75
property int maxAbsoluteRotationAngle: 15
/* Maximum depth the submarine can dive when ballast tank is full */
property real maximumDepthOnFullTanks: maximumWaterDepth.y * 0.45
property real ballastTankDiveSpeed: 10
/* Engine properties */
property point velocity
property int maximumXVelocity: 5
property int currentFinalVelocity: 0
/* Wings property */
property int wingsAngle
property int initialWingsAngle: 0
property int maxWingsAngle: 2
property int minWingsAngle: -2
function destroySubmarine() {
isHit = true
}
function resetSubmarine() {
isHit = false
submarineImage.reset()
leftBallastTank.resetBallastTanks()
rightBallastTank.resetBallastTanks()
centralBallastTank.resetBallastTanks()
currentFinalVelocity = 0
velocity = Qt.point(0,0)
smoothHorizontalVelocity.stop()
wingsAngle = initialWingsAngle
}
/* While increasing or decreasing, we can't use submarine.velocity.x since it is interpolating */
function increaseHorizontalVelocity(amount) {
if (submarine.currentFinalVelocity + amount <= submarine.maximumXVelocity) {
submarine.currentFinalVelocity += amount
smoothHorizontalVelocity.stop()
smoothHorizontalVelocity.setFinalVelocity(submarine.currentFinalVelocity)
smoothHorizontalVelocity.setIncreaseVelocity(true)
smoothHorizontalVelocity.start()
}
}
function decreaseHorizontalVelocity(amount) {
if (submarine.currentFinalVelocity - amount >= 0) {
submarine.currentFinalVelocity -= amount
smoothHorizontalVelocity.stop()
smoothHorizontalVelocity.setFinalVelocity(submarine.currentFinalVelocity)
smoothHorizontalVelocity.setIncreaseVelocity(false)
smoothHorizontalVelocity.start()
}
}
function increaseWingsAngle(amount) {
if (wingsAngle + amount <= maxWingsAngle) {
wingsAngle += amount
} else {
wingsAngle = maxWingsAngle
}
}
function decreaseWingsAngle(amount) {
if (wingsAngle - amount >= minWingsAngle) {
wingsAngle -= amount
} else {
wingsAngle = minWingsAngle
}
}
function changeVerticalVelocity() {
/* Check if we are currently using diving planes or ballast tanks */
var isDivingPlanesActive
if (submarineImage.y > 0 && submarine.velocity.x > 0 && wingsAngle != 0) {
/*
* Movement due to planes
* Movement is affected only when the submarine is moving forward
* When the submarine is on the surface, the planes cannot be used
*/
isDivingPlanesActive = true
} else {
isDivingPlanesActive = false
}
var yPosition
if (isDivingPlanesActive) {
/* Currently using diving planes */
var multiplier
if (wingsAngle == 1) {
multiplier = 0.6
} else if (wingsAngle == 2) {
multiplier = 0.8
} else if (wingsAngle == -1) {
multiplier = 0.2
} else if (wingsAngle == -2) {
multiplier = 0.1
}
yPosition = multiplier * maximumWaterDepth.y
} else {
/* Currently under the influence of Ballast Tanks */
yPosition = submarineImage.currentWaterLevel / submarineImage.totalWaterLevel * submarine.maximumDepthOnFullTanks
if (bar.level >= 7) {
var finalAngle = ((rightBallastTank.waterLevel - leftBallastTank.waterLevel) / leftBallastTank.maxWaterLevel) * submarine.maxAbsoluteRotationAngle
submarineRotation.angle = finalAngle
}
}
var depthToMove
if (submarineImage.y <= submarine.initialPosition.y && yPosition == 0){
depthToMove = 0
}else {
depthToMove = yPosition - submarineImage.y
}
submarine.velocity.y = ballastTankDiveSpeed * (depthToMove / background.width)
}
Timer {
id: smoothHorizontalVelocity
running: false
repeat: true
interval: 100
property real finalVelocity
property real smoothRate: 0.1
property bool increaseVelocity
function increaseVelocitySmoothly() {
if (submarine.velocity.x + smoothRate > finalVelocity) {
submarine.velocity.x = finalVelocity
smoothHorizontalVelocity.stop()
} else {
submarine.velocity.x += smoothRate
}
}
function decreaseVelocitySmoothly() {
if (submarine.velocity.x - smoothRate <= finalVelocity) {
submarine.velocity.x = finalVelocity
smoothHorizontalVelocity.stop()
} else {
submarine.velocity.x -= smoothRate
}
}
function setFinalVelocity(_finalVelocity) {
finalVelocity = _finalVelocity
}
function setIncreaseVelocity(value) {
increaseVelocity = value
}
onTriggered: {
if (increaseVelocity) {
increaseVelocitySmoothly()
} else {
decreaseVelocitySmoothly()
}
}
}
BallastTank {
id: leftBallastTank
}
BallastTank {
id: rightBallastTank
}
BallastTank {
id: centralBallastTank
}
Image {
id: submarineImage
source: submarine.isHit ? url + "submarine-broken.svg" : url + "submarine.svg"
property int currentWaterLevel: bar.level < 7 ? centralBallastTank.waterLevel : leftBallastTank.waterLevel + rightBallastTank.waterLevel
property int totalWaterLevel: bar.level < 7 ? centralBallastTank.maxWaterLevel : leftBallastTank.maxWaterLevel + rightBallastTank.maxWaterLevel
width: background.width / 9
sourceSize.width: submarineImage.width
fillMode: Image.PreserveAspectFit
function reset() {
x = submarine.initialPosition.x
y = submarine.initialPosition.y
}
onXChanged: {
if (submarineImage.x >= background.width) {
Activity.finishLevel(true)
}
}
transform: Rotation {
id: submarineRotation
origin.x: submarineImage.width / 2;
origin.y: 0;
angle: 0;
Behavior on angle {
NumberAnimation {
duration: 1000
}
}
}
Loader {
anchors.fill: parent
active: ApplicationInfo.hasShader && submarine.velocity.x > 0 && submarineImage.y > 0 && !submarine.isHit
sourceComponent: ParticleSystem {
anchors.fill: parent
Emitter {
x: parent.x
y: parent.y + parent.height / 1.75
width: 1
height: 1
emitRate: 0.8
lifeSpan: 800
lifeSpanVariation: 2500
acceleration: PointDirection {
x: -20
xVariation: 5
y: 0
yVariation: 0
}
velocity: PointDirection {
x: -20
xVariation: 10
y: 0
yVariation: 0
}
size: 12
sizeVariation: 8
}
ImageParticle {
source: "qrc:/gcompris/src/activities/clickgame/resource/bubble.png"
}
}
}
}
Body {
id: submarineBody
target: submarineImage
bodyType: Body.Dynamic
fixedRotation: true
linearDamping: 0
linearVelocity: submarine.isHit ? Qt.point(0,0) : submarine.velocity
fixtures: [
Box {
id: submarineFixer
y: submarineImage.height * 0.50
width: submarineImage.width
height: submarineImage.height * 0.50
categories: items.submarineCategory
collidesWith: Fixture.All
density: 1
friction: 0
restitution: 0
onBeginContact: {
var collidedObject = other.getBody().target
if (collidedObject == whale) {
whale.hit()
}
if (collidedObject == crown) {
crown.captureCrown()
} else {
Activity.finishLevel(false)
}
}
},
Box {
id: submarinePeriscopeFixer
x: submarineImage.width * 0.5
width: submarineImage.width * 0.25
height: submarineImage.height
categories: items.submarineCategory
collidesWith: Fixture.All
density: 1
friction: 0
restitution: 0
onBeginContact: {
var collidedObject = other.getBody().target
- if (collidedObject == whale) {
+ if (collidedObject === whale) {
whale.hit()
}
- if (collidedObject == crown) {
+ if (collidedObject === crown) {
crown.captureCrown()
} else {
Activity.finishLevel(false)
}
}
}
]
}
Timer {
id: updateVerticalVelocity
interval: 50
running: true
repeat: true
onTriggered: submarine.changeVerticalVelocity()
}
}
Image {
id: sparkle
source: "qrc:/gcompris/src/activities/mining/resource/sparkle.svg"
x: crown.x
y: crown.y
z: 1
width: crown.width
height: width * 0.7
property bool isCaptured: false
scale: isCaptured ? 1 : 0
function createSparkle() {
isCaptured = true
removeSparkleTimer.start()
}
function removeSparkle() {
isCaptured = false
}
Behavior on scale {
NumberAnimation {
duration: 100
}
}
Timer {
id: removeSparkleTimer
interval: 3000
repeat: false
running: false
onTriggered: sparkle.removeSparkle()
}
}
Rectangle {
id: upperGate
visible: (bar.level > 1) ? true : false
width: background.width / 18
height: isGateOpen ? background.height * (5 / 36) : background.height * (5 / 12) + 4
y: -2
z: 2
color: "#9E948A"
border.color: "#766C62"
border.width: 2
anchors.right: background.right
anchors.rightMargin: -2
property bool isGateOpen: false
Body {
id: upperGateBody
target: upperGate
bodyType: Body.Static
sleepingAllowed: true
fixedRotation: true
linearDamping: 0
fixtures: Box {
id: upperGatefixer
width: upperGate.width
height: upperGate.height
categories: items.upperGatefixerCategory
collidesWith: upperGate.visible ? items.submarineCategory : Fixture.None
density: 1
friction: 0
restitution: 0
}
}
Behavior on height {
NumberAnimation {
duration: 1000
}
}
}
Rectangle {
id: lowerGate
z: 1
visible: upperGate.visible
width: background.width / 18
height: background.height * (5 / 12) - subSchemaImage.height / 1.4
y: background.height * (5 / 12)
color: "#9E948A"
border.color: "#766C62"
border.width: 2
anchors.right:background.right
anchors.rightMargin: -2
Body {
id: lowerGateBody
target: lowerGate
bodyType: Body.Static
sleepingAllowed: true
fixedRotation: true
linearDamping: 0
fixtures: Box {
id: lowerGatefixer
width: lowerGate.width
height: lowerGate.height
categories: items.lowerGatefixerCategory
collidesWith: lowerGate.visible ? items.submarineCategory : Fixture.None
density: 1
friction: 0
restitution: 0
}
}
}
Rectangle {
id: subSchemaImage
width: background.width/1.3
height: background.height/4
x: background.width/9
y: background.height/1.5
visible: false
}
Image {
id: crown
width: submarineImage.width * 0.85
height: crown.width * 0.5
sourceSize.width: crown.width
sourceSize.height: crown.height
visible: ((bar.level > 2) && !isCaptured) ? true : false
source: url + "crown.svg"
property bool isCaptured: false
function captureCrown() {
upperGate.isGateOpen = true
isCaptured = true
sparkle.createSparkle()
}
function reset() {
isCaptured = false
upperGate.isGateOpen = false
}
x: background.width / 2
y: background.height - (subSchemaImage.height * 2)
z: 1
Body {
id: crownbody
target: crown
bodyType: Body.Static
sleepingAllowed: true
fixedRotation: true
linearDamping: 0
fixtures: Box {
id: crownfixer
width: crown.width
height: crown.height
sensor: true
categories: items.crownCategory
collidesWith: crown.visible ? items.submarineCategory : Fixture.None
density: 0.1
friction: 0
restitution: 0
}
}
}
Whale {
id: whale
visible: (bar.level > 5) ? true : false
y: rock2.y - (rock2.height * 1.15)
z: 1
leftLimit: 0
rightLimit: background.width - whale.width - (upperGate.visible ? upperGate.width : 0)
}
Image {
id: ship
width: background.width / 9
sourceSize.width: ship.width
fillMode: Image.PreserveAspectFit
visible: (bar.level > 3) ? true : false
source: collided ? url + "boat-hit.svg" : url + "boat.svg"
x: initialXPosition
z: 1
anchors.bottom: waterLevel.top
property bool movingLeft: true
property bool collided: false
property real initialXPosition: background.width - ship.width - (upperGate.visible ? upperGate.width : 0)
property real horizontalSpeed: 1
function reset() {
ship.collided = false
ship.x = initialXPosition
}
function collide() {
/* Add few visual effects */
collided = true
}
transform: Rotation {
id: rotateShip
origin.x: ship.width / 2;
origin.y: 0;
axis { x: 0; y: 1; z: 0 } angle: 0
}
SequentialAnimation {
id: rotateShipLeft
loops: 1
PropertyAnimation {
target: rotateShip
properties: "angle"
from: 0
to: 180
duration: 500
}
}
SequentialAnimation {
id: rotateShipRight
loops: 1
PropertyAnimation {
target: rotateShip
properties: "angle"
from: 180
to: 0
duration: 500
}
}
onXChanged: {
if (x <= 0) {
rotateShipLeft.start()
movingLeft = false
} else if (x >= background.width - ship.width - (upperGate.visible ? upperGate.width : 0)) {
rotateShipRight.start()
movingLeft = true
}
}
Body {
id: shipbody
target: ship
bodyType: Body.Dynamic
sleepingAllowed: true
fixedRotation: true
linearDamping: 0
linearVelocity: Qt.point( (ship.collided ? 0 : ((ship.movingLeft ? -1 : 1) * ship.horizontalSpeed)), 0)
fixtures: Box {
id: shipfixer
width: ship.width
height: ship.height
categories: items.shipCategory
collidesWith: ship.visible ? items.submarineCategory : Fixture.None
density: 1
friction: 0
restitution: 0
onBeginContact: ship.collide()
}
}
}
Image {
id: rock2
width: background.width / 6
height: rock2.width * 0.48
z: 5
visible: (bar.level > 4) ? true : false
anchors.bottom: crown.bottom
anchors.left: crown.right
source: "qrc:/gcompris/src/activities/mining/resource/stone2.svg"
transform: Rotation {
origin.x: rock2.width / 2;
origin.y: rock2.height / 2
axis { x: 0; y: 0; z: 1 } angle: 180
}
Body {
id: rock2Body
target: rock2
bodyType: Body.Static
sleepingAllowed: true
linearDamping: 0
fixtures: Box {
id: rock2Fixer
categories: items.rockCategory
collidesWith: rock2.visible ? items.submarineCategory : Fixture.None
x: rock2.width / 8
y: rock2.height / 12
width: rock2.width / 1.2
height: rock2.height / 1.5
density: 1
friction: 0
restitution: 0
}
}
}
/* Just a space */
Rectangle {
id: space
width: bar.level < 8 ? rock1.width : rock1.width * (1 - (Math.random() * 0.5))
height: rock1.height
color: "transparent"
anchors {
right: crown.left
bottom: crown.bottom
}
}
Image {
id: rock1
width: rock2.width
height: rock2.width * 0.46
z: 5
visible: (bar.level > 6) ? true : false
anchors.bottom: crown.bottom
anchors.right: space.left
source: "qrc:/gcompris/src/activities/mining/resource/stone1.svg"
Body {
id: rock1Body
target: rock1
bodyType: Body.Static
sleepingAllowed: true
linearDamping: 0
fixtures: [
Circle {
id: rock1FixerLeft
categories: items.rockCategory
collidesWith: rock1.visible ? items.submarineCategory : Fixture.None
x: rock1.width / 10
radius: rock1.width / 4
density: 1
friction: 0
restitution: 0
},Circle {
id: rock1FixerRight
categories: items.rockCategory
collidesWith: rock1.visible ? items.submarineCategory : Fixture.None
x: rock1.width / 1.6
y: rock1.height / 4
radius: rock1.width / 6
density: 1
friction: 0
restitution: 0
}
]
}
}
Image {
id: rock3
width: background.width
height: background.height * 0.25
sourceSize.width: rock3.width
sourceSize.height: rock3.height
visible: (bar.level > 2) ? true : false
anchors.top: crown.top
anchors.horizontalCenter: crown.left
// anchors.topMargin: height * 0.5
source: url + "rocks.svg"
}
Timer {
/*
* A delay is used since on setting fullscreen on/off
* first the onWidthChanged is executed, followed by
* the width change
*/
id: updateOnWidthReset
repeat: false
interval: 100
running: false
onTriggered: {
whale.reset()
ship.reset()
}
}
Controls {
id: controls
z: 10
enginePosition.x: background.width * 0.1
enginePosition.y: buttonPlusY + buttonSize * 0.2
engineWidth: background.width / 8
engineHeight: hori ? buttonSize * 1.8 : buttonSize * 2.5
submarineHorizontalSpeed: submarine.currentFinalVelocity * 1000
leftTankVisible: bar.level >= 7 ? true : false
leftBallastTankPosition.x: background.width * 0.35
leftBallastTankPosition.y: enginePosition.y
leftBallastTankWidth: background.width / 8
leftBallastTankHeight: engineHeight
centralTankVisible: bar.level < 7 ? true : false
centralBallastTankPosition.x: background.width * 0.45
centralBallastTankPosition.y: enginePosition.y
centralBallastTankWidth: background.width / 8
centralBallastTankHeight: engineHeight
rightTankVisible: bar.level >= 7 ? true : false
rightBallastTankPosition.x: background.width * 0.6
rightBallastTankPosition.y: enginePosition.y
rightBallastTankWidth: background.width / 8
rightBallastTankHeight: engineHeight
divingPlaneVisible: true
divingPlanePosition.x: background.width * 0.8
divingPlanePosition.y: enginePosition.y + (engineHeight * 0.5) - (divingPlaneHeight * 0.5)
divingPlaneWidth: hori ? background.width * 0.08 : background.width * 0.12
divingPlaneHeight: divingPlaneWidth * 0.33
buttonSize: hori ? subSchemaImage.height * 0.3 : subSchemaImage.height * 0.2
buttonPlusY: hori ? background.height * 0.61 : background.height * 0.63
buttonMinusY: enginePosition.y + engineHeight - buttonSize * 0.8
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level }
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
}
Bonus {
id: bonus
onLoose: Activity.initLevel()
Component.onCompleted: win.connect(Activity.nextLevel)
}
/*
DebugDraw {
id: debugDraw
world: physicalWorld
anchors.fill: parent
opacity: 0.75
visible: false
}
MouseArea {
id: debugMouseArea
anchors.fill: parent
onPressed: debugDraw.visible = !debugDraw.visible
}
*/
}
}
diff --git a/src/activities/submarine/Whale.qml b/src/activities/submarine/Whale.qml
index 7a8a4023e..f61b7c18e 100644
--- a/src/activities/submarine/Whale.qml
+++ b/src/activities/submarine/Whale.qml
@@ -1,147 +1,147 @@
/* GCompris - Whale.qml
*
* Copyright (C) 2017 RUDRA NIL BASU <rudra.nil.basu.1996@gmail.com>
*
* Authors:
* Pascal Georges <pascal.georges1@free.fr> (GTK+ version)
* Rudra Nil Basu <rudra.nil.basu.1996@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import QtQuick.Particles 2.0
import Box2D 2.0
import QtGraphicalEffects 1.0
import GCompris 1.0
Image {
id: whale
source: isHit ? url + "whale-hit.svg" : url + "whale.svg"
width: submarineImage.width * 1.2
sourceSize.width: whale.width
fillMode: Image.PreserveAspectFit
property bool isHit: false
function hit() {
isHit = true
}
function reset() {
isHit = false
x = rightLimit
}
property bool movingLeft: true
property real leftLimit
property real rightLimit
transform: Rotation {
id: rotate;
origin.x: whale.width / 2;
origin.y: 0;
axis { x: 0; y: 1; z: 0 } angle: 0
}
SequentialAnimation {
id: rotateLeftAnimation
loops: 1
PropertyAnimation {
target: rotate
properties: "angle"
from: 0
to: 180
duration: 500
}
}
SequentialAnimation {
id: rotateRightAnimation
loops: 1
PropertyAnimation {
target: rotate
properties: "angle"
from: 180
to: 0
duration: 500
}
}
onXChanged: {
if (x <= leftLimit) {
rotateLeftAnimation.start()
whale.movingLeft = false
} else if (x >= rightLimit) {
rotateRightAnimation.start()
whale.movingLeft = true
}
}
Loader {
id: bubbleEffect
anchors.fill: parent
active: ApplicationInfo.hasShader
sourceComponent: ParticleSystem {
anchors.fill: parent
Emitter {
x: parent.x
y: parent.y + parent.height / 2
width: 1
height: 1
emitRate: 0.5
lifeSpan: 1000
lifeSpanVariation: 2500
acceleration: PointDirection {
x: -10
xVariation: 10
y: -20
yVariation: 10
}
velocity: PointDirection {
x: 20
xVariation: 10
y: -20
yVariation: 10
}
size: 12
sizeVariation: 8
}
ImageParticle {
source: "qrc:/gcompris/src/activities/clickgame/resource/bubble.png"
}
}
}
Body {
target: whale
bodyType: Body.Dynamic
sleepingAllowed: true
fixedRotation: true
linearDamping: 0
linearVelocity: isHit ? Qt.point(0,0) : Qt.point( (whale.movingLeft ? -1 : 1) , 0)
fixtures: Box {
width: whale.width * 0.7
height: whale.height * 0.8
y: whale.height * 0.1
categories: items.whaleCategory
collidesWith: whale.visible ? items.submarineCategory : Fixture.None
density: 1
friction: 0
restitution: 0
}
}
}
diff --git a/src/activities/submarine/submarine.js b/src/activities/submarine/submarine.js
index 05ac4e42e..e38a3d4af 100644
--- a/src/activities/submarine/submarine.js
+++ b/src/activities/submarine/submarine.js
@@ -1,137 +1,137 @@
/* GCompris - submarine.js
*
* Copyright (C) 2017 Rudra Nil Basu <rudra.nil.basu.1996@gmail.com>
*
* Authors:
* Pascal Georges <pascal.georges1@free.fr> (GTK+ version)
* Rudra Nil Basu <rudra.nil.basu.1996@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import GCompris 1.0 as GCompris
.import QtQuick 2.6 as Quick
var currentLevel = 0
var numberOfLevel = 10
var items
var tutorials = [
[
qsTr("Move the submarine to the other side of the screen."),
qsTr("The leftmost item in the control panel is the engine of the submarine, indicating the current speed of the submarine."),
qsTr("Increase or decrease the velocity of the submarine using the engine."),
qsTr("Press the + button to increase the velocity, or the - button to decrease the velocity."),
],
[
qsTr("The item next to the engine is the Ballast tanks."),
qsTr("The Ballast tanks are used to float or dive under water."),
qsTr("If the ballast tanks are empty, the submarine will float. If the ballast tanks are full of water, the submarine will dive underwater."),
qsTr("Turning the upper valve on or off will alternatively allow or stop water from filling in the Ballast tanks, thus allowing it to dive underwater."),
qsTr("Turning the lower valve on or off will alternatively allow or stop water from flushing out the Ballast tanks, thus allowing it to float on the surface of the water."),
],
[
qsTr("The rightmost item in the control panel controls the diving planes of the submarine"),
qsTr("The Diving Planes in a submarine is used to control the depth of the submarine accurately once it is underwater."),
qsTr("Once the submarine is moving underwater, increasing or decreasing the angle of the planes will increase and decrease the depth of the submarine."),
qsTr("The + button will increase the depth of the submarine, while the - button will decrease the depth of the submarine."),
qsTr("Grab the crown to open the gate."),
qsTr("Check out the help menu for the keyboard controls."),
]
]
function start(items_) {
items = items_
currentLevel = 0
initLevel()
}
function stop() {
}
function initLevel() {
items.bar.level = currentLevel + 1
/* Tutorial Levels, display tutorials */
if (currentLevel < tutorials.length) {
items.tutorial.visible = true
items.tutorial.index = 0
items.tutorial.intro = tutorials[currentLevel]
} else {
items.tutorial.visible = false
}
setUpLevelElements()
}
function setUpLevelElements() {
/* Set up initial position and state of the submarine */
items.submarine.resetSubmarine()
if(items.ship.visible) {
items.ship.reset()
}
items.crown.reset()
items.whale.reset()
items.controls.resetVannes()
items.processingAnswer = false
resetUpperGate()
}
function resetUpperGate() {
if (items && items.crown && !items.crown.visible && items.upperGate && items.upperGate.visible) {
items.upperGate.isGateOpen = true
}
}
function closeGate() {
if (items.upperGate.visible) {
items.upperGate.isGateOpen = false
}
}
function finishLevel(win) {
if (items.processingAnswer)
return
items.processingAnswer = true
if (win) {
items.bonus.good("flower")
} else {
items.submarine.destroySubmarine()
items.bonus.bad("flower")
}
}
function nextLevel() {
items.processingAnswer = true
closeGate()
if(numberOfLevel <= ++currentLevel) {
currentLevel = 0
}
initLevel();
}
function previousLevel() {
items.processingAnswer = true
closeGate()
if(--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
initLevel();
}
diff --git a/src/activities/sudoku/ActivityInfo.qml b/src/activities/sudoku/ActivityInfo.qml
index c8fa74930..6d678c8fc 100644
--- a/src/activities/sudoku/ActivityInfo.qml
+++ b/src/activities/sudoku/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Johnny Jazeix <jazeix@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "sudoku/Sudoku.qml"
difficulty: 4
icon: "sudoku/sudoku.svg"
author: "Johnny Jazeix &lt;jazeix@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Sudoku, place unique symbols in a grid")
//: Help title
description: qsTr("Symbols must be unique in a row, in a column, and (if defined) each region.")
// intro: "Select a number or a symbol and click its target area. Each symbol must appear only once in a row, in a column and in a subregion if any."
//: Help goal
goal: qsTr("The aim of the puzzle is to enter a symbol or numeral from 1 through 9 in each cell of a grid. In the official Sudoku the grid is 9x9 made up of 3x3 subgrids (called 'regions'). In GCompris we start at lower levels with a simpler version using symbols and with no regions. In all cases the grid is presented with various symbols or numerals given in some cells (the 'givens'). Each row, column and region must contain only one instance of each symbol or numeral (Source &lt;http://en.wikipedia.org/wiki/Sudoku&gt;).")
//: Help prerequisite
prerequisite: qsTr("Completing the puzzle requires patience and logical ability")
//: Help manual
manual: qsTr("Select a number or a symbol on the left and click on its target position. GCompris will not let you enter invalid data.")
credit: ""
section: "puzzle"
createdInVersion: 0
}
diff --git a/src/activities/sudoku/Sudoku.qml b/src/activities/sudoku/Sudoku.qml
index 3611eb463..f41b67c92 100644
--- a/src/activities/sudoku/Sudoku.qml
+++ b/src/activities/sudoku/Sudoku.qml
@@ -1,210 +1,210 @@
/* gcompris - Sudoku.qml
Copyright (C) 2014 Johnny Jazeix <jazeix@gmail.com>
2003, 2014: Bruno Coudoin: initial version
2014: Johnny Jazeix: Qt port
This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "sudoku.js" as Activity
import "."
ActivityBase {
id: activity
focus: true
onStart: {focus=true}
onStop: {}
pageComponent: Image {
id: background
anchors.fill: parent
source: Activity.url + "background.svg"
sourceSize.width: Math.max(parent.width, parent.height)
fillMode: Image.PreserveAspectCrop
signal start
signal stop
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
focus = true
}
property int nbRegions
QtObject {
id: items
property alias background: background
property alias bar: bar
property alias bonus: bonus
property alias score: score
property GCSfx audioEffects: activity.audioEffects
property alias availablePiecesModel: availablePieces
property alias columns: sudoColumn.columns
property alias rows: sudoColumn.rows
property alias sudokuModel: sudokuModel
}
onStart: Activity.start(items)
onStop: { Activity.stop() }
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level | reload }
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onReloadClicked: Activity.initLevel()
onHomeClicked: activity.home()
}
Bonus {
id: bonus
z: 1002
Component.onCompleted: win.connect(Activity.incrementLevel)
}
Score {
id: score
z: 1003
anchors.bottom: background.bottom
anchors.right: background.right
}
Keys.onPressed: {
Activity.onKeyPressed(event);
}
SudokuListWidget {
id: availablePieces
audioEffects: activity.audioEffects
}
ListModel {
id: sudokuModel
}
Grid {
z: 100
anchors {
left: availablePieces.right
top: parent.top
topMargin: 2 * ApplicationInfo.ratio
}
id: sudoColumn
width: Math.min(background.width - availablePieces.width -
availablePieces.anchors.leftMargin,
background.height - 2 * bar.height)
height: width
Repeater {
id: repeater
model: sudokuModel
delegate: blueSquare
Component {
id: blueSquare
SudokuCase {
x: (index%sudoColumn.columns)*width
y: Math.floor(index/sudoColumn.columns)*height
width: parent != null ? parent.width / sudoColumn.columns : 1
height: parent != null ? parent.height/ sudoColumn.columns : 1
gridIndex: index
isInitial: initial
text: textValue
state: mState
}
}
}
}
MouseArea {
id: dynamic
anchors.fill: sudoColumn
hoverEnabled: true
property int previousHoveredCase: -1
onPositionChanged: {
var x = Math.floor(sudoColumn.rows * mouseX / (sudoColumn.width+1));
var y = Math.floor(sudoColumn.columns * mouseY / (sudoColumn.height+1));
var id = x + y * sudoColumn.rows;
// Only color if we can modify the case
- if(sudokuModel.get(id).mState == "default")
+ if(sudokuModel.get(id).mState === "default")
sudokuModel.get(id).mState = "hovered";
// Restore previous case if different from the new one
if(previousHoveredCase != id) {
- if(previousHoveredCase != -1 && sudokuModel.get(previousHoveredCase).mState == "hovered")
+ if(previousHoveredCase != -1 && sudokuModel.get(previousHoveredCase).mState === "hovered")
sudokuModel.get(previousHoveredCase).mState = "default"
previousHoveredCase = id
}
}
onExited: {
- if(previousHoveredCase != -1 && sudokuModel.get(previousHoveredCase).mState == "hovered")
+ if(previousHoveredCase != -1 && sudokuModel.get(previousHoveredCase).mState === "hovered")
sudokuModel.get(previousHoveredCase).mState = "default"
previousHoveredCase = -1
}
onClicked: {
var x = Math.floor(sudoColumn.rows * mouseX / sudoColumn.width);
var y = Math.floor(sudoColumn.columns * mouseY / sudoColumn.height);
Activity.clickOn(x, y)
}
}
Grid {
z: 1001
id: regionGrid
columns: rows
rows: nbRegions
visible: nbRegions > 1
anchors.fill: sudoColumn
Repeater {
id: regionRepeater
model: nbRegions*nbRegions
Rectangle {
z: 1001
color: "transparent"
border.color: "orange"
border.width: 4
x: index / nbRegions * sudoColumn.width
y: (index % nbRegions) * sudoColumn.width
width: nbRegions * sudoColumn.width / sudoColumn.columns
height: nbRegions * sudoColumn.height/ sudoColumn.columns
}
}
}
}
}
diff --git a/src/activities/sudoku/SudokuCase.qml b/src/activities/sudoku/SudokuCase.qml
index 4539c320e..69d762aa7 100644
--- a/src/activities/sudoku/SudokuCase.qml
+++ b/src/activities/sudoku/SudokuCase.qml
@@ -1,87 +1,87 @@
/* gcompris - SudokuCase.qml
Copyright (C) 2014 Johnny Jazeix <jazeix@gmail.com>
2003, 2014: Bruno Coudoin: initial version
2014: Johnny Jazeix: Qt port
This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "sudoku.js" as Activity
import GCompris 1.0
Rectangle {
id: mCase
border.width: 2
border.color: "#2a2a2a"
property string text
property bool isInitial
property int gridIndex
Image {
id: imageId
source: Activity.dataToImageSource(mCase.text)
sourceSize.height: parent.height
width: 3 * parent.width / 4
height: width
anchors.centerIn: parent
}
states: [
State {
name: "default"
PropertyChanges {
target: mCase
color: "#33333333"
}
},
State {
name: "error"
PropertyChanges {
target: mCase
color: "#AAEE1111"
}
PropertyChanges {
target: restoreColorTimer
running: true
}
},
State {
name: "hovered"
PropertyChanges {
target: mCase
color: "#EE1111EE"
}
},
State {
name: "initial"
PropertyChanges {
target: mCase
color: "#AA996699"
}
}
]
Timer {
id: restoreColorTimer
interval: 1500
repeat: false
onTriggered: {
Activity.restoreState(mCase)
}
}
}
diff --git a/src/activities/sudoku/SudokuListWidget.qml b/src/activities/sudoku/SudokuListWidget.qml
index 6ebe747e2..f95661441 100644
--- a/src/activities/sudoku/SudokuListWidget.qml
+++ b/src/activities/sudoku/SudokuListWidget.qml
@@ -1,155 +1,155 @@
/* gcompris - SudokuListWidget.qml
Copyright (C) 2014 Johnny Jazeix <jazeix@gmail.com>
2003, 2014: Bruno Coudoin: initial version
2014: Johnny Jazeix: Qt port
This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "sudoku.js" as Activity
import "../../core"
Item {
id: listWidget
width: view.width
height: view.height
anchors {
left: parent.left
leftMargin: 2 * ApplicationInfo.ratio
top: parent.top
topMargin: 2 * ApplicationInfo.ratio
}
property alias model: mymodel;
property alias view: view;
property GCSfx audioEffects
ListModel {
id: mymodel
}
ListView {
id: view
width: background.width / 5
height: background.height - 2 * bar.height
interactive: false
spacing: 10
model: mymodel
delegate: contactsDelegate
property int iconSize: Math.min((height - mymodel.count * spacing) /
mymodel.count,
view.width * 0.95)
Component {
id: contactsDelegate
Item {
width: view.iconSize
height: view.iconSize
Image {
id: icon
anchors.centerIn: parent
sourceSize.height: view.iconSize
source: model.imgName === undefined ? "" :
Activity.url + model.imgName + extension
z: iAmSelected ? 10 : 1
property bool iAmSelected: view.currentIndex == index
states: [
State {
name: "notclicked"
when: !icon.iAmSelected && !mouseArea.containsMouse
PropertyChanges {
target: icon
scale: 0.8
}
},
State {
name: "clicked"
when: mouseArea.pressed
PropertyChanges {
target: icon
scale: 0.7
}
},
State {
name: "hover"
when: mouseArea.containsMouse
PropertyChanges {
target: icon
scale: 1.1
}
},
State {
name: "selected"
when: icon.iAmSelected
PropertyChanges {
target: icon
scale: 1
}
}
]
SequentialAnimation {
id: anim
running: icon.iAmSelected
loops: Animation.Infinite
alwaysRunToEnd: true
NumberAnimation {
target: icon
property: "rotation"
from: 0; to: 10
duration: 200
easing.type: Easing.OutQuad
}
NumberAnimation {
target: icon
property: "rotation"
from: 10; to: -10
duration: 400
easing.type: Easing.InOutQuad
}
NumberAnimation {
target: icon
property: "rotation"
from: -10; to: 0
duration: 200
easing.type: Easing.InQuad
}
}
Behavior on scale { NumberAnimation { duration: 70 } }
MouseArea {
id: mouseArea
anchors.fill: icon
hoverEnabled: true
onClicked: {
listWidget.audioEffects.play('qrc:/gcompris/src/core/resource/sounds/scroll.wav')
view.currentIndex = index
}
}
}
}
}
}
}
diff --git a/src/activities/sudoku/sudoku.js b/src/activities/sudoku/sudoku.js
index 667a284d9..46140b468 100644
--- a/src/activities/sudoku/sudoku.js
+++ b/src/activities/sudoku/sudoku.js
@@ -1,857 +1,857 @@
/* gcompris - sudoku.js
Copyright (C)
2003, 2014: Bruno Coudoin: initial version
2014: Johnny Jazeix: Qt port
This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
.import "qrc:/gcompris/src/core/core.js" as Core
// Hard coded level definitions
var levels = [
[ // Level 1
[
['.','C','B'],
['.','B','A'],
['.','A','C']
],
[
['C','A','B'],
['.','.','.'],
['B','C','A']
],
[
['C','A','B'],
['A','B','C'],
['.','.','.']
],
[
['A','.','C'],
['C','.','B'],
['B','.','A']
],
[
['A','.','C'],
['B','C','.'],
['.','A','B']
],
[
['A','B','C'],
['B','.','A'],
['.','A','.']
],
[
['.','B','A'],
['B','.','C'],
['A','C','.']
], [
['A','B','C'],
['.','C','A'],
['.','A','.']
],
],
[ // Level 2
[
['A','.','.'],
['D','.','.'],
['C','A','.'],
],
[
['C','.','D'],
['.','.','B'],
['.','D','C'],
],
[
['.','B','D'],
['D','.','.'],
['B','.','C'],
],
[
['A','.','.'],
['.','D','A'],
['D','.','C'],
],
[
['C','.','D'],
['.','C','.'],
['B','.','C'],
],
],
[ // Level 3
[
['.','A','.'],
['A','C','.'],
['.','B','.'],
],
[
['B','A','.'],
['A','C','.'],
['.','.','.'],
],
[
['.','A','C'],
['.','.','B'],
['C','.','.'],
],
[
['.','.','C'],
['D','.','A'],
['C','.','.'],
],
[
['.','.','C'],
['D','.','A'],
['.','A','.'],
],
],
[ // Level 4
[
['.','B','C','D'],
['D','C','.','A'],
['.','D','A','B'],
['B','A','.','C'],
],
[
['A','.','.','D'],
['D','C','B','.'],
['C','D','A','.'],
['.','.','D','C'],
],
[
['.','B','.','.'],
['.','C','B','A'],
['C','D','A','.'],
['.','.','D','.'],
],
[
['.','B','A','.'],
['D','.','B','C'],
['A','C','.','B'],
['.','D','C','.']
],
[
['.','.','.','.'],
['D','A','B','C'],
['A','C','D','B'],
['.','.','.','.']
],
],
[ // Level 5
[
['.','.','.','.'],
['D','A','B','.'],
['C','.','A','B'],
['.','.','.','D']
],
[
['A','B','C','D'],
['.','.','.','.'],
['.','.','.','.'],
['B','C','D','A']
],
[
['.','.','A','D'],
['D','.','.','C'],
['A','.','.','B'],
['B','D','.','.']
],
[
['.','.','A','.'],
['D','A','B','.'],
['.','C','D','B'],
['.','D','.','.']
],
[
['C','B','.','D'],
['.','.','.','C'],
['A','.','.','.'],
['B','.','C','A']
],
],
[ // Level 6
[
['C','.','.','D'],
['.','.','B','.'],
['A','.','.','.'],
['.','.','D','.']
],
[
['.','B','.','A'],
['.','.','B','.'],
['C','.','D','.'],
['.','.','.','C']
],
[
['A','.','B','.'],
['.','C','.','A'],
['.','.','.','D'],
['D','.','C','.']
],
[
['.','A','.','.'],
['C','.','A','B'],
['.','.','C','.'],
['D','.','.','A']
],
[
['C','.','.','D'],
['B','.','A','.'],
['.','B','.','A'],
['.','.','.','.']
],
[
['.','A','C','.'],
['.','.','.','D'],
['C','.','.','A'],
['.','B','.','.']
],
[
['.','C','.','D'],
['B','.','.','.'],
['.','.','.','.'],
['C','A','.','B']
],
[
['B','.','.','C'],
['.','A','.','.'],
['.','.','D','.'],
['.','B','.','.']
],
],
[ // Level 7
[
['A','B','C','D','E'],
['.','A','B','C','D'],
['.','.','A','B','C'],
['.','.','.','A','B'],
['.','.','.','.','A']
],
[
['A','B','.','D','.'],
['.','.','D','E','A'],
['C','.','.','A','.'],
['D','E','.','.','C'],
['.','A','B','.','D']
],
[
['.','C','.','A','.'],
['A','.','B','.','C'],
['.','B','.','C','.'],
['D','.','C','.','A'],
['.','A','E','.','B']
],
[
['C','B','.','.','D'],
['.','.','D','C','.'],
['D','.','B','.','E'],
['.','A','.','D','C'],
['E','.','.','B','.']
],
[
['D','.','.','B','E'],
['.','E','A','.','.'],
['A','C','.','.','B'],
['.','.','B','C','.'],
['C','B','.','A','.']
],
[
['.','.','C','D','.'],
['B','.','.','.','C'],
['.','C','.','B','D'],
['C','.','D','A','.'],
['D','E','.','.','A']
],
],
[ // Level 8
[
['1','2','3','4','5'],
['.','1','2','3','4'],
['.','.','1','2','3'],
['.','.','.','1','2'],
['.','.','.','.','1']
],
[
['1','2','.','4','.'],
['.','.','4','5','1'],
['3','.','.','1','.'],
['4','5','.','.','3'],
['.','1','2','.','4']
],
[
['.','3','.','1','.'],
['1','.','2','.','3'],
['.','2','.','3','.'],
['4','.','3','.','1'],
['.','1','5','.','2']
],
[
['3','2','.','.','4'],
['.','.','4','3','.'],
['4','.','2','.','5'],
['.','1','.','4','3'],
['5','.','.','2','.']
],
[
['4','.','.','2','5'],
['.','5','1','.','.'],
['1','3','.','.','2'],
['.','.','2','3','.'],
['3','2','.','1','.']
],
[
['.','.','3','4','.'],
['2','.','.','.','3'],
['.','3','.','2','4'],
['3','.','4','1','.'],
['4','5','.','.','1']
],
],
[ // Level 9
[
['8', '9', '3', '4', '5', '2', '6', '7', '1'],
['7', '1', '6', '3', '9', '8', '5', '.', '2'],
['2', '4', '5', '1', '7', '6', '9', '8', '3'],
['5', '2', '1', '8', '4', '9', '3', '6', '7'],
['9', '6', '.', '2', '3', '7', '1', '5', '8'],
['3', '8', '7', '5', '6', '1', '4', '2', '9'],
['4', '7', '.', '9', '1', '5', '8', '.', '6'],
['6', '5', '9', '7', '8', '3', '2', '1', '4'],
['1', '3', '8', '6', '.', '4', '.', '9', '5']
],
[
['7', '9', '4', '6', '3', '5', '8', '1', '2'],
['8', '3', '2', '4', '9', '1', '5', '7', '6'],
['6', '1', '5', '.', '8', '2', '4', '.', '3'],
['5', '2', '8', '1', '7', '3', '6', '4', '9'],
['4', '7', '3', '2', '6', '9', '1', '5', '8'],
['9', '6', '1', '8', '5', '4', '3', '2', '7'],
['3', '8', '9', '5', '1', '7', '2', '6', '4'],
['2', '5', '6', '.', '4', '.', '7', '3', '1'],
['1', '4', '7', '3', '2', '6', '9', '8', '5'],
],
[
['5', '6', '2', '1', '7', '9', '4', '3', '8'],
['.', '3', '4', '8', '5', '6', '7', '1', '2'],
['1', '8', '7', '4', '3', '2', '5', '9', '6'],
['6', '9', '.', '7', '1', '5', '3', '2', '4'],
['4', '1', '3', '9', '2', '8', '6', '.', '5'],
['7', '2', '5', '3', '6', '4', '9', '8', '1'],
['8', '5', '9', '2', '4', '3', '1', '6', '7'],
['2', '7', '6', '5', '9', '1', '8', '4', '3'],
['3', '4', '1', '.', '8', '7', '2', '5', '9'],
],
[
['2', '1', '6', '4', '7', '8', '9', '5', '3'],
['4', '9', '7', '.', '5', '3', '2', '6', '8'],
['5', '3', '8', '2', '6', '9', '4', '1', '7'],
['8', '.', '4', '9', '3', '6', '1', '7', '5'],
['6', '5', '.', '7', '4', '1', '8', '2', '9'],
['1', '7', '9', '8', '2', '5', '3', '4', '6'],
['3', '4', '1', '6', '9', '7', '5', '8', '2'],
['7', '8', '5', '3', '1', '2', '6', '.', '4'],
['9', '6', '2', '5', '8', '4', '7', '3', '1'],
]
],
[ // Level 10
[
['3', '8', '4', '9', '5', '6', '2', '7', '1'],
['9', '.', '6', '8', '7', '2', '5', '3', '4'],
['2', '5', '7', '1', '4', '.', '6', '9', '8'],
['8', '9', '3', '.', '.', '5', '1', '.', '7'],
['7', '2', '1', '4', '3', '9', '8', '5', '6'],
['6', '4', '5', '7', '1', '8', '9', '2', '.'],
['1', '3', '9', '.', '8', '7', '.', '6', '2'],
['4', '6', '2', '3', '9', '1', '7', '.', '5'],
['5', '7', '8', '2', '6', '4', '.', '1', '.'],
],
[
['1', '2', '8', '4', '9', '3', '.', '6', '5'],
['6', '.', '4', '5', '7', '8', '2', '9', '1'],
['5', '7', '9', '2', '1', '6', '8', '4', '3'],
['2', '6', '1', '3', '8', '5', '4', '7', '9'],
['8', '5', '3', '.', '4', '9', '1', '2', '6'],
['9', '.', '7', '6', '.', '1', '3', '5', '8'],
['.', '.', '6', '1', '5', '.', '9', '3', '2'],
['3', '9', '2', '8', '6', '7', '5', '1', '.'],
['4', '1', '5', '9', '3', '2', '6', '.', '.'],
],
[
['.', '8', '.', '4', '9', '2', '5', '1', '6'],
['5', '.', '.', '7', '1', '6', '8', '.', '3'],
['.', '6', '1', '3', '5', '.', '2', '4', '7'],
['1', '2', '6', '.', '3', '7', '4', '5', '9'],
['.', '9', '5', '2', '6', '1', '3', '7', '8'],
['8', '7', '3', '.', '4', '5', '6', '2', '1'],
['.', '3', '9', '1', '2', '4', '7', '8', '5'],
['7', '1', '4', '5', '8', '3', '9', '6', '2'],
['2', '5', '8', '6', '7', '9', '1', '3', '4'],
],
[
['3', '7', '.', '4', '1', '.', '8', '5', '9'],
['9', '5', '.', '8', '7', '3', '6', '.', '2'],
['6', '1', '8', '2', '9', '5', '3', '4', '7'],
['4', '3', '9', '1', '8', '.', '2', '6', '5'],
['1', '2', '7', '5', '6', '4', '9', '8', '3'],
['.', '8', '6', '3', '2', '9', '4', '7', '1'],
['8', '9', '.', '7', '.', '2', '5', '3', '.'],
['7', '6', '5', '9', '3', '8', '1', '2', '4'],
['2', '4', '3', '6', '5', '.', '7', '9', '.'],
]
],
[ // Level 11
[
['6', '1', '7', '5', '2', '9', '3', '.', '8'],
['.', '4', '.', '.', '8', '6', '9', '2', '7'],
['8', '9', '.', '.', '7', '4', '5', '6', '.'],
['1', '8', '.', '.', '5', '7', '4', '.', '2'],
['.', '2', '6', '9', '3', '1', '7', '.', '5'],
['7', '.', '5', '2', '4', '8', '.', '1', '9'],
['9', '7', '8', '4', '.', '2', '1', '5', '3'],
['3', '.', '1', '8', '.', '.', '.', '7', '4'],
['.', '5', '4', '7', '1', '3', '8', '.', '6'],
],
[
['8', '5', '2', '4', '3', '1', '9', '6', '7'],
['1', '9', '6', '2', '.', '5', '4', '.', '8'],
['.', '.', '.', '6', '8', '9', '5', '2', '1'],
['2', '1', '5', '.', '6', '8', '.', '4', '9'],
['7', '.', '.', '1', '2', '4', '3', '.', '.'],
['6', '.', '3', '9', '5', '7', '1', '8', '.'],
['.', '2', '1', '7', '4', '6', '8', '9', '3'],
['.', '6', '.', '5', '1', '3', '2', '7', '4'],
['3', '.', '4', '.', '.', '.', '6', '.', '5'],
],
[
['.', '3', '2', '8', '5', '1', '6', '.', '.'],
['6', '8', '9', '3', '4', '2', '.', '7', '1'],
['4', '1', '5', '.', '9', '7', '8', '2', '3'],
['2', '4', '.', '.', '.', '9', '7', '3', '.'],
['5', '.', '7', '2', '3', '.', '1', '6', '8'],
['1', '6', '3', '7', '8', '5', '4', '9', '2'],
['9', '7', '.', '4', '.', '8', '3', '5', '.'],
['3', '2', '.', '.', '1', '6', '9', '.', '7'],
['8', '.', '6', '.', '7', '3', '2', '.', '.'],
],
[
['9', '5', '8', '6', '4', '.', '1', '7', '2'],
['2', '6', '4', '.', '5', '1', '.', '8', '3'],
['1', '3', '7', '.', '8', '2', '4', '.', '6'],
['3', '4', '9', '8', '2', '.', '6', '1', '7'],
['6', '1', '2', '4', '9', '7', '8', '3', '.'],
['.', '.', '.', '1', '3', '6', '2', '9', '4'],
['5', '.', '1', '.', '.', '9', '7', '.', '8'],
['7', '8', '6', '.', '.', '.', '3', '.', '9'],
['4', '9', '3', '2', '.', '8', '5', '.', '.'],
]
],
[ // Level 12
[
['.', '1', '7', '3', '.', '8', '.', '.', '2'],
['2', '9', '8', '.', '1', '6', '3', '7', '.'],
['3', '5', '.', '9', '7', '2', '.', '.', '4'],
['6', '3', '9', '5', '4', '.', '7', '.', '8'],
['.', '.', '4', '.', '.', '3', '5', '1', '9'],
['1', '8', '.', '2', '9', '.', '4', '.', '.'],
['5', '.', '3', '.', '.', '9', '2', '.', '7'],
['.', '7', '.', '6', '3', '5', '9', '.', '.'],
['.', '.', '1', '7', '2', '4', '.', '5', '.'],
],
[
['.', '5', '8', '6', '7', '.', '3', '9', '2'],
['2', '.', '.', '4', '5', '.', '.', '7', '6'],
['.', '.', '6', '.', '.', '.', '8', '5', '4'],
['.', '8', '.', '7', '2', '6', '5', '4', '.'],
['5', '.', '2', '9', '.', '4', '.', '3', '.'],
['1', '7', '4', '5', '.', '3', '2', '6', '.'],
['3', '.', '.', '8', '6', '.', '4', '1', '.'],
['8', '9', '5', '.', '4', '.', '6', '.', '.'],
['6', '4', '.', '.', '.', '5', '9', '8', '7'],
],
[
['4', '.', '5', '7', '3', '1', '9', '6', '2'],
['3', '.', '6', '4', '.', '.', '.', '8', '.'],
['9', '1', '7', '.', '.', '2', '4', '5', '3'],
['.', '9', '8', '5', '2', '7', '.', '1', '.'],
['.', '7', '.', '.', '.', '4', '.', '.', '8'],
['.', '.', '1', '3', '6', '8', '.', '7', '.'],
['.', '3', '2', '.', '.', '9', '7', '4', '.'],
['7', '.', '.', '.', '.', '.', '2', '3', '1'],
['1', '6', '.', '2', '7', '3', '8', '9', '5'],
],
[
['6', '5', '1', '8', '4', '7', '3', '.', '9'],
['.', '4', '9', '.', '1', '5', '6', '.', '.'],
['7', '.', '3', '.', '2', '9', '4', '.', '.'],
['.', '2', '.', '7', '9', '6', '8', '4', '1'],
['.', '9', '.', '4', '3', '.', '5', '.', '2'],
['1', '6', '4', '.', '.', '2', '.', '.', '3'],
['4', '1', '.', '9', '.', '.', '7', '5', '.'],
['5', '3', '6', '.', '.', '.', '.', '9', '.'],
['.', '7', '8', '1', '5', '.', '.', '3', '6'],
]
],
[ // Level 13
[
['.', '2', '.', '1', '.', '5', '.', '.', '9'],
['.', '.', '1', '4', '7', '6', '2', '8', '.'],
['3', '7', '4', '.', '8', '2', '.', '.', '6'],
['.', '6', '3', '.', '4', '1', '.', '9', '2'],
['4', '5', '9', '.', '.', '.', '8', '.', '7'],
['.', '.', '2', '7', '5', '.', '6', '3', '.'],
['.', '4', '7', '.', '.', '8', '3', '.', '1'],
['.', '3', '.', '6', '.', '4', '.', '2', '5'],
['6', '.', '.', '3', '.', '.', '.', '.', '8'],
],
[
['4', '.', '5', '.', '2', '.', '7', '.', '1'],
['.', '.', '.', '3', '4', '.', '5', '6', '8'],
['6', '.', '.', '8', '5', '7', '2', '.', '.'],
['.', '.', '4', '.', '.', '5', '.', '7', '.'],
['.', '3', '.', '2', '.', '.', '8', '.', '.'],
['5', '.', '.', '.', '.', '9', '.', '.', '2'],
['.', '7', '1', '.', '.', '.', '4', '2', '.'],
['2', '.', '6', '.', '9', '.', '3', '.', '.'],
['3', '.', '9', '1', '.', '2', '6', '.', '.'],
],
[
['5', '7', '8', '.', '.', '3', '.', '9', '.'],
['.', '6', '.', '4', '.', '9', '7', '.', '8'],
['2', '4', '9', '7', '8', '1', '5', '3', '.'],
['.', '1', '.', '.', '9', '7', '.', '.', '.'],
['.', '.', '.', '5', '.', '.', '4', '.', '3'],
['6', '8', '5', '2', '3', '.', '.', '.', '.'],
['.', '5', '1', '9', '.', '.', '.', '.', '2'],
['4', '.', '6', '3', '.', '2', '.', '5', '1'],
['.', '.', '2', '.', '4', '5', '.', '7', '.'],
],
[
['9', '.', '.', '.', '7', '2', '.', '3', '.'],
['4', '1', '.', '8', '5', '.', '9', '.', '.'],
['2', '7', '3', '9', '.', '.', '.', '.', '.'],
['.', '3', '.', '.', '.', '.', '7', '.', '.'],
['1', '9', '7', '.', '3', '.', '.', '.', '5'],
['6', '5', '2', '1', '.', '.', '4', '8', '3'],
['.', '.', '9', '.', '.', '4', '.', '1', '8'],
['.', '.', '.', '2', '.', '5', '3', '4', '.'],
['5', '.', '8', '.', '.', '.', '.', '6', '7'],
]
]
]
var currentLevel = 0
var numberOfLevel = levels.length
var items
var symbolizeLevelMax = 7 // Last level in which we set symbols
var url = "qrc:/gcompris/src/activities/sudoku/resource/"
var symbols = [
{"imgName": "circle", "text": 'A', "extension": ".svg"},
{"imgName": "rectangle", "text": 'B', "extension": ".svg"},
{"imgName": "rhombus", "text": 'C', "extension": ".svg"},
{"imgName": "star", "text": 'D', "extension": ".svg"},
{"imgName": "triangle", "text": 'E', "extension": ".svg"}
]
function start(items_) {
items = items_
currentLevel = 0
items.score.currentSubLevel = 1
// Shuffle all levels
for(var nb = 0 ; nb < levels.length ; ++ nb) {
Core.shuffle(levels[nb]);
}
// Shuffle the symbols
Core.shuffle(symbols);
for(var s = 0 ; s < symbols.length ; ++ s) {
// Change the letter
symbols[s].text = String.fromCharCode('A'.charCodeAt() +s);
}
initLevel()
}
function stop() {
}
function initLevel() {
items.bar.level = currentLevel + 1;
items.score.numberOfSubLevels = levels[currentLevel].length
for(var i = items.availablePiecesModel.model.count-1 ; i >= 0 ; -- i) {
items.availablePiecesModel.model.remove(i);
}
items.sudokuModel.clear();
// Copy current sudoku in local variable
var initialSudoku = levels[currentLevel][items.score.currentSubLevel-1];
items.columns = initialSudoku.length
items.rows = items.columns
// Compute number of regions
var nbLines = Math.floor(Math.sqrt(items.columns));
items.background.nbRegions = nbLines*nbLines == items.columns ? nbLines : 1;
// Create grid
for(var i = 0 ; i < initialSudoku.length ; ++ i) {
var line = [];
for(var j = 0 ; j < initialSudoku[i].length ; ++ j) {
items.sudokuModel.append({
'textValue': initialSudoku[i][j],
'initial': initialSudoku[i][j] != ".",
'mState': initialSudoku[i][j] != "." ? "initial" : "default",
})
}
}
if(currentLevel < symbolizeLevelMax) { // Play with symbols
// Randomize symbols
for(var i = 0 ; i < symbols.length ; ++ i) {
for(var line = 0 ; line < items.sudokuModel.count ; ++ line) {
if(items.sudokuModel.get(line).textValue == symbols[i].text) {
items.availablePiecesModel.model.append(symbols[i]);
break; // break to pass to the next symbol
}
}
}
}
else { // Play with numbers
for(var i = 1 ; i < items.columns+1 ; ++ i) {
items.availablePiecesModel.model.append({"imgName": i.toString(),
"text": i.toString(),
"extension": ".svg"});
}
}
}
function nextLevel() {
items.score.currentSubLevel = 1
if(numberOfLevel <= ++currentLevel) {
currentLevel = 0
}
initLevel();
}
function previousLevel() {
items.score.currentSubLevel = 1
if(--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
initLevel();
}
/*
Code that increments the sublevel and level
And bail out if no more levels are available
*/
function incrementLevel() {
items.score.currentSubLevel ++
if(items.score.currentSubLevel > items.score.numberOfSubLevels) {
// Try the next level
items.score.currentSubLevel = 1
currentLevel ++
}
if(currentLevel > numberOfLevel) {
currentLevel = numberOfLevel
}
initLevel();
}
function clickOn(caseX, caseY) {
var initialSudoku = levels[currentLevel][items.score.currentSubLevel-1];
var currentCase = caseX + caseY * initialSudoku.length;
if(initialSudoku[caseY][caseX] == '.') { // Don't update fixed cases.
var currentSymbol = items.availablePiecesModel.model.get(items.availablePiecesModel.view.currentIndex);
var isGood = isLegal(caseX, caseY, currentSymbol.text);
/*
If current case is empty, we look if it is legal and put the symbol.
Else, we colorize the existing cases in conflict with the one pressed
*/
if(items.sudokuModel.get(currentCase).textValue == '.') {
if(isGood) {
items.audioEffects.play('qrc:/gcompris/src/core/resource/sounds/win.wav')
items.sudokuModel.get(currentCase).textValue = currentSymbol.text
} else {
items.audioEffects.play('qrc:/gcompris/src/core/resource/sounds/smudge.wav')
}
}
else {
// Already a symbol in this case, we remove it
items.audioEffects.play('qrc:/gcompris/src/core/resource/sounds/darken.wav')
items.sudokuModel.get(currentCase).textValue = '.'
}
}
if(isSolved()) {
items.bonus.good("flower")
}
}
// return true or false if the given number is possible
function isLegal(posX, posY, value) {
var possible = true
// Check this number is not already in a row
var firstX = posY * items.columns;
var lastX = firstX + items.columns-1;
var clickedCase = posX + posY * items.columns;
for (var x = firstX ; x <= lastX ; ++ x) {
if (x == clickedCase)
continue
var rowValue = items.sudokuModel.get(x)
if(value == rowValue.textValue) {
items.sudokuModel.get(x).mState = "error";
possible = false
}
}
var firstY = posX;
var lastY = items.sudokuModel.count - items.columns + firstY;
// Check this number is not already in a column
for (var y = firstY ; y <= lastY ; y += items.columns) {
if (y == clickedCase)
continue
var colValue = items.sudokuModel.get(y)
if(value == colValue.textValue) {
items.sudokuModel.get(y).mState = "error";
possible = false
}
}
// Check this number is in a region
if(items.background.nbRegions > 1) {
// First, find the top-left square of the region
var firstSquareX = Math.floor(posX/items.background.nbRegions)*items.background.nbRegions;
var firstSquareY = Math.floor(posY/items.background.nbRegions)*items.background.nbRegions;
for(var x = firstSquareX ; x < firstSquareX +items.background.nbRegions ; x ++) {
for(var y = firstSquareY ; y < firstSquareY + items.background.nbRegions ; y ++) {
if(x == posX && y == posY) {
// Do not check the current square
continue;
}
var checkedCase = x + y * items.columns;
var checkedCaseValue = items.sudokuModel.get(checkedCase)
if(value == checkedCaseValue.textValue) {
items.sudokuModel.get(checkedCase).mState = "error";
possible = false
}
}
}
}
return possible
}
/*
Return true or false if the given sudoku is solved
We don't really check it's solved, only that all squares
have a value. This works because only valid numbers can
be entered up front.
*/
function isSolved() {
for(var i = 0 ; i < items.sudokuModel.count ; ++ i) {
var value = items.sudokuModel.get(i).textValue
if(value == '.')
return false
}
return true
}
function restoreState(mCase) {
items.sudokuModel.get(mCase.gridIndex).mState = mCase.isInitial ? "initial" : "default"
}
function dataToImageSource(data) {
var imageName = "";
if(currentLevel < symbolizeLevelMax) { // Play with symbols
for(var i = 0 ; i < symbols.length ; ++ i) {
if(symbols[i].text == data) {
imageName = url + symbols[i].imgName+symbols[i].extension;
break;
}
}
}
else { // numbers
if(data != ".") {
imageName = url+data+".svg";
}
}
return imageName;
}
function onKeyPressed(event) {
var keyValue = -1;
switch(event.key)
{
case Qt.Key_1:
keyValue = 0;
break;
case Qt.Key_2:
keyValue = 1;
break;
case Qt.Key_3:
keyValue = 2;
break;
case Qt.Key_4:
keyValue = 3;
break;
case Qt.Key_5:
keyValue = 4;
break;
case Qt.Key_6:
keyValue = 5;
break;
case Qt.Key_7:
keyValue = 6;
break;
case Qt.Key_8:
keyValue = 7;
break;
case Qt.Key_9:
keyValue = 8;
break;
}
if(keyValue >= 0 && keyValue < items.availablePiecesModel.model.count) {
items.availablePiecesModel.view.currentIndex = keyValue;
event.accepted=true;
}
}
diff --git a/src/activities/superbrain/ActivityInfo.qml b/src/activities/superbrain/ActivityInfo.qml
index 10a318d3d..4884c113a 100644
--- a/src/activities/superbrain/ActivityInfo.qml
+++ b/src/activities/superbrain/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Holger Kaelberer <holger.k@elberer.de>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "superbrain/Superbrain.qml"
difficulty: 2
icon: "superbrain/superbrain.svg"
author: "Holger Kaelberer &lt;holger.k@elberer.de&gt;"
demo: true
//: Activity title
title: qsTr("Super Brain")
//: Help title
description: qsTr("Tux has hidden several items. Find them again in the correct order")
//intro: "Find out the right combination of colors. A dot framed in a black square means that you found the correct colour in the correct position, while a dot framed in a white square means it's the correct colour, but in the wrong position."
//: Help goal
goal: qsTr("Tux has hidden several items. Find them again in the correct order")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("Click on the items until you find what you think is the correct answer. Then, click on the OK button. In the lower levels, Tux gives you an indication if you found a hiding place by marking the item with a black box. In the levels 4 and 8 an item may be hidden several times.<br/>You can use the right mouse button to flip the items in the opposite order or the item chooser to directly pick an item. Press and hold a mouse button or on the touch screen to automatically choose the last item selected on a column. Double click or tap on a previously selected item in your guess history to mark it as 'correct'. Such marked items are automatically selected in your current and future guesses until you un-mark them, again by double clicking or tapping.")
credit: ""
section: "puzzle"
createdInVersion: 4000
}
diff --git a/src/activities/superbrain/SearchItem.qml b/src/activities/superbrain/SearchItem.qml
index 8bc4e30ea..30bb13413 100644
--- a/src/activities/superbrain/SearchItem.qml
+++ b/src/activities/superbrain/SearchItem.qml
@@ -1,65 +1,65 @@
/* GCompris - SearchItem.qml
*
* Copyright (C) 2015 Holger Kaelberer <holger.k@elberer.de>
*
* Authors:
* Holger Kaelberer <holger.k@elberer.de>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
//import QtGraphicalEffects 1.0
import "superbrain.js" as Activity
Item {
id: root
property int searchItemIndex: 0
property alias border: color.border
property alias radius: color.radius
property bool highlightSymbol: false
Image {
id: symbol
visible: Activity.mode === "symbol"
fillMode: Image.PreserveAspectFit
source: Activity.symbols[root.searchItemIndex]
anchors.left: parent.left
anchors.top: parent.top
anchors.margins: 3
width: parent.width - 6
height: parent.height - 6
}
Rectangle {
id: symbolHighlighter
visible: (Activity.mode === "symbol") && root.highlightSymbol
anchors.fill: parent
width: parent.width
height: parent.height
border.width: 3
border.color: "white"
color: "transparent"
}
Rectangle {
id: color
visible: Activity.mode === "color"
color: Activity.colors[root.searchItemIndex]
anchors.fill: parent
width: parent.width
height: parent.height
radius: width / 2
}
}
diff --git a/src/activities/superbrain/Superbrain.qml b/src/activities/superbrain/Superbrain.qml
index 217f2735b..af4b63693 100644
--- a/src/activities/superbrain/Superbrain.qml
+++ b/src/activities/superbrain/Superbrain.qml
@@ -1,707 +1,707 @@
/* GCompris - Superbrain.qml
*
* Copyright (C) 2015 Holger Kaelberer <holger.k@elberer.de>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Holger Kaelberer <holger.k@elberer.de> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
import "superbrain.js" as Activity
import GCompris 1.0
ActivityBase {
id: activity
onStart: focus = true
onStop: {}
pageComponent: Image {
id: background
source: Activity.baseUrl + "background.svg"
sourceSize.width: Math.max(parent.width, parent.height)
fillMode: Image.PreserveAspectCrop
focus: true
readonly property double scaleFactor: 1
- readonly property bool isPortrait: (height > width)
+ readonly property bool isPortrait: (height >= width)
signal start
signal stop
MouseArea {
anchors.fill: parent
onClicked: showChooser(false);
}
Component.onCompleted: {
dialogActivityConfig.getInitialConfiguration()
activity.start.connect(start)
activity.stop.connect(stop)
}
QtObject {
id: items
property Item main: activity.main
property alias background: background
property alias bar: bar
property alias bonus: bonus
property alias score: score
property alias colorsRepeater: colorsRepeater
property alias chooserGrid: chooserGrid
property alias guessModel: guessModel
property alias guessColumn: guessColumn
property alias currentRepeater: currentRepeater
}
onStart: { Activity.start(items) }
onStop: { Activity.stop() }
Column {
id: colorsColumn
anchors.left: parent.left
anchors.leftMargin: 5 * ApplicationInfo.ratio
anchors.top: parent.top
anchors.topMargin: 5 * ApplicationInfo.ratio
spacing: 3 * ApplicationInfo.ratio
width: guessColumn.guessSize
height: guessColumn.guessSize
add: Transition {
NumberAnimation { properties: "y"; duration: 1000; easing.type: Easing.OutBounce }
}
Repeater {
id: colorsRepeater
model: ListModel {}
delegate: SearchItem {
width: 40 * ApplicationInfo.ratio
height: 40 * ApplicationInfo.ratio
border.width: 2
border.color: "white"
searchItemIndex: itemIndex
}
}
}
Rectangle {
id: tooltipRect
width: 100 * ApplicationInfo.ratio
height: tooltipText.height + 10 * ApplicationInfo.ratio
radius: 4
x: 0
y: 0
color: "lightgray"
opacity: 0
z: 10
property alias text: tooltipText.text
GCText {
id: tooltipText
anchors.centerIn: parent
fontSize: 13
text: ""
color: "black"
onTextChanged: parent.width = width + 10
}
Behavior on opacity {
NumberAnimation { duration: 100 }
}
}
function showTooltip(visible, status, mouseArea)
{
if (!visible || status === Activity.STATUS_UNKNOWN) {
tooltipRect.opacity = 0;
return;
}
showChooser(false);
var obj = background.mapFromItem(mouseArea, mouseArea.mouseX, mouseArea.mouseY);
if (status === Activity.STATUS_CORRECT)
tooltipRect.text = qsTr("This item is well placed");
if (status === Activity.STATUS_MISPLACED)
tooltipRect.text = qsTr("This item is misplaced");
tooltipRect.x = obj.x - 5 - tooltipRect.width;
tooltipRect.y = obj.y - 5 - tooltipRect.height;
tooltipRect.opacity = 0.9;
}
function showChooser(visible, guessIndex, item)
{
if (!visible) {
chooserTimer.stop();
chooser.scale = 0;
return;
}
var modelObj = guessModel.get(0).guess.get(guessIndex);
var absolute = currentRow.mapToItem(background, item.x, item.y);
chooserGrid.colIndex = modelObj.colIndex;
chooserGrid.guessIndex = guessIndex;
var chooserOffset = 0.5*chooser.width - item.width/2;
var arrowOffset = 0;
var targetX = item.x - chooserOffset;
// beyond left screen border:
if (absolute.x - chooserOffset < 0) {
arrowOffset = absolute.x - chooserOffset;
targetX -= arrowOffset;
}
// beyond right screen border:
if (absolute.x + chooserOffset + item.width > background.width) {
arrowOffset = absolute.x + chooserOffset + item.width - background.width;
targetX -= arrowOffset;
}
chooser.x = targetX;
chooser.arrowOffset = arrowOffset;
var targetY = item.y - chooser.height - 15;
var targetAbove = true;
/* //only on top-level, at window border:
if (targetY < 0) {
targetY = item.y + guessColumn.guessSize + 10;
targetAbove = false;
}*/
chooser.y = targetY;
chooser.above = targetAbove;
chooser.scale = 1;
chooser.visible = true;
chooserTimer.restart();
//console.log("XXX chooser at item.x=" + item.x + " absolute.x=" + absolute.x + " chooser.x/w=" + chooser.x + "/" + chooser.width + " background.width=" + background.width + " currentRow.x/y/w/h=" + currentRow.x + "/" + currentRow.y + "/" + currentRow.width + "/" + currentRow.height + " guessIdx=" + guessIndex + " arrowOff=" + arrowOffset);
}
Item {
id: currentWrapper
width: currentRow.width
height: currentRow.height
z: 8
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottomMargin: 20 * ApplicationInfo.ratio
state: ApplicationSettings.isBarHidden ? "hidden" : "shown"
states: [
State {
name: "hidden"
when: ApplicationSettings.isBarHidden
AnchorChanges {
target: currentWrapper;
anchors.bottom: parent.bottom
}
},
State {
name: "shown"
when: !ApplicationSettings.isBarHidden
AnchorChanges {
target: currentWrapper;
anchors.bottom: bar.top
}
}
]
transitions: Transition {
AnchorAnimation { duration: 800; easing.type: Easing.OutBounce }
}
Rectangle {
id: chooser
width: chooserGrid.width + 15
height: chooserGrid.height + 15
color: "darkgray"
border.width: 0
border.color: "white"
opacity: 1
scale: 0
visible: false
z: 10
property bool above: true
property real arrowOffset: 0
Rectangle {
id: chooserArrow
width: 10
height: 10
x: chooser.width / 2 - 5 + chooser.arrowOffset
y: chooser.above ? (chooser.height - 5) : (-5)
color: chooser.color
z: chooser.z
transform: Rotation { origin.x: 5; origin.y: 5; angle: 45}
}
GridView {
id: chooserGrid
cellWidth: guessColumn.guessSize * 2
cellHeight: guessColumn.guessSize * 2
width: Math.ceil(count / 2) * cellWidth
height: 2 * cellHeight
anchors.centerIn: parent
z: 11
clip: false
interactive: false
verticalLayoutDirection: GridView.TopToBottom
layoutDirection: Qt.LeftToRight
flow: GridView.FlowLeftToRight
property int colIndex: 0
property int guessIndex: 0
Timer {
id: chooserTimer
interval: 5000
onTriggered: showChooser(false);
}
model: new Array()
delegate: SearchItem {
id: chooserItem
width: chooserGrid.cellWidth
height: chooserGrid.cellWidth
border.width: index == chooserGrid.colIndex ? 3 : 1
border.color: index == chooserGrid.colIndex ? "white" : "darkgray"
highlightSymbol: index == chooserGrid.colIndex
searchItemIndex: modelData
radius: 5
MouseArea {
id: chooserMouseArea
anchors.fill: parent
acceptedButtons: Qt.LeftButton
z: 11
hoverEnabled: ApplicationInfo.isMobile ? false : true
onClicked: {
chooserGrid.colIndex = chooserItem.searchItemIndex;
var obj = items.guessModel.get(0);
obj.guess.setProperty(chooserGrid.guessIndex, "colIndex", chooserGrid.colIndex);
showChooser(false);
}
}
}
}
Behavior on scale {
NumberAnimation { duration: 100 }
}
}
Row {
id: currentRow
visible: true
property double factor: 1.9
anchors.left: parent.left
anchors.top: parent.top
spacing: guessColumn.horizSpacing * factor
height: guessColumn.guessSize * factor
scale: 1
z: 9
Repeater {
id: currentRepeater
delegate: SearchItem {
id: currentGuess
width: guessColumn.guessSize * currentRow.factor
height: guessColumn.guessSize * currentRow.factor
border.width: 2 * currentRow.factor
border.color: "lightgray"
searchItemIndex: colIndex
opacity: 1.0
z: 2
MouseArea {
id: mouseArea
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton
enabled: true
z: 3
hoverEnabled: ApplicationInfo.isMobile ? false : true
onPressAndHold: {
if (guessColumn.count > 1)
guessModel.get(0).guess.get(index).colIndex = guessModel.get(1).guess.get(index).colIndex;
}
onClicked: {
var obj = items.guessModel.get(0).guess.get(index);
if(chooserTimer.running && chooserGrid.guessIndex === index) {
if (mouse.button == Qt.LeftButton)
obj.colIndex = (obj.colIndex ==
Activity.currentIndeces.length - 1) ? 0 : obj.colIndex + 1;
else
obj.colIndex = (obj.colIndex == 0) ?
Activity.currentIndeces.length - 1 : obj.colIndex - 1;
}
showChooser(true, index, parent);
}
}
states: State {
name: "scaled"; when: mouseArea.containsMouse
PropertyChanges {
target: currentGuess
scale: 1.1
}
}
transitions: Transition {
NumberAnimation { properties: "scale"; easing.type: Easing.OutCubic }
}
}
}
BarButton {
id: okButton
source: "qrc:/gcompris/src/core/resource/bar_ok.svg"
sourceSize.width: 66 * bar.barZoom
width: guessColumn.guessSize * currentRow.factor
height: guessColumn.guessSize * currentRow.factor
visible: true
z: 8
onClicked: {
showChooser(false);
Activity.checkGuess();
}
}
}
}
ListModel {
id: guessModel
dynamicRoles: true
}
ListView {
id: guessColumn
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: currentWrapper.top
anchors.bottomMargin: 10 * ApplicationInfo.ratio
boundsBehavior: Flickable.DragOverBounds
verticalLayoutDirection: ListView.BottomToTop
readonly property int guessSize: 30 * ApplicationInfo.ratio
readonly property int vertSpacing: 15 * ApplicationInfo.ratio
readonly property int horizSpacing: 15 * ApplicationInfo.ratio
readonly property int statusMargin: 5 * ApplicationInfo.ratio
readonly property int resultSize: 10 * ApplicationInfo.ratio
readonly property int guessColWidth: Activity.maxPieces * (guessSize + (2 * guessColumn.statusMargin))
+ (Activity.maxPieces-1) * horizSpacing;
readonly property int resultColWidth: Activity.maxPieces * resultSize
+ (Activity.maxPieces-1) * 2;
spacing: vertSpacing
width: guessColWidth + 10 + (2 * horizSpacing) + resultColWidth
height: count * (guessSize + vertSpacing)
displaced: Transition {
NumberAnimation { easing.type: Easing.OutCubic; properties: "y"; duration: 300 }
}
model: guessModel
delegate: Row {
id: guessRow
width: guessColumn.width
height: guessColumn.guessSize
spacing: guessColumn.horizSpacing
property int rowIndex: index
visible: index != 0
Item {
id: guessRowSpacer
width: guessColumn.guessColWidth -
(guessRepeater.count * (guessColumn.guessSize +
(2 * guessColumn.statusMargin) + guessColumn.horizSpacing))
height: parent.height
}
Repeater {
id: guessRepeater
anchors.left: parent.left
anchors.top: parent.top
model: guess
delegate: Item { // wrapper needed for singleGuessStatusRect's opacity
id: singleGuessWrapper
width: guessColumn.guessSize + (2 * guessColumn.statusMargin);
height: guessColumn.guessSize + (2 * guessColumn.statusMargin);
Rectangle {
id: singleGuessStatusRect
border.width: 2
border.color: (status == Activity.STATUS_CORRECT) ? "white" : "black";
anchors.fill: parent
radius: 3
color: (status == Activity.STATUS_CORRECT) ? "black" : "white";
opacity: (status == Activity.STATUS_UNKNOWN) ? 0 : 0.9
z: 1
MouseArea {
id: mouseAreaRect
anchors.fill: parent
acceptedButtons: Qt.LeftButton
enabled: guessRow.rowIndex > 0
z: 4
hoverEnabled: ApplicationInfo.isMobile ? false : true
Timer {
id: tooltipTimer
repeat: false
interval: 500
onTriggered: showTooltip(true, status, mouseAreaRect)
}
onEntered: tooltipTimer.restart()
onExited: {
tooltipTimer.stop()
showTooltip(false)
}
onClicked: showTooltip(true, status, mouseAreaRect);
onDoubleClicked: Activity.ackColor(index, colIndex);
}
}
SearchItem {
id: singleGuess
width: guessColumn.guessSize
height: guessColumn.guessSize
anchors.left: parent.left
anchors.top: parent.top
anchors.leftMargin: guessColumn.statusMargin
anchors.topMargin: guessColumn.statusMargin
border.width: 2
border.color: "lightgray"
searchItemIndex: colIndex
opacity: 1.0
z: 2
Image {
id: okImage
visible: isAcked
width: parent.width / 2
height: parent.height / 2
anchors.centerIn: parent
source: Activity.baseUrl + "apply.svg"
}
MouseArea {
id: ackMouseArea
anchors.fill: parent
acceptedButtons: Qt.LeftButton
enabled: status == Activity.STATUS_UNKNOWN
visible: status == Activity.STATUS_UNKNOWN
z: 3
hoverEnabled: ApplicationInfo.isMobile ? false : true
onDoubleClicked: Activity.ackColor(index, colIndex);
}
}
}
}
Item {
id: guessRowSpacer2
width: 10
height: guessColumn.guessSize
}
Column {
id: guessResultColumn
width: guessColumn.resultColWidth
height: guessColumn.guessSize
spacing: 2
Item {
id: guessResultColSpacer
width: guessResultColumn.width
height: (guessResultColumn.height - 2 * (guessColumn.resultSize))
}
Row {
id: guessResultCorrectRow
width: guessResultColumn.width
height: guessColumn.resultSize
spacing: 2
Repeater {
id: guessResultCorrectRepeater
model: result.correct
delegate: Rectangle {
id: singleCorrectResult
width: guessColumn.resultSize
height: guessColumn.resultSize
radius: width * 0.5
border.width: 1
border.color: "white"
color: "black"
}
}
}
Row {
id: guessResultMisplacedRow
width: guessResultColumn.width
height: guessColumn.resultSize
spacing: 2
Repeater {
id: guessResultMisplacedRepeater
model: result.misplaced
delegate: Rectangle {
id: singleMisplacedResult
width: guessColumn.resultSize
height: guessColumn.resultSize
radius: width * 0.5
border.width: 1
border.color: "black"
color: "white"
}
}
}
}
}
}
DialogHelp {
id: dialogHelp
onClose: home()
}
DialogActivityConfig {
id: dialogActivityConfig
currentActivity: activity
content: Component {
Item {
property alias modeBox: modeBox
property var availableModes: [
{ "text": qsTr("Colors"), "value": "color" },
{ "text": qsTr("Shapes"), "value": "symbol" }
]
Flow {
id: flow
spacing: 5
width: dialogActivityConfig.width
GCComboBox {
id: modeBox
model: availableModes
background: dialogActivityConfig
label: qsTr("Select your mode")
}
}
}
}
onClose: home()
onLoadData: {
if(dataToSave && dataToSave["mode"]) {
Activity.mode = dataToSave["mode"];
}
}
onSaveData: {
var newMode = dialogActivityConfig.configItem.availableModes[dialogActivityConfig.configItem.modeBox.currentIndex].value;
if (newMode !== Activity.mode) {
chooserGrid.model = new Array();
Activity.mode = newMode;
dataToSave = {"mode": Activity.mode};
Activity.initLevel();
}
}
function setDefaultValues() {
for(var i = 0 ; i < dialogActivityConfig.configItem.availableModes.length ; i ++) {
if(dialogActivityConfig.configItem.availableModes[i].value === Activity.mode) {
dialogActivityConfig.configItem.modeBox.currentIndex = i;
break;
}
}
}
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level | config }
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
onConfigClicked: {
dialogActivityConfig.active = true
// Set default values
dialogActivityConfig.setDefaultValues();
displayDialog(dialogActivityConfig)
}
}
Bonus {
id: bonus
Component.onCompleted: win.connect(Activity.nextSubLevel)
}
Score {
id: score
anchors.bottom: undefined
anchors.rightMargin: 10 * ApplicationInfo.ratio
anchors.topMargin: 10 * ApplicationInfo.ratio
anchors.left: undefined
anchors.top: parent.top
anchors.right: parent.right
}
}
}
diff --git a/src/activities/superbrain/superbrain.js b/src/activities/superbrain/superbrain.js
index 98f1518f1..eb0072c3a 100644
--- a/src/activities/superbrain/superbrain.js
+++ b/src/activities/superbrain/superbrain.js
@@ -1,221 +1,221 @@
/* GCompris - superbrain.js
*
* Copyright (C) 2015 Holger Kaelberer <holger.k@elberer.de>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Holger Kaelberer <holger.k@elberer.de> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
.import GCompris 1.0 as GCompris
var currentLevel = 0;
var maxLevel = 8;
var currentSubLevel = 0;
var maxSubLevel = 6;
var items;
var baseUrl = "qrc:/gcompris/src/activities/superbrain/resource/";
var levels = [
{ numberOfPieces: 3, numberOfColors: 5, help: true, uniqueColors: true },
{ numberOfPieces: 4, numberOfColors: 6, help: true, uniqueColors: true },
{ numberOfPieces: 5, numberOfColors: 7, help: true, uniqueColors: true },
{ numberOfPieces: 5, numberOfColors: 7, help: true, uniqueColors: false },
{ numberOfPieces: 3, numberOfColors: 5, help: false, uniqueColors: true },
{ numberOfPieces: 4, numberOfColors: 6, help: false, uniqueColors: true },
{ numberOfPieces: 5, numberOfColors: 7, help: false, uniqueColors: true },
{ numberOfPieces: 5, numberOfColors: 7, help: false, uniqueColors: false }
];
var maxPieces = 5;
var solution = new Array(maxPieces);
var colors = [
"#FF0000FF", // dark blue
"#FF00FF00", // light green
"#FFFF0000", // red
"#FF00FFFF", // light blue
"#FFFF00FF", // magenta
"#FFFFFF00", // yellow
"#FF8e7016", // brown
"#FF04611a", // dark green
"#FFa0174b", // dark magenta
];
var mode = "color";
var symbols = [
baseUrl + "darkblue_star.svg",
baseUrl + "lightgreen_triangle.svg",
baseUrl + "red_heart.svg",
baseUrl + "lightblue_cloud.svg",
baseUrl + "magenta_diamond.svg",
baseUrl + "yellow_star.svg",
baseUrl + "brown_cross.svg",
baseUrl + "darkgreen_ring.svg",
baseUrl + "red_circle.svg",
];
var ackColors = new Array();
var currentIndeces = new Array();
var maxColors = colors.length;
var STATUS_UNKNOWN = 0;
var STATUS_MISPLACED = 1;
var STATUS_CORRECT = 2;
function start(items_) {
items = items_;
currentLevel = 0;
currentSubLevel = 0;
initLevel();
}
function stop() {
}
function initLevel() {
if (currentSubLevel == 0) {
// init level
items.bar.level = currentLevel + 1;
}
// init sublevel
ackColors = new Array(levels[currentLevel].numberOfPieces);
items.score.numberOfSubLevels = maxSubLevel;
items.score.currentSubLevel = currentSubLevel + 1;
var selectedColors = new Array(maxColors);
solution = new Array(levels[currentLevel].numberOfPieces);
for (var i = 0; i < maxColors; ++i)
selectedColors[i] = false;
// generate solution:
for(var i = 0; i < levels[currentLevel].numberOfPieces; ++i) {
var j;
do
j = Math.floor(Math.random() * levels[currentLevel].numberOfColors);
while (levels[currentLevel].uniqueColors && selectedColors[j]);
solution[i] = j;
selectedColors[j] = true;
}
//console.log("XXX solution: " + JSON.stringify(solution));
// populate currentIndeces:
items.colorsRepeater.model.clear();
items.currentRepeater.model = new Array();
currentIndeces = new Array();
for (var i = 0; i < levels[currentLevel].numberOfColors; ++i) {
currentIndeces[i] = i;
items.colorsRepeater.model.append({"itemIndex": i});
}
items.chooserGrid.model = currentIndeces;
// add first guess row:
items.guessModel.clear();
appendGuessRow();
}
function appendGuessRow()
{
var guessRow = new Array();
for (var i = 0; i < levels[currentLevel].numberOfPieces; ++i) {
var col =
guessRow.push({
index: i,
colIndex: (ackColors[i] === undefined) ? 0 : ackColors[i],
status: STATUS_UNKNOWN,
isAcked: (ackColors[i] !== undefined)
});
}
items.guessModel.insert(0, {
guess: guessRow,
result: {correct: 0, misplaced: 0}
});
var obj = items.guessModel.get(0);
items.currentRepeater.model = obj.guess;
}
function ackColor(column, colIndex)
{
ackColors[column] = (ackColors[column] == colIndex) ? undefined : colIndex;
for (var i = 0; i < items.guessModel.count; i++) {
var obj = items.guessModel.get(i).guess.get(column);
obj.isAcked = (ackColors[column] == obj.colIndex);
}
items.currentRepeater.model.get(column).colIndex = colIndex;
items.currentRepeater.model.get(column).isAcked = (ackColors[column] !== undefined);
}
function checkGuess()
{
var remainingIndeces = solution.slice();
var obj = items.guessModel.get(0);
var correctCount = 0;
var misplacedCount = 0;
// check for exact matches first:
for (var i = 0; i < levels[currentLevel].numberOfPieces; i++) {
var guessIndex = obj.guess.get(i).colIndex;
var newStatus;
if (solution[i] == guessIndex) {
// correct
remainingIndeces.splice(remainingIndeces.indexOf(guessIndex), 1);
if (levels[currentLevel].help)
obj.guess.setProperty(i, "status", STATUS_CORRECT);
correctCount++;
}
}
obj.result = ({ correct: correctCount });
if (remainingIndeces.length == 0) {
items.bonus.good("smiley");
}
for (var i = 0; i < levels[currentLevel].numberOfPieces; i++) {
if (obj.guess.get(i).status == STATUS_CORRECT)
continue;
var guessIndex = obj.guess.get(i).colIndex;
var newStatus = STATUS_UNKNOWN;
if (solution.indexOf(guessIndex) != -1 &&
remainingIndeces.indexOf(guessIndex) != -1) {
// misplaced
remainingIndeces.splice(remainingIndeces.indexOf(guessIndex), 1);
if (levels[currentLevel].help)
obj.guess.setProperty(i, "status", STATUS_MISPLACED);
misplacedCount++;
}
}
obj.result = ({ misplaced: misplacedCount, correct: correctCount });
appendGuessRow();
}
function nextLevel() {
if(maxLevel <= ++currentLevel ) {
currentLevel = 0;
}
currentSubLevel = 0;
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = maxLevel - 1
}
currentSubLevel = 0;
initLevel();
}
function nextSubLevel() {
if( ++currentSubLevel >= maxSubLevel) {
currentSubLevel = 0
nextLevel()
}
initLevel();
}
diff --git a/src/activities/tangram/ActivityInfo.qml b/src/activities/tangram/ActivityInfo.qml
index e1efe3af6..7d44d7b89 100644
--- a/src/activities/tangram/ActivityInfo.qml
+++ b/src/activities/tangram/ActivityInfo.qml
@@ -1,47 +1,47 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2016 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "tangram/Tangram.qml"
difficulty: 3
icon: "tangram/tangram.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
//: Activity title
title: qsTr("The tangram puzzle game")
//: Help title
description: qsTr("The objective is to form a given shape")
// intro: "Click on each object to obtain the same figure. You can change their orientation by clicking on the arrows."
//: Help goal
goal: qsTr("From Wikipedia, the free encyclopedia. Tangram (Chinese: literally 'seven boards of cunning') is a Chinese puzzle. While the tangram is often said to be ancient, its existence has only been verified as far back as 1800. It consists of 7 pieces, called tans, which fit together to form a square; Using the square side as 1 unit, the 7 pieces contains:
5 right isosceles triangles, including:
- 2 small size ones (legs of 1)
- 1 medium size (legs of square root of 2)
- 2 large size (legs of 2)
1 square (side of 1) and
1 parallelogram (sides of 1 and square root of 2)
")
//: Help prerequisite
prerequisite: qsTr("Mouse-manipulation")
//: Help manual
manual: qsTr("Select the tangram to form. Move a piece by dragging it. The symmetrical button appears on items that supports it. Click on the rotation button or drag around it to show the rotation you want. At first levels, simpler objects are used to introduce the tangram concept.")
credit: ""
section: "puzzle"
createdInVersion: 6000
}
diff --git a/src/activities/tangram/RotateMouseArea.qml b/src/activities/tangram/RotateMouseArea.qml
index ee5923441..60abe337d 100644
--- a/src/activities/tangram/RotateMouseArea.qml
+++ b/src/activities/tangram/RotateMouseArea.qml
@@ -1,53 +1,53 @@
/* GCompris - tangram.qml
*
* Copyright (C) 2016 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Yves Combe / Philippe Banwarth (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import QtGraphicalEffects 1.0
import GCompris 1.0
import "../../core"
import "tangram.js" as Activity
MouseArea {
id: rotateArea
anchors.fill: parent
enabled: items.selectedItem && items.selectedItem.selected && items.selectedItem.rotable
property double prevRotation: 0
onPositionChanged: {
var backPoint = background.mapFromItem(parent, mouseX, mouseY)
// Calc the angle touch / object center
var rotation = Activity.getAngleOfLineBetweenTwoPoints(
items.selectedItem.x + items.selectedItem.width / 2, items.selectedItem.y +
items.selectedItem.height / 2,
backPoint.x, backPoint.y) * (180 / Math.PI)
if(prevRotation) {
items.selectedItem.rotation += rotation - prevRotation
}
prevRotation = rotation
}
onReleased: {
prevRotation = 0
// Force a modulo 45 rotation
items.selectedItem.rotation = Math.floor((items.selectedItem.rotation + 45 / 2) / 45) * 45
items.selectedItem.selected = false
background.checkWin()
}
}
diff --git a/src/activities/tangram/Tangram.qml b/src/activities/tangram/Tangram.qml
index 0ade5a12b..5db23154b 100644
--- a/src/activities/tangram/Tangram.qml
+++ b/src/activities/tangram/Tangram.qml
@@ -1,366 +1,366 @@
/* GCompris - tangram.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Yves Combe / Philippe Banwarth (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "tangram.js" as Activity
import "dataset.js" as Dataset
import "."
ActivityBase {
id: activity
onStart: focus = true
onStop: {}
Keys.onPressed: Activity.processPressedKey(event)
pageComponent: Item {
id: background
anchors.fill: parent
- property bool horizontalLayout: background.width > background.height
+ property bool horizontalLayout: background.width >= background.height
property int playX: (activity.width - playWidth) / 2
property int playY: (activity.height - playHeight) / 2
property int playWidth: horizontalLayout ? activity.height : activity.width
property int playHeight: playWidth
property double playRatio: playWidth / 1000
signal start
signal stop
/* In order to accept any screen ratio the play area is always a 1000x1000
* square and is centered in a big background image that is 2000x2000
*/
Image {
id: bg
source: Activity.url + "tangram/background.svg"
sourceSize.width: 2000 * ApplicationInfo.ratio
sourceSize.height: 2000 * ApplicationInfo.ratio
width: 2000 * background.playRatio
height: width
anchors.centerIn: parent
}
Rectangle {
width: background.playWidth
height: background.playHeight
anchors.centerIn: parent
border.width: 2
border.color: "black"
color: "transparent"
visible: items.editionMode /* debug to see the play area */
}
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property alias background: background
property alias bar: bar
property alias bonus: bonus
property alias modelListModel: modelList.model
property alias userList: userList
property alias userListModel: userList.model
property Item selectedItem
property var currentTans: Dataset.dataset[bar.level - 1]
property int numberOfLevel: Dataset.dataset.length
property bool editionMode: false
}
onStart: {
Activity.start(items)
}
onStop: { Activity.stop() }
Image {
id: bgData
source: items.currentTans.bg ? Activity.url + items.currentTans.bg : ''
sourceSize.width: 1000 * background.playRatio
sourceSize.height: 1000 * background.playRatio
width: 1000 * background.playRatio
height: width
anchors.centerIn: parent
}
RotateMouseArea {}
DropArea {
id: dropableArea
anchors.left: background.left
anchors.bottom: background.bottom
width: background.width
height: background.height
}
Repeater {
id: modelList
model: items.currentTans.pieces
Item {
anchors.fill: background
Image {
id: tansModel
x: background.playX + background.playWidth * modelData.x - width / 2
y: background.playY + background.playHeight * modelData.y - height / 2
source: Activity.url + "m-" + modelData.img
sourceSize.width: modelData.width * background.playWidth
sourceSize.height: modelData.height * background.playWidth
z: index
rotation: modelData.rotation
mirror: modelData.flipping ? true : false
visible: true
}
}
}
Repeater {
id: userList
model: items.currentTans.pieces
Item {
id: tansItem
x: background.playX + background.playWidth * xRatio - tans.width / 2
y: background.playY + background.playHeight * yRatio - tans.height / 2
width: tans.width
height: tans.height
z: 100 + index
property real xRatio: !items.editionMode ? modelData.initX : modelData.x
property real yRatio: !items.editionMode ? modelData.initY : modelData.y
property bool selected: false
property int animDuration: 48
property bool flippable: modelData.flippable
property bool rotable: modelData.moduloRotation != 0
property alias tans: tans
rotation: !items.editionMode ? modelData.initRotation : modelData.rotation
property alias mirror: tans.mirror
function restoreZindex() {
z = 100 + index
}
onSelectedChanged: {
if(!selected)
restoreZindex()
}
function positionToTans() {
return [
(x + width / 2 - background.playX) / background.playWidth,
(y + height / 2 - background.playY) / background.playHeight
]
}
// After a drag the [x, y] positions are addressed directly breaking our
// binding. Call me to reset the binding.
function restoreBindings() {
x = Qt.binding(function() { return background.playX + background.playWidth * xRatio - width / 2})
y = Qt.binding(function() { return background.playY + background.playHeight * yRatio - height / 2 })
}
Image {
id: tans
mirror: !items.editionMode ? modelData.initFlipping : modelData.flipping
source: Activity.url + modelData.img
sourceSize.width: modelData.width * background.playWidth
sourceSize.height: modelData.height * background.playWidth
}
// Manage to return a base rotation as it was provided in the model
function rotationToTans() {
// moduloRotation == 0 to disable rotation, assume 360 in this case
var mod = modelData.moduloRotation ? modelData.moduloRotation : 360
if(modelData.flipable || modelData.flipping || !mirror)
return rotation >= 0 ? rotation % mod : (360 + rotation) % mod
else
// It flipping but model is not flipping sensitive we have to rotate accordingly
return rotation >= 0 ? (rotation - (mod - 90)) % mod : (360 + rotation - (mod - 90)) % mod
}
// Return all the positions as we got it from a tans definition
function asTans() {
return {
'img': modelData.img,
'flipping': mirror,
'x': positionToTans()[0],
'y': positionToTans()[1],
'rotation': rotationToTans()
}
}
function flipMe() {
if(flippable)
mirror = !mirror
background.checkWin()
}
Drag.active: dragArea.drag.active
Drag.hotSpot.x : width / 2
Drag.hotSpot.y : height / 2
MouseArea {
id: dragArea
anchors.fill: parent
drag.target: parent
onPressed: {
tansItem.z = 200
if(items.selectedItem && items.selectedItem != tansItem)
items.selectedItem.selected = false
items.selectedItem = tansItem
tansItem.selected = true
background.checkWin()
}
onDoubleClicked: {
flipMe()
}
onReleased: {
parent.Drag.drop()
var posTans = positionToTans()
var closest = Activity.getClosest(posTans)
if(closest && !items.editionMode) {
tansItem.xRatio = closest[0]
tansItem.yRatio = closest[1]
} else {
tansItem.xRatio = posTans[0]
tansItem.yRatio = posTans[1]
}
tansItem.restoreBindings()
background.checkWin()
}
}
Image {
id: rotateButton
source: "qrc:/gcompris/src/core/resource/bar_reload.svg"
x: - width
y: parent.height / 2 - height / 2
visible: tansItem.selected && tansItem.rotable
sourceSize.width: 40 * ApplicationInfo.ratio
z: tansItem.z + 1
RotateMouseArea {}
}
Image {
id: flip
source: "qrc:/gcompris/src/activities/tangram/resource/tangram/flip.svg"
x: parent.width / 2 - width / 2
y: parent.height - height / 2
visible: tansItem.selected && tansItem.flippable
sourceSize.width: 40 * ApplicationInfo.ratio
z: tansItem.z + 1
MouseArea {
anchors.fill: parent
onClicked: tansItem.flipMe()
}
}
Behavior on x {
PropertyAnimation {
duration: animDuration
easing.type: Easing.InOutQuad
}
}
Behavior on y {
PropertyAnimation {
duration: animDuration
easing.type: Easing.InOutQuad
}
}
}
// Return the tans model of all the user tans
function asTans() {
var tans = []
for(var i = 0; i < userList.count; i++) {
tans.push(userList.itemAt(i).asTans())
}
return tans
}
}
// We use a timer here because we have to check only once the potential
// animation are over
Timer {
id: checkWinTimer
interval: 200
property bool alreadyStarted: false
onTriggered: {
if(Activity.check() && !alreadyStarted) {
alreadyStarted = true
if(!items.editionMode)
bonus.good('flower')
}
}
}
function checkWin() {
checkWinTimer.start()
}
GCText {
anchors.top: parent.top
anchors.left: parent.left
text: items.currentTans.name
visible: items.editionMode
}
DialogHelp {
id: dialogHelp
onClose: home()
}
File {
id: file
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level |
(items.editionMode ? repeat : 0) }
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
onRepeatClicked: file.write(Activity.toDataset(), "/tmp/" + items.currentTans.name)
}
Bonus {
id: bonus
interval: 1600
Component.onCompleted: win.connect(nextLevel)
function nextLevel() {
checkWinTimer.alreadyStarted = false
Activity.nextLevel()
}
}
}
}
diff --git a/src/activities/tangram/tangram.js b/src/activities/tangram/tangram.js
index 6feb30c48..bde0f61a7 100644
--- a/src/activities/tangram/tangram.js
+++ b/src/activities/tangram/tangram.js
@@ -1,182 +1,182 @@
/* GCompris - tangram.js
*
* Copyright (C) 2016 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Yves Combe / Philippe Banwarth (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
var url = "qrc:/gcompris/src/activities/tangram/resource/"
var currentLevel = 0
var items
function start(items_) {
items = items_
currentLevel = 0
initLevel()
}
function stop() {
}
function initLevel() {
items.bar.level = currentLevel + 1
}
function nextLevel() {
if(items.numberOfLevel <= ++currentLevel ) {
currentLevel = 0
}
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = items.numberOfLevel - 1
}
initLevel();
}
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
}
// Determines the angle of a straight line drawn between point one and two.
// The number returned, which is a float in radian,
// tells us how much we have to rotate a horizontal line clockwise
// for it to match the line between the two points.
function getAngleOfLineBetweenTwoPoints(x1, y1, x2, y2) {
var xDiff = x2 - x1;
var yDiff = y2 - y1;
return Math.atan2(yDiff, xDiff);
}
function getDistance(ix, iy, jx, jy) {
return Math.sqrt(Math.pow((ix - jx), 2) + Math.pow((iy - jy), 2))
}
function dumpTans(tans) {
console.log("== tans ==")
for(var i = 0; i < tans.length; i++) {
console.log(tans[i].img, tans[i].x, tans[i].y, tans[i].rotation, tans[i].flipping)
}
}
/* Returns the [x, y] coordinate of the closest point */
function getClosest(point) {
var nbpiece = items.currentTans.pieces.length
var closestItem
var closestDist = 1
for(var i = 0; i < nbpiece; i++) {
var p1 = items.currentTans.pieces[i]
var dist = getDistance(p1.x, p1.y, point[0], point[1])
if(dist < closestDist) {
closestDist = dist
closestItem = p1
}
}
if(closestDist < 0.1)
return [closestItem.x, closestItem.y]
return
}
function check() {
var nbpiece = items.currentTans.pieces.length
var userTans = items.userList.asTans()
for(var i = 0; i < nbpiece; i++) {
var p1 = items.currentTans.pieces[i]
var ok = false
for(var j = 0; j < nbpiece; j++) {
var p2 = userTans[j]
// Check type distance and rotation are close enough
if(p1.img === p2.img &&
p1.flipping == p2.flipping &&
getDistance(p1.x, p1.y, p2.x, p2.y) < 0.01 &&
p1.rotation === p2.rotation ) {
ok = true
break
}
}
if(!ok)
return false
}
return true
}
function toDataset() {
var nbpiece = items.currentTans.pieces.length
var userTans = items.userList.asTans()
var tanss = ' {\n' +
" 'bg': '',\n" +
" 'name': '" + items.currentTans.name + "',\n" +
" 'colorMask': '#999',\n" +
" 'pieces': [\n"
for(var i = 0; i < nbpiece; i++) {
var p1 = items.currentTans.pieces[i]
var p2 = userTans[i]
tanss += ' {' + '\n' +
" 'img': '" + p1.img + "',\n" +
" 'flippable': " + p1.flippable + ',\n' +
" 'flipping': " + p2.flipping + ',\n' +
" 'height': " + p1.height + ',\n' +
" 'initFlipping': " + p1.initFlipping + ',\n' +
" 'initRotation': " + p1.initRotation + ',\n' +
" 'initX': " + p1.initX + ',\n' +
" 'initY': " + p1.initY + ',\n' +
" 'moduloRotation': " + p1.moduloRotation + ',\n' +
" 'rotation': " + p2.rotation + ',\n' +
" 'width': " + p1.width + ',\n' +
" 'x': " + p2.x + ',\n' +
" 'y': " + p2.y + '\n' +
" },\n";
}
tanss += ' ]\n' +
' },\n'
return(tanss)
}
/* In edition mode arrow keys allow the move by 1 pixels in any direction */
function processPressedKey(event) {
if ( items.editionMode && items.selectedItem && items.selectedItem.selected) {
/* Move the player */
switch (event.key) {
case Qt.Key_Right:
items.selectedItem.x += 1
event.accepted = true
break
case Qt.Key_Left:
items.selectedItem.x -= 1
event.accepted = true
break
case Qt.Key_Up:
items.selectedItem.y -= 1
event.accepted = true
break
case Qt.Key_Down:
items.selectedItem.y += 1
event.accepted = true
break
}
}
}
diff --git a/src/activities/target/ActivityInfo.qml b/src/activities/target/ActivityInfo.qml
index 0751b2c19..e1c6cef0e 100644
--- a/src/activities/target/ActivityInfo.qml
+++ b/src/activities/target/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "target/Target.qml"
difficulty: 2
icon: "target/target.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
//: Activity title
title: qsTr("Practice addition with a target game")
//: Help title
description: qsTr("Hit the target and count your points")
// intro: "Click on the target to launch darts, then count your final score!"
//: Help goal
goal: qsTr("Throw darts at a target and count your score.")
//: Help prerequisite
prerequisite: qsTr("Can move the mouse, can read numbers and count up to 15 for the first level")
//: Help manual
manual: qsTr("Check the speed and direction of the target, and then click on it to launch a dart. When all your darts are thrown, you are asked to count your score. Enter the score with the keyboard.")
credit: ""
section: "math addition"
createdInVersion: 0
}
diff --git a/src/activities/target/Arrow.qml b/src/activities/target/Arrow.qml
index 9b0c51a0f..07a126d1f 100644
--- a/src/activities/target/Arrow.qml
+++ b/src/activities/target/Arrow.qml
@@ -1,66 +1,66 @@
/* GCompris - arrow.qml
*
* Copyright (C) 2014 Bruno coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "target.js" as Activity
Repeater {
id: arrowRepeater
model: 0
signal init(int nbArrow)
onInit: {
// Set to 0 to force a delete of previous arrows
model = 0
model = nbArrow
items.currentArrow = 0
}
Rectangle {
id: arrow
width: 30 * ApplicationInfo.ratio
height: 30 * ApplicationInfo.ratio
radius: width / 2
anchors.centerIn: parent
border.width: 1 * ApplicationInfo.ratio
border.color: "black"
opacity: 0
Behavior on scale {
id: scale
NumberAnimation {
id: anim
duration: 1000
easing.type: Easing.InOutQuad
onRunningChanged: {
if(!anim.running) {
// Reparent the arrow on the target
targetItem.attachArrow(arrow)
}
}
}
}
}
}
diff --git a/src/activities/target/Target.qml b/src/activities/target/Target.qml
index ec5b95da4..9fe5bd1d9 100644
--- a/src/activities/target/Target.qml
+++ b/src/activities/target/Target.qml
@@ -1,242 +1,242 @@
/* GCompris - target.qml
*
* Copyright (C) 2014 Bruno coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "target.js" as Activity
ActivityBase {
id: activity
onStart: focus = true
onStop: {}
pageComponent: Item {
id: background
anchors.fill: parent
signal start
signal stop
signal targetReached
Keys.onPressed: {
if(items.currentArrow != items.nbArrow)
return
if(event.key === Qt.Key_Backspace) {
backspace()
}
appendText(event.text)
}
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property alias background: background
property alias bar: bar
property alias bonus: bonus
property alias targetModel: targetItem.model
property alias targetItem: targetItem
property alias userEntry: userEntry
property int currentArrow
property int nbArrow
property int currentSubLevel
property int numberOfSubLevel
property bool arrowFlying
onNbArrowChanged: {
arrowRepeater.init(nbArrow)
}
}
onStart: {
keyboard.populate();
Activity.start(items)
}
onStop: { Activity.stop() }
TargetItem {
id: targetItem
}
onTargetReached: {
items.arrowFlying = false
if(items.currentArrow == items.nbArrow) {
targetItem.stop()
targetItem.scoreText += " = "
userEntry.text = "?"
}
}
Arrow {
id: arrowRepeater
}
Image {
id: cross
anchors.centerIn: parent
source: Activity.url + "cross.svg"
opacity: items.currentArrow != items.nbArrow ? 1 : 0
sourceSize.width: 50 * ApplicationInfo.ratio
}
MouseArea {
id: mouseArea
anchors.fill: parent
enabled: items.currentArrow != items.nbArrow && !items.arrowFlying
onClicked: {
activity.audioEffects.play(Activity.url + 'arrow.wav')
items.arrowFlying = true
if(items.currentArrow != items.nbArrow) {
arrowRepeater.itemAt(items.currentArrow).opacity = 1
arrowRepeater.itemAt(items.currentArrow++).scale = 0.5
}
}
}
GCText {
id: scoreItem
anchors.horizontalCenter: parent.horizontalCenter
width: parent.width
text: targetItem.scoreText
fontSize: 22
font.bold: true
style: Text.Outline
styleColor: "black"
color: "white"
wrapMode: Text.WordWrap
horizontalAlignment: Text.AlignHCenter
}
function backspace() {
userEntry.text = userEntry.text.slice(0, -1)
if(userEntry.text.length === 0) {
userEntry.text = "?"
} else {
- if(targetItem.scoreTotal == userEntry.text)
+ if(targetItem.scoreTotal === userEntry.text)
bonus.good("flower")
}
}
function appendText(text) {
if(text === keyboard.backspace) {
backspace()
return
}
var number = parseInt(text)
if(isNaN(number))
return
if(userEntry.text === "?") {
userEntry.text = ""
}
if(userEntry.text.length > ('' + targetItem.scoreTotal).length) {
return
}
userEntry.text += text
- if(targetItem.scoreTotal == userEntry.text)
+ if(targetItem.scoreTotal === userEntry.text)
bonus.good("flower")
}
GCText {
id: userEntry
anchors.top: scoreItem.bottom
width: parent.width
fontSize: 22
font.bold: true
style: Text.Outline
styleColor: "black"
color: "white"
wrapMode: Text.WordWrap
horizontalAlignment: Text.AlignHCenter
}
VirtualKeyboard {
id: keyboard
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
hide: items.currentArrow == items.nbArrow ? false : true
function populate() {
layout = [
[
{ label: "0" },
{ label: "1" },
{ label: "2" },
{ label: "3" },
{ label: "4" },
{ label: "5" },
{ label: "6" },
{ label: "7" },
{ label: "8" },
{ label: "9" },
{ label: keyboard.backspace }
] ]
}
onKeypress: background.appendText(text)
onError: console.log("VirtualKeyboard error: " + msg);
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
anchors.bottom: keyboard.top
content: BarEnumContent { value: help | home | level }
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
}
Score {
id: score
anchors.right: parent.right
anchors.top: parent.top
anchors.bottom: undefined
currentSubLevel: items.currentSubLevel + 1
numberOfSubLevels: items.numberOfSubLevel
}
Bonus {
id: bonus
Component.onCompleted: win.connect(Activity.nextSubLevel)
}
}
}
diff --git a/src/activities/target/TargetItem.qml b/src/activities/target/TargetItem.qml
index acdf591e6..0d721426a 100644
--- a/src/activities/target/TargetItem.qml
+++ b/src/activities/target/TargetItem.qml
@@ -1,159 +1,159 @@
/* GCompris - TargetItem.qml
*
* Copyright (C) 2014 Bruno coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "target.js" as Activity
Image {
id: targetItem
fillMode: Image.PreserveAspectCrop
source: Activity.url + "target_background.svg"
width: parent.width * zoom
height: parent.height * zoom
sourceSize.width: Math.max(parent.width, parent.height) * zoom
anchors.centerIn: parent
property int zoom: 2
property alias model: targetModel
property bool stopMe: false
property var scores: []
property string scoreText
property int scoreTotal
signal start
signal stop
signal attachArrow(Item arrow)
onStart: {
scores = []
scoreText = ""
scoreTotal = 0
stopMe = false
targetItem.anchors.horizontalCenterOffset = getRandomOffset(0)
targetItem.anchors.verticalCenterOffset = getRandomOffset(0)
}
onStop: {
stopMe = true
targetItem.anchors.horizontalCenterOffset = 0
targetItem.anchors.verticalCenterOffset = 0
}
// Avoid taking the same value or the animation won't restart
function getRandomOffset(oldValue) {
if(oldValue != 0 && Math.random() < 0.5)
return 0
var maxSize = targetModel.get(0).size * ApplicationInfo.ratio
do {
var newValue = Math.floor(Math.random() * maxSize) - maxSize / 2
} while(oldValue == newValue)
return newValue
}
onAttachArrow: {
arrow.anchors.centerIn = undefined
var coordArrow = parent.mapToItem(targetItem, arrow.x, arrow.y)
arrow.parent = targetItem
arrow.x = coordArrow.x
arrow.y = coordArrow.y
var arrowCenterX = arrow.x + arrow.width / 2
var arrowCenterY = arrow.y + arrow.height / 2
var centerX = targetItem.width / 2
var centerY = targetItem.height / 2
// Calc the arrow score
var dist = Math.sqrt(Math.pow(arrowCenterX - centerX, 2) +
Math.pow(arrowCenterY - centerY, 2))
dist *= zoom / ApplicationInfo.ratio
var score = 0
for(var i = targetModel.count - 1; i >= 0; --i) {
if(dist < targetModel.get(i).size) {
score = targetModel.get(i).score
break
}
}
scores.push(score)
scoreTotal += score
scoreText = scores.join(" + ")
parent.targetReached()
}
Behavior on anchors.horizontalCenterOffset {
id: horizontal
NumberAnimation {
id: anim1
duration: 3000
easing.type: Easing.InOutQuad
onRunningChanged: {
if(!anim1.running) {
var newValue = getRandomOffset(targetItem.anchors.horizontalCenterOffset)
if(!stopMe)
targetItem.anchors.horizontalCenterOffset = newValue
}
}
}
}
Behavior on anchors.verticalCenterOffset {
id: vertical
NumberAnimation {
id: anim2
duration: 3000
easing.type: Easing.InOutQuad
onRunningChanged: {
if(!anim2.running) {
var newValue = getRandomOffset(targetItem.anchors.verticalCenterOffset)
if(!stopMe)
targetItem.anchors.verticalCenterOffset = newValue
}
}
}
}
ListModel {
id: targetModel
}
Repeater {
id: repeater
model: targetModel
Rectangle {
anchors.centerIn: targetItem
width: size * ApplicationInfo.ratio
height: size * ApplicationInfo.ratio
color: model.color
radius: width / 2
border.width: 1 * ApplicationInfo.ratio
border.color: "black"
GCText {
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
text: score
}
}
}
}
diff --git a/src/activities/target/target.js b/src/activities/target/target.js
index 0019a416a..329abbe3f 100644
--- a/src/activities/target/target.js
+++ b/src/activities/target/target.js
@@ -1,152 +1,152 @@
/* GCompris - target.js
*
* Copyright (C) 2014 Bruno coudoin
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Bruno Coudoin <bruno.coudoin@gcompris.net> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
var url = "qrc:/gcompris/src/activities/target/resource/"
var colors = [
"#ff1b00",
"#7edee2",
"#f1f500",
"#3dff00",
"#b7d2d4",
"#6db5ba"
]
var levels = [
[
{size: 50, color: colors[0], score: 5},
{size: 100, color: colors[1], score: 4},
{size: 150, color: colors[2], score: 3},
{size: 200, color: colors[3], score: 2},
{size: 250, color: colors[4], score: 1}
],
[
{size: 50, color: colors[0], score: 10},
{size: 100, color: colors[1], score: 5},
{size: 150, color: colors[2], score: 3},
{size: 200, color: colors[3], score: 2},
{size: 250, color: colors[4], score: 1}
],
[
{size: 50, color: colors[0], score: 20},
{size: 100, color: colors[1], score: 10},
{size: 150, color: colors[2], score: 8},
{size: 200, color: colors[3], score: 5},
{size: 250, color: colors[4], score: 3},
{size: 300, color: colors[5], score: 2}
],
[
{size: 50, color: colors[0], score: 30},
{size: 100, color: colors[1], score: 20},
{size: 150, color: colors[2], score: 10},
{size: 200, color: colors[3], score: 5},
{size: 250, color: colors[4], score: 3},
{size: 300, color: colors[5], score: 2}
],
[
{size: 50, color: colors[0], score: 50},
{size: 100, color: colors[1], score: 30},
{size: 150, color: colors[2], score: 20},
{size: 200, color: colors[3], score: 8},
{size: 250, color: colors[4], score: 3},
{size: 300, color: colors[5], score: 2}
],
[
{size: 50, color: colors[0], score: 100},
{size: 100, color: colors[1], score: 50},
{size: 150, color: colors[2], score: 12},
{size: 200, color: colors[3], score: 8},
{size: 250, color: colors[4], score: 3},
{size: 300, color: colors[5], score: 2}
],
[
{size: 50, color: colors[0], score: 500},
{size: 100, color: colors[1], score: 100},
{size: 150, color: colors[2], score: 50},
{size: 200, color: colors[3], score: 15},
{size: 250, color: colors[4], score: 7},
{size: 300, color: colors[5], score: 3}
],
[
{size: 50, color: colors[0], score: 64},
{size: 100, color: colors[1], score: 32},
{size: 150, color: colors[2], score: 16},
{size: 200, color: colors[3], score: 8},
{size: 250, color: colors[4], score: 4},
{size: 300, color: colors[5], score: 2}
]
]
var currentLevel = 0
var numberOfLevel = levels.length
var items
function start(items_) {
items = items_
currentLevel = 0
items.currentSubLevel = 0
items.numberOfSubLevel = 5
initLevel()
}
function stop() {
}
function initLevel() {
items.bar.level = currentLevel + 1
items.targetModel.clear()
items.arrowFlying = false
for(var i = levels[currentLevel].length - 1; i >= 0 ; --i) {
items.targetModel.append(levels[currentLevel][i])
}
// Reset the arrows first
items.nbArrow = 0
items.nbArrow = Math.min(currentLevel + 3, 6)
items.targetItem.start()
items.userEntry.text = ""
}
function nextSubLevel() {
if(items.numberOfSubLevel <= ++items.currentSubLevel ) {
nextLevel()
} else {
initLevel();
}
}
function nextLevel() {
items.currentSubLevel = 0
if(numberOfLevel <= ++currentLevel ) {
currentLevel = 0
}
initLevel();
}
function previousLevel() {
items.currentSubLevel = 0
if(--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
initLevel();
}
diff --git a/src/activities/template/ActivityInfo.qml b/src/activities/template/ActivityInfo.qml
index 58a6a7f19..13a2ba9c7 100644
--- a/src/activities/template/ActivityInfo.qml
+++ b/src/activities/template/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2018 Your Name <yy@zz.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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "template/Template.qml"
difficulty: 1
icon: "template/template.svg"
author: "Your Name &lt;yy@zz.org&gt;"
demo: true
//: Activity title
title: "Template activity"
//: Help title
description: ""
//intro: "put here in comment the text for the intro voice"
//: Help goal
goal: ""
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: ""
credit: ""
section: "fun"
createdInVersion: creationversion
}
diff --git a/src/activities/template/Template.qml b/src/activities/template/Template.qml
index 6622bca1f..7fd526824 100644
--- a/src/activities/template/Template.qml
+++ b/src/activities/template/Template.qml
@@ -1,85 +1,85 @@
/* GCompris - template.qml
*
* Copyright (C) 2018 YOUR NAME <xx@yy.org>
*
* Authors:
* <THE GTK VERSION AUTHOR> (GTK+ version)
* YOUR NAME <YOUR EMAIL> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
import "template.js" as Activity
ActivityBase {
id: activity
onStart: focus = true
onStop: {}
pageComponent: Rectangle {
id: background
anchors.fill: parent
color: "#ABCDEF"
signal start
signal stop
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property alias background: background
property alias bar: bar
property alias bonus: bonus
}
onStart: { Activity.start(items) }
onStop: { Activity.stop() }
GCText {
anchors.centerIn: parent
text: "template activity"
fontSize: largeSize
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level }
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
}
Bonus {
id: bonus
Component.onCompleted: win.connect(Activity.nextLevel)
}
}
}
diff --git a/src/activities/template/template.js b/src/activities/template/template.js
index 50384b0d7..98ee6acf4 100644
--- a/src/activities/template/template.js
+++ b/src/activities/template/template.js
@@ -1,54 +1,54 @@
/* GCompris - template.js
*
* Copyright (C) 2018 YOUR NAME <xx@yy.org>
*
* Authors:
* <THE GTK VERSION AUTHOR> (GTK+ version)
* "YOUR NAME" <YOUR EMAIL> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
var currentLevel = 0
var numberOfLevel = 4
var items
function start(items_) {
items = items_
currentLevel = 0
initLevel()
}
function stop() {
}
function initLevel() {
items.bar.level = currentLevel + 1
}
function nextLevel() {
if(numberOfLevel <= ++currentLevel) {
currentLevel = 0
}
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = numberOfLevel - 1
}
initLevel();
}
diff --git a/src/activities/tic_tac_toe/ActivityInfo.qml b/src/activities/tic_tac_toe/ActivityInfo.qml
index 076dc25a5..e64da94b8 100644
--- a/src/activities/tic_tac_toe/ActivityInfo.qml
+++ b/src/activities/tic_tac_toe/ActivityInfo.qml
@@ -1,43 +1,43 @@
/* GCompris - ActivityIngo.qml
*
* Copyright (C) 2014 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Pulkit Gupta <pulkitgenius@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "tic_tac_toe/TicTacToe.qml"
difficulty: 2
icon: "tic_tac_toe/tic_tac_toe.svg"
author: "Pulkit Gupta &lt;pulkitgenius@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Tic Tac Toe (against Tux)")
//: Help title
description: qsTr("Place three marks in a row")
// intro: "Click on the square which you wish to mark and try to mark 3 consecutive squares before Tux."
//: Help goal
goal: qsTr("Place three respective marks in any horizontal, vertical, or diagonal row to win the game")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("Play with the computer. Take turns to click on the square which you want to mark. First player to create a line of 3 marks wins")
credit: ""
section: "strategy"
createdInVersion: 4000
}
diff --git a/src/activities/tic_tac_toe/Piece.qml b/src/activities/tic_tac_toe/Piece.qml
index 9631412fe..8bdd6a71d 100644
--- a/src/activities/tic_tac_toe/Piece.qml
+++ b/src/activities/tic_tac_toe/Piece.qml
@@ -1,54 +1,54 @@
/* GCompris - TicTacToe.qml
*
* Copyright (C) 2014 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Pulkit Gupta <pulkitgenius@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "tic_tac_toe.js" as Activity
import GCompris 1.0
Image {
id: piece
opacity: 1.0
states: [
State {
name: "invisible"
PropertyChanges {
target: piece
opacity: 0
}
},
State {
name: "2" // Player 2
PropertyChanges{
target: piece
source: Activity.url + "circle.svg"
}
},
State {
name: "1" // Player 1
PropertyChanges {
target: piece
source: Activity.url + "cross.svg"
}
}
]
}
diff --git a/src/activities/tic_tac_toe/TicTacToe.qml b/src/activities/tic_tac_toe/TicTacToe.qml
index e3e6f62e6..f9e0be407 100644
--- a/src/activities/tic_tac_toe/TicTacToe.qml
+++ b/src/activities/tic_tac_toe/TicTacToe.qml
@@ -1,230 +1,230 @@
/* GCompris - TicTacToe.qml
*
* Copyright (C) 2014 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Pulkit Gupta <pulkitgenius@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
import "tic_tac_toe.js" as Activity
import GCompris 1.0
ActivityBase {
id: activity
property bool twoPlayer: false
onStart: focus = true
onStop: {}
pageComponent: Image {
id: background
anchors.fill: parent
source: Activity.url + "background.svg"
sourceSize.width: Math.max(parent.width, parent.height)
fillMode: Image.PreserveAspectCrop
signal start
signal stop
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
// Add here the QML items you need to access in javascript
QtObject {
id: items
property Item main: activity.main
property alias background: background
property alias player1score: player1score
property alias player2score: player2score
property alias pieces: pieces
property alias createPiece: createPiece
property alias repeater: repeater
property alias columns: grid.columns
property alias rows: grid.rows
property alias magnify: magnify
property alias demagnify: demagnify
property bool gameDone
property int counter
property int playSecond
property alias bar: bar
property alias bonus: bonus
}
onStart: Activity.start(items, twoPlayer)
onStop: Activity.stop()
Image {
id: board
source: Activity.url + "board.svg"
sourceSize.width: 4 * Math.min(background.width / 4, background.height / 6)
anchors {
verticalCenter: parent.verticalCenter
horizontalCenter: parent.horizontalCenter
}
ListModel {
id: pieces
}
Grid {
id: grid
rows: 3
columns: 3
anchors {
fill: parent
left: parent.left
leftMargin: parent.width/18
top: parent.top
topMargin: board.width/20
}
spacing: board.width/16
Repeater {
id: repeater
model: pieces
delegate: blueSquare
Component {
id: blueSquare
Rectangle {
width: (grid.height/4)*1.1
height: (grid.height/4)*1.1
border.color: "transparent"
border.width: 5
radius: 10
state: "INITIAL"
color: "#c7ecfb"
Piece {
anchors.fill: parent
state: stateTemp
}
states: [
State {
name: "INITIAL"
PropertyChanges {
target: area
visible: true
}
},
State {
name: "DONE"
PropertyChanges {
target: area;
visible: false;
}
}
]
MouseArea {
id: area
enabled: !magnify.running && !items.gameDone
hoverEnabled: enabled
width: parent.width
height: parent.height
onEntered: { border.color = "#62db53" }
onExited: { border.color = "transparent" }
onClicked: { Activity.handleCreate(parent) }
}
}
}
}
Piece {
id: createPiece
state: (items.counter + items.playSecond) % 2 ? "2": "1"
width: (grid.height/4)*1.1
height: (grid.height/4)*1.1
opacity: 0
}
}
}
PropertyAnimation {
id: demagnify
target: createPiece
properties: "scale"
from: 1.0
to: 0.0
duration: 1
}
PropertyAnimation {
id: magnify
target: createPiece
properties: "scale"
from: 0.0
to: 1.0
duration: 1000
onStarted: activity.audioEffects.play(Activity.url + 'click.wav')
onStopped: { Activity.continueGame() }
}
ScoreItem {
id: player1score
player: 1
height: Math.min(background.height/7, Math.min(background.width/7, bar.height * 1.05))
width: height*11/8
anchors {
top: background.top
topMargin: 5
left: background.left
leftMargin: 5
}
playerImageSource: Activity.url + "player_1.svg"
backgroundImageSource: Activity.url + "score_1.svg"
}
ScoreItem {
id: player2score
player: 2
height: Math.min(background.height/7, Math.min(background.width/7, bar.height * 1.05))
width: height*11/8
anchors {
top: background.top
topMargin: 5
right: background.right
rightMargin: 5
}
playerImageSource: Activity.url + "player_2.svg"
backgroundImageSource: Activity.url + "score_2.svg"
playerScaleOriginX: player2score.width
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: (twoPlayer ? (help | home | reload) : (help | home | level | reload))}
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
onReloadClicked: {
Activity.reset()
}
}
Bonus {
id: bonus
}
}
}
diff --git a/src/activities/tic_tac_toe/tic_tac_toe.js b/src/activities/tic_tac_toe/tic_tac_toe.js
index ce05308ba..aac417d33 100644
--- a/src/activities/tic_tac_toe/tic_tac_toe.js
+++ b/src/activities/tic_tac_toe/tic_tac_toe.js
@@ -1,545 +1,545 @@
/* GCompris - TicTacToe.js
*
* Copyright (C) 2014 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Pulkit Gupta <pulkitgenius@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
var currentLevel = 0
var numberOfLevel = 6
var items
var url = "qrc:/gcompris/src/activities/tic_tac_toe/resource/"
var currentPiece
var currentPlayer
var currentLocation
var twoPlayer
var track = [] //For tracking moves
var hx //x co-ordinate needed for creating first image when playSecond is enabled
var vy //y co-ordinate needed for creating first image when playSecond is enabled
var stopper //For stopping game when doing reset
function start(items_, twoPlayer_) {
items = items_
currentLevel = 1
currentPlayer = 1
twoPlayer = twoPlayer_
items.playSecond = 0
initLevel()
}
function stop() {
}
function initLevel() {
items.bar.level = currentLevel
items.counter = 0
items.gameDone = false
items.pieces.clear()
track = []
for(var y = 0; y < items.rows; y++) {
for(var x = 0; x < items.columns; x++) {
items.pieces.append({'stateTemp': "invisible"})
}
}
if (items.playSecond)
initiatePlayer2()
else
initiatePlayer1()
stopper = false
if (items.playSecond)
changePlayToSecond()
}
function nextLevel() {
if(numberOfLevel <= ++currentLevel) {
currentLevel = 1
}
reset();
}
function previousLevel() {
if(--currentLevel < 1) {
currentLevel = numberOfLevel - 1
}
reset();
}
function reset() {
stopper = true
hx = items.repeater.itemAt(1).x
vy = items.repeater.itemAt(3).y
stopAnimations()
items.pieces.clear() // Clear the board
if (items.playSecond)
items.playSecond = 0
else
items.playSecond = 1
initLevel()
}
function stopAnimations() {
items.magnify.stop()
items.player1score.endTurn();
items.player2score.endTurn();
}
//Initial values at the start of game when its player 1 turn
function initiatePlayer1() {
items.player2score.endTurn();
items.player1score.beginTurn();
}
//Initial values at the start of game when its player 2 turn
function initiatePlayer2() {
items.player1score.endTurn();
items.player2score.beginTurn();
}
//Change scale of score boxes according to turns
function changeScale() {
if (items.playSecond) {
if (items.counter%2 == 0) {
initiatePlayer2()
shouldComputerPlay()
}
else
initiatePlayer1()
}
else {
if (items.counter%2 == 0) {
initiatePlayer1()
}
else {
initiatePlayer2()
shouldComputerPlay()
}
}
}
//Changing play to second in single player mode
function changePlayToSecond() {
if (items.playSecond == 0) {
items.playSecond = 1
reset()
return 0
}
if (!twoPlayer) {
var rand = Math.floor((Math.random() * 9))
var y = parseInt(rand/3) * vy
var x = parseInt(rand%3) * hx
items.repeater.itemAt(rand).state = "DONE"
currentPiece = rand
items.createPiece.x = x
items.createPiece.y = y
items.demagnify.start()
items.createPiece.opacity = 1
items.magnify.start()
}
}
//Changing play to second in single player mode
function changePlayToFirst() {
items.playSecond = 0
reset()
}
//Get row of the corresponding square box (square boxes are defined in repeater)
function getrowno(parentY) {
for(var i = 0; i < items.rows - 1; i++) {
if(parentY == items.repeater.itemAt(i*3).y) {
return i
}
}
return items.rows - 1
}
//Get column of the corresponding square box (square boxes are defined in repeater)
function getcolno(parentX) {
for(var i = 0; i < items.columns - 1; i++) {
if(parentX == items.repeater.itemAt(i).x) {
return i
}
}
return items.columns - 1
}
//Create the piece (cross or circle) at given position
function handleCreate(parent) {
parent.state = "DONE"
var rowno = getrowno(parent.y)
var colno = getcolno(parent.x)
currentPiece = (rowno * items.columns) + colno
items.createPiece.x=parent.x
items.createPiece.y=parent.y
items.demagnify.start()
items.createPiece.opacity = 1
items.magnify.start()
}
//Return the state of piece (1 or 2), 1 and 2 corresponds to Player 1 and Player 2 respectively
function getPieceState(col, row) {
return items.pieces.get(row * items.columns + col).stateTemp
}
/* setmove() decides the move which is to be played by computer. It decides according to the current level of player:
* At level 1 -> No if statements are parsed, and in the end, a random empty location is returned
* At level 2 -> Only first 'if' statement is parsed, evaluateBoard(computerState) is called which checks if computer can
* win in this turn, if there is an empty location in which computer can get three consecutive marks, then
* computer will play there, else computer will play on a random empty location. At level 2, computer will
* not check if player can win in next turn or not, this increases the winning chance of player at level 2.
* At level 3 -> First two 'if' statements are parsed, hence computer will first check if it can win in this turn by executing
* evaluateBoard(computerState). If not, then it will execute evaluateBoard(playerState) which will check if
* player can win in next turn or not, if player can win, then computer will play at that location to stop
* the player from winning. Else computer will play randomly. Therefore player can not win, unless he uses
* a double trick (Having two positions from where you can win).
* At level 4 -> Same as level 3
* At level 5 -> Along with evaluateBoard(computerState) and evaluateBoard(playerState), applyLogic(playerState) is called
* which counters all the possibilities of double trick. Hence at level 5, player can not win, it will either
* be a draw or the player will lose.
* setmove() returns the position where computer has to play its turn
*/
function setmove() {
//Assigning States -> Which state "1" or "2" is used for identifying player and computer
var playerState = items.playSecond ? "2" : "1"
var computerState = items.playSecond ? "1" : "2"
if (currentLevel > 1) {
var value = evaluateBoard(computerState)
if (value != -1){
return value}
}
if (currentLevel > 2) {
var value = evaluateBoard(playerState)
if (value != -1){
return value}
}
if (currentLevel > 4) {
var value = applyLogic(playerState)
if (value != -1)
return value
}
var found = false
while (!found) {
var randno = Math.floor((Math.random() * 9));
if (items.pieces.get(randno).stateTemp == "invisible")
found = true
}
return randno
}
//Returns the position after analyzing such that no double trick is possible
function applyLogic(player) {
if (items.pieces.get(4).stateTemp == "invisible")
return 4
if (!items.playSecond) {
if (items.counter == 1 && track[0] == 4) {
var temp = [0,2,6,8]
var randno = Math.floor((Math.random() * 4));
return temp[randno]
}
if (items.counter == 3 && track[0] == 4) {
var temp = [0,2,6,8]
var found = false
while (!found) {
var randno = Math.floor((Math.random() * 4));
if (items.pieces.get(temp[randno]).stateTemp == "invisible")
found = true
}
return temp[randno]
}
var value = giveNearest()
if (value != -1)
return value
return -1
}
else {
if (items.counter == 2 && track[1] == 4) {
var temp = [0,2,6,8]
var found = false
while (!found) {
var randno = Math.floor((Math.random() * 4));
if (items.pieces.get(temp[randno]).stateTemp == "invisible")
found = true
}
}
else {
var value = giveNearest()
if (value != -1)
return value
return -1
}
}
}
/* One of the function used by applyLogic, giveNearest() returns the immediate empty position (up, down, left or right) to the
* position at which player played his turn. The logic is, that in most cases if computer plays just immediate to where the
* player has played, then player wont be able to get three consecutive marks.
* Returns -1 if no immediate empty position is found
*/
function giveNearest() {
var currentRow = parseInt(currentPiece / items.columns)
var currentCol = parseInt(currentPiece % items.columns)
var temp = []
if ( currentRow + 1 < 3 ) {
if(getPieceState(currentCol, currentRow + 1) == "invisible")
temp.push((currentRow + 1) * items.columns + currentCol)
}
if ( currentRow - 1 > 0 ) {
if(getPieceState(currentCol, currentRow - 1) == "invisible")
temp.push((currentRow - 1) * items.columns + currentCol)
}
if ( currentCol + 1 < 3 ) {
if(getPieceState(currentCol + 1, currentRow) == "invisible")
temp.push(currentRow * items.columns + currentCol + 1)
}
if ( currentCol - 1 > 0 ) {
if(getPieceState(currentCol - 1, currentRow) == "invisible")
temp.push(currentRow * items.columns + currentCol - 1)
}
if (temp.length != 0) {
var randno = Math.floor((Math.random() * temp.length));
return temp[randno]
}
return -1
}
//Starts the process of computer turn
function doMove() {
var pos = setmove ()
handleCreate(items.repeater.itemAt(pos))
}
/* evaluateBoard(player) checks if the player has marked two consecutive places and if third place is empty or not, if found
* such a place, then return that place, else return -1
*/
function evaluateBoard(player) {
var countp, counti, invisibleX, invisibleY
//Horizontal
for(var i = 0; i < 3; i++) {
countp=0
counti=0
for(var j=0; j<3; j++) {
if(getPieceState(j,i) == player)
countp++
else if(getPieceState(j,i) == "invisible") {
counti++
invisibleX=i
invisibleY=j
}
}
if(countp==2 && counti==1) {
return (invisibleX * items.columns + invisibleY)
}
}
//Vertical
for(var i = 0; i < 3; i++) {
countp=0
counti=0
for(var j=0; j<3; j++) {
if(getPieceState(i,j) == player)
countp++
else if(getPieceState(i,j) == "invisible") {
counti++
invisibleX=j
invisibleY=i
}
}
if(countp==2 && counti==1) {
return (invisibleX * items.columns + invisibleY)
}
}
// Diagonal top left / bottom right
countp=0
counti=0
for(var i=0; i<3; i++) {
if(getPieceState(i,i) == player)
countp++
else if(getPieceState(i,i) == "invisible") {
counti++
invisibleX=i
invisibleY=i
}
}
if(countp==2 && counti==1) {
return (invisibleX * items.columns + invisibleY)
}
// Diagonal top right / bottom left
countp=0
counti=0
var j=2
for(var i=0; i<3; i++) {
if(getPieceState(j,i) == player)
countp++
else if(getPieceState(j,i) == "invisible") {
counti++
invisibleX=i
invisibleY=j
}
j--
}
if(countp==2 && counti==1) {
return (invisibleX * items.columns + invisibleY)
}
return -1
}
//Checks the condition if game is won or not
function checkGameWon(currentPieceRow, currentPieceColumn) {
currentPlayer = getPieceState(currentPieceColumn, currentPieceRow)
// Horizontal
var sameColor = 0
for(var col = 0; col < items.columns; col++) {
if(getPieceState(col, currentPieceRow) === currentPlayer) {
if(++sameColor == 3) {
items.repeater.itemAt(currentPieceRow * items.columns + col).visible = true
items.repeater.itemAt(currentPieceRow * items.columns + col -1).visible = true
items.repeater.itemAt(currentPieceRow * items.columns + col -2).visible = true
items.repeater.itemAt(currentPieceRow * items.columns + col).border.color = "#62db53"
items.repeater.itemAt(currentPieceRow * items.columns + col - 1).border.color = "#62db53"
items.repeater.itemAt(currentPieceRow * items.columns + col - 2).border.color = "#62db53"
return true
}
}
else {
sameColor = 0
}
}
// Vertical
sameColor = 0
for(var row = 0; row < items.rows; row++) {
if(getPieceState(currentPieceColumn, row) === currentPlayer) {
if(++sameColor == 3) {
items.repeater.itemAt(row * items.columns + currentPieceColumn).visible = true
items.repeater.itemAt((row - 1) * items.columns + currentPieceColumn).visible = true
items.repeater.itemAt((row -2) * items.columns + currentPieceColumn).visible = true
items.repeater.itemAt(row * items.columns + currentPieceColumn).border.color = "#62db53"
items.repeater.itemAt((row -1) * items.columns + currentPieceColumn).border.color = "#62db53"
items.repeater.itemAt((row -2) * items.columns + currentPieceColumn).border.color = "#62db53"
return true
}
}
else {
sameColor = 0
}
}
// Diagonal top left / bottom right
if(getPieceState(0,0) === currentPlayer && getPieceState(1,1) === currentPlayer && getPieceState(2,2) === currentPlayer) {
items.repeater.itemAt(0).visible = true
items.repeater.itemAt(4).visible = true
items.repeater.itemAt(8).visible = true
items.repeater.itemAt(0).border.color = "#62db53"
items.repeater.itemAt(4).border.color = "#62db53"
items.repeater.itemAt(8).border.color = "#62db53"
return true
}
// Diagonal top right / bottom left
if(getPieceState(2,0) === currentPlayer && getPieceState(1,1) === currentPlayer && getPieceState(0,2) === currentPlayer) {
items.repeater.itemAt(2).visible = true
items.repeater.itemAt(4).visible = true
items.repeater.itemAt(6).visible = true
items.repeater.itemAt(2).border.color = "#62db53"
items.repeater.itemAt(4).border.color = "#62db53"
items.repeater.itemAt(6).border.color = "#62db53"
return true
}
return false
}
//Checks if its Computer's turn or not, if its Computer's turn, then call doMove()
function shouldComputerPlay() {
if(!twoPlayer) {
if(items.counter % 2 && items.playSecond == false && stopper == false) {
doMove()
}
else if((items.counter % 2 == 0) && items.playSecond == true && stopper == false) {
doMove()
}
}
}
//This function is called after every turn to proceed the game
function continueGame() {
items.createPiece.opacity = 0
if (!items.playSecond)
items.pieces.set(currentPiece, {"stateTemp": items.counter++ % 2 ? "2": "1"})
else {
if (items.counter++ % 2 == 0)
items.pieces.set(currentPiece, {"stateTemp": "2"})
else
items.pieces.set(currentPiece, {"stateTemp": "1"})
}
track.push(currentPiece)
/* Update score if game won */
if(twoPlayer) {
if(checkGameWon(parseInt(currentPiece / items.columns),
parseInt(currentPiece % items.columns))) {
items.gameDone = true
if(currentPlayer === "1") {
items.player1score.win()
}
else {
items.player2score.win()
}
items.bonus.good("flower")
items.bonus.isWin = false
}
else if(items.counter == 9) {
items.player1score.endTurn();
items.player2score.endTurn();
items.bonus.bad("tux")
}
else
changeScale()
}
else {
if(checkGameWon(parseInt(currentPiece / items.columns),
parseInt(currentPiece % items.columns))) {
items.gameDone = true
if(currentPlayer == "1") {
items.player1score.win()
items.bonus.good("flower")
}
else {
items.player2score.win()
items.bonus.bad("tux")
}
}
else if(items.counter == 9) {
items.player1score.endTurn();
items.player2score.endTurn();
items.bonus.bad("tux")
}
else
changeScale()
}
}
diff --git a/src/activities/tic_tac_toe_2players/ActivityInfo.qml b/src/activities/tic_tac_toe_2players/ActivityInfo.qml
index a12bb9014..7e0eb6f6c 100644
--- a/src/activities/tic_tac_toe_2players/ActivityInfo.qml
+++ b/src/activities/tic_tac_toe_2players/ActivityInfo.qml
@@ -1,43 +1,43 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2014 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Pulkit Gupta <pulkitgenius@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "tic_tac_toe_2players/Tic_tac_toe_2players.qml"
difficulty: 2
icon: "tic_tac_toe_2players/tic_tac_toe_2players.svg"
author: "Pulkit Gupta &lt;pulkitgenius@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Tic Tac Toe (with a friend)")
//: Help title
description: qsTr("Place three marks in a row")
// intro: "Click on the square which you wish to mark and try to mark 3 consecutive squares before Tux."
//: Help goal
goal: qsTr("Place three respective marks in any horizontal, vertical, or diagonal row to win the game")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("Play with a friend. Take turns to click on the square which you want to mark. First player to create a line of 3 marks wins")
credit: ""
section: "strategy"
createdInVersion: 4000
}
diff --git a/src/activities/tic_tac_toe_2players/Tic_tac_toe_2players.qml b/src/activities/tic_tac_toe_2players/Tic_tac_toe_2players.qml
index bd25632e6..d624b6590 100644
--- a/src/activities/tic_tac_toe_2players/Tic_tac_toe_2players.qml
+++ b/src/activities/tic_tac_toe_2players/Tic_tac_toe_2players.qml
@@ -1,28 +1,28 @@
/* GCompris - tic_tac_toe_2players.qml
*
* Copyright (C) 2014 Pulkit Gupta <pulkitgenius@gmail.com>
*
* Authors:
* Pulkit Gupta <pulkitgenius@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import "../../core"
import "../tic_tac_toe"
TicTacToe {
twoPlayer: true
}
diff --git a/src/activities/traffic/ActivityInfo.qml b/src/activities/traffic/ActivityInfo.qml
index 3a468d23a..3c7c0d020 100644
--- a/src/activities/traffic/ActivityInfo.qml
+++ b/src/activities/traffic/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Holger Kaelberer <holger.k@elberer.de>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "traffic/Traffic.qml"
difficulty: 2
icon: "traffic/traffic.svg"
author: "Holger Kaelberer &lt;holger.k@elberer.de&gt;"
demo: true
//: Activity title
title: qsTr("A sliding-block puzzle game")
//: Help title
description: qsTr("Remove the red car from the parking lot through the gate on the right")
// intro: "Slide the cars to make a space so that the red car can go out of the box."
//: Help goal
goal: ""
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("Each car can only move either horizontally or vertically. You must make some room in order to let the red car move through the gate on the right.")
credit: ""
section: "puzzle"
createdInVersion: 0
}
diff --git a/src/activities/traffic/Car.qml b/src/activities/traffic/Car.qml
index 91b91a89d..ac187ea2f 100644
--- a/src/activities/traffic/Car.qml
+++ b/src/activities/traffic/Car.qml
@@ -1,184 +1,184 @@
/* GCompris - Car.qml
*
* Copyright (C) 2014 Holger Kaelberer <holger.k@elberer.de>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ Mostly full rewrite)
* Holger Kaelberer <holger.k@elberer.de> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import QtGraphicalEffects 1.0
import "../../core"
import "traffic.js" as Activity
Item {
id: car
property int xPos
property int yPos
property int size
property bool goal: false
property bool isHorizontal: false
property alias color: carRect.color
property alias source: carImage.source
property real blockSize: ((parent.width-3) / 6)
property var xBounds: undefined
property var yBounds: undefined
property string mode
property bool isMoving: false
Component.onCompleted: {
mode = parent.mode
connection.target = parent
}
// Connect the jamGrid.mode to car.mode to automatically change the wrapped object
Connections {
id: connection
onModeChanged: {
car.mode = parent.mode;
}
}
x: (mode == "COLOR" || car.isHorizontal) ? (xPos * blockSize) : ((xPos+1) * blockSize)
y: (mode == "COLOR" || car.isHorizontal) ? (yPos * blockSize) : ((yPos) * blockSize)
// track effective coordinates (needed for transformed image):
property real effX: car.xPos * car.blockSize
property real effY: car.yPos * car.blockSize
property real effWidth: (mode == "COLOR" || car.isHorizontal) ? car.width : car.height
property real effHeight: (mode == "COLOR" || car.isHorizontal) ? car.height : car.width
property GCSfx audioEffects
width: (mode == "IMAGE" || isHorizontal) ? (size * blockSize) : blockSize
height: (mode == "IMAGE" || isHorizontal) ? blockSize : (size * blockSize)
Item {
id: carWrapper
anchors.fill: parent
width: parent.width
height: parent.height
Rectangle {
id: carRect
visible: (mode == "COLOR")
z: 11
anchors.fill: parent
width: parent.width
height: parent.height
border.width: 1
border.color: "white"
MultiPointTouchArea {
id: rectTouch
anchors.fill: parent
touchPoints: [ TouchPoint { id: point1 } ]
property real startX;
property real startY;
onPressed: {
if (!Activity.isMoving) {
Activity.isMoving = true;
car.isMoving = true;
car.audioEffects.play(Activity.baseUrl + "car.wav")
rectTouch.startX = point1.x;
rectTouch.startY = point1.y;
}
}
onUpdated: {
if (car.isMoving && !Activity.haveWon) {
var deltaX = point1.x - startX;
var deltaY = point1.y - startY;
Activity.updateCarPosition(car, car.x + deltaX, car.y + deltaY);
}
}
onReleased: {
if (car.isMoving) {
car.isMoving = false;
Activity.isMoving = false;
if (!Activity.haveWon)
Activity.snapCarToGrid(car);
}
}
}
}
Image {
id: carImage
visible: (mode == "IMAGE")
fillMode: Image.PreserveAspectFit
anchors.fill: parent
sourceSize.width: parent.width
sourceSize.height: parent.height
rotation: car.isHorizontal ? 0 : 90
transformOrigin: Item.TopLeft
MultiPointTouchArea {
id: imageTouch
anchors.fill: parent
touchPoints: [ TouchPoint { id: imagePoint } ]
property real startX;
property real startY;
onPressed: {
if (!Activity.isMoving) {
Activity.isMoving = true;
car.isMoving = true;
car.audioEffects.play(Activity.baseUrl + "car.wav")
imageTouch.startX = imagePoint.x;
imageTouch.startY = imagePoint.y;
}
}
onUpdated: {
if (car.isMoving && !Activity.haveWon) {
var deltaX = imagePoint.x - startX;
var deltaY = imagePoint.y - startY;
if (!car.isHorizontal) {
var w = deltaX;
deltaX = deltaY;
deltaY = w;
}
Activity.updateCarPosition(car, car.effX + deltaX, car.effY + deltaY);
}
}
onReleased: {
if (car.isMoving) {
Activity.isMoving = false;
car.isMoving = false;
if (!Activity.haveWon)
Activity.snapCarToGrid(car);
}
}
}
}
}
// note: the following leads to delayed dragging, therefore deactivated:
//Behavior on x { PropertyAnimation { duration: 50 } }
//Behavior on y { PropertyAnimation { duration: 50 } }
}
diff --git a/src/activities/traffic/Traffic.qml b/src/activities/traffic/Traffic.qml
index bd38a8f29..000cc7d87 100644
--- a/src/activities/traffic/Traffic.qml
+++ b/src/activities/traffic/Traffic.qml
@@ -1,192 +1,191 @@
/* GCompris - Traffic.qml
*
* Copyright (C) 2014 Holger Kaelberer <holger.k@elberer.de>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Holger Kaelberer <holger.k@elberer.de> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "traffic.js" as Activity
ActivityBase {
id: activity
onStart: focus = true
onStop: {}
pageComponent: Image {
id: background
source: "qrc:/gcompris/src/activities/traffic/resource/traffic_bg.svg"
sourceSize.width: Math.max(parent.width, parent.height)
fillMode: Image.PreserveAspectCrop
signal start
signal stop
property string mode: "IMAGE" // allow to choose between "COLOR" and "IMAGE"
// mode, candidate for a config dialog
Component.onCompleted: {
dialogActivityConfig.getInitialConfiguration()
activity.start.connect(start)
activity.stop.connect(stop)
}
QtObject {
id: items
property Item main: activity.main
property GCSfx audioEffects: activity.audioEffects
property alias background: background
property alias bar: bar
property alias bonus: bonus
property alias score: score
property alias jamBox: jamBox
property alias jamGrid: jamGrid
}
onStart: { Activity.start(items, mode) }
onStop: { Activity.stop() }
Image {
id: jamBox
source: "qrc:/gcompris/src/activities/traffic/resource/traffic_box.svg"
anchors.centerIn: parent
sourceSize.width: Math.min(background.width * 0.85,
background.height * 0.85)
fillMode: Image.PreserveAspectFit
property double scaleFactor: background.width / background.sourceSize.width
Grid {
id: jamGrid
anchors.centerIn: parent
width: parent.width - 86 * jamBox.scaleFactor * ApplicationInfo.ratio
height: parent.height - 86 * jamBox.scaleFactor * ApplicationInfo.ratio
columns: 6
rows: 6
spacing: 0
// Add an alias to mode so it can be used on Car items
property alias mode: background.mode
Repeater {
id: gridRepeater
model: jamGrid.columns * jamGrid.rows
delegate: Rectangle {
id: gridDelegate
height: jamGrid.height/ jamGrid.rows
width: height
border.width: 1
border.color: "white"
color: "#444444"
}
}
}
}
DialogHelp {
id: dialogHelp
onClose: home()
}
DialogActivityConfig {
id: dialogActivityConfig
currentActivity: activity
content: Component {
Item {
property alias modeBox: modeBox
property var availableModes: [
{ "text": qsTr("Colors"), "value": "COLOR" },
{ "text": qsTr("Images"), "value": "IMAGE" }
]
Flow {
id: flow
spacing: 5
width: dialogActivityConfig.width
GCComboBox {
id: modeBox
model: availableModes
background: dialogActivityConfig
label: qsTr("Select your mode")
}
}
}
}
onClose: home()
onLoadData: {
if(dataToSave && dataToSave["mode"]) {
mode = dataToSave["mode"];
Activity.mode = dataToSave["mode"];
}
}
onSaveData: {
mode = dialogActivityConfig.configItem.availableModes[dialogActivityConfig.configItem.modeBox.currentIndex].value;
dataToSave = {"mode": mode}
Activity.mode = mode;
}
function setDefaultValues() {
for(var i = 0 ; i < dialogActivityConfig.configItem.availableModes.length ; i ++) {
if(dialogActivityConfig.configItem.availableModes[i].value === mode) {
dialogActivityConfig.configItem.modeBox.currentIndex = i;
break;
}
}
}
}
Bar {
id: bar
content: BarEnumContent { value: help | home | level | reload | config }
onHelpClicked: {
displayDialog(dialogHelp)
}
onPreviousLevelClicked: Activity.previousLevel()
onNextLevelClicked: Activity.nextLevel()
onHomeClicked: activity.home()
onReloadClicked: Activity.initLevel()
onConfigClicked: {
dialogActivityConfig.active = true
// Set default values
dialogActivityConfig.setDefaultValues();
displayDialog(dialogActivityConfig)
}
}
Bonus {
id: bonus
Component.onCompleted: win.connect(Activity.nextSubLevel)
}
Score {
id: score
-
anchors.top: parent.top
anchors.topMargin: 10 * ApplicationInfo.ratio
anchors.right: parent.right
anchors.rightMargin: 10 * ApplicationInfo.ratio
anchors.bottom: undefined
}
}
}
diff --git a/src/activities/traffic/traffic.js b/src/activities/traffic/traffic.js
index 3acc43ca8..17bbe10f5 100644
--- a/src/activities/traffic/traffic.js
+++ b/src/activities/traffic/traffic.js
@@ -1,418 +1,418 @@
/* GCompris - traffic.js
*
* Copyright (C) 2014 Holger Kaelberer
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Holger Kaelberer <holger.k@elberer.de> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
.pragma library
.import QtQuick 2.6 as Quick
.import GCompris 1.0 as GCompris
.import QtQml 2.2 as Qml
/* The format and the dataset for the traffic game in gcompris
* is taken from
* http://www.javascript-games.org/puzzle/rushhour/
*
* [LevelX]
* CardY=string describing card 1
* CardY=string describing card 2
* ...
* Where X is the Gcompris Level (in the control bar)
* Where Y is the sublevel.
*
* This is followed by a comma separated list defining the cars on the
* grid. So the string looks as follows:
*
* 'ID''X''Y'
*
* - 'ID' is one char in the range A-R and X
* A-N Specify a different car color of size 2
* O-R Specify a different car color of size 3
* X Always Red, the goal car of size 2
*
* - 'X' xpos numbers between
* 1 to 6 for Vertical car
* A to F for Horizontal car
*
* - 'Y' ypos numbers between
* 1 to 6 for Horizontal car
* A to F for Vertical car
*
*/
var dataList = [
/* [Level1] */
"XD3,O2F",
"XD3,A4C,O2F,PD5",
"XC3,A2E,BE5,O2F,P4B",
"XB3,AB1,B2E,C2F,D4C,OD1,PD4",
"XC3,A3F,BE6,O2E,PD5,Q2B",
/* [Level2] */
"XB3,AE5,O2F,P4D",
"XB3,A2F,B4C,OD4,PB6,QA1,RD1",
"XC3,AC2,B3B,C4C,O2F,PD5",
"XD3,AB2,B4D,CE5,O2F",
"XC3,A1F,B2E,CD4,DE6,E5D,O3F",
/* [Level3] */
"XC3,A2E,BB4,C5B,OA1,PD1,QC5",
"XC3,AB2,B3B,C4D,DE5,O1E",
"XD3,AE2,BE6,C5B,O3F,P4D",
"XD3,AD2,BE5,C4D,OA1,PD1,Q2F",
"XC3,AB4,CE6,D5B,OC5,P1E",
/* [Level4] */
"XC3,AA1,BC2,CE5,D2B,E4C,O1E",
"XA3,AB1,B2C,CD4,E3F,OD1,F4C,QD5",
"XA3,AE4,BC6,CE6,D2C,E2F,F4C,G4D,OD1,P4A",
"XC3,AB2,BD2,CC4,D5B,E3E,FC6,GE6,O2F,PD5",
"XD3,A2C,BD2,C2F,DE4,E4D,F5B,OA1,PD1,QC6",
/* [Level5] */
"XC3,A1C,B2F,C4C,D4D,EE4,FC6,GE6,OD1,P4B",
"XD3,A2B,B4C,CE6,O2F,P4D,Q1A,R4A",
"XD3,A1D,BC5,CC6,DE6,E4E,F5B,GE1,O2F,PB4",
"XB3,AD2,BB4,C3E,DE5,EE6,O2F,P3D",
"XB3,AD2,B3E,CB4,DE5,EE6,OA1,PD1,Q2F,R3D",
/* [Level6] */
"XC3,AC2,BE2,C3E,D3F,EB4,FE5,GE6,HA6,O4D,P3A,QD1",
"XB3,AA1,B5A,CE5,O1F,P2A,Q2D,RC6",
"XA3,A1A,B2D,C3E,D5C,EE5,FA6,GD6,OD1,P2F,QA4",
"XB3,AB4,B5B,CC6,O3D,P4F",
"XB3,A4C,B5F,O1A,P1D,QD4,RC6",
/* [Level7] */
"XB3,AA1,B1D,CA2,DA4,E4C,F5A,O2E,P2F,Q3D,RD6",
"XB3,A1B,BC1,C1E,D1F,E2D,F3F,IC4,H5D",
"XA3,AD1,BC2,C2E,D3C,E3D,FA4,GE4,HA5,I5C,KA6,O1F,PD5,QD6",
"XA3,A1B,BC1,CE1,D2D,EE2,F3F,G5C,H5F,O3E,P4A,QB4",
"XB3,AA1,B1C,CE1,DA2,E5D,FE5,GA6,HE6,O2F,P3A,QB4",
/* [Level8] */
"XB3,AB1,B4C,E5F,O1A,P1D,QD4,RC6",
"XA3,A1A,BB1,C5E,O1F,P2C,QD4,RA6",
"XD3,AA1,BC1,C1E,D2C,E3B,FD4,G5D,HE5,IB6,KE6,O2F,P4A",
"XC3,AA1,B1C,CE2,D3A,E3B,F3E,G3F,HC4,I5C,JE5,KA6",
"XC3,AB1,BD1,CA2,DC2,E4C,F4D,GE5,HB6,ID6,O2E,P2F,Q3A,R3B",
/* [Level9] */
"XD3,AA1,BC1,C1E,D2A,EC2,F3B,GA6,O1F,P3C,QD4",
"XA3,A1A,BC2,CE2,D3C,EA4,F5E,G5F,OB1,P4D,QA5,RA6",
"XB3,AA1,B1C,CA2,DB5,O1D,P3A,QB4,RA6",
"XC3,A1C,BD1,D3B,EC4,F4E,J2E,OB5",
"XA3,A1A,BB2,C2D,D3C,E5C,FD5,OD1,P3F,QD6",
/* [Level10] */
"XB3,AA1,B1C,O1D,P2A,QB4,RD6",
"XB3,A1C,B2A,CE2,D4B,EE4,F5A,GC5,H5F,OD1,P2D,QB6",
"XD3,A2C,BD2,C4C,D4D,EE4,FE5,OC1,P1F,QC6",
"XC3,A1C,BD1,C2B,D3A,E3E,FB4,G5E,HA6,OA5",
"XB3,AA1,B1C,CE1,DA2,E3E,F5B,G5D,HE5,IE6,O2F,P3A,QB4",
/* [Level11] */
"XB3,A1B,B2A,C2D,D3F,E4A,F5C,G5F,HD6,OD1,P2E,RB4",
"XA3,A1A,BB1,CB2,D3C,ED4,F5C,O1D,P3F,RD6",
"XA3,A1D,BE2,C4A,D4B,ED4,FA6,GC6,OA1,P2C,Q4F,RC5",
"XA3,A2C,B3F,C4A,DB4,ED4,FB5,G5D,H5F,OA1,P1E,RA6",
"XB3,A1C,B2D,CA4,DC4,EA6,FC6,O1A,PD1,Q4F",
/* [Level12] */
"XB3,AA1,B2D,CE2,D3A,ED4,FA5,OD1,P3F,Q4C,RD6",
"XA3,AA1,B1D,CE1,D4A,EB4,FD4,HA6,K5D,O1C,P4F",
"XA3,A1B,BE1,DB4,ED4,FB5,G5D,H5E,I4A,P4F,QA6,R1C",
"XA3,A1A,B2D,C3E,D4D,E5C,FE5,HD6,IA6,P2F,QA4,RD1",
"XA3,AD1,B2D,DB5,E5D,F5E,GA6,K4A,O1C,P1F,QB4",
/* [Level13] */
"XC3,AE1,B2B,CC2,D4D,E5C,FE5,GA6,O1A,PB1,Q2F,RA4",
"XB3,AA1,B1C,CE1,DA2,E5D,FE5,GA6,HE6,O2E,P2F,Q3A,RB4",
"XA3,A1A,BB2,C2D,D3C,ED4,F5C,GD5,OD1,QD6,R3F",
"XA3,A1C,B2D,C3C,DA4,ED4,F5A,G5B,HC5,IC6,OD1,R3F",
"XD3,AB1,B1E,C2B,D2C,E4D,F5C,GE5,HA6,ID6,O1A,P2F,QA4"
];
var colorMap = {
'X': "#FF0000",
'A': "#80FF80",
'B': "#C0C000",
'C': "#8080FF",
'D': "#FF80FF",
'E': "#C00000",
'F': "#008000",
'G': "#C0C0C0",
'H': "#6000ef",
'I': "#FFFF00",
'J': "#FFA801",
'K': "#00FF00",
'O': "#FFFF00",
'P': "#FF80FF",
'Q': "#0000FF",
'R': "#00FFFF"
};
var baseUrl="qrc:/gcompris/src/activities/traffic/resource/";
var carList = [
baseUrl + "car1.svg",
baseUrl + "car2.svg",
baseUrl + "car3.svg",
baseUrl + "car4.svg",
baseUrl + "car5.svg",
baseUrl + "car6.svg",
baseUrl + "car7.svg",
baseUrl + "car8.svg",
baseUrl + "car9.svg",
baseUrl + "car10.svg",
baseUrl + "car11.svg",
baseUrl + "car12.svg",
baseUrl + "car13.svg",
baseUrl + "car14.svg",
baseUrl + "car15.svg"
];
var truckList = [
baseUrl + "truck1.svg",
baseUrl + "truck2.svg",
baseUrl + "truck3.svg",
baseUrl + "truck4.svg"
];
var currentLevel = 0;
var currentSubLevel = 0;
var level = null;
var maxLevel = 13;
var maxSubLevel = 5;
var items;
var cars;
var numCars;
var carComponent = null;
var activeCars = new Array();
var haveWon = false;
var mode = null;
var truckIndex = 0;
var carIndex = 0;
var isMoving = false;
function start(items_, mode_) {
items = items_;
mode = mode_;
currentLevel = 0;
currentSubLevel = 0;
initLevel();
}
function stop() {
cleanupActiveCars();
}
function findYBounds(car)
{
if (car.yBounds !== undefined)
return;
var bounds = { "lower": 0, "upper": items.jamGrid.height };
for (var i = 0; i < activeCars.length; i++) {
if (activeCars[i] != car &&
((activeCars[i].xPos == car.xPos)
|| (activeCars[i].isHorizontal && activeCars[i].xPos < car.xPos
&& activeCars[i].xPos+activeCars[i].size > car.xPos)))
{
// y intersects
if (activeCars[i].effY < car.effY &&
activeCars[i].effY + activeCars[i].effHeight > bounds.lower) {
bounds.lower = activeCars[i].effY + activeCars[i].effHeight;
}
else if (activeCars[i].effY > car.effY && activeCars[i].effY < bounds.upper)
bounds.upper = activeCars[i].effY;
}
}
car.yBounds = bounds;
}
function findXBounds(car)
{
if (car.xBounds !== undefined)
return;
var bounds = { "lower": 0, "upper": items.jamGrid.width + (car.goal ? car.blockSize : 0)};
for (var i = 0; i < activeCars.length; i++) {
if (activeCars[i] != car &&
((activeCars[i].yPos == car.yPos)
|| (!activeCars[i].isHorizontal && activeCars[i].yPos < car.yPos
&& activeCars[i].yPos+activeCars[i].size > car.yPos)))
{
// y intersects
if (activeCars[i].effX < car.effX &&
activeCars[i].effX + activeCars[i].effWidth > bounds.lower) {
bounds.lower = activeCars[i].effX + activeCars[i].effWidth;
}
else if (activeCars[i].effX > car.effX && activeCars[i].effX < bounds.upper)
bounds.upper = activeCars[i].effX;
}
}
car.xBounds = bounds;
}
function updateCarPosition(car, newX, newY)
{
if (car.isHorizontal) {
findXBounds(car);
var deltaX = Math.min(car.xBounds.upper - car.effWidth, Math.max(car.xBounds.lower, newX)) - car.effX;
car.x += deltaX;
car.effX += deltaX;
// check for reached goal:
if (car.goal && car.effX + car.width >= items.jamGrid.width) {
haveWon = true;
items.bonus.good("smiley");
return;
}
} else {
findYBounds(car)
var deltaY = Math.min(car.yBounds.upper - car.effHeight, Math.max(car.yBounds.lower, newY)) - car.effY;
car.y += deltaY;
car.effY += deltaY;
}
}
function snapCarToGrid(car)
{
if (car.isHorizontal) {
car.xPos = Math.min(5, Math.max(0, Math.round(car.x / car.blockSize)));
car.x = car.effX = Qt.binding(function() { return car.xPos * car.blockSize; });
} else {
car.yPos = Math.min(5, Math.max(0, Math.round(car.y / car.blockSize)));
car.y = car.effY = Qt.binding(function() { return car.yPos * car.blockSize; });
}
car.xBounds = car.yBounds = undefined;
}
function drawCar(car)
{
if (!carComponent) {
carComponent = Qt.createComponent("qrc:/gcompris/src/activities/traffic/Car.qml");
if (carComponent.status != Qml.Component.Ready) {
console.error("Error creating Rectangle component ("
+ carComponent.status + "): " + carComponent.errorString());
carComponent = null;
return;
}
}
var id = car[0];
var x = car[1];
var y = car[2];
var xPos;
var yPos;
xPos = 0;
yPos = y.charCodeAt(0) - '1'.charCodeAt(0);
var isHorizontal = true;
var size = 0;
var source;
if (id == 'O' || id == 'P' || id == 'Q' || id == 'R') {
size = 3;
source = truckList[Math.floor(truckIndex++ % truckList.length)];
} else {
size = 2;
source = carList[Math.floor(carIndex++ % (carList.length-1)) + 1];
}
if (x == 'A') xPos = 0;
else if (x == 'B') xPos = 1;
else if (x == 'C') xPos = 2;
else if (x == 'D') xPos = 3;
else if (x == 'E') xPos = 4;
else if (x == 'F') xPos = 5;
else { // vertical
yPos = x.charCodeAt(0) - '1'.charCodeAt(0); //vertical
isHorizontal = false;
if (y == 'A') xPos = 0;
else if (y == 'B') xPos = 1;
else if (y == 'C') xPos = 2;
else if (y == 'D') xPos = 3;
else if (y == 'E') xPos = 4;
else if (y == 'F') xPos = 5;
}
var color = colorMap[id];
var goal;
if (id == 'X') {
goal = 1;
source = carList[0];
}
var carObject = carComponent.createObject( items.jamGrid, {
"xPos": xPos,
"yPos": yPos,
"size": size,
"goal": goal,
"color": color,
"source": source,
"isHorizontal": isHorizontal,
"audioEffects": items.audioEffects
});
if (carObject == null)
console.error("traffic: Error creating Car object!");
else
activeCars.push(carObject);
}
function drawJam()
{
for (var i = 0; i < cars.length; i++)
drawCar(cars[i]);
}
function cleanupActiveCars()
{
while (activeCars.length > 0)
activeCars.pop().destroy();
}
function initLevel() {
// destroy old cars
isMoving = false;
cleanupActiveCars();
truckIndex = 0;
carIndex = 0;
items.bar.level = currentLevel + 1;
if (currentSubLevel == 0) {
// initialize level
items.score.numberOfSubLevels = maxSubLevel;
}
// initialize sublevel
haveWon = false;
items.score.currentSubLevel = currentSubLevel + 1;
cars = dataList[(currentLevel * maxSubLevel) + currentSubLevel].split(",");
drawJam();
}
function nextLevel() {
if(maxLevel <= ++currentLevel ) {
currentLevel = 0
}
currentSubLevel = 0;
initLevel();
}
function previousLevel() {
if(--currentLevel < 0) {
currentLevel = maxLevel - 1
}
currentSubLevel = 0;
initLevel();
}
function nextSubLevel() {
if( ++currentSubLevel >= maxSubLevel) {
currentSubLevel = 0;
nextLevel();
} else
initLevel();
}
diff --git a/src/activities/watercycle/ActivityInfo.qml b/src/activities/watercycle/ActivityInfo.qml
index a04e63c6c..f1bdaee96 100644
--- a/src/activities/watercycle/ActivityInfo.qml
+++ b/src/activities/watercycle/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Sagar Chand Agarwal <atomsagar@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "watercycle/Watercycle.qml"
difficulty: 3
icon: "watercycle/watercycle.svg"
author: "Sagar Chand Agarwal &lt;atomsagar@gmail.com&gt;"
demo: true
//: Activity title
title: qsTr("Watercycle")
//: Help title
description: qsTr("Tux has come back from fishing on his boat. Bring the water system back up so he can take a shower.")
//intro: "Click on the various active elements that make up the water supply. Then press the shower button for Tux."
//: Help goal
goal: qsTr("Learn the water cycle")
//: Help prerequisite
prerequisite: ""
//: Help manual
manual: qsTr("Click on different active elements: sun, cloud, pumping station, and the sewage treatment plant, in order to reactivate the entire water system. When the system is back up and Tux is in the shower, push the shower button for him.")
credit: qsTr("Drawing by Stephane Cabaraux.")
section: "experiment"
createdInVersion: 5000
}
diff --git a/src/activities/watercycle/Watercycle.qml b/src/activities/watercycle/Watercycle.qml
index b662c5c60..452b33f54 100644
--- a/src/activities/watercycle/Watercycle.qml
+++ b/src/activities/watercycle/Watercycle.qml
@@ -1,802 +1,802 @@
/* GCompris - watercycle.qml
*
* Copyright (C) 2015 Sagar Chand Agarwal <atomsagar@gmail.com>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net>(GTK+ version)
* Sagar Chand Agarwal <atomsagar@gmail.com> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "."
ActivityBase {
id: activity
onStart: focus = true
onStop: {}
property string url: "qrc:/gcompris/src/activities/watercycle/resource/"
property var barAtStart
pageComponent: Item {
id: background
anchors.fill: parent
signal start
signal stop
Component.onCompleted: {
activity.start.connect(start)
activity.stop.connect(stop)
}
onStart: {
barAtStart = ApplicationSettings.isBarHidden;
ApplicationSettings.isBarHidden = true;
shower.hide()
river.level = 0
}
onStop: {
ApplicationSettings.isBarHidden = barAtStart;
}
QtObject {
id: items
property var dataset: {
"none": "",
"start": qsTr("Sun is the main component of water cycle. Click on the sun to start the water cycle."),
"sun": qsTr("As the sun rises, the water of the sea starts heating and evaporates."),
"cloud": qsTr(" Water vapor condenses to form cloud and when clouds become heavy, it rains. Click on the cloud."),
"rain": qsTr("Rain causes rivers to swell up and this water is transported to us via motor pumps through water-tower." +
" Click on the motor pump to supply water to residents."),
"tower": qsTr("See the tower filled with water. Activate the sewage treatment station by clicking on it."),
"shower": qsTr("Great, click on the shower, as Tux arrives home."),
"done": qsTr("Fantastic, you have completed water cycle. You can continue playing.")
}
property bool cycleDone: false
property GCSfx audioEffects: activity.audioEffects
}
IntroMessage {
id: message
anchors {
top: parent.top
topMargin: 10
right: parent.right
rightMargin: 5
left: parent.left
leftMargin: 5
}
z: 100
onIntroDone: {
anim.running = true
info.visible = true
sun_area.enabled = true
}
intro: [
qsTr("The water cycle (also known as the hydrologic cycle) is the journey water takes"
+" as it circulates from the land to the sky and back again."
+" The sun's heat provides energy to evaporate water from water bodies like oceans."),
qsTr("Plants also lose water to the air through transpiration. The water vapor eventually, "
+"cools forming tiny droplets in clouds. When the clouds meet cool air over land, "
+"precipitation is triggered and fall down as rain.") ,
qsTr("Some of the water is trapped between rock or clay layers, called groundwater. "
+"But most of the water flows as runoff, eventually returning to the seas via rivers."),
qsTr("Your goal is to complete water cycle before Tux reaches home. "
+"Click on the different components which make up the water cycle. "
+"First click on sun, then cloud, water pumping station near the river, "
+"sewage treatment, and at last regulate the switch to provide water to Tux's shower.")
]
}
Image {
id: sky
anchors.top: parent.top
sourceSize.width: parent.width
source: activity.url + "sky.svg"
height: (background.height - landscape.paintedHeight) / 2 + landscape.paintedHeight * 0.3
z: 1
}
Image {
id: sea
anchors {
left: parent.left
bottom: parent.bottom
}
sourceSize.width: parent.width
source: activity.url + "sea.svg"
height: (background.height - landscape.paintedHeight) / 2 + landscape.paintedHeight * 0.7
z:3
}
Image {
id: landscape
anchors.fill: parent
sourceSize.width: parent.width
source: activity.url + "landscape.svg"
z: 6
}
Image {
id: tuxboat
opacity: 1
source: activity.url + "boat.svg"
sourceSize.width: parent.width*0.15
sourceSize.height: parent.height*0.15
anchors{
bottom: parent.bottom
bottomMargin: 15
}
x:0
z:30
Behavior on opacity { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 200 } }
NumberAnimation on x {
id: anim
running: false
to: parent.width - tuxboat.width
duration: 15000
easing.type: Easing.InOutSine
onRunningChanged: {
if(!anim.running)
{
items.audioEffects.play('qrc:/gcompris/src/activities/watercycle/resource/harbor2.wav')
tuxboat.opacity = 0
boatparked.opacity = 1
shower.stop()
if(!sun.hasRun)
info.setText('start')
} else {
items.audioEffects.play('qrc:/gcompris/src/activities/watercycle/resource/harbor1.wav')
}
}
}
}
Image {
id: boatparked
source: activity.url + "boat_parked.svg"
sourceSize.width: parent.width*0.15
sourceSize.height: parent.height*0.15
opacity: 0
anchors {
right: parent.right
bottom: parent.bottom
bottomMargin: 20
}
z: 29
Behavior on opacity { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 200 } }
}
Image {
id: sun
source: activity.url + "sun.svg"
sourceSize.width: parent.width * 0.05
anchors {
left: parent.left
top: parent.top
leftMargin: parent.width*0.05
topMargin: parent.height * 0.28
}
z: 2
property bool hasRun: false
MouseArea {
id: sun_area
anchors.fill: sun
onClicked: {
if(cloud.opacity == 0)
sun.up()
}
}
Behavior on anchors.topMargin { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 5000 } }
function up() {
items.audioEffects.play('qrc:/gcompris/src/core/resource/sounds/bleep.wav')
info.setText('sun')
sun.hasRun = true
sun.anchors.topMargin = parent.height * 0.05
vapor.up()
}
function down() {
sun.anchors.topMargin = parent.height * 0.28
}
}
Image {
id: vapor
opacity: 0
state: "vapor"
source: activity.url + "vapor.svg"
sourceSize.width: parent.width*0.05
anchors {
left: sun.left
}
y: background.height * 0.28
z: 10
SequentialAnimation {
id: vaporAnim
loops: 2
NumberAnimation {
target: vapor
property: "opacity"
duration: 200
from: 0
to: 1
}
NumberAnimation {
target: vapor
property: "y"
duration: 5000
from: background.height * 0.28
to: background.height * 0.1
}
NumberAnimation {
target: vapor
property: "opacity"
duration: 200
from: 1
to: 0
}
NumberAnimation {
target: vapor
property: "y"
duration: 0
to: background.height * 0.28
}
onRunningChanged: {
if(!running)
info.setText('cloud')
}
}
function up() {
vaporAnim.start()
cloud.up()
}
function down() {
}
}
Image {
id: cloud
opacity: 0
source: activity.url + "cloud.svg"
sourceSize.width: parent.width * 0.20
fillMode: Image.PreserveAspectFit
width: 0
anchors {
top: parent.top
topMargin: parent.height * 0.05
}
x: parent.width * 0.05
z: 11
MouseArea {
id: cloud_area
anchors.fill: cloud
onClicked: {
sun.down()
rain.up()
}
}
ParallelAnimation {
id: cloudanimOn
running: false
PropertyAnimation {
target: cloud
property: 'opacity'
easing.type: Easing.InOutQuad
duration: 5000
from: 0
to: 1
}
PropertyAnimation {
target: cloud
property: 'width'
easing.type: Easing.InOutQuad
duration: 15000
from: 0
to: cloud.sourceSize.width
}
PropertyAnimation {
target: cloud
property: 'x'
easing.type: Easing.InOutQuad
duration: 15000
from: background.width * 0.05
to: background.width * 0.4
}
}
SequentialAnimation {
id: cloudanimOff
running: false
PropertyAnimation {
target: cloud
property: 'opacity'
easing.type: Easing.InOutQuad
duration: 3000
from: 1
to: 0
}
PropertyAnimation {
target: cloud
property: 'width'
easing.type: Easing.InOutQuad
duration: 0
to: 0
}
PropertyAnimation {
target: cloud
property: 'x'
easing.type: Easing.InOutQuad
duration: 0
to: background.width * 0.05
}
}
function up() {
cloudanimOn.start()
}
function down() {
opacity = 0
width = 0
x = parent.width * 0.05
}
}
Image {
id: rain
source: activity.url + "rain.svg"
sourceSize.height: cloud.height * 2
opacity: 0
anchors {
top: cloud.bottom
}
x: cloud.x
z: 10
Behavior on opacity { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 300 } }
SequentialAnimation{
id: rainAnim
running: false
loops: 10
NumberAnimation {
target: rain
property: "scale"
duration: 500
to: 0.95
}
NumberAnimation {
target: rain
property: "scale"
duration: 500
to: 1
}
onRunningChanged: {
if(!running) {
rain.down()
cloud.down()
}
}
}
function up() {
items.audioEffects.play('qrc:/gcompris/src/core/resource/sounds/water.wav')
info.setText('rain')
opacity = 1
rainAnim.start()
}
function down() {
opacity = 0
}
}
Image {
id: river
source: activity.url + "river.svg"
sourceSize.width: parent.width * 0.415
sourceSize.height: parent.height * 0.74
width: parent.width * 0.415
height: parent.height * 0.74
opacity: level > 0 ? 1 : 0
anchors {
top: parent.top
left: parent.left
topMargin: parent.height*0.1775
leftMargin: parent.width*0.293
}
z: 10
Behavior on opacity { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 5000 } }
property double level: 0
}
Image {
id: reservoir1
source: activity.url + "reservoir1.svg"
sourceSize.width: parent.width*0.06
width: parent.width*0.06
height: parent.height*0.15
anchors {
top: parent.top
left: parent.left
topMargin: parent.height*0.2925
leftMargin: parent.width*0.3225
}
opacity: river.level > 0.2 ? 1 : 0
z: 10
Behavior on opacity { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 5000 } }
}
Image {
id: reservoir2
source: activity.url + "reservoir2.svg"
sourceSize.width: parent.width*0.12
width: parent.width*0.12
height: parent.height*0.155
anchors {
top: parent.top
left: parent.left
topMargin: parent.height*0.2925
leftMargin: parent.width*0.285
}
opacity: river.level > 0.5 ? 1 : 0
z: 10
Behavior on opacity { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 5000 } }
}
Image {
id: reservoir3
source: activity.url + "reservoir3.svg"
sourceSize.width: parent.width*0.2
width: parent.width*0.2
height: parent.height*0.17
anchors {
top: parent.top
left: parent.left
topMargin: parent.height*0.29
leftMargin: parent.width*0.25
}
opacity: river.level > 0.8 ? 1 : 0
z: 10
Behavior on opacity { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 5000 } }
}
Image {
id: waterplant
source: activity.url + "motor.svg"
sourceSize.width: parent.width*0.07
sourceSize.height: parent.height*0.08
anchors {
top: parent.top
left:parent.left
topMargin: parent.height*0.38
leftMargin: parent.width*0.4
}
z: 20
property bool running: false
MouseArea {
id: motor_area
enabled: river.level > 0.2
anchors.fill: parent
onClicked: {
items.audioEffects.play('qrc:/gcompris/src/activities/watercycle/resource/bubble.wav')
info.setText('tower')
waterplant.running = true
}
}
}
Image {
id: fillpipe
anchors.fill: parent
sourceSize.width: parent.width
width: parent.width
source: activity.url + "fillwater.svg"
opacity: waterplant.running ? 1 : 0.1
z: 9
Behavior on opacity { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 300 } }
}
Image {
id: sewageplant
source: activity.url + "waste.svg"
sourceSize.height: parent.height * 0.15
anchors {
top: parent.top
left: parent.left
topMargin: parent.height*0.74
leftMargin: parent.width*0.66
}
z: 11
property bool running: false
MouseArea {
id: waste_area
enabled: river.opacity == 1
anchors.fill: parent
onClicked: {
items.audioEffects.play('qrc:/gcompris/src/activities/watercycle/resource/bubble.wav')
info.setText('shower')
sewageplant.running = true
}
}
}
Image {
id: wastepipe
anchors.fill: parent
sourceSize.width: parent.width
width: parent.width
source: activity.url + "wastewater.svg"
opacity: sewageplant.running ? 1 : 0.1
z: 10
Behavior on opacity { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 300 } }
}
Image {
id: tower
source: activity.url + "watertower.svg"
sourceSize.width: parent.width*0.18
sourceSize.height: parent.height*0.15
anchors {
top: parent.top
right: parent.right
topMargin: parent.height*0.225
rightMargin: parent.width*0.175
}
z: 10
property double level: 0
Image {
id: towerfill
scale: tower.level
source: activity.url + "watertowerfill.svg"
sourceSize.width: tower.width*0.4
anchors {
top: tower.top
left:tower.left
topMargin: tower.height*0.13
leftMargin: tower.width*0.3
}
Behavior on scale { PropertyAnimation { duration: timer.interval } }
}
}
Image {
id: shower
source: activity.url + "shower.svg"
sourceSize.height: parent.height*0.2
sourceSize.width: parent.width*0.15
anchors {
bottom: parent.bottom
right: parent.right
bottomMargin: parent.height* 0.32
rightMargin: parent.width*0.012
}
z: 10
visible: false
property bool on: false
MouseArea {
id: shower_area
anchors.fill: parent
onClicked: {
if(!shower.on &&
river.opacity == 1 && wastepipe.opacity > 0.8 &&
fillpipe.opacity > 0.8 && tower.level > 0.5)
shower.start()
else
shower.stop()
}
}
function start() {
shower.on = true
shower.visible = true
showerhot.visible = true
tuxbath.visible = true
showercold.visible = false
tuxoff.visible = false
if(!items.cycleDone) {
info.setText('done')
bonus.good('smiley')
items.cycleDone = true
}
items.audioEffects.play('qrc:/gcompris/src/activities/watercycle/resource/apert.wav')
}
function stop() {
shower.on = false
shower.visible = true
showerhot.visible = false
tuxbath.visible = false
showercold.visible = true
tuxoff.visible = true
}
function hide() {
shower.visible = false
shower.on = false
tuxoff.visible = false
showercold.visible = false
showerhot.visible = false
tuxbath.visible = false
}
}
Image {
id: tuxoff
source:activity.url + "tuxoff.svg"
sourceSize.width: shower.height * 0.4
anchors {
horizontalCenter: shower.horizontalCenter
verticalCenter: shower.verticalCenter
verticalCenterOffset: shower.height*0.1
horizontalCenterOffset: -shower.width*0.05
}
z: 10
visible: false
}
Image {
id: tuxbath
source: activity.url + "tuxbath.svg"
sourceSize.width: shower.height * 0.5
anchors {
horizontalCenter: shower.horizontalCenter
verticalCenter: shower.verticalCenter
verticalCenterOffset: shower.height*0.1
horizontalCenterOffset: -shower.width*0.05
}
z: 10
visible: false
}
Image {
id: showerhot
source: activity.url + "showerhot.svg"
sourceSize.width: shower.width * 0.1
anchors {
right: shower.right
top: shower.top
rightMargin: shower.width*0.15
topMargin: shower.height*0.25
}
z: 10
visible: false
}
Image {
id: showercold
source: activity.url + "showercold.svg"
sourceSize.width: shower.width * 0.1
anchors {
right: shower.right
top: shower.top
rightMargin: shower.width*0.15
topMargin: shower.height*0.25
}
z: 10
visible: false
}
// Manage stuff that changes periodically
Timer {
id: timer
interval: 100
running: true
repeat: true
onTriggered: {
if(rain.opacity > 0.9 && river.level < 1) {
river.level += 0.01
}
if(river.level > 0 && fillpipe.opacity > 0.9 && tower.level < 1 && !shower.on) {
river.level -= 0.02
tower.level += 0.05
}
if(tower.level > 0 && shower.on) {
tower.level -= 0.02
}
if(tower.level <= 0 && boatparked.opacity) {
shower.stop()
}
}
}
GCText {
id: info
visible: true
fontSize: smallSize
font.weight: Font.DemiBold
horizontalAlignment: Text.AlignHCenter
anchors {
top: parent.top
topMargin: 10 *ApplicationInfo.ratio
right: parent.right
rightMargin: 5 * ApplicationInfo.ratio
left: parent.left
leftMargin: parent.width * 0.50
}
width: parent.width
wrapMode: Text.WordWrap
z: 100
onTextChanged: textanim.start()
property string newKey
SequentialAnimation {
id: textanim
NumberAnimation {
target: info
property: "opacity"
duration: 200
from: 1
to: 0
}
PropertyAction {
target: info
property: 'text'
value: items.dataset[info.newKey]
}
NumberAnimation {
target: info
property: "opacity"
duration: 200
from: 0
to: 1
}
}
function setText(key) {
if(newKey != key) {
newKey = key
textanim.start()
}
}
}
Rectangle {
id: infoBg
z: 99
anchors.fill: info
color: '#8ebfc7'
radius: width * 0.01
opacity: info.text ? 0.7 : 0
Behavior on opacity { PropertyAnimation { easing.type: Easing.InOutQuad; duration: 200 } }
}
DialogHelp {
id: dialogHelp
onClose: home()
}
Bar {
id: bar
content: BarEnumContent { value: help | home }
onHelpClicked: {
displayDialog(dialogHelp)
}
onHomeClicked: activity.home()
}
Bonus {
id:bonus
}
}
}
diff --git a/src/activities/wordsgame/ActivityInfo.qml b/src/activities/wordsgame/ActivityInfo.qml
index c3af8a16d..21a68cbd4 100644
--- a/src/activities/wordsgame/ActivityInfo.qml
+++ b/src/activities/wordsgame/ActivityInfo.qml
@@ -1,40 +1,40 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Holger Kaelberer <holger.k@elberer.de>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "wordsgame/Wordsgame.qml"
difficulty: 2
icon: "wordsgame/wordsgame.svg"
author: "Holger Kaelberer &lt;holger.k@elberer.de&gt;"
demo: true
//: Activity title
title: qsTr("Falling Words")
//: Help title
description: qsTr("Type the falling words before they reach the ground")
// intro: "Type the words on your keyboard before they reach the ground."
//: Help goal
goal: qsTr("Keyboard training")
//: Help prerequisite
prerequisite: qsTr("Keyboard manipulation")
//: Help manual
manual: qsTr("Type the complete word as it falls, before it reaches the ground")
credit: ""
section: "computer keyboard reading"
createdInVersion: 0
}
diff --git a/src/activities/wordsgame/Wordsgame.qml b/src/activities/wordsgame/Wordsgame.qml
index a731e08fa..d9fb1ab0b 100644
--- a/src/activities/wordsgame/Wordsgame.qml
+++ b/src/activities/wordsgame/Wordsgame.qml
@@ -1,35 +1,35 @@
/* GCompris - Wordsgame.qml
*
* Copyright (C) 2014 Holger Kaelberer <holger.k@elberer.de>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net> (GTK+ version)
* Holger Kaelberer <holger.k@elberer.de> (Qt Quick port)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "../../core"
import "../gletters"
Gletters {
id: activity
mode: "word"
dataSetUrl: "qrc:/gcompris/src/activities/wordsgame/resource/"
}
diff --git a/src/core/ActivityBase.qml b/src/core/ActivityBase.qml
index 8ce64ce8d..c084588e2 100644
--- a/src/core/ActivityBase.qml
+++ b/src/core/ActivityBase.qml
@@ -1,254 +1,254 @@
/* GCompris - ActivityBase.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "qrc:/gcompris/src/core/core.js" as Core
/**
* The base QML component for activities in GCompris.
* @ingroup components
*
* Each activity should be derived from this component. It is responsible for
*
* * basic common key handling,
* * unified audio handling,
* * screen switching dynamics (from/to Menu/DialogHelp/etc.)
*
* The following common keys are handled so far:
*
* * @c Ctrl+q: Exit the application.
* * @c Ctrl+b: Toggle the bar.
* * @c Ctrl+f: Toggle fullscreen.
* * @c Ctrl+m: Toggle audio effects.
* * @c Ctrl+w: Exit the current activity and return to the menu.
* * @c Ctrl+p: Make a screenshot.
* * @c Back: Return to the home screen (corresponds to the 'Back' button on
* Android).
*
* Cf. Template.qml for a sample skeleton activity.
*
* Cf.
- * [the wiki](http://gcompris.net/wiki/Qt_Quick_development_process#Adding_a_new_activity)
+ * [the wiki](https://gcompris.net/wiki/Qt_Quick_development_process#Adding_a_new_activity)
* for further information about creating a new activity.
*
* @inherit QtQuick.Item
*/
Item {
id: page
/**
* type:Item
* Parent object.
*/
property Item main: parent;
/**
* type:Component
* The top-level component containing the visible viewport of an activity.
*
* Put all you want to present the user into this container. Mostly
* implemented using a Rectangle or Image component, itself
* containing further graphical elements. You are pretty free of doing
* whatever you want inside this component.
*
* Also common elements as Bar, Score, DialogHelp, etc. should be placed
* inside this element.
*/
property Component pageComponent
/**
* type:QtObject
* Reference to the menu activity.
*
* Populated automatically during activity-loading.
*/
property QtObject menu
/**
* type:QtObject
* Reference to the ActivityInfo object of the activity.
*
* Populated automatically during activity-loading.
*/
property QtObject activityInfo
/**
* type:GCAudio
* The global audio item for voices.
*
* Because of problems synchronizing multiple Audio objects between
* global/menu/main and individual activities, activities should refrain
* from implementing additional Audio elements.
*
* Instead append to this global object to play your voices after the
* intro music.
* @sa GCAudio audioVoices
*/
property GCAudio audioVoices
/**
* type:GCSfx
* The global audio item for audio effects.
*
* Use it to play your effects.
* @sa GCSfx audioEffects
*/
property GCSfx audioEffects
/**
* type:Loading
* The global loading object.
*
* Start it to signal heavy computation in case of GUI freezes.
* @sa Loading
*/
property Loading loading
/**
* type:string
* The resource folder for the current activity. The resources
* of each activity needs to be stored with the same pattern.
* "qrc:/gcompris/src/activities/" + activity name + "/resource/"
*
*/
property string resourceUrl: (activityInfo && activityInfo.name) ? "qrc:/gcompris/src/activities/" + activityInfo.name.split('/')[0] + "/resource/": ""
/**
* type: bool
* This variable stores if the activity is a musical activity.
*
* If it is a musical activity and the audioEffects is disabled, we temporarily unmute the GCSfx audioEffects for that activity and mute again on exiting it in main.qml.
*/
property bool isMusicalActivity: false
property alias datasetLoader: datasetLoader
property string levelFolder
/**
* Emitted when the user wants to return to the Home/Menu screen.
*/
signal home
/**
* Emitted when the user wants to return several views back in the
* page stack.
*/
signal back(Item to)
/**
* Emitted every time the activity has been started.
*
* Initialize your activity upon this signal.
*/
signal start
/**
* Emitted when the activity is about to stop
*
* Shutdown whatever you need to upon this signal.
*/
signal stop
/**
* Emitted when dialog @p dialog should be shown
*
* Emit this signal when you want to show another dialog, e.g. on
* Bar.onHelpClicked
*
* @param dialog Dialog to show.
*/
signal displayDialog(Item dialog)
/**
* Emitted when multiple @p dialogs should be pushed on the page-stack
*
* Emit this signal when you want to stack >1 views. The last one will be
* shown the intermediated ones will be kept on the page stack for later
* pop() calls.
*
* @param dialogs Array of dialogs to push;
*/
signal displayDialogs(var dialogs)
onBack: menu ? menu.back(to) : ""
onHome: menu ? menu.home() : ""
onDisplayDialog: menu ? menu.displayDialog(dialog) : ""
onDisplayDialogs: menu ? menu.displayDialogs(dialogs) : ""
Keys.forwardTo: activity.children
Keys.onEscapePressed: home();
Keys.onPressed: {
if (event.modifiers === Qt.ControlModifier &&
event.key === Qt.Key_Q) {
// Ctrl+Q exit the application
Core.quit(main);
} else if (event.modifiers === Qt.ControlModifier &&
event.key === Qt.Key_B) {
// Ctrl+B toggle the bar
ApplicationSettings.isBarHidden = !ApplicationSettings.isBarHidden;
} else if (event.modifiers === Qt.ControlModifier &&
event.key === Qt.Key_F) {
// Ctrl+F toggle fullscreen
ApplicationSettings.isFullscreen = !ApplicationSettings.isFullscreen
} else if (event.modifiers === Qt.ControlModifier &&
event.key === Qt.Key_M) {
// Ctrl+M toggle sound
// We mute / unmute both channels in sync
ApplicationSettings.isAudioVoicesEnabled = !ApplicationSettings.isAudioVoicesEnabled
ApplicationSettings.isAudioEffectsEnabled = !ApplicationSettings.isAudioEffectsEnabled
} else if (event.modifiers === Qt.ControlModifier &&
event.key === Qt.Key_W) {
// Ctrl+W exit the current activity
home()
} else if (event.modifiers === Qt.ControlModifier &&
event.key === Qt.Key_P) {
// Ctrl+P Screenshot
ApplicationInfo.screenshot("/tmp/" + activityInfo.name.split('/')[0] + ".png")
}
}
Keys.onReleased: {
if (event.key === Qt.Key_Back) {
event.accepted = true
home()
}
}
Loader {
id: activity
sourceComponent: pageComponent
anchors.fill: parent
}
Loader {
id: demoPageLoader
source: ApplicationSettings.activationMode == 1 ?
"BuyMeOverlayInapp.qml" : "BuyMeOverlay.qml"
anchors.fill: parent
active: !activityInfo.demo && ApplicationSettings.isDemoMode
}
Loader {
id: datasetLoader
asynchronous: false
source: resourceUrl + levelFolder + "/Data.qml"
active: levelFolder != ""
}
}
diff --git a/src/core/ActivityInfo.cpp b/src/core/ActivityInfo.cpp
index 767a40b14..2281fdab3 100644
--- a/src/core/ActivityInfo.cpp
+++ b/src/core/ActivityInfo.cpp
@@ -1,242 +1,245 @@
/* GCompris - ActivityInfo.cpp
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
#include "ActivityInfo.h"
#include <QtDebug>
#include <QQmlProperty>
#include <QQmlEngine>
#include <QQmlComponent>
#include "ApplicationSettings.h"
ActivityInfo::ActivityInfo(QObject *parent):
QObject(parent),
+ m_difficulty(0),
m_demo(true),
m_favorite(false),
m_enabled(true),
m_createdInVersion(0)
{
}
QString ActivityInfo::name() const
{
return m_name;
}
void ActivityInfo::setName(const QString &name)
{
m_name = name;
// Once we are given a name, we can get the favorite property
// from the persistant configuration
- if(!ApplicationSettings::getInstance()->isKioskMode())
- m_favorite = ApplicationSettings::getInstance()->isFavorite(m_name);
+ m_favorite = ApplicationSettings::getInstance()->isFavorite(m_name);
setCurrentLevel();
emit nameChanged();
}
QString ActivityInfo::section() const
{
return m_section;
}
void ActivityInfo::setSection(const QString &section)
{
m_section = section;
emit sectionChanged();
}
quint32 ActivityInfo::difficulty() const
{
return m_difficulty;
}
void ActivityInfo::setDifficulty(const quint32 &difficulty)
{
m_difficulty = difficulty;
emit difficultyChanged();
}
QString ActivityInfo::icon() const
{
return m_icon;
}
void ActivityInfo::setIcon(const QString &icon)
{
m_icon = icon;
emit iconChanged();
}
QString ActivityInfo::author() const
{
return m_author;
}
void ActivityInfo::setAuthor(const QString &author)
{
m_author = author;
emit authorChanged();
}
bool ActivityInfo::demo() const
{
return m_demo;
}
void ActivityInfo::setDemo(const bool &demo)
{
m_demo = demo;
emit demoChanged();
}
QString ActivityInfo::title() const
{
return m_title;
}
void ActivityInfo::setTitle(const QString &title)
{
m_title = title;
emit titleChanged();
}
QString ActivityInfo::description() const
{
return m_description;
}
void ActivityInfo::setDescription(const QString &description)
{
m_description = description;
emit descriptionChanged();
}
QString ActivityInfo::goal() const
{
return m_goal;
}
void ActivityInfo::setGoal(const QString &goal)
{
m_goal = goal;
emit goalChanged();
}
QString ActivityInfo::prerequisite() const
{
return m_prerequisite;
}
void ActivityInfo::setPrerequisite(const QString &prerequisite)
{
m_prerequisite = prerequisite;
emit prerequisiteChanged();
}
QString ActivityInfo::manual() const
{
return m_manual;
}
void ActivityInfo::setManual(const QString &manual)
{
m_manual = manual;
emit manualChanged();
}
QString ActivityInfo::credit() const
{
return m_credit;
}
void ActivityInfo::setCredit(const QString &credit)
{
m_credit = credit;
emit creditChanged();
}
bool ActivityInfo::favorite() const
{
return m_favorite;
}
void ActivityInfo::setFavorite(const bool favorite)
{
m_favorite = favorite;
ApplicationSettings::getInstance()->setFavorite(m_name, m_favorite);
emit favoriteChanged();
}
bool ActivityInfo::enabled() const
{
return m_enabled;
}
void ActivityInfo::setEnabled(const bool enabled)
{
m_enabled = enabled;
emit enabledChanged();
}
int ActivityInfo::createdInVersion() const
{
return m_createdInVersion;
}
void ActivityInfo::setCreatedInVersion(const int created)
{
m_createdInVersion = created;
emit createdInVersionChanged();
}
+<<<<<<< HEAD
QStringList ActivityInfo::levels() const
{
return m_levels;
}
void ActivityInfo::setLevels(const QStringList &levels)
{
// levels only contains one element containing all the difficulties
m_levels = levels.front().split(',');
setCurrentLevel();
emit levelsChanged();
}
QString ActivityInfo::currentLevel() const
{
return m_currentLevel;
}
void ActivityInfo::setCurrentLevel(const QString &currentLevel)
{
m_currentLevel = currentLevel;
emit currentLevelChanged();
}
void ActivityInfo::setCurrentLevel()
{
if(!m_name.isEmpty()) {
if(!m_levels.empty() && ApplicationSettings::getInstance()->currentLevel(m_name) == "") {
ApplicationSettings::getInstance()->setCurrentLevel(m_name, m_levels[0]);
}
m_currentLevel = ApplicationSettings::getInstance()->currentLevel(m_name);
}
}
QStringList ActivityInfo::getSectionPath()
{
QStringList path;
ActivityInfo *activity(this);
do {
path.prepend(activity->section());
} while( ( activity = qobject_cast<ActivityInfo*>(activity->parent()) ) );
return path;
}
+=======
+>>>>>>> master
diff --git a/src/core/ActivityInfo.h b/src/core/ActivityInfo.h
index b50a48bee..c63ca6c3d 100644
--- a/src/core/ActivityInfo.h
+++ b/src/core/ActivityInfo.h
@@ -1,222 +1,220 @@
/* GCompris - ActivityInfo.h
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
#ifndef ACTIVITYINFO_H
#define ACTIVITYINFO_H
#include <QObject>
#include <QString>
#include <QStringList>
#include <QQmlListProperty>
/**
* @class ActivityInfo
* @short A QML component holding meta information about an activity.
* @ingroup components
*
* Each GCompris activity has to provide some meta data about itself in form
* of an ActivityInfo definition. This data will be used to register it in the
* ActivityInfoTree, and populate the full screen help dialog.
*
* @sa DialogHelp
*/
class ActivityInfo : public QObject
{
Q_OBJECT
/**
* Name of the main activity QML file.
*
* Example: "activity/Activity.qml"
*/
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
/**
* Section(s) this activity belongs to.
*
* An activity can belong to one or multiple activity sections
* (separated by whitespace) out of:
* computer, discovery, experiment, fun, math, puzzle,
* reading, strategy.
*/
Q_PROPERTY(QString section READ section WRITE setSection NOTIFY sectionChanged)
/**
* Difficulty of the activity.
*
* A difficulty level from 1 (easiest) to 6 (most difficult).
*/
Q_PROPERTY(quint32 difficulty READ difficulty WRITE setDifficulty NOTIFY difficultyChanged)
/**
* Relative path to the icon of the activity.
*
* Example: "activity/activity.svg"
*/
Q_PROPERTY(QString icon READ icon WRITE setIcon NOTIFY iconChanged)
/**
* Author of the activity.
*/
Q_PROPERTY(QString author READ author WRITE setAuthor NOTIFY authorChanged)
/**
* Whether the activity is part of the demo version of GCompris.
*/
Q_PROPERTY(bool demo READ demo WRITE setDemo NOTIFY demoChanged)
/**
* Title of the activity.
*/
Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged)
/**
* Description of the activity.
*/
Q_PROPERTY(QString description READ description WRITE setDescription NOTIFY descriptionChanged)
/**
* Goal that this activity wants to achieve.
*/
Q_PROPERTY(QString goal READ goal WRITE setGoal NOTIFY goalChanged)
/**
* Prerequisite for using this activity.
*/
Q_PROPERTY(QString prerequisite READ prerequisite WRITE setPrerequisite NOTIFY prerequisiteChanged)
/**
* Manual describing the activity's usage.
*/
Q_PROPERTY(QString manual READ manual WRITE setManual NOTIFY manualChanged)
/**
* Credits to third parties.
*/
Q_PROPERTY(QString credit READ credit WRITE setCredit NOTIFY creditChanged)
Q_PROPERTY(bool favorite READ favorite WRITE setFavorite NOTIFY favoriteChanged)
/**
* This activity is enabled.
*/
Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
/**
* Version in which this activity has been created
*/
Q_PROPERTY(int createdInVersion READ createdInVersion WRITE setCreatedInVersion NOTIFY createdInVersionChanged)
/**
* Contains a list of string defining the folder names for the different datasets.
*/
Q_PROPERTY(QStringList levels READ levels WRITE setLevels NOTIFY levelsChanged)
/**
* Current dataset used for the activity (it is among the 'levels' list)
*/
Q_PROPERTY(QString currentLevel READ currentLevel WRITE setCurrentLevel NOTIFY currentLevelChanged)
public:
/// @cond INTERNAL_DOCS
explicit ActivityInfo(QObject *parent = 0);
QString name() const;
void setName(const QString &);
QString section() const;
void setSection(const QString &);
quint32 difficulty() const;
void setDifficulty(const quint32 &);
QString icon() const;
void setIcon(const QString &);
QString author() const;
void setAuthor(const QString &);
bool demo() const;
void setDemo(const bool &);
QString title() const;
void setTitle(const QString &);
QString description() const;
void setDescription(const QString &);
QString goal() const;
void setGoal(const QString &);
QString prerequisite() const;
void setPrerequisite(const QString &);
QString manual() const;
void setManual(const QString &);
QString credit() const;
void setCredit(const QString &);
bool favorite() const;
void setFavorite(const bool);
bool enabled() const;
void setEnabled(const bool);
int createdInVersion() const;
void setCreatedInVersion(const int);
QStringList levels() const;
void setLevels(const QStringList&);
QString currentLevel() const;
void setCurrentLevel(const QString&);
- QStringList getSectionPath();
-
signals:
void nameChanged();
void sectionChanged();
void difficultyChanged();
void iconChanged();
void authorChanged();
void demoChanged();
void titleChanged();
void descriptionChanged();
void goalChanged();
void prerequisiteChanged();
void manualChanged();
void creditChanged();
void favoriteChanged();
void enabledChanged();
void createdInVersionChanged();
void levelsChanged();
void currentLevelChanged();
/// @endcond
private:
QString m_name;
QString m_section;
quint32 m_difficulty;
QString m_icon;
QString m_author;
bool m_demo;
QString m_title;
QString m_description;
QString m_goal;
QString m_prerequisite;
QString m_manual;
QString m_credit;
bool m_favorite;
bool m_enabled;
int m_createdInVersion;
QStringList m_levels;
QString m_currentLevel;
/*
* Set current level once we have the name and the levels
*/
void setCurrentLevel();
};
#endif // ACTIVITYINFO_H
diff --git a/src/core/ActivityInfoTree.cpp b/src/core/ActivityInfoTree.cpp
index 477cc7f84..5a6f2d13f 100644
--- a/src/core/ActivityInfoTree.cpp
+++ b/src/core/ActivityInfoTree.cpp
@@ -1,345 +1,340 @@
/* GCompris - ActivityInfoTree.cpp
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
#include "ActivityInfoTree.h"
#include "ApplicationInfo.h"
#include <QtDebug>
#include <QQmlProperty>
#include <QQmlComponent>
#include <QResource>
#include <QStandardPaths>
#include <QCoreApplication>
#include <QTextStream>
ActivityInfoTree::ActivityInfoTree(QObject *parent) : QObject(parent),
- m_currentActivity(NULL)
+ m_rootMenu(nullptr), m_currentActivity(nullptr)
{
}
void ActivityInfoTree::setRootMenu(ActivityInfo *rootMenu)
{
m_rootMenu = rootMenu;
}
ActivityInfo *ActivityInfoTree::getRootMenu() const
{
return m_rootMenu;
}
QQmlListProperty<ActivityInfo> ActivityInfoTree::menuTree()
{
- return QQmlListProperty<ActivityInfo>(this, NULL, &menuTreeCount, &menuTreeAt);
+ return {this, nullptr, &menuTreeCount, &menuTreeAt};
}
int ActivityInfoTree::menuTreeCount(QQmlListProperty<ActivityInfo> *property)
{
ActivityInfoTree *obj = qobject_cast<ActivityInfoTree*>(property->object);
- if(obj)
+ if(obj != nullptr)
return obj->m_menuTree.count();
- else
- return 0;
+
+ return 0;
}
ActivityInfo *ActivityInfoTree::menuTreeAt(QQmlListProperty<ActivityInfo> *property, int index)
{
ActivityInfoTree *obj = qobject_cast<ActivityInfoTree*>(property->object);
- if(obj)
+ if(obj != nullptr)
return obj->m_menuTree.at(index);
- else
- return 0;
+
+ return nullptr;
}
ActivityInfo *ActivityInfoTree::menuTree(int index) const
{
return m_menuTree.at(index);
}
void ActivityInfoTree::setCurrentActivity(ActivityInfo *currentActivity)
{
m_currentActivity = currentActivity;
emit currentActivityChanged();
}
ActivityInfo *ActivityInfoTree::getCurrentActivity() const
{
return m_currentActivity;
}
void ActivityInfoTree::menuTreeAppend(ActivityInfo *menu)
{
m_menuTreeFull.append(menu);
}
void ActivityInfoTree::menuTreeAppend(QQmlEngine *engine,
const QDir &menuDir, const QString &menuFile)
{
QQmlComponent component(engine,
QUrl::fromLocalFile(menuDir.absolutePath() + '/' + menuFile));
QObject *object = component.create();
if(component.isReady()) {
if(QQmlProperty::read(object, "section").toString() == "/") {
menuTreeAppend(qobject_cast<ActivityInfo*>(object));
}
} else {
qDebug() << menuFile << ": Failed to load";
}
}
void ActivityInfoTree::sortByDifficulty(bool emitChanged)
{
std::sort(m_menuTree.begin(), m_menuTree.end(), SortByDifficulty());
if (emitChanged)
Q_EMIT menuTreeChanged();
}
void ActivityInfoTree::sortByName(bool emitChanged)
{
std::sort(m_menuTree.begin(), m_menuTree.end(), SortByName());
if (emitChanged)
Q_EMIT menuTreeChanged();
}
// Filter the current activity list by the given tag
// the tag 'all' means no filter
// the tag 'favorite' means only marked as favorite
// The level is also filtered based on the global property
void ActivityInfoTree::filterByTag(const QString &tag, bool emitChanged)
{
m_menuTree.clear();
// https://www.kdab.com/goodbye-q_foreach/, for loops on QList may cause detach
const auto constMenuTreeFull = m_menuTreeFull;
for(const auto &activity: constMenuTreeFull) {
if((activity->section().indexOf(tag) != -1 ||
tag == "all" ||
(tag == "favorite" && activity->favorite())) &&
(activity->difficulty() >= ApplicationSettings::getInstance()->filterLevelMin() &&
activity->difficulty() <= ApplicationSettings::getInstance()->filterLevelMax())) {
m_menuTree.push_back(activity);
}
}
sortByDifficulty();
if (emitChanged)
Q_EMIT menuTreeChanged();
}
void ActivityInfoTree::filterByDifficulty(quint32 levelMin, quint32 levelMax)
{
auto it = std::remove_if(m_menuTree.begin(), m_menuTree.end(),
[&](const ActivityInfo* activity) {
return activity->difficulty() < levelMin || activity->difficulty() > levelMax;
});
m_menuTree.erase(it, m_menuTree.end());
}
void ActivityInfoTree::filterLockedActivities(bool emitChanged)
{
// If we have the full version or if we show all the activities, we don't need to do anything
if(!ApplicationSettings::getInstance()->isDemoMode() || ApplicationSettings::getInstance()->showLockedActivities())
return;
// Remove non free activities if needed. We need to already have a menuTree filled!
auto it = std::remove_if(m_menuTree.begin(), m_menuTree.end(),
[](const ActivityInfo* activity) { return !activity->demo(); });
m_menuTree.erase(it, m_menuTree.end());
if (emitChanged)
Q_EMIT menuTreeChanged();
}
void ActivityInfoTree::filterEnabledActivities(bool emitChanged)
{
auto it = std::remove_if(m_menuTree.begin(), m_menuTree.end(),
[](const ActivityInfo* activity) { return !activity->enabled(); });
m_menuTree.erase(it, m_menuTree.end());
if (emitChanged)
Q_EMIT menuTreeChanged();
}
void ActivityInfoTree::filterCreatedWithinVersions(int firstVersion,
int lastVersion,
bool emitChanged)
{
m_menuTree.clear();
const auto constMenuTreeFull = m_menuTreeFull;
for(const auto &activity: constMenuTreeFull) {
if(firstVersion < activity->createdInVersion() && activity->createdInVersion() <= lastVersion) {
m_menuTree.push_back(activity);
}
}
if (emitChanged)
Q_EMIT menuTreeChanged();
}
void ActivityInfoTree::exportAsSQL()
{
QTextStream cout(stdout);
ApplicationSettings::getInstance()->setFilterLevelMin(1);
ApplicationSettings::getInstance()->setFilterLevelMax(6);
filterByTag("all");
cout << "CREATE TABLE activities (" <<
"id INT UNIQUE, " <<
"name TEXT," <<
"section TEXT," <<
"author TEXT," <<
"difficulty INT," <<
"icon TEXT," <<
"title TEXT," <<
"description TEXT," <<
"prerequisite TEXT," <<
"goal TEXT," <<
"manual TEXT," <<
"credit TEXT," <<
"demo INT);" << endl;
cout << "DELETE FROM activities" << endl;
int i(0);
const auto constMenuTree = m_menuTree;
for(const auto &activity: constMenuTree) {
cout << "INSERT INTO activities VALUES(" <<
i++ << ", " <<
"'" << activity->name() << "', " <<
"'" << activity->section() << "', " <<
"'" << activity->author() << "', " <<
activity->difficulty() << ", " <<
"'" << activity->icon() << "', " <<
"\"" << activity->title() << "\", " <<
"\"" << activity->description() << "\", " <<
"\"" << activity->prerequisite() << "\", " <<
"\"" << activity->goal().toHtmlEscaped() << "\", " <<
"\"" << activity->manual().toHtmlEscaped() << "\", " <<
"\"" << activity->credit() << "\", " <<
- activity->demo() <<
+ static_cast<int>(activity->demo()) <<
");" << endl;
}
}
QObject *ActivityInfoTree::menuTreeProvider(QQmlEngine *engine, QJSEngine *scriptEngine)
{
Q_UNUSED(scriptEngine)
- ActivityInfoTree *menuTree = new ActivityInfoTree(NULL);
+ ActivityInfoTree *menuTree = new ActivityInfoTree(nullptr);
QQmlComponent componentRoot(engine,
QUrl("qrc:/gcompris/src/activities/menu/ActivityInfo.qml"));
QObject *objectRoot = componentRoot.create();
menuTree->setRootMenu(qobject_cast<ActivityInfo*>(objectRoot));
QFile file(":/gcompris/src/activities/activities_out.txt");
if(!file.open(QFile::ReadOnly)) {
qDebug() << "Failed to load the activity list";
}
QTextStream in(&file);
while (!in.atEnd()) {
QString line = in.readLine();
if(!line.startsWith(QLatin1String("#"))) {
QString url = QString("qrc:/gcompris/src/activities/%1/ActivityInfo.qml").arg(line);
if(!QResource::registerResource(
ApplicationInfo::getFilePath(line + ".rcc")))
qDebug() << "Failed to load the resource file " << line + ".rcc";
QQmlComponent componentRoot(engine, QUrl(url));
QObject *objectRoot = componentRoot.create();
- if(objectRoot) {
+ if(objectRoot != nullptr) {
menuTree->menuTreeAppend(qobject_cast<ActivityInfo*>(objectRoot));
} else {
qDebug() << "ERROR: failed to load " << line << " " << componentRoot.errors();
}
}
}
file.close();
menuTree->filterByTag("favorite");
menuTree->filterLockedActivities();
menuTree->filterEnabledActivities();
return menuTree;
}
-void ActivityInfoTree::init()
+void ActivityInfoTree::registerResources()
{
if(!QResource::registerResource(ApplicationInfo::getFilePath("core.rcc")))
qDebug() << "Failed to load the resource file " << ApplicationInfo::getFilePath("core.rcc");
if(!QResource::registerResource(ApplicationInfo::getFilePath("menu.rcc")))
qDebug() << "Failed to load the resource file menu.rcc";
if(!QResource::registerResource(ApplicationInfo::getFilePath("activities.rcc")))
qDebug() << "Failed to load the resource file activities.rcc";
if(QResource::registerResource(ApplicationSettings::getInstance()->cachePath() +
"/data2/" + QString("full-%1.rcc").arg(COMPRESSED_AUDIO)))
qDebug() << "Registered the pre-download " << QString("full-%1.rcc").arg(COMPRESSED_AUDIO);
-
- qmlRegisterSingletonType<QObject>("GCompris", 1, 0, "ActivityInfoTree", menuTreeProvider);
- qmlRegisterType<ActivityInfo>("GCompris", 1, 0, "ActivityInfo");
-
-
}
void ActivityInfoTree::filterBySearch(const QString& text)
{
m_menuTree.clear();
if(!text.trimmed().isEmpty()) {
// perform search on each word entered in the searchField
const QStringList wordsList = text.split(' ', QString::SkipEmptyParts);
for(const QString &searchTerm: wordsList) {
const QString trimmedText = searchTerm.trimmed();
- const auto constMenuTreeFull = m_menuTreeFull;
+ const auto &constMenuTreeFull = m_menuTreeFull;
for(const auto &activity: constMenuTreeFull) {
if(activity->title().contains(trimmedText, Qt::CaseInsensitive) ||
activity->name().contains(trimmedText, Qt::CaseInsensitive) ||
activity->description().contains(trimmedText, Qt::CaseInsensitive)) {
// add the activity only if it's not added
if(m_menuTree.indexOf(activity) == -1)
m_menuTree.push_back(activity);
}
}
}
}
else
m_menuTree = m_menuTreeFull;
filterEnabledActivities(false);
filterLockedActivities(false);
filterByDifficulty(ApplicationSettings::getInstance()->filterLevelMin(), ApplicationSettings::getInstance()->filterLevelMax());
sortByDifficulty(false);
Q_EMIT menuTreeChanged();
}
QVariantList ActivityInfoTree::allCharacters() {
QSet<QChar> keyboardChars;
const auto constMenuTreeFull = m_menuTreeFull;
- for(auto &tree: constMenuTreeFull) {
+ for(const auto &tree: constMenuTreeFull) {
const QString &title = tree->title();
- Q_FOREACH(const QChar &letter, title) {
+ for(const QChar &letter: title) {
if(!letter.isSpace() && !letter.isPunct()) {
keyboardChars.insert(letter.toLower());
}
}
}
- Q_FOREACH(const QString &letters, keyboardChars) {
+ for(const QChar &letters: keyboardChars) {
m_keyboardCharacters.push_back(letters);
}
std::sort(m_keyboardCharacters.begin(), m_keyboardCharacters.end());
return m_keyboardCharacters;
}
diff --git a/src/core/ActivityInfoTree.h b/src/core/ActivityInfoTree.h
index e8396be97..817be12b3 100644
--- a/src/core/ActivityInfoTree.h
+++ b/src/core/ActivityInfoTree.h
@@ -1,99 +1,99 @@
/* GCompris - ActivityInfoTree.h
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
#ifndef ACTIVITYINFOTREE_H
#define ACTIVITYINFOTREE_H
#include "ActivityInfo.h"
#include <QQmlEngine>
#include <QDir>
class ActivityInfoTree : public QObject
{
Q_OBJECT
Q_PROPERTY(ActivityInfo* rootMenu READ getRootMenu CONSTANT)
Q_PROPERTY(QQmlListProperty<ActivityInfo> menuTree READ menuTree NOTIFY menuTreeChanged)
Q_PROPERTY(ActivityInfo* currentActivity READ getCurrentActivity WRITE setCurrentActivity NOTIFY currentActivityChanged)
Q_PROPERTY(QVariantList characters READ allCharacters CONSTANT)
public:
explicit ActivityInfoTree(QObject *parent = 0);
QQmlListProperty<ActivityInfo> menuTree();
ActivityInfo *getRootMenu() const;
void setRootMenu(ActivityInfo *rootMenu);
ActivityInfo *menuTree(int) const;
void setCurrentActivity(ActivityInfo *currentActivity);
ActivityInfo *getCurrentActivity() const;
void menuTreeAppend(ActivityInfo *menu);
void menuTreeAppend(QQmlEngine *engine,
const QDir &menuDir, const QString &menuFile);
void sortByDifficulty(bool emitChanged = true);
void sortByName(bool emitChanged = true);
QVariantList allCharacters();
protected Q_SLOTS:
Q_INVOKABLE void filterByTag(const QString &tag, bool emitChanged = true);
Q_INVOKABLE void filterLockedActivities(bool emitChanged = true);
Q_INVOKABLE void filterEnabledActivities(bool emitChanged = true);
// create a tree from the whole list of activities with the activities created between the two versions
Q_INVOKABLE void filterCreatedWithinVersions(int firstVersion, int lastVersion,
bool emitChanged = true);
Q_INVOKABLE void filterBySearch(const QString& text);
Q_INVOKABLE void filterByDifficulty(quint32 levelMin, quint32 levelMax);
signals:
void menuTreeChanged();
void currentActivityChanged();
void allCharactersChanged();
private:
// this is the full activity list, it never changes
QList<ActivityInfo *> m_menuTreeFull;
// represents the Menu view and can be filtered
QList<ActivityInfo *> m_menuTree;
ActivityInfo *m_rootMenu;
ActivityInfo *m_currentActivity;
QVariantList m_keyboardCharacters;
static int menuTreeCount(QQmlListProperty<ActivityInfo> *property);
static ActivityInfo *menuTreeAt(QQmlListProperty<ActivityInfo> *property, int index);
struct SortByDifficulty
{
bool operator()(const ActivityInfo *a, const ActivityInfo *b) const
{
return a->difficulty() < b->difficulty();
}
};
struct SortByName
{
bool operator()(const ActivityInfo *a, const ActivityInfo *b) const
{
return a->name() < b->name();
}
};
public:
- static void init();
+ static void registerResources();
static QObject *menuTreeProvider(QQmlEngine *engine, QJSEngine *scriptEngine);
void exportAsSQL();
};
#endif // ACTIVITYINFOTREE_H
diff --git a/src/core/ApplicationAndroid.cpp b/src/core/ApplicationAndroid.cpp
index 622bfc092..e9c513798 100644
--- a/src/core/ApplicationAndroid.cpp
+++ b/src/core/ApplicationAndroid.cpp
@@ -1,126 +1,126 @@
-/* GCompris - ApplicationSettingsAndroid.cpp
+/* GCompris - ApplicationAndroid.cpp
*
* Copyright (C) 2014-2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
#include "ApplicationSettings.h"
#include "ApplicationInfo.h"
#include <QAndroidJniObject>
#include <QDebug>
#include <QtAndroid>
void ApplicationSettings::setDemoMode(const bool newDemoMode)
{
if(!newDemoMode) {
// Call Google play store
QAndroidJniObject::callStaticMethod<void>("net/gcompris/GComprisActivity",
"buyGCompris");
} else {
// Going back to demo mode, should never happens except for testing
ApplicationSettings::getInstance()->bought(false);
}
}
void ApplicationSettings::checkPayment() {
#if defined(WITH_ACTIVATION_CODE)
QAndroidJniObject::callStaticMethod<void>("net/gcompris/GComprisActivity",
"checkPayment");
#endif
}
uint ApplicationSettings::checkActivationCode(const QString &code) {
// Not used in inapp mode.
return 0;
}
static void bought(JNIEnv *, jclass /*clazz*/, jboolean b)
{
ApplicationSettings::getInstance()->bought(b);
}
static JNINativeMethod methods[] = {
{"bought", "(Z)V", (void *)bought}
};
bool ApplicationInfo::requestAudioFocus() const
{
qDebug() << "requestAudioFocus";
return QAndroidJniObject::callStaticMethod<jboolean>("net/gcompris/GComprisActivity",
"requestAudioFocus");
}
void ApplicationInfo::abandonAudioFocus() const
{
QAndroidJniObject::callStaticMethod<void>("net/gcompris/GComprisActivity",
"abandonAudioFocus");
}
jint JNICALL JNI_OnLoad(JavaVM *vm, void *)
{
JNIEnv *env;
if (vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_4) != JNI_OK)
return JNI_FALSE;
jclass clazz = env->FindClass("net/gcompris/GComprisActivity");
if (env->RegisterNatives(clazz, methods, sizeof(methods) / sizeof(methods[0])) < 0)
return JNI_FALSE;
return JNI_VERSION_1_4;
}
void ApplicationInfo::setRequestedOrientation(int orientation)
{
QAndroidJniObject activity = QtAndroid::androidActivity();
activity.callMethod<void>("setRequestedOrientation", "(I)V", orientation);
}
int ApplicationInfo::getRequestedOrientation()
{
QAndroidJniObject activity = QtAndroid::androidActivity();
jint orientation = activity.callMethod<jint>("getRequestedOrientation");
return orientation;
}
void ApplicationInfo::setKeepScreenOn(bool value)
{
QAndroidJniObject activity = QtAndroid::androidActivity();
activity.callMethod<void>("setKeepScreenOn", "(Z)V", value);
}
int ApplicationInfo::localeCompare(const QString& a, const QString& b,
const QString& locale) const
{
QString _locale = locale.isEmpty() ? \
ApplicationSettings::getInstance()->locale() \
: locale;
if (_locale == GC_DEFAULT_LOCALE)
_locale = QLocale::system().name();
// QCollator on Android uses only the posix backend as of Qt 5.5.1,
// which is not capable of doing locale aware comparison.
// cf. https://bugreports.qt.io/browse/QTBUG-43637
// Therefore use native Collation via jni:
jint res = QtAndroid::androidActivity().callMethod<jint>(
"localeCompare",
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I",
QAndroidJniObject::fromString(a).object<jstring>(),
QAndroidJniObject::fromString(b).object<jstring>(),
QAndroidJniObject::fromString(_locale).object<jstring>());
return res;
}
diff --git a/src/core/ApplicationInfo.cpp b/src/core/ApplicationInfo.cpp
index d8618bea0..d1ca1052d 100644
--- a/src/core/ApplicationInfo.cpp
+++ b/src/core/ApplicationInfo.cpp
@@ -1,268 +1,287 @@
/* GCompris - ApplicationInfo.cpp
*
* Copyright (C) 2014-2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This file was originally created from Digia example code under BSD license
* and heavily modified since then.
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
#include "ApplicationInfo.h"
#include <QtQml>
#include <QtMath>
#include <QUrl>
#include <QUrlQuery>
#include <QGuiApplication>
#include <QScreen>
#include <QLocale>
#include <QQuickWindow>
#include <QStandardPaths>
#include <QSensor>
#include <qmath.h>
#include <QDebug>
#include <QFontDatabase>
#include <QDir>
-QQuickWindow *ApplicationInfo::m_window = NULL;
-ApplicationInfo *ApplicationInfo::m_instance = NULL;
+QQuickWindow *ApplicationInfo::m_window = nullptr;
+ApplicationInfo *ApplicationInfo::m_instance = nullptr;
ApplicationInfo::ApplicationInfo(QObject *parent): QObject(parent)
{
- m_isMobile = false;
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) || defined(Q_OS_BLACKBERRY) || defined(SAILFISHOS)
m_isMobile = true;
+#else
+ m_isMobile = false;
#endif
#if defined(Q_OS_ANDROID)
// Put android before checking linux/unix as it is also a linux
m_platform = Android;
#elif defined(Q_OS_MAC)
m_platform = MacOSX;
#elif (defined(Q_OS_LINUX) || defined(Q_OS_UNIX))
m_platform = Linux;
#elif defined(Q_OS_WIN)
m_platform = Windows;
#elif defined(Q_OS_IOS)
m_platform = Ios;
#elif defined(Q_OS_BLACKBERRY)
m_platform = Blackberry;
#elif defined(SAILFISHOS)
m_platform = SailfishOS;
+#else // default is Linux
+ m_platform = Linux;
#endif
+ m_isBox2DInstalled = false;
+
QRect rect = qApp->primaryScreen()->geometry();
m_ratio = qMin(qMax(rect.width(), rect.height())/800. , qMin(rect.width(), rect.height())/520.);
// calculate a factor for font-scaling, cf.
// http://doc.qt.io/qt-5/scalability.html#calculating-scaling-ratio
qreal refDpi = 216.;
qreal refHeight = 1776.;
qreal refWidth = 1080.;
qreal height = qMax(rect.width(), rect.height());
qreal width = qMin(rect.width(), rect.height());
qreal dpi = qApp->primaryScreen()->logicalDotsPerInch();
m_fontRatio = qMax(qreal(1.0), qMin(height*refDpi/(dpi*refHeight), width*refDpi/(dpi*refWidth)));
m_isPortraitMode = m_isMobile ? rect.height() > rect.width() : false;
m_applicationWidth = m_isMobile ? rect.width() : 1120;
+ m_useOpenGL = true;
+
if (m_isMobile)
connect(qApp->primaryScreen(), &QScreen::physicalSizeChanged, this, &ApplicationInfo::notifyPortraitMode);
// @FIXME this does not work on iOS: https://bugreports.qt.io/browse/QTBUG-50624
#if not defined(Q_OS_IOS)
// Get all symbol fonts to remove them
QFontDatabase database;
m_excludedFonts = database.families(QFontDatabase::Symbol);
#endif
// Get fonts from rcc
const QStringList fontFilters = {"*.otf", "*.ttf"};
m_fontsFromRcc = QDir(":/gcompris/src/core/resource/fonts").entryList(fontFilters);
-
}
ApplicationInfo::~ApplicationInfo()
{
- m_instance = NULL;
+ m_instance = nullptr;
}
bool ApplicationInfo::sensorIsSupported(const QString& sensorType)
{
return QSensor::sensorTypes().contains(sensorType.toUtf8());
}
Qt::ScreenOrientation ApplicationInfo::getNativeOrientation()
{
return QGuiApplication::primaryScreen()->nativeOrientation();
}
void ApplicationInfo::setApplicationWidth(const int newWidth)
{
if (newWidth != m_applicationWidth) {
m_applicationWidth = newWidth;
emit applicationWidthChanged();
}
}
QString ApplicationInfo::getResourceDataPath()
{
return QString("qrc:/gcompris/data");
}
QString ApplicationInfo::getFilePath(const QString &file)
{
#if defined(Q_OS_ANDROID)
- return QString("assets:/%1").arg(file);
+ return QString("assets:/share/GCompris/rcc/%1").arg(file);
#elif defined(Q_OS_MACX)
return QString("%1/../Resources/rcc/%2").arg(QCoreApplication::applicationDirPath(), file);
#elif defined(Q_OS_IOS)
return QString("%1/rcc/%2").arg(QCoreApplication::applicationDirPath(), file);
#else
return QString("%1/%2/rcc/%3").arg(QCoreApplication::applicationDirPath(), GCOMPRIS_DATA_FOLDER, file);
#endif
}
QString ApplicationInfo::getAudioFilePath(const QString &file)
{
QString localeName = getVoicesLocale(ApplicationSettings::getInstance()->locale());
return getAudioFilePathForLocale(file, localeName);
}
QString ApplicationInfo::getAudioFilePathForLocale(const QString &file,
const QString &localeName)
{
QString filename = file;
filename.replace("$LOCALE", localeName);
- filename.replace("$CA", COMPRESSED_AUDIO);
+ filename.replace("$CA", CompressedAudio());
if(file.startsWith('/') || file.startsWith(QLatin1String("qrc:")) || file.startsWith(':'))
return filename;
- else
- return getResourceDataPath() + '/' + filename;
+ return getResourceDataPath() + '/' + filename;
}
QString ApplicationInfo::getLocaleFilePath(const QString &file)
{
QString localeShortName = localeShort();
QString filename = file;
filename.replace("$LOCALE", localeShortName);
return filename;
}
-QString ApplicationInfo::getSharedWritablePath() const
-{
- return QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)
- + QLatin1String("/GCompris");
-}
-
QStringList ApplicationInfo::getSystemExcludedFonts()
{
return m_excludedFonts;
}
QStringList ApplicationInfo::getFontsFromRcc()
{
return m_fontsFromRcc;
}
void ApplicationInfo::notifyPortraitMode()
{
int width = qApp->primaryScreen()->geometry().width();
int height = qApp->primaryScreen()->geometry().height();
setIsPortraitMode(height > width);
}
void ApplicationInfo::setIsPortraitMode(const bool newMode)
{
if (m_isPortraitMode != newMode) {
m_isPortraitMode = newMode;
emit portraitModeChanged();
}
}
void ApplicationInfo::setWindow(QQuickWindow *window)
{
m_window = window;
}
-void ApplicationInfo::screenshot(QString const &path)
+void ApplicationInfo::screenshot(const QString &file)
{
QImage img = m_window->grabWindow();
- img.save(path);
+ img.save(file);
}
void ApplicationInfo::notifyFullscreenChanged()
{
if(ApplicationSettings::getInstance()->isFullscreen())
m_window->showFullScreen();
else
m_window->showNormal();
}
+// Would be better to create a component importing Box2D 2.0 using QQmlContext and test if it exists but it does not work.
+void ApplicationInfo::setBox2DInstalled(const QQmlEngine &engine) {
+ /*
+ QQmlContext *context = new QQmlContext(engine.rootContext());
+ context->setContextObject(&myDataSet);
+
+ QQmlComponent component(&engine);
+ component.setData("import QtQuick 2.0\nimport Box2D 2.0\nItem { }", QUrl());
+ component.create(context);
+ box2dInstalled = (component != nullptr);
+ */
+ bool box2dInstalled = false;
+ for(const QString &folder: engine.importPathList()) {
+ if(QDir(folder).entryList().contains(QStringLiteral("Box2D.2.0"))) {
+ if(QDir(folder+"/Box2D.2.0").entryList().contains("qmldir")) {
+ qDebug() << "Found box2d in " << folder;
+ box2dInstalled = true;
+ break;
+ }
+ }
+ }
+ m_isBox2DInstalled = box2dInstalled;
+ emit isBox2DInstalledChanged();
+}
+
// return the shortest possible locale name for the given locale, describing
// a unique voices dataset
QString ApplicationInfo::getVoicesLocale(const QString &locale)
{
QString _locale = locale;
if(_locale == GC_DEFAULT_LOCALE) {
_locale = QLocale::system().name();
if(_locale == "C")
_locale = "en_US";
}
// locales we have country-specific voices for:
if (_locale.startsWith(QLatin1String("pt_BR")) ||
_locale.startsWith(QLatin1String("zh_CN")) ||
_locale.startsWith(QLatin1String("zh_TW")))
return QLocale(_locale).name();
// short locale for all the rest:
return localeShort(_locale);
}
QVariantList ApplicationInfo::localeSort(QVariantList list,
const QString& locale) const
{
std::sort(list.begin(), list.end(),
[&locale,this](const QVariant& a, const QVariant& b) {
return (localeCompare(a.toString(), b.toString(), locale) < 0);
});
return list;
}
-QObject *ApplicationInfo::systeminfoProvider(QQmlEngine *engine,
+QObject *ApplicationInfo::applicationInfoProvider(QQmlEngine *engine,
QJSEngine *scriptEngine)
{
Q_UNUSED(engine)
Q_UNUSED(scriptEngine)
/*
* Connect the fullscreen change signal to applicationInfo in order to change
* the QQuickWindow value
*/
ApplicationInfo* appInfo = getInstance();
connect(ApplicationSettings::getInstance(), &ApplicationSettings::fullscreenChanged, appInfo,
&ApplicationInfo::notifyFullscreenChanged);
- return appInfo;
-}
-void ApplicationInfo::init()
-{
- qmlRegisterSingletonType<ApplicationInfo>("GCompris", 1, 0,
- "ApplicationInfo", systeminfoProvider);
+ return appInfo;
}
diff --git a/src/core/ApplicationInfo.h b/src/core/ApplicationInfo.h
index 74249ed8c..8c9adbac0 100644
--- a/src/core/ApplicationInfo.h
+++ b/src/core/ApplicationInfo.h
@@ -1,452 +1,441 @@
-/* GCompris - ApplicationSettingsDefault.cpp
+/* GCompris - ApplicationInfo.h
*
* Copyright (C) 2014-2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This file was originally created from Digia example code under BSD license
* and heavily modified since then.
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
#ifndef APPLICATIONINFO_H
#define APPLICATIONINFO_H
#include <config.h>
#include "ApplicationSettings.h"
#include <QObject>
-#include <QQmlPropertyMap>
#include <QQmlEngine>
#include <QtGlobal>
class QQuickWindow;
/**
* @class ApplicationInfo
* @short A general purpose singleton that exposes miscellaneous native
* functions to the QML layer.
* @ingroup infrastructure
*/
class ApplicationInfo : public QObject
{
Q_OBJECT
/**
* Width of the application viewport.
*/
- Q_PROPERTY(int applicationWidth READ applicationWidth WRITE setApplicationWidth NOTIFY applicationWidthChanged)
+ Q_PROPERTY(int applicationWidth READ applicationWidth WRITE setApplicationWidth NOTIFY applicationWidthChanged)
/**
* Platform the application is currently running on.
*/
- Q_PROPERTY(Platform platform READ platform CONSTANT)
+ Q_PROPERTY(Platform platform READ platform CONSTANT)
/**
* Whether the application is currently running on a mobile platform.
*
* Mobile platforms are Android, Ios (not supported yet),
* Blackberry (not supported)
*/
- Q_PROPERTY(bool isMobile READ isMobile CONSTANT)
+ Q_PROPERTY(bool isMobile READ isMobile CONSTANT)
/**
* Whether the current platform supports fragment shaders.
*
* This flag is used in some core modules to selectively deactivate
* particle effects which cause crashes on some Android devices.
*
* cf. https://bugreports.qt.io/browse/QTBUG-44194
*
* For now always set to false, to prevent crashes.
*/
- Q_PROPERTY(bool hasShader READ hasShader CONSTANT)
+ Q_PROPERTY(bool hasShader READ hasShader CONSTANT)
/**
* Whether currently in portrait mode, on mobile platforms.
*
* Based on viewport geometry.
*/
- Q_PROPERTY(bool isPortraitMode READ isPortraitMode WRITE setIsPortraitMode NOTIFY portraitModeChanged)
+ Q_PROPERTY(bool isPortraitMode READ isPortraitMode WRITE setIsPortraitMode NOTIFY portraitModeChanged)
/**
* Ratio factor used for scaling of sizes on high-dpi devices.
*
* Must be used by activities as a scaling factor to all pixel values.
*/
- Q_PROPERTY(qreal ratio READ ratio NOTIFY ratioChanged)
+ Q_PROPERTY(qreal ratio READ ratio NOTIFY ratioChanged)
/**
* Ratio factor used for font scaling.
*
* On some low-dpi Android devices with high res (e.g. Galaxy Tab 4) the
* fonts in Text-like elements appear too small with respect to the other
* graphics -- also if we are using font.pointSize.
*
* For these cases we calculate a fontRatio in ApplicationInfo that takes
* dpi information into account, as proposed on
* http://doc.qt.io/qt-5/scalability.html#calculating-scaling-ratio
*
* GCText applies this factor automatically on its new fontSize property.
*/
- Q_PROPERTY(qreal fontRatio READ fontRatio NOTIFY fontRatioChanged)
+ Q_PROPERTY(qreal fontRatio READ fontRatio NOTIFY fontRatioChanged)
- /**
- * Short (2-letter) locale string of the currently active language.
- */
- Q_PROPERTY(QString localeShort READ localeShort)
+ /**
+ * Short (2-letter) locale string of the currently active language.
+ */
+ Q_PROPERTY(QString localeShort READ localeShort CONSTANT)
/**
* GCompris version string (compile time).
*/
- Q_PROPERTY(QString GCVersion READ GCVersion CONSTANT)
+ Q_PROPERTY(QString GCVersion READ GCVersion CONSTANT)
/**
* GCompris version code (compile time).
*/
- Q_PROPERTY(int GCVersionCode READ GCVersionCode CONSTANT)
+ Q_PROPERTY(int GCVersionCode READ GCVersionCode CONSTANT)
/**
* Qt version string (runtime).
*/
- Q_PROPERTY(QString QTVersion READ QTVersion CONSTANT)
+ Q_PROPERTY(QString QTVersion READ QTVersion CONSTANT)
/**
* Audio codec used for voices resources.
*
* This is determined at compile time (ogg for free platforms, aac on
* MacOSX and IOS).
*/
Q_PROPERTY(QString CompressedAudio READ CompressedAudio CONSTANT)
/**
* Download allowed
*
* This is determined at compile time. If set to NO GCompris will
* never download anything.
*/
Q_PROPERTY(bool isDownloadAllowed READ isDownloadAllowed CONSTANT)
/**
* Whether the application is currently using OpenGL or not.
*
* Use to deactivate some effects if OpenGL not used.
*/
- Q_PROPERTY(bool useOpenGL READ useOpenGL CONSTANT)
+ Q_PROPERTY(bool useOpenGL READ useOpenGL WRITE setUseOpenGL NOTIFY useOpenGLChanged)
+
+ /**
+ * Whether Box2D is installed or not.
+ *
+ * Use to disable activities that use Box2D when it's not installed.
+ */
+ Q_PROPERTY(bool isBox2DInstalled READ isBox2DInstalled NOTIFY isBox2DInstalledChanged)
public:
/**
* Known host platforms.
*/
enum Platform {
Linux, /**< Linux (except Android) */
Windows, /**< Windows */
MacOSX, /**< MacOSX */
Android, /**< Android */
Ios, /**< IOS (not supported) */
Blackberry, /**< Blackberry (not supported) */
SailfishOS /**< SailfishOS */
};
Q_ENUM(Platform)
- /**
- * Registers singleton in the QML engine.
- *
- * It is not recommended to create a singleton of Qml Singleton registered
- * object but we could not found a better way to let us access ApplicationInfo
- * on the C++ side. All our test shows that it works.
- */
- static void init();
-
/**
* Returns an absolute and platform independent path to the passed @p file
*
* @param file A relative filename.
* @returns Absolute path to the file.
*/
static QString getFilePath(const QString &file);
/**
* Returns the short locale name for the passed @p locale.
*
* Handles also 'system' (GC_DEFAULT_LOCALE) correctly which resolves to
* QLocale::system().name().
*
* @param locale A locale string of the form \<language\>_\<country\>
* @returns A short locale string of the form \<language\>
*/
static QString localeShort(const QString &locale) {
QString _locale = locale;
if(_locale == GC_DEFAULT_LOCALE) {
_locale = QLocale::system().name();
}
// Can't use left(2) because of Asturian where there are 3 chars
return _locale.left(_locale.indexOf('_'));
}
/**
* Returns a locale string that can be used in voices filenames.
*
* @param locale A locale string of the form \<language\>_\<country\>
* @returns A locale string as used in voices filenames.
*/
Q_INVOKABLE QString getVoicesLocale(const QString &locale);
/**
* Request GCompris to take the Audio Focus at the system level.
*
* On systems that support it, it will mute a running audio player.
*/
Q_INVOKABLE bool requestAudioFocus() const;
/**
* Abandon the Audio Focus.
*
* On systems that support it, it will let an audio player start again.
*/
Q_INVOKABLE void abandonAudioFocus() const;
- /**
- * Return the platform specific path for storing data shared between apps
- *
- * On Android: /storage/emulated/0/GCompris (>= Android 4.2),
- * /storage/sdcard0/GCompris (< Android 4.2)
- * On Linux: $HOME/local/share/GCompris
- */
- Q_INVOKABLE QString getSharedWritablePath() const;
-
/**
* Compare two strings respecting locale specific sort order.
*
* @param a First string to compare
* @param b Second string to compare
* @param locale Locale to respect for comparison in any of the forms
* used in GCompris xx[_XX][.codeset]. Defaults to currently
* set language from global configuration.
* @returns -1, 0 or 1 if a is less than, equal to or greater than b
*/
Q_INVOKABLE int localeCompare(const QString& a, const QString& b, const QString& locale = "") const;
/**
* Sort a list of strings respecting locale specific sort order.
*
* This function is supposed to be called from QML/JS. As there are still
* problems marshalling QStringList from C++ to QML/JS we use QVariantList
* both for argument and return value.
*
* @param list List of strings to be sorted.
* @param locale Locale to respect for sorting in any of the forms
* used in GCompris xx[_XX][.codeset].
* @returns List sorted by the sort order of the passed locale.
*/
Q_INVOKABLE QVariantList localeSort(QVariantList list, const QString& locale = "") const;
/// @cond INTERNAL_DOCS
static ApplicationInfo *getInstance() {
if(!m_instance) {
m_instance = new ApplicationInfo();
}
return m_instance;
}
- static QObject *systeminfoProvider(QQmlEngine *engine,
- QJSEngine *scriptEngine);
+ static QObject *applicationInfoProvider(QQmlEngine *engine,
+ QJSEngine *scriptEngine);
static void setWindow(QQuickWindow *window);
explicit ApplicationInfo(QObject *parent = 0);
~ApplicationInfo();
- int applicationWidth() const { return m_applicationWidth; }
- void setApplicationWidth(const int newWidth);
+ int applicationWidth() const { return m_applicationWidth; }
+ void setApplicationWidth(const int newWidth);
Platform platform() const { return m_platform; }
- bool isPortraitMode() const { return m_isPortraitMode; }
- void setIsPortraitMode(const bool newMode);
+ bool isPortraitMode() const { return m_isPortraitMode; }
+ void setIsPortraitMode(const bool newMode);
bool isMobile() const { return m_isMobile; }
bool hasShader() const {
#if defined(Q_OS_ANDROID)
return false;
#else
return true;
#endif
}
- qreal ratio() const { return m_ratio; }
+ qreal ratio() const { return m_ratio; }
qreal fontRatio() const { return m_fontRatio; }
QString localeShort() const {
return localeShort( ApplicationSettings::getInstance()->locale() );
}
static QString GCVersion() { return VERSION; }
static int GCVersionCode() { return VERSION_CODE; }
static QString QTVersion() { return qVersion(); }
static QString CompressedAudio() { return COMPRESSED_AUDIO; }
static bool isDownloadAllowed() { return QString(DOWNLOAD_ALLOWED) == "ON"; }
- static bool useOpenGL() {
-#if QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)
- return QString(GRAPHICAL_RENDERER) != "software";
-#else
- return true;
-#endif
- }
+ bool useOpenGL() const { return m_useOpenGL; }
+ void setUseOpenGL(bool useOpenGL) { m_useOpenGL = useOpenGL; }
+
+ bool isBox2DInstalled() const { return m_isBox2DInstalled; }
+ void setBox2DInstalled(const QQmlEngine &engine);
/**
* Returns the native screen orientation.
*
* Wraps QScreen::nativeOrientation: The native orientation of the screen
* is the orientation where the logo sticker of the device appears the
* right way up, or Qt::PrimaryOrientation if the platform does not support
* this functionality.
*
* The native orientation is a property of the hardware, and does not change
*/
Q_INVOKABLE Qt::ScreenOrientation getNativeOrientation();
/**
* Change the desired orientation of the application.
*
* Android specific function, cf. http://developer.android.com/reference/android/app/Activity.html#setRequestedOrientation(int)
*
* @param orientation Desired orientation of the application. For possible
* values cf. http://developer.android.com/reference/android/content/pm/ActivityInfo.html#screenOrientation .
* Some useful values:
* - -1: SCREEN_ORIENTATION_UNSPECIFIED
* - 0: SCREEN_ORIENTATION_LANDSCAPE: forces landscape
* - 1: SCREEN_ORIENTATION_PORTRAIT: forces portrait
* - 5: SCREEN_ORIENTATION_NOSENSOR: forces native
* orientation mode on each device (portrait on
* smartphones, landscape on tablet)
* - 14: SCREEN_ORIENTATION_LOCKED: lock current orientation
*/
Q_INVOKABLE void setRequestedOrientation(int orientation);
/**
* Query the desired orientation of the application.
*
* @sa setRequestedOrientation
*/
Q_INVOKABLE int getRequestedOrientation();
/**
* Checks whether a sensor type from the QtSensor module is supported on
* the current platform.
*
* @param sensorType Classname of a sensor from the QtSensor module
* to be checked (e.g. "QTiltSensor").
*/
Q_INVOKABLE bool sensorIsSupported(const QString& sensorType);
/**
* Toggles activation of screensaver on android
*
* @param value Whether screensaver should be disabled (true) or
* enabled (false).
*/
Q_INVOKABLE void setKeepScreenOn(bool value);
/// @endcond
-protected slots:
- /**
- * Returns the resource root-path used for GCompris resources.
- */
- QString getResourceDataPath();
+public slots:
+ /**
+ * Returns the resource root-path used for GCompris resources.
+ */
+ QString getResourceDataPath();
/**
* Returns an absolute path to a language specific sound/voices file. If
* the file is already absolute only the token replacement is applied.
*
* @param file A templated relative path to a language specific file. Any
* occurrence of the '$LOCALE' placeholder will be replaced by
* the currently active locale string.
* Any occurrence of '$CA' placeholder will be replaced by
* the current compressed audio format ('ogg' or 'aac).
* Example: 'voices-$CA/$LOCALE/misc/click_on_letter.$CA'
* @returns An absolute path to the corresponding resource file.
*/
Q_INVOKABLE QString getAudioFilePath(const QString &file);
/**
* Returns an absolute path to a language specific sound/voices file. If
* the file is already absolute only the token replacement is applied.
*
* @param file A templated relative path to a language specific file. Any
* occurrence of the '$LOCALE' placeholder will be replaced by
* the currently active locale string.
* Any occurrence of '$CA' placeholder will be replaced by
* the current compressed audio format ('ogg' or 'aac).
* Example: 'voices-$CA/$LOCALE/misc/click_on_letter.$CA'
- * @param locale the locale for which to get this audio file
+ * @param localeName the locale for which to get this audio file
* @returns An absolute path to the corresponding resource file.
*/
Q_INVOKABLE QString getAudioFilePathForLocale(const QString &file,
const QString &localeName);
/**
* Returns an absolute path to a language specific resource file.
*
* Generalization of getAudioFilePath().
* @sa getAudioFilePath
*/
Q_INVOKABLE QString getLocaleFilePath(const QString &file);
/**
* @returns A list of systems-fonts that should be excluded from font
* selection.
*/
Q_INVOKABLE QStringList getSystemExcludedFonts();
/**
* @returns A list of fonts contained in the fonts resources.
*/
Q_INVOKABLE QStringList getFontsFromRcc();
/**
* Stores a screenshot in the passed @p file.
*
* @param file Absolute destination filename.
*/
Q_INVOKABLE void screenshot(const QString &file);
void notifyPortraitMode();
Q_INVOKABLE void notifyFullscreenChanged();
protected:
- qreal getSizeWithRatio(const qreal height) { return ratio() * height; }
+ qreal getSizeWithRatio(const qreal height) { return ratio() * height; }
signals:
- void applicationWidthChanged();
- void portraitModeChanged();
- void ratioChanged();
+ void applicationWidthChanged();
+ void portraitModeChanged();
+ void ratioChanged();
void fontRatioChanged();
void applicationSettingsChanged();
void fullscreenChanged();
+ void useOpenGLChanged();
+ void isBox2DInstalledChanged();
private:
static ApplicationInfo *m_instance;
int m_applicationWidth;
Platform m_platform;
- QQmlPropertyMap *m_constants;
- bool m_isPortraitMode;
- bool m_isMobile;
- qreal m_ratio;
+ bool m_isPortraitMode;
+ bool m_isMobile;
+ bool m_useOpenGL;
+ bool m_isBox2DInstalled;
+ qreal m_ratio;
qreal m_fontRatio;
// Symbols fonts that user can't see
QStringList m_excludedFonts;
QStringList m_fontsFromRcc;
static QQuickWindow *m_window;
};
#endif // APPLICATIONINFO_H
diff --git a/src/core/ApplicationInfoDefault.cpp b/src/core/ApplicationInfoDefault.cpp
index 98992b7c7..dfab8c9e5 100644
--- a/src/core/ApplicationInfoDefault.cpp
+++ b/src/core/ApplicationInfoDefault.cpp
@@ -1,59 +1,59 @@
/* GCompris - ApplicationInfoDefault.cpp
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
#include "ApplicationInfo.h"
#include <QCollator>
#include <QLocale>
bool ApplicationInfo::requestAudioFocus() const
{
return true;
}
void ApplicationInfo::abandonAudioFocus() const
{
}
void ApplicationInfo::setRequestedOrientation(int orientation)
{
Q_UNUSED(orientation);
}
int ApplicationInfo::getRequestedOrientation()
{
return -1;
}
void ApplicationInfo::setKeepScreenOn(bool value)
{
Q_UNUSED(value);
}
int ApplicationInfo::localeCompare(const QString& a, const QString& b,
const QString& locale) const
{
QString _locale = locale.isEmpty() ? \
ApplicationSettings::getInstance()->locale() \
: locale;
QLocale l = (_locale == GC_DEFAULT_LOCALE) ? QLocale::system() \
: QLocale(_locale);
return QCollator(l).compare(a, b);
}
diff --git a/src/core/ApplicationSettings.cpp b/src/core/ApplicationSettings.cpp
index 6d39f8e3e..0e57d9f8a 100644
--- a/src/core/ApplicationSettings.cpp
+++ b/src/core/ApplicationSettings.cpp
@@ -1,504 +1,522 @@
/* GCompris - ApplicationSettings.cpp
*
* Copyright (C) 2014-2016 Johnny Jazeix <jazeix@gmail.com>
*
* Authors:
* Johnny Jazeix <jazeix@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
#include "ApplicationSettings.h"
#include "ApplicationInfo.h"
#include "DownloadManager.h"
#include <qmath.h>
#include <QUrl>
#include <QUrlQuery>
#include <QGuiApplication>
#include <QScreen>
#include <QLocale>
#include <QApplication>
#include <QRect>
#include <QDesktopWidget>
#include <QtQml>
-#define GC_DEFAULT_FONT "Andika-R.otf"
+#define GC_DEFAULT_FONT QLatin1String("Andika-R.otf")
#define GC_DEFAULT_FONT_CAPITALIZATION 0 // Font.MixedCase
#define GC_DEFAULT_FONT_LETTER_SPACING 0
-static const QString GENERAL_GROUP_KEY = "General";
-static const QString ADMIN_GROUP_KEY = "Admin";
-static const QString INTERNAL_GROUP_KEY = "Internal";
-static const QString FAVORITE_GROUP_KEY = "Favorite";
-static const QString LEVELS_GROUP_KEY = "Levels";
-
-static const QString FULLSCREEN_KEY = "fullscreen";
-static const QString PREVIOUS_HEIGHT_KEY = "previousHeight";
-static const QString PREVIOUS_WIDTH_KEY = "previousWidth";
-static const QString SHOW_LOCKED_ACTIVITIES_KEY = "showLockedActivities";
-static const QString ENABLE_AUDIO_VOICES_KEY = "enableAudioVoices";
-static const QString ENABLE_AUDIO_EFFECTS_KEY = "enableAudioEffects";
-static const QString VIRTUALKEYBOARD_KEY = "virtualKeyboard";
-static const QString LOCALE_KEY = "locale";
-static const QString FONT_KEY = "font";
-static const QString IS_CURRENT_FONT_EMBEDDED = "isCurrentFontEmbedded";
-static const QString ENABLE_AUTOMATIC_DOWNLOADS = "enableAutomaticDownloads";
-
-static const QString DOWNLOAD_SERVER_URL_KEY = "downloadServerUrl";
-static const QString CACHE_PATH_KEY = "cachePath";
-
-static const QString EXE_COUNT_KEY = "exeCount";
-static const QString LAST_GC_VERSION_RAN = "lastGCVersionRan";
-
-static const QString FILTER_LEVEL_MIN = "filterLevelMin";
-static const QString FILTER_LEVEL_MAX = "filterLevelMax";
-
-static const QString BASE_FONT_SIZE_KEY = "baseFontSize";
-static const QString FONT_CAPITALIZATION = "fontCapitalization";
-static const QString FONT_LETTER_SPACING = "fontLetterSpacing";
-
-static const QString DEFAULT_CURSOR = "defaultCursor";
-static const QString NO_CURSOR = "noCursor";
-static const QString DEMO_KEY = "demo";
-static const QString CODE_KEY = "key";
-static const QString KIOSK_KEY = "kiosk";
-static const QString SECTION_VISIBLE = "sectionVisible";
-static const QString WORDSET = "wordset";
-
-static const QString PROGRESS_KEY = "progress";
-
-ApplicationSettings *ApplicationSettings::m_instance = NULL;
+static const char *GENERAL_GROUP_KEY = "General";
+static const char *ADMIN_GROUP_KEY = "Admin";
+static const char *INTERNAL_GROUP_KEY = "Internal";
+static const char *FAVORITE_GROUP_KEY = "Favorite";
+static const char *LEVELS_GROUP_KEY = "Levels";
+
+static const char *FULLSCREEN_KEY = "fullscreen";
+static const char *PREVIOUS_HEIGHT_KEY = "previousHeight";
+static const char *PREVIOUS_WIDTH_KEY = "previousWidth";
+static const char *SHOW_LOCKED_ACTIVITIES_KEY = "showLockedActivities";
+static const char *ENABLE_AUDIO_VOICES_KEY = "enableAudioVoices";
+static const char *ENABLE_AUDIO_EFFECTS_KEY = "enableAudioEffects";
+static const char *VIRTUALKEYBOARD_KEY = "virtualKeyboard";
+static const char *LOCALE_KEY = "locale";
+static const char *FONT_KEY = "font";
+static const char *IS_CURRENT_FONT_EMBEDDED = "isCurrentFontEmbedded";
+static const char *ENABLE_AUTOMATIC_DOWNLOADS = "enableAutomaticDownloads";
+
+static const char *DOWNLOAD_SERVER_URL_KEY = "downloadServerUrl";
+static const char *CACHE_PATH_KEY = "cachePath";
+static const char *USERDATA_PATH_KEY = "userDataPath";
+static const char *RENDERER_KEY = "renderer";
+
+static const char *EXE_COUNT_KEY = "exeCount";
+static const char *LAST_GC_VERSION_RAN = "lastGCVersionRan";
+
+static const char *FILTER_LEVEL_MIN = "filterLevelMin";
+static const char *FILTER_LEVEL_MAX = "filterLevelMax";
+
+static const char *BASE_FONT_SIZE_KEY = "baseFontSize";
+static const char *FONT_CAPITALIZATION = "fontCapitalization";
+static const char *FONT_LETTER_SPACING = "fontLetterSpacing";
+
+static const char *DEFAULT_CURSOR = "defaultCursor";
+static const char *NO_CURSOR = "noCursor";
+static const char *DEMO_KEY = "demo";
+static const char *CODE_KEY = "key";
+static const char *KIOSK_KEY = "kiosk";
+static const char *SECTION_VISIBLE = "sectionVisible";
+static const char *WORDSET = "wordset";
+
+static const char *PROGRESS_KEY = "progress";
+
+static const char *DEFAULT_DOWNLOAD_SERVER = "https://cdn.kde.org/gcompris";
+
+ApplicationSettings *ApplicationSettings::m_instance = nullptr;
ApplicationSettings::ApplicationSettings(const QString &configPath, QObject *parent): QObject(parent),
m_baseFontSizeMin(-7), m_baseFontSizeMax(7),
m_fontLetterSpacingMin(0.0), m_fontLetterSpacingMax(8.0),
m_config(configPath, QSettings::IniFormat)
{
const QRect &screenSize = QApplication::desktop()->screenGeometry();
// initialize from settings file or default
// general group
m_config.beginGroup(GENERAL_GROUP_KEY);
m_isAudioEffectsEnabled = m_config.value(ENABLE_AUDIO_EFFECTS_KEY, true).toBool();
m_isFullscreen = m_config.value(FULLSCREEN_KEY, true).toBool();
m_previousHeight = m_config.value(PREVIOUS_HEIGHT_KEY, screenSize.height()).toUInt();
m_previousWidth = m_config.value(PREVIOUS_WIDTH_KEY, screenSize.width()).toUInt();
m_isAudioVoicesEnabled = m_config.value(ENABLE_AUDIO_VOICES_KEY, true).toBool();
m_isVirtualKeyboard = m_config.value(VIRTUALKEYBOARD_KEY,
ApplicationInfo::getInstance()->isMobile()).toBool();
m_locale = m_config.value(LOCALE_KEY, GC_DEFAULT_LOCALE).toString();
m_font = m_config.value(FONT_KEY, GC_DEFAULT_FONT).toString();
- if(m_font == "Andika-R.ttf")
+ if(m_font == QLatin1String("Andika-R.ttf"))
m_font = "Andika-R.otf";
m_fontCapitalization = m_config.value(FONT_CAPITALIZATION, GC_DEFAULT_FONT_CAPITALIZATION).toUInt();
- setFontLetterSpacing(m_config.value(FONT_LETTER_SPACING, GC_DEFAULT_FONT_LETTER_SPACING).toReal());
+ m_fontLetterSpacing = m_config.value(FONT_LETTER_SPACING, GC_DEFAULT_FONT_LETTER_SPACING).toReal();
m_isEmbeddedFont = m_config.value(IS_CURRENT_FONT_EMBEDDED, true).toBool();
// Init the activation mode
if(QLatin1String(ACTIVATION_MODE) == "no")
m_activationMode = 0;
else if(QLatin1String(ACTIVATION_MODE) == "inapp")
m_activationMode = 1;
else if(QLatin1String(ACTIVATION_MODE) == "internal")
m_activationMode = 2;
else
qFatal("Unknown activation mode");
// Set the demo mode
if(QLatin1String(ACTIVATION_MODE) != "no")
m_isDemoMode = m_config.value(DEMO_KEY, true).toBool();
else
m_isDemoMode = false;
m_codeKey = m_config.value(CODE_KEY, "").toString();
#if defined(WITH_KIOSK_MODE)
m_isKioskMode = m_config.value(KIOSK_KEY, true).toBool();
#else
m_isKioskMode = m_config.value(KIOSK_KEY, false).toBool();
#endif
// Option only useful if we are in demo mode (else all the activities are available and unlocked)
// By default, all the activities are displayed (even locked ones)
m_showLockedActivities = m_config.value(SHOW_LOCKED_ACTIVITIES_KEY, m_isDemoMode).toBool();
m_sectionVisible = m_config.value(SECTION_VISIBLE, true).toBool();
m_wordset = m_config.value(WORDSET, "").toString();
m_isAutomaticDownloadsEnabled = m_config.value(ENABLE_AUTOMATIC_DOWNLOADS,
!ApplicationInfo::getInstance()->isMobile() && ApplicationInfo::isDownloadAllowed()).toBool();
m_filterLevelMin = m_config.value(FILTER_LEVEL_MIN, 1).toUInt();
m_filterLevelMax = m_config.value(FILTER_LEVEL_MAX, 6).toUInt();
m_defaultCursor = m_config.value(DEFAULT_CURSOR, false).toBool();
m_noCursor = m_config.value(NO_CURSOR, false).toBool();
- setBaseFontSize(m_config.value(BASE_FONT_SIZE_KEY, 0).toInt());
+ m_baseFontSize = m_config.value(BASE_FONT_SIZE_KEY, 0).toInt();
m_config.sync(); // make sure all defaults are written back
m_config.endGroup();
// admin group
m_config.beginGroup(ADMIN_GROUP_KEY);
- m_downloadServerUrl = m_config.value(DOWNLOAD_SERVER_URL_KEY, "http://gcompris.net").toString();
+ m_downloadServerUrl = m_config.value(DOWNLOAD_SERVER_URL_KEY, QLatin1String(DEFAULT_DOWNLOAD_SERVER)).toString();
+ if(m_downloadServerUrl == "http://gcompris.net") {
+ setDownloadServerUrl(DEFAULT_DOWNLOAD_SERVER);
+ }
m_cachePath = m_config.value(CACHE_PATH_KEY, QStandardPaths::writableLocation(QStandardPaths::CacheLocation)).toString();
+ m_userDataPath = m_config.value(USERDATA_PATH_KEY, QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1String("/GCompris")).toString();
+ m_renderer = m_config.value(RENDERER_KEY, GRAPHICAL_RENDERER).toString();
m_config.endGroup();
// internal group
m_config.beginGroup(INTERNAL_GROUP_KEY);
m_exeCount = m_config.value(EXE_COUNT_KEY, 0).toUInt();
m_lastGCVersionRan = m_config.value(LAST_GC_VERSION_RAN, 0).toUInt();
m_config.endGroup();
// no group
m_isBarHidden = false;
connect(this, &ApplicationSettings::showLockedActivitiesChanged, this, &ApplicationSettings::notifyShowLockedActivitiesChanged);
connect(this, &ApplicationSettings::audioVoicesEnabledChanged, this, &ApplicationSettings::notifyAudioVoicesEnabledChanged);
connect(this, &ApplicationSettings::audioEffectsEnabledChanged, this, &ApplicationSettings::notifyAudioEffectsEnabledChanged);
connect(this, &ApplicationSettings::fullscreenChanged, this, &ApplicationSettings::notifyFullscreenChanged);
connect(this, &ApplicationSettings::previousHeightChanged, this, &ApplicationSettings::notifyPreviousHeightChanged);
connect(this, &ApplicationSettings::previousWidthChanged, this, &ApplicationSettings::notifyPreviousWidthChanged);
connect(this, &ApplicationSettings::localeChanged, this, &ApplicationSettings::notifyLocaleChanged);
connect(this, &ApplicationSettings::fontChanged, this, &ApplicationSettings::notifyFontChanged);
connect(this, &ApplicationSettings::virtualKeyboardChanged, this, &ApplicationSettings::notifyVirtualKeyboardChanged);
connect(this, &ApplicationSettings::automaticDownloadsEnabledChanged, this, &ApplicationSettings::notifyAutomaticDownloadsEnabledChanged);
connect(this, &ApplicationSettings::filterLevelMinChanged, this, &ApplicationSettings::notifyFilterLevelMinChanged);
connect(this, &ApplicationSettings::filterLevelMaxChanged, this, &ApplicationSettings::notifyFilterLevelMaxChanged);
connect(this, &ApplicationSettings::sectionVisibleChanged, this, &ApplicationSettings::notifySectionVisibleChanged);
connect(this, &ApplicationSettings::wordsetChanged, this, &ApplicationSettings::notifyWordsetChanged);
connect(this, &ApplicationSettings::demoModeChanged, this, &ApplicationSettings::notifyDemoModeChanged);
connect(this, &ApplicationSettings::codeKeyChanged, this, &ApplicationSettings::notifyCodeKeyChanged);
connect(this, &ApplicationSettings::kioskModeChanged, this, &ApplicationSettings::notifyKioskModeChanged);
connect(this, &ApplicationSettings::downloadServerUrlChanged, this, &ApplicationSettings::notifyDownloadServerUrlChanged);
connect(this, &ApplicationSettings::cachePathChanged, this, &ApplicationSettings::notifyCachePathChanged);
+ connect(this, &ApplicationSettings::userDataPathChanged, this, &ApplicationSettings::notifyUserDataPathChanged);
+ connect(this, &ApplicationSettings::rendererChanged, this, &ApplicationSettings::notifyRendererChanged);
connect(this, &ApplicationSettings::exeCountChanged, this, &ApplicationSettings::notifyExeCountChanged);
connect(this, &ApplicationSettings::barHiddenChanged, this, &ApplicationSettings::notifyBarHiddenChanged);
connect(this, &ApplicationSettings::lastGCVersionRanChanged, this, &ApplicationSettings::notifyLastGCVersionRanChanged);
}
ApplicationSettings::~ApplicationSettings()
{
// make sure settings file is up2date:
// general group
m_config.beginGroup(GENERAL_GROUP_KEY);
m_config.setValue(SHOW_LOCKED_ACTIVITIES_KEY, m_showLockedActivities);
m_config.setValue(ENABLE_AUDIO_VOICES_KEY, m_isAudioVoicesEnabled);
m_config.setValue(LOCALE_KEY, m_locale);
m_config.setValue(FONT_KEY, m_font);
m_config.setValue(IS_CURRENT_FONT_EMBEDDED, m_isEmbeddedFont);
m_config.setValue(FULLSCREEN_KEY, m_isFullscreen);
m_config.setValue(PREVIOUS_HEIGHT_KEY, m_previousHeight);
m_config.setValue(PREVIOUS_WIDTH_KEY, m_previousWidth);
m_config.setValue(VIRTUALKEYBOARD_KEY, m_isVirtualKeyboard);
m_config.setValue(ENABLE_AUTOMATIC_DOWNLOADS, m_isAutomaticDownloadsEnabled);
m_config.setValue(FILTER_LEVEL_MIN, m_filterLevelMin);
m_config.setValue(FILTER_LEVEL_MAX, m_filterLevelMax);
m_config.setValue(DEMO_KEY, m_isDemoMode);
m_config.setValue(CODE_KEY, m_codeKey);
m_config.setValue(KIOSK_KEY, m_isKioskMode);
m_config.setValue(SECTION_VISIBLE, m_sectionVisible);
m_config.setValue(WORDSET, m_wordset);
m_config.setValue(DEFAULT_CURSOR, m_defaultCursor);
m_config.setValue(NO_CURSOR, m_noCursor);
m_config.setValue(BASE_FONT_SIZE_KEY, m_baseFontSize);
m_config.setValue(FONT_CAPITALIZATION, m_fontCapitalization);
m_config.setValue(FONT_LETTER_SPACING, m_fontLetterSpacing);
m_config.endGroup();
// admin group
m_config.beginGroup(ADMIN_GROUP_KEY);
m_config.setValue(DOWNLOAD_SERVER_URL_KEY, m_downloadServerUrl);
m_config.setValue(CACHE_PATH_KEY, m_cachePath);
+ m_config.setValue(USERDATA_PATH_KEY, m_userDataPath);
+ m_config.setValue(RENDERER_KEY, m_renderer);
m_config.endGroup();
// internal group
m_config.beginGroup(INTERNAL_GROUP_KEY);
m_config.setValue(EXE_COUNT_KEY, m_exeCount);
m_config.setValue(LAST_GC_VERSION_RAN, m_lastGCVersionRan);
m_config.endGroup();
m_config.sync();
- m_instance = NULL;
+ m_instance = nullptr;
}
void ApplicationSettings::notifyShowLockedActivitiesChanged()
{
updateValueInConfig(GENERAL_GROUP_KEY, SHOW_LOCKED_ACTIVITIES_KEY, m_showLockedActivities);
qDebug() << "notifyShowLockedActivitiesChanged: " << m_showLockedActivities;
}
void ApplicationSettings::notifyAudioVoicesEnabledChanged()
{
updateValueInConfig(GENERAL_GROUP_KEY, ENABLE_AUDIO_VOICES_KEY, m_isAudioVoicesEnabled);
qDebug() << "notifyAudioVoices: " << m_isAudioVoicesEnabled;
}
void ApplicationSettings::notifyAudioEffectsEnabledChanged()
{
updateValueInConfig(GENERAL_GROUP_KEY, ENABLE_AUDIO_EFFECTS_KEY, m_isAudioEffectsEnabled);
qDebug() << "notifyAudioEffects: " << m_isAudioEffectsEnabled;
}
void ApplicationSettings::notifyLocaleChanged()
{
updateValueInConfig(GENERAL_GROUP_KEY, LOCALE_KEY, m_locale);
qDebug() << "new locale: " << m_locale;
}
void ApplicationSettings::notifyFontChanged()
{
updateValueInConfig(GENERAL_GROUP_KEY, FONT_KEY, m_font);
qDebug() << "new font: " << m_font;
}
void ApplicationSettings::notifyEmbeddedFontChanged()
{
updateValueInConfig(GENERAL_GROUP_KEY, IS_CURRENT_FONT_EMBEDDED, m_isEmbeddedFont);
qDebug() << "new font is embedded: " << m_isEmbeddedFont;
}
void ApplicationSettings::notifyFontCapitalizationChanged()
{
updateValueInConfig(GENERAL_GROUP_KEY, FONT_CAPITALIZATION, m_fontCapitalization);
qDebug() << "new fontCapitalization: " << m_fontCapitalization;
}
void ApplicationSettings::notifyFontLetterSpacingChanged()
{
updateValueInConfig(GENERAL_GROUP_KEY, FONT_LETTER_SPACING, m_fontLetterSpacing);
qDebug() << "new fontLetterSpacing: " << m_fontLetterSpacing;
}
void ApplicationSettings::notifyFullscreenChanged()
{
updateValueInConfig(GENERAL_GROUP_KEY, FULLSCREEN_KEY, m_isFullscreen);
qDebug() << "fullscreen set to: " << m_isFullscreen;
}
void ApplicationSettings::notifyPreviousHeightChanged()
{
updateValueInConfig(GENERAL_GROUP_KEY, PREVIOUS_HEIGHT_KEY, m_previousHeight);
qDebug() << "previous height set to: " << m_previousHeight;
}
void ApplicationSettings::notifyPreviousWidthChanged()
{
updateValueInConfig(GENERAL_GROUP_KEY, PREVIOUS_WIDTH_KEY, m_previousWidth);
qDebug() << "previous width set to: " << m_previousWidth;
}
void ApplicationSettings::notifyVirtualKeyboardChanged()
{
updateValueInConfig(GENERAL_GROUP_KEY, VIRTUALKEYBOARD_KEY, m_isVirtualKeyboard);
qDebug() << "virtualkeyboard set to: " << m_isVirtualKeyboard;
}
bool ApplicationSettings::isAutomaticDownloadsEnabled() const {
return m_isAutomaticDownloadsEnabled && ApplicationInfo::isDownloadAllowed();
}
void ApplicationSettings::setIsAutomaticDownloadsEnabled(const bool newIsAutomaticDownloadsEnabled) {
if(ApplicationInfo::isDownloadAllowed()) {
m_isAutomaticDownloadsEnabled = newIsAutomaticDownloadsEnabled;
emit automaticDownloadsEnabledChanged();
}
}
void ApplicationSettings::notifyAutomaticDownloadsEnabledChanged()
{
updateValueInConfig(GENERAL_GROUP_KEY, ENABLE_AUTOMATIC_DOWNLOADS, m_isAutomaticDownloadsEnabled);
qDebug() << "enableAutomaticDownloads set to: " << m_isAutomaticDownloadsEnabled;
}
void ApplicationSettings::notifyFilterLevelMinChanged()
{
updateValueInConfig(GENERAL_GROUP_KEY, FILTER_LEVEL_MIN, m_filterLevelMin);
qDebug() << "filterLevelMin set to: " << m_filterLevelMin;
}
void ApplicationSettings::notifyFilterLevelMaxChanged()
{
updateValueInConfig(GENERAL_GROUP_KEY, FILTER_LEVEL_MAX, m_filterLevelMax);
qDebug() << "filterLevelMax set to: " << m_filterLevelMax;
}
void ApplicationSettings::notifyDemoModeChanged()
{
updateValueInConfig(GENERAL_GROUP_KEY, DEMO_KEY, m_isDemoMode);
qDebug() << "notifyDemoMode: " << m_isDemoMode;
}
void ApplicationSettings::notifyCodeKeyChanged()
{
checkPayment();
if(!m_isDemoMode)
updateValueInConfig(GENERAL_GROUP_KEY, CODE_KEY, m_codeKey);
qDebug() << "notifyCodeKey: " << m_codeKey;
}
void ApplicationSettings::notifyKioskModeChanged()
{
updateValueInConfig(GENERAL_GROUP_KEY, KIOSK_KEY, m_isKioskMode);
qDebug() << "notifyKioskMode: " << m_isKioskMode;
}
void ApplicationSettings::notifySectionVisibleChanged()
{
updateValueInConfig(GENERAL_GROUP_KEY, SECTION_VISIBLE, m_sectionVisible);
qDebug() << "notifySectionVisible: " << m_sectionVisible;
}
void ApplicationSettings::notifyWordsetChanged()
{
if(!m_wordset.isEmpty() &&
DownloadManager::getInstance()->haveLocalResource(m_wordset) &&
!DownloadManager::getInstance()->isDataRegistered("words")) {
// words.rcc is there -> register old file first
// then try to update in the background
DownloadManager::getInstance()->updateResource(m_wordset);
}
updateValueInConfig(GENERAL_GROUP_KEY, WORDSET, m_wordset);
qDebug() << "notifyWordset: " << m_wordset;
}
void ApplicationSettings::notifyDownloadServerUrlChanged()
{
updateValueInConfig(ADMIN_GROUP_KEY, DOWNLOAD_SERVER_URL_KEY, m_downloadServerUrl);
qDebug() << "downloadServerUrl set to: " << m_downloadServerUrl;
}
void ApplicationSettings::notifyCachePathChanged()
{
updateValueInConfig(ADMIN_GROUP_KEY, CACHE_PATH_KEY, m_cachePath);
qDebug() << "cachePath set to: " << m_cachePath;
}
+void ApplicationSettings::notifyUserDataPathChanged()
+{
+ updateValueInConfig(ADMIN_GROUP_KEY, USERDATA_PATH_KEY, m_userDataPath);
+ qDebug() << "userDataPath set to: " << m_userDataPath;
+}
+
+void ApplicationSettings::notifyRendererChanged()
+{
+ updateValueInConfig(ADMIN_GROUP_KEY, RENDERER_KEY, m_renderer);
+ qDebug() << "renderer set to: " << m_renderer;
+}
+
void ApplicationSettings::notifyExeCountChanged()
{
updateValueInConfig(INTERNAL_GROUP_KEY, EXE_COUNT_KEY, m_exeCount);
qDebug() << "exeCount set to: " << m_exeCount;
}
void ApplicationSettings::notifyLastGCVersionRanChanged()
{
updateValueInConfig(INTERNAL_GROUP_KEY, LAST_GC_VERSION_RAN, m_lastGCVersionRan);
qDebug() << "lastVersionRan set to: " << m_lastGCVersionRan;
}
void ApplicationSettings::notifyBarHiddenChanged()
{
qDebug() << "is bar hidden: " << m_isBarHidden;
}
void ApplicationSettings::saveBaseFontSize()
{
updateValueInConfig(GENERAL_GROUP_KEY, BASE_FONT_SIZE_KEY, m_baseFontSize);
}
void ApplicationSettings::saveActivityConfiguration(const QString &activity, const QVariantMap &data)
{
qDebug() << "save configuration for:" << activity;
QMapIterator<QString, QVariant> i(data);
while (i.hasNext()) {
i.next();
updateValueInConfig(activity, i.key(), i.value());
}
}
QVariantMap ApplicationSettings::loadActivityConfiguration(const QString &activity)
{
qDebug() << "load configuration for:" << activity;
m_config.beginGroup(activity);
QStringList keys = m_config.childKeys();
QVariantMap data;
- foreach(const QString &key, keys) {
+ for(const QString &key : keys) {
data[key] = m_config.value(key);
}
m_config.endGroup();
return data;
}
void ApplicationSettings::setFavorite(const QString &activity, bool favorite)
{
updateValueInConfig(FAVORITE_GROUP_KEY, activity, favorite);
}
bool ApplicationSettings::isFavorite(const QString &activity)
{
m_config.beginGroup(FAVORITE_GROUP_KEY);
bool favorite = m_config.value(activity, false).toBool();
m_config.endGroup();
return favorite;
}
void ApplicationSettings::setCurrentLevel(const QString &activity, const QString &level)
{
updateValueInConfig(LEVELS_GROUP_KEY, activity, level);
}
QString ApplicationSettings::currentLevel(const QString &activity)
{
m_config.beginGroup(LEVELS_GROUP_KEY);
QString level = m_config.value(activity, "").toString();
m_config.endGroup();
return level;
}
template<class T> void ApplicationSettings::updateValueInConfig(const QString& group,
const QString& key, const T& value)
{
m_config.beginGroup(group);
m_config.setValue(key, value);
m_config.endGroup();
m_config.sync();
}
int ApplicationSettings::loadActivityProgress(const QString &activity)
{
int progress = 0;
m_config.beginGroup(activity);
progress = m_config.value(PROGRESS_KEY, 0).toInt();
m_config.endGroup();
qDebug() << "loaded progress for activity" << activity << ":" << progress;
return progress;
}
void ApplicationSettings::saveActivityProgress(const QString &activity, int progress)
{
updateValueInConfig(activity, PROGRESS_KEY, progress);
}
bool ApplicationSettings::useExternalWordset()
{
return !m_wordset.isEmpty() && DownloadManager::getInstance()->isDataRegistered("words");
}
-QObject *ApplicationSettings::systeminfoProvider(QQmlEngine *engine,
- QJSEngine *scriptEngine)
+QObject *ApplicationSettings::applicationSettingsProvider(QQmlEngine *engine,
+ QJSEngine *scriptEngine)
{
Q_UNUSED(engine)
Q_UNUSED(scriptEngine)
ApplicationSettings* appSettings = getInstance();
return appSettings;
}
-
-void ApplicationSettings::init()
-{
- qmlRegisterSingletonType<ApplicationSettings>("GCompris", 1, 0,
- "ApplicationSettings", systeminfoProvider);
-}
-
diff --git a/src/core/ApplicationSettings.h b/src/core/ApplicationSettings.h
index 5cc7cbc7a..f702e6e4e 100644
--- a/src/core/ApplicationSettings.h
+++ b/src/core/ApplicationSettings.h
@@ -1,629 +1,659 @@
-/* GCompris - ApplicationSettingsDefault.cpp
+/* GCompris - ApplicationSettings.h
*
* Copyright (C) 2014 Johnny Jazeix <jazeix@gmail.com>
*
* Authors:
* Johnny Jazeix <jazeix@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
#ifndef APPLICATIONSETTINGS_H
#define APPLICATIONSETTINGS_H
#include <QObject>
#include <QQmlEngine>
#include <QtGlobal>
#include <QDebug>
#include <QSettings>
#include <QStandardPaths>
#include <config.h>
#define GC_DEFAULT_LOCALE "system"
/**
* @class ApplicationSettings
* @short Singleton that contains GCompris' persistent settings.
* @ingroup infrastructure
*
* Settings are persisted using QSettings, which stores them in platform
* specific locations.
*
* The settings are subdivided in different groups of settings.
*
* <em>[General]</em> settings are mostly changeable by users in the DialogConfig
* dialog.
*
* <em>[Admin]</em> and <em>[Internal]</em> settings are not changeable by the
* user and used for internal purposes. Should only be changed if you really know
* what you are doing.
*
* The <em>[Favorite]</em> group is auto-generated from the favorite activities
* selected by a user.
*
* The <em>[Levels]</em> group is auto-generated from the levels chosen by
* a user (if the activity provides multiple datasets).
*
* Besides these global settings there is one group for each activity that
* stores persistent settings.
*
* Settings defaults are defined in the source code.
*
* @sa DialogActivityConfig
*/
class ApplicationSettings : public QObject
{
Q_OBJECT
/* General group */
/**
* Whether to show locked activities.
* False if in Demo mode, true otherwise.
*/
Q_PROPERTY(bool showLockedActivities READ showLockedActivities WRITE setShowLockedActivities NOTIFY showLockedActivitiesChanged)
/**
* Whether audio voices/speech should be enabled.
*/
Q_PROPERTY(bool isAudioVoicesEnabled READ isAudioVoicesEnabled WRITE setIsAudioVoicesEnabled NOTIFY audioVoicesEnabledChanged)
/**
* Whether audio effects should be enabled.
*/
Q_PROPERTY(bool isAudioEffectsEnabled READ isAudioEffectsEnabled WRITE setIsAudioEffectsEnabled NOTIFY audioEffectsEnabledChanged)
/**
* Whether GCompris should run in fullscreen mode.
*/
Q_PROPERTY(bool isFullscreen READ isFullscreen WRITE setFullscreen NOTIFY fullscreenChanged)
/**
* Window Height on Application's Startup
*/
Q_PROPERTY(quint32 previousHeight READ previousHeight WRITE setPreviousHeight NOTIFY previousHeightChanged)
/**
* Window Width on Application's Startup
*/
Q_PROPERTY(quint32 previousWidth READ previousWidth WRITE setPreviousWidth NOTIFY previousWidthChanged)
/**
* Whether on-screen keyboard should be enabled per default in activities
* that use it.
*/
Q_PROPERTY(bool isVirtualKeyboard READ isVirtualKeyboard WRITE setVirtualKeyboard NOTIFY virtualKeyboardChanged)
/**
* Locale string for currently active language.
*/
Q_PROPERTY(QString locale READ locale WRITE setLocale NOTIFY localeChanged)
/**
* Currently selected font.
*/
Q_PROPERTY(QString font READ font WRITE setFont NOTIFY fontChanged)
/**
* Whether currently active font is a shipped font (or a system font).
*
* Updated automatically.
* @sa font
*/
Q_PROPERTY(bool isEmbeddedFont READ isEmbeddedFont WRITE setIsEmbeddedFont NOTIFY embeddedFontChanged)
/**
* Font Capitalization
*
* Force all texts to be rendered in UpperCase, LowerCase or MixedCase (default)
* @sa font
*/
Q_PROPERTY(quint32 fontCapitalization READ fontCapitalization WRITE setFontCapitalization NOTIFY fontCapitalizationChanged)
/**
* Font letter spacing
*
* Change the letter spacing of all the texts
* @sa font
*/
Q_PROPERTY(qreal fontLetterSpacing READ fontLetterSpacing WRITE setFontLetterSpacing NOTIFY fontLetterSpacingChanged)
/**
* Minimum allowed value for font spacing letter.
*
* Constant value: +0.0
*/
Q_PROPERTY(qreal fontLetterSpacingMin READ fontLetterSpacingMin CONSTANT)
/**
* Maximum allowed value for font spacing letter.
*
* Constant value: +8.0
*/
Q_PROPERTY(qreal fontLetterSpacingMax READ fontLetterSpacingMax CONSTANT)
/**
* Whether downloads/updates of resource files should be done automatically,
* without user-interaction.
*
* Note, that on Android GCompris currently can't distinguish Wifi
* from mobile data connections (cf. Qt ticket #30394).
*/
Q_PROPERTY(bool isAutomaticDownloadsEnabled READ isAutomaticDownloadsEnabled WRITE setIsAutomaticDownloadsEnabled NOTIFY automaticDownloadsEnabledChanged)
/**
* Minimum value for difficulty level filter.
*/
Q_PROPERTY(quint32 filterLevelMin READ filterLevelMin WRITE setFilterLevelMin NOTIFY filterLevelMinChanged)
/**
* Maximum value for difficulty level filter.
*/
Q_PROPERTY(quint32 filterLevelMax READ filterLevelMax WRITE setFilterLevelMax NOTIFY filterLevelMaxChanged)
/**
* Whether in demo mode.
*/
Q_PROPERTY(bool isDemoMode READ isDemoMode WRITE setDemoMode NOTIFY demoModeChanged)
/**
* Activation code key.
*/
Q_PROPERTY(QString codeKey READ codeKey WRITE setCodeKey NOTIFY codeKeyChanged)
/**
* Activation mode.
*/
Q_PROPERTY(quint32 activationMode READ activationMode CONSTANT)
/**
* Whether kiosk mode is currently active.
*/
Q_PROPERTY(bool isKioskMode READ isKioskMode WRITE setKioskMode NOTIFY kioskModeChanged)
/**
* Whether the section selection row is visible in the menu view.
*/
Q_PROPERTY(bool sectionVisible READ sectionVisible WRITE setSectionVisible NOTIFY sectionVisibleChanged)
/**
* The name of the default wordset to use. If empty then the internal sample wordset is used.
*/
Q_PROPERTY(QString wordset READ wordset WRITE setWordset NOTIFY wordsetChanged)
/**
* Current base font-size used for font scaling.
*
* This setting is the basis for application-wide font-scaling. A value
* of 0 means to use the font-size as set by the application. Other values
* between @ref baseFontSizeMin and @ref baseFontSizeMax enforce
* font-scaling.
*
* @sa GCText.fontSize baseFontSizeMin baseFontSizeMax
*/
Q_PROPERTY(int baseFontSize READ baseFontSize WRITE setBaseFontSize NOTIFY baseFontSizeChanged)
/**
* Minimum allowed value for font-scaling.
*
* Constant value: -7
*/
Q_PROPERTY(int baseFontSizeMin READ baseFontSizeMin CONSTANT)
/**
* Maximum allowed value for font-scaling.
*
* Constant value: +7
*/
Q_PROPERTY(int baseFontSizeMax READ baseFontSizeMax CONSTANT)
// admin group
/**
* Base-URL for resource downloads.
*
* @sa DownloadManager
*/
Q_PROPERTY(QString downloadServerUrl READ downloadServerUrl WRITE setDownloadServerUrl NOTIFY downloadServerUrlChanged)
/**
* Path where resources are downloaded and stored.
*
* @sa DownloadManager
*/
Q_PROPERTY(QString cachePath READ cachePath WRITE setCachePath NOTIFY cachePathChanged)
+ /**
+ * Return the platform specific path for storing data shared between apps
+ *
+ * On Android: /storage/emulated/0/GCompris (>= Android 4.2),
+ * /storage/sdcard0/GCompris (< Android 4.2)
+ * On Linux: $HOME/local/share/GCompris
+ */
+ Q_PROPERTY(QString userDataPath READ userDataPath WRITE setUserDataPath NOTIFY userDataPathChanged)
+
+ /**
+ * Define the renderer used.
+ * Either openGL or software renderer (only for Qt >= 5.8)
+ */
+ Q_PROPERTY(QString renderer READ renderer WRITE setRenderer NOTIFY rendererChanged)
+
// internal group
Q_PROPERTY(quint32 exeCount READ exeCount WRITE setExeCount NOTIFY exeCountChanged)
// keep last version ran. If different than ApplicationInfo.GCVersionCode(), it means a new version is running
Q_PROPERTY(int lastGCVersionRan READ lastGCVersionRan WRITE setLastGCVersionRan NOTIFY lastGCVersionRanChanged)
// no group
Q_PROPERTY(bool isBarHidden READ isBarHidden WRITE setBarHidden NOTIFY barHiddenChanged)
public:
/// @cond INTERNAL_DOCS
- explicit ApplicationSettings(const QString &path = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation)
+ explicit ApplicationSettings(const QString &configPath = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation)
+ "/gcompris/" + GCOMPRIS_APPLICATION_NAME + ".conf", QObject *parent = 0);
virtual ~ApplicationSettings();
- static void init();
// It is not recommended to create a singleton of Qml Singleton registered
// object but we could not found a better way to let us access ApplicationInfo
// on the C++ side. All our test shows that it works.
static ApplicationSettings *getInstance() {
if(!m_instance) {
m_instance = new ApplicationSettings();
}
return m_instance;
}
- static QObject *systeminfoProvider(QQmlEngine *engine,
- QJSEngine *scriptEngine);
+ static QObject *applicationSettingsProvider(QQmlEngine *engine,
+ QJSEngine *scriptEngine);
bool showLockedActivities() const { return m_showLockedActivities; }
void setShowLockedActivities(const bool newMode) {
m_showLockedActivities = newMode;
emit showLockedActivitiesChanged();
}
bool isAudioVoicesEnabled() const { return m_isAudioVoicesEnabled; }
void setIsAudioVoicesEnabled(const bool newMode) {
m_isAudioVoicesEnabled = newMode;
emit audioVoicesEnabledChanged();
}
- bool isAudioEffectsEnabled() const { return m_isAudioEffectsEnabled; }
- void setIsAudioEffectsEnabled(const bool newMode) {
- m_isAudioEffectsEnabled = newMode;
- emit audioEffectsEnabledChanged();
+ bool isAudioEffectsEnabled() const { return m_isAudioEffectsEnabled; }
+ void setIsAudioEffectsEnabled(const bool newMode) {
+ m_isAudioEffectsEnabled = newMode;
+ emit audioEffectsEnabledChanged();
}
bool isFullscreen() const { return m_isFullscreen; }
void setFullscreen(const bool newMode) {
if(m_isFullscreen != newMode) {
m_isFullscreen = newMode;
emit fullscreenChanged();
}
}
quint32 previousHeight() const { return m_previousHeight; }
void setPreviousHeight(quint32 height) {
if(m_previousHeight != height) {
m_previousHeight = height;
emit previousHeightChanged();
}
}
quint32 previousWidth() const { return m_previousWidth; }
void setPreviousWidth(quint32 width) {
if(m_previousWidth != width) {
m_previousWidth = width;
emit previousWidthChanged();
}
}
bool isVirtualKeyboard() const { return m_isVirtualKeyboard; }
void setVirtualKeyboard(const bool newMode) {
m_isVirtualKeyboard = newMode;
emit virtualKeyboardChanged();
}
QString locale() const {
return m_locale;
}
void setLocale(const QString &newLocale) {
m_locale = newLocale;
emit localeChanged();
}
QString font() const { return m_font; }
void setFont(const QString &newFont) {
m_font = newFont;
emit fontChanged();
}
bool isEmbeddedFont() const { return m_isEmbeddedFont; }
void setIsEmbeddedFont(const bool newIsEmbeddedFont) {
m_isEmbeddedFont = newIsEmbeddedFont;
emit embeddedFontChanged();
}
quint32 fontCapitalization() const { return m_fontCapitalization; }
void setFontCapitalization(quint32 newFontCapitalization) {
m_fontCapitalization = newFontCapitalization;
emit fontCapitalizationChanged();
}
qreal fontLetterSpacing() const { return m_fontLetterSpacing; }
void setFontLetterSpacing(qreal newFontLetterSpacing) {
m_fontLetterSpacing = newFontLetterSpacing;
emit fontLetterSpacingChanged();
}
qreal fontLetterSpacingMin() const { return m_fontLetterSpacingMin; }
qreal fontLetterSpacingMax() const { return m_fontLetterSpacingMax; }
bool isAutomaticDownloadsEnabled() const;
void setIsAutomaticDownloadsEnabled(const bool newIsAutomaticDownloadsEnabled);
quint32 filterLevelMin() const { return m_filterLevelMin; }
void setFilterLevelMin(const quint32 newFilterLevelMin) {
m_filterLevelMin = newFilterLevelMin;
emit filterLevelMinChanged();
}
quint32 filterLevelMax() const { return m_filterLevelMax; }
void setFilterLevelMax(const quint32 newFilterLevelMax) {
m_filterLevelMax = newFilterLevelMax;
emit filterLevelMaxChanged();
}
bool isDemoMode() const { return m_isDemoMode; }
void setDemoMode(const bool newMode);
QString codeKey() const { return m_codeKey; }
void setCodeKey(const QString &newCodeKey) {
m_codeKey = newCodeKey;
emit codeKeyChanged();
}
/**
* @brief activationMode
* @return 0: no, 1: inapp, 2: internal
*/
quint32 activationMode() const { return m_activationMode; }
bool isKioskMode() const { return m_isKioskMode; }
void setKioskMode(const bool newMode) {
m_isKioskMode = newMode;
emit kioskModeChanged();
}
/**
* Check validity of the activation code
* @param code An activation code to check
* @returns 0 if the code is not valid or we don't know yet
* 1 if the code is valid but out of date
* 2 if the code is valid and under 2 years
*/
Q_INVOKABLE uint checkActivationCode(const QString &code);
/**
* Check Payment API
* Call a payment system to sync our demoMode state with it
*/
void checkPayment();
// Called by the payment system
void bought(const bool isBought) {
if(m_isDemoMode != !isBought) {
m_isDemoMode = !isBought;
emit demoModeChanged();
}
}
bool sectionVisible() const { return m_sectionVisible; }
void setSectionVisible(const bool newMode) {
qDebug() << "c++ setSectionVisible=" << newMode;
m_sectionVisible = newMode;
emit sectionVisibleChanged();
}
QString wordset() const { return m_wordset; }
void setWordset(const QString &newWordset) {
m_wordset = newWordset;
emit wordsetChanged();
}
QString downloadServerUrl() const { return m_downloadServerUrl; }
void setDownloadServerUrl(const QString &newDownloadServerUrl) {
m_downloadServerUrl = newDownloadServerUrl;
emit downloadServerUrlChanged();
}
QString cachePath() const { return m_cachePath; }
void setCachePath(const QString &newCachePath) {
m_cachePath = newCachePath;
emit cachePathChanged();
}
+ QString userDataPath() const { return m_userDataPath; }
+ void setUserDataPath(const QString &newUserDataPath) {
+ m_userDataPath = newUserDataPath;
+ emit userDataPathChanged();
+ }
quint32 exeCount() const { return m_exeCount; }
void setExeCount(const quint32 newExeCount) {
m_exeCount = newExeCount;
emit exeCountChanged();
}
bool isBarHidden() const { return m_isBarHidden; }
void setBarHidden(const bool newBarHidden) {
m_isBarHidden = newBarHidden;
emit barHiddenChanged();
}
int baseFontSize() const { return m_baseFontSize; }
void setBaseFontSize(const int newBaseFontSize) {
m_baseFontSize = qMax(qMin(newBaseFontSize, baseFontSizeMax()), baseFontSizeMin());
emit baseFontSizeChanged();
}
int baseFontSizeMin() const { return m_baseFontSizeMin; }
int baseFontSizeMax() const { return m_baseFontSizeMax; }
int lastGCVersionRan() const { return m_lastGCVersionRan; }
void setLastGCVersionRan(const int newLastGCVersionRan) {
m_lastGCVersionRan = newLastGCVersionRan;
emit lastGCVersionRanChanged();
}
+ QString renderer() const { return m_renderer; }
+ void setRenderer(const QString &newRenderer) {
+ m_renderer = newRenderer;
+ emit rendererChanged();
+ }
+
/**
* Check if we use the external wordset for activity based on lang_api
* @returns true if wordset is loaded
* false if wordset is not loaded
*/
Q_INVOKABLE bool useExternalWordset();
protected slots:
Q_INVOKABLE void notifyShowLockedActivitiesChanged();
Q_INVOKABLE void notifyAudioVoicesEnabledChanged();
Q_INVOKABLE void notifyAudioEffectsEnabledChanged();
Q_INVOKABLE void notifyFullscreenChanged();
Q_INVOKABLE void notifyPreviousHeightChanged();
Q_INVOKABLE void notifyPreviousWidthChanged();
Q_INVOKABLE void notifyVirtualKeyboardChanged();
Q_INVOKABLE void notifyLocaleChanged();
Q_INVOKABLE void notifyFontChanged();
Q_INVOKABLE void notifyFontCapitalizationChanged();
Q_INVOKABLE void notifyFontLetterSpacingChanged();
Q_INVOKABLE void notifyEmbeddedFontChanged();
Q_INVOKABLE void notifyAutomaticDownloadsEnabledChanged();
Q_INVOKABLE void notifyFilterLevelMinChanged();
Q_INVOKABLE void notifyFilterLevelMaxChanged();
Q_INVOKABLE void notifyDemoModeChanged();
Q_INVOKABLE void notifyCodeKeyChanged();
Q_INVOKABLE void notifyKioskModeChanged();
Q_INVOKABLE void notifySectionVisibleChanged();
Q_INVOKABLE void notifyWordsetChanged();
Q_INVOKABLE void notifyDownloadServerUrlChanged();
Q_INVOKABLE void notifyCachePathChanged();
-
+ Q_INVOKABLE void notifyUserDataPathChanged();
Q_INVOKABLE void notifyExeCountChanged();
Q_INVOKABLE void notifyLastGCVersionRanChanged();
+ Q_INVOKABLE void notifyRendererChanged();
Q_INVOKABLE void notifyBarHiddenChanged();
public slots:
Q_INVOKABLE bool isFavorite(const QString &activity);
Q_INVOKABLE void setFavorite(const QString &activity, bool favorite);
Q_INVOKABLE void setCurrentLevel(const QString &activity, const QString &level);
Q_INVOKABLE QString currentLevel(const QString &activity);
Q_INVOKABLE void saveBaseFontSize();
/// @endcond
/**
* Stores per-activity configuration @p data for @p activity.
*
* @param activity Name of the activity that wants to persist settings.
* @param data Map of configuration data so save.
*/
Q_INVOKABLE void saveActivityConfiguration(const QString &activity, const QVariantMap &data);
/**
* Loads per-activity configuration data for @p activity.
*
* @param activity Name of the activity that wants to persist settings.
* @returns Map of configuration items.
*/
Q_INVOKABLE QVariantMap loadActivityConfiguration(const QString &activity);
/**
* Loads per-activity progress using the default "progress" key.
*
* @param activity Name of the activity to load progress for.
* @returns Last started level of the activity, 0 if none saved.
*/
Q_INVOKABLE int loadActivityProgress(const QString &activity);
/**
* Saves per-activity progress using the default "progress" key.
*
* @param activity Name of the activity that wants to persist settings.
* @param progress Last started level to save as progress value.
*/
Q_INVOKABLE void saveActivityProgress(const QString &activity, int progress);
signals:
void showLockedActivitiesChanged();
void audioVoicesEnabledChanged();
void audioEffectsEnabledChanged();
void fullscreenChanged();
void previousHeightChanged();
void previousWidthChanged();
void virtualKeyboardChanged();
void localeChanged();
void fontChanged();
void fontCapitalizationChanged();
void fontLetterSpacingChanged();
void embeddedFontChanged();
void automaticDownloadsEnabledChanged();
void filterLevelMinChanged();
void filterLevelMaxChanged();
void demoModeChanged();
void codeKeyChanged();
void kioskModeChanged();
void sectionVisibleChanged();
void wordsetChanged();
void baseFontSizeChanged();
void downloadServerUrlChanged();
void cachePathChanged();
+ void userDataPathChanged();
void exeCountChanged();
void lastGCVersionRanChanged();
+ void rendererChanged();
void barHiddenChanged();
protected:
static ApplicationSettings *m_instance;
private:
// Update in configuration the couple {key, value} in the group.
template<class T> void updateValueInConfig(const QString& group,
const QString& key, const T& value);
bool m_showLockedActivities;
bool m_isAudioVoicesEnabled;
bool m_isAudioEffectsEnabled;
bool m_isFullscreen;
quint32 m_previousHeight;
quint32 m_previousWidth;
bool m_isVirtualKeyboard;
bool m_isAutomaticDownloadsEnabled;
bool m_isEmbeddedFont;
quint32 m_fontCapitalization;
qreal m_fontLetterSpacing;
quint32 m_filterLevelMin;
quint32 m_filterLevelMax;
bool m_defaultCursor;
bool m_noCursor;
QString m_locale;
QString m_font;
bool m_isDemoMode;
QString m_codeKey;
quint32 m_activationMode;
bool m_isKioskMode;
bool m_sectionVisible;
QString m_wordset;
int m_baseFontSize;
const int m_baseFontSizeMin;
const int m_baseFontSizeMax;
const qreal m_fontLetterSpacingMin;
const qreal m_fontLetterSpacingMax;
QString m_downloadServerUrl;
QString m_cachePath;
+ QString m_userDataPath;
quint32 m_exeCount;
int m_lastGCVersionRan;
+ QString m_renderer;
bool m_isBarHidden;
QSettings m_config;
};
#endif // APPLICATIONSETTINGS_H
diff --git a/src/core/ApplicationSettingsDefault.cpp b/src/core/ApplicationSettingsDefault.cpp
index e25ef8882..5a9d53d9b 100644
--- a/src/core/ApplicationSettingsDefault.cpp
+++ b/src/core/ApplicationSettingsDefault.cpp
@@ -1,58 +1,58 @@
/* GCompris - ApplicationSettingsDefault.cpp
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
#include "ApplicationSettings.h"
#include "config.h"
#include <QDebug>
void ApplicationSettings::setDemoMode(const bool newMode) {
m_isDemoMode = newMode;
emit demoModeChanged();
}
void ApplicationSettings::checkPayment() {
if(m_activationMode == 2)
setDemoMode(checkActivationCode(m_codeKey) < 2);
}
uint ApplicationSettings::checkActivationCode(const QString &code) {
if(code.length() != 12) {
return 0;
}
bool ok;
uint year = code.midRef(4, 3).toUInt(&ok, 16);
uint month = code.midRef(7, 1).toUInt(&ok, 16);
uint crc = code.midRef(8, 4).toUInt(&ok, 16);
uint expectedCrc =
code.midRef(0, 4).toUInt(&ok, 16) ^
code.midRef(4, 4).toUInt(&ok, 16) ^
0xCECA;
ok = (expectedCrc == crc && year < 2100 && month <= 12);
if(!ok)
// Bad crc, year or month
return 0;
// Check date is under 2 years
ok = int(year * 100 + month + 200) >= atoi(BUILD_DATE);
return(ok ? 2 : 1);
}
diff --git a/src/core/Balloon.qml b/src/core/Balloon.qml
index 458a9a854..9abc64da1 100644
--- a/src/core/Balloon.qml
+++ b/src/core/Balloon.qml
@@ -1,199 +1,199 @@
/* GCompris - Balloon.qml
*
* Copyright (C) 2014 Aruna Sankaranarayanan <arunasank@src.gnome.org>
*
* Authors:
* Aruna Sankaranarayanan <arunasank@src.gnome.org>
* Bruno Coudoin <bruno.coudoin@gcompris.net> Improved Animation
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
/**
* A QML component to visualize countdown.
*
* Balloon usually consists of timeout duration (@ref duration)
* and a boolean to check if animation are running at a moment (@ref disabled).
*
* A balloon falls from top to bottom in a given duration on
* calling startMoving method and stops on calling stopMoving method.
*
* @inherit QtQuick.Image
*/
Image {
id: balloon
source: "qrc:/gcompris/src/core/resource/tuxballoon.svg";
sourceSize.width: parent.width * 0.4
scale: 0.8
x: parent.width / 2
y: - balloon.height
/**
* type:int
* Height of activity window.
*/
property int parentHeight: parent.height
/**
* Emitted when balloon hits the ground i.e. on completion of time duration.
*/
signal timeout
/**
* Emitted when countdown is ready to start.
*/
signal ready
/**
* type:int
* Total duration of the countdown.
*/
property int duration
/**
* type:boolean
* To know if countdown is running at a moment.
*/
property bool disabled
onParentHeightChanged: startMoving(duration)
// Starts the countdown and down animation starts.
function startMoving(durationIncoming)
{
stopMoving()
disabled = false
duration = durationIncoming
down.restart()
}
// Stops the countdown and the down animation stops.
function stopMoving()
{
disabled = true
reinit.start()
down.stop()
}
ParallelAnimation {
id: reinit
running: false
NumberAnimation {
target: balloon
property: "scale"
to: 0.8
duration: 1000
}
NumberAnimation {
target: balloon
property: "y"
to: - balloon.height
duration: 1000
easing.type: Easing.InOutQuad
}
NumberAnimation {
target: balloon
property: "rotation"
to: 0
duration: 1000
easing.type: Easing.InOutQuad
}
}
SequentialAnimation {
id: down
onRunningChanged: {
if (!down.running && !balloon.disabled) {
timeout()
}
}
ParallelAnimation {
NumberAnimation {
target: balloon
property: "scale"
to: 0.8
duration: 1000
}
NumberAnimation {
target: balloon
property: "y"
to: - balloon.height
duration: 1000
easing.type: Easing.InOutQuad
}
NumberAnimation {
target: balloon
property: "rotation"
to: 0
duration: 1000
easing.type: Easing.InOutQuad
}
}
ParallelAnimation {
running: false
NumberAnimation {
target: balloon
property: "scale"
to: 1
duration: balloon.duration
}
NumberAnimation {
target: balloon
property: "y"
to: parent.height - balloon.height
duration: balloon.duration
easing.type: Easing.InOutQuad
}
SequentialAnimation {
NumberAnimation {
target: balloon
property: "rotation"
to: -5
duration: 3000
easing.type: Easing.InOutQuad
}
SequentialAnimation {
loops: 1
NumberAnimation {
target: balloon
property: "rotation"
from: -5; to: 5
duration: 3000
easing.type: Easing.InOutQuad
}
NumberAnimation {
target: balloon
property: "rotation"
from: 5; to: -5
duration: 3000
easing.type: Easing.InOutQuad }
}
NumberAnimation {
target: balloon
property: "rotation"
to: 0
duration: 3000
easing.type: Easing.InOutQuad
}
}
}
}
}
diff --git a/src/core/Bar.qml b/src/core/Bar.qml
index 590edd04c..bfcf1b161 100644
--- a/src/core/Bar.qml
+++ b/src/core/Bar.qml
@@ -1,520 +1,520 @@
/* GCompris - Bar.qml
*
* Copyright (C) 2014-2016 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "qrc:/gcompris/src/core/core.js" as Core
/**
* A QML component for GCompris' navigation bar.
* @ingroup components
*
* The Bar is visible in all activities and the main menu screen. It can be
* hidden by clicking on the 'toggle' region.
*
* It can consist of a couple of child-elements, mostly buttons, defined
* in the BarEnumContent container. An activity can define which elements its bar should
* present using the content property. In most cases it contains at least
* BarEnumContent.help, BarEnumContent.home and BarEnumContent.level.
*
* Cf. the BarEnumContent container for a full list of available Bar elements.
*
* Cf. the Bar object used in Template.qml as an example of how a minimal
* Bar implementation should look like.
*
* @sa BarButton, BarEnumContent
* @inherit QtQuick.Item
*/
Item {
id: bar
/**
* type: real
* Minimum size for BarZoom
*/
readonly property real minWidth: (parent.width - 20 -
10 * ApplicationInfo.ratio) / (totalWidth + textLength)
/**
* type: real
* Maximum size for barZoom
*/
readonly property real maxWidth: 1.2 * ApplicationInfo.ratio
/**
* type: real
* Length of level String
*/
property real textLength
/**
* type: real
* The maximum size allowed for the bar
*/
readonly property real maxBarWidth: (totalWidth+textLength) * maxWidth +
(numberOfButtons - 1) * 5 + 10 * ApplicationInfo.ratio
/**
* type: real
* Font size for text level
*/
readonly property real textSize: (parent.width<maxBarWidth) ? 32 * minWidth / maxWidth : 32
/**
* type:real
* Zoom factor of the bar and its children.
*/
property real barZoom: (parent.width<maxBarWidth) ? minWidth : maxWidth
/**
* type: real
* Keeps track of the number of buttons that are displayed
*/
property int numberOfButtons: 0
//totalWidth has 66 as initial value because it will always have the "hideBar" button
/**
* type: real
* Width of all the buttons
*/
property real totalWidth: 66
readonly property int fullButton: 66
readonly property int halfButton: 30
readonly property int fullButtonScaled: fullButton * barZoom
readonly property int halfButtonScaled: halfButton * barZoom
/**
* type:BarEnumContent
* Defines the content/children of the bar.
*
* @sa BarEnumContent
*/
property BarEnumContent content
/**
* type:int
* Current level to be shown in the level child.
*
* Set this to the current level of your activity.
*/
property int level: 0
/**
* Emitted when the about button was clicked.
*/
signal aboutClicked
/**
* Emitted when the help button was clicked.
*
* Show help dialog upon this signal.
*/
signal helpClicked
/**
* Emitted when the config button was clicked.
*
* Should be implemented if an activity provides per-activity
* configuration.
*/
signal configClicked
/**
* Emitted when the next level button was clicked.
*
* Switch to the next level upon this signal.
*/
signal nextLevelClicked
/**
* Emitted when the previous level button was clicked.
*
* Switch to the previous level upon this signal.
*/
signal previousLevelClicked
/**
* Emitted when the repeat button was clicked.
*
* Implement if your activity needs to repeat audio voices.
*/
signal repeatClicked
/**
* Emitted when the reload button was clicked.
*
* Implement if you want to support repeating a level from the beginning.
*/
signal reloadClicked
/**
* Emitted when the hint button was clicked.
*
* Implement if your activity needs a hint to help children.
*/
signal hintClicked
/**
* Emitted when the activity configuration button was clicked.
*
* Only in menu to change the activity configuration.
*/
signal activityConfigClicked
/**
* Emitted when the home button was clicked.
*
* Should always be connected to the ActivityBase.home signal and thus
* return to the home/main menu.
*/
signal homeClicked
/// @cond INTERNAL_DOCS
/*
* A list of all our possible buttons.
*
* bid = Button ID. And references the Component object of the button
* This way we can have any visual object in the bar.
*/
property var buttonList: [
{
'bid': exit,
'contentId': content.exit,
'allowed': !ApplicationSettings.isKioskMode
},
{
'bid': about,
'contentId': content.about,
'allowed': true
},
{
'bid': help,
'contentId': content.help,
'allowed': true
},
{
'bid': home,
'contentId': content.home,
'allowed': true
},
{
'bid': previous,
'contentId': content.level,
'allowed': true
},
{
'bid': levelText,
'contentId': content.level,
'allowed': true
},
{
'bid': next,
'contentId': content.level,
'allowed': true
},
{
'bid': repeat,
'contentId': content.repeat,
'allowed': true
},
{
'bid': reload,
'contentId': content.reload,
'allowed': true
},
{
'bid': config,
'contentId': content.config,
'allowed': !ApplicationSettings.isKioskMode
},
{
'bid': hint,
'contentId': content.hint,
'allowed': true
},
{
'bid': activityConfigImage,
'contentId': content.activityConfig,
'allowed': true
},
{
'bid': downloadImage,
'contentId': content.download,
'allowed': true
}
]
/* internal? */
property var buttonModel
x: 0
anchors.bottom: parent.bottom
width: openBar.width
height: openBar.height
z: 1000
function show(newContent) {
content.value = newContent
}
Connections {
target: DownloadManager
onDownloadStarted: content.value |= content.download
onDownloadFinished: content.value &= ~content.download
onError: content.value &= ~content.download
}
Image {
id: openBar
source: "qrc:/gcompris/src/core/resource/bar_open.svg";
anchors.bottom: parent.bottom
anchors.left: parent.left
sourceSize.width: fullButtonScaled
MouseArea {
anchors.fill: parent
onClicked: {
ApplicationSettings.isBarHidden = !ApplicationSettings.isBarHidden;
}
}
}
function computeWidth(bid) {
if (bid===levelText) {
return 0
}
else if (bid===previous||bid===next)
return halfButton
else return fullButton
}
function updateContent() {
var newButtonModel = new Array()
numberOfButtons = 0
totalWidth = 66;
for(var def in buttonList) {
if((content.value & buttonList[def].contentId) &&
buttonList[def].allowed) {
newButtonModel.push(buttonList[def])
totalWidth += computeWidth(buttonList[def].bid)
numberOfButtons++
}
}
buttonModel = newButtonModel
}
Connections {
target: content
onValueChanged: updateContent()
}
onContentChanged: {
updateContent()
}
Row {
id: barRow
spacing: 5
anchors.bottom: parent.bottom
anchors.bottomMargin: 10
anchors.left: openBar.right
anchors.leftMargin: 10 * ApplicationInfo.ratio
Repeater {
model: buttonModel
Loader {
sourceComponent: modelData.bid
}
}
state: ApplicationSettings.isBarHidden ? "hidden" : "shown"
states: [
State {
name: "shown"
AnchorChanges {
target: barRow
anchors.top: undefined
anchors.bottom: parent.bottom
}
},
State {
name: "hidden"
AnchorChanges {
target: barRow
anchors.bottom: undefined
anchors.top: parent.bottom
}
}
]
transitions: Transition {
AnchorAnimation { duration: 800; easing.type: Easing.OutBounce }
}
populate: Transition {
NumberAnimation {
properties: "x,y"; from: 200;
duration: 1500; easing.type: Easing.OutBounce
}
}
add: Transition {
NumberAnimation {
properties: "x,y"; from: 200;
duration: 1500; easing.type: Easing.OutBounce
}
}
move: Transition {
NumberAnimation {
properties: "x,y"
duration: 1500; easing.type: Easing.OutBounce
}
}
}
// All the possible bar buttons are defined here
// ---------------------------------------------
Component {
id: exit
BarButton {
source: "qrc:/gcompris/src/core/resource/bar_exit.svg";
sourceSize.width: fullButtonScaled
onClicked: Core.quit(bar.parent.parent);
}
}
Component {
id: about
BarButton {
source: "qrc:/gcompris/src/core/resource/bar_about.svg";
sourceSize.width: fullButtonScaled
onClicked: bar.aboutClicked()
}
}
Component {
id: help
BarButton {
source: "qrc:/gcompris/src/core/resource/bar_help.svg";
sourceSize.width: fullButtonScaled
onClicked: bar.helpClicked()
}
}
Component {
id: previous
BarButton {
source: "qrc:/gcompris/src/core/resource/bar_previous.svg";
sourceSize.width: halfButtonScaled
onClicked: bar.previousLevelClicked()
}
}
Component {
id: levelText
GCText {
id: levelTextId
text: "" + level
fontSize: textSize
font.weight: Font.DemiBold
style: Text.Outline
styleColor: "black"
color: "white"
visible: content.level & content.value
onTextChanged: {
if (level>9)
textLength = fullButtonScaled
else textLength = halfButtonScaled
}
}
}
Component {
id: next
BarButton {
source: "qrc:/gcompris/src/core/resource/bar_next.svg";
sourceSize.width: halfButtonScaled
onClicked: bar.nextLevelClicked()
}
}
Component {
id: repeat
BarButton {
source: "qrc:/gcompris/src/core/resource/bar_repeat.svg";
sourceSize.width: fullButtonScaled
onClicked: bar.repeatClicked()
}
}
Component {
id: hint
BarButton {
source: "qrc:/gcompris/src/core/resource/bar_hint.svg";
sourceSize.width: fullButtonScaled
onClicked: bar.hintClicked()
}
}
Component {
id: activityConfigImage
BarButton {
source: "qrc:/gcompris/src/core/resource/bar_activity_config.svg";
sourceSize.width: fullButtonScaled
onClicked: bar.activityConfigClicked()
}
}
Component {
id: reload
BarButton {
source: "qrc:/gcompris/src/core/resource/bar_reload.svg";
sourceSize.width: fullButtonScaled
onClicked: bar.reloadClicked()
}
}
Component {
id: config
BarButton {
source: "qrc:/gcompris/src/core/resource/bar_config.svg";
sourceSize.width: fullButtonScaled
onClicked: bar.configClicked()
}
}
Component {
id: home
BarButton {
source: "qrc:/gcompris/src/core/resource/bar_home.svg";
sourceSize.width: fullButtonScaled
onClicked: bar.homeClicked()
}
}
Component {
id: downloadImage
AnimatedImage {
source: "qrc:/gcompris/src/core/resource/loader.gif"
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: {
var downloadDialog = Core.showDownloadDialog(bar.parent, {});
}
}
}
}
/// @endcond
}
diff --git a/src/core/BarButton.qml b/src/core/BarButton.qml
index d89625a94..c79108ae5 100644
--- a/src/core/BarButton.qml
+++ b/src/core/BarButton.qml
@@ -1,76 +1,76 @@
/* GCompris - BarButton.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
/**
* Helper QML component for a button shown on the Bar.
* @ingroup components
*
* Used internally by the Bar component.
*
* @sa Bar
*/
Image {
id: button
state: "notclicked"
property alias mouseArea: mouseArea
signal clicked
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: button.clicked()
}
states: [
State {
name: "notclicked"
PropertyChanges {
target: button
scale: 1.0
}
},
State {
name: "clicked"
when: mouseArea.pressed
PropertyChanges {
target: button
scale: 0.9
}
},
State {
name: "hover"
when: mouseArea.containsMouse
PropertyChanges {
target: button
scale: 1.1
}
}
]
Behavior on scale { NumberAnimation { duration: 70 } }
Behavior on opacity { PropertyAnimation { duration: 200 } }
}
diff --git a/src/core/BarEnumContent.qml b/src/core/BarEnumContent.qml
index 841ac4ebd..89da3ce45 100644
--- a/src/core/BarEnumContent.qml
+++ b/src/core/BarEnumContent.qml
@@ -1,124 +1,124 @@
/* GCompris - BarEnumContent.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
/**
* QML container for defining all visible child elements of a Bar.
* @ingroup components
*
* Used in the Bar.content property.
*
* The @p value property must be set to a logically OR-ed combination of
* the other properties each representing one Bar element.
*/
QtObject {
/**
* type:int
* Bitmask defininig all visible elements of a bar.
*/
property int value: 0
/**
* type:int
* Representation of the help button.
*
* Used for opening a help screen.
*/
readonly property int help: 1
/**
* type:int
* Representation of the about button.
*
* Used on the menu screen.
*/
readonly property int about: 2
/**
* type:int
* Representation of the exit button.
*
* Used for exiting the application or returning to the menu.
*/
readonly property int exit: 4
/**
* type:int
* Representation of the home button.
*
* Used for returning from an acitivity to the main menu.
*/
readonly property int home: 8
/**
* type:int
* Representation of the config button.
*
* Used for switching to a config screen.
*/
readonly property int config: 16
/**
* type:int
* Representation of the current level and next and previous buttons.
*/
readonly property int level: 32
/**
* type:int
* Representation of the reload button.
*
* Used for restarting the current level of an activity.
*/
readonly property int reload: 64
/**
* type:int
* Representation of the repeat button.
*
* Used for repeating audio voices.
*/
readonly property int repeat: 128
/**
* type:int
* Representation of a currently running download.
*
* Shown automatically during running download.
*/
readonly property int download: 256
/**
* type:int
* Representation of the hint button.
*
* Used for displaying a hint to the children to help.
*/
readonly property int hint: 512
/**
* type:int
* Representation of the activity configuration button.
*
* Used for displaying the configuration of activities in the menu.
*/
readonly property int activityConfig: 1024
}
diff --git a/src/core/Bonus.qml b/src/core/Bonus.qml
index 81a87d0b6..51add58ae 100644
--- a/src/core/Bonus.qml
+++ b/src/core/Bonus.qml
@@ -1,204 +1,204 @@
/* GCompris - Bonus.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
// Requires the global property in the scope:
// property GCAudio audioEffects, audioVoices
/**
* A QML component providing user feedback upon winning/loosing.
* @ingroup components
*
* Usually triggered by an activity when a user has won/lost a level via the
* @ref good / @ref bad methods. Bonus then provides visual and auditive
* feedback to the user and emits the @ref win / @ref loose signals when
* finished.
*
* Maintains a list of possible audio voice resources to be playebd back
* upon winning/loosing events, and selects randomly from them when triggered.
*
* @inherit QtQuick.Image
*/
Image {
id: bonus
/**
* type:string
* Url of the audio resource to be used as winning sound.
*/
property string winSound: url + "sounds/bonus.wav"
/**
* type:string
* Url of the audio resource to be used as loosing sound.
*/
property string looseSound
/**
* type:int
* Interval in milliseconds after which the bonus will be played (default is 500ms)
*/
property alias interval: timer.interval
/**
* Emitted when the bonus starts
*/
signal start
/**
* Emitted when the bonus stops
*/
signal stop
/**
* Emitted when the win event is over.
*
* After the animation has finished.
*/
signal win
/**
* Emitted when the loose event is over.
*
* After the animation has finished.
*/
signal loose
/// @cond INTERNAL_DOCS
property string url: "qrc:/gcompris/src/core/resource/"
property bool isWin: false
property var winVoices: [
"voices-$CA/$LOCALE/misc/congratulation.$CA",
"voices-$CA/$LOCALE/misc/great.$CA",
"voices-$CA/$LOCALE/misc/good.$CA",
"voices-$CA/$LOCALE/misc/awesome.$CA",
"voices-$CA/$LOCALE/misc/fantastic.$CA",
"voices-$CA/$LOCALE/misc/waytogo.$CA",
"voices-$CA/$LOCALE/misc/super.$CA",
"voices-$CA/$LOCALE/misc/perfect.$CA"
]
property var looseVoices: [
"voices-$CA/$LOCALE/misc/check_answer.$CA"
]
/// @endcond
/**
* type:bool
* True between the moment we have the win/lose signal emitted and the
* bonus image is no more displayed
*/
property bool isPlaying: animation.running || timer.running
visible: true
opacity: 0
anchors.fill: parent
anchors.margins: 50 * ApplicationInfo.ratio
fillMode: Image.PreserveAspectFit
z: 1000
sourceSize.width: parent.width * 0.5
/**
* Triggers win feedback.
*
* Tries to play back a voice resource for winning, if not found fall back
* to the winSound.
*
* @param name Type of win image to show.
* Possible values are "flower", "gnu", "lion", "note", "smiley", "tux"
*/
function good(name) {
source = url + "bonus/" + name + "_good.svg"
isWin = true
timer.start()
}
/**
* Triggers loose feedback.
*
* Tries to play back a voice resource for loosing, if not found fall back
* to the looseSound.
*
* @param name Type of win image to show.
* Possible values are "flower", "gnu", "lion", "note", "smiley", "tux"
*/
function bad(name) {
source = url + "bonus/" + name + "_bad.svg"
isWin = false;
timer.start()
}
/**
* Private: Triggers win feedback after the timer completion
*/
function _good() {
if(!audioVoices.play(
ApplicationInfo.getAudioFilePath(
winVoices[Math.floor(Math.random()*winVoices.length)])))
if(winSound)
audioEffects.play(winSound)
start()
animation.start()
}
/**
* Private: Triggers loose feedback after the timer completion.
*/
function _bad(name) {
if(!audioVoices.play(
ApplicationInfo.getAudioFilePath(
looseVoices[Math.floor(Math.random()*looseVoices.length)])))
if(looseSound)
audioEffects.play(looseSound)
start()
animation.start()
}
SequentialAnimation {
id: animation
NumberAnimation {
target: bonus
property: "opacity"
from: 0; to: 1.0
duration: 1000
easing.type: Easing.InOutQuad
}
NumberAnimation {
target: bonus
property: "opacity"
from: 1.0; to: 0
duration: 500
easing.type: Easing.InOutQuad
}
onStopped: {
bonus.stop()
isWin ? win() : loose()
}
}
// It is useful to launch the bonus after a delay to let the children
// appreciate the completed level
Timer {
id: timer
interval: 500
onTriggered: isWin ? bonus._good() : bonus._bad()
}
}
diff --git a/src/core/BuyMeOverlay.qml b/src/core/BuyMeOverlay.qml
index 52b022ac5..f1daa02a0 100644
--- a/src/core/BuyMeOverlay.qml
+++ b/src/core/BuyMeOverlay.qml
@@ -1,121 +1,121 @@
/* GCompris - BuyMeOverlay.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import QtQuick.Controls 1.5
import GCompris 1.0
Item {
anchors {
fill: parent
bottomMargin: bar.height * 1.2
}
Rectangle {
anchors.fill: parent
opacity: 0.5
color: "grey"
}
/* Activation Instruction */
Rectangle {
id: instruction
z: 99
anchors {
horizontalCenter: parent.horizontalCenter
horizontalCenterOffset: - cancelButton.width / 2
top: parent.top
topMargin: 40
}
width: parent.width - cancelButton.width * 2
height: parent.height/2
radius: 10
border.width: 2
border.color: "black"
color: 'white'
Row {
id: row
anchors {
fill: parent
margins: 10
}
Image {
id: lock
source: "qrc:/gcompris/src/activities/menu/resource/lock.svg"
sourceSize.width: 30 * ApplicationInfo.ratio
}
GCText {
id: instructionTxt
fontSizeMode: Text.Fit
color: "black"
style: Text.Outline
styleColor: "white"
horizontalAlignment: Text.AlignHCenter
width: parent.width - lock.width
height: instruction.height - row.anchors.margins/2
wrapMode: TextEdit.WordWrap
z: 2
text: qsTr("This activity is only available in the full version of GCompris." + "<br/>" +
- "On <a href='http://gcompris.net'>http://gcompris.net</a> " +
+ "On <a href='https://gcompris.net'>https://gcompris.net</a> " +
"you will find the instructions to obtain an activation code." + " " +
"Then go to the main configuration dialog to enter the code.")
}
}
}
MultiPointTouchArea {
// Just to catch mouse events
anchors.fill: parent
}
Keys.onEscapePressed: home()
Keys.onPressed: {
event.accepted = true
if (event.modifiers === Qt.ControlModifier &&
event.key === Qt.Key_Q) {
// Ctrl+Q exit the application
Core.quit(page);
} else if (event.modifiers === Qt.ControlModifier &&
event.key === Qt.Key_B) {
// Ctrl+B toggle the bar
ApplicationSettings.isBarHidden = !ApplicationSettings.isBarHidden;
} else if (event.modifiers === Qt.ControlModifier &&
event.key === Qt.Key_F) {
// Ctrl+F toggle fullscreen
ApplicationSettings.isFullscreen = !ApplicationSettings.isFullscreen
} else if (event.modifiers === Qt.ControlModifier &&
event.key === Qt.Key_M) {
// Ctrl+M toggle sound
ApplicationSettings.isAudioEffectsEnabled = !ApplicationSettings.isAudioEffectsEnabled
} else if (event.modifiers === Qt.ControlModifier &&
event.key === Qt.Key_W) {
// Ctrl+W exit the current activity
home()
}
}
// The cancel button
GCButtonCancel {
id: cancelButton
onClose: home()
}
}
diff --git a/src/core/BuyMeOverlayInapp.qml b/src/core/BuyMeOverlayInapp.qml
index 2c8fa070c..5e57f44b2 100644
--- a/src/core/BuyMeOverlayInapp.qml
+++ b/src/core/BuyMeOverlayInapp.qml
@@ -1,136 +1,136 @@
/* GCompris - BuyMeOverlayInapp.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import QtQuick.Controls 1.5
import GCompris 1.0
Item {
anchors {
fill: parent
bottomMargin: bar.height * 1.2
}
Rectangle {
anchors.fill: parent
opacity: 0.5
color: "grey"
}
/* Activation Instruction */
Rectangle {
id: instructionsArea
z: 99
anchors {
horizontalCenter: parent.horizontalCenter
horizontalCenterOffset: - cancelButton.width / 2
top: parent.top
topMargin: 40
}
width: parent.width - cancelButton.width * 2
height: Math.max(instructionTxt.height, lock.height) + 2*row.anchors.margins
radius: 10
border.width: 2
border.color: "black"
color: 'white'
Row {
id: row
anchors {
fill: parent
margins: 10
}
Image {
id: lock
source: "qrc:/gcompris/src/activities/menu/resource/lock.svg"
sourceSize.width: 30 * ApplicationInfo.ratio
}
GCText {
id: instructionTxt
fontSize: mediumSize
color: "black"
style: Text.Outline
styleColor: "white"
horizontalAlignment: Text.AlignHCenter
width: parent.width - lock.width
wrapMode: TextEdit.WordWrap
z: 2
text: qsTr("This activity is only available in the full version of GCompris.")
}
}
Button {
width: instructionsArea.width * 0.9
height: 60 * ApplicationInfo.ratio
anchors {
horizontalCenter: parent.horizontalCenter
top: instructionsArea.bottom
topMargin: 10
}
text: qsTr("Buy the full version").toUpperCase()
style: GCButtonStyle {
theme: "highContrast"
}
onClicked: {
if(ApplicationSettings.isDemoMode)
ApplicationSettings.isDemoMode = false
}
}
}
MultiPointTouchArea {
// Just to catch mouse events
anchors.fill: parent
}
Keys.onEscapePressed: home()
Keys.onPressed: {
event.accepted = true
if (event.modifiers === Qt.ControlModifier &&
event.key === Qt.Key_Q) {
// Ctrl+Q exit the application
Core.quit(page);
} else if (event.modifiers === Qt.ControlModifier &&
event.key === Qt.Key_B) {
// Ctrl+B toggle the bar
ApplicationSettings.isBarHidden = !ApplicationSettings.isBarHidden;
} else if (event.modifiers === Qt.ControlModifier &&
event.key === Qt.Key_F) {
// Ctrl+F toggle fullscreen
ApplicationSettings.isFullscreen = !ApplicationSettings.isFullscreen
} else if (event.modifiers === Qt.ControlModifier &&
event.key === Qt.Key_M) {
// Ctrl+M toggle sound
ApplicationSettings.isAudioEffectsEnabled = !ApplicationSettings.isAudioEffectsEnabled
} else if (event.modifiers === Qt.ControlModifier &&
event.key === Qt.Key_W) {
// Ctrl+W exit the current activity
home()
}
}
// The cancel button
GCButtonCancel {
id: cancelButton
onClose: home()
}
}
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 799d0e41c..b0229178d 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -1,292 +1,357 @@
include(qt_helper)
configure_file(config.h.in "${CMAKE_CURRENT_BINARY_DIR}/config.h" @ONLY)
if(WITH_KIOSK_MODE)
add_definitions(-DWITH_KIOSK_MODE)
endif()
if(SAILFISHOS)
add_definitions(-DSAILFISHOS)
endif()
+if(ANDROID)
+ # needed since ECM 5.45 (https://bugs.kde.org/show_bug.cgi?id=394042)
+ include_directories(SYSTEM
+ "${CMAKE_SYSROOT}/usr/include"
+ )
+endif()
+
set(gcompris_SRCS
ActivityInfo.cpp
ActivityInfo.h
ActivityInfoTree.cpp
ActivityInfoTree.h
ApplicationInfo.cpp
ApplicationInfo.h
ApplicationSettings.cpp
ApplicationSettings.h
File.cpp
File.h
Directory.cpp
Directory.h
DownloadManager.cpp
DownloadManager.h
+ GComprisPlugin.cpp
+ GComprisPlugin.h
main.cpp
config.h.in
+ synth/ADSRenvelope.cpp
+ synth/ADSRenvelope.h
+ synth/GSynth.cpp
+ synth/GSynth.h
+ synth/linearSynthesis.cpp
+ synth/linearSynthesis.h
+ synth/modulation.cpp
+ synth/modulation.h
+ synth/generator.cpp
+ synth/generator.h
+ synth/preset.h
+ synth/preset.cpp
+ synth/waveform.cpp
+ synth/waveform.h
)
if(ANDROID)
list(APPEND gcompris_SRCS ApplicationAndroid.cpp)
else()
list(APPEND gcompris_SRCS ApplicationSettingsDefault.cpp ApplicationInfoDefault.cpp)
endif()
# Resources
set(GCOMPRIS_RESOURCES "${PROJECT_SOURCE_DIR}/installer")
if(CMAKE_HOST_WIN32)
set(gcompris_icon GCompris.ico)
set(gcompris_RES
${GCOMPRIS_RESOURCES}/${gcompris_icon}
GCompris.rc
)
elseif(CMAKE_HOST_APPLE)
set(gcompris_icon GCompris.icns)
set(gcompris_RES ${GCOMPRIS_RESOURCES}/${gcompris_icon})
set_source_files_properties(${gcompris_RES} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
endif()
set(used_qt_modules Qt5::Qml Qt5::Quick Qt5::Gui Qt5::Multimedia Qt5::Core Qt5::Svg Qt5::Xml Qt5::XmlPatterns Qt5::Sensors)
if(ANDROID)
add_library(${GCOMPRIS_EXECUTABLE_NAME} SHARED ${gcompris_SRCS})
set(used_qt_modules ${used_qt_modules} Qt5::AndroidExtras)
elseif(CMAKE_HOST_APPLE)
add_executable(${GCOMPRIS_EXECUTABLE_NAME} MACOSX_BUNDLE ${gcompris_SRCS} ${gcompris_RES})
elseif(CMAKE_HOST_WIN32)
add_executable(${GCOMPRIS_EXECUTABLE_NAME} WIN32 ${gcompris_SRCS} ${gcompris_RES})
elseif(SAILFISHOS)
add_executable(${GCOMPRIS_EXECUTABLE_NAME} ${gcompris_SRCS} ${gcompris_RES})
set(used_qt_modules ${used_qt_modules} Qt5::Widgets)
else()
add_executable(${GCOMPRIS_EXECUTABLE_NAME} ${gcompris_SRCS} ${gcompris_RES})
endif()
# only build the lib for testing purpose
if(BUILD_TESTING)
add_library(gcompris_core SHARED ${gcompris_SRCS})
target_link_libraries(gcompris_core ${used_qt_modules})
endif()
target_link_libraries(${GCOMPRIS_EXECUTABLE_NAME} ${used_qt_modules})
GCOMPRIS_ADD_RCC(core *.qml *.js resource/*.${COMPRESSED_AUDIO} resource/*.gif resource/*.png resource/*.svg resource/bonus/* resource/sounds/* resource/fonts/* qmldir COPYING)
# Installation
# ============
install(TARGETS ${GCOMPRIS_EXECUTABLE_NAME}
ARCHIVE DESTINATION bin
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
BUNDLE DESTINATION .)
if(BUILD_STANDALONE)
# Qt plugins to install
set(_qt_plugins "")
if(NOT SAILFISHOS)
list(APPEND _qt_plugins Qt5::QJpegPlugin)
endif()
if(APPLE)
- list(APPEND _qt_plugins Qt5::QTgaPlugin Qt5::QTiffPlugin)
+ list(APPEND _qt_plugins Qt5::QTgaPlugin Qt5::QTiffPlugin Qt5::QCocoaIntegrationPlugin)
elseif(WIN32)
list(APPEND _qt_plugins Qt5::QWindowsIntegrationPlugin Qt5::QWindowsAudioPlugin Qt5::AudioCaptureServicePlugin Qt5::DSServicePlugin)
elseif(UNIX AND NOT ANDROID AND NOT SAILFISHOS)
- list(APPEND _qt_plugins Qt5::QXcbIntegrationPlugin Qt5::QXcbEglIntegrationPlugin Qt5::QXcbGlxIntegrationPlugin)
+ list(APPEND _qt_plugins Qt5::QXcbIntegrationPlugin Qt5::QXcbEglIntegrationPlugin Qt5::QXcbGlxIntegrationPlugin Qt5::QAlsaPlugin Qt5::QPulseAudioPlugin)
endif()
list(APPEND _qt_plugins Qt5::genericSensorPlugin Qt5::QtSensorGesturePlugin Qt5::QShakeSensorGesturePlugin)
# Qml plugins to install
if(WIN32)
set(_lib_prefix "")
else()
set(_lib_prefix "lib")
endif()
set(_qt_plugins2 imageformats/${_lib_prefix}qsvg)
if(UNIX AND NOT ANDROID AND NOT APPLE AND NOT SAILFISHOS)
list(APPEND _qt_plugins2 mediaservice/${_lib_prefix}gstaudiodecoder
mediaservice/${_lib_prefix}gstcamerabin
mediaservice/${_lib_prefix}gstmediacapture
mediaservice/${_lib_prefix}gstmediaplayer)
elseif(APPLE)
- list(APPEND _qt_plugins2 mediaservice/${_lib_prefix}qavfmediaplayer
+ list(APPEND _qt_plugins2 audio/${_lib_prefix}qtaudio_coreaudio
+ mediaservice/${_lib_prefix}qavfmediaplayer
mediaservice/${_lib_prefix}qtmedia_audioengine
mediaservice/${_lib_prefix}qavfcamera)
endif()
set(_qml_plugins
+ QtGraphicalEffects/${_lib_prefix}qtgraphicaleffectsplugin
+ QtGraphicalEffects/private/${_lib_prefix}qtgraphicaleffectsprivate
QtQuick/Window.2/${_lib_prefix}windowplugin
QtQuick/Particles.2/${_lib_prefix}particlesplugin
QtQuick.2/${_lib_prefix}qtquick2plugin
QtMultimedia/${_lib_prefix}declarative_multimedia
QtSensors/${_lib_prefix}declarative_sensors)
if(NOT SAILFISHOS)
list(APPEND _qml_plugins
QtQuick/Controls/${_lib_prefix}qtquickcontrolsplugin
QtQuick/Layouts/${_lib_prefix}qquicklayoutsplugin)
endif()
set(GCOMPRIS_OTHER_LIBS)
if(APPLE)
set(_app gcompris-qt.app)
set(_qtconf_destdir ${_app}/Contents/Resources)
set(_qt_plugins_destdir ${_app}/Contents/plugins)
set(_qt_qml_destdir ${_app}/Contents/qml)
set(GCOMPRIS_BUNDLE "\${CMAKE_INSTALL_PREFIX}/${_app}")
set_target_properties(gcompris-qt PROPERTIES
MACOSX_BUNDLE_INFO_STRING "GCompris, Educational game for children 2 to 10"
MACOSX_BUNDLE_ICON_FILE "${gcompris_icon}"
MACOSX_BUNDLE_GUI_IDENTIFIER "net.gcompris"
MACOSX_BUNDLE_LONG_VERSION_STRING "${GCOMPRIS_MAJOR_VERSION}.${GCOMPRIS_MINOR_VERSION}.${GCOMPRIS_PATCH_VERSION}"
MACOSX_BUNDLE_BUNDLE_NAME "gcompris-qt"
MACOSX_BUNDLE_SHORT_VERSION_STRING "${GCOMPRIS_VERSION}"
MACOSX_BUNDLE_BUNDLE_VERSION "${GCOMPRIS_VERSION}"
- MACOSX_BUNDLE_COPYRIGHT "GPL License, Copyright 2000-2015 Bruno Coudoin and Others.")
+ MACOSX_BUNDLE_COPYRIGHT "GPL License, Copyright 2000-2019 Timothee Giet and Others.")
set_source_files_properties(${GCOMPRIS_RESOURCES}/${gcompris_icon} PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
else()
set(_qtconf_destdir bin)
set(_qt_plugins_destdir bin/plugins)
set(_qt_qml_destdir bin/qml)
if(CMAKE_HOST_WIN32)
set(GCOMPRIS_BUNDLE "\${CMAKE_INSTALL_PREFIX}/bin/${GCOMPRIS_EXECUTABLE_NAME}.exe")
else()
set(GCOMPRIS_BUNDLE "\${CMAKE_INSTALL_PREFIX}/bin/${GCOMPRIS_EXECUTABLE_NAME}")
endif()
endif()
# install qt.conf file
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/qt.conf DESTINATION ${_qtconf_destdir})
# install qt plugins
foreach(_plugin ${_qt_plugins})
installQtPlugin(${_plugin} ${_qt_plugins_destdir} _lib)
list(APPEND GCOMPRIS_OTHER_LIBS ${_lib})
endforeach()
foreach(_plugin ${_qt_plugins2})
- installQtPlugin2(${_plugin} ${_qt_plugins_destdir} _lib)
+ if(APPLE)
+ installQtPlugin2(${_plugin} ${_qt_plugins_destdir}/../Plugins _lib)
+ else()
+ installQtPlugin2(${_plugin} ${_qt_plugins_destdir} _lib)
+ endif()
list(APPEND GCOMPRIS_OTHER_LIBS ${_lib})
endforeach()
# install qml plugins
foreach(_plugin ${_qml_plugins})
installQmlPlugin(${_plugin} ${_qt_qml_destdir} _lib)
list(APPEND GCOMPRIS_OTHER_LIBS ${_lib})
endforeach()
- # install QtGraphicalEffects (which is not a lib but only qml files)
- set(_qml_subdir QtGraphicalEffects)
- getQtQmlPath(_qt_qml_path)
- install(DIRECTORY ${_qt_qml_path}/QtGraphicalEffects DESTINATION ${_qt_qml_destdir})
+ ## install QtGraphicalEffects (which is not a lib but only qml files)
+ # BUT, actually there are some libs in it, and this does not work on APPLE. Moved to _qml_plugins instead
+ #
+ #set(_qml_subdir QtGraphicalEffects)
+ #getQtQmlPath(_qt_qml_path)
+ #install(DIRECTORY ${_qt_qml_path}/QtGraphicalEffects DESTINATION ${_qt_qml_destdir})
- # Fix for Linux 'make package' that fails to link with libicu
+ # Fix for Linux 'make package' that fails to link with libicu; also package OpenSSL libs from system
if(UNIX AND NOT APPLE AND NOT SAILFISHOS AND NOT ANDROID)
add_library( libicudata SHARED IMPORTED )
FILE(GLOB LIBICUDATA_SO "${Qt5_DIR}/../../libicudata.so.[0-9][0-9]")
if ("${LIBICUDATA_SO}" STREQUAL "")
FILE(GLOB LIBICUDATA_SO "/usr/lib/*/libicudata.so.[0-9][0-9]")
endif()
set_target_properties( libicudata PROPERTIES IMPORTED_LOCATION ${LIBICUDATA_SO} )
add_library( libicui18n SHARED IMPORTED )
FILE(GLOB LIBICUI18N_SO "${Qt5_DIR}/../../libicui18n.so.[0-9][0-9]")
if ("${LIBICUI18N_SO}" STREQUAL "")
FILE(GLOB LIBICUI18N_SO "/usr/lib/*/libicui18n.so.[0-9][0-9]")
endif()
set_target_properties( libicui18n PROPERTIES IMPORTED_LOCATION ${LIBICUI18N_SO} )
add_library( libicuuc SHARED IMPORTED )
FILE(GLOB LIBICUUC_SO "${Qt5_DIR}/../../libicuuc.so.[0-9][0-9]")
if ("${LIBICUUC_SO}" STREQUAL "")
FILE(GLOB LIBICUUC_SO "/usr/lib/*/libicuuc.so.[0-9][0-9]")
endif()
set_target_properties( libicuuc PROPERTIES IMPORTED_LOCATION ${LIBICUUC_SO} )
TARGET_LINK_LIBRARIES(${GCOMPRIS_EXECUTABLE_NAME} libicudata libicui18n libicuuc)
+ # package installed OpenSSL libraries
+ install(FILES "${OPENSSL_SSL_LIBRARY}" DESTINATION bin)
+ install(FILES "${OPENSSL_CRYPTO_LIBRARY}" DESTINATION bin)
+ install(FILES "${OPENSSL_SSL_LIBRARY}.10" DESTINATION bin)
+ install(FILES "${OPENSSL_CRYPTO_LIBRARY}.10" DESTINATION bin)
+ install(FILES "${OPENSSL_SSL_LIBRARY}.1.0.2k" DESTINATION bin)
+ install(FILES "${OPENSSL_CRYPTO_LIBRARY}.1.0.2k" DESTINATION bin)
+ TARGET_LINK_LIBRARIES(${GCOMPRIS_EXECUTABLE_NAME} OpenSSL::SSL OpenSSL::Crypto)
endif()
+
+ #Add OpenSSL support on Windows builds
+ if(WIN32)
+ if(MINGW)
+ if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ #64bit
+ set(OPENSSL_DLL_SUFFIX "-x64")
+ endif()
+ install(FILES "${Qt5_DIR}/../../../bin/libcrypto-1_1${OPENSSL_DLL_SUFFIX}.dll" DESTINATION bin)
+ install(FILES "${Qt5_DIR}/../../../bin/libssl-1_1${OPENSSL_DLL_SUFFIX}.dll" DESTINATION bin)
+ else(MINGW) # appveyor
+ install(FILES "${OPENSSL_INCLUDE_DIR}/../libeay32.dll" DESTINATION bin)
+ install(FILES "${OPENSSL_INCLUDE_DIR}/../libssl32.dll" DESTINATION bin)
+ install(FILES "${OPENSSL_INCLUDE_DIR}/../ssleay32.dll" DESTINATION bin)
+ endif()
+ target_link_libraries(${GCOMPRIS_EXECUTABLE_NAME} OpenSSL::SSL OpenSSL::Crypto)
+ endif()
+
endif(BUILD_STANDALONE)
# Hack: do not fixup Qt and Qml plugins on Windows because fixup_bundle takes ages (cmake bug ?) -> Johnny : we need this even if it takes time because some required dependencies are pulled here
#if(WIN32) set(GCOMPRIS_OTHER_LIBS "") endif()
# install fixup_bundle script to resolve and fixup runtime dependencies
-if(BUILD_STANDALONE)
+if(BUILD_STANDALONE AND NOT ANDROID)
configure_file(${CMAKE_SOURCE_DIR}/cmake/FixBundle.cmake.in FixBundle.cmake)
install(SCRIPT ${CMAKE_CURRENT_BINARY_DIR}/FixBundle.cmake)
# install a startup script for linux bundle
if(UNIX AND NOT APPLE AND NOT SAILFISHOS)
install(PROGRAMS ../../tools/gcompris-qt.sh DESTINATION bin)
endif()
endif()
if(WIN32 AND NOT MINGW)
# install libEGL.dll, libGLESv2.dll, d3dcompiler_47.dll from Qt installation. Not sure if there is a clean way to get them...
# Qt5_Dir is like C:/Qt/Qt5.5.1/5.5/mingw492_32/lib/cmake/Qt5
install(FILES ${Qt5_DIR}/../../../bin/libEGL.dll DESTINATION bin)
install(FILES ${Qt5_DIR}/../../../bin/libGLESv2.dll DESTINATION bin)
install(FILES ${Qt5_DIR}/../../../bin/d3dcompiler_47.dll DESTINATION bin)
target_link_libraries(${GCOMPRIS_EXECUTABLE_NAME} ${Qt5_DIR}/../../libEGL.lib)
target_link_libraries(${GCOMPRIS_EXECUTABLE_NAME} ${Qt5_DIR}/../../libGLESv2.lib)
install(FILES ${Qt5_DIR}/../../../bin/opengl32sw.dll DESTINATION bin)
# CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS contains visual c++ libraries
install(FILES ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS} DESTINATION bin)
endif()
# Packaging
# =========
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "GCompris is a high quality educational software suite, including a large number of activities for children aged 2 to 10.")
set(CPACK_PACKAGE_VERSION_MAJOR ${GCOMPRIS_MAJOR_VERSION})
set(CPACK_PACKAGE_VERSION_MINOR ${GCOMPRIS_MINOR_VERSION})
set(CPACK_PACKAGE_VERSION_PATCH ${GCOMPRIS_PATCH_VERSION})
set(CPACK_PACKAGE_VERSION ${GCOMPRIS_VERSION})
set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/COPYING")
set(CPACK_RESOURCE_FILE_README "${PROJECT_SOURCE_DIR}/README")
if(WIN32)
set(CPACK_PACKAGE_INSTALL_DIRECTORY "${GCOMPRIS_EXECUTABLE_NAME}-Qt")
set(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "${GCOMPRIS_EXECUTABLE_NAME}-Qt")
set(CPACK_PACKAGE_ICON "${PROJECT_SOURCE_DIR}/installer\\\\gcompris-header.bmp")
set(CPACK_NSIS_MUI_ICON "${PROJECT_SOURCE_DIR}/installer\\\\GCompris-install.ico")
set(CPACK_NSIS_MUI_UNIICON "${PROJECT_SOURCE_DIR}/installer\\\\GCompris-uninstall.ico")
set(CPACK_NSIS_EXECUTABLES_DIRECTORY "bin")
set(CPACK_PACKAGE_EXECUTABLES "${GCOMPRIS_EXECUTABLE_NAME};GCompris")
set(CPACK_CREATE_DESKTOP_LINKS "${GCOMPRIS_EXECUTABLE_NAME};GCompris")
- set(CPACK_NSIS_URL_INFO_ABOUT "http:\\\\\\\\gcompris.net")
+ set(CPACK_NSIS_URL_INFO_ABOUT "https:\\\\\\\\gcompris.net")
set(CPACK_NSIS_DISPLAY_NAME "GCompris Educational Software")
set(CPACK_NSIS_MUI_FINISHPAGE_RUN "${GCOMPRIS_EXECUTABLE_NAME}")
+ set(CPACK_PACKAGE_VENDOR "GCompris team")
+
+ # Create shortcuts in menu to be able to launch in software or opengl mode
+ list(APPEND CPACK_NSIS_CREATE_ICONS_EXTRA " CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\GCompris (Safe Mode).lnk' '$INSTDIR\\\\bin\\\\${GCOMPRIS_EXECUTABLE_NAME}.exe' '--software-renderer'")
+ list(APPEND CPACK_NSIS_CREATE_ICONS_EXTRA " CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\GCompris.lnk' '$INSTDIR\\\\bin\\\\${GCOMPRIS_EXECUTABLE_NAME}.exe' '--opengl-renderer'")
+ string (REPLACE ";" "\n" CPACK_NSIS_CREATE_ICONS_EXTRA "${CPACK_NSIS_CREATE_ICONS_EXTRA}")
+
else(WIN32)
set(CPACK_PACKAGE_ICON "${PROJECT_SOURCE_DIR}/GCompris64.png")
endif()
if(APPLE)
set(CPACK_GENERATOR "DragNDrop")
set(CPACK_DMG_DS_STORE "${GCOMPRIS_RESOURCES}/dmg_DS_Store")
set(CPACK_DMG_BACKGROUND_IMAGE "${GCOMPRIS_RESOURCES}/dmg_background.png")
elseif(WIN32)
set(CPACK_GENERATOR "NSIS")
elseif(SAILFISHOS)
configure_file(${PROJECT_SOURCE_DIR}/platforms/sailfishOS/harbour-gcompris-qt.spec.cmake ${CMAKE_BINARY_DIR}/harbour-gcompris-qt.spec @ONLY)
install(FILES ${PROJECT_SOURCE_DIR}/platforms/sailfishOS/harbour-gcompris-qt.desktop DESTINATION share/applications)
install(FILES ${PROJECT_SOURCE_DIR}/platforms/sailfishOS/harbour-gcompris-qt.png DESTINATION share/icons/hicolor/86x86/apps)
set(CPACK_RPM_PACKAGE_SUMMARY "gcompris-qt")
# BUILD_ARCH is either armv7hl or i486
set(CPACK_RPM_PACKAGE_ARCHITECTURE "${BUILD_ARCH}")
set(CPACK_RPM_PACKAGE_NAME "${GCOMPRIS_EXECUTABLE_NAME}")
set(CPACK_RPM_PACKAGE_VERSION "${GCOMPRIS_VERSION}")
set(CPACK_RPM_PACKAGE_LICENSED "GPLv3")
set(CPACK_RPM_PACKAGE_URL "https://www.gcompris.org")
set(CPACK_RPM_PACKAGE_DESCRIPTION "GCompris is a high quality educational software suite comprising of numerous activities for children aged 2 to 10.")
set(CPACK_RPM_USER_BINARY_SPECFILE "${CMAKE_BINARY_DIR}/harbour-gcompris-qt.spec")
set(CMAKE_INSTALL_PREFIX "/usr")
set(CPACK_PACKAGING_INSTALL_PREFIX "/usr")
set(CPACK_GENERATOR "RPM")
else()
set(CPACK_GENERATOR "STGZ")
endif()
include(CPack)
diff --git a/src/core/ChangeLog.qml b/src/core/ChangeLog.qml
index ae90b4935..87b22d852 100644
--- a/src/core/ChangeLog.qml
+++ b/src/core/ChangeLog.qml
@@ -1,89 +1,96 @@
/* GCompris - ChangeLog.qml
*
* Copyright (C) 2016 Johnny Jazeix <jazeix@gmail.com>
*
* Authors:
* Johnny Jazeix <jazeix@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
/**
* Container object with a list of all the changes by version.
* @ingroup infrastructure
*
*/
QtObject {
/**
* type: list
* List of changelog objects.
*
* A changelog object consists of the properties @c versionCode
* and an optional @c content (which changes have been added in this version).
* The activities added in this version are retrieved from the ActivityInfoTree and directly displayed.
*
*/
property var changelog: [
- { "versionCode": 9100, "content": qsTr("Many little fixes and improvements. Translations added for Scottish Gaelic.") },
- { "versionCode": 9000, "content": qsTr("License page added in configuration. Multiple changes on layouts to improve the ergonomy.") },
- { "versionCode": 8000, "content": qsTr("Lang activity now available in Polish, Swedish and Ukrainian.") },
- { "versionCode": 7000, "content": qsTr("Search feature.") },
- { "versionCode": 6000, "content": qsTr("A Changelog.") },
- { "versionCode": 5200, "content": qsTr("Many little fixes. Lang activity now available in French.") },
- { "versionCode": 5000, "content": qsTr("Adding a loading overlay to let the user know that some actions are taking place (loading an activity for example) and can take some seconds. Translations added for: Catalan (Valencian), Chinese Traditional, Finnish (92% translated), Russian (98% translated), Slovak (92% translated), Turkish.") },
- { "versionCode": 4000, "content": qsTr("Translations added for: Slovenian, German, Galician.") }
+
+ { "versionCode": 9600, "content": [qsTr("Translation updated for multiple languages (Breton, Brazilian Portuguese, Finnish...)."),
+ qsTr("Add Russian dataset for Click on letter activity."),
+qsTr("Lang activity now available in Dutch.")] },
+ { "versionCode": 9500, "content": [qsTr("Merge Norwegian counties Nord-Trøndelag and Sør-Trøndelag into Trøndelag in geo-country activity."),
+ qsTr("Fix in braille activities where the cells start at 1, not 0."),
+ qsTr("Translation added for Basque, Hungarian and Malayalam."),
+ qsTr("Loading/saving of creations (Baby Wordprocessor, Balance Box and Piano Composition).")] },
+ { "versionCode": 9100, "content": [qsTr("Many little fixes and improvements."), qsTr("Translations added for Scottish Gaelic.")] },
+ { "versionCode": 9000, "content": [qsTr("License page added in configuration."), qsTr("Multiple changes on layouts to improve the ergonomy.")] },
+ { "versionCode": 8000, "content": [qsTr("Lang activity now available in Polish, Swedish and Ukrainian.")] },
+ { "versionCode": 7000, "content": [qsTr("Search feature.")] },
+ { "versionCode": 6000, "content": [qsTr("A Changelog.")] },
+ { "versionCode": 5200, "content": [qsTr("Many little fixes."), qsTr("Lang activity now available in French.")] },
+ { "versionCode": 5000, "content": [qsTr("Adding a loading overlay to let the user know that some actions are taking place (loading an activity for example) and can take some seconds."), qsTr("Translations added for: Catalan (Valencian), Chinese Traditional, Finnish (92% translated), Russian (98% translated), Slovak (92% translated), Turkish.")] },
+ { "versionCode": 4000, "content": [qsTr("Translations added for: Slovenian, German, Galician.")] }
]
function isNewerVersion(previousVersion, newVersion) {
return newVersion > previousVersion
}
function getLogBetween(previousVersion, newVersion) {
var filtered = changelog.filter(function filter(obj) {
return isNewerVersion(previousVersion, obj['versionCode'])
});
var output = "";
// Retrieve all the activities created between the two versions
ActivityInfoTree.filterCreatedWithinVersions(previousVersion, newVersion);
var activities = ActivityInfoTree.menuTree;
// display for each version an optional text ("content") then the new activities
filtered.map(function filter(obj) {
obj['versionCode'];
var version = (obj['versionCode'] / 10000).toFixed(2);
output += "<b>" + qsTr("Version %1:").arg(version) + "</b>";
output += "<ul>";
// display free text if exist
- if(obj['content']) {
- output += "<li>" + obj['content'] + "</li>";
- }
+ for(var i = 0; i < obj['content'].length; i++)
+ output += "<li>" + obj['content'][i] + "</li>";
// display the activity titles
for(var i in activities) {
var activity = activities[i];
if(activity.createdInVersion == obj['versionCode'] && activity.enabled) {
output += "<li>" + activity.title + "</li>";
}
}
output += "</ul>";
});
// restore menu context
ActivityInfoTree.filterByTag("favorite")
ActivityInfoTree.filterLockedActivities()
ActivityInfoTree.filterEnabledActivities()
return output
}
}
diff --git a/src/core/DialogAbout.qml b/src/core/DialogAbout.qml
index 3cd6dc1ff..c45c3c0c8 100644
--- a/src/core/DialogAbout.qml
+++ b/src/core/DialogAbout.qml
@@ -1,153 +1,153 @@
/* GCompris - DialogAbout.qml
*
* Copyright (C) 2016 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import QtQuick.Controls 1.5
import GCompris 1.0
/**
* GCompris' full screen about dialog.
* @ingroup infrastructure
*
* @sa DialogBackground
*/
DialogBackground {
visible: false
title: qsTr("About GCompris")
button0Text: qsTr("License")
onButton0Hit: { licenseContainer.visible = true }
File {
id: licenseFile
name: "qrc:/gcompris/src/core/COPYING"
onError: print(msg)
}
DialogBackground {
id: licenseContainer
visible: false
anchors.fill: parent
title: qsTr("License")
onVisibleChanged: {
if(!content) {
content = licenseFile.read()
}
}
onClose: visible = false
}
//: Replace this string with your names, one name per line.
property string translators: qsTr("translator-credits") ===
"translator-credits" ? "" : qsTr("translator-credits") + "<br/>"
// Let's try to maitain here the contributor list sorted by number of commits
// git shortlog -se | sort -nr | cut -c8- | sed 's/ <.*>/,/' | xargs
- property string developers: "Bruno Coudoin, Johnny Jazeix, Timothée Giet, Holger Kaelberer, Rajdeep Kaur, siddhesh suthar, Akshat Tandon, Aruna Sankaranarayanan, Thibaut ROMAIN, Stephane Mankowski, Amit Tomar, Yuri Chornoivan, Ilya Bizyaev, Amit Sagtani, Stefan Toncu, Aman Kumar Gupta, Divyam Madaan, SagarC Agarwal, Ayush Agrawal, Rudra Nil Basu, Manuel Tondeur, Pulkit Gupta, Burkhard Lück, Ganesh Harshan, Bharath M S, Horia PELLE, Harry Mecwan, Antoni Bella Pérez, Emmanuel Charruau, Per Andersson, JB BUTET, Rohit Das, Karl Ove Hufthammer, Arkit Vora, Sergey Popov, Nitish Chauhan, Imran Tatriev, Harpreet S, Aleix Pol, Antos Vaclauski, rahul yadav, Himanshu Vishwakarma, Aseem Arora, Souradeep Barua, Parth Partani, Paolo Gibellini, Luciano Montanaro, Luigi Toscano, B.J. Cupps, Utkarsh Tiwari, Harald H, Chaitanya KS, Alexander Potashev, Anu Mittal, André Marcelo Alvarenga, Alexis Breton, Ynon Perek, Yask Srivastava, Hannah von Reth, Sayan Biswas, Stefan Asserhäll, Shashwat Dixit, Séamus Ó Briain, Rishabh Gupta, Răpițeanu Viorel-Cătălin, Rajat Asthana, Mantas Kriaučiūnas, Łukasz Wojniłowicz, Jose Riha, Jiri Bohac, Djalil Mesli, Artur Puzio, Andrey Cygankov, Arnold Dumas, Clément Coudoin"
+ property string developers: "Bruno Coudoin, Johnny Jazeix, Timothée Giet, Holger Kaelberer, Akshat Tandon, Rajdeep Kaur, siddhesh suthar, Aruna Sankaranarayanan, Aman Kumar Gupta, Stephane Mankowski, Amit Tomar, Yuri Chornoivan, Thibaut ROMAIN, Amit Sagtani, Ilya Bizyaev, Stefan Toncu, SagarC Agarwal, Ganesh Harshan, Divyam Madaan, Ayush Agrawal, Rudra Nil Basu, Harry Mecwan, Pulkit Gupta, Manuel Tondeur, Karl Ove Hufthammer, Burkhard Lück, Horia PELLE, Bharath M S, Per Andersson, JB BUTET, Himanshu Vishwakarma, Emmanuel Charruau, Rohit Das, Arkit Vora, Antoni Bella Pérez, Sergey Popov, Séamus Ó Briain, Nitish Chauhan, Imran Tatriev, Harpreet S, Harald H, Alexis Breton, Aleix Pol, Rajat Asthana, rahul yadav, Aseem Arora, Akshay Kumar, Utkarsh Tiwari, Souradeep Barua, Parth Partani, Paolo Gibellini, Nick Richards, Luigi Toscano, Luciano Montanaro, Chaitanya KS, B.J. Cupps, Anu Mittal, Antos Vaclauski, André Marcelo Alvarenga, Alexander Potashev, Ynon Perek, Yask Srivastava, Stefan Asserhäll, Shashwat Dixit, Sayan Biswas, Rishabh Gupta, Răpițeanu Viorel-Cătălin, Mantas Kriaučiūnas, Łukasz Wojniłowicz, Jose Riha, Jonathan Demeyer, Jiri Bohac, Hannah von Reth, Djalil Mesli, Clément Coudoin, Billy Laws, Artur Puzio, Arnold Dumas, Antoś Vaclaŭski, Andrey Cygankov"
property string gcVersion: ApplicationInfo.GCVersion
property string qtVersion: ApplicationInfo.QTVersion
property string gcVersionTxt: qsTr("GCompris %1").arg(gcVersion)
property string qtVersionTxt: qsTr("Based on Qt %1").arg(qtVersion)
content:
- "<center><b>" + "<a href='http://gcompris.net'>" +
- qsTr("GCompris Home Page: http://gcompris.net") + "</a>" +
+ "<center><b>" + "<a href='https://gcompris.net'>" +
+ qsTr("GCompris Home Page: https://gcompris.net") + "</a>" +
"</b></center>" +
"<center>" + gcVersionTxt + " " + qtVersionTxt + "</center>" + "<br/>" +
"<img align='right' width='" + 320 * ApplicationInfo.ratio +
"' height='" + 114 * ApplicationInfo.ratio + "' src='qrc:/gcompris/src/core/resource/gcompris.png'/>" +
qsTr("<b>GCompris</b> is a Free Software developed within the KDE community.") +
"<br /> <br />" +
qsTr("<b>KDE</b> is a world-wide network of software engineers, artists, writers, translators and facilitators " +
"who are committed to <a href=\"%1\">Free Software</a> development. " +
"This community has created hundreds of Free Software applications as part of the KDE " +
"frameworks, workspaces and applications.<br /><br />" +
"KDE is a cooperative enterprise in which no single entity controls the " +
"efforts or products of KDE to the exclusion of others. Everyone is welcome to join and " +
"contribute to KDE, including you.<br /><br />" +
"Visit <a href=\"%2\">%2</a> for " +
"more information about the KDE community and the software we produce.")
- .arg("http://www.gnu.org/philosophy/free-sw.html")
- .arg("http://www.kde.org/") +
+ .arg("https://www.gnu.org/philosophy/free-sw.html")
+ .arg("https://www.kde.org/") +
"<img align='right' width='" + 138 * ApplicationInfo.ratio +
"' height='" + 202 * ApplicationInfo.ratio + "' src='qrc:/gcompris/src/core/resource/aboutkde.png'/>" +
"<br /> <br />" +
qsTr("Software can always be improved, and the KDE team is ready to " +
"do so. However, you - the user - must tell us when " +
"something does not work as expected or could be done better.<br /><br />" +
"KDE has a bug tracking system. Visit " +
"<a href=\"%1\">%1</a> to report a bug.<br /><br />" +
"If you have a suggestion for improvement then you are welcome to use " +
"the bug tracking system to register your wish. Make sure you use the " +
"severity called \"Wishlist\".")
.arg("https://bugs.kde.org/") +
"<br /> <br />" +
qsTr("You do not have to be a software developer to be a member of the " +
"KDE team. You can join the national teams that translate " +
"program interfaces. You can provide graphics, themes, sounds, and " +
"improved documentation. You decide!" +
"<br /><br />" +
"Visit " +
"<a href=\"%1\">%1</a> " +
"for information on some projects in which you can participate." +
"<br /><br />" +
"If you need more information or documentation, then a visit to " +
"<a href=\"%2\">%2</a> " +
"will provide you with what you need.")
- .arg("http://www.kde.org/community/getinvolved/")
- .arg("http://techbase.kde.org/") +
+ .arg("https://www.kde.org/community/getinvolved/")
+ .arg("https://techbase.kde.org/") +
"<br /> <br />" +
qsTr("To support development the KDE community has formed the KDE e.V., a non-profit organization " +
"legally founded in Germany. KDE e.V. represents the KDE community in legal and financial matters. " +
"See <a href=\"%1\">%1</a>" +
" for information on KDE e.V.<br /><br />" +
"KDE benefits from many kinds of contributions, including financial. " +
"We use the funds to reimburse members and others for expenses " +
"they incur when contributing. Further funds are used for legal " +
"support and organizing conferences and meetings. <br /> <br />" +
"We would like to encourage you to support our efforts with a " +
"financial donation, using one of the ways described at " +
"<a href=\"%2\">%2</a>." +
"<br /><br />Thank you very much in advance for your support.")
- .arg("http://ev.kde.org/")
- .arg("http://www.kde.org/community/donations/") +
+ .arg("https://ev.kde.org/")
+ .arg("https://www.kde.org/community/donations/") +
"<br /> <br />" +
qsTr("<b>A big thanks to the development team:</b> %1").arg(developers) +
"<br /> <br />" +
qsTr("<b>A big thanks to the translation team:</b> %1")
.arg(translators) +
"<br/><center><b>" + "Copyright 2000-2018 Timothée Giet and Others" + "</b></center>" + "<br/>"
}
diff --git a/src/core/DialogActivityConfig.qml b/src/core/DialogActivityConfig.qml
index 205b916af..c230c1d8e 100644
--- a/src/core/DialogActivityConfig.qml
+++ b/src/core/DialogActivityConfig.qml
@@ -1,249 +1,249 @@
/* GCompris - DialogActivityConfig.qml
*
* Copyright (C) 2014 Johnny Jazeix <jazeix@gmail.com>
*
* Authors:
* Johnny Jazeix <jazeix@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
/**
* A QML component for a full screen configuration dialog.
* @ingroup components
*
* All user editable settings are presented to the user in a
* DialogActivityConfig dialog. The global configuration can be accessed
* through the Bar in the main menu, activity specific configuration from the
* respective activity.
*
* All config items that are shown in this dialog are persisted
* using ApplicationSettings.
*
* For an example have a look at Menu.qml.
*
* For more details on how to add configuration to an activity cf.
- * [the wiki](http://gcompris.net/wiki/Qt_Quick_development_process#Adding_a_configuration_for_a_specific_activity)
+ * [the wiki](https://gcompris.net/wiki/Qt_Quick_development_process#Adding_a_configuration_for_a_specific_activity)
*
* @sa ApplicationSettings
* @inherit QtQuick.Item
*/
Rectangle {
id: dialogActivityContent
visible: false
/* Public interface: */
/**
* type:object
* The content object as loaded dynamically.
*/
property alias configItem: loader.item
/**
* type:Component
* Content component which holds the visual presentation of the
* config settings in the QML scene.
*/
property Component content
/**
* type:string
* The name of the activity in case of per-activity config.
*
* Will be autogenerated unless set by the caller.
*/
property string activityName: ""
/**
* type:object
* Map containing all settings as key/value-pairs.
*
* Will be populated from ApplicationSettings.loadActivityConfiguration
* and can be passed to ApplicationSettings.saveActivityConfiguration.
*/
property var dataToSave
property var dataValidationFunc: null
/// @cond INTERNAL_DOCS
property bool isDialog: true
/**
* type:string
* Title of the configuration dialog.
* Global configuration name is "Configuration".
* For activities, it is "activity name configuration".
*/
readonly property string title: {
if(activityName != "")
qsTr("%1 configuration").arg(activityInfo.title)
else
qsTr("Configuration")
}
property alias active: loader.active
property alias loader: loader
property QtObject activityInfo: ActivityInfoTree.currentActivity
property ActivityBase currentActivity
/// @endcond
/**
* Emitted when the config dialog has been closed.
*/
signal close
/**
* Emitted when the config dialog has been started.
*/
signal start
/**
* Emitted when the settings are to be saved.
*
* The actual persisting of the settings in the settings file is done by
* DialogActivityConfig. The activity has to take care to update its
* internal state.
*/
signal saveData
/**
* Emitted when the config settings have been loaded.
*/
signal loadData
signal stop
color: "#696da3"
border.color: "black"
border.width: 1
function getInitialConfiguration() {
if(activityName == "") {
activityName = activityInfo.name.split('/')[0];
}
dataToSave = ApplicationSettings.loadActivityConfiguration(activityName)
loadData()
}
function saveDatainConfiguration() {
saveData()
ApplicationSettings.saveActivityConfiguration(activityName, dataToSave)
}
Row {
visible: dialogActivityContent.active
spacing: 2
Item { width: 10; height: 1 }
Column {
spacing: 10
anchors.top: parent.top
Item { width: 1; height: 10 }
Rectangle {
color: "#e6e6e6"
radius: 6.0
width: dialogActivityContent.width - 30
height: title.height * 1.2
border.color: "black"
border.width: 2
Row {
spacing: 2
padding: 8
Image {
id: titleIcon
anchors {
left: parent.left
top: parent.top
margins: 4 * ApplicationInfo.ratio
}
}
GCText {
id: title
text: dialogActivityContent.title
width: dialogActivityContent.width - (30 + cancel.width)
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
color: "black"
fontSize: 20
font.weight: Font.DemiBold
wrapMode: Text.WordWrap
}
}
}
Rectangle {
color: "#e6e6e6"
radius: 6.0
width: dialogActivityContent.width - 30
height: dialogActivityContent.height - (30 + title.height * 1.2)
border.color: "black"
border.width: 2
anchors.margins: 100
Flickable {
id: flick
anchors.margins: 8
anchors.fill: parent
flickableDirection: Flickable.VerticalFlick
clip: true
contentHeight: contentItem.childrenRect.height + 40 * ApplicationInfo.ratio
Loader {
id: loader
active: false
sourceComponent: dialogActivityContent.content
property alias rootItem: dialogActivityContent
}
}
// The scroll buttons
GCButtonScroll {
anchors.right: parent.right
anchors.rightMargin: 5 * ApplicationInfo.ratio
anchors.bottom: flick.bottom
anchors.bottomMargin: 5 * ApplicationInfo.ratio
onUp: flick.flick(0, 1400)
onDown: flick.flick(0, -1400)
upVisible: flick.visibleArea.yPosition <= 0 ? false : true
downVisible: flick.visibleArea.yPosition + flick.visibleArea.heightRatio >= 1 ? false : true
}
}
Item { width: 1; height: 10 }
}
}
// The cancel button
GCButtonCancel {
id: cancel
onClose: {
if (dialogActivityContent.dataValidationFunc && !
dialogActivityContent.dataValidationFunc()) {
console.log("Configuration data is invalid, not saving!");
return;
}
saveData()
ApplicationSettings.saveActivityConfiguration(activityName, dataToSave)
parent.close()
}
}
}
diff --git a/src/core/DialogBackground.qml b/src/core/DialogBackground.qml
index a317f1fe8..a655e46a9 100644
--- a/src/core/DialogBackground.qml
+++ b/src/core/DialogBackground.qml
@@ -1,173 +1,173 @@
-/* GCompris - dialogBackground.qml
+/* GCompris - DialogBackground.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import QtQuick.Controls 1.5
import GCompris 1.0
/**
* Base QML component for all full screen dialog screens.
* @ingroup components
*
* Defines the general screen layout used by the following full screen
* dialog elements:
*
* DialogAbout, DialogHelp.
*
* For a general purpose dialog cf. GCDialog.
*
* @inherit QtQuick.Rectangle
*/
Rectangle {
id: dialogBackground
color: "#696da3"
border.color: "black"
border.width: 1
z: 1000
property bool isDialog: true
property string title
property alias titleIcon: titleIcon.source
property string content
property string contentIcon
property alias button0Text: button0.text
signal close
signal start
signal pause
signal play
signal stop
signal button0Hit
Row {
spacing: 2
Item { width: 10; height: 1 }
Column {
spacing: 10
anchors.top: parent.top
Item { width: 1; height: 10 }
Rectangle {
color: "#e6e6e6"
radius: 6.0
width: dialogBackground.width - 30
height: title.height * 1.2
border.color: "black"
border.width: 2
Row {
spacing: 2
padding: 8
Image {
id: titleIcon
}
GCText {
id: title
text: dialogBackground.title
width: dialogBackground.width - (70 + cancel.width)
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
color: "black"
fontSize: 20
font.weight: Font.DemiBold
wrapMode: Text.WordWrap
}
}
}
Rectangle {
color: "#e6e6e6"
radius: 6.0
width: dialogBackground.width - 30
height: dialogBackground.height - (30 + title.height * 1.2)
border.color: "black"
border.width: 2
anchors.margins: 100
Flickable {
id: flick
anchors.margins: 8
anchors.fill: parent
contentWidth: textContent.contentWidth
contentHeight: iconImage.height + textContent.contentHeight
flickableDirection: Flickable.VerticalFlick
clip: true
Button {
id: button0
visible: text != ""
onClicked: { dialogBackground.button0Hit() }
width: 150 * ApplicationInfo.ratio
height: visible ? 40 * ApplicationInfo.ratio : 0
anchors {
horizontalCenter: parent.horizontalCenter
top: parent.top
topMargin: 8
}
style: GCButtonStyle {
theme: "highContrast"
}
}
Image {
id: iconImage
source: contentIcon
visible: contentIcon != ""
width: 100 * ApplicationInfo.ratio
height: visible ? iconImage.width : 0
sourceSize.width: iconImage.width
sourceSize.height: iconImage.width
anchors.top: button0.bottom
anchors.horizontalCenter: parent.horizontalCenter
}
GCText {
id: textContent
text: style + "<body>" + content + "</body>"
width: flick.width
height: flick.height - button0.height
anchors.top: iconImage.bottom
fontSize: regularSize
wrapMode: TextEdit.Wrap
textFormat: TextEdit.RichText
property string style: "<HEAD><STYLE type='text/css'>A {color: black;}</STYLE></HEAD>"
}
}
// The scroll buttons
GCButtonScroll {
anchors.right: parent.right
anchors.rightMargin: 5 * ApplicationInfo.ratio
anchors.bottom: flick.bottom
anchors.bottomMargin: 5 * ApplicationInfo.ratio
onUp: flick.flick(0, 1400)
onDown: flick.flick(0, -1400)
upVisible: flick.visibleArea.yPosition <= 0 ? false : true
downVisible: flick.visibleArea.yPosition + flick.visibleArea.heightRatio >= 1 ? false : true
}
}
Item { width: 1; height: 10 }
}
}
// The cancel button
GCButtonCancel {
id: cancel
onClose: parent.close()
}
}
diff --git a/src/core/DialogHelp.qml b/src/core/DialogHelp.qml
index 5888ff017..2438d91b1 100644
--- a/src/core/DialogHelp.qml
+++ b/src/core/DialogHelp.qml
@@ -1,93 +1,93 @@
/* GCompris - DialogHelp.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
/**
* GCompris' full screen help dialog.
* @ingroup infrastructure
*
* Used in Menu.qml as well as all activities to show more detailed
* information like author, manual, difficulty etc. as defined in each
* activities ActivityInfo.qml
*
* The help screens for the activities are generated automatically by
* the core and are started via the 'help' button on the Bar.
*
* @sa Bar.helpClicked, BarEnumContent.help, DialogBackground, ActivityInfo
*/
DialogBackground {
visible: false
title: activityInfo.title
titleIcon: activityInfo.difficulty != 0 ? "qrc:/gcompris/src/core/resource/difficulty" +
activityInfo.difficulty + ".svg" : ""
property QtObject activityInfo: ActivityInfoTree.currentActivity
function getIcon() {
if(activityInfo.icon) {
return "qrc:/gcompris/src/activities/" + activityInfo.icon
}
return ""
}
function reformat(string) {
var text = string.replace(/^ (.*)\n/gm,'<ul><li>$1</li></ul>')
text = text.replace(/\n/gm,'<br/>')
return text
}
function getContent() {
var contentText = "<b>" + activityInfo.description + "</b>"
contentText += "<br/><br/>"
if(activityInfo.author) {
contentText += "<b>" + qsTr("Author:") + " </b>" + activityInfo.author
contentText += "<br/><br/>"
}
if(activityInfo.prerequisite) {
contentText += "<b>" + qsTr("Prerequisite:") + " </b>" + activityInfo.prerequisite
contentText += "<br/><br/>"
}
if(activityInfo.goal) {
var goal = reformat(activityInfo.goal)
contentText += "<b>" + qsTr("Goal:") + " </b>" + goal
contentText += "<br/><br/>"
}
if(activityInfo.manual) {
var manual = reformat(activityInfo.manual)
contentText += "<b>" + qsTr("Manual:") + " </b>" + manual
contentText += "<br/><br/>"
}
if(activityInfo.credit) {
contentText += "<b>" + qsTr("Credit:") + " </b>" + activityInfo.credit
contentText += "<br/><br/>"
}
if(activityInfo.section) {
contentText += "<b>" + qsTr("Section:") + " </b>" + activityInfo.section
contentText += " (" + activityInfo.name.split('/')[0] + ")"
contentText += "<br/><br/>"
}
return contentText
}
contentIcon: getIcon()
content: getContent()
}
diff --git a/src/core/Directory.cpp b/src/core/Directory.cpp
index 7410c2198..ba768f1be 100644
--- a/src/core/Directory.cpp
+++ b/src/core/Directory.cpp
@@ -1,39 +1,33 @@
/* GCompris - Directory.cpp
*
* Copyright (C) 2017 Rudra Nil Basu <rudra.nil.basu.1996@gmail.com>
*
* Authors:
* Rudra Nil Basu <rudra.nil.basu.1996@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
#include "Directory.h"
#include <QDir>
-#include <QQmlComponent>
Directory::Directory(QObject *parent) : QObject(parent)
{
}
QStringList Directory::getFiles(const QString& location, const QStringList &nameFilters)
{
QDir dir(location);
- return dir.entryList(nameFilters);
-}
-
-void Directory::init()
-{
- qmlRegisterType<Directory>("GCompris", 1, 0, "Directory");
+ return dir.entryList(nameFilters, (QDir::NoDotAndDotDot | QDir::AllEntries));
}
diff --git a/src/core/Directory.h b/src/core/Directory.h
index cabeea880..b3f761599 100644
--- a/src/core/Directory.h
+++ b/src/core/Directory.h
@@ -1,60 +1,56 @@
/* GCompris - Directory.h
*
* Copyright (C) 2017 Rudra Nil Basu <rudra.nil.basu.1996@gmail.com>
*
* Authors:
* Rudra Nil Basu <rudra.nil.basu.1996@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
#ifndef DIRECTORY_H
#define DIRECTORY_H
#include <QString>
#include <QStringList>
#include <QObject>
/**
* @class Directory
* @short A helper component for accessing directories from QML.
* @ingroup components
*/
class Directory : public QObject
{
Q_OBJECT
public:
/**
* Constructor
*/
explicit Directory(QObject *parent = 0);
/**
* Returns the names of all the files and directories in a given path
*
* @param location: the path of the directory
* @param nameFilters: name filters to apply to the filenames
*
* @returns list of the names of all the files and directories
* in the directory.
*/
Q_INVOKABLE QStringList getFiles(const QString& location, const QStringList &nameFilters = QStringList());
-
- /// @cond INTERNAL_DOCS
- static void init();
- /// @endcond
};
#endif
diff --git a/src/core/Domino.qml b/src/core/Domino.qml
index cde34e4a7..6934043c5 100644
--- a/src/core/Domino.qml
+++ b/src/core/Domino.qml
@@ -1,144 +1,166 @@
/* GCompris - Domino.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
/**
* A QML component to display a domino.
*
* Domino consists of Flipable sides(front and back)
* and uses DominoNumber to display numbers.
* It is divided into two regions containing DominoNumbers.
*
* @inherit QtQuick.Flipable
*/
Flipable {
id: flipable
/**
* type:int
* Integer displayed in first region.
*/
property alias value1: number1.value
/**
* type:int
* Integer displayed in second region.
*/
property alias value2: number2.value
/**
* type:int
* Highest integer to display.
*/
property int valueMax: 9
// Domino style
property color color: "white"
property color borderColor: "black"
property int borderWidth: 2
property int radius: width * 0.05
property color backColor: "white"
property color pointColor: "black"
+ // Define the mode/representation of domino
+ property string mode: "dot"
+
+ // menu modes for setting different types for domino
+ readonly property var menuModes : [
+ //: "Dots" is for representation of the points in a domino in the form of dots
+ { "text": qsTr("Dots"), "value": "dot" },
+ //: "Arabic Numbers" is for representation of the points in a domino in the form of integer numbers
+ { "text": qsTr("Arabic Numbers"), "value": "number" },
+ //: "Roman Numbers" is for representation of the points in a domino in the form of roman numbers
+ { "text": qsTr("Roman Numbers"), "value": "roman" },
+ //: "Images" is for representation of the points in a domino in the form of an image (containing a specific count of same elements)
+ { "text": qsTr("Images"), "value": "image" }
+ ]
+
+ // Source of the images should be in the same format as below with the number associated and svg format
+ property string source: "qrc:/gcompris/src/activities/memory-enumerate/resource/math_"
+
// Set to true when to display on both sides.
property bool flipEnabled: false
property bool flipped: true
// Set to false to prevent user inputs.
property bool isClickable: true
property GCSfx audioEffects
front: Rectangle {
anchors.fill: parent
smooth: true;
color: flipable.color
border.color: "black"
border.width: flipable.borderWidth
radius: flipable.radius
DominoNumber {
id: number1
+ mode: flipable.mode
width: parent.width / 2
height: parent.height
color: flipable.pointColor
borderColor: "black"
borderWidth: 0
radius: parent.height * 0.25
valueMax: flipable.valueMax
+ source: flipable.source
onValueChanged: if(flipEnabled) flipable.flipped = !flipable.flipped
isClickable: flipable.isClickable
audioEffects: flipable.audioEffects
}
// Separation
Rectangle {
x: parent.width / 2
anchors.verticalCenter: parent.verticalCenter
width: 2
height: parent.height * 0.7
color: flipable.borderColor
}
DominoNumber {
id: number2
+ mode: flipable.mode
x: parent.width / 2
width: parent.width / 2
height: parent.height
color: flipable.pointColor
borderColor: "black"
borderWidth: 0
radius: parent.height * 0.25
valueMax: flipable.valueMax
+ source: flipable.source
onValueChanged: if(flipEnabled) flipable.flipped = !flipable.flipped
isClickable: flipable.isClickable
audioEffects: flipable.audioEffects
}
}
back: Rectangle {
anchors.fill: parent
smooth: true;
color: flipable.backColor
border.width: flipable.borderWidth
radius: flipable.radius
}
transform: Rotation {
id: rotation
origin.x: flipable.width/2
origin.y: flipable.height/2
axis.x: 0; axis.y: 1; axis.z: 0 // set axis.y to 1 to rotate around y-axis
angle: 0 // the default angle
}
states: State {
name: "back"
PropertyChanges { target: rotation; angle: 180 }
when: flipable.flipped
onCompleted: flipable.flipped = false
}
transitions: Transition {
NumberAnimation { target: rotation; property: "angle"; duration: 250 }
}
}
diff --git a/src/core/DominoNumber.qml b/src/core/DominoNumber.qml
index c14f1f526..c3a5d66d6 100644
--- a/src/core/DominoNumber.qml
+++ b/src/core/DominoNumber.qml
@@ -1,205 +1,241 @@
/* GCompris - DominoNumber.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
/**
* A QML component to display integers(0-9) on Domino.
- * Numbers are displayed in the form of number of circles.
+ * Numbers are displayed in the form of specified representation.
*
* @inherit QtQuick.Item
*/
Item {
id: item
/**
* type:int
* Integer to display on the domino
*/
property int value
+ /**
+ * type:string
+ * String to specify representation of Domino
+ */
+ property string mode
+
/**
* type:int
* Highest number visible on domino.
*/
property int valueMax
/**
* type:color
* color of the dots to display an integer.
*/
property color color
/**
* type:color
* Border color of the dots to display an integer.
*/
property color borderColor
/**
* type:int
* Border width of the dots to display an integer.
*/
property int borderWidth
/**
* type:int
* Radius of the dots to display an integer.
*/
property int radius
/**
* type:boolean
* Set false to disable mouse/touch inputs on domino.
*/
property bool isClickable: true // Default value
/**
* type:GCAudio
* To play sound and audio effects.
*/
property GCSfx audioEffects
+ /**
+ * type:string
+ * String to specify the source folder for the image mode
+ */
+ property string source
+
+ readonly property variant romans : ["", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"]
+
+ GCText {
+ id: numberText
+ visible: (item.mode == "number" || item.mode == "roman")
+ fontSize: ((item.mode == "number") ? 30 : (item.value == 8) ? 20 : (item.value == 7 || item.value == 3) ? 25 : 30)
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.verticalCenter: parent.verticalCenter
+ color: item.color
+ anchors.margins: ApplicationInfo.ratio * 5
+ text: (mode == "number") ? item.value : romans[item.value]
+ }
+
+ Image {
+ id: imageText
+ visible: (item.mode == "image")
+ height: parent.height
+ fillMode: Image.PreserveAspectFit
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.margins: ApplicationInfo.ratio * 5
+ source: item.source + item.value + ".svg"
+ }
+
function isVisible(index) {
var value = item.value
var visible = false
switch(index) {
case 0:
if(value >= 2) visible = true
break
case 1:
if(value >= 6) visible = true
break
case 2:
if(value >= 4) visible = true
break
case 3:
if(value >= 8) visible = true
break
case 4:
if(value == 1 || value == 3 || value == 5 ||
value == 7 || value == 9) visible = true
break
case 5:
if(value >= 8) visible = true
break
case 6:
if(value >= 4) visible = true
break
case 7:
if(value >= 6) visible = true
break
case 8:
if(value >= 2) visible = true
break
}
return visible
}
Grid {
columns: 3
spacing: 3
+ visible: (item.mode == "dot")
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
horizontalItemAlignment: Grid.AlignHCenter
verticalItemAlignment: Grid.AlignVCenter
Repeater {
model: 9
Rectangle {
width: radius
height: radius
border.width: item.borderWidth
color: item.color
border.color: item.borderColor
radius: item.radius
opacity: isVisible(index)
Behavior on opacity { PropertyAnimation { duration: 200 } }
}
}
}
// Increase the displayed integer value by one.
function up() {
audioEffects.play('qrc:/gcompris/src/core/resource/sounds/scroll.wav')
if(item.value == item.valueMax)
item.value = 0
else
item.value++
}
// Decrease the displayed integer by one.
function down() {
audioEffects.play('qrc:/gcompris/src/core/resource/sounds/scroll.wav')
if(item.value == 0)
item.value = item.valueMax
else
item.value--
}
MouseArea {
enabled: !ApplicationInfo.isMobile && item.isClickable
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton
onClicked: {
if (mouse.button == Qt.LeftButton)
up()
else
down()
}
}
/**
* type:boolean
* To check on touch devices to increase or decrease the integer value.
*/
property bool goUp
Timer {
id: timer
interval: 500
repeat: true
onTriggered: goUp ? up() : down()
}
- MultiPointTouchArea
- {
+ MultiPointTouchArea {
enabled: ApplicationInfo.isMobile && item.isClickable
anchors.fill: parent
maximumTouchPoints: 1
onPressed: {
goUp = true
up()
timer.start()
}
onTouchUpdated: {
if(touchPoints.length) {
var touch = touchPoints[0]
if(touch.y < parent.y + parent.height)
goUp = true
else
goUp = false
}
}
onReleased: timer.stop()
}
}
diff --git a/src/core/DownloadDialog.qml b/src/core/DownloadDialog.qml
index ca546cd70..13bdef977 100644
--- a/src/core/DownloadDialog.qml
+++ b/src/core/DownloadDialog.qml
@@ -1,299 +1,299 @@
/* GCompris - DownloadDialog.qml
*
* Copyright (C) 2014 Holger Kaelberer <holger.k@elberer.de>
*
* Authors:
* Holger Kaelberer <holger.k@elberer.de>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import QtQuick.Layouts 1.3
import QtQuick.Controls 1.5
import "qrc:/gcompris/src/core/core.js" as Core
/**
* A QML component visualizing download progress.
* @ingroup infrastructure
*
* A GCDialog style dialog providing visual feedback for download progress.
* Uses DownloadManager for download control.
*
* Can be conveniently instantiated dynamically using showDownloadDialog
* from core.js.
*
* @inherit QtQuick.Item
* @sa DownloadManager, showDownloadDialog
*/
Item {
id: downloadDialog
opacity: 0
anchors {
fill: parent
}
/**
* type:Item
* Parent object for the dialog in the qml hierarchy.
*/
property Item main
/**
* type:bool
* Whether to close the dialog automatically when download has finished.
* Default is false.
*/
property bool autohide: false;
/**
* type:bool
* Whether to report download success in a Dialog.
* Default is true.
*/
property bool reportSuccess: true;
/**
* type:bool
* Whether to report download errors in a Dialog.
* Default is true.
*/
property bool reportError: true;
/**
* type:bool
* Whether the dialog has been created dynamically. If set to true, the
* component takes care of destroying itself after finished.
* Default is false.
*
* @sa Core.destroyDialog
*/
property bool dynamic: false
/**
* type:bool
* Whether the 'Background' button should be visible.
* Default is true.
*/
property alias backgroundButtonVisible: backgroundButton.visible
/**
* type:bool
* Whether the 'Abort' button should be visible.
* Default is true.
*/
property alias abortButtonVisible: abortButton.visible
/**
* type:bool
* Fixed font size used in this dialog. Note, fixed font-sizes should be
* used in dialog components, to make sure they stay within bounds when
* user increases font size.
* Default is 14.
*/
property int fixedFontSize: 14
/// @cond INTERNAL_DOCS
// start and stop trigs the animation FIXME: need to document?
signal start
signal stop
// emitted at stop animation end
signal close
signal finished
onStart: opacity = 1
onStop: opacity = 0
onClose: destroy()
Behavior on opacity { NumberAnimation { duration: 200 } }
onOpacityChanged: opacity === 0 ? close() : null
function shutdown()
{
if (downloadDialog.dynamic)
Core.destroyDialog(downloadDialog);
else
downloadDialog.close();
}
/// @endcond
Rectangle {
anchors.fill: parent
opacity: 0.8
color: "grey"
MouseArea {
// Empty mouseArea to prevent clicking "behind" the Dialog
anchors.fill: parent
enabled: downloadDialog.opacity != 0
}
}
Item {
id: instruction
anchors {
horizontalCenter: parent.horizontalCenter
top: parent.top
topMargin: parent.height * 0.1
}
width: parent.width * 0.8
GCText {
id: instructionTxt
fontSize: mediumSize
color: "black"
horizontalAlignment: Text.AlignHCenter
width: parent.width
wrapMode: TextEdit.WordWrap
z: 2
height: 60 * ApplicationInfo.ratio
text: qsTr("Downloading ...")
}
Rectangle {
anchors.fill: instructionTxt
z: 1
opacity: 0.9
radius: 10
border.width: 2
border.color: "white"
gradient: Gradient {
GradientStop { position: 0.0; color: "#fff" }
GradientStop { position: 0.9; color: "#fff" }
GradientStop { position: 1.0; color: "#ddd" }
}
}
ProgressBar {
id: downloadDialogProgress
width: parent.width
anchors {
horizontalCenter: parent.horizontalCenter
top: instructionTxt.bottom
topMargin: 10
}
visible: true
Layout.alignment: Qt.AlignHCenter
Layout.rowSpan: 1
Layout.fillWidth: true
minimumValue: 0
maximumValue: 100
value: 0
}
Button {
id: backgroundButton
width: parent.width
height: 60 * ApplicationInfo.ratio
anchors {
horizontalCenter: parent.horizontalCenter
top: downloadDialogProgress.bottom
topMargin: 10
}
//: Run this task in background
text: qsTr("Background")
style: GCButtonStyle {
fixedFontSize: downloadDialog.fixedFontSize
theme: "highContrast"
}
visible: true
onClicked: downloadDialog.shutdown();
}
Button {
id: abortButton
width: parent.width
height: 60 * ApplicationInfo.ratio
anchors {
horizontalCenter: parent.horizontalCenter
top: backgroundButton.bottom
topMargin: 10
}
text: qsTr("Abort")
style: GCButtonStyle {
fixedFontSize: downloadDialog.fixedFontSize
theme: "highContrast"
}
visible: true
onClicked: {
if (DownloadManager.downloadIsRunning())
DownloadManager.abortDownloads();
downloadDialog.finished();
downloadDialog.shutdown();
}
}
}
Connections {
target: DownloadManager
onError: {
//console.warn("DownloadDialog: DM reports error: " + code + ": " + msg);
downloadDialog.finished();
if (downloadDialog.reportError
&& code != 5) { // no error: OperationCanceledError
// show error message
var messageDialog = Core.showMessageDialog(main,
- qsTr("Download error") + code + ": " + msg,
+ qsTr("Download error (code: %1): %2").arg(code).arg(msg),
"", null,
"", null,
function() {
downloadDialog.shutdown();
}
);
} else
downloadDialog.shutdown();
}
onDownloadProgress: downloadDialogProgress.value = 100 * bytesReceived / bytesTotal;
onDownloadStarted: {
//console.log("dialog: DM reports started: " + resource);
downloadDialogProgress.value = 0;
}
onDownloadFinished: {
//console.log("dialog: DM reports finished: " + code);
downloadDialog.finished();
if (downloadDialog.reportSuccess
&& code != 1) // note: errors will be reported by the onError handler
{
// report success
downloadDialog.stop();
var infText = "";
if (code == 0) { // Success
infText = qsTr("Your download finished successfully. The data files are now available.")
+ '\n'
+ qsTr("Restart any currently active activity.");
} else if (code == 2) // NoChange
infText = qsTr("Your local data files are up-to-date.")
var messageDialog = Core.showMessageDialog(main,
infText,
"", null,
"", null,
null
);
} else if (downloadDialog.autohide)
downloadDialog.shutdown();
}
}
}
diff --git a/src/core/DownloadManager.cpp b/src/core/DownloadManager.cpp
index 2ba2caf35..e4c95067e 100644
--- a/src/core/DownloadManager.cpp
+++ b/src/core/DownloadManager.cpp
@@ -1,702 +1,677 @@
/* GCompris - DownloadManager.cpp
*
* Copyright (C) 2014 Holger Kaelberer <holger.k@elberer.de>
*
* Authors:
* Holger Kaelberer <holger.k@elberer.de>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
#include "DownloadManager.h"
#include "ApplicationSettings.h"
#include "ApplicationInfo.h"
#include <QFile>
#include <QDir>
#include <QResource>
#include <QStandardPaths>
#include <QMutexLocker>
#include <QNetworkConfiguration>
#include <QDirIterator>
#include <QtQml>
-const QString DownloadManager::contentsFilename = QString("Contents");
-DownloadManager* DownloadManager::_instance = 0;
-
-void copyPath(QString src, QString dst)
-{
- QDir dir(src);
- if (!dir.exists())
- return;
-
- Q_FOREACH(const QString &d, dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) {
- QString dst_path = dst + QDir::separator() + d;
- dir.mkpath(dst_path);
- copyPath(src+ QDir::separator() + d, dst_path);
- }
-
- Q_FOREACH(const QString &f, dir.entryList(QDir::Files)) {
- qDebug() << "Copying " << src + QDir::separator() + f << " to " << dst + QDir::separator() + f;
- QFile::copy(src + QDir::separator() + f, dst + QDir::separator() + f);
- }
-}
+const QString DownloadManager::contentsFilename = QStringLiteral("Contents");
+DownloadManager* DownloadManager::_instance = nullptr;
/* Public interface: */
DownloadManager::DownloadManager()
: accessManager(this), serverUrl(ApplicationSettings::getInstance()->downloadServerUrl())
{
- // Cleanup of previous data directory no more used
- QList<QDir> previousDataLocations = QList<QDir>() <<
- QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/data" <<
- QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/data2";
-
- for(auto it = previousDataLocations.begin(); it != previousDataLocations.end() ; ++ it) {
- QDir &prevDir = *it;
- if(prevDir.exists()) {
- if(prevDir.dirName() == "data2") {
- qDebug() << "Data changed place, move from previous folder to the new one";
- copyPath(prevDir.absolutePath(), getSystemDownloadPath() + "/data2");
- }
- qDebug() << "Remove previous directory data: " << prevDir.absolutePath();
- prevDir.removeRecursively();
- }
- }
}
DownloadManager::~DownloadManager()
{
shutdown();
- _instance = 0;
+ _instance = nullptr;
}
void DownloadManager::shutdown()
{
qDebug() << "DownloadManager: shutting down," << activeJobs.size() << "active jobs";
abortDownloads();
}
// It is not recommended to create a singleton of Qml Singleton registered
// object but we could not found a better way to let us access DownloadManager
// on the C++ side. All our test shows that it works.
// Using the singleton after the QmlEngine has been destroyed is forbidden!
DownloadManager* DownloadManager::getInstance()
{
- if (!_instance)
+ if (_instance == nullptr)
_instance = new DownloadManager;
return _instance;
}
-QObject *DownloadManager::systeminfoProvider(QQmlEngine *engine,
+QObject *DownloadManager::downloadManagerProvider(QQmlEngine *engine,
QJSEngine *scriptEngine)
{
Q_UNUSED(engine)
Q_UNUSED(scriptEngine)
return getInstance();
}
-void DownloadManager::init()
-{
- qmlRegisterSingletonType<DownloadManager>("GCompris", 1, 0,
- "DownloadManager",
- systeminfoProvider);
-}
-
bool DownloadManager::downloadIsRunning() const
{
- return (activeJobs.size() > 0);
+ return !activeJobs.empty();
}
void DownloadManager::abortDownloads()
{
- if (activeJobs.size() > 0) {
+ if (downloadIsRunning()) {
QMutexLocker locker(&jobsMutex);
QMutableListIterator<DownloadJob*> iter(activeJobs);
while (iter.hasNext()) {
DownloadJob *job = iter.next();
- if (job->reply) {
+ if (job->reply != nullptr) {
disconnect(job->reply, SIGNAL(finished()), this, SLOT(downloadFinished()));
disconnect(job->reply, SIGNAL(error(QNetworkReply::NetworkError)),
this, SLOT(handleError(QNetworkReply::NetworkError)));
if (job->reply->isRunning()) {
qDebug() << "Aborting download job:" << job->url;
job->reply->abort();
job->file.close();
job->file.remove();
}
- delete job->reply;
+ job->reply->deleteLater();
}
iter.remove();
}
locker.unlock();
- emit error(QNetworkReply::OperationCanceledError, "Download cancelled by user");
+ emit error(QNetworkReply::OperationCanceledError, QObject::tr("Download cancelled by user"));
}
}
QString DownloadManager::getVoicesResourceForLocale(const QString& locale) const
{
return QString("data2/voices-" COMPRESSED_AUDIO "/voices-%1.rcc")
.arg(ApplicationInfo::getInstance()->getVoicesLocale(locale));
}
inline QString DownloadManager::getAbsoluteResourcePath(const QString& path) const
{
- foreach (const QString &base, getSystemResourcePaths()) {
+ for (const QString &base : getSystemResourcePaths()) {
if (QFile::exists(base + '/' + path))
return QString(base + '/' + path);
}
return QString();
}
// @FIXME should support a variable subpath length like data2/full.rcc"
inline QString DownloadManager::getRelativeResourcePath(const QString& path) const
{
QStringList parts = path.split('/', QString::SkipEmptyParts);
if (parts.size() < 3)
return QString();
return QString(parts[parts.size()-3] + '/' + parts[parts.size()-2]
+ '/' + parts[parts.size()-1]);
}
bool DownloadManager::haveLocalResource(const QString& path) const
{
return (!getAbsoluteResourcePath(path).isEmpty());
}
bool DownloadManager::updateResource(const QString& path)
{
if (checkDownloadRestriction())
return downloadResource(path); // check for updates and register
- else {
- QString absPath = getAbsoluteResourcePath(path);
- // automatic download prohibited -> register if available
- if (!absPath.isEmpty())
- return registerResourceAbsolute(absPath);
- else {
- qDebug() << "No such local resource and download prohibited:"
- << path;
- return false;
- }
- }
+
+ QString absPath = getAbsoluteResourcePath(path);
+ // automatic download prohibited -> register if available
+ if (!absPath.isEmpty())
+ return registerResourceAbsolute(absPath);
+
+ qDebug() << "No such local resource and download prohibited: "
+ << path;
+ return false;
}
bool DownloadManager::downloadResource(const QString& path)
{
DownloadJob* job = nullptr;
{
QMutexLocker locker(&jobsMutex);
QUrl url(serverUrl.toString() + '/' + path);
- if (getJobByUrl_locked(url)) {
+ if (getJobByUrl_locked(url) != nullptr) {
qDebug() << "Download of" << url << "is already running, skipping second attempt.";
return false;
}
job = new DownloadJob(url);
activeJobs.append(job);
}
qDebug() << "Downloading resource file" << path;
if (!download(job)) {
QMutexLocker locker(&jobsMutex);
activeJobs.removeOne(job);
return false;
}
return true;
}
-#if 0
-// vvv might be helpful later with other use-cases:
-void DownloadManager::registerLocalResources()
-{
- QStringList filenames = getLocalResources();
- if (filenames.empty()) {
- qDebug() << "No local resources found";
- return;
- }
-
- QList<QString>::const_iterator iter;
- for (iter = filenames.constBegin(); iter != filenames.constEnd(); iter++)
- registerResource(*iter);
-}
-
-bool DownloadManager::checkForUpdates()
-{
- QStringList filenames = getLocalResources();
- if (filenames.empty()) {
- qDebug() << "No local resources found";
- return true;
- }
-
- if (!checkDownloadRestriction()) {
- qDebug() << "Can't download with current network connection (" <<
- networkConfiguration.bearerTypeName() << ")!";
- return false;
- }
-
- QList<QString>::const_iterator iter;
- DownloadJob *job = new DownloadJob();
- for (iter = filenames.constBegin(); iter != filenames.constEnd(); iter++) {
- QUrl url = getUrlForFilename(*iter);
- qDebug() << "Scheduling resource for update: " << url;
- job->queue.append(url);
- }
- job->url = job->queue.takeFirst();
-
- {
- QMutexLocker locker(&jobsMutex);
- activeJobs.append(job);
- }
-
- if (!download(job)) {
- QMutexLocker locker(&jobsMutex);
- activeJobs.removeOne(job);
- return false;
- }
- return true;
-
-}
-#endif
-
/* Private: */
inline QString DownloadManager::tempFilenameForFilename(const QString &filename) const
{
return QString(filename).append("_");
}
inline QString DownloadManager::filenameForTempFilename(const QString &tempFilename) const
{
if (tempFilename.endsWith(QLatin1String("_")))
return tempFilename.left(tempFilename.length() - 1);
return tempFilename;
}
bool DownloadManager::download(DownloadJob* job)
{
QNetworkRequest request;
// First download Contents file for verification if not yet done:
if (!job->contents.contains(job->url.fileName())) {
int len = job->url.fileName().length();
QUrl contentsUrl = QUrl(job->url.toString().remove(job->url.toString().length() - len, len)
+ contentsFilename);
if (!job->knownContentsUrls.contains(contentsUrl)) {
// Note: need to track already tried Contents files or we can end
// up in an infinite loop if corresponding Contents file does not
// exist upstream
job->knownContentsUrls.append(contentsUrl);
//qDebug() << "Postponing rcc download, first fetching Contents" << contentsUrl;
job->queue.prepend(job->url);
job->url = contentsUrl;
}
}
QFileInfo fi(getFilenameForUrl(job->url));
// make sure target path exists:
QDir dir;
if (!dir.exists(fi.path()) && !dir.mkpath(fi.path())) {
qDebug() << "Could not create resource path " << fi.path();
- emit error(QNetworkReply::ProtocolUnknownError, "Could not create resource path");
+ emit error(QNetworkReply::ProtocolUnknownError, QObject::tr("Could not create resource path"));
return false;
}
job->file.setFileName(tempFilenameForFilename(fi.filePath()));
if (!job->file.open(QIODevice::WriteOnly)) {
emit error(QNetworkReply::ProtocolUnknownError,
- QString("Could not open target file %1").arg(job->file.fileName()));
+ QObject::tr("Could not open target file %1").arg(job->file.fileName()));
return false;
}
// start download:
request.setUrl(job->url);
//qDebug() << "Now downloading" << job->url << "to" << fi.filePath() << "...";
QNetworkReply *reply = accessManager.get(request);
job->reply = reply;
connect(reply, SIGNAL(finished()), this, SLOT(downloadFinished()));
connect(reply, &QNetworkReply::readyRead, this, &DownloadManager::downloadReadyRead);
connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
this, SLOT(handleError(QNetworkReply::NetworkError)));
if (job->url.fileName() != contentsFilename) {
connect(reply, &QNetworkReply::downloadProgress,
this, &DownloadManager::downloadProgress);
emit downloadStarted(job->url.toString().remove(0, serverUrl.toString().length()));
}
return true;
}
inline DownloadManager::DownloadJob* DownloadManager::getJobByUrl_locked(const QUrl& url) const
{
- for (int i = 0; i < activeJobs.size(); i++)
- if (activeJobs[i]->url == url || activeJobs[i]->queue.indexOf(url) != -1)
- return activeJobs[i];
+ for (auto activeJob : activeJobs)
+ if (activeJob->url == url || activeJob->queue.indexOf(url) != -1)
+ return activeJob;
return nullptr;
}
inline DownloadManager::DownloadJob* DownloadManager::getJobByReply(QNetworkReply *r)
{
QMutexLocker locker(&jobsMutex);
- for (int i = 0; i < activeJobs.size(); i++)
- if (activeJobs[i]->reply == r)
- return activeJobs[i];
+ for (auto activeJob : activeJobs)
+ if (activeJob->reply == r)
+ return activeJob;
return nullptr; // should never happen!
}
void DownloadManager::downloadReadyRead()
{
QNetworkReply *reply = dynamic_cast<QNetworkReply*>(sender());
DownloadJob *job = getJobByReply(reply);
job->file.write(reply->readAll());
}
inline QString DownloadManager::getFilenameForUrl(const QUrl& url) const
{
QString relPart = url.toString().remove(0, serverUrl.toString().length());
return QString(getSystemDownloadPath() + relPart);
}
inline QUrl DownloadManager::getUrlForFilename(const QString& filename) const
{
return QUrl(serverUrl.toString() + '/' + getRelativeResourcePath(filename));
}
inline QString DownloadManager::getSystemDownloadPath() const
{
return ApplicationSettings::getInstance()->cachePath();
}
inline QStringList DownloadManager::getSystemResourcePaths() const
{
QStringList results({
QCoreApplication::applicationDirPath() + '/' + QString(GCOMPRIS_DATA_FOLDER) + "/rcc/",
getSystemDownloadPath(),
QStandardPaths::writableLocation(QStandardPaths::CacheLocation),
#if defined(Q_OS_ANDROID)
"assets:",
#endif
QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) +
'/' + GCOMPRIS_APPLICATION_NAME
});
#if QT_VERSION >= 0x050400
// Append standard application directories (like /usr/share/KDE/gcompris-qt)
results += QStandardPaths::standardLocations(QStandardPaths::AppDataLocation);
#endif
return results;
}
bool DownloadManager::checkDownloadRestriction() const
{
#if 0
// note: Something like the following can be used once bearer mgmt
// has been implemented for android (cf. Qt bug #30394)
QNetworkConfiguration::BearerType conn = networkConfiguration.bearerType();
qDebug() << "Bearer type: "<< conn << ": "<< networkConfiguration.bearerTypeName();
if (!ApplicationSettings::getInstance()->isMobileNetworkDownloadsEnabled() &&
conn != QNetworkConfiguration::BearerEthernet &&
conn != QNetworkConfiguration::QNetworkConfiguration::BearerWLAN)
return false;
return true;
#endif
return ApplicationSettings::getInstance()->isAutomaticDownloadsEnabled() &&
ApplicationInfo::getInstance()->isDownloadAllowed();
}
void DownloadManager::handleError(QNetworkReply::NetworkError code)
{
Q_UNUSED(code);
QNetworkReply *reply = dynamic_cast<QNetworkReply*>(sender());
+ qDebug() << reply->errorString() << " " << reply->error();
emit error(reply->error(), reply->errorString());
}
bool DownloadManager::parseContents(DownloadJob *job)
{
if (job->file.isOpen())
job->file.close();
if (!job->file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qWarning() << "Could not open file " << job->file.fileName();
return false;
}
/*
* We expect the line-syntax, that md5sum and colleagues creates:
* <MD5SUM> <FILENAME>
* 53f0a3eb206b3028500ca039615c5f84 voices-en.rcc
*/
QTextStream in(&job->file);
while (!in.atEnd()) {
QString line = in.readLine();
QStringList parts = line.split(' ', QString::SkipEmptyParts);
if (parts.size() != 2) {
qWarning() << "Invalid format of Contents file!";
return false;
}
job->contents[parts[1]] = parts[0];
//qDebug() << "Contents: " << parts[1] << " -> " << parts[0];
}
job->file.close();
return true;
}
bool DownloadManager::checksumMatches(DownloadJob *job, const QString& filename) const
{
- Q_ASSERT(job->contents != (QMap<QString, QString>()));
+ Q_ASSERT(!job->contents.empty());
if (!QFile::exists(filename))
return false;
QString basename = QFileInfo(filename).fileName();
if (!job->contents.contains(basename))
return false;
QFile file(filename);
file.open(QIODevice::ReadOnly);
QCryptographicHash fileHasher(hashMethod);
if (!fileHasher.addData(&file)) {
qWarning() << "Could not read file for hashing: " << filename;
return false;
}
file.close();
QByteArray fileHash = fileHasher.result().toHex();
//qDebug() << "Checking file-hash ~ contents-hash: " << fileHash << " ~ " << job->contents[basename];
return (fileHash == job->contents[basename]);
}
void DownloadManager::unregisterResource_locked(const QString& filename)
{
if (!QResource::unregisterResource(filename))
qDebug() << "Error unregistering resource file" << filename;
else {
qDebug() << "Successfully unregistered resource file" << filename;
registeredResources.removeOne(filename);
}
}
inline bool DownloadManager::isRegistered(const QString& filename) const
{
return (registeredResources.indexOf(filename) != -1);
}
/*
* Registers an rcc file given by absolute path
*/
bool DownloadManager::registerResourceAbsolute(const QString& filename)
{
QMutexLocker locker(&rcMutex);
if (isRegistered(filename))
unregisterResource_locked(filename);
if (!QResource::registerResource(filename)) {
qDebug() << "Error registering resource file" << filename;
return false;
- } else {
- qDebug() << "Successfully registered resource"
- << filename;
- registeredResources.append(filename);
+ }
- locker.unlock(); /* note: we unlock before emitting to prevent
- * potential deadlocks */
+ qDebug() << "Successfully registered resource"
+ << filename;
+ registeredResources.append(filename);
- emit resourceRegistered(getRelativeResourcePath(filename));
+ locker.unlock(); /* note: we unlock before emitting to prevent
+ * potential deadlocks */
- QString v = getVoicesResourceForLocale(
- ApplicationSettings::getInstance()->locale());
- if (v == getRelativeResourcePath(filename))
- emit voicesRegistered();
- return true;
- }
+ emit resourceRegistered(getRelativeResourcePath(filename));
+
+ QString v = getVoicesResourceForLocale(
+ ApplicationSettings::getInstance()->locale());
+ if (v == getRelativeResourcePath(filename))
+ emit voicesRegistered();
+ return true;
}
/*
* Registers an rcc file given by a relative resource path
*/
bool DownloadManager::registerResource(const QString& filename)
{
return registerResourceAbsolute(getAbsoluteResourcePath(filename));
}
bool DownloadManager::isDataRegistered(const QString& data) const
{
QString res = QString(":/gcompris/data/%1").arg(data);
return !QDir(res).entryList().empty();
}
bool DownloadManager::areVoicesRegistered() const
{
QString resource = QString("voices-" COMPRESSED_AUDIO "/%1").
arg(ApplicationInfo::getInstance()->getVoicesLocale(ApplicationSettings::getInstance()->locale()));
return isDataRegistered(resource);
}
void DownloadManager::downloadFinished()
{
QNetworkReply* reply = dynamic_cast<QNetworkReply*>(sender());
DownloadFinishedCode code = Success;
DownloadJob *job = getJobByReply(reply);
if (job->file.isOpen()) {
job->file.flush(); // note: important, or checksums might be wrong!
job->file.close();
}
- if (reply->error() && job->file.exists())
+
+ if (reply->error() != 0 && job->file.exists()) {
job->file.remove();
+ }
else {
// active temp file
QString tFilename = filenameForTempFilename(job->file.fileName());
- if (QFile::exists(tFilename))
+ if (QFile::exists(tFilename)) {
QFile::remove(tFilename);
- if (!job->file.rename(tFilename))
+ }
+ if (!job->file.rename(tFilename)) {
qWarning() << "Could not rename temporary file to" << tFilename;
+ }
}
QString targetFilename = getFilenameForUrl(job->url);
if (job->url.fileName() == contentsFilename) {
// Contents
- if (reply->error()) {
+ if (reply->error() != 0) {
qWarning() << "Error downloading Contents from" << job->url
<< ":" << reply->error() << ":" << reply->errorString();
// note: errorHandler() emit's error!
- code = Error;
goto outError;
}
//qDebug() << "Download of Contents finished successfully: " << job->url;
if (!parseContents(job)) {
qWarning() << "Invalid format of Contents file" << job->url;
- emit error(QNetworkReply::UnknownContentError, "Invalid format of Contents file");
- code = Error;
+ emit error(QNetworkReply::UnknownContentError, QObject::tr("Invalid format of Contents file"));
goto outError;
}
} else {
+ QUrl redirect = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
// RCC file
- if (reply->error()) {
+ if (reply->error() != 0) {
qWarning() << "Error downloading RCC file from " << job->url
<< ":" << reply->error() << ":" << reply->errorString();
// note: errorHandler() emit's error!
code = Error;
// register already existing files (if not yet done):
if (QFile::exists(targetFilename) && !isRegistered(targetFilename))
registerResourceAbsolute(targetFilename);
- } else {
+ }
+ // In case the file does not exist on the server, it is redirected to
+ // an error page and this error page is downloaded but on our case
+ // this is an error as we don't have the expected rcc.
+ else if (!redirect.isEmpty()) {
+ qWarning() << QString("The url %1 does not exist.").arg(job->url.toString());
+ emit error(QNetworkReply::UnknownContentError,
+ QObject::tr("The url %1 does not exist.")
+ .arg(job->url.toString()));
+ code = Error;
+ if (QFile::exists(targetFilename)) {
+ QFile::remove(targetFilename);
+ }
+ }
+ else {
qDebug() << "Download of RCC file finished successfully: " << job->url;
if (!checksumMatches(job, targetFilename)) {
qWarning() << "Checksum of downloaded file does not match: "
<< targetFilename;
emit error(QNetworkReply::UnknownContentError,
- QString("Checksum of downloaded file does not match: %1")
+ QObject::tr("Checksum of downloaded file does not match: %1")
.arg(targetFilename));
code = Error;
} else
registerResourceAbsolute(targetFilename);
}
}
// try next:
while (!job->queue.isEmpty()) {
job->url = job->queue.takeFirst();
QString relPath = getRelativeResourcePath(getFilenameForUrl(job->url));
// check in each resource-path for an up2date rcc file:
- foreach (const QString &base, getSystemResourcePaths()) {
+ for (const QString &base : getSystemResourcePaths()) {
QString filename = base + '/' + relPath;
if (QFile::exists(filename)
&& checksumMatches(job, filename))
{
// file is up2date, register! necessary:
qDebug() << "Local resource is up-to-date:"
<< QFileInfo(filename).fileName();
if (!isRegistered(filename)) // no update and already registered -> noop
registerResourceAbsolute(filename);
code = NoChange;
break;
}
}
if (code != NoChange) // nothing is up2date locally -> download it
if (download(job))
goto outNext;
}
// none left, DownloadJob finished
if (job->file.isOpen())
job->file.close();
{ // note: must remove before signalling downloadFinished(), otherwise race condition for the Qt.quit() case
QMutexLocker locker(&jobsMutex);
activeJobs.removeOne(job);
}
emit downloadFinished(code);
- delete reply;
+ reply->deleteLater();
delete job;
return;
outError:
if (job->url.fileName() == contentsFilename) {
// if we could not download the contents file register local existing
// files for outstanding jobs:
QUrl nUrl;
while (!job->queue.isEmpty()) {
nUrl = job->queue.takeFirst();
QString relPath = getRelativeResourcePath(getFilenameForUrl(nUrl));
- foreach (const QString &base, getSystemResourcePaths()) {
+ for (const QString &base: getSystemResourcePaths()) {
QString filename = base + '/' + relPath;
if (QFile::exists(filename))
registerResourceAbsolute(filename);
}
}
}
if (job->file.isOpen())
job->file.close();
{
QMutexLocker locker(&jobsMutex);
activeJobs.removeOne(job);
}
- delete reply;
+ reply->deleteLater();
delete job;
return;
outNext:
// next sub-job started
- delete reply;
+ reply->deleteLater();
return;
}
+#if 0
+// vvv might be helpful later with other use-cases:
+void DownloadManager::registerLocalResources()
+{
+ QStringList filenames = getLocalResources();
+ if (filenames.empty()) {
+ qDebug() << "No local resources found";
+ return;
+ }
+
+ QList<QString>::const_iterator iter;
+ for (iter = filenames.constBegin(); iter != filenames.constEnd(); iter++)
+ registerResource(*iter);
+}
+
+bool DownloadManager::checkForUpdates()
+{
+ QStringList filenames = getLocalResources();
+ if (filenames.empty()) {
+ qDebug() << "No local resources found";
+ return true;
+ }
+
+ if (!checkDownloadRestriction()) {
+ qDebug() << "Can't download with current network connection (" <<
+ networkConfiguration.bearerTypeName() << ")!";
+ return false;
+ }
+
+ QList<QString>::const_iterator iter;
+ DownloadJob *job = new DownloadJob();
+ for (iter = filenames.constBegin(); iter != filenames.constEnd(); iter++) {
+ QUrl url = getUrlForFilename(*iter);
+ qDebug() << "Scheduling resource for update: " << url;
+ job->queue.append(url);
+ }
+ job->url = job->queue.takeFirst();
+
+ {
+ QMutexLocker locker(&jobsMutex);
+ activeJobs.append(job);
+ }
+
+ if (!download(job)) {
+ QMutexLocker locker(&jobsMutex);
+ activeJobs.removeOne(job);
+ return false;
+ }
+ return true;
+
+}
+
QStringList DownloadManager::getLocalResources()
{
QStringList result;
- foreach (const QString &path, getSystemResourcePaths()) {
+ for (const QString &path : getSystemResourcePaths()) {
QDir dir(path);
if (!dir.exists(path) && !dir.mkpath(path)) {
qWarning() << "Could not create resource path " << path;
continue;
}
QDirIterator it(dir, QDirIterator::Subdirectories);
while (it.hasNext()) {
QString filename = it.next();
QFileInfo fi = it.fileInfo();
if (fi.isFile() &&
(filename.endsWith(QLatin1String(".rcc"))))
result.append(filename);
}
}
return result;
}
+#endif
diff --git a/src/core/DownloadManager.h b/src/core/DownloadManager.h
index f06d78df2..ae03264b5 100644
--- a/src/core/DownloadManager.h
+++ b/src/core/DownloadManager.h
@@ -1,381 +1,382 @@
/* GCompris - DownloadManager.h
*
* Copyright (C) 2014 Holger Kaelberer <holger.k@elberer.de>
*
* Authors:
* Holger Kaelberer <holger.k@elberer.de>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
#ifndef DOWNLOADMANAGER_H
#define DOWNLOADMANAGER_H
#include <QCryptographicHash>
#include <QFile>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QMutex>
#include <QNetworkConfiguration>
#include <QString>
#include <QUrl>
#include <QVariant>
#include <QQmlEngine>
#include <QJSEngine>
/**
* @class DownloadManager
* @short A singleton class responsible for downloading, updating and
* maintaining remote resources.
* @ingroup infrastructure
*
* DownloadManager is responsible for downloading, updating and registering
* additional resources (in Qt's binary .rcc format) used by GCompris.
* It downloads from a upstream URL (ApplicationSettings.downloadServerUrl) to the
* default local writable location. Downloads are based on common relative
* resource paths, such that a URL of the form
*
* <tt>http://\<server-base\>/\<path/to/my/resource.rcc\></tt>
*
* will be downloaded to a local path
*
* <tt>/\<ApplicationSettings::getInstance()->cachePath()\>/\<path/to/my/resource.rcc\></tt>
*
* and registered with a resource root path
*
* <tt>qrc:/\<path/to/my\>/</tt>
*
* Internally resources are uniquely identified by their <em>relative resource
* path</em>
*
* <tt>\<path/to/my/resource.rcc\></tt>
* (e.g. <tt>data2/voices-ogg/voices-en.rcc></tt>)
*
* Downloading and verification of local files is controlled by MD5
* checksums that are expected to be stored in @c Contents files in each
* upstream directory according to the syntax produced by the @c md5sum
* tool. The checksums are used for checking whether a local rcc file is
* up-to-date (to avoid unnecesary rcc downloads) and to verify that the
* transfer was complete. Only valid rcc files (with correct checksums)
* are registered.
*
* A resource file must reference the "/gcompris/data" prefix with
* \<qresource prefix="/gcompris/data"\>. All data are loaded and referenced
* from this prefix. It is possible to check if a data is registered with
* isDataRegistered.
*
* @sa DownloadDialog, ApplicationSettings.downloadServerUrl,
* ApplicationSettings.isAutomaticDownloadsEnabled,
* ApplicationSettings.cachePath
*/
class DownloadManager : public QObject
{
Q_OBJECT
private:
DownloadManager(); // prohibit external creation, we are a singleton!
static DownloadManager* _instance; // singleton instance
/** Container for a full download job */
typedef struct DownloadJob
{
QUrl url; ///< url of the currently running sub-job
QFile file; ///< target file for the currently running sub-job
QNetworkReply *reply; ///< reply object for the currently running sub-job
QList<QUrl> queue; ///< q of remaining sub jobs (QList for convenience)
QMap<QString,QString> contents; ///< checksum map for download verification
QList<QUrl> knownContentsUrls; ///< store already tried upstream Contents files (for infinite loop protection)
DownloadJob(const QUrl &u = QUrl()) : url(u), file(), reply(0),
queue(QList<QUrl>()) {}
} DownloadJob;
QList<DownloadJob*> activeJobs; ///< track active jobs to allow for parallel downloads
QMutex jobsMutex; ///< not sure if we need to expect concurrent access, better lockit!
static const QString contentsFilename;
static const QCryptographicHash::Algorithm hashMethod = QCryptographicHash::Md5;
QList<QString> registeredResources;
QMutex rcMutex; ///< not sure if we need to expect concurrent access, better lockit!
QNetworkAccessManager accessManager;
QUrl serverUrl;
/**
* Get the platform-specific path storing downloaded resources.
*
* Uses QStandardPaths::writableLocation(QStandardPaths::CacheLocation)
* which returns
* - on desktop linux $HOME/.cache/KDE/gcompris-qt/
* - on other platforms check <http://doc.qt.io/qt-5/qstandardpaths.html>
*
* @return An absolute path.
*/
QString getSystemDownloadPath() const;
/**
* Get all paths that are used for storing resources.
*
* @returns A list of absolute paths used for storing local resources.
* The caller should keep the returned list order when looking for
* resources, for now the lists contains:
* 1. data folder in the application path
* 2. getSystemDownloadPath()
* 3. QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)/gcompris-qt
* which is
* - $HOME/.local/share/gcompris-qt (on linux desktop)
* - /storage/sdcard0/GCompris (on android)
* 4. [QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation)]/gcompris-qt
* which is on GNU/Linux
* - $HOME/.local/share/KDE/gcompris-qt
* - $HOME/.local/share/gcompris-qt
* - $HOME/.local/share/applications/gcompris-qt
* - /usr/local/share/KDE/gcompris-qt
* - /usr/share/KDE/gcompris-qt
*/
QStringList getSystemResourcePaths() const;
QString getResourceRootForFilename(const QString& filename) const;
QString getFilenameForUrl(const QUrl& url) const;
QUrl getUrlForFilename(const QString& filename) const;
/**
* Transforms the passed relative path to an absolute resource path of an
* existing .rcc file, honouring the order of the systemResourcePaths
*
* @returns The absolute path of the .rcc file if it exists, QString()
* otherwise
*/
QString getAbsoluteResourcePath(const QString& path) const;
/**
* Transforms the passed absolute path to a relative resource path if
* possible.
*
* @returns The relative path if it could be generated, QString() otherwise.
*/
QString getRelativeResourcePath(const QString& path) const;
QString tempFilenameForFilename(const QString &filename) const;
QString filenameForTempFilename(const QString &tempFilename) const;
bool checkDownloadRestriction() const;
DownloadJob* getJobByReply(QNetworkReply *r);
DownloadJob* getJobByUrl_locked(const QUrl& url) const;
/** Start a new download specified by the passed DownloadJob */
bool download(DownloadJob* job);
/** Parses upstream Contents file and build checksum map. */
bool parseContents(DownloadJob *job);
/** Compares the checksum of the file in filename with the contents map in
* the passed DownloadJob */
bool checksumMatches(DownloadJob *job, const QString& filename) const;
bool registerResourceAbsolute(const QString& filename);
/** Unregisters the passed resource
*
* Caller must lock rcMutex.
*/
void unregisterResource_locked(const QString& filename);
bool isRegistered(const QString& filename) const;
+#if 0
QStringList getLocalResources();
+#endif
private slots:
/** Handle a finished download.
*
* Called whenever a single download (sub-job) has finished. Responsible
* for iterating over possibly remaining sub-jobs of our DownloadJob.
*/
void downloadFinished();
void downloadReadyRead();
void handleError(QNetworkReply::NetworkError code);
public:
// public interface:
/**
* Possible return codes of a finished download
*/
enum DownloadFinishedCode {
Success = 0, /**< Download finished successfully */
Error = 1, /**< Download error */
NoChange = 2 /**< Local files are up-to-date, no download was needed */
};
virtual ~DownloadManager();
/**
* Registers DownloadManager singleton in the QML engine.
*/
- static void init();
- static QObject *systeminfoProvider(QQmlEngine *engine,
- QJSEngine *scriptEngine);
+ static QObject *downloadManagerProvider(QQmlEngine *engine,
+ QJSEngine *scriptEngine);
static DownloadManager* getInstance();
/**
* Generates a relative voices resources file-path for a given @p locale.
*
* @param locale Locale name string of the form \<language\>_\<country\>.
*
* @returns A relative voices resource path.
*/
Q_INVOKABLE QString getVoicesResourceForLocale(const QString& locale) const;
/**
* Checks whether the given relative resource @p path exists locally.
*
* @param path A relative resource path.
*/
Q_INVOKABLE bool haveLocalResource(const QString& path) const;
/**
* Whether any download is currently running.
*/
Q_INVOKABLE bool downloadIsRunning() const;
/**
* Whether the passed relative @p data is registered.
*
* For example, if you have a resource file which loads files under the
* 'words' path like 'words/one.png'. You can call this method with 'words/one.png'
* or with 'words'.
*
* @param data Relative resource path (file or directory).
*
* @sa areVoicesRegistered
*/
Q_INVOKABLE bool isDataRegistered(const QString& data) const;
/**
* Whether voices for the currently active locale are registered.
*
* @sa isDataRegistered
*/
Q_INVOKABLE bool areVoicesRegistered() const;
- /*
+ /**
* Registers a rcc resource file given by a relative resource path
*
* @param filename Relative resource path.
*/
Q_INVOKABLE bool registerResource(const QString& filename);
public slots:
/**
* Updates a resource @p path from the upstream server unless prohibited
* by the settings and registers it if possible.
*
* If not prohibited by the setting 'isAutomaticDownloadsEnabled' checks
* for an available upstream resource specified by @p path.
* If the corresponding local resource does not exist or is out of date,
* the resource is downloaded and registered.
*
* If automatic downloads/updates are prohibited and a local copy of the
* specified resource exists, it is registered.
*
* @param path A relative resource path.
*
* @returns success
*/
Q_INVOKABLE bool updateResource(const QString& path);
/**
* Download a resource specified by the relative resource @p path and
* register it if possible.
*
* If a corresponding local resource exists, an update will only be
* downloaded if it is not up-to-date according to checksum comparison.
* Whenever at the end we have a valid .rcc file it will be registered.
*
* @param path A relative resource path.
*
* @returns success
*/
Q_INVOKABLE bool downloadResource(const QString& path);
/**
* Shutdown DownloadManager instance.
*
* Aborts all currently running downloads.
*/
Q_INVOKABLE void shutdown();
/**
* Abort all currently running downloads.
*/
Q_INVOKABLE void abortDownloads();
#if 0
Q_INVOKABLE bool checkForUpdates(); // might be helpful later with other use-cases!
Q_INVOKABLE void registerLocalResources();
#endif
signals:
/** Emitted when a download error occurs.
*
* @param code enum NetworkError code.
* @param msg Error string.
*/
void error(int code, const QString& msg);
/** Emitted when a download has started.
*
* @param resource Relative resource path of the started download.
*/
void downloadStarted(const QString& resource);
/** Emitted during a running download.
*
* All values refer to the currently active sub-job.
*
* @param bytesReceived Downloaded bytes.
* @param bytesTotal Total bytes to download.
*/
void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
/** Emitted when a download has finished.
*
* Also emitted in error cases.
*
* @param code DownloadFinishedCode. FIXME: when using DownloadFinishedCode
* instead of int the code will not be passed to the QML layer,
* use QENUMS?
*/
void downloadFinished(int code);
/** Emitted when a resource has been registered.
*
* @param resource Relative resource path of the registered resource.
*
* @sa voicesRegistered
*/
void resourceRegistered(const QString& resource);
/** Emitted when voices resources for current locale have been registered.
*
* Convenience signal and special case of resourceRegistered.
*
* @sa resourceRegistered
*/
void voicesRegistered();
};
#endif /* DOWNLOADMANAGER_H */
diff --git a/src/core/File.cpp b/src/core/File.cpp
index 00169b0bf..eb2707ff1 100644
--- a/src/core/File.cpp
+++ b/src/core/File.cpp
@@ -1,132 +1,155 @@
/* GCompris - File.cpp
*
* Copyright (C) 2014,2015 Holger Kaelberer <holger.k@elberer.de>
*
* Authors:
* Holger Kaelberer <holger.k@elberer.de>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
#include "File.h"
#include <QFile>
#include <QDir>
#include <QString>
#include <QTextStream>
-#include <QQmlComponent>
File::File(QObject *parent) : QObject(parent)
{
}
QString File::name() const
{
return m_name;
}
-QString File::sanitizeUrl(const QString &str)
+QString File::sanitizeUrl(const QString &url)
{
- QString target(str);
+ QString target(url);
// make sure we strip off invalid URL schemes:
if (target.startsWith(QLatin1String("file://")))
target.remove(0, 7);
else if (target.startsWith(QLatin1String("qrc:/")))
target.remove(0, 3);
return target;
}
void File::setName(const QString &str)
{
QString target = sanitizeUrl(str);
if (target != m_name) {
m_name = target;
emit nameChanged();
}
}
QString File::read(const QString& name)
{
if (!name.isEmpty())
setName(name);
if (m_name.isEmpty()){
emit error("source is empty");
return QString();
}
QFile file(m_name);
QString fileContent;
if (file.open(QIODevice::ReadOnly) ) {
QString line;
QTextStream t(&file);
/* Force utf-8 : for some languages, it seems to be loaded in other
encoding even if the file is in utf-8 */
t.setCodec("UTF-8");
do {
line = t.readLine();
fileContent += line;
} while (!line.isNull());
file.close();
} else {
emit error("Unable to open the file");
return QString();
}
return fileContent;
}
bool File::write(const QString& data, const QString& name)
{
if (!name.isEmpty())
setName(name);
if (m_name.isEmpty()) {
emit error("source is empty");
return false;
}
QFile file(m_name);
if (!file.open(QFile::WriteOnly | QFile::Truncate)) {
emit error("could not open file " + m_name);
return false;
}
QTextStream out(&file);
out << data;
file.close();
return true;
}
-void File::init()
+bool File::append(const QString& data, const QString& name)
{
- qmlRegisterType<File>("GCompris", 1, 0, "File");
+ if (!name.isEmpty())
+ setName(name);
+
+ if (m_name.isEmpty()) {
+ emit error("source is empty");
+ return false;
+ }
+
+ QFile file(m_name);
+ if (!file.open(QFile::WriteOnly | QFile::Append)) {
+ emit error("could not open file " + m_name);
+ return false;
+ }
+
+ QTextStream out(&file);
+ out << data;
+
+ file.close();
+
+ return true;
}
bool File::exists(const QString& path)
{
return QFile::exists(sanitizeUrl(path));
}
bool File::mkpath(const QString& path)
{
QDir dir;
return dir.mkpath(dir.filePath(sanitizeUrl(path)));
}
+
+bool File::rmpath(const QString& path)
+{
+ return QFile::remove(sanitizeUrl(path));
+}
diff --git a/src/core/File.h b/src/core/File.h
index 04a2a9b5d..97181d2b8 100644
--- a/src/core/File.h
+++ b/src/core/File.h
@@ -1,116 +1,133 @@
/* GCompris - File.h
*
* Copyright (C) 2014,2015 Holger Kaelberer <holger.k@elberer.de>
*
* Authors:
* Holger Kaelberer <holger.k@elberer.de>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
#ifndef FILE_H
#define FILE_H
#include <QObject>
#include <QString>
/**
* @class File
* @short A helper component for accessing local files from QML.
* @ingroup components
*
*/
class File : public QObject
{
Q_OBJECT
/**
* Filename
*
* Accepted are absolute paths and URLs starting with the schemes
* 'file://' and 'qrc://'.
*/
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
public:
/**
* Constructor
*/
explicit File(QObject *parent = 0);
/**
* Reads contents of a file.
*
* @param name [optional] Filename to read from. If omitted reads from
* the file specified by the member name.
* @returns Whole file contents.
* @sa name
*/
Q_INVOKABLE QString read(const QString& name = QString());
/**
* Writes @p data to a file.
*
* @param data Text data to write.
* @param name [optional] Filename to write to. If omitted writes to
* the file specified by the member name.
* @returns success of the operation.
* @sa name
*/
Q_INVOKABLE bool write(const QString& data, const QString& name = QString());
+ /**
+ * Appends @p data to a file.
+ *
+ * @param data Text data to append.
+ * @param name [optional] Filename to append to. If omitted writes to
+ * the file specified by the member name.
+ * @returns success of the operation.
+ * @sa name
+ */
+ Q_INVOKABLE bool append(const QString& data, const QString& name = QString());
/**
* Checks whether file @p path exists.
*
* @param path Filename to check.
* @returns @c true if @p path exists, @c false otherwise.
*/
Q_INVOKABLE static bool exists(const QString& path);
/**
* Creates directory @p path.
*
* Creates also all parent directories necessary to create the directory.
*
* @param path Directory to create.
* @returns success
*/
Q_INVOKABLE static bool mkpath(const QString& path);
+ /**
+ * Deletes a file @p path.
+ *
+ * @param path file to delete.
+ * @returns success
+ */
+ Q_INVOKABLE static bool rmpath(const QString& path);
+
/// @cond INTERNAL_DOCS
- static void init();
QString name() const;
void setName(const QString &str);
/// @endcond
signals:
/**
* Emitted when the name changes.
*/
void nameChanged();
/**
* Emitted when an error occurs.
*
* @param msg Error message.
*/
void error(const QString& msg);
private:
QString m_name;
static QString sanitizeUrl(const QString& url);
};
#endif
diff --git a/src/core/GCAudio.qml b/src/core/GCAudio.qml
index ba52bf905..0d1d0028e 100644
--- a/src/core/GCAudio.qml
+++ b/src/core/GCAudio.qml
@@ -1,224 +1,224 @@
/* GCompris - GCAudio.qml
*
* Copyright (C) 2014 Johnny Jazeix <jazeix@gmail.com>
*
* Authors:
* Johnny Jazeix <jazeix@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import QtMultimedia 5.0
import GCompris 1.0
/**
* A QML component for audio playback.
* @ingroup components
*
* Wrapper component around QtQuick's Audio element, handling all audio
* playback in GCompris uniformly.
*
* It maintains a queue of audio-sources (@ref files) that are played back
* sequentially, to which the user can enqueue files that should be scheduled
* for playback.
*
* To make sure an audio voice will be localized, replace the locale part
* of the file by '$LOCALE'.
*
* To makes sure that all audio sources are normalized with respect to
* ApplicationInfo.CompressedAudio replace the 'ogg' part of the file by
* '$CA'.
*
* @inherit QtQuick.Item
*/
Item {
id: gcaudio
/**
* type:bool
* Whether audio should be muted.
*/
property bool muted
/**
* type:url
* URL to the audio source to be played back.
*/
property alias source: audio.source
/**
* type:string
* Detailed error message in case of playback errors.
*/
property alias errorString: audio.errorString
/**
* type:var
* Current playback state.
*
* Possible values taken from Audio.status
*/
property var playbackState: (audio.error == Audio.NoError) ?
audio.playbackState : Audio.StoppedState;
/**
* type:list
* Playback queue.
*/
property var files: []
/**
* Emitted in case of error.
*/
signal error
/**
* Emitted when playback of all scheduled audio sources has finished.
*/
signal done
/**
* When mute is changed we set the volume to 0 to mute a potential playing
* sound.
*/
onMutedChanged: muted ? audio.volume = 0 : audio.volume = 1
/**
* Plays back the audio resource @p file.
*
* @param type:string file [optional] URL to an audio source.
* @returns @c true if playback has been started, @c false if file does not
* exist or audio is muted
*/
function play(file) {
if(!fileId.exists(file) || muted)
return false
if(file) {
// Setting the source to "" on Linux fix a case where the sound is no more played if you play twice the same sound in a row
source = ""
source = file
}
if(!muted) {
audio.play()
}
return true
}
/**
* Stops audio playback.
*/
function stop() {
if(audio.playbackState != Audio.StoppedState)
audio.stop()
}
/**
* Schedules a @p file for audio playback.
*
* If there is no playback currently running, the new source will be
* played back immediately. Otherwise it is appended to the file queue of
* sources.
*
* @param type:string file File to the audio file to be played back.
* @returns @c true upon success, or @c false if @p file does not exist or
* audio is muted
*/
function append(file) {
if(!fileId.exists(file) || muted)
return false
if(audio.playbackState !== Audio.PlayingState
|| audio.status === Audio.EndOfMedia
|| audio.status === Audio.NoMedia
|| audio.status === Audio.InvalidMedia) {
// Setting the source to "" on Linux fix a case where the sound is no more played
source = ""
source = file
files.push(file)
silenceTimer.start()
} else {
files.push(file)
}
return true
}
/**
* Adds a pause of the given duration in ms before playing of the next file.
*
* @param type:int duration_ms Pause in milliseconds.
*/
function silence(duration_ms) {
silenceTimer.interval = duration_ms
}
/**
* Flushes the list of scheduled files.
* @sa files
*/
function clearQueue() {
while(files.length > 0) {
files.pop();
}
}
/// @cond INTERNAL_DOCS
function _playNextFile() {
var nextFile = files.shift()
if(!nextFile || 0 === nextFile.length) {
audio.source = ""
gcaudio.done()
} else {
audio.source = ""
audio.source = nextFile
if(!muted)
audio.play()
}
}
Audio {
id: audio
onError: {
// This file cannot be played, remove it from the source asap
source = ""
if(files.length)
silenceTimer.start()
else
gcaudio.error()
}
onStopped: {
if(files.length)
silenceTimer.start()
else
gcaudio.done()
}
}
Timer {
id: silenceTimer
repeat: false
onTriggered: {
interval = 0
_playNextFile()
}
}
File {
id: fileId
}
/// @endcond
}
diff --git a/src/core/GCButtonCancel.qml b/src/core/GCButtonCancel.qml
index 92dc03892..523b69471 100644
--- a/src/core/GCButtonCancel.qml
+++ b/src/core/GCButtonCancel.qml
@@ -1,63 +1,63 @@
/* GCompris - GCButtonCancel.qml
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
/**
* A QML component representing GCompris' cancel button.
* @ingroup components
*
* @inherit QtQuick.Image
*/
Image {
id: cancel
source: "qrc:/gcompris/src/core/resource/cancel.svg";
anchors.right: parent.right
anchors.top: parent.top
smooth: true
sourceSize.width: 60 * ApplicationInfo.ratio
anchors.margins: 10
signal close
SequentialAnimation {
id: anim
running: true
loops: Animation.Infinite
NumberAnimation {
target: cancel
property: "rotation"
from: -10; to: 10
duration: 500
easing.type: Easing.InOutQuad
}
NumberAnimation {
target: cancel
property: "rotation"
from: 10; to: -10
duration: 500
easing.type: Easing.InOutQuad }
}
MouseArea {
anchors.fill: parent
onClicked: close()
}
}
diff --git a/src/core/GCButtonScroll.qml b/src/core/GCButtonScroll.qml
index dd64c5ed6..6ff46b4a5 100644
--- a/src/core/GCButtonScroll.qml
+++ b/src/core/GCButtonScroll.qml
@@ -1,74 +1,74 @@
/* GCompris - GCButtonScroll.qml
*
* Copyright (C) 2017 Timothée Giet <animtim@gcompris.net>
* 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Timothée Giet <animtim@gcompris.net>
* Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.2
import GCompris 1.0
/**
* A QML component representing GCompris' scroll buttons.
* @ingroup components
*
* @inherit QtQuick.Image
*/
Rectangle {
id: scrollButtons
color: "#00000000"
width: (isHorizontal ? 110 : 50) * ApplicationInfo.ratio
height: (isHorizontal ? 50 : 110) * ApplicationInfo.ratio
signal up
signal down
property bool upVisible: false
property bool downVisible: false
property bool isHorizontal: false
property real heightRatio: isHorizontal ? (50 / 110) : (110 / 50)
property real widthRatio: 1 / heightRatio
BarButton {
id: scrollUp
width: isHorizontal ? parent.height : parent.width
height: width
source: "qrc:/gcompris/src/core/resource/scroll_down.svg";
sourceSize.width: scrollUp.width
sourceSize.height: scrollUp.height
rotation: 180
anchors.top: isHorizontal ? undefined : parent.top
anchors.left: isHorizontal ? parent.left : undefined
onClicked: up()
visible: upVisible
}
BarButton {
id: scrollDown
width: isHorizontal ? parent.height : parent.width
height: width
source: "qrc:/gcompris/src/core/resource/scroll_down.svg";
sourceSize.width: scrollDown.width
sourceSize.height: scrollDown.height
anchors.bottom: parent.bottom
anchors.right: isHorizontal ? parent.right : undefined
onClicked: down()
visible: downVisible
}
}
diff --git a/src/core/GCButtonStyle.qml b/src/core/GCButtonStyle.qml
index fb9e86ea7..722c4e918 100644
--- a/src/core/GCButtonStyle.qml
+++ b/src/core/GCButtonStyle.qml
@@ -1,142 +1,142 @@
/* GCompris - GCButtonStyle.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import QtQuick.Controls 1.5
import QtQuick.Controls.Styles 1.4
import GCompris 1.0
/**
* Provides styling for GCompris' Buttons.
* @ingroup components
*
* @inherit QtQuick.Controls.Styles.ButtonStyle
*/
ButtonStyle {
/**
* type:real
* Fixed font size of the label in pt.
*
* Set to a value > 0 for enforcing a fixed font.pointSize for the label,
* that won't be updated with ApplicationSettings.baseFontSize.
* @sa ApplicationSettings.baseFontSize, GCText.fixFontSize
*/
property real fixedFontSize: -1
/**
* type:string
* theme of the button. For now, three themes are accepted: "light" and "dark" and "highContrast"
*
* Default is dark.
*/
property string theme: "dark"
/**
* type:var
* existing themes for the button.
* A theme is composed of:
* the colors of the button when selected: selectedColorGradient0 and selectedColorGradient1.
* the colors of the button when not selected: backgroundColorGradient0 and backgroundColorGradient1.
* the button's border color
* the text color
*/
property var themes: {
"dark": {
backgroundColorGradient0: "#23373737",
selectedColorGradient0: "#C03ACAFF",
backgroundColorGradient1: "#13373737",
selectedColorGradient1: "#803ACAFF",
borderColor: "#FF373737",
textColor: "#FF373737"
},
"light": {
backgroundColorGradient0: "#42FFFFFF",
selectedColorGradient0: "#C03ACAFF",
backgroundColorGradient1: "#23FFFFFF",
selectedColorGradient1: "#803ACAFF",
borderColor: "white",
textColor: "white"
},
"highContrast": {
backgroundColorGradient0: "#EEFFFFFF",
selectedColorGradient0: "#C03ACAFF",
backgroundColorGradient1: "#AAFFFFFF",
selectedColorGradient1: "#803ACAFF",
borderColor: "white",
textColor: "373737"
}
}
property string textSize: "regular"
property var textSizes: {
"regular": {
fontSize: 14,
fontBold: false
},
"subtitle": {
fontSize: 16,
fontBold: true
},
"title": {
fontSize: 24,
fontBold: true
}
}
property bool selected: false
background: Rectangle {
border.width: control.activeFocus ? 4 : 2
border.color: themes[theme].borderColor
radius: 10
gradient: Gradient {
GradientStop { position: 0 ; color: (control.pressed || selected) ? themes[theme].selectedColorGradient0 : themes[theme].backgroundColorGradient0 }
GradientStop { position: 1 ; color: (control.pressed || selected) ? themes[theme].selectedColorGradient1 : themes[theme].backgroundColorGradient1 }
}
}
label: Item {
id: labelItem
anchors.fill: parent
implicitWidth: labelText.implicitWidth
implicitHeight: labelText.implicitHeight
GCText {
id: labelText
color: themes[theme].textColor
text: control.text
fontSize: textSizes[textSize].fontSize
font.bold: textSizes[textSize].fontBold
anchors.fill: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
wrapMode: Text.WordWrap
fontSizeMode: Text.Fit
Component.onCompleted: {
if (fixedFontSize > 0) {
labelText.fixFontSize = true;
labelText.fontSize = fixedFontSize;
}
}
}
}
}
diff --git a/src/core/GCComboBox.qml b/src/core/GCComboBox.qml
index ef7765145..f11aa1da0 100644
--- a/src/core/GCComboBox.qml
+++ b/src/core/GCComboBox.qml
@@ -1,322 +1,322 @@
/* GCompris - GCComboBox.qml
*
* Copyright (C) 2015 Johnny Jazeix <jazeix@gmail.com>
*
* Authors:
* Johnny Jazeix <jazeix@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import QtQuick.Controls 1.5
import GCompris 1.0
/**
* A QML component unifying comboboxes in GCompris.
* @ingroup components
*
* GCComboBox contains a combobox and a label.
* When the combobox isn't active, it is displayed as a button containing the current value
* and the combobox label (its description).
* Once the button is clicked, the list of all available choices is displayed.
* Also, above the list is the combobox label.
*
* Navigation can be done with keys and mouse/gestures.
* As Qt comboboxes, you can either have a js Array or a Qml model as model.
* GCComboBox should now be used wherever you'd use a QtQuick combobox. It has
* been decided to implement comboboxes ourselves in GCompris because of
* some integration problems on some OSes (native dialogs unavailable).
*/
Item {
id: gccombobox
focus: true
width: parent.width
height: flow.height
/**
* type:Item
* Where the list containing all choices will be displayed.
* Should be the dialogActivityConfig item if used on config.
*/
property Item background
/**
* type:int
* Current index of the combobox.
*/
property int currentIndex: -1
/**
* type:string
* Current text displayed in the combobox when inactive.
*/
property string currentText
/**
* type:alias
* Model for the list (user has to specify one).
*/
property alias model: gridview.model
/**
* type:string
* Text besides the combobox, used to describe what the combobox is for.
*/
property string label
/**
* type:bool
* Internal value.
* If model is an js Array, we access data using modelData and [] else qml Model, we need to use model and get().
*/
readonly property bool isModelArray: model.constructor === Array
// start and stop trigs the animation
signal start
signal stop
// emitted at stop animation end
signal close
onCurrentIndexChanged: {
currentText = isModelArray ? model[currentIndex].text : (model && model.get(currentIndex) ? model.get(currentIndex).text : "")
}
/**
* type:Flow
* Combobox display when inactive: the button with current choice and its label besides.
*/
Flow {
id: flow
width: parent.width
spacing: 5 * ApplicationInfo.ratio
Rectangle {
id: button
visible: true
// Add radius to add some space between text and borders
implicitWidth: Math.max(200, currentTextBox.width+radius)
implicitHeight: 50 * ApplicationInfo.ratio
border.width: 2
border.color: "#373737"
radius: 10
gradient: Gradient {
GradientStop { position: 0 ; color: mouseArea.pressed ? "#C03ACAFF" : "#23373737" }
GradientStop { position: 1 ; color: mouseArea.pressed ? "#803ACAFF" : "#13373737" }
}
// Current value of combobox
GCText {
id: currentTextBox
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
text: currentText
fontSize: mediumSize
color: "#373737"
}
MouseArea {
id: mouseArea
anchors.fill: parent
onReleased: {
popup.visible = true
}
}
}
Item {
width: labelText.width
height: button.height
GCText {
id: labelText
text: label
anchors.verticalCenter: parent.verticalCenter
fontSize: mediumSize
wrapMode: Text.WordWrap
}
}
}
/**
* type:Item
* Combobox display when active: header with the description and the gridview containing all the available choices.
*/
Item {
id: popup
visible: false
width: parent.width
height: parent.height
parent: background
z: 100
focus: visible
// Forward event to activity if key pressed is not one of the handled key
// (ctrl+F should still resize the window for example)
Keys.onPressed: {
if(event.key !== Qt.Key_Back) {
background.currentActivity.Keys.onPressed(event)
}
}
Keys.onReleased: {
if(event.key === Qt.Key_Back) {
// Keep the old value
discardChange();
hidePopUpAndRestoreFocus();
event.accepted = true
}
}
Keys.onRightPressed: gridview.moveCurrentIndexRight();
Keys.onLeftPressed: gridview.moveCurrentIndexLeft();
Keys.onDownPressed: gridview.moveCurrentIndexDown();
Keys.onUpPressed: gridview.moveCurrentIndexUp();
Keys.onEscapePressed: {
// Keep the old value
discardChange();
hidePopUpAndRestoreFocus();
}
Keys.onEnterPressed: {
acceptChange();
hidePopUpAndRestoreFocus();
}
Keys.onReturnPressed: {
acceptChange();
hidePopUpAndRestoreFocus();
}
Keys.onSpacePressed: {
acceptChange();
hidePopUpAndRestoreFocus();
}
// Don't accept the list value, restore previous value
function discardChange() {
if(isModelArray) {
for(var i = 0 ; i < model.count ; ++ i) {
if(model[currentIndex].text === currentText) {
currentIndex = i;
break;
}
}
}
else {
for(var i = 0 ; i < model.length ; ++ i) {
if(model.get(currentIndex).text === currentText) {
currentIndex = i;
break;
}
}
}
gridview.currentIndex = currentIndex;
}
// Accept the change. Updates the currentIndex and text of the button
function acceptChange() {
currentIndex = gridview.currentIndex;
currentText = isModelArray ? model[currentIndex].text : (model && model.get(currentIndex) ? model.get(currentIndex).text : "")
}
function hidePopUpAndRestoreFocus() {
popup.visible = false;
// Restore focus on previous activity for keyboard input
background.currentActivity.forceActiveFocus();
}
Rectangle {
id: listBackground
anchors.fill: parent
radius: 10
color: "grey"
Rectangle {
id : headerDescription
z: 10
width: gridview.width
height: gridview.elementHeight
GCText {
text: label
fontSize: mediumSize
wrapMode: Text.WordWrap
anchors.horizontalCenter: parent.horizontalCenter
}
GCButtonCancel {
id: discardIcon
anchors.right: headerDescription.right
anchors.top: headerDescription.top
MouseArea {
anchors.fill: parent
onClicked: {
popup.acceptChange();
popup.hidePopUpAndRestoreFocus();
}
}
}
}
GridView {
id: gridview
z: 4
readonly property int elementHeight: 40 * ApplicationInfo.ratio
// each element has a 300 width size minimum. If the screen is larger than it,
// we do a grid with cases with 300px for width at minimum.
// If you have a better idea/formula to have a different column number, don't hesitate, change it :).
readonly property int numberOfColumns: Math.max(1, Math.floor(width / (300 * ApplicationInfo.ratio)))
contentHeight: isModelArray ? elementHeight*model.count/numberOfColumns : elementHeight*model.length/numberOfColumns
width: listBackground.width
height: listBackground.height-headerDescription.height
currentIndex: gccombobox.currentIndex
flickableDirection: Flickable.VerticalFlick
clip: true
anchors.top: headerDescription.bottom
cellWidth: width / numberOfColumns
cellHeight: elementHeight
delegate: Component {
Rectangle {
width: gridview.cellWidth
height: gridview.elementHeight
color: GridView.isCurrentItem ? "darkcyan" : "beige"
border.width: GridView.isCurrentItem ? 3 : 2
radius: 5
Image {
id: isSelectedIcon
visible: parent.GridView.isCurrentItem
source: "qrc:/gcompris/src/core/resource/apply.svg"
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
anchors.leftMargin: 10
sourceSize.width: (gridview.elementHeight * 0.8)
}
GCText {
id: textValue
text: isModelArray ? modelData.text : model.text
anchors.centerIn: parent
}
MouseArea {
anchors.fill: parent
onClicked: {
currentIndex = index
popup.acceptChange();
popup.hidePopUpAndRestoreFocus();
}
}
}
}
}
}
}
}
diff --git a/src/core/GCCreationHandler.qml b/src/core/GCCreationHandler.qml
new file mode 100644
index 000000000..7953dca62
--- /dev/null
+++ b/src/core/GCCreationHandler.qml
@@ -0,0 +1,358 @@
+/* GCompris - GCCreationHandler.qml
+ *
+ * Copyright (C) 2018 Aman Kumar Gupta <gupta2140@gmail.com>
+ *
+ * Authors:
+ * Aman Kumar Gupta <gupta2140@gmail.com>
+ *
+ * This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+ */
+
+import QtQuick 2.6
+import QtQuick.Controls 1.5
+import GCompris 1.0
+import QtQuick.Controls.Styles 1.4
+import "qrc:/gcompris/src/core/core.js" as Core
+
+Rectangle {
+ id: creationHandler
+
+ width: parent.width
+ height: parent.height
+ color: "#ABCDEF"
+ border.color: "white"
+ border.width: 2
+ radius: 20
+ visible: false
+ z: 2000
+
+ signal close
+ signal fileLoaded(var data, var filePath)
+
+ onClose: {
+ fileNameInput.focus = false
+ fileNameInput.text = ""
+ visible = false
+ viewContainer.selectedFileIndex = -1
+ creationsList.flick(0, 1400)
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: viewContainer.selectedFileIndex = -1
+ }
+
+
+ property var dataToSave
+ property bool isSaveMode: false
+ readonly property string activityName: ActivityInfoTree.currentActivity.name.split('/')[0]
+ readonly property string sharedDirectoryPath: ApplicationSettings.userDataPath + "/" + activityName + "/"
+ readonly property string fileSavePath: "file://" + sharedDirectoryPath + '/' + fileNameInput.text + ".json"
+
+ ListModel {
+ id: fileNames
+ }
+
+ Directory {
+ id: directory
+ }
+
+ File {
+ id: file
+ onError: console.error("File error: " + msg);
+ }
+
+ JsonParser {
+ id: parser
+ onError: console.error("Error parsing JSON: " + msg);
+ }
+
+ Loader {
+ id: replaceFileDialog
+ sourceComponent: GCDialog {
+ parent: activity.main
+ message: qsTr("A file with this name already exists. Do you want to replace it?")
+ button1Text: qsTr("Yes")
+ button2Text: qsTr("No")
+ onButton1Hit: {
+ writeData()
+ active = false
+ }
+ onButton2Hit: active = false
+ }
+ anchors.fill: parent
+ focus: true
+ active: false
+ onStatusChanged: if (status == Loader.Ready) item.start()
+ }
+
+ function refreshWindow(filterText) {
+ var pathExists = file.exists(sharedDirectoryPath)
+ if(!pathExists)
+ return
+
+ fileNames.clear()
+
+ var files = directory.getFiles(sharedDirectoryPath)
+ for(var i = 0; i < files.length; i++) {
+ if(filterText === undefined || filterText === "" ||
+ (files[i].toLowerCase()).indexOf(filterText) !== -1)
+ fileNames.append({ "name": files[i] })
+ }
+ }
+
+ function loadWindow() {
+ creationHandler.visible = true
+ creationHandler.isSaveMode = false
+ fileNameInput.forceActiveFocus()
+ refreshWindow()
+ }
+
+ function loadFile(fileName) {
+ var filePath = "file://" + sharedDirectoryPath + fileNames.get(viewContainer.selectedFileIndex).name
+ var data = parser.parseFromUrl(filePath)
+ creationHandler.fileLoaded(data, filePath)
+ creationHandler.close()
+ }
+
+ function deleteFile() {
+ var filePath = "file://" + sharedDirectoryPath + fileNames.get(viewContainer.selectedFileIndex).name
+ if(file.rmpath(filePath)) {
+ Core.showMessageDialog(creationHandler,
+ qsTr("%1 deleted successfully!").arg(filePath),
+ qsTr("Ok"), null, "", null, null);
+ }
+ else {
+ Core.showMessageDialog(creationHandler,
+ qsTr("Unable to delete %1!").arg(filePath),
+ qsTr("Ok"), null, "", null, null);
+ }
+
+ viewContainer.selectedFileIndex = -1
+ refreshWindow()
+ }
+
+ function saveWindow(data) {
+ creationHandler.visible = true
+ creationHandler.isSaveMode = true
+ creationHandler.dataToSave = data
+ fileNameInput.forceActiveFocus()
+ refreshWindow()
+ }
+
+ function saveFile() {
+ if(activityName === "" || fileNameInput.text === "")
+ return
+
+ if(!file.exists(sharedDirectoryPath))
+ file.mkpath(sharedDirectoryPath)
+
+ if(file.exists(fileSavePath)) {
+ replaceFileDialog.active = true
+ }
+ else
+ writeData()
+ }
+
+ function writeData() {
+ file.write(JSON.stringify(creationHandler.dataToSave), fileSavePath)
+ Core.showMessageDialog(creationHandler,
+ qsTr("Saved successfully!"),
+ qsTr("Ok"), null, "", null, null);
+ refreshWindow()
+ }
+
+ function searchFiles() {
+ viewContainer.selectedFileIndex = -1
+ refreshWindow(fileNameInput.text.toLowerCase())
+ }
+
+ TextField {
+ id: fileNameInput
+ width: parent.width / 2
+ font.pointSize: NaN
+ font.pixelSize: height * 0.6
+ height: saveButton.height
+ anchors.verticalCenter: saveButton.verticalCenter
+ anchors.left: parent.left
+ anchors.leftMargin: 20
+ verticalAlignment: TextInput.AlignVCenter
+ selectByMouse: true
+ maximumLength: 15
+ placeholderText: creationHandler.isSaveMode ? qsTr("Enter file name") : qsTr("Search")
+ onTextChanged: {
+ if(!creationHandler.isSaveMode)
+ searchFiles()
+ }
+ style: TextFieldStyle {
+ textColor: "black"
+ background: Rectangle {
+ border.color: "black"
+ border.width: 1
+ radius: fileNameInput.height / 4
+ }
+ }
+ }
+
+ Button {
+ id: saveButton
+ width: 70 * ApplicationInfo.ratio
+ height: Math.min(creationHandler.height / 15, cancelButton.height)
+ visible: creationHandler.isSaveMode
+ text: qsTr("Save")
+ style: GCButtonStyle {
+ theme: "highContrast"
+ }
+ anchors.verticalCenter: cancelButton.verticalCenter
+ anchors.left: fileNameInput.right
+ anchors.leftMargin: 20
+ onClicked: saveFile()
+ }
+
+ property real cellWidth: 50 * ApplicationInfo.ratio
+ property real cellHeight: cellWidth * 1.3
+
+ Rectangle {
+ id: viewContainer
+ anchors.top: cancelButton.bottom
+ anchors.topMargin: 10
+ anchors.bottom: buttonRow.top
+ anchors.margins: 20
+ border.color: "black"
+ border.width: 2
+ radius: 20
+ anchors.left: parent.left
+ anchors.right: parent.right
+
+ property int selectedFileIndex: -1
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: viewContainer.selectedFileIndex = -1
+ }
+
+ GridView {
+ id: creationsList
+ model: fileNames
+ width: parent.width - 10
+ height: parent.height - 10
+ interactive: true
+ cellHeight: creationHandler.cellHeight
+ cellWidth: creationHandler.cellWidth
+ anchors.top: parent.top
+ anchors.topMargin: 10
+ anchors.left: parent.left
+ anchors.leftMargin: 5
+ clip: true
+
+ MouseArea {
+ anchors.fill: parent
+ enabled: !creationHandler.isSaveMode
+ onClicked: {
+ var itemIndex = creationsList.indexAt(mouseX, mouseY+creationsList.contentY)
+ if(itemIndex == -1)
+ viewContainer.selectedFileIndex = -1
+ else
+ viewContainer.selectedFileIndex = itemIndex
+ }
+ }
+
+ delegate: Item {
+ height: creationHandler.cellHeight
+ width: creationHandler.cellWidth
+ readonly property string fileName: fileName.text
+ Rectangle {
+ anchors.fill: parent
+ visible: index === viewContainer.selectedFileIndex
+ color: "#E77936"
+ opacity: 0.4
+ radius: 10
+ }
+
+ Image {
+ id: fileIcon
+ width: creationHandler.cellWidth
+ height: parent.height / 1.5
+ anchors.top: parent.top
+ anchors.topMargin: 3
+ source: "qrc:/gcompris/src/core/resource/file_icon.svg"
+ }
+
+ GCText {
+ id: fileName
+ anchors.top: fileIcon.bottom
+ height: parent.height - fileIcon.height - 15
+ width: creationHandler.cellWidth
+ font.pointSize: tinySize
+ fontSizeMode: Text.Fit
+ wrapMode: Text.WordWrap
+ horizontalAlignment: Text.AlignHCenter
+ // Exclude ".json" while displaying file name
+ text: name.slice(0, name.length - 5)
+ }
+ }
+ }
+ }
+
+ Row {
+ id: buttonRow
+ x: parent.width / 20
+ spacing: 20
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: 10
+ visible: !creationHandler.isSaveMode
+ Button {
+ id: loadButton
+ width: 70 * ApplicationInfo.ratio
+ height: creationHandler.height / 15
+ text: qsTr("Load")
+ enabled: viewContainer.selectedFileIndex != -1
+ style: GCButtonStyle {
+ theme: "highContrast"
+ }
+ onClicked: creationHandler.loadFile()
+ }
+
+ Button {
+ id: deleteButton
+ width: 70 * ApplicationInfo.ratio
+ height: creationHandler.height / 15
+ text: qsTr("Delete")
+ enabled: viewContainer.selectedFileIndex != -1
+ style: GCButtonStyle {
+ theme: "highContrast"
+ }
+ onClicked: deleteFile()
+ }
+ }
+
+ GCButtonCancel {
+ id: cancelButton
+ onClose: {
+ parent.close()
+ }
+ }
+
+ // The scroll buttons
+ GCButtonScroll {
+ anchors.right: viewContainer.right
+ anchors.rightMargin: 5 * ApplicationInfo.ratio
+ anchors.bottom: viewContainer.bottom
+ anchors.bottomMargin: 5 * ApplicationInfo.ratio
+ onUp: creationsList.flick(0, 1400)
+ onDown: creationsList.flick(0, -1400)
+ upVisible: creationsList.visibleArea.yPosition <= 0 ? false : true
+ downVisible: creationsList.visibleArea.yPosition + creationsList.visibleArea.heightRatio >= 1 ? false : true
+ }
+}
diff --git a/src/core/GCDialog.qml b/src/core/GCDialog.qml
index 5d458ac54..b7715d162 100644
--- a/src/core/GCDialog.qml
+++ b/src/core/GCDialog.qml
@@ -1,225 +1,225 @@
/* GCompris - GCDialog.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import QtQuick.Controls 1.5
import GCompris 1.0
/**
* A QML component for GCompris dialogs.
* @ingroup components
*
* Contains the following basic layout elements: Title (message), a GCompris
* cancel button (GCButtonCancel) at the top right and two optional buttons.
*
* Can be conveniently instantiated dynamically in conjunction with
* showMessageDialog from core.js.
*
* GCDialog should now be used wherever you'd use a QtQuick dialog. It has
* been decided to implement dialogs ourselves in GCompris because of
* missing translations of labels of Qt's standard buttons for some language
* supported by GCompris, as well as integration problems on some OSes
* (Sailfish OS).
*
* @inherit QtQuick.Item
* @sa showMessageDialog
*/
Item {
id: gcdialog
/**
* type:string
* Heading instruction text.
*/
property alias message: instructionTxt.textIn
/**
* type:string
* Label of the first button.
*/
property alias button1Text: button1.text
/**
* type:string
* Label of the second button.
*/
property alias button2Text: button2.text
/**
* Emitted when the dialog should be started.
*
* Triggers fading in.
*/
signal start
/**
* Emitted when the dialog should be stopped.
*
* Triggers fading out.
*/
signal stop
/**
* Emitted when the dialog has stopped.
*/
signal close
/**
* Emitted when the first button has been clicked.
*/
signal button1Hit
/**
* Emitted when the second button has been clicked.
*/
signal button2Hit
focus: true
opacity: 0
anchors {
fill: parent
}
onStart: opacity = 1
onStop: opacity = 0
onClose: destroy()
Behavior on opacity { NumberAnimation { duration: 200 } }
onOpacityChanged: opacity === 0 ? close() : null
z: 1500
Rectangle {
anchors.fill: parent
opacity: 0.8
color: "grey"
}
MultiPointTouchArea {
// Just to catch mouse events
anchors.fill: parent
}
/* Message */
Item {
id: instruction
anchors {
horizontalCenter: parent.horizontalCenter
top: parent.top
topMargin: buttonCancel.height
}
width: parent.width * 0.8
Rectangle {
id: instructionTxtBg
anchors.top: instruction.top
z: 1
width: parent.width
height: gcdialog.height - button1.height * 5
opacity: 0.9
radius: 10
border.width: 2
border.color: "white"
gradient: Gradient {
GradientStop { position: 0.0; color: "#fff" }
GradientStop { position: 0.9; color: "#fff" }
GradientStop { position: 1.0; color: "#ddd" }
}
Flickable {
id: flick
anchors.margins: 8
anchors.fill: parent
contentWidth: instructionTxt.contentWidth
contentHeight: instructionTxt.contentHeight
flickableDirection: Flickable.VerticalFlick
clip: true
GCText {
id: instructionTxt
fontSize: regularSize
color: "black"
// @FIXME This property breaks the wrapping
// horizontalAlignment: Text.AlignHCenter
// need to remove the anchors (left and right) else sometimes text is hidden on the side
width: instruction.width - 2*flick.anchors.margins
wrapMode: TextEdit.WordWrap
textFormat: TextEdit.RichText
z: 2
text: style + "<body>" + textIn + "</body>"
property string textIn
property string style: "<HEAD><STYLE type='text/css'>A {color: black;}</STYLE></HEAD>"
}
}
}
Button {
id: button1
width: parent.width
height: (visible ? 60 : 30) * ApplicationInfo.ratio
anchors {
horizontalCenter: parent.horizontalCenter
top: instructionTxtBg.bottom
topMargin: 10
}
style: GCButtonStyle {
theme: "highContrast"
}
visible: text != ""
onClicked: {
gcdialog.button1Hit()
gcdialog.stop()
}
}
Button {
id: button2
width: parent.width
height: (visible ? 60 : 30) * ApplicationInfo.ratio
anchors {
horizontalCenter: parent.horizontalCenter
top: button1.bottom
topMargin: 10
}
style: GCButtonStyle {
theme: "highContrast"
}
visible: text != ""
onClicked: {
gcdialog.button2Hit()
gcdialog.stop()
}
}
}
// Fixme not working, need to properly get the focus on this dialog
Keys.onEscapePressed: {
stop()
event.accepted = true;
}
// The cancel button
GCButtonCancel {
id: buttonCancel
onClose: parent.stop()
}
}
diff --git a/src/core/GCDialogCheckBox.qml b/src/core/GCDialogCheckBox.qml
index c6d5a5625..6cefe6d64 100644
--- a/src/core/GCDialogCheckBox.qml
+++ b/src/core/GCDialogCheckBox.qml
@@ -1,67 +1,67 @@
/* GCompris - GCDialogCheckBox.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import QtQuick.Controls 1.5
import QtQuick.Controls.Styles 1.4
import GCompris 1.0
/**
* GCompris' CheckBox component.
* @ingroup components
*
* @inherit QtQuick.Controls.CheckBox
*/
CheckBox {
id: checkBox
width: parent.width
/**
* type:int
* Font size of the label text.
* By default it is set to 16 i.e. GCText.mediumSize
*
*/
property int labelTextFontSize: 16
/**
* type:int
* Height of the indicator image.
*/
property int indicatorImageHeight: 50 * ApplicationInfo.ratio
style: CheckBoxStyle {
spacing: 10
indicator: Image {
sourceSize.height: indicatorImageHeight
property string suffix: control.enabled ? ".svg" : "_disabled.svg"
source:
control.checked ? "qrc:/gcompris/src/core/resource/apply" + suffix :
"qrc:/gcompris/src/core/resource/cancel" + suffix
}
label: GCText {
fontSize: labelTextFontSize
text: control.text
wrapMode: Text.WordWrap
width: parent.parent.width - 50 * ApplicationInfo.ratio - 10 * 2
}
}
}
diff --git a/src/core/GCSfx.qml b/src/core/GCSfx.qml
index d9ff27dba..9f2aa2c33 100644
--- a/src/core/GCSfx.qml
+++ b/src/core/GCSfx.qml
@@ -1,95 +1,95 @@
-/* GCompris - GCSoundEffect.qml
+/* GCompris - GCSfx.qml
*
* Copyright (C) 2018 Timothée Giet <animtim@gmail.com>
*
* Authors:
* Johnny Jazeix <jazeix@gmail.com> (GCAudio base, 2014)
* Timothée Giet <animtim@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import QtMultimedia 5.0
import GCompris 1.0
/**
* A QML component for sfx playback.
* @ingroup components
*
* Wrapper component around QtQuick's SoundEffect element, handling all sfx
* playback in GCompris uniformly.
*
*
* @inherit QtQuick.Item
*/
Item {
id: gcsfx
/**
* type:bool
* Whether sfx should be muted.
*/
property bool muted
/**
* type:url
* URL to the sfx source to be played back.
*/
property alias source: sfx.source
/**
* type:string
* Status of the fx player.
*/
property alias status: sfx.status
/**
* When mute is changed we set the volume to 0 to mute a potential playing
* sound.
*/
onMutedChanged: muted ? sfx.volume = 0 : sfx.volume = 1
/**
* Plays back the sfx resource @p file.
*
* @param type:string file [optional] URL to an sfx source.
* @returns @c true if playback has been started, @c false if file does not
* exist or sfx is muted
*/
function play(file) {
if(file) {
source = file
}
if(!muted) {
sfx.play()
}
}
/**
* Stops sfx playback.
*/
function stop() {
if(sfx.playing)
sfx.stop()
}
/// @cond INTERNAL_DOCS
SoundEffect {
id: sfx
}
/// @endcond
}
diff --git a/src/core/GCSingletonFontLoader.qml b/src/core/GCSingletonFontLoader.qml
index 378b6eb04..2239ca906 100644
--- a/src/core/GCSingletonFontLoader.qml
+++ b/src/core/GCSingletonFontLoader.qml
@@ -1,52 +1,52 @@
/* GCompris - GCSingletonFontLoader.qml
*
* Copyright (C) 2014 Johnny Jazeix <jazeix@gmail.com>
*
* Authors:
* Johnny Jazeix <jazeix@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
//QTBUG-34418, singletons require explicit import to load qmldir file
//https://qt-project.org/wiki/QmlStyling#6b81104b320e452a59cc3bf6857115ab
import "."
// FIXME: this triggers a doxygen error, why?
pragma Singleton
/**
* A QML singleton helper to load currently active font based on current font
* settings
* @ingroup infrastructure
*
* @inherit QtQuick.QtObject
* @sa ApplicationSettings.isEmbeddedFont, ApplicationSettings.font
*/
QtObject {
property QtObject fontLoader: ApplicationSettings.isEmbeddedFont ? sourceLoader : nameLoader
property QtObject fontSourceLoader: FontLoader {
id: sourceLoader
source: ApplicationSettings.isEmbeddedFont ? "resource/fonts/"+ApplicationSettings.font : ""
}
property QtObject fontNameLoader: FontLoader {
id: nameLoader
name: ApplicationSettings.font
}
}
diff --git a/src/core/GCSlider.qml b/src/core/GCSlider.qml
index 6a9ba910f..856f2a93f 100644
--- a/src/core/GCSlider.qml
+++ b/src/core/GCSlider.qml
@@ -1,62 +1,62 @@
/* GCompris - GCSlider.qml
*
* Copyright (C) 2018 Alexis Breton <alexis95150@gmail.com>
*
* Authors:
* Alexis Breton <alexis95150@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import QtQuick.Controls 1.5
/**
* A Slider component with GCompris' style.
* @ingroup components
*
* Provides the "scrollEnabled" property to replace "wheelEnabled"
* that is only available with QtQuick.Controls > 1.6. If using
* QtQuick.Controls >= 1.6, please use the built-in "wheelEnabled" property
*
* @inherit QtQuick.Controls.Slider
*/
Slider {
/**
* type:bool
* Set to false to disable changing the value by scrolling the mouse.
* Default is true.
*
* If false, the mouse scrolling is disabled while hovering the slider.
*
* Deprecated if using QtQuick.Controls >= 1.6
*/
property bool scrollEnabled : true
style: GCSliderStyle {}
stepSize: 1.0
tickmarksEnabled: true
// Removes scrolling when hovering sliders if scrollEnabled = false
MouseArea {
anchors.fill: parent
enabled: !scrollEnabled
onWheel: {}
onPressed: mouse.accepted = false
onReleased: mouse.accepted = false
}
}
diff --git a/src/core/GCSliderStyle.qml b/src/core/GCSliderStyle.qml
index fb6c3db3d..11191ab28 100644
--- a/src/core/GCSliderStyle.qml
+++ b/src/core/GCSliderStyle.qml
@@ -1,62 +1,62 @@
/* GCompris - GCSliderStyle.qml
*
* Copyright (C) 2014 Holger Kaelberer <holger.k@elberer.de>
*
* Authors:
* Holger Kaelberer <holger.k@elberer.de>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import QtQuick.Controls 1.5
import QtQuick.Controls.Styles 1.4
import GCompris 1.0
/**
* Provides styling for GCompris sliders.
* @ingroup components
*
* @inherit QtQuick.Controls.Styles.SliderStyle
*/
SliderStyle {
groove: Item {
anchors.verticalCenter: parent.verticalCenter
implicitWidth: 250 * ApplicationInfo.ratio
implicitHeight: 8 * ApplicationInfo.ratio
Rectangle {
radius: height/2
anchors.fill: parent
border.width: 1
border.color: "#888"
gradient: Gradient {
GradientStop { color: "#bbb" ; position: 0 }
GradientStop { color: "#ccc" ; position: 0.6 }
GradientStop { color: "#ccc" ; position: 1 }
}
}
Item {
width: styleData.handlePosition
height: parent.height
Rectangle {
anchors.fill: parent
border.color: Qt.darker("#f8d600", 1.2)
radius: height/2
gradient: Gradient {
GradientStop {color: "#ffe85c"; position: 0}
GradientStop {color: "#f8d600"; position: 1.4}
}
}
}
}
}
diff --git a/src/core/GCText.qml b/src/core/GCText.qml
index ee55eb027..5a90d6aa3 100644
--- a/src/core/GCText.qml
+++ b/src/core/GCText.qml
@@ -1,133 +1,133 @@
/* GCompris - GCText.qml
*
* Copyright (C) 2014 Johnny Jazeix <jazeix@gmail.com>
*
* Authors:
* Johnny Jazeix <jazeix@gmail.com>
* Holger Kaelberer <holger.k@elberer.de>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "."
/**
* A QML component unifying text presentation in GCompris.
* @ingroup components
*
* GCText wraps QtQuick's Text to provide
*
* (1) a uniform font-family,<br/>
* (2) DPI based automatic font-scaling and<br/>
* (3) application-wide manual font-sizing.<br/>
*
* Activities should almost always use the @ref fontSize property to
* define font sizes, it implements both (2) and (3). <b>Do not</b> set
* @c font.pointSize directly, or GCText's automatic scaling will be
* deactivated. If you really need to enforce a fixed font size (which
* might be the case for dialogs) use the fixFontSize property.
*
* The xxxSize properties are meant to be enum-like values for often needed
* font sizes. (QtQuick does not support enum definitions on QML layer, cf.
* Qt issue #14861.)
*
* @inherit QtQuick.Text
* @sa GCSingletonFontLoader
*/
Text {
/**
* type:int
* Tiny font-size.
* Value: 10
*/
readonly property int tinySize: 10.0
/**
* type:int
* Small font-size.
* Value: 12
*/
readonly property int smallSize: 12.0
/**
* type:int
* Regular font-size.
* Value: 14
*/
readonly property int regularSize: 14.0
/**
* type:int
* Medium font-size.
* Value: 16
*/
readonly property int mediumSize: 16.0
/**
* type:int
* Large font-size.
* Value: 24
*/
readonly property int largeSize: 24.0
/**
* type:int
* Huge font-size.
* Value: 32
*/
readonly property int hugeSize: 32.0
/**
* type:bool
* Whether to not apply ApplicationSettings.baseFontSize.
*
* Set to true if you don't want to scale fonts. Used in some rare cases
* like for dialogs.
*/
property bool fixFontSize: false
/**
* type:int
* Font size wrapping font.pointSize and applying font-scaling.
*
* Font-sizes are best specified using the fontSize property, which
* wraps font.pointSize to take the DPI of the display into account.
* If font.pointSize is used directly text might appear to small on some
* devices.
*
* If you really need to specify font.pixelSize instead of pointSize,
* you need to clear font.pointSize explicitly with NaN:
*
* @code
* font.pointSize: NaN
* @endcode
*
* Default is 14.
*/
property int fontSize: 14
/**
* type:int
* Read only value of the calculated pointSize
*/
readonly property int pointSize: font.pointSize
font.pointSize: ((fixFontSize ? 0 : ApplicationSettings.baseFontSize)
+ fontSize) * ApplicationInfo.fontRatio
font.family: GCSingletonFontLoader.fontLoader.name
font.capitalization: ApplicationSettings.fontCapitalization
font.letterSpacing: ApplicationSettings.fontLetterSpacing
}
diff --git a/src/core/GComprisPlugin.cpp b/src/core/GComprisPlugin.cpp
new file mode 100644
index 000000000..d698959f2
--- /dev/null
+++ b/src/core/GComprisPlugin.cpp
@@ -0,0 +1,61 @@
+/* GCompris - GComprisPlugin.cpp
+ *
+ * Copyright (C) 2018 Johnny Jazeix <jazeix@gmail.com>
+ *
+ * Authors:
+ * Johnny Jazeix <jazeix@gmail.com>
+ *
+ * This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+ */
+#include "GComprisPlugin.h"
+#include "ApplicationInfo.h"
+#include "ActivityInfoTree.h"
+#include "ApplicationSettings.h"
+#include "File.h"
+#include "Directory.h"
+#include "DownloadManager.h"
+#include "synth/GSynth.h"
+#include <QQmlComponent>
+
+const int versionMajor = 1;
+const int versionMinor = 0;
+
+GComprisPlugin::GComprisPlugin(QObject *parent) :
+ QQmlExtensionPlugin(parent)
+{
+}
+
+void GComprisPlugin::registerTypes(const char *uri)
+{
+ qmlRegisterType<File>(uri, versionMajor, versionMinor,
+ "File");
+ qmlRegisterType<Directory>(uri, versionMajor, versionMinor,
+ "Directory");
+
+ qmlRegisterSingletonType<ApplicationInfo>(uri, versionMajor, versionMinor,
+ "ApplicationInfo", ApplicationInfo::applicationInfoProvider);
+
+ qmlRegisterSingletonType<QObject>(uri, versionMajor, versionMinor,
+ "ActivityInfoTree", ActivityInfoTree::menuTreeProvider);
+ qmlRegisterType<ActivityInfo>(uri, versionMajor, versionMinor, "ActivityInfo");
+
+ qmlRegisterSingletonType<ApplicationSettings>(uri, versionMajor, versionMinor,
+ "ApplicationSettings", ApplicationSettings::applicationSettingsProvider);
+ qmlRegisterSingletonType<DownloadManager>(uri, versionMajor, versionMinor,
+ "DownloadManager", DownloadManager::downloadManagerProvider);
+
+ qmlRegisterSingletonType<GSynth>(uri, versionMajor, versionMinor,
+ "GSynth", GSynth::synthProvider);
+
+}
diff --git a/src/activities/checkers_2players/Checkers2Players.qml b/src/core/GComprisPlugin.h
similarity index 51%
copy from src/activities/checkers_2players/Checkers2Players.qml
copy to src/core/GComprisPlugin.h
index 2de30afff..b80658b88 100644
--- a/src/activities/checkers_2players/Checkers2Players.qml
+++ b/src/core/GComprisPlugin.h
@@ -1,28 +1,42 @@
-/* GCompris - checkers_2players.qml
+/* GCompris - GComprisPlugin.h
*
- * Copyright (C) 2017 Johnny Jazeix <jazeix@gmail.com>
+ * Copyright (C) 2018 Johnny Jazeix <jazeix@gmail.com>
*
* Authors:
* Johnny Jazeix <jazeix@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
-import QtQuick 2.6
+#ifndef GCOMPRISPLUGIN_H
+#define GCOMPRISPLUGIN_H
-import "../../core"
-import "../checkers"
+#include <QQmlExtensionPlugin>
-Checkers {
- twoPlayers: true
-}
+/**
+ * A plugin that exposes GCompris to QML in the form of declarative items.
+ */
+class Q_DECL_EXPORT GComprisPlugin : public QQmlExtensionPlugin
+{
+ Q_OBJECT
+#if !defined(STATIC_PLUGIN_GCOMPRIS)
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
+#endif
+
+public:
+ explicit GComprisPlugin(QObject *parent = 0);
+
+ void registerTypes(const char *uri);
+};
+
+#endif
diff --git a/src/core/IntroButton.qml b/src/core/IntroButton.qml
index f2582824d..812e44cf8 100644
--- a/src/core/IntroButton.qml
+++ b/src/core/IntroButton.qml
@@ -1,81 +1,81 @@
/* GCompris - IntroButton.qml
*
* Copyright (C) 2018 Johnny Jazeix <jazeix@gmail.com>
*
* Authors:
* Johnny Jazeix <jazeix@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
/*
* A generic QML button for intro/tutorial in GCompris.
* Can probably be used at some other places.
*/
import QtQuick 2.6
Rectangle {
id: button
color: "#d8ffffff"
border.color: "#2a2a2a"
border.width: 3
radius: 8
property alias text: buttonText.text
signal clicked
GCText {
id: buttonText
width: parent.width
height: parent.height
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
wrapMode: Text.WordWrap
fontSizeMode: Text.Fit
}
MouseArea {
id: buttonArea
anchors.fill: parent
onClicked: parent.clicked()
}
states: [
State {
name: "notclicked"
PropertyChanges {
target: button
scale: 1.0
}
},
State {
name: "clicked"
when: buttonArea.pressed
PropertyChanges {
target: button
scale: 0.9
}
},
State {
name: "hover"
when: buttonArea.containsMouse
PropertyChanges {
target: button
scale: 1.1
}
}
]
Behavior on scale { NumberAnimation { duration: 70 } }
}
diff --git a/src/core/IntroMessage.qml b/src/core/IntroMessage.qml
index 39c4f04ba..15bd53845 100644
--- a/src/core/IntroMessage.qml
+++ b/src/core/IntroMessage.qml
@@ -1,156 +1,156 @@
/*GCompris - IntroMessage.qml
*
* Copyright (C) 2015 Siddhesh suthar <siddhesh.it@gmail.com>
*
* Authors:
*
* Siddhesh suthar <siddhesh.it@gmail.com>
* Sagar Chand Agarwal <atomsagar@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+* along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
/**
* A QML component for multi activity introduction in GCompris.
*
* Use IntroMessage when you want to present an introductory message to the
* user, that provides background information or gameplay hints.
*
* Contains the following basic layout elements: Introduction text (intro), a
* skip and an @c Next button to leave the introduction or navigate through it.
* The introDone signal is emitted when the introduction has finished and can
* be used to prepare the start of the activity.
*
* @ingroup components
* @inherit QtQuick.Item
*/
Item {
id: message
anchors.fill: parent
visible: index == -1 ? false : true
/**
* Emitted when the index of intro is equal to its length
* or when skipButton is clicked.
*/
signal introDone
/**
* The index of the intro array.
*
* Set to -1 to hide the IntroMessage item.
*/
property int index: 0
/**
* The texts array used as introduction.
*
* It has to be filled by the user when defining an IntroMessage item.
*/
property var intro;
property int textContainerWidth: 0.9 * parent.width
property int textContainerHeight: 0.75 * parent.height - nextButton.height
// to avoid clicking on the activity
MouseArea {
anchors.fill: parent
}
Rectangle {
id: introTextContainer
width: introText.width + 20
height: introText.height + 2
anchors.top: introText.top
anchors.horizontalCenter: introText.horizontalCenter
opacity: 0.9
color: "white"
border.color: "#87A6DD"
border.width: 6
radius: 10
}
GCText {
id: introText
anchors {
horizontalCenter: parent.horizontalCenter
top: parent.top
topMargin: 10
}
width: textContainerWidth
height: textContainerHeight
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
color: "black"
minimumPixelSize: 10
wrapMode: Text.WordWrap
fontSizeMode: Text.Fit
text: parent.index == -1 ? "" : parent.intro[parent.index]
}
IntroButton {
id: previousButton
width: parent.width / 4
height: 90
z: 5
anchors.right: nextButton.left
anchors.topMargin: 15
anchors.rightMargin: 15
anchors.top: introTextContainer.bottom
visible: index != 0
text: qsTr("Previous")
onClicked: --index
}
IntroButton {
id: nextButton
width: parent.width / 4
height: 90
z: 5
anchors.right: skipButton.left
anchors.topMargin: 15
anchors.rightMargin: 15
anchors.top: introTextContainer.bottom
visible: index != (intro.length - 1)
text: qsTr("Next")
onClicked: index++
}
IntroButton {
id: skipButton
width: parent.width / 4
height: 90
z: 5
anchors.right: parent.right
anchors.rightMargin: 15
anchors.topMargin: 15
anchors.top: introTextContainer.bottom
text: nextButton.visible ? qsTr("Skip") : qsTr("Start")
onClicked: {
index = -1
message.introDone()
}
}
}
diff --git a/src/core/JsonParser.qml b/src/core/JsonParser.qml
index 38d7472fa..6edf71348 100644
--- a/src/core/JsonParser.qml
+++ b/src/core/JsonParser.qml
@@ -1,108 +1,108 @@
/* GCompris - JsonParser.qml
*
* Copyright (C) 2014 Holger Kaelberer <holger.k@elberer.de>
*
* Authors:
* Holger Kaelberer <holger.k@elberer.de>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
/**
* A QML helper component for loading and validating JSON data.
* @ingroup components
*
* @inherit QtQuick.Item
*/
QtObject {
id: jsonparser
/**
* type:File
* File with json content to parse.
*/
property File jsonFile: File {
id: jsonfile
name: ""
onError: jsonparser.error(msg);
}
/**
* Emitted upon error.
*
* @param msg Error message.
*/
signal error(string msg);
/* public interface: */
/**
* Parse the passed json string and return a corresponding object.
*
* @param type:string json JSON string to parse.
* @param type:function validateFunc Function used to semantically validate
* the parsed json [optional].
* The function must have the signature
* <tt>bool validateFunc(jsonString)</tt>
* and return @c true if json string is semantically
* valid, @c false otherwise.
* @returns The object parsed from json if valid, @c null if json is
* syntactically or semantically invalid.
*/
function parseString(json, validateFunc)
{
var doc;
try {
doc = JSON.parse(json);
// validate if requested:
if (validateFunc !== undefined
&& !validateFunc(doc)) {
error("JsonParser: JSON is semantically invalid");
return null;
}
} catch(e) {
error("JsonParser: JSON is syntactically invalid: " + e);
return null;
}
return doc;
}
/**
* Parse a json string from the given url and return a corresponding
* object.
*
* @param type:string url Source URL for the json file to parse.
* Supported URL-schemes: file://, qrc://.
* @param type:functions validateFunc cf. @ref parseString
* @returns cf. @ref parseString
*/
function parseFromUrl(url, validateFunc)
{
var json = "'";
if (url.substring(0,3) == "qrc" || url.substring(0,4) == "file"
|| url.substring(0,1) == ":") {
json = jsonFile.read(url);
if (json != "")
return parseString(json, validateFunc);
} else if (url.substring(0,4) == "http")
error("http:// scheme not yet implemented");
else // unknown url scheme
error("Unknown url scheme in url parameter: " + url);
return null;
}
}
diff --git a/src/core/LanguageList.qml b/src/core/LanguageList.qml
index 39c72284d..3ac4346f9 100644
--- a/src/core/LanguageList.qml
+++ b/src/core/LanguageList.qml
@@ -1,85 +1,87 @@
/* GCompris - LanguageList.qml
*
* Copyright (C) 2014 Johnny Jazeix <jazeix@gmail.com>
*
* Authors:
* Johnny Jazeix <jazeix@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
/**
* Container object with a list of all available translations.
* @ingroup infrastructure
*
* Put here the locales for which we have a good enough translation.
*/
QtObject {
/**
* type:list
* List of language objects.
*
* A language object consists of the properties @c text (language string in
* the locales' language) and @c locale (locale string of the form
* aa_AA.UTF-8).
*
* The special purpose locale 'system' is used to refer to the system's
* standard locale.
*/
property var languages: [
{ "text": qsTr("Your system default"), "locale": "system" },
{ "text": "UK English", "locale": "en_GB.UTF-8" },
{ "text": "American English", "locale": "en_US.UTF-8" },
//{ "text": "български", "locale": "bg_BG.UTF-8" },
{ "text": "Brezhoneg", "locale": "br_FR.UTF-8" },
{"text": "Беларуская", "locale": "be_BY.UTF-8" },
{ "text": "Català", "locale": "ca_ES.UTF-8" },
//{ "text": "Česká", "locale": "cs_CZ.UTF-8" },
//{ "text": "Dansk", "locale": "da_DK.UTF-8" },
{ "text": "Deutsch", "locale": "de_DE.UTF-8" },
{ "text": "Ελληνικά", "locale": "el_GR.UTF-8" },
{ "text": "Español", "locale": "es_ES.UTF-8" },
{ "text": "Eesti", "locale": "et_EE.UTF-8" },
+ { "text": "Euskara", "locale": "eu_ES.UTF-8" },
{ "text": "Suomi", "locale": "fi_FI.UTF-8" },
{ "text": "Français", "locale": "fr_FR.UTF-8" },
{ "text": "Gaeilge", "locale": "ga_IE.UTF-8" },
{ "text": "Gàidhlig", "locale": "gd_GB.UTF-8" },
{ "text": "Galego", "locale": "gl_ES.UTF-8" },
{ "text": "हिन्दी", "locale": "hi_IN.UTF-8" },
- //{ "text": "Magyar", "locale": "hu_HU.UTF-8" },
+ { "text": "Magyar", "locale": "hu_HU.UTF-8" },
{ "text": "Indonesia", "locale": "id_ID.UTF-8" },
{ "text": "Italiano", "locale": "it_IT.UTF-8" },
//{ "text": "Lietuvių", "locale": "lt_LT.UTF-8" },
//{ "text": "Latviešu", "locale": "lv_LV.UTF-8" },
+ { "text": "മലയാളം", "locale": "ml_IN.UTF-8" },
{ "text": "Nederlands", "locale": "nl_NL.UTF-8" },
{ "text": "Norsk (nynorsk)", "locale": "nn_NO.UTF-8" },
{ "text": "Polski", "locale": "pl_PL.UTF-8" },
{ "text": "Português", "locale": "pt_PT.UTF-8" },
{ "text": "Português do Brasil", "locale": "pt_BR.UTF-8" },
{ "text": "Română", "locale": "ro_RO.UTF-8" },
{ "text": "Русский", "locale": "ru_RU.UTF-8" },
{ "text": "Slovenský", "locale": "sk_SK.UTF-8" },
{ "text": "Slovenski", "locale": "sl_SI.UTF-8" },
//{ "text": "црногорски jeзик", "locale": "sr_ME.UTF-8" },
{ "text": "Svenska", "locale": "sv_FI.UTF-8" },
//{ "text": "தமிழ்", "locale": "ta_IN.UTF-8" },
//{ "text": "ไทย", "locale": "th_TH.UTF-8" },
{ "text": "Türk", "locale": "tr_TR.UTF-8" },
{ "text": "український", "locale": "uk_UA.UTF-8" },
{ "text": "中文(简体)", "locale": "zh_CN.UTF-8" },
{ "text": "繁體中文", "locale": "zh_TW.UTF-8" }
]
}
diff --git a/src/core/Loading.qml b/src/core/Loading.qml
index ab2c1714c..63c672c52 100644
--- a/src/core/Loading.qml
+++ b/src/core/Loading.qml
@@ -1,117 +1,117 @@
/* GCompris - Loading.qml
*
* Copyright (C) 2015 Holger Kaelberer <holger.k@elberer.de>
*
* Authors:
* Holger Kaelberer <holger.k@elberer.de>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import QtQuick.Controls 1.5
import GCompris 1.0
/**
* A QML component presenting a loading overlay to the user
*
* Should be used whenever the application is performing heavy work, that
* would lead to a freeze in the GUI. The interface is simple:
* <ul>
* <li>
start() starts the loading overlay. As a result interaction with the ui
* is no longer possible (via touch/mouse) except for key event handling.
* </li>
* <li>
* stop() stops the loading overlay. A user must take care to call stop()
* in all possible (also error-) cases or the application never leaves
* the loading overlay again.
* </li>
* </ul>
*
* There should be only one single Loading object anchored in the main window
* as a sibling to the page stack. Activities are supposed to use this single
* instance via the ActivityBase.loading property.
*
* Note that you can't use the loading animation to signal heavy ui changes that are
* issued synchronously as the QML scene won't be updated fast enough to
* even show the loading item. Therefore, to avoid freezing the ui, use...
* <ul>
* <li>
* ... WorkerScript-s for ListModel based ui changes and
* </li>
* <li>
* ... Component.incubateObject() for dynamic ui changes object creation
* </li>
* </ul>
*/
Item {
id: root
/**
* type:bool
* Whether the loading icon is active.
*/
property bool active: true
/**
* Start the loading overlay.
*/
function start() {
visible = true;
active = true;
}
/**
* Stop the loading overlay.
*/
function stop() {
active = false;
visible = false;
}
anchors.fill: parent
z: 10001 // should be the highest value in the whole scene
visible: false
MultiPointTouchArea {
// Just to catch mouse events
anchors.fill: parent
}
Rectangle {
anchors.fill: parent
opacity: 0.8
color: "grey"
}
Image {
id: loadingImage
source: "qrc:/gcompris/src/core/resource/loading.svg";
anchors.centerIn: parent
sourceSize.width: 1024
width: 150
height: 150
opacity: 0.8
RotationAnimation on rotation {
id: rotation
running: root.active
from: 0
to: 360
loops: Animation.Infinite
duration: 1500
}
}
}
diff --git a/src/core/NumPad.qml b/src/core/NumPad.qml
index 3b3dcfe57..cf5fe2118 100644
--- a/src/core/NumPad.qml
+++ b/src/core/NumPad.qml
@@ -1,337 +1,337 @@
/* GCompris - NumPad.qml
*
* Copyright (C) 2014 Aruna Sankaranarayanan <arunasank@src.gnome.org>
*
* Authors:
* Aruna Sankaranarayanan <arunasank@src.gnome.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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
/**
* A QML component providing an on screen numpad.
*
* Numpad displays integers from 0 to 9 that can be used
* in applications that need numerical inputs from the user.
* By default it shows integer 0 - 4 in a column on left and
* integers 5 - 9 on right in a column.
* It also contains the backspace button to remove the last input value.
* It is also only displayed when the "virtual keyboard" is enabled in the options.
*
* @inherit QtQuick.Item
*/
Item {
id: containerPanel
anchors.fill: parent
/**
* type:list
*
* Default keys-rectangle color used unless the user provides another.
*/
property var colours: ["#ea7025", "#67c111", "#00bde3", "#bde300","#e3004c"]
/**
* type:list
*
* Default sequence of numbers displayed unless the user provides another.
*/
property var numbers: [0, 1, 2, 3, 4]
/**
* type:string
*
* String containing the numbers selected by user.
*/
property string answer: ""
/**
* type:bool
*
* Set to true when good answer is submitted and to
* avoid the inputs until required.
*/
property bool answerFlag: false
/**
* type:var
*
* Column containing containing first half integers i.e.
* 0 - 4, displayed at the left edge of the activity window.
*/
property var leftPanelComponent: leftPanel
/**
* type:var
*
* Column containing containing second half integers i.e.
* 5 - 9, displayed at the right edge of the activity window.
*/
property var rightPanelComponent: rightPanel
/**
* type:var
*
* Button for displaying backSpace key.
* Removes last input from answer on clicked or pressed.
*/
property var backspaceButtonComponent: backspaceButton
/**
* type:int
*
* Stores the maximum length of the correct answer.
*/
property int maxDigit: 2
/**
* type:int
*
* Stores the width of each key container.
*/
property int columnWidth: 80 * ApplicationInfo.ratio
signal answer
visible: ApplicationSettings.isVirtualKeyboard
Column {
id: leftPanel
width: columnWidth
height: parent.height - 90 * ApplicationInfo.ratio
opacity: 0.8
Repeater {
model: 5
Rectangle{
width: parent.width
height: parent.height/5
color: colours[index]
border.color: Qt.darker(color)
border.width: 2
GCText {
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
text: numbers[index]
fontSize: 28
font.bold: true
}
MouseArea {
// Create a bigger area than the top rectangle to suit fingers
anchors {
left: parent.left
top: parent.top
bottom: parent.bottom
}
width: parent.width * 2
enabled: ApplicationSettings.isVirtualKeyboard &&
containerPanel.opacity > 0
onClicked: {
if(answer.length < maxDigit)
answer += numbers[index]
}
onPressed: {
leftPanel.children[index].color = Qt.lighter(colours[index])
leftPanel.children[index].border.width = 5
}
onReleased: {
leftPanel.children[index].color = colours[index]
leftPanel.children[index].border.width = 2
}
}
}
}
}
Column {
id: rightPanel
width: columnWidth
height: parent.height - 90 * ApplicationInfo.ratio
x: parent.width - columnWidth
opacity: 0.8
Repeater {
model: 5
Rectangle {
width: parent.width
height: parent.height/5
color: colours[index]
border.color: Qt.darker(color)
border.width:2
GCText {
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
text: numbers[index] + 5
fontSize: 28
font.bold: true
}
MouseArea {
// Create a bigger area than the top rectangle to suit fingers
anchors {
right: parent.right
top: parent.top
bottom: parent.bottom
}
width: parent.width * 2
enabled: ApplicationSettings.isVirtualKeyboard &&
containerPanel.opacity > 0
onClicked: {
if(answer.length < maxDigit)
answer += numbers[index] + 5
}
onPressed: {
rightPanel.children[index].color = Qt.lighter(colours[index])
rightPanel.children[index].border.width = 5
}
onReleased: {
rightPanel.children[index].color = colours[index]
rightPanel.children[index].border.width = 2
}
}
}
}
Rectangle {
id: backspaceButton
width: parent.width
height: containerPanel.height - rightPanel.height
color: "white"
border.color: "black"
border.width: 2
GCText {
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
text: "←"
fontSize: 28
font.bold: true
}
MouseArea {
anchors.fill: parent
enabled: ApplicationSettings.isVirtualKeyboard &&
containerPanel.opacity > 0
onClicked: {
answer = answer.substring(0,answer.length - 1)
}
onPressed: {
backspaceButton.color = Qt.lighter("white")
backspaceButton.border.width = 5
}
onReleased: {
backspaceButton.color = "white"
backspaceButton.border.width = 2
}
}
}
}
function resetText() {
answer = ""
}
function updateAnswer(key, isKeyPressed) {
var keyValue;
switch(key)
{
case Qt.Key_0 :
keyValue = 0;
break;
case Qt.Key_1:
keyValue = 1;
break;
case Qt.Key_2:
keyValue = 2;
break;
case Qt.Key_3:
keyValue = 3;
break;
case Qt.Key_4:
keyValue = 4;
break;
case Qt.Key_5:
keyValue = 5;
break;
case Qt.Key_6:
keyValue = 6;
break;
case Qt.Key_7:
keyValue = 7;
break;
case Qt.Key_8:
keyValue = 8;
break;
case Qt.Key_9:
keyValue = 9;
break;
case Qt.Key_Backspace:
keyValue = 10;
}
if(isKeyPressed && !answerFlag)
{
if(keyValue < 5 && answer.length < maxDigit)
{
answer += keyValue;
leftPanel.children[keyValue].color = Qt.lighter(colours[keyValue])
leftPanel.children[keyValue].border.width = 5
}
else if(keyValue < 10 && answer.length < maxDigit)
{
answer += keyValue;
rightPanel.children[keyValue - 5].color = Qt.lighter(colours[keyValue - 5])
rightPanel.children[keyValue - 5].border.width = 5
}
else if(keyValue === 10)
{
answer = answer.substring(0,answer.length - 1);
backspaceButton.color = Qt.lighter("white")
backspaceButton.border.width = 5
}
}
else
{
if(keyValue < 5)
{
leftPanel.children[keyValue].color = colours[keyValue]
leftPanel.children[keyValue].border.width = 2
}
else if(keyValue < 10)
{
rightPanel.children[keyValue - 5].color = colours[keyValue - 5]
rightPanel.children[keyValue - 5].border.width = 2
}
else if(keyValue === 10)
{
backspaceButton.color = "white"
backspaceButton.border.width = 2
}
}
}
}
diff --git a/src/core/ParticleSystemStar.qml b/src/core/ParticleSystemStar.qml
index d892f3d3a..e7754b876 100644
--- a/src/core/ParticleSystemStar.qml
+++ b/src/core/ParticleSystemStar.qml
@@ -1,74 +1,74 @@
/* GCompris - ParticleSystemStar.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import QtQuick.Particles 2.0
import GCompris 1.0
/**
* A ParticleSystem component using star image particles.
* @ingroup components
*
* Used for click effects.
*
* Because of problems on some Android devices leading to crashes must be
* used via the wrapper @ref ParticleSystemStarLoader.
*
* @inherit QtQuick.ParticleSystem
* @sa ParticleSystemStarLoader
*/
ParticleSystem {
id: particles
anchors.fill: parent
/// @cond INTERNAL_DOCS
property alias emitter: clickedEmitter
property alias clip: imageParticle.clip
/// @endcond
Emitter {
id: clickedEmitter
anchors.fill: parent
emitRate: 20
lifeSpan: 800
lifeSpanVariation: 400
sizeVariation: 12
size: 24 * ApplicationInfo.ratio
system: particles
velocity: PointDirection {xVariation: 100; yVariation: 100;}
acceleration: PointDirection {xVariation: 50; yVariation: 50;}
velocityFromMovement: 50
enabled: false
}
ImageParticle {
id: imageParticle
source: "qrc:/gcompris/src/core/resource/star.png"
anchors.fill: parent
color: "white"
blueVariation: 0.5
greenVariation: 0.5
redVariation: 0.5
clip: true
smooth: false
autoRotation: true
}
}
diff --git a/src/core/ParticleSystemStarLoader.qml b/src/core/ParticleSystemStarLoader.qml
index 189bd324e..24e6b763d 100644
--- a/src/core/ParticleSystemStarLoader.qml
+++ b/src/core/ParticleSystemStarLoader.qml
@@ -1,50 +1,50 @@
/* GCompris - ParticleSystemStarLoader.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
/**
* A QML loader that wraps ParticleSystemStar.
* @ingroup components
*
* Wrapper loading/activating a @ref ParticleSystemStarLoader only if
* the Android systems supports fragment shaders according to
* ApplicationInfo.hasShader.
*
* @inherit QtQuick.Loader
* @sa ParticleSystemStar ApplicationInfo.hasShader
*/
Loader {
anchors.fill: parent
active: ApplicationInfo.hasShader
/**
* Emits count particles from the particle emitter immediately.
*
* Cf. Emitter.burst
*/
function burst(val) {
if(active)
item.emitter.burst(val)
}
onLoaded: item.clip = clip
source: "ParticleSystemStar.qml"
}
diff --git a/src/core/ReadyButton.qml b/src/core/ReadyButton.qml
index 812adc793..d16fbc5c2 100644
--- a/src/core/ReadyButton.qml
+++ b/src/core/ReadyButton.qml
@@ -1,125 +1,120 @@
/* GCompris - ReadyButton.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
Rectangle {
id: iAmReady
/**
* type: var
* Existing themes for the button.
* A theme is composed of:
* The button's border color
* The text color
*/
property var themes: {
"dark": {
- borderColor: "#FF373737",
- fillColor0: "#A8FFFFFF",
- fillColor1: "#68FFFFFF",
- textColor: "#FF373737"
+ borderColor: "#373737",
+ fillColor: "#FFFFFF",
+ textColor: "#373737"
},
"light": {
borderColor: "white",
- fillColor0: "#42FFFFFF",
- fillColor1: "#23FFFFFF",
+ fillColor: "#373737",
textColor: "white"
}
}
/**
* type: string
* Defines the theme of the ReadyButton - dark or light.
*
* Default theme is dark.
*/
property string theme: "dark"
/**
* Emitted when the ReadyButton is clicked
*/
signal clicked
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
border.color: themes[theme].borderColor
visible: true
radius: 10
smooth: true
border.width: 4
width: iAmReadyText.width + 50 * ApplicationInfo.ratio
height: iAmReadyText.height + 50 * ApplicationInfo.ratio
- gradient: Gradient {
- GradientStop { position: 0 ; color: themes[theme].fillColor0 }
- GradientStop { position: 1 ; color: themes[theme].fillColor1 }
- }
+ color: themes[theme].fillColor
GCText {
id: iAmReadyText
color: themes[theme].textColor
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
font.bold: true
fontSize: mediumSize
text: qsTr("I am Ready")
visible: iAmReady.visible
}
MouseArea {
id: mouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: {
iAmReady.visible = false
iAmReady.clicked()
}
}
states: [
State {
name: "notClicked"
PropertyChanges {
target: iAmReady
scale: 1.0
}
},
State {
name: "clicked"
when: mouseArea.pressed
PropertyChanges {
target: iAmReady
scale: 0.9
}
},
State {
name: "hover"
when: mouseArea.containsMouse
PropertyChanges {
target: iAmReady
scale: 1.1
}
}
]
Behavior on scale { NumberAnimation { duration: 70 } }
}
diff --git a/src/core/Score.qml b/src/core/Score.qml
index 1d18af448..76a727119 100644
--- a/src/core/Score.qml
+++ b/src/core/Score.qml
@@ -1,144 +1,160 @@
/* GCompris - Score.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
/**
* A QML component to visualize sub-level progress.
* @ingroup components
*
* Score usually consists of current-level (@ref currentSubLevel)
* and the max number of levels (@ref numberOfSubLevels).
*
* For other cases an activity can also directly define the whole message
* it wants to be shown (@ref message).
*
* @inherit QtQuick.Rectangle
*/
Rectangle {
id: score
/**
* type:int
* Size of the font used in pt.
*
* @sa GCFont.fontSize.
*/
property alias fontSize: subLevelText.fontSize
+ /**
+ * type:string
+ * Define how text size is determined
+ *
+ * @sa GCFont.fontSizeMode.
+ */
+ property alias fontSizeMode: subLevelText.fontSizeMode
+
+ /**
+ * type:real
+ * Define margins
+ */
+ property real margins: 30
+
/**
* type:int
* Total number of sub-levels to show.
*
* @sa currentSubLevel
*/
property int numberOfSubLevels
/**
* type:int
* Current sub-level to show.
*
* @sa numberOfSubLevels
*/
property int currentSubLevel
/**
* type:string
* Complete message string to show.
*
* Mutually exclusive with currentSubLevel and numberOfSubLevels
*/
property string message
/**
* Alias for external reference of subLevelText.
*/
readonly property alias internalTextComponent: subLevelText
/**
* Emitted when the win animation should be started.
*
* Triggers scale and rotation animation.
*/
signal playWinAnimation
color: "#AAFFFFFF"
width: subLevelText.width * 2
height: subLevelText.height * 1.4
radius: 10
anchors.bottom: parent.bottom
anchors.right: parent.right
- anchors.margins: 30
+ anchors.margins: margins
border.color: "black"
border.width: 0
z: 1000
onCurrentSubLevelChanged: message = currentSubLevel + "/" + numberOfSubLevels
onNumberOfSubLevelsChanged: message = currentSubLevel + "/" + numberOfSubLevels
onPlayWinAnimation: winAnimation.start()
+ readonly property bool isWinAnimationPlaying: winAnimation.running
+
GCText {
id: subLevelText
anchors.centerIn: parent
- fontSize: mediumSize
+ fontSizeMode: Text.Fit
font.bold: true
color: "#373737"
text: message
}
SequentialAnimation {
id: winAnimation
ParallelAnimation {
PropertyAnimation {
target: score
properties: "scale"
from: 1.0
to: 1.4
duration: 500
}
NumberAnimation {
target: score
property: "rotation"
from: -10; to: 10
duration: 750
easing.type: Easing.InOutQuad
}
}
ParallelAnimation {
PropertyAnimation {
target: score
properties: "scale"
from: 1.4
to: 1.0
duration: 500
}
NumberAnimation {
target: score
property: "rotation"
from: 10; to: 0
duration: 750
easing.type: Easing.InOutQuad
}
}
}
}
diff --git a/src/core/ScoreItem.qml b/src/core/ScoreItem.qml
index 0feecccda..6602bf839 100644
--- a/src/core/ScoreItem.qml
+++ b/src/core/ScoreItem.qml
@@ -1,246 +1,245 @@
/* GCompris - ScoreItem.qml
*
* Copyright (C) 2017 Johnny Jazeix <jazeix@gmail.com>
*
* Authors:
* Pulkit Gupta <pulkitgenius@gmail.com> (main code)
* Johnny Jazeix <jazeix@gmail.com> (refactorisation)
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
/**
* A QML component to visualize number of wins.
* @ingroup components
*
* ScoreItem consists of player score (@ref playerScore)
* and player image (@ref playerImageSource).
* Mostly used in multi-player activities.
*
* @inherit QtQuick.Item
*/
Item {
id: scoreItem
/**
* type:int
* Id of the player.
*/
property int player: 1
/**
* type:string
* Source of background image to display.
*
* @sa backgroundImage.source
*/
property string backgroundImageSource
/**
* type:string
* Source of player image to display.
*
* @sa playerImage.source
*/
property string playerImageSource
/**
* type:int
* Count of score(i.e. number of wins).
*
* @sa scoreLabel.text
*/
property int playerScore
/**
* type:int
* Holds the point from which the player image
* is scaled on x-axis.
*
* @sa scaleTransform.origin.x
*/
property int playerScaleOriginX
/**
* type:int
* Holds the point from which the player image
* is scaled on y-axis.
*
* @sa scaleTransform.origin.y
*/
property int playerScaleOriginY
/**
* Emitted when the win animation should be started.
*
* Triggers scale, rotation animation and increases playerScore count.
*/
signal win
/**
* Emitted when the player turn should be started.
*
* Triggers scale and rotation animation.
*/
signal beginTurn
/**
* Emitted when the player turn should be ended.
*
* Triggers shrink and rotation animation on player image.
*/
signal endTurn
onBeginTurn: {
scaleAnimation.start()
}
onEndTurn: {
scaleAnimation.stop()
playerImageRotate.stop()
playerImage.rotation = 0
shrinkAnimation.start()
backgroundRectangle.state = "second"
}
onWin: {
scaleAnimation.start()
backgroundRectangle.state = "win"
playerScore ++;
}
PropertyAnimation {
id: scaleAnimation
target: scaleTransform
properties: "scale"
from: 1.0
to: 1.4
duration: 500
onStarted: {
backgroundRectangle.state = "first"
playerImageRotate.start()
}
}
PropertyAnimation {
id: shrinkAnimation
target: scaleTransform
properties: "scale"
from: 1.4
to: 1.0
duration: 500
}
SequentialAnimation {
id: playerImageRotate
loops: Animation.Infinite
NumberAnimation {
target: playerImage
property: "rotation"
from: -30; to: 30
duration: 750
easing.type: Easing.InOutQuad
}
NumberAnimation {
target: playerImage
property: "rotation"
from: 30; to: -30
duration: 750
easing.type: Easing.InOutQuad
}
}
Rectangle {
id: backgroundRectangle
anchors.fill: parent
radius: 15
state: "second"
Image {
id: backgroundImage
source: backgroundImageSource
sourceSize.height: height
sourceSize.width: width
anchors.fill: parent
anchors.margins: parent.height * 0.04
Image {
id: playerImage
source: playerImageSource
fillMode: Image.PreserveAspectFit
height: parent.height*0.8
sourceSize.height: height
- sourceSize.width: width
x: parent.width*0.06
anchors.verticalCenter: parent.verticalCenter
}
GCText {
id: scoreLabel
anchors.verticalCenter: parent.verticalCenter
color: "#2a2a2a"
x: parent.width*0.65
fontSizeMode: Text.Fit
text: playerScore
}
}
states: [
State {
name: "first"
PropertyChanges {
target: backgroundRectangle
color: "#80ffffff"
}
PropertyChanges {
target: playerImage
source: playerImageSource
}
},
State {
name: "second"
PropertyChanges {
target: backgroundRectangle
color: "transparent"
}
PropertyChanges {
target: playerImage
source: playerImageSource
}
},
State {
name: "win"
PropertyChanges {
target: playerImage
source: "qrc:/gcompris/src/core/resource/win.svg"
}
PropertyChanges {
target: backgroundRectangle
color: "#80ffffff"
}
}
]
transform: Scale {
id: scaleTransform
property real scale: 1
origin.x: playerScaleOriginX
origin.y: playerScaleOriginY
xScale: scale
yScale: scale
}
}
}
diff --git a/src/core/Tutorial.qml b/src/core/Tutorial.qml
index 7e53d789b..4499d386e 100644
--- a/src/core/Tutorial.qml
+++ b/src/core/Tutorial.qml
@@ -1,175 +1,193 @@
/* GCompris - Tutorial.qml
*
* Copyright (C) 2017 Divyam Madaan <divyam3897@gmail.com>
*
* Authors:
* Divyam Madaan <divyam3897@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
/*
* A QML component for tutorial in activity in GCompris.
*
* Use Tutorial when you want to add a tutorial section which contains instructions and images.
*
* Contains the following basic layout elements: text (instructions), a Skip,
* a Next and a Previous button to leave the tutorial or navigate through it.
* The skipPressed, nextPressed, previousPressed signals are emitted when user clicks on skip, next and previous button respectively.
*
*/
/* To use the component add:
* Tutorial {
* id: tutorialSection
* source: "sourceForTutorialBackgroundImage"
* tutorialDetails: Activity.tutorialInstructions
* onSkipPressed: {
* Activity.initLevel()
* }
* }
*/
import QtQuick 2.6
import GCompris 1.0
Item {
id: tutorialSection
anchors.fill: parent
/* type: int
* Counter for tutorial instructions
*/
property int tutorialNumber: 0
/* Container for all the tutorial instructions */
property var tutorialDetails
+ /* Do we use image or qml files for illustrations */
+ property bool useImage: true
+
// Emitted when skipButton is clicked
signal skipPressed
// Emitted when nextButton is clicked
signal nextPressed
// Emitted when previousButton is clicked
signal previousPressed
// Tutorial instructions
GCText {
id: tutorialText
anchors {
horizontalCenter: parent.horizontalCenter
top: parent.top
topMargin: 10
}
text: tutorialDetails ? tutorialDetails[tutorialNumber].instruction : ""
fontSizeMode: Text.Fit
minimumPixelSize: 10
color: "black"
horizontalAlignment: Text.AlignHLeft
width: Math.min(implicitWidth, 0.8 * parent.width)
height: Math.min(implicitHeight, 0.25 * parent.height)
wrapMode: Text.WordWrap
z: 2
}
MouseArea {
anchors.fill: parent
}
Rectangle {
id: tutorialTextContainer
anchors.top: tutorialText.top
anchors.horizontalCenter: tutorialText.horizontalCenter
width: tutorialText.width + 20
height: tutorialText.height + 2
opacity: 0.8
radius: 10
border.width: 6
color: "white"
border.color: "#87A6DD"
}
// previousButton: It emits skipPressed and navigates to previous tutorial when clicked
IntroButton {
id: previousButton
width: parent.width / 4
height: 90
z: 5
anchors.right: nextButton.left
anchors.topMargin: 15
anchors.rightMargin: 15
anchors.top: tutorialTextContainer.bottom
visible: tutorialNumber != 0
text: qsTr("Previous")
onClicked: {
--tutorialNumber
previousPressed()
}
}
// nextButton: It emits nextPressed which navigates to next tutorial when clicked
IntroButton {
id: nextButton
width: parent.width / 4
height: 90
z: 5
anchors.right: skipButton.left
anchors.topMargin: 15
anchors.rightMargin: 15
anchors.top: tutorialTextContainer.bottom
visible: tutorialNumber != (tutorialDetails.length - 1)
text: qsTr("Next")
onClicked: {
++tutorialNumber
nextPressed()
}
}
// skipButton: It emits the skipPressed signal which calls the initLevel to close the tutorial when clicked.
IntroButton {
id: skipButton
width: parent.width / 4
height: 90
z: 5
anchors.right: parent.right
anchors.rightMargin: 15
anchors.topMargin: 15
anchors.top: tutorialTextContainer.bottom
text: nextButton.visible ? qsTr("Skip") : qsTr("Start")
onClicked: {
tutorialSection.visible = false
skipPressed()
}
}
// Image component for tutorial instructions
Image {
id: tutorialImage
+ visible: useImage
width: parent.width * 0.8
height: (parent.height - nextButton.height) * 0.48
fillMode: Image.PreserveAspectFit
- source: tutorialDetails ? tutorialDetails[tutorialNumber].instructionImage : ""
+ source: tutorialDetails && useImage ? tutorialDetails[tutorialNumber].instructionImage : ""
+ anchors {
+ top: previousButton.bottom
+ topMargin: 10
+ horizontalCenter: parent.horizontalCenter
+ }
+ }
+
+ // Alternative QML component for tutorial instructions
+ Loader {
+ id: tutorialQml
+ enabled: !tutorialImage.visible
+ width: parent.width * 0.8
+ height: (parent.height - nextButton.height) * 0.48
+ source: tutorialDetails && !useImage ? tutorialDetails[tutorialNumber].instructionQml : ""
anchors {
top: previousButton.bottom
topMargin: 10
horizontalCenter: parent.horizontalCenter
}
}
}
diff --git a/src/core/VirtualKey.qml b/src/core/VirtualKey.qml
index f201c62bc..33ecd5106 100644
--- a/src/core/VirtualKey.qml
+++ b/src/core/VirtualKey.qml
@@ -1,114 +1,114 @@
/* GCompris - VirtualKey.qml
*
* Copyright (C) 2014 Holger Kaelberer <holger.k@elberer.de>
*
* Authors:
* Holger Kaelberer <holger.k@elberer.de>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import QtGraphicalEffects 1.0
import QtQuick.Controls 1.5
import QtQuick.Controls.Styles 1.4
Item {
id: virtualKey
property alias text: button.text
property var modifiers: 0 /* Supposed to hold any active key modifiers
* in a bitmask from the Qt namespace:
* Qt.ShiftModifier/MetaModifier/ControlModifier.
* 0 if none. */
property var specialKey: 0 /* Supposed to hold special key values from the
* Qt namespace like Qt.Key_Shift/Key_Control/
* Key_Alt if VirtualKey is a special key.
* 0 Otherwise */
signal pressed(var virtualKey);
Button {
id: button
text: ((modifiers & Qt.ShiftModifier) && (shiftLabel !== undefined)) ? shiftLabel : label
width: parent.width
height: virtualKey.height
style: ButtonStyle {
background: Rectangle {
border.width: control.activeFocus ? 2 : 1
border.color: "black"
radius: 4
gradient: Gradient {
GradientStop {
position: 0;
color: (control.pressed
|| ( virtualKey.specialKey == Qt.Key_Shift
&& virtualKey.modifiers & Qt.ShiftModifier))
? "#ccc" : "#eee";
}
GradientStop {
position: 1;
color: (control.pressed
|| ( virtualKey.specialKey == Qt.Key_Shift
&& virtualKey.modifiers & Qt.ShiftModifier))
? "#aaa" : "#ccc";
}
}
}
label: Item {
GCText {
//renderType: Text.NativeRendering
anchors.centerIn: parent
text: control.text
fontSize: 20
font.bold: false
color: "black"
//antialiasing: true
}
}
}
SequentialAnimation {
id: anim
PropertyAction { target: virtualKey; property: 'z'; value: 1 }
NumberAnimation { target: button; properties: "scale"; to: 1.3; duration: 100; easing.type: Easing.OutCubic }
NumberAnimation { target: button; properties: "scale"; to: 1.0; duration: 100; easing.type: Easing.OutCubic }
PropertyAction { target: virtualKey; property: 'z'; value: 0 }
}
onClicked: {
//console.log("### virtualKey.onClicked text=" + virtualKey.text
// + " specialKey="+ virtualKey.specialKey
// + " modifiers= "+ virtualKey.modifiers);
anim.start()
virtualKey.pressed(virtualKey);
button.focus = false;
}
}
DropShadow {
anchors.fill: button
cached: false
horizontalOffset: 3
verticalOffset: 3
radius: 8.0
samples: 16
color: "#80000000"
source: button
scale: button.scale
}
}
diff --git a/src/core/VirtualKeyboard.qml b/src/core/VirtualKeyboard.qml
index aadf11ba7..c471db2b4 100644
--- a/src/core/VirtualKeyboard.qml
+++ b/src/core/VirtualKeyboard.qml
@@ -1,395 +1,395 @@
/* GCompris - VirtualKeyboard.qml
*
* Copyright (C) 2014 Holger Kaelberer <holger.k@elberer.de>
*
* Authors:
* Holger Kaelberer <holger.k@elberer.de>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
/**
* A QML component providing an on screen keyboard.
* @ingroup components
*
* VirtualKeyboard displays a virtual on screen keyboard that can be used
* in applications that need keyboard support, especially on mobile devices.
*
* The component itself does not provide builtin localized keyboard layouts,
* the user has to define the keyboard-layout dynamically.
*
* @inherit QtQuick.Item
*/
Item {
id: keyboard
/* Public interface: */
/**
* type:list
*
* Default basic qwerty-layout used unless the user provides another.
* @sa layout.
*/
readonly property var qwertyLayout:
[ [ { label: "1", shiftLabel: "!" },
{ label: "2", shiftLabel: "@" },
{ label: "3", shiftLabel: "#" },
{ label: "4", shiftLabel: "$" },
{ label: "5", shiftLabel: "%" },
{ label: "6", shiftLabel: "^" },
{ label: "7", shiftLabel: "&" },
{ label: "8", shiftLabel: "*" },
{ label: "9", shiftLabel: "(" },
{ label: "0", shiftLabel: ")" },
{ label: "-", shiftLabel: "_" },
{ label: "=", shiftLabel: "+" } ],
[ { label: "q", shiftLabel: "Q" },
{ label: "w", shiftLabel: "W" },
{ label: "e", shiftLabel: "E" },
{ label: "r", shiftLabel: "R" },
{ label: "t", shiftLabel: "T" },
{ label: "y", shiftLabel: "Y" },
{ label: "u", shiftLabel: "U" },
{ label: "i", shiftLabel: "I" },
{ label: "o", shiftLabel: "O" },
{ label: "p", shiftLabel: "P" } ],
[ { label: "a", shiftLabel: "A" },
{ label: "s", shiftLabel: "S" },
{ label: "d", shiftLabel: "D" },
{ label: "f", shiftLabel: "F" },
{ label: "g", shiftLabel: "G" },
{ label: "h", shiftLabel: "H" },
{ label: "j", shiftLabel: "J" },
{ label: "k", shiftLabel: "K" },
{ label: "l", shiftLabel: "L" } ],
[ { label: "z", shiftLabel: "Z" },
{ label: "x", shiftLabel: "X" },
{ label: "c", shiftLabel: "C" },
{ label: "v", shiftLabel: "V" },
{ label: "b", shiftLabel: "B" },
{ label: "n", shiftLabel: "N" },
{ label: "m", shiftLabel: "M" } ]]
/**
* type:string
* Symbol that can be used for the space key.
*/
readonly property string space: "\u2423"
/**
* type:string
* Symbol that can be used for the backspace key.
*/
readonly property string backspace: "\u2190"
/**
* type:string
* Symbol for the shift-up key.
*/
readonly property string shiftUpSymbol: "\u21E7"
/**
* type:string
* Symbol for the shift-down key.
*/
readonly property string shiftDownSymbol: "\u21E9"
/**
* type:list
* Keyboard layout.
*
* The layout should be provided by the user. It can contain
* unicode characters, and can be set dynamically also on a per-level
* basis.
*
* The expected format of the @ref layout property is a list of row lists.
* Example:
*
* @code
* [
* [ <-- start of the first row
* { label: "1", shiftLabel: "!" }, <-- first key of the first row
* { label: "2", shiftLabel: "@" },
* ...
* ],
* [
* { label: "q", shiftLabel: "Q" },
* { label: "w", shiftLabel: "W" },
* ...
* ],
* ...
* ]
* @endcode
*
* The order passed in layout will not be altered.
*
* Use the @ref shiftKey property to activate a shift button which allows
* to assign 2 letters on one key. You can define an additional shiftLabel
* per key, or leave it undefined, in which case VirtualKeyboard
* automatically defines the shift-label (using
* String.toLocaleUpperCase()).
*
* Default is to use the qwertyLayout.
*
* @sa qwertyLayout shiftKey
*/
property var layout: null
/**
* type:bool
* Whether a shift key should be used.
*/
property bool shiftKey: false
// property bool ctrlKey: false;
// ...
/**
* type:int
* Vertical spacing between rows in pixel.
* Default: 5 * ApplicationInfo.ratio
*/
property int rowSpacing: 5 * ApplicationInfo.ratio
/**
* type:int
* Horizontal spacing between keys in pixel.
* Default: 3 * ApplicationInfo.ratio
*/
property int keySpacing: 3 * ApplicationInfo.ratio
/**
* type:int
* Height of the keys in pixel.
* Default: 45 * ApplicationInfo.ratio
*/
property int keyHeight: 45 * ApplicationInfo.ratio
/**
* type:int
* Margin around the keyboard in pixel.
* Default: 5 * ApplicationInfo.ratio
*/
property int margin: 5 * ApplicationInfo.ratio
/**
* type:bool
* Whether the keyboard should be hidden.
*
* Besides this property the visibility of the virtual keyboard also
* depends on the setting ApplicationSettings.isVirtualKeyboard and
* its successful initialization.
*/
property bool hide
/**
* Emitted for every keypress.
*
* @param text The label of the pressed key.
*/
signal keypress(string text)
/**
* Emitted upon error.
*
* @param msg Error message.
*/
signal error(string msg)
/// @cond INTERNAL_DOCS
opacity: 0.9
visible: !hide && ApplicationSettings.isVirtualKeyboard && priv.initialized
enabled: visible
z: 9999
width: parent.width
height: visible ? priv.cHeight : 0
anchors.horizontalCenter: parent.horizontalCenter
property int modifiers: Qt.NoModifier; // currently active key modifiers, internal only
// private properties:
QtObject {
id: priv
readonly property int cHeight: numRows * keyboard.keyHeight +
(numRows + 1) * keyboard.rowSpacing
property int numRows: 0
property bool initialized: false
}
WorkerScript {
id: keyboardWorker
source: "virtualkeyboard_worker.js"
onMessage: {
// worker finished
activity.loading.stop();
if (messageObject.error !== "") {
error(messageObject.error);
} else {
// update all changed values (except the model):
priv.numRows = messageObject.numRows;
priv.initialized = messageObject.initialized;
}
}
}
function populateKeyboard(a) {
if(activity.activityInfo.name != "menu/Menu.qml")
activity.loading.start();
// populate asynchronously in a worker thread:
keyboardWorker.sendMessage({
shiftKey: keyboard.shiftKey,
shiftUpSymbol: keyboard.shiftUpSymbol,
shiftDownSymbol: keyboard.shiftDownSymbol,
a: a,
rowListModel: rowListModel
});
}
function handleVirtualKeyPress(virtualKey) {
if (virtualKey.specialKey == Qt.Key_Shift)
keyboard.modifiers ^= Qt.ShiftModifier;
// else if (virtualKey.specialKey == Qt.Key_Alt)
// keyboard.modifiers ^= Qt.AltModifier;
else
keyboard.keypress(virtualKey.text);
}
onLayoutChanged: {
priv.initialized = false;
if (layout != null)
populateKeyboard(layout);
}
ListModel {
id: rowListModel
/* Currently expects the following
* ListElement {
* rowNum: 1
* keys: [ { label: "a", shiftLabel: "A" },
* { label: "b", shiftLabel: "B" },
* { label: "Shift", shiftLabel: "Shift", special },
* ...}
* ]
* }
*/
}
Behavior on height {
NumberAnimation {
duration: 500
easing.type: Easing.OutCubic
}
}
Rectangle {
id: keyboardBackground
width: parent.width
height: keyboard.height
color: "#8C8F8C"
opacity: keyboard.opacity
ListView {
id: rowList
anchors.top: parent.top
anchors.topMargin: keyboard.margin
anchors.left: parent.left
anchors.margins: keyboard.margin
width: parent.width
height: parent.height - keyboard.margin * 2
spacing: keyboard.rowSpacing
orientation: Qt.Vertical
verticalLayoutDirection: ListView.TopToBottom
interactive: false
model: rowListModel
delegate:
Item {
/* Wrap keyboardRow for attaching a MouseArea. Not possible
* in Row-s directly */
id: rowListDelegate
width: rowList.width
height: keyboardRow.height
x: keyboardRow.x
y: keyboardRow.y
z: keyboardRow.z
MouseArea {
anchors.fill: parent
propagateComposedEvents: true
// update index to allow for updating z value of the rows
onEntered: rowList.currentIndex = index;
onPressed: {
// same onPress for mobile
rowList.currentIndex = index;
// need to propagate through to the key for mobile!
mouse.accepted = false;
}
}
Row {
id: keyboardRow
spacing: keyboard.keySpacing
width: parent.width
z: rowListDelegate.ListView.isCurrentItem ? 1 : -1
Item {
id: keyboardRowSpacing
width: offset / 2;
height: keyboard.keyHeight
}
Repeater {
id: keyboardRowRepeater
z: rowListDelegate.ListView.isCurrentItem ? 1 : -1
model: keys
delegate: VirtualKey {
width: (keyboard.width - keyboardRowRepeater.count *
keyboardRow.spacing - offset - keyboard.margin*2) /
keyboardRowRepeater.count
height: keyboard.keyHeight
modifiers: keyboard.modifiers
specialKey: specialKeyValue
}
onItemAdded: item.pressed.connect(keyboard.handleVirtualKeyPress);
onItemRemoved: item.pressed.disconnect(keyboard.handleVirtualKeyPress);
} // Repeater
} // Row
} // Item
} // ListView
} // keyboardBackground
/// @endcond
}
diff --git a/src/core/Wordlist.qml b/src/core/Wordlist.qml
index 2a96b8768..48f6e25ed 100644
--- a/src/core/Wordlist.qml
+++ b/src/core/Wordlist.qml
@@ -1,226 +1,226 @@
/* GCompris - Wordlist.qml
*
* Copyright (C) 2014 Holger Kaelberer <holger.k@elberer.de>
*
* Authors:
* Holger Kaelberer <holger.k@elberer.de>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import GCompris 1.0
import "core.js" as Core
/**
* A Wordlist component loads and maintains GCompris wordlists.
* @ingroup components
*
* It loads wordlists from json-files, validates its content and exposes
* wordlists and levels to activities.
*
* It expects and returns the following wordlist format (UTF8 encoded):
*
* @code
* {
* "name":"default-gd",
* "description":"Gàidhlig",
* "locale":"gd",
* "levels":[ { "level":1,
* "speed":150, <-- optional
* "fallspeed":7000, <-- optional
* "sublevels":10, <-- optional
* "words":["a","jim", "beam", ... ]}, <-- mandatory
* { "level":2, ... }
* ]
* }
* @endcode
*
* @inherit QtQuick.Item
* @sa JsonParser
*/
Item {
id: wordlist
/**
* type:string
* Default filename to be used if the language specific wordlist file could
* not be loaded.
* Default is emtpy.
*/
property string defaultFilename: ""
/**
* type:bool
* Whether to automatically fallback to the default filename if the
* language specific wordlist file could not be loaded.
* Default is true.
*/
property bool useDefault: true
/**
* type:string
* Name of the file to load the language specific wordlist from.
* Default is empty. Can also be passed directly in loadFromFile().
* If set in the QML definition, the wordlist is autoloaded onCompleted.
*/
property string filename: ""
/**
* type:object
* Complete Wordlist content loaded. You probably want to use one of the
* convenience accessors like getLevelWordList().
* Default is empty.
*/
property var wordList: ({})
/// @cond INTERNAL_DOCS
property var randomWordList: []
property int maxLevel: 0
/// @endcond
/**
* Emitted if an error occurs.
* @param msg Error message.
*/
signal error(string msg);
/**
* Load Wordlist from file @p fname.
*
* @param type:string fname Filename to load wordlist from.
*/
function loadFromFile(fname) {
filename = fname;
var from;
maxLevel = 0
wordList = parser.parseFromUrl(filename, validateWordlist);
if (wordList == null) {
error("Wordlist: Invalid wordlist file " + fname);
if (useDefault) {
// fallback to default file:
wordList = parser.parseFromUrl(defaultFilename, validateWordlist);
if (wordList == null) {
error("Wordlist: Invalid wordlist file " + defaultFilename);
return;
}
from = "default-file " + defaultFilename;
}
else {
error("Wordlist: do not use default list, no list loaded");
return;
}
} else {
from = "file " + fname;
}
// at this point we have valid levels
maxLevel = wordList.levels.length;
console.log("Wordlist: loaded " + maxLevel + " levels from " + from);
return wordList;
}
/**
* Get wordlist data for @p level
*
* @param type:int level Level.
* @returns type:object wordlist data.
*/
function getLevelWordList(level) {
if (level > maxLevel)
return null;
return wordList.levels[level - 1];
}
/**
* Get number of sub-levels in @p level.
*
* @param type:int level Level.
* @returns type:int Number of sublevels.
*/
function getMaxSubLevel(level) {
if (level > maxLevel || level === 0) {
console.log("ERROR: Wordlist.getMaxSubLevel out of range, requested level", level,
"out of expected range", 1, "-", maxLevel)
return null;
}
return wordList.levels[level - 1].sublevels !== undefined ?
wordList.levels[level - 1].sublevels : 0;
}
/**
* Build a random word list for @p level.
*
* We don't want to propose several time the same word. First call
* initRandomWord(level) to create the initial shuffled list of words.
* Then call getRandomWord() to get the words one at a time.
* If a word was not found by the child, add it again to the list
* with appendRandomWord(word)
*
* @param type:int level Level.
*/
function initRandomWord(level) {
randomWordList = Core.shuffle(wordList.levels[level - 1].words).slice(0)
}
/**
* Re-add a random word to a shuffled word list.
*
* @param type:string word Word to append.
* @sa initRandomWord
*/
function appendRandomWord(word) {
randomWordList.unshift(word)
}
/**
* Returns the next random word from a shuffled wordlist.
*
* @sa initRandomWord
*/
function getRandomWord() {
return randomWordList.pop()
}
/// @cond INTERNAL_DOCS
function validateWordlist(doc)
{
// minimal syntax check:
var i;
if (undefined === doc.levels)
return false;
for (i = 0; i < doc.levels.length; i++) {
// check mandatory level properties only (speed, fallspeed and sublevels are optional)
if (doc.levels[i].words.length < 1)
return false;
}
if (i < 1)
return false;
return true;
}
/// @endcond
JsonParser {
id: parser
onError: wordlist.error(msg);
}
Component.onCompleted: {
if (filename != "")
loadFromFile(filename);
}
}
diff --git a/src/core/config.h.in b/src/core/config.h.in
index de08b0947..8bd2fe3b7 100644
--- a/src/core/config.h.in
+++ b/src/core/config.h.in
@@ -1,52 +1,52 @@
/* GCompris - config.h
*
* Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
#ifndef GCOMPRIS_CONFIG_H
#define GCOMPRIS_CONFIG_H
#include <qglobal.h>
/* Version number of package (string) */
#define VERSION "@GCOMPRIS_VERSION@"
/* Version number of package (integer) */
#define VERSION_CODE @GCOMPRIS_VERSION_CODE@
/* Folder where rccs and translations are installed */
#ifdef Q_OS_MACX
#define GCOMPRIS_DATA_FOLDER "../Resources"
#elif Q_OS_IOS
#define GCOMPRIS_DATA_FOLDER "."
#else
#define GCOMPRIS_DATA_FOLDER "../@_data_dest_dir@"
#endif
/* GCompris for android, gcompris-qt for others */
#define GCOMPRIS_APPLICATION_NAME "@GCOMPRIS_EXECUTABLE_NAME@"
/* Compressed audio format */
#define COMPRESSED_AUDIO "@COMPRESSED_AUDIO@"
/* Download Allowed */
#define DOWNLOAD_ALLOWED "@WITH_DOWNLOAD@"
/* Date at which GCompris has been built */
#define BUILD_DATE "@BUILD_DATE@"
/* Type of activation system */
#define ACTIVATION_MODE "@ACTIVATION_MODE@"
/* Defines the renderer backend: Qt software renderer (requires Qt 5.8), openGL or default one */
#define GRAPHICAL_RENDERER "@GRAPHICAL_RENDERER@"
#endif // GCOMPRIS_CONFIG_H
diff --git a/src/core/core.js b/src/core/core.js
index 848550485..da10f2110 100644
--- a/src/core/core.js
+++ b/src/core/core.js
@@ -1,246 +1,246 @@
/* GCompris - core.js
*
* Copyright (C) 2014
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net>
* Holger Kaelberer <holger.k@elberer.de>
* Johnny Jazeix <jazeix@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
/**
* @file
* Contains commonly used javascript methods.
* @ingroup components
*
* FIXME: how to include this file in kgenapidox's output?
*/
.pragma library
.import QtQml 2.2 as Qml
.import GCompris 1.0 as GCompris
/**
* Shuffle the array @p o and returns it.
*
* @param o Array to shuffle.
* @returns A shuffled array.
*/
function shuffle(o) {
for(var j, x, i = o.length; i;
j = Math.floor(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
return o;
}
/**
* Return the filename of the audio voices file for the passed letters
* (or a number) @p c
*
* A letter maybe a digraph or more characters (a pair of characters used
* to write one phoneme). In this case the result have the form U0066U0068.ogg
*
* The returned audio file. has the suffix .ogg
*
* @param c Letter or number character.
* @return A filename for the audio file for the passed letter @p c of the
* form U0033.ogg
*/
function getSoundFilenamForChar(c)
{
var results = ''
for(var i = 0; i < c.length; ++i) {
var result = "U";
var codeHex = c.toLowerCase().charCodeAt(i).toString(16).toUpperCase();
while (codeHex.length < 4) {
codeHex = "0" + codeHex;
}
results += "U" + codeHex
}
results += ".$CA";
return results;
}
/**
* Create and present a GCDialog with the given parameters
*
* Instantiates a GCDialog object dynamically as child of the passed
* parent object. After one of the buttons passed in the buttonHandler parameter
* has been pressed, the dialog will be closed and destroyed automatically.
*
* @param parent QML parent object
* @param informativeText Informative text
* @param button1Text the Label of the first button
* @param button1Callback Callback handler for the first button
* @param button2Text Label of the second button
* @param button2Callback Callback handler for the second button
* @param closeCallback Callback handler for the close button
* @returns The GCDialog object upon success, null otherwise
*
* @sa GCDialog
*/
function showMessageDialog(parent, informativeText,
button1Text, button1Callback,
button2Text, button2Callback,
closeCallback) {
//console.debug("Core.showMessageDialog: parent=" + parent + " backtrace="); console.trace();
var qmlStr =
'import QtQuick 2.6\n'
+ 'GCDialog {\n'
+ ' message: "' + informativeText + '"\n'
+ ' button1Text: "' + button1Text + '"\n'
+ ' button2Text: "' + button2Text + '"\n'
+ ' }\n';
var dialog = null;
try {
dialog = Qt.createQmlObject(qmlStr, parent);
if(button1Callback)
dialog.button1Hit.connect(button1Callback);
if(button2Callback)
dialog.button2Hit.connect(button2Callback);
if(closeCallback)
dialog.close.connect(closeCallback);
dialog.start();
} catch (e) {
console.error("core.js: Error creating a MessageDialog: " + e);
if (dialog)
dialog.destroy();
return null;
}
return dialog;
}
/**
* Destroy dialog @p dialog
*
* @param dialog A dynamically created GCDialog or DownloadDialog
*/
function destroyDialog(dialog) {
if (dialog) {
dialog.stop();
dialog.destroy();
}
}
var downloadDialogComponent = null;
/**
* Create and present a DownloadDialog with the given parameters.
*
* Instantiates a DownloadDialog object dynamically as child of the passed
* parent object. The DownloadDialog.dynamic property will be set, and the
* dialog will be destroyed dynamically after closing.
*
* @param parent QML parent object
* @param properties Object with property-value pairs used to parametrize the new
* object. Used directly as properties parameter of
* Component.createObject()
* @returns A newly created DownloadDialog object upon success, null
* otherwise.
*/
function showDownloadDialog(parent, properties) {
var dialog = null;
try {
if (!downloadDialogComponent) {
downloadDialogComponent = Qt.createComponent("qrc:/gcompris/src/core/DownloadDialog.qml");
if (downloadDialogComponent.status != Qml.Component.Ready) {
throw new Error("Error creating DownloadDialog component: "
+ downloadDialogComponent.errorString());
downloadDialogComponent = null;
}
}
properties.dynamic = true;
dialog = downloadDialogComponent.createObject(parent, properties);
dialog.main = parent
dialog.start();
} catch (e) {
console.error("core.js: Error creating a DownloadDialog: " + e);
if (dialog)
dialog.destroy();
return null;
}
//console.log("created DownloadDialog " + dialog);
return dialog;
}
/**
* Helper checking for availability of audio voices for the current locale and
* informing the user in case they're missing.
*
* Can be used by acitivities that depend on audio voices to inform the user
* of missing resources during startup.
*
* @param parent Parent QML object.
*/
function checkForVoices(parent)
{
if (!GCompris.DownloadManager.areVoicesRegistered()) {
showMessageDialog(parent,
qsTr("Missing sound files!") + '\n'
+ qsTr("This activity uses language sound files, that are not yet installed on your system.")
+ '\n'
+ qsTr("For downloading the needed sound files go to the preferences dialog."),
"", null,
"", null,
null);
}
}
var aboutToQuit = false;
/**
* Central function for quitting GCompris.
*
* Should be used everywhere instead of Qt.quit(), warning in case of running
* downloadloads and showing a confirmation dialog on mobile devices.
* Call Qt.quit() itself upon confirmation.
*
* @param parent QML parent object used for the dynamic dialog.
*/
function quit(parent)
{
if (aboutToQuit) // don't execute concurrently
return;
aboutToQuit = true;
GCompris.ApplicationSettings.previousHeight = parent.height;
GCompris.ApplicationSettings.previousWidth = parent.width;
GCompris.ApplicationInfo.abandonAudioFocus()
if (GCompris.DownloadManager.downloadIsRunning()) {
var dialog = showDownloadDialog(parent, {
text: qsTr("Download in progress")
+ '\n'
+ qsTr("Download in progress.<br/>'Abort' it to quit immediately."),
autohide: true,
reportError: false,
reportSuccess: false,
backgroundButtonVisible: false
});
dialog.finished.connect(function() {Qt.quit();});
} else if (GCompris.ApplicationInfo.isMobile) {
// prevent the user from quitting accidentially by clicking back too often:
showMessageDialog(parent,
qsTr("Quit?") +
'\n' +
qsTr("Do you really want to quit GCompris?"),
qsTr("Yes"), function() { Qt.quit(); },
qsTr("No"), function() { aboutToQuit = false; },
function() { aboutToQuit = false; } );
} else
Qt.quit();
}
function isLeftToRightLocale(locale) {
var localeShort = GCompris.ApplicationInfo.getVoicesLocale(locale)
return (localeShort != "ar" && localeShort != "he");
}
diff --git a/src/core/main.cpp b/src/core/main.cpp
index c48c3e119..25bb584d5 100644
--- a/src/core/main.cpp
+++ b/src/core/main.cpp
@@ -1,282 +1,291 @@
/* GCompris - main.cpp
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
#include <QtDebug>
#include <QApplication>
#include <QQuickWindow>
#include <QQmlApplicationEngine>
#include <QStandardPaths>
#include <QObject>
#include <QTranslator>
#include <QCommandLineParser>
#include <QCursor>
#include <QPixmap>
#include <QSettings>
+#include "GComprisPlugin.h"
#include "ApplicationInfo.h"
#include "ActivityInfoTree.h"
-#include "File.h"
-#include "Directory.h"
#include "DownloadManager.h"
bool loadAndroidTranslation(QTranslator &translator, const QString &locale)
{
- QFile file("assets:/gcompris_" + locale + ".qm");
+ QFile file("assets:/share/GCompris/gcompris_" + locale + ".qm");
file.open(QIODevice::ReadOnly);
QDataStream in(&file);
uchar *data = (uchar*)malloc(file.size());
if(!file.exists())
- qDebug() << "file assets:/" << locale << ".qm does not exist";
+ qDebug() << "file assets:/share/GCompris/gcompris_" << locale << ".qm does not exist";
in.readRawData((char*)data, file.size());
if(!translator.load(data, file.size())) {
qDebug() << "Unable to load translation for locale " <<
locale << ", use en_US by default";
free(data);
return false;
}
// Do not free data, it is still needed by translator
return true;
}
// Return the locale
QString loadTranslation(QSettings &config, QTranslator &translator)
{
QString locale;
// Get locale
- if(config.contains("General/locale")) {
- locale = config.value("General/locale").toString();
- } else {
- locale = GC_DEFAULT_LOCALE;
- }
+ locale = config.value("General/locale", GC_DEFAULT_LOCALE).toString();
+
if(locale == GC_DEFAULT_LOCALE)
locale = QString(QLocale::system().name() + ".UTF-8");
if(locale == "C.UTF-8" || locale == "en_US.UTF-8")
return "en_US";
// Load translation
// Remove .UTF8
locale.remove(".UTF-8");
#if defined(Q_OS_ANDROID)
if(!loadAndroidTranslation(translator, locale))
loadAndroidTranslation(translator, ApplicationInfo::localeShort(locale));
#else
#if (defined(Q_OS_LINUX) || defined(Q_OS_UNIX))
// only useful for translators: load from $application_dir/../share/... if exists as it is where kde scripts install translations
if(translator.load("gcompris_qt.qm", QString("%1/../share/locale/%2/LC_MESSAGES").arg(QCoreApplication::applicationDirPath(), locale))) {
qDebug() << "load translation for locale " << locale << " in " <<
QString("%1/../share/locale/%2/LC_MESSAGES").arg(QCoreApplication::applicationDirPath(), locale);
}
else if(translator.load("gcompris_qt.qm", QString("%1/../share/locale/%2/LC_MESSAGES").arg(QCoreApplication::applicationDirPath(), locale.split('_')[0]))) {
qDebug() << "load translation for locale " << locale << " in " <<
QString("%1/../share/locale/%2/LC_MESSAGES").arg(QCoreApplication::applicationDirPath(), locale.split('_')[0]);
}
else
#endif
if(!translator.load("gcompris_" + locale, QString("%1/%2/translations").arg(QCoreApplication::applicationDirPath(), GCOMPRIS_DATA_FOLDER))) {
qDebug() << "Unable to load translation for locale " <<
locale << ", use en_US by default";
}
#endif
return locale;
}
int main(int argc, char *argv[])
{
// Disable it because we already support HDPI display natively
qunsetenv("QT_DEVICE_PIXEL_RATIO");
-#if QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)
- QString renderer = QString(GRAPHICAL_RENDERER);
- if(renderer == "software")
- QQuickWindow::setSceneGraphBackend(QSGRendererInterface::Software);
- else if(renderer == "opengl")
- QQuickWindow::setSceneGraphBackend(QSGRendererInterface::OpenGL);
-#endif
-
QApplication app(argc, argv);
app.setOrganizationName("KDE");
app.setApplicationName(GCOMPRIS_APPLICATION_NAME);
app.setOrganizationDomain("kde.org");
app.setApplicationVersion(ApplicationInfo::GCVersion());
-
+
+ //add a variable to disable default fullscreen on Mac, see below..
#if defined(Q_OS_MAC)
// Sandboxing on MacOSX as documented in:
// http://doc.qt.io/qt-5/osx-deployment.html
QDir dir(QGuiApplication::applicationDirPath());
dir.cdUp();
dir.cd("Plugins");
QGuiApplication::setLibraryPaths(QStringList(dir.absolutePath()));
#endif
// Local scope for config
QSettings config(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) +
"/gcompris/" + GCOMPRIS_APPLICATION_NAME + ".conf",
QSettings::IniFormat);
// Load translations
QTranslator translator;
loadTranslation(config, translator);
// Apply translation
app.installTranslator(&translator);
QCommandLineParser parser;
parser.setApplicationDescription("GCompris is an educational software for children 2 to 10");
parser.addHelpOption();
parser.addVersionOption();
QCommandLineOption exportActivitiesAsSQL("export-activities-as-sql", "Export activities as SQL");
parser.addOption(exportActivitiesAsSQL);
- QCommandLineOption clDefaultCursor(QStringList() << "c" << "cursor",
+ QCommandLineOption clDefaultCursor(QStringList() << "c" << "cursor",
QObject::tr("Run GCompris with the default system cursor."));
- parser.addOption(clDefaultCursor);
+ parser.addOption(clDefaultCursor);
QCommandLineOption clNoCursor(QStringList() << "C" << "nocursor",
QObject::tr("Run GCompris without cursor (touch screen mode)."));
parser.addOption(clNoCursor);
QCommandLineOption clFullscreen(QStringList() << "f" << "fullscreen",
QObject::tr("Run GCompris in fullscreen mode."));
parser.addOption(clFullscreen);
QCommandLineOption clWindow(QStringList() << "w" << "window",
QObject::tr("Run GCompris in window mode."));
parser.addOption(clWindow);
QCommandLineOption clSound(QStringList() << "s" << "sound",
QObject::tr("Run GCompris with sound enabled."));
parser.addOption(clSound);
QCommandLineOption clMute(QStringList() << "m" << "mute",
QObject::tr("Run GCompris without sound."));
parser.addOption(clMute);
QCommandLineOption clWithoutKioskMode(QStringList() << "disable-kioskmode",
QObject::tr("Disable the kiosk mode (default)."));
parser.addOption(clWithoutKioskMode);
QCommandLineOption clWithKioskMode(QStringList() << "enable-kioskmode",
QObject::tr("Enable the kiosk mode."));
parser.addOption(clWithKioskMode);
- parser.process(app);
+ QCommandLineOption clSoftwareRenderer(QStringList() << "software-renderer",
+ QObject::tr("Use software renderer instead of openGL (slower but should run with any graphical card, needs Qt 5.8 minimum)."));
+ parser.addOption(clSoftwareRenderer);
+ QCommandLineOption clOpenGLRenderer(QStringList() << "opengl-renderer",
+ QObject::tr("Use openGL renderer instead of software (faster but crash potentially depending on your graphical card)."));
+ parser.addOption(clOpenGLRenderer);
+
+ parser.process(app);
- ApplicationInfo::init();
- ActivityInfoTree::init();
- ApplicationSettings::init();
- File::init();
- Directory::init();
- DownloadManager::init();
+ GComprisPlugin plugin;
+ plugin.registerTypes("GCompris");
+ ActivityInfoTree::registerResources();
// Tell media players to stop playing, it's GCompris time
ApplicationInfo::getInstance()->requestAudioFocus();
// Must be done after ApplicationSettings is constructed because we get an
// async callback from the payment system
ApplicationSettings::getInstance()->checkPayment();
- // Getting fullscreen mode from config if exist, else true is default value
+ // Disable default fullscreen launch on Mac as it's a bit broken, window is behind desktop bars
+#if defined(Q_OS_MAC)
+ bool isFullscreen = false;
+#else
+ // for other platforms, fullscreen is the default value
bool isFullscreen = true;
+#endif
{
+ isFullscreen = config.value("General/fullscreen", isFullscreen).toBool();
- if(config.contains("General/fullscreen")) {
- isFullscreen = config.value("General/fullscreen").toBool();
- }
-
- // Set the cursor image
- bool defaultCursor = false;
- if(config.contains("General/defaultCursor")) {
- defaultCursor = config.value("General/defaultCursor").toBool();
- }
- if(!defaultCursor && !parser.isSet(clDefaultCursor))
- QGuiApplication::setOverrideCursor(
- QCursor(QPixmap(":/gcompris/src/core/resource/cursor.svg"),
- 0, 0));
-
- // Hide the cursor
- bool noCursor = false;
- if(config.contains("General/noCursor")) {
- noCursor = config.value("General/noCursor").toBool();
- }
- if(noCursor || parser.isSet(clNoCursor))
- QGuiApplication::setOverrideCursor(QCursor(Qt::BlankCursor));
+ // Set the cursor image
+ bool defaultCursor = config.value("General/defaultCursor", false).toBool();
+
+ if(!defaultCursor && !parser.isSet(clDefaultCursor))
+ QGuiApplication::setOverrideCursor(
+ QCursor(QPixmap(":/gcompris/src/core/resource/cursor.svg"),
+ 0, 0));
+
+ // Hide the cursor
+ bool noCursor = config.value("General/noCursor", false).toBool();
+
+ if(noCursor || parser.isSet(clNoCursor))
+ QGuiApplication::setOverrideCursor(QCursor(Qt::BlankCursor));
}
// Update execution counter
ApplicationSettings::getInstance()->setExeCount(ApplicationSettings::getInstance()->exeCount() + 1);
if(parser.isSet(clFullscreen)) {
isFullscreen = true;
}
if(parser.isSet(clWindow)) {
isFullscreen = false;
}
if(parser.isSet(clMute)) {
ApplicationSettings::getInstance()->setIsAudioEffectsEnabled(false);
ApplicationSettings::getInstance()->setIsAudioVoicesEnabled(false);
}
if(parser.isSet(clSound)) {
ApplicationSettings::getInstance()->setIsAudioEffectsEnabled(true);
ApplicationSettings::getInstance()->setIsAudioVoicesEnabled(true);
}
if(parser.isSet(clWithoutKioskMode)) {
ApplicationSettings::getInstance()->setKioskMode(false);
}
if(parser.isSet(clWithKioskMode)) {
ApplicationSettings::getInstance()->setKioskMode(true);
}
+ if(parser.isSet(clSoftwareRenderer)) {
+ ApplicationSettings::getInstance()->setRenderer(QStringLiteral("software"));
+ }
+ if(parser.isSet(clOpenGLRenderer)) {
+ ApplicationSettings::getInstance()->setRenderer(QStringLiteral("opengl"));
+ }
+
+ // Set the renderer used
+ const QString &renderer = ApplicationSettings::getInstance()->renderer();
+ ApplicationInfo::getInstance()->setUseOpenGL(renderer != QLatin1String("software"));
+
+#if QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)
+ if(renderer == QLatin1String("software"))
+ QQuickWindow::setSceneGraphBackend(QSGRendererInterface::Software);
+ else if(renderer == QLatin1String("opengl"))
+ QQuickWindow::setSceneGraphBackend(QSGRendererInterface::OpenGL);
+#endif
QQmlApplicationEngine engine(QUrl("qrc:/gcompris/src/core/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::quit, DownloadManager::getInstance(),
&DownloadManager::shutdown);
// add import path for shipped qml modules:
#ifdef SAILFISHOS
engine.addImportPath(QStringLiteral("%1/../share/%2/lib/qml")
.arg(QCoreApplication::applicationDirPath()).arg(GCOMPRIS_APPLICATION_NAME));
#else
engine.addImportPath(QStringLiteral("%1/../lib/qml")
.arg(QCoreApplication::applicationDirPath()));
#endif
+ ApplicationInfo::getInstance()->setBox2DInstalled(engine);
+
if(parser.isSet(exportActivitiesAsSQL)) {
- ActivityInfoTree *menuTree(qobject_cast<ActivityInfoTree*>(ActivityInfoTree::menuTreeProvider(&engine, NULL)));
+ ActivityInfoTree *menuTree(qobject_cast<ActivityInfoTree*>(ActivityInfoTree::menuTreeProvider(&engine, nullptr)));
menuTree->exportAsSQL();
exit(0);
}
QObject *topLevel = engine.rootObjects().value(0);
QQuickWindow *window = qobject_cast<QQuickWindow *>(topLevel);
- if (!window) {
- qWarning("Error: Your root item has to be a Window.");
- return -1;
- }
-
+ if (window == nullptr) {
+ qWarning("Error: Your root item has to be a Window.");
+ return -1;
+ }
ApplicationInfo::setWindow(window);
window->setIcon(QIcon(QPixmap(QString::fromUtf8(":/gcompris/src/core/resource/gcompris-icon.png"))));
if(isFullscreen) {
window->showFullScreen();
}
else {
window->show();
}
return app.exec();
}
diff --git a/src/core/main.qml b/src/core/main.qml
index b024a81a2..85ee8d965 100644
--- a/src/core/main.qml
+++ b/src/core/main.qml
@@ -1,353 +1,373 @@
/* GCompris - main.qml
*
* Copyright (C) 2014 Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* Authors:
* Bruno Coudoin <bruno.coudoin@gcompris.net>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick 2.6
import QtQuick.Controls 1.5
-import QtQuick.Window 2.1
+import QtQuick.Window 2.2
import QtQml 2.2
import GCompris 1.0
import "qrc:/gcompris/src/core/core.js" as Core
/**
* GCompris' main QML file defining the top level window.
* @ingroup infrastructure
*
* Handles application start (Component.onCompleted) and shutdown (onClosing)
* on the QML layer.
*
* Contains the central GCAudio objects audio effects and audio voices.
*
* Contains the top level StackView presenting and animating GCompris'
* full screen views.
*
* @sa BarButton, BarEnumContent
* @inherit QtQuick.Window
*/
Window {
id: main
// Start in window mode at full screen size
width: ApplicationSettings.previousWidth
height: ApplicationSettings.previousHeight
minimumWidth: 400 * ApplicationInfo.ratio
minimumHeight: 400 * ApplicationInfo.ratio
title: "GCompris"
/// @cond INTERNAL_DOCS
property var applicationState: Qt.application.state
property bool isMusicalActivityRunning: false
onApplicationStateChanged: {
if (ApplicationInfo.isMobile && applicationState != Qt.ApplicationActive) {
audioVoices.stop();
audioEffects.stop();
}
}
onClosing: Core.quit(main)
GCAudio {
id: audioVoices
muted: !ApplicationSettings.isAudioVoicesEnabled
Timer {
id: delayedWelcomeTimer
interval: 10000 /* Make sure, that playing welcome.ogg if delayed
* because of not yet registered voices, will only
* happen max 10sec after startup */
repeat: false
onTriggered: {
DownloadManager.voicesRegistered.disconnect(playWelcome);
}
function playWelcome() {
audioVoices.append(ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/misc/welcome.$CA"));
}
}
Component.onCompleted: {
if(ApplicationSettings.isAudioEffectsEnabled)
audioVoices.append(ApplicationInfo.getAudioFilePath("qrc:/gcompris/src/core/resource/intro.$CA"))
if (DownloadManager.areVoicesRegistered())
delayedWelcomeTimer.playWelcome();
else {
DownloadManager.voicesRegistered.connect(
delayedWelcomeTimer.playWelcome);
delayedWelcomeTimer.start();
}
}
}
GCSfx {
id: audioEffects
muted: !ApplicationSettings.isAudioEffectsEnabled && !main.isMusicalActivityRunning
}
function playIntroVoice(name) {
name = name.split("/")[0]
audioVoices.play(ApplicationInfo.getAudioFilePath("voices-$CA/$LOCALE/intro/" + name + ".$CA"))
}
function checkWordset() {
var wordset = ApplicationSettings.wordset
if(wordset == '')
// Maybe the wordset has been bundled or copied manually
// we have to register it if we find it.
wordset = 'data2/words/words.rcc'
// check for words.rcc:
if (DownloadManager.isDataRegistered("words")) {
// words.rcc is already registered -> nothing to do
} else if(DownloadManager.haveLocalResource(wordset)) {
// words.rcc is there -> register old file first
// then try to update in the background
if(DownloadManager.updateResource(wordset)) {
ApplicationSettings.wordset = wordset
}
} else if(ApplicationSettings.wordset) { // Only if wordset specified
// words.rcc has not been downloaded yet -> ask for download
Core.showMessageDialog(
main,
qsTr("The images for several activities are not yet installed. " +
"Do you want to download them now?"),
qsTr("Yes"),
function() {
if (DownloadManager.downloadResource(wordset))
var downloadDialog = Core.showDownloadDialog(pageView.currentItem, {});
},
qsTr("No"), null,
function() { pageView.currentItem.focus = true }
);
}
}
ChangeLog {
id: changelog
}
Component.onCompleted: {
console.log("enter main.qml (run #" + ApplicationSettings.exeCount
+ ", ratio=" + ApplicationInfo.ratio
+ ", fontRatio=" + ApplicationInfo.fontRatio
+ ", dpi=" + Math.round(Screen.pixelDensity*25.4)
- + ", sharedWritablePath=" + ApplicationInfo.getSharedWritablePath()
+ + ", userDataPath=" + ApplicationSettings.userDataPath
+ ")");
if (ApplicationSettings.exeCount === 1 &&
!ApplicationSettings.isKioskMode &&
ApplicationInfo.isDownloadAllowed) {
// first run
var dialog;
dialog = Core.showMessageDialog(
main,
qsTr("Welcome to GCompris!") + '\n'
+ qsTr("You are running GCompris for the first time.") + '\n'
+ qsTr("You should verify that your application settings especially your language is set correctly, and that all language specific sound files are installed. You can do this in the Preferences Dialog.")
+ "\n"
+ qsTr("Have Fun!")
+ "\n"
+ qsTr("Your current language is %1 (%2).")
.arg(Qt.locale(ApplicationInfo.getVoicesLocale(ApplicationSettings.locale)).nativeLanguageName)
.arg(ApplicationInfo.getVoicesLocale(ApplicationSettings.locale))
+ "\n"
+ qsTr("Do you want to download the corresponding sound files now?"),
qsTr("Yes"),
function() {
if (DownloadManager.downloadResource(
DownloadManager.getVoicesResourceForLocale(ApplicationSettings.locale)))
var downloadDialog = Core.showDownloadDialog(pageView.currentItem, {});
},
qsTr("No"), null,
function() {
pageView.currentItem.focus = true
checkWordset()
}
);
}
else {
// Register voices-resources for current locale, updates/downloads only if
// not prohibited by the settings
if (!DownloadManager.areVoicesRegistered()) {
DownloadManager.updateResource(
DownloadManager.getVoicesResourceForLocale(ApplicationSettings.locale));
}
checkWordset()
if(changelog.isNewerVersion(ApplicationSettings.lastGCVersionRan, ApplicationInfo.GCVersionCode)) {
// display log between ApplicationSettings.lastGCVersionRan and ApplicationInfo.GCVersionCode
- var dialog;
- dialog = Core.showMessageDialog(
+ Core.showMessageDialog(
main,
qsTr("GCompris has been updated! Here are the new changes:<br/>") + changelog.getLogBetween(ApplicationSettings.lastGCVersionRan, ApplicationInfo.GCVersionCode),
"", null,
"", null,
function() { pageView.currentItem.focus = true }
);
// Store new version
ApplicationSettings.lastGCVersionRan = ApplicationInfo.GCVersionCode;
}
}
}
Loading {
id: loading
}
StackView {
id: pageView
anchors.fill: parent
initialItem: {
"item": "qrc:/gcompris/src/activities/" + ActivityInfoTree.rootMenu.name,
"properties": {
'audioVoices': audioVoices,
'audioEffects': audioEffects,
'loading': loading
}
}
focus: true
delegate: StackViewDelegate {
id: root
function getTransition(properties)
{
audioVoices.clearQueue()
audioVoices.stop()
if(!properties.exitItem.isDialog && // if coming from menu and
!properties.enterItem.isDialog) // going into an activity then
playIntroVoice(properties.enterItem.activityInfo.name); // play intro
// is this if needed?
//if (!properties.exitItem.isDialog || // if coming from menu or
// properties.enterItem.alwaysStart) // start signal enforced (for special case like transition from config-dialog to editor)
properties.enterItem.start();
if(properties.name === "pushTransition") {
if(properties.enterItem.isDialog) {
return pushVTransition
} else {
if(properties.enterItem.isMusicalActivity)
main.isMusicalActivityRunning = true
return pushHTransition
}
} else {
if(properties.exitItem.isDialog) {
return popVTransition
} else {
main.isMusicalActivityRunning = false
return popHTransition
}
}
}
function transitionFinished(properties)
{
properties.exitItem.opacity = 1
if(!properties.enterItem.isDialog) {
properties.exitItem.stop()
}
}
property Component pushHTransition: StackViewTransition {
PropertyAnimation {
target: enterItem
property: "x"
from: target.width
to: 0
duration: 500
easing.type: Easing.OutSine
}
PropertyAnimation {
target: exitItem
property: "x"
from: 0
to: -target.width
duration: 500
easing.type: Easing.OutSine
}
}
property Component popHTransition: StackViewTransition {
PropertyAnimation {
target: enterItem
property: "x"
from: -target.width
to: 0
duration: 500
easing.type: Easing.OutSine
}
PropertyAnimation {
target: exitItem
property: "x"
from: 0
to: target.width
duration: 500
easing.type: Easing.OutSine
}
}
property Component pushVTransition: StackViewTransition {
PropertyAnimation {
target: enterItem
property: "y"
from: -target.height
to: 0
duration: 500
easing.type: Easing.OutSine
}
PropertyAnimation {
target: exitItem
property: "y"
from: 0
to: target.height
duration: 500
easing.type: Easing.OutSine
}
}
property Component popVTransition: StackViewTransition {
PropertyAnimation {
target: enterItem
property: "y"
from: target.height
to: 0
duration: 500
easing.type: Easing.OutSine
}
PropertyAnimation {
target: exitItem
property: "y"
from: 0
to: -target.height
duration: 500
easing.type: Easing.OutSine
}
}
property Component replaceTransition: pushHTransition
}
}
+ onSceneGraphError: {
+ print("scene graph error ", error, message)
+ ApplicationSettings.renderer = "software"
+ Core.showMessageDialog(
+ main,
+ qsTr("There is an issue while running GCompris. " +
+ "We have fallbacken to software renderer mode that should solve the issue. ") +
+ "You need to restart GCompris so it can take effect.",
+ "", null, "", null, null);
+ }
+
+ onSceneGraphInvalidated: {
+ print("scene graph invalidated")
+ ApplicationSettings.renderer = "software"
+ Core.showMessageDialog(
+ main,
+ qsTr("There is an issue while running GCompris. " +
+ "We have fallbacken to software renderer mode that should solve the issue. ") +
+ "You need to restart GCompris so it can take effect.",
+ "", null, "", null, null);
+ }
/// @endcond
}
diff --git a/src/core/qmldir b/src/core/qmldir
index 9279e8187..b1da79b4f 100644
--- a/src/core/qmldir
+++ b/src/core/qmldir
@@ -1 +1,3 @@
-singleton GCSingletonFontLoader GCSingletonFontLoader.qml
\ No newline at end of file
+module GCompris
+singleton GCSingletonFontLoader GCSingletonFontLoader.qml
+classname GComprisPlugin
diff --git a/src/core/resource/README b/src/core/resource/README
index 54cdcf479..9f9750e97 100644
--- a/src/core/resource/README
+++ b/src/core/resource/README
@@ -1,76 +1,81 @@
Copyright: Ludovic Grossard, 2005 - based on a theme by Djilali Sebihi
License: GPL
File:
intro.ogg
Copyright: warszawianka, 2010
License: Public Domain
Files:
arrows_move.svg
Copyright: Tyson Tan, 2014
License: CC-BY-SA
Files:
aboutkde.png
Copyright: Holger Kaelberer, 2014
License: GPL v3
Files:
arrow.png
Copyright: Bruno Coudoin, 2014
License: GPL
Files:
star.png
Copyright: Timothée Giet, 2015
License: CC-BY-SA 4.0
Files:
apply_disabled.svg
apply.svg
bar_about.svg
bar_config.svg
bar_exit.svg
bar_help.svg
bar_hint.svg
bar_home.svg
bar_next.svg
bar_ok.svg
bar_open.svg
bar_previous.svg
bar_reload.svg
bar_repeat.svg
button.svg
cancel_disabled.svg
cancel.svg
cursor.svg
difficulty1.svg
difficulty2.svg
difficulty3.svg
difficulty4.svg
difficulty5.svg
difficulty6.svg
loader.gif
loading.svg
Copyright: Timothée Giet, 2016 - based on http://openclipart.org/detail/32719/architetto
License: CC-BY-SA 4.0
File:
tuxballoon.svg
Copyright: Timothée Giet, 2016 - based on https://openclipart.org/detail/48937/Trophy
License: CC-BY-SA 4.0
File:
win.svg
Copyright: Timothée Giet, 2016
License: GPL v3
Files:
gcompris-icon.png
gcompris.png
Copyright: Timothée Giet, 2017
License: CC-BY-SA 4.0
Files:
scroll_down.svg
scroll_up.svg
+
+Copyright: Web Lab X
+License: Creative Commons (Attribution 3.0 Unported)
+Files:
+file_icon.svg
diff --git a/src/core/resource/bar_down.svg b/src/core/resource/bar_down.svg
new file mode 100644
index 000000000..215a391d7
--- /dev/null
+++ b/src/core/resource/bar_down.svg
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="40"
+ height="20"
+ id="svg4211"
+ version="1.1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="bar_down.svg">
+ <defs
+ id="defs4213" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#959595"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="15.839192"
+ inkscape:cx="22.43111"
+ inkscape:cy="5.76364"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1">
+ <inkscape:grid
+ type="xygrid"
+ id="grid815" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata4216">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ <dc:date>2015</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Timothée Giet</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Calque 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-483.18356,-437.54484)">
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 503.18356,457.54484 20,-15 h -40 z"
+ id="path817"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#e99e33;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 503.18356,455.54484 16,-12 h -32 z"
+ id="path819"
+ inkscape:connector-curvature="0" />
+ </g>
+</svg>
diff --git a/src/core/resource/bar_up.svg b/src/core/resource/bar_up.svg
new file mode 100644
index 000000000..bb9ae5e39
--- /dev/null
+++ b/src/core/resource/bar_up.svg
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="40"
+ height="20"
+ id="svg4211"
+ version="1.1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="bar_up.svg">
+ <defs
+ id="defs4213" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#959595"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="15.839192"
+ inkscape:cx="22.43111"
+ inkscape:cy="5.76364"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0"
+ inkscape:window-width="1884"
+ inkscape:window-height="1051"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1">
+ <inkscape:grid
+ type="xygrid"
+ id="grid815" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata4216">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ <dc:date>2015</dc:date>
+ <dc:creator>
+ <cc:Agent>
+ <dc:title>Timothée Giet</dc:title>
+ </cc:Agent>
+ </dc:creator>
+ <cc:license
+ rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
+ </cc:Work>
+ <cc:License
+ rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Reproduction" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#Distribution" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Notice" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#Attribution" />
+ <cc:permits
+ rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+ <cc:requires
+ rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+ </cc:License>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Calque 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-483.18356,-437.54484)">
+ <path
+ style="fill:#ffffff;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
+ d="m 503.18356,437.54484 -20,15 h 40 z"
+ id="path817"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#e99e33;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
+ d="m 503.18356,439.54484 -16,12 h 32 z"
+ id="path819"
+ inkscape:connector-curvature="0" />
+ </g>
+</svg>
diff --git a/src/core/resource/file_icon.svg b/src/core/resource/file_icon.svg
new file mode 100644
index 000000000..86edf1d97
--- /dev/null
+++ b/src/core/resource/file_icon.svg
@@ -0,0 +1 @@
+<?xml version="1.0" ?><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'><svg enable-background="new 0 0 512 512" height="512px" id="Layer_1" version="1.1" viewBox="0 0 512 512" width="512px" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M438.247,183.129L261.315,6.196h-15.192h-5.633H73.888V506h364.44V183.16L438.247,183.129z M261.315,35.645 l137.153,137.152H261.315V35.645z M94.713,485.175V27.021H240.49v166.601h177.014v291.552H94.713z" fill="#37404D"/></svg>
\ No newline at end of file
diff --git a/src/core/synth/ADSRenvelope.cpp b/src/core/synth/ADSRenvelope.cpp
new file mode 100644
index 000000000..4e146727e
--- /dev/null
+++ b/src/core/synth/ADSRenvelope.cpp
@@ -0,0 +1,72 @@
+/* miniSynth - A Simple Software Synthesizer
+ Copyright (C) 2015 Ville Räisänen <vsr at vsr.name>
+
+ This program is free software: you can 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 <https://www.gnu.org/licenses/>.
+*/
+
+
+#include "ADSRenvelope.h"
+//#include <QDebug>
+
+ADSREnvelope::ADSREnvelope() : ADSREnvelope(0, 0, 0, 0.f, 0.f, 0.f) {
+}
+
+ADSREnvelope::ADSREnvelope(unsigned int _attackTime,
+ unsigned int _decayTime,
+ unsigned int _releaseTime,
+ qreal _initialAmpl,
+ qreal _peakAmpl,
+ qreal _sustainAmpl) : initialAmpl(_initialAmpl),
+ peakAmpl(_peakAmpl),
+ sustainAmpl(_sustainAmpl),
+ attackTime(_attackTime),
+ decayTime(_decayTime),
+ releaseTime(_releaseTime) {
+}
+
+qreal
+ADSREnvelope::eval(qreal t, unsigned char state) const {
+ qreal attackTimeF = ((qreal)attackTime)/1000;
+ qreal decayTimeF = ((qreal)decayTime)/1000;
+ qreal releaseTimeF = ((qreal)releaseTime)/1000;
+
+ switch (state) {
+ case STATE_ATTACK:
+ if (t < attackTimeF) {
+ return initialAmpl*(attackTimeF - t)/attackTimeF + peakAmpl*t/attackTimeF;
+ } else {
+ //qWarning() << "ADSREnvelope::eval - attack outside range";
+ return peakAmpl;
+ }
+ break;
+ case STATE_DECAY:
+ if (t < decayTimeF) {
+ return peakAmpl*(decayTimeF-t)/decayTimeF + sustainAmpl*t/decayTimeF;
+ } else {
+ return sustainAmpl;
+ }
+ break;
+ case STATE_RELEASE:
+ if (t < releaseTimeF) {
+ return sustainAmpl*(1 - t/releaseTimeF);
+ } else {
+ //qWarning() << "ADSREnvelope::eval - release outside range";
+ return 0;
+ }
+ break;
+ }
+
+ //qWarning() << "ADSREnvelope::eval - invalid state";
+ return 0;
+}
diff --git a/src/core/synth/ADSRenvelope.h b/src/core/synth/ADSRenvelope.h
new file mode 100644
index 000000000..bd9a4ed18
--- /dev/null
+++ b/src/core/synth/ADSRenvelope.h
@@ -0,0 +1,42 @@
+/* miniSynth - A Simple Software Synthesizer
+ Copyright (C) 2015 Ville Räisänen <vsr at vsr.name>
+
+ This program is free software: you can 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 <https://www.gnu.org/licenses/>.
+*/
+
+#ifndef ADSRENVELOPE_H
+#define ADSRENVELOPE_H
+
+#include <qmath.h>
+
+class ADSREnvelope {
+public:
+ ADSREnvelope();
+ ADSREnvelope(unsigned int _attackTime,
+ unsigned int _decayTime,
+ unsigned int _releaseTime,
+ qreal _initialAmpl,
+ qreal _peakAmpl,
+ qreal _sustainAmpl);
+ ~ADSREnvelope() = default;
+ enum {STATE_OFF, STATE_ATTACK, STATE_DECAY, STATE_RELEASE};
+
+ qreal initialAmpl, peakAmpl, sustainAmpl;
+ unsigned int attackTime, decayTime, releaseTime;
+
+ qreal eval(qreal t, unsigned char state) const;
+private:
+};
+
+#endif // ADSRENVELOPE_H
diff --git a/src/core/synth/GSynth.cpp b/src/core/synth/GSynth.cpp
new file mode 100644
index 000000000..6c8b32c2c
--- /dev/null
+++ b/src/core/synth/GSynth.cpp
@@ -0,0 +1,97 @@
+/* GCompris - GSynth.cpp
+ *
+ * Copyright (C) 2018 Timothée Giet <animtim@gmail.com>
+ *
+ * Authors:
+ * Johnny Jazeix <jazeix@gmail.com>
+ * Timothée Giet <animtim@gmail.com>
+ *
+ * This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+ */
+
+#include "GSynth.h"
+#include "generator.h"
+
+#include <QDebug>
+
+GSynth *GSynth::m_instance = nullptr;
+
+GSynth::GSynth(QObject *parent) : QObject(parent)
+{
+ bufferSize = 8192;
+
+ m_format.setSampleRate(22050);
+ m_format.setChannelCount(1);
+ m_format.setSampleSize(16);
+ m_format.setCodec("audio/pcm");
+ m_format.setByteOrder(QAudioFormat::LittleEndian);
+ m_format.setSampleType(QAudioFormat::SignedInt);
+
+ QAudioDeviceInfo info(QAudioDeviceInfo::defaultOutputDevice());
+ if (!info.isFormatSupported(m_format)) {
+ qWarning() << "Default format not supported - trying to use nearest";
+ m_format = info.nearestFormat(m_format);
+ }
+ m_device = QAudioDeviceInfo::defaultOutputDevice();
+ m_buffer = QByteArray(bufferSize, 0);
+
+ m_audioOutput = new QAudioOutput(m_device, m_format, this);
+ m_audioOutput->setBufferSize(bufferSize);
+ m_generator = new Generator(m_format, this);
+ // todo Only start generator if musical activity, and stop it on exit (in main.qml, activity.isMusicalActivity)
+ m_generator->setPreset(PresetCustom);
+ m_generator->start();
+ m_audioOutput->start(m_generator);
+ m_audioOutput->setVolume(1);
+}
+
+GSynth::~GSynth() {
+ m_audioOutput->stop();
+ m_generator->stop();
+ delete m_audioOutput;
+ delete m_generator;
+
+ auto i = m_timers.constBegin();
+ while (i != m_timers.constEnd()) {
+ delete i.value();
+ ++i;
+ }
+}
+
+void GSynth::generate(int note, int duration) {
+ //test part...
+ m_generator->noteOn(1, note, 255);
+ if(!m_timers.contains(note)) {
+ m_timers[note] = new QTimer();
+ connect(m_timers[note], &QTimer::timeout, this,
+ [this, note]() {
+ stopAudio(note);
+ });
+ }
+ m_timers[note]->start(duration);
+}
+
+void GSynth::stopAudio(int note) {
+ m_generator->noteOff(1, note);
+}
+
+QObject *GSynth::synthProvider(QQmlEngine *engine,
+ QJSEngine *scriptEngine)
+{
+ Q_UNUSED(engine)
+ Q_UNUSED(scriptEngine)
+
+ GSynth* synth = getInstance();
+ return synth;
+}
diff --git a/src/core/synth/GSynth.h b/src/core/synth/GSynth.h
new file mode 100644
index 000000000..962e975ed
--- /dev/null
+++ b/src/core/synth/GSynth.h
@@ -0,0 +1,79 @@
+/* GCompris - GSynth.h
+ *
+ * Copyright (C) 2018 Timothée Giet <animtim@gmail.com>
+ *
+ * Authors:
+ * Johnny Jazeix <jazeix@gmail.com>
+ * Timothée Giet <animtim@gmail.com>
+ *
+ * This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+ */
+#ifndef GSYNTH_H
+#define GSYNTH_H
+
+#include <QAudioDeviceInfo>
+#include <QAudioOutput>
+#include <QTimer>
+#include <QQmlEngine>
+#include "preset.h"
+
+class Generator;
+
+class GSynth : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit GSynth(QObject *parent = 0);
+ virtual ~GSynth();
+
+ /**
+ * Generate a note and start the corresponding timer
+ * to stop it at "duration" ms.
+ *
+ * @param note note to play
+ * @param duration how much time the note needs to be played
+ */
+ Q_INVOKABLE void generate(int note, int duration);
+
+ static GSynth *getInstance() {
+ if(!m_instance) {
+ m_instance = new GSynth();
+ }
+ return m_instance;
+ }
+ static QObject *synthProvider(QQmlEngine *engine,
+ QJSEngine *scriptEngine);
+
+protected:
+ static GSynth *m_instance;
+
+private slots:
+ void stopAudio(int note);
+
+private:
+ unsigned int bufferSize;
+
+ Generator *m_generator;
+ QAudioDeviceInfo m_device;
+ QAudioFormat m_format;
+ QByteArray m_buffer;
+ QAudioOutput *m_audioOutput;
+ QMap<int, QTimer *> m_timers;
+
+ Preset PresetCustom;
+};
+
+#endif // GSYNTH_H
+
diff --git a/src/core/synth/generator.cpp b/src/core/synth/generator.cpp
new file mode 100644
index 000000000..70132f527
--- /dev/null
+++ b/src/core/synth/generator.cpp
@@ -0,0 +1,268 @@
+/* miniSynth - A Simple Software Synthesizer
+ Copyright (C) 2015 Ville Räisänen <vsr at vsr.name>
+
+ This program is free software: you can 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 <https://www.gnu.org/licenses/>.
+*/
+
+
+#include "generator.h"
+#include <qendian.h>
+
+Generator::Generator(const QAudioFormat &_format, QObject *parent) : QIODevice(parent), format(_format) {
+ linSyn = new LinearSynthesis(Waveform::MODE_SIN);
+ curtime = 0;
+
+ defaultEnv.attackTime = 100;
+ defaultEnv.decayTime = 400;
+ defaultEnv.releaseTime = 100;
+
+ defaultEnv.initialAmpl = 0;
+ defaultEnv.peakAmpl = 1;
+ defaultEnv.sustainAmpl = 0.8;
+
+ mod_waveform = new Waveform(Waveform::MODE_SIN);
+
+ synthData = new qreal[maxUsedBytes];
+
+ for (unsigned int indMaxRead = 0; indMaxRead < maxUsedBytes; indMaxRead++) {
+ synthData[indMaxRead] = 0;
+ }
+}
+
+Generator::~Generator() {
+ delete linSyn;
+ delete [] synthData;
+ delete mod_waveform;
+}
+
+void
+Generator::start() {
+ open(QIODevice::ReadOnly);
+}
+
+void
+Generator::stop() {
+ close();
+}
+
+void
+Generator::addWave(unsigned char note, unsigned char vel) {
+ Wave wav;
+ wav.state = wav.STATE_ATTACK;
+ wav.note = note;
+ wav.vel = vel;
+ wav.state_age = 0;
+ wav.age = 0;
+ wav.env = defaultEnv;
+
+ m_lock.lock();
+ waveList.push_back(wav);
+ m_lock.unlock();
+}
+
+qint64
+Generator::readData(char *data, qint64 len) {
+ // QAudioOutput tends to ask large packets of data, which can lead to a
+ // large delay between noteOn requests and the generation of audio. Thus,
+ // in order to provide more responsive interface, the packet size is
+ // limited to 2048 bytes ~ 1024 samples.
+ if (len > maxUsedBytes) len = maxUsedBytes;
+
+ generateData(len);
+ memcpy(data, m_buffer.constData(), len);
+ curtime += (qreal)len/(m_samplingRate*2);
+ return len;
+}
+
+// Not used.
+qint64
+Generator::writeData(const char *data, qint64 len) {
+ Q_UNUSED(data);
+ Q_UNUSED(len);
+ return 0;
+}
+
+// Doesn't seem to be called by QAudioOutput.
+qint64
+Generator::bytesAvailable() const {
+ return m_buffer.size() + QIODevice::bytesAvailable();
+}
+
+void
+Generator::noteOn(unsigned char chan, unsigned char note, unsigned char vel) {
+ // Velocity of 255 is assumed since a "pleasant" relationship between the
+ // velocity in the MIDI event and the parameters of the corresponding Wave
+ // cannot be currently selected by the user.
+
+ if (vel > 0) vel = 255;
+ addWave(note, vel);
+ Q_UNUSED(chan);
+}
+
+void
+Generator::noteOff(unsigned char chan, unsigned char note) {
+ QMutableListIterator<Wave> i(waveList);
+
+ while (i.hasNext()) {
+ Wave wav = i.next();
+ if (wav.note == note && wav.state != Wave::STATE_RELEASE) {
+ // To avoid discontinuity in the envelope, the initial value for
+ // the release part of the envelope should be equal to current
+ // value.
+
+ wav.env.sustainAmpl = wav.env.eval(wav.state_age, wav.state);
+
+ wav.state = Wave::STATE_RELEASE;
+ wav.state_age = 0;
+ }
+ i.setValue(wav);
+ }
+ Q_UNUSED(chan);
+}
+
+void
+Generator::setMode(int _mode) {
+ delete linSyn;
+ linSyn = new LinearSynthesis(_mode);
+ curtime = 0;
+}
+
+void
+Generator::setTimbre(QVector<int> &amplitudes, QVector<int> &phases) {
+ linSyn->setTimbre(amplitudes, phases);
+}
+
+void
+Generator::generateData(qint64 len) {
+ unsigned int numSamples = len/2;
+ m_buffer.resize(len);
+
+ // Raw synthesized data is assembled into synthData.
+ memset(synthData, 0, numSamples*sizeof(qreal));
+
+ // All samples for each active note in waveList are synthesized separately.
+ m_lock.lock();
+ QMutableListIterator<Wave> i(waveList);
+
+ while (i.hasNext()) {
+ Wave wav = i.next();
+ qreal attackTime = 0.001*(qreal)wav.env.attackTime,
+ releaseTime = 0.001*(qreal)wav.env.releaseTime;
+
+ qreal freq = 8.175 * 0.5 * qPow(2, ((qreal)wav.note)/12);
+ qreal ampl = 0.5*((qreal)wav.vel)/256;
+
+ qreal stateAge = wav.state_age,
+ wavAge = wav.age;
+
+ const qreal step = 1.f / m_samplingRate;
+ qreal samplePerStep = 0.f;
+ for (unsigned int sample = 0; sample < numSamples; sample++, samplePerStep += step) {
+ qreal t = curtime + samplePerStep;
+ qreal envt = stateAge + samplePerStep;
+ qreal modt = wavAge + samplePerStep;
+
+ // Handle timed change of state in the ADSR-envelopes ATTACK->DECAY
+ // and RELEASE->OFF.
+ switch(wav.state) {
+ case ADSREnvelope::STATE_ATTACK:
+ if (envt > attackTime) {
+ stateAge -= attackTime;
+ wav.state = ADSREnvelope::STATE_DECAY;
+ wav.state_age -= attackTime;
+ envt = stateAge + samplePerStep;
+ }
+ break;
+ case ADSREnvelope::STATE_RELEASE:
+ if (envt > releaseTime) {
+ stateAge = 0;
+ wav.state = ADSREnvelope::STATE_OFF;
+ }
+ break;
+ }
+
+ if (wav.state == ADSREnvelope::STATE_OFF) {
+ break;
+ } else {
+ qreal freqmod = 0, amod = 0;
+
+ // Compute modulation waves.
+
+ if (mod.FM_freq > 0) {
+ qreal envVal = mod.useEnvelope ? wav.env.eval(envt, wav.state) : 1;
+ if (mod.propFreq) {
+ freqmod = mod.FM_ampl
+ * envVal* mod_waveform->eval(2*M_PI*mod.FM_freq*freq*modt);
+ } else {
+ freqmod = mod.FM_ampl
+ * mod_waveform->eval(2*M_PI*mod.FM_freq*modt);
+ }
+ }
+ if (mod.AM_freq > 0) {
+ amod = (1 - qExp(-modt/mod.AM_time))*mod.AM_ampl * mod_waveform->eval(2*M_PI*mod.AM_freq*t);
+ }
+
+ // Evaluate the output wave for the current note and add to the
+ // output obtained with other notes.
+
+ qreal envVal = wav.env.eval(envt, wav.state);
+ qreal newVal = envVal * (ampl + amod)
+ * 0.5 * linSyn->evalTimbre(2*M_PI*(freq+freqmod)*(modt+100));
+
+ synthData[sample] += newVal;
+ }
+ }
+ wav.age += (qreal)numSamples/m_samplingRate;
+ if (wav.state != ADSREnvelope::STATE_OFF) {
+ wav.state_age += (qreal)numSamples/m_samplingRate;
+ i.setValue(wav);
+ }
+ else {
+ i.remove();
+ }
+ }
+ m_lock.unlock();
+
+ // Convert data from qreal to qint16.
+ const int channelBytes = format.sampleSize() / 8;
+ unsigned char *ptr = reinterpret_cast<unsigned char *>(m_buffer.data());
+ for (unsigned int sample = 0; sample < numSamples; sample++) {
+ if (synthData[sample] > 1) synthData[sample] = 1;
+ if (synthData[sample] < -1) synthData[sample] = -1;
+ qint16 value = static_cast<qint16>(synthData[sample] * 32767);
+ qToLittleEndian<qint16>(value, ptr);
+ ptr += channelBytes;
+ }
+}
+
+void
+Generator::setEnvelope(ADSREnvelope &env) {
+ defaultEnv = env;
+}
+
+void
+Generator::setModulation(Modulation &modulation) {
+ if (modulation.mode != mod_waveform->mode) {
+ delete mod_waveform;
+ mod_waveform = new Waveform(modulation.mode);
+ }
+ mod = modulation;
+}
+
+void Generator::setPreset(Preset &preset) {
+ setModulation(preset.mod);
+ setMode(preset.waveformMode);
+ setTimbre(preset.timbreAmplitudes, preset.timbrePhases);
+ setEnvelope(preset.env);
+}
diff --git a/src/core/synth/generator.h b/src/core/synth/generator.h
new file mode 100644
index 000000000..3f6bf21f6
--- /dev/null
+++ b/src/core/synth/generator.h
@@ -0,0 +1,103 @@
+/* miniSynth - A Simple Software Synthesizer
+ Copyright (C) 2015 Ville Räisänen <vsr at vsr.name>
+
+ This program is free software: you can 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 <https://www.gnu.org/licenses/>.
+*/
+
+#ifndef GENERATOR_H
+#define GENERATOR_H
+
+#include <QAudioDeviceInfo>
+#include <QAudioOutput>
+#include <QByteArray>
+#include <QIODevice>
+
+#include <QMutex>
+#include <QList>
+#include <QMutableListIterator>
+
+#include "linearSynthesis.h"
+#include "modulation.h"
+#include "ADSRenvelope.h"
+#include "preset.h"
+
+// The state of each active note is described with an Wave object. Wave
+// objects are assembled into the QList<Wave> waveList and removed once
+// they reach the state STATE_OFF.
+
+class Wave {
+public:
+ enum {STATE_OFF, STATE_ATTACK, STATE_DECAY, STATE_RELEASE};
+ unsigned char note, vel, state;
+ qreal state_age, age;
+ ADSREnvelope env;
+};
+
+// The synthesizer is implemented as a QIODevice and is connected to
+// a QAudioOutput in mainWindow.cpp. QAudioOutput reads data from the
+// synthersizer using the function readData(data, size). readData
+// returns maximum of 2048 samples generated with generateData(len).
+
+class Generator : public QIODevice {
+ Q_OBJECT
+public:
+ explicit Generator(const QAudioFormat &_format, QObject *parent = 0);
+ ~Generator();
+
+ void start ();
+ void stop ();
+ void setState ();
+
+ void addWave (unsigned char note, unsigned char vel);
+
+ qint64 readData(char *data, qint64 len);
+ qint64 writeData(const char *data, qint64 len);
+ qint64 bytesAvailable() const;
+
+ void generateData(qint64 len);
+
+public slots:
+ void noteOn (unsigned char chan, unsigned char note, unsigned char vel);
+ void noteOff (unsigned char chan, unsigned char note);
+
+ // Slots for manipulation of the current patch.
+ void setMode (int _mode);
+ void setTimbre (QVector<int> &amplitudes, QVector<int> &phases);
+ void setEnvelope (ADSREnvelope &env);
+ void setModulation(Modulation &modulation);
+ void setPreset (Preset &preset);
+
+private:
+ QAudioFormat format;
+ QByteArray m_buffer;
+
+ // State of the synthesizer
+ qreal curtime;
+ QList<Wave> waveList;
+
+ // Parameters of the current patch
+ LinearSynthesis *linSyn;
+ ADSREnvelope defaultEnv;
+ Modulation mod;
+ Waveform *mod_waveform;
+
+ static const int m_samplingRate = 22050;
+ static const int maxUsedBytes = 2048;
+
+ qreal *synthData;
+
+ QMutex m_lock;
+};
+
+#endif // GENERATOR_H
diff --git a/src/core/synth/linearSynthesis.cpp b/src/core/synth/linearSynthesis.cpp
new file mode 100644
index 000000000..c5796b5ab
--- /dev/null
+++ b/src/core/synth/linearSynthesis.cpp
@@ -0,0 +1,68 @@
+/* miniSynth - A Simple Software Synthesizer
+ Copyright (C) 2015 Ville Räisänen <vsr at vsr.name>
+
+ This program is free software: you can 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 <https://www.gnu.org/licenses/>.
+*/
+
+#include "linearSynthesis.h"
+#include <QDebug>
+
+LinearSynthesis::LinearSynthesis(unsigned int mode, unsigned int size) :
+ Waveform(mode, size) {
+
+ numHarmonics = 16;
+
+ timbreAmplitudes = new int[numHarmonics];
+ timbrePhases = new int[numHarmonics];
+
+ timbreAmplitudes[0] = 100;
+}
+
+void
+LinearSynthesis::setTimbre(QVector<int> &amplitudes, QVector<int> &phases) {
+ Q_ASSERT(amplitudes.size() == phases.size());
+
+ delete[] timbreAmplitudes;
+ delete[] timbrePhases;
+
+ numHarmonics = amplitudes.size();
+ timbreAmplitudes = new int[numHarmonics];
+ timbrePhases = new int[numHarmonics];
+ for(int i = 0 ; i < numHarmonics ; ++ i) {
+ timbreAmplitudes[i] = amplitudes[i];
+ timbrePhases[i] = phases[i];
+ }
+}
+
+LinearSynthesis::~LinearSynthesis() {
+ delete[] timbreAmplitudes;
+ delete[] timbrePhases;
+}
+
+qreal
+LinearSynthesis::evalTimbre(qreal t) {
+ qreal val = 0;
+ for (unsigned int harm = 0; harm < numHarmonics; harm++) {
+ int qa_int = timbreAmplitudes[harm],
+ qp_int = timbrePhases[harm];
+
+ if (qa_int > 0) {
+ qreal qa = (qreal)qa_int/100,
+ qp = (2*M_PI*(qreal)qp_int)/360;
+
+ val += qa * eval(((qreal)harm + 1) * t - qp);
+ }
+ }
+ return val;
+}
diff --git a/src/core/synth/linearSynthesis.h b/src/core/synth/linearSynthesis.h
new file mode 100644
index 000000000..663577d4d
--- /dev/null
+++ b/src/core/synth/linearSynthesis.h
@@ -0,0 +1,38 @@
+/* miniSynth - A Simple Software Synthesizer
+ Copyright (C) 2015 Ville Räisänen <vsr at vsr.name>
+
+ This program is free software: you can 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 <https://www.gnu.org/licenses/>.
+*/
+
+#ifndef LINEARSYNTHESIS_H
+#define LINEARSYNTHESIS_H
+
+#include "waveform.h"
+#include <QVector>
+
+class LinearSynthesis : public Waveform {
+public:
+ explicit LinearSynthesis(unsigned int mode, unsigned int size=4096);
+ ~LinearSynthesis();
+
+ qreal evalTimbre(qreal t);
+ void setTimbre(QVector<int> &amplitudes, QVector<int> &phases);
+
+private:
+ int *timbreAmplitudes;
+ int *timbrePhases;
+ unsigned int numHarmonics;
+};
+
+#endif // LINEARSYNTHESIS_H
diff --git a/src/core/synth/modulation.cpp b/src/core/synth/modulation.cpp
new file mode 100644
index 000000000..ceb113094
--- /dev/null
+++ b/src/core/synth/modulation.cpp
@@ -0,0 +1,25 @@
+/* miniSynth - A Simple Software Synthesizer
+ Copyright (C) 2015 Ville Räisänen <vsr at vsr.name>
+
+ This program is free software: you can 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 <https://www.gnu.org/licenses/>.
+*/
+
+#include "modulation.h"
+#include "waveform.h"
+
+Modulation::Modulation() : FM_freq(0.f), FM_ampl(0.f),
+ AM_freq(0.f), AM_ampl(0.f), AM_time(0.2f),
+ mode(Waveform::MODE_SIN),
+ propFreq(false), useEnvelope(false) {
+}
diff --git a/src/core/synth/modulation.h b/src/core/synth/modulation.h
new file mode 100644
index 000000000..747a5cdd5
--- /dev/null
+++ b/src/core/synth/modulation.h
@@ -0,0 +1,36 @@
+/* miniSynth - A Simple Software Synthesizer
+ Copyright (C) 2015 Ville Räisänen <vsr at vsr.name>
+
+ This program is free software: you can 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 <https://www.gnu.org/licenses/>.
+*/
+
+#ifndef MODULATION_H
+#define MODULATION_H
+
+#include <qmath.h>
+#include "waveform.h"
+
+class Modulation {
+public:
+ Modulation();
+ ~Modulation() = default;
+
+ qreal FM_freq, FM_ampl;
+ qreal AM_freq, AM_ampl, AM_time;
+ unsigned int mode;
+
+ bool propFreq, useEnvelope;
+};
+
+#endif // MODULATION_H
diff --git a/src/core/synth/preset.cpp b/src/core/synth/preset.cpp
new file mode 100644
index 000000000..d7a0c4af7
--- /dev/null
+++ b/src/core/synth/preset.cpp
@@ -0,0 +1,36 @@
+/* miniSynth - A Simple Software Synthesizer
+ Copyright (C) 2015 Ville Räisänen <vsr at vsr.name>
+
+ This program is free software: you can 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 <https://www.gnu.org/licenses/>.
+*/
+
+#include "preset.h"
+
+Preset::Preset() : timbreAmplitudes(8, 0), timbrePhases(8, 0) {
+//hardcode custom church pad preset
+ waveformMode = Waveform::MODE_SIN;
+ env.attackTime = 50;
+ env.decayTime = 400;
+ env.releaseTime = 100;
+
+ env.initialAmpl = 0;
+ env.peakAmpl = 1;
+ env.sustainAmpl = 0.8;
+
+ timbreAmplitudes[0] = 50;
+ timbreAmplitudes[1] = 15;
+ timbreAmplitudes[3] = 15;
+ timbreAmplitudes[7] = 50;
+ timbrePhases[0] = 0;
+}
diff --git a/src/core/synth/preset.h b/src/core/synth/preset.h
new file mode 100644
index 000000000..08784e84b
--- /dev/null
+++ b/src/core/synth/preset.h
@@ -0,0 +1,40 @@
+/* miniSynth - A Simple Software Synthesizer
+ Copyright (C) 2015 Ville Räisänen <vsr at vsr.name>
+
+ This program is free software: you can 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 <https://www.gnu.org/licenses/>.
+*/
+
+#ifndef PRESET_H
+#define PRESET_H
+
+#include "ADSRenvelope.h"
+#include "linearSynthesis.h"
+#include "modulation.h"
+
+#include <QVector>
+
+class Preset {
+public:
+ Preset ();
+ ~Preset() = default;
+
+ QVector<int> timbreAmplitudes;
+ QVector<int> timbrePhases;
+ unsigned int waveformMode;
+
+ ADSREnvelope env;
+ Modulation mod;
+};
+
+#endif // PRESET_H
diff --git a/src/core/synth/waveform.cpp b/src/core/synth/waveform.cpp
new file mode 100644
index 000000000..993e69a55
--- /dev/null
+++ b/src/core/synth/waveform.cpp
@@ -0,0 +1,126 @@
+/* miniSynth - A Simple Software Synthesizer
+ Copyright (C) 2015 Ville Räisänen <vsr at vsr.name>
+
+ This program is free software: you can 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 <https://www.gnu.org/licenses/>.
+*/
+
+#include "waveform.h"
+#include <QCoreApplication>
+#include <QDebug>
+
+Waveform::Waveform(unsigned int mode, unsigned int size) {
+ waveTable = new qreal[size];
+ tableSize = size;
+ this->mode = mode;
+
+ for (unsigned int sample = 0; sample < tableSize; sample++) {
+ qreal u = (2*M_PI * (qreal)sample) / ((qreal)tableSize);
+
+ switch(mode) {
+ case MODE_SIN:
+ waveTable[sample] = waveSin(u);
+ break;
+ case MODE_SAW:
+ waveTable[sample] = waveSaw(u);
+ break;
+ case MODE_SAW2:
+ waveTable[sample] = waveSaw2(u);
+ break;
+ case MODE_SQU:
+ waveTable[sample] = waveSqu(u);
+ break;
+ }
+ }
+}
+
+Waveform::~Waveform() {
+ delete [] waveTable;
+ waveTable = nullptr;
+}
+
+qreal
+Waveform::waveSin(qreal t) {
+ return qSin(t);
+}
+
+qreal
+Waveform::waveSaw(qreal t) {
+ qreal tmod = (qreal)(fmod((double)t, 2*M_PI) - M_PI);
+ return tmod / M_PI;
+}
+
+qreal
+Waveform::waveSaw2(qreal t) {
+ qreal tmod = (qreal)(fmod((double)t, 2*M_PI) - M_PI);
+ return 1 - 2 * qAbs(tmod) / M_PI;
+}
+
+qreal
+Waveform::waveSqu(qreal t) {
+ qreal tmod = (qreal)fmod((double)t, 2*M_PI);
+ if (tmod < M_PI) {
+ return 1;
+ }
+ return -1;
+}
+
+
+qreal
+Waveform::eval(qreal t) {
+ qreal tmod = fmod((double)t, 2*M_PI);
+ if (tmod < 0) tmod += 2*M_PI;
+
+ // Position indexed by a continuous variable does not generally fall on
+ // integer-valued points. Here indF is the "continuous-valued position"
+ // of the argument and is somewhere between the integers qFloor(indF) and
+ // qCeil(indF). When indF is not an integer, we use linear interpolation
+ // to obtain the appropriate value.
+
+ qreal indF = ((qreal)tableSize) * tmod / (2*(qreal)M_PI);
+ if (indF == (qreal)tableSize) indF = 0;
+
+ Q_ASSERT(indF >= 0);
+ Q_ASSERT(indF < (qreal)tableSize);
+
+ unsigned int ind_min = (unsigned int) qFloor(indF);
+ unsigned int ind_max = (unsigned int) qCeil(indF);
+
+ Q_ASSERT(ind_min <= ind_max);
+ Q_ASSERT(ind_max <= tableSize);
+ Q_ASSERT(ind_min < tableSize);
+
+ qreal indmod = indF - (qreal)ind_min;
+ Q_ASSERT(indmod < 1 && indmod >= 0);
+
+ qreal value_next, value_prev;
+
+ if (ind_min == ind_max) {
+ return waveTable[ind_min];
+ }
+ if (ind_max == tableSize) {
+ value_prev = waveTable[ind_min];
+ value_next = waveTable[0];
+ return indmod * value_next + (1-indmod) * value_prev;
+ }
+ if (ind_min < ind_max) {
+ Q_ASSERT(ind_max < tableSize);
+ value_prev = waveTable[ind_min];
+ value_next = waveTable[ind_max];
+ return indmod * value_next + (1-indmod) * value_prev;
+ }
+ // This shouldn't be reached;
+ qCritical("Wave Table Interpolation Failed");
+ QCoreApplication::exit(-1);
+ return 0;
+}
diff --git a/src/core/synth/waveform.h b/src/core/synth/waveform.h
new file mode 100644
index 000000000..8e8d702a0
--- /dev/null
+++ b/src/core/synth/waveform.h
@@ -0,0 +1,50 @@
+/* miniSynth - A Simple Software Synthesizer
+ Copyright (C) 2015 Ville Räisänen <vsr at vsr.name>
+
+ This program is free software: you can 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 <https://www.gnu.org/licenses/>.
+*/
+
+#ifndef WAVEFORM_H
+#define WAVEFORM_H
+
+#include <qmath.h>
+#include <math.h>
+
+// The Waveform class implements the necessary code for the generation of the
+// basic waveforms. The waveform is computed at the constructor stage and
+// assembled into a wavetable, which is evaluated with the eval(qreal t)
+// function.
+
+class Waveform {
+public:
+ explicit Waveform(unsigned int mode, unsigned int size=4096);
+ ~Waveform();
+
+ qreal eval(qreal t);
+
+ enum {MODE_SIN, MODE_SAW, MODE_SQU, MODE_SAW2};
+private:
+ qreal waveSin (qreal t);
+ qreal waveSaw (qreal t);
+ qreal waveSqu (qreal t);
+ qreal waveSaw2(qreal t);
+
+ qreal *waveTable;
+ unsigned int tableSize;
+
+public:
+ unsigned int mode;
+};
+
+#endif // WAVEFORM_H
diff --git a/src/core/virtualkeyboard_worker.js b/src/core/virtualkeyboard_worker.js
index 8b2746624..d59b86bd0 100644
--- a/src/core/virtualkeyboard_worker.js
+++ b/src/core/virtualkeyboard_worker.js
@@ -1,94 +1,94 @@
/* GCompris - virtualkeyboard_worker.js
*
* Copyright (C) 2016 Holger Kaelberer <holger.k@elberer.de>
*
* Authors:
* Holger Kaelberer <holger.k@elberer.de>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
WorkerScript.onMessage = function(msg) {
var nRows;
var maxButtons = 0;
msg.rowListModel.clear();
msg.rowListModel.sync();
// validate layout syntax:
if (!Array.isArray(msg.a) || msg.a.length < 1) {
msg.error = "VirtualKeyboard: Invalid layout, array of length > 0";
WorkerScript.sendMessage(msg);
return;
}
nRows = msg.a.length;
// if we need special keys, put them in a separate row at the bottom:
if (msg.shiftKey) {
msg.a.push([ {
label : msg.shiftUpSymbol + " Shift",
shiftLabel: msg.shiftDownSymbol + " Shift",
specialKeyValue: Qt.Key_Shift } ]);
}
var i
var seenLabels = [];
for (i = 0; i < msg.a.length; i++) {
if (!Array.isArray(msg.a[i])) {
msg.error = "VirtualKeyboard: Invalid layout, expecting array of arrays of keys";
WorkerScript.sendMessage(msg);
return;
}
if (msg.a[i].length > maxButtons)
maxButtons = msg.a[i].length;
for (var j = 0; j < msg.a[i].length; j++) {
if (undefined === msg.a[i][j].label) {
msg.error = "VirtualKeyboard: Invalid layout, invalid key object";
WorkerScript.sendMessage(msg);
return;
}
if (undefined === msg.a[i][j].specialKeyValue)
msg.a[i][j].specialKeyValue = 0;
var label = msg.a[i][j].label;
// if we have a shift key lowercase all labels:
if (msg.shiftKey && label == label.toLocaleUpperCase())
label = label.toLocaleLowerCase();
// drop duplicates (this alters keyboard layout, though!):
if (seenLabels.indexOf(label) !=-1) {
msg.a[i].splice(j, 1);
j--;
continue;
}
msg.a[i][j].label = label;
seenLabels.push(label);
if (msg.shiftKey && undefined === msg.a[i][j].shiftLabel)
msg.a[i][j].shiftLabel = msg.a[i][j].label.toLocaleUpperCase();
}
}
// populate the model:
for (i = 0; i < msg.a.length; i++) {
var row = msg.a[i];
var offset = 0;
msg.rowListModel.append({
rowNum: i,
offset: offset,
keys: row
});
msg.rowListModel.sync(); // sync once per row, on Android where
// this seems to be executed on the GUI
// thread this leads to an update of
// the Loading overlay
}
msg.numRows = i;
msg.initialized = (msg.numRows > 0);
msg.error = "";
WorkerScript.sendMessage(msg);
}
diff --git a/tests/core/ActivityInfoTest.cpp b/tests/core/ActivityInfoTest.cpp
index ae426f902..b4192bd91 100644
--- a/tests/core/ActivityInfoTest.cpp
+++ b/tests/core/ActivityInfoTest.cpp
@@ -1,150 +1,112 @@
/* GCompris - ActivityInfoTest.cpp
*
* Copyright (C) 2018 Himanshu Vishwakarma <himvish997@gmail.com>
*
* Authors:
* Himanshu Vishwakarma <himvish997@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
#include <QtTest>
#include <QObject>
#include "ApplicationSettingsMock.h"
#include "src/core/ActivityInfo.h"
#define ACTIVITY_INFO_TEST_ATTRIBUTE(attributeName, accessorName, attributeType) \
{ \
QFETCH(attributeType, attributeName); \
QSignalSpy spy(&activityinfo, &ActivityInfo::attributeName ## Changed); \
QVERIFY(spy.isValid()); \
QVERIFY(spy.count() == 0); \
activityinfo.set ## accessorName(attributeName); \
QVERIFY(spy.count() == 1); \
QCOMPARE(activityinfo.attributeName(), attributeName); \
}
class CoreActivityInfoTest : public QObject
{
Q_OBJECT
private slots:
void ActivityInfoTest();
void ActivityInfoTest_data();
- void getSectionPathTest();
- void setNameWithKioskMode();
};
void CoreActivityInfoTest::ActivityInfoTest_data()
{
QTest::addColumn<QString>("name");
QTest::addColumn<QString>("section");
QTest::addColumn<unsigned int>("difficulty");
QTest::addColumn<QString>("icon");
QTest::addColumn<QString>("author");
QTest::addColumn<bool>("demo");
QTest::addColumn<QString>("title");
QTest::addColumn<QString>("description");
QTest::addColumn<QString>("goal");
QTest::addColumn<QString>("prerequisite");
QTest::addColumn<QString>("manual");
QTest::addColumn<QString>("credit");
QTest::addColumn<bool>("favorite");
QTest::addColumn<bool>("enabled");
QTest::addColumn<int>("createdInVersion");
QTest::newRow("ActivityInfo") << "Name" << "section" << (unsigned int)3 << "icon" << "author" << true << "title" << "description" << "goal" << "prerequisite" << "manual" << "credit" << false << false << 2;
QTest::newRow("UnknownInfo") << "Unknown" << "Unknown" << (unsigned int)5 << "Unknown" << "Unknown" << false << "Unknown" << "Unknown" << "Unknown" << "Unknown" << "Unknown" << "Unknown" << true << true << 10;
QTest::newRow("Empty") << "" << "" << (unsigned int)0 << "" << "" << false << "" << "" << "" << "" << "" << "" << true << true << 0;
}
void CoreActivityInfoTest::ActivityInfoTest()
{
ActivityInfo activityinfo;
// called here to set the static instance object to the mock one
ApplicationSettingsMock::getInstance();
- QCOMPARE(activityinfo.name(), QStringLiteral(""));
- QCOMPARE(activityinfo.section(), QStringLiteral(""));
- QCOMPARE(activityinfo.icon(), QStringLiteral(""));
- QCOMPARE(activityinfo.author(), QStringLiteral(""));
+ QVERIFY(activityinfo.name().isEmpty());
+ QVERIFY(activityinfo.section().isEmpty());
+ QVERIFY(activityinfo.icon().isEmpty());
+ QVERIFY(activityinfo.author().isEmpty());
QVERIFY(activityinfo.demo());
- QCOMPARE(activityinfo.title(), QStringLiteral(""));
- QCOMPARE(activityinfo.description(), QStringLiteral(""));
- QCOMPARE(activityinfo.goal(), QStringLiteral(""));
- QCOMPARE(activityinfo.prerequisite(), QStringLiteral(""));
- QCOMPARE(activityinfo.manual(), QStringLiteral(""));
- QCOMPARE(activityinfo.credit(), QStringLiteral(""));
+ QVERIFY(activityinfo.title().isEmpty());
+ QVERIFY(activityinfo.description().isEmpty());
+ QVERIFY(activityinfo.goal().isEmpty());
+ QVERIFY(activityinfo.prerequisite().isEmpty());
+ QVERIFY(activityinfo.manual().isEmpty());
+ QVERIFY(activityinfo.credit().isEmpty());
QVERIFY(!activityinfo.favorite());
QVERIFY(activityinfo.enabled());
QCOMPARE(activityinfo.createdInVersion(), 0);
ACTIVITY_INFO_TEST_ATTRIBUTE(name, Name, QString);
ACTIVITY_INFO_TEST_ATTRIBUTE(section, Section, QString);
ACTIVITY_INFO_TEST_ATTRIBUTE(difficulty, Difficulty, unsigned int);
ACTIVITY_INFO_TEST_ATTRIBUTE(icon, Icon, QString);
ACTIVITY_INFO_TEST_ATTRIBUTE(author, Author, QString);
ACTIVITY_INFO_TEST_ATTRIBUTE(demo, Demo, bool);
ACTIVITY_INFO_TEST_ATTRIBUTE(title, Title, QString);
ACTIVITY_INFO_TEST_ATTRIBUTE(description, Description, QString);
ACTIVITY_INFO_TEST_ATTRIBUTE(goal, Goal, QString);
ACTIVITY_INFO_TEST_ATTRIBUTE(prerequisite, Prerequisite, QString);
ACTIVITY_INFO_TEST_ATTRIBUTE(manual, Manual, QString);
ACTIVITY_INFO_TEST_ATTRIBUTE(credit, Credit, QString);
ACTIVITY_INFO_TEST_ATTRIBUTE(favorite, Favorite, bool);
ACTIVITY_INFO_TEST_ATTRIBUTE(enabled, Enabled, bool);
ACTIVITY_INFO_TEST_ATTRIBUTE(createdInVersion, CreatedInVersion, int);
delete ApplicationSettingsMock::getInstance();
}
-void CoreActivityInfoTest::getSectionPathTest()
-{
- ActivityInfo parent;
- parent.setSection("parent");
- ActivityInfo child(&parent);
- child.setSection("child");
- QStringList sectionPath = child.getSectionPath();
-
- QCOMPARE(sectionPath.size(), 2);
- QCOMPARE(sectionPath.join('/'), QStringLiteral("parent/child"));
-}
-
-void CoreActivityInfoTest::setNameWithKioskMode()
-{
- const QString fakeActivity = QStringLiteral("fakeActivity");
- ActivityInfo activityInfo;
- activityInfo.setFavorite(true);
- ApplicationSettingsMock::getInstance()->setKioskMode(true);
- ApplicationSettingsMock::getInstance()->setFavorite(fakeActivity, false);
- activityInfo.setName(fakeActivity);
- // in kiosk mode, we don't retrieve the favorite to always have a clean start
- QVERIFY(activityInfo.favorite());
-
- ApplicationSettingsMock::getInstance()->setKioskMode(false);
- activityInfo.setName(fakeActivity);
- // the activity is not a favorite, we remove its flag when setting the name
- QVERIFY(!activityInfo.favorite());
-
- ApplicationSettingsMock::getInstance()->setFavorite(fakeActivity, true);
- activityInfo.setName(fakeActivity);
- // the activity is a favorite, we add its flag when setting the name
- QVERIFY(activityInfo.favorite());
-
- delete ApplicationSettingsMock::getInstance();
-}
-
QTEST_MAIN(CoreActivityInfoTest)
#include "ActivityInfoTest.moc"
diff --git a/tests/core/ApplicationInfoTest.cpp b/tests/core/ApplicationInfoTest.cpp
new file mode 100644
index 000000000..327f836ab
--- /dev/null
+++ b/tests/core/ApplicationInfoTest.cpp
@@ -0,0 +1,178 @@
+/* GCompris - ApplicationInfoTest.cpp
+ *
+ * Copyright (C) 2018 Billy Laws <blaws05@gmail.com>
+ * GCompris (C) 2018 GCompris Developers <gcompris-devel@kde.org>
+ *
+ * Authors:
+ * Billy Laws <blaws05@gmail.com>
+ *
+ * This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+ */
+
+#include <QObject>
+#include <QtTest>
+
+#include "src/core/ApplicationInfo.h"
+
+class ApplicationInfoTest : public QObject
+{
+public:
+ Q_OBJECT
+private slots:
+ void LocaleTest_data();
+ void LocaleTest();
+ void WindowTest_data();
+ void WindowTest();
+
+ void getVoicesLocaleTest_data();
+ void getVoicesLocaleTest();
+ void getAudioFilePathForLocaleTest_data();
+ void getAudioFilePathForLocaleTest();
+};
+
+void ApplicationInfoTest::LocaleTest_data()
+{
+ QTest::addColumn<QString>("localeFull");
+ QTest::addColumn<QString>("localeShort");
+ QTest::addColumn<QString>("higherWord");
+ QTest::addColumn<QString>("lowerWord");
+ QTest::newRow("British English") << QStringLiteral("en_GB")
+ << QStringLiteral("en")
+ << QStringLiteral("apple")
+ << QStringLiteral("banana");
+}
+
+void ApplicationInfoTest::LocaleTest()
+{
+ ApplicationInfo appInfo;
+ ApplicationInfo::getInstance();
+
+ QFETCH(QString, localeFull);
+ QFETCH(QString, localeShort);
+ QFETCH(QString, higherWord);
+ QFETCH(QString, lowerWord);
+
+ QVERIFY(appInfo.localeShort(localeFull) == localeShort);
+ QVERIFY(appInfo.localeCompare(higherWord, lowerWord, localeFull) == -1);
+ QVERIFY(appInfo.localeCompare(lowerWord, higherWord, localeFull) == 1);
+ QVERIFY(appInfo.localeCompare(higherWord, higherWord, localeFull) == 0);
+
+ QVariantList sortList;
+
+ sortList.append(QVariant(higherWord));
+ sortList.append(QVariant(lowerWord));
+ sortList.append(QVariant(higherWord));
+ sortList.append(QVariant(lowerWord));
+
+ sortList = appInfo.localeSort(sortList, localeFull);
+
+ QVERIFY(sortList[0] == higherWord);
+ QVERIFY(sortList[1] == higherWord);
+ QVERIFY(sortList[2] == lowerWord);
+ QVERIFY(sortList[3] == lowerWord);
+}
+
+void ApplicationInfoTest::WindowTest_data()
+{
+ QTest::addColumn<bool>("useOpenGL");
+ QTest::addColumn<int>("applicationWidth");
+ QTest::addColumn<bool>("portraitMode");
+ QTest::newRow("dummy1") << true
+ << 1920
+ << true;
+}
+
+void ApplicationInfoTest::WindowTest()
+{
+ ApplicationInfo appInfo;
+ ApplicationInfo::getInstance();
+
+ QFETCH(bool, useOpenGL);
+ QFETCH(int, applicationWidth);
+ QFETCH(bool, portraitMode);
+
+ appInfo.setApplicationWidth(applicationWidth);
+ appInfo.setIsPortraitMode(portraitMode);
+ appInfo.setUseOpenGL(useOpenGL);
+
+ QVERIFY(appInfo.useOpenGL() == useOpenGL);
+ QVERIFY(appInfo.applicationWidth() == applicationWidth);
+ QVERIFY(appInfo.isPortraitMode() == portraitMode);
+}
+
+void ApplicationInfoTest::getVoicesLocaleTest_data()
+{
+ QTest::addColumn<QString>("actual");
+ QTest::addColumn<QString>("expected");
+ QTest::newRow("default") << GC_DEFAULT_LOCALE
+ << "en";
+ QTest::newRow("en_US") << "en_US"
+ << "en";
+ QTest::newRow("pt_BR") << "pt_BR"
+ << "pt_BR";
+ QTest::newRow("pt_PT") << "pt_PT"
+ << "pt";
+ QTest::newRow("fr_FR") << "fr_FR"
+ << "fr";
+}
+
+void ApplicationInfoTest::getVoicesLocaleTest()
+{
+ // Set default locale to "C". ALlows to test GC_DEFAULT_LOCALE
+ QLocale defaultLocale = QLocale::system();
+ QLocale::setDefault(QLocale::c());
+ ApplicationInfo appInfo;
+ ApplicationInfo::getInstance();
+
+ QFETCH(QString, actual);
+ QFETCH(QString, expected);
+
+ QCOMPARE(appInfo.getVoicesLocale(actual), expected);
+
+ QLocale::setDefault(defaultLocale);
+}
+
+void ApplicationInfoTest::getAudioFilePathForLocaleTest_data()
+{
+ QTest::addColumn<QString>("file");
+ QTest::addColumn<QString>("locale");
+ QTest::addColumn<QString>("expected");
+ QTest::newRow("absolutePath_en") << "/$LOCALE/$CA"
+ << "en"
+ << QString("/en/%1").arg(COMPRESSED_AUDIO);
+ QTest::newRow("absolutePath_pt_BR") << "qrc:/$LOCALE/test"
+ << "pt_BR"
+ << "qrc:/pt_BR/test";
+ QTest::newRow("absolute_fr") << ":/test/test2"
+ << "unused"
+ << ":/test/test2";
+ QTest::newRow("relative_fr") << "$LOCALE/$CA"
+ << "fr"
+ << QString("qrc:/gcompris/data/fr/%1").arg(COMPRESSED_AUDIO);
+}
+
+void ApplicationInfoTest::getAudioFilePathForLocaleTest()
+{
+ ApplicationInfo appInfo;
+ ApplicationInfo::getInstance();
+
+ QFETCH(QString, file);
+ QFETCH(QString, locale);
+ QFETCH(QString, expected);
+
+ QCOMPARE(appInfo.getAudioFilePathForLocale(file, locale), expected);
+}
+
+QTEST_MAIN(ApplicationInfoTest)
+#include "ApplicationInfoTest.moc"
diff --git a/tests/core/ApplicationSettingsMock.h b/tests/core/ApplicationSettingsMock.h
index 18377e9d2..6e44a8e7e 100644
--- a/tests/core/ApplicationSettingsMock.h
+++ b/tests/core/ApplicationSettingsMock.h
@@ -1,47 +1,47 @@
/* GCompris - ApplicationSettingsMock.h
*
* Copyright (C) 2018 Himanshu Vishwakarma <himvish997@gmail.com>
* GCompris (C) 2018 GCompris Developers <gcompris-devel@kde.org>
*
* Authors:
* Himanshu Vishwakarma <himvish997@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
/* This file is used for the unit tests */
#ifndef APPLICATIONSETTINGSMOCK_H
#define APPLICATIONSETTINGSMOCK_H
#include <QObject>
#include "src/core/ApplicationSettings.h"
class ApplicationSettingsMock : public ApplicationSettings
{
public:
ApplicationSettingsMock() : ApplicationSettings(QStringLiteral("./dummy_application_settings.conf"))
{
}
static ApplicationSettings *getInstance() {
if(!m_instance) {
m_instance = new ApplicationSettingsMock();
}
return m_instance;
}
};
#endif // APPLICATIONSETTINGSMOCK_H
diff --git a/tests/core/ApplicationSettingsTest.cpp b/tests/core/ApplicationSettingsTest.cpp
index 3a09759ca..d77af79ce 100644
--- a/tests/core/ApplicationSettingsTest.cpp
+++ b/tests/core/ApplicationSettingsTest.cpp
@@ -1,183 +1,187 @@
/* GCompris - ApplicationSettingsTest.cpp
*
* Copyright (C) 2018 Himanshu Vishwakarma <himvish997@gmail.com>
*
* Authors:
* Himanshu Vishwakarma <himvish997@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
#include <QtTest>
#include <QObject>
#include <QFile>
#include "src/core/ApplicationSettings.h"
#include "ApplicationSettingsMock.h"
#define APPLICATION_SETTINGS_TEST_ATTRIBUTE(attributeType, attributeName, accessorName, accessorNameChanged) \
{ \
QFETCH(attributeType, attributeName); \
QSignalSpy spy(&applicationSettingsMock, &ApplicationSettings::accessorNameChanged); \
QVERIFY(spy.isValid()); \
QVERIFY(spy.count() == 0); \
applicationSettingsMock.accessorName(attributeName); \
QVERIFY(spy.count() == 1); \
QCOMPARE(applicationSettingsMock.attributeName(), attributeName); \
}
class CoreApplicationSettingsTest : public QObject
{
Q_OBJECT
private slots:
void cleanup();
void ApplicationSettingsInitializationTest();
void ApplicationSettingsTest();
void ApplicationSettingsTest_data();
void ActivitySettingsTest();
};
void CoreApplicationSettingsTest::ApplicationSettingsInitializationTest()
{
ApplicationSettingsMock applicationSettings;
QCOMPARE(applicationSettings.baseFontSizeMin(), -7);
QCOMPARE(applicationSettings.baseFontSizeMax(), 7);
QCOMPARE(applicationSettings.fontLetterSpacingMin(), (qreal)0.0);
QCOMPARE(applicationSettings.fontLetterSpacingMax(), (qreal)8.0);
}
void CoreApplicationSettingsTest::ApplicationSettingsTest_data()
{
QTest::addColumn<bool>("showLockedActivities");
QTest::addColumn<bool>("isAudioVoicesEnabled");
QTest::addColumn<bool>("isAudioEffectsEnabled");
QTest::addColumn<quint32>("previousHeight");
QTest::addColumn<quint32>("previousWidth");
QTest::addColumn<bool>("isVirtualKeyboard");
QTest::addColumn<QString>("locale");
QTest::addColumn<QString>("font");
QTest::addColumn<bool>("isEmbeddedFont");
QTest::addColumn<quint32>("fontCapitalization");
QTest::addColumn<qreal>("fontLetterSpacing");
QTest::addColumn<bool>("isAutomaticDownloadsEnabled");
QTest::addColumn<quint32>("filterLevelMin");
QTest::addColumn<quint32>("filterLevelMax");
QTest::addColumn<bool>("isDemoMode");
QTest::addColumn<QString>("codeKey");
QTest::addColumn<bool>("isKioskMode");
QTest::addColumn<bool>("sectionVisible");
QTest::addColumn<QString>("wordset");
QTest::addColumn<QString>("downloadServerUrl");
QTest::addColumn<QString>("cachePath");
+ QTest::addColumn<QString>("userDataPath");
QTest::addColumn<quint32>("exeCount");
QTest::addColumn<bool>("isBarHidden");
QTest::addColumn<int>("baseFontSize");
QTest::addColumn<int>("lastGCVersionRan");
QTest::addColumn<bool>("isFullscreen");
+ QTest::addColumn<QString>("renderer");
- QTest::newRow("dummySettings1") << true << true << true << (quint32)21 << (quint32)25 << true << "en_EN" << "font1" << true << (quint32)36 << (qreal)2.532 << true << (quint32)26 << (quint32)84 << true << "codeKey1" << true << true << "wordset1" << "downloadServerUrl1" << "cachePath1" << (quint32)48 << true << 7 << 52 << false;
- QTest::newRow("dummySettings2") << false << false << false << (quint32)20 << (quint32)32 << false << "en_US" << "font2" << false << (quint32)34 <<(qreal)2.3 << false << (quint32)24 << (quint32)80 << false << "codekey2" << false << false << "wordset2" << "downloadServerUrl2" << "cachePath2" << (quint32)44 << false << 5 << 64 << false;
+ QTest::newRow("dummySettings1") << true << true << true << (quint32)21 << (quint32)25 << true << "en_EN" << "font1" << true << (quint32)36 << (qreal)2.532 << true << (quint32)26 << (quint32)84 << true << "codeKey1" << true << true << "wordset1" << "downloadServerUrl1" << "cachePath1" << "userDataPath1" << (quint32)48 << true << 7 << 52 << false << "softwareRenderer";
+ QTest::newRow("dummySettings2") << false << false << false << (quint32)20 << (quint32)32 << false << "en_US" << "font2" << false << (quint32)34 <<(qreal)2.3 << false << (quint32)24 << (quint32)80 << false << "codekey2" << false << false << "wordset2" << "downloadServerUrl2" << "cachePath2" << "userDataPath2" << (quint32)44 << false << 5 << 64 << false << "openglRenderer";
}
void CoreApplicationSettingsTest::ApplicationSettingsTest()
{
ApplicationSettingsMock applicationSettingsMock;
ApplicationSettingsMock::getInstance();
APPLICATION_SETTINGS_TEST_ATTRIBUTE(bool, showLockedActivities, setShowLockedActivities, showLockedActivitiesChanged);
APPLICATION_SETTINGS_TEST_ATTRIBUTE(bool, isAudioVoicesEnabled, setIsAudioVoicesEnabled, audioVoicesEnabledChanged);
APPLICATION_SETTINGS_TEST_ATTRIBUTE(bool, isAudioEffectsEnabled, setIsAudioEffectsEnabled, audioEffectsEnabledChanged);
APPLICATION_SETTINGS_TEST_ATTRIBUTE(quint32, previousHeight, setPreviousHeight, previousHeightChanged);
APPLICATION_SETTINGS_TEST_ATTRIBUTE(quint32, previousWidth, setPreviousWidth, previousWidthChanged);
APPLICATION_SETTINGS_TEST_ATTRIBUTE(bool, isVirtualKeyboard, setVirtualKeyboard, virtualKeyboardChanged);
APPLICATION_SETTINGS_TEST_ATTRIBUTE(QString, locale, setLocale, localeChanged);
APPLICATION_SETTINGS_TEST_ATTRIBUTE(QString, font, setFont, fontChanged);
APPLICATION_SETTINGS_TEST_ATTRIBUTE(bool, isEmbeddedFont, setIsEmbeddedFont, embeddedFontChanged);
APPLICATION_SETTINGS_TEST_ATTRIBUTE(quint32, fontCapitalization, setFontCapitalization, fontCapitalizationChanged);
APPLICATION_SETTINGS_TEST_ATTRIBUTE(qreal, fontLetterSpacing, setFontLetterSpacing, fontLetterSpacingChanged);
APPLICATION_SETTINGS_TEST_ATTRIBUTE(bool, isAutomaticDownloadsEnabled, setIsAutomaticDownloadsEnabled, automaticDownloadsEnabledChanged);
APPLICATION_SETTINGS_TEST_ATTRIBUTE(quint32, filterLevelMin, setFilterLevelMin, filterLevelMinChanged);
APPLICATION_SETTINGS_TEST_ATTRIBUTE(quint32, filterLevelMax, setFilterLevelMax, filterLevelMaxChanged);
APPLICATION_SETTINGS_TEST_ATTRIBUTE(bool, isDemoMode, setDemoMode, demoModeChanged);
APPLICATION_SETTINGS_TEST_ATTRIBUTE(QString, codeKey, setCodeKey, codeKeyChanged);
APPLICATION_SETTINGS_TEST_ATTRIBUTE(bool, isKioskMode, setKioskMode, kioskModeChanged);
APPLICATION_SETTINGS_TEST_ATTRIBUTE(bool, sectionVisible, setSectionVisible, sectionVisibleChanged);
APPLICATION_SETTINGS_TEST_ATTRIBUTE(QString, wordset, setWordset, wordsetChanged);
APPLICATION_SETTINGS_TEST_ATTRIBUTE(QString, downloadServerUrl, setDownloadServerUrl, downloadServerUrlChanged);
APPLICATION_SETTINGS_TEST_ATTRIBUTE(QString, cachePath, setCachePath, cachePathChanged);
+ APPLICATION_SETTINGS_TEST_ATTRIBUTE(QString, userDataPath, setUserDataPath, userDataPathChanged);
APPLICATION_SETTINGS_TEST_ATTRIBUTE(quint32, exeCount, setExeCount, exeCountChanged);
APPLICATION_SETTINGS_TEST_ATTRIBUTE(bool, isBarHidden, setBarHidden, barHiddenChanged);
APPLICATION_SETTINGS_TEST_ATTRIBUTE(int, baseFontSize, setBaseFontSize, baseFontSizeChanged);
APPLICATION_SETTINGS_TEST_ATTRIBUTE(int, lastGCVersionRan, setLastGCVersionRan, lastGCVersionRanChanged);
APPLICATION_SETTINGS_TEST_ATTRIBUTE(bool, isFullscreen, setFullscreen, fullscreenChanged);
+ APPLICATION_SETTINGS_TEST_ATTRIBUTE(QString, renderer, setRenderer, rendererChanged);
delete ApplicationSettingsMock::getInstance();
}
void CoreApplicationSettingsTest::ActivitySettingsTest()
{
ApplicationSettingsMock applicationSettingsMock;
ApplicationSettingsMock::getInstance();
// Creating a dummyActivity
QString dummyActivity = QStringLiteral("DummyActivity");
// By Default the DummyActivity is not favorite
QVERIFY(!applicationSettingsMock.isFavorite(dummyActivity));
// Setting Up the DummyActivity as Favorite
applicationSettingsMock.setFavorite(dummyActivity, true);
QVERIFY(applicationSettingsMock.isFavorite(dummyActivity));
// setting Up the DummyActivity as Not favorite
applicationSettingsMock.setFavorite(dummyActivity, false);
QVERIFY(!applicationSettingsMock.isFavorite(dummyActivity));
// By Default the activity progress is zero
QCOMPARE(applicationSettingsMock.loadActivityProgress(dummyActivity), 0);
// Saving the Activity Progress
applicationSettingsMock.saveActivityProgress(dummyActivity, 3);
QCOMPARE(applicationSettingsMock.loadActivityProgress(dummyActivity), 3);
applicationSettingsMock.saveActivityProgress(dummyActivity, 10);
QCOMPARE(applicationSettingsMock.loadActivityProgress(dummyActivity), 10);
applicationSettingsMock.saveActivityProgress(dummyActivity, 0);
QCOMPARE(applicationSettingsMock.loadActivityProgress(dummyActivity), 0);
// Test current level getter/setter
QCOMPARE(applicationSettingsMock.currentLevel(dummyActivity), "");
applicationSettingsMock.setCurrentLevel(dummyActivity, "3");
QCOMPARE(applicationSettingsMock.currentLevel(dummyActivity), "3");
// By Default the activity
QVariantMap configuration;
configuration.insert(QStringLiteral("DummyKey1"), QStringLiteral("DummyValue1"));
configuration.insert(QStringLiteral("DummyKey2"), QStringLiteral("DummyValue2"));
configuration.insert(QStringLiteral("DummyKey3"), QStringLiteral("DummyValue3"));
configuration.insert(QStringLiteral("DummyKey4"), QStringLiteral("DummyValue4"));
applicationSettingsMock.saveActivityConfiguration(dummyActivity, configuration);
QVariantMap newConfiguration = applicationSettingsMock.loadActivityConfiguration(dummyActivity);
QCOMPARE(newConfiguration.value(QStringLiteral("DummyKey1")), configuration.value(QStringLiteral("DummyKey1")));
QCOMPARE(newConfiguration.value(QStringLiteral("DummyKey2")), configuration.value(QStringLiteral("DummyKey2")));
QCOMPARE(newConfiguration.value(QStringLiteral("DummyKey3")), configuration.value(QStringLiteral("DummyKey3")));
QCOMPARE(newConfiguration.value(QStringLiteral("DummyKey4")), configuration.value(QStringLiteral("DummyKey4")));
delete ApplicationSettingsMock::getInstance();
}
void CoreApplicationSettingsTest::cleanup()
{
QFile::remove("./dummy_application_settings.conf");
}
QTEST_MAIN(CoreApplicationSettingsTest)
#include "ApplicationSettingsTest.moc"
diff --git a/tests/core/CMakeLists.txt b/tests/core/CMakeLists.txt
index 595b70f93..cee00e4e2 100644
--- a/tests/core/CMakeLists.txt
+++ b/tests/core/CMakeLists.txt
@@ -1,17 +1,19 @@
find_package(Qt5 REQUIRED COMPONENTS Test)
include_directories(${CMAKE_SOURCE_DIR} "${CMAKE_BINARY_DIR}/src/core/")
set(CORE_TEST_LIBRARIES
gcompris_core
Qt5::Core
Qt5::Test
)
ecm_add_tests(ActivityInfoTest.cpp
ApplicationSettingsTest.cpp
DirectoryTest.cpp
FileTest.cpp
+ ApplicationInfoTest.cpp
+ DownloadManagerTest.cpp
# add new test file here
NAME_PREFIX Core
LINK_LIBRARIES ${CORE_TEST_LIBRARIES})
diff --git a/tests/core/DirectoryTest.cpp b/tests/core/DirectoryTest.cpp
index 796fe16dc..c0162f634 100644
--- a/tests/core/DirectoryTest.cpp
+++ b/tests/core/DirectoryTest.cpp
@@ -1,73 +1,78 @@
/* GCompris - DirectoryTest.cpp
*
* Copyright (C) 2018 Himanshu Vishwakarma <himvish997@gmail.com>
* GCompris (C) 2018 GCompris Developers <gcompris-devel@kde.org>
*
* Authors:
* Himanshu Vishwakarma <himvish997@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
#include <QObject>
#include <QtTest>
#include <QDir>
#include "src/core/File.h"
#include "src/core/Directory.h"
class DirectoryTest : public QObject
{
public:
Q_OBJECT
private slots:
void GetFilesTest();
};
void DirectoryTest::GetFilesTest()
{
// Removing the directory.
// It is required as it may already be present in memory because of unsuccessful test/ interruption
QDir dir("./dummy_directory");
dir.removeRecursively();
File file;
- QVERIFY(file.mkpath("./dummy_directory"));
+ QVERIFY(File::mkpath("./dummy_directory"));
Directory directory;
QStringList filelist = directory.getFiles("./dummy_directory");
- // It counts './' & '../' in directory.
- QCOMPARE(filelist.count(), 2);
+ // We do not count './' & '../' in directory.
+ QCOMPARE(filelist.count(), 0);
// Creating the empty file of name file1.
file.write("", "./dummy_directory/file1");
// Creating the empty directory of name dir1.
- file.mkpath("./dummy_directory/dir1");
- filelist = directory.getFiles("./dummy_directory");
- QCOMPARE(filelist.count(), 4);
+ File::mkpath("./dummy_directory/dir1");
+ filelist = directory.getFiles("./dummy_directory", {"*"});
+ QCOMPARE(filelist.count(), 2);
file.write("", "./dummy_directory/file2");
file.write("", "./dummy_directory/file3");
- file.mkpath("./dummy_directory/dir2");
- file.mkpath("./dummy_directory/dir3");
+ File::mkpath("./dummy_directory/dir2");
+ File::mkpath("./dummy_directory/dir3");
filelist = directory.getFiles("./dummy_directory");
- QCOMPARE(filelist.count(), 8);
+ QCOMPARE(filelist.count(), 6);
// Removing the directory.
+ QVERIFY(File::rmpath("./dummy_directory/file3"));
+ QVERIFY(File::rmpath("./dummy_directory/file2"));
+ QVERIFY(!File::rmpath("./dummy_directory/dir3"));
+ filelist = directory.getFiles("./dummy_directory");
+ QCOMPARE(filelist.count(), 4);
dir.removeRecursively();
}
QTEST_MAIN(DirectoryTest)
#include "DirectoryTest.moc"
diff --git a/tests/core/DownloadManagerTest.cpp b/tests/core/DownloadManagerTest.cpp
new file mode 100644
index 000000000..d899243e2
--- /dev/null
+++ b/tests/core/DownloadManagerTest.cpp
@@ -0,0 +1,184 @@
+/* GCompris - DownloadManagerTest.cpp
+ *
+ * Copyright (C) 2018 Alex Kovrigin <a.kovrigin0@gmail.com>
+ * GCompris (C) 2018 GCompris Developers <gcompris-devel@kde.org>
+ *
+ * Authors:
+ * Alex Kovrigin <a.kovrigin0@gmail.com>
+ *
+ * This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+ */
+
+#include <QObject>
+#include <QtTest>
+#include <QString>
+
+#include "src/core/DownloadManager.h"
+#include "src/core/ApplicationInfo.h"
+#include "ApplicationSettingsMock.h"
+/**
+ * @brief The DownloadManagerTest class Unit tests class for DownloadManager testing
+ * @sa DownloadManager
+ */
+class DownloadManagerTest : public QObject
+{
+ Q_OBJECT
+
+private slots:
+ /**
+ * @brief initTestCase Case for basic functionality of DownloadManager
+ */
+ void initTestCase()
+ {
+ ApplicationSettingsMock::getInstance()->setIsAutomaticDownloadsEnabled(false);
+ downloadManager = DownloadManager::getInstance();
+ }
+
+ void test_getVoicesResourceForLocale_data()
+ {
+ QTest::addColumn<QString>("locale");
+ QTest::addColumn<QString>("language");
+
+ QTest::newRow("en_US") << "en_US" << "en";
+ QTest::newRow("en_UK") << "en_UK" << "en";
+ QTest::newRow("ru_RU") << "ru_RU" << "ru";
+ QTest::newRow("de_DE") << "de_DE" << "de";
+ QTest::newRow("fr_FR") << "fr_FR" << "fr";
+ }
+ void test_getVoicesResourceForLocale()
+ {
+ QFETCH(QString, locale);
+ QFETCH(QString, language);
+
+ QCOMPARE(downloadManager->getVoicesResourceForLocale(locale),
+ QString("data2/voices-%1/voices-%2.rcc").arg(COMPRESSED_AUDIO, language));
+ }
+
+ void test_haveLocalResource_data()
+ {
+ QTest::addColumn<QString>("resource");
+ QTest::addColumn<bool>("expected_success");
+
+ QTest::newRow("invalid.invalid") << "invalid.invalid" << false;
+ QTest::newRow("no.no") << "no.no" << false;
+ QTest::newRow("money.rcc") << "money.rcc" << true;
+ QTest::newRow("penalty.rcc") << "penalty.rcc" << true;
+ }
+ void test_haveLocalResource()
+ {
+ QFETCH(QString, resource);
+ QFETCH(bool, expected_success);
+
+ QVERIFY(expected_success == downloadManager->haveLocalResource(resource));
+ }
+
+ void test_downloadResource_data()
+ {
+ QTest::addColumn<QString>("resource");
+
+ QTest::newRow("invalid.blabla") << "invalid.blabla";
+ QTest::newRow("algorithm.rcc") << "algorithm.rcc";
+ }
+ void test_downloadResource()
+ {
+ QFETCH(QString, resource);
+
+ QVERIFY(downloadManager->downloadResource(resource));
+ QVERIFY(!downloadManager->downloadResource(resource));
+ downloadManager->abortDownloads();
+ }
+
+ void test_updateResource_data()
+ {
+ QTest::addColumn<QString>("resource");
+ QTest::addColumn<bool>("expected_success");
+
+ QTest::newRow("invalid.haha") << "invalid.haha" << false;
+ QTest::newRow("money.rcc") << "money.rcc" << true;
+ }
+ void test_updateResource()
+ {
+ QFETCH(QString, resource);
+ QFETCH(bool, expected_success);
+
+ QVERIFY(expected_success == downloadManager->updateResource(resource));
+ }
+
+ void test_downloadIsRunning_data()
+ {
+ QTest::addColumn<QString>("resource");
+
+ QTest::newRow("colors.rcc") << "colors.rcc";
+ }
+ void test_downloadIsRunning()
+ {
+ QFETCH(QString, resource);
+
+ downloadManager->abortDownloads();
+ QVERIFY(!downloadManager->downloadIsRunning());
+ QVERIFY(downloadManager->downloadResource(resource));
+ QVERIFY(downloadManager->downloadIsRunning());
+ downloadManager->abortDownloads();
+ }
+
+ void test_registerResource_data()
+ {
+ QTest::addColumn<QString>("resource");
+ QTest::addColumn<bool>("expected_success");
+
+ QTest::newRow("invalid.rcc") << "invalid.rcc" << false;
+ QTest::newRow("money.rcc") << "money.rcc" << true;
+ }
+ void test_registerResource()
+ {
+ QFETCH(QString, resource);
+ QFETCH(bool, expected_success);
+
+ QVERIFY(expected_success == downloadManager->registerResource(resource));
+ }
+
+ void test_isDataRegistered_data()
+ {
+ QTest::addColumn<QString>("resource");
+ QTest::addColumn<QString>("register_mode");
+
+ QTest::newRow("invalid.rcc") << "invalid.rcc" << "invalid";
+ QTest::newRow("mosaic.rcc") << "mosaic.rcc" << "not_registered";
+ }
+ void test_isDataRegistered()
+ {
+ QFETCH(QString, resource);
+ QFETCH(QString, register_mode);
+
+ if(register_mode == "not_registered") {
+ QVERIFY(!downloadManager->isDataRegistered(resource));
+ }
+ else if(register_mode == "invalid") {
+ QVERIFY(!downloadManager->registerResource(resource));
+ QVERIFY(!downloadManager->isDataRegistered(resource));
+ }
+ else {
+ QVERIFY(false);
+ }
+ }
+
+private:
+ /**
+ * @brief downloadManager The DownloadManager object, that is the test downloadManager
+ */
+ DownloadManager *downloadManager;
+};
+
+QTEST_MAIN(DownloadManagerTest);
+#include "DownloadManagerTest.moc"
diff --git a/tests/core/FileTest.cpp b/tests/core/FileTest.cpp
index 4c03c5120..f3e1caa0a 100644
--- a/tests/core/FileTest.cpp
+++ b/tests/core/FileTest.cpp
@@ -1,137 +1,147 @@
/* GCompris - FileTest.cpp
*
* Copyright (C) 2018 Himanshu Vishwakarma <himvish997@gmail.com>
* GCompris (C) 2018 GCompris Developers <gcompris-devel@kde.org>
*
* Authors:
* Himanshu Vishwakarma <himvish997@gmail.com>
*
* This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
/* This file is used for the unit tests */
#include <QtTest>
#include <QObject>
#include <QFile>
#include "src/core/File.h"
class CoreFileTest : public QObject
{
Q_OBJECT
private slots:
void cleanup();
void FileExistsTest();
void ReadWriteErrorsTest();
void ReadWriteErrorsTest_data();
void ReadWriteTest();
void NameTest();
};
-static const QString tempFilename = QStringLiteral("./dummy_test_files.txt");
-static const QString fakeFilename = QStringLiteral("-_/fezagvvx&V/d;-ùlc");
+static const char *tempFilename = "./dummy_test_files.txt";
+static const char *fakeFilename = "-_/fezagvvx&V/d;-ùlc";
void CoreFileTest::FileExistsTest()
{
QFile tempFile(tempFilename);
// open in write mode to create the file if does not exist
tempFile.open(QIODevice::ReadWrite);
tempFile.close();
QVERIFY(File::exists(tempFilename));
}
void CoreFileTest::ReadWriteErrorsTest_data()
{
QTest::addColumn<QString>("filename");
QTest::addColumn<QString>("readError");
QTest::addColumn<QString>("writeError");
- QTest::newRow("empty file") << QStringLiteral("")
+ QTest::newRow("empty file") << ""
<< QStringLiteral("source is empty")
<< QStringLiteral("source is empty");
QTest::newRow("non existing file") << fakeFilename
<< QStringLiteral("Unable to open the file")
<< QStringLiteral("could not open file ") + fakeFilename;
}
void CoreFileTest::ReadWriteErrorsTest()
{
QFETCH(QString, filename);
QFETCH(QString, readError);
QFETCH(QString, writeError);
const QString fileContent = QStringLiteral("this is going to test the class File in the core");
File file;
QSignalSpy spyError(&file, &File::error);
QVERIFY(spyError.isValid());
QVERIFY(spyError.count() == 0);
// we can't read
QVERIFY(file.read(filename).isEmpty());
QVERIFY(spyError.count() == 1);
QString error = qvariant_cast<QString>(spyError.at(0).at(0));
QCOMPARE(error, readError);
// we can't write
QVERIFY(!file.write(fileContent, filename));
QVERIFY(spyError.count() == 2);
error = qvariant_cast<QString>(spyError.at(1).at(0));
QCOMPARE(error, writeError);
+ // we can't append
+ QVERIFY(!file.append(fileContent, filename));
+ QVERIFY(spyError.count() == 3);
+ error = qvariant_cast<QString>(spyError.at(2).at(0));
+ QCOMPARE(error, writeError);
}
void CoreFileTest::ReadWriteTest()
{
QFile tempFile(tempFilename);
// open in write mode to create the file if does not exist
tempFile.open(QIODevice::ReadWrite);
tempFile.close();
File file;
const QString fileContent = QStringLiteral("this is going to test the class File in the core");
// normal use case, file exists
QVERIFY(file.write(fileContent, tempFilename));
QCOMPARE(file.read(), fileContent);
+
+ // append to the file
+ const QString appendedText = QStringLiteral("appended text.");
+ QVERIFY(file.append(appendedText, tempFilename));
+ QCOMPARE(file.read(), fileContent+appendedText);
}
void CoreFileTest::NameTest()
{
File file;
QSignalSpy spyName(&file, &File::nameChanged);
QVERIFY(spyName.isValid());
QVERIFY(spyName.count() == 0);
file.setName(tempFilename);
QVERIFY(spyName.count() == 1);
- QCOMPARE(file.name(), tempFilename);
+ QCOMPARE(file.name(), QString(tempFilename));
// test sanitizeUrl
const QString sameNameUnsanitized = QStringLiteral("file://")+tempFilename;
file.setName(sameNameUnsanitized);
// no update triggered as same name after sanitization
QVERIFY(spyName.count() == 1);
- QCOMPARE(file.name(), tempFilename);
+ QCOMPARE(file.name(), QString(tempFilename));
const QString filenameUnsanitized = QStringLiteral("qrc:/")+tempFilename;
file.setName(filenameUnsanitized);
// no update triggered as same name after sanitization
QVERIFY(spyName.count() == 2);
QCOMPARE(file.name(), QStringLiteral(":/")+tempFilename);
}
void CoreFileTest::cleanup()
{
QFile::remove("./dummy_test_files.txt");
}
QTEST_MAIN(CoreFileTest)
#include "FileTest.moc"
diff --git a/tools/android_build_all_apk.sh b/tools/android_build_all_apk.sh
index 91c08b2cb..fbbb3c227 100755
--- a/tools/android_build_all_apk.sh
+++ b/tools/android_build_all_apk.sh
@@ -1,142 +1,118 @@
#!/bin/sh
# Automate the android builds
-# This script creates the different apk for arm and x86
+# This script creates the different apk for arm
#
# Copyright (C) 2016 Bruno Coudoin <bruno.coudoin@gcompris.net>
#
# This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+# along with this program; if not, see <https://www.gnu.org/licenses/>.
# Uncomment if this is not already done
# make getSvnTranslations
-Qt5_BaseDIR=~/Qt5.9.3/5.9.3
+Qt5_BaseDIR=~/Qt5.12.1/5.12.1
export ANDROID_NDK_ROOT=$ANDROID_NDK
# The current version
version=$(sed -n -e 's/set(GCOMPRIS_MINOR_VERSION \([0-9]\+\)).*/\1/p' CMakeLists.txt)
# The prefix of the build dir, will be suffixed by the arch target
buildprefix=bb-$version
# Remove po files android do not support
rm -f po/*@*
#
if [ ! -f org.kde.gcompris.appdata.xml ]
then
echo "ERROR: Run me from the top level GCompris source dir"
exit 1
fi
# Param: ANDROID_ARCHITECTURE WITH_ACTIVATION_CODE DEMO_ONLY DOWNLOAD KIOSK_MODE
f_cmake()
{
if [ $# != 5 ]
then
echo "f_cmake missing parameter"
return
fi
if [ -f CMakeCache.txt ]
then
make clean
rm CMakeCache.txt
rm cmake_install.cmake
rm Makefile
rm -rf CMakeFiles
fi
cmake -DCMAKE_TOOLCHAIN_FILE=/usr/share/ECM/toolchain/Android.cmake \
+ -DCMAKE_ANDROID_API=16 \
-DCMAKE_BUILD_TYPE=release \
+ -DCMAKE_ANDROID_STL_TYPE=c++_shared \
+ -DANDROID_TOOLCHAIN_PATH=/opt/android-16-arm/bin/ \
+ -DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=clang \
-DANDROID_ARCHITECTURE=$1 \
-DQt5_DIR=${Qt5_BaseDIR}/${QtTarget}/lib/cmake/Qt5 \
- -DQt5Qml_DIR=~/Qt5.9.3/5.9.3/android_armv7/lib/cmake/Qt5Qml \
- -DQt5Network_DIR=~/Qt5.9.3/5.9.3/android_armv7/lib/cmake/Qt5Network \
- -DQt5Core_DIR=~/Qt5.9.3/5.9.3/android_armv7/lib/cmake/Qt5Core \
- -DQt5Quick_DIR=~/Qt5.9.3/5.9.3/android_armv7/lib/cmake/Qt5Quick \
- -DQt5Gui_DIR=~/Qt5.9.3/5.9.3/android_armv7/lib/cmake/Qt5Gui \
- -DQt5Multimedia_DIR=~/Qt5.9.3/5.9.3/android_armv7/lib/cmake/Qt5Multimedia \
- -DQt5Svg_DIR=~/Qt5.9.3/5.9.3/android_armv7/lib/cmake/Qt5Svg \
- -DQt5Widgets_DIR=~/Qt5.9.3/5.9.3/android_armv7/lib/cmake/Qt5Widgets \
- -DQt5Xml_DIR=~/Qt5.9.3/5.9.3/android_armv7/lib/cmake/Qt5Xml \
- -DQt5XmlPatterns_DIR=~/Qt5.9.3/5.9.3/android_armv7/lib/cmake/Qt5XmlPatterns \
- -DQt5LinguistTools_DIR=~/Qt5.9.3/5.9.3/android_armv7/lib/cmake/Qt5LinguistTools \
- -DQt5Sensors_DIR=~/Qt5.9.3/5.9.3/android_armv7/lib/cmake/Qt5Sensors \
- -DQt5AndroidExtras_DIR=~/Qt5.9.3/5.9.3/android_armv7/lib/cmake/Qt5AndroidExtras \
+ -DQt5Qml_DIR=${Qt5_BaseDIR}/${QtTarget}/lib/cmake/Qt5Qml \
+ -DQt5Network_DIR=${Qt5_BaseDIR}/${QtTarget}/lib/cmake/Qt5Network \
+ -DQt5Core_DIR=${Qt5_BaseDIR}/${QtTarget}/lib/cmake/Qt5Core \
+ -DQt5Quick_DIR=${Qt5_BaseDIR}/${QtTarget}/lib/cmake/Qt5Quick \
+ -DQt5Gui_DIR=${Qt5_BaseDIR}/${QtTarget}/lib/cmake/Qt5Gui \
+ -DQt5Multimedia_DIR=${Qt5_BaseDIR}/${QtTarget}/lib/cmake/Qt5Multimedia \
+ -DQt5Svg_DIR=${Qt5_BaseDIR}/${QtTarget}/lib/cmake/Qt5Svg \
+ -DQt5Widgets_DIR=${Qt5_BaseDIR}/${QtTarget}/lib/cmake/Qt5Widgets \
+ -DQt5Xml_DIR=${Qt5_BaseDIR}/${QtTarget}/lib/cmake/Qt5Xml \
+ -DQt5XmlPatterns_DIR=${Qt5_BaseDIR}/${QtTarget}/lib/cmake/Qt5XmlPatterns \
+ -DQt5LinguistTools_DIR=${Qt5_BaseDIR}/${QtTarget}/lib/cmake/Qt5LinguistTools \
+ -DQt5Sensors_DIR=${Qt5_BaseDIR}/${QtTarget}/lib/cmake/Qt5Sensors \
+ -DQt5AndroidExtras_DIR=${Qt5_BaseDIR}/${QtTarget}/lib/cmake/Qt5AndroidExtras \
-Wno-dev \
-DQML_BOX2D_MODULE=submodule \
-DACTIVATION_MODE=$2 \
-DWITH_DEMO_ONLY=$3 \
-DWITH_DOWNLOAD=$4 \
-DWITH_KIOSK_MODE=$5 \
..
}
# ARM
QtTarget=android_armv7
builddir=${buildprefix}-${QtTarget}
mkdir -p ${builddir}
cd ${builddir}
-f_cmake armeabi inapp OFF ON OFF
+f_cmake arm inapp OFF ON OFF
make
make BuildTranslations
make apk_release && make apk_signed && make apk_signed_aligned
-f_cmake armeabi internal OFF ON OFF
+f_cmake arm internal OFF ON OFF
make
make apk_release && make apk_signed && make apk_signed_aligned
-f_cmake armeabi no OFF ON OFF
+f_cmake arm no OFF ON OFF
make
make apk_release && make apk_signed && make apk_signed_aligned
-f_cmake armeabi no ON ON OFF
+f_cmake arm no ON ON OFF
make clean
make
make BuildTranslations
make apk_release && make apk_signed && make apk_signed_aligned
# Remove extra apk
rm -f android/bin/*release-armeabi*
rm -f android/bin/*release-signed-armeabi*
-
-# X86
-cd ..
-QtTarget=android_x86
-builddir=${buildprefix}-${QtTarget}
-mkdir -p ${builddir}
-cd ${builddir}
-
-f_cmake x86 inapp OFF ON OFF
-make
-make BuildTranslations
-make apk_release && make apk_signed && make apk_signed_aligned
-
-f_cmake x86 internal OFF ON OFF
-make
-make apk_release && make apk_signed && make apk_signed_aligned
-
-f_cmake x86 no OFF ON OFF
-make
-make apk_release && make apk_signed && make apk_signed_aligned
-
-f_cmake x86 no ON ON OFF
-make
-make apk_release && make apk_signed && make apk_signed_aligned
-
-# Remove extra apk
-rm -f android/bin/*release-x86*
-rm -f android/bin/*release-signed-x86*
diff --git a/tools/android_build_embedded_apk.sh b/tools/android_build_embedded_apk.sh
index 027a1a6a8..27e57fe7f 100755
--- a/tools/android_build_embedded_apk.sh
+++ b/tools/android_build_embedded_apk.sh
@@ -1,104 +1,104 @@
#!/bin/bash
# Automate the android builds
# This script creates the different apk for arm and x86
#
# Copyright (C) 2016 Bruno Coudoin <bruno.coudoin@gcompris.net>
#
# This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+# along with this program; if not, see <https://www.gnu.org/licenses/>.
# =======================================================================
# This script builds an 'embedded' apk that includes a list of resources.
# =======================================================================
#
# Uncomment if this is not already done
# make getSvnTranslations
Qt5_BaseDIR=~/Qt5.4.2/5.4
export ANDROID_NDK_ROOT=$ANDROID_NDK
# The current version
version=$(sed -n -e 's/set(GCOMPRIS_MINOR_VERSION \([0-9]\+\)).*/\1/p' CMakeLists.txt)
# The prefix of the build dir, will be suffixed by the arch target
buildprefix=emb-$version
# Remove po files android do not support
rm -f po/*@*
#
if [ ! -f gcompris.appdata.xml ]
then
echo "ERROR: Run me from the top level GCompris source dir"
exit 1
fi
if [ "$#" == "0" ]
then
echo "ERROR: Missing download asset parameter (e.g: words,en,fr)"
exit 1
fi
download_assets=$1
# Param: ANDROID_ARCHITECTURE WITH_ACTIVATION_CODE DEMO_ONLY DOWNLOAD KIOSK_MODE DOWNLOAD_ASSETS
# DOWNLOAD_ASSETS: list of assets to bundle in the apk
# e.g: words,en,fr # This packages the large words rcc, the french and english voices
f_cmake()
{
if [ $# != 6 ]
then
echo "f_cmake parameter number mismatch"
return
fi
if [ -f CMakeCache.txt ]
then
make clean
rm CMakeCache.txt
rm cmake_install.cmake
rm Makefile
rm -rf CMakeFiles
fi
cmake -DCMAKE_TOOLCHAIN_FILE=/usr/share/ECM/toolchain/Android.cmake \
-DCMAKE_BUILD_TYPE=release \
-DANDROID_ARCHITECTURE=$1 \
-DQt5_DIR=${Qt5_BaseDIR}/${QtTarget}/lib/cmake/Qt5 \
-Wno-dev \
-DQML_BOX2D_MODULE=submodule \
-DACTIVATION_MODE=$2 \
-DWITH_DEMO_ONLY=$3 \
-DWITH_DOWNLOAD=$4 \
-DWITH_KIOSK_MODE=$5 \
-DDOWNLOAD_ASSETS=$6 \
..
}
# ARM
QtTarget=android_armv7
builddir=${buildprefix}-${QtTarget}
mkdir -p ${builddir}
cd ${builddir}
f_cmake arm no OFF OFF OFF $download_assets
make
make BuildTranslations
make getAssets
make apk_release && make apk_signed && make apk_signed_aligned
# Remove extra apk
rm -f android/bin/*release-arm*
rm -f android/bin/*release-signed-arm*
diff --git a/tools/convertPoToTsFiles/convertPo.py b/tools/convertPoToTsFiles/convertPo.py
index 63d109d8a..a475d2f85 100755
--- a/tools/convertPoToTsFiles/convertPo.py
+++ b/tools/convertPoToTsFiles/convertPo.py
@@ -1,63 +1,61 @@
#!/usr/bin/python
#
# GCompris - convertPo.py
#
# Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
#
# This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+# along with this program; if not, see <https://www.gnu.org/licenses/>.
# Using polib.py from https://bitbucket.org/izi/polib/wiki/Home
# Usage : python convertPo.py input1.po input2.ts output.ts
# Find in the first argument po file the translated lines of the ts file
# (if existing) and replace the translation for the ts file.
# For those not found, no translation is provided.
-import polib
-import re
import sys
import xml.etree.ElementTree as ET
+import polib
if len(sys.argv) < 4:
print('Usage : python convertPo.py gcompris_gtk.po gcompris_qt_template.ts $LOCALE.'
' Output will be gcompris_$LOCALE.ts ($LOCALE is fr_FR for example).')
sys.exit(1)
# load an existing po file
po = polib.pofile(sys.argv[1])
tree = ET.parse(sys.argv[2])
root = tree.getroot()
# Change the language in the xml file
root.set('language', sys.argv[3])
for messages in root.iter('message'):
original = messages.find('source').text
- if original != None:
+ if original is not None:
for entry in po:
if entry.msgid.encode('utf-8') == original.encode('utf-8') and \
'type' in messages.find('translation').attrib and \
messages.find('translation').attrib['type'] == 'unfinished':
messages.find('translation').text = entry.msgstr
try:
messages.find('translation').attrib.pop('type')
except:
pass
break
with open('gcompris_' + sys.argv[3] + '.ts', 'wb') as f:
f.write('<?xml version="1.0" encoding="utf-8" ?>\n<!DOCTYPE TS>\n'.encode('utf-8'))
tree.write(f, 'utf-8')
# tree.write('gcompris_' + sys.argv[3] + '.ts', 'utf-8');
-
diff --git a/tools/convertPoToTsFiles/mergePo.py b/tools/convertPoToTsFiles/mergePo.py
index 49feb5791..12f7d000d 100755
--- a/tools/convertPoToTsFiles/mergePo.py
+++ b/tools/convertPoToTsFiles/mergePo.py
@@ -1,72 +1,73 @@
#!/usr/bin/python2
#
# GCompris - mergePo.py
#
# Copyright (C) 2017 Johnny Jazeix <jazeix@gmail.com>
#
# This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+# along with this program; if not, see <https://www.gnu.org/licenses/>.
# Using polib.py from https://bitbucket.org/izi/polib/wiki/Home
# Usage : python2 mergePo.py qt.po gtk.po
# Find in the first argument po file the translated lines of the gtk po file
# (if existing) and replace the translation for the po file.
# For those not found, no translation is provided.
# something like: python2 mergePo.py gcompris_fi.po fi.po && sed '/^#|/ d' < gcompris_fi.po > qtgl.po && mv qtgl.po gcompris_fi.po
-import polib
-import re
import sys
+import polib
if len(sys.argv) < 3:
print('Usage : python mergePo.py gcompris_qt.po gcompris_gtk.po.'
' Output will be in the input file!')
sys.exit(1)
# load an existing po file
po = polib.pofile(sys.argv[1])
poGtk = polib.pofile(sys.argv[2])
print(po.percent_translated())
# First remove all fuzzy strings
for entry in po.fuzzy_entries():
entry.msgstr = ''
- if entry.msgid_plural: entry.msgstr_plural['0'] = ''
- if entry.msgid_plural and '1' in entry.msgstr_plural: entry.msgstr_plural['1'] = ''
- if entry.msgid_plural and '2' in entry.msgstr_plural: entry.msgstr_plural['2'] = ''
+ if entry.msgid_plural:
+ entry.msgstr_plural['0'] = ''
+ if entry.msgid_plural and '1' in entry.msgstr_plural:
+ entry.msgstr_plural['1'] = ''
+ if entry.msgid_plural and '2' in entry.msgstr_plural:
+ entry.msgstr_plural['2'] = ''
entry.flags.remove('fuzzy')
po.save()
# uncomment to create a new po
#for entry in po:
# if entry.msgstr != "":
# entry.msgstr = "";
#print(po.percent_translated())
# Then replace in the output all the good strings
for entry in po:
if entry.msgstr != "":
- continue;
+ continue
for entryGtk in poGtk:
if entry.msgid.encode('utf-8') == entryGtk.msgid.encode('utf-8') and entryGtk.msgstr != "":
entry.msgstr = entryGtk.msgstr
po.save()
print(po.percent_translated())
-
diff --git a/tools/download-assets.py b/tools/download-assets.py
index d0a9abbc9..765a13b3a 100644
--- a/tools/download-assets.py
+++ b/tools/download-assets.py
@@ -1,73 +1,57 @@
#!/usr/bin/python
#
# GCompris - download-assets.py
#
-# Copyright (C) 2016 Johnny Jazeix <jazeix@gmail.com>
+# Copyright (C) 2016-2018 Johnny Jazeix <jazeix@gmail.com>
#
# This program is free software; you can 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 <http://www.gnu.org/licenses/>.
-#import os
-import urllib2
+# along with this program; if not, see <https://www.gnu.org/licenses/>.
+import urllib.request
+import shutil
import sys
-# code from http://stackoverflow.com/questions/22676/how-do-i-download-a-file-over-http-using-python
-def download_file(file, output_dir):
- u = urllib2.urlopen(file)
- file_name = output_dir + "/" + file.split('/')[-1]
- f = open(file_name, 'wb')
- meta = u.info()
- file_size = int(meta.getheaders("Content-Length")[0])
- print "Downloading: %s in %s Bytes: %s" % (file, file_name, file_size)
- file_size_dl = 0
- block_sz = 8192
- while True:
- buffer = u.read(block_sz)
- if not buffer:
- break
- file_size_dl += len(buffer)
- f.write(buffer)
- status = r"%10d [%3.2f%%]" % (file_size_dl, file_size_dl * 100. / file_size)
- status = status + chr(8)*(len(status)+1)
- print status,
- f.close()
+# see https://stackoverflow.com/questions/7243750/download-file-from-web-in-python-3/7244263#7244263
+def download_file(from_url, output_dir):
+ file_name = output_dir + "/" + from_url.split('/')[-1]
+ with urllib.request.urlopen(from_url) as response, open(file_name, 'wb') as out_file:
+ shutil.copyfileobj(response, out_file)
# argv[0]: program name
# argv[1]: assets to download (words, full for full rccs, locale to get correpsonding locale voices)
# argv[2]: audio format (ogg, mp3, aac)
# argv[3]: output directory (rcc directory)
if len(sys.argv) != 4:
- print "Usage: download-assets.py \"words,full,en,fr,pt_BR\""
+ print("Usage: download-assets.py \"words,full,en,fr,pt_BR\" ogg/mp3/aac outputFolder")
sys.exit(0)
"""Download the voices and words assets depending on the wanted audio format
"""
-DOWNLOAD_PATH = "http://gcompris.net/data2/"
+DOWNLOAD_PATH = "https://cdn.kde.org/gcompris/data2/"
AUDIO_FORMAT = sys.argv[2]
OUTPUT_FOLDER = sys.argv[3]+"/data2/"
-all_languages = [x.strip() for x in sys.argv[1].split(",") if len(x)]
-downloadWords = "words" in all_languages
-downloadFull = "full" in all_languages
-if downloadWords:
- all_languages.remove("words")
+ALL_LANGUAGES = [x.strip() for x in sys.argv[1].split(",") if len(x)]
+DOWNLOAD_WORDS = "words" in ALL_LANGUAGES
+DOWNLOAD_FULL = "full" in ALL_LANGUAGES
+if DOWNLOAD_WORDS:
+ ALL_LANGUAGES.remove("words")
download_file(DOWNLOAD_PATH+"words/words.rcc", OUTPUT_FOLDER+"words/")
-if downloadFull:
- all_languages.remove("full")
+if DOWNLOAD_FULL:
+ ALL_LANGUAGES.remove("full")
download_file(DOWNLOAD_PATH+"full-"+AUDIO_FORMAT+".rcc", OUTPUT_FOLDER)
-for lang in all_languages:
- download_file(DOWNLOAD_PATH+"voices-"+AUDIO_FORMAT+"/voices-"+lang+".rcc", OUTPUT_FOLDER+"voices-"+AUDIO_FORMAT+"/")
-# Inform qmake about the updated file list
-#os.utime("CMakeLists.txt", None)
+for lang in ALL_LANGUAGES:
+ lang_url = DOWNLOAD_PATH+"voices-"+AUDIO_FORMAT+"/voices-"+lang+".rcc"
+ download_file(lang_url, OUTPUT_FOLDER+"voices-"+AUDIO_FORMAT+"/")
diff --git a/tools/gcompris-qt.sh b/tools/gcompris-qt.sh
index a76ea4cf9..8472e7fea 100755
--- a/tools/gcompris-qt.sh
+++ b/tools/gcompris-qt.sh
@@ -1,4 +1,6 @@
#!/bin/sh
export LD_LIBRARY_PATH=$(dirname $0)
+## uncomment the line below in case of too fast animations, with nvidia drivers especially...
+#export QSG_RENDER_LOOP=basic
$(dirname $0)/gcompris-qt
diff --git a/tools/gencode.py b/tools/gencode.py
index 225fda3d9..33a4d6406 100755
--- a/tools/gencode.py
+++ b/tools/gencode.py
@@ -1,28 +1,28 @@
#!/usr/bin/python
#
# GCompris - gencode.py
#
# Copyright (C) 2016 Bruno Coudoin <bruno.coudoin@gcompris.net>
#
# This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+# along with this program; if not, see <https://www.gnu.org/licenses/>.
# Generate code for today
import random
from datetime import datetime
user = int(random.random() * 0xFFFF)
date = (datetime.now().year << 4) | datetime.now().month
crc = user ^ date ^ 0xCECA
print "%04X-%04X-%04X" %(user, date, crc)
diff --git a/tools/l10n-fetch-po-files.py b/tools/l10n-fetch-po-files.py
index 8deaa3a20..bc7f06cfa 100644
--- a/tools/l10n-fetch-po-files.py
+++ b/tools/l10n-fetch-po-files.py
@@ -1,70 +1,70 @@
#!/usr/bin/python
#
# GCompris - l10n-fetch-po-files.py
#
# Copyright (C) 2015 Trijita org <jktjkt@trojita.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 <http://www.gnu.org/licenses/>.
+# along with this program; if not, see <https://www.gnu.org/licenses/>.
import os
import re
import subprocess
# Copied from Trojita
"""Fetch the .po files from KDE's SVN for GCompris
Run me from GCompris's top-level directory.
"""
-SVN_PATH = "svn://anonsvn.kde.org/home/kde/branches/stable/l10n-kf5/"
+SVN_PATH = "svn://anonsvn.kde.org/home/kde/trunk/l10n-kf5/"
SOURCE_PO_PATH = "/messages/extragear-edu/gcompris_qt.po"
OUTPUT_PO_PATH = "./po/"
OUTPUT_PO_PATTERN = "gcompris_%s.po"
fixer = re.compile(r'^#~\| ', re.MULTILINE)
re_empty_msgid = re.compile('^msgid ""$', re.MULTILINE)
re_empty_line = re.compile('^$', re.MULTILINE)
re_has_qt_contexts = re.compile('X-Qt-Contexts: true\\n')
if not os.path.exists(OUTPUT_PO_PATH):
os.mkdir(OUTPUT_PO_PATH)
all_languages = subprocess.check_output(['svn', 'cat', SVN_PATH + 'subdirs'],
stderr=subprocess.STDOUT)
all_languages = [x.strip() for x in all_languages.split("\n") if len(x)]
all_languages.remove("x-test")
for lang in all_languages:
try:
raw_data = subprocess.check_output(['svn', 'cat', SVN_PATH + lang + SOURCE_PO_PATH],
stderr=subprocess.PIPE)
(transformed, subs) = fixer.subn('# ~| ', raw_data)
pos1 = re_empty_msgid.search(transformed).start()
pos2 = re_empty_line.search(transformed).start()
if re_has_qt_contexts.search(transformed, pos1, pos2) is None:
transformed = transformed[:pos2] + \
'"X-Qt-Contexts: true\\n"\n' + \
transformed[pos2:]
subs = subs + 1
if (subs > 0):
print "Fetched %s (and performed %d cleanups)" % (lang, subs)
else:
print "Fetched %s" % lang
file(OUTPUT_PO_PATH + OUTPUT_PO_PATTERN % lang, "wb").write(transformed)
except subprocess.CalledProcessError:
print "No data for %s" % lang
# Inform qmake about the updated file list
#os.utime("CMakeLists.txt", None)
diff --git a/tools/menus/anim.qml b/tools/menus/anim.qml
index 9b543fcc4..09718b73e 100644
--- a/tools/menus/anim.qml
+++ b/tools/menus/anim.qml
@@ -1,33 +1,33 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Your Name <yy@zz.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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "anim/Anim.qml"
difficulty: 3
icon: "anim/anim.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
title: qsTr("Create a drawing or an animation")
description: qsTr("Free drawing and animation tool.")
goal: qsTr("In this game, children can draw freely. The goal is to discover how to create attractive drawings based on basic shapes: rectangles, ellipses and lines. To give children a wider range of choices, a set of images can also be used.")
prerequisite: qsTr("Needs to be capable of moving and clicking the mouse easily")
manual: qsTr("Select a drawing tool on the left, and a color down the bottom. Then click and drag in the white area to create a new shape. Once you've completed a drawing, you can select a new frame to work on by selecting one of the small rectangles on the bottom. Each frame contains the same content as its previous one. You can then edit it by moving objects a little bit or adding/deleting objects. When you create several frames and then click on the 'film' button, you will see all your images in a continuous slide-show (an infinite loop pattern). You can change the last image in your film by right clicking on a time frame. You can also change the viewing speed in this mode. In viewing mode, click on the 'drawing' button to return to drawing mode. You can also save and reload your animations with the 'floppy disk' and 'folder' buttons.")
credit: ""
section: "/fun"
}
diff --git a/tools/menus/awele.qml b/tools/menus/awele.qml
index 47221425f..1f6d92be2 100644
--- a/tools/menus/awele.qml
+++ b/tools/menus/awele.qml
@@ -1,33 +1,33 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Your Name <yy@zz.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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "awele/Awele.qml"
difficulty: 2
icon: "awele/awele.svg"
author: "Frédéric Mazzarol"
demo: true
title: qsTr("Oware")
description: qsTr("Play the Oware strategy game against Tux")
goal: qsTr("The object of the game is to capture more seeds than one's opponent. Since the game has only 48 seeds, capturing 25 is sufficient to accomplish this. Since there are an even number of seeds, it is possible for the game to end in a draw, where each player has captured 24. The game is over when one player has captured 25 or more seeds, or both players have taken 24 seeds each (draw). If both players agree that the game has been reduced to an endless cycle, each player captures the seeds on their side of the board.")
prerequisite: ""
manual: qsTr("At the beginning of the game four seeds are placed in each house. Players take turns moving the seeds. In each turn, a player chooses one of the six houses under his or her control. The player removes all seeds from this house, and distributes them, dropping one in each house counter-clockwise from the original house, in a process called sowing. Seeds are not distributed into the end scoring houses, nor into the house drawn from. That is, the starting house is left empty; if it contained 12 seeds, it is skipped, and the twelfth seed is placed in the next house. After a turn, if the last seed was placed into an opponent's house and brought its total to two or three, all the seeds in that house are captured and placed in the player's scoring house (or set aside if the board has no scoring houses). If the previous-to-last seed also brought the total seeds in an opponent's house to two or three, these are captured as well, and so on. However, if a move would capture all an opponent's seeds, the capture is forfeited, and the seeds are instead left on the board, since this would prevent the opponent from continuing the game. The proscription against capturing all an opponent's seeds is related to a more general idea, that one ought to make a move that allows the opponent to continue playing. If an opponent's houses are all empty, the current player must make a move that gives the opponent seeds. If no such move is possible, the current player captures all seeds in his/her own territory, ending the game. (Source Wikipedia &lt;http://en.wikipedia.org/wiki/Oware&gt;)")
credit: ""
section: "/strategy"
}
diff --git a/tools/menus/braille_lotto.qml b/tools/menus/braille_lotto.qml
index 973de7ffb..9628adfc6 100644
--- a/tools/menus/braille_lotto.qml
+++ b/tools/menus/braille_lotto.qml
@@ -1,33 +1,33 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Your Name <yy@zz.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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "braille_lotto/BrailleLotto.qml"
difficulty: 6
icon: "braille_lotto/braille_lotto.svg"
author: "Srishti Sethi &lt;srishakatux@gmail.com&gt;"
demo: true
title: qsTr("Braille Lotto")
description: qsTr("Discover the Braille system for numbers.")
goal: ""
prerequisite: ""
manual: qsTr("Each player must find if the proposed number is in their board. If the code is in the board, just click on it in order to validate it. The player who crosses all the Braille numbers correctly wins the game. Check the Braille table by clicking on the toggle button in the control bar.")
credit: ""
section: "/discovery/braille"
}
diff --git a/tools/menus/chat.qml b/tools/menus/chat.qml
index c81b0db7a..98c34f290 100644
--- a/tools/menus/chat.qml
+++ b/tools/menus/chat.qml
@@ -1,33 +1,33 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Your Name <yy@zz.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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "chat/Chat.qml"
difficulty: 3
icon: "chat/chat.svg"
author: "Bruno coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
title: qsTr("Chat and draw with your friends")
description: qsTr("This chat activity only works on the local network")
goal: ""
prerequisite: ""
manual: qsTr("This chat activity will only work with other GCompris users on your local network, not on the Internet. To use it, just type in your message and hit Enter. Your message is then broadcast on the local network, and any GCompris program running the chat activity on that local network will receive and display your message.")
credit: ""
section: "/fun"
}
diff --git a/tools/menus/doubleentry.qml b/tools/menus/doubleentry.qml
index 15e73c050..29161511f 100644
--- a/tools/menus/doubleentry.qml
+++ b/tools/menus/doubleentry.qml
@@ -1,33 +1,33 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Your Name <yy@zz.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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "doubleentry/Doubleentry.qml"
difficulty: 2
icon: "doubleentry/doubleentry.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
title: qsTr("Double-entry table")
description: qsTr("Drag and Drop the items in the double-entry table")
goal: qsTr("Move the items on the left to their proper position in the double-entry table.")
prerequisite: qsTr("Basic counting skills")
manual: qsTr("Drag and Drop each proposed item on its destination")
credit: ""
section: "/discovery/miscellaneous"
}
diff --git a/tools/menus/draw.qml b/tools/menus/draw.qml
index 9af1ee202..293ffe242 100644
--- a/tools/menus/draw.qml
+++ b/tools/menus/draw.qml
@@ -1,33 +1,33 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Your Name <yy@zz.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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "draw/Draw.qml"
difficulty: 2
icon: "draw/draw.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
title: qsTr("A simple vector-drawing tool")
description: qsTr("A creative board where you can draw freely")
goal: qsTr("In this game, children can draw freely. The goal is to discover how to create attractive drawings based on basic shapes: rectangles, ellipses and lines.")
prerequisite: qsTr("Needs to be capable of moving and clicking the mouse easily")
manual: qsTr("Select a drawing tool on the left, and a color down the bottom, then click and drag in the white area to create a new shape. To save time, you can click with the middle mouse button to delete an object.")
credit: ""
section: "/math/geometry"
}
diff --git a/tools/menus/electric.qml b/tools/menus/electric.qml
index 60059dce3..af1f83f3d 100644
--- a/tools/menus/electric.qml
+++ b/tools/menus/electric.qml
@@ -1,33 +1,33 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Your Name <yy@zz.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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "electric/Electric.qml"
difficulty: 5
icon: "electric/electric.svg"
author: "Bruno Coudoin &lt;bruno.coudoin@gcompris.net&gt;"
demo: false
title: qsTr("Electricity")
description: qsTr("Create and simulate an electric schema")
goal: qsTr("Freely create an electric schema with a real time simulation of it.")
prerequisite: qsTr("Requires some basic understanding of the concept of electricity.")
manual: qsTr("Drag electrical components from the selector and drop them in the working area. Create wires by clicking on a connection spot, dragging the mouse to the next connection spot, and letting go. You can also move components by dragging them. You can delete wires by clicking on them. To delete a component, select the deletion tool on top of the component selector. You can click on the switch to open and close it. You can change the rheostat value by dragging its wiper. In order to simulate what happens when a bulb is blown, you can blown it by right-clicking on it. The simulation is updated in real time by any user action.")
- credit: qsTr("GCompris uses the Gnucap electric simulator as a backend. You can get more information on gnucap at &lt;http://www.gnu.org/software/gnucap/&gt;.")
+ credit: qsTr("GCompris uses the Gnucap electric simulator as a backend. You can get more information on gnucap at &lt;https://www.gnu.org/software/gnucap/&gt;.")
section: "/experience"
}
diff --git a/tools/menus/maze3D.qml b/tools/menus/maze3D.qml
index 0686a0ef9..8c1b4f24e 100644
--- a/tools/menus/maze3D.qml
+++ b/tools/menus/maze3D.qml
@@ -1,33 +1,33 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Your Name <yy@zz.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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "maze3D/Maze3D.qml"
difficulty: 2
icon: "maze3D/maze3D.svg"
author: "Christof Petig &lt;christof@petig-baender.de&gt;"
demo: true
title: qsTr("3D Maze")
description: qsTr("Find your way out of the 3D maze")
goal: qsTr("Help Tux get out of this maze.")
prerequisite: qsTr("Can use the keyboard arrow to move an object.")
manual: qsTr("Use the keyboard arrows to move Tux up to the door. Use the spacebar to switch between 2D and 3D modes. 2D mode just gives you an indication of your position, like a map. You cannot move Tux in 2D mode.")
credit: ""
section: "/discovery/mazeMenu"
}
diff --git a/tools/menus/piano_composition.qml b/tools/menus/piano_composition.qml
deleted file mode 100644
index 2422c9bf9..000000000
--- a/tools/menus/piano_composition.qml
+++ /dev/null
@@ -1,67 +0,0 @@
-/* GCompris - ActivityInfo.qml
- *
- * Copyright (C) 2015 Your Name <yy@zz.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 <http://www.gnu.org/licenses/>.
- */
-import GCompris 1.0
-
-ActivityInfo {
- name: "piano_composition/PianoComposition.qml"
- difficulty: 4
- icon: "piano_composition/piano_composition.svg"
- author: "Beth Hadley &lt;bethmhadley@gmail.com&gt;"
- demo: true
- title: qsTr("Piano Composition")
- description: qsTr("An activity to learn how the piano keyboard works, how notes are written on a musical staff and explore music composition by loading and saving your work.")
- goal: qsTr("Develop an understanding of music composition, and increase interest in making music with a piano keyboard. This activity covers many fundamental aspects of music, but there is much more to explore about music composition. If you enjoy this activity but want a more advanced tool, try downloading MuseScore (http://musescore.org/en/download), an open source music notation tool.")
- prerequisite: qsTr("Familiarity with note naming conventions, note-names activity useful to learn this notation.")
- manual: qsTr("This activity has several levels, each level adds a new functionality to the previous level.
-Level 1: basic piano keyboard (white keys only) and students can experiment with clicking the colored rectangle keys to write music
-Level 2: the musical staff switches to bass clef, so pitches are lower than in previous level
-Level 3: option to choose between treble and bass clef, additional function includes option to select note duration (quarter, half, and whole notes)
-Level 4: addition of black keys (sharp keys)
-Level 5: flat notation used for black keys
-Level 6: load children's melodies from around the world
-Level 7: all features available, with the additional feature to load and save your composition
-
-The following keyboard bindings work in this activity:
-- backspace: erase one note
-- delete: erase all notes
-- space bar: play composition
-- number keys:
- 1: C
- 2: D
- 3: E
- 4: F
- 5: G
- 6: A
- 7: B
- 8: C (higher octave)
- etc.
- F1: C# / Db
- F2: D# / Eb
- F3: F# / Gb
- F4: G# / Ab
- F5: A# / Bb
-")
- credit: qsTr("
-Thank you to Bruno Coudoin for his mentorship.
-Thank you to Olivier Samyn for his contribution to improving the note design and coloring.
-Thank you to Federico Mena who inspired me with his wonderful enthusiasm for my music projects at GUADEC.
-Thank you to all contributors of children's songs from around the world, especially the GNOME community. Learn more about these
-melodies and who contributed them here: https://live.gnome.org/GComprisMelodies
-")
- section: "/discovery/sound_group"
-}
diff --git a/tools/menus/place_your_satellite.qml b/tools/menus/place_your_satellite.qml
index 40592be68..3c06d95df 100644
--- a/tools/menus/place_your_satellite.qml
+++ b/tools/menus/place_your_satellite.qml
@@ -1,37 +1,37 @@
/* GCompris - ActivityInfo.qml
*
* Copyright (C) 2015 Your Name <yy@zz.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 <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
*/
import GCompris 1.0
ActivityInfo {
name: "place_your_satellite/PlaceYourSatellite.qml"
difficulty: 4
icon: "place_your_satellite/place_your_satellite.svg"
author: "Matilda Bernard &lt;seah4291@gmail.com&gt;"
demo: true
title: qsTr("Place your satellite")
description: qsTr("Understanding effect of mass and distance on orbital velocity.")
goal: qsTr("Make sure the satellite does not crash or fly away")
prerequisite: ""
manual: qsTr("
A satellite revolves around the Earth because of the force between them. Orbital velocity of a satellite of Earth is directly proportional to the square root of the mass of Earth and inversely proportional to the square root of the distance from the center of Earth to the satellite.
In this activity, play with the speed of the satellite and mass of Earth to see what happens to the satellite. If the speed of the satellite is slower than the required orbital speed then the force applied by the Earth on the satellite is too much and thus the satellite gets pulled towards the Earth and burns in it's atmosphere. If the speed of the satellite is more than the required orbital speed then the Earth's force is not enough to keep it in orbit and thus the satellite flies away due to it's own inertia.
")
credit: ""
section: "/experience"
}
diff --git a/tools/menus/play_rhythm.qml b/tools/menus/play_rhythm.qml
deleted file mode 100644
index 07f0a2364..000000000
--- a/tools/menus/play_rhythm.qml
+++ /dev/null
@@ -1,46 +0,0 @@
-/* GCompris - ActivityInfo.qml
- *
- * Copyright (C) 2015 Your Name <yy@zz.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 <http://www.gnu.org/licenses/>.
- */
-import GCompris 1.0
-
-ActivityInfo {
- name: "play_rhythm/PlayRhythm.qml"
- difficulty: 3
- icon: "play_rhythm/play_rhythm.svg"
- author: "Beth Hadley &lt;bethmhadley@gmail.com&gt;"
- demo: true
- title: qsTr("Play Rhythm")
- description: qsTr("Learn to listen to, read, and play musical rhythms.")
- goal: qsTr("Learn to beat rhythms precisely and accurately based on what you see and hear.")
- prerequisite: qsTr("Simple understanding of musical rhythm and beat.")
- manual: qsTr("This is a relatively challenging game to master, so good luck.
-
-Listen to the rhythm played, and follow along with the music. If you would like to hear it again, click the play button. When you're ready to perform the identical rhythm, click the drum to the rhythm, then click the OK button. If you clicked correctly and in the right tempo, another rhythm is displayed. If not, you must try again.
-
-Even levels display a vertical playing line when you click the drum, which helps you see when to click to follow the rhythm. Click on the drum when the line is in the middle of the notes.
-
-Odd levels are harder, because there is no vertical playing line. The rhythm will not be played for you. You must read the rhythm, and click it back in tempo. Click the metronome to hear the quarter note tempo.
-
-The following keyboard bindings work in this game:
-- backspace: erase attempt
-- delete: erase attempt
-- enter/return: OK button
-- space bar: play
-")
- credit: ""
- section: "/discovery/sound_group"
-}
diff --git a/tools/menus/resource/note_names.svg b/tools/menus/resource/note_names.svg
deleted file mode 100644
index 3d0303089..000000000
--- a/tools/menus/resource/note_names.svg
+++ /dev/null
@@ -1,83 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="100"
- height="100"
- id="svg2"
- sodipodi:version="0.32"
- inkscape:version="0.91 r13725"
- version="1.0"
- sodipodi:docname="note_names.svg">
- <defs
- id="defs4">
- <filter
- inkscape:collect="always"
- id="filter4351"
- x="-0.13237838"
- width="1.2647568"
- y="-0.065687165"
- height="1.1313743">
- <feGaussianBlur
- inkscape:collect="always"
- stdDeviation="2.233172"
- id="feGaussianBlur4353" />
- </filter>
- </defs>
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="3.1100436"
- inkscape:cx="32.87338"
- inkscape:cy="89.444925"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- width="100px"
- height="100px"
- showguides="true"
- inkscape:guide-bbox="true"
- inkscape:window-width="1112"
- inkscape:window-height="949"
- inkscape:window-x="567"
- inkscape:window-y="25"
- showgrid="false"
- inkscape:window-maximized="0" />
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Calque 1"
- inkscape:groupmode="layer"
- id="layer1">
- <path
- style="fill:#1e2f1e;fill-opacity:1;filter:url(#filter4351)"
- d="m 40.044237,87.456962 c -4.748895,-1.22651 -8.367964,-3.90639 -9.425546,-6.97953 -2.140335,-6.21941 4.983667,-14.036641 15.401589,-16.900297 4.243565,-1.166464 11.1139,-1.46389 14.508652,-0.628106 1.410545,0.347276 2.796818,0.631412 3.080596,0.631412 0.616464,0 0.278429,-1.508824 -7.311187,-32.633898 -0.755491,-3.098278 -1.929332,-7.993362 -2.608539,-10.877966 -0.679199,-2.884603 -1.590405,-6.585045 -2.02489,-8.223203 -0.434486,-1.638159 -0.789975,-3.2642057 -0.789975,-3.6134377 0,-0.557714 2.163541,-1.760816 3.166483,-1.760816 0.440684,0 0.655946,0.798449 6.965,25.8351687 3.268106,12.969103 4.561442,18.09273 6.227263,24.669672 2.664833,10.5212 3.49146,14.339013 3.49146,16.125361 0,3.71636 -4.555518,8.96126 -10.115763,11.64656 -6.145256,2.96783 -15.031061,4.13837 -20.565143,2.70908 z m 12.47824,-5.04778 c 1.178722,-0.58455 2.132228,-1.80122 2.57741,-3.28879 0.258881,-0.86502 0.143424,-0.81552 -1.055647,0.45264 -0.740482,0.78314 -1.766109,1.62464 -2.279182,1.87 -1.561586,0.7468 -3.948281,0.56806 -5.626835,-0.42138 l -1.542437,-0.9092 0.641778,0.96084 c 1.456959,2.18131 4.467103,2.73331 7.284913,1.33589 z m -11.055128,-6.22456 c 1.161475,-0.78018 1.142077,-1.55641 -0.05774,-2.31033 -0.977965,-0.61452 -2.702178,-0.33658 -3.25749,0.52509 -0.387815,0.60178 0.20234,1.64903 1.132355,2.0094 1.175602,0.45554 1.17014,0.45611 2.182872,-0.22416 z m 17.828429,-2.67018 c 1.390453,-1.259247 -1.315872,-3.033528 -3.00659,-1.971144 -1.199421,0.753673 -1.219262,1.530114 -0.05899,2.309464 0.931205,0.6255 2.149867,0.49101 3.065611,-0.33832 z"
- id="path3541-2"
- inkscape:connector-curvature="0"
- transform="matrix(1.0940455,0,0,1.0940455,-2.3397074,-0.1045323)" />
- <path
- style="fill:#008f00;fill-opacity:1"
- d="m 36.912839,91.470092 c -5.195507,-1.341854 -9.154933,-4.273768 -10.311976,-7.635917 -2.341624,-6.804318 5.452358,-15.356727 16.850039,-18.489697 4.642653,-1.276165 12.159113,-1.601562 15.873126,-0.687177 1.5432,0.379936 3.059846,0.690794 3.370312,0.690794 0.67444,0 0.304614,-1.650722 -7.998771,-35.70297 -0.826542,-3.389657 -2.110777,-8.745102 -2.853861,-11.90099 -0.743074,-3.155887 -1.739975,-7.204339 -2.215321,-8.9965583 -0.475348,-1.7922205 -0.864269,-3.5711898 -0.864269,-3.9532655 0,-0.6101646 2.367012,-1.9264131 3.464276,-1.9264131 0.482129,0 0.717635,0.8735392 7.620027,28.2648509 3.575457,14.188789 4.990426,19.79427 6.81291,26.989744 2.915448,11.510672 3.819816,15.687533 3.819816,17.641876 0,4.065867 -4.983944,9.804026 -11.067105,12.741866 -6.72319,3.246947 -16.444665,4.527571 -22.499203,2.963857 z m 13.651763,-5.522498 c 1.289575,-0.639525 2.332754,-1.970621 2.819804,-3.598086 0.283227,-0.946374 0.156912,-0.892211 -1.154926,0.495209 -0.810121,0.856791 -1.932204,1.77743 -2.493529,2.04587 -1.708446,0.817024 -4.319599,0.621482 -6.156014,-0.46101 l -1.687496,-0.994711 0.702134,1.051202 c 1.59398,2.386459 4.887214,2.990362 7.970027,1.461526 z m -12.094813,-6.80995 c 1.270706,-0.853552 1.249484,-1.702789 -0.06317,-2.527609 -1.069938,-0.672312 -2.956305,-0.368237 -3.563842,0.574474 -0.424287,0.658371 0.221369,1.804109 1.238848,2.198377 1.286162,0.498382 1.280186,0.499 2.388161,-0.245242 z m 19.505112,-2.921301 c 1.521219,-1.377673 -1.439624,-3.318817 -3.289346,-2.15652 -1.312221,0.824552 -1.333928,1.674018 -0.06454,2.526661 1.018781,0.684324 2.352053,0.537186 3.353918,-0.370141 z"
- id="path3541"
- inkscape:connector-curvature="0" />
- </g>
-</svg>
diff --git a/tools/menus/resource/piano_composition.svg b/tools/menus/resource/piano_composition.svg
deleted file mode 100644
index dc85f6c35..000000000
--- a/tools/menus/resource/piano_composition.svg
+++ /dev/null
@@ -1,113 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="100"
- height="100"
- id="svg2"
- sodipodi:version="0.32"
- inkscape:version="0.91 r13725"
- version="1.0"
- sodipodi:docname="piano_composition.svg">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="3.1100436"
- inkscape:cx="95.34904"
- inkscape:cy="54.895496"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- width="100px"
- height="100px"
- showguides="true"
- inkscape:guide-bbox="true"
- inkscape:window-width="1112"
- inkscape:window-height="949"
- inkscape:window-x="608"
- inkscape:window-y="68"
- showgrid="false"
- inkscape:window-maximized="0" />
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Calque 1"
- inkscape:groupmode="layer"
- id="layer1">
- <path
- inkscape:connector-curvature="0"
- d="m 56.780671,46.641568 22.800238,-3.772591 8e-6,27.703172 c -2.129497,-0.644855 -5.177526,-0.64383 -7.515988,1.853498 -4.681556,4.999607 -0.572852,10.619564 4.785026,7.831216 3.048781,-1.586645 4.066203,-4.135469 4.066203,-7.980526 l 0,-34.437467 -25.470735,3.772582 9e-6,34.499214 c -2.129498,-0.644864 -5.177528,-0.64383 -7.51598,1.85349 -4.681565,4.999616 -0.572861,10.619572 4.785016,7.831224 3.048783,-1.586646 4.066203,-4.135469 4.066203,-7.980535 l 0,-31.173277 z"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path2796" />
- <path
- inkscape:connector-curvature="0"
- d="m 3.0030639,30.536758 93.8613821,0"
- style="fill:none;stroke:#000000;stroke-width:1.04345846;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="path2810" />
- <use
- transform="translate(-7.1940475e-8,11.327292)"
- id="use2812"
- x="0"
- y="0"
- width="400"
- height="300"
- xlink:href="#path2810" />
- <use
- transform="translate(-7.1940475e-8,22.654584)"
- id="use2814"
- x="0"
- y="0"
- width="400"
- height="300"
- xlink:href="#path2810" />
- <use
- transform="translate(-7.1940475e-8,33.981877)"
- id="use2816"
- x="0"
- y="0"
- width="400"
- height="300"
- xlink:href="#path2810" />
- <use
- transform="translate(-7.1940475e-8,45.30916)"
- id="use2818"
- x="0"
- y="0"
- width="400"
- height="300"
- xlink:href="#path2810" />
- <path
- inkscape:connector-curvature="0"
- d="m 96.864438,31.099212 0,44.158079"
- style="fill:none;stroke:#000000;stroke-width:2.08691788;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
- id="path2820" />
- <path
- inkscape:connector-curvature="0"
- d="m 18.026168,87.597113 c 9.850892,-9.827318 -9.1709005,-14.119455 -3.324784,0.943146 1.276228,3.288221 13.668564,11.479571 13.668564,-12.575281 0,-18.076974 -8.619814,-41.026864 -8.619814,-50.14395 0,-9.117081 5.66445,-13.990004 5.66445,-1.886293 0,12.103713 -13.914845,22.478324 -13.914845,35.053605 0,20.760044 22.288379,21.074171 22.288379,5.658882 0,-14.305251 -10.424237,-14.745634 -13.791705,-11.160567 -4.805959,5.116516 -3.06446,15.058962 2.585946,15.719105 -8.288922,-13.551861 7.805921,-17.106108 8.866095,-5.658882 1.165537,12.58488 -17.11649,12.941443 -17.11649,-2.35786 0,-12.103712 15.090063,-24.396442 14.407404,-36.311136 C 27.754249,7.6841045 18.922414,2.3685775 17.903027,23.305971 c -0.716613,14.56154 8.578085,33.016211 8.989244,53.602152 0.262539,13.144847 -7.466744,16.616217 -8.866103,10.68899 z"
- style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path1981" />
- </g>
-</svg>
diff --git a/tools/menus/resource/play_piano.svg b/tools/menus/resource/play_piano.svg
deleted file mode 100644
index 71bc80e89..000000000
--- a/tools/menus/resource/play_piano.svg
+++ /dev/null
@@ -1,586 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="100"
- height="100"
- id="svg2"
- sodipodi:version="0.32"
- inkscape:version="0.91 r13725"
- version="1.0"
- sodipodi:docname="play_piano.svg">
- <defs
- id="defs4">
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient21874"
- id="linearGradient4373"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.37737016,0,0,0.1328618,104.37801,8.1363933)"
- x1="-177.00168"
- y1="454.6254"
- x2="-177.00168"
- y2="648.55573" />
- <linearGradient
- inkscape:collect="always"
- id="linearGradient21874">
- <stop
- style="stop-color:#ffffff;stop-opacity:1;"
- offset="0"
- id="stop21876" />
- <stop
- style="stop-color:#ffffff;stop-opacity:0;"
- offset="1"
- id="stop21878" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient21874"
- id="linearGradient4376"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.19512603,0,0,0.1790193,85.304878,-12.518254)"
- spreadMethod="reflect"
- x1="-247.43213"
- y1="411.5748"
- x2="-215.85513"
- y2="405.35657" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient15717"
- id="linearGradient4379"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.18690911,0.04708202,0.00415489,0.06859599,55.450464,49.077538)"
- x1="-98.593307"
- y1="289.05264"
- x2="-332.37381"
- y2="246.84198" />
- <linearGradient
- inkscape:collect="always"
- id="linearGradient15717">
- <stop
- style="stop-color:#ffffff;stop-opacity:1;"
- offset="0"
- id="stop15719" />
- <stop
- style="stop-color:#ffffff;stop-opacity:0;"
- offset="1"
- id="stop15721" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient21874"
- id="linearGradient4382"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.19512603,0,0,0.1790193,116.18123,-27.763314)"
- x1="-177.00168"
- y1="454.6254"
- x2="-177.00168"
- y2="648.55573" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient18346"
- id="linearGradient4385"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.19512603,0,0,0.1328618,52.602467,0.02904526)"
- x1="-177.00168"
- y1="454.6254"
- x2="-177.00168"
- y2="648.55573" />
- <linearGradient
- inkscape:collect="always"
- id="linearGradient18346">
- <stop
- style="stop-color:#ffffff;stop-opacity:1;"
- offset="0"
- id="stop18348" />
- <stop
- style="stop-color:#ffffff;stop-opacity:0;"
- offset="1"
- id="stop18350" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient21874"
- id="linearGradient4388"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.19512603,0,0,0.1790193,85.807446,-12.574071)"
- x1="-177.00168"
- y1="454.6254"
- x2="-177.00168"
- y2="648.55573" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient18346"
- id="linearGradient4391"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.19512603,0,0,0.17901928,85.62363,-13.080254)"
- spreadMethod="reflect"
- x1="-29.717674"
- y1="362.42477"
- x2="-7.9825511"
- y2="362.42477" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient15717"
- id="linearGradient4394"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.19512603,0,0,0.1790193,71.863043,-1.6634238)"
- x1="-98.593307"
- y1="289.05264"
- x2="-332.37381"
- y2="246.84198" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient11326"
- id="linearGradient4397"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.19512603,0,0,0.2313851,66.859279,-19.997201)"
- spreadMethod="reflect"
- x1="53.320744"
- y1="328.71255"
- x2="61.128662"
- y2="328.71255" />
- <linearGradient
- inkscape:collect="always"
- id="linearGradient11326">
- <stop
- style="stop-color:#ffffff;stop-opacity:1;"
- offset="0"
- id="stop11328" />
- <stop
- style="stop-color:none"
- offset="1"
- id="stop11330" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient11326"
- id="linearGradient4400"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.19512603,0,0,0.1790193,85.780216,-12.741329)"
- spreadMethod="reflect"
- x1="53.320744"
- y1="328.71255"
- x2="61.128662"
- y2="328.71255" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3220"
- id="linearGradient4415"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.12466369,0,0,0.1790193,45.12124,-9.7601568)"
- x1="185.75323"
- y1="318.01575"
- x2="187.57375"
- y2="299.96475" />
- <linearGradient
- id="linearGradient3220">
- <stop
- style="stop-color:#3f1a1c;stop-opacity:1;"
- offset="0"
- id="stop3222" />
- <stop
- style="stop-color:#d88e27;stop-opacity:1;"
- offset="1"
- id="stop3224" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient11316"
- id="linearGradient4418"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.19512603,0,0,0.17901928,-17.364521,-37.714368)"
- x1="389.41888"
- y1="225.04726"
- x2="665.18036"
- y2="217.47618" />
- <linearGradient
- inkscape:collect="always"
- id="linearGradient11316">
- <stop
- style="stop-color:#ffffff;stop-opacity:1;"
- offset="0"
- id="stop11318" />
- <stop
- style="stop-color:#ffffff;stop-opacity:0;"
- offset="1"
- id="stop11320" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient8675"
- id="linearGradient4421"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.19512603,0,0,0.1790193,85.347199,-12.4861)"
- x1="-327.64285"
- y1="274.20898"
- x2="-179.92877"
- y2="266.12531" />
- <linearGradient
- id="linearGradient8675">
- <stop
- style="stop-color:#000000;stop-opacity:1;"
- offset="0"
- id="stop8677" />
- <stop
- id="stop8683"
- offset="0.5"
- style="stop-color:#000000;stop-opacity:1;" />
- <stop
- style="stop-color:#ffffff;stop-opacity:1;"
- offset="1"
- id="stop8679" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient10433"
- id="linearGradient4424"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.19512603,0,0,0.17901928,-17.364521,-37.714368)"
- x1="305.57623"
- y1="343.23511"
- x2="511.63718"
- y2="139.1843" />
- <linearGradient
- inkscape:collect="always"
- id="linearGradient10433">
- <stop
- style="stop-color:#ffffff;stop-opacity:1;"
- offset="0"
- id="stop10435" />
- <stop
- style="stop-color:#ffffff;stop-opacity:0;"
- offset="1"
- id="stop10437" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient7770"
- id="linearGradient4427"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.19512603,0,0,0.17901928,85.7735,-13.16312)"
- spreadMethod="reflect"
- x1="-84.706306"
- y1="290.29047"
- x2="-66.625877"
- y2="286.00476" />
- <linearGradient
- id="linearGradient7770">
- <stop
- style="stop-color:#000000;stop-opacity:1;"
- offset="0"
- id="stop7772" />
- <stop
- style="stop-color:#ffffff;stop-opacity:1;"
- offset="1"
- id="stop7774" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient19229"
- id="linearGradient4430"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.19512603,0,0,0.1790193,-17.364512,-37.71434)"
- x1="72.357162"
- y1="335.21933"
- x2="567.57428"
- y2="325.21933" />
- <linearGradient
- id="linearGradient19229">
- <stop
- style="stop-color:#e04422;stop-opacity:1;"
- offset="0"
- id="stop19231" />
- <stop
- style="stop-color:#6e1d05;stop-opacity:0.28865978;"
- offset="1"
- id="stop19233" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3220"
- id="linearGradient4434"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.19512603,0,0,0.1790193,45.715086,-16.562884)"
- x1="185.75323"
- y1="318.01575"
- x2="187.57375"
- y2="299.96475" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3220"
- id="linearGradient4437"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.16647621,0,0,0.1790193,45.856116,-13.34054)"
- x1="185.75323"
- y1="318.01575"
- x2="187.57375"
- y2="299.96475" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3220"
- id="linearGradient4440"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.19512603,0,0,0.1790193,-17.364512,-37.71434)"
- x1="332.48096"
- y1="503.81046"
- x2="587.33167"
- y2="372.53067" />
- </defs>
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="1.5550218"
- inkscape:cx="162.73691"
- inkscape:cy="-1.4427698"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- width="100px"
- height="100px"
- showguides="true"
- inkscape:guide-bbox="true"
- inkscape:window-width="838"
- inkscape:window-height="990"
- inkscape:window-x="840"
- inkscape:window-y="27"
- showgrid="false"
- inkscape:window-maximized="0" />
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Calque 1"
- inkscape:groupmode="layer"
- id="layer1">
- <path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.18689911px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="M 87.856013,1.7372742 64.60696,2.0310482 35.148462,28.470352 31.306046,29.057893 c 0,0 -1.666497,-0.726339 -2.984455,0.08434 -1.317957,0.810688 -0.766415,1.028553 -2.287372,3.158384 -1.520946,2.129839 -1.132196,4.321863 -4.654407,4.101537 -3.522211,-0.220332 -12.4878417,1.175075 -12.4878417,1.175075 0,0 1.5318827,5.247192 0.3202053,7.050484 -3.5114976,5.22603 -6.5447412,2.150817 -7.6970877,4.270207 -0.3309185,0.608633 -1.2285756,2.66077 -1.26854319,4.542899 -0.0340317,1.605194 -0.0218517,1.805146 0.96060409,2.350156 4.2059719,2.333324 16.0100522,6.756708 16.0100522,6.756708 0,0 1.031044,14.587028 1.646974,20.049459 0.108523,0.962486 2.641652,1.730281 3.156047,0.514452 1.956463,-4.624387 0.960593,-18.759119 0.960593,-18.759119 l 12.88771,5.854327 -0.399858,1.153984 0,16.157359 -2.561617,0.587539 -0.320195,2.350155 7.364616,3.819013 c 0,0 2.538629,0.839503 3.499232,-0.115309 0.960604,-0.954753 0.343185,-3.703762 0.343185,-3.703762 0,0 -0.204904,3.05578 -0.582175,-1.584097 -1.06363,-1.963618 -1.083548,-10.80307 -0.9269,-16.975421 2.730521,-2.394079 5.671685,-1.416843 5.671685,-1.416843 l 1.875249,3.022044 c 0,0 1.246803,20.668267 1.372737,24.822866 1.360855,2.19131 4.757041,0.944565 4.757041,0.944565 l 1.601012,-25.558 c 0,0 1.601004,-2.937705 3.842417,-3.819013 2.241402,-0.881308 3.842406,-1.175078 3.842406,-1.175078 l -0.320205,-0.58755 11.207043,-1.468846 c 0,0 -0.320205,-1.762616 0.960604,-3.231475 1.280799,-1.468846 2.206933,-1.309997 2.469679,-0.81805 2.033236,3.806891 2.013136,17.269191 2.013136,17.269191 l 2.515637,1.101979 2.287374,-1.101979 0.960604,-21.445231 1.280813,-2.056385 7.044415,-1.762623 1.703658,-4.039692 0.21755,-12.117664 -39.384731,-2.643924 13.597058,-3.483077 c 0,0 17.782654,-6.211337 20.344258,-9.442808 2.561603,-3.231472 5.443415,-5.875402 2.561603,-7.050483 C 91.824044,14.663105 81.93937,12.20242 77.414997,10.550325 82.552027,7.5282856 88.17621,2.0309938 87.856013,1.7372198 z"
- id="path3105"
- sodipodi:nodetypes="ccccssscsssscsscccccccsccccccccscccssccccccccccsscc" />
- <path
- inkscape:connector-curvature="0"
- style="fill:url(#linearGradient4440);fill-opacity:1;fill-rule:evenodd;stroke:none"
- d="m 20.614234,37.803196 31.267717,10.102376 26.454528,-1.60129 c 0,0 1.544319,-0.157422 1.715911,-1.259418 0.171593,-1.101996 1.372727,-2.518842 3.431834,-3.148551 2.059099,-0.629708 13.555727,-2.518834 13.727321,-3.14855 0.171582,-0.629709 -0.51477,-1.731697 -0.51477,-1.731697 0,0 -11.325045,-3.620837 -24.366002,-3.463409 -13.040954,0.157429 -27.007368,1.416846 -51.716539,4.250539 z"
- id="path2229"
- sodipodi:nodetypes="cccssscsc" />
- <path
- inkscape:connector-curvature="0"
- style="fill:url(#linearGradient4437);fill-opacity:1;fill-rule:evenodd;stroke:none"
- d="m 47.768451,40.212033 29.09446,0.146883 c 0,0 4.234409,1.321964 4.234409,2.497046 0,1.175082 -1.229351,-0.587541 -3.688033,-0.44065 -2.458692,0.146883 -26.499188,1.175075 -27.59193,1.175075 -1.092752,0 -3.141657,-0.734425 -3.141657,-0.734425 l 1.092751,-2.643929 z"
- id="path4131"
- sodipodi:nodetypes="ccssscc" />
- <path
- inkscape:connector-curvature="0"
- style="fill:url(#linearGradient4434);fill-opacity:1;fill-rule:evenodd;stroke:none"
- d="m 47.956498,36.989692 34.101415,0.146876 c 0,0 4.963122,1.321966 4.963122,2.497053 0,1.175075 -1.440896,-0.587539 -4.322712,-0.440656 -2.881812,0.146883 -31.059501,1.175074 -32.340309,1.175074 -1.28081,0 -3.682314,-0.734418 -3.682314,-0.734418 l 1.280798,-2.643929 z"
- id="path3248"
- sodipodi:nodetypes="ccssscc" />
- <path
- inkscape:connector-curvature="0"
- style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none"
- d="m 19.136315,49.925119 c 0,0 -14.651887,0.0063 -15.2716425,0.629708 -0.2891292,0.290742 0.5147663,1.652986 0.5147663,1.652986 L 35.265918,64.014874 c 0,0 -0.257388,-0.59034 0,-1.338129 0.257379,-0.747778 1.029543,-1.259417 1.029543,-1.259417 0,0 4.976153,-0.511639 7.035249,-1.101991 2.059105,-0.590351 1.201145,-1.259428 1.201145,-1.259428 l -25.39554,-9.13079 z"
- id="path4855"
- sodipodi:nodetypes="csccsczcc" />
- <path
- inkscape:connector-curvature="0"
- style="fill:url(#linearGradient4430);fill-opacity:1;fill-rule:evenodd;stroke:none"
- d="m 84.379674,3.6272223 -17.840067,0 -31.570612,26.1726717 16.891638,2.992495 c 0,0 17.642585,-1.208238 24.903703,-4.249989 7.217353,-3.02342 7.06711,-5.456239 8.172853,-13.151055 C 85.44465,11.859835 71.835875,10.020766 72.114631,8.4863163 72.393377,6.9518667 83.543424,4.394454 84.379674,3.6272223 z"
- id="path7780"
- sodipodi:nodetypes="ccccsssc" />
- <path
- inkscape:connector-curvature="0"
- style="fill:url(#linearGradient4427);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.18689911px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="m 72.64129,46.854735 -9.056652,-36.559913 11.320813,36.559913 -2.264161,0 z"
- id="path6895" />
- <path
- inkscape:connector-curvature="0"
- style="fill:url(#linearGradient4424);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.18689911px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="M 65.814591,4.2009841 36.839873,29.698955 31.12378,29.518122 c 0,0 6.307422,-1.989207 6.307422,-2.712549 0,-0.723349 27.397852,-24.5937956 27.397852,-24.5937956 l 0.985537,1.9892067 z"
- id="path9558" />
- <path
- inkscape:connector-curvature="0"
- style="fill:url(#linearGradient4421);fill-opacity:1;fill-rule:evenodd;stroke:none"
- d="M 45.121763,46.068351 19.450498,38.00503 c 0,0 6.24393,-3.523273 6.522687,-5.569207 0.278747,-2.045935 0.836251,-5.626319 2.50876,-4.859087 1.67251,0.767224 -0.632826,1.221598 2.154681,0.965859 2.787517,-0.255746 8.995366,-0.71012 10.946623,1.591553 1.951257,2.301675 3.769268,2.150526 6.411273,2.045936 2.508761,-0.09932 -0.209062,4.406992 -0.957582,8.018203 -0.381602,3.428002 -1.915177,5.870064 -1.915177,5.870064 z"
- id="path8663"
- sodipodi:nodetypes="ccssssscc" />
- <path
- inkscape:connector-curvature="0"
- style="fill:url(#linearGradient4418);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.18689911px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="M 87.496352,1.3075942 64.631944,2.0309428 65.223272,3.8393092 88.087666,2.935126 87.496352,1.3075942 z"
- id="path10441" />
- <path
- inkscape:connector-curvature="0"
- style="fill:url(#linearGradient4415);fill-opacity:1;fill-rule:evenodd;stroke:none"
- d="M 46.553279,43.792417 68.340298,43.9393 c 0,0 3.17088,1.321965 3.17088,2.497047 0,1.175081 -0.920585,-0.587541 -2.761737,-0.440651 -1.841152,0.146877 -19.843566,1.175075 -20.661862,1.175075 -0.818295,0 -2.352585,-0.734424 -2.352585,-0.734424 l 0.818285,-2.64393 z"
- id="path4135"
- sodipodi:nodetypes="ccssscc" />
- <g
- id="g4264"
- transform="matrix(0.07575083,0,0.12059042,0.03963088,-58.659885,34.668975)">
- <g
- id="g4248">
- <rect
- style="fill:#000001;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="rect4240"
- width="95.714287"
- height="17.142857"
- x="288.57141"
- y="385.21933"
- rx="35.606754"
- ry="38.906239" />
- <rect
- style="fill:#000001;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="rect4242"
- width="95.714287"
- height="17.142857"
- x="288.57141"
- y="413.21933"
- rx="35.606754"
- ry="38.906239" />
- <rect
- style="fill:#000001;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="rect4244"
- width="95.714287"
- height="17.142857"
- x="288.57141"
- y="443.21933"
- rx="35.606754"
- ry="38.906239" />
- <rect
- style="fill:#000001;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="rect4246"
- width="95.714287"
- height="17.142857"
- x="288.57141"
- y="473.21933"
- rx="35.606754"
- ry="38.906239" />
- </g>
- <g
- transform="translate(0,116)"
- id="g4254">
- <rect
- style="fill:#000001;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="rect4256"
- width="95.714287"
- height="17.142857"
- x="288.57141"
- y="385.21933"
- rx="35.606754"
- ry="38.906239" />
- <rect
- style="fill:#000001;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="rect4258"
- width="95.714287"
- height="17.142857"
- x="288.57141"
- y="413.21933"
- rx="35.606754"
- ry="38.906239" />
- <rect
- style="fill:#000001;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="rect4260"
- width="95.714287"
- height="17.142857"
- x="288.57141"
- y="443.21933"
- rx="35.606754"
- ry="38.906239" />
- <rect
- style="fill:#000001;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="rect4262"
- width="95.714287"
- height="17.142857"
- x="288.57141"
- y="473.21933"
- rx="35.606754"
- ry="38.906239" />
- </g>
- </g>
- <path
- inkscape:connector-curvature="0"
- style="fill:#000000"
- d="m 52.26754,100.23783 c -3.440493,-2.94575 -1.152889,-9.078126 -2.20229,-13.276833 -0.411832,-3.458386 -0.07774,-10.26683 -0.942821,-11.716517 -1.884644,4.45102 -3.918384,9.015587 -5.614669,13.429652 1.100335,1.315959 2.667463,7.1339 -2.605442,6.185503 -2.378425,0.645019 -0.90386,-3.8855 -0.327001,-0.695241 4.917635,0.762203 3.485163,-4.123213 1.092147,-5.526475 -0.001,-3.380576 -0.05126,-8.713876 0.974772,-10.822184 -0.810883,-0.923461 -2.234766,-10.481123 2.995512,-7.710626 3.747305,-0.317352 4.555137,2.429226 3.868558,3.264145 1.493929,1.204031 0.486349,6.812276 1.08093,9.527689 0.331916,5.332049 0.486611,10.674645 0.914695,16.000663 6.684612,3.407654 4.058185,-6.230735 4.874758,-9.644178 0.43326,-5.409408 0.311172,-10.991419 0.982284,-16.329951 2.459266,-3.569526 7.160419,-5.035235 11.182664,-5.914367 9.242504,-0.130069 5.782616,-4.317141 10.895247,-5.78314 3.188925,5.701417 2.509495,15.399348 2.640908,18.715034 5.64643,2.24662 3.456975,-5.390583 4.212262,-8.404222 0.529458,-4.67895 -0.09119,-9.56183 1.298966,-14.100998 1.131676,-3.182258 7.479611,-1.037623 7.318508,-4.316595 0.03082,-4.586459 0.06175,-9.172919 0.09257,-13.759386 5.04166,-2.204772 -4.546326,-3.257936 -6.73186,-3.911405 -5.558779,-0.977367 -11.21856,-1.467929 -16.878384,-1.464633 -0.951117,1.33546 0.32094,-1.623712 2.6987,-0.428049 7.921336,0.29933 16.269712,0.644918 23.477845,3.920321 0.433697,3.603112 0.07164,7.604228 0.234024,11.333718 0.659154,2.300816 -1.470772,1.351817 -2.349506,6.253414 -2.623056,1.305404 -8.047904,1.033941 -7.683716,4.923425 -0.433113,6.898965 -0.697725,13.81209 -1.36839,20.69428 -8.554,2.7071 -4.608859,-5.991123 -5.473114,-9.772521 -0.764855,-2.42624 0.02437,-7.118503 -2.75197,-8.136398 -0.815748,3.777683 -3.477631,5.269857 -8.030846,4.85315 -4.606122,0.733747 -11.623234,2.387491 -12.228248,7.52376 -0.729387,8.240661 -0.508634,16.581464 -1.538619,24.776187 -1.226694,0.366108 -2.864241,0.683428 -4.108495,0.312778 z M 42.984223,86.068389 c 2.203438,-4.482543 3.952249,-9.187576 5.868612,-13.789456 -3.45743,-3.087965 -4.258617,4.965274 -5.999814,6.93717 -0.160888,0.861117 -0.929498,10.365768 0.131202,6.852286 z m 1.018536,-0.238974 c 1.466741,-4.342993 -2.227264,5.159376 0,0 l 0,0 z m -1.006674,-9.651148 c 0.99602,-1.69937 3.798229,-6.945227 -0.151804,-5.097323 -0.01208,0.878159 -0.438004,6.734455 0.151804,5.097323 z M 97.419731,45.317296 c 0.11097,-2.057428 -0.460108,6.991685 -0.114828,5.994092 0.0913,-1.996769 0.103945,-3.995838 0.114828,-5.994092 z M 36.852601,90.82237 c 2.234375,-0.501405 -4.498644,-0.682587 -1.244294,-0.781559 1.420943,-0.634148 4.644619,0.884665 1.244294,0.781559 z m -3.804954,-1.086119 c -0.872865,-2.799971 3.6258,-2.551885 2.313423,-5.39482 -0.112543,-4.887453 -0.204925,-9.776157 -0.459725,-14.659547 -3.463553,-0.913017 -8.563748,-4.374193 -11.006992,-3.528925 -0.460803,5.686506 -0.274931,11.500349 -1.131915,17.107227 -6.380751,2.39255 -4.931855,-5.046187 -5.317766,-8.581815 -1.274928,-3.980224 1.533806,-10.41467 -2.381737,-12.93194 C 10.485854,59.645103 5.5024311,58.143482 1.1175163,55.791774 -0.58870847,51.63463 0.27942325,46.221368 6.3743794,47.024905 13.14657,45.746648 5.2860576,35.999702 12.602561,36.937048 c 3.70627,-0.88551 9.169124,0.653435 11.991241,-1.478042 1.629693,-3.436602 2.163975,-9.89783 7.958613,-7.065887 5.51109,-0.06036 8.233947,-5.83476 12.387233,-8.542507 C 51.763146,13.826856 58.480113,7.7016251 65.350698,1.7228665 72.98533,1.5986012 80.620145,1.4737351 88.252691,1.2645482 88.244189,5.1766919 82.157134,7.4260353 79.382294,10.275689 77.084862,9.1750181 77.521527,8.7850464 79.202153,9.4967971 c 2.869486,-2.451136 6.051826,-4.7164755 8.67586,-7.3206784 -4.044795,-0.7483645 -8.801966,0.040914 -13.115011,-0.1039393 -2.647213,0.7101553 -9.767684,-1.47828663 -9.206978,2.1593 -3.204181,4.3670411 -8.248759,7.5573756 -12.164918,11.4629616 -4.92977,4.342479 -9.80178,8.745184 -14.870908,12.950997 -4.35248,1.694806 -11.750721,-2.789489 -11.813316,3.976246 -0.68817,6.620498 -8.838888,4.045373 -13.7572,5.084214 -3.7893065,-0.695789 -3.249889,1.854717 -2.574366,4.483453 0.990976,5.413597 -6.0224521,5.556836 -8.7305069,6.921534 -0.354221,1.827652 -1.35920339,6.372083 1.7222565,7.014469 4.6263113,2.042655 9.5523064,3.592183 13.9820424,5.958082 0.85351,6.713663 0.691001,13.529308 1.352879,20.270906 5.846812,2.638297 3.026206,-6.498317 4.043402,-9.505148 0.349983,-2.356245 0.207502,-9.173939 0.127889,-8.445368 5.047166,1.298941 9.32961,4.392115 14.424376,5.572205 C 36.99183,66.423304 38.161586,63.011053 36.241506,61.554953 26.831297,57.992998 17.321627,54.534749 7.8656804,51.06642 c -7.05721178,-0.617226 2.2122296,2.74505 4.2390016,3.422405 8.046635,3.105804 16.180113,6.042097 24.155554,9.291272 0.980029,4.830911 -5.875098,-0.873991 -8.21863,-1.079566 -3.423666,-1.911625 8.250854,3.158851 7.064039,2.16029 C 26.851568,61.560625 18.473531,58.494496 10.282029,55.079048 18.863137,57.949422 27.137615,61.595391 35.630763,64.6748 33.457202,62.41827 27.378358,61.273258 23.74132,59.477485 17.317025,56.914115 10.660739,54.7756 4.3487454,52.023964 c -1.423651,-4.512503 5.3968257,-0.732333 8.4665836,-0.07344 7.942099,3.147498 16.10318,5.784792 23.984486,8.978351 2.807213,2.271951 0.892722,6.725494 1.003835,9.787248 -4.207433,-0.922245 -0.851174,7.30655 -1.784115,10.280005 -0.617924,2.362889 1.687131,6.355686 -1.913847,7.066579 -0.279795,1.98661 -0.780262,2.956031 -1.058041,1.673541 z M 39.739469,26.774209 C 48.1943,19.459768 56.47904,11.983313 64.835729,4.5752596 64.100522,1.1941246 60.000809,7.8329733 58.0738,8.6444145 50.853375,15.197478 43.383124,21.696476 36.217208,28.199502 c 1.508359,0.637167 2.551718,-0.595862 3.522261,-1.425293 z M 53.926113,12.759507 c 2.287473,-2.071304 4.606032,-4.1133571 6.926967,-6.1529845 -2.962664,2.8159622 -5.992846,5.5730835 -9.170917,8.1851895 0.747977,-0.677397 1.495964,-1.354801 2.24395,-2.032205 z M 38.207989,78.606892 c 0.524363,-2.302492 -0.779334,-7.198929 1.033199,-8.102974 0.340495,4.90872 0.309802,9.846152 0.207561,14.764064 -2.258028,4.260483 -0.973785,-5.22804 -1.24076,-6.66109 z m 0.839039,-5.820708 c -0.170897,0.448798 0.01078,6.807935 0.02588,1.924452 l -0.0061,-1.025373 -0.01944,-0.899079 -1.1e-5,0 z m 0.997923,-11.256639 c 2.959734,-0.82238 3.949541,-0.11033 0.272524,0.206964 l -0.733113,0.06657 0.460589,-0.273533 0,0 z m 3.893521,-2.307481 c -8.238438,-2.892006 -16.579277,-5.598115 -24.764274,-8.611087 4.024712,0.200538 8.775862,2.824213 13.092946,3.954786 4.12809,1.40377 8.247018,2.826908 12.40854,4.147927 2.485065,-1.173156 1.54873,-1.130216 1.988073,-2.473976 1.303546,2.219893 1.509518,-3.482603 -0.282694,-4.277254 -1.42337,-1.420164 -2.218775,-1.495586 -2.101823,-2.269216 -8.94537,-3.151763 -18.263731,-5.437525 -27.115147,-8.758643 9.265343,2.676619 18.582646,5.406559 27.746775,8.401207 2.666254,1.955876 -0.23897,-2.733989 -2.921849,-2.188065 -7.655046,-2.853076 8.908955,2.270037 1.644404,-0.17208 -2.153864,-0.501359 -5.184953,-1.956358 -0.916901,-0.660579 5.027158,-0.482065 6.086639,4.034759 4.838728,5.333055 2.480715,2.68607 0.857578,8.278497 -3.616778,7.573925 z m 3.74361,-6.888828 c -1.463589,-1.230763 0.08509,1.293732 0,0 l 0,0 z m -0.730254,-1.611173 c 0.06949,-1.97372 0.15397,-1.710125 -0.443743,-0.113687 -1.022826,0.386502 0.07925,0.421922 0.443743,0.113687 z m -13.221236,4.03956 c -4.93105,-1.494664 -9.730334,-3.512448 -14.713304,-4.740891 4.678233,-0.02767 9.454728,3.016143 14.169989,4.193246 2.289245,0.660125 5.712055,2.303932 1.135046,0.739562 l -0.591731,-0.191917 0,0 z M 95.95506,54.407079 c -0.347045,-2.98901 1.980897,0.572005 0,0 l 0,0 z M 63.292155,47.016032 c -4.691635,-1.963689 -10.302992,0.230091 -14.666235,-2.55588 0.301172,-1.544959 7.905554,-0.754455 2.403598,-0.55136 -4.09064,0.70962 4.766275,2.132627 6.398334,1.490358 0.98732,-0.881509 11.585503,2.765988 5.864303,1.616882 z m 5.996865,0.197256 c -4.584129,-1.796023 4.679542,0.823067 1.609774,-2.878231 -5.278887,-2.610739 3.581856,-0.672574 1.162195,2.600424 -0.611862,0.726967 -1.967137,0.235945 -2.771969,0.277807 z m 3.505616,-0.563913 C 70.255726,38.812708 68.359925,30.770248 66.88826,22.74182 c 2.240406,5.41541 2.714278,11.290192 4.529459,16.825672 -0.960322,-1.894075 -0.298292,-6.659996 0.143085,-2.069221 -0.238246,2.198024 3.922371,9.122674 1.233832,9.151104 z m -0.05035,-2.844037 c -0.591047,-2.48749 -1.836046,-5.463613 -0.551905,-1.180016 0.534263,2.264831 1.764057,5.397428 0.551905,1.180016 l 0,0 z m 1.815836,2.623098 c -1.177702,-2.163405 -3.188502,-8.866244 -2.262368,-9.132815 1.147059,3.46759 1.404336,11.561516 7.189842,7.604192 -3.256394,-0.443027 -3.318365,-0.609914 -0.09083,-0.622446 0.911644,-3.096394 7.979359,-2.101157 7.359859,-4.475478 1.320063,1.654659 8.153571,-0.858272 2.787794,1.00839 -3.457354,1.342102 -8.661055,0.677166 -9.979375,4.75173 -0.753383,0.87652 -3.843281,1.273071 -5.004942,0.866427 z M 44.703377,45.872783 c -2.256347,-0.635502 -7.898386,-2.820959 -2.339807,-1.331731 5.930977,3.105219 3.431018,-5.765389 5.876065,-8.60182 1.358317,-1.48617 0.03454,-5.477066 1.424568,-1.517067 -3.489756,2.697124 -0.699833,10.998285 -4.960826,11.450618 z m 5.90558,-3.110635 c -5.133345,-1.320056 0.70099,-0.947501 2.239368,0.426801 -0.773121,0.0071 -1.506527,-0.240357 -2.239368,-0.426801 z m 20.012208,0.217335 c -1.576291,-2.472116 -0.485392,-7.800367 -3.029901,-8.908057 -2.178565,-0.62743 -4.978539,-0.0207 -7.079667,-0.618975 3.490833,0.304326 9.51964,-3.12677 8.807451,2.500525 0.195559,1.922024 2.696897,6.288954 1.302117,7.026507 z m -23.326284,-1.43216 c -1.303909,-4.092845 4.472897,-4.887168 5.460468,-3.882284 -4.524726,-0.631583 -4.516197,1.676349 -5.460468,3.882284 z M 15.967438,40.709174 c -3.687589,-1.231134 2.489426,0.2605 0,0 l 0,0 z m -3.734153,-1.052865 c -4.6608725,-1.82869 5.911541,1.599192 0,0 l 0,0 z m 74.549219,-0.374611 c -1.037488,-0.896641 -8.743321,-2.151709 -6.000545,-1.951932 1.786251,-0.346348 8.586668,1.899805 6.955506,2.05041 l -0.954961,-0.09848 0,-7e-6 z m -35.685728,-5.02718 c 2.290795,-0.249292 11.147439,-1.438202 4.611973,-0.074 -1.352528,-0.0088 -3.763669,0.341749 -4.611973,0.074 z M 70.3412,32.490146 c -1.192194,-2.097023 -3.038994,-9.520076 -2.283838,-8.523173 1.609432,3.169474 1.101323,10.349968 6.742727,6.921004 7.872394,-2.4005 16.320895,-6.002574 20.531591,-12.913472 -2.661137,-3.856837 -8.754631,-3.434392 -12.912819,-5.191941 -2.607214,0.192174 -7.819879,-5.6461684 -2.990769,-2.019673 4.909269,2.381647 10.602475,2.917723 15.593201,5.085296 2.769194,4.814765 -4.654236,8.258567 -8.049382,10.894601 -5.021786,2.793142 -10.653624,4.879258 -16.3903,5.90025 l -0.240411,-0.152892 0,0 z M 73.097217,9.1840309 c -1.377399,-2.8216559 4.424067,0.27499 0,0 l 0,0 z M 71.487433,2.7449175 c 2.588958,-0.5837772 6.854443,0.3105504 1.874081,0.1518952 l -0.796473,-0.03039 -1.077608,-0.1215134 0,0 z m 8.000153,0.00972 c -4.283661,0.1041246 1.250438,-0.7398055 2.430396,0.00347 -0.685221,0.3501812 -1.672742,-0.1295352 -2.430396,-0.00347 z M 82.512039,2.565911 c 3.007732,-0.6241258 6.077303,0.3868574 1.176978,0.1672777 l -0.683922,-0.0345 -0.493056,-0.1327837 0,0 z"
- id="path1350"
- sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" />
- <path
- inkscape:connector-curvature="0"
- style="fill:url(#linearGradient4400);fill-opacity:1;fill-rule:evenodd;stroke:none"
- d="m 96.621091,38.758343 -1.440077,0.640742 c 0,0 -0.495649,11.81791 0.06281,14.60825 1.286467,-0.883155 2.171047,-3.44689 2.171047,-3.44689 l -0.04708,-12.536435 -0.746679,0.734333 z"
- id="path11324"
- sodipodi:nodetypes="cccccc" />
- <path
- inkscape:connector-curvature="0"
- style="opacity:0.8;fill:url(#linearGradient4397);fill-opacity:1;fill-rule:evenodd;stroke:none"
- d="m 77.700157,46.566844 -1.440075,0.828177 c 0,0 -0.495633,15.274824 0.06284,18.881374 1.286478,-1.141493 2.171043,-4.455164 2.171043,-4.455164 l -0.04713,-16.203525 -0.746678,0.949138 z"
- id="path13957"
- sodipodi:nodetypes="cccccc" />
- <path
- inkscape:connector-curvature="0"
- style="opacity:0.69444442;fill:url(#linearGradient4394);fill-opacity:1;fill-rule:evenodd;stroke:none"
- d="m 14.723103,40.636896 c 0,0 -0.686368,4.250539 -0.171592,5.195105 0.514766,0.944567 6.863657,4.093118 8.751161,4.722826 1.887513,0.629709 24.537589,8.973371 24.537589,8.973371 0,0 1.715912,-2.833706 1.715912,-4.093123 0,-1.259417 0.171592,-3.935688 -1.201146,-4.407968 C 46.9823,50.554827 15.237869,40.951747 14.723103,40.636896 z"
- id="path13961" />
- <path
- inkscape:connector-curvature="0"
- style="fill:url(#linearGradient4391);fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.18689911px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="m 83.968367,42.187502 c 0,0 -2.3908,-0.168727 -2.574709,1.012362 -0.183897,1.181082 -1.287343,2.193446 -1.287343,2.193446 l -0.183908,16.029031 c 0,0 0.735621,-4.049443 2.206883,-4.386893 1.471261,-0.337457 1.839077,-0.168725 1.839077,-0.843637 0,-0.674909 0,-14.173036 0,-14.004309 z"
- id="path17471" />
- <path
- inkscape:connector-curvature="0"
- style="opacity:0.6;fill:url(#linearGradient4388);fill-opacity:1;fill-rule:evenodd;stroke:none"
- d="m 49.393805,71.039753 c 0,0 3.678144,1.518535 3.678144,2.193447 0,0.674911 0.183907,27.16499 0.183907,27.16499 l -2.942513,-1.349816 c 0,0 0,-20.584645 -0.551723,-23.284278 -0.551724,-2.699621 -0.551724,-4.724343 -0.367815,-4.724343 z"
- id="path18354" />
- <path
- inkscape:connector-curvature="0"
- style="opacity:0.6;fill:url(#linearGradient4385);fill-opacity:1;fill-rule:evenodd;stroke:none"
- d="m 16.188846,62.084321 c 0,0 3.678145,1.126997 3.678145,1.627893 0,0.500884 0.183908,20.160911 0.183908,20.160911 L 18.141151,81.73012 c 0,0 -1.271433,-13.005501 -0.680821,-14.998351 0.481053,-1.62317 -1.455391,-4.647448 -1.271484,-4.647448 z"
- id="path20110"
- sodipodi:nodetypes="csccsc" />
- <path
- inkscape:connector-curvature="0"
- style="opacity:0.4;fill:url(#linearGradient4382);fill-opacity:1;fill-rule:evenodd;stroke:none"
- d="m 83.542619,57.109923 c -0.362992,0.135186 -0.09688,0.259119 -0.09688,0.934019 0,0.674911 0.3555,23.071873 0.3555,23.071873 l -2.599329,-1.349811 c 0,0 0.630611,-12.840133 -2.267635,-16.987172 1.164188,-2.857047 1.889789,-6.936799 4.608336,-5.668909 z"
- id="path20114"
- sodipodi:nodetypes="cscccc" />
- <path
- inkscape:connector-curvature="0"
- style="opacity:0.39444436;fill:url(#linearGradient4379);fill-opacity:1;fill-rule:evenodd;stroke:none"
- d="m 1.6984425,51.49876 c 0,0 -0.558813,1.463099 -0.04381,1.949242 0.5150182,0.486149 6.6696287,3.224529 8.4922712,3.921249 1.822633,0.696734 23.712567,9.359068 23.712567,9.359068 0,0 1.577893,-0.671774 1.54866,-1.154354 -0.02921,-0.482581 0.07301,-1.466659 -1.252865,-1.978865 C 32.829379,63.082917 2.1988288,51.743619 1.6984319,51.49876 z"
- id="path20118"
- sodipodi:nodetypes="csscssc" />
- <path
- inkscape:connector-curvature="0"
- style="fill:url(#linearGradient4376);fill-opacity:1;fill-rule:evenodd;stroke:none"
- d="m 48.586385,48.526679 0,2.643082 c 0,0 0.728007,0.890534 0.606664,1.892401 -0.121333,1.001859 -0.939537,5.516249 -1.788878,6.072831 -0.849331,0.556593 -8.570012,1.080341 -10.147351,2.193527 -1.577339,1.113175 -1.334672,2.448989 -1.334672,2.448989 l 0,3.896139 1.456005,0.890535 0,-5.45457 c 0,0 1.456006,-1.558453 1.820005,-1.669779 0.363999,-0.111372 4.765449,-0.23887 5.945337,-0.445267 2.773036,-0.485081 5.573945,-2.912629 5.50556,-4.370226 -0.06787,-1.445799 1.092008,-3.673502 0.36401,-4.786677 -0.728009,-1.113183 -0.485342,-2.782952 -0.485342,-2.782952 l -1.941338,-0.528033 z"
- id="path20999"
- sodipodi:nodetypes="ccsssccccsssscc" />
- <path
- inkscape:connector-curvature="0"
- style="opacity:0.24444442;fill:url(#linearGradient4373);fill-opacity:1;fill-rule:evenodd;stroke:none"
- d="m 35.245648,69.684478 c 0.389475,-2.501306 5.827125,1.604519 5.822503,2.135098 -0.02306,2.651565 0.35567,20.423121 0.35567,20.160911 l -5.690778,-1.001791 c 0.436262,1.448679 -0.371662,-9.605788 -0.421538,-17.027171 -0.0145,-2.166507 -0.421529,-4.267047 -0.06585,-4.267047 z"
- id="path1470"
- sodipodi:nodetypes="csccsc" />
- </g>
-</svg>
diff --git a/tools/menus/resource/play_rhythm.svg b/tools/menus/resource/play_rhythm.svg
deleted file mode 100644
index 474f32c7a..000000000
--- a/tools/menus/resource/play_rhythm.svg
+++ /dev/null
@@ -1,480 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="100"
- height="100"
- id="svg2"
- sodipodi:version="0.32"
- inkscape:version="0.91 r13725"
- version="1.0"
- sodipodi:docname="play_rhythm.svg">
- <defs
- id="defs4">
- <radialGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3679"
- id="radialGradient4211"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.99781284,-0.0661024,0.01706392,0.25757912,-10.718047,106.13878)"
- cx="350.58179"
- cy="103.92841"
- fx="350.58179"
- fy="103.92841"
- r="28.320353" />
- <linearGradient
- id="linearGradient3679">
- <stop
- style="stop-color:#939393;stop-opacity:1;"
- offset="0"
- id="stop3681" />
- <stop
- style="stop-color:#606263;stop-opacity:1;"
- offset="1"
- id="stop3683" />
- </linearGradient>
- </defs>
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="1.5550218"
- inkscape:cx="162.73691"
- inkscape:cy="-1.4427698"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- width="100px"
- height="100px"
- showguides="true"
- inkscape:guide-bbox="true"
- inkscape:window-width="838"
- inkscape:window-height="990"
- inkscape:window-x="840"
- inkscape:window-y="27"
- showgrid="false"
- inkscape:window-maximized="0" />
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Calque 1"
- inkscape:groupmode="layer"
- id="layer1">
- <g
- transform="matrix(0.3112043,0,0,0.29684183,-52.312184,-27.133886)"
- id="g4137">
- <path
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="csssssccc"
- id="path3677"
- d="m 326.20035,117.84742 c -6.14659,-0.98854 -13.17893,-2.28154 -13.33199,-2.41558 -0.15304,-0.13404 4.84507,-2.67896 7.9838,-4.14171 13.12231,-6.11544 20.3328,-7.7084 26.59969,-6.07026 1.89151,0.49444 6.07991,2.21129 8.48672,3.25977 4.24759,1.85038 14.2056,7.38653 13.71041,7.52361 -0.13501,0.0374 -8.37273,1.22527 -16.6,2.09114 l -15.03902,1.43707 -11.80961,-1.68404 z"
- style="color:#000000;fill:url(#radialGradient4211);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <path
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cscc"
- id="path4129"
- d="m 212.24322,344.16255 c 0,0 0.1908,13.82097 5.37695,15.08185 3.78125,0.91931 8.53125,-7.96899 8.53125,-7.96899 l -13.9082,-7.11286 z"
- style="fill:#261410;fill-opacity:1;stroke:none" />
- <path
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cscc"
- id="path4127"
- d="m 268.42828,403.67264 c 0,0 1.58872,16.72674 7.95349,17.52231 8.5746,1.07179 18.19022,-16.18135 18.19022,-16.18135 l -26.14371,-1.34096 z"
- style="fill:#261410;fill-opacity:1;stroke:none" />
- <path
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cscc"
- id="path4131"
- d="m 440.8968,379.25922 c 0,0 5.08198,15.42293 10.86899,14.10407 7.01153,-1.59792 4.46415,-21.10697 4.46415,-21.10697 l -15.33314,7.0029 z"
- style="fill:#261410;fill-opacity:1;stroke:none" />
- <path
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cccccccccc"
- id="path3935"
- d="m 273.33633,410.2442 -2.61029,-3.10955 9.46305,-42.23561 c 5.01761,-22.88094 9.80759,-45.08826 10.81192,-49.6409 l 2.23215,-9.06862 2.46347,2.15735 1.91574,1.96438 -10.49521,50.06343 -11.01071,52.29725 -2.77012,-2.42773 z"
- style="color:#000000;fill:#765110;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.69999999;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <path
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cccccsscc"
- id="path3713"
- d="m 294.03593,305.98817 2.00831,-0.45385 c 0.80586,-0.0646 30.16981,-5.09447 65.10839,-11.0815 l 63.96811,-11.1269 1.86452,1.90674 c 1.3328,1.13726 2.74621,2.14085 2.23311,2.34548 -0.80262,0.32008 -129.22432,22.25726 -130.78587,22.33929 -0.56284,0.0293 -1.20404,-1.02208 -2.19629,-1.91878 l -2.20028,-2.01048 z"
- style="color:#000000;fill:#241c10;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <path
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cccccsssccc"
- id="path3700"
- d="m 238.39958,373.704 -28.84384,-30.57253 102.62894,-227.44769 13.20462,2.2062 12.48836,2.05234 -8.79329,34.62983 c -9.19896,36.22742 -21.1314,84.34951 -26.23041,106.28435 -3.93198,16.9145 -7.36563,31.24231 -20.89884,94.12849 l -11.12678,51.70399 -30.06043,-30.42972 -2.36833,-2.55526 z"
- style="color:#000000;fill:#775010;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <path
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cscccsscccccccccscsc"
- id="path3689"
- d="m 293.44117,305.20555 c -0.0336,-0.50667 4.81915,-23.70167 8.65955,-40.32716 5.24055,-22.68689 19.64446,-80.30813 28.65737,-115.55915 l 7.45407,-29.3362 15.88921,-1.77963 c 8.45659,-0.88795 15.636,-1.73834 15.81582,-1.56002 0.62799,0.62276 55.56792,165.75892 54.8975,165.89351 l -23.60056,4.73782 -26.00417,4.12528 -4.29378,-55.84825 c -1.60902,-21.5342 -3.39567,-54.16633 -4.60866,-72.47356 l -2.71042,-32.99015 -3.80836,0.81643 c -2.24774,0.31492 -5.69652,0.82226 -8.46184,1.18028 l -5.02787,0.65094 0.37196,10.51448 c 0.22359,6.0702 1.99384,42.52909 3.68493,81.03428 l 3.10156,70.6208 -56.9575,9.98483 c -0.74325,0.13032 -3.04818,0.47597 -3.05881,0.31547 z"
- style="color:#000000;fill:#282828;fill-opacity:1;fill-rule:nonzero;stroke:#2b292b;stroke-width:0.5;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <path
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccc"
- id="path3687"
- d="m 346.53024,132.87661 7.26362,162.47291 20.74433,-3.83875 -11.14928,-160.75094 -16.85867,2.11678 z"
- style="fill:#f4f4f6;fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cc"
- id="path2822-1"
- d="M 293.25384,305.68715 424.93276,283.21583"
- style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccccccc"
- id="path2816"
- d="m 276.52291,412.41801 21.44655,-102.38894 -4.9412,-4.52277 c 15.4295,-73.19872 45.21265,-185.88314 45.21265,-185.88314 l 32.21077,-3.33127 54.62022,166.83348 5.23275,4.81711 29.20738,88.76824 -182.98912,35.70729 z"
- style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <g
- transform="matrix(0.99781284,-0.0661024,0.0661024,0.99781284,-17.176504,23.742626)"
- id="g3702">
- <path
- inkscape:connector-curvature="0"
- style="fill:#e5e9e9;fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="m 367.23799,300.02067 99.08361,-134.07496 -5.48975,-4.35955 -104.1871,138.95902 7.66119,4.78931 2.93205,-5.31382 z"
- id="path2848"
- sodipodi:nodetypes="cccccc" />
- <g
- id="g3691"
- transform="matrix(0.9933217,0.11537768,-0.11537768,0.9933217,27.810058,-48.201552)">
- <path
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cccccc"
- id="path2873"
- d="m 422.35664,212.24181 c 4.04742,-2.80842 2.46902,-24.60104 -0.835,-26.66605 l -2.13125,-0.1259 -7.17643,20.7638 10.14268,6.0282 0,-5e-5 z"
- style="fill:#989695;fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- inkscape:connector-curvature="0"
- id="path2871"
- d="m 415.06327,205.27393 6.98424,-19.45609 33.42456,23.94595 -17.46059,9.97749 -22.94821,-14.46735 z"
- style="fill:#d0cfd2;fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccc"
- id="path2875"
- d="m 437.70561,219.64886 -7.36862,-4.64812 -1.09098,1.54692 6.05029,3.90595 2.40931,-0.80475 z"
- style="fill:#606263;fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- inkscape:connector-curvature="0"
- id="path3649"
- d="m 434.02048,193.79982 -7.48311,11.97298"
- style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- inkscape:connector-curvature="0"
- id="path3651"
- d="m 442.00247,200.28519 -6.48536,9.97748"
- style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- d="m 426.03849,198.04025 a 1.4966223,1.7460594 0 0 1 -1.49662,1.74606 1.4966223,1.7460594 0 0 1 -1.49662,-1.74606 1.4966223,1.7460594 0 0 1 1.49662,-1.74606 1.4966223,1.7460594 0 0 1 1.49662,1.74606 z"
- sodipodi:ry="1.7460594"
- sodipodi:rx="1.4966223"
- sodipodi:cy="198.04025"
- sodipodi:cx="424.54187"
- id="path3653"
- style="color:#000000;fill:#606263;fill-opacity:1;fill-rule:nonzero;stroke:#2b292b;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- sodipodi:type="arc" />
- <path
- d="m 426.03849,198.04025 a 1.4966223,1.7460594 0 0 1 -1.49662,1.74606 1.4966223,1.7460594 0 0 1 -1.49662,-1.74606 1.4966223,1.7460594 0 0 1 1.49662,-1.74606 1.4966223,1.7460594 0 0 1 1.49662,1.74606 z"
- sodipodi:ry="1.7460594"
- sodipodi:rx="1.4966223"
- sodipodi:cy="198.04025"
- sodipodi:cx="424.54187"
- id="path3653-9"
- style="color:#000000;fill:#606263;fill-opacity:1;fill-rule:nonzero;stroke:#2b292b;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- sodipodi:type="arc"
- transform="translate(18.957223,11.723542)" />
- </g>
- </g>
- <path
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cccccc"
- id="path3715"
- d="m 297.95739,310.55379 132.10315,-22.65552 14.74084,44.5313 14.32793,44.05808 -182.36254,35.69312 21.19062,-101.62698 z"
- style="color:#000000;fill:#8b6621;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
- <path
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cccc"
- id="path2818"
- d="m 276.20299,412.7146 -66.83003,-69.22794 102.7198,-227.90328 26.05062,4.15557"
- style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="csc"
- id="path2820"
- d="m 312.12481,115.45911 c 0,0 19.84537,-10.91827 30.0285,-11.07108 9.62071,-0.14438 28.45664,11.79364 28.45664,11.79364"
- style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cc"
- id="path2822"
- d="M 297.79078,310.15615 429.79211,287.85034"
- style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cc"
- id="path2824"
- d="M 270.72152,407.38128 293.06006,305.39025"
- style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- inkscape:connector-curvature="0"
- id="path3717"
- d="m 371.53491,285.44537 3.75478,2.81008"
- style="fill:none;stroke:#505050;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- inkscape:connector-curvature="0"
- id="path3717-8"
- d="m 379.74018,272.7313 3.75479,2.81007"
- style="fill:none;stroke:#505050;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- inkscape:connector-curvature="0"
- id="path3717-2"
- d="m 387.67167,260.47455 3.75478,2.81008"
- style="fill:none;stroke:#505050;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- inkscape:connector-curvature="0"
- id="path3717-8-9"
- d="m 393.50121,251.24223 3.75478,2.81008"
- style="fill:none;stroke:#505050;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- inkscape:connector-curvature="0"
- id="path3717-6"
- d="m 399.21249,242.09591 3.75478,2.81007"
- style="fill:none;stroke:#505050;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- inkscape:connector-curvature="0"
- id="path3717-8-0"
- d="m 404.24557,234.49985 3.75478,2.81008"
- style="fill:none;stroke:#505050;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- inkscape:connector-curvature="0"
- id="path3717-3"
- d="m 409.23238,226.98218 3.75478,2.81008"
- style="fill:none;stroke:#505050;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- inkscape:connector-curvature="0"
- id="path3717-5"
- d="m 433.85106,188.36806 3.75478,2.81008"
- style="fill:none;stroke:#505050;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- inkscape:connector-curvature="0"
- id="path3717-8-4"
- d="m 435.92843,185.08123 3.75479,2.81007"
- style="fill:none;stroke:#505050;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- inkscape:connector-curvature="0"
- id="path3717-54"
- d="m 437.78692,182.27262 3.75479,2.81008"
- style="fill:none;stroke:#505050;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- inkscape:connector-curvature="0"
- id="path3717-85"
- d="m 417.3102,214.12247 3.75478,2.81008"
- style="fill:none;stroke:#505050;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- inkscape:connector-curvature="0"
- id="path3717-8-2"
- d="m 413.44905,220.15304 3.75478,2.81008"
- style="fill:none;stroke:#505050;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- inkscape:connector-curvature="0"
- id="path3717-85-2"
- d="m 420.92779,208.50521 3.75478,2.81007"
- style="fill:none;stroke:#505050;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- inkscape:connector-curvature="0"
- id="path3717-85-7"
- d="m 439.42929,179.66649 3.75479,2.81007"
- style="fill:none;stroke:#505050;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- inkscape:connector-curvature="0"
- id="path3717-85-3"
- d="m 440.7023,177.633 3.75478,2.81008"
- style="fill:none;stroke:#505050;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- inkscape:connector-curvature="0"
- id="path3717-85-6"
- d="m 441.73435,176.04861 3.75479,2.81008"
- style="fill:none;stroke:#505050;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- inkscape:connector-curvature="0"
- id="path3717-85-63"
- d="m 442.81673,174.40676 3.75479,2.81007"
- style="fill:none;stroke:#505050;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- inkscape:connector-curvature="0"
- id="path3717-85-4"
- d="m 443.64743,173.05228 3.75479,2.81008"
- style="fill:none;stroke:#505050;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- inkscape:connector-curvature="0"
- id="path3717-85-72"
- d="m 444.38105,171.86668 3.75478,2.81008"
- style="fill:none;stroke:#505050;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- inkscape:connector-curvature="0"
- id="path3717-85-8"
- d="m 445.07145,170.84637 3.75479,2.81007"
- style="fill:none;stroke:#505050;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- inkscape:connector-curvature="0"
- id="path3717-85-0"
- d="m 445.75829,169.77214 3.75479,2.81008"
- style="fill:none;stroke:#505050;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- inkscape:connector-curvature="0"
- id="path3717-85-76"
- d="m 449.3867,164.0633 3.75479,2.81008"
- style="fill:none;stroke:#505050;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- inkscape:connector-curvature="0"
- id="path3717-85-1"
- d="m 451.74567,160.44186 3.75478,2.81007"
- style="fill:none;stroke:#505050;stroke-width:0.69999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cc"
- id="path3933"
- d="M 364.91544,289.64841 355.12446,134.30713"
- style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
- <path
- inkscape:connector-curvature="0"
- id="path3941"
- d="m 364.27025,282.36855 -6.90443,0.90058"
- style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- inkscape:connector-curvature="0"
- id="path3941-9"
- d="m 370.58758,268.7098 -6.90443,0.90058"
- style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- inkscape:connector-curvature="0"
- id="path3941-0"
- d="m 362.86525,257.54854 -6.90443,0.90058"
- style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- inkscape:connector-curvature="0"
- id="path3941-91"
- d="m 369.22244,244.00543 -6.90443,0.90058"
- style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- inkscape:connector-curvature="0"
- id="path3941-90"
- d="m 361.24717,233.84515 -6.90443,0.90058"
- style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- inkscape:connector-curvature="0"
- id="path3941-98"
- d="m 367.80219,219.97035 -6.90443,0.90058"
- style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- inkscape:connector-curvature="0"
- id="path3941-3"
- d="m 360.04541,209.91932 -6.90443,0.90058"
- style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- inkscape:connector-curvature="0"
- id="path3941-06"
- d="m 366.70968,200.30528 -6.90443,0.90058"
- style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- inkscape:connector-curvature="0"
- id="path3941-2"
- d="m 359.17141,193.64102 -6.90443,0.90058"
- style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- inkscape:connector-curvature="0"
- id="path3941-7"
- d="m 365.61718,185.01024 -6.90443,0.90058"
- style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- inkscape:connector-curvature="0"
- id="path3941-6"
- d="m 358.18816,179.54772 -6.90443,0.90058"
- style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- inkscape:connector-curvature="0"
- id="path3941-71"
- d="m 364.74318,172.5557 -6.90443,0.90058"
- style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- inkscape:connector-curvature="0"
- id="path3941-8"
- d="m 357.31415,167.74868 -6.90443,0.90058"
- style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- inkscape:connector-curvature="0"
- id="path3941-5"
- d="m 363.86917,161.84915 -6.90443,0.90058"
- style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- inkscape:connector-curvature="0"
- id="path3941-68"
- d="m 356.7679,158.24389 -6.90443,0.90058"
- style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- inkscape:connector-curvature="0"
- id="path3941-83"
- d="m 363.65067,153.21837 -6.90443,0.90058"
- style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- inkscape:connector-curvature="0"
- id="path3941-52"
- d="m 356.00315,150.70561 -6.90443,0.90058"
- style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- inkscape:connector-curvature="0"
- id="path3941-05"
- d="m 363.21367,146.66335 -6.90443,0.90058"
- style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- inkscape:connector-curvature="0"
- id="path3941-27"
- d="m 355.6754,144.36909 -6.90443,0.90058"
- style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- inkscape:connector-curvature="0"
- id="path3941-34"
- d="m 362.99517,140.76383 -6.90443,0.90058"
- style="fill:none;stroke:#000000;stroke-width:0.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" />
- <path
- inkscape:connector-curvature="0"
- id="path4133"
- d="m 340.41935,132.22296 28.46151,-3.84615 -1.60839,-11.60839 -27.48249,3.00699 0.62937,12.44755 z"
- style="fill:#000000;fill-opacity:1;stroke:none" />
- <path
- transform="matrix(1,0,0,1.1578947,0,-18.933991)"
- d="m 355.9438,121.24394 a 1.5034955,1.3286704 0 0 1 -1.50349,1.32867 1.5034955,1.3286704 0 0 1 -1.5035,-1.32867 1.5034955,1.3286704 0 0 1 1.5035,-1.32867 1.5034955,1.3286704 0 0 1 1.50349,1.32867 z"
- sodipodi:ry="1.3286704"
- sodipodi:rx="1.5034955"
- sodipodi:cy="121.24394"
- sodipodi:cx="354.44031"
- id="path4135"
- style="color:#000000;fill:#d9dbd8;fill-opacity:1;fill-rule:nonzero;stroke:#505050;stroke-width:0.4646602;stroke-opacity:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
- sodipodi:type="arc" />
- </g>
- </g>
-</svg>
diff --git a/tools/move_translations.sh b/tools/move_translations.sh
new file mode 100644
index 000000000..420b6c480
--- /dev/null
+++ b/tools/move_translations.sh
@@ -0,0 +1,27 @@
+#!/bin/bash
+#
+# move_translations.sh
+#
+# Copyright (C) 2018 Johnny Jazeix
+#
+# This is a (temporary) script to move translations retrieved by releaseme
+# fetchpo.rb script. The final aim is to have the po in the good arborescence
+# for all the platforms, like they are retrieved from svn:
+# poFolder/$locale/gcompris_qt.po
+# (where for now, it is: sourceFolder/po/gcompris_$locale.po)
+#
+# $1 is where the folder containing the po retrieved by the script
+# $2 is the destination folder
+if [ "$#" -ne 2 ]; then
+ echo "usage: $0 poFolder destinationFolder"
+ exit 1
+fi
+
+if [ ! -d "$2" ]; then
+ mkdir -p $2
+fi
+
+for filename in $1/*/*.po; do
+ locale=$(basename $(dirname $filename))
+ mv $filename $2/gcompris_$locale.po
+done
diff --git a/tools/validate-json.py b/tools/validate-json.py
index ad7a40263..6c4311871 100755
--- a/tools/validate-json.py
+++ b/tools/validate-json.py
@@ -1,36 +1,36 @@
#!/usr/bin/python
#
# GCompris - validate-json.py
#
# Copyright (C) 2015 Bruno Coudoin <bruno.coudoin@gcompris.net>
#
# This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+# along with this program; if not, see <https://www.gnu.org/licenses/>.
import json
import sys
if len(sys.argv) != 2:
print "Usage: validate-json.py json_file"
sys.exit(1)
inf=sys.argv[1]
with open(inf) as data_file:
try:
data = json.load(data_file)
print "Processing OK " + inf
except ValueError as e:
print dir(e)
print "Processing KO " + inf
print "Parser error: {0}".format(e.message)
diff --git a/tools/wordlist-json-2html.py b/tools/wordlist-json-2html.py
new file mode 100644
index 000000000..48a9010e2
--- /dev/null
+++ b/tools/wordlist-json-2html.py
@@ -0,0 +1,82 @@
+#!/usr/bin/python
+#
+# GCompris - wordlist-json-2html.py
+#
+# Copyright (C) 2018 Johnny Jazeix <jazeix@gmail.com>
+#
+# This program is free software; you can 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 <https://www.gnu.org/licenses/>.
+
+import json
+
+wordsFile="../src/activities/lang/resource/words.json"
+
+with open(wordsFile) as data_file:
+ try:
+ data = json.load(data_file)
+ print("Processing OK " + wordsFile)
+ except ValueError as e:
+ print(dir(e))
+ print("Processing KO " + wordsFile)
+ print("Parser error: {0}".format(e.message))
+
+header="""<html dir=\"ltr\" lang=\"fr\">
+<head>
+ <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">
+</head>
+<body>
+ <a name=\"words_by_section\" href=\"words_by_section.html\"/>Same list of words by section</a>
+ <p></p>
+ <a name=\"empty json\" href=\"words.json\"/>Empty json data file ready to be translated</a>
+ <hr>
+"""
+
+footer= """
+</body>
+</html>"""
+
+orderedData = {}
+
+with open("words_by_section.html", "w") as section_file:
+ section_file.write("""<html dir=\"ltr\" lang=\"fr\">
+
+<head>
+ <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">
+</head>
+<body>
+
+""")
+ for chapter in data:
+ for lesson in chapter["content"]:
+ lessonName = lesson["name"];
+ if lessonName == "otherLesson":
+ lessonName = "other"
+ section_file.write(" <h1>" + lessonName + "</h1>\n")
+ for content in lesson["content"]:
+ # store the info for words.html
+ orderedData[content["description"]] = {
+ "image": content["image"],
+ "section": lessonName
+ };
+ # write in the file
+ section_file.write(""" <a name=\""""+content["description"]+"""\" href=\"lang/""" + content["image"] + """\"><img src=\"lang/"""+content["image"] + """\"/></a>
+ <p>"""+content["description"]+"""</p>
+ <hr/>
+""")
+ section_file.write(footer)
+
+with open("words.html", "w") as words_file:
+ words_file.write(header)
+ for key in sorted(orderedData):
+ words_file.write(" <a name=\""+key+"\" href=\"lang/"+orderedData[key]["image"]+"\"><img src=\"lang/"+orderedData[key]["image"]+"\"/></a><p>"+key+" ("+orderedData[key]["section"]+")</p><hr/>\n")
+ words_file.write(footer)
diff --git a/tools/wordlist-xml2json.pl b/tools/wordlist-xml2json.pl
index 588086d19..faae223b6 100644
--- a/tools/wordlist-xml2json.pl
+++ b/tools/wordlist-xml2json.pl
@@ -1,95 +1,95 @@
#!/usr/bin/perl
#
# wordlist_xml2json.pl
#
# Copyright (C) 2014 Holger Kaelberer <holger.k@elberer.de>
#
#
# This program is free software; you can 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 <http://www.gnu.org/licenses/>.
+# along with this program; if not, see <https://www.gnu.org/licenses/>.
#
# Transforms GCompris' wordlist xml syntax in a corresponding json
# document. Reads from stdin, writes to stdout (UTF8 encoded).
#
# It produces the following json format:
#
# { "name":"default-gd",
# "description":"Gàidhlig",
# "locale":"gd",
# "levels":[ { "level":1,
# "speed":150, <-- optional
# "fallspeed":7000, <-- optional
# "sublevels":10, <-- optional
# "words":["a","jim", "beam", ... ]}, <-- mandatory
# { "level":2, ... }
# ]
# }
#
# Example usage:
# ./wordlist_xml2json.php <default-en.xml >default-en.json
#
use XML::Simple;
use Data::Dumper;
use JSON;
use utf8;
use Encode;
binmode STDIN, ":utf8";
binmode STDOUT, ":utf8";
binmode STDERR, ":utf8";
my $xml_str;
while (<STDIN>) {
$xml_str .= encode('utf8', $_);
}
my $xml = XMLin($xml_str);
my $obj = {};
# Wordlist attributes:
$obj->{name} = $xml->{Wordlist}->{name} if (exists($xml->{Wordlist}->{name}));
$obj->{locale} = $xml->{Wordlist}->{locale};
$obj->{description} = $xml->{Wordlist}->{description};
$obj->{name} = $xml->{Wordlist}->{name};
# levels
$obj->{levels} = ();
my $levels;
if (ref($xml->{Wordlist}->{level}) eq "ARRAY") {
$levels = $xml->{Wordlist}->{level};
} else {
# assume scalar for single level files:
$levels = [$xml->{Wordlist}->{level}];
}
foreach $l (@{$levels}) {
$l->{level} = $l->{value}; delete $l->{value};
my $wordarr = [];
foreach $word (split('\n', $l->{content})) {
$word =~ s/^\s+//;
$word =~ s/\s+$//;
push(@$wordarr, $word) if (length($word) > 0);
}
$l->{words} = $wordarr;
delete $l->{content};
push (@{$obj->{levels}}, $l);
}
my $json = JSON->new->allow_nonref->pretty;
my $json_text = $json->encode( $obj );
print $json_text;
#EOF