diff --git a/documentation/doxygen/js.dox b/documentation/doxygen/js.dox
index 71eb37b17b..7abde9389f 100644
--- a/documentation/doxygen/js.dox
+++ b/documentation/doxygen/js.dox
@@ -16,12 +16,13 @@ Flipper Zero's built-in JavaScript engine enables you to run lightweight scripts
## JavaScript modules {#js_modules}
- @subpage js_badusb — This module allows you to emulate a standard USB keyboard
-- @subpage js_serial — The module for interaction with external devices via UART
-- @subpage js_math — This module contains mathematical methods and constants
-- @subpage js_notification — This module allows you to use LED, speaker and vibro for notifications
- @subpage js_event_loop — The module for easy event-based developing
- @subpage js_gpio — This module allows you to control GPIO pins
- @subpage js_gui — This module allows you to use GUI (graphical user interface)
+- @subpage js_math — This module contains mathematical methods and constants
+- @subpage js_notification — This module allows you to use LED, speaker and vibro for notifications
+- @subpage js_serial — The module for interaction with external devices via UART
+- @subpage js_storage — The module for accessing the filesystem
## Examples {#js_examples}
diff --git a/documentation/js/js_badusb.md b/documentation/js/js_badusb.md
index df02dbdb04..d1d1e558d5 100644
--- a/documentation/js/js_badusb.md
+++ b/documentation/js/js_badusb.md
@@ -4,16 +4,17 @@
let badusb = require("badusb");
```
# Methods
-## setup
+## setup()
Start USB HID with optional parameters. Should be called before all other methods.
-### Parameters
-Configuration object (optional):
+**Parameters**
+
+Configuration object *(optional)*:
- vid, pid (number): VID and PID values, both are mandatory
- mfr_name (string): Manufacturer name (32 ASCII characters max), optional
- prod_name (string): Product name (32 ASCII characters max), optional
-### Examples:
+**Examples**
```js
// Start USB HID with default parameters
badusb.setup();
@@ -23,10 +24,12 @@ badusb.setup({ vid: 0xAAAA, pid: 0xBBBB });
badusb.setup({ vid: 0xAAAA, pid: 0xBBBB, mfr_name: "Flipper Devices", prod_name: "Flipper Zero" });
```
-## isConnected
+
+
+## isConnected()
Returns USB connection state.
-### Example:
+**Example**
```js
if (badusb.isConnected()) {
// Do something
@@ -35,15 +38,18 @@ if (badusb.isConnected()) {
}
```
-## press
+
+
+## press()
Press and release a key.
-### Parameters
+**Parameters**
+
Key or modifier name, key code.
-See a list of key names below.
+See a [list of key names below](#js_badusb_keynames).
-### Examples:
+**Examples**
```js
badusb.press("a"); // Press "a" key
badusb.press("A"); // SHIFT + "a"
@@ -53,58 +59,70 @@ badusb.press(98); // Press key with HID code (dec) 98 (Numpad 0 / Insert)
badusb.press(0x47); // Press key with HID code (hex) 0x47 (Scroll lock)
```
-## hold
+
+
+## hold()
Hold a key. Up to 5 keys (excluding modifiers) can be held simultaneously.
-### Parameters
+**Parameters**
+
Same as `press`.
-### Examples:
+**Examples**
```js
badusb.hold("a"); // Press and hold "a" key
badusb.hold("CTRL", "v"); // Press and hold CTRL + "v" combo
```
-## release
+
+
+## release()
Release a previously held key.
-### Parameters
+**Parameters**
+
Same as `press`.
Release all keys if called without parameters.
-### Examples:
+**Examples**
```js
badusb.release(); // Release all keys
badusb.release("a"); // Release "a" key
```
-## print
+
+
+## print()
Print a string.
-### Parameters
+**Parameters**
+
- A string to print
- *(optional)* Delay between key presses
-### Examples:
+**Examples**
```js
badusb.print("Hello, world!"); // print "Hello, world!"
badusb.print("Hello, world!", 100); // Add 100ms delay between key presses
```
+
-## println
+## println()
Same as `print` but ended with "ENTER" press.
-### Parameters
+**Parameters**
+
- A string to print
- *(optional)* Delay between key presses
-### Examples:
+**Examples**
```js
badusb.println("Hello, world!"); // print "Hello, world!" and press "ENTER"
```
+
-# Key names list
+# Key names list {#js_badusb_keynames}
## Modifier keys
diff --git a/documentation/js/js_builtin.md b/documentation/js/js_builtin.md
index 9c59b98224..0a128859a9 100644
--- a/documentation/js/js_builtin.md
+++ b/documentation/js/js_builtin.md
@@ -1,49 +1,65 @@
# Built-in methods {#js_builtin}
-## require
+## require()
Load a module plugin.
-### Parameters
+**Parameters**
- Module name
-### Examples:
+**Examples**
```js
let serial = require("serial"); // Load "serial" module
```
-## delay
-### Parameters
+
+
+## delay()
+**Parameters**
- Delay value in ms
-### Examples:
+**Examples**
```js
delay(500); // Delay for 500ms
```
-## print
+
+
+## print()
Print a message on a screen console.
-### Parameters
+**Parameters**
The following argument types are supported:
- String
- Number
- Bool
- undefined
-### Examples:
+**Examples**
```js
print("string1", "string2", 123);
```
+
-## console.log
-## console.warn
-## console.error
-## console.debug
+## console.log()
+
+
+
+## console.warn()
+
+
+
+## console.error()
+
+
+
+## console.debug()
Same as `print`, but output to serial console only, with corresponding log level.
-## to_string
+
+
+## to_string()
Convert a number to string with an optional base.
-### Examples:
+**Examples**
```js
to_string(123) // "123"
to_string(123, 16) // "0x7b"
diff --git a/documentation/js/js_event_loop.md b/documentation/js/js_event_loop.md
index 04192b88fa..7da3f93416 100644
--- a/documentation/js/js_event_loop.md
+++ b/documentation/js/js_event_loop.md
@@ -1,27 +1,28 @@
# Event Loop module {#js_event_loop}
-```js
-let eventLoop = require("event_loop");
-```
-
The event loop is central to event-based programming in many frameworks, and our
JS subsystem is no exception. It is a good idea to familiarize yourself with the
event loop first before using any of the advanced modules (e.g. GPIO and GUI).
+```js
+let eventLoop = require("event_loop");
+```
+
## Conceptualizing the event loop
-If you ever wrote JavaScript before, you have definitely seen callbacks. It's
-when a function accepts another function (usually an anonymous one) as one of
-the arguments, which it will call later on, e.g. when an event happens or when
+If you've ever written JavaScript code before, you've definitely seen callbacks. It's
+when a function takes another function (usually an anonymous one) as one of
+the arguments, which it will call later, e.g. when an event happens or when
data becomes ready:
```js
setTimeout(function() { console.log("Hello, World!") }, 1000);
```
-Many JavaScript engines employ a queue that the runtime fetches events from as
+Many JavaScript engines employ a queue from which the runtime fetches events as
they occur, subsequently calling the corresponding callbacks. This is done in a
long-running loop, hence the name "event loop". Here's the pseudocode for a
typical event loop:
-```js
+
+\code{.js}
while(loop_is_running()) {
if(event_available_in_queue()) {
let event = fetch_event_from_queue();
@@ -33,12 +34,14 @@ while(loop_is_running()) {
sleep_until_any_event_becomes_available();
}
}
-```
+\endcode
Most JS runtimes enclose the event loop within themselves, so that most JS
-programmers does not even need to be aware of its existence. This is not the
+programmers don't even need to be aware of its existence. This is not the
case with our JS subsystem.
+---
+
# Example
This is how one would write something similar to the `setTimeout` example above:
```js
@@ -87,14 +90,18 @@ The first two arguments that get passed to our callback are:
- The event item, used for events that have extra data. Timer events do not,
they just produce `undefined`.
+---
+
# API reference
-## `run`
+## run()
Runs the event loop until it is stopped with `stop`.
-## `subscribe`
+
+
+## subscribe()
Subscribes a function to an event.
-### Parameters
+**Parameters**
- `contract`: an event source identifier
- `callback`: the function to call when the event happens
- extra arguments: will be passed as extra arguments to the callback
@@ -107,35 +114,45 @@ to `undefined`. The callback may return an array of the same length as the count
of the extra arguments to modify them for the next time that the event handler
is called. Any other returns values are discarded.
-### Returns
+**Returns**
+
A `SubscriptionManager` object:
- `SubscriptionManager.cancel()`: unsubscribes the callback from the event
-### Warning
+**Warning**
+
Each event source may only have one callback associated with it.
-## `stop`
+
+
+## stop()
Stops the event loop.
-## `timer`
+
+
+## timer()
Produces an event source that fires with a constant interval either once or
indefinitely.
-### Parameters
+**Parameters**
- `mode`: either `"oneshot"` or `"periodic"`
- `interval`: the timeout (for `"oneshot"`) timers or the period (for
`"periodic"` timers)
-### Returns
+**Returns**
+
A `Contract` object, as expected by `subscribe`'s first parameter.
-## `queue`
+
+
+## queue()
Produces a queue that can be used to exchange messages.
-### Parameters
+**Parameters**
- `length`: the maximum number of items that the queue may contain
-### Returns
+**Returns**
+
A `Queue` object:
- `Queue.send(message)`:
- `message`: a value of any type that will be placed at the end of the queue
diff --git a/documentation/js/js_gpio.md b/documentation/js/js_gpio.md
index bb60ac5f34..59a5504b06 100644
--- a/documentation/js/js_gpio.md
+++ b/documentation/js/js_gpio.md
@@ -21,21 +21,26 @@ led.write(false);
delay(1000);
```
+---
+
# API reference
-## `get`
+## get
Gets a `Pin` object that can be used to manage a pin.
-### Parameters
+**Parameters**
- `pin`: pin identifier (examples: `"pc3"`, `7`, `"pa6"`, `3`)
-### Returns
+**Returns**
+
A `Pin` object.
-## `Pin` object
-### `Pin.init()`
+
+
+## Pin object
+### Pin.init()
Configures a pin.
-#### Parameters
+**Parameters**
- `mode`: `Mode` object:
- `direction` (required): either `"in"` or `"out"`
- `outMode` (required for `direction: "out"`): either `"open_drain"` or
@@ -46,30 +51,41 @@ Configures a pin.
`"rising"`, `"falling"` or `"both"`
- `pull` (optional): either `"up"`, `"down"` or unset
-### `Pin.write()`
+
+
+### Pin.write()
Writes a digital value to a pin configured with `direction: "out"`.
-#### Parameters
+**Parameters**
- `value`: boolean logic level to write
-### `Pin.read()`
+
+
+### Pin.read()
Reads a digital value from a pin configured with `direction: "in"` and any
`inMode` except `"analog"`.
-#### Returns
-Boolean logic level
+**Returns**
-### `Pin.readAnalog()`
+Boolean logic level.
+
+
+
+### Pin.readAnalog()
Reads an analog voltage level in millivolts from a pin configured with
`direction: "in"` and `inMode: "analog"`.
-#### Returns
+**Returns**
+
Voltage on pin in millivolts.
-### `Pin.interrupt()`
+
+
+### Pin.interrupt()
Attaches an interrupt to a pin configured with `direction: "in"` and
`inMode: "interrupt"` or `"event"`.
-#### Returns
+**Returns**
+
An event loop `Contract` object that identifies the interrupt event source. The
event does not produce any extra data.
diff --git a/documentation/js/js_gui.md b/documentation/js/js_gui.md
index c30447c543..2bb2a2eee1 100644
--- a/documentation/js/js_gui.md
+++ b/documentation/js/js_gui.md
@@ -18,6 +18,8 @@ GUI module has several submodules:
- @subpage js_gui__dialog — Dialog with up to 3 options
- @subpage js_gui__widget — Displays a combination of custom elements on one screen
+---
+
## Conceptualizing GUI
### Event loop
It is highly recommended to familiarize yourself with the event loop first
@@ -78,7 +80,9 @@ a GUI application:
| ViewDispatcher | Common UI elements that fit with the overall look of the system | ✅ |
| SceneManager | Additional navigation flow management for complex applications | ❌ |
-# Example
+---
+
+## Example
An example with three different views using the ViewDispatcher approach:
```js
let eventLoop = require("event_loop");
@@ -123,48 +127,64 @@ gui.viewDispatcher.switchTo(views.demos);
eventLoop.run();
```
+---
+
# API reference
-## `viewDispatcher`
+## viewDispatcher
The `viewDispatcher` constant holds the `ViewDispatcher` singleton.
-### `viewDispatcher.switchTo(view)`
+
+
+### viewDispatcher.switchTo(view)
Switches to a view, giving it control over the display and input.
-#### Parameters
+**Parameters**
- `view`: the `View` to switch to
-### `viewDispatcher.sendTo(direction)`
+
+
+### viewDispatcher.sendTo(direction)
Sends the viewport that the dispatcher manages to the front of the stackup
(effectively making it visible), or to the back (effectively making it
invisible).
-#### Parameters
+**Parameters**
- `direction`: either `"front"` or `"back"`
-### `viewDispatcher.sendCustom(event)`
+
+
+### viewDispatcher.sendCustom(event)
Sends a custom number to the `custom` event handler.
-#### Parameters
+**Parameters**
- `event`: number to send
-### `viewDispatcher.custom`
+
+
+### viewDispatcher.custom
An event loop `Contract` object that identifies the custom event source,
triggered by `ViewDispatcher.sendCustom(event)`.
-### `viewDispatcher.navigation`
+
+
+### viewDispatcher.navigation
An event loop `Contract` object that identifies the navigation event source,
triggered when the back key is pressed.
-## `ViewFactory`
-When you import a module implementing a view, a `ViewFactory` is instantiated.
-For example, in the example above, `loadingView`, `submenuView` and `emptyView`
-are view factories.
+
-### `ViewFactory.make()`
+## ViewFactory
+When you import a module implementing a view, a `ViewFactory` is instantiated. For example, in the example above, `loadingView`, `submenuView` and `emptyView` are view factories.
+
+
+
+### ViewFactory.make()
Creates an instance of a `View`.
-### `ViewFactory.make(props)`
+
+
+### ViewFactory.make(props)
Creates an instance of a `View` and assigns initial properties from `props`.
-#### Parameters
+**Parameters**
- `props`: simple key-value object, e.g. `{ header: "Header" }`
diff --git a/documentation/js/js_gui__dialog.md b/documentation/js/js_gui__dialog.md
index dce45c49d3..4f26cfa1bf 100644
--- a/documentation/js/js_gui__dialog.md
+++ b/documentation/js/js_gui__dialog.md
@@ -11,42 +11,24 @@ let dialogView = require("gui/dialog");
```
This module depends on the `gui` module, which in turn depends on the
-`event_loop` module, so they _must_ be imported in this order. It is also
+`event_loop` module, so they **must** be imported in this order. It is also
recommended to conceptualize these modules first before using this one.
# Example
For an example, refer to the `gui.js` example script.
# View props
-## `header`
-Text that appears in bold at the top of the screen.
-Type: `string`
-
-## `text`
-Text that appears in the middle of the screen.
-
-Type: `string`
-
-## `left`
-Text for the left button. If unset, the left button does not show up.
-
-Type: `string`
-
-## `center`
-Text for the center button. If unset, the center button does not show up.
-
-Type: `string`
-
-## `right`
-Text for the right button. If unset, the right button does not show up.
-
-Type: `string`
+| **Prop** | **Type** | **Description** |
+|------------|-----------|----------------------------------------------------------------|
+| `header` | string | Text that appears in bold at the top of the screen. |
+| `text` | string | Text that appears in the middle of the screen. |
+| `left` | string | Text for the left button. If unset, the left button does not show up. |
+| `center` | string | Text for the center button. If unset, the center button does not show up. |
+| `right` | string | Text for the right button. If unset, the right button does not show up. |
# View events
-## `input`
-Fires when the user presses on either of the three possible buttons. The item
-contains one of the strings `"left"`, `"center"` or `"right"` depending on the
-button.
-Item type: `string`
+| Item | Type | Description |
+|----------|--------|-----------------------------------------------------------------------------|
+| `input` | `string`| Fires when the user presses on either of the three possible buttons. The item contains one of the strings `"left"`, `"center"`, or `"right"` depending on the button. |
diff --git a/documentation/js/js_gui__empty_screen.md b/documentation/js/js_gui__empty_screen.md
index 68b7e31248..6ee6ba20e7 100644
--- a/documentation/js/js_gui__empty_screen.md
+++ b/documentation/js/js_gui__empty_screen.md
@@ -11,7 +11,7 @@ let emptyView = require("gui/empty_screen");
```
This module depends on the `gui` module, which in turn depends on the
-`event_loop` module, so they _must_ be imported in this order. It is also
+`event_loop` module, so they **must** be imported in this order. It is also
recommended to conceptualize these modules first before using this one.
# Example
diff --git a/documentation/js/js_gui__loading.md b/documentation/js/js_gui__loading.md
index 0d3c186449..35ea987c12 100644
--- a/documentation/js/js_gui__loading.md
+++ b/documentation/js/js_gui__loading.md
@@ -11,7 +11,7 @@ let loadingView = require("gui/loading");
```
This module depends on the `gui` module, which in turn depends on the
-`event_loop` module, so they _must_ be imported in this order. It is also
+`event_loop` module, so they **must** be imported in this order. It is also
recommended to conceptualize these modules first before using this one.
# Example
diff --git a/documentation/js/js_gui__submenu.md b/documentation/js/js_gui__submenu.md
index 755d87d8b0..9105330a29 100644
--- a/documentation/js/js_gui__submenu.md
+++ b/documentation/js/js_gui__submenu.md
@@ -11,26 +11,19 @@ let submenuView = require("gui/submenu");
```
This module depends on the `gui` module, which in turn depends on the
-`event_loop` module, so they _must_ be imported in this order. It is also
+`event_loop` module, so they **must** be imported in this order. It is also
recommended to conceptualize these modules first before using this one.
-# Example
-For an example, refer to the GUI example.
+## View props
-# View props
-## `header`
-A single line of text that appears above the list.
+| Property | Type | Description |
+|----------|-----------|-------------------------------------------|
+| `header` | `string` | A single line of text that appears above the list. |
+| `items` | `string[]`| The list of options. |
-Type: `string`
-## `items`
-The list of options.
+## View events
-Type: `string[]`
-
-# View events
-## `chosen`
-Fires when an entry has been chosen by the user. The item contains the index of
-the entry.
-
-Item type: `number`
+| Item | Type | Description |
+|----------|---------|---------------------------------------------------------------|
+| `chosen` | `number`| Fires when an entry has been chosen by the user. The item contains the index of the entry. |
diff --git a/documentation/js/js_gui__text_box.md b/documentation/js/js_gui__text_box.md
index 62828a37f6..cdbeec7b71 100644
--- a/documentation/js/js_gui__text_box.md
+++ b/documentation/js/js_gui__text_box.md
@@ -11,14 +11,14 @@ let textBoxView = require("gui/text_box");
```
This module depends on the `gui` module, which in turn depends on the
-`event_loop` module, so they _must_ be imported in this order. It is also
+`event_loop` module, so they **must** be imported in this order. It is also
recommended to conceptualize these modules first before using this one.
-# Example
+## Example
For an example, refer to the `gui.js` example script.
-# View props
-## `text`
-Text to show in the text box.
+## View props
-Type: `string`
+| Prop | Type | Description |
+|----------|---------|------------------------------------|
+| `text` | `string`| Text to show in the text box. |
diff --git a/documentation/js/js_gui__text_input.md b/documentation/js/js_gui__text_input.md
index 44752ab554..3b8aafaad8 100644
--- a/documentation/js/js_gui__text_input.md
+++ b/documentation/js/js_gui__text_input.md
@@ -11,33 +11,22 @@ let textInputView = require("gui/text_input");
```
This module depends on the `gui` module, which in turn depends on the
-`event_loop` module, so they _must_ be imported in this order. It is also
+`event_loop` module, so they **must** be imported in this order. It is also
recommended to conceptualize these modules first before using this one.
-# Example
+## Example
For an example, refer to the `gui.js` example script.
-# View props
-## `minLength`
-The shortest allowed text length.
+## View props
-Type: `number`
+| Prop | Type | Description |
+|-------------|--------|--------------------------------------------------|
+| `minLength` | `number` | The shortest allowed text length. |
+| `maxLength` | `number` | The longest allowed text length.
Default: `32` |
+| `header` | `string` | A single line of text that appears above the keyboard. |
-## `maxLength`
-The longest allowed text length.
+## View events
-Type: `number`
-
-Default: `32`
-
-## `header`
-A single line of text that appears above the keyboard.
-
-Type: `string`
-
-# View events
-## `input`
-Fires when the user selects the "Save" button and the text matches the length
-constrained by `minLength` and `maxLength`.
-
-Item type: `string`
+| Item | Type | Description |
+|-------------|--------|--------------------------------------------------|
+| `input` | `string` | Fires when the user selects the "Save" button and the text matches the length constrained by `minLength` and `maxLength`. |
diff --git a/documentation/js/js_gui__widget.md b/documentation/js/js_gui__widget.md
index f0409e87b0..2c31327d2b 100644
--- a/documentation/js/js_gui__widget.md
+++ b/documentation/js/js_gui__widget.md
@@ -11,14 +11,14 @@ let widgetView = require("gui/widget");
```
This module depends on the `gui` module, which in turn depends on the
-`event_loop` module, so they _must_ be imported in this order. It is also
+`event_loop` module, so they **must** be imported in this order. It is also
recommended to conceptualize these modules first before using this one.
-# Example
+## Example
For an example, refer to the `gui.js` example script.
-# View props
+## View props
This view does not have any props.
-# Children
+## Children
This view has the elements as its children.
diff --git a/documentation/js/js_math.md b/documentation/js/js_math.md
index cab9ac0c73..78357bbd7d 100644
--- a/documentation/js/js_math.md
+++ b/documentation/js/js_math.md
@@ -5,6 +5,7 @@ The module contains mathematical methods and constants. Call the `require` funct
```js
let math = require("math");
```
+
# Constants
## PI
@@ -17,204 +18,248 @@ The number e (Euler's number) = 2.71828182845904523536028747135266250.
The smallest number that satisfies the condition: 1.0 + EPSILON != 1.0.
EPSILON = 2.2204460492503131e-16.
+
+
+---
+
# Methods
-## abs
+## abs()
Return the absolute value of a number.
-### Parameters
+**Parameters**
- x: A number
-### Returns
+**Returns**
+
The absolute value of `x`. If `x` is negative (including -0), returns `-x`. Otherwise, returns `x`. The result is therefore always a positive number or 0.
-### Example
+**Example**
```js
math.abs(-5); // 5
```
-## acos
+
+
+## acos()
Return the inverse cosine (in radians) of a number.
-### Parameters
+**Parameters**
- x: A number between -1 and 1, inclusive, representing the angle's cosine value
-### Returns
+**Returns**
+
The inverse cosine (angle in radians between 0 and π, inclusive) of `x`. If `x` is less than -1 or greater than 1, returns `NaN`.
-### Example
+**Example**
```js
math.acos(-1); // 3.141592653589793
```
-## acosh
+
+
+## acosh()
Return the inverse hyperbolic cosine of a number.
-### Parameters
+**Parameters**
- x: A number greater than or equal to 1
-### Returns
+**Returns**
+
The inverse hyperbolic cosine of `x`.
-### Example
+**Example**
```js
math.acosh(1); // 0
```
-## asin
+
+
+## asin()
Return the inverse sine (in radians) of a number.
-### Parameters
+**Parameters**
- x: A number between -1 and 1, inclusive, representing the angle's sine value
-### Returns
+**Returns**
+
The inverse sine (angle in radians between -𝜋/2 and 𝜋/2, inclusive) of `x`.
-### Example
+**Example**
```js
math.asin(0.5); // 0.5235987755982989
```
-## asinh
+
+
+## asinh()
Return the inverse hyperbolic sine of a number.
-### Parameters
+**Parameters**
- x: A number
-### Returns
+**Returns**
+
The inverse hyperbolic sine of `x`.
-### Example
+**Example**
```js
math.asinh(1); // 0.881373587019543
```
-## atan
+
+
+## atan()
Return the inverse tangent (in radians) of a number.
-### Parameters
+**Parameters**
- x: A number
-### Returns
+**Returns**
+
The inverse tangent (angle in radians between -𝜋/2 and 𝜋/2, inclusive) of `x`.
-### Example
+**Example**
```js
math.atan(1); // 0.7853981633974483
```
-## atan2
+
+
+## atan2()
Return the angle in the plane (in radians) between the positive x-axis and the ray from (0, 0) to the point (x, y), for math.atan2(y, x).
-### Parameters
+**Parameters**
- y: The y coordinate of the point
- x: The x coordinate of the point
-### Returns
+**Returns**
+
The angle in radians (between -π and π, inclusive) between the positive x-axis and the ray from (0, 0) to the point (x, y).
-### Example
+**Example**
```js
math.atan2(90, 15); // 1.4056476493802699
```
-## atanh
+
+
+## atanh()
The method returns the inverse hyperbolic tangent of a number.
-### Parameters
+**Parameters**
- x: A number between -1 and 1, inclusive
-### Returns
+**Returns**
+
The inverse hyperbolic tangent of `x`.
-### Example
+**Example**
```js
math.atanh(0.5); // 0.5493061443340548
```
-## cbrt
+
+
+## cbrt()
Return the cube root of a number.
-### Parameters
+**Parameters**
- x: A number
-### Returns
+**Returns**
+
The cube root of `x`.
-### Example
+**Example**
```js
math.cbrt(2); // 1.2599210498948732
```
-## ceil
+
+
+## ceil()
Round up and return the smallest integer greater than or equal to a given number.
-### Parameters
+**Parameters**
- x: A number
-### Returns
+**Returns**
+
The smallest integer greater than or equal to `x`. It's the same value as `-math.floor(-x)`.
-### Example
+**Example**
```js
math.ceil(-7.004); // -7
math.ceil(7.004); // 8
```
-## clz32
+
+
+## clz32()
Return the number of leading zero bits in the 32-bit binary representation of a number.
-### Parameters
+**Parameters**
- x: A number
-### Returns
+**Returns**
+
The number of leading zero bits in the 32-bit binary representation of `x`.
-### Example
+**Example**
```js
math.clz32(1); // 31
math.clz32(1000); // 22
```
-## cos
+
+
+## cos()
Return the cosine of a number in radians.
-### Parameters
+**Parameters**
- x: A number representing an angle in radians
-### Returns
+**Returns**
+
The cosine of `x`, between -1 and 1, inclusive.
-### Example
+**Example**
```js
math.cos(math.PI); // -1
```
-## exp
+
+
+## exp()
Return e raised to the power of a number.
-### Parameters
+**Parameters**
- x: A number
-### Returns
+**Returns**
+
A nonnegative number representing `e^x`, where `e` is the base of the natural logarithm.
-### Example
+**Example**
```js
math.exp(0); // 1
math.exp(1); // 2.718281828459045
```
-## floor
+
+
+## floor()
Round down and return the largest integer less than or equal to a given number.
-### Parameters
+**Parameters**
- x: A number
-### Returns
+**Returns**
+
The largest integer smaller than or equal to `x`. It's the same value as `-math.ceil(-x)`.
-### Example
+**Example**
```js
math.floor(-45.95); // -46
math.floor(-45.05); // -46
@@ -224,137 +269,165 @@ math.floor(45.05); // 45
math.floor(45.95); // 45
```
-## isEqual
+
+
+## isEqual()
Return true if the difference between numbers `a` and `b` is less than the specified parameter `e`.
-### Parameters
+**Parameters**
- a: A number a
- b: A number b
- e: An epsilon parameter
-### Returns
+**Returns**
+
True if the difference between numbers `a` and `b` is less than the specified parameter `e`. Otherwise, false.
-### Example
+**Example**
```js
math.isEqual(1.4, 1.6, 0.2); // false
math.isEqual(3.556, 3.555, 0.01); // true
```
-## max
+
+
+## max()
Return the largest of two numbers given as input parameters.
-### Parameters
+**Parameters**
- a: A number a
- b: A number b
-### Returns
+**Returns**
+
The largest of the given numbers.
-### Example
+**Example**
```js
math.max(10, 20); // 20
math.max(-10, -20); // -10
```
-## min
+
+
+## min()
Return the smallest of two numbers given as input parameters.
-### Parameters
+**Parameters**
- a: A number a
- b: A number b
-### Returns
+**Returns**
+
The smallest of the given numbers.
-### Example
+**Example**
```js
math.min(10, 20); // 10
math.min(-10, -20); // -20
```
-## pow
+
+
+## pow()
Return the value of a base raised to a power.
-### Parameters
+**Parameters**
- base: The base number
- exponent: The exponent number
-### Returns
+**Returns**
+
A number representing base taken to the power of exponent.
-### Example
+**Example**
```js
math.pow(7, 2); // 49
math.pow(7, 3); // 343
math.pow(2, 10); // 1024
```
-## random
+
+
+## random()
Return a floating-point, pseudo-random number that's greater than or equal to 0 and less than 1, with approximately uniform distribution over that range — which you can then scale to your desired range.
-### Returns
+**Returns**
+
A floating-point, pseudo-random number between 0 (inclusive) and 1 (exclusive).
-### Example
+**Example**
```js
let num = math.random();
```
-## sign
+
+
+## sign()
Return 1 or -1, indicating the sign of the number passed as argument.
-### Parameters
+**Parameters**
- x: A number
-### Returns
+**Returns**
+
-1 if the number is less than 0, and 1 otherwise.
-### Example
+**Example**
```js
math.sign(3); // 1
math.sign(0); // 1
math.sign(-3); // -1
```
-## sin
+
+
+## sin()
Return the sine of a number in radians.
-### Parameters
+**Parameters**
- x: A number representing an angle in radians
-### Returns
+**Returns**
+
The sine of `x`, between -1 and 1, inclusive.
-### Example
+**Example**
```js
math.sin(math.PI / 2); // 1
```
-## sqrt
+
+
+## sqrt()
Return the square root of a number.
-### Parameters
+**Parameters**
- x: A number greater than or equal to 0
-### Returns
+**Returns**
+
+
The square root of `x`, a nonnegative number. If `x` < 0, script will fail with an error.
-### Example
+**Example**
```js
math.sqrt(25); // 5
```
-## trunc
+
+
+## trunc()
Return the integer part of a number by removing any fractional digits.
-### Parameters
+**Parameters**
- x: A number
-### Returns
+**Returns**
+
The integer part of `x`.
-### Example
+**Example**
```js
math.trunc(-1.123); // -1
math.trunc(0.123); // 0
diff --git a/documentation/js/js_notification.md b/documentation/js/js_notification.md
index 543df3504a..753f4c9e98 100644
--- a/documentation/js/js_notification.md
+++ b/documentation/js/js_notification.md
@@ -3,32 +3,36 @@
```js
let notify = require("notification");
```
-# Methods
+## Methods
-## success
+### success()
"Success" flipper notification message.
-### Examples:
+**Example**
```js
notify.success();
```
-## error
+
+
+### error()
"Error" flipper notification message.
-### Examples:
+**Example**
```js
notify.error();
```
-## blink
+
+
+### blink()
Blink notification LED.
-### Parameters
+**Parameters**
- Blink color (blue/red/green/yellow/cyan/magenta)
- Blink type (short/long)
-### Examples:
+**Examples**
```js
notify.blink("red", "short"); // Short blink of red LED
notify.blink("green", "short"); // Long blink of green LED
diff --git a/documentation/js/js_serial.md b/documentation/js/js_serial.md
index ffaee89bc4..01a72b97b1 100644
--- a/documentation/js/js_serial.md
+++ b/documentation/js/js_serial.md
@@ -5,78 +5,99 @@ let serial = require("serial");
```
# Methods
-## setup
+## setup()
Configure serial port. Should be called before all other methods.
-### Parameters
+**Parameters**
+
- Serial port name (usart, lpuart)
- Baudrate
-### Examples:
+**Example**
+
```js
// Configure LPUART port with baudrate = 115200
serial.setup("lpuart", 115200);
```
-## write
+
+
+## write()
Write data to serial port.
-### Parameters
+**Parameters**
+
One or more arguments of the following types:
- A string
- Single number, each number is interpreted as a byte
- Array of numbers, each number is interpreted as a byte
- ArrayBuffer or DataView
-### Examples:
+**Example**
+
```js
serial.write(0x0a); // Write a single byte 0x0A
serial.write("Hello, world!"); // Write a string
serial.write("Hello, world!", [0x0d, 0x0a]); // Write a string followed by two bytes
```
-## read
+
+
+## read()
Read a fixed number of characters from serial port.
-### Parameters
+**Parameters**
+
- Number of bytes to read
- *(optional)* Timeout value in ms
-### Returns
+**Returns**
+
A sting of received characters or undefined if nothing was received before timeout.
-### Examples:
+**Example**
+
```js
serial.read(1); // Read a single byte, without timeout
serial.read(10, 5000); // Read 10 bytes, with 5s timeout
```
-## readln
+
+
+## readln()
Read from serial port until line break character.
-### Parameters
+**Parameters**
+
*(optional)* Timeout value in ms.
-### Returns
+**Returns**
+
A sting of received characters or undefined if nothing was received before timeout.
-### Examples:
+**Example**
+
```js
serial.readln(); // Read without timeout
serial.readln(5000); // Read with 5s timeout
```
-## readBytes
+
+
+## readBytes()
Read from serial port until line break character.
-### Parameters
+**Parameters**
+
- Number of bytes to read
- *(optional)* Timeout value in ms
-### Returns
+**Returns**
+
ArrayBuffer with received data or undefined if nothing was received before timeout.
-### Examples:
+**Example**
+
```js
serial.readBytes(4); // Read 4 bytes, without timeout
@@ -84,19 +105,24 @@ serial.readBytes(4); // Read 4 bytes, without timeout
serial.readBytes(1, 0);
```
-## expect
+
+
+## expect()
Search for a string pattern in received data stream.
-### Parameters
+**Parameters**
+
- Single argument or array of the following types:
- A string
- Array of numbers, each number is interpreted as a byte
- *(optional)* Timeout value in ms
-### Returns
+**Returns**
+
Index of matched pattern in input patterns list, undefined if nothing was found.
-### Examples:
+**Example**
+
```js
// Wait for root shell prompt with 1s timeout, returns 0 if it was received before timeout, undefined if not
serial.expect("# ", 1000);
diff --git a/documentation/js/js_storage.md b/documentation/js/js_storage.md
new file mode 100644
index 0000000000..acfa4e3317
--- /dev/null
+++ b/documentation/js/js_storage.md
@@ -0,0 +1,445 @@
+# Storage module {#js_storage}
+
+The module allows you to access files and directories on the Flipper Zero filesystems. Call the `require` function to load the module before first using its methods:
+
+```js
+let storage = require("storage");
+```
+
+## Paths
+
+To work with files and folders, you'll need to specify paths to them. File paths have the following structure:
+
+```
+/ext/example_subdir_1/example_subdir_2/example_file.txt
+\____________________________________/ \__________/ \_/
+ dirPath fileName fileExt
+```
+
+* **dirPath** — directory path starting with `/int/` (small storage in the MCU's flash memory) or `/ext/` (microSD card storage). Specify the sub-directories containing the file using `/` as a separator between directory names.
+* **fileName** — file name.
+* **fileExt** — file extension (separated from the file name by a period).
+
+---
+
+# Structures
+
+## FsInfo
+
+Filesystem information structure.
+
+**Fields**
+
+- totalSpace: Total size of the filesystem, in bytes
+- freeSpace: Free space in the filesystem, in bytes
+
+
+
+## FileInfo
+
+File information structure.
+
+**Fields**
+
+- path: Full path (e.g. "/ext/test", returned by `stat`) or file name (e.g. "test", returned by `readDirectory`)
+- isDirectory: Returns `true` if path leads to a directory (not a file)
+- size: File size in bytes, or 0 in the case of directories
+- accessTime: Time of last access as a UNIX timestamp
+
+---
+
+# Classes
+
+## File
+
+This class implements methods for working with file. To get an object of the File class, use the `OpenFile` method.
+
+
+
+### close()
+
+Closes the file. After this method is called, all other operations related to this file become unavailable.
+
+**Returns**
+
+`true` on success, `false` on failure.
+
+
+
+### isOpen()
+
+**Returns**
+
+`true` if file is currently opened, `false` otherwise.
+
+
+
+### read()
+
+Reads bytes from a file opened in read-only or read-write mode.
+
+**Parameters**
+
+- mode: The data type to interpret the bytes as: a `string` decoded from ASCII data (`"ascii"`), or an `ArrayBuf` (`"binary"`)
+- bytes: How many bytes to read from the file
+
+**Returns**
+
+An `ArrayBuf` if the mode is `"binary"`, a `string` if the mode is `ascii`. The number of bytes that was actually read may be fewer than requested.
+
+
+
+### write()
+
+Writes bytes to a file opened in write-only or read-write mode.
+
+**Parameters**
+
+- data: The data to write: a string that will be ASCII-encoded, or an ArrayBuf
+
+**Returns**
+
+The amount of bytes that was actually written.
+
+
+
+### seekRelative()
+
+Moves the R/W pointer forward.
+
+**Parameters**
+
+- bytes: How many bytes to move the pointer forward by
+
+**Returns**
+
+`true` on success, `false` on failure.
+
+
+
+### seekAbsolute()
+
+Moves the R/W pointer to an absolute position inside the file.
+
+**Parameters**
+
+- bytes: The position inside the file
+
+**Returns**
+
+`true` on success, `false` on failure.
+
+
+
+### tell()
+
+Gets the absolute position of the R/W pointer in bytes.
+
+**Returns**
+
+The absolute current position in the file.
+
+
+
+### truncate()
+
+Discards the data after the current position of the R/W pointer in a file opened in either write-only or read-write mode.
+
+**Returns**
+
+`true` on success, `false` on failure.
+
+
+
+### size()
+
+**Returns**
+
+The total size of the file in bytes.
+
+
+
+### eof()
+
+Detects whether the R/W pointer has reached the end of the file.
+
+**Returns**
+
+`true` if end of file reached, `false` otherwise.
+
+
+
+### copyTo()
+
+Copies bytes from the R/W pointer in the current file to the R/W pointer in another file.
+
+**Parameters**
+
+- dest: The file to copy the bytes into
+- bytes: The number of bytes to copy
+
+**Returns**
+
+`true` on success, `false` on failure.
+
+---
+
+# Methods
+
+## arePathsEqual()
+
+Determines whether the two paths are equivalent. Respects filesystem-defined path equivalence rules.
+
+**Parameters**
+
+- path1: The first path for comparison
+- path2: The second path for comparison
+
+**Returns**
+
+`true` if path1 and path2 are equals, `false` otherwise.
+
+
+
+## isSubpathOf()
+
+Determines whether a path is a subpath of another path. Respects filesystem-defined path equivalence rules.
+
+**Parameters**
+
+- parentPath: The parent path
+- childPath: The child path
+
+**Returns**
+
+`true` if path1 and path2 are equals, `false` otherwise.
+
+
+
+## fileOrDirExists()
+
+Detects whether a file or a directory exists.
+
+**Parameters**
+
+- path: The path to the file or directory
+
+**Returns**
+
+`true` if file/directory exists, `false` otherwise.
+
+**Example**
+```js
+if (storage.fileOrDirExists("/ext/test_dir")) {
+ print("Test directory exists");
+}
+```
+
+
+
+## fsInfo()
+
+Fetches generic information about a filesystem.
+
+**Parameters**
+
+- filesystem: The path to the filesystem (e.g. `"/ext"` or `"/int"`)
+
+**Returns**
+
+A `fsInfo` structure or `undefined` on failure.
+
+**Example**
+```js
+let fsinfo = storage.fsInfo("/ext");
+if (fsinfo === undefined) {
+ print("Filesystem access error");
+} else {
+ print("Free space on the /ext filesystem:", fsinfo.freeSpace);
+}
+```
+
+
+
+## stat()
+
+Acquires metadata about a file or directory.
+
+**Parameters**
+
+- path: The path to the file or directory
+
+**Returns**
+
+A `FileInfo` structure or `undefined` on failure.
+
+**Example**
+```js
+let finfo = storage.stat("/ext/test_file.txt");
+if (finfo === undefined) {
+ print("File not found");
+} else {
+ print("File size:", finfo.size);
+}
+```
+
+
+
+## directoryExists()
+
+Detects whether a directory exists.
+
+**Parameters**
+
+- path: The path to the directory
+
+**Returns**
+
+`true` if directory exists, `false` otherwise.
+
+
+
+## makeDirectory()
+
+Creates an empty directory.
+
+**Parameters**
+
+- path: The path to the new directory
+
+**Returns**
+
+`true` on success, `false` on failure.
+
+
+
+## readDirectory()
+
+Reads the list of files in a directory.
+
+**Parameters**
+
+- path: The path to the directory
+
+**Returns**
+
+Array of `FileInfo` structures with directory entries, or `undefined` on failure.
+
+
+
+## nextAvailableFilename()
+
+Chooses the next available filename with a numeric suffix in a directory.
+```
+/ext/example_dir/example_file123.txt
+\______________/ \__________/\_/ \_/
+ dirPath fileName | |
+ | +--- fileExt
+ +------- suffix selected by this function
+```
+
+**Parameters**
+
+- dirPath: The directory to look in
+- fileName: The base of the filename (the part before the numeric suffix)
+- fileExt: The extension of the filename (the part after the numeric suffix)
+- maxLen: The maximum length of the filename with the numeric suffix
+
+**Returns**
+
+The base of the filename with the next available numeric suffix, without the extension or the base directory.
+
+
+
+## copy()
+
+Copies a file or recursively copies a possibly non-empty directory.
+
+**Parameters**
+
+- oldPath: The original path to the file or directory
+- newPath: The new path that the copy of the file or directory will be accessible under
+
+**Returns**
+
+`true` on success, `false` on failure.
+
+**Example**
+```js
+if (storage.copy("/ext/src_file.txt", "/ext/dst_file.txt")) {
+ print("File copied");
+}
+```
+
+
+
+## rename()
+
+Renames or moves a file or directory.
+
+**Parameters**
+
+- oldPath: The old path to the file or directory
+- newPath: The new path that the file or directory will become accessible
+
+**Returns**
+
+`true` on success, `false` on failure.
+
+**Example**
+```js
+if (storage.rename("/ext/src_file.txt", "/ext/dst_file.txt")) {
+ print("File moved");
+}
+```
+
+
+
+## remove()
+
+Removes a file or an empty directory.
+
+**Parameters**
+
+- path: The path to the file or directory
+
+**Returns**
+
+`true` on success, `false` on failure.
+
+**Example**
+```js
+let path = "/ext/test_file.txt";
+
+file = storage.openFile(path, "w", "create_always");
+file.write("Test");
+file.close();
+print("File created");
+
+if (storage.remove(path)) {
+ print("File removed");
+}
+```
+
+
+
+## rmrf()
+
+Removes a file or recursively removes a possibly non-empty directory.
+
+**Parameters**
+
+- path: The path to the file or directory
+
+**Returns**
+
+`true` on success, `false` on failure.
+
+**Example**
+```js
+let path = "/ext/test_dir";
+
+if (storage.rmrf(path)) {
+ print("Directory removed");
+}
+```