Skip to content

firelab/behave-app

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Behave Polylith

Prerequisites

Getting Started

Emacs/CIDER

  1. Pull down the repository (git clone [email protected]:sig-gis/behave-polylith)
  2. Pull down the submodules (git submodule update --init --remote)
  3. Follow the Datomic Setup (see below)
  4. Start the Datomic Transactor (see below)
  5. Open development/user.cljs in Emacs
  6. Start the CIDER nREPL cider-jack-in-clj&cljs
  7. Choose figwheel-main and dev for the front-end build.
  8. Open http://localhost:8080 in your browser.

Architecture

Polylith

This project adopts a Polylith design, which allows both a mono-repo experience across mulitple projects.

What is a Polylith?

The Polylith project organization method attempts to marry the best parts of operating within a single Monorepo (single source of truth, DRY code, less repos to manage), with the benefits of having single repos for each project (customization).

The Polylith design is made up of three parts: Components, Bases, and Projects.

Components

This is the most basic unit for Polylith. Ideally, Components require few, if any, dependencies. Each component always has an <component>.interface namespace, which includes the public functions that are meant to be exported from the component. Components (ideally) are written in the Clojure Common (*.cljc) format so as to be used in both CLJ and CLJS environments.

Bases

Bases are groups of components and other dependencies that constitute a middle-tier of the Polylith. Bases can be project-specific, but ideally are general enough to be used across multiple projects. Bases typically only have a main.clj[sc] file.

Projects

Projects are made up of multiple bases and components. Many projects can exist within a Polylith, which enables a great deal of customization while also sharing components and bases across projects.

Components Library

The projects take advantage of the Behave Components shared UI components library. Check out the docs on the Behave Components page to learn more.

Reagent & Re-Frame

The projects use both Reagent and Re-Frame to manage application state and application logic. Re-Frame was adopted to reduce tight coupling between views/components and the data/actions that are used within them.

Datalog & Datoms

The projects store data in Datoms and performs queries using the Datalog syntax. The back-end access Datoms using DataHike, and the front-end accesses Datoms through DataScript. Re-Posh is also used to enable subscriptions on DataScript entities, reducing view logic.

Projects

App (projects/behave)

Schema

digraph GitHub {
    graph [rankdir = "LR"]

    node [shape = record]

    Tool [label="Tools
          |{ :bp/uuid              | string }
          |{ :tool/name            | string }
          |{ :tool/order           | number }
          |{ :tool/translation-key | string }
          |{ :tool/help-key        | string }"]

    SubTool [label="Subtool
             |{ :bp/uuid                 | string }
             |{ :subtool/name            | string }
             |{ :subtool/order           | number }
             |{ :subtool/autocompute?    | boolean }
             |{ :subtool/translation-key | string }
             |{ :subtool/help-key        | string }"]

    SubToolVariable [label="Subtool-Variable
                     |{ :bp/uuid                             | string }
                     |{ :subtool-variable/io                 | keyword }
                     |{ :subtool-variable/order              | number }
                     |{ :subtool-variable/cpp-namespace-uuid | string }
                     |{ :subtool-variable/cpp-mclass         | string }
                     |{ :subtool-variable/cpp-function-uuid  | string }
                     |{ :subtool-variable/translation-key    | string }
                     |{ :subtool-variable/help-key           | string }"]

    Variable [label="Variable
              |{ :bp/uuid                         | string }
              |{ :variable/name                   | string }
              |{ :variable/bp6-label              | string }
              |{ :variable/bp6-code               | string }
              |{ :variable/kind                   | keyword}
              |{ :variable/translation-key        | string }
              |{ :variable/native-decimals        | double }
              |{ :variable/english-decimals       | double }
              |{ :variable/metric-decimals        | double }
              |{ :variable/maximum                | double }
              |{ :variable/minimum                | double }
              |{ :variable/default-value          | double }
              |{ :variable/map-units-convertible? | double }
              "]
    List [label="List
          |{ :bp/uuid               | string }
          |{ :list/name             | string }
          |{ :list/translation-key  | string }
          "]

    ListOptions [label="List-Options
                 |{ :bp/uuid                     | string }
                 |{ :list-option/name            | string }
                 |{ :list-option/default         | string }
                 |{ :list-option/value           | string }
                 |{ :list-option/order           | string }
                 |{ :list-option/translation-key | string }
                 "]

    Dimension [label="Dimension
               |{ :bp/uuid                 | string }
               |{ :dimension/name          | string }
               |{ :dimension/cpp-enum-uuid | string }
               "]

    Unit [label="Unit
          |{ :bp/uuid                   | string }
          |{ :unit/name                 | string }
          |{ :unit/short-code           | string }
          |{ :unit/system               | string }
          |{ :unit/cpp-enum-member-uuid | string }
          "]

    DomainSet [label="Domain-Set
               |{ :bp/uuid         | string }
               |{ :domain-set/name | string }
               "]

    Domain [label="Domain
            |{ :bp/uuid               | string }
            |{ :domain/name     | string }
            |{ :domain/decimals | string }
            "]

    Tool      -> SubTool         [label=":tool/subtools" taillabel=1 headlabel=N]
    SubTool   -> SubToolVariable [label=":subtool/variables" taillabel=1 headlabel=N]
    Variable  -> SubToolVariable [label=":variable/subtool-variables" taillabel=1 headlabel=N]
    Variable  -> List            [label=":variable/list" taillabel=1 headlabel=1]
    Variable  -> Domain          [label=":variable/domain-uuid" taillabel=1 headlabel=1]
    Variable  -> Unit            [label=":variable/native-unit-uuid" taillabel=1 headlabel=1]
    Variable  -> Unit            [label=":variable/english-unit-uuid" taillabel=1 headlabel=1]
    Variable  -> Unit            [label=":variable/metric-unit-uuid" taillabel=1 headlabel=1]
    List      -> ListOptions     [label=":list/options" taillabel=1 headlabel=N]
    Dimension -> Unit            [label=":dimension/units" taillabel=1 headlabel=N]
    DomainSet -> Domain          [label=":domain-set/domains" taillabel=1 headlabel=N]
    Domain    -> Dimension       [label=":domain/dimension-uuid" taillabel=1 headlabel=1]
    Domain    -> Unit            [label=":domain/native-unit-uuid" taillabel=1 headlabel=1]
    Domain    -> Unit            [label=":domain/english-unit-uuid" taillabel=1 headlabel=1]
    Domain    -> Unit            [label=":domain/metric-unit-uuid" taillabel=1 headlabel=1]
}

Building the Behave UberJAR

  1. Navigate to projects/behave. All paths described here will use this directory as root.
  2. Add/edit the resources/config.edn for your deployment. Below is an example file:
;; resources/config.edn
{:database {:config {:store {:backend :file
                             :path    "~/.behave/db"}}}
 :site     {:title       "BehavePlus 7"
            :description "Wildfire Analysis toolkit."}
 :server   {:http-port 8007
            :mode      "prod"}
 :vms      {:secret-token "<vms-secret-token>"}}
  1. Compile ClojureScript
bb build-js
  1. Build the UberJAR

NOTE: The uberjar build process requires triangulum to be available in the deps.edn located at the user level (i.e. home/<user>/.clojure/deps.edn).

{sig-gis/triangulum {:git/url "https://github.com/sig-gis/triangulum"
                     :sha     "<latest-sha>"}}
bb uber
  1. Congratulations! You’re now the owner of an UberJAR. (i.e. target/behave7-2023.10.19-97f1ef9-standalone.jar)

Behave CMS (projects/behave_cms)

Schema

TODO

Datomic Setup

Download & Setup Datomic Pro

mkdir -p ~/.datomic
cd ~/.datomic
curl -O https://datomic-pro-downloads.s3.amazonaws.com/1.0.7075/datomic-pro-1.0.7075.zip
unzip *.zip
ln -s $PWD/datomic-pro-1.0.7075 $PWD/current
echo 'export PATH="$HOME/.datomic/current/bin:$PATH"' >> ~/.bashrc # Or ~/.zshrc

Setting up PostgreSQL for Datomic

Be sure that PostgreSQL is running on port 5432.

cd /bases/datomic_store/sql/
psql -U postgres -f 01_setup.sql # Creates the Datomic DB, User
psql -U datomic datomic -f 02_tables.sql # Sets up the KV table

Running the Transactor

bb transactor

Running the Datomic Console

bb console --port <port>

Then visit localhost:8000/browse

Restoring CMS using a backup file

bb restore --file <datomic-2024-##-##.dump>

Behave-Lib

The “behave-lib” directory includes the build process for generating a WASM file using c++ code from “behave-mirror” and “include” directories. Here’s Checklist for when new c++ code needs to be transcribed into wasm and be available via the Behave CMS.

Create new WASM file

Updating Hatchet’s idl output and copying to behave.idl

  • [ ] Run the pair of header files (i.e. surface.h and SIGSurface.h) through Hatchet (see Hatchet README).
  • [ ] Replace/Edit text
    • [ ] “std_string” with “[Const] DOMString”
    • [ ] “string” with [Const] DOMString
    • [ ] Any type ref to other classes with “[Ref] SIG<module>”
    • [ ] Add [Const] to beginning of function in behave.idl for any functions in header file ending in const.
  • [ ] Copy missing functions to the SIG<module> interface in “behave-lib/include/idl/behave.idl”
  • [ ] Add new enums in “behave-lib/include/idl/behave.idl”
    • [ ] For each enum in behave.idl there should be an enum entry in “src/cljs/behave/lib/enums.cljs”

Updating CLJS file in Behave with Hatchet’s output.

  • [ ] Add missing functions from hatchet’s output cljs file to “behave/src/cljs/behave/lib/<model>.cljs”
  • [ ] Add this to the end of the file
(def ^:export ns-public-fns (update-keys (ns-publics 'behave.lib.ignite) name))

Updating enums.cpp

  • [ ] Add mapping for new enums in “behave-lib/include/cpp/emscripten/enums.cpp”

Updating behave_extern.js

  • [ ] Update behave_extern.js with functions from cljs file

Create new WASM file

  • [ ] In “behave-lib” run
make install

Import EDN files from hatchet into CMS

  • [ ] Both edn files have been created through hatchet (i.e. surface.edn and SIGSurface.edn)
  • [ ] Run a modified version of the code block below for the module that needs updating
(ns cms-import)
;; Combine edn files from hatchet
(cms-import {:behave-file      "path/to/hatchet/output/surface.edn"
             :sig-adapter-file "path/to/hatchet/output/SIGSurface.edn"
             :out-file-name    "SIGSurface.edn"
             :from-key         :Surface
             :to-key           :SIGSurface})

(add-export-file-to-conn "./cms-exports/SIGSurface.edn" conn)

Schema ERDs

VMS

This schema is used for the Behave VMS. It largely impacts the rendering UI of the Behave VMS and the Application.

// Relations (NOTE when a relation attribute of type :db/type/string instead of type :db.type/ref, this means the value is a UUID that matches the :bp/uuid of the related entity.)

digraph GitHub {
    graph [rankdir = "LR"]

    node [shape = record]

    //----------------------------------------------------------------------------------------------
    // VMS Schema Starts Here
    //----------------------------------------------------------------------------------------------

    User [label="User
          |{ :bp/uuid           | string }
          |{ :user/name         | string }
          |{ :user/email        | string }
          |{ :user/password     | string }
          |{ :user/reset-key    | string }
          |{ :user/verified?    | boolean }
          |{ :user/super-admin? | boolean }
          |{ :user/help-key     | string }
          "]

    //----------------------------------------------------------------------------------------------

    Application [label="Application
                 |{ :bp/uuid                   | string }
                 |{ :application/name          | string }
                 |{ :application/version-major | number }
                 |{ :application/version-minor | number }
                 |{ :application/version-patch | number }
                 |{ :application/version       | tuple }
                 |{ :application/help-key      | string }
                 "]
    Application -> Module      [label=":application/modules" taillabel=1 headlabel=N]
    Application -> Tool        [label=":application/tools" taillabel=1 headlabel=N]
    Application -> HelpPage    [label=":application/help-key" taillabel=1 headlabel=1]
    Application -> Translation [label=":application/translation-key" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    Module [label="Module
            |{ :bp/uuid                | string }
            |{ :module/name            | string }
            |{ :module/order           | number }
            "]
    Module -> Submodule   [label=":module/submodules" taillabel=1 headlabel=N]
    Module -> Diagram     [label=":module/diagram" taillabel=1 headlabel=N]
    Module -> HelpPage    [label=":module/help-key" taillabel=1 headlabel=1]
    Module -> Translation [label=":module/translation-key" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    Submodule [label="Submodule
               |{ :bp/uuid                         | string }
               |{ :submodule/name                  | string }
               |{ :submodule/order                 | number }
               |{ :submodule/io                    | keyword }
               |{ :submodule/research?             | boolean }
               |{ :submodule/conditionals-operator | keyword }
               "]
    Submodule -> Group       [label=":submodule/groups" taillabel=1 headlabel=N]
    Submodule -> Conditional [label=":submodule/conditionals" taillabel=1 headlabel=N]
    Submodule -> HelpPage    [label=":submodule/help-key" taillabel=1 headlabel=1]
    Submodule -> Translation [label=":submodule/translation-key" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    Group [label="Group
           |{ :bp/uuid                     | string }
           |{ :group/name                  | string }
           |{ :group/order                 | long }
           |{ :group/io                    | keyword }
           |{ :group/research?             | boolean }
           |{ :group/repeat?               | boolean }
           |{ :group/max-repeat            | long }
           |{ :group/conditionals-operator | keyword }
           "]
    Group -> Group         [label=":group/children" taillabel=1 headlabel=1]
    Group -> Conditional   [label=":group/conditionals" taillabel=1 headlabel=N]
    Group -> GroupVariable [label=":group/group-variables" taillabel=1 headlabel=N]
    Group -> HelpPage      [label=":group/help-key" taillabel=1 headlabel=1]
    Group -> Translation   [label=":group/translation-key" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    GroupVariable [label="Group-Variable
                   |{ :bp/uuid                      | string }
                   |{ :group-variable/cpp-class     | string }
                   |{ :group-variable/cpp-function  | string }
                   |{ :group-variable/cpp-namespace | string }
                   |{ :group-variable/cpp-parameter | string }
                   |{ :group-variable/order         | long}
                   |{ :group-variable/research?     | boolean }
                   "]
    GroupVariable -> CppClass     [label=":group-variable/cpp-class (uuid)" taillabel=1 headlabel=1]
    GroupVariable -> CppFunction  [label=":group-variable/cpp-function (uuid)" taillabel=1 headlabel=1]
    GroupVariable -> CppNamespace [label=":group-variable/cpp-namespace (uuid)" taillabel=1 headlabel=1]
    GroupVariable -> CppParameter [label=":group-variable/cpp-parameter (uuid)" taillabel=1 headlabel=1]
    GroupVariable -> HelpPage     [label=":group-variable/help-key" taillabel=1 headlabel=1]
    GroupVariable -> Translation  [label=":group-variable/translation-key" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    CppClass [label="Cpp.Class
              |{ :bp/uuid        | string }
              |{ :cpp.class/name | string }
              "]
    CppClass -> CppFunction [label=":cpp.class/function" taillabel=1 headlabel=N]

    //----------------------------------------------------------------------------------------------

    CppFunction [label="Cpp.Function
                 |{ :bp/uuid                  | string }
                 |{ :cpp.function/name        | string }
                 |{ :cpp.function/return-type | stringema}
                 "]
    CppFunction -> CppParameter [label=":cpp.function/parameter" taillabel=1 headlabel=N]

    //----------------------------------------------------------------------------------------------

    CppParameter [label="Cpp.Parameter
                  |{ :bp/uuid             | string }
                  |{ :cpp.parameter/name  | string }
                  |{ :cpp.parameter/order | number }
                  |{ :cpp.parameter/type  | string }
                  "]

    //----------------------------------------------------------------------------------------------

    CppNamespace [label="Cpp.Namespace
                  |{ :bp/uuid             | string }
                  |{ :cpp.namespace/name  | string }
                  "]
    CppNamespace -> CppClass [label=":cpp.namespace/class" taillabel=1 headlabel=N]
    CppNamespace -> CppEnum  [label=":cpp.namespace/enum" taillabel=1 headlabel=N]

    //----------------------------------------------------------------------------------------------

    CppEnum [label="Cpp.Enum
             |{ :bp/uuid       | string }
             |{ :cpp.enum/name | string }
             "]
    CppEnum -> CppEnumMember [label=":cpp.enum/enum-member" taillabel=1 headlabel=N]

    //----------------------------------------------------------------------------------------------

    CppEnumMember [label="Cpp.Enum-member
                   |{ :bp/uuid               | string }
                   |{ :cpp.enum-member/name  | string }
                   |{ :cpp.enum-member/value | number }
                   "]

    //----------------------------------------------------------------------------------------------

    Tool [label="Tools
          |{ :bp/uuid    | string }
          |{ :tool/name  | string }
          |{ :tool/order | number }
          "]
    Tool -> SubTool     [label=":tool/subtools" taillabel=1 headlabel=N]
    Tool -> HelpPage    [label=":tool/help-key" taillabel=1 headlabel=1]
    Tool -> Translation [label=":tool/translation-key" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    SubTool [label="Subtool
             |{ :bp/uuid              | string }
             |{ :subtool/name         | string }
             |{ :subtool/order        | number }
             |{ :subtool/autocompute? | boolean }
             "]
    SubTool -> SubToolVariable [label=":subtool/variables" taillabel=1 headlabel=N]
    SubTool -> HelpPage        [label=":subtool/help-key" taillabel=1 headlabel=1]
    SubTool -> Translation     [label=":subtool/translation-key" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    SubToolVariable [label="Subtool-Variable
                     |{ :bp/uuid                             | string }
                     |{ :subtool-variable/io                 | keyword }
                     |{ :subtool-variable/order              | long }
                     |{ :subtool-variable/cpp-namespace-uuid | string }
                     |{ :subtool-variable/cpp-mclass         | string }
                     |{ :subtool-variable/cpp-function-uuid  | string }
                     "]
    SubToolVariable -> HelpPage    [label=":subtool-variable/help-key" taillabel=1 headlabel=1]
    SubToolVariable -> Translation [label=":subtool-variable/translation-key" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    Variable [label="Variable
              |{ :bp/uuid                         | string }
              |{ :variable/name                   | string }
              |{ :variable/bp6-label              | string }
              |{ :variable/bp6-code               | string }
              |{ :variable/kind                   | keyword}
              |{ :variable/native-decimals        | double }
              |{ :variable/english-decimals       | double }
              |{ :variable/metric-decimals        | double }
              |{ :variable/maximum                | double }
              |{ :variable/minimum                | double }
              |{ :variable/default-value          | double }
              |{ :variable/map-units-convertible? | boolean }
              "]
    Variable -> GroupVariable   [label=":variable/group-variables" taillabel=1 headlabel=N]
    Variable -> SubToolVariable [label=":variable/subtool-variables" taillabel=1 headlabel=N]
    Variable -> List            [label=":variable/list" taillabel=1 headlabel=1]
    Variable -> Domain          [label=":variable/domain-uuid" taillabel=1 headlabel=1]
    Variable -> Unit            [label=":variable/native-unit-uuid" taillabel=1 headlabel=1]
    Variable -> Unit            [label=":variable/english-unit-uuid" taillabel=1 headlabel=1]
    Variable -> Unit            [label=":variable/metric-unit-uuid" taillabel=1 headlabel=1]
    Variable -> Translation     [label=":variable/translation-key" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    List [label="List
          |{ :bp/uuid   | string }
          |{ :list/name | string }
          "]
    List -> ListOption  [label=":list/options" taillabel=1 headlabel=N]
    List -> Translation [label=":list/translation-key" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    ListOption [label="List-Option
                 |{ :bp/uuid             | string }
                 |{ :list-option/name    | string }
                 |{ :list-option/default | string }
                 |{ :list-option/value   | string }
                 |{ :list-option/order   | long }
                 |{ :list-option/hide?   | boolean }
                 "]
    ListOption -> Translation [label=":list-option/translation-key" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    Dimension [label="Dimension
               |{ :bp/uuid                 | string }
               |{ :dimension/name          | string }
               |{ :dimension/cpp-enum-uuid | string }
               "]
    Dimension -> Unit [label=":dimension/units" taillabel=1 headlabel=N]

    //----------------------------------------------------------------------------------------------

    Unit [label="Unit
          |{ :bp/uuid                   | string }
          |{ :unit/name                 | string }
          |{ :unit/short-code           | string }
          |{ :unit/system               | string }
          |{ :unit/cpp-enum-member-uuid | string }
          "]

    //----------------------------------------------------------------------------------------------

    DomainSet [label="Domain-Set
               |{ :bp/uuid         | string }
               |{ :domain-set/name | string }
               "]
    DomainSet -> Domain [label=":domain-set/domains" taillabel=1 headlabel=N]

    //----------------------------------------------------------------------------------------------

    Domain [label="Domain
            |{ :bp/uuid         | string }
            |{ :domain/name     | string }
            |{ :domain/decimals | string }
            "]
    Domain -> Dimension [label=":domain/dimension-uuid" taillabel=1 headlabel=1]
    Domain -> Unit      [label=":domain/native-unit-uuid" taillabel=1 headlabel=1]
    Domain -> Unit      [label=":domain/english-unit-uuid" taillabel=1 headlabel=1]
    Domain -> Unit      [label=":domain/metric-unit-uuid" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    Conditional [label="Conditional
                 |{ :bp/uuid              | string }
                 |{ :conditional/type     | keyword }
                 |{ :conditional/operator | keyword }
                 |{ :conditional/values   | string }
                 "]
    Conditional -> GroupVariable [label=":conditional/group-variable-uuid" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    Diagram [label="Diagram
             |{ :bp/uuid      | keyword }
             |{ :diagram/type | string }
             "]
    Diagram -> GroupVariable [label=":diagram/group-variable" taillabel=1 headlabel=1]
    Diagram -> GroupVariable [label=":diagram/input-group-variables" taillabel=1 headlabel=N]
    Diagram -> GroupVariable [label=":diagram/output-group-variables" taillabel=1 headlabel=N]

    //----------------------------------------------------------------------------------------------

    Language [label="Language
              |{ :bp/uuid              | keyword }
              |{ :language/name        | string }
              |{ :language/short-code  | string }
              "]
    Language -> Translation [label=":language/translation" taillabel=1 headlabel=1]
    Language -> HelpPage    [label=":language/help-page" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    Translation [label="Translation
                 |{ :bp/uuid                 | keyword }
                 |{ :translation/name        | string }
                 |{ :translation/key         | string }
                 |{ :translation/translation | string }
                 "]

    //----------------------------------------------------------------------------------------------

    HelpPage [label="Help-page
          |{ :bp/uuid           | keyword }
          |{ :help-page/key     | string }
          |{ :help-page/content | string }
          "]

    //----------------------------------------------------------------------------------------------

    Link [label="Link
          |{ :bp/uuid | keyword }
          "]
    Link -> GroupVariable [label="link/source" taillabel=1 headlabel=1]
    Link -> GroupVariable [label="link/destination" taillabel=1 headlabel=1]
}

Worksheet

This schema is used to store instances of worksheet information in the Behave application.

// Relations (NOTE when a relation attribute of type :db/type/string instead of type :db.type/ref, this means the value is a UUID that matches the :bp/uuid of the related entity.)

digraph GitHub {
    graph [rankdir = "LR"]

    node [shape = record]

    //----------------------------------------------------------------------------------------------
    // Worksheet Schema Starts Here
    //----------------------------------------------------------------------------------------------

    Worksheet [label="Worksheet
               |{ :bp/uuid                         | string }
               |{ :worksheet/run-description       | string }
               |{ :worksheet/name                  | string }
               |{ :worksheet/created               | long }
               |{ :worksheet/furthest-visited-step | keyword }
               |{ :worksheet/modules               | keywords }
               "]
    Worksheet -> Note             [label=":worksheet/notes" taillabel=1 headlabel=N]
    Worksheet -> InputGroup       [label=":worksheet/input-groups" taillabel=1 headlabel=N]
    Worksheet -> RepeatGroup      [label=":worksheet/repeat-groups" taillabel=1 headlabel=N]
    Worksheet -> Output           [label=":worksheet/outputs" taillabel=1 headlabel=N]
    Worksheet -> ResultTable      [label=":worksheet/result-table" taillabel=1 headlabel=1]
    Worksheet -> GraphSettings    [label=":worksheet/graph-settings" taillabel=1 headlabel=1]
    Worksheet -> TableSettings    [label=":worksheet/table-settings" taillabel=1 headlabel=1]
    Worksheet -> WorksheetDiagram [label=":worksheet/diagrams" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    Note [label="Note
          |{ :bp/uuid        | string }
          |{ :note/name      | string }
          |{ :note/content   | string }
          |{ :note/submodule | string }
          "]

    //----------------------------------------------------------------------------------------------

    InputGroup [label="Input-Group
                |{ :bp/uuid                | string }
                |{ :input-group/repeat-id  | long }
                |{ :input-group/inputs     | long }
                "]
    InputGroup -> Group [label=":input-group/group-uuid" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    RepeatGroup [label="Repeat-Group
                 |{ :bp/uuid                 | string }
                 |{ :repeat-group/group-uuid | string }
                 |{ :repeat-group/repeats    | long }
                 |{ :repeat-group/inputs     | long }
                 "]
    RepeatGroup -> Group [label=":repeat-group/group-uuid" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    Output [label="Output
            |{ :bp/uuid         | string }
            |{ :output/enabled? | boolean }
            "]
    Output -> GroupVariable [label=":output/group-variable-uuid" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    ResultTable [label="Result-Table
                 |{ :bp/uuid | string }
                 "]
    ResultTable -> ResultHeader [label=":result-table/headers" taillabel=1 headlabel=N]
    ResultTable -> ResultRow    [label=":result-table/rows" taillabel=1 headlabel=N]

    //----------------------------------------------------------------------------------------------

    ResultHeader [label="Result-Header
                  |{ :bp/uuid                 | string }
                  |{ :result-header/repeat-id | long }
                  |{ :result-header/order     | long }
                  |{ :result-header/units     | string }
                  "]
    ResultHeader -> GroupVariable [label=":result-header/group-variable-uuid" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    ResultRow [label="Result-Row
               |{ :bp/uuid       | string }
               |{ :result-row/id | long }
               "]
    ResultRow -> ResultCell [label=":result-row/cells" taillabel=1 headlabel=N]

    //----------------------------------------------------------------------------------------------

    ResultCell [label="Result-Cell
                |{ :bp/uuid           | string }
                |{ :result-cell/value | string }
                "]
    ResultCell -> ResultHeader [label=":result-cell/header" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    TableSettings [label="Table-Settings
                   |{ :bp/uuid                 | string }
                   |{ :table-settings/enabled? | boolean }
                   "]
    TableSettings -> TableFilter      [label=":table-settings/filters" taillabel=1 headlabel=N]
    TableSettings -> MapUnitsSettings [label=":table-settings/map-units-settings" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    TableFilter [label="Table-Filter
                 |{ :bp/uuid               | string }
                 |{ :table-filter/min      | long }
                 |{ :table-filter/max      | long }
                 |{ :table-filter/enabled? | boolean }
                 "]
    TableFilter      -> GroupVariable    [label=":table-filter/group-variable-uuid" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    MapUnitsSettings [label="Map-Units-settings
                      |{ :bp/uuid                             | string }
                      |{ :map-units-settings/enabled?         | boolean }
                      |{ :map-units-settings/units            | string }
                      |{ :map-units-settings/map-rep-fraction | long }
                      "]

    //----------------------------------------------------------------------------------------------

    GraphSettings [label="Graph-Settings
                   |{ :bp/uuid                 | string }
                   |{ :graph-settings/enabled? | boolean }
                   "]
    GraphSettings -> YAxisLimit    [label=":graph-settings/y-axis-limits" taillabel=1 headlabel=N]
    GraphSettings -> GroupVariable [label=":graph-settings/x-axis-group-variable-uuid" taillabel=1 headlabel=1]
    GraphSettings -> GroupVariable [label=":graph-settings/z-axis-group-variable-uuid" taillabel=1 headlabel=1]
    GraphSettings -> GroupVariable [label=":graph-settings/z2-axis-group-variable-uuid" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    YAxisLimit [label="Y-Axis-Limit
                |{ :bp/uuid                          | string }
                |{ :y-axis-limit/min                 | long }
                |{ :y-axis-limit/max                 | long }
                "]
    YAxisLimit -> GroupVariable [label=":y-axis-limit/group-variable-uuid" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    WorksheetDiagram [label="Worksheet-diagram
                      |{ :bp/uuid                  | string }
                      |{ :worksheet.diagram/title  | string }
                      |{ :worksheet.diagram/row-id | long }
                      "]
    WorksheetDiagram -> GroupVariable [label=":worksheet.diagram/group-variable-uuid" taillabel=1 headlabel=1]
    WorksheetDiagram -> Ellipse       [label=":worksheet.diagram/ellises" taillabel=1 headlabel=N]
    WorksheetDiagram -> Arrow         [label=":worksheet.diagram/arrows" taillabel=1 headlabel=N]
    WorksheetDiagram -> ScatterPlot   [label=":worksheet.diagram/scatter-plots" taillabel=1 headlabel=N]

    //----------------------------------------------------------------------------------------------

    Ellipse [label="Ellipse
             |{ :bp/uuid                 | string }
             |{ :ellipse/legend-id       | string }
             |{ :ellipse/semi-major-axis | double }
             |{ :ellipse/semi-minor-axis | double }
             |{ :ellipse/rotation        | long }
             |{ :ellipse/color           | string }
             "]

    //----------------------------------------------------------------------------------------------

    Arrow [label="Arrow
           |{ :bp/uuid         | string }
           |{ :arrow/legend-id | string }
           |{ :arrow/length    | double }
           |{ :arrow/rotation  | double }
           |{ :arrow/color     | string }
           |{ :arrow/dashed?   | string }
           "]

    //----------------------------------------------------------------------------------------------

    ScatterPlot [label="Scatter-Plot
                 |{ :bp/uuid                    | string }
                 |{ :scatter-plot/legend-id     | string }
                 |{ :scatter-plot/color         | string }
                 |{ :scatter-plot/x-coordinates | string }
                 |{ :scatter-plot/y-coordinates | string }
                 "]
}

VMS + Worksheet

This Documents the schema for both the behave and behave_cms project.

// Relations (NOTE when a relation attribute of type :db/type/string instead of type :db.type/ref, this means the value is a UUID that matches the :bp/uuid of the related entity.)

digraph GitHub {
    graph [rankdir = "LR"]

    node [shape = record]

    //----------------------------------------------------------------------------------------------
    // VMS Schema Starts Here
    //----------------------------------------------------------------------------------------------

    User [label="User
          |{ :bp/uuid           | string }
          |{ :user/name         | string }
          |{ :user/email        | string }
          |{ :user/password     | string }
          |{ :user/reset-key    | string }
          |{ :user/verified?    | boolean }
          |{ :user/super-admin? | boolean }
          |{ :user/help-key     | string }
          "]

    //----------------------------------------------------------------------------------------------

    Application [label="Application
                 |{ :bp/uuid                   | string }
                 |{ :application/name          | string }
                 |{ :application/version-major | number }
                 |{ :application/version-minor | number }
                 |{ :application/version-patch | number }
                 |{ :application/version       | tuple }
                 |{ :application/help-key      | string }
                 "]
    Application -> Module      [label=":application/modules" taillabel=1 headlabel=N]
    Application -> Tool        [label=":application/tools" taillabel=1 headlabel=N]
    Application -> HelpPage    [label=":application/help-key" taillabel=1 headlabel=1]
    Application -> Translation [label=":application/translation-key" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    Module [label="Module
            |{ :bp/uuid                | string }
            |{ :module/name            | string }
            |{ :module/order           | number }
            "]
    Module -> Submodule   [label=":module/submodules" taillabel=1 headlabel=N]
    Module -> Diagram     [label=":module/diagram" taillabel=1 headlabel=N]
    Module -> HelpPage    [label=":module/help-key" taillabel=1 headlabel=1]
    Module -> Translation [label=":module/translation-key" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    Submodule [label="Submodule
               |{ :bp/uuid                         | string }
               |{ :submodule/name                  | string }
               |{ :submodule/order                 | number }
               |{ :submodule/io                    | keyword }
               |{ :submodule/research?             | boolean }
               |{ :submodule/conditionals-operator | keyword }
               "]
    Submodule -> Group       [label=":submodule/groups" taillabel=1 headlabel=N]
    Submodule -> Conditional [label=":submodule/conditionals" taillabel=1 headlabel=N]
    Submodule -> HelpPage    [label=":submodule/help-key" taillabel=1 headlabel=1]
    Submodule -> Translation [label=":submodule/translation-key" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    Group [label="Group
           |{ :bp/uuid                     | string }
           |{ :group/name                  | string }
           |{ :group/order                 | long }
           |{ :group/io                    | keyword }
           |{ :group/research?             | boolean }
           |{ :group/repeat?               | boolean }
           |{ :group/max-repeat            | long }
           |{ :group/conditionals-operator | keyword }
           "]
    Group -> Group         [label=":group/children" taillabel=1 headlabel=1]
    Group -> Conditional   [label=":group/conditionals" taillabel=1 headlabel=N]
    Group -> GroupVariable [label=":group/group-variables" taillabel=1 headlabel=N]
    Group -> HelpPage      [label=":group/help-key" taillabel=1 headlabel=1]
    Group -> Translation   [label=":group/translation-key" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    GroupVariable [label="Group-Variable
                   |{ :bp/uuid                      | string }
                   |{ :group-variable/cpp-class     | string }
                   |{ :group-variable/cpp-function  | string }
                   |{ :group-variable/cpp-namespace | string }
                   |{ :group-variable/cpp-parameter | string }
                   |{ :group-variable/order         | long}
                   |{ :group-variable/research?     | boolean }
                   "]
    GroupVariable -> CppClass     [label=":group-variable/cpp-class (uuid)" taillabel=1 headlabel=1]
    GroupVariable -> CppFunction  [label=":group-variable/cpp-function (uuid)" taillabel=1 headlabel=1]
    GroupVariable -> CppNamespace [label=":group-variable/cpp-namespace (uuid)" taillabel=1 headlabel=1]
    GroupVariable -> CppParameter [label=":group-variable/cpp-parameter (uuid)" taillabel=1 headlabel=1]
    GroupVariable -> HelpPage     [label=":group-variable/help-key" taillabel=1 headlabel=1]
    GroupVariable -> Translation  [label=":group-variable/translation-key" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    CppClass [label="Cpp.Class
              |{ :bp/uuid        | string }
              |{ :cpp.class/name | string }
              "]
    CppClass -> CppFunction [label=":cpp.class/function" taillabel=1 headlabel=N]

    //----------------------------------------------------------------------------------------------

    CppFunction [label="Cpp.Function
                 |{ :bp/uuid                  | string }
                 |{ :cpp.function/name        | string }
                 |{ :cpp.function/return-type | stringema}
                 "]
    CppFunction -> CppParameter [label=":cpp.function/parameter" taillabel=1 headlabel=N]

    //----------------------------------------------------------------------------------------------

    CppParameter [label="Cpp.Parameter
                  |{ :bp/uuid             | string }
                  |{ :cpp.parameter/name  | string }
                  |{ :cpp.parameter/order | number }
                  |{ :cpp.parameter/type  | string }
                  "]

    //----------------------------------------------------------------------------------------------

    CppNamespace [label="Cpp.Namespace
                  |{ :bp/uuid             | string }
                  |{ :cpp.namespace/name  | string }
                  "]
    CppNamespace -> CppClass [label=":cpp.namespace/class" taillabel=1 headlabel=N]
    CppNamespace -> CppEnum  [label=":cpp.namespace/enum" taillabel=1 headlabel=N]

    //----------------------------------------------------------------------------------------------

    CppEnum [label="Cpp.Enum
             |{ :bp/uuid       | string }
             |{ :cpp.enum/name | string }
             "]
    CppEnum -> CppEnumMember [label=":cpp.enum/enum-member" taillabel=1 headlabel=N]

    //----------------------------------------------------------------------------------------------

    CppEnumMember [label="Cpp.Enum-member
                   |{ :bp/uuid               | string }
                   |{ :cpp.enum-member/name  | string }
                   |{ :cpp.enum-member/value | number }
                   "]

    //----------------------------------------------------------------------------------------------

    Tool [label="Tools
          |{ :bp/uuid    | string }
          |{ :tool/name  | string }
          |{ :tool/order | number }
          "]
    Tool -> SubTool     [label=":tool/subtools" taillabel=1 headlabel=N]
    Tool -> HelpPage    [label=":tool/help-key" taillabel=1 headlabel=1]
    Tool -> Translation [label=":tool/translation-key" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    SubTool [label="Subtool
             |{ :bp/uuid              | string }
             |{ :subtool/name         | string }
             |{ :subtool/order        | number }
             |{ :subtool/autocompute? | boolean }
             "]
    SubTool -> SubToolVariable [label=":subtool/variables" taillabel=1 headlabel=N]
    SubTool -> HelpPage        [label=":subtool/help-key" taillabel=1 headlabel=1]
    SubTool -> Translation     [label=":subtool/translation-key" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    SubToolVariable [label="Subtool-Variable
                     |{ :bp/uuid                             | string }
                     |{ :subtool-variable/io                 | keyword }
                     |{ :subtool-variable/order              | long }
                     |{ :subtool-variable/cpp-namespace-uuid | string }
                     |{ :subtool-variable/cpp-mclass         | string }
                     |{ :subtool-variable/cpp-function-uuid  | string }
                     "]
    SubToolVariable -> HelpPage    [label=":subtool-variable/help-key" taillabel=1 headlabel=1]
    SubToolVariable -> Translation [label=":subtool-variable/translation-key" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    Variable [label="Variable
              |{ :bp/uuid                         | string }
              |{ :variable/name                   | string }
              |{ :variable/bp6-label              | string }
              |{ :variable/bp6-code               | string }
              |{ :variable/kind                   | keyword}
              |{ :variable/native-decimals        | double }
              |{ :variable/english-decimals       | double }
              |{ :variable/metric-decimals        | double }
              |{ :variable/maximum                | double }
              |{ :variable/minimum                | double }
              |{ :variable/default-value          | double }
              |{ :variable/map-units-convertible? | boolean }
              "]
    Variable -> GroupVariable   [label=":variable/group-variables" taillabel=1 headlabel=N]
    Variable -> SubToolVariable [label=":variable/subtool-variables" taillabel=1 headlabel=N]
    Variable -> List            [label=":variable/list" taillabel=1 headlabel=1]
    Variable -> Domain          [label=":variable/domain-uuid" taillabel=1 headlabel=1]
    Variable -> Unit            [label=":variable/native-unit-uuid" taillabel=1 headlabel=1]
    Variable -> Unit            [label=":variable/english-unit-uuid" taillabel=1 headlabel=1]
    Variable -> Unit            [label=":variable/metric-unit-uuid" taillabel=1 headlabel=1]
    Variable -> Translation     [label=":variable/translation-key" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    List [label="List
          |{ :bp/uuid   | string }
          |{ :list/name | string }
          "]
    List -> ListOption  [label=":list/options" taillabel=1 headlabel=N]
    List -> Translation [label=":list/translation-key" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    ListOption [label="List-Option
                 |{ :bp/uuid             | string }
                 |{ :list-option/name    | string }
                 |{ :list-option/default | string }
                 |{ :list-option/value   | string }
                 |{ :list-option/order   | long }
                 |{ :list-option/hide?   | boolean }
                 "]
    ListOption -> Translation [label=":list-option/translation-key" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    Dimension [label="Dimension
               |{ :bp/uuid                 | string }
               |{ :dimension/name          | string }
               |{ :dimension/cpp-enum-uuid | string }
               "]
    Dimension -> Unit [label=":dimension/units" taillabel=1 headlabel=N]

    //----------------------------------------------------------------------------------------------

    Unit [label="Unit
          |{ :bp/uuid                   | string }
          |{ :unit/name                 | string }
          |{ :unit/short-code           | string }
          |{ :unit/system               | string }
          |{ :unit/cpp-enum-member-uuid | string }
          "]

    //----------------------------------------------------------------------------------------------

    DomainSet [label="Domain-Set
               |{ :bp/uuid         | string }
               |{ :domain-set/name | string }
               "]
    DomainSet -> Domain [label=":domain-set/domains" taillabel=1 headlabel=N]

    //----------------------------------------------------------------------------------------------

    Domain [label="Domain
            |{ :bp/uuid         | string }
            |{ :domain/name     | string }
            |{ :domain/decimals | string }
            "]
    Domain -> Dimension [label=":domain/dimension-uuid" taillabel=1 headlabel=1]
    Domain -> Unit      [label=":domain/native-unit-uuid" taillabel=1 headlabel=1]
    Domain -> Unit      [label=":domain/english-unit-uuid" taillabel=1 headlabel=1]
    Domain -> Unit      [label=":domain/metric-unit-uuid" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    Conditional [label="Conditional
                 |{ :bp/uuid              | string }
                 |{ :conditional/type     | keyword }
                 |{ :conditional/operator | keyword }
                 |{ :conditional/values   | string }
                 "]
    Conditional -> GroupVariable [label=":conditional/group-variable-uuid" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    Diagram [label="Diagram
             |{ :bp/uuid      | keyword }
             |{ :diagram/type | string }
             "]
    Diagram -> GroupVariable [label=":diagram/group-variable" taillabel=1 headlabel=1]
    Diagram -> GroupVariable [label=":diagram/input-group-variables" taillabel=1 headlabel=N]
    Diagram -> GroupVariable [label=":diagram/output-group-variables" taillabel=1 headlabel=N]

    //----------------------------------------------------------------------------------------------

    Language [label="Language
              |{ :bp/uuid              | keyword }
              |{ :language/name        | string }
              |{ :language/short-code  | string }
              "]
    Language -> Translation [label=":language/translation" taillabel=1 headlabel=1]
    Language -> HelpPage    [label=":language/help-page" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    Translation [label="Translation
                 |{ :bp/uuid                 | keyword }
                 |{ :translation/name        | string }
                 |{ :translation/key         | string }
                 |{ :translation/translation | string }
                 "]

    //----------------------------------------------------------------------------------------------

    HelpPage [label="Help-page
          |{ :bp/uuid           | keyword }
          |{ :help-page/key     | string }
          |{ :help-page/content | string }
          "]

    //----------------------------------------------------------------------------------------------

    Link [label="Link
          |{ :bp/uuid | keyword }
          "]
    Link -> GroupVariable [label="link/source" taillabel=1 headlabel=1]
    Link -> GroupVariable [label="link/destination" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------
    // Worksheet Schema Starts Here
    //----------------------------------------------------------------------------------------------

    Worksheet [label="Worksheet
               |{ :bp/uuid                         | string }
               |{ :worksheet/run-description       | string }
               |{ :worksheet/name                  | string }
               |{ :worksheet/created               | long }
               |{ :worksheet/furthest-visited-step | keyword }
               |{ :worksheet/modules               | keywords }
               "]
    Worksheet -> Note             [label=":worksheet/notes" taillabel=1 headlabel=N]
    Worksheet -> InputGroup       [label=":worksheet/input-groups" taillabel=1 headlabel=N]
    Worksheet -> RepeatGroup      [label=":worksheet/repeat-groups" taillabel=1 headlabel=N]
    Worksheet -> Output           [label=":worksheet/outputs" taillabel=1 headlabel=N]
    Worksheet -> ResultTable      [label=":worksheet/result-table" taillabel=1 headlabel=1]
    Worksheet -> GraphSettings    [label=":worksheet/graph-settings" taillabel=1 headlabel=1]
    Worksheet -> TableSettings    [label=":worksheet/table-settings" taillabel=1 headlabel=1]
    Worksheet -> WorksheetDiagram [label=":worksheet/diagrams" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    Note [label="Note
          |{ :bp/uuid        | string }
          |{ :note/name      | string }
          |{ :note/content   | string }
          |{ :note/submodule | string }
          "]

    //----------------------------------------------------------------------------------------------

    InputGroup [label="Input-Group
                |{ :bp/uuid                | string }
                |{ :input-group/repeat-id  | long }
                |{ :input-group/inputs     | long }
                "]
    InputGroup -> Group [label=":input-group/group-uuid" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    RepeatGroup [label="Repeat-Group
                 |{ :bp/uuid                 | string }
                 |{ :repeat-group/group-uuid | string }
                 |{ :repeat-group/repeats    | long }
                 |{ :repeat-group/inputs     | long }
                 "]
    RepeatGroup -> Group [label=":repeat-group/group-uuid" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    Output [label="Output
            |{ :bp/uuid         | string }
            |{ :output/enabled? | boolean }
            "]
    Output -> GroupVariable [label=":output/group-variable-uuid" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    ResultTable [label="Result-Table
                 |{ :bp/uuid | string }
                 "]
    ResultTable -> ResultHeader [label=":result-table/headers" taillabel=1 headlabel=N]
    ResultTable -> ResultRow    [label=":result-table/rows" taillabel=1 headlabel=N]

    //----------------------------------------------------------------------------------------------

    ResultHeader [label="Result-Header
                  |{ :bp/uuid                 | string }
                  |{ :result-header/repeat-id | long }
                  |{ :result-header/order     | long }
                  |{ :result-header/units     | string }
                  "]
    ResultHeader -> GroupVariable [label=":result-header/group-variable-uuid" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    ResultRow [label="Result-Row
               |{ :bp/uuid       | string }
               |{ :result-row/id | long }
               "]
    ResultRow -> ResultCell [label=":result-row/cells" taillabel=1 headlabel=N]

    //----------------------------------------------------------------------------------------------

    ResultCell [label="Result-Cell
                |{ :bp/uuid           | string }
                |{ :result-cell/value | string }
                "]
    ResultCell -> ResultHeader [label=":result-cell/header" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    TableSettings [label="Table-Settings
                   |{ :bp/uuid                 | string }
                   |{ :table-settings/enabled? | boolean }
                   "]
    TableSettings -> TableFilter      [label=":table-settings/filters" taillabel=1 headlabel=N]
    TableSettings -> MapUnitsSettings [label=":table-settings/map-units-settings" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    TableFilter [label="Table-Filter
                 |{ :bp/uuid               | string }
                 |{ :table-filter/min      | long }
                 |{ :table-filter/max      | long }
                 |{ :table-filter/enabled? | boolean }
                 "]
    TableFilter      -> GroupVariable    [label=":table-filter/group-variable-uuid" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    MapUnitsSettings [label="Map-Units-settings
                      |{ :bp/uuid                             | string }
                      |{ :map-units-settings/enabled?         | boolean }
                      |{ :map-units-settings/units            | string }
                      |{ :map-units-settings/map-rep-fraction | long }
                      "]

    //----------------------------------------------------------------------------------------------

    GraphSettings [label="Graph-Settings
                   |{ :bp/uuid                 | string }
                   |{ :graph-settings/enabled? | boolean }
                   "]
    GraphSettings -> YAxisLimit    [label=":graph-settings/y-axis-limits" taillabel=1 headlabel=N]
    GraphSettings -> GroupVariable [label=":graph-settings/x-axis-group-variable-uuid" taillabel=1 headlabel=1]
    GraphSettings -> GroupVariable [label=":graph-settings/z-axis-group-variable-uuid" taillabel=1 headlabel=1]
    GraphSettings -> GroupVariable [label=":graph-settings/z2-axis-group-variable-uuid" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    YAxisLimit [label="Y-Axis-Limit
                |{ :bp/uuid                          | string }
                |{ :y-axis-limit/min                 | long }
                |{ :y-axis-limit/max                 | long }
                "]
    YAxisLimit -> GroupVariable [label=":y-axis-limit/group-variable-uuid" taillabel=1 headlabel=1]

    //----------------------------------------------------------------------------------------------

    WorksheetDiagram [label="Worksheet-diagram
                      |{ :bp/uuid                  | string }
                      |{ :worksheet.diagram/title  | string }
                      |{ :worksheet.diagram/row-id | long }
                      "]
    WorksheetDiagram -> GroupVariable [label=":worksheet.diagram/group-variable-uuid" taillabel=1 headlabel=1]
    WorksheetDiagram -> Ellipse       [label=":worksheet.diagram/ellises" taillabel=1 headlabel=N]
    WorksheetDiagram -> Arrow         [label=":worksheet.diagram/arrows" taillabel=1 headlabel=N]
    WorksheetDiagram -> ScatterPlot   [label=":worksheet.diagram/scatter-plots" taillabel=1 headlabel=N]

    //----------------------------------------------------------------------------------------------

    Ellipse [label="Ellipse
             |{ :bp/uuid                 | string }
             |{ :ellipse/legend-id       | string }
             |{ :ellipse/semi-major-axis | double }
             |{ :ellipse/semi-minor-axis | double }
             |{ :ellipse/rotation        | long }
             |{ :ellipse/color           | string }
             "]

    //----------------------------------------------------------------------------------------------

    Arrow [label="Arrow
           |{ :bp/uuid         | string }
           |{ :arrow/legend-id | string }
           |{ :arrow/length    | double }
           |{ :arrow/rotation  | double }
           |{ :arrow/color     | string }
           |{ :arrow/dashed?   | string }
           "]

    //----------------------------------------------------------------------------------------------

    ScatterPlot [label="Scatter-Plot
                 |{ :bp/uuid                    | string }
                 |{ :scatter-plot/legend-id     | string }
                 |{ :scatter-plot/color         | string }
                 |{ :scatter-plot/x-coordinates | string }
                 |{ :scatter-plot/y-coordinates | string }
                 "]
}