## About

This is a fork of drawio. The purpose of this fork is to create a version of drawio that includes some custom plugins.

*Why create a fork* instead of just creating a repo for the plugins? Because the webapp version of drawio does not allow you to load anything but "stock" plugins (I guess for safety reasons).


## Building the project

First of all, what is there to build? There are 3 main build targets. Ordered by "number of steps involved", those are:

 * `staticWebApp`: You can build the project as a *static webapp* (= a set of HTML, JS, CSS, ... files), and just serve the files with a static file server, such as Nginx, Apache, ... The webapp will function correctly EXCEPT for the collaboration plugin

 * `server`: You can build the project as a NodeJS application, that (1) serves the files from the static webapp (see above) and (2) has a websocket 'endpoint', which is required for the collaboration plugin to work.

 * `dockerServer`: You can build the project as a Docker container, which has the above mentioned NodeJS application, static web app, and all necessary dependencies cooked in.

### A word about Nix

All builds are carried out by Nix. Nix can be thought of as a package manager and build system, which adheres to the (IMO valid) philosophy that a build should be deterministic, which in turn means being explicit about every dependency, and every influence from "outside", no matter how tiny, that can influence the result. You may say 'duh-huh', but most build systems actually do not care to enforce this (e.g. NPM, PyPI, CMake, GNU Autotools, some bash script that you wrote), leading to obscure bugs ("how is that? it works on my machine!").

As a build system, Nix is language-agnostic and basically wraps any existing build system in a sandbox to guarantee determinism. A build only has *read*-access to its inputs and produces exactly one output (= a file or directory tree).

As a package manager, on the producer side, Nix can cache build outputs, and distribute them on the internet. On the consumer side, Nix can fetch cached build outputs (which may be build inputs for another build) from the internet.

From my own experience with Nix, I've become convinced that the way software is traditionally distributed, too much accidental complexity has been taken for granted, for too long: While Nix isn't perfect (its tooling has some sharp edges, there is a learning curve and its documentation can be sub-optimal), its core principle works and is incredibly valuable, and it is well worth the investment.

### How to build

Nix runs on Linux and MacOS. Install Nix on your system. Then clone this repository (and perhaps do a shallow clone to save disk space), navigate to the root directory and run:
```
nix-build nix/ -A staticWebApp
```
where `staticWebApp` is the build target. Other build targets were listed above.

Nix will fetch all dependencies from the internet and cache them locally in your `/nix/store`.

A symlink called `result` will be placed in your current working directory, pointing to the build output (in `/nix/store`, where all build outputs are placed). Depending on the build target, result can be different things:
  * if `staticWebApp`, then `result` will point to a root directory with all the HTML, JS, ... files that you can statically host.
  * if `server`, then you can run `./result/bin/drawioserver` to launch the (NodeJS) backend
  * if `dockerServer`, then `result` points to a docker image (.tar.gz)


## Development

To run the server script without installation, you can ask Nix to give you a 'development shell'. In the root directory, run:
```
nix-shell
```
This will fetch all development dependencies (NodeJS, the SCCD compiler, some NPM packages) and you will enter a shell with all environment variables set such that it will appear as if those dependencies are installed on your system. (Your system state is however unaltered).

Then, run `scripts/dev_server.sh` to start a development server. Navigate to `http://localhost:8700`

There are 2 other (build) scripts in the `scripts` directory. The reason is as follows: In the original drawio repository, build outputs are placed in the source tree, and committed into the repository, giving us 2 options:

  1. Rewrite drawio's build script to become pure, such that Nix can take care of the build for us.
  2. Require developers to run the build script from a development shell, and `git add`/`commit` the build output.

We chose option 2, simply because rewriting drawio's build is outside of the scope of this project.


## Running

When you are running the backend server (either after building the server package or running a development server), navigate to <http://localhost:8700> to load the frontend.

### Plugins

2 custom plugins are available that are not part of upstream drawio.

#### Collab

Extends the UI with a collaboration menu, to allow "share by link" and multi-user, synchronous collaboration.

To use this plugin, navigate to <http://localhost:8700/?p=collab>.

#### FTG+PM

Adds a set of primitives to the library panel on the left for the concrete syntax of the FTG+PM formalism. Additionally, creating arrows between FTG+PM primitives will automatically update the style of those arrows to be consistent with the FTG+PM notation.

To use this plugin, navigate to <http://localhost:8700/?p=ftgpm>.
