~aleteoryx/muditaos

178fba165e9a426fb2da84e4091b701ff610d280 — Lefucjusz 3 years ago 902a3a3
[MOS-783] First part of new dir structure implementation

    Works:
    - generating .img for Pure;
    - Pure boots after flashing new image and
    seems to be working fine;

    Not yet:
    - generating update package;
    - generating image for Harmony;
    - simulator;
    - path-related unit tests fail
    due to paths being hardcoded
    in test scenarios.
75 files changed, 461 insertions(+), 647 deletions(-)

M CMakeLists.txt
M cmake/modules/AddBootBin.cmake
M cmake/modules/AddVersionJson.cmake
M cmake/modules/Assets.cmake
M cmake/modules/DiskImage.cmake
M cmake/modules/DownloadAsset.cmake
M cmake/modules/SerialPort.cmake
D cmake/modules/TestTarget.cmake
D image/.boot.json
D image/.boot.json.crc32
M image/CMakeLists.txt
R image/{user => system_a}/data/applications/settings/quotes.json
R image/{assets => system_a/data}/certification_info/Deutsch/sar.txt
R image/{assets => system_a/data}/certification_info/English/sar.txt
R image/{assets => system_a/data}/certification_info/Espanol/sar.txt
R image/{assets => system_a/data}/certification_info/Polski/sar.txt
R image/{user => system_a}/data/equalizer/earspeaker_routing.json
R image/{user => system_a}/data/equalizer/headphones_playback.json
R image/{user => system_a}/data/equalizer/headphones_routing.json
R image/{user => system_a}/data/equalizer/loudspeaker_playback.json
R image/{user => system_a}/data/equalizer/loudspeaker_routing.json
R image/{assets => system_a/data}/lang/Deutsch.json
R image/{assets => system_a/data}/lang/English.json
R image/{assets => system_a/data}/lang/Espanol.json
R image/{assets => system_a/data}/lang/Francais.json
R image/{assets => system_a/data}/lang/Polski.json
R image/{assets => system_a/data}/lang/Svenska.json
R image/{assets => system_a/data}/licenses/Deutsch/eula.txt
R image/{assets => system_a/data}/licenses/English/eula.txt
R image/{assets => system_a/data}/licenses/Espanol/eula.txt
R image/{assets => system_a/data}/licenses/Polski/eula.txt
R image/{ => system_a/data}/personalization.json
R image/{assets => system_a/data}/profiles/Deutsch_lower.json
R image/{assets => system_a/data}/profiles/Deutsch_upper.json
R image/{assets => system_a/data}/profiles/English_lower.json
R image/{assets => system_a/data}/profiles/English_upper.json
R image/{assets => system_a/data}/profiles/Espanol_lower.json
R image/{assets => system_a/data}/profiles/Espanol_upper.json
R image/{assets => system_a/data}/profiles/Francais_lower.json
R image/{assets => system_a/data}/profiles/Francais_upper.json
R image/{assets => system_a/data}/profiles/Polski_lower.json
R image/{assets => system_a/data}/profiles/Polski_upper.json
R image/{assets => system_a/data}/profiles/Svenska_lower.json
R image/{assets => system_a/data}/profiles/Svenska_upper.json
R image/{assets => system_a/data}/profiles/numeric.json
R image/{assets => system_a/data}/profiles/phone.json
R image/{ => system_a/db}/country-codes.db
A image/user/boot.json
M module-apps/application-alarm-clock/widgets/AlarmMusicOptionsItem.cpp
M module-apps/application-meditation/widgets/MeditationTimer.cpp
M module-apps/application-music-player/ApplicationMusicPlayer.cpp
M module-apps/application-onboarding/ApplicationOnBoarding.cpp
M module-apps/application-settings/models/apps/SoundsModel.cpp
M module-audio/Audio/Profiles/ProfilePlaybackHeadphones.hpp
M module-audio/Audio/Profiles/ProfilePlaybackLoudspeaker.hpp
M module-audio/Audio/Profiles/ProfileRoutingEarspeaker.hpp
M module-audio/Audio/Profiles/ProfileRoutingHeadphones.hpp
M module-audio/Audio/Profiles/ProfileRoutingLoudspeaker.hpp
M module-bsp/board/rt1051/bsp/eink/EinkDisplay.cpp
M module-services/service-desktop/ServiceDesktop.cpp
M module-services/service-desktop/endpoints/deviceInfo/DeviceInfoEndpointCommon.cpp
M module-services/service-fileindexer/ServiceFileIndexer.cpp
M module-services/service-fileindexer/StartupIndexer.cpp
M module-services/service-gui/ServiceGUI.cpp
M module-utils/bootconfig/src/bootconfig.cpp
M module-utils/i18n/i18nImpl.hpp
M module-vfs/paths/filesystem_paths.cpp
M module-vfs/paths/include/purefs/filesystem_paths.hpp
M module-vfs/src/purefs/fs/filesystem_syscalls.cpp
M module-vfs/src/purefs/vfs_subsystem.cpp
M products/PurePhone/CMakeLists.txt
M products/PurePhone/PurePhoneMain.cpp
M products/PurePhone/assets/assets_common.json
M test/harness
M tools/generate_image.sh
M CMakeLists.txt => CMakeLists.txt +7 -6
@@ 170,26 170,27 @@ add_custom_target(
        "Generating version info"
    )

# Create common user directories
# Create common system directories
add_directories(
        TARGET user_directories_common
        PREFIX ${CMAKE_BINARY_DIR}/sysroot/sys/user
        TARGET system_directories_common
        PREFIX ${CMAKE_BINARY_DIR}/sysroot/system_a
        DEPENDS assets
        DIRECTORIES logs crash_dumps backup tmp storage audio db
        DIRECTORIES log assets crash_dumps data bin db scripts
)

# Create and initialize common databases
add_databases_target(
        TARGET create_databases_common
        SOURCE_DIR ${CMAKE_SOURCE_DIR}/module-db/databases/scripts
        DEST_DIR ${CMAKE_BINARY_DIR}/sysroot/sys/user/db
        DEST_DIR ${CMAKE_BINARY_DIR}/sysroot/system_a/db
        DEVEL ${WITH_DEVELOPMENT_FEATURES}
)

# Create and initialize product-specific databases
add_databases_target(
        TARGET create_product_databases
        SOURCE_DIR ${CMAKE_SOURCE_DIR}/products/${PRODUCT}/services/db/databases/scripts
        DEST_DIR ${CMAKE_BINARY_DIR}/sysroot/sys/user/db
        DEST_DIR ${CMAKE_BINARY_DIR}/sysroot/system_a/db
        DEVEL ${WITH_DEVELOPMENT_FEATURES}
        DEPENDS create_databases_common
)

M cmake/modules/AddBootBin.cmake => cmake/modules/AddBootBin.cmake +1 -1
@@ 1,5 1,5 @@
function(add_boot_bin SOURCE_TARGET)
    set(BIN_FILE ${CMAKE_BINARY_DIR}/sysroot/sys/current/${SOURCE_TARGET}-boot.bin)
    set(BIN_FILE ${CMAKE_BINARY_DIR}/sysroot/system_a/bin/boot.bin)

    set_target_properties(
            ${SOURCE_TARGET}

M cmake/modules/AddVersionJson.cmake => cmake/modules/AddVersionJson.cmake +20 -4
@@ 24,9 24,17 @@ function(add_version_rt1051_json SOURCE_TARGET)
        DEPENDS ${SOURCE_TARGET}-boot.bin
    )

    add_custom_target(${SOURCE_TARGET}-version.json-target DEPENDS ${SOURCE_TARGET}-version.json)
    add_custom_command(OUTPUT add-${SOURCE_TARGET}-version.json
        COMMAND rsync -qravu
            ${CMAKE_BINARY_DIR}/${SOURCE_TARGET}-version.json
            ${CMAKE_BINARY_DIR}/sysroot/system_a/version.json
        DEPENDS
            ${SOURCE_TARGET}-version.json
    )

    add_custom_target(${SOURCE_TARGET}-version.json-target DEPENDS add-${SOURCE_TARGET}-version.json)

    multicomp_install(FILES ${CMAKE_BINARY_DIR}/${SOURCE_TARGET}-version.json DESTINATION "./" RENAME "version.json" COMPONENTS Standalone Update)
#    multicomp_install(FILES ${CMAKE_BINARY_DIR}/${SOURCE_TARGET}-version.json DESTINATION "./" RENAME "version.json" COMPONENTS Standalone Update)
endfunction()

function(add_version_linux_json SOURCE_TARGET)


@@ 43,7 51,15 @@ function(add_version_linux_json SOURCE_TARGET)
            -P ${CMAKE_SOURCE_DIR}/cmake/modules/ConfigureVersionJson.cmake
    )

    add_custom_target(${SOURCE_TARGET}-version.json-target DEPENDS ${SOURCE_TARGET}-version.json)
    add_custom_command(OUTPUT add-${SOURCE_TARGET}-version.json
        COMMAND rsync -qravu
            ${CMAKE_BINARY_DIR}/${SOURCE_TARGET}-version.json
            ${CMAKE_BINARY_DIR}/sysroot/system_a/version.json
        DEPENDS
            ${SOURCE_TARGET}-version.json
    )

    add_custom_target(${SOURCE_TARGET}-version.json-target DEPENDS add-${SOURCE_TARGET}-version.json)

    multicomp_install(FILES ${CMAKE_BINARY_DIR}/${SOURCE_TARGET}-version.json DESTINATION "./" RENAME "version.json" COMPONENTS Standalone Update)
#    multicomp_install(FILES ${CMAKE_BINARY_DIR}/${SOURCE_TARGET}-version.json DESTINATION "./" RENAME "version.json" COMPONENTS Standalone Update)
endfunction()

M cmake/modules/Assets.cmake => cmake/modules/Assets.cmake +21 -17
@@ 4,30 4,34 @@ function(add_assets_target)
    cmake_parse_arguments(
        _ASSETS
        ""
        "TARGET;SOURCE_DIR;DEST_DIR;DEVEL;"
        "TARGET;SOURCE_DIR;SYSTEM_DEST_DIR;USER_DEST_DIR;DEVEL;"
        "DEPENDS"
        ${ARGN}
    )

    if(NOT ${_ASSETS_DEVEL})
        set(EXCLUDED --exclude \"*-devel*\")
    endif()

    add_custom_target(
        ${_ASSETS_TARGET}
        DEPENDS ${_ASSETS_DEPENDS}
        COMMAND mkdir -p ${_ASSETS_DEST_DIR}
        COMMAND rsync -qravu --delete
            ${_ASSETS_SOURCE_DIR}/.boot.json*
            ${_ASSETS_SOURCE_DIR}/personalization.json
            ${_ASSETS_DEST_DIR}

        # Copy user assets
        COMMAND mkdir -p ${_ASSETS_USER_DEST_DIR}
        COMMAND rsync -qravu
            ${_ASSETS_SOURCE_DIR}/user/
            ${_ASSETS_USER_DEST_DIR}
        COMMAND find ${_ASSETS_USER_DEST_DIR} -name "*-devel*" | sed "\"s,\\(.*\\)-devel\\(.*\\),& \\1\\2,\"" | xargs --no-run-if-empty -L1 mv

        # Copy system assets
        COMMAND mkdir -p ${_ASSETS_SYSTEM_DEST_DIR}
        COMMAND rsync -qravu
            ${_ASSETS_SOURCE_DIR}/assets
            ${_ASSETS_DEST_DIR}/current
        COMMAND rsync -qravu ${EXCLUDED}
            ${_ASSETS_SOURCE_DIR}/user
            ${_ASSETS_DEST_DIR}
        COMMENT
            "Copying assets, development features: ${_ASSETS_DEVEL}"
            ${_ASSETS_SOURCE_DIR}/system_a/data
            ${_ASSETS_SOURCE_DIR}/system_a/db
            ${_ASSETS_SYSTEM_DEST_DIR}

        # Create 'golden copy' of DBs
        COMMAND rsync -qravu
            ${_ASSETS_SYSTEM_DEST_DIR}/db/
            ${_ASSETS_SYSTEM_DEST_DIR}/db/factory

        COMMENT  "Copying assets... add_assets_target (${_ASSETS_TARGET}) <- ${_ASSETS_DEPENDS}"
    )
endfunction()

M cmake/modules/DiskImage.cmake => cmake/modules/DiskImage.cmake +1 -34
@@ 2,17 2,11 @@ function(add_image)
    cmake_parse_arguments(
        _ARG
        ""
        "PRODUCT;SYSROOT;IMAGE_PARTITIONS;LUTS"
        "PRODUCT;SYSROOT;IMAGE_PARTITIONS"
        "DEPENDS"
        ${ARGN}
    )

    if(NOT ${PROJECT_TARGET_NAME} STREQUAL "linux")
        set(HAS_BOOTFILE YES)
        set(HAS_UPDATER YES)
        set(HAS_VERSION YES)
    endif()

    set(SCRIPT_PATH ${CMAKE_SOURCE_DIR}/tools/generate_image.sh)

    set(DISK_IMAGE_NAME ${_ARG_PRODUCT}.img)


@@ 23,28 17,6 @@ function(add_image)
        set(IMAGE_PARTITIONS ${CMAKE_SOURCE_DIR}/config/products/${_ARG_PRODUCT}/image_partitions.map)
    endif()

    if(HAS_BOOTFILE)
        set(BIN_FILE_TARGET ${_ARG_PRODUCT}-boot.bin)
        set(BIN_FILE_PATH ${CMAKE_BINARY_DIR}/sysroot/sys/current/${_ARG_PRODUCT}-boot.bin)
    else()
        set(BIN_FILE_PATH "")
    endif()


    if(HAS_UPDATER)
        set(UPDATER_FILE_PATH ${CMAKE_BINARY_DIR}/updater.bin)
    else()
        set(UPDATER_FILE_PATH "")
    endif()

    # set(COMMAND_DEPENDS "genlittlefs")

    if(HAS_VERSION)
        set(VERSION_FILE_PATH ${CMAKE_BINARY_DIR}/${_ARG_PRODUCT}-version.json)
    else()
        set(VERSION_FILE_PATH "")
    endif()

    add_custom_command(
        OUTPUT ${DISK_IMAGE_NAME}
        DEPENDS ${SCRIPT_PATH} ${_ARG_DEPENDS}


@@ 53,10 25,6 @@ function(add_image)
            ${DISK_IMAGE_NAME}
            ${IMAGE_PARTITIONS}
            ${CMAKE_BINARY_DIR}/${_ARG_SYSROOT}
            "${_ARG_LUTS}"
            "${VERSION_FILE_PATH}"
            "${BIN_FILE_PATH}"
            "${UPDATER_FILE_PATH}"
        WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
        COMMENT "Generate ${DISK_IMAGE_NAME} with: add_image: ${_ARG_PRODUCT} : ${_ARG_DEPENDS}"
    )


@@ 67,4 35,3 @@ function(add_image)
        DEPENDS ${DISK_IMAGE_NAME})

endfunction()


M cmake/modules/DownloadAsset.cmake => cmake/modules/DownloadAsset.cmake +1 -3
@@ 18,8 18,7 @@ function(download_asset_release asset_name_in asset_name_out asset_repo asset_ve

    add_custom_target(${asset_name_out}-target DEPENDS ${asset_repo})

    multicomp_install(PROGRAMS ${CMAKE_BINARY_DIR}/${asset_repo} DESTINATION "./"
        COMPONENTS Standalone Update)
#    multicomp_install(PROGRAMS ${CMAKE_BINARY_DIR}/${asset_repo} DESTINATION "./" COMPONENTS Standalone Update)
endfunction()

function(download_asset_release_json


@@ 32,7 31,6 @@ function(download_asset_release_json
        )
    add_custom_target(
        ${target}
        # python3 tools/download_asset.py github --repository "MuditaOSPublicAssets" download --json products/PurePhone/assets_images.json --version '0.0.1' --product pure
        COMMAND python3 ${CMAKE_SOURCE_DIR}/tools/download_asset.py
            --cache_dir ${cache_dir}
            github

M cmake/modules/SerialPort.cmake => cmake/modules/SerialPort.cmake +4 -4
@@ 5,18 5,18 @@
#   define_serial(TARGET_NAME)
#
#  this checks if SERIAL_PORT variable is defined and if so, add proper defines
#  for the specyfied target
#  for the specified target
#
#####
#   message_seraial_satus()
#   message_serial_status()
#
#  This macro can be ussed to message if and which port is ussed
#  This macro can be used to message if and which port is used

include(Colours)

macro(define_serial)
    if(NOT ${ARGC} EQUAL 1 )
        messge(WARNING "No target specyfied!")
        message(WARNING "No target specified!")
    else()
        if(${PROJECT_TARGET} STREQUAL "TARGET_Linux")
            if (SERIAL_PORT)

D cmake/modules/TestTarget.cmake => cmake/modules/TestTarget.cmake +0 -0
D image/.boot.json => image/.boot.json +0 -12
@@ 1,12 0,0 @@
{
    "main": 
    {
        "ostype": "current",
        "imagename": "boot.bin"
    },
    "bootloader":
    {
        "version":"0.0.0"
    },
    "git": {}
}

D image/.boot.json.crc32 => image/.boot.json.crc32 +0 -1
@@ 1,1 0,0 @@
07760FAB
\ No newline at end of file

M image/CMakeLists.txt => image/CMakeLists.txt +6 -11
@@ 2,7 2,8 @@
include(Utils)

set(SYSROOT ${CMAKE_BINARY_DIR}/sysroot)
set(ASSETS_DEST_DIR ${SYSROOT}/sys)
set(SYSTEM_DEST_DIR ${SYSROOT}/system_a)
set(USER_DEST_DIR ${SYSROOT}/user)

set(ASSETS_DEPENDENCIES "json-common-target")



@@ 21,16 22,10 @@ endif()
add_assets_target(
    TARGET assets
    SOURCE_DIR ${ASSETS_SOURCE_DIR}
    DEST_DIR ${ASSETS_DEST_DIR}
    SYSTEM_DEST_DIR ${SYSTEM_DEST_DIR}
    USER_DEST_DIR ${USER_DEST_DIR}
    DEVEL ${WITH_DEVELOPMENT_FEATURES}
    DEPENDS
        ${ASSETS_DEPENDENCIES}
    DEPENDS ${ASSETS_DEPENDENCIES}
)

multicomp_install(
    FILES
        ${ASSETS_DEST_DIR}/.boot.json
        ${ASSETS_DEST_DIR}/.boot.json.crc32
    DESTINATION ./
    COMPONENTS Standalone Update
)
#multicomp_install(FILES  ${USER_DEST_DIR}/boot.json DESTINATION ./ COMPONENTS Standalone Update)

R image/user/data/applications/settings/quotes.json => image/system_a/data/applications/settings/quotes.json +0 -0
R image/assets/certification_info/Deutsch/sar.txt => image/system_a/data/certification_info/Deutsch/sar.txt +0 -0
R image/assets/certification_info/English/sar.txt => image/system_a/data/certification_info/English/sar.txt +0 -0
R image/assets/certification_info/Espanol/sar.txt => image/system_a/data/certification_info/Espanol/sar.txt +0 -0
R image/assets/certification_info/Polski/sar.txt => image/system_a/data/certification_info/Polski/sar.txt +0 -0
R image/user/data/equalizer/earspeaker_routing.json => image/system_a/data/equalizer/earspeaker_routing.json +0 -0
R image/user/data/equalizer/headphones_playback.json => image/system_a/data/equalizer/headphones_playback.json +0 -0
R image/user/data/equalizer/headphones_routing.json => image/system_a/data/equalizer/headphones_routing.json +0 -0
R image/user/data/equalizer/loudspeaker_playback.json => image/system_a/data/equalizer/loudspeaker_playback.json +0 -0
R image/user/data/equalizer/loudspeaker_routing.json => image/system_a/data/equalizer/loudspeaker_routing.json +0 -0
R image/assets/lang/Deutsch.json => image/system_a/data/lang/Deutsch.json +0 -0
R image/assets/lang/English.json => image/system_a/data/lang/English.json +0 -0
R image/assets/lang/Espanol.json => image/system_a/data/lang/Espanol.json +0 -0
R image/assets/lang/Francais.json => image/system_a/data/lang/Francais.json +0 -0
R image/assets/lang/Polski.json => image/system_a/data/lang/Polski.json +0 -0
R image/assets/lang/Svenska.json => image/system_a/data/lang/Svenska.json +0 -0
R image/assets/licenses/Deutsch/eula.txt => image/system_a/data/licenses/Deutsch/eula.txt +0 -0
R image/assets/licenses/English/eula.txt => image/system_a/data/licenses/English/eula.txt +0 -0
R image/assets/licenses/Espanol/eula.txt => image/system_a/data/licenses/Espanol/eula.txt +0 -0
R image/assets/licenses/Polski/eula.txt => image/system_a/data/licenses/Polski/eula.txt +0 -0
R image/personalization.json => image/system_a/data/personalization.json +0 -0
R image/assets/profiles/Deutsch_lower.json => image/system_a/data/profiles/Deutsch_lower.json +0 -0
R image/assets/profiles/Deutsch_upper.json => image/system_a/data/profiles/Deutsch_upper.json +0 -0
R image/assets/profiles/English_lower.json => image/system_a/data/profiles/English_lower.json +0 -0
R image/assets/profiles/English_upper.json => image/system_a/data/profiles/English_upper.json +0 -0
R image/assets/profiles/Espanol_lower.json => image/system_a/data/profiles/Espanol_lower.json +0 -0
R image/assets/profiles/Espanol_upper.json => image/system_a/data/profiles/Espanol_upper.json +0 -0
R image/assets/profiles/Francais_lower.json => image/system_a/data/profiles/Francais_lower.json +0 -0
R image/assets/profiles/Francais_upper.json => image/system_a/data/profiles/Francais_upper.json +0 -0
R image/assets/profiles/Polski_lower.json => image/system_a/data/profiles/Polski_lower.json +0 -0
R image/assets/profiles/Polski_upper.json => image/system_a/data/profiles/Polski_upper.json +0 -0
R image/assets/profiles/Svenska_lower.json => image/system_a/data/profiles/Svenska_lower.json +0 -0
R image/assets/profiles/Svenska_upper.json => image/system_a/data/profiles/Svenska_upper.json +0 -0
R image/assets/profiles/numeric.json => image/system_a/data/profiles/numeric.json +0 -0
R image/assets/profiles/phone.json => image/system_a/data/profiles/phone.json +0 -0
R image/country-codes.db => image/system_a/db/country-codes.db +0 -0
A image/user/boot.json => image/user/boot.json +24 -0
@@ 0,0 1,24 @@
{
    "boot": {
        "slots": {
            "a": {
                "bootable": true,
                "successful": true,
                "boot_attempts_left": "1",
                "prefix" : "/system_a"
            },
            "b": {
                "bootable": true,
                "successful": true,
                "boot_attempts_left": "10",
                "prefix" : "/system_b"
            },
            "active": "a",
            "boot_attempts_max": "10"
        },
        "os": "boot.bin",
        "recovery": "recovery.bin",
        "bin_dir": "bin",
        "update_dir": "/user/update"
    }
}

M module-apps/application-alarm-clock/widgets/AlarmMusicOptionsItem.cpp => module-apps/application-alarm-clock/widgets/AlarmMusicOptionsItem.cpp +2 -2
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "AlarmMusicOptionsItem.hpp"


@@ 93,7 93,7 @@ namespace gui

    std::vector<tags::fetcher::Tags> AlarmMusicOptionsItem::getMusicFilesList()
    {
        const auto musicFolder = (purefs::dir::getCurrentOSPath() / "assets/audio/alarm").string();
        const auto musicFolder = (purefs::dir::getSystemDiskPath() / "assets/audio/alarm").string();
        std::vector<tags::fetcher::Tags> musicFiles;
        LOG_INFO("Scanning music folder: %s", musicFolder.c_str());
        for (const auto &ent : std::filesystem::directory_iterator(musicFolder)) {

M module-apps/application-meditation/widgets/MeditationTimer.cpp => module-apps/application-meditation/widgets/MeditationTimer.cpp +2 -2
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "MeditationTimer.hpp"


@@ 88,6 88,6 @@ namespace gui
    {
        AudioServiceAPI::PlaybackStart(application,
                                       audio::PlaybackType::Meditation,
                                       purefs::dir::getCurrentOSPath() / "assets/audio/meditation/gong.mp3");
                                       purefs::dir::getSystemDiskPath() / "assets/audio/meditation/gong.mp3");
    }
} // namespace gui

M module-apps/application-music-player/ApplicationMusicPlayer.cpp => module-apps/application-music-player/ApplicationMusicPlayer.cpp +1 -1
@@ 46,7 46,7 @@ namespace app

        bus.channels.push_back(sys::BusChannel::ServiceAudioNotifications);

        const auto paths     = std::vector<std::string>{purefs::dir::getUserAudioPath()};
        const auto paths     = std::vector<std::string>{purefs::dir::getUserMediaPath()};
        auto tagsFetcher     = std::make_unique<app::music::ServiceAudioTagsFetcher>(this);
        auto songsRepository = std::make_unique<app::music::SongsRepository>(this, std::move(tagsFetcher), paths);


M module-apps/application-onboarding/ApplicationOnBoarding.cpp => module-apps/application-onboarding/ApplicationOnBoarding.cpp +1 -1
@@ 143,7 143,7 @@ namespace app
                                  return std::make_unique<app::onBoarding::StartConfigurationWindow>(app);
                              });
        windowsFactory.attach(gui::window::name::onBoarding_eula, [&](ApplicationCommon *app, const std::string &name) {
            auto eulaRepository = std::make_unique<app::onBoarding::EULARepository>("assets/licenses", "eula.txt");
            auto eulaRepository = std::make_unique<app::onBoarding::EULARepository>("data/licenses", "eula.txt");
            auto presenter      = std::make_unique<app::onBoarding::EULALicenseWindowPresenter>([&]() { acceptEULA(); },
                                                                                           std::move(eulaRepository));
            return std::make_unique<app::onBoarding::EULALicenseWindow>(app, std::move(presenter));

M module-apps/application-settings/models/apps/SoundsModel.cpp => module-apps/application-settings/models/apps/SoundsModel.cpp +9 -9
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "SoundsModel.hpp"


@@ 77,16 77,16 @@ std::filesystem::path SoundsModel::getSoundPath(audio_settings::AbstractAudioSet
    assert(model);
    switch (model->getPlaybackType()) {
    case audio::PlaybackType::CallRingtone:
        return purefs::dir::getCurrentOSPath() / "assets/audio/ringtone";
        return purefs::dir::getSystemDiskPath() / "assets/audio/ringtone";

    case audio::PlaybackType::TextMessageRingtone:
        return purefs::dir::getCurrentOSPath() / "assets/audio/sms";
        return purefs::dir::getSystemDiskPath() / "assets/audio/sms";

    case audio::PlaybackType::Notifications:
        return purefs::dir::getCurrentOSPath() / "assets/audio/alarm";
        return purefs::dir::getSystemDiskPath() / "assets/audio/alarm";

    default:
        return purefs::dir::getCurrentOSPath() / "assets/audio";
        return purefs::dir::getSystemDiskPath() / "assets/audio";
    }
}



@@ 97,7 97,7 @@ void SoundsModel::applyItems(const std::vector<std::filesystem::path> &sounds,
    auto currentItemIndex  = 0;
    auto selectedItemIndex = 0;

    std::string selectedSound = purefs::dir::getCurrentOSPath() / model->getSound();
    std::string selectedSound = purefs::dir::getSystemDiskPath() / model->getSound();
    for (const auto &sound : sounds) {

        bool isSelected = false;


@@ 122,7 122,7 @@ void SoundsModel::applyItems(const std::vector<std::filesystem::path> &sounds,
        case audio::PlaybackType::TextMessageRingtone:
        case audio::PlaybackType::Notifications:
            item->activatedCallback = [=](gui::Item &) {
                auto fileRelativePath = sound.lexically_relative(purefs::dir::getCurrentOSPath());
                auto fileRelativePath = sound.lexically_relative(purefs::dir::getSystemDiskPath());
                LOG_INFO("Setting sound to %s", fileRelativePath.c_str());
                model->setSound(fileRelativePath);
                soundsPlayer->stop();


@@ 132,7 132,7 @@ void SoundsModel::applyItems(const std::vector<std::filesystem::path> &sounds,

            // callback to handle preview of the sound
            item->inputCallback = [=](gui::Item &item, const gui::InputEvent &event) {
                auto fileRelativePath = sound.lexically_relative(purefs::dir::getCurrentOSPath());
                auto fileRelativePath = sound.lexically_relative(purefs::dir::getSystemDiskPath());

                if (event.isShortRelease(gui::KeyCode::KEY_RF)) {
                    soundsPlayer->stop();


@@ 168,7 168,7 @@ void SoundsModel::applyItems(const std::vector<std::filesystem::path> &sounds,
                    return true;
                }

                auto fileRelativePath = sound.lexically_relative(purefs::dir::getCurrentOSPath());
                auto fileRelativePath = sound.lexically_relative(purefs::dir::getSystemDiskPath());
                if (!soundsPlayer->previouslyPlayed(fileRelativePath)) {
                    app->getCurrentWindow()->navBarTemporaryMode(
                        utils::translate(style::strings::common::play), gui::nav_bar::Side::Left, false);

M module-audio/Audio/Profiles/ProfilePlaybackHeadphones.hpp => module-audio/Audio/Profiles/ProfilePlaybackHeadphones.hpp +1 -1
@@ 14,7 14,7 @@ namespace audio
            : Profile(
                  "Playback Headphones",
                  Type::PlaybackHeadphones,
                  purefs::dir::getCurrentOSPath() / "user/data/equalizer/headphones_playback.json",
                  purefs::dir::getSystemDiskPath() / "data/equalizer/headphones_playback.json",
                  audio::codec::Configuration{
                      .sampleRate_Hz = 0,
                      .bitWidth      = 16,

M module-audio/Audio/Profiles/ProfilePlaybackLoudspeaker.hpp => module-audio/Audio/Profiles/ProfilePlaybackLoudspeaker.hpp +1 -1
@@ 15,7 15,7 @@ namespace audio
            : Profile(
                  "Playback Loudspeaker",
                  Type::PlaybackLoudspeaker,
                  purefs::dir::getCurrentOSPath() / "user/data/equalizer/loudspeaker_playback.json",
                  purefs::dir::getSystemDiskPath() / "data/equalizer/loudspeaker_playback.json",
                  audio::codec::Configuration{
                      .sampleRate_Hz     = 0,
                      .bitWidth          = 16,

M module-audio/Audio/Profiles/ProfileRoutingEarspeaker.hpp => module-audio/Audio/Profiles/ProfileRoutingEarspeaker.hpp +1 -1
@@ 14,7 14,7 @@ namespace audio
            : Profile(
                  "Routing Earspeaker",
                  Type::RoutingEarspeaker,
                  purefs::dir::getCurrentOSPath() / "user/data/equalizer/earspeaker_routing.json",
                  purefs::dir::getSystemDiskPath() / "data/equalizer/earspeaker_routing.json",
                  audio::codec::Configuration{
                      .sampleRate_Hz = 16000,
                      .bitWidth      = 16,

M module-audio/Audio/Profiles/ProfileRoutingHeadphones.hpp => module-audio/Audio/Profiles/ProfileRoutingHeadphones.hpp +1 -1
@@ 14,7 14,7 @@ namespace audio
            : Profile(
                  "Routing Headset",
                  Type::RoutingHeadphones,
                  purefs::dir::getCurrentOSPath() / "user/data/equalizer/headphones_routing.json",
                  purefs::dir::getSystemDiskPath() / "data/equalizer/headphones_routing.json",
                  audio::codec::Configuration{
                      .sampleRate_Hz = 16000,
                      .bitWidth      = 16,

M module-audio/Audio/Profiles/ProfileRoutingLoudspeaker.hpp => module-audio/Audio/Profiles/ProfileRoutingLoudspeaker.hpp +1 -1
@@ 15,7 15,7 @@ namespace audio
        ProfileRoutingLoudspeaker(Volume volume, Gain gain)
            : Profile("Routing Speakerphone",
                      Type::RoutingLoudspeaker,
                      purefs::dir::getCurrentOSPath() / "user/data/equalizer/loudspeaker_routing.json",
                      purefs::dir::getSystemDiskPath() / "data/equalizer/loudspeaker_routing.json",
                      audio::codec::Configuration{
                          .sampleRate_Hz = sampleRate,
                          .bitWidth      = 16,

M module-bsp/board/rt1051/bsp/eink/EinkDisplay.cpp => module-bsp/board/rt1051/bsp/eink/EinkDisplay.cpp +5 -3
@@ 3,6 3,7 @@

#include "EinkDisplay.hpp"

#include <purefs/filesystem_paths.hpp>
#include <board/BoardDefinitions.hpp>
#include <log/log.hpp>



@@ 17,7 18,6 @@ namespace hal::eink
    namespace
    {
        constexpr auto DefaultSurroundingTemperature = -1000;
        constexpr auto LutsFileName                  = "Luts.bin";
        constexpr auto LUTDSize                      = 16385;
        constexpr auto LUTCSize                      = 64;
        constexpr auto LUTRSize                      = 256; ///< Needed due to \ref LutsFileName structure


@@ 31,6 31,8 @@ namespace hal::eink
        constexpr auto LUTTemperatureOffsetSubcritical = 12;
        constexpr auto LUTTemperatureOffsetCritical    = 13;

        const auto LutsFilePath = purefs::dir::getSystemDiskPath() / "assets" / "Luts.bin";

        EinkWaveformSettings_t createDefaultWaveFormSettings(EinkWaveforms_e waveformMode)
        {
            EinkWaveformSettings_t settings{};


@@ 321,9 323,9 @@ namespace hal::eink
            return EinkStatus::EinkOK;
        }

        auto file = std::fopen(LutsFileName, "rb");
        auto file = std::fopen(LutsFilePath.c_str(), "rb");
        if (file == nullptr) {
            LOG_FATAL("Could not find the LUTS.bin file. Returning");
            LOG_FATAL("Could not find LUTS file in '%s'! Returning...", LutsFilePath.c_str());
            return EinkStatus::EinkWaveformsFileOpenFail;
        }
        auto fileHandlerCleanup = gsl::finally([&file]() { std::fclose(file); });

M module-services/service-desktop/ServiceDesktop.cpp => module-services/service-desktop/ServiceDesktop.cpp +1 -1
@@ 192,7 192,7 @@ auto ServiceDesktop::usbWorkerInit() -> sys::ReturnCodes
                                                    *usbSecurityModel,
                                                    serialNumber,
                                                    caseColour,
                                                    purefs::dir::getUserStoragePath());
                                                    purefs::dir::getUserMediaPath());

    initialized =
        desktopWorker->init({{sdesktop::RECEIVE_QUEUE_BUFFER_NAME, sizeof(std::string *), sdesktop::cdc_queue_len},

M module-services/service-desktop/endpoints/deviceInfo/DeviceInfoEndpointCommon.cpp => module-services/service-desktop/endpoints/deviceInfo/DeviceInfoEndpointCommon.cpp +1 -2
@@ 143,8 143,7 @@ namespace sdesktop::endpoints
        unsigned long reservedSystemSpaceMiB = 0;
        unsigned long usedUserSpaceMiB       = 0;

        const std::array<std::filesystem::path, 2> systemStoragePaths{purefs::dir::getRootDiskPath(),
                                                                      purefs::dir::getPreviousOSPath()};
        const std::array<std::filesystem::path, 1> systemStoragePaths{purefs::dir::getSystemDiskPath()};
        for (const auto &p : systemStoragePaths) {
            auto [totalSpace, freeSpace] = getStorageStats(p);


M module-services/service-fileindexer/ServiceFileIndexer.cpp => module-services/service-fileindexer/ServiceFileIndexer.cpp +1 -1
@@ 31,7 31,7 @@ namespace service
    sys::ReturnCodes ServiceFileIndexer::InitHandler()
    {
        if (mInotifyHandler.init(shared_from_this())) {
            mInotifyHandler.addWatch(purefs::dir::getUserAudioPath().c_str());
            mInotifyHandler.addWatch(purefs::dir::getUserMediaPath().c_str());

            // Start the initial indexer
            mStartupIndexer.start(shared_from_this(), service::name::file_indexer);

M module-services/service-fileindexer/StartupIndexer.cpp => module-services/service-fileindexer/StartupIndexer.cpp +1 -1
@@ 20,7 20,7 @@ namespace service::detail
    using namespace std::literals;
    using namespace std::chrono_literals;

    const auto lock_file_name        = purefs::dir::getUserDiskPath() / ".directory_is_indexed";
    const auto lock_file_name        = purefs::dir::getUserDiskPath() / "data" / ".directory_is_indexed";
    constexpr auto indexing_interval = 50ms;
    constexpr auto start_delay       = 10000ms;


M module-services/service-gui/ServiceGUI.cpp => module-services/service-gui/ServiceGUI.cpp +1 -1
@@ 53,7 53,7 @@ namespace service::gui

    void ServiceGUI::initAssetManagers()
    {
        const auto assetsPath = purefs::dir::getCurrentOSPath() / "assets";
        const auto assetsPath = purefs::dir::getSystemDiskPath() / "assets";
        ::gui::FontManager::getInstance().init(assetsPath);
        ::gui::ImageManager::getInstance().init(assetsPath);
    }

M module-utils/bootconfig/src/bootconfig.cpp => module-utils/bootconfig/src/bootconfig.cpp +5 -55
@@ 1,4 1,4 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include <boot/bootconfig.hpp>
#include <boot/bootconstants.hpp>


@@ 22,7 22,6 @@ namespace boot
{
    namespace
    {

        std::string loadFileAsString(const std::filesystem::path &fileToLoad)
        {
            std::string content;


@@ 30,54 29,9 @@ namespace boot
            std::getline(in, content, std::string::traits_type::to_char_type(std::string::traits_type::eof()));
            return content;
        }

        bool verifyCRC(const std::filesystem::path &file, const unsigned long crc32)
        {
            auto fp = fopen(file.c_str(), "r");
            if (!fp) {
                LOG_ERROR("verifyCRC can't open %s", file.c_str());
                return false;
            }
            auto fpCloseAct = gsl::finally([fp] { fclose(fp); });

            unsigned long crc32Read = utils::filesystem::computeFileCRC32(fp);
            LOG_INFO(
                "verifyCRC computed crc32 for %s is %08" PRIX32, file.c_str(), static_cast<std::uint32_t>(crc32Read));

            return crc32Read == crc32;
        }

        bool readAndVerifyCRC(const std::filesystem::path &file)
        {
            std::filesystem::path crcFilePath(file);
            crcFilePath += boot::consts::ext_crc32;

            auto fp = fopen(crcFilePath.c_str(), "r");
            if (!fp) {
                LOG_ERROR("verifyCRC can't open %s", crcFilePath.c_str());
                return false;
            }
            auto fpCloseAct = gsl::finally([fp] { fclose(fp); });

            std::array<char, boot::consts::crc_char_size + 1> crcBuf;
            size_t readSize = std::fread(crcBuf.data(), 1, boot::consts::crc_char_size, fp);
            if (readSize != boot::consts::crc_char_size) {
                LOG_ERROR("verifyCRC fread on %s returned different size then %d [%zu]",
                          crcFilePath.c_str(),
                          boot::consts::crc_char_size,
                          readSize);
                return false;
            }

            crcBuf[boot::consts::crc_char_size] = 0;
            const unsigned long crc32Read       = strtoull(crcBuf.data(), nullptr, boot::consts::crc_radix);

            LOG_INFO("verifyCRC read %s string:\"%s\" hex:%08lX", crcFilePath.c_str(), crcBuf.data(), crc32Read);
            return verifyCRC(file, crc32Read);
        }
    } // namespace

    BootConfig::BootConfig() : m_os_root_path(purefs::dir::getRootDiskPath())
    BootConfig::BootConfig() : m_os_root_path(purefs::dir::getSystemDiskPath())
    {}

    json11::Json BootConfig::to_json() const


@@ 141,7 95,7 @@ namespace boot
        if (parseErrors == "") {
            m_os_type            = m_boot_json_parsed[boot::json::main][boot::json::os_type].string_value();
            m_os_image           = m_boot_json_parsed[boot::json::main][boot::json::os_image].string_value();
            m_os_root_path       = purefs::createPath(purefs::dir::getRootDiskPath(), m_os_type);
            m_os_root_path       = purefs::createPath(purefs::dir::getSystemDiskPath(), m_os_type);
            m_boot_json          = bootJsonPath;
            m_bootloader_version = m_boot_json_parsed[boot::json::bootloader][boot::json::os_version].string_value();
            m_timestamp          = utils::time::getCurrentTimestamp().str("%c");


@@ 151,9 105,8 @@ namespace boot
            return true;
        }
        else {
            m_os_type      = purefs::dir::getCurrentOSPath();
            m_os_image     = purefs::file::boot_bin;
            m_os_root_path = purefs::createPath(purefs::dir::getRootDiskPath(), m_os_type);
            m_os_root_path = purefs::dir::getSystemDiskPath();
            m_boot_json    = bootJsonPath;
            m_timestamp    = utils::time::getCurrentTimestamp().str("%c");
            m_os_version   = std::string(VERSION);


@@ 164,10 117,7 @@ namespace boot

    std::filesystem::path BootConfig::getCurrentBootJSON()
    {
        auto boot_json_path = purefs::dir::getRootDiskPath() / purefs::file::boot_json;
        if (!readAndVerifyCRC(boot_json_path)) {
            LOG_INFO("CRC check failed on %s", boot_json_path.c_str());
        }
        auto boot_json_path = purefs::dir::getUserDiskPath() / purefs::file::boot_json;
        return boot_json_path;
    }
} // namespace boot

M module-utils/i18n/i18nImpl.hpp => module-utils/i18n/i18nImpl.hpp +2 -2
@@ 25,8 25,8 @@ namespace utils
        Language inputLanguage        = fallbackLanguageName;
        Language inputLanguageFilename;
        Language currentDisplayLanguage;
        std::filesystem::path InputLanguageDirPath   = "assets/profiles";
        std::filesystem::path DisplayLanguageDirPath = "assets/lang";
        std::filesystem::path InputLanguageDirPath   = "data/profiles";
        std::filesystem::path DisplayLanguageDirPath = "data/lang";
        cpp_freertos::MutexStandard mutex;
        std::vector<LanguageMetadata> metadata;


M module-vfs/paths/filesystem_paths.cpp => module-vfs/paths/filesystem_paths.cpp +32 -48
@@ 5,23 5,19 @@

namespace
{
    constexpr inline auto PATH_SYS          = "/sys";
    constexpr inline auto PATH_SYSTEM       = "/system";
    constexpr inline auto PATH_USER         = "/user";
    constexpr inline auto PATH_CONF         = "/mfgconf";
    constexpr inline auto PATH_USER         = "user";
    constexpr inline auto PATH_DB           = "db";
    constexpr inline auto PATH_OS          = "os";
    constexpr inline auto PATH_CURRENT      = "current";
    constexpr inline auto PATH_PREVIOUS     = "previous";
    constexpr inline auto PATH_UPDATES      = "updates";
    constexpr inline auto PATH_TMP          = "tmp";
    constexpr inline auto PATH_BACKUP       = "backup";
    constexpr inline auto PATH_SYNC  = "sync";
    constexpr inline auto PATH_FACTORY      = "factory";
    constexpr inline auto PATH_UPDATE       = "update";
    constexpr inline auto PATH_SYNC         = "sync";
    constexpr inline auto PATH_LOGS         = "logs";
    constexpr inline auto PATH_CRASH_DUMPS  = "crash_dumps";
    constexpr inline auto PATH_USER_AUDIO   = "audio";
    constexpr inline auto PATH_USER_STORAGE = "storage";
    constexpr inline auto eMMC_disk         = PATH_SYS;
    constexpr inline auto PATH_USER_MEDIA =
        "media"; // TODO this won't work with our current non-hierarchical MTP implementation
    constexpr inline auto PATH_TMP    = "tmp";
    constexpr inline auto PATH_BACKUP = "backup";
} // namespace

namespace purefs


@@ 33,76 29,64 @@ namespace purefs

    namespace dir
    {
        std::filesystem::path getRootDiskPath() noexcept
        std::filesystem::path getSystemDiskPath() noexcept
        {
            return std::filesystem::path{eMMC_disk} / PATH_OS;
        }

        std::filesystem::path getMfgConfPath() noexcept
        {
            return std::filesystem::path{PATH_CONF};
            return std::filesystem::path{PATH_SYSTEM};
        }

        std::filesystem::path getUserDiskPath() noexcept
        {
            return std::filesystem::path{eMMC_disk} / PATH_USER;
        }
        std::filesystem::path getDatabasesPath() noexcept
        {
            return getUserDiskPath() / PATH_DB;
            return std::filesystem::path{PATH_USER};
        }

        std::filesystem::path getCurrentOSPath() noexcept
        std::filesystem::path getMfgConfPath() noexcept
        {
            return getRootDiskPath() / PATH_CURRENT;
            return std::filesystem::path{PATH_CONF};
        }

        std::filesystem::path getPreviousOSPath() noexcept
        std::filesystem::path getDatabasesPath() noexcept
        {
            return getRootDiskPath() / PATH_PREVIOUS;
            return getSystemDiskPath() / PATH_DB;
        }

        std::filesystem::path getUpdatesOSPath() noexcept
        std::filesystem::path getUpdateDirPath() noexcept
        {
            return getUserDiskPath() / PATH_UPDATES;
            return getUserDiskPath() / PATH_UPDATE;
        }

        std::filesystem::path getTemporaryPath() noexcept
        std::filesystem::path getSyncPackagePath() noexcept
        {
            return getUserDiskPath() / PATH_TMP;
            return getUserDiskPath() / PATH_SYNC; // TODO what's this?
        }

        std::filesystem::path getBackupOSPath() noexcept
        std::filesystem::path getFactoryDBsPath() noexcept
        {
            return getUserDiskPath() / PATH_BACKUP;
            return getDatabasesPath() / PATH_FACTORY; // TODO this might not be required in OS
        }

        std::filesystem::path getSyncPackagePath() noexcept
        std::filesystem::path getLogsPath() noexcept
        {
            return getUserDiskPath() / PATH_SYNC;
            return getSystemDiskPath() / PATH_LOGS;
        }

        std::filesystem::path getFactoryOSPath() noexcept
        std::filesystem::path getCrashDumpsPath() noexcept
        {
            return std::filesystem::path{eMMC_disk} / PATH_FACTORY;
            return getSystemDiskPath() / PATH_CRASH_DUMPS;
        }

        std::filesystem::path getLogsPath() noexcept
        std::filesystem::path getUserMediaPath() noexcept
        {
            return getUserDiskPath() / PATH_LOGS;
            return getUserDiskPath() / PATH_USER_MEDIA;
        }

        std::filesystem::path getCrashDumpsPath() noexcept
        {
            return getUserDiskPath() / PATH_CRASH_DUMPS;
        }
        std::filesystem::path getUserAudioPath() noexcept
        std::filesystem::path getTemporaryPath() noexcept
        {
            return getUserDiskPath() / PATH_USER_AUDIO;
            return getSystemDiskPath() / PATH_TMP; // TODO is it needed + if it is, where it should be placed
        }
        std::filesystem::path getUserStoragePath() noexcept

        std::filesystem::path getBackupOSPath() noexcept
        {
            return getUserDiskPath() / PATH_USER_STORAGE;
            return getUserDiskPath() / PATH_BACKUP; // TODO is it still needed?
        }
    } // namespace dir
} // namespace purefs

M module-vfs/paths/include/purefs/filesystem_paths.hpp => module-vfs/paths/include/purefs/filesystem_paths.hpp +8 -16
@@ 11,35 11,27 @@ namespace purefs

    namespace dir
    {
        std::filesystem::path getRootDiskPath() noexcept;
        std::filesystem::path getMfgConfPath() noexcept;
        std::filesystem::path getSystemDiskPath() noexcept;
        std::filesystem::path getUserDiskPath() noexcept;
        std::filesystem::path getMfgConfPath() noexcept;
        std::filesystem::path getDatabasesPath() noexcept;
        std::filesystem::path getCurrentOSPath() noexcept;
        std::filesystem::path getPreviousOSPath() noexcept;
        std::filesystem::path getUpdatesOSPath() noexcept;
        std::filesystem::path getTemporaryPath() noexcept;
        std::filesystem::path getBackupOSPath() noexcept;
        std::filesystem::path getUpdateDirPath() noexcept;
        std::filesystem::path getSyncPackagePath() noexcept;
        std::filesystem::path getFactoryOSPath() noexcept;
        std::filesystem::path getFactoryDBsPath() noexcept;
        std::filesystem::path getLogsPath() noexcept;
        std::filesystem::path getCrashDumpsPath() noexcept;
        std::filesystem::path getUserAudioPath() noexcept;
        std::filesystem::path getUserStoragePath() noexcept;
        std::filesystem::path getUserMediaPath() noexcept;
        std::filesystem::path getTemporaryPath() noexcept;
        std::filesystem::path getBackupOSPath() noexcept;
    } // namespace dir

    namespace file
    {
        constexpr inline auto boot_json    = ".boot.json";
        constexpr inline auto boot_json    = "boot.json";
        constexpr inline auto boot_bin     = "boot.bin";
        constexpr inline auto version_json = "version.json";
    } // namespace file

    namespace extension
    {
        constexpr inline auto tar = ".tar";
    }

    namespace buffer
    {
        constexpr inline auto tar_buf = 1024;

M module-vfs/src/purefs/fs/filesystem_syscalls.cpp => module-vfs/src/purefs/fs/filesystem_syscalls.cpp +2 -3
@@ 1,10 1,9 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include <purefs/fs/filesystem.hpp>
#include <errno.h>
#include <log/log.hpp>
#include <purefs/fs/filesystem_operations.hpp>
#include <purefs/fs/file_handle.hpp>
#include <purefs/fs/directory_handle.hpp>
#include <purefs/fs/thread_local_cwd.hpp>
#include <purefs/fs/notifier.hpp>


@@ 160,7 159,7 @@ namespace purefs::fs
        auto fsops = mountp->fs_ops();
        if (fsops) {
            if ((flags & O_ACCMODE) != O_RDONLY && (mountp->flags() & mount_flags::read_only)) {
                LOG_ERROR("Trying to open file with WR... flag on RO filesystem");
                LOG_ERROR("Trying to open file with 'WR' flag on read-only filesystem");
                return -EACCES;
            }
            auto fh = fsops->open(mountp, abspath, flags, mode);

M module-vfs/src/purefs/vfs_subsystem.cpp => module-vfs/src/purefs/vfs_subsystem.cpp +2 -65
@@ 42,61 42,6 @@ namespace purefs::subsystem

    namespace
    {
        int read_file_to_cpp_string(std::shared_ptr<fs::filesystem> vfs, std::string_view file, std::string &str)
        {
            int fd = vfs->open(file, O_RDONLY, 0664);
            if (fd < 0) {
                return fd;
            }
            size_t rd_pos  = 0;
            size_t to_read = str.size();
            do {
                int err = vfs->read(fd, &str[rd_pos], to_read);
                if (err < 0) {
                    vfs->close(fd);
                    return err;
                }
                else {
                    to_read -= err;
                    rd_pos += err;
                }
            } while (to_read > 0);
            return vfs->close(fd);
        }

        std::string parse_boot_json_directory(std::string_view file)
        {
            using namespace std::literals;
            auto vfsn = g_fs_core.lock();
            if (!vfsn) {
                LOG_ERROR("Unable to lock vfs. Fallback to current dir");
                return "current"s;
            }
            struct stat stbuf;
            int err = vfsn->stat(file, stbuf);
            if (err) {
                LOG_ERROR("Unable to lock vfs. Fallback to current dir");
                return "current"s;
            }
            if (stbuf.st_size > boot_size_limit) {
                LOG_ERROR("Boot file to long. Fallback to current dir");
                return "current"s;
            }
            std::string json_str(stbuf.st_size, ' ');
            std::string error;
            err = read_file_to_cpp_string(vfsn, file, json_str);
            if (err) {
                LOG_ERROR("Unable to read boot file (err: %i). Fallback to current dir", err);
                return "current"s;
            }
            auto json = json11::Json::parse(json_str, error);
            if (!error.empty()) {
                LOG_ERROR("Unable to parse json boot file (err: %s). Fallback to current dir", error.c_str());
                return "current"s;
            }
            return json[json::main][json::os_type].string_value();
        }

        int read_mbr_lfs_erase_size(std::shared_ptr<blkdev::disk_manager> disk_mngr,
                                    std::string_view dev_name,
                                    int part_no)


@@ 185,10 130,6 @@ namespace purefs::subsystem
        }
        const auto &boot_part = parts[boot_part_index];
        const auto &user_part = parts[user_part_index];
        if (!boot_part.bootable) {
            LOG_FATAL("First partition is not bootable");
            return -EIO;
        }
        if ((boot_part.type != fat_part_code) && (boot_part.type != linux_part_code)) {
            LOG_FATAL("Invalid boot partition type expected code: %02X or %02X current code: %02X",
                      fat_part_code,


@@ 206,8 147,7 @@ namespace purefs::subsystem
            LOG_FATAL("Unable to lock vfs core");
            return -EIO;
        }
        auto err =
            vfs->mount(boot_part.name, purefs::dir::getRootDiskPath().string(), "auto", fs::mount_flags::read_only);
        auto err = vfs->mount(boot_part.name, purefs::dir::getSystemDiskPath().string(), "auto");
        if (err) {
            return err;
        }


@@ 225,10 165,7 @@ namespace purefs::subsystem
        else {
            err = vfs->mount(user_part.name, purefs::dir::getUserDiskPath().string(), "ext4");
        }
        const std::string json_file = (dir::getRootDiskPath() / file::boot_json).string();
        const auto boot_dir_name    = parse_boot_json_directory(json_file);
        const auto user_dir         = (dir::getRootDiskPath() / boot_dir_name).string();
        fs::internal::set_default_thread_cwd(user_dir);
        fs::internal::set_default_thread_cwd(dir::getSystemDiskPath().string());

        // Mount NVRAM memory
        err = vfs->mount(default_nvrom_name,

M products/PurePhone/CMakeLists.txt => products/PurePhone/CMakeLists.txt +9 -10
@@ 41,7 41,7 @@ target_include_directories(PurePhone
set_target_properties(PurePhone
    PROPERTIES
        SUFFIX ".elf"
        LINK_FLAGS "-Xlinker -Map=${CMAKE_BINARY_DIR}/PurePhone.map "
        LINK_FLAGS "-Xlinker -Map=${CMAKE_BINARY_DIR}/PurePhone.map"
    )

target_link_libraries(PurePhone


@@ 108,8 108,8 @@ include(AddVersionJson)

add_directories(
        TARGET create_user_directories
        PREFIX ${CMAKE_BINARY_DIR}/sysroot/sys/user/audio
        DEPENDS user_directories_common
        PREFIX ${CMAKE_BINARY_DIR}/sysroot/user/media/app
        DEPENDS system_directories_common
        DIRECTORIES music_player
)



@@ 119,12 119,12 @@ if (${PROJECT_TARGET} STREQUAL "TARGET_RT1051")
    add_image(
        PRODUCT PurePhone
        SYSROOT sysroot
        LUTS Luts.bin
        DEPENDS
            install_scripts
            create_product_databases
            create_user_directories
            assets updater.bin-target
            assets
            updater.bin-target
            ecoboot.bin-target
            PurePhone-boot.bin
            PurePhone-version.json-target


@@ 134,7 134,6 @@ else()
    add_image(
        PRODUCT PurePhone
        SYSROOT sysroot
        LUTS ""
        DEPENDS
            install_scripts
            create_product_databases


@@ 153,27 152,27 @@ include(DownloadAsset)

download_asset_json(json-proprietary-target
                    ${CMAKE_CURRENT_SOURCE_DIR}/assets/assets_proprietary.json
                    ${CMAKE_BINARY_DIR}/sysroot/sys/current/
                    ${CMAKE_BINARY_DIR}/sysroot/system_a/
                    MuditaOSAssets
                    ${MUDITA_CACHE_DIR}
    )
download_asset_release_json(json-common-target
                            ${CMAKE_CURRENT_SOURCE_DIR}/assets/assets_common.json
                            ${CMAKE_BINARY_DIR}/sysroot/sys/current/
                            ${CMAKE_BINARY_DIR}/sysroot/
                            MuditaOSPublicAssets
                            0.0.8
                            ${MUDITA_CACHE_DIR}
    )
download_asset_release_json(json-community-target
                            ${CMAKE_CURRENT_SOURCE_DIR}/assets/assets_community.json
                            ${CMAKE_BINARY_DIR}/sysroot/sys/current/
                            ${CMAKE_BINARY_DIR}/sysroot/system_a/
                            MuditaOSPublicAssets
                            0.0.8
                            ${MUDITA_CACHE_DIR}
    )
download_asset_json(json-rt1051-target
                            ${CMAKE_CURRENT_SOURCE_DIR}/assets/assets_rt1051.json
                            ${CMAKE_BINARY_DIR}/sysroot/sys/current/
                            ${CMAKE_BINARY_DIR}/sysroot/system_a/assets
                            MuditaOSAssets
                            ${MUDITA_CACHE_DIR}
    )

M products/PurePhone/PurePhoneMain.cpp => products/PurePhone/PurePhoneMain.cpp +2 -2
@@ 113,7 113,7 @@ void atexit_cleanup_handler()
    LOG_INFO("Starting clean up");
}

class Cleanup
class Cleanup // TODO is this required? It doesn't seem to do anything productive
{
  public:
    ~Cleanup()


@@ 129,7 129,7 @@ int main()
{
    constexpr auto ApplicationName = "PurePhone";

    const std::vector<std::string> fileIndexerAudioPaths = {{purefs::dir::getUserAudioPath()}};
    const std::vector<std::string> fileIndexerAudioPaths = {{purefs::dir::getUserMediaPath()}};

    prof::init();


M products/PurePhone/assets/assets_common.json => products/PurePhone/assets/assets_common.json +232 -232
@@ 1,238 1,238 @@
{
    "assets": [
        {"name":"release.tgz", "tarfile": "./image/assets/images/music-player/mp_nowplaying_play_list_W_M.vpi", "output": "assets/images/music-player/mp_nowplaying_play_list_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/music-player/mp_note_W_G.vpi", "output": "assets/images/music-player/mp_note_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/music-player/mp_line_arrow_down_W_G.vpi", "output": "assets/images/music-player/mp_line_arrow_down_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/music-player/mp_next_gray_W_G.vpi", "output": "assets/images/music-player/mp_next_gray_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/music-player/mp_now_playing_icon_pause_W_G.vpi", "output": "assets/images/music-player/mp_now_playing_icon_pause_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/music-player/mp_prev_gray_W_G.vpi", "output": "assets/images/music-player/mp_prev_gray_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/music-player/mp_bar_W_G.vpi", "output": "assets/images/music-player/mp_bar_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/music-player/mp_next_W_G.vpi", "output": "assets/images/music-player/mp_next_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/music-player/mp_nowplaying_paused_list_W_M.vpi", "output": "assets/images/music-player/mp_nowplaying_paused_list_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/music-player/mp_pause_gray_W_G.vpi", "output": "assets/images/music-player/mp_pause_gray_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/music-player/mp_play_W_G.vpi", "output": "assets/images/music-player/mp_play_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/music-player/mp_now_playing_icon_W_G.vpi", "output": "assets/images/music-player/mp_now_playing_icon_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/music-player/mp_line_arrow_up_W_G.vpi", "output": "assets/images/music-player/mp_line_arrow_up_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/music-player/mp_now_playing_icon_pause_gray_W_G.vpi", "output": "assets/images/music-player/mp_now_playing_icon_pause_gray_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/music-player/mp_prev_W_G.vpi", "output": "assets/images/music-player/mp_prev_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/music-player/mp_pause_W_G.vpi", "output": "assets/images/music-player/mp_pause_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/music-player/mp_bar_gray_W_G.vpi", "output": "assets/images/music-player/mp_bar_gray_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/small_tick_32px_W_M.vpi", "output": "assets/images/small_tick_32px_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/arrow_left_32px_W_G.vpi", "output": "assets/images/arrow_left_32px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/desktop-menu/menu_tools_W_G.vpi", "output": "assets/images/desktop-menu/menu_tools_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/desktop-menu/menu_messages_W_G.vpi", "output": "assets/images/desktop-menu/menu_messages_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/desktop-menu/menu_meditation_W_G.vpi", "output": "assets/images/desktop-menu/menu_meditation_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/desktop-menu/menu_tools_torch_W_G.vpi", "output": "assets/images/desktop-menu/menu_tools_torch_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/desktop-menu/menu_alarm_disabled_W_G.vpi", "output": "assets/images/desktop-menu/menu_alarm_disabled_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/desktop-menu/menu_music_player_W_G.vpi", "output": "assets/images/desktop-menu/menu_music_player_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/desktop-menu/menu_tools_recorder_W_G.vpi", "output": "assets/images/desktop-menu/menu_tools_recorder_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/desktop-menu/menu_calendar_W_G.vpi", "output": "assets/images/desktop-menu/menu_calendar_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/desktop-menu/menu_alarm_W_G.vpi", "output": "assets/images/desktop-menu/menu_alarm_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/desktop-menu/menu_phone_W_G.vpi", "output": "assets/images/desktop-menu/menu_phone_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/desktop-menu/menu_settings_W_G.vpi", "output": "assets/images/desktop-menu/menu_settings_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/desktop-menu/menu_tools_notes_W_G.vpi", "output": "assets/images/desktop-menu/menu_tools_notes_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/desktop-menu/menu_contacts_W_G.vpi", "output": "assets/images/desktop-menu/menu_contacts_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/desktop-menu/menu_tools_calculator_W_G.vpi", "output": "assets/images/desktop-menu/menu_tools_calculator_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/dot_12px_hard_alpha_W_M.vpi", "output": "assets/images/dot_12px_hard_alpha_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/label_rectangle_W_M.vpi", "output": "assets/images/label_rectangle_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/delete_24px_W_G.vpi", "output": "assets/images/delete_24px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/arrow_right_24px_W_G.vpi", "output": "assets/images/arrow_right_24px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/arrow_right_32px_W_G.vpi", "output": "assets/images/arrow_right_32px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/phonebook/phonebook_empty_grey_circle_speed_dial.vpi", "output": "assets/images/phonebook/phonebook_empty_grey_circle_speed_dial.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/phonebook/phonebook_speed_dial_32px_W_G.vpi", "output": "assets/images/phonebook/phonebook_speed_dial_32px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/phonebook/phonebook_blocked_32px_W_G.vpi", "output": "assets/images/phonebook/phonebook_blocked_32px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/phonebook/phonebook_heart_32px_W_M.vpi", "output": "assets/images/phonebook/phonebook_heart_32px_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/sim1_option_32px_W_G.vpi", "output": "assets/images/sim1_option_32px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/enter_icon_alpha_W_M.vpi", "output": "assets/images/enter_icon_alpha_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/logo_no_text.vpi", "output": "assets/images/logo_no_text.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_0_noconnection_W_G.vpi", "output": "assets/images/status-bar/signal/gsm_0_noconnection_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_4_W_G.vpi", "output": "assets/images/status-bar/signal/gsm_4_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_0_roaming_W_G.vpi", "output": "assets/images/status-bar/signal/gsm_0_roaming_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_3_roaming_W_M.vpi", "output": "assets/images/status-bar/signal/gsm_3_roaming_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_3_W_G.vpi", "output": "assets/images/status-bar/signal/gsm_3_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_1_W_G.vpi", "output": "assets/images/status-bar/signal/gsm_1_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_2_roaming_W_M.vpi", "output": "assets/images/status-bar/signal/gsm_2_roaming_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_3_roaming_W_G.vpi", "output": "assets/images/status-bar/signal/gsm_3_roaming_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_2_W_G.vpi", "output": "assets/images/status-bar/signal/gsm_2_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_4_LTE_roaming_W_G.vpi", "output": "assets/images/status-bar/signal/gsm_4_LTE_roaming_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_4_roaming_W_G.vpi", "output": "assets/images/status-bar/signal/gsm_4_roaming_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_0_roaming_W_M.vpi", "output": "assets/images/status-bar/signal/gsm_0_roaming_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_2_roaming_W_G.vpi", "output": "assets/images/status-bar/signal/gsm_2_roaming_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_4_W_M.vpi", "output": "assets/images/status-bar/signal/gsm_4_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_0_noconnection_W_M.vpi", "output": "assets/images/status-bar/signal/gsm_0_noconnection_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_2_W_M.vpi", "output": "assets/images/status-bar/signal/gsm_2_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_1_roaming_W_M.vpi", "output": "assets/images/status-bar/signal/gsm_1_roaming_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_4_LTE_roaming_W_M.vpi", "output": "assets/images/status-bar/signal/gsm_4_LTE_roaming_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_3_W_M.vpi", "output": "assets/images/status-bar/signal/gsm_3_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_1_roaming_W_G.vpi", "output": "assets/images/status-bar/signal/gsm_1_roaming_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_1_W_M.vpi", "output": "assets/images/status-bar/signal/gsm_1_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_4_roaming_W_M.vpi", "output": "assets/images/status-bar/signal/gsm_4_roaming_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_0_W_G.vpi", "output": "assets/images/status-bar/signal/gsm_0_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_0_W_M.vpi", "output": "assets/images/status-bar/signal/gsm_0_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/locked_status_W_G.vpi", "output": "assets/images/status-bar/locked_status_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/locked_status_W_M.vpi", "output": "assets/images/status-bar/locked_status_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/sim/sim_1_status_W_G.vpi", "output": "assets/images/status-bar/sim/sim_1_status_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/sim/sim_2_status_W_M.vpi", "output": "assets/images/status-bar/sim/sim_2_status_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/sim/no_sim_status_W_M.vpi", "output": "assets/images/status-bar/sim/no_sim_status_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/sim/no_sim_status_W_G.vpi", "output": "assets/images/status-bar/sim/no_sim_status_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/sim/sim_1_status_W_M.vpi", "output": "assets/images/status-bar/sim/sim_1_status_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/sim/sim_2_status_W_G.vpi", "output": "assets/images/status-bar/sim/sim_2_status_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/battery/battery_charging_ready_W_G.vpi", "output": "assets/images/status-bar/battery/battery_charging_ready_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/battery/battery_5_W_G.vpi", "output": "assets/images/status-bar/battery/battery_5_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/battery/battery_4_W_G.vpi", "output": "assets/images/status-bar/battery/battery_4_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/battery/battery_5_W_M.vpi", "output": "assets/images/status-bar/battery/battery_5_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/battery/battery_1_W_G.vpi", "output": "assets/images/status-bar/battery/battery_1_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/battery/battery_2_W_M.vpi", "output": "assets/images/status-bar/battery/battery_2_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/battery/battery_1_W_M.vpi", "output": "assets/images/status-bar/battery/battery_1_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/battery/battery_charging_W_M.vpi", "output": "assets/images/status-bar/battery/battery_charging_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/battery/battery_3_W_G.vpi", "output": "assets/images/status-bar/battery/battery_3_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/battery/battery_charging_ready_W_M.vpi", "output": "assets/images/status-bar/battery/battery_charging_ready_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/battery/battery_low_W_M.vpi", "output": "assets/images/status-bar/battery/battery_low_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/battery/battery_3_W_M.vpi", "output": "assets/images/status-bar/battery/battery_3_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/battery/battery_low_W_G.vpi", "output": "assets/images/status-bar/battery/battery_low_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/battery/battery_2_W_G.vpi", "output": "assets/images/status-bar/battery/battery_2_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/battery/battery_charging_W_G.vpi", "output": "assets/images/status-bar/battery/battery_charging_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/battery/battery_4_W_M.vpi", "output": "assets/images/status-bar/battery/battery_4_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/alarmclock_status_W_M.vpi", "output": "assets/images/status-bar/alarmclock_status_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/bt_connected_status_W_M.vpi", "output": "assets/images/status-bar/bt_connected_status_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/bt_connected_status_W_G.vpi", "output": "assets/images/status-bar/bt_connected_status_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/bt_status_W_G.vpi", "output": "assets/images/status-bar/bt_status_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/alarmclock_status_W_G.vpi", "output": "assets/images/status-bar/alarmclock_status_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/bt_status_W_M.vpi", "output": "assets/images/status-bar/bt_status_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/dot_12px_hard_alpha_W_G.vpi", "output": "assets/images/dot_12px_hard_alpha_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/arrow_left_20px_W_M.vpi", "output": "assets/images/arrow_left_20px_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/arrow_right_empty_32px_W_G.vpi", "output": "assets/images/arrow_right_empty_32px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/search_32px_W_G.vpi", "output": "assets/images/search_32px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/sim2_option_32px_W_G.vpi", "output": "assets/images/sim2_option_32px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/notifications/tethering_128px_W_G.vpi", "output": "assets/images/notifications/tethering_128px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/notifications/info_128px_W_G.vpi", "output": "assets/images/notifications/info_128px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/notifications/lock_128px_W_G.vpi", "output": "assets/images/notifications/lock_128px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/notifications/search_128px_W_G.vpi", "output": "assets/images/notifications/search_128px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/notifications/turn_off_128px_W_G.vpi", "output": "assets/images/notifications/turn_off_128px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/notifications/bluetooth_128px_W_G.vpi", "output": "assets/images/notifications/bluetooth_128px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/notifications/block_128px_W_G.vpi", "output": "assets/images/notifications/block_128px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/notifications/delete_128px_W_G.vpi", "output": "assets/images/notifications/delete_128px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/notifications/fail_128px_W_G.vpi", "output": "assets/images/notifications/fail_128px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/notifications/progress_128px_W_G.vpi", "output": "assets/images/notifications/progress_128px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/notifications/error_128px_W_G.vpi", "output": "assets/images/notifications/error_128px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/notifications/success_128px_W_G.vpi", "output": "assets/images/notifications/success_128px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/notifications/sim_128px_W_G.vpi", "output": "assets/images/notifications/sim_128px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/call/call_mute_W_M.vpi", "output": "assets/images/call/call_mute_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/call/call_mute_on_W_M.vpi", "output": "assets/images/call/call_mute_on_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/call/call_speaker_W_M.vpi", "output": "assets/images/call/call_speaker_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/call/call_add_W_M.vpi", "output": "assets/images/call/call_add_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/call/call_message_W_M.vpi", "output": "assets/images/call/call_message_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/call/call_speaker_on_W_M.vpi", "output": "assets/images/call/call_speaker_on_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/call/circle_top.mpi", "output": "assets/images/call/circle_top.mpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/call/circle_bottom.mpi", "output": "assets/images/call/circle_bottom.mpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/calendar_event_dot.vpi", "output": "assets/images/calendar_event_dot.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/dead_battery_W_G.vpi", "output": "assets/images/dead_battery_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/messages/messages_error_32px_W_M.vpi", "output": "assets/images/messages/messages_error_32px_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/messages/messages_reply_32px_W_M.vpi", "output": "assets/images/messages/messages_reply_32px_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/settings/empty_list_add_test_W_G_3.vpi", "output": "assets/images/settings/empty_list_add_test_W_G_3.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/settings/settings_certification_Eurlope.vpi", "output": "assets/images/settings/settings_certification_Eurlope.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/settings/settings_certification_Australia.vpi", "output": "assets/images/settings/settings_certification_Australia.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/settings/empty_list_add_test_W_G_4.vpi", "output": "assets/images/settings/empty_list_add_test_W_G_4.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/settings/settings_certification_Canada.vpi", "output": "assets/images/settings/settings_certification_Canada.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/settings/settings_certification_fc.vpi", "output": "assets/images/settings/settings_certification_fc.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/settings/settings_certification_UKCA.vpi", "output": "assets/images/settings/settings_certification_UKCA.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/settings/settings_certification_US.vpi", "output": "assets/images/settings/settings_certification_US.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/settings/empty_list_add_test_W_G_2.vpi", "output": "assets/images/settings/empty_list_add_test_W_G_2.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/settings/settings_certification_ce.vpi", "output": "assets/images/settings/settings_certification_ce.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/settings/settings_certification_ic.vpi", "output": "assets/images/settings/settings_certification_ic.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/settings/empty_list_add_test_W_G_1.vpi", "output": "assets/images/settings/empty_list_add_test_W_G_1.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/empty_list_add_W_G.vpi", "output": "assets/images/empty_list_add_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/charging_battery_W_G.vpi", "output": "assets/images/charging_battery_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/calllog/calllog_empty_128px_W_G.vpi", "output": "assets/images/calllog/calllog_empty_128px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/calllog/calllog_arrow_in_W_M.vpi", "output": "assets/images/calllog/calllog_arrow_in_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/calllog/calllog_arrow_out_W_G.vpi", "output": "assets/images/calllog/calllog_arrow_out_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/calllog/calllog_arrow_in_W_G.vpi", "output": "assets/images/calllog/calllog_arrow_in_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/calllog/calllog_arrow_den_W_G.vpi", "output": "assets/images/calllog/calllog_arrow_den_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/calllog/calllog_arrow_den_W_M.vpi", "output": "assets/images/calllog/calllog_arrow_den_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/calllog/calllog_arrow_out_W_M.vpi", "output": "assets/images/calllog/calllog_arrow_out_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/call_32px_W_G.vpi", "output": "assets/images/call_32px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/arrow_right_20px_W_M.vpi", "output": "assets/images/arrow_right_20px_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/plus_32px_W_G.vpi", "output": "assets/images/plus_32px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/messages_32px_W_G.vpi", "output": "assets/images/messages_32px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/plus_32px_W_M.vpi", "output": "assets/images/plus_32px_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/phonebook_32px_W_G.vpi", "output": "assets/images/phonebook_32px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/desktop-notifications/messages_notification_icon_W_G.vpi", "output": "assets/images/desktop-notifications/messages_notification_icon_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/desktop-notifications/lock_notification_icon_W_G.vpi", "output": "assets/images/desktop-notifications/lock_notification_icon_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/desktop-notifications/calls_notification_icon_W_G.vpi", "output": "assets/images/desktop-notifications/calls_notification_icon_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/desktop-notifications/now_playing_notification_icon_W_G.vpi", "output": "assets/images/desktop-notifications/now_playing_notification_icon_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/desktop-notifications/tethering_notification_icon_W_G.vpi", "output": "assets/images/desktop-notifications/tethering_notification_icon_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/desktop-notifications/alarm_notification_icon_W_G.vpi", "output": "assets/images/desktop-notifications/alarm_notification_icon_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/alarm/vertical_arcs_W_G.vpi", "output": "assets/images/alarm/vertical_arcs_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/alarm/snooze_icon_W_G.vpi", "output": "assets/images/alarm/snooze_icon_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/arrow_left_24px_W_G.vpi", "output": "assets/images/arrow_left_24px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/bluetooth_32px_W_M.vpi", "output": "assets/images/bluetooth_32px_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/ice_32px_W_G.vpi", "output": "assets/images/ice_32px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/logo_W_G.vpi", "output": "assets/images/logo_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/quote_W_G.vpi", "output": "assets/images/quote_W_G.vpi" },
        {"name":"release.tgz", "tarfile" :"./image/assets/images/common/alarm_colon_select_W_M.vpi", "output": "assets/images/alarm_colon_select_W_M.vpi"},
        {"name":"release.tgz", "tarfile": "./image/assets/images/music-player/mp_nowplaying_play_list_W_M.vpi", "output": "system_a/assets/images/music-player/mp_nowplaying_play_list_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/music-player/mp_note_W_G.vpi", "output": "system_a/assets/images/music-player/mp_note_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/music-player/mp_line_arrow_down_W_G.vpi", "output": "system_a/assets/images/music-player/mp_line_arrow_down_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/music-player/mp_next_gray_W_G.vpi", "output": "system_a/assets/images/music-player/mp_next_gray_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/music-player/mp_now_playing_icon_pause_W_G.vpi", "output": "system_a/assets/images/music-player/mp_now_playing_icon_pause_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/music-player/mp_prev_gray_W_G.vpi", "output": "system_a/assets/images/music-player/mp_prev_gray_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/music-player/mp_bar_W_G.vpi", "output": "system_a/assets/images/music-player/mp_bar_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/music-player/mp_next_W_G.vpi", "output": "system_a/assets/images/music-player/mp_next_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/music-player/mp_nowplaying_paused_list_W_M.vpi", "output": "system_a/assets/images/music-player/mp_nowplaying_paused_list_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/music-player/mp_pause_gray_W_G.vpi", "output": "system_a/assets/images/music-player/mp_pause_gray_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/music-player/mp_play_W_G.vpi", "output": "system_a/assets/images/music-player/mp_play_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/music-player/mp_now_playing_icon_W_G.vpi", "output": "system_a/assets/images/music-player/mp_now_playing_icon_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/music-player/mp_line_arrow_up_W_G.vpi", "output": "system_a/assets/images/music-player/mp_line_arrow_up_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/music-player/mp_now_playing_icon_pause_gray_W_G.vpi", "output": "system_a/assets/images/music-player/mp_now_playing_icon_pause_gray_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/music-player/mp_prev_W_G.vpi", "output": "system_a/assets/images/music-player/mp_prev_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/music-player/mp_pause_W_G.vpi", "output": "system_a/assets/images/music-player/mp_pause_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/music-player/mp_bar_gray_W_G.vpi", "output": "system_a/assets/images/music-player/mp_bar_gray_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/small_tick_32px_W_M.vpi", "output": "system_a/assets/images/small_tick_32px_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/arrow_left_32px_W_G.vpi", "output": "system_a/assets/images/arrow_left_32px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/desktop-menu/menu_tools_W_G.vpi", "output": "system_a/assets/images/desktop-menu/menu_tools_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/desktop-menu/menu_messages_W_G.vpi", "output": "system_a/assets/images/desktop-menu/menu_messages_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/desktop-menu/menu_meditation_W_G.vpi", "output": "system_a/assets/images/desktop-menu/menu_meditation_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/desktop-menu/menu_tools_torch_W_G.vpi", "output": "system_a/assets/images/desktop-menu/menu_tools_torch_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/desktop-menu/menu_alarm_disabled_W_G.vpi", "output": "system_a/assets/images/desktop-menu/menu_alarm_disabled_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/desktop-menu/menu_music_player_W_G.vpi", "output": "system_a/assets/images/desktop-menu/menu_music_player_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/desktop-menu/menu_tools_recorder_W_G.vpi", "output": "system_a/assets/images/desktop-menu/menu_tools_recorder_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/desktop-menu/menu_calendar_W_G.vpi", "output": "system_a/assets/images/desktop-menu/menu_calendar_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/desktop-menu/menu_alarm_W_G.vpi", "output": "system_a/assets/images/desktop-menu/menu_alarm_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/desktop-menu/menu_phone_W_G.vpi", "output": "system_a/assets/images/desktop-menu/menu_phone_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/desktop-menu/menu_settings_W_G.vpi", "output": "system_a/assets/images/desktop-menu/menu_settings_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/desktop-menu/menu_tools_notes_W_G.vpi", "output": "system_a/assets/images/desktop-menu/menu_tools_notes_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/desktop-menu/menu_contacts_W_G.vpi", "output": "system_a/assets/images/desktop-menu/menu_contacts_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/desktop-menu/menu_tools_calculator_W_G.vpi", "output": "system_a/assets/images/desktop-menu/menu_tools_calculator_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/dot_12px_hard_alpha_W_M.vpi", "output": "system_a/assets/images/dot_12px_hard_alpha_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/label_rectangle_W_M.vpi", "output": "system_a/assets/images/label_rectangle_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/delete_24px_W_G.vpi", "output": "system_a/assets/images/delete_24px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/arrow_right_24px_W_G.vpi", "output": "system_a/assets/images/arrow_right_24px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/arrow_right_32px_W_G.vpi", "output": "system_a/assets/images/arrow_right_32px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/phonebook/phonebook_empty_grey_circle_speed_dial.vpi", "output": "system_a/assets/images/phonebook/phonebook_empty_grey_circle_speed_dial.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/phonebook/phonebook_speed_dial_32px_W_G.vpi", "output": "system_a/assets/images/phonebook/phonebook_speed_dial_32px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/phonebook/phonebook_blocked_32px_W_G.vpi", "output": "system_a/assets/images/phonebook/phonebook_blocked_32px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/phonebook/phonebook_heart_32px_W_M.vpi", "output": "system_a/assets/images/phonebook/phonebook_heart_32px_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/sim1_option_32px_W_G.vpi", "output": "system_a/assets/images/sim1_option_32px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/enter_icon_alpha_W_M.vpi", "output": "system_a/assets/images/enter_icon_alpha_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/logo_no_text.vpi", "output": "system_a/assets/images/logo_no_text.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_0_noconnection_W_G.vpi", "output": "system_a/assets/images/status-bar/signal/gsm_0_noconnection_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_4_W_G.vpi", "output": "system_a/assets/images/status-bar/signal/gsm_4_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_0_roaming_W_G.vpi", "output": "system_a/assets/images/status-bar/signal/gsm_0_roaming_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_3_roaming_W_M.vpi", "output": "system_a/assets/images/status-bar/signal/gsm_3_roaming_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_3_W_G.vpi", "output": "system_a/assets/images/status-bar/signal/gsm_3_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_1_W_G.vpi", "output": "system_a/assets/images/status-bar/signal/gsm_1_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_2_roaming_W_M.vpi", "output": "system_a/assets/images/status-bar/signal/gsm_2_roaming_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_3_roaming_W_G.vpi", "output": "system_a/assets/images/status-bar/signal/gsm_3_roaming_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_2_W_G.vpi", "output": "system_a/assets/images/status-bar/signal/gsm_2_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_4_LTE_roaming_W_G.vpi", "output": "system_a/assets/images/status-bar/signal/gsm_4_LTE_roaming_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_4_roaming_W_G.vpi", "output": "system_a/assets/images/status-bar/signal/gsm_4_roaming_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_0_roaming_W_M.vpi", "output": "system_a/assets/images/status-bar/signal/gsm_0_roaming_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_2_roaming_W_G.vpi", "output": "system_a/assets/images/status-bar/signal/gsm_2_roaming_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_4_W_M.vpi", "output": "system_a/assets/images/status-bar/signal/gsm_4_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_0_noconnection_W_M.vpi", "output": "system_a/assets/images/status-bar/signal/gsm_0_noconnection_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_2_W_M.vpi", "output": "system_a/assets/images/status-bar/signal/gsm_2_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_1_roaming_W_M.vpi", "output": "system_a/assets/images/status-bar/signal/gsm_1_roaming_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_4_LTE_roaming_W_M.vpi", "output": "system_a/assets/images/status-bar/signal/gsm_4_LTE_roaming_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_3_W_M.vpi", "output": "system_a/assets/images/status-bar/signal/gsm_3_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_1_roaming_W_G.vpi", "output": "system_a/assets/images/status-bar/signal/gsm_1_roaming_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_1_W_M.vpi", "output": "system_a/assets/images/status-bar/signal/gsm_1_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_4_roaming_W_M.vpi", "output": "system_a/assets/images/status-bar/signal/gsm_4_roaming_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_0_W_G.vpi", "output": "system_a/assets/images/status-bar/signal/gsm_0_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/signal/gsm_0_W_M.vpi", "output": "system_a/assets/images/status-bar/signal/gsm_0_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/locked_status_W_G.vpi", "output": "system_a/assets/images/status-bar/locked_status_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/locked_status_W_M.vpi", "output": "system_a/assets/images/status-bar/locked_status_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/sim/sim_1_status_W_G.vpi", "output": "system_a/assets/images/status-bar/sim/sim_1_status_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/sim/sim_2_status_W_M.vpi", "output": "system_a/assets/images/status-bar/sim/sim_2_status_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/sim/no_sim_status_W_M.vpi", "output": "system_a/assets/images/status-bar/sim/no_sim_status_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/sim/no_sim_status_W_G.vpi", "output": "system_a/assets/images/status-bar/sim/no_sim_status_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/sim/sim_1_status_W_M.vpi", "output": "system_a/assets/images/status-bar/sim/sim_1_status_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/sim/sim_2_status_W_G.vpi", "output": "system_a/assets/images/status-bar/sim/sim_2_status_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/battery/battery_charging_ready_W_G.vpi", "output": "system_a/assets/images/status-bar/battery/battery_charging_ready_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/battery/battery_5_W_G.vpi", "output": "system_a/assets/images/status-bar/battery/battery_5_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/battery/battery_4_W_G.vpi", "output": "system_a/assets/images/status-bar/battery/battery_4_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/battery/battery_5_W_M.vpi", "output": "system_a/assets/images/status-bar/battery/battery_5_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/battery/battery_1_W_G.vpi", "output": "system_a/assets/images/status-bar/battery/battery_1_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/battery/battery_2_W_M.vpi", "output": "system_a/assets/images/status-bar/battery/battery_2_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/battery/battery_1_W_M.vpi", "output": "system_a/assets/images/status-bar/battery/battery_1_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/battery/battery_charging_W_M.vpi", "output": "system_a/assets/images/status-bar/battery/battery_charging_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/battery/battery_3_W_G.vpi", "output": "system_a/assets/images/status-bar/battery/battery_3_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/battery/battery_charging_ready_W_M.vpi", "output": "system_a/assets/images/status-bar/battery/battery_charging_ready_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/battery/battery_low_W_M.vpi", "output": "system_a/assets/images/status-bar/battery/battery_low_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/battery/battery_3_W_M.vpi", "output": "system_a/assets/images/status-bar/battery/battery_3_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/battery/battery_low_W_G.vpi", "output": "system_a/assets/images/status-bar/battery/battery_low_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/battery/battery_2_W_G.vpi", "output": "system_a/assets/images/status-bar/battery/battery_2_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/battery/battery_charging_W_G.vpi", "output": "system_a/assets/images/status-bar/battery/battery_charging_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/battery/battery_4_W_M.vpi", "output": "system_a/assets/images/status-bar/battery/battery_4_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/alarmclock_status_W_M.vpi", "output": "system_a/assets/images/status-bar/alarmclock_status_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/bt_connected_status_W_M.vpi", "output": "system_a/assets/images/status-bar/bt_connected_status_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/bt_connected_status_W_G.vpi", "output": "system_a/assets/images/status-bar/bt_connected_status_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/bt_status_W_G.vpi", "output": "system_a/assets/images/status-bar/bt_status_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/alarmclock_status_W_G.vpi", "output": "system_a/assets/images/status-bar/alarmclock_status_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/status-bar/bt_status_W_M.vpi", "output": "system_a/assets/images/status-bar/bt_status_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/dot_12px_hard_alpha_W_G.vpi", "output": "system_a/assets/images/dot_12px_hard_alpha_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/arrow_left_20px_W_M.vpi", "output": "system_a/assets/images/arrow_left_20px_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/arrow_right_empty_32px_W_G.vpi", "output": "system_a/assets/images/arrow_right_empty_32px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/search_32px_W_G.vpi", "output": "system_a/assets/images/search_32px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/sim2_option_32px_W_G.vpi", "output": "system_a/assets/images/sim2_option_32px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/notifications/tethering_128px_W_G.vpi", "output": "system_a/assets/images/notifications/tethering_128px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/notifications/info_128px_W_G.vpi", "output": "system_a/assets/images/notifications/info_128px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/notifications/lock_128px_W_G.vpi", "output": "system_a/assets/images/notifications/lock_128px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/notifications/search_128px_W_G.vpi", "output": "system_a/assets/images/notifications/search_128px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/notifications/turn_off_128px_W_G.vpi", "output": "system_a/assets/images/notifications/turn_off_128px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/notifications/bluetooth_128px_W_G.vpi", "output": "system_a/assets/images/notifications/bluetooth_128px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/notifications/block_128px_W_G.vpi", "output": "system_a/assets/images/notifications/block_128px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/notifications/delete_128px_W_G.vpi", "output": "system_a/assets/images/notifications/delete_128px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/notifications/fail_128px_W_G.vpi", "output": "system_a/assets/images/notifications/fail_128px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/notifications/progress_128px_W_G.vpi", "output": "system_a/assets/images/notifications/progress_128px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/notifications/error_128px_W_G.vpi", "output": "system_a/assets/images/notifications/error_128px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/notifications/success_128px_W_G.vpi", "output": "system_a/assets/images/notifications/success_128px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/notifications/sim_128px_W_G.vpi", "output": "system_a/assets/images/notifications/sim_128px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/call/call_mute_W_M.vpi", "output": "system_a/assets/images/call/call_mute_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/call/call_mute_on_W_M.vpi", "output": "system_a/assets/images/call/call_mute_on_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/call/call_speaker_W_M.vpi", "output": "system_a/assets/images/call/call_speaker_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/call/call_add_W_M.vpi", "output": "system_a/assets/images/call/call_add_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/call/call_message_W_M.vpi", "output": "system_a/assets/images/call/call_message_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/call/call_speaker_on_W_M.vpi", "output": "system_a/assets/images/call/call_speaker_on_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/call/circle_top.mpi", "output": "system_a/assets/images/call/circle_top.mpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/call/circle_bottom.mpi", "output": "system_a/assets/images/call/circle_bottom.mpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/calendar_event_dot.vpi", "output": "system_a/assets/images/calendar_event_dot.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/dead_battery_W_G.vpi", "output": "system_a/assets/images/dead_battery_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/messages/messages_error_32px_W_M.vpi", "output": "system_a/assets/images/messages/messages_error_32px_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/messages/messages_reply_32px_W_M.vpi", "output": "system_a/assets/images/messages/messages_reply_32px_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/settings/empty_list_add_test_W_G_3.vpi", "output": "system_a/assets/images/settings/empty_list_add_test_W_G_3.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/settings/settings_certification_Eurlope.vpi", "output": "system_a/assets/images/settings/settings_certification_Eurlope.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/settings/settings_certification_Australia.vpi", "output": "system_a/assets/images/settings/settings_certification_Australia.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/settings/empty_list_add_test_W_G_4.vpi", "output": "system_a/assets/images/settings/empty_list_add_test_W_G_4.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/settings/settings_certification_Canada.vpi", "output": "system_a/assets/images/settings/settings_certification_Canada.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/settings/settings_certification_fc.vpi", "output": "system_a/assets/images/settings/settings_certification_fc.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/settings/settings_certification_UKCA.vpi", "output": "system_a/assets/images/settings/settings_certification_UKCA.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/settings/settings_certification_US.vpi", "output": "system_a/assets/images/settings/settings_certification_US.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/settings/empty_list_add_test_W_G_2.vpi", "output": "system_a/assets/images/settings/empty_list_add_test_W_G_2.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/settings/settings_certification_ce.vpi", "output": "system_a/assets/images/settings/settings_certification_ce.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/settings/settings_certification_ic.vpi", "output": "system_a/assets/images/settings/settings_certification_ic.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/settings/empty_list_add_test_W_G_1.vpi", "output": "system_a/assets/images/settings/empty_list_add_test_W_G_1.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/empty_list_add_W_G.vpi", "output": "system_a/assets/images/empty_list_add_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/charging_battery_W_G.vpi", "output": "system_a/assets/images/charging_battery_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/calllog/calllog_empty_128px_W_G.vpi", "output": "system_a/assets/images/calllog/calllog_empty_128px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/calllog/calllog_arrow_in_W_M.vpi", "output": "system_a/assets/images/calllog/calllog_arrow_in_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/calllog/calllog_arrow_out_W_G.vpi", "output": "system_a/assets/images/calllog/calllog_arrow_out_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/calllog/calllog_arrow_in_W_G.vpi", "output": "system_a/assets/images/calllog/calllog_arrow_in_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/calllog/calllog_arrow_den_W_G.vpi", "output": "system_a/assets/images/calllog/calllog_arrow_den_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/calllog/calllog_arrow_den_W_M.vpi", "output": "system_a/assets/images/calllog/calllog_arrow_den_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/calllog/calllog_arrow_out_W_M.vpi", "output": "system_a/assets/images/calllog/calllog_arrow_out_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/call_32px_W_G.vpi", "output": "system_a/assets/images/call_32px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/arrow_right_20px_W_M.vpi", "output": "system_a/assets/images/arrow_right_20px_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/plus_32px_W_G.vpi", "output": "system_a/assets/images/plus_32px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/messages_32px_W_G.vpi", "output": "system_a/assets/images/messages_32px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/plus_32px_W_M.vpi", "output": "system_a/assets/images/plus_32px_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/phonebook_32px_W_G.vpi", "output": "system_a/assets/images/phonebook_32px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/desktop-notifications/messages_notification_icon_W_G.vpi", "output": "system_a/assets/images/desktop-notifications/messages_notification_icon_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/desktop-notifications/lock_notification_icon_W_G.vpi", "output": "system_a/assets/images/desktop-notifications/lock_notification_icon_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/desktop-notifications/calls_notification_icon_W_G.vpi", "output": "system_a/assets/images/desktop-notifications/calls_notification_icon_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/desktop-notifications/now_playing_notification_icon_W_G.vpi", "output": "system_a/assets/images/desktop-notifications/now_playing_notification_icon_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/desktop-notifications/tethering_notification_icon_W_G.vpi", "output": "system_a/assets/images/desktop-notifications/tethering_notification_icon_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/desktop-notifications/alarm_notification_icon_W_G.vpi", "output": "system_a/assets/images/desktop-notifications/alarm_notification_icon_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/alarm/vertical_arcs_W_G.vpi", "output": "system_a/assets/images/alarm/vertical_arcs_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/alarm/snooze_icon_W_G.vpi", "output": "system_a/assets/images/alarm/snooze_icon_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/arrow_left_24px_W_G.vpi", "output": "system_a/assets/images/arrow_left_24px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/bluetooth_32px_W_M.vpi", "output": "system_a/assets/images/bluetooth_32px_W_M.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/ice_32px_W_G.vpi", "output": "system_a/assets/images/ice_32px_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/logo_W_G.vpi", "output": "system_a/assets/images/logo_W_G.vpi" },
        {"name":"release.tgz", "tarfile": "./image/assets/images/quote_W_G.vpi", "output": "system_a/assets/images/quote_W_G.vpi" },
        {"name":"release.tgz", "tarfile" :"./image/assets/images/common/alarm_colon_select_W_M.vpi", "output": "system_a/assets/images/alarm_colon_select_W_M.vpi"},

        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/meditation/gong.mp3", "output": "assets/audio/meditation/gong.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/sms/sms_drum.mp3", "output": "assets/audio/sms/sms_drum.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/sms/sms_harpsichord.mp3", "output": "assets/audio/sms/sms_harpsichord.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/sms/sms_koshi_2.mp3", "output": "assets/audio/sms/sms_koshi_2.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/sms/sms_tibetan_bowl.mp3", "output": "assets/audio/sms/sms_tibetan_bowl.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/sms/sms_bowl.mp3", "output": "assets/audio/sms/sms_bowl.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/sms/sms_cymbals_2.mp3", "output": "assets/audio/sms/sms_cymbals_2.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/sms/sms_guitar.mp3", "output": "assets/audio/sms/sms_guitar.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/sms/sms_cymbals_3.mp3", "output": "assets/audio/sms/sms_cymbals_3.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/sms/sms_guitar_4.mp3", "output": "assets/audio/sms/sms_guitar_4.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/sms/sms_guitar_5.mp3", "output": "assets/audio/sms/sms_guitar_5.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/sms/sms_guitar_3.mp3", "output": "assets/audio/sms/sms_guitar_3.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/sms/sms_koshi_3.mp3", "output": "assets/audio/sms/sms_koshi_3.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/sms/sms_gong.mp3", "output": "assets/audio/sms/sms_gong.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/sms/sms_cymbals.mp3", "output": "assets/audio/sms/sms_cymbals.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/sms/sms_koshi.mp3", "output": "assets/audio/sms/sms_koshi.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/sms/sms_drum_2.mp3", "output": "assets/audio/sms/sms_drum_2.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/sms/sms_guitar_2.mp3", "output": "assets/audio/sms/sms_guitar_2.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/alarm/alarm_koshi.mp3", "output": "assets/audio/alarm/alarm_koshi.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/alarm/alarm_dulcimer.mp3", "output": "assets/audio/alarm/alarm_dulcimer.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/alarm/alarm_cymbals.mp3", "output": "assets/audio/alarm/alarm_cymbals.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/alarm/alarm_hang_drum.mp3", "output": "assets/audio/alarm/alarm_hang_drum.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/alarm/prewakeup/01_A_MUDITA_FINAL_DV_PROG_WAKEUP.mp3", "output": "assets/audio/alarm/prewakeup/01_A_MUDITA_FINAL_DV_PROG_WAKEUP.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/alarm/prewakeup/03_A_MUDITA_FINAL_MEDSUP_PROG_WAKEUP.mp3", "output": "assets/audio/alarm/prewakeup/03_A_MUDITA_FINAL_MEDSUP_PROG_WAKEUP.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/alarm/prewakeup/02_A_MUDITA_FINAL_BNM_PROG_WAKEUP_I.mp3", "output": "assets/audio/alarm/prewakeup/02_A_MUDITA_FINAL_BNM_PROG_WAKEUP_I.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/alarm/alarm_mudita_bell.mp3", "output": "assets/audio/alarm/alarm_mudita_bell.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/alarm/alarm_guitar.mp3", "output": "assets/audio/alarm/alarm_guitar.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/alarm/snooze/chime_bnm.mp3", "output": "assets/audio/alarm/snooze/chime_bnm.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/alarm/snooze/chime_litclo.mp3", "output": "assets/audio/alarm/snooze/chime_litclo.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/alarm/snooze/chime_dv.mp3", "output": "assets/audio/alarm/snooze/chime_dv.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/alarm/snooze/chime_medsup.mp3", "output": "assets/audio/alarm/snooze/chime_medsup.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/ringtone/ringtone_country_guitar_2.mp3", "output": "assets/audio/ringtone/ringtone_country_guitar_2.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/ringtone/ringtone_harp.mp3", "output": "assets/audio/ringtone/ringtone_harp.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/ringtone/ringtone_gong.mp3", "output": "assets/audio/ringtone/ringtone_gong.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/ringtone/ringtone_guitar_2.mp3", "output": "assets/audio/ringtone/ringtone_guitar_2.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/ringtone/ringtone_country_guitar.mp3", "output": "assets/audio/ringtone/ringtone_country_guitar.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/ringtone/ringtone_country_guitar_3.mp3", "output": "assets/audio/ringtone/ringtone_country_guitar_3.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/ringtone/ringtone_koshi_2.mp3", "output": "assets/audio/ringtone/ringtone_koshi_2.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/ringtone/ringtone_guitar_3.mp3", "output": "assets/audio/ringtone/ringtone_guitar_3.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/ringtone/ringtone_ukulele.mp3", "output": "assets/audio/ringtone/ringtone_ukulele.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/ringtone/ringtone_cymbals.mp3", "output": "assets/audio/ringtone/ringtone_cymbals.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/ringtone/ringtone_guitar_4.mp3", "output": "assets/audio/ringtone/ringtone_guitar_4.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/ringtone/ringtone_koshi.mp3", "output": "assets/audio/ringtone/ringtone_koshi.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/ringtone/ringtone_bowl.mp3", "output": "assets/audio/ringtone/ringtone_bowl.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/ringtone/ringtone_country_guitar_4.mp3", "output": "assets/audio/ringtone/ringtone_country_guitar_4.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/ringtone/ringtone_guitar.mp3", "output": "assets/audio/ringtone/ringtone_guitar.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/ringtone/ringtone_drum_2.mp3", "output": "assets/audio/ringtone/ringtone_drum_2.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/ringtone/ringtone_drum.mp3", "output": "assets/audio/ringtone/ringtone_drum.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/meditation/gong.mp3", "output": "system_a/assets/audio/meditation/gong.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/sms/sms_drum.mp3", "output": "system_a/assets/audio/sms/sms_drum.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/sms/sms_harpsichord.mp3", "output": "system_a/assets/audio/sms/sms_harpsichord.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/sms/sms_koshi_2.mp3", "output": "system_a/assets/audio/sms/sms_koshi_2.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/sms/sms_tibetan_bowl.mp3", "output": "system_a/assets/audio/sms/sms_tibetan_bowl.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/sms/sms_bowl.mp3", "output": "system_a/assets/audio/sms/sms_bowl.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/sms/sms_cymbals_2.mp3", "output": "system_a/assets/audio/sms/sms_cymbals_2.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/sms/sms_guitar.mp3", "output": "system_a/assets/audio/sms/sms_guitar.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/sms/sms_cymbals_3.mp3", "output": "system_a/assets/audio/sms/sms_cymbals_3.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/sms/sms_guitar_4.mp3", "output": "system_a/assets/audio/sms/sms_guitar_4.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/sms/sms_guitar_5.mp3", "output": "system_a/assets/audio/sms/sms_guitar_5.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/sms/sms_guitar_3.mp3", "output": "system_a/assets/audio/sms/sms_guitar_3.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/sms/sms_koshi_3.mp3", "output": "system_a/assets/audio/sms/sms_koshi_3.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/sms/sms_gong.mp3", "output": "system_a/assets/audio/sms/sms_gong.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/sms/sms_cymbals.mp3", "output": "system_a/assets/audio/sms/sms_cymbals.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/sms/sms_koshi.mp3", "output": "system_a/assets/audio/sms/sms_koshi.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/sms/sms_drum_2.mp3", "output": "system_a/assets/audio/sms/sms_drum_2.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/sms/sms_guitar_2.mp3", "output": "system_a/assets/audio/sms/sms_guitar_2.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/alarm/alarm_koshi.mp3", "output": "system_a/assets/audio/alarm/alarm_koshi.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/alarm/alarm_dulcimer.mp3", "output": "system_a/assets/audio/alarm/alarm_dulcimer.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/alarm/alarm_cymbals.mp3", "output": "system_a/assets/audio/alarm/alarm_cymbals.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/alarm/alarm_hang_drum.mp3", "output": "system_a/assets/audio/alarm/alarm_hang_drum.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/alarm/prewakeup/01_A_MUDITA_FINAL_DV_PROG_WAKEUP.mp3", "output": "system_a/assets/audio/alarm/prewakeup/01_A_MUDITA_FINAL_DV_PROG_WAKEUP.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/alarm/prewakeup/03_A_MUDITA_FINAL_MEDSUP_PROG_WAKEUP.mp3", "output": "system_a/assets/audio/alarm/prewakeup/03_A_MUDITA_FINAL_MEDSUP_PROG_WAKEUP.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/alarm/prewakeup/02_A_MUDITA_FINAL_BNM_PROG_WAKEUP_I.mp3", "output": "system_a/assets/audio/alarm/prewakeup/02_A_MUDITA_FINAL_BNM_PROG_WAKEUP_I.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/alarm/alarm_mudita_bell.mp3", "output": "system_a/assets/audio/alarm/alarm_mudita_bell.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/alarm/alarm_guitar.mp3", "output": "system_a/assets/audio/alarm/alarm_guitar.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/alarm/snooze/chime_bnm.mp3", "output": "system_a/assets/audio/alarm/snooze/chime_bnm.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/alarm/snooze/chime_litclo.mp3", "output": "system_a/assets/audio/alarm/snooze/chime_litclo.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/alarm/snooze/chime_dv.mp3", "output": "system_a/assets/audio/alarm/snooze/chime_dv.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/alarm/snooze/chime_medsup.mp3", "output": "system_a/assets/audio/alarm/snooze/chime_medsup.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/ringtone/ringtone_country_guitar_2.mp3", "output": "system_a/assets/audio/ringtone/ringtone_country_guitar_2.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/ringtone/ringtone_harp.mp3", "output": "system_a/assets/audio/ringtone/ringtone_harp.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/ringtone/ringtone_gong.mp3", "output": "system_a/assets/audio/ringtone/ringtone_gong.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/ringtone/ringtone_guitar_2.mp3", "output": "system_a/assets/audio/ringtone/ringtone_guitar_2.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/ringtone/ringtone_country_guitar.mp3", "output": "system_a/assets/audio/ringtone/ringtone_country_guitar.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/ringtone/ringtone_country_guitar_3.mp3", "output": "system_a/assets/audio/ringtone/ringtone_country_guitar_3.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/ringtone/ringtone_koshi_2.mp3", "output": "system_a/assets/audio/ringtone/ringtone_koshi_2.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/ringtone/ringtone_guitar_3.mp3", "output": "system_a/assets/audio/ringtone/ringtone_guitar_3.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/ringtone/ringtone_ukulele.mp3", "output": "system_a/assets/audio/ringtone/ringtone_ukulele.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/ringtone/ringtone_cymbals.mp3", "output": "system_a/assets/audio/ringtone/ringtone_cymbals.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/ringtone/ringtone_guitar_4.mp3", "output": "system_a/assets/audio/ringtone/ringtone_guitar_4.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/ringtone/ringtone_koshi.mp3", "output": "system_a/assets/audio/ringtone/ringtone_koshi.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/ringtone/ringtone_bowl.mp3", "output": "system_a/assets/audio/ringtone/ringtone_bowl.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/ringtone/ringtone_country_guitar_4.mp3", "output": "system_a/assets/audio/ringtone/ringtone_country_guitar_4.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/ringtone/ringtone_guitar.mp3", "output": "system_a/assets/audio/ringtone/ringtone_guitar.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/ringtone/ringtone_drum_2.mp3", "output": "system_a/assets/audio/ringtone/ringtone_drum_2.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/ringtone/ringtone_drum.mp3", "output": "system_a/assets/audio/ringtone/ringtone_drum.mp3"},

        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/music/Nick_Lewis_-_Love_Peace_Harmony.mp3", "output": "../user/audio/music_player/Nick_Lewis_-_Love_Peace_Harmony.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/music/lazy_nature_reserve-devel.mp3", "output": "../user/audio/music_player/lazy_nature_reserve-devel.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/music/Nick_Lewis_-_Que_Bien_Me_Dijo_Mi_Madre.mp3", "output": "../user/audio/music_player/Nick_Lewis_-_Que_Bien_Me_Dijo_Mi_Madre.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/music/Nick_Lewis_-_Mahamrityunjaya_Mantra.mp3", "output": "../user/audio/music_player/Nick_Lewis_-_Mahamrityunjaya_Mantra.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/music/autumn_in_jelitkowo-devel.mp3", "output": "../user/audio/music_player/autumn_in_jelitkowo-devel.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/music/Nick_Lewis_-_Love_Peace_And_Forgiveness.mp3", "output": "../user/audio/music_player/Nick_Lewis_-_Love_Peace_And_Forgiveness.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/music/Nick_Lewis_-_Bring_The_Light.mp3", "output": "../user/audio/music_player/Nick_Lewis_-_Bring_The_Light.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/music/Nick_Lewis_-_Kristies_Elephant.mp3", "output": "../user/audio/music_player/Nick_Lewis_-_Kristies_Elephant.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/music/secret_river-devel.mp3", "output": "../user/audio/music_player/secret_river-devel.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/music/beka_nature_reserve-devel.mp3", "output": "../user/audio/music_player/beka_nature_reserve-devel.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/music/Nick_Lewis_-_Always_With_You.mp3", "output": "../user/audio/music_player/Nick_Lewis_-_Always_With_You.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/music/baltic_seagulls-devel.mp3", "output": "../user/audio/music_player/baltic_seagulls-devel.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/music/Nick_Lewis_-_You_Are_Holy.mp3", "output": "../user/audio/music_player/Nick_Lewis_-_You_Are_Holy.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/music/Nick_Lewis_-_Pure_Ocean.mp3", "output": "../user/audio/music_player/Nick_Lewis_-_Pure_Ocean.mp3"}
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/music/Nick_Lewis_-_Love_Peace_Harmony.mp3", "output": "user/media/app/music_player/Nick_Lewis_-_Love_Peace_Harmony.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/music/lazy_nature_reserve-devel.mp3", "output": "user/media/app/music_player/lazy_nature_reserve-devel.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/music/Nick_Lewis_-_Que_Bien_Me_Dijo_Mi_Madre.mp3", "output": "user/media/app/music_player/Nick_Lewis_-_Que_Bien_Me_Dijo_Mi_Madre.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/music/Nick_Lewis_-_Mahamrityunjaya_Mantra.mp3", "output": "user/media/app/music_player/Nick_Lewis_-_Mahamrityunjaya_Mantra.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/music/autumn_in_jelitkowo-devel.mp3", "output": "user/media/app/music_player/autumn_in_jelitkowo-devel.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/music/Nick_Lewis_-_Love_Peace_And_Forgiveness.mp3", "output": "user/media/app/music_player/Nick_Lewis_-_Love_Peace_And_Forgiveness.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/music/Nick_Lewis_-_Bring_The_Light.mp3", "output": "user/media/app/music_player/Nick_Lewis_-_Bring_The_Light.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/music/Nick_Lewis_-_Kristies_Elephant.mp3", "output": "user/media/app/music_player/Nick_Lewis_-_Kristies_Elephant.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/music/secret_river-devel.mp3", "output": "user/media/app/music_player/secret_river-devel.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/music/beka_nature_reserve-devel.mp3", "output": "user/media/app/music_player/beka_nature_reserve-devel.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/music/Nick_Lewis_-_Always_With_You.mp3", "output": "user/media/app/music_player/Nick_Lewis_-_Always_With_You.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/music/baltic_seagulls-devel.mp3", "output": "user/media/app/music_player/baltic_seagulls-devel.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/music/Nick_Lewis_-_You_Are_Holy.mp3", "output": "user/media/app/music_player/Nick_Lewis_-_You_Are_Holy.mp3"},
        {"name" : "release_audio.tgz", "tarfile": "./image/assets/audio/pure/music/Nick_Lewis_-_Pure_Ocean.mp3", "output": "user/media/app/music_player/Nick_Lewis_-_Pure_Ocean.mp3"}
    ]
}

M test/harness => test/harness +1 -1
@@ 1,1 1,1 @@
Subproject commit 611ba529a40570016f3648601e089e12d626e947
Subproject commit 755a7f13473cd3094838dffbdccf50f93ea5e986

M tools/generate_image.sh => tools/generate_image.sh +51 -91
@@ 4,59 4,35 @@

usage() {
cat << ==usage
Usage: $(basename $0) image_path image_partitions build_dir [version.json_file] [boot.bin_file] [updater.bin_file]
Usage: $(basename $0) image_path image_partitions sysroot
    image_path        - Destination image path name e.g., PurePhone.img
    image_partitions  - Path to image_partitions.map product-specific file
    sysroot           - product's system root e.g., build-rt1051-RelWithDebInfo/sysroot
    version.json_file - version file
    boot.bin_file     - optional for linux image - name of the boot.bin file (for different targets)
    updater.bin_file  - optional for linux image - name of the updater.bin file
==usage
}

if [[ ( $# -lt 3 )  || ( $# -gt 8 ) ]]; then
if [[ ( $# -ne 3 ) ]]; then
	echo "Error! Invalid argument count $# args: $*"
	usage
	exit -1
	exit 1
fi

IMAGE_NAME=$(realpath $1)
PRODUCT_NAME=$(basename -s .img $1)
IMAGE_PARTITIONS=$(realpath $2)

SYSROOT=$(realpath $3)
LUTS=$4
VERSION_FILE=$5
BIN_FILE=$6
UPDATER_FILE=$7

if [ ! -d "$SYSROOT" ]; then
	echo "Error! ${SYSROOT} is not a directory"
	usage
	exit -1
	exit 1
fi
_REQ_CMDS="sfdisk mtools awk truncate"
_REQ_CMDS="sfdisk truncate mke2fs"
for cmd in $_REQ_CMDS; do
	if [ ! $(command -v $cmd) ]; then
		echo "Error! $cmd is not installed, please use 'sudo apt install' for install required tool"
		exit -1
		exit 1
	fi
done
#mtools version
_AWK_SCRIPT='
/[0-9]/ {
	split($4,vers,".");
	if(vers[1]>=4 && vers[2]>=0 && vers[3] >= 24) {
		print "true";
	}
	exit 0;
}'
MTOOLS_OK=$(mtools --version | awk "${_AWK_SCRIPT}")

if [ ! $MTOOLS_OK ]; then
	echo "Invalid mtools version, please upgrade mtools to >= 4.0.24"
	exit -1
fi

source ${IMAGE_PARTITIONS}
DEVICE_BLK_SIZE=512


@@ 68,81 44,62 @@ PART2_SIZE=$PART1_SIZE
PART3_START=$(($PART2_START + $PART2_SIZE))
PART3_SIZE=$(($DEVICE_BLK_COUNT - $PART1_SIZE - $PART2_SIZE - $PART1_START))

echo "Remove previous image file"
# Remove previous file
echo "Removing previous image file..."
rm -f $IMAGE_NAME
# Create image file and set its length to block device size
truncate -s $(($DEVICE_BLK_COUNT * $DEVICE_BLK_SIZE)) $IMAGE_NAME

# Create image
echo "Creating empty disk image..."
sfdisk $IMAGE_NAME << ==sfdisk
label: dos
label-id: 0x09650eb4
unit: sectors

/dev/sdx1 : start=    $PART1_START,  size=    $PART1_SIZE, type=b, bootable
/dev/sdx1 : start=    $PART1_START,  size=    $PART1_SIZE, type=83
/dev/sdx2 : start=    $PART2_START,  size=    $PART2_SIZE, type=83
/dev/sdx3 : start=    $PART3_START,  size=    $PART3_SIZE, type=83
==sfdisk


# Format FAT partitions
PART1="$IMAGE_NAME@@$(($PART1_START * $DEVICE_BLK_SIZE))"
mformat -i "$PART1" -F -T $PART1_SIZE -M $DEVICE_BLK_SIZE -v MUDITAOS

PART2="$IMAGE_NAME@@$(($PART2_START * $DEVICE_BLK_SIZE))"
mformat -i "$PART2" -F -T $PART2_SIZE -M $DEVICE_BLK_SIZE -v RECOVER

if [ ! -d "${SYSROOT}/sys" ]; then
	echo "Fatal! Image folder sys/ missing in build. Check build system."
	exit -1
# Validate image source folder
if [ ! -d "${SYSROOT}/system_a" ]; then
	echo "Fatal! Image folder 'system_a' missing in build. Check build system."
	exit 1
fi
cd "${SYSROOT}/sys"

#Copy FAT data
CURRENT_DATA="assets ${LUTS}"

mmd -i "$PART1" ::/current
mmd -i "$PART1" ::/current/sys
mmd -i "$PART1" ::/updates

for i in $CURRENT_DATA; do
	f="current/$i"
	if [ -f "$f" -o -d "$f" ]; then
		mcopy -s -i "$PART1" $f ::/current/
	else
        echo "Error! partition: $PART Unable to copy item: $(pwd)/$f"
		exit 1
	fi
done

if [[ -n "${VERSION_FILE}" && -f "${VERSION_FILE}" ]]; then
	mcopy -v -s -i "$PART1" ${VERSION_FILE} ::/current/version.json
else
	echo "Warning! Missing version.json"
	echo "(it's fine for a Linux build)"
if [ ! -d "${SYSROOT}/user" ]; then
	echo "Fatal! Image folder 'user' missing in build. Check build system."
	exit 1
fi
cd "${SYSROOT}"

if [[ -n "${BIN_FILE}" && -f "${BIN_FILE}" ]]; then
	mcopy -v -s -i "$PART1" ${BIN_FILE} ::/current/boot.bin
else
	echo "Warning! Missing boot.bin"
	echo "(it's fine for a Linux build)"
fi
# Format partitions
# Disabling of the below options is required:
# ^64bit - 64-bit inodes are not supported by lwext4
# ^metadata_csum - metadata checksums have buggy implementation in lwext4

if [[ -n "${UPDATER_FILE}" && -f "${UPDATER_FILE}" ]]; then
	mcopy -v -s -i "$PART1" ${UPDATER_FILE} ::/current/updater.bin
else
	echo "Warning! Missing updater.bin"
	echo "(it's fine for a Linux build)"
fi

mcopy -s -i "$PART1" .boot.json ::
mcopy -s -i "$PART1" .boot.json.crc32 ::

# ^64bit - 64bit inodes are not supported by the lwext4
# ^metadata_csum - Metatata checksums has buggy implementation in the lwext4
# Format ext4 system_a partition
echo "Formatting system_a partition as ext4..."
mke2fs \
  -F \
  -L 'system_a' \
  -N 0 \
  -E offset=$(($PART1_START*$DEVICE_BLK_SIZE)) \
  -O ^64bit \
  -O ^flex_bg \
  -O ^metadata_csum \
  -m 0 \
  -r 1 \
  -d 'system_a' \
  -t ext4 \
  "$IMAGE_NAME" \
  $((($PART1_SIZE*$DEVICE_BLK_SIZE)/1024))  > /dev/null

# Ext4 backup partition used by updater
# Format ext4 system_b partition
echo "Formatting system_b partition as ext4..."
mke2fs \
  -F \
  -L 'backup' \
  -L 'system_b' \
  -N 0 \
  -E offset=$(($PART2_START*$DEVICE_BLK_SIZE)) \
  -O ^64bit \


@@ 154,7 111,8 @@ mke2fs \
  "$IMAGE_NAME" \
  $((($PART2_SIZE*$DEVICE_BLK_SIZE)/1024))  > /dev/null

# EXT4 user partition
# Format ext4 user partition
echo "Formatting user partition as ext4..."
mke2fs \
  -F \
  -L 'user' \


@@ 163,13 121,15 @@ mke2fs \
  -O ^64bit \
  -O ^flex_bg \
  -O ^metadata_csum \
  -d "user" \
  -m 0 \
  -r 1 \
  -d 'user' \
  -t ext4 \
  "$IMAGE_NAME" \
  $((($PART3_SIZE*$DEVICE_BLK_SIZE)/1024)) > /dev/null

# back to previous dir
cd -
echo "Image created!"

# Back to previous dir
cd - > /dev/null
sync