From c880f90eb515870ff7787a10769f0de903251a7a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E3=81=82=E3=81=8F?= <alleteam@gmail.com>
Date: Wed, 5 May 2021 17:53:07 +0300
Subject: [PATCH] Update code owners and remove obsolete code (#446)

---
 .github/CODEOWNERS                       | 144 ++----
 applications/template/template.c.example | 104 ----
 flp/.gitignore                           |   0
 flp/Pipfile                              |  14 -
 flp/Pipfile.lock                         | 142 ------
 flp/flipper/__init__.py                  |   2 -
 flp/flipper/file.py                      | 122 -----
 flp/flp.py                               |  39 --
 lib/ui/ui.cpp                            | 589 -----------------------
 lib/ui/ui.h                              | 218 ---------
 10 files changed, 44 insertions(+), 1330 deletions(-)
 delete mode 100644 applications/template/template.c.example
 delete mode 100644 flp/.gitignore
 delete mode 100644 flp/Pipfile
 delete mode 100644 flp/Pipfile.lock
 delete mode 100644 flp/flipper/__init__.py
 delete mode 100644 flp/flipper/file.py
 delete mode 100644 flp/flp.py
 delete mode 100644 lib/ui/ui.cpp
 delete mode 100644 lib/ui/ui.h

diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 96d7194e..bd008e70 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -1,116 +1,60 @@
-# who owns all the code by default
-
+# Who owns all the code by default
 * @skotopes
 
-# unknow applications
-
+# Applications
 applications/** @skotopes
-
-# assets and asset generator
-
-assets/** @skotopes
-
-# bootloader
-
-bootloader/** @skotopes
-firmware/targets/f4/api-hal/api-hal-boot.c @skotopes
-
-# debug tools
-
-debug/** @skotopes
-
-# Core, HAL and applocation loader
-
-applications/app-loader/** @DrZlo13
-core/** @DrZlo13
-firmware/targets/api-hal-include/** @DrZlo13
-
-firmware/targets/f4/api-hal/api-hal-clock.c @skotopes
-firmware/targets/f4/api-hal/api-hal-clock.h @skotopes
-firmware/targets/f4/api-hal/api-hal-delay.c @DrZlo13
-firmware/targets/f4/api-hal/api-hal-flash.c @skotopes
-firmware/targets/f4/api-hal/api-hal-flash.h @skotopes
-firmware/targets/f4/api-hal/api-hal-gpio.c @DrZlo13
-firmware/targets/f4/api-hal/api-hal-gpio.h @DrZlo13
-firmware/targets/f4/api-hal/api-hal-pwm.c @DrZlo13
-firmware/targets/f4/api-hal/api-hal-pwm.h @DrZlo13
-firmware/targets/f4/api-hal/api-hal-resources.c @DrZlo13
-firmware/targets/f4/api-hal/api-hal-resources.h @DrZlo13
-firmware/targets/f4/api-hal/api-hal-spi-config.c @DrZlo13
-firmware/targets/f4/api-hal/api-hal-spi-config.h @DrZlo13
-firmware/targets/f4/api-hal/api-hal-spi.c @DrZlo13
-firmware/targets/f4/api-hal/api-hal-spi-config.h @DrZlo13
-firmware/targets/f4/api-hal/api-hal-tim.c @DrZlo13
-firmware/targets/f4/api-hal/api-hal-tim.h @DrZlo13
-firmware/targets/f4/api-hal/api-hal-timebase-timer.h @skotopes
-firmware/targets/f4/api-hal/api-hal-timebase.c @skotopes
-firmware/targets/f4/api-hal/api-hal-timebase.h @skotopes
-firmware/targets/f4/api-hal/api-hal-uuid.c @skotopes
-firmware/targets/f4/api-hal/api-hal-vcp.c @skotopes
-firmware/targets/f4/api-hal/api-hal.c @DrZlo13
-firmware/targets/f4/api-hal/api-interrupts.c @DrZlo13
-
-firmware/targets/f4/Src/i2c.c @skotopes
-firmware/targets/f5/Src/i2c.c @skotopes
-
-# BLE
-
-firmware/targets/f4/ble-glue/** @skotopes
+applications/accessor/** @DrZlo13
+applications/app-loader/** @gornekich
 applications/bt/** @skotopes
-firmware/targets/f4/api-hal/api-hal-bt.c @skotopes
-
-# Dolphin
-
-applications/dolphin/** @skotopes
-
-# GUI Stuff
-
+applications/cli/** @skotopes
+applications/dolphin/** @skotopes @itsyourbedtime
+applications/gpio-tester/** @skotopes
 applications/gui/** @skotopes
-applications/input/** @skotopes
-
-# iButton
-
+applications/gui-test/** @DrZlo13
 applications/ibutton/** @DrZlo13
-lib/cyfral/** @DrZlo13
-lib/onewire/** @DrZlo13
-
-# IR
-
-applications/irda/** @DrZlo13
-
-# LF-Rfid
-
-applications/lf-rfid/** @DrZlo13
-
-# Menu
-
+applications/input/** @skotopes
+applications/irda/** @DrZlo13 @albkharisov
+applications/lf-rfid/** @DrZlo13 
 applications/menu/** @skotopes
-
-# NFC
-
-applications/nfc/** @skotopes
-lib/ST25RFAL002/** @skotopes
-
-# SD Card and filesystem
-
+applications/music-player/** @DrZlo13
+applications/nfc/** @skotopes @gornekich
+applications/power/** @skotopes
 applications/sd-card-test/** @DrZlo13
 applications/sd-filesystem/** @DrZlo13
-lib/common-api/filesystem-api.h @DrZlo13
-lib/fatfs/** @DrZlo13
-firmware/targets/f4/Src/fatfs/** @DrZlo13
+applications/subghz/** @skotopes
+applications/template/** @skotopes
+applications/tests/** @skotopes @DrZlo13
 
-# Power control app
+# Assets and asset generator
+assets/** @skotopes
 
-applications/power/** @skotopes
-lib/drivers/bq* @skotopes
-firmware/targets/f4/api-hal/api-hal-power.c @skotopes
+# Bootloader
+bootloader/** @skotopes
 
-# Some applications
+# Core, HAL and applocation loader
+core/** @DrZlo13
 
-applications/music-player/** @DrZlo13
-applications/floopper-bloopper/** @skotopes
-applications/gui-test/** @DrZlo13
+# Debug tools
+debug/** @skotopes
 
+# Firmware
+firmware/** @skotopes
+
+# Lib
 lib/app-template/** @DrZlo13
-lib/qrcode/** @DrZlo13
 lib/callback-connector/** @DrZlo13
+lib/common-api/** @DrZlo13
+lib/cyfral/** @DrZlo13
+lib/drivers/** @skotopes @gornekich
+lib/fatfs/** @DrZlo13
+lib/fnv1a-hash/** @DrZlo13
+lib/mlib/** @skotopes
+lib/onewire/** @DrZlo13
+lib/qrcode/** @DrZlo13
+lib/ST25RFAL002/** @skotopes @gornekich
+lib/STM32CubeWB/** @skotopes
+lib/u8g2/** @skotopes
+lib/version/** @skotopes
+
+# Make
+make/** @skotopes
diff --git a/applications/template/template.c.example b/applications/template/template.c.example
deleted file mode 100644
index fcb9bc9d..00000000
--- a/applications/template/template.c.example
+++ /dev/null
@@ -1,104 +0,0 @@
-#include <furi.h>
-
-typedef enum {
-    EventTypeTick,
-    EventTypeKey,
-    // add your events type
-} EventType;
-
-typedef struct {
-    union {
-        InputEvent input;
-        // add your events payload
-    } value;
-    EventType type;
-} Event;
-
-typedef struct {
-    // describe state here
-} State;
-
-static void render_callback(Canvas* canvas, void* ctx) {
-    State* state = (State*)acquire_mutex((ValueMutex*)ctx, 25);
-
-    canvas_clear(canvas);
-
-    // draw your app
-
-    release_mutex((ValueMutex*)ctx, state);
-}
-
-static void input_callback(InputEvent* input_event, void* ctx) {
-    osMessageQueueId_t event_queue = (QueueHandle_t)ctx;
-
-    Event event;
-    event.type = EventTypeKey;
-    event.value.input = *input_event;
-    osMessageQueuePut(event_queue, &event, 0, 0);
-}
-
-int32_t template_app(void* p) {
-    osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(Event), NULL);
-
-    State _state;
-    /* init state here */
-    ValueMutex state_mutex;
-    if(!init_mutex(&state_mutex, &_state, sizeof(State))) {
-        printf("cannot create mutex\r\n");
-        return 255;
-    }
-
-    ViewPort* view_port = view_port_alloc();
-
-    view_port_draw_callback_set(view_port, render_callback, &state_mutex);
-    view_port_input_callback_set(view_port, input_callback, event_queue);
-
-    // Open GUI and register view_port
-    Gui* gui = furi_record_open("gui");
-    if(gui == NULL) {
-        printf("gui is not available\r\n");
-        return 255;
-    }
-    gui_add_view_port(gui, view_port, /* specify UI layer */);
-
-    Event event;
-    while(1) {
-        osStatus_t event_status = osMessageQueueGet(
-            event_queue, &event, NULL,
-            /* specify timeout */
-        );
-        State* state = (State*)acquire_mutex_block(&state_mutex);
-
-        if(event_status == osOK) {
-            if(event.type == EventTypeKey) {
-                // press events
-                if(event.value.input.type == InputTypeShort && event.value.input.key == InputKeyBack) {
-                }
-
-                if(event.value.input.type == InputTypeShort && event.value.input.key == InputKeyUp) {
-                }
-
-                if(event.value.input.type == InputTypeShort && event.value.input.key == InputKeyDown) {
-                }
-
-                if(event.value.input.type == InputTypeShort && event.value.input.key == InputKeyLeft) {
-                }
-
-                if(event.value.input.type == InputTypeShort && event.value.input.key == InputKeyRight) {
-                }
-
-                if(event.value.input.key == InputKeyOk) {
-                }
-            }
-        } else {
-            // event timeout
-        }
-
-        // common code, for example, force update UI
-        // view_port_update(view_port);
-
-        release_mutex(&state_mutex, state);
-    }
-
-    return 0;
-}
diff --git a/flp/.gitignore b/flp/.gitignore
deleted file mode 100644
index e69de29b..00000000
diff --git a/flp/Pipfile b/flp/Pipfile
deleted file mode 100644
index bf2a7263..00000000
--- a/flp/Pipfile
+++ /dev/null
@@ -1,14 +0,0 @@
-[[source]]
-name = "pypi"
-url = "https://pypi.org/simple"
-verify_ssl = true
-
-[dev-packages]
-black = "20.8b1"
-
-[packages]
-pyserial = "3.4"
-click = "7.1.2"
-
-[requires]
-python_version = "3.8"
diff --git a/flp/Pipfile.lock b/flp/Pipfile.lock
deleted file mode 100644
index bc5c414b..00000000
--- a/flp/Pipfile.lock
+++ /dev/null
@@ -1,142 +0,0 @@
-{
-    "_meta": {
-        "hash": {
-            "sha256": "62bedeef792c73b899be0e307396e579f1af2d0c1d49dbccc252cc14e11e50d4"
-        },
-        "pipfile-spec": 6,
-        "requires": {
-            "python_version": "3.8"
-        },
-        "sources": [
-            {
-                "name": "pypi",
-                "url": "https://pypi.org/simple",
-                "verify_ssl": true
-            }
-        ]
-    },
-    "default": {
-        "click": {
-            "hashes": [
-                "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a",
-                "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"
-            ],
-            "index": "pypi",
-            "version": "==7.1.2"
-        },
-        "pyserial": {
-            "hashes": [
-                "sha256:6e2d401fdee0eab996cf734e67773a0143b932772ca8b42451440cfed942c627",
-                "sha256:e0770fadba80c31013896c7e6ef703f72e7834965954a78e71a3049488d4d7d8"
-            ],
-            "index": "pypi",
-            "version": "==3.4"
-        }
-    },
-    "develop": {
-        "appdirs": {
-            "hashes": [
-                "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41",
-                "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"
-            ],
-            "version": "==1.4.4"
-        },
-        "black": {
-            "hashes": [
-                "sha256:1c02557aa099101b9d21496f8a914e9ed2222ef70336404eeeac8edba836fbea",
-                "sha256:70b62ef1527c950db59062cda342ea224d772abdf6adc58b86a45421bab20a6b"
-            ],
-            "index": "pypi",
-            "version": "==20.8b1"
-        },
-        "click": {
-            "hashes": [
-                "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a",
-                "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"
-            ],
-            "index": "pypi",
-            "version": "==7.1.2"
-        },
-        "mypy-extensions": {
-            "hashes": [
-                "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d",
-                "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"
-            ],
-            "version": "==0.4.3"
-        },
-        "pathspec": {
-            "hashes": [
-                "sha256:7d91249d21749788d07a2d0f94147accd8f845507400749ea19c1ec9054a12b0",
-                "sha256:da45173eb3a6f2a5a487efba21f050af2b41948be6ab52b6a1e3ff22bb8b7061"
-            ],
-            "version": "==0.8.0"
-        },
-        "regex": {
-            "hashes": [
-                "sha256:0dc64ee3f33cd7899f79a8d788abfbec168410be356ed9bd30bbd3f0a23a7204",
-                "sha256:1269fef3167bb52631ad4fa7dd27bf635d5a0790b8e6222065d42e91bede4162",
-                "sha256:14a53646369157baa0499513f96091eb70382eb50b2c82393d17d7ec81b7b85f",
-                "sha256:3a3af27a8d23143c49a3420efe5b3f8cf1a48c6fc8bc6856b03f638abc1833bb",
-                "sha256:46bac5ca10fb748d6c55843a931855e2727a7a22584f302dd9bb1506e69f83f6",
-                "sha256:4c037fd14c5f4e308b8370b447b469ca10e69427966527edcab07f52d88388f7",
-                "sha256:51178c738d559a2d1071ce0b0f56e57eb315bcf8f7d4cf127674b533e3101f88",
-                "sha256:5ea81ea3dbd6767873c611687141ec7b06ed8bab43f68fad5b7be184a920dc99",
-                "sha256:6961548bba529cac7c07af2fd4d527c5b91bb8fe18995fed6044ac22b3d14644",
-                "sha256:75aaa27aa521a182824d89e5ab0a1d16ca207318a6b65042b046053cfc8ed07a",
-                "sha256:7a2dd66d2d4df34fa82c9dc85657c5e019b87932019947faece7983f2089a840",
-                "sha256:8a51f2c6d1f884e98846a0a9021ff6861bdb98457879f412fdc2b42d14494067",
-                "sha256:9c568495e35599625f7b999774e29e8d6b01a6fb684d77dee1f56d41b11b40cd",
-                "sha256:9eddaafb3c48e0900690c1727fba226c4804b8e6127ea409689c3bb492d06de4",
-                "sha256:bbb332d45b32df41200380fff14712cb6093b61bd142272a10b16778c418e98e",
-                "sha256:bc3d98f621898b4a9bc7fecc00513eec8f40b5b83913d74ccb445f037d58cd89",
-                "sha256:c11d6033115dc4887c456565303f540c44197f4fc1a2bfb192224a301534888e",
-                "sha256:c50a724d136ec10d920661f1442e4a8b010a4fe5aebd65e0c2241ea41dbe93dc",
-                "sha256:d0a5095d52b90ff38592bbdc2644f17c6d495762edf47d876049cfd2968fbccf",
-                "sha256:d6cff2276e502b86a25fd10c2a96973fdb45c7a977dca2138d661417f3728341",
-                "sha256:e46d13f38cfcbb79bfdb2964b0fe12561fe633caf964a77a5f8d4e45fe5d2ef7"
-            ],
-            "version": "==2020.7.14"
-        },
-        "toml": {
-            "hashes": [
-                "sha256:926b612be1e5ce0634a2ca03470f95169cf16f939018233a670519cb4ac58b0f",
-                "sha256:bda89d5935c2eac546d648028b9901107a595863cb36bae0c73ac804a9b4ce88"
-            ],
-            "version": "==0.10.1"
-        },
-        "typed-ast": {
-            "hashes": [
-                "sha256:0666aa36131496aed8f7be0410ff974562ab7eeac11ef351def9ea6fa28f6355",
-                "sha256:0c2c07682d61a629b68433afb159376e24e5b2fd4641d35424e462169c0a7919",
-                "sha256:249862707802d40f7f29f6e1aad8d84b5aa9e44552d2cc17384b209f091276aa",
-                "sha256:24995c843eb0ad11a4527b026b4dde3da70e1f2d8806c99b7b4a7cf491612652",
-                "sha256:269151951236b0f9a6f04015a9004084a5ab0d5f19b57de779f908621e7d8b75",
-                "sha256:4083861b0aa07990b619bd7ddc365eb7fa4b817e99cf5f8d9cf21a42780f6e01",
-                "sha256:498b0f36cc7054c1fead3d7fc59d2150f4d5c6c56ba7fb150c013fbc683a8d2d",
-                "sha256:4e3e5da80ccbebfff202a67bf900d081906c358ccc3d5e3c8aea42fdfdfd51c1",
-                "sha256:6daac9731f172c2a22ade6ed0c00197ee7cc1221aa84cfdf9c31defeb059a907",
-                "sha256:715ff2f2df46121071622063fc7543d9b1fd19ebfc4f5c8895af64a77a8c852c",
-                "sha256:73d785a950fc82dd2a25897d525d003f6378d1cb23ab305578394694202a58c3",
-                "sha256:8c8aaad94455178e3187ab22c8b01a3837f8ee50e09cf31f1ba129eb293ec30b",
-                "sha256:8ce678dbaf790dbdb3eba24056d5364fb45944f33553dd5869b7580cdbb83614",
-                "sha256:aaee9905aee35ba5905cfb3c62f3e83b3bec7b39413f0a7f19be4e547ea01ebb",
-                "sha256:bcd3b13b56ea479b3650b82cabd6b5343a625b0ced5429e4ccad28a8973f301b",
-                "sha256:c9e348e02e4d2b4a8b2eedb48210430658df6951fa484e59de33ff773fbd4b41",
-                "sha256:d205b1b46085271b4e15f670058ce182bd1199e56b317bf2ec004b6a44f911f6",
-                "sha256:d43943ef777f9a1c42bf4e552ba23ac77a6351de620aa9acf64ad54933ad4d34",
-                "sha256:d5d33e9e7af3b34a40dc05f498939f0ebf187f07c385fd58d591c533ad8562fe",
-                "sha256:fc0fea399acb12edbf8a628ba8d2312f583bdbdb3335635db062fa98cf71fca4",
-                "sha256:fe460b922ec15dd205595c9b5b99e2f056fd98ae8f9f56b888e7a17dc2b757e7"
-            ],
-            "version": "==1.4.1"
-        },
-        "typing-extensions": {
-            "hashes": [
-                "sha256:7cb407020f00f7bfc3cb3e7881628838e69d8f3fcab2f64742a5e76b2f841918",
-                "sha256:99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c",
-                "sha256:dafc7639cde7f1b6e1acc0f457842a83e722ccca8eef5270af2d74792619a89f"
-            ],
-            "version": "==3.7.4.3"
-        }
-    }
-}
diff --git a/flp/flipper/__init__.py b/flp/flipper/__init__.py
deleted file mode 100644
index a8b7b81c..00000000
--- a/flp/flipper/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-from flipper import file
-from flipper.file import File
diff --git a/flp/flipper/file.py b/flp/flipper/file.py
deleted file mode 100644
index 2539ec94..00000000
--- a/flp/flipper/file.py
+++ /dev/null
@@ -1,122 +0,0 @@
-from enum import Enum
-
-import serial
-
-
-class RemoteIOError(IOError):
-    pass
-
-
-class UnsupportedOperation(RemoteIOError):
-    # TODO: Tell more on error
-    pass
-
-
-class ReadWriteError(RemoteIOError):
-    pass
-
-
-class FileMode(Enum):
-    READ = "r"
-    WRITE = "w"
-    # APPEND = "a" - Not Impl
-    # READ_WRITE = "w+"
-    # READ_APPEND = "a+"
-
-
-class File:
-    opened: bool = False
-    filename: str
-    conn: serial.Serial
-    mode = FileMode.READ
-
-    def _open(self):
-        # Opening file on Flipper's end
-        self.conn.write(f"f_open {self.filename} {self.mode}\n".encode())
-
-        # Checking, if everything is OK.
-        self.conn.write(b"f_valid\n")
-        return bool(int(self.conn.read_until().decode()))
-
-    def __init__(self, conn: serial.Serial, filename: str, mode=FileMode.READ):
-        self.conn = conn
-        self.mode = mode
-        self.filename = filename
-
-        if not self._open():
-            raise RemoteIOError
-        self.opened = True
-
-    def lseek(self, size: int):
-        self.conn.write(f"f_lseek {size}\n".encode())
-
-    def tell(self):
-        self.conn.write(b"f_tell\n")
-        return int(self.conn.read_until().decode())
-
-    def size(self):
-        self.conn.write(b"f_size\n")
-        return int(self.conn.read_until().decode())
-
-    def write(self, data: bytes):
-        if self.mode != FileMode.WRITE:
-            raise UnsupportedOperation
-        self.conn.write(f"f_write {len(data)}\n".encode())
-        self.conn.write(data)
-        self.conn.write(b"\n")
-
-        if self.conn.read_until().decode().strip() != "OK":
-            raise ReadWriteError
-
-    def read(self, size: int) -> bytes:
-        self.conn.write(f"f_read {size}\n".encode())
-        return self.conn.read(size)
-
-    def _close(self):
-        self.conn.write(b"f_close\n")
-
-    def close(self):
-        self._close()
-        # TODO: Add termination of remote file process.
-        del self
-
-    def read_all(self, block_size=128) -> bytes:
-        """
-        Function to simplify reading of file over serial.
-
-        :return: content of file represented in `bytes`
-        """
-        size = self.size()
-        a = bytearray()
-        seek = 0
-        # Reading in blocks of block_size
-        while seek < block_size * (size // block_size - 1):
-            seek += block_size
-            self.lseek(seek)
-            a.extend(self.read(block_size))
-
-        seek += block_size
-        self.lseek(seek)
-        a.extend(self.read(size - seek))  # Appending mod
-
-        self.lseek(0)  # Resetting seek to default-position
-
-        return bytes(a)
-
-
-def push(ser: serial.Serial, local_path, remote_path):
-    with open(local_path, "rb") as local_f:  # Reading local file
-        a = local_f.read()
-
-    remote_f = File(ser, remote_path, FileMode.WRITE)
-    remote_f.write(a)
-    remote_f.close()
-
-
-def pull(ser: serial.Serial, remote_path, local_path):
-    remote_f = File(ser, remote_path, FileMode.READ)
-
-    with open(local_path, "wb") as f:
-        f.write(remote_f.read_all())
-
-    remote_f.close()
diff --git a/flp/flp.py b/flp/flp.py
deleted file mode 100644
index 0ef5a870..00000000
--- a/flp/flp.py
+++ /dev/null
@@ -1,39 +0,0 @@
-import flipper
-import serial
-import click
-
-DEFAULT_TTY = "/dev/ttyUSB0"
-
-
-@click.group()
-def cli():
-    pass
-
-
-@cli.group()
-def fs():
-    pass
-
-
-@fs.command()
-@click.argument("file_in", type=click.Path(exists=True))
-@click.argument("file_out")
-@click.option("--port", default=DEFAULT_TTY)
-def push(file_in, file_out, port):
-    with serial.Serial(port, 115200, timeout=10) as p:
-        flipper.file.push(p, file_in, file_out)
-    print("OK.")
-
-
-@fs.command()
-@click.argument("file_in")
-@click.argument("file_out", type=click.Path())
-@click.option("--port", default=DEFAULT_TTY)
-def pull(file_in, file_out, port):
-    with serial.Serial(port, 115200, timeout=10) as p:
-        flipper.file.pull(p, file_in, file_out)
-    print("OK.")
-
-
-if __name__ == "__main__":
-    cli()
diff --git a/lib/ui/ui.cpp b/lib/ui/ui.cpp
deleted file mode 100644
index 61f73dae..00000000
--- a/lib/ui/ui.cpp
+++ /dev/null
@@ -1,589 +0,0 @@
-#include <stdio.h>
-
-extern "C" {
-    #include "main.h"
-    #include "cmsis_os.h"
-    #include "u8g2_support.h"
-    #include "u8g2/u8g2.h"
-}
-
-#include "ui.h"
-#include "events.h"
-
-// function draw basic layout -- single bmp
-void draw_bitmap(const char* bitmap, u8g2_t* u8g2, ScreenArea area) {
-    if(bitmap == NULL) {
-        printf("[basic layout] no content\n");
-        u8g2_SetFont(u8g2, u8g2_font_6x10_mf);
-        u8g2_SetDrawColor(u8g2, 1);
-        u8g2_SetFontMode(u8g2, 1);
-        u8g2_DrawStr(u8g2, 2, 12, "no content");
-    } else {
-        u8g2_SetDrawColor(u8g2, 1);
-        u8g2_DrawXBM(u8g2, 0, 0, area.x + area.width, area.y + area.height, (unsigned char*)bitmap);
-    }
-}
-
-void draw_text(const char* text, u8g2_t* u8g2, ScreenArea area) {
-    // TODO proper cleanup statusbar
-    u8g2_SetDrawColor(u8g2, 0);
-    u8g2_DrawBox(u8g2, 0, 0, area.x + area.width, area.y + area.height);
-
-    Block text_block = Block {
-        width: area.width,
-        height: area.height,
-        margin_left: 0,
-        margin_top: 0,
-        padding_left: 3,
-        padding_top: 7,
-        background: 0,
-        color: 1,
-        font: (uint8_t*)u8g2_font_6x10_mf,
-    };
-
-    draw_block(u8g2, text, text_block, area.x, area.y);
-}
-
-// draw layout and switch between ui item by button and timer
-void LayoutComponent::handle(Event* event, Store* store, u8g2_t* u8g2, ScreenArea area) {
-    switch(event->type) {
-        // get button event
-        case EventTypeButton:
-            if(event->value.button.state) {
-                for(size_t i = 0; i < this->actions_size; i++) {
-                    FlipperComponent* next = NULL;
-
-                    switch(this->actions[i].action) {
-                        case LayoutActionUp:
-                            if(event->value.button.id == ButtonsUp) {
-                                next = this->actions[i].item;
-                            }
-                        break;
-                        case LayoutActionDown:
-                            if(event->value.button.id == ButtonsDown) {
-                                next = this->actions[i].item;
-                            }
-                        break;
-                        case LayoutActionLeft:
-                            if(event->value.button.id == ButtonsLeft) {
-                                next = this->actions[i].item;
-                            }
-                        break;
-                        case LayoutActionRight:
-                            if(event->value.button.id == ButtonsRight) {
-                                next = this->actions[i].item;
-                            }
-                        break;
-                        case LayoutActionOk:
-                            if(event->value.button.id == ButtonsOk) {
-                                next = this->actions[i].item;
-                            }
-                        break;
-                        case LayoutActionBack:
-                            if(event->value.button.id == ButtonsBack) {
-                                next = this->actions[i].item;
-                            }
-                        break;
-
-                        // stub action
-                        case LayoutActionUsbDisconnect:
-                            if(event->value.button.id == ButtonsLeft) {
-                                next = this->actions[i].item;
-                            }
-                        break;
-
-                        case LayoutActionUsbConnect:
-                            if(event->value.button.id == ButtonsRight) {
-                                next = this->actions[i].item;
-                            }
-                        break;
-
-                        default: break;
-                    }
-
-                    if(next) {
-                        printf("[layout view] go to next item\n");
-                        Event send_event;
-                        send_event.type = EventTypeUiNext;
-                        next->handle(
-                            &send_event,
-                            store,
-                            u8g2,
-                            area
-                        );
-                    }
-                }
-            }
-        break;
-
-        case EventTypeUsb: {
-            printf("get usb event\n");
-            
-            FlipperComponent* next = NULL;
-
-            if(event->value.usb == UsbEventConnect) {
-                for(size_t i = 0; i < this->actions_size; i++) {
-                    if(this->actions[i].action == LayoutActionUsbConnect) {
-                        next = this->actions[i].item;
-                    }
-                }
-            }
-
-            if(event->value.usb == UsbEventDisconnect) {
-                for(size_t i = 0; i < this->actions_size; i++) {
-                    if(this->actions[i].action == LayoutActionUsbDisconnect) {
-                        next = this->actions[i].item;
-                    }
-                }
-            }
-
-            if(next) {
-                printf("[layout view] go to next item\n");
-                Event send_event;
-                send_event.type = EventTypeUiNext;
-                next->handle(
-                    &send_event,
-                    store,
-                    u8g2,
-                    area
-                );
-            }
-        } break;
-
-        // start component from prev
-        case EventTypeUiNext:
-            printf("[layout view] start component %lX\n", (uint32_t)this);
-
-            if(this->timeout > 0) {
-                // TODO start timer
-            }
-
-            // set current item to self
-            store->current_component = this;
-
-            this->wait_time = 0;
-
-            // render layout
-            this->dirty = true;
-        break;
-
-        case EventTypeTick:
-            this->wait_time += event->value.tick_delta;
-
-            if(this->wait_time > this->timeout) {
-                for(size_t i = 0; i < this->actions_size; i++) {
-                    if(this->actions[i].action == LayoutActionTimeout ||
-                        this->actions[i].action == LayoutActionEndOfCycle
-                    ) {
-                        if(this->actions[i].item != NULL) {
-                            printf("[layout view] go to next item\n");
-                            Event send_event;
-                            send_event.type = EventTypeUiNext;
-                            this->actions[i].item->handle(
-                                &send_event,
-                                store,
-                                u8g2,
-                                area
-                            );
-
-                            return;
-                        }
-                    }
-                }
-            }
-
-            if(this->dirty) {
-                this->draw_fn(this->data, u8g2, area);
-
-                store->dirty_screen = true;
-
-                this->dirty = false;
-            }
-        break;
-
-        default: break;
-    }
-}
-
-void BlinkerComponent::handle(Event* event, Store* store, u8g2_t* u8g2, ScreenArea area) {
-    switch(event->type) {
-        // get button event
-        case EventTypeButton:
-            if(event->value.button.state && event->value.button.id == ButtonsBack) {
-                if(this->prev && this->prev != this) {
-                    printf("[blinker view] go back\n");
-
-                    Event send_event;
-                    send_event.type = EventTypeUiNext;
-                    this->prev->handle(
-                        &send_event,
-                        store,
-                        u8g2,
-                        area
-                    );
-
-                    this->prev = NULL;
-
-                    store->led = ColorBlack;
-                    this->wait_time = 0;
-                    this->is_on = true;
-                    this->active = false;
-                } else {
-                    printf("[blinker view] no back/loop\n");
-                }
-            }
-
-            if(event->value.button.state && event->value.button.id != ButtonsBack) {
-                this->active = false;
-            }
-
-            if(!event->value.button.state && event->value.button.id != ButtonsBack) {
-                this->active = true;
-            }
-        break;
-
-        // start component from prev
-        case EventTypeUiNext:
-            printf("[blinker view] start component %lX\n", (uint32_t)this);
-
-            if(this->prev == NULL) {
-                this->prev = store->current_component;
-            }
-
-            // set current item to self
-            store->current_component = this;
-
-            this->dirty = true;
-            this->wait_time = 0;
-            this->is_on = true;
-            this->active = false;
-        break;
-
-        case EventTypeTick:
-            if(this->active) {
-                this->wait_time += event->value.tick_delta;
-
-                if(this->is_on) {
-                    if(this->wait_time > this->config.on_time) {
-                        this->wait_time = 0;
-                        this->is_on = false;
-                    }
-                } else {
-                    if(this->wait_time > this->config.off_time) {
-                        this->wait_time = 0;
-                        this->is_on = true;
-                    }
-                }
-
-                store->led = this->is_on ? this->config.on_color : this->config.off_color;
-            } else {
-                store->led = ColorBlack;
-                this->wait_time = 0;
-                this->is_on = true;
-            }
-
-            if(this->dirty) {
-                this->draw_fn(this->data, u8g2, area);
-
-                store->dirty_screen = true;
-
-                this->dirty = false;
-            }
-        break;
-
-        default: break;
-    }
-}
-void BlinkerComponentOnBtn::handle(Event* event, Store* store, u8g2_t* u8g2, ScreenArea area) {
-    switch(event->type) {
-        // get button event
-        case EventTypeButton:
-            if(event->value.button.state && event->value.button.id == ButtonsBack) {
-                if(this->prev && this->prev != this) {
-                    printf("[blinker view] go back\n");
-
-                    Event send_event;
-                    send_event.type = EventTypeUiNext;
-                    this->prev->handle(
-                        &send_event,
-                        store,
-                        u8g2,
-                        area
-                    );
-
-                    this->prev = NULL;
-
-                    store->led = ColorBlack;
-                    this->wait_time = 0;
-                    this->is_on = true;
-                    this->active = false;
-                } else {
-                    printf("[blinker view] no back/loop\n");
-                }
-            }
-
-            if(event->value.button.state && event->value.button.id != ButtonsBack) {
-                this->active = true;
-            }
-
-            if(!event->value.button.state && event->value.button.id != ButtonsBack) {
-                this->active = false;
-            }
-        break;
-
-        // start component from prev
-        case EventTypeUiNext:
-            printf("[blinker view] start component %lX\n", (uint32_t)this);
-
-            if(this->prev == NULL) {
-                this->prev = store->current_component;
-            }
-
-            // set current item to self
-            store->current_component = this;
-
-            this->dirty = true;
-            this->wait_time = 0;
-            this->is_on = true;
-            this->active = false;
-        break;
-
-        case EventTypeTick:
-            if(this->active) {
-                this->wait_time += event->value.tick_delta;
-
-                if(this->is_on) {
-                    if(this->wait_time > this->config.on_time) {
-                        this->wait_time = 0;
-                        this->is_on = false;
-                    }
-                } else {
-                    if(this->wait_time > this->config.off_time) {
-                        this->wait_time = 0;
-                        this->is_on = true;
-                    }
-                }
-
-                store->led = this->is_on ? this->config.on_color : this->config.off_color;
-            } else {
-                store->led = ColorBlack;
-                this->wait_time = 0;
-                this->is_on = true;
-            }
-
-            if(this->dirty) {
-                this->draw_fn(this->data, u8g2, area);
-
-                store->dirty_screen = true;
-
-                this->dirty = false;
-            }
-        break;
-
-        default: break;
-    }
-}
-
-#define MENU_DRAW_LINES 4
-
-Point draw_block(u8g2_t* u8g2, const char* text, Block layout, uint8_t x, uint8_t y) {
-    u8g2_SetDrawColor(u8g2, layout.background);
-    u8g2_DrawBox(u8g2,
-        x + layout.margin_left,
-        y + layout.margin_top,
-        layout.width, layout.height
-    );
-
-    u8g2_SetDrawColor(u8g2, layout.color);
-    u8g2_SetFont(u8g2, layout.font);
-    if(text != NULL) {
-        u8g2_DrawStr(u8g2,
-            x + layout.margin_left + layout.padding_left,
-            y + layout.margin_top + layout.padding_top,
-            text
-        );
-    }
-
-    return {
-        x: x + layout.margin_left + layout.width,
-        y: y + layout.margin_top + layout.height
-    };
-}
-
-void draw_menu(MenuCtx* ctx, u8g2_t* u8g2, ScreenArea area) {
-    // u8g2_ClearBuffer(u8g2);
-    // clear area
-    u8g2_SetDrawColor(u8g2, 0);
-    u8g2_DrawBox(u8g2, area.x, area.y, area.width, area.height);
-
-    u8g2_SetFontMode(u8g2, 1);
-
-    uint8_t list_start = ctx->current - ctx->cursor;
-    uint8_t list_size = ctx->size > MENU_DRAW_LINES ? MENU_DRAW_LINES : ctx->size;
-
-    // draw header
-    /*
-    Point next = draw_block(u8g2, (const char*)data->name, Block {
-        width: 128,
-        height: 14,
-        margin_left: 0,
-        margin_top: 0,
-        padding_left: 4,
-        padding_top: 13,
-        background: 1,
-        color: 0,
-        font: (uint8_t*)u8g2_font_helvB14_tf,
-    }, area.x, area.y);
-    */
-
-    Point next = {area.x, area.y};
-
-    for(size_t i = 0; i < list_size; i++) {
-        next = draw_block(u8g2, (const char*)ctx->list[list_start + i].name, Block {
-            width: 128,
-            height: 15,
-            margin_left: 0,
-            margin_top: i == 0 ? 2 : 0,
-            padding_left: 2,
-            padding_top: 12,
-            background: i == ctx->cursor ? 1 : 0,
-            color: i == ctx->cursor ? 0 : 1,
-            font: (uint8_t*)u8g2_font_7x14_tf,
-        }, area.x, next.y);
-    }
-
-    // u8g2_font_7x14_tf
-    // u8g2_font_profont12_tf smallerbut cute
-    // u8g2_font_samim_12_t_all орочий
-}
-
-void MenuCtx::handle(MenuEvent event) {
-    uint8_t menu_size = this->size > MENU_DRAW_LINES ? MENU_DRAW_LINES : this->size;
-
-    switch(event) {
-        case MenuEventDown: {
-            if(this->current < (this->size - 1)) {
-                this->current++;
-
-                if(this->cursor < menu_size - 2 || this->current == this->size - 1) {
-                    this->cursor++;
-                }
-            } else {
-                this->current = 0;
-                this->cursor = 0;
-            }
-        } break;
-
-        case MenuEventUp: {
-            if(this->current > 0) {
-                this->current--;
-
-                if(this->cursor > 1 || this->current == 0) {
-                    this->cursor--;
-                }
-
-            } else {
-                this->current = this->size - 1;
-                this->cursor = menu_size - 1;
-            }
-        } break;
-    }
-}
-
-void MenuCtx::reset() {
-    this->current = 0;
-    this->cursor = 0;
-}
-
-// draw numenu and handle navigation
-void MenuComponent::handle(Event* event, Store* store, u8g2_t* u8g2, ScreenArea area) {
-    switch(event->type) {
-        // get button event
-        case EventTypeButton: {
-            if(event->value.button.id == ButtonsOk && event->value.button.state) {
-                if(this->ctx.current < this->ctx.size) {
-                    FlipperComponent* next_item = (FlipperComponent*)this->ctx.list[this->ctx.current].item;
-
-                    if(next_item) {
-                        store->is_fullscreen = false;
-
-                        printf("[layout view] go to %d item\n", this->ctx.current);
-                        Event send_event;
-                        send_event.type = EventTypeUiNext;
-
-                        next_item->handle(
-                            &send_event,
-                            store,
-                            u8g2,
-                            area
-                        );
-                    } else {
-                        printf("[menu view] no item at %d\n", this->ctx.current);
-                    }
-                }
-            }
-
-            if(event->value.button.id == ButtonsDown && event->value.button.state) {
-                this->ctx.handle(MenuEventDown);
-                this->dirty = true;
-            }
-
-            if(event->value.button.id == ButtonsUp && event->value.button.state) {
-                this->ctx.handle(MenuEventUp);
-                this->dirty = true;
-            }
-
-            // go back item
-            if(event->value.button.id == ButtonsBack && event->value.button.state) {
-                if(this->prev && this->prev != this) {
-                    store->is_fullscreen = false;
-
-                    printf("[menu view] go back\n");
-
-                    this->ctx.reset();
-
-                    Event send_event;
-                    send_event.type = EventTypeUiNext;
-                    this->prev->handle(
-                        &send_event,
-                        store,
-                        u8g2,
-                        area
-                    );
-
-                    this->prev = NULL;
-                } else {
-                    printf("[menu view] no back/loop\n");
-                }
-            }
-        } break;
-
-        // start component from prev
-        case EventTypeUiNext:
-            printf("[menu view] start component %lX (size %d)\n", (uint32_t)this, this->ctx.size);
-
-            // set prev item
-            if(this->prev == NULL) {
-                printf("[menu view] set prev element to %lX\n", (uint32_t)store->current_component);
-                this->prev = store->current_component;
-            }
-            // set current item to self
-            store->current_component = this;
-
-            store->is_fullscreen = true;
-
-            // render menu
-            this->dirty = true;
-        break;
-
-        case EventTypeTick:
-            if(this->dirty) {
-                draw_menu(&this->ctx, u8g2, area);
-                store->dirty_screen = true;
-                this->dirty = false;
-            }
-        break;
-
-        default: break;
-    }
-}
diff --git a/lib/ui/ui.h b/lib/ui/ui.h
deleted file mode 100644
index 0eb89bb6..00000000
--- a/lib/ui/ui.h
+++ /dev/null
@@ -1,218 +0,0 @@
-#pragma once
-
-extern "C" {
-    #include "main.h"
-    #include "cmsis_os.h"
-    #include "u8g2_support.h"
-    #include "u8g2/u8g2.h"
-}
-
-#include "events.h"
-
-typedef struct {
-    void* item;
-    const char* name;
-} MenuItem;
-
-#include "vendor.h"
-
-typedef enum {
-    LayoutActionUp,
-    LayoutActionDown,
-    LayoutActionLeft,
-    LayoutActionRight,
-    LayoutActionOk,
-    LayoutActionBack,
-    LayoutActionTimeout,
-    LayoutActionUsbConnect,
-    LayoutActionUsbDisconnect,
-    LayoutActionEndOfCycle
-} LayoutAction;
-
-typedef struct {
-    FlipperComponent* item;
-    LayoutAction action;
-} ActionItem;
-
-void draw_text(const char* text, u8g2_t* u8g2, ScreenArea area);
-void draw_bitmap(const char* bitmap, u8g2_t* u8g2, ScreenArea area);
-
-class LayoutComponent: FlipperComponent {
-public:
-    LayoutComponent(void (*draw_fn)(const char* text, u8g2_t* u8g2, ScreenArea area), ActionItem* actions, size_t actions_size, uint32_t timeout, const char* data) {
-        this->data = data;
-        this->actions = actions;
-        this->actions_size = actions_size;
-        this->timeout = timeout;
-        this->draw_fn = draw_fn;
-
-        this->dirty = true;
-
-        this->wait_time = 0;
-    }
-
-    virtual void handle(Event* event, struct _Store* store, u8g2_t* u8g2, ScreenArea area);
-
-private:
-    const char* data;
-    ActionItem* actions;
-    size_t actions_size;
-    uint32_t timeout;
-
-    void (*draw_fn)(const char* text, u8g2_t* u8g2, ScreenArea area);
-
-    uint32_t wait_time;
-
-    bool dirty;
-};
-
-typedef struct {
-    uint32_t on_time;
-    Color on_color;
-    uint32_t off_time;
-    Color off_color;
-} BlinkerComponentConfig;
-
-class BlinkerComponent: FlipperComponent {
-public:
-    BlinkerComponent(
-        void (*draw_fn)(const char* text, u8g2_t* u8g2, ScreenArea area),
-        BlinkerComponentConfig config,
-        const char* data
-    ) {
-        this->data = data;
-        this->draw_fn = draw_fn;
-        this->config = config;
-
-        this->dirty = true;
-
-        this->wait_time = 0;
-        this->is_on = true;
-        this->active = false;
-        this->prev = NULL;
-    }
-
-    virtual void handle(Event* event, struct _Store* store, u8g2_t* u8g2, ScreenArea area);
-
-private:
-    const char* data;
-    BlinkerComponentConfig config;
-
-    void (*draw_fn)(const char* text, u8g2_t* u8g2, ScreenArea area);
-
-    uint32_t wait_time;
-
-    bool is_on;
-    bool active;
-
-    bool dirty;
-    FlipperComponent* prev;
-};
-
-typedef struct {
-    uint32_t on_time;
-    Color on_color;
-    uint32_t off_time;
-    Color off_color;
-} BlinkerComponentOnBtnConfig;
-
-class BlinkerComponentOnBtn: FlipperComponent {
-public:
-    BlinkerComponentOnBtn(
-        void (*draw_fn)(const char* text, u8g2_t* u8g2, ScreenArea area),
-        BlinkerComponentOnBtnConfig config,
-        const char* data
-    ) {
-        this->data = data;
-        this->draw_fn = draw_fn;
-        this->config = config;
-
-        this->dirty = true;
-
-        this->wait_time = 0;
-        this->is_on = true;
-        this->active = false;
-        this->prev = NULL;
-    }
-
-    virtual void handle(Event* event, struct _Store* store, u8g2_t* u8g2, ScreenArea area);
-
-private:
-    const char* data;
-    BlinkerComponentOnBtnConfig config;
-
-    void (*draw_fn)(const char* text, u8g2_t* u8g2, ScreenArea area);
-
-    uint32_t wait_time;
-
-    bool is_on;
-    bool active;
-
-    bool dirty;
-    FlipperComponent* prev;
-};
-
-
-
-typedef enum {
-    MenuEventUp,
-    MenuEventDown
-} MenuEvent;
-
-class MenuCtx {
-public:
-    size_t size;
-    size_t current;
-    uint8_t cursor;
-    MenuItem* list;
-
-    void handle(MenuEvent event);
-    void reset();
-};
-
-void draw_menu(MenuCtx* ctx, u8g2_t* u8g2, ScreenArea area);
-
-class MenuComponent: FlipperComponent {
-public:
-    MenuComponent(MenuItem* list, size_t size, const char* name) {
-        this->ctx.size = size;
-        this->ctx.current = 0;
-        this->ctx.cursor = 0;
-
-        this->ctx.list = list;
-        
-        this->name = name;
-        this->prev = NULL;
-
-        this->dirty = true;
-    }
-
-    
-    const char* name;
-    FlipperComponent* prev;
-    MenuCtx ctx;
-    
-
-    bool dirty;
-
-    virtual void handle(Event* event, struct _Store* store, u8g2_t* u8g2, ScreenArea area);
-};
-
-typedef struct {
-    uint8_t x;
-    uint8_t y;
-} Point;
-
-typedef struct {
-    uint8_t width;
-    uint8_t height;
-    uint8_t margin_left;
-    uint8_t margin_top;
-    uint8_t padding_left;
-    uint8_t padding_top;
-    uint8_t background;
-    uint8_t color;
-    uint8_t* font;
-} Block;
-
-Point draw_block(u8g2_t* u8g2, const char* text, Block layout, uint8_t x, uint8_t y);