Skip to content

Commit

Permalink
rename project and update instructions
Browse files Browse the repository at this point in the history
  • Loading branch information
Christopher Coté authored and Christopher Coté committed Mar 22, 2017
1 parent d94ccdd commit 20e1ba8
Show file tree
Hide file tree
Showing 12 changed files with 165 additions and 40 deletions.
60 changes: 60 additions & 0 deletions INSTALL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# RosettaHome Installation

The installation steps below have only been tested with Ubuntu 14.04 and 16.04.

Following the installation steps below will allow you to run Rosetta Home locally as well as build the system for a [Raspberry Pi 3 Model B](https://www.raspberrypi.org/products/raspberry-pi-3-model-b/)

The much easier path is to just download the [pre-built firmware]() and burn it with `mix firmware.burn` this still requires you to install Nerves boostrap from the instructions below, but should work on all OS types.

Once burned and installed on a Raspberry Pi, you can follow the [setup](/SETUP.md) instructions for getting the system on WiFi.

## Installation
* Install build-essential
* Install libmnl-dev
* Install Erlang v19.2
* Install erlang-esl
* Install erlang-dev
* Install erlang-xmerl
* Install erlang-os-mon
* Install erlang-src
* Install erlang-eunit
* Install erlang-parsetools
* Install [Elixir v1.4](http://elixir-lang.org/install.html#unix-and-unix-like)
* Install [Nerves](https://www.random.org/cgi-bin/randbyte?nbytes=10&format=h)
* Install fwup
* Install ssh-askpass
* Install squashfs-tool
* Install rebar and hex
* Install [bootstrap v0.2.1](/~https://github.com/nerves-project/archives/raw/master/nerves_bootstrap-0.2.1.ez)
* You will have to go into `~/.mix/archives/nerves_bootstrap-0.2.1/` and rename `nerves_bootstrap` to `nerves_bootstrap-0.2.1` there is a bug when you install bootstrap and it's not the latest build.
* Install Node >= 6.1
* Install Elm 0.17.1


## Setup
`cp default.env .env`

change cipher keys to [random 10 digits](https://www.random.org/cgi-bin/randbyte?nbytes=10&format=h) *remember to remove the spaces*

`source .env`

## Build Web UI
`cd apps/interface/priv`

`elm-make src/Main.elm --output=app.js`

## Running locally
`MIX_ENV=dev mix do deps.get, deps.compile`

`MIX_ENV=dev mix compile`

`MIX_ENV=dev iex -S mix`

## Build Firmware
`cd apps/fw`

`MIX_ENV=prod mix do deps.get, deps.compile`

`MIX_ENV=prod mix firmware`

Insert microSD card and burn it with `MIX_ENV=prod mix firmware.burn`
57 changes: 20 additions & 37 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,51 +1,34 @@
# Example FW
# Rosetta Home 2.0

## Installation
* Install build-essential
* Install libmnl-dev
* Install Erlang
* Install erlang-esl
* Install erlang-dev
* Install erlang-xmerl
* Install erlang-os-mon
* Install erlang-src
* Install erlang-eunit
* Install erlang-parsetools
* Install Elixir 1.4
* Install Nerves
* Install fwup
* Install ssh-askpass
* Install squashfs-tool
* Install rebar and hex
* Install bootstrap
* Install Node >= 6.1
* Install Elm 0.17.1
Rosetta Home 2.0 is an open source Apache 2.0 licensed home automation system built with security and privacy in mind. This means it has an offline first mentality, no internet required. Cloud connectivity is optional for data backup and more in-depth data analysis. You are not locked into any one cloud provider. Out of the box we support encrypted MQTT backends on port `4883`. [Brood](/~https://github.com/rosetta-home/brood) provides all the necessary infrastructure for hosting your own cloud based backend.

It offers a zero-configuration installation, meaning it will attempt to auto-discover as many devices on your network as possible. The system works with a plethora of consumer products for lighting, HVAC, media playback, energy monitoring and weather monitoring. It also works with [CRT Labs](https://crtlabs.org) open source [IEQ (Indoor Environmental Quality) sensors](/~https://github.com/NationalAssociationOfRealtors/IndoorAirQualitySensor).

## Setup
`cp default.env .env`
For an overview of the system, see the slides from [Erlang & Elixir Factory SF Bay 2017](https://docs.google.com/presentation/d/1ebwoJh2H1aQTldHATP0jEGBsT74Yr3dEMmRqTPQvQec/pub?start=false&loop=false&delayms=30000)

change cipher keys to random 10 digits
The system itself runs on a [Raspberry Pi](https://www.raspberrypi.org/) and utilizes several USB dongles to communicate with a multitude of devices over differing protocols. Network connectivity is provided over WiFi or ethernet.

`source .env`
For installation instructions please see the [installation instructions](/INSTALL.md)

## Build Web UI
`cd apps/interface/priv`
Here are some screen shots of the LAN interface.

`elm-make src/Main.elm --output=app.js`
**IEQ**

## Running locally
`MIX_ENV=dev mix do deps.get, deps.compile`
![Scolling Graphs](/assets/RosettaHome2.0.gif)

`MIX_ENV=dev mix compile`

`MIX_ENV=dev iex -S mix`
**Lighting Control**

## Build Firmware
`cd apps/fw`
![Lights](/assets/lights.png)

`MIX_ENV=prod mix do deps.get, deps.compile`
**HVAC Control**

`MIX_ENV=prod mix firmware`
![HVAC](/assets/hvac.png)

`MIX_ENV=prod mix firmware.burn`
**Media Player**

![Media Player](/assets/media_player.png)

**Weather Stations**

![Weather Stations](/assets/weather_stations.png)
29 changes: 29 additions & 0 deletions SETUP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
## Setup

After burning your SD Card follow the instructions below to connect Rosetta Home to WiFi. Alternatively you can just plug it in to ethernet.


1. Plug in all USB dongles
* MeteoStick
* Raven SMCD
* Touchstone Gateway
2. Ensure microSD card is fully inserted into Raspberry Pi
3. Power on Raspberry Pi with a 5.1v 2.5amp power supply
4. Put your phone in airplane mode
5. Turn **ONLY** WiFi back on, usually by tapping your WiFi button after enabling Airplane mode.
6. Connect to **ROSETTA_HOME** network/SSID
7. Go to http://192.168.24.1:8080/network
* Currently Firefox is not supported.
8. Select network and enter network passcode into text input
9. Hit **Connect**
10. Reconnect to the same network you connected the PI too
11. Wait up to 1 minute, usually a 10-20 seconds
12. Goto http://rosetta.local:8080 in your browser
13. If http://rosetta.local:8080 isn’t available after a few minutes there’s a chance you mistyped the network password, this means you will have to manually reset the network

## Rest WiFi Credentials

1. Plug the raspi into ethernet
2. Get the ip address from your router or other method
3. Goto http://{ip}:8080/reset_network
4. Repeat setup instructions
53 changes: 53 additions & 0 deletions apps/fw/mix.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
%{"certifi": {:hex, :certifi, "1.0.0", "1c787a85b1855ba354f0b8920392c19aa1d06b0ee1362f9141279620a5be2039", [:rebar3], []},
"chromecast": {:hex, :chromecast, "0.1.5", "6ffd7615b2abdee3c2394c7190f18c6fb17d67736c00eca11860fa904552a466", [:mix], [{:exprotobuf, "~> 1.1.0", [hex: :exprotobuf, optional: false]}, {:poison, "~> 2.2.0", [hex: :poison, optional: false]}]},
"cicada": {:git, "/~https://github.com/rosetta-home/cicada.git", "5c53a9469b9817d3b4636ac13c8fffb3f9b4bf3e", []},
"cipher": {:hex, :cipher, "1.3.0", "f0ab87bb5c89a284f24a997cd40acbdfef2f2fa2acd7dc0abcd487c7319c8f43", [:mix], [{:plug, ">= 1.1.0", [hex: :plug, optional: false]}, {:poison, "~> 2.0", [hex: :poison, optional: false]}]},
"cowboy": {:hex, :cowboy, "1.1.2", "61ac29ea970389a88eca5a65601460162d370a70018afe6f949a29dca91f3bb0", [:rebar3], [{:cowlib, "~> 1.0.2", [hex: :cowlib, optional: false]}, {:ranch, "~> 1.3.2", [hex: :ranch, optional: false]}]},
"cowlib": {:hex, :cowlib, "1.0.2", "9d769a1d062c9c3ac753096f868ca121e2730b9a377de23dec0f7e08b1df84ee", [:make], []},
"distillery": {:hex, :distillery, "1.1.2", "4cf32ecc70ca7eecca9e52e111edf320bd78011050825863cd8bc7ffee686c5d", [:mix], []},
"dns": {:hex, :dns, "0.0.4", "2e347a0a03e8345bc70c6d69ed08788103a3bec81b93e4636b1b432110835436", [:mix], [{:socket, "~> 0.3.5", [hex: :socket, optional: false]}]},
"elixir_make": {:hex, :elixir_make, "0.4.0", "992f38fabe705bb45821a728f20914c554b276838433349d4f2341f7a687cddf", [:mix], []},
"exjsx": {:hex, :exjsx, "4.0.0", "60548841e0212df401e38e63c0078ec57b33e7ea49b032c796ccad8cde794b5c", [:mix], [{:jsx, "~> 2.8.0", [hex: :jsx, optional: false]}]},
"exprotobuf": {:hex, :exprotobuf, "1.1.0", "0d91a0b527abac118e03361d12eac7262299cdda3a0316fc60763557c227c890", [:mix], [{:gpb, "~> 3.24", [hex: :gpb, optional: false]}]},
"gen_mqtt": {:hex, :gen_mqtt, "0.3.1", "6ce6af7c2bcb125d5b4125c67c5ab1f29bcec2638236509bcc6abf510a6661ed", [:mix], [{:vmq_commons, "1.0.0", [hex: :vmq_commons, optional: false]}]},
"gpb": {:hex, :gpb, "3.26.7", "65497b9991edbf2b7fcedb344e319cba8c411822d8c4df50ede12bc9f6030358", [:make, :rebar], []},
"hackney": {:hex, :hackney, "1.6.6", "5564b4695d48fd87859e9df77a7fa4b4d284d24519f0cd7cc898f09e8fbdc8a3", [:rebar3], [{:certifi, "1.0.0", [hex: :certifi, optional: false]}, {:idna, "4.0.0", [hex: :idna, optional: false]}, {:metrics, "1.0.1", [hex: :metrics, optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, optional: false]}, {:ssl_verify_fun, "1.1.1", [hex: :ssl_verify_fun, optional: false]}]},
"httpoison": {:hex, :httpoison, "0.8.3", "b675a3fdc839a0b8d7a285c6b3747d6d596ae70b6ccb762233a990d7289ccae4", [:mix], [{:hackney, "~> 1.6.0", [hex: :hackney, optional: false]}]},
"idna": {:hex, :idna, "4.0.0", "10aaa9f79d0b12cf0def53038547855b91144f1bfcc0ec73494f38bb7b9c4961", [:rebar3], []},
"ieq_gateway": {:hex, :ieq_gateway, "0.1.4", "eaed8548717a2b0ecac4502c731b2992dbb8270a8f4c02e418b1d9663838d297", [:mix], [{:nerves_uart, "~> 0.1.1", [hex: :nerves_uart, optional: false]}]},
"jsx": {:hex, :jsx, "2.8.2", "7acc7d785b5abe8a6e9adbde926a24e481f29956dd8b4df49e3e4e7bcc92a018", [:mix, :rebar3], []},
"lifx": {:hex, :lifx, "0.1.7", "e213d63b4c8982ce6914849620b92f6cde63e8d91f66d3feca63e8015e69b39d", [:mix], [{:cowboy, "~> 1.0", [hex: :cowboy, optional: false]}, {:poison, "~> 2.1", [hex: :poison, optional: false]}]},
"mdns": {:hex, :mdns, "0.1.5", "566548ae7a1b806e2beb0d3b69a7858580c2f9fec4f8f128602a59a09f3aab39", [:mix], [{:dns, "~> 0.0.4", [hex: :dns, optional: false]}]},
"meteo_stick": {:hex, :meteo_stick, "0.2.2", "177e62bf4d3c69eba947c806e9a4af71f224b7253c46a3407a1e64d977651302", [:mix], [{:nerves_uart, "~> 0.1.1", [hex: :nerves_uart, optional: false]}]},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], []},
"mime": {:hex, :mime, "1.1.0", "01c1d6f4083d8aa5c7b8c246ade95139620ef8effb009edde934e0ec3b28090a", [:mix], []},
"mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], []},
"movi": {:hex, :movi, "0.1.1", "6f17b9f86d3d75b5e8ac566c97522fb3c3f9ab71bdfd47b4571538cefbcd0210", [:mix], [{:nerves_uart, "~> 0.1.1", [hex: :nerves_uart, optional: false]}]},
"nerves": {:git, "/~https://github.com/nerves-project/nerves.git", "58583670f4c4eadab33d25015f99dce44827a7e7", [tag: "v0.4.7"]},
"nerves_firmware": {:hex, :nerves_firmware, "0.3.0", "e04dda1dc6ce13bc39f79596a14805e233e5fa78b29e21c2a71eb65691753fe9", [:mix], []},
"nerves_firmware_http": {:git, "/~https://github.com/nerves-project/nerves_firmware_http.git", "7114cca11439b84e446479023672f76074d9ada8", []},
"nerves_interim_wifi": {:git, "/~https://github.com/rosetta-home/nerves_interim_wifi.git", "8b96addef1644397195e5247b595c19c4ed29a4e", []},
"nerves_network_interface": {:hex, :nerves_network_interface, "0.4.0", "a8e7662cd56fb4fe9060c891d35c43bbbff692ee6fd2d5efd538717da0cd96b8", [:make, :mix], [{:elixir_make, "~> 0.3", [hex: :elixir_make, optional: false]}]},
"nerves_system_br": {:hex, :nerves_system_br, "0.9.4", "5096a9dfec49d4663ccb94c4a4fe45885303fbf31108f7e9400369bdec94b5e7", [:mix], []},
"nerves_system_rpi3": {:git, "/~https://github.com/rosetta-home/nerves_system_rpi3.git", "0872a4486479f72b578443be9331af9f9b679cba", [tag: "v0.10.2"]},
"nerves_toolchain_arm_unknown_linux_gnueabihf": {:hex, :nerves_toolchain_arm_unknown_linux_gnueabihf, "0.9.0", "5a1bca8c46776ad24c358ab58800ed470f91a3e294ac6eb8ffda0041954781e1", [:mix], [{:nerves, "~> 0.4.0", [hex: :nerves, optional: false]}, {:nerves_toolchain_ctng, "~> 0.8.0", [hex: :nerves_toolchain_ctng, optional: false]}]},
"nerves_toolchain_ctng": {:hex, :nerves_toolchain_ctng, "0.8.0", "6dff7ed51e1711c5f4da3d559bc528a8265e3dd950dda95f4d6832aed9dbe320", [:mix], []},
"nerves_uart": {:hex, :nerves_uart, "0.1.2", "4310dbb1721a5a007b8e5c416cf81754415bde6b7e2c9aa65a059886b85e637c", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, optional: false]}]},
"nerves_wpa_supplicant": {:git, "/~https://github.com/rosetta-home/nerves_wpa_supplicant.git", "d8f7d63e2754ca7e41c048ae07c5e3137c03ff90", []},
"plug": {:hex, :plug, "1.3.4", "b4ef3a383f991bfa594552ded44934f2a9853407899d47ecc0481777fb1906f6", [:mix], [{:cowboy, "~> 1.0.1 or ~> 1.1", [hex: :cowboy, optional: true]}, {:mime, "~> 1.0", [hex: :mime, optional: false]}]},
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], []},
"radio_thermostat": {:git, "/~https://github.com/NationalAssociationOfRealtors/radio_thermostat.git", "1e515b070c879ae84e5d7b7ff50351e589462d03", []},
"ranch": {:hex, :ranch, "1.3.2", "e4965a144dc9fbe70e5c077c65e73c57165416a901bd02ea899cfd95aa890986", [:rebar3], []},
"raven_smcd": {:hex, :raven_smcd, "0.2.1", "2f974d93edce367769a9166b2082572b72113619129ab63786d850156814fce7", [:mix], [{:nerves_uart, "~> 0.1.1", [hex: :nerves_uart, optional: false]}, {:sweet_xml, "~> 0.6.1", [hex: :sweet_xml, optional: false]}]},
"rosetta_home_chromecast": {:git, "/~https://github.com/rosetta-home/rosetta_home_chromecast.git", "3599841cdc279141e37593ffabbea5ddd291b619", []},
"rosetta_home_ieq_sensor": {:git, "/~https://github.com/rosetta-home/rosetta_home_ieq_sensor.git", "c78a04cc34ea47b7dad8118c827cee36478ea698", []},
"rosetta_home_lifx": {:git, "/~https://github.com/rosetta-home/rosetta_home_lifx.git", "e267b39003dab6cbf04ed596aaff45a6e7ffae64", []},
"rosetta_home_meteo_stick": {:git, "/~https://github.com/rosetta-home/rosetta_home_meteo_stick.git", "e713daf7d8e713debd5c836126c52a21358ec3f8", []},
"rosetta_home_radio_thermostat": {:git, "/~https://github.com/rosetta-home/rosetta_home_radio_thermostat.git", "0790cf7d85348da71ec06df30b725ed149051ecc", []},
"rosetta_home_raven_smcd": {:git, "/~https://github.com/rosetta-home/rosetta_home_raven_smcd.git", "ea60c699dafad270cf7ba2579b392b56d1fcaebd", []},
"socket": {:hex, :socket, "0.3.7", "68c029a8449fc6efc5f4c3bdf6d8b19ca94d3304e419f364c5cfc8b716f7c219", [:mix], []},
"ssdp": {:hex, :ssdp, "0.1.2", "e6bb53c3a422e93cf99d96f043f1c4ddac7d7b350a8d210ee2a9d08cd082c11c", [:mix], [{:httpoison, "~> 0.8.3", [hex: :httpoison, optional: false]}, {:poison, "~> 2.0", [hex: :poison, optional: false]}, {:sweet_xml, "~> 0.6.1", [hex: :sweet_xml, optional: false]}]},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.1", "28a4d65b7f59893bc2c7de786dec1e1555bd742d336043fe644ae956c3497fbe", [:make, :rebar], []},
"statistics": {:hex, :statistics, "0.4.1", "e9bfe6649f70842d9ebce69aa31ac8b6928e096bde43b683d7d673057237d028", [:mix], []},
"sweet_xml": {:hex, :sweet_xml, "0.6.5", "dd9cde443212b505d1b5f9758feb2000e66a14d3c449f04c572f3048c66e6697", [:mix], []},
"vmq_commons": {:hex, :vmq_commons, "1.0.0", "5f5005c12db33f92f40e818a3617fb148972d59adcf99298c9d3808ef3582e34", [:rebar3], []}}
Binary file added assets/IEQ.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/RosettaHome2.0.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/hvac.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/lights.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/media_player.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/weather_stations.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
defmodule Cherp.Mixfile do
defmodule RosettaHome.Mixfile do
use Mix.Project

def project do
Expand Down
4 changes: 2 additions & 2 deletions mix.lock
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
%{"certifi": {:hex, :certifi, "1.0.0", "1c787a85b1855ba354f0b8920392c19aa1d06b0ee1362f9141279620a5be2039", [:rebar3], []},
"chromecast": {:hex, :chromecast, "0.1.5", "6ffd7615b2abdee3c2394c7190f18c6fb17d67736c00eca11860fa904552a466", [:mix], [{:exprotobuf, "~> 1.1.0", [hex: :exprotobuf, optional: false]}, {:poison, "~> 2.2.0", [hex: :poison, optional: false]}]},
"cicada": {:git, "/~https://github.com/rosetta-home/cicada.git", "fa32c25dfc567e4f7572582581402ac1837a1c28", []},
"cicada": {:git, "/~https://github.com/rosetta-home/cicada.git", "5c53a9469b9817d3b4636ac13c8fffb3f9b4bf3e", []},
"cipher": {:hex, :cipher, "1.3.0", "f0ab87bb5c89a284f24a997cd40acbdfef2f2fa2acd7dc0abcd487c7319c8f43", [:mix], [{:plug, ">= 1.1.0", [hex: :plug, optional: false]}, {:poison, "~> 2.0", [hex: :poison, optional: false]}]},
"cowboy": {:hex, :cowboy, "1.1.2", "61ac29ea970389a88eca5a65601460162d370a70018afe6f949a29dca91f3bb0", [:rebar3], [{:cowlib, "~> 1.0.2", [hex: :cowlib, optional: false]}, {:ranch, "~> 1.3.2", [hex: :ranch, optional: false]}]},
"cowlib": {:hex, :cowlib, "1.0.2", "9d769a1d062c9c3ac753096f868ca121e2730b9a377de23dec0f7e08b1df84ee", [:make], []},
Expand Down Expand Up @@ -28,7 +28,7 @@
"nerves_firmware_http": {:git, "/~https://github.com/nerves-project/nerves_firmware_http.git", "7114cca11439b84e446479023672f76074d9ada8", []},
"nerves_interim_wifi": {:git, "/~https://github.com/rosetta-home/nerves_interim_wifi.git", "8b96addef1644397195e5247b595c19c4ed29a4e", []},
"nerves_network_interface": {:hex, :nerves_network_interface, "0.4.0", "a8e7662cd56fb4fe9060c891d35c43bbbff692ee6fd2d5efd538717da0cd96b8", [:make, :mix], [{:elixir_make, "~> 0.3", [hex: :elixir_make, optional: false]}]},
"nerves_uart": {:hex, :nerves_uart, "0.1.1", "32e6186b1a1b1d744631126df0b6c4049ddde5b04bc0303de29ab86a2edf60a2", [:make, :mix], [{:elixir_make, "~> 0.3", [hex: :elixir_make, optional: false]}]},
"nerves_uart": {:hex, :nerves_uart, "0.1.2", "4310dbb1721a5a007b8e5c416cf81754415bde6b7e2c9aa65a059886b85e637c", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, optional: false]}]},
"nerves_wpa_supplicant": {:git, "/~https://github.com/rosetta-home/nerves_wpa_supplicant.git", "d8f7d63e2754ca7e41c048ae07c5e3137c03ff90", []},
"plug": {:hex, :plug, "1.3.4", "b4ef3a383f991bfa594552ded44934f2a9853407899d47ecc0481777fb1906f6", [:mix], [{:cowboy, "~> 1.0.1 or ~> 1.1", [hex: :cowboy, optional: true]}, {:mime, "~> 1.0", [hex: :mime, optional: false]}]},
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], []},
Expand Down

0 comments on commit 20e1ba8

Please sign in to comment.