diff --git a/.babelrc b/.babelrc
new file mode 100644
index 0000000..4aa11a5
--- /dev/null
+++ b/.babelrc
@@ -0,0 +1,4 @@
+{
+ "presets": ["react", "es2015"],
+ "plugins": ["transform-class-properties"]
+}
diff --git a/.eslintrc.json b/.eslintrc.json
new file mode 100644
index 0000000..66dd0a1
--- /dev/null
+++ b/.eslintrc.json
@@ -0,0 +1,35 @@
+{
+ "env": {
+ "browser": true,
+ "es6": true,
+ "node": true
+ },
+ "extends": ["eslint:recommended"],
+ "parserOptions": {
+ "ecmaFeatures": {
+ "experimentalObjectRestSpread": true,
+ "jsx": true
+ },
+ "sourceType": "module",
+ "allowImportExportEverywhere": false,
+ "codeFrame": false
+ },
+ "rules": {
+ "indent": [
+ "error",
+ 4
+ ],
+ "linebreak-style": [
+ "error",
+ "unix"
+ ],
+ "quotes": [
+ "error",
+ "single"
+ ],
+ "semi": [
+ "error",
+ "never"
+ ]
+ }
+}
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..86dc2cb
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,6 @@
+.DS_Store
+node_modules
+app
+dist
+yarn-error.log
+dump.md
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..a6d75f0
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,19 @@
+Copyright (c) 2017 Radek Kyselý
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/PUBLISH.md b/PUBLISH.md
new file mode 100644
index 0000000..8c5ac04
--- /dev/null
+++ b/PUBLISH.md
@@ -0,0 +1,95 @@
+# Publish Your Module
+
+## 1. Create an example code (snippet)
+People who will use your module need to know how it works. For these purposes,
+*create a code snippet* that shows how to use your module and save it
+in a `.coffee` file.
+
+Please don't include `require()` statement in your example.
+
+## 2. Create `module.json`
+Module.json holds all important metadata about your module.
+
+| key | type | description |
+| ---------------|:-----------------:|---------------------------------------|
+| `name` | *String* | Human readable name of your module that is seen in the app.
*Do know that a `unique_name` **will be automatically created** from the `name` and used as the main identificator for the directory name, dependency link, etc.
[Check for name availability and `unique_name` before publishing](https://checkname.framermodules.com)*
+| `description` | *String* | Brief description of what your module does *(recommended 100 characters).*
*Keep in mind including keywords in description greatly increases chances of being found via the app search.*
+| `author` | *String* | Your name, right?
+| `require` | *String* | A `require()` statement that will load your module to the prototype.
*Please avoid using path to the module file that includes `.framer`. Framer won't be able to recognize the module.*
+| `install` | *String or Array* | Path to the file(s) you'd like to be downloaded and installed to the prototype. Please note it's only possible to define exact files, not full directories.
+| `example` | *String* | Path to the file with the snippet created in step 1.
+| `thumb` *(optional)* | *String* | Path to the thumbnail. Thumbnails are shown at `80×80px` (@2x is recommended).
Please use a thumbnail with opaque background (`#1D1D1F` is recommended). Allowed filetypes are `mp4` `mov` `png` `jpg` `gif`.
+| `dependencies` *(optional)* | *Array* | Array of dependencies' *unique names*. Please note each dependency will be installed inside a subdirectory named after their `unique_name`.
+
+### Example `module.json`
+Taken from [this module](https://github.com/kysely/framer-bidirectional-cycle).
+```javascript
+{
+ "name": "Bidirectional Cycle",
+ "description": "Extension that will make Utils.cycle() iterate in both directions",
+ "author": "Radek Kysely",
+
+ "require": "Utilscycle = require 'Utilscycle'",
+ "install": "Utilscycle.coffee",
+ "example": "example.coffee",
+
+ "thumb": "bidirectional-cycle-thumb.mov"
+}
+```
+
+### Note
+To maintain clean prototype directories hierarchy, modules will be installed to
+a subdirectory in `modules` folder named after their `unique_name`. If you need
+to reach parent directories from your code, please use one more set of `../`.
+
+Please note the `require()` command *will be automatically updated* to reach
+module's actual directory.
+
+*Example: A module named `iOS Status Bar` will get a unique name `ios-status-bar`
+and will be installed to `/modules/ios-status-bar/`.
+All paths inside your repository will be preserved under the modules's directory.*
+
+## 3. Push to GitHub
+And keep it there. Your module will always be installed from its GitHub repository.
+
+### Add the badge to your README
+*If you want to* that show your module can be discovered and installed
+via Framer Modules, you can include the following badge to your `README.md`.
+Clicking the badge will also automatically open the app and redirect the
+user to your module!
+
+
+
+Just copy one of the snippets and replace `` with yours as defined in `name` key.
+
+HTML **(recommended, will use @2x)**
+```html
+
+
+
+```
+
+Markdown (will use @1x)
+```md
+[![Install with Framer Modules](https://www.framermodules.com/assets/badge.png)](https://open.framermodules.com/)
+```
+
+## 4. Publish to Framer Modules
+Open Framer Modules, click Publish button in the top right corner,
+enter your GitHub repository link and follow the instructions on the screen.
+
+## Okay, how do I update?
+Just push the changes to GitHub. If you make some changes to `module.json`,
+please re-publish in Framer Modules as described in step #4.
+
+---
+## Questions?
+[Open an issue](https://github.com/kysely/framer-modules/issues) |
+[Send me an e-mail](mailto:kyselyradek@gmail.com) |
+[Reach me on Messenger](https://m.me/kysely)
+
+---
+
+### [← Return to the main page](https://github.com/kysely/framer-modules)
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..4190345
--- /dev/null
+++ b/README.md
@@ -0,0 +1,252 @@
+
+
+
+
+Framer Modules
+Discover, install and save your favorite modules at one place
+
+
+
+
+
+
+## :sparkles: Discover
+Looking for the right module used to be time-consuming and annoying—you didn't know if
+a module for the job exists, you weren't sure where to look for it and you had to
+manually download and move the files just to try things out.
+
+Not anymore. Search for what you need and discover new useful modules without
+disrupting your workflow during prototyping. Not sure what's available? Try **'all'**
+
+![Screenshot of listing the whole registry](./resources/feature-discover.png)
+
+
+
+## :zap: Install
+Tired of downloading and copying modules to the prototype on your own?
+We all are. That's why installing modules is now so easy even your grandma
+can do it. Seriously, it's just “press Enter”.
+
+All modules ship with example code snippets. When you're not yet familiar with
+how a module works, press Cmd C and paste the code in Framer.
+
+
+Found out you don't need the module anymore? Press Cmd Backspace
+and say bye *(the latter is optional)*.
+
+###### Please make sure your prototype is saved before installing a module.
+
+![Screenshot of 'Installed' tab](./resources/feature-install.png)
+
+
+
+## :heart: Save
+Yes, it's true. You can now save your favorite or regularly used modules in presets
+and install them to the prototype in batch with one button. Making wireframe prototype?
+Install these. Doing VR? Install those. Anything you need.
+
+Just press Cmd S on a selected module, add it to a preset
+or create new one and save even more time!
+
+![Screenshot of adding module to a preset](./resources/feature-save.png)
+
+
+
+### All the shortcuts you'll ever need
+
+| Action | Shortcut |
+| ------------------------------------------|-------------------------------------|
+| **Open Framer Modules window** | Cmd ; |
+| Switch between individual tabs | Tab |
+| Close the window | Esc |
+| **Selected module** | |
+| Install selected module | return |
+| Copy the code snippet for selected module | Cmd C |
+| Save the module to a preset | Cmd S |
+| Go to module's GitHub repository | Cmd G |
+| Remove module | Cmd Backspace |
+| **Selected preset** | |
+| Install modules from preset | return |
+| Delete preset | Cmd Backspace |
+| Edit preset modules | Cmd E |
+
+![It's what we make it. So let's make it great!](./resources/feature-community@2x.png)
+
+The “community-driven” part in the description is not just an empty phrase.
+This app is developed by the same people who are using it. If you are
+one of them (actually... us) and want to make our modules registry/manager even
+better, **you're more than welcome to contribute**.
+
+This part of the docs will hopefully acquaint you with the inner workings of
+the whole system.
+
+## Architecture
+
+### Hosting the modules and `module.json`
+Due to this project's open-source nature, the modules' management was designed
+to be as easy as possible and seamlessly integrated with other technologies
+available.
+
+That's why there is **no own** server **hosting** the actual modules files.
+Instead, **modules are hosted on GitHub** and recognized by their **`module.json`**
+metadata file. Upon the installation, module files are pulled from the GitHub
+repository as specified in *module.json* and installed to the prototype.
+
+That is why we don't need our own fileserver and why the **Framer Modules registry
+is basically just a database holding modules' `module.json` files**.
+
+![Modules Hosting Scheme](./resources/modules-hosting@2x.png)
+
+Hosting on GitHub also provides us the perks of **not needing user accounts**.
+When the module is published to the registry, it carries the information
+about the author in its repository link. This is enough to recognize the author
+and give them the permissions to update and overwrite. Publishing or updating
+a module with the same name from a different GitHub user is automatically rejected.
+
+### System Components & Technology stack
+You can say the whole system consists of 3 major parts:
+
+- **[Framer Modules app](#framer-modules-app)** — The main app for the designer
+ that handles the prototype management
+- **[Server](#server)** — Small server for communication with the modules registry
+- **[Modules Registry](#modules-registry-database)** — Collection of modules
+ metadata in database
+
+
+
+ Framer Modules App
+
+
+Is built on [**`Electron`**](https://electron.atom.io) and handles all actions
+related to prototype management. The app is split into two parts that communicate
+with each other using `ipcMain` and `ipcRenderer` modules from Electron.
+
+#### Core
+The `main` Electron process that is responsible for all 3 main types of actions being taken.
+
+First is communication with the renderer process via `ipc`. Literally all methods for this
+are defined in self-titled `Actions.js`. Some methods also preprocess the responses
+before sending them back to renderer process, but otherwise they're pretty straightforward.
+
+Second type of actions is HTTP requests. Although the requests are being used throughout
+the whole core and aren't defined at one place, they all use
+[**`request`**](https://www.npmjs.com/package/request) package to make the calls.
+However, methods for making the requests to the Framer Modules server share many properties
+and thus are defined in `ServerRequest.js`.
+
+And last but not least, the actions that actually handle the prototype are to be found
+in `prototype-actions` subdirectory. The functions are fed `module.json`
+(or an array of those) and prototype's path. Using `request`, they then **pull the files**
+from the corresponding GitHub repository as defined in the JSON and **pipe them** to
+the module-specific subfolder in prototype's `modules` directory.
+
+If the un/installation is successful, the core will update prototype's
+`app.coffee` (by adding/removing `require()` statement) and
+`framer/config.json` (by recalculating folded code ranges). If any error occurs during
+the installation, the whole module gets removed.
+
+Installed modules are also recognized by directory name and `module.json` inside.
+Any loose files or directories without `module.json` will result in “unmanaged” modules.
+
+#### Interface
+Interface is written with [**`React`**](https://facebook.github.io/react/) and
+although we are *not* using any “single source of truth” state container,
+**the state** for the most of the app **is stored within a single**, highest-level,
+component. There are two components that have their own state, `Splash` and
+`ModalWindow`, and the reasons for those are pretty obvious in use.
+
+Please note that because I couldn't get `webpack` to bundle `ipcRenderer` module
+from Electron, the methods for communication between the two processes are defined
+in the separate `Action.js` file loaded to the page via `
+
+