Full Code of witheve/Eve for AI

master f680d331d827 cached
68 files
851.0 KB
226.3k tokens
919 symbols
1 requests
Download .txt
Showing preview only (882K chars total). Download the full file or copy to clipboard to get everything.
Repository: witheve/Eve
Branch: master
Commit: f680d331d827
Files: 68
Total size: 851.0 KB

Directory structure:
gitextract_5kl2vc7y/

├── .gitattributes
├── .gitignore
├── .npmignore
├── ATTRIBUTIONS.md
├── Dockerfile
├── LICENSE
├── Procfile
├── README.md
├── assets/
│   └── css/
│       ├── app-preview.css
│       ├── base.css
│       ├── codemirror.css
│       ├── editor.css
│       ├── examples/
│       │   ├── crm.css
│       │   └── todomvc.css
│       ├── ide.css
│       ├── simplescrollbars.css
│       └── trace.css
├── bin/
│   └── eve.js
├── circle.yml
├── docker-compose.yml
├── index.html
├── package.json
├── src/
│   ├── bootstrap.ts
│   ├── index.ts
│   ├── loadWorker.js
│   ├── microReact.ts
│   ├── parser/
│   │   ├── errors.ts
│   │   └── parser.ts
│   ├── programs/
│   │   └── perfReport.ts
│   ├── runtime/
│   │   ├── dsl2.ts
│   │   ├── indexes.ts
│   │   ├── performance.ts
│   │   ├── runtime.ts
│   │   ├── stdlib.ts
│   │   └── trace.ts
│   ├── system-polyfills.js
│   ├── system.js
│   ├── systemJSConfig.js
│   ├── types.d.ts
│   └── watchers/
│       ├── canvas.ts
│       ├── compiler.ts
│       ├── console.ts
│       ├── dom.ts
│       ├── editor.ts
│       ├── file.ts
│       ├── html.ts
│       ├── index.ts
│       ├── notify.ts
│       ├── shape.ts
│       ├── svg.ts
│       ├── system.ts
│       ├── tag-browser.ts
│       ├── ui.ts
│       └── watcher.ts
├── syntax_diagrams.html
├── test/
│   ├── aggregate.ts
│   ├── all.ts
│   ├── antijoin.ts
│   ├── choose.ts
│   ├── distinct.ts
│   ├── foundation.ts
│   ├── performance.ts
│   ├── stdlib/
│   │   └── math.ts
│   ├── union.ts
│   └── util.ts
├── tsconfig.json
└── typings/
    ├── codemirror/
    │   └── codemirror.d.ts
    └── commonmark/
        └── commonmark.d.ts

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitattributes
================================================
build/* linguist-vendored
csrc/core/* linguist-vendored
csrc/crypto/* linguist-vendored
csrc/http/* linguist-vendored
csrc/luapower/* linguist-vendored
csrc/luautf8/* linguist-vendored
csrc/unix/* linguist-vendored
csrc/dns/* linguist-vendored
examples/* linguist-vendored
jssrc/codemirror.js linguist-vendored
index.html linguist-vendored
readme.md linguist-vendored
*.css linguist-vendored


================================================
FILE: .gitignore
================================================
# Compiled Lua sources
luac.out

# luarocks build files
*.src.rock
*.zip
*.tar.gz

# Object files
*.o
*.os
*.ko
*.obj
*.elf

# Precompiled Headers
*.gch
*.pch

# Libraries
*.lib
*.a
*.la
*.lo
*.def
*.exp

# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib

# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex

lua_modules/

*~
dist/
build/
node_modules/
.idea

experimental/build/continuation_templates.h
experimental/build/eve
experimental/build/path.c
experimental/build/Eve.xcodeproj/xcuserdata
experimental/build/Eve.xcodeproj/*/xcuserdata
experimental/build/lua
experimental/build/luajit-2.0
experimental/build/*.js

experimental/build/*.js
experimental/build/*.js.map


================================================
FILE: .npmignore
================================================


================================================
FILE: ATTRIBUTIONS.md
================================================
# Software Attributions

Eve is built using the following technologies generously supplied by their attributed authors in accordance with the following licenses. If you recognize anything in this list as incorrect, please bring it to our attention and we will correct it.

-------------------------------------------------------------------------------
 
### @types/body-parser
- TypeScript definitions for body-parser
- By Santi Albo (https://github.com/santialbo/), VILIC VANE (https://vilic.info), Jonathan Häberle (https://github.com/dreampulse)
- [MIT][MIT] License
- https://www.npmjs.com/package/@types/body-parser

-------------------------------------------------------------------------------

### @types/commonmark
- TypeScript definitions for commonmark.js 0.22.1
- By Nico Jansen (https://github.com/nicojs)
- [MIT][MIT] License
- https://www.npmjs.com/package/@types/commonmark

-------------------------------------------------------------------------------

### @types/express
- TypeScript definitions for Express 4.x
- By by Boris Yankov https://github.com/borisyankov/.
- [MIT][MIT] License
- https://www.npmjs.com/package/@types/express

-------------------------------------------------------------------------------

### @types/glob 
- TypeScript definitions for Glob 5.0.10
- By vvakame (https://github.com/vvakame)
- [MIT][MIT] License
- https://www.npmjs.com/package/@types/glob 

-------------------------------------------------------------------------------

### @types/minimist 
- TypeScript definitions for minimist 1.1.3
- By Bart van der Schoor (https://github.com/Bartvds), Necroskillz (https://github.com/Necroskillz)
- [MIT][MIT] License
- https://www.npmjs.com/package/@types/minimist

-------------------------------------------------------------------------------

### @types/mkdirp
- TypeScript definitions for mkdirp 0.3.0
- By Bart van der Schoor (https://github.com/Bartvds)
- [MIT][MIT] License
- https://www.npmjs.com/package/@types/mkdirp

-------------------------------------------------------------------------------

### @types/node
- TypeScript definitions for Node.js v6.x
- By Microsoft TypeScript (http://typescriptlang.org), DefinitelyTyped (https://github.com/DefinitelyTyped/DefinitelyTyped)
- [MIT][MIT] License
- https://www.npmjs.com/package/@types/node

-------------------------------------------------------------------------------

### @types/request
- TypeScript definitions for request
- By Carlos Ballesteros Velasco (https://github.com/soywiz), et. al.
- [MIT][MIT] License
- https://www.npmjs.com/package/@types/request

-------------------------------------------------------------------------------

### @types/tape
- TypeScript definitions for tape v4.2.2
- By Bart van der Schoor (https://github.com/Bartvds), Haoqun Jiang (https://github.com/sodatea)
- [MIT][MIT] License
- https://www.npmjs.com/package/@types/tape

-------------------------------------------------------------------------------

### @types/ws 
- TypeScript definitions for ws
- By Paul Loyd (https://github.com/loyd)
- [MIT][MIT] License
- https://www.npmjs.com/package/@types/ws

-------------------------------------------------------------------------------

### codemirror.d.ts
- TypeScript definitions for codemirror
- By mihailik (https://github.com/mihailik)
- [MIT][MIT] License
- [https://github.com/DefinitelyTyped/DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/03b3450d08a0b0a1b9e820e581a52c8e6c21f32e/codemirror/codemirror.d.ts)

-------------------------------------------------------------------------------

### System.js
- Universal dynamic module loader 
- [MIT][MIT] License
- https://github.com/systemjs/systemjs

-------------------------------------------------------------------------------

### body-parser
- Node.js body parsing middleware
- [MIT][MIT] License
- https://www.npmjs.com/package/body-parser

-------------------------------------------------------------------------------

### chevrotain
- Chevrotain is a high performance fault tolerant javascript parsing DSL for building recursive decent parsers
- [Apache 2.0][Apache] License
- https://www.npmjs.com/package/chevrotain

-------------------------------------------------------------------------------

### commonmark
- a strongly specified, highly compatible variant of Markdown
- [BSD-2-Clause][BSD] License
- https://www.npmjs.com/package/commonmark

-------------------------------------------------------------------------------

### express
- Fast, unopinionated, minimalist web framework
- [MIT][MIT] License
- https://www.npmjs.com/package/express

-------------------------------------------------------------------------------

### glob
- a little globber
- by Isaac Schlueter (https://github.com/isaacs)
- [ISC][ISC] License
- https://www.npmjs.com/package/glob

-------------------------------------------------------------------------------

### minimist
- parse argument options
- [MIT][MIT] License
- https://www.npmjs.com/package/minimist

-------------------------------------------------------------------------------

### mkdirp
- Recursively mkdir, like mkdir -p
- [MIT][MIT] License
- https://www.npmjs.com/package/mkdirp

-------------------------------------------------------------------------------

### node-uuid
- Rigorous implementation of RFC4122 (v1 and v4) UUIDs.
- [MIT][MIT] License
- https://www.npmjs.com/package/node-uuid

-------------------------------------------------------------------------------

### request
- Simplified HTTP request client
- [Apache 2.0][Apache] License
- https://www.npmjs.com/package/request

-------------------------------------------------------------------------------

### typescript
- TypeScript is a language for application scale JavaScript development
- [Apache 2.0][Apache] License
- https://www.npmjs.com/package/typescript

-------------------------------------------------------------------------------

### ws
- simple to use, blazing fast and thoroughly tested websocket client, server and console for node.js, up-to-date against RFC-6455
- [MIT][MIT] License
- https://www.npmjs.com/package/ws

-------------------------------------------------------------------------------

### uuid.js
- Simple, fast generation of RFC4122 UUIDS.
- By Robert Kieffer (https://github.com/broofa)
- [MIT][MIT] License
- https://github.com/broofa/node-uuid

-------------------------------------------------------------------------------

### Codemirror
- In-browser code editor 
- By Marijn Haverbeke (https://github.com/marijnh)
- [MIT][MIT] License
- https://github.com/codemirror/codemirror

-------------------------------------------------------------------------------

### Simple Scrollbars
- Addon for CodeMirror
- By Marijn Haverbeke (https://github.com/marijnh)
- [MIT][MIT] License
- https://codemirror.net/doc/manual.html#addon_simplescrollbars

-------------------------------------------------------------------------------

### Annotate Scrollbar
- Addon for CodeMirror
- By Marijn Haverbeke (https://github.com/marijnh)
- [MIT][MIT] License
- https://codemirror.net/doc/manual.html#addon_annotatescrollbar

-------------------------------------------------------------------------------

### ionicons
The premium icon font for Ionic
- [MIT][MIT] License
- by Ben Sperry (https://twitter.com/benjsperry)
- https://github.com/driftyco/ionicons

-------------------------------------------------------------------------------

[BSD]: https://spdx.org/licenses/BSD-2-Clause
[MIT]: https://spdx.org/licenses/MIT
[Apache]: https://spdx.org/licenses/Apache-2.0
[ISC]: https://spdx.org/licenses/ISC

================================================
FILE: Dockerfile
================================================
FROM node:6-slim
MAINTAINER Kodowa, Inc. <info@kodowa.com>
ADD / /eve
RUN chown -R node:node /eve
USER node
ENV HOME /eve
WORKDIR /eve
RUN npm install
EXPOSE 8080
CMD npm start

================================================
FILE: LICENSE
================================================
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "{}"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright {yyyy} {name of copyright owner}

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.


================================================
FILE: Procfile
================================================
web: ./node_modules/.bin/tsc && cp src/*.js build/src/ && cp ./node_modules/chevrotain/lib/chevrotain.js build/src/ && node build/src/runtime/server.js


================================================
FILE: README.md
================================================
<p align="center">
  <img src="http://www.witheve.com/logo.png" alt="Eve logo" width="10%" />
</p>

---
 
Eve is a programming language based on years of research into building a human-first programming platform. 

**This repository hosts a preview of Eve v0.3 alpha, which is no longer under active development.**

## Getting Started with Eve v0.3 preview

Install [Node](https://nodejs.org/en/download/) for your platform, then clone and build the [Eve starter repository](https://github.com/witheve/eve-starter):

```
git clone git@github.com:witheve/eve-starter.git
cd eve-starter
npm install
```

You can start the program switcher, which allows you to browse included example programs:

```
npm start
```

Or you can run a specific program by providing its path as an argument:

```
npm start -- path/to/program.js
```

## Integrating Eve into an existing project

You can get Eve as an npm package

```
npm install witheve@preview
```

Then import Eve to use it in your project

```
import {Program} from "witheve";
```

## Learning Eve

You can learn about Eve with the following resources:

- [Read the Quick Start Tutorial](http://play.witheve.com/) (use Chrome for best results)
- [Syntax Quick Reference](https://witheve.github.io/assets/docs/SyntaxReference.pdf)
- [Language Handbook (draft)](http://docs.witheve.com)

Also, the [mailing list archive](https://groups.google.com/forum/#!forum/eve-talk) is a good resource for help and inspiration. In particular, the [Puzzles & Paradoxes series](https://groups.google.com/forum/#!searchin/eve-talk/Puzzles$20$26$20Paradoxes%7Csort:date) answers a lot of questions beginners face about the Eve langauge.

## Get Involved

### Join the Community

The Eve community is small but constantly growing, and everyone is welcome!

- Join or start a discussion on our [mailing list](https://groups.google.com/forum/#!forum/eve-talk).
- Impact the future of Eve by getting involved with our [Request for Comments](https://github.com/witheve/rfcs) process.
- Read our [development blog](http://incidentalcomplexity.com/).
- Follow us on [Twitter](https://twitter.com/with_eve).

### How to Contribute

The best way to contribute right now is to write Eve code and report your experiences. [Let us know](https://groups.google.com/forum/#!forum/eve-talk) what kind of programs you’re trying to write, what barriers you are facing in writing code (both mental and technological), and any errors you encounter along the way.

### How to File an Issue

Please file any issues in this repository. Before you file an issue, please take a look to see if the issue already exists. When you file an issue, please include:

1. The steps needed to reproduce the bug
2. Your operating system and browser.
3. If applicable, the `.*eve` file that causes the bug.

## License

Eve is licensed under the Apache 2.0 license, see [LICENSE](https://github.com/witheve/eve/blob/master/LICENSE) for details.

## Disclaimer

Eve is currently at a very early, "alpha" stage of development. This means the language, tools, and docs are largely incomplete, but undergoing rapid and continuous development. If you encounter errors while using Eve, don't worry: it's likely our fault. Please bring the problem to our attention by [filing an issue](https://github.com/witheve/eve#how-to-file-an-issue).

As always, with pre-release software, don’t use this for anything important. We are continuously pushing to this codebase, so you can expect very rapid changes. At this time, we’re not prepared make the commitment that our changes will not break your code, but we’ll do our best to [update you](https://groups.google.com/forum/#!forum/eve-talk) on the biggest changes.


================================================
FILE: assets/css/app-preview.css
================================================
/*
 * app preview iframe wrapper stylesheets
 */

* { box-sizing:border-box; }
body { background: rgb(47,47,49); color: #d8d8d8; font-family: Avenir, "Helvetica neue", sans-serif; display: flex; flex-direction: row; margin:0; width: 100%; }
html, body, __root { height: 100%; }
body { background: #f5f5f5; color: #555; }
body { justify-content: stretch; }
.__root { display: flex; flex-direction: column; align-self: stretch; }
.application-root { overflow: auto; }
.__root.application-root { order: 2; flex: 1 1 auto; color: #555; }
.application-container { display: flex; flex-direction: column; flex: 1; }
.program { position: relative; flex: 1; flex-direction: column; align-self: stretch; padding:20px; overflow: auto; display:flex; }

================================================
FILE: assets/css/base.css
================================================
/******************************************************************************\
 * UI Components                                                              *
\******************************************************************************/

row { display: flex; flex-direction: row; }
column {display: flex;flex-direction: column;align-items: stretch;}

spacer { display: flex; flex: 1; }

text { display: inline-block; white-space: pre-wrap; }

button { display: flex; flex-direction: row; padding: 5px 10px; background: transparent; border: none; outline: none; -webkit-appearance: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; background-clip: padding-box !important; }

button:before { align-self: center; }

button:not(:empty):before { margin-right: 10px; }

button { background: #f0f0f0; border-radius: 4px; border: 1px solid #e5e5e5; }
button:hover { background: #e9e9e9; }
button:active { background: #e0e0e0; }

button.inset { border-radius: 4px; background: #EEE; border: 1px solid rgba(0, 0, 0, 0.1); }
button.inset:not(.disabled):hover { background: #EEE; box-shadow: inset 0 0 1000px rgba(0, 0, 0, 0.05), inset 0 1px 1px rgba(0, 0, 0, 0.25); border-top-color: rgba(0, 0, 0, 0.2); }
button.inset:not(.disabled):active { background: #EEE; box-shadow: inset 0 0 1000px rgba(0, 0, 0, 0.1), inset 0 2px 1px rgba(0, 0, 0, 0.25); border-top-color: rgba(0, 0, 0, 0.3); }

button.flat { background: transparent; border: none; border-radius: 0; }
button.flat:not(.disabled):hover { background: rgba(0, 0, 0, 0.05); }
button.flat:not(.disabled):active { background: rgba(0, 0, 0, 0.1); }

.dark button.flat:not(.disabled):hover { background: rgba(255, 255, 255, 0.1); }
.dark button.flat:not(.disabled):active { background: rgba(255, 255, 255, 0.2); }

.ui-field-table {border-collapse: collapse;}
.ui-field-table td {padding: 0;margin: 0;vertical-align: top; border: 1px solid #ccc;}
.ui-field-table .ui-field-table-attribute {}
.ui-field-table .ui-field-table-value-set {display: flex;flex-direction: column;}
.ui-field-table .ui-field-table-cell { padding: 0 10; margin: 0; }
.ui-field-table .ui-field-table-cell + .ui-field-table-cell { border-top: 1px solid #ccc; }

.ui-field-table input.ui-field-table-cell {min-width:100%;font-size: 1em;font-weight: inherit;font-family: inherit;background: transparent;border: none;color: inherit;}
.ui-field-table input::-webkit-input-placeholder { font-weight: 300; }
.ui-field-table input.ui-field-table-attribute {padding-right: 0;}

.ui-autocomplete { position: relative; flex: 0 0 auto; width: 200px; }
.ui-autocomplete-matches { position: absolute; top: 100%; width: 100%; flex: 0 0 auto; z-index: 5; background: white; border-top: 0px solid #f0f0f0; border-radius: 4px; box-shadow: 0 2px 3px rgba(0, 0, 0, 0.2); }
.ui-autocomplete[open="true"] .ui-autocomplete-matches { border-top-width: 1px; }

.ui-autocomplete-match { padding: 0 10px; height: 0; overflow: hidden; }
.ui-autocomplete[open="true"] .ui-autocomplete-match { padding: 0 10px; height: 100%; overflow: hidden; }
.ui-autocomplete-match:hover { background: #f9f9f9; }
.ui-autocomplete-match:active { background: #f0f0f0; }

/******************************************************************************\
 * Shape                                                                      *
\******************************************************************************/
.shape-hexagon {position: relative;}
.shape-hexagon > canvas {position: absolute;top: 0;left: 0;width: 100%;height: 100%;}
.shape-hexagon > div { display: flex; flex-direction: column; justify-content: center; align-items: center; position: absolute; }

/******************************************************************************\
 * compiler
\******************************************************************************/

.eve-compiler-error { background:#333; color: #ccc; margin:20px; padding:10px 20px; align-self:center; width:700px; border-radius:3px; box-shadow:2px 2px 8px #999; }
.eve-compiler-line-info { margin-right:20px; color: #999; margin-right: 20px; padding-right: 20px; color: #888; border-right: 1px solid #666; justify-content: center;}
.eve-compiler-error-sample { font-family:"Inconsolata", "Monaco", "Consolas", "Ubuntu Mono", monospace; margin-top:10px; background:#444; padding:10px; border-radius:3px; }
.eve-compiler-error-message-line { font-size:20pt; color: #ff8c24; }
.eve-compiler-error-message { color: #ff8c24; }
.eve-compiler-error-content {padding: 5px; flex: 1;}

/******************************************************************************\
 * Notify
\******************************************************************************/
@keyframes slide-down {
    0% { padding: 0px 30px; max-height: 0; }
    100% { padding: 5px 30px; max-height: 80px; }
}

.notify-wrapper { position: relative; max-height: 165px; overflow-y: hidden; }
.notify-wrapper:after {position: absolute; content: " "; display: "block"; left: 0; right: 0; top: 155px; height: 10px; box-shadow: inset 0 -5px 5px rgba(0, 0, 0, 0.1); }
.notify-scroller { overflow-y: auto; max-height: 165px; overflow-y: auto; }
.notify-root { border-bottom: 1px solid rgba(0, 0, 0, 0.1);  }

.notify-notice-wrapper { flex: 0 0 auto; align-items: center; padding: 5px 30px; padding-right: 40px; animation: slide-down 0.3s 1; animation-timing-function: ease-in; overflow: hidden; }
.notify-notice { align-items: center; }
.notify-notice-wrapper + .notify-notice-wrapper { border-top: 1px solid rgba(0, 0, 0, 0.1); }
.notify-notice-wrapper:before { margin-left: -30px; width: 30px; text-align: center; font-family: "Ionicons"; line-height: 1; }
.notify-notice-wrapper[type="warning"] { background: rgba(255, 255, 0, 0.1); }
.notify-notice-wrapper[type="warning"]:before {content: "\f100"; color: rgb(128, 128, 0); }
.notify-notice-wrapper[type="error"] { background: rgba(255, 96, 96, 0.2); }
.notify-notice-wrapper[type="error"]:before {content: "\f101"; color: rgb(255, 0, 0); }
.notify-notice-wrapper .notify-dismiss { margin-right: -40px; width: 30px; margin-left: 10px; }


================================================
FILE: assets/css/codemirror.css
================================================
/* BASICS */

.CodeMirror {
  /* Set height, width, borders, and global font properties here */
  font-family: monospace;
  height: 300px;
  color: black;
}

/* PADDING */

.CodeMirror-lines {
  padding: 4px 0; /* Vertical padding around content */
}
.CodeMirror pre {
  padding: 0 4px; /* Horizontal padding of content */
}

.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
  background-color: white; /* The little square between H and V scrollbars */
}

/* GUTTER */

.CodeMirror-gutters {
  border-right: 1px solid #ddd;
  background-color: #f7f7f7;
  white-space: nowrap;
}
.CodeMirror-linenumbers {}
.CodeMirror-linenumber {
  padding: 0 3px 0 5px;
  min-width: 20px;
  text-align: right;
  color: #999;
  white-space: nowrap;
}

.CodeMirror-guttermarker { color: black; }
.CodeMirror-guttermarker-subtle { color: #999; }

/* CURSOR */

.CodeMirror-cursor {
  border-left: 1px solid black;
  border-right: none;
  width: 0;
}
/* Shown when moving in bi-directional text */
.CodeMirror div.CodeMirror-secondarycursor {
  border-left: 1px solid silver;
}
.cm-fat-cursor .CodeMirror-cursor {
  width: auto;
  border: 0 !important;
  background: #7e7;
}
.cm-fat-cursor div.CodeMirror-cursors {
  z-index: 1;
}

.cm-animate-fat-cursor {
  width: auto;
  border: 0;
  -webkit-animation: blink 1.06s steps(1) infinite;
  -moz-animation: blink 1.06s steps(1) infinite;
  animation: blink 1.06s steps(1) infinite;
  background-color: #7e7;
}
@-moz-keyframes blink {
  0% {}
  50% { background-color: transparent; }
  100% {}
}
@-webkit-keyframes blink {
  0% {}
  50% { background-color: transparent; }
  100% {}
}
@keyframes blink {
  0% {}
  50% { background-color: transparent; }
  100% {}
}

/* Can style cursor different in overwrite (non-insert) mode */
.CodeMirror-overwrite .CodeMirror-cursor {}

.cm-tab { display: inline-block; text-decoration: inherit; }

.CodeMirror-rulers {
  position: absolute;
  left: 0; right: 0; top: -50px; bottom: -20px;
  overflow: hidden;
}
.CodeMirror-ruler {
  border-left: 1px solid #ccc;
  top: 0; bottom: 0;
  position: absolute;
}

/* DEFAULT THEME */

.cm-s-default .cm-header {color: blue;}
.cm-s-default .cm-quote {color: #090;}
.cm-negative {color: #d44;}
.cm-positive {color: #292;}
.cm-header, .cm-strong {font-weight: bold;}
.cm-em {font-style: italic;}
.cm-link {text-decoration: underline;}
.cm-strikethrough {text-decoration: line-through;}

.cm-s-default .cm-keyword {color: #708;}
.cm-s-default .cm-atom {color: #219;}
.cm-s-default .cm-number {color: #164;}
.cm-s-default .cm-def {color: #00f;}
.cm-s-default .cm-variable,
.cm-s-default .cm-punctuation,
.cm-s-default .cm-property,
.cm-s-default .cm-operator {}
.cm-s-default .cm-variable-2 {color: #05a;}
.cm-s-default .cm-variable-3 {color: #085;}
.cm-s-default .cm-comment {color: #a50;}
.cm-s-default .cm-string {color: #a11;}
.cm-s-default .cm-string-2 {color: #f50;}
.cm-s-default .cm-meta {color: #555;}
.cm-s-default .cm-qualifier {color: #555;}
.cm-s-default .cm-builtin {color: #30a;}
.cm-s-default .cm-bracket {color: #997;}
.cm-s-default .cm-tag {color: #170;}
.cm-s-default .cm-attribute {color: #00c;}
.cm-s-default .cm-hr {color: #999;}
.cm-s-default .cm-link {color: #00c;}

.cm-s-default .cm-error {color: #f00;}
.cm-invalidchar {color: #f00;}

.CodeMirror-composing { border-bottom: 2px solid; }

/* Default styles for common addons */

div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
.CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }
.CodeMirror-activeline-background {background: #e8f2ff;}

/* STOP */

/* The rest of this file contains styles related to the mechanics of
   the editor. You probably shouldn't touch them. */

.CodeMirror {
  position: relative;
  overflow: hidden;
  background: white;
}

.CodeMirror-scroll {
  overflow: scroll !important; /* Things will break if this is overridden */
  /* 30px is the magic margin used to hide the element's real scrollbars */
  /* See overflow: hidden in .CodeMirror */
  margin-bottom: -30px; margin-right: -30px;
  padding-bottom: 30px;
  height: 100%;
  outline: none; /* Prevent dragging from highlighting the element */
  position: relative;
}
.CodeMirror-sizer {
  position: relative;
  border-right: 30px solid transparent;
}

/* The fake, visible scrollbars. Used to force redraw during scrolling
   before actual scrolling happens, thus preventing shaking and
   flickering artifacts. */
.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
  position: absolute;
  z-index: 6;
  display: none;
}
.CodeMirror-vscrollbar {
  right: 0; top: 0;
  overflow-x: hidden;
  overflow-y: scroll;
}
.CodeMirror-hscrollbar {
  bottom: 0; left: 0;
  overflow-y: hidden;
  overflow-x: scroll;
}
.CodeMirror-scrollbar-filler {
  right: 0; bottom: 0;
}
.CodeMirror-gutter-filler {
  left: 0; bottom: 0;
}

.CodeMirror-gutters {
  position: absolute; left: 0; top: 0;
  min-height: 100%;
  z-index: 3;
}
.CodeMirror-gutter {
  white-space: normal;
  height: 100%;
  display: inline-block;
  vertical-align: top;
  margin-bottom: -30px;
  /* Hack to make IE7 behave */
  *zoom:1;
  *display:inline;
}
.CodeMirror-gutter-wrapper {
  position: absolute;
  z-index: 4;
  background: none !important;
  border: none !important;
}
.CodeMirror-gutter-background {
  position: absolute;
  top: 0; bottom: 0;
  z-index: 4;
}
.CodeMirror-gutter-elt {
  position: absolute;
  cursor: default;
  z-index: 4;
}
.CodeMirror-gutter-wrapper {
  -webkit-user-select: none;
  -moz-user-select: none;
  user-select: none;
}

.CodeMirror-lines {
  cursor: text;
  min-height: 1px; /* prevents collapsing before first draw */
}
.CodeMirror pre {
  /* Reset some styles that the rest of the page might have set */
  -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
  border-width: 0;
  background: transparent;
  font-family: inherit;
  font-size: inherit;
  margin: 0;
  white-space: pre;
  word-wrap: normal;
  line-height: inherit;
  color: inherit;
  z-index: 2;
  position: relative;
  overflow: visible;
  -webkit-tap-highlight-color: transparent;
  -webkit-font-variant-ligatures: none;
  font-variant-ligatures: none;
}
.CodeMirror-wrap pre {
  word-wrap: break-word;
  white-space: pre-wrap;
  word-break: normal;
}

.CodeMirror-linebackground {
  position: absolute;
  left: 0; right: 0; top: 0; bottom: 0;
  z-index: 0;
}

.CodeMirror-linewidget {
  position: relative;
  z-index: 2;
  overflow: auto;
}

.CodeMirror-widget {}

.CodeMirror-code {
  outline: none;
}

/* Force content-box sizing for the elements where we expect it */
.CodeMirror-scroll,
.CodeMirror-sizer,
.CodeMirror-gutter,
.CodeMirror-gutters,
.CodeMirror-linenumber {
  -moz-box-sizing: content-box;
  box-sizing: content-box;
}

.CodeMirror-measure {
  position: absolute;
  width: 100%;
  height: 0;
  overflow: hidden;
  visibility: hidden;
}

.CodeMirror-cursor {
  position: absolute;
  pointer-events: none;
}
.CodeMirror-measure pre { position: static; }

div.CodeMirror-cursors {
  visibility: hidden;
  position: relative;
  z-index: 3;
}
div.CodeMirror-dragcursors {
  visibility: visible;
}

.CodeMirror-focused div.CodeMirror-cursors {
  visibility: visible;
}

.CodeMirror-selected { background: #d9d9d9; }
.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
.CodeMirror-crosshair { cursor: crosshair; }
.CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }
.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }

.cm-searching {
  background: #ffa;
  background: rgba(255, 255, 0, .4);
}

/* IE7 hack to prevent it from returning funny offsetTops on the spans */
.CodeMirror span { *vertical-align: text-bottom; }

/* Used to force a border model for a node */
.cm-force-border { padding-right: .1px; }

@media print {
  /* Hide the cursor when printing */
  .CodeMirror div.CodeMirror-cursors {
    visibility: hidden;
  }
}

/* See issue #2901 */
.cm-tab-wrap-hack:after { content: ''; }

/* Help users use markselection to safely style text background */
span.CodeMirror-selectedtext { background: none; }


================================================
FILE: assets/css/editor.css
================================================
.editor-view {padding: 40px; align-items: stretch;height: 100%;background: white;}

/****************************************************************************\
 * Editor Nav
\****************************************************************************/

.editor-view .editor-nav { margin-right: 20px; }
.editor-view .editor-nav .editor-nav-tag { padding: 10px; }
.editor-view .editor-nav .editor-nav-block { padding: 5px; padding-left: 20px; padding-right: 0; }



/****************************************************************************\
 * Editor Main
\****************************************************************************/

.editor-view .editor-main { flex: 1; }
.editor-view .editor-block-header { margin-bottom: 40px; }
.editor-view .editor-block-description {max-width: 480px;font-weight: 300; line-height: 1.5; padding: 10px 0;margin-right: 40px;flex: 1;font-size: 1em;}
.editor-view .editor-block-title {font-size: 1.25em; margin-bottom: 0.25em;font-weight: 500; margin-bottom: 0.5em; }

.editor-view .editor-block-storyboard { flex: 1; align-self: flex-start; }

.editor-view .editor-block-frame { width: 130px; height: 80px; margin: 10px; margin-top: 3em;justify-content: center; align-items: center; border: 2px solid #888; border-radius: 3px; }
.editor-view .editor-block-frame.active,
.editor-view .editor-block-frame:not([open="true"]).active:hover{ background: #f0f0f0; }

.editor-view .editor-block-frame:not([open="true"]):hover { background: #fcfcfc; }
.editor-view .editor-block-frame:not([open="true"]):active { background: #f0f0f0; }


.editor-view .editor-new-frame { border-color: #ccc; color: #ccc; justify-content: space-around; }
.editor-view .editor-new-frame:empty:after { display: flex; content: "+"; font-size: 3em; font-weight: 200;}

.editor-view .editor-new-frame-type { align-self: stretch; color: #606060; }


.editor-view .editor-block-content { flex: 1; }

/****************************************************************************\
 * Editor Node Tree
\****************************************************************************/

.editor-node-tree { align-self: flex-start; padding-left: 44px; padding-top: 16px; }
.editor-node-tree input {font-size: 1em; font-weight: inherit;font-family: inherit; border: none; color: inherit;}
.editor-node-tree-node { position: relative; padding: 5px 0; margin-top: -16px; min-height: 60px; }
.editor-node-tree > .editor-node-tree-node { min-height: 65px; }

.editor-node-tree-node-new {margin-top: -16px; align-items: flex-start; }
.editor-node-tree-node-new > .ui-autocomplete {margin-top: 10px;width: 100px;z-index: 2;}
.editor-node-tree-node-new > .button {margin-top: 7px;}
.editor-node-tree-node-new > .button:before {width: 1.3em; line-height: 1.3em;text-align: center; font-size: 0.9em; border: 1px solid #ccc; border-radius: 100px;}

.editor-node-tree-node-pattern { margin-top: 11px; margin-left: 15px; }
.editor-node-tree-node-pattern .editor-node-tree-node-pattern-name { margin-left: -15px; margin-bottom: 8px;}
.editor-node-tree-node-pattern-field {position: relative; min-height: 22px; z-index: 1; }
.editor-node-tree-node-pattern-field > text:not(:last-child):after {content: ":"}
.editor-node-tree-node-pattern-value {padding:0;padding-left: 5px; max-width: 100px;}

.editor-node-tree-node-pattern div.button {position: relative;width: 40px; line-height: 1.3em; margin-top: -4px;margin-left: -34px;margin-bottom:-4px;font-size: 0.9em; color: #999; }
.editor-node-tree-node-pattern div.button:before { width: 1.3em; line-height: 1.3em; text-align: center; border: 1px solid #ddd; border-radius: 100px; background: white; font-weight: 100; }
.editor-node-tree-node-pattern div.button:after {content: " "; display: block; position: absolute; left: 50%; right: 5px; top: 50%; margin-top: 0; z-index: -1; border-top: 1px solid #ccc; }

.editor-node-tree-node-controls { position: absolute; top: 38px; left: -21px; padding: 4px 0;}
.editor-node-tree-node-controls > div.button {position:relative; margin:0; margin-right: -4px; ;z-index: 1;font-size:0.9em;}

.editor-node-tree-node-controls:before {content: " ";display: block;position: absolute;top: 4px;bottom: 18px;right: -4px;border-left: 1px solid #ccc;}
.editor-node-tree-node-controls > div.button:before {width: 1.3em;margin-top: -5px;text-align: center;line-height: 1.3em;border: 1px solid #ccc;border-radius: 100px;background: white;font-weight: 100;}
.editor-node-tree-node-controls > div.button:after {content: " "; display: block; position: absolute; left: 50%; right: 0; top: 50%; margin-top: -3px; z-index: -1; border-top: 1px solid #ccc; }

.editor-node-tree-node-field-new-attribute {width: 100px;z-index: 2;}

/* Crazy tree positioning magic */

.editor-node-tree-node-hex { position: absolute; left: -44px; cursor: default; -webkit-user-select: none; }
.editor-node-tree-node-pattern .editor-node-tree-node-hex { position: absolute; left: -59px; }
.editor-node-tree-node-pattern .editor-node-tree-node-pattern .editor-node-tree-node-hex { position: absolute; left: -74px; }
.editor-node-tree-node-pattern .editor-node-tree-node-pattern .editor-node-tree-node-pattern .editor-node-tree-node-hex { position: absolute; left: -89px; }
.editor-node-tree-node-pattern .editor-node-tree-node-pattern .editor-node-tree-node-pattern .editor-node-tree-node-pattern .editor-node-tree-node-hex { position: absolute; left: -104px; }
/* okay, you win. */

.editor-node-tree-node-pattern-field:before {display: block;content: " ";position: absolute;top: 11px;left: -13px;width: 9px;height: 1px;border-top: 1px solid #ccc;}

.editor-node-tree-node-pattern-name:before {display: block;content: " ";position: absolute;top: 26px;left: -13px;width: 9px;height: 1px;border-top: 1px solid #ccc;}
.editor-node-tree > .editor-node-tree-node > .editor-node-tree-node-pattern > row > .editor-node-tree-node-pattern-name:before {display: none; }

.editor-node-tree-node-pattern:before {display: block;content: " ";position: absolute; left: 1px; top: 38px; bottom: 6px;width: 0;border-left: 1px solid #ccc;}

.editor-node-tree-fields:last-child > .editor-node-tree-node-pattern-field:last-child:after {display: block;content: " ";position: absolute;top: 11px;bottom: -10px;left:-14px;width: 0;margin-top: 1px;border-left: 2px solid white;}

.editor-node-tree-subnodes:last-child .editor-node-tree-node:last-child:after {display: block;content: " ";position: absolute;top: 26px;bottom: -10px;left: -14px;width: 0;margin-top: 1px;border-left: 1px solid white;}

.editor-node-tree-node-pattern row:first-child:last-child > .editor-node-tree-node-pattern-name:after {display: block;content: " ";position: absolute;top: 38px;bottom: 5px;left:0;width: 0;border-left: 2px solid white;}

.editor-node-tree-subnodes:nth-child(2) { margin-top: 20px;}
.editor-node-tree-subnodes:nth-child(3) { margin-top: 5px;}

/* Animations */
.editor-node-tree-node-hex > canvas { transition: transform 0.2s ease-out; }
.editor-node-tree-node[open="true"] > .editor-node-tree-node-hex > canvas { transform: rotateZ(60deg); }

/****************************************************************************\
 * Editor Molecule List
\****************************************************************************/
.editor-molecule-list { position: relative; flex: 1; }
.editor-molecule-list-molecule { position: relative; display: flex; flex: 0 0 auto; padding-bottom: 10px;}
.editor-molecule-list-molecule-grid { position: relative;}
.editor-molecule-list-molecule-cell { cursor: default; -webkit-user-select: none; }

.editor-infobox { position: absolute; top: 100%; left: 0; /*left: 75%; transform: translateX(-50%);*/ width: 250px; padding: 10px; z-index: 3; background: white; border-radius: 3px; border: 1px solid #bbb; }

.editor-infobox-field-new  {position: relative;width: 40px; line-height: 1.3em; margin-top: 0;margin-left: -4px;margin-bottom:-4px;font-size: 0.9em; color: #999; }
.editor-infrobox-field-new:before { width: 1.3em; line-height: 1.3em; text-align: center; background: white; font-weight: 100; }

.editor-infobox-field-attribute { margin-left: -8px; width: auto; }
.editor-infobox-field-attribute input { font-size: 1em; line-height: 1.3em; padding: 5px 10px; font-weight: inherit;font-family: inherit; border: none; color: inherit;}

.editor-infobox-node { margin-bottom: 10px; }

.editor-infobox-node-header { margin: 0 9px; margin-bottom: 0.25rem; }
.editor-infobox-node-name { font-size: 1.25em; font-weight: 500; color: #606060; }

.editor-infobox-atom { width: 100%; }
.editor-infobox .ui-field-table td { border: none; }
.editor-infobox .ui-field-table td:first-child { width: 75px; }

.editor-infobox .editor-paginator { padding-left: 0.5em; color: #909090; margin-top: 4px; }
.editor-infobox .editor-paginator > div { margin-top: -2px; }

/****************************************************************************\
 * Editor Block Canvas
\****************************************************************************/
.editor-view .editor-query-tree { width: 180px; margin-right: 10px; }


/****************************************************************************\
 * Data Editor
\****************************************************************************/
.editor-block-data-canvas {position: relative;flex: 1;align-items: flex-start;}
.editor-block-data-canvas .editor-data-toolbar { flex: 0 0 auto; background: #eee; border-radius: 3px; }
.editor-block-data-canvas .editor-data-toolbar > .ui-button { display: flex; flex-direction: column; align-items: center; padding: 10px; color: #999; }
.editor-block-data-canvas .editor-data-toolbar > .ui-button:before { font-size: 1.5em; color: #404040;}
.editor-block-data-canvas .editor-data-toolbar > .ui-button.editor-active {  color: #66f; }
.editor-block-data-canvas .editor-data-toolbar > .ui-button.editor-active:before {  color: #44f; }
.editor-block-data-canvas .editor-data-toolbar > .editor-data-toolbar-select:before { transform: rotateZ(-30deg); }

.editor-block-data-canvas .editor-data-molecule-infobox {position: absolute;top: 300px;left: 70px;padding: 10px;z-index: 2;border: 1px solid gray;background: rgba(255, 255, 255, 0.5);}
.editor-block-data-canvas .editor-data-node-infobox { padding: 10px; }
.editor-block-data-canvas .editor-data-node-infobox + .editor-node-infobox { border-top: 1px solid gray; }
.editor-block-data-canvas .editor-data-atom-infobox + .editor-atom-infobox { margin-top: 20px; }

.editor-block-data-canvas .editor-data-node-header { font-weight: 500; text-align: center; }
.editor-block-data-canvas .editor-data-field-row { min-width: 200px; min-height: 20px; margin-bottom: -1px; border: 1px solid #ccc; }
.editor-block-data-canvas .editor-data-field-attribute {display: flex;flex: 0;width: auto;min-width: 100px;padding: 0 10px; margin: -1px; margin-right: 0; background: transparent; border: 1px solid transparent; border-right-color: #ccc;}
.editor-block-data-canvas .editor-data-field-value-set {flex: 1 1 auto;/* max-width: 140px; */}
.editor-block-data-canvas .editor-data-field-value {display: flex;flex: 1;min-width: 80px;min-height: 20px;padding: 0 10px;margin: -1px;background: transparent;border: 1px solid transparent;}

.editor-block-data-canvas .editor-data-molecule-infobox input { font-size: 1em; font-weight: inherit;font-family: inherit; color: inherit;}
.editor-block-data-canvas .editor-data-molecule-infobox input::-webkit-input-placeholder { font-weight: 300; }

.editor-block-data-canvas .editor-data-field-new-row { background: #ddffdd; border-color: #44cc44; }

.editor-block-data-canvas .editor-data-field-row.editor-data-erasing { background: #ffdddd; border-color: #cc4444; }
.editor-block-data-canvas .editor-data-field-value.editor-data-erasing { background: #ffdddd; border-color: #cc4444; }



/****************************************************************************\
 * Shapes
\****************************************************************************/

/* .shape-hexagon { position: relative; } */
/* .shape-hexagon .shape-hexagon-body { justify-content: center; align-items: center; } */
/* .shape-hexagon .shape-hexagon-cap { } */

/* .shape-hexagon .shape-hexagon-inner {  } */

/* .shape-hex-grid {position: relative;left: 70px;} */





.hex-grid > .shape-hexagon-body,
.hex-grid > .shape-hexagon-cap { transition: 0.5s background ease-in, 0.5s border-top-color ease-in, 0.5s border-bottom-color ease-in; }

.hex-grid:hover > .shape-hexagon-body,
.hex-grid:hover > .shape-hexagon-cap { transition: 0.2s background ease-out, 0.2s border-top-color ease-out, 0.2s border-bottom-color ease-out; }


.hex-grid:hover > .shape-hexagon-body { background: #ccc !important; }
.hex-grid:hover > .shape-hexagon-cap.first { border-bottom-color: #ccc !important; }
.hex-grid:hover > .shape-hexagon-cap.last { border-top-color: #ccc !important; }

text { flex: 0 0 auto; }
column { flex: 0 0 auto; }
row { flex: 0 0 auto; }


================================================
FILE: assets/css/examples/crm.css
================================================
h3, h4 { font-weight:normal; font-size:16px; }

.container {
  box-shadow: 0 3px 8px #bbb;
  width: 400px;
  height: 711px;
  background: white;
  font-family: sans-serif;
  font-size: 14px;
  display: flex;
  flex-direction: column;
}

.scroll {
  flex: 1;
  overflow: auto;
  display:flex;
  flex-direction:column;
}

.avatar {
  width: 128;
  height: 128;
}

.banner {
  background: linear-gradient(-90deg, rgb(74,64,136), rgb(0,158,224));
  width: 100%;
  height: 150px;
  flex:none;
}

.avatar-container {
  border-radius: 6px;
  width: 128px;
  height: 128px;
  overflow: hidden;
  border: 5px solid white;
  margin: auto;
  margin-top: -60px;
}

.name2 {
  width: 100%;
  text-align: center;
  color: rgb(11,11,37);
  font-family: sans-serif;
  font-size: 20px;
  font-weight: bold;
  margin-top: 10px;
}

.info {
  width: 100%;
  text-align: center;
  color: rgb(147,167,178);
  color: #999;
  font-family: sans-serif;
  font-size: 14px;
  margin-top: 5px;
}

.navigation {
  display: flex;
  flex:none;
  border-top: 1px solid #eee;
  padding:5px 0;
}

.nav-button {
  position:relative;
  flex-grow: 1;
  text-align: center;
  height: 60px;
  cursor: pointer;
  color: #999;
}

.icon {
  font-size: 30px;
  padding: 3px;
  height: 35px;
  margin-top:2px;
}

.middle {
  border-right: 1px solid #eee;
}

.bubble {
  position: absolute;
  top:8px;
  left: 56px;
  color: white;
  font-weight: bold;
}

.content {
  margin-top: 10px;
  padding: 0px;
  flex-grow: 1;
  display: flex;
  flex-direction: column;
}

.convo {
  height: 280px;
  margin-bottom: 10px;
  padding: 10px 20px;
  overflow: auto;
}

.msg-avatar {
  height: 40px;
  width: 40px;
  margin-right: 15px;
  float: left;
  border-radius: 4px;
  border: 1px solid #ddd;
}

.msg-name {
  font-weight: bold;
  color: #555;
  margin-top:2px;
  margin-bottom:2px;
}

.msg {
  margin-bottom: 10px;
  min-height: 40px;
  flex:none;
}

.thread:first-child { margin-top:30px; border-top:1px solid #eee; }

.thread {
  padding: 15px 20px;
  display: flex;
  flex-direction: row;
  border-bottom: 1px solid #eee;
  align-items: center;
  color: #999;
}

.thread img {}

.thread-box {
  flex-grow: 1;
}

.archive {
  cursor: pointer;
  color: #999;
  font-size: 25px;
}

.contact-avatar {
  width: 80px;
  height: 80px;
  float: left;
  margin-right: 10px;
  border-radius: 4px;
}

.contact-name {
  font-weight: bold;
  font-size: 18px;
  margin-top:3px;
  margin-bottom: 5px;
  color: #666;
}

.contact {
  flex: none;
  padding: 15px 20px;
  border-bottom: 1px solid #eee;
  color: #999;
}

.contact:first-child { margin-top: 20px; border-top:1px solid #eee; }

.recent-avatar {
  width: 40px;
  height: 40px;
  margin-right: 10px;
}

.msg-input {
  width: 360px;
  margin: 0 20px;
  border: 1px solid #ddd;
  border-radius: 2px;
  padding: 5px;
  font-size: 12pt;
}

.msg-time {
  color: rgb(175,175,175);
  margin-left: 10px;
  font-size: 12px;
}

.about { padding: 0 40px; padding-top: 10px; }

.about-line {
  display: flex;
  flex-direction:column;
  margin-top:20px;
}

.about-label, .about h3 {
  color: rgb(152, 171, 181);
  color: #999;
  margin-bottom:6px;
  font-size: 14px;
}

.about h3 { margin-top:20px; margin-bottom:10px; }
.about img { border-radius:4px; border:1px solid #ddd; }

.plus {
  background-color: rgb(111, 165, 81);
  color: white;
  width: 16px;
  height: 16px;
  float: left;
  border-radius: 50%;
  text-align: center;
  font-size: 14px;
  font-weight: bold;
  margin-right: 5px;
  cursor: pointer;
}

a {
 color: rgb(0,158,224);
 line-height: 20px;
 text-decoration: none;
 border-bottom: 1px dashed rgb(0,158,224);
}

a:hover {
  color: rgb(91,89,164);
}

.more {
  padding: 0 40px;
}

.more h2 { font-weight: normal; font-size: 16pt; margin-top: 30px; margin-bottom: 10px; }

.more ul { margin: 5px 0; }
.more li { margin-bottom:8px; }

.button {
  background-color: rgb(111, 165, 81);
  color: white;
  width: 80%;
  height: 25px;
  border-radius: 10px;
  text-align: center;
  font-size: 14px;
  font-weight: bold;
  margin-right: auto;
  margin-left: auto;
  margin-top: 10px;
  padding-top: 4px;
  cursor: pointer;
}

================================================
FILE: assets/css/examples/todomvc.css
================================================
.program {
    margin: 0 auto;
    padding: 0;
    font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
    line-height: 1.4em;
    background: #f5f5f5;
    color: #4d4d4d;
    -webkit-font-smoothing: antialiased;
    -moz-font-smoothing: antialiased;
    font-smoothing: antialiased;
    font-weight: 300;
}

.todoapp {
    flex: 0 0 auto;
    min-width: 450px;
    max-width: 650px;
    height: auto;
    margin: 130px auto 40px auto;

    background: #fff;
    position: relative;
    box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2),
        0 25px 50px 0 rgba(0, 0, 0, 0.1);
}

.todoapp button {
    margin: 0;
    padding: 0;
    border: 0;
    background: none;
    font-size: 100%;
    vertical-align: baseline;
    font-family: inherit;
    font-weight: inherit;
    color: inherit;
    -webkit-appearance: none;
    appearance: none;
    -webkit-font-smoothing: antialiased;
    -moz-font-smoothing: antialiased;
    font-smoothing: antialiased;
}

.todoapp button,
.todoapp input[type="checkbox"] {
    outline: none;
}

.todoapp input::-webkit-input-placeholder {
    font-style: italic;
    font-weight: 300;
    color: #e6e6e6;
}

.todoapp input::-moz-placeholder {
    font-style: italic;
    font-weight: 300;
    color: #e6e6e6;
}

.todoapp input::input-placeholder {
    font-style: italic;
    font-weight: 300;
    color: #e6e6e6;
}

.todoapp h1 {
    position: absolute;
    top: -155px;
    width: 100%;
    font-size: 100px;
    font-weight: 100;
    text-align: center;
    color: rgba(175, 47, 47, 0.15);
    -webkit-text-rendering: optimizeLegibility;
    -moz-text-rendering: optimizeLegibility;
    text-rendering: optimizeLegibility;
}

.todoapp .hidden {
    display: none !important;
}

.todoapp .new-todo,
.todoapp .edit {
    position: relative;
    margin: 0;
    width: 100%;
    font-size: 24px;
    font-family: inherit;
    font-weight: inherit;
    line-height: 1.4em;
    border: 0;
    outline: none;
    color: inherit;
    padding: 6px;
    border: 1px solid #999;
    box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
    box-sizing: border-box;
    -webkit-font-smoothing: antialiased;
    -moz-font-smoothing: antialiased;
    font-smoothing: antialiased;
}

.todoapp .new-todo {
    padding: 16px 16px 16px 60px;
    border: none;
    background: rgba(0, 0, 0, 0.003);
    box-shadow: inset 0 -2px 1px rgba(0,0,0,0.03);
}

.todoapp .toggle-all {
    position: absolute;
    top: 12px;
    left: 14px;
    width: 60px;
    height: 34px;
    text-align: center;
    border: none; /* Mobile Safari */
}

.todoapp .main {
    position: relative;
    z-index: 2;
    border-top: 1px solid #e6e6e6;
}

.todoapp .todo-list {
    margin: 0;
    padding: 0;
    list-style: none;
}

.todoapp .todo-list li {
    position: relative;
    padding-left: 40px;
    font-size: 24px;
    border-bottom: 1px solid #ededed;
}

.todoapp .todo-list li:last-child {
    border-bottom: none;
}

.todoapp .todo-list li.editing {
    display: flex;
    flex-direction: row;
    border-bottom: none;
    padding: 0;
    height: 44px;
}

.todoapp .todo-list li.editing .edit {
    display: flex;
    flex: 1;
    padding: 13px 15px 12px 15px;
    margin: -1px 0 0 43px;
}

.todoapp .todo-list li .toggle {
    text-align: center;
    width: 40px;
    /* auto, since non-WebKit browsers doesn't support input styling */
    height: auto;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0px;
    border: none; /* Mobile Safari */
    -webkit-appearance: none;
    appearance: none;
}

.todoapp .todo-list li .toggle:after {
    content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="-10 -18 100 135"><circle cx="50" cy="50" r="50" fill="none" stroke="#ededed" stroke-width="3"/></svg>');
}

.todoapp .todo-list li .toggle:checked:after {
    content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="40" height="40" viewBox="-10 -18 100 135"><circle cx="50" cy="50" r="50" fill="none" stroke="#bddad5" stroke-width="3"/><path fill="#5dc2af" d="M72 25L42 71 27 56l-4 4 20 20 34-52z"/></svg>');
}

.todoapp .todo-list li label {
    white-space: pre-line;
    word-break: break-all;
    margin-left: 12px;
    padding: 8px 6px;
    display: block;
    line-height: 1.2;
    transition: color 0.4s;
}

.todoapp .todo-list li.completed label {
    color: #d9d9d9;
    text-decoration: line-through;
}

.todoapp .todo-list li .destroy {
    display: none;
    position: absolute;
    top: 0;
    right: 10px;
    bottom: 0;
    width: 40px;
    height: 40px;
    margin: auto 0;
    font-size: 30px;
    color: #cc9a9a;
    margin-bottom: 11px;
    transition: color 0.2s ease-out;
}

.todoapp .todo-list li .destroy:hover {
    color: #af5b5e;
}

.todoapp .todo-list li .destroy:after {
    position: relative;
    content: "×";
    top: 8px;
}

.todoapp .todo-list li:hover .destroy {
    display: block;
}

.todoapp footer {
    color: #777;
    padding: 10px 15px;
    height: 41px;
    text-align: center;
    border-top: 1px solid #e6e6e6;
}

.todoapp footer:before {
    content: '';
    position: absolute;
    right: 0;
    bottom: 0;
    left: 0;
    height: 50px;
    overflow: hidden;
    box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2),
        0 8px 0 -3px #f6f6f6,
        0 9px 1px -3px rgba(0, 0, 0, 0.2),
        0 16px 0 -6px #f6f6f6,
        0 17px 2px -6px rgba(0, 0, 0, 0.2);
}

.todoapp .todo-count {
    float: left;
    text-align: left;
}

.todoapp .todo-count strong {
    font-weight: 300;
}

.todoapp .clear-completed,
html .todoapp .clear-completed:active {
    float: right;
    position: relative;
    line-height: 20px;
    text-decoration: none;
    cursor: pointer;
    position: relative;
}

.todoapp .clear-completed:hover {
    text-decoration: underline;
}


.todoapp .filters {
    margin: 0;
    padding: 0;
    list-style: none;
    position: absolute;
    right: 0;
    left: 0;
}

.todoapp .filters li {
    display: inline;
}

.todoapp .filters li a {
    color: inherit;
    margin: 3px;
    padding: 3px 7px;
    text-decoration: none;
    border: 1px solid transparent;
    border-radius: 3px;
}

.todoapp .filters li a.selected,
.todoapp .filters li a:hover {
    border-color: rgba(175, 47, 47, 0.1);
}

.todoapp .filters li a.selected {
    border-color: rgba(175, 47, 47, 0.2);
}


================================================
FILE: assets/css/ide.css
================================================
.flex-spacer { flex: 1; }
.flex-row { display: flex; flex: 1; flex-direction: row; }

@keyframes hide-delayed {
    from { opacity: 1; }
    99% { opacity: 1; }
    to { opacity: 0; }
}

* { box-sizing: border-box; }


html, body, __root { height: 100%; }
body { background: #f5f5f5; color: #555; }
button { font-family: "Avenir", "Helvetica neue", sans-serif; }
/****************************************************************************\
 * Root
\****************************************************************************/
body { justify-content: stretch; }
.application-root { overflow: auto; }

.editor-root { display: flex; flex-direction: row; height: 100%; align-items: stretch; background: #fff; }

.navigator-pane { width: 280px; flex: 0 0 auto; align-self: stretch; overflow-x: hidden; background:#555; color:#eee; transition: width 0.3s ease-in-out, background-color 0.2s ease-in-out; padding-bottom:30px; }
.navigator-pane.collapsed { width: 20px; background-color: #fff; }
.navigator-pane.collapsed:hover { background: #555; color: #eee; }
.navigator-pane .navigator-pane-inner { width: 280px; padding: 0 5px; margin-left: 0; transition: margin-left 0.3s ease-in-out; }
.navigator-pane.collapsed .navigator-pane-inner { margin-left: -255px; }
.navigator-pane.collapsed .tree-item { pointer-events: none; }

.editor-pane { position: relative; height: 100%; }

.CodeMirror-sizer > div:first-child { width: 650px; min-height: 100%; }

/****************************************************************************\
 * Navigator
\****************************************************************************/
.navigator-header { display: flex; flex-direction: column; padding:10px 5px; user-select: none; -webkit-user-select: none; margin-bottom:10px; font-size:18px; color: #aaa; transition:color 0.2s ease-in-out; }
.navigator-header > .controls { display:flex; flex-direction:row; flex:1; }
.navigator-header > .controls > * {height: 20px; text-align: center; padding: 0 5px; transition: transform 0.3s; cursor: pointer; }
.navigator-header > .controls > *:last-child { margin-right: -5px; }
.navigator-header > .controls > div:not(.disabled):hover { color: #eee; }
.navigator-pane.collapsed:hover .navigator-header > .controls > div { color: #eee; }
.navigator-header .collapse-btn { transform: rotate(180deg); color: #999; }
.navigator-header .up-btn.disabled > .up-icon { opacity: 0; }

.navigator-pane .load-dialog { padding: 10 25; color: #555; margin-top: -10px; margin-bottom: 10px; }
.navigator-pane .load-dialog input { padding: 5px; outline: none; border-top-left-radius: 2px; border: 1px solid #CCC; border-bottom-left-radius: 2px; }
.navigator-pane .load-dialog .load-btn { padding: 5px; background: white; border: 1px solid #CCC; border-left-color: transparent; border-top-right-radius: 2px; border-bottom-right-radius: 2px; }
.navigator-pane .load-dialog .load-btn:before { position: relative; top: 3px; }
.navigator-pane .load-dialog .load-btn:hover { background: #EEE; }
.navigator-pane .load-dialog .load-btn:active { background: #DDD; }

.navigator-header .up-btn .label { display: flex; font-size:16px; margin-left: 10px; }
.navigator-header .label { white-space: pre; display:none; }

.navigator-header .inspector-controls { margin-top: 20px; }
.navigator-header .inspector-controls button {border:none; color:#eee; outline:none; cursor:pointer; padding:3px 10px; font-size: 10pt; margin-left:20px; background:#666; border-radius:2px; margin-top: 20px; transition:background 0.1s ease-in-out; }
.navigator-header .inspector-controls button:hover { background: #777; }



.tree-item { flex-direction: column; align-items: stretch; }
.tree-item > .tree-items { display: flex; flex-direction: column; }

.item-level-1 > div > .label { font-size:14pt; }
.item-level-1 > .flex-row { margin-bottom:25px; }
.tree-item + .item-level-1 > .flex-row { margin-top: 25px; }
.item-level-2 { margin-bottom:25px; margin-left:3px; }
.item-level-2 > div > .label { font-weight: bold; margin-bottom:5px; }
.item-level-3 { margin-top:3px; }
.item-level-3 > div > .label { color:#bbb; font-size: 11pt; }

.tree-item .label { display: flex; flex: 1 1 auto; margin-left: 20px; user-select: none; -webkit-user-select: none; transition: opacity 0.15s; cursor: pointer;}
.tree-item .label:before { display: inline-block; margin-left: -15px; margin-right: 5px; height: 15px; width: 15px; text-align: center; }
.tree-item.branch .label:before { opacity: 0.25; transition: transform 0.15s; }
.tree-item.branch.root > .flex-row > .label { opacity: 0; pointer-events: none; }
.tree-item.branch.collapsed .label:before { transform: rotate(-90deg); opacity: 0.5; }
.tree-item.branch:hover .label:before { opacity: 1; }
.tree-item .label.no-icon:before { content: ""; }

.tree-item .controls { display: flex; flex: 0 0 auto; align-items: center; color:#bbb; margin-left: 5px; opacity: 0; transition: opacity 0.15s; user-select: none; -webkit-user-select: none; }
.tree-item .controls > * { cursor:pointer; display: inline-block; width: 20px; text-align: center; }
.tree-item .controls > div:hover { color: #eee; }
.tree-item:hover > .flex-row > .controls { opacity: 1; }

.tree-item.hidden > .flex-row > .label { opacity: 0.5; }

/****************************************************************************\
 * Notices
\****************************************************************************/
.main-pane { display: flex; flex-direction: column; justify-content: stretch; overflow-y: hidden; position: relative; }
.main-pane .notices { display: flex; flex: 0 0 auto; flex-direction: column; border-right: 1px solid #ddd; border-bottom: 1px solid #ddd; }

.main-pane .notices > .notice { padding: 5px 60px; background: #f5f5f5; flex: 0 0 auto; }
.main-pane .notices > .notice + .notice { border-top: 1px solid #ddd; }
.main-pane .notices > .notice > .time { margin-right: 10px;  }

.main-pane .notices > .notice > .dismiss-btn { margin-left: 10px; vertical-align: bottom; align-self: center; opacity: 0; transition: opacity 0.2s; }
.main-pane .notices:hover > .notice > .dismiss-btn { opacity: 1; }
.main-pane .notices > .notice > .dismiss-btn:hover { background: #eee; }

.main-pane .notices > .notice.error { background: rgb(255, 216, 222); }
.main-pane .notices > .notice.warning { background: rgb(255, 247, 217); }

/****************************************************************************\
 * Modals
\****************************************************************************/
.main-pane > .modal-overlay {display: flex;justify-content: center;align-items: center;position: absolute;top: 0;left: 0;bottom: 0;right: 0;z-index: 5;background: rgba(0, 0, 0, 0.1);}
.main-pane > .modal-overlay .modal-window { display: flex; flex-direction: column; width: 320; padding: 20; background: #FFF; border-radius: 4px; z-index: 10; box-shadow: 0 4px 5px rgba(0, 0, 0, 0.25); }
.main-pane > .modal-overlay .modal-window h3 { align-self: center; margin-top: 0; }
.main-pane > .modal-overlay .modal-window .controls { flex: 0 0 auto; }
.main-pane > .modal-overlay .modal-window .btn { flex: 1; text-align: center; padding: 5 10; border: 1px solid #DDD; border-radius: 4px; -webkit-user-select: none; -moz-webkit-user-select: none; }
.main-pane > .modal-overlay .modal-window .btn + .btn { margin-left: 10; }
.main-pane > .modal-overlay .modal-window .btn:hover { background: #EEE; }
.main-pane > .modal-overlay .modal-window .btn:active {background: #DDD; }
.main-pane > .modal-overlay .modal-window .btn.danger { background: #EE5555; color: white; border: #CC3333; }
.main-pane > .modal-overlay .modal-window .btn.danger:hover { background: #DD4444; }
.main-pane > .modal-overlay .modal-window .btn.danger:active { background: #CC3333; }

/****************************************************************************\
 * Editor
\****************************************************************************/
.editor-pane { margin-left: 50px; }

.editor-pane > .controls { position: absolute; top: 10px; right: 30px; z-index: 10; background: rgba(255, 255, 255, 1); }
.editor-pane > .controls > div { padding: 5px 10px; font-size:22px; color: #999; border-radius:2px; }
.editor-pane > .controls > div:hover { background: #eee; color: #555; }

.CodeMirror-lines { padding-top:30px; }

.CodeMirror { background:none; color: inherit; height:100%; font-size:11pt;  }
.CodeMirror-scroll, .CodeMirror-gutters { height:100%; }
.CodeMirror-cursor { background: #555; border-color:#555; }

.CodeMirror { color: #555; line-height:25px; font-family: Avenir, "Helvetica Neue", sans-serif; }
.CodeMirror pre { padding-left: 8px; padding-right:50px; }
.CodeMirror-scroll { scroll-behavior: smooth; }
.CodeMirror-gutters { background: #303030; border-right: none; padding-right: 5px; }
.CodeMirror-selected { background: rgba(0,117,255,0.1); }
.CodeMirror-focused .CodeMirror-selected { background: rgba(0,117,255,0.2); }

.CodeMirror-simplescroll-vertical { width:14px; background: #fff; border-left:1px solid #ddd; border-right:1px solid #ddd; }
.CodeMirror-simplescroll-vertical div { border:none; border-radius:0; background: #f4f4f4; border-top:1px solid #ddd; border-bottom:1px solid #ddd; }
.CodeMirror .scrollbar-annotation { width: 8px !important; min-height:3px !important; height:3px !important; right: 3px !important; }

.CodeMirror .STRONG { font-weight:bold; }
.CodeMirror .EMPH { font-style:italic; }
.CodeMirror .CODE { margin-left: 10px; margin-right:50px; border-left:5px solid #eaeaea; background: #f4f4f4; font-family: "Inconsolata", "Monaco", "Consolas", "Ubuntu Mono", monospace;  }
.CodeMirror .CODE.css { background: #f0f5ff; border-left-color: #e1ebff;}
.CodeMirror .CODE-TEXT { line-height:19px; padding-left:30px; transition: opacity 0.3s; }
.CodeMirror .CODE-TEXT.CODE-DISABLED { opacity: 0.6; }
.CodeMirror span.CODE { color: #0076ce; background:none; margin:0; padding:0; border:none; }

.CodeMirror .CODE_BLOCK { font-family: "Inconsolata", "Monaco", "Consolas", "Ubuntu Mono", monospace; }
.CodeMirror .CODE-TOP { border-radius:3px 3px 0 0; padding-top:8px; }
.CodeMirror .CODE-BOTTOM { border-radius:0 0 3px 3px; padding-bottom:8px; }

.CodeMirror .CodeMirror-linewidget { overflow: visible; z-index: 3; }
.CodeMirror .code-controls-widget { display: flex; flex-direction: row; justify-content: flex-end; margin-right: 50px; padding: 3px 6px; padding-bottom: 0; height: 20px; font-size: 1.2rem; transition: opacity 0.3s; }
.CodeMirror .code-controls-widget .enable-btn { cursor:pointer; opacity: 0.2; }
.CodeMirror .CodeMirror-linewidget .code-controls-widget .enable-btn:hover { opacity: 1; }
.CodeMirror .CodeMirror-linewidget .code-controls-widget .code-language-label {font-size: 1.0rem; margin-top: -2px; margin-right: 5px; opacity: 0.5;}

.CodeMirror .code-footer-widget { height: 15px; }

.CodeMirror .DOC { color: #d8d8d8; }
.CodeMirror .HEADING1 { font-size:30px; padding-top:20px; padding-bottom: 30px;}
.CodeMirror .HEADING2 { font-size:20px; padding-top:20px; padding-bottom: 10px; font-weight: bold; }
.CodeMirror .HEADING3 { font-size:16px; padding-top:20px; padding-bottom: 10px; font-weight: bold; }
.CodeMirror .HEADING4 { font-size:12pt;}

.CodeMirror .link { color: #0079d3; }
.CodeMirror .link-widget { margin-right: 8px; }

/* Syntax Styles */

.CodeMirror .COMMENT { color: #747474; }

/* Variables/Attributes */
.CodeMirror .ALIAS { }
.CodeMirror .TAG, .CodeMirror .TAG + .IDENTIFIER { color: #50edf6; color: #4bcbd3; color: #0076ce; }
.CodeMirror .NAME, .CodeMirror .NAME + .IDENTIFIER { color: #50edf6; color: #4bcbd3; color: #0076ce; }
/* Phases */
.CodeMirror .ACTION, .SEARCH { color: black; }
/* Statements */
.CodeMirror .IF, .ELSE, .THEN { color: black; }
/* Literals */
.CodeMirror .STRING, .QUOTE, .BOOL, .NUM { color: #00a588; }
/* Brackets */
.CodeMirror .OPEN-BRACKET, .CodeMirror .CLOSE-BRACKET, .CodeMirror .OPEN-PAREN, .CodeMirror .CLOSE-PAREN { color: gray; }
.CodeMirror .STRING-EMBED-OPEN, .CodeMirror .STRING-EMBED-CLOSE { color: gray; }
.CodeMirror .DOT, .CodeMirror .COMMA { color: gray; }
/* Binding/Action Operators */
.CodeMirror .EQUALITY, .CodeMirror .MERGE, .CodeMirror .SET, .CodeMirror .MUTATE { color: gray; }
/* Infix Operators */
.CodeMirror .INFIX, .CodeMirror .COMPARISON { color: gray; }

/****************************************************************************\
 * Elision
\****************************************************************************/

.elision { border-top:1px solid #ddd; }

/****************************************************************************\
 * Format Bars
\****************************************************************************/
.editor-pane .new-block-bar { position: absolute; top: 0; left: 0; margin-left: -28px; display: flex; flex-direction: row; width: 28px; overflow: hidden; transition: width 0.15s; z-index: 5; color: #666; border-radius:5px; border:1px solid #ddd; font-size:10pt; background:white; }
.editor-pane .new-block-bar.active { width: 267px; }


.editor-pane .new-block-bar > .new-block-bar-toggle,
.editor-pane .new-block-bar > .controls > div { display:flex; padding: 3px 10px; align-items:center; cursor:pointer; }

.editor-pane .new-block-bar > .new-block-bar-toggle { padding: 3px 8px; }

.editor-pane > .controls > div { cursor:pointer; }
.editor-pane .new-block-bar > .new-block-bar-toggle:hover,
.editor-pane .new-block-bar > .controls > div:hover{ background: #e4e4e4; }
.editor-pane .new-block-bar > .new-block-bar-toggle:before { transition: transform 0.15s; }
.editor-pane .new-block-bar.active > .new-block-bar-toggle:before { transform: rotate(45deg); }

.editor-pane .format-bar { position: absolute; top: 0; left: 0; display: flex; flex-direction: row; background: #666; color: #eee; z-index: 9; border-radius:2px; overflow:hidden; }
.editor-pane .format-bar > * { padding: 5px 10px; cursor:pointer; }
.editor-pane .format-bar > div:hover { background: #888; color: #fff; }


/****************************************************************************\
 * Comments
\****************************************************************************/

.comment-widget { padding: 2px 0; }
.code-comment-widget { padding-left: 30px; margin-top: 2px; margin-left: 10px; margin-right: 50px; border-left: 5px solid #ff7e92; }

.comment-widget.error { background: rgb(255, 216, 222); color: #b7003e; }

.comment-widget .comment { font-size: 10pt; }

.comment-widget .comment-inner { display: block; }
.comment-inner { display: none; }

.comment-widget .quick-actions { display: flex; flex-direction: row; flex-wrap: wrap; opacity: 0.5; transition: opacity 0.15s; }
.comment-widget:hover .quick-actions { opacity: 1; }
.comment-widget .quick-actions > .comment-action { flex: 1 0 auto; max-width: 50%; padding: 2px 5px; margin-top: 5px; text-align: center; background: #404040; }
.comment-widget .quick-actions > .comment-action + .comment-action { margin-left: 1px; }
.comment-widget .quick-actions > .comment-action:hover { background: #505050; }

.comment.error { border-color: #F06060; color: #b7003e; }
.comment.warning { border-color: #C0C060; }

.CodeMirror .document_comment { }
.CodeMirror .document_comment.error { border-bottom: 1px solid #ff7e92; }
.CodeMirror .document_comment.warning { border-bottom: 1px solid #C0C060; }

.CodeMirror .scrollbar-annotation { background: #AAA; min-height: 5px; opacity: 1; transition: opacity 0.15s; z-index: 2; }
.CodeMirror .scrollbar-annotation:hover { opacity: 0.5; }
.CodeMirror .scrollbar-annotation.error { background: #ff7e92; }
.CodeMirror .scrollbar-annotation.warning { background: #C0C060; }
.CodeMirror .scrollbar-annotation.affector, .CodeMirror .scrollbar-annotation.source { background: #66b1e9; }

/* .CodeMirror .COMMENT_error { border-color: #ff7e92; } */

/****************************************************************************\
 * Views
\****************************************************************************/
.program > .view { display: none !important; }

.view-container { margin:10px 50px 0px 10px; padding-left: 20px; border-left:5px solid #96e4d7; background: #d1f5eb; }
.CodeMirror-linewidget + .CodeMirror-linewidget .view-container { margin-top:0; }

table.view { border-collapse: collapse; }
table.view thead { border: 1px solid #ccc; }
table.view td { padding: 0 5px; border: 1px solid #ccc; border-top: none; border-bottom: none; }

.view.kv-table { display: table; border-collapse: collapse; border: 1px solid #202020; }
.view.kv-table .kv-row { display: table-row; }
.view.kv-table .kv-row + .kv-row { border-top: 1px solid #606060; }
.view.kv-table .kv-row > div { display: table-cell; padding: 0 5px; }
.view.kv-table .kv-values { border-left: 1px solid #202020; }

.view.bar-graph { position: relative; display: flex; flex-direction: row; align-items: flex-end; }
.view.bar-graph .bar-graph-bar { display: flex; align-items: flex-end; margin:10px 0; justify-content: center; min-height: 1px; background: #6ed2c1; margin-right: 2px; transition: 0.3s width, 0.3s height; }

/****************************************************************************\
 * Inspector
\****************************************************************************/
.editor-pane .controls .inspector-button.waiting { color: #ff0028; background: #ffdde2; }
.editor-pane .controls .inspector-button.inspecting { color: #ff0028; background: #ffdde2; }

.CodeMirror .code.annotated { border-left-color: #66b1e9; }
.CodeMirror .code.annotated.annotated_performance-red { border-left-color: #c65555; }
.CodeMirror .code.annotated.annotated_performance-orange { border-left-color: #e9c070; }
.CodeMirror .scrollbar-annotation.performance-red { background: #c65555; min-height: 5px; opacity: 1; transition: opacity 0.15s; z-index: 2; }
.CodeMirror .scrollbar-annotation.performance-orange { background: #e9c070; min-height: 5px; opacity: 1; transition: opacity 0.15s; z-index: 2; }

.code-comment-widget.performance-green { white-space: pre; background: #e0e0e0; border-left: 5px solid #EEEEAA; }
.code-comment-widget.performance-orange { white-space: pre; background: #ffe9c0; border-left: 5px solid #e9c070; }
.code-comment-widget.performance-red { white-space: pre; background: #f9cccc; border-left: 5px solid #c65555; }

.CodeMirror .shadow { color: #999 !important; }
.CodeMirror .highlight { background: rgba(127, 192, 255, 0.4); }
.CodeMirror .badge {  }
.CodeMirror .badge-widget { display: inline-block; margin-left: 2px; font-size: 10pt; color: #E91E63; padding: 0 3px; }
.CodeMirror .badge-widget:before { content: "( "; }
.CodeMirror .badge-widget:after { content: " )"; }
.CodeMirror .cause-of-failure { background: rgb(255, 200, 215); }

.inspector-pane { overflow:hidden; display:flex; width:250px; background: #666; flex-direction: column; color: #eee; border-radius:2px; box-shadow: 0 2px 8px #aaa; z-index: 10; }
.inspector-pane .buttons { display:flex; flex-direction:column; }
.inspector-pane .buttons button { background:none; border:none; color: #eee; font-size: 10pt; width: 100%; padding: 8px 15px; text-align:left; }
.inspector-pane .buttons button + button { border-top:1px solid #555; }

.inspector-pane .kv-table { border:none; width:100%; background: #777; border-radius: 2px 2px 0 0; }
.inspector-pane .kv-key { color: #ddd; }
.inspector-pane .kv-table .kv-values { border-left: 1px solid #555; }
.inspector-pane .kv-table .kv-row > div { padding: 4px 15px; font-size:11pt; }
.inspector-pane .kv-table .kv-row { border:none; border-bottom:1px solid #555; }

.inspector-pane div[is-entity="true"] { color: #A6D0FF; }


================================================
FILE: assets/css/simplescrollbars.css
================================================
.CodeMirror-simplescroll-horizontal div, .CodeMirror-simplescroll-vertical div {
  position: absolute;
  background: #ccc;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
  border: 1px solid #bbb;
  border-radius: 2px;
}

.CodeMirror-simplescroll-horizontal, .CodeMirror-simplescroll-vertical {
  position: absolute;
  z-index: 6;
  background: #eee;
}

.CodeMirror-simplescroll-horizontal {
  bottom: 0; left: 0;
  height: 8px;
}
.CodeMirror-simplescroll-horizontal div {
  bottom: 0;
  height: 100%;
}

.CodeMirror-simplescroll-vertical {
  right: 0; top: 0;
  width: 8px;
}
.CodeMirror-simplescroll-vertical div {
  right: 0;
  width: 100%;
}


.CodeMirror-overlayscroll .CodeMirror-scrollbar-filler, .CodeMirror-overlayscroll .CodeMirror-gutter-filler {
  display: none;
}

.CodeMirror-overlayscroll-horizontal div, .CodeMirror-overlayscroll-vertical div {
  position: absolute;
  background: #bcd;
  border-radius: 3px;
}

.CodeMirror-overlayscroll-horizontal, .CodeMirror-overlayscroll-vertical {
  position: absolute;
  z-index: 6;
}

.CodeMirror-overlayscroll-horizontal {
  bottom: 0; left: 0;
  height: 6px;
}
.CodeMirror-overlayscroll-horizontal div {
  bottom: 0;
  height: 100%;
}

.CodeMirror-overlayscroll-vertical {
  right: 0; top: 0;
  width: 6px;
}
.CodeMirror-overlayscroll-vertical div {
  right: 0;
  width: 100%;
}


================================================
FILE: assets/css/trace.css
================================================
.trace { position:absolute; bottom:20px; right:20px; width:75vw; background: #202020; color: #ccc;  height:70vh; font-family: inconsolata; }
.trace .searcher { overflow:auto; padding:10px; flex:none; }
.trace button { flex:none; text-align:left; border:none; background: #444; margin-top:5px; cursor:pointer; color: #ccc; }
.trace .change-link { flex:none; }

.trace .vis { overflow:auto; }
.trace .vis row { flex:none; }
.trace .vis column { flex:none; }
.trace .node { padding:10px; border:1px solid #777; flex:none; margin:5px; }

.trace .block { margin:15px 0; }


================================================
FILE: bin/eve.js
================================================
#!/usr/bin/env node
"use strict";

var path = require("path");
var fs = require("fs");
var minimist = require("minimist");

var config = require("../build/src/config");
var Owner = config.Owner;
var Mode = config.Mode;
var server = require("../build/src/runtime/server");

const argv = minimist(process.argv.slice(2), {boolean: ["help", "version", "localControl", "server", "editor", "multiDoc"]});

// Since our current development pattern uses npm as its package repository, we treat the nearest ancestor directory with a package.json (inclusive) as the directory's "root".
function findRoot(root) {
  var pkg;
  root = root.split(path.sep);
  while(!pkg && root.length > 1) {
    var cur = root.join(path.sep);
    if(fs.existsSync(path.join(cur, "package.json"))) {
      return cur;
    }
    root.pop();
  }
}


var port = argv["port"] || process.env.PORT || 8080;
var runtimeOwner = argv["server"] ? Owner.server : Owner.client;
var controlOwner = argv["localControl"] ? Owner.client : Owner.server;
var editor = argv["editor"] || false;
var multiDoc = argv["multiDoc"] || false;
var filepath = argv["_"][0];
var internal = false;

var root = findRoot(process.cwd());
var eveRoot = findRoot(__dirname);

if(argv["help"]) {
  let pkg = require(path.join(eveRoot, "package.json"));
  console.log(`
    Eve ${pkg.version}

    Usage: eve [flags] [file]

    --help          Display this message.
    --version       Display installed version and exit.
    --server        Execute code on the server rather than the client.
    --editor        Display the editor (default if no file is specified).
    --port <number> Change the port the Eve server listens to (default 8080).
    --localControl  Entirely disable server interaction. File changes will be
                    stored in localStorage.

    If the Eve binary is run in a project directory (a directory containing a
    package.json file), it will use that directory as your workspace. Otherwise
    Eve will use the built-in examples workspace.

    If a file is provided, Eve will run it in application-only mode unless the
    --editor flag is supplied.

    Please refer questions and comments to the mailing list:
    https://groups.google.com/forum/#!forum/eve-talk

    Please report bugs via GH issues:
    https://github.com/witheve/eve/issues
`);
  process.exit(0);
}
if(argv["version"]) {
  let pkg = require(path.join(eveRoot, "package.json"));
  console.log(pkg.version);
  process.exit(0);
}


// If we're executing within the eve module/repo, we're running internally and should expose our examples, src, etc.
// This should be handled down the road by some sort of a manifest in conjunction with the `root` rather than hardcoding.
if(root === eveRoot) internal = true;
else if(!root) {
  internal = true;
  // We shouldn't (and when globally installed, *can't*) taint the internal examples when running as an installed binary.
  // @TODO: In the future we should have a more flexible solution that can copy out the examples into your current workspace when edited.
  controlOwner = Owner.client;
}


// If we're not given an explicit filepath to run, assume the user wanted the editor (rather than a blank page).
// Similarly, if we're running internally, send the user over to the quickstart, since they're likely testing the waters.
if(!filepath) {
  editor = true;
  if(internal) filepath = eveRoot + "/" + "examples/quickstart.eve";
} else {
  filepath = path.resolve(filepath);
  if(process.platform.indexOf("win") === 0) {
    filepath = filepath.replace(/\\/g, "/");
  }
}

let mode = Mode.workspace;
if(filepath && !editor) mode = Mode.file

var opts = {internal: internal, runtimeOwner: runtimeOwner, controlOwner: controlOwner, editor: editor, port: port, path: filepath, internal: internal, root: root, eveRoot: eveRoot, mode: mode, multiDoc: multiDoc};
config.init(opts);

server.run(opts);


================================================
FILE: circle.yml
================================================
machine:
  node:
    version: 7.4.0


================================================
FILE: docker-compose.yml
================================================
eve:
  build: .
  ports:
    - 18080:8080

================================================
FILE: index.html
================================================
<html>
  <head>
    <title>Eve</title>
    <link rel="stylesheet" type="text/css" href="assets/css/codemirror.css">
    <link rel="stylesheet" type="text/css" href="assets/css/simplescrollbars.css">
    <link rel="stylesheet" type="text/css" href="assets/css/ionicons.min.css">

    <style id="app-styles"></style>

    <link rel="stylesheet" type="text/css" href="assets/css/base.css">
    <link rel="stylesheet" type="text/css" href="assets/css/trace.css">
    <link href="assets/favicon.png" rel="icon" type="image/png" />
  </head>
  <body>
    <script type="text/javascript" src="build/watchers.js"></script>
    <script type="text/javascript" src="src/system.js"></script>
    <script type="text/javascript" src="src/systemJSConfig.js"></script>

    <script>
      SystemJS.import("/build/src/bootstrap");
    </script>

    <!-- PRODUCTION ANALYTICS -->
  </body>
</html>


================================================
FILE: package.json
================================================
{
  "name": "witheve",
  "version": "0.3.0-preview5",
  "description": "Programming designed for humans",
  "keywords": [
    "language",
    "ide",
    "relational",
    "database",
    "dataflow"
  ],
  "homepage": "http://witheve.com",
  "repository": {
    "type": "git",
    "url": "https://github.com/witheve/Eve"
  },
  "bugs": {
    "url": "https://github.com/witheve/Eve/issues"
  },
  "license": "Apache-2.0",
  "engines": {
    "node": ">=7.4.0"
  },
  "main": "build/src/index.js",
  "types": "build/src/index.d.ts",
  "scripts": {
    "build": "tsc",
    "postinstall": "tsc",
    "prepublish": "tsc",
    "test": "node build/test/all.js | faucet",
    "start": "echo 'Please download the eve-starter repository to begin using Eve <https://github.com/witheve/eve-starter>.'"
  },
  "dependencies": {
    "@types/commonmark": "^0.22.29",
    "@types/dateformat": "^1.0.1",
    "@types/node": "^6.0.41",
    "@types/tape": "^4.2.28",
    "@types/uuid": "^2.0.29",
    "chevrotain": "0.28.2",
    "commonmark": "^0.27.0",
    "dateformat": "^2.0.0",
    "express": "^4.14.0",
    "falafel": "^2.0.0",
    "javascript-natural-sort": "^0.7.1",
    "setimmediate": "^1.0.5",
    "typescript": "^2.1.4",
    "uuid": "^3.0.1"
  },
  "devDependencies": {
    "faucet": "0.0.1",
    "tape": "^4.6.0"
  }
}


================================================
FILE: src/bootstrap.ts
================================================
import "setimmediate";
import {Program} from "./runtime/dsl2";
import * as testUtil from "../test/util";
import "./parser/parser";

// let assert = {};
// function verify(assert:any, prog:Program, ins:any[], outs:any[]) {
//   prog.test(prog.nextTransactionId, ins);
// }

// function verifyIO(assert:any, progName:string, inputString:string, expecteds:testUtil.EAVRCTuple[][]) {
//   let inputs = testUtil.createInputs(inputString);
//   for(let input of inputs) {
//     prog.test(prog.nextTransactionId, input);
//     console.groupCollapsed("Expected");
//     console.info(testUtil.pprint(expecteds));
//     console.groupEnd();
//   }
// }

// let prog = new Program("test");

// import "./programs/flappy";
// import "./programs/compiler";
// import "./programs/hover";
// import "./programs/canvas-demo";
// import "./programs/shape-demo";
// import "./programs/ui-demo";
// import "./programs/editor-demo";


================================================
FILE: src/index.ts
================================================
export {Watcher, Program, appendAsEAVs, RawEAV, RawEAVC, RawValue, RawMap, RawRecord, createId, EAVDiffs, Diffs} from "./watchers/watcher";
export {parseDoc} from "./parser/parser";

export var watcherPath = "./build/src/watchers";
import * as watchers from "./watchers/index";
export {watchers};


================================================
FILE: src/loadWorker.js
================================================
//-------------------------------------------------------------------
// Web worker initialization
//-------------------------------------------------------------------

// We need to import uuid and commonmark before systemJS since the config tries
// to read their global objects
importScripts("/build/src/uuid.js", "/build/src/commonmark.js", "/build/src/system.js", "/build/src/systemJSConfig.js");

// while we're loading stuff in using systemJS we need to queue any messages
// we may get from the browser
let queue = [];

// We set an initial onmessage here that just adds messages to the queue,
// we'll override this with a real on message once the webworker code is loaded
onmessage = function(event) {
  queue.push(event);
}

SystemJS.import("runtime/webworker").then(function(worker) {
  onmessage = worker.onmessage;
  for(let queued of queue) {
    onmessage(queued);
  }
});



================================================
FILE: src/microReact.ts
================================================
declare var Velocity:any;

export interface Handler<T extends Event> {
  (evt:T, elem:uElement): void
}
export interface RenderHandler {
  (node:HTMLElement, elem:uElement): void
}

export interface uElement {
  t?:string
  c?:string
  id?:string
  parent?:string
  children?:uElement[]
  ix?:number
  key?:string
  dirty?:boolean
  semantic?:string
  tween?: any
  enter?: any
  leave?: any
  debug?:any

  // Content
  contentEditable?:boolean
  checked?:boolean
  draggable?:boolean
  spellcheck?:boolean
  href?:string
  src?:string
  data?:any
  download?:string
  allowfullscreen?:boolean
  placeholder?:string
  selected?:boolean
  tabindex?:number
  text?:string
  strictText?: boolean
  type?:string
  value?:string
  dangerouslySetInnerHTML?:string
  target?:string

  style?: string,

  // Styles (Structure)
  flex?:number|string
  left?:number|string
  top?:number|string
  width?:number|string
  height?:number|string
  textAlign?:string
  transform?:string
  verticalAlign?:string
  zIndex?:number

  // Styles (Aesthetic)
  backgroundColor?:string
  backgroundImage?:string
  border?:string
  borderColor?:string
  borderWidth?:number|string
  borderRadius?:number|string
  color?:string
  colspan?:number
  fontFamily?:string
  fontSize?:string

  opacity?:number

  // Svg
  svg?:boolean
  x?:number|string
  y?:number|string
  dx?:number|string
  dy?:number|string
  cx?:number|string
  cy?:number|string
  r?:number|string
  d?:number|string
  fill?:string
  stroke?:string
  strokeWidth?:string
  startOffset?:number|string
  textAnchor?:string
  viewBox?:string
  xlinkhref?:string

  // Events
  dblclick?:Handler<MouseEvent>
  click?:Handler<MouseEvent>
  contextmenu?:Handler<MouseEvent>
  mousedown?:Handler<MouseEvent>
  mousemove?:Handler<MouseEvent>
  mouseup?:Handler<MouseEvent>
  mouseover?:Handler<MouseEvent>
  mouseout?:Handler<MouseEvent>
  mouseleave?:Handler<MouseEvent>
  mousewheel?:Handler<MouseEvent>
  dragover?:Handler<MouseEvent>
  dragstart?:Handler<MouseEvent>
  dragend?:Handler<MouseEvent>
  drag?:Handler<MouseEvent>
  drop?:Handler<MouseEvent>
  scroll?:Handler<MouseEvent>
  focus?:Handler<FocusEvent>
  blur?:Handler<FocusEvent>
  input?:Handler<Event>
  change?:Handler<Event>
  keyup?:Handler<KeyboardEvent>
  keydown?:Handler<KeyboardEvent>
  cut?:Handler<KeyboardEvent>
  copy?:Handler<KeyboardEvent>
  paste?:Handler<KeyboardEvent>

  postRender?:RenderHandler

  [attr:string]: any
}

function now() {
  if(window.performance) {
    return window.performance.now();
  }
  return (new Date()).getTime();
}

function shallowEquals(a:any, b:any) {
  if(a === b) return true;
  if(!a || !b) return false;
  for(var k in a) {
    if(a[k] !== b[k]) return false;
  }
  for(var k in b) {
    if(b[k] !== a[k]) return false;
  }
  return true;
}

function postAnimationRemove(elements:Element[]) {
  for(let elem of elements) {
    if(elem.parentNode) elem.parentNode.removeChild(elem);
  }
}

export class Renderer {
  // @TODO: A more performant implementation would have a way of rendering subtrees and just have a lambda Renderer to compile into
  static _compileRenderer:{[id:string]: Renderer} = {};
  static compile(elem:uElement) {
    if(!elem.id) throw new Error("Cannot compile element with id " + elem.id);
    let renderer = Renderer._compileRenderer[elem.id];
    if(!renderer) renderer = Renderer._compileRenderer[elem.id] = new Renderer();
    renderer.render([elem]);
    return renderer.elementCache[elem.id];
  }

  content: HTMLElement;
  elementCache: {[id:string]: HTMLElement|undefined};
  prevTree:{[id:string]: uElement};
  tree:{[id:string]: uElement};
  postRenders: uElement[];
  lastDiff: {adds: string[], updates: {}};
  queued: boolean;
  handleEvent: (any);
  constructor() {
    this.content = document.createElement("div");
    this.content.className = "__root";
    this.elementCache = { "__root": this.content };
    this.prevTree = {};
    this.tree = {};
    this.postRenders = [];
    this.lastDiff = {adds: [], updates: {}};
    var self = this;
    this.handleEvent = function handleEvent(e: Event) {
      var id = ((e.currentTarget || e.target) as any)["_id"];
      var elem = self.tree[id];
      if (!elem) return;
      var handler = elem[e.type];
      if (handler) { handler(e, elem); }
    };
  }
  reset() {
    this.prevTree = this.tree;
    this.tree = {};
    this.postRenders = [];
  }

  domify() {
    var fakePrev:uElement = {}; //create an empty object once instead of every instance of the loop
    var elements = this.tree;
    var prevElements = this.prevTree;
    var diff = this.lastDiff;
    var adds = diff.adds;
    var updates:any = diff.updates;
    var elemKeys = Object.keys(updates);
    var elementCache = this.elementCache;
    var tempTween:any = {};

    //Create all the new elements to ensure that they're there when they need to be
    //parented
    for(var i = 0, len = adds.length; i < len; i++) {
      var id = adds[i];
      var cur = elements[id]!;
      var div: any;
      if (cur.svg) {
        div = document.createElementNS("http://www.w3.org/2000/svg", cur.t || "rect");
      } else {
        div = document.createElement(cur.t || "div");
      }
      div._id = id;
      elementCache[id] = div;
      if(cur.enter) {
        if(cur.enter.delay) {
          cur.enter.display = "auto";
          div.style.display = "none";
        }

        Velocity(div, cur.enter, cur.enter);

      }
    }

    for(var i = 0, len = elemKeys.length; i < len; i++) {
      var id = elemKeys[i];
      var cur = elements[id]!;
      var prev = prevElements[id] || fakePrev;
      var type:any = updates[id];
      var div;
      if(type === "replaced") {
        let me = elementCache[id]!;
        if (me.parentNode) me.parentNode.removeChild(me);
        if (cur.svg) {
          div = document.createElementNS("http://www.w3.org/2000/svg", cur.t || "rect");
        } else {
          div = document.createElement(cur.t || "div");
        }
        prev = fakePrev;
        div._id = id;
        elementCache[id] = div;
      } else if (type === "removed") {
        //NOTE: Batching the removes such that you only remove the parent
        //didn't actually make this faster surprisingly. Given that this
        //strategy is much simpler and there's no noticable perf difference
        //we'll just do the dumb thing and remove all the children one by one.
        let me = elementCache[id]!
        if(prev.leave) {
          prev.leave.complete = postAnimationRemove;
          if(prev.leave.absolute) {
            me.style.position = "absolute";
          }
          Velocity(me, prev.leave, prev.leave);
        }
        else if(me.parentNode) me.parentNode.removeChild(me);
        elementCache[id] = undefined;
        continue;
      } else {
        div = elementCache[id];
      }

      var style = div.style;
      if(cur.c !== prev.c) div.className = cur.c;
      if(cur.draggable !== prev.draggable) div.draggable = cur.draggable === undefined ? null : "true";
      if(cur.spellcheck !== prev.spellcheck) div.setAttribute("spellcheck", cur.spellcheck);
      if(cur.contentEditable !== prev.contentEditable) div.contentEditable = cur.contentEditable !== undefined ? JSON.stringify(cur.contentEditable) : "inherit";
      if(cur.colspan !== prev.colspan) div.colSpan = cur.colspan;
      if(cur.placeholder !== prev.placeholder) div.setAttribute("placeholder", cur.placeholder);
      if(cur.selected !== prev.selected) div.selected = cur.selected;
      if((cur.value !== prev.value || cur.strictText) && div.value !== cur.value) div.value = cur.value;
      if(cur.t === "input" && cur.type !== prev.type) div.type = cur.type;
      if(cur.t === "input" && cur.checked !== prev.checked) div.checked = cur.checked;
      if((cur.text !== prev.text || cur.strictText) && div.textContent !== cur.text) div.textContent = cur.text === undefined ? "" : cur.text;
      if(cur.tabindex !== prev.tabindex) div.setAttribute("tabindex", cur.tabindex);
      if(cur.href !== prev.href) div.setAttribute("href", cur.href);
      if(cur.src !== prev.src) div.setAttribute("src", cur.src);
      if(cur.target !== prev.target) div.setAttribute("target", cur.target);
      if(cur.data !== prev.data) div.setAttribute("data", cur.data);
      if(cur.download !== prev.download) div.setAttribute("download", cur.download);
      if(cur.allowfullscreen !== prev.allowfullscreen) div.setAttribute("allowfullscreen", cur.allowfullscreen);

      // animateable properties
      var tween = cur.tween || tempTween;
      if(cur.flex !== prev.flex) {
        if(tween.flex) tempTween.flex = cur.flex;
        else style.flex = cur.flex === undefined ? "" : cur.flex;
      }
      if(cur.left !== prev.left) {
          if(tween.left) tempTween.left = cur.left;
          else style.left = cur.left === undefined ? "" : cur.left;
      }
      if(cur.top !== prev.top) {
        if(tween.top) tempTween.top = cur.top;
        else style.top = cur.top === undefined ? "" : cur.top;
      }
      if(cur.height !== prev.height) {
        if(tween.height) tempTween.height = cur.height;
        else style.height = cur.height === undefined ? "auto" : cur.height;
      }
      if(cur.width !== prev.width) {
        if(tween.width) tempTween.width = cur.width;
        else style.width = cur.width === undefined ? "auto" : cur.width;
      }
      if(cur.zIndex !== prev.zIndex) {
        if(tween.zIndex) tempTween.zIndex = cur.zIndex;
        else style.zIndex = cur.zIndex;
      }
      if(cur.backgroundColor !== prev.backgroundColor) {
        if(tween.backgroundColor) tempTween.backgroundColor = cur.backgroundColor;
        else style.backgroundColor = cur.backgroundColor || "transparent";
      }
      if(cur.borderColor !== prev.borderColor) {
        if(tween.borderColor) tempTween.borderColor = cur.borderColor;
        else style.borderColor = cur.borderColor || "none";
      }
      if(cur.borderWidth !== prev.borderWidth) {
        if(tween.borderWidth) tempTween.borderWidth = cur.borderWidth;
        else style.borderWidth = cur.borderWidth || 0;
      }
      if(cur.borderRadius !== prev.borderRadius) {
        if(tween.borderRadius) tempTween.borderRadius = cur.borderRadius;
        else style.borderRadius = (cur.borderRadius || 0) + "px";
      }
      if(cur.opacity !== prev.opacity) {
        if(tween.opacity) tempTween.opacity = cur.opacity;
        else style.opacity = cur.opacity === undefined ? 1 : cur.opacity;
      }
      if(cur.fontSize !== prev.fontSize) {
        if(tween.fontSize) tempTween.fontSize = cur.fontSize;
        else style.fontSize = cur.fontSize;
      }
      if(cur.color !== prev.color) {
        if(tween.color) tempTween.color = cur.color;
        else style.color = cur.color || "inherit";
      }

      let animKeys = Object.keys(tempTween);
      if(animKeys.length) {
        Velocity(div, tempTween, tween);
        tempTween = {};
      }

      // non-animation style properties
      if(cur.backgroundImage !== prev.backgroundImage) style.backgroundImage = `url('${cur.backgroundImage}')`;
      if(cur.border !== prev.border) style.border = cur.border || "none";
      if(cur.textAlign !== prev.textAlign) {
        style.alignItems = cur.textAlign;
        if(cur.textAlign === "center") {
          style.textAlign = "center";
        } else if(cur.textAlign === "flex-end") {
          style.textAlign = "right";
        } else {
          style.textAlign = "left";
        }
      }
      if(cur.verticalAlign !== prev.verticalAlign) style.justifyContent = cur.verticalAlign;
      if(cur.fontFamily !== prev.fontFamily) style.fontFamily = cur.fontFamily || "inherit";
      if(cur.transform !== prev.transform) style.transform = cur.transform || "none";
      if(cur.style !== prev.style) div.setAttribute("style", cur.style);

      if(cur.dangerouslySetInnerHTML !== prev.dangerouslySetInnerHTML) div.innerHTML = cur.dangerouslySetInnerHTML;

      // debug/programmatic properties
      if(cur.semantic !== prev.semantic) div.setAttribute("data-semantic", cur.semantic);
      if(cur.debug !== prev.debug) div.setAttribute("data-debug", cur.debug);

      // SVG properties
      if(cur.svg) {
        if(cur.fill !== prev.fill) div.setAttributeNS(null, "fill", cur.fill);
        if(cur.stroke !== prev.stroke) div.setAttributeNS(null, "stroke", cur.stroke);
        if(cur.strokeWidth !== prev.strokeWidth) div.setAttributeNS(null, "stroke-width", cur.strokeWidth);
        if(cur.d !== prev.d) div.setAttributeNS(null, "d", cur.d);
        if(cur.c !== prev.c) div.setAttributeNS(null, "class", cur.c);
        if(cur.x !== prev.x)  div.setAttributeNS(null, "x", cur.x);
        if(cur.y !== prev.y) div.setAttributeNS(null, "y", cur.y);
        if(cur.dx !== prev.dx)  div.setAttributeNS(null, "dx", cur.dx);
        if(cur.dy !== prev.dy) div.setAttributeNS(null, "dy", cur.dy);
        if(cur.cx !== prev.cx)  div.setAttributeNS(null, "cx", cur.cx);
        if(cur.cy !== prev.cy) div.setAttributeNS(null, "cy", cur.cy);
        if(cur.r !== prev.r) div.setAttributeNS(null, "r", cur.r);
        if(cur.height !== prev.height) div.setAttributeNS(null, "height", cur.height);
        if(cur.width !== prev.width)  div.setAttributeNS(null, "width", cur.width);
        if(cur.xlinkhref !== prev.xlinkhref)  div.setAttributeNS('http://www.w3.org/1999/xlink', "href", cur.xlinkhref);
        if(cur.startOffset !== prev.startOffset) div.setAttributeNS(null, "startOffset", cur.startOffset);
        if(cur.id !== prev.id) div.setAttributeNS(null, "id", cur.id);
        if(cur.viewBox !== prev.viewBox) div.setAttributeNS(null, "viewBox", cur.viewBox);
        if(cur.transform !== prev.transform) div.setAttributeNS(null, "transform", cur.transform);
        if(cur.draggable !== prev.draggable) div.setAttributeNS(null, "draggable", cur.draggable);
        if(cur.textAnchor !== prev.textAnchor) div.setAttributeNS(null, "text-anchor", cur.textAnchor);
      }

      //events
      if(cur.dblclick !== prev.dblclick) div.ondblclick = cur.dblclick !== undefined ? this.handleEvent : undefined;
      if(cur.click !== prev.click) div.onclick = cur.click !== undefined ? this.handleEvent : undefined;
      if(cur.contextmenu !== prev.contextmenu) div.oncontextmenu = cur.contextmenu !== undefined ? this.handleEvent : undefined;
      if(cur.mousedown !== prev.mousedown) div.onmousedown = cur.mousedown !== undefined ? this.handleEvent : undefined;
      if(cur.mousemove !== prev.mousemove) div.onmousemove = cur.mousemove !== undefined ? this.handleEvent : undefined;
      if(cur.mouseup !== prev.mouseup) div.onmouseup = cur.mouseup !== undefined ? this.handleEvent : undefined;
      if(cur.mouseover !== prev.mouseover) div.onmouseover = cur.mouseover !== undefined ? this.handleEvent : undefined;
      if(cur.mouseout !== prev.mouseout) div.onmouseout = cur.mouseout !== undefined ? this.handleEvent : undefined;
      if(cur.mouseleave !== prev.mouseleave) div.onmouseleave = cur.mouseleave !== undefined ? this.handleEvent : undefined;
      if(cur.mousewheel !== prev.mousewheel) div.onmouseheel = cur.mousewheel !== undefined ? this.handleEvent : undefined;
      if(cur.dragover !== prev.dragover) div.ondragover = cur.dragover !== undefined ? this.handleEvent : undefined;
      if(cur.dragstart !== prev.dragstart) div.ondragstart = cur.dragstart !== undefined ? this.handleEvent : undefined;
      if(cur.dragend !== prev.dragend) div.ondragend = cur.dragend !== undefined ? this.handleEvent : undefined;
      if(cur.drag !== prev.drag) div.ondrag = cur.drag !== undefined ? this.handleEvent : undefined;
      if(cur.drop !== prev.drop) div.ondrop = cur.drop !== undefined ? this.handleEvent : undefined;
      if(cur.scroll !== prev.scroll) div.onscroll = cur.scroll !== undefined ? this.handleEvent : undefined;
      if(cur.focus !== prev.focus) div.onfocus = cur.focus !== undefined ? this.handleEvent : undefined;
      if(cur.blur !== prev.blur) div.onblur = cur.blur !== undefined ? this.handleEvent : undefined;
      if(cur.input !== prev.input) div.oninput = cur.input !== undefined ? this.handleEvent : undefined;
      if(cur.change !== prev.change) div.onchange = cur.change !== undefined ? this.handleEvent : undefined;
      if(cur.keyup !== prev.keyup) div.onkeyup = cur.keyup !== undefined ? this.handleEvent : undefined;
      if(cur.keydown !== prev.keydown) div.onkeydown = cur.keydown !== undefined ? this.handleEvent : undefined;
      if(cur.cut !== prev.cut) div.oncut = cur.cut !== undefined ? this.handleEvent : undefined;
      if(cur.copy !== prev.copy) div.oncopy = cur.copy !== undefined ? this.handleEvent : undefined;
      if(cur.paste !== prev.paste) div.onpaste = cur.paste !== undefined ? this.handleEvent : undefined;

      if(type === "added" || type === "replaced" || type === "moved") {
        var parentEl:any = elementCache[cur.parent!];
        if(parentEl) {
          if(cur.ix! >= parentEl.children.length) {
            parentEl.appendChild(div);
          } else {
            parentEl.insertBefore(div, parentEl.children[cur.ix!]);
          }
        }
      }
    }
  }

  diff() {
    var a = this.prevTree;
    var b = this.tree;
    var as = Object.keys(a);
    var bs = Object.keys(b);
    var updated:any = {};
    var adds = [];
    for(var i = 0, len = as.length; i < len; i++) {
      var id = as[i];
      var curA = a[id];
      var curB = b[id];
      if(curB === undefined) {
        updated[id] = "removed";
        continue;
      }
      if(curA.t !== curB.t) {
        updated[id] = "replaced";
        continue;
      }
      if(curA.ix !== curB.ix || curA.parent !== curB.parent) {
        updated[id] = "moved";
        continue;
      }

      if(!curB.dirty
          && curA.c === curB.c
          && curA.key === curB.key
          && curA.dangerouslySetInnerHTML === curB.dangerouslySetInnerHTML
          && curA.tabindex === curB.tabindex
          && curA.href === curB.href
          && curA.src === curB.src
          && curA.data === curB.data
          && curA.download === curB.download
          && curA.allowfullscreen === curB.allowfullscreen
          && curA.placeholder === curB.placeholder
          && curA.selected === curB.selected
          && curA.draggable === curB.draggable
          && curA.spellcheck === curB.spellcheck
          && curA.contentEditable === curB.contentEditable
          && curA.value === curB.value
          && curA.target === curB.target
          && curA.type === curB.type
          && curA.checked === curB.checked
          && curA.text === curB.text
          && curA.top === curB.top
          && curA.flex === curB.flex
          && curA.left === curB.left
          && curA.width === curB.width
          && curA.height === curB.height
          && curA.zIndex === curB.zIndex
          && curA.backgroundColor === curB.backgroundColor
          && curA.backgroundImage === curB.backgroundImage
          && curA.color === curB.color
          && curA.colspan === curB.colspan
          && curA.border === curB.border
          && curA.borderColor === curB.borderColor
          && curA.borderWidth === curB.borderWidth
          && curA.borderRadius === curB.borderRadius
          && curA.opacity === curB.opacity
          && curA.fontFamily === curB.fontFamily
          && curA.fontSize === curB.fontSize
          && curA.textAlign === curB.textAlign
          && curA.transform === curB.transform
          && curA.verticalAlign === curB.verticalAlign
          && curA.semantic === curB.semantic
          && curA.debug === curB.debug
          && curA.style === curB.style
          && (curB.svg === undefined || (
              curA.x === curB.x
              && curA.y === curB.y
              && curA.dx === curB.dx
              && curA.dy === curB.dy
              && curA.cx === curB.cx
              && curA.cy === curB.cy
              && curA.r === curB.r
              && curA.d === curB.d
              && curA.fill === curB.fill
              && curA.stroke === curB.stroke
              && curA.strokeWidth === curB.strokeWidth
              && curA.startOffset === curB.startOffset
              && curA.textAnchor === curB.textAnchor
              && curA.viewBox === curB.viewBox
              && curA.xlinkhref === curB.xlinkhref))
              ) {
        continue;
      }
      updated[id] = "updated";
    }
    for(var i = 0, len = bs.length; i < len; i++) {
      var id = bs[i];
      var curA = a[id];
      if(curA === undefined) {
        adds.push(id);
        updated[id] = "added";
        continue;
      }
    }
    this.lastDiff = {adds: adds, updates: updated};
    return this.lastDiff;
  }

  prepare(root:uElement) {
    var elemLen = 1;
    var tree = this.tree;
    var elements = [root];
    var elem:uElement;
    for(var elemIx = 0; elemIx < elemLen; elemIx++) {
      elem = elements[elemIx];
      if(elem.parent === undefined) elem.parent = "__root";
      if(elem.id === undefined) elem.id = "__root__" + elemIx;
      tree[elem.id] = elem;
      if(elem.postRender !== undefined) {
        this.postRenders.push(elem);
      }
      var children = elem.children;
      if(children !== undefined) {
        for(var childIx = 0, len = children.length; childIx < len; childIx++) {
          var child = children[childIx];
          if(child === undefined) continue;
          if(child.id === undefined) { child.id = elem.id + "__" + childIx; }
          if(child.ix === undefined) { child.ix = childIx; }
          if(child.parent === undefined) { child.parent = elem.id; }
          elements.push(child);
          elemLen++;
        }
      }
    }
    return tree;
  }

  postDomify() {
    var postRenders:any = this.postRenders;
    var diff:any = this.lastDiff.updates;
    var elementCache = this.elementCache;
    for(var i = 0, len = postRenders.length; i < len; i++) {
      var elem = postRenders[i];
      var id = elem.id!;
      if(diff[id] === "updated" || diff[id] === "added" || diff[id] === "replaced" || elem.dirty || diff[id] === "moved") {
        elem.postRender(elementCache[id]!, elem);
      }
    }
  }

  render(elems:uElement[]) {
      this.reset();
    // We sort elements by depth to allow them to be self referential.
    elems.sort((a, b) => (a.parent ? a.parent.split("__").length : 0) - (b.parent ? b.parent.split("__").length : 0));
    let start = now();
    for(let elem of elems) {
      let post = this.prepare(elem);

    }
    let prepare = now();
    let d = this.diff();
    let diff = now();
    this.domify();
    let domify = now();
    this.postDomify();
    let postDomify = now();
    let time = now() - start;
    if(time > 5) {
      console.log("slow render (> 5ms): ", time, {
        prepare: prepare - start,
        diff: diff - prepare,
        domify: domify - diff,
        postDomify: postDomify - domify
      });
    }
  }
}


================================================
FILE: src/parser/errors.ts
================================================
//--------------------------------------------------------------
// Errors
//--------------------------------------------------------------

import {exceptions, Token, EOF} from "chevrotain";
import * as parser from "./parser";

const SPAN_TYPE = "document_comment";

//--------------------------------------------------------------
// EveError
//--------------------------------------------------------------

export class EveError {
  static ID = 0;

  type = "error";
  id: string;
  blockId: string;
  message: string;
  start: number;
  stop: number;
  context?: any;
  spanId: string;

  constructor(blockId:string, start:number, stop:number, message:string, context?:any) {
    this.blockId = blockId;
    this.id = `${blockId}|error|${EveError.ID++}`;
    this.start = start;
    this.stop = stop;
    this.message = message;
    this.context = context;
  }

  injectSpan(spans:any, extraInfo:any) {
    spans.push(this.start, this.stop, SPAN_TYPE, this.id);
    extraInfo[this.id] = this;
  }
}

//--------------------------------------------------------------
// Parse error utils
//--------------------------------------------------------------

function regexGroup(str:string, regex:RegExp, group = 1) {
  var matches = [];
  var match;
  while (match = regex.exec(str)) {
    matches.push(match[group]);
  }
  return matches;
}

function className(thing:any) {
   var funcNameRegex = /function (.{1,})\(/;
   var results = (funcNameRegex).exec((thing).constructor.toString());
   return (results && results.length > 1) ? results[1] : "";
};

function lastTokenWithType(tokens:any, type:any) {
  let ix = tokens.length - 1;
  while(ix >= 0) {
    let cur = tokens[ix];
    if(cur instanceof type) {
      return cur;
    }
    ix--;
  }
}


//--------------------------------------------------------------
// Parse errors
//--------------------------------------------------------------

export function parserErrors(errors: any[], parseInfo: {blockId: string, blockStart: number, spans: any[], extraInfo: any, tokens: Token[]}) {
  let {blockId, blockStart, spans, extraInfo} = parseInfo;
  let normalized = [];
  let errorIx = 1;

  for(let error of errors) {
    let {token, context, message, resyncedTokens, name} = error;

    let eveError: EveError;
    if(name === "MismatchedTokenException") {
      eveError = mismatchedToken(error, parseInfo);
    } else if(name === "NotAllInputParsedException") {
      eveError = notAllInputParsed(error, parseInfo);
    } else {
      // console.log("UNHANDLED ERROR TYPE", name);
      let start = token.startOffset;
      let stop = token.startOffset + token.image.length;
      eveError = new EveError(blockId, start, stop, message, context);
    }

    eveError.injectSpan(spans, extraInfo);
    normalized.push(eveError);
  }
  return normalized;
}

//--------------------------------------------------------------
// MismatchedToken parse error
//--------------------------------------------------------------

const MismatchRegex = /-->\s*(.*?)\s*<--/gi;

function mismatchedToken(error:any, parseInfo:any) {
  const Pairs:any = {
    "CloseString": parser.OpenString,
    "CloseBracket": parser.OpenBracket,
    "CloseParen": parser.OpenParen,
  };

  let {blockId, blockStart, spans, extraInfo, tokens} = parseInfo;
  let {token, context, message, resyncedTokens, name} = error;

  let blockEnd = tokens[tokens.length - 1].endOffset + 1;

  let [expectedType, foundType] = regexGroup(message, MismatchRegex);

  let start, stop;

  if(token instanceof EOF) {
    let pair = Pairs[expectedType] as any;
    if(pair) {
      token = lastTokenWithType(tokens, pair);
      message = messages.unclosedPair(expectedType);
    } else {
      token = tokens[tokens.length - 1];
    }
    stop = blockEnd;
  }

  // We didn't find a matching pair, check if we're some other mistmatched bit of syntax.
  if(stop === undefined) {
    if(expectedType === "Tag") {
      if(token.label === "identifier") {
        message = messages.actionRawIdentifier(token.image);
      } else {
        message = messages.actionNonTag(token.image);
      }
    }
  }

  if(start === undefined) start = token.startOffset;
  if(stop === undefined) stop = token.startOffset + token.image.length;

  return new EveError(blockId, start, stop, message, context);
}

//--------------------------------------------------------------
// NotAllInputParsed parse error
//--------------------------------------------------------------

const NotAllInputRegex = /found:\s*([^\s]+)/gi;
const CloseChars:any = {")": true, "]": true};

function notAllInputParsed(error:any, parseInfo:any) {
  let {blockId, blockStart, spans, extraInfo, tokens} = parseInfo;
  let {token, context, message, resyncedTokens, name} = error;

  let blockEnd = tokens[tokens.length - 1].endOffset + 1;

  let [foundChar] = regexGroup(message, NotAllInputRegex);

  let start, stop;

  if(CloseChars[foundChar]) {
    message = messages.extraCloseChar(foundChar);
  } else {
    console.log("WEIRD STUFF AT THE END", context);
  }

  if(start === undefined) start = token.startOffset;
  if(stop === undefined) stop = token.startOffset + token.image.length;

  return new EveError(blockId, start, stop, message, context);
}

//--------------------------------------------------------------
// Build errors
//--------------------------------------------------------------

export function unprovidedVariableGroup(block:any, variables:any) {
  let {id, start: blockStart} = block;
  let found;
  for(let variable of variables) {
    if(!variable.generated) {
      found = variable;
      break;
    }
  }
  if(!found) {
    found = variables[0];
  }
  let [start, stop] = parser.nodeToBoundaries(found, blockStart);
  return new EveError(id, start, stop, messages.unprovidedVariable(found.name));
}

export function blankScan(block:any, scan:any) {
  let {id, start: blockStart} = block;
  let [start, stop] = parser.nodeToBoundaries(scan, blockStart);
  return new EveError(id, start, stop, messages.blankScan());
}

export function invalidLookupAction(block:any, action:any) {
  let {id, start: blockStart} = block;
  let [start, stop] = parser.nodeToBoundaries(action, blockStart);
  let missing = [];
  if(action.entity === undefined) missing.push("record");
  if(action.attribute === undefined) missing.push("attribute");
  if(action.value === undefined) missing.push("value");
  return new EveError(id, start, stop, messages.invalidLookupAction(missing));
}

export function unimplementedExpression(block:any, expression:any) {
  let {id, start: blockStart} = block;
  let [start, stop] = parser.nodeToBoundaries(expression, blockStart);
  return new EveError(id, start, stop, messages.unimplementedExpression(expression.op));
}

export function incompatabileConstantEquality(block:any, left:any, right:any) {
  let {id, start: blockStart} = block;
  let [start] = parser.nodeToBoundaries(left, blockStart);
  let [_, stop] = parser.nodeToBoundaries(right, blockStart);
  return new EveError(id, start, stop, messages.neverEqual(left.value, right.value));
}

export function incompatabileVariableToConstantEquality(block:any, variable:any, variableValue:any, constant:any) {
  let {id, start: blockStart} = block;
  let [start] = parser.nodeToBoundaries(variable, blockStart);
  let [_, stop] = parser.nodeToBoundaries(constant, blockStart);
  return new EveError(id, start, stop, messages.variableNeverEqual(variable, variableValue, constant.value));
}

export function incompatabileTransitiveEquality(block:any, variable:any, value:any) {
  let {id, start: blockStart} = block;
  let [start, stop] = parser.nodeToBoundaries(variable, blockStart);
  return new EveError(id, start, stop, messages.variableNeverEqual(variable, variable.constant, value));
}

export function unrecognisedFunctionAttribute(block:any, expression:any, attribute:any) {
  let {id, start: blockStart} = block;
  return new EveError(id, attribute.startOffset , attribute.endOffset, messages.unrecognisedFunctionAttribute(attribute.attribute, expression.op));
}

//--------------------------------------------------------------
// Messages
//--------------------------------------------------------------

const PairToName:any = {
  "CloseString": "quote",
  "CloseBracket": "bracket",
  "CloseParen": "paren",
  "]": "bracket",
  ")": "paren",
  "\"": "quote",
}

export var messages = {

  unclosedPair: (type:string) => `Looks like a close ${PairToName[type]} is missing`,

  extraCloseChar: (char:string) => `This close ${PairToName[char]} is missing an open ${PairToName[char]}`,

  unprovidedVariable: (varName:string) => `Nothing is providing a value for ${varName}`,
  unrecognisedFunctionAttribute: (attributeName:string, functionName:string) => `${attributeName} is not a recognised attribute for ${functionName}.`,

  unimplementedExpression: (op:string) => `There's no definition for the function ${op}`,

  blankScan: () => 'Lookup requires at least one attribute: record, attribute, value, or node',
  invalidLookupAction: (missing:string[]) => `Updating a lookup requires that record, attribute, and value all be provided. Looks like ${missing.join("and")} ${missing.length > 1 ? "are" : "is"} missing.`,

  neverEqual: (left:string, right:string) => `${left} can never equal ${right}`,
  variableNeverEqual: (variable:any, value:string, right:string) => `${variable.name} is equivalent to ${value}, which can't be equal to ${right}`,

  actionNonTag: (found:string) => `Looks like this should be a tag, try changing the ${found} to #${found}`,
  actionRawIdentifier: (found:string) => `I can only add/remove tags directly on a record. If you meant to add ${found} as an attribute to the record, try 'my-record.${found} += ${found}'; if you meant to add the #${found} tag, add #.`
};


================================================
FILE: src/parser/parser.ts
================================================
//-----------------------------------------------------------
// Parser
//-----------------------------------------------------------

import * as commonmark from "commonmark";
import * as chev from "chevrotain";
import {parserErrors, EveError} from "./errors";
var {Lexer, tokenMatcher} = chev;
export var Token = chev.Token;
import * as uuid from "uuid";

//-----------------------------------------------------------
// Utils
//-----------------------------------------------------------

function cleanString(str:string) {
  let cleaned = str
    .replace(/\\n/g, "\n")
    .replace(/\\t/g, "\t")
    .replace(/\\r/g, "\r")
    .replace(/\\"/g, "\"")
    .replace(/\\{/g, "{")
    .replace(/\\}/g, "}");
  return cleaned;
}

function toEnd(node:any) {
  if(node && node.tokenType !== undefined) {
    return node.endOffset! + 1;
  }
  return node.endOffset;
}

//-----------------------------------------------------------
// Markdown
//-----------------------------------------------------------

let markdownParser = new commonmark.Parser();

function parseMarkdown(markdown: string, docId: string) {
  let parsed = markdownParser.parse(markdown);
  let walker = parsed.walker();
  var cur;
  let tokenId = 0;
  var text = [];
  var extraInfo:any = {};
  var pos = 0;
  var lastLine = 1;
  var spans = [];
  var context = [];
  var blocks = [];
  while(cur = walker.next()) {
    let node = cur.node as any;
    if(cur.entering) {
      while(node.sourcepos && node.sourcepos[0][0] > lastLine) {
        lastLine++;
        pos++;
        text.push("\n");
      }
      if(node.type !== "text") {
        context.push({node, start: pos});
      }
      if(node.type == "text" || node.type === "code_block" || node.type == "code") {
        text.push(node.literal);
        pos += node.literal.length;
      }
      if(node.type == "softbreak") {
        text.push("\n");
        pos += 1;
        lastLine++;
        context.pop();
      }
      if(node.type == "code_block") {
        let spanId = `${docId}|block|${tokenId++}`;
        let start = context.pop()!.start;
        node.id = spanId;
        node.startOffset = start;
        let type = node.type;
        if(!(node as any)._isFenced) {
          type = "indented_code_block";
        } else {
          blocks.push(node);
        }
        spans.push(start, pos, node.type, spanId);
        lastLine = node.sourcepos[1][0] + 1;
      }
      if(node.type == "code") {
        let spanId = `${docId}|${tokenId++}`;
        let start = context.pop()!.start;
        spans.push(start, pos, node.type, spanId);
      }
    } else {
      let info = context.pop()!;
      if(node !== info.node) {
        throw new Error("Common mark is exiting a node that doesn't agree with the context stack");
      }
      if(node.type == "emph" || node.type == "strong" || node.type == "link") {
        let spanId = `${docId}|${tokenId++}`;
        spans.push(info.start, pos, node.type, spanId);
        if(node.type === "link") {
          extraInfo[spanId] = {destination: node._destination};
        }
      } else if(node.type == "heading" || node.type == "item") {
        let spanId = `${docId}|${tokenId++}`;
        spans.push(info.start, info.start, node.type, spanId);
        extraInfo[spanId] = {level: node._level, listData: node._listData};
      }
    }
  }
  return {text: text.join(""), spans, blocks, extraInfo};
}

//-----------------------------------------------------------
// Tokens
//-----------------------------------------------------------

const breakChars = "@#\\.,\\(\\)\\[\\]\\{\\}⦑⦒:\\\"";

// Markdown
export class DocContent extends Token { static PATTERN = /[^\n]+/; }
export class Fence extends Token {
  static PATTERN = /```|~~~/;
  static PUSH_MODE = "code";
}
export class CloseFence extends Token {
  static PATTERN = /```|~~~/;
  static POP_MODE = true;
}

// Comments
export class CommentLine extends Token { static PATTERN = /\/\/.*\n/; label = "comment"; static GROUP = "comments"; }

// Operators
export class Equality extends Token { static PATTERN = /:|=/; label = "equality"; }
export class Comparison extends Token { static PATTERN = />=|<=|!=|>|</; label = "comparison"; }
export class AddInfix extends Token { static PATTERN = /\+|-/; label = "infix"; }
export class MultInfix extends Token { static PATTERN = /\*|\//; label = "infix"; }
export class Merge extends Token { static PATTERN = /<-/; label = "merge"; }
export class Set extends Token { static PATTERN = /:=/; label = "set"; }
export class Mutate extends Token { static PATTERN = /\+=|-=/; label = "mutate"; }
export class Dot extends Token { static PATTERN = /\./; label = "dot"; }
export class Pipe extends Token { static PATTERN = /\|/; label = "pipe"; }

// Identifier
export class Identifier extends Token { static PATTERN = new RegExp(`([\\+-/\\*][^\\s${breakChars}]+|[^\\d${breakChars}\\+-/\\*][^\\s${breakChars}]*)(?=[^\\[])`); label = "identifier"; }
export class FunctionIdentifier extends Token { static PATTERN = new RegExp(`([\\+-/\\*][^\\s${breakChars}]+|[^\\d${breakChars}\\+-/\\*][^\\s${breakChars}]*)(?=\\[)`); label = "functionIdentifier"; }

// Keywords
export class Keyword extends Token {
    static PATTERN = Lexer.NA;
    static LONGER_ALT = Identifier;
}
export class Lookup extends Keyword { static PATTERN = /lookup(?=\[)/; label = "lookup"; }
export class Action extends Keyword { static PATTERN = /bind|commit/; label = "action"; }
export class Search extends Keyword { static PATTERN = /search/; label = "search"; }
export class If extends Keyword { static PATTERN = /if/; label = "if"; }
export class Else extends Keyword { static PATTERN = /else/; label = "else"; }
export class Then extends Keyword { static PATTERN = /then/; label = "then"; }
export class Not extends Keyword { static PATTERN = /not/; label = "not"; }

// Values
export class Bool extends Keyword { static PATTERN = /true|false/; label = "bool"; }
export class Num extends Token { static PATTERN = /-?\d+(\.\d+)?/; label = "num"; }
export class None extends Keyword { static PATTERN = /none/; label = "none"; }
export class Name extends Token { static PATTERN = /@/; label = "name"; }
export class Tag extends Token { static PATTERN = /#/; label = "tag"; }

// Delimiters
export class OpenBracket extends Token { static PATTERN = /\[/; label = "open-bracket"; }
export class CloseBracket extends Token { static PATTERN = /\]/; label = "close-bracket"; }
export class OpenParen extends Token { static PATTERN = /\(/; label = "open-paren"; }
export class CloseParen extends Token { static PATTERN = /\)/; label = "close-paren"; }

// Strings
export class StringChars extends Token { static PATTERN = /(\\.|{(?=[^{])|[^"\\{])+/; label = "string"; }
export class OpenString extends Token {
  static PATTERN = /"/;
  static PUSH_MODE = "string";
  label = "quote";
}
export class CloseString extends Token {
  static PATTERN = /"/;
  static POP_MODE = true;
  label = "quote";
}

// String Embeds
export class StringEmbedOpen extends Token {
  static PATTERN = /{{/;
  static PUSH_MODE = "code";
  label = "string-embed-open";
}
export class StringEmbedClose extends Token {
  static PATTERN = /}}/;
  static POP_MODE = true;
  label = "string-embed-close";
}

// Whitespace
export class WhiteSpace extends Token {
  static PATTERN = /\s+|,/;
  static GROUP = Lexer.SKIPPED;
}

//-----------------------------------------------------------
// Lexers
//-----------------------------------------------------------

let codeTokens: any[] = [
  CloseFence, WhiteSpace, CommentLine, OpenBracket, CloseBracket, OpenParen,
  CloseParen, StringEmbedClose, OpenString, Bool, Action, Set, Equality, Dot, Pipe, Merge,
  Mutate, Comparison, Num,  Search, Lookup, If, Else, Then,
  Not, None, Name, Tag, FunctionIdentifier, Identifier, AddInfix, MultInfix
];

let stringEmbedTokens: any[] = [StringEmbedClose].concat(codeTokens);

let LexerModes:any = {
  "doc": [WhiteSpace, Fence, DocContent],
  "code": codeTokens,
  "string": [CloseString, StringEmbedOpen, StringChars],
  // "stringEmbed": stringEmbedTokens,
};

let allTokens: any[] = codeTokens.concat([Fence, DocContent, CloseString, StringEmbedOpen, StringEmbedClose, StringChars]);

let EveDocLexer = new Lexer({modes: LexerModes, defaultMode: "doc"});
let EveBlockLexer = new Lexer({modes: LexerModes, defaultMode: "code"});

//-----------------------------------------------------------
// Parse Nodes
//-----------------------------------------------------------

export type NodeDependent = chev.IToken | ParseNode;

export interface ParseNode {
  type?: string
  id?: string
  startOffset?: number,
  endOffset?: number,
  from: NodeDependent[]
  [property: string]: any
}

export class ParseBlock {
  id: string;
  start: number;
  nodeId = 0;
  variables: {[name: string]: ParseNode} = {};
  equalities: any[] = [];
  scanLike: ParseNode[] = [];
  expressions: ParseNode[] = [];
  binds: ParseNode[] = [];
  commits: ParseNode[] = [];
  variableLookup: {[name: string]: ParseNode};
  links: string[] = [];
  tokens: chev.Token[];
  searchScopes: string[] = [];
  parent: ParseBlock | undefined;

  constructor(id:string, variableLookup?:any) {
    this.id = id;
    this.variableLookup = variableLookup || {};
  }

  toVariable(name:string, generated = false) {
    let variable = this.variableLookup[name];
    if(!variable) {
      this.variableLookup[name] = this.makeNode("variable", {name, from: [], generated});
    }
    variable = this.variables[name] = this.variableLookup[name];
    return {id: variable.id, type: "variable", name, from: [], generated};
  }

  addUsage(variable:any, usage:any) {
    let global = this.variableLookup[variable.name];
    global.from.push(usage)
    if(global.from.length === 1) {
      global.startOffset = usage.startOffset;
      global.endOffset = toEnd(usage);
    }
    variable.from.push(usage);
    variable.startOffset = usage.startOffset;
    variable.endOffset = toEnd(usage);
    this.links.push(variable.id, usage.id);
  }

  equality(a:any, b:any) {
    this.equalities.push([a, b]);
  }

  commit(node: ParseNode) {
    this.commits.push(node);
  }

  bind(node: ParseNode) {
    this.binds.push(node);
  }

  expression(node: ParseNode) {
    this.expressions.push(node);
  }

  scan(node: ParseNode) {
    this.scanLike.push(node);
  }

  makeNode(type:any, node: ParseNode) {
    if(!node.id) {
      node.id = `${this.id}|node|${this.nodeId++}`;
    }
    for(let from of node.from as any[]) {
      this.links.push(node.id, from.id);
    }
    if(node.from.length) {
      node.startOffset = node.from[0].startOffset;
      node.endOffset = toEnd(node.from[node.from.length - 1]);
    }
    node.type = type;
    return node;
  }

  addSearchScopes(scopes: string[]) {
    for(let scope of scopes) {
      if(this.searchScopes.indexOf(scope) === -1) {
        this.searchScopes.push(scope);
      }
    }
  }

  subBlock() {
    let neue = new ParseBlock(`${this.id}|sub${this.nodeId++}`, this.variableLookup);
    neue.parent = this;
    return neue;
  }
}


//-----------------------------------------------------------
// Parser
//-----------------------------------------------------------

export class Parser extends chev.Parser {
  customErrors: any[];
  block: ParseBlock;
  activeScopes: string[];
  currentAction: string;

  // Parser patterns
  doc: any;
  codeBlock: any;
  fencedBlock: any;
  section: any;
  searchSection: any;
  actionSection: any;
  value: any;
  bool: any;
  num: any;
  scopeDeclaration: any;
  name: any;
  statement: any;
  expression: any;
  attribute: any;
  attributeEquality: any;
  attributeComparison: any;
  attributeNot: any;
  attributeOperation: any;
  record: any;
  tag: any;
  functionRecord: any;
  notStatement: any;
  comparison: any;
  infix: any;
  attributeAccess: any;
  actionStatement: any;
  actionEqualityRecord: any;
  actionAttributeExpression: any;
  actionOperation: any;
  actionLookup: any;
  variable: any;
  recordOperation: any;
  ifExpression: any;
  ifBranch: any;
  elseIfBranch: any;
  elseBranch: any;
  multiplication: any;
  addition: any;
  infixValue: any;
  parenthesis: any;
  attributeMutator: any;
  singularAttribute: any;
  stringInterpolation: any;


  constructor(input:any) {
    super(input, allTokens, {});
    let self = this;
    let asValue = (node:any) => {
      if(node.type === "constant" || node.type === "variable" || node.type === "parenthesis") {
        return node;
      } else if(node.variable) {
        return node.variable;
      }
      throw new Error("Tried to get value of a node that is neither a constant nor a variable.\n\n" + JSON.stringify(node));
    }
    let ifOutputs = (expression:any) => {
      let outputs = [];
      if(expression.type === "parenthesis") {
        for(let item of expression.items) {
          outputs.push(asValue(item));
        }
      } else {
        outputs.push(asValue(expression));
      }
      return outputs;
    }

    let makeNode = (type:string, node:any) => {
      return self.block.makeNode(type, node);
    }

    let blockStack:any[] = [];
    let pushBlock = (blockId?:string) => {
      let block;
      let prev = blockStack[blockStack.length - 1];
      if(prev) {
        block = prev.subBlock();
      } else {
        block = new ParseBlock(blockId || "block");
      }
      blockStack.push(block);
      self.block = block;
      return block;
    }

    let popBlock = () => {
      let popped = blockStack.pop();
      self.block = blockStack[blockStack.length - 1];
      return popped;
    }

    //-----------------------------------------------------------
    // Doc rules
    //-----------------------------------------------------------

    self.RULE("doc", () => {
      let doc = {
        full: [] as any[],
        content: [] as any[],
        blocks: [] as any[],
      }
      self.MANY(() => {
        self.OR([
          {ALT: () => {
            let content = self.CONSUME(DocContent);
            doc.full.push(content);
            doc.content.push(content);
          }},
          {ALT: () => {
            let block : any = self.SUBRULE(self.fencedBlock);
            if(doc.content.length) {
              block.name = doc.content[doc.content.length - 1].image;
            } else {
              block.name = "Unnamed block";
            }
            doc.full.push(block);
            doc.blocks.push(block);
          }},
        ])
      });
      return doc;
    });

    self.RULE("fencedBlock", () => {
      self.CONSUME(Fence);
      let block = self.SUBRULE(self.codeBlock);
      let fence = self.CONSUME(CloseFence);
      return block;
    });

    //-----------------------------------------------------------
    // Blocks
    //-----------------------------------------------------------

    self.RULE("codeBlock", (blockId = "block") => {
      blockStack = [];
      let block = pushBlock(blockId);
      self.MANY(() => { self.SUBRULE(self.section) })
      return popBlock();
    })

    self.RULE("section", () => {
      return self.OR([
        {ALT: () => { return self.SUBRULE(self.searchSection) }},
        {ALT: () => { return self.SUBRULE(self.actionSection) }},
        {ALT: () => { return self.CONSUME(CommentLine); }},
      ]);
    });


    //-----------------------------------------------------------
    // Scope declaration
    //-----------------------------------------------------------

    self.RULE("scopeDeclaration", () => {
      let scopes:any[] = [];
      self.OR([
        {ALT: () => {
          self.CONSUME(OpenParen);
          self.AT_LEAST_ONE(() => {
            let name: any = self.SUBRULE(self.name);
            scopes.push(name.name);
          })
          self.CONSUME(CloseParen);
        }},
        {ALT: () => {
          self.AT_LEAST_ONE2(() => {
            let name: any = self.SUBRULE2(self.name);
            scopes.push(name.name);
          })
        }},
      ]);
      return scopes;
    });


    //-----------------------------------------------------------
    // Search section
    //-----------------------------------------------------------

    self.RULE("searchSection", () => {
      // @TODO fill in from
      let from:any[] = [];
      self.CONSUME(Search);
      let scopes:any = ["session"];
      self.OPTION(() => { scopes = self.SUBRULE(self.scopeDeclaration) })
      self.activeScopes = scopes;
      self.currentAction = "match";
      self.block.addSearchScopes(scopes);
      let statements:any[] = [];
      self.MANY(() => {
        let statement: any = self.SUBRULE(self.statement);
        if(statement) {
          statements.push(statement);
          statement.scopes = scopes;
        }
      });
      return makeNode("searchSection", {statements, scopes, from});
    });

    self.RULE("statement", () => {
      return self.OR([
        {ALT: () => { return self.SUBRULE(self.comparison); }},
        {ALT: () => { return self.SUBRULE(self.notStatement); }},
      ])
    });

    //-----------------------------------------------------------
    // Action section
    //-----------------------------------------------------------

    self.RULE("actionSection", () => {
      // @TODO fill in from
      let from:any[] = [];
      let action = self.CONSUME(Action).image;
      let actionKey = action;
      let scopes:any = ["session"];
      self.OPTION(() => { scopes = self.SUBRULE(self.scopeDeclaration) })
      self.activeScopes = scopes;
      self.currentAction = action!;
      let statements:any[] = [];
      self.MANY(() => {
        let statement = self.SUBRULE(self.actionStatement, [actionKey]) as any;
        if(statement) {
          statements.push(statement);
          statement.scopes = scopes;
        }
      });
      return makeNode("actionSection", {statements, scopes, from});
    });


    self.RULE("actionStatement", (actionKey) => {
      return self.OR([
        {ALT: () => {
          let record = self.SUBRULE(self.record, [false, actionKey, "+="]);
          return record;
        }},
        {ALT: () => { return self.SUBRULE(self.actionEqualityRecord, [actionKey]); }},
        {ALT: () => {
          let record = self.SUBRULE(self.actionOperation, [actionKey]);
          (self.block as any)[actionKey](record);
          return record;
        }},
        {ALT: () => { return self.SUBRULE(self.actionLookup, [actionKey]); }},
      ])
    });

    //-----------------------------------------------------------
    // Action operations
    //-----------------------------------------------------------

    self.RULE("actionOperation", (actionKey) => {
      return self.OR([
        {ALT: () => { return self.SUBRULE(self.recordOperation, [actionKey]) }},
        {ALT: () => { return self.SUBRULE(self.attributeOperation, [actionKey]) }},
      ]);
    });

    self.RULE("attributeOperation", (actionKey) => {
      let mutator = self.SUBRULE(self.attributeMutator) as any;
      let {attribute, parent} = mutator;
      return self.OR([
        {ALT: () => {
          let variable = self.block.toVariable(`${attribute.image}|${attribute.startLine}|${attribute.startColumn}`, true);
          let scan = makeNode("scan", {entity: parent, attribute: makeNode("constant", {value: attribute.image, from: [attribute]}), value: variable, scopes: self.activeScopes, from: [mutator]});
          self.block.addUsage(variable, scan);
          self.block.scan(scan);
          self.CONSUME(Merge);
          let record = self.SUBRULE(self.record, [true, actionKey, "+=", undefined, variable]) as any;
          record.variable = variable;
          record.action = "<-";
          return record;
        }},
        {ALT: () => {
          let op = self.CONSUME(Set);
          let none = self.CONSUME(None);
          return makeNode("action", {action: "erase", entity: asValue(parent), attribute: attribute.image, from: [mutator, op, none]});
        }},
        {ALT: () => {
          let op = self.CONSUME2(Set);
          let value = self.SUBRULE(self.infix);
          return makeNode("action", {action: op.image, entity: asValue(parent), attribute: attribute.image, value: asValue(value), from: [mutator, op, value]});
        }},
        {ALT: () => {
          let op = self.CONSUME3(Set);
          let value = self.SUBRULE2(self.record, [false, actionKey, "+=", parent]);
          return makeNode("action", {action: op.image, entity: asValue(parent), attribute: attribute.image, value: asValue(value), from: [mutator, op, value]});
        }},
        {ALT: () => {
          let variable = self.block.toVariable(`${attribute.image}|${attribute.startLine}|${attribute.startColumn}`, true);
          let scan = makeNode("scan", {entity: parent, attribute: makeNode("constant", {value: attribute.image, from: [attribute]}), value: variable, scopes: self.activeScopes, from: [mutator]});
          self.block.addUsage(variable, scan);
          self.block.scan(scan);
          let op = self.CONSUME(Mutate);
          let tag : any = self.SUBRULE(self.tag);
          return makeNode("action", {action: op.image, entity: variable, attribute: "tag", value: makeNode("constant", {value: tag.tag, from: [tag]}), from: [mutator, op, tag]});
        }},
        {ALT: () => {
          let op = self.CONSUME2(Mutate);
          let value: any = self.SUBRULE2(self.actionAttributeExpression, [actionKey, op.image, parent]);
          if(value.type === "record" && !value.extraProjection) {
            value.extraProjection = [parent];
          }
          if(value.type === "parenthesis") {
            let autoIndex = 0;
            for(let item of value.items) {
              if(item.type === "record" && !value.extraProjection) {
                item.extraProjection = [parent];
              }
              if(item.from[0] && item.from[0].type === "record") {
                let record = item.from[0];
                record.attributes.push(makeNode("attribute", {attribute: "eve-auto-index", value: makeNode("constant", {value: autoIndex, from: [record]}), from: [record]}));
                autoIndex++;
              }
            }
          }
          return makeNode("action", {action: op.image, entity: asValue(parent), attribute: attribute.image, value: asValue(value), from: [mutator, op, value]});
        }},
      ])
    });

    self.RULE("recordOperation", (actionKey) => {
      let variable = self.SUBRULE(self.variable) as any;
      return self.OR([
        {ALT: () => {
          let set = self.CONSUME(Set);
          let none = self.CONSUME(None);
          return makeNode("action", {action: "erase", entity: asValue(variable), from: [variable, set, none]});
        }},
        {ALT: () => {
          self.CONSUME(Merge);
          let record = self.SUBRULE(self.record, [true, actionKey, "+=", undefined, variable]) as any;
          record.needsEntity = true;
          record.action = "<-";
          return record;
        }},
        {ALT: () => {
          let op = self.CONSUME(Mutate);
          let tag : any = self.SUBRULE(self.tag);
          return makeNode("action", {action: op.image, entity: asValue(variable), attribute: "tag", value: makeNode("constant", {value: tag.tag, from: [tag]}), from: [variable, op, tag]});
        }},
      ])
    });

    self.RULE("actionLookup", (actionKey) => {
      let lookup = self.CONSUME(Lookup);
      let record: any = self.SUBRULE(self.record, [true]);
      let info: any = {};
      for(let attribute of record.attributes) {
        info[attribute.attribute] = attribute.value;
      }
      let actionType = "+=";
      self.OPTION(() => {
        self.CONSUME(Set);
        self.CONSUME(None);
        if(info["value"] !== undefined) {
          actionType = "-=";
        } else {
          actionType = "erase";
        }
      })
      let action = makeNode("action", {action: actionType, entity: info.record, attribute: info.attribute, value: info.value, node: info.node, scopes: self.activeScopes, from: [lookup, record]});
      (self.block as any)[actionKey](action);
      return action;
    });

    self.RULE("actionAttributeExpression", (actionKey, action, parent) => {
      return self.OR([
        {ALT: () => { return self.SUBRULE(self.record, [false, actionKey, action, parent]); }},
        {ALT: () => { return self.SUBRULE(self.infix); }},
      ])
    })

    self.RULE("actionEqualityRecord", (actionKey) => {
      let variable = self.SUBRULE(self.variable);
      self.CONSUME(Equality);
      let record : any = self.SUBRULE(self.record, [true, actionKey, "+="]);
      record.variable = variable;
      (self.block as any)[actionKey](record);
      return record;
    });

    //-----------------------------------------------------------
    // Record + attribute
    //-----------------------------------------------------------

    self.RULE("record", (noVar = false, blockKey = "scan", action = false, parent?, passedVariable?) => {
      let attributes:any[] = [];
      let start = self.CONSUME(OpenBracket);
      let from: NodeDependent[] = [start];
      let info: any = {attributes, action, scopes: self.activeScopes, from};
      if(parent) {
        info.extraProjection = [parent];
      }
      if(passedVariable) {
        info.variable = passedVariable;
        info.variable.nonProjecting = true;
      } else if(!noVar) {
        info.variable = self.block.toVariable(`record|${start.startLine}|${start.startColumn}`, true);
        info.variable.nonProjecting = true;
      }
      let nonProjecting = false;
      self.MANY(() => {
        self.OR([
          {ALT: () => {
            let attribute: any = self.SUBRULE(self.attribute, [false, blockKey, action, info.variable]);
            // Inline handles attributes itself and so won't return any attribute for us to add
            // to this object
            if(!attribute) return;

            if(attribute.constructor === Array) {
              for(let attr of attribute as any[]) {
                attr.nonProjecting = nonProjecting;
                attributes.push(attr);
                from.push(attr);
              }
            } else {
              attribute.nonProjecting = nonProjecting;
              attributes.push(attribute);
              from.push(attribute);
            }
          }},
          {ALT: () => {
            nonProjecting = true;
            let pipe = self.CONSUME(Pipe);
            from.push(pipe);
            return pipe;
          }},
        ]);
      })
      from.push(self.CONSUME(CloseBracket));
      let record : any = makeNode("record", info);
      if(!noVar) {
        self.block.addUsage(info.variable, record);
        (self.block as any)[blockKey](record);
      }
      return record;
    });

    self.RULE("attribute", (noVar, blockKey, action, recordVariable) => {
      return self.OR([
        {ALT: () => { return self.SUBRULE(self.attributeEquality, [noVar, blockKey, action, recordVariable]); }},
        {ALT: () => { return self.SUBRULE(self.attributeComparison); }},
        {ALT: () => { return self.SUBRULE(self.attributeNot, [recordVariable]); }},
        {ALT: () => { return self.SUBRULE(self.singularAttribute); }},
        {ALT: () => {
          let value: any = self.SUBRULE(self.value);
          let token = value.from[0];

          let message = "Value missing attribute";

          if (value.hasOwnProperty("value")) {
            message = `"${value.value}" needs to be labeled with an attribute`;
          }

          self.customErrors.push({
            message,
            name: "Unlabeled value",
            resyncedTokens: [],
            context: {
              ruleOccurrenceStack: [],
              ruleStack: []
            },
            token
          });
        }},
      ]);
    });

    self.RULE("singularAttribute", (forceGenerate) => {
      return self.OR([
        {ALT: () => {
          let tag : any = self.SUBRULE(self.tag);
          return makeNode("attribute", {attribute: "tag", value: makeNode("constant", {value: tag.tag, from: [tag]}), from: [tag]});
        }},
        {ALT: () => {
          let variable : any = self.SUBRULE(self.variable, [forceGenerate]);
          return makeNode("attribute", {attribute: variable.from[0].image, value: variable, from: [variable]});
        }},
      ]);
    });

    self.RULE("attributeMutator", () => {
      let scans:any[] = [];
      let entity:any, attribute:any, value:any;
      let needsEntity = true;
      let from:any[] = [];
      entity = self.SUBRULE(self.variable);
      let dot = self.CONSUME(Dot);
      from.push(entity, dot);
      self.MANY(() => {
        attribute = self.CONSUME(Identifier);
        from.push(attribute);
        from.push(self.CONSUME2(Dot));
        value = self.block.toVariable(`${attribute.image}|${attribute.startLine}|${attribute.startColumn}`, true);
        self.block.addUsage(value, attribute);
        let scopes = self.activeScopes;
        if(self.currentAction !== "match") {
          scopes = self.block.searchScopes;
        }
        let scan = makeNode("scan", {entity, attribute: makeNode("constant", {value: attribute.image, from: [value]}), value, needsEntity, scopes, from: [entity, dot, attribute]});
        self.block.scan(scan);
        needsEntity = false;
        entity = value;
      });
      attribute = self.CONSUME2(Identifier);
      from.push(attribute);
      return makeNode("attributeMutator", {attribute: attribute, parent: entity, from});
    });

    self.RULE("attributeAccess", () => {
      let scans:any[] = [];
      let entity:any, attribute:any, value:any;
      let needsEntity = true;
      entity = self.SUBRULE(self.variable);
      let parentId = entity.name;
      self.AT_LEAST_ONE(() => {
        let dot = self.CONSUME(Dot);
        attribute = self.CONSUME(Identifier);
        parentId = `${parentId}|${attribute.image}`;
        value = self.block.toVariable(parentId, true);
        self.block.addUsage(value, attribute);
        let scopes = self.activeScopes;
        if(self.currentAction !== "match") {
          scopes = self.block.searchScopes;
        }
        let scan = makeNode("scan", {entity, attribute: makeNode("constant", {value: attribute.image, from: [attribute]}), value, needsEntity, scopes, from: [entity, dot, attribute]});
        self.block.scan(scan);
        needsEntity = false;
        entity = value;
      });
      return value;
    });

    self.RULE("attributeEquality", (noVar, blockKey, action, parent) => {
      let attributes:any[] = [];
      let autoIndex = 1;
      let attributeNode:any;
      let attribute: any = self.OR([
        {ALT: () => {
          attributeNode = self.CONSUME(Identifier);
          return attributeNode.image;
        }},
        {ALT: () => {
          attributeNode = self.CONSUME(Num);
          return parseFloat(attributeNode.image) as any;
        }}
      ]);
      let equality = self.CONSUME(Equality);
      let result : any;
      self.OR2([
        {ALT: () => {
          result = self.SUBRULE(self.infix);
          // if the result is a parenthesis, we have to make sure that if there are sub-records
          // inside that they get eve-auto-index set on them and they also have the parent transfered
          // down to them. If we don't do this, we'll end up with children that are shared between
          // the parents instead of one child per parent.
          if(result.type === "parenthesis") {
            for(let item of result.items) {
              // this is a bit sad, but by the time we see the parenthesis, the records have been replaced
              // with their variables. Those variables are created from the record object though, so we can
              // check the from of the variable for a reference to the record.
              if(item.type === "variable" && item.from[0] && item.from[0].type === "record") {
                let record = item.from[0];
                // if we have a parent, we need to make sure it ends up part of our extraProjection set
                if(parent && !item.extraProjection) {
                  record.extraProjection = [parent];
                } else if(parent) {
                  record.extraProjection.push(parent);
                }
                // Lastly we need to add the eve-auto-index attribute to make sure this is consistent with the case
                // where we leave the parenthesis off and just put records one after another.
                record.attributes.push(makeNode("attribute", {attribute: "eve-auto-index", value: makeNode("constant", {value: autoIndex, from: [record]}), from: [record]}));
                autoIndex++;
              }
            }
          }
        }},
        {ALT: () => {
          result = self.SUBRULE(self.record, [noVar, blockKey, action, parent]);
          self.MANY(() => {
            autoIndex++;
            let record : any = self.SUBRULE2(self.record, [noVar, blockKey, action, parent]);
            record.attributes.push(makeNode("attribute", {attribute: "eve-auto-index", value: makeNode("constant", {value: autoIndex, from: [record]}), from: [record]}));
            attributes.push(makeNode("attribute", {attribute, value: asValue(record), from: [attributeNode, equality, record]}));
          })
          if(autoIndex > 1) {
            result.attributes.push(makeNode("attribute", {attribute: "eve-auto-index", value: makeNode("constant", {value: 1, from: [result]}), from: [result]}));
          }
        }},
      ]);
      attributes.push(makeNode("attribute", {attribute, value: asValue(result), from: [attributeNode, equality, result]}))
      return attributes;
    });

    self.RULE("attributeComparison", () => {
      let attribute = self.CONSUME(Identifier);
      let comparator = self.CONSUME(Comparison);
      let result = self.SUBRULE(self.expression);
      let variable = self.block.toVariable(`attribute|${attribute.startLine}|${attribute.startColumn}`, true);
      let expression = makeNode("expression", {op: `compare/${comparator.image}`, args: [asValue(variable), asValue(result)], from: [attribute, comparator, result]})
      self.block.addUsage(variable, expression);
      self.block.expression(expression);
      return makeNode("attribute", {attribute: attribute.image, value: variable, from: [attribute, comparator, expression]});
    });

    self.RULE("attributeNot", (recordVariable) => {
      let block = pushBlock();
      block.type = "not";
      let not = self.CONSUME(Not);
      let start = self.CONSUME(OpenParen);
      let attribute: any = self.OR([
        {ALT: () => { return self.SUBRULE(self.attributeComparison); }},
        {ALT: () => { return self.SUBRULE(self.singularAttribute, [true]); }},
      ]);
      let end = self.CONSUME(CloseParen);
      // we have to add a record for this guy
      let scan : any = makeNode("scan", {entity: recordVariable, attribute: makeNode("constant", {value: attribute.attribute, from: [attribute]}), value: attribute.value, needsEntity: true, scopes: self.activeScopes, from: [attribute]});
      block.variables[recordVariable.name] = recordVariable;
      block.scan(scan);
      block.from = [not, start, attribute, end];
      block.startOffset = not.startOffset;
      block.endOffset = toEnd(end);
      popBlock();
      self.block.scan(block);
      return;
    });

    //-----------------------------------------------------------
    // Name and tag
    //-----------------------------------------------------------

    self.RULE("name", () => {
      let at = self.CONSUME(Name);
      let name = self.CONSUME(Identifier);
      self.customErrors.push({message: `Databases have been deprecated, so @${name.image} has no meaning here`, name: "Database deprecation", resyncedTokens: [], context:{ruleOccurrenceStack: [], ruleStack: []}, token:name})
      return makeNode("name", {name: name.image, from: [at, name]});
    });

    self.RULE("tag", () => {
      let hash = self.CONSUME(Tag);
      let tag = self.CONSUME(Identifier);
      return makeNode("tag", {tag: tag.image, from: [hash, tag]});
    });

    //-----------------------------------------------------------
    // Function
    //-----------------------------------------------------------

    self.RULE("functionRecord", (): any => {
      let name = self.OR([
          {ALT: () => { return self.CONSUME(FunctionIdentifier); }},
          {ALT: () => { return self.CONSUME(Lookup); }}
      ]);
      let record: any = self.SUBRULE(self.record, [true]);
      if(name.image === "lookup") {
        let info: any = {};
        for(let attribute of record.attributes) {
          info[attribute.attribute] = attribute.value;
        }
        let scan = makeNode("scan", {entity: info.record, attribute: info.attribute, value: info.value, node: info.node, scopes: self.activeScopes, from: [name, record]});
        self.block.scan(scan);
        return scan;
      } else {
        let variable = self.block.toVariable(`return|${name.startLine}|${name.startColumn}`, true);
        let functionRecord = makeNode("functionRecord", {op: name.image, record, variable, from: [name, record]});
        self.block.addUsage(variable, functionRecord);
        self.block.expression(functionRecord);
        return functionRecord;
      }
    });

    //-----------------------------------------------------------
    // Comparison
    //-----------------------------------------------------------

    self.RULE("comparison", (nonFiltering) : any => {
      let left = self.SUBRULE(self.expression);
      let from = [left];
      let rights:any[] = [];
      self.MANY(() => {
        let comparator = self.OR([
          {ALT: () => { return self.CONSUME(Comparison); }},
          {ALT: () => { return self.CONSUME(Equality); }}
        ]);
        let value = self.OR2([
          {ALT: () => { return self.SUBRULE2(self.expression); }},
          {ALT: () => { return self.SUBRULE(self.ifExpression); }}
        ]);
        from.push(comparator, value);
        rights.push({comparator, value});
      })
      if(rights.length) {
        let expressions = [];
        let curLeft: any = left;
        for(let pair of rights) {
          let {comparator, value} = pair;
          let expression = null;
          // if this is a nonFiltering comparison, then we return an expression
          // with a variable for its return value
          if(nonFiltering) {
            let variable = self.block.toVariable(`comparison|${comparator.startLine}|${comparator.startColumn}`, true);
            expression = makeNode("expression", {variable, op: `compare/${comparator.image}`, args: [asValue(curLeft), asValue(value)], from: [curLeft, comparator, value]});
            self.block.addUsage(variable, expression);
            self.block.expression(expression);
          } else if(tokenMatcher(comparator, Equality)) {
            if(value.type === "choose" || value.type === "union") {
              value.outputs = ifOutputs(left);
              self.block.scan(value);
            } else if(value.type === "functionRecord" && curLeft.type === "parenthesis") {
              value.returns = curLeft.items.map(asValue);
              self.block.equality(asValue(value.returns[0]), asValue(value));
            } else if(curLeft.type === "parenthesis") {
              throw new Error("Left hand parenthesis without an if or function on the right");
            } else {
              self.block.equality(asValue(curLeft), asValue(value));
            }
          } else {
            expression = makeNode("expression", {op: `compare/${comparator.image}`, args: [asValue(curLeft), asValue(value)], from: [curLeft, comparator, value]});
            self.block.expression(expression);
          }
          curLeft = value;
          if(expression) {
            expressions.push(expression);
          }
        }
        return makeNode("comparison", {expressions, from});
      };
      return left;
    });

    //-----------------------------------------------------------
    // Special Forms
    //-----------------------------------------------------------

    self.RULE("notStatement", () => {
      let block = pushBlock();
      block.type = "not";
      let from: NodeDependent[] = [
        self.CONSUME(Not),
        self.CONSUME(OpenParen),
      ];
      self.MANY(() => {
        from.push(self.SUBRULE(self.statement) as ParseNode);
      });
      from.push(self.CONSUME(CloseParen));
      popBlock();
      block.from = from;
      block.startOffset = from[0].startOffset;
      block.endOffset = toEnd(from[from.length - 1]);
      self.block.scan(block);
      return;
    });

    //-----------------------------------------------------------
    // If ... then
    //-----------------------------------------------------------

    self.RULE("ifExpression", () => {
      let branches:any[] = [];
      let exclusive = false;
      let from = branches;
      branches.push(self.SUBRULE(self.ifBranch));
      self.MANY(() => {
        branches.push(self.OR([
          {ALT: () => { return self.SUBRULE2(self.ifBranch); }},
          {ALT: () => {
            exclusive = true;
            return self.SUBRULE(self.elseIfBranch);
          }},
        ]));
      });
      self.OPTION(() => {
        exclusive = true;
        branches.push(self.SUBRULE(self.elseBranch));
      });
      let expressionType = exclusive ? "choose" : "union";
      return makeNode(expressionType, {branches, from});
    });

    self.RULE("ifBranch", () => {
      let block = pushBlock();
      let from: NodeDependent[] = [
        self.CONSUME(If)
      ]
      self.AT_LEAST_ONE(() => {
        let statement = self.SUBRULE(self.statement) as ParseNode;
        if(statement) {
          from.push(statement);
        }
      })
      from.push(self.CONSUME(Then));
      let expression = self.SUBRULE(self.expression) as ParseNode;
      from.push(expression);
      block.startOffset = from[0].startOffset;
      block.endOffset = toEnd(from[from.length - 1]);
      popBlock();
      return makeNode("ifBranch", {block, outputs: ifOutputs(expression), exclusive: false, from});
    });

    self.RULE("elseIfBranch", () => {
      let block = pushBlock();
      let from: NodeDependent[] = [
        self.CONSUME(Else),
        self.CONSUME(If),
      ]
      self.AT_LEAST_ONE(() => {
        let statement = self.SUBRULE(self.statement) as ParseNode;
        if(statement) {
          from.push(statement);
        }
      })
      from.push(self.CONSUME(Then));
      let expression = self.SUBRULE(self.expression) as ParseNode;
      from.push(expression);
      block.startOffset = from[0].startOffset;
      block.endOffset = toEnd(from[from.length - 1]);
      popBlock();
      return makeNode("ifBranch", {block, outputs: ifOutputs(expression), exclusive: true, from});
    });

    self.RULE("elseBranch", () => {
      let block = pushBlock();
      let from: NodeDependent[] = [self.CONSUME(Else)];
      let expression = self.SUBRULE(self.expression) as ParseNode;
      from.push(expression);
      block.startOffset = from[0].startOffset;
      block.endOffset = toEnd(from[from.length - 1]);
      popBlock();
      return makeNode("ifBranch", {block, outputs: ifOutputs(expression), exclusive: true, from});
    });

    //-----------------------------------------------------------
    // Infix and operator precedence
    //-----------------------------------------------------------

    self.RULE("infix", () => {
      return self.SUBRULE(self.addition);
    });

    self.RULE("addition", () : any => {
      let left = self.SUBRULE(self.multiplication);
      let from = [left];
      let ops:any[] = [];
      self.MANY(function() {
        let op = self.CONSUME(AddInfix);
        let right = self.SUBRULE2(self.multiplication);
        from.push(op, right);
        ops.push({op, right})
      });
      if(!ops.length) {
        return left;
      } else {
        let expressions = [];
        let curVar;
        let curLeft = left;
        for(let pair of ops) {
          let {op, right} = pair;
          curVar = self.block.toVariable(`addition|${op.startLine}|${op.startColumn}`, true);
          let expression = makeNode("expression", {op: `math/${op.image}`, args: [asValue(curLeft), asValue(right)], variable: curVar, from: [curLeft, op, right]});
          expressions.push(expression);
          self.block.addUsage(curVar, expression);
          self.block.expression(expression)
          curLeft = expression;
        }
        return makeNode("addition", {expressions, variable: curVar, from});
      }
    });

    self.RULE("multiplication", () : any => {
      let left = self.SUBRULE(self.infixValue);
      let from = [left];
      let ops:any = [];
      self.MANY(function() {
        let op = self.CONSUME(MultInfix);
        let right = self.SUBRULE2(self.infixValue);
        from.push(op, right);
        ops.push({op, right})
      });
      if(!ops.length) {
        return left;
      } else {
        let expressions = [];
        let curVar;
        let curLeft = left;
        for(let pair of ops) {
          let {op, right} = pair;
          curVar = self.block.toVariable(`addition|${op.startLine}|${op.startColumn}`, true);
          let expression = makeNode("expression", {op: `math/${op.image}`, args: [asValue(curLeft), asValue(right)], variable: curVar, from: [curLeft, op, right]});
          expressions.push(expression);
          self.block.addUsage(curVar, expression);
          self.block.expression(expression)
          curLeft = expression;
        }
        return makeNode("multiplication", {expressions, variable: curVar, from});
      }
    });

    self.RULE("parenthesis", () => {
      let items:any[] = [];
      let from:any[] = [];
      from.push(self.CONSUME(OpenParen));
      self.AT_LEAST_ONE(() => {
        let item = self.SUBRULE(self.expression);
        items.push(asValue(item));
        from.push(item);
      })
      from.push(self.CONSUME(CloseParen));
      if(items.length === 1) {
        return items[0];
      }
      return makeNode("parenthesis", {items, from});
    });

    self.RULE("infixValue", () => {
      return self.OR([
        {ALT: () => { return self.SUBRULE(self.attributeAccess); }},
        {ALT: () => { return self.SUBRULE(self.functionRecord); }},
        {ALT: () => { return self.SUBRULE(self.variable); }},
        {ALT: () => { return self.SUBRULE(self.value); }},
        {ALT: () => { return self.SUBRULE(self.parenthesis); }},
      ]);
    })

    //-----------------------------------------------------------
    // Expression
    //-----------------------------------------------------------

    self.RULE("expression", () => {
      let blockKey:any, action:any;
      if(self.currentAction !== "match") {
        blockKey = self.currentAction;
        action = "+=";
      }
      return self.OR([
        {ALT: () => { return self.SUBRULE(self.infix); }},
        {ALT: () => { return self.SUBRULE(self.record, [false, blockKey, action]); }},
      ]);
    });

    //-----------------------------------------------------------
    // Variable
    //-----------------------------------------------------------

    self.RULE("variable", (forceGenerate = false) => {
      let token = self.CONSUME(Identifier);
      let name = token.image;
      if(forceGenerate) {
        name = `${token.image}-${token.startLine}-${token.startColumn}`;
      }
      let variable = self.block.toVariable(name!, forceGenerate);
      self.block.addUsage(variable, token);
      return variable;
    });

    //-----------------------------------------------------------
    // Values
    //-----------------------------------------------------------

    self.RULE("stringInterpolation", () : any => {
      let args:any[] = [];
      let start = self.CONSUME(OpenString);
      let from: NodeDependent[] = [start];
      self.MANY(() => {
        let arg = self.OR([
          {ALT: () => {
            let str = self.CONSUME(StringChars)!;
            return makeNode("constant", {value: cleanString(str.image!), from: [str]});
          }},
          {ALT: () => {
            self.CONSUME(StringEmbedOpen);
            let expression = self.SUBRULE(self.infix);
            self.CONSUME(StringEmbedClose);
            return expression;
          }},
        ]);
        args.push(asValue(arg));
        from.push(arg as ParseNode);
      });
      from.push(self.CONSUME(CloseString));
      if(args.length === 1 && args[0].type === "constant") {
        return args[0];
      } else if(args.length === 0) {
        return makeNode("constant", {value: "", from});
      }
      let variable = self.block.toVariable(`concat|${start.startLine}|${start.startColumn}`, true);
      let expression = makeNode("expression", {op: "eve/internal/concat", args, variable, from});
      self.block.addUsage(variable, expression);
      self.block.expression(expression);
      return expression;
    });

    self.RULE("value", () => {
      return self.OR([
        {ALT: () => { return self.SUBRULE(self.stringInterpolation) }},
        {ALT: () => { return self.SUBRULE(self.num) }},
        {ALT: () => { return self.SUBRULE(self.bool) }},
      ])
    })

    self.RULE("bool", () => {
      let value = self.CONSUME(Bool);
      return makeNode("constant", {value: value.image === "true", from: [value]});
    })

    self.RULE("num", () => {
      let num = self.CONSUME(Num);
      return makeNode("constant", {value: parseFloat(num.image!), from: [num]}) ;
    });

    //-----------------------------------------------------------
    // Chevrotain analysis
    //-----------------------------------------------------------

    Parser.performSelfAnalysis(this);
  }
}

//-----------------------------------------------------------
// Public API
//-----------------------------------------------------------

export function nodeToBoundaries(node:any, offset = 0) {
  return [node.startOffset, toEnd(node)];
}

let eveParser = new Parser([]);

export function parseBlock(block:any, blockId:string, offset = 0, spans:any[] = [], extraInfo:any = {}) {
  let lex: any = EveBlockLexer.tokenize(block);
  let token: any;
  let tokenIx = 0;
  for(token of lex.tokens) {
    let tokenId = `${blockId}|token|${tokenIx++}`;
    token.id = tokenId;
    token.startOffset += offset;
    spans.push(token.startOffset, token.startOffset + token.image.length, token.label, tokenId);
  }
  for(token of lex.groups.comments) {
    let tokenId = `${blockId}|token|${tokenIx++}`;
    token.id = tokenId;
    token.startOffset += offset;
    spans.push(token.startOffset, token.startOffset + token.image.length, token.label, tokenId);
  }
  eveParser.input = lex.tokens;
  let results;
  try {
    eveParser.customErrors = [];
    // The parameters here are a strange quirk of how Chevrotain works, I believe the
    // 1 tells chevrotain what level the rule is starting at, we then pass our params
    // to the codeBlock parser function as an array
    results = eveParser.codeBlock(1, [blockId]);
  } catch(e) {
    console.error("The parser threw an error: " + e);
  }
  if(results) {
    results.start = offset;
    results.startOffset = offset;
    results.tokens = lex.tokens;
    for(let scan of results.scanLike) {
      let type = "scan-boundary";
      if(scan.type === "record") {
        type = "record-boundary";
      }
      spans.push(scan.startOffset, scan.endOffset, type, scan.id);
    }
    for(let action of results.binds) {
      let type = "action-boundary";
      if(action.type === "record") {
        type = "action-record-boundary";
      }
      spans.push(action.startOffset, action.endOffset, type, action.id);
      extraInfo[action.id] = {kind: "bind"};
    }
    for(let action of results.commits) {
      let type = "action-boundary";
      if(action.type === "record") {
        type = "action-record-boundary";
      }
      spans.push(action.startOffset, action.endOffset, type, action.id);
      extraInfo[action.id] = {kind: "commits"};
    }
  }
  let errors = parserErrors(eveParser.errors.concat(eveParser.customErrors), {blockId, blockStart: offset, spans, extraInfo, tokens: lex.tokens});
  lex.groups.comments.length = 0;
  return {
    results,
    lex,
    errors,
  }
}

let docIx = 0;
export function parseDoc(doc:string, docId = `doc|${docIx++}`) {
  let {text, spans, blocks, extraInfo} = parseMarkdown(doc, docId);
  let parsedBlocks = [];
  let allErrors = [];
  for(let block of blocks) {
    extraInfo[block.id] = {info: block.info, block};
    if(block.info.indexOf("disabled") > -1) {
      extraInfo[block.id].disabled = true;
    }
    if(block.info !== "" && block.info.indexOf("eve") === -1) continue;
    let {results, lex, errors} = parseBlock(block.literal, block.id, block.startOffset, spans, extraInfo);
    // if this block is disabled, we want the parsed spans and such, but we don't want
    // the block to be in the set sent to the builder
    if(!extraInfo[block.id].disabled) {
      if(errors.length) {
        allErrors.push(errors);
      } else if(results) {
        results.endOffset = block.endOffset;
        parsedBlocks.push(results);
      }
    }
  }

  let eavs:any[] = [];
  for(let block of parsedBlocks) {
    //if(typeof process === "undefined") console.log(block);
    toFacts(eavs, block);
  }

  for(let errorSet of allErrors) {
    for(let error of errorSet) {
      errorToFacts(eavs, error, extraInfo[error.blockId].block);
    }
  }

  return {
    results: {blocks: parsedBlocks, text, spans, extraInfo, eavs},
    errors: allErrors,
  }
}

export function errorToFacts(eavs:any[], error:EveError, block:any) {
  let text = block.literal;
  let offset = block.startOffset;
  let blockStartLine = block.sourcepos[0][0];
  let blockLines = text.split("\n");
  let pos = 0;
  let start = error.start - offset;
  let stop = error.stop - offset;
  if(isNaN(stop)) stop = text.length + offset;
  if(isNaN(start)) start = offset;
  let curLine = 0;
  let startLine = 0;
  let startChar = 0;
  let stopLine = 0;
  let stopChar = 0;
  while(curLine < blockLines.length && pos < start) {
    pos += blockLines[curLine++].length + 1;
  }
  startLine = blockStartLine + curLine;
  startChar = start - (pos - (blockLines[curLine - 1] || "").length) + 2;
  while(curLine < blockLines.length && pos < stop) {
    pos += (blockLines[curLine++] || "").length + 1;
  }
  stopLine = blockStartLine + curLine;
  stopChar = stop - (pos - (blockLines[curLine - 1] || "").length) + 2;

  let sampleText = [];
  let relativeStart = startLine - blockStartLine;
  let relativeStop = stopLine - blockStartLine;
  if(relativeStart != 0) {
    sampleText.push(blockLines[relativeStart - 1]);
    sampleText.push(blockLines[relativeStart]);
  }

  if(relativeStop > relativeStart) {
    let cur = relativeStart;
    while(cur <= relativeStop) {
      sampleText.push(blockLines[cur]);
      cur++;
    }
  }

  if(relativeStop < blockLines.length && blockLines[relativeStop + 1]) {
    sampleText.push(blockLines[relativeStop + 1]);
  }

  let errorId = uuid();
  let startId = uuid();
  let stopId = uuid();
  eavs.push([errorId, "tag", "eve/compiler/error"]);
  eavs.push([errorId, "message", error.message]);
  eavs.push([errorId, "start", startId]);
  eavs.push([startId, "line", startLine]);
  eavs.push([startId, "char", startChar]);
  eavs.push([errorId, "stop", stopId]);
  eavs.push([stopId, "line", stopLine]);
  eavs.push([stopId, "char", stopChar]);
  eavs.push([errorId, "sample", sampleText.join("\n")])
}

export function recordToFacts(eavs:any[], vars:any, scanLike:any) {
  let rec = uuid();
  eavs.push([rec, "tag", "eve/compiler/record"]);
  eavs.push([rec, "record", vars[scanLike.variable.name]]);

  for(let attr of scanLike.attributes) {
    if(attr.type === "attribute") {
      let values;
      if(attr.value && attr.value.type === "parenthesis") {
        values = attr.value.items;
      } else {
        values = [attr.value];
      }
      for(let value of values) {
        let attrId = uuid();
        eavs.push([attrId, "attribute", attr.attribute]);
        eavs.push([attrId, "value", asFactValue(vars, value)]);
        eavs.push([rec, "attribute", attrId]);
      }
    }
  }

  return rec;
}

function asFactValue(vars:any, value:any) {
  if(typeof value !== "object") return value;
  return value.type == "constant" ? value.value : vars[value.name];
}

export function outputToFacts(eavs:any[], vars:any, scanLike:any, blockId:string) {
  let rec = uuid();
  eavs.push([rec, "tag", "eve/compiler/output"]);
  eavs.push([rec, "record", vars[scanLike.variable.name]]);
  if(scanLike.action === "-=" || scanLike.action === "erase") {
    eavs.push([rec, "tag", "eve/compiler/remove"]);
  } else if(scanLike.action === ":=" || scanLike.action === "<-") {
    let attrs = [];
    for(let attribute of scanLike.attributes) {
      attribute.nonProjecting = true;
      if(attribute.type === "attribute") {
        if(scanLike.action === ":=" || (attribute.attribute !== "tag")) {
          attrs.push({type: "attribute", attribute: attribute.attribute, nonProjecting:true});
        }
      }
    }
    outputToFacts(eavs, vars, {variable:scanLike.variable, action: "erase", attributes:attrs}, blockId);
  }

  for(let attr of scanLike.attributes) {
    if(attr.type === "attribute") {
      let values;
      if(attr.value && attr.value.type === "parenthesis") {
        values = attr.value.items;
      } else {
        values = [attr.value];
      }
      for(let value of values) {
        let attrId = uuid();
        eavs.push([attrId, "attribute", asFactValue(vars, attr.attribute)]);
        if(value) {
          eavs.push([attrId, "value", asFactValue(vars, value)]);
        }
        if(attr.nonProjecting) {
          eavs.push([attrId, "tag", "eve/compiler/attribute/non-identity"]);
        }
        eavs.push([rec, "attribute", attrId]);
      }
    }
  }
  eavs.push([blockId, "constraint", rec]);
  return rec;
}

function subBlockToFacts(eavs:any[], vars:any, blockId: string, block:any) {
  for(let [left, right] of block.equalities) {
    let eqId = uuid();
    eavs.push([eqId, "tag", "eve/compiler/equality"]);
    eavs.push([eqId, "left", asFactValue(vars, left)]);
    eavs.push([eqId, "right", asFactValue(vars, right)]);
    eavs.push([blockId, "constraint", eqId]);
  }

  for(let scanLike of block.scanLike) {
    switch(scanLike.type) {
      case "record":
        let constraint = recordToFacts(eavs, vars, scanLike);
        eavs.push([blockId, "constraint", constraint]);
        break;
      case "scan":
        let lookupId = uuid();
        eavs.push([lookupId, "tag", "eve/compiler/lookup"]);
        eavs.push([lookupId, "record", asFactValue(vars, scanLike.entity)]);
        eavs.push([lookupId, "attribute", asFactValue(vars, scanLike.attribute)]);
        eavs.push([lookupId, "value", asFactValue(vars, scanLike.value)]);
        eavs.push([blockId, "constraint", lookupId]);
        break;
      case "not":
        let notId = uuid();
        eavs.push([notId, "tag", "eve/compiler/not"]);
        eavs.push([notId, "tag", "eve/compiler/block"]);
        eavs.push([blockId, "constraint", notId]);
        subBlockToFacts(eavs, vars, notId, scanLike);
        break;
      case "choose":
      case "union":
        let chooseId = uuid();
        if(scanLike.type === "choose") {
          eavs.push([chooseId, "tag", "eve/compiler/choose"]);
        } else {
          eavs.push([chooseId, "tag", "eve/compiler/union"]);
        }
        eavs.push([chooseId, "tag", "eve/compiler/branch-set"]);
        eavs.push([blockId, "constraint", chooseId]);
        for(let branch of scanLike.branches) {
          let branchId = uuid();
          eavs.push([chooseId, "branch", branchId]);
          eavs.push([branchId, "tag", "eve/compiler/block"]);
          subBlockToFacts(eavs, vars, branchId, branch.block);
          let ix = 1;
          for(let output of branch.outputs) {
            let outputId = uuid();
            eavs.push([branchId, "output", outputId]);
            eavs.push([outputId, "value", asFactValue(vars, output)]);
            eavs.push([outputId, "index", ix]);
            ix++;
          }
        }
        let ix = 1;
        for(let output of scanLike.outputs) {
          let outputId = uuid();
          eavs.push([chooseId, "output", outputId]);
          eavs.push([outputId, "value", asFactValue(vars, output)]);
          eavs.push([outputId, "index", ix]);
          ix++;
        }
        break;
    }
  }

  for(let expr of block.expressions) {
    let exprId = uuid();
    let isAggregate = expr.op.indexOf("gather/") === 0;
    eavs.push([blockId, "constraint", exprId]);
    eavs.push([exprId, "tag", "eve/compiler/expression"]);
    if(isAggregate) {
      eavs.push([exprId, "tag", "eve/compiler/aggregate"]);
    }
    eavs.push([exprId, "op", expr.op]);
    if(expr.type === "expression") {
      let ix = 1;
      for(let arg of expr.args) {
        let argId = uuid();
        eavs.push([exprId, "arg", argId]);
        eavs.push([argId, "index", ix]);
        eavs.push([argId, "value", asFactValue(vars, arg)]);
        ix++;
      }
      if(expr.variable) {
        let returnId = uuid();
        eavs.push([exprId, "return", returnId]);
        eavs.push([returnId, "index", 1]);
        eavs.push([returnId, "value", asFactValue(vars, expr.variable)]);
      }
    } else if(expr.type === "functionRecord") {
      for(let arg of expr.record.attributes) {
        let ix = 1;
        if(arg.value.type === "parenthesis") {
          for(let value of arg.value.items) {
            let argId = uuid();
            eavs.push([exprId, "arg", argId]);
            eavs.push([argId, "name", arg.attribute]);

            eavs.push([argId, "value", asFactValue(vars, value)]);
            eavs.push([argId, "index", ix]);
            ix++;
          }
        } else {
          let argId = uuid();
          eavs.push([exprId, "arg", argId]);
          eavs.push([argId, "name", arg.attribute]);

          eavs.push([argId, "value", asFactValue(vars, arg.value)]);
          eavs.push([argId, "index", ix]);
        }
      }
      if(expr.returns) {
        let ix = 1;
        for(let ret of expr.returns) {
          let returnId = uuid();
          eavs.push([exprId, "return", returnId]);
          eavs.push([returnId, "index", ix]);
          eavs.push([returnId, "value", asFactValue(vars, ret.value)]);
          ix++;
        }
      } else if(expr.variable) {
        let returnId = uuid();
        eavs.push([exprId, "return", returnId]);
        eavs.push([returnId, "index", 1]);
        eavs.push([returnId, "value", asFactValue(vars, expr.variable)]);
      }
    }
  }
}

export function toFacts(eavs:any[], block:any) {
  let blockId = uuid();
  eavs.push([blockId, "tag", "eve/compiler/rule"]);
  eavs.push([blockId, "tag", "eve/compiler/block"]);
  eavs.push([blockId, "name", block.id]);
  let blockType = "bind";
  if(block.commits.length) { blockType = "commit"; }
  eavs.push([blockId, "type", blockType]);

  let vars:any = {};
  for(let variable in block.variableLookup) {
    let varId = uuid();
    vars[variable] = varId;
    eavs.push([varId, "tag", "eve/compiler/var"]);
  }

  subBlockToFacts(eavs, vars, blockId, block);

  let outputs = block.binds.concat(block.commits);
  for(let output of outputs) {
    switch(output.type) {
      case "record":
        outputToFacts(eavs, vars, output, blockId);
      break;
      case "action":
        outputToFacts(eavs, vars, {
          action: output.action,
          variable: output.entity,
          attributes: [{type: "attribute", attribute: output.attribute, value: output.value, nonProjecting: true}]
        }, blockId)
        break;
    }
  }

  return eavs;

  // let lookup = find("eve/compiler/lookup");
  // let {record:rec, attribute, value} = lookup;

}


================================================
FILE: src/programs/perfReport.ts
================================================
//---------------------------------------------------------------------
// Performance Report
//---------------------------------------------------------------------
import {v4 as uuid} from "uuid";
import {Program} from "../watchers/watcher";
import {PerformanceTracker} from "../runtime/performance";


export class PerformanceReporter {
  constructor() { }

  blocksToEAVs(blocks:any, eavs:any[] = []) {
    for(let name in blocks) {
      let {counts, times} = blocks[name];
      let blockId = uuid();
      eavs.push(
        [blockId, "tag", "block"],
        [blockId, "name", name],
      );
      for(let property in counts) {
        let count = counts[property];
        let time = times[property];
        let propertyId = uuid();
        eavs.push(
          [blockId, "property", propertyId],
          [propertyId, "name", property],
          [propertyId, "count", count],
          [propertyId, "time", time]
        );
      }
    }
    return eavs as any[];
  }

  totalsToEAVs(counts:any, times:any, eavs:any[] = []) {
    let programId = uuid();
    eavs.push(
      [programId, "tag", "total"],
    );
    for(let property in counts) {
      let count = counts[property];
      let time = times[property];
      let propertyId = uuid();
      eavs.push(
        [programId, "property", propertyId],
        [propertyId, "name", property],
        [propertyId, "count", count],
        [propertyId, "time", time]
      );
    }
  }

  report(perf:PerformanceTracker) {
    let eavs = this.blocksToEAVs(perf.blocks);
    this.totalsToEAVs(perf.counts, perf.times, eavs);
    let me = new Program("Performance report");
    me.attach("ui");

    me.bind("calculate block percentage", ({find, record, lib: {math}}) => {
      let total = find("total");
      total.property.name == "transaction"
      let block = find("block");
      let property = block.property;
      property.name == "block";
      let percent = math.round(property.time * 100 / total.property.time);
      return [
        block.add("percent", percent)
      ]
    });

    me.bind("draw total", ({find, record, lib: {math}}) => {
      let container = find("block-times")
      let total = find("total");
      let property = total.property;
      let avg = math.toFixed(property.time / property.count, 4);
      let timeStr = math.toFixed(property.time, 2)
      return [
        container.add("children", [
          record("ui/row", {total})
          .add("style", record({flex: "none", padding: "10px 20px", "margin-bottom":"10px", background: "#ccc"}))
          .add("sort", -10000).add("children", [
            record("ui/column", {total, sort:0}).add("children", [
              record("ui/text", {text:"Total", sort:0, style: record({"font-size": "16pt"})}),
              record("ui/row", {total, sort:1, style:record({"font-size":"14pt", margin:"10px 0"})}).add("children", [
                record("ui/text", {text:property.count, sort:0}),
                record("ui/text", {text:timeStr, sort:1, style: record({margin: "0 10px"})}),
                record("ui/text", {text:avg, sort:2}),
              ]),
            ]),
            record("ui/spacer", {sort:1}),
            record("ui/text", {text:"100%", sort:1, style:record({"font-size":"20pt"})})
          ])
        ])
      ]
    });

    me.bind("draw blocks 2", ({find, record, lib: {math}}) => {
      let block = find("block");
      let {name, property} = block;
      property.name == "block"
      let rev = -1;
      let avg = math.toFixed(property.time / property.count, 4);
      let timeStr = math.toFixed(property.time, 2)
      let foo = record({"font-size":"14pt", margin: "10px 0"});
      return [
        record("ui/column", "block-times", {style:record({"max-width":500}), sort:2}).add("children", [
          record("ui/row", {block})
            .add("style", record({flex: "none", padding: "10px 20px", "margin-bottom":"10px", background: "#ccc"}))
            .add("sort", rev * property.time).add("children", [
              record("ui/column", {block, sort:0}).add("children", [
                record("ui/text", {text:block.name, sort:0, style: record({"font-size": "16pt"})}),
                record("ui/row", {block, sort:1, style:foo}).add("children", [
                  record("ui/text", {text:property.count, sort:0}),
                  record("ui/text", {text:timeStr, sort:1, style: record({margin: "0 10px"})}),
                  record("ui/text", {text:avg, sort:2}),
                ]),
                record("ui/column", "props", {block, sort:2})
              ]),
              record("ui/spacer", {sort:1}),
              record("ui/text", {text:block.percent + "%", sort:1, style:record({"font-size":"20pt"})})
            ])
        ])
      ]
    });

    me.bind("draw props", ({find, record, lib: {math}}) => {
      let container = find("props");
      let {block} = container;
      let property = block.property;
      property.name != "block"
      let avg = math.toFixed(property.time / property.count, 4);
      let timeStr = math.toFixed(property.time, 2)
      return [
        container.add("children", [
          record("ui/row", {block, property, sort:property.name}).add("children", [
            record("ui/text", {sort:0, text:property.name, style:record({"margin-right":"15px", width:"120px"})}),
            record("ui/text", {sort:1, text:property.count, style:record({width:50})}),
            record("ui/text", {sort:2, text:timeStr, style:record({margin: "0 10px", width:50})}),
            record("ui/text", {sort:3, text:avg, style:record({width:50})}),
          ])
        ])
      ]
    });

    me.bind("Translate elements into html", ({find, record, union}) => {
      let elem = find("html/div");
      return [elem.add("tag", "html/element").add("tagname", "div")];
    });

    // console.profile("perf");
    me.inputEAVs(eavs);
    // console.profileEnd();
  }

}

let baseline = {"times":{"transaction":1559.8550000000002},"counts":{"transaction":155},"blocks":{"setup timers":{"counts":{"block":5022,"PresolveCheck":0,"GenericJoin":0},"times":{"block":14.034999999994398,"PresolveCheck":0,"GenericJoin":0}},"Remove click events!":{"counts":{"block":10044,"PresolveCheck":110,"GenericJoin":0},"times":{"block":13.43499999997448,"PresolveCheck":0.23000000000092768,"GenericJoin":0}},"Elements with no parents are roots.":{"counts":{"block":10044,"PresolveCheck":1486,"GenericJoin":190},"times":{"block":42.510000000021364,"PresolveCheck":3.640000000006694,"GenericJoin":3.845000000001164}},"Create an instance for each child of a rooted parent.":{"counts":{"block":10044,"PresolveCheck":2230,"GenericJoin":268},"times":{"block":58.76499999999328,"PresolveCheck":12.61500000000592,"GenericJoin":9.5949999999998}},"Export all instances.":{"counts":{"block":10044,"PresolveCheck":1302,"GenericJoin":186},"times":{"block":32.044999999980746,"PresolveCheck":3.1350000000034015,"GenericJoin":4.429999999996198}},"Export roots.":{"counts":{"block":10044,"PresolveCheck":2,"GenericJoin":2},"times":{"block":10.035000000010314,"PresolveCheck":0.015000000000100044,"GenericJoin":0.03499999999962711}},"Export instance parents.":{"counts":{"block":10044,"PresolveCheck":554,"GenericJoin":184},"times":{"block":23.02999999999588,"PresolveCheck":1.8199999999999363,"GenericJoin":3.1999999999986812}},"Export element styles.":{"counts":{"block":10044,"PresolveCheck":10418,"GenericJoin":1},"times":{"block":70.72999999996205,"PresolveCheck":38.89999999996758,"GenericJoin":0.2949999999998454}},"Exp
Download .txt
gitextract_5kl2vc7y/

├── .gitattributes
├── .gitignore
├── .npmignore
├── ATTRIBUTIONS.md
├── Dockerfile
├── LICENSE
├── Procfile
├── README.md
├── assets/
│   └── css/
│       ├── app-preview.css
│       ├── base.css
│       ├── codemirror.css
│       ├── editor.css
│       ├── examples/
│       │   ├── crm.css
│       │   └── todomvc.css
│       ├── ide.css
│       ├── simplescrollbars.css
│       └── trace.css
├── bin/
│   └── eve.js
├── circle.yml
├── docker-compose.yml
├── index.html
├── package.json
├── src/
│   ├── bootstrap.ts
│   ├── index.ts
│   ├── loadWorker.js
│   ├── microReact.ts
│   ├── parser/
│   │   ├── errors.ts
│   │   └── parser.ts
│   ├── programs/
│   │   └── perfReport.ts
│   ├── runtime/
│   │   ├── dsl2.ts
│   │   ├── indexes.ts
│   │   ├── performance.ts
│   │   ├── runtime.ts
│   │   ├── stdlib.ts
│   │   └── trace.ts
│   ├── system-polyfills.js
│   ├── system.js
│   ├── systemJSConfig.js
│   ├── types.d.ts
│   └── watchers/
│       ├── canvas.ts
│       ├── compiler.ts
│       ├── console.ts
│       ├── dom.ts
│       ├── editor.ts
│       ├── file.ts
│       ├── html.ts
│       ├── index.ts
│       ├── notify.ts
│       ├── shape.ts
│       ├── svg.ts
│       ├── system.ts
│       ├── tag-browser.ts
│       ├── ui.ts
│       └── watcher.ts
├── syntax_diagrams.html
├── test/
│   ├── aggregate.ts
│   ├── all.ts
│   ├── antijoin.ts
│   ├── choose.ts
│   ├── distinct.ts
│   ├── foundation.ts
│   ├── performance.ts
│   ├── stdlib/
│   │   └── math.ts
│   ├── union.ts
│   └── util.ts
├── tsconfig.json
└── typings/
    ├── codemirror/
    │   └── codemirror.d.ts
    └── commonmark/
        └── commonmark.d.ts
Download .txt
SYMBOL INDEX (919 symbols across 33 files)

FILE: bin/eve.js
  function findRoot (line 16) | function findRoot(root) {

FILE: src/microReact.ts
  type Handler (line 3) | interface Handler<T extends Event> {
  type RenderHandler (line 6) | interface RenderHandler {
  type uElement (line 10) | interface uElement {
  function now (line 122) | function now() {
  function shallowEquals (line 129) | function shallowEquals(a:any, b:any) {
  function postAnimationRemove (line 141) | function postAnimationRemove(elements:Element[]) {
  class Renderer (line 147) | class Renderer {
    method compile (line 150) | static compile(elem:uElement) {
    method constructor (line 166) | constructor() {
    method reset (line 183) | reset() {
    method domify (line 189) | domify() {
    method diff (line 431) | diff() {
    method prepare (line 532) | prepare(root:uElement) {
    method postDomify (line 561) | postDomify() {
    method render (line 574) | render(elems:uElement[]) {

FILE: src/parser/errors.ts
  constant SPAN_TYPE (line 8) | const SPAN_TYPE = "document_comment";
  class EveError (line 14) | class EveError {
    method constructor (line 26) | constructor(blockId:string, start:number, stop:number, message:string,...
    method injectSpan (line 35) | injectSpan(spans:any, extraInfo:any) {
  function regexGroup (line 45) | function regexGroup(str:string, regex:RegExp, group = 1) {
  function className (line 54) | function className(thing:any) {
  function lastTokenWithType (line 60) | function lastTokenWithType(tokens:any, type:any) {
  function parserErrors (line 76) | function parserErrors(errors: any[], parseInfo: {blockId: string, blockS...
  function mismatchedToken (line 108) | function mismatchedToken(error:any, parseInfo:any) {
  function notAllInputParsed (line 159) | function notAllInputParsed(error:any, parseInfo:any) {
  function unprovidedVariableGroup (line 185) | function unprovidedVariableGroup(block:any, variables:any) {
  function blankScan (line 201) | function blankScan(block:any, scan:any) {
  function invalidLookupAction (line 207) | function invalidLookupAction(block:any, action:any) {
  function unimplementedExpression (line 217) | function unimplementedExpression(block:any, expression:any) {
  function incompatabileConstantEquality (line 223) | function incompatabileConstantEquality(block:any, left:any, right:any) {
  function incompatabileVariableToConstantEquality (line 230) | function incompatabileVariableToConstantEquality(block:any, variable:any...
  function incompatabileTransitiveEquality (line 237) | function incompatabileTransitiveEquality(block:any, variable:any, value:...
  function unrecognisedFunctionAttribute (line 243) | function unrecognisedFunctionAttribute(block:any, expression:any, attrib...

FILE: src/parser/parser.ts
  function cleanString (line 16) | function cleanString(str:string) {
  function toEnd (line 27) | function toEnd(node:any) {
  function parseMarkdown (line 40) | function parseMarkdown(markdown: string, docId: string) {
  class DocContent (line 120) | class DocContent extends Token { static PATTERN = /[^\n]+/; }
  class Fence (line 121) | class Fence extends Token {
  class CloseFence (line 125) | class CloseFence extends Token {
  class CommentLine (line 131) | class CommentLine extends Token { static PATTERN = /\/\/.*\n/; label = "...
  class Equality (line 134) | class Equality extends Token { static PATTERN = /:|=/; label = "equality...
  class Comparison (line 135) | class Comparison extends Token { static PATTERN = />=|<=|!=|>|</; label ...
  class AddInfix (line 136) | class AddInfix extends Token { static PATTERN = /\+|-/; label = "infix"; }
  class MultInfix (line 137) | class MultInfix extends Token { static PATTERN = /\*|\//; label = "infix...
  class Merge (line 138) | class Merge extends Token { static PATTERN = /<-/; label = "merge"; }
  class Set (line 139) | class Set extends Token { static PATTERN = /:=/; label = "set"; }
  class Mutate (line 140) | class Mutate extends Token { static PATTERN = /\+=|-=/; label = "mutate"; }
  class Dot (line 141) | class Dot extends Token { static PATTERN = /\./; label = "dot"; }
  class Pipe (line 142) | class Pipe extends Token { static PATTERN = /\|/; label = "pipe"; }
  class Identifier (line 145) | class Identifier extends Token { static PATTERN = new RegExp(`([\\+-/\\*...
  class FunctionIdentifier (line 146) | class FunctionIdentifier extends Token { static PATTERN = new RegExp(`([...
  class Keyword (line 149) | class Keyword extends Token {
  class Lookup (line 153) | class Lookup extends Keyword { static PATTERN = /lookup(?=\[)/; label = ...
  class Action (line 154) | class Action extends Keyword { static PATTERN = /bind|commit/; label = "...
  class Search (line 155) | class Search extends Keyword { static PATTERN = /search/; label = "searc...
  class If (line 156) | class If extends Keyword { static PATTERN = /if/; label = "if"; }
  class Else (line 157) | class Else extends Keyword { static PATTERN = /else/; label = "else"; }
  class Then (line 158) | class Then extends Keyword { static PATTERN = /then/; label = "then"; }
  class Not (line 159) | class Not extends Keyword { static PATTERN = /not/; label = "not"; }
  class Bool (line 162) | class Bool extends Keyword { static PATTERN = /true|false/; label = "boo...
  class Num (line 163) | class Num extends Token { static PATTERN = /-?\d+(\.\d+)?/; label = "num...
  class None (line 164) | class None extends Keyword { static PATTERN = /none/; label = "none"; }
  class Name (line 165) | class Name extends Token { static PATTERN = /@/; label = "name"; }
  class Tag (line 166) | class Tag extends Token { static PATTERN = /#/; label = "tag"; }
  class OpenBracket (line 169) | class OpenBracket extends Token { static PATTERN = /\[/; label = "open-b...
  class CloseBracket (line 170) | class CloseBracket extends Token { static PATTERN = /\]/; label = "close...
  class OpenParen (line 171) | class OpenParen extends Token { static PATTERN = /\(/; label = "open-par...
  class CloseParen (line 172) | class CloseParen extends Token { static PATTERN = /\)/; label = "close-p...
  class StringChars (line 175) | class StringChars extends Token { static PATTERN = /(\\.|{(?=[^{])|[^"\\...
  class OpenString (line 176) | class OpenString extends Token {
  class CloseString (line 181) | class CloseString extends Token {
  class StringEmbedOpen (line 188) | class StringEmbedOpen extends Token {
  class StringEmbedClose (line 193) | class StringEmbedClose extends Token {
  class WhiteSpace (line 200) | class WhiteSpace extends Token {
  type NodeDependent (line 234) | type NodeDependent = chev.IToken | ParseNode;
  type ParseNode (line 236) | interface ParseNode {
  class ParseBlock (line 245) | class ParseBlock {
    method constructor (line 261) | constructor(id:string, variableLookup?:any) {
    method toVariable (line 266) | toVariable(name:string, generated = false) {
    method addUsage (line 275) | addUsage(variable:any, usage:any) {
    method equality (line 288) | equality(a:any, b:any) {
    method commit (line 292) | commit(node: ParseNode) {
    method bind (line 296) | bind(node: ParseNode) {
    method expression (line 300) | expression(node: ParseNode) {
    method scan (line 304) | scan(node: ParseNode) {
    method makeNode (line 308) | makeNode(type:any, node: ParseNode) {
    method addSearchScopes (line 323) | addSearchScopes(scopes: string[]) {
    method subBlock (line 331) | subBlock() {
  class Parser (line 343) | class Parser extends chev.Parser {
    method constructor (line 395) | constructor(input:any) {
  function nodeToBoundaries (line 1374) | function nodeToBoundaries(node:any, offset = 0) {
  function parseBlock (line 1380) | function parseBlock(block:any, blockId:string, offset = 0, spans:any[] =...
  function parseDoc (line 1445) | function parseDoc(doc:string, docId = `doc|${docIx++}`) {
  function errorToFacts (line 1486) | function errorToFacts(eavs:any[], error:EveError, block:any) {
  function recordToFacts (line 1546) | function recordToFacts(eavs:any[], vars:any, scanLike:any) {
  function asFactValue (line 1571) | function asFactValue(vars:any, value:any) {
  function outputToFacts (line 1576) | function outputToFacts(eavs:any[], vars:any, scanLike:any, blockId:strin...
  function subBlockToFacts (line 1620) | function subBlockToFacts(eavs:any[], vars:any, blockId: string, block:an...
  function toFacts (line 1751) | function toFacts(eavs:any[], block:any) {

FILE: src/programs/perfReport.ts
  class PerformanceReporter (line 9) | class PerformanceReporter {
    method constructor (line 10) | constructor() { }
    method blocksToEAVs (line 12) | blocksToEAVs(blocks:any, eavs:any[] = []) {
    method totalsToEAVs (line 35) | totalsToEAVs(counts:any, times:any, eavs:any[] = []) {
    method report (line 53) | report(perf:PerformanceTracker) {

FILE: src/runtime/dsl2.ts
  constant UNASSIGNED (line 17) | const UNASSIGNED = -1;
  function isArray (line 36) | function isArray<T>(v:any): v is Array<T> {
  function isASTString (line 40) | function isASTString(thing:any) {
  function macro (line 44) | function macro<FuncType extends Function>(func:FuncType, transform:(code...
  type Value (line 76) | type Value = Reference|RawValue;
  type ProxyReference (line 77) | type ProxyReference = any;
  function isRawValue (line 79) | function isRawValue(v:any): v is RawValue {
  function isReference (line 83) | function isReference(v:any): v is Reference {
  type Owner (line 87) | type Owner = any;
  class Reference (line 89) | class Reference {
    method create (line 91) | static create(context:ReferenceContext, value?:Owner|RawValue) {
    method constructor (line 103) | constructor(public __context:ReferenceContext, public __owner?:Owner) {
    method add (line 112) | add(attrMapOrAttr:Value|{[attr:string]:Value|Value[]}, value?:Value|Va...
    method remove (line 138) | remove(attribute?:Value, value?:Value|Value[]):Reference {
    method toString (line 153) | toString() {
    method __proxy (line 157) | __proxy() {
  class ReferenceContext (line 192) | class ReferenceContext {
    method push (line 195) | static push(context:ReferenceContext) {
    method pop (line 198) | static pop() {
    method constructor (line 211) | constructor(public parent?:ReferenceContext, flow?:LinearFlow) {
    method register (line 216) | register(ref:Reference) {
    method equality (line 235) | equality(a:Value, b:Value) {
    method getActive (line 245) | getActive():ReferenceContext {
    method owns (line 249) | owns(ref:Reference) {
    method getValue (line 253) | getValue(ref:Reference|RawValue, orGenerateRegister?:boolean):Register...
    method interned (line 267) | interned(ref:Reference|RawValue):Register|ID {
    method maybeInterned (line 273) | maybeInterned(ref:Reference|RawValue|undefined):Register|ID|undefined {
    method selectReference (line 280) | selectReference(refIds:any, ref:Reference, ref2:Reference) {
    method unify (line 293) | unify() {
    method getMoves (line 359) | getMoves() {
    method getInputReferences (line 377) | getInputReferences():Reference[] {
    method getInputRegisters (line 386) | getInputRegisters():Register[] {
    method updateMaxRegisters (line 390) | updateMaxRegisters(maybeMax:number) {
    method assignRegisters (line 398) | assignRegisters() {
  type Node (line 419) | type Node = Record | Insert | Fn | Not | Choose | Union | Aggregate | Lo...
  type LinearFlowFunction (line 420) | type LinearFlowFunction = (self:LinearFlow) => (Value|Value[])
  type RecordAttributes (line 421) | type RecordAttributes = {[key:string]:Value|Value[]}
  type FlowRecordArg (line 422) | type FlowRecordArg = string | RecordAttributes
  class FlowLevel (line 424) | class FlowLevel {
    method collect (line 435) | collect(node:Node) {
    method findReference (line 462) | findReference(node:any) {
    method toConstraints (line 476) | toConstraints(injections:Node[]) {
    method compile (line 486) | compile(nodes:Runtime.Node[], injections:Node[], toPass:Node[]):Runtim...
    method split (line 556) | split(context:ReferenceContext):FlowLevel[] {
  class DSLBase (line 725) | class DSLBase {
  class LinearFlow (line 730) | class LinearFlow extends DSLBase {
    method constructor (line 737) | constructor(func:LinearFlowFunction, parent?:LinearFlow) {
    method createLib (line 765) | createLib() {
    method collect (line 794) | collect(node:Node) {
    method findReference (line 798) | findReference(node:Node) {
    method getInputRegisters (line 806) | getInputRegisters() {
    method unify (line 871) | unify() {
    method compile (line 875) | compile(_:Node[] = []):Runtime.Node[] {
    method transform (line 916) | transform(func:LinearFlowFunction) {
  class WatchFlow (line 944) | class WatchFlow extends LinearFlow {
    method collect (line 945) | collect(node:Node) {
  class CommitFlow (line 958) | class CommitFlow extends LinearFlow {
    method collect (line 959) | collect(node:Node) {
  class Record (line 976) | class Record extends DSLBase {
    method constructor (line 978) | constructor(public context:ReferenceContext, tags:string[] = [], attri...
    method createReference (line 1006) | createReference() {
    method createSub (line 1010) | createSub(context:ReferenceContext, record?:Reference):Record {
    method reference (line 1014) | reference() {
    method add (line 1018) | add(context:ReferenceContext, attribute:Value, value:Value|Value[]) {
    method remove (line 1029) | remove(context:ReferenceContext, attribute:Value, value:Value|Value[]) {
    method copyToContext (line 1040) | copyToContext(activeContext:ReferenceContext) {
    method findAttribute (line 1049) | findAttribute(name:string):Reference|undefined {
    method access (line 1058) | access(refContext:ReferenceContext, activeContext:ReferenceContext, pr...
    method getRegisters (line 1073) | getRegisters():Register[] {
    method compile (line 1084) | compile():(Runtime.Node|Runtime.Scan)[] {
  class Lookup (line 1102) | class Lookup extends DSLBase {
    method constructor (line 1106) | constructor(public context:ReferenceContext, public record:Value) {
    method reference (line 1118) | reference():Reference {
    method output (line 1122) | output() {
    method compile (line 1126) | compile():Runtime.Scan[] {
  class Move (line 1138) | class Move extends DSLBase {
    method constructor (line 1140) | constructor(public context:ReferenceContext, public from:Value, to?:Re...
    method toKey (line 1153) | toKey() {
    method getInputRegisters (line 1159) | getInputRegisters():Register[] {
    method getOutputRegisters (line 1167) | getOutputRegisters():Register[] {
    method compile (line 1173) | compile():Runtime.Constraint[] {
  class Insert (line 1185) | class Insert extends Record {
    method constructor (line 1187) | constructor(public context:ReferenceContext, tags:string[] = [], attri...
    method createReference (line 1203) | createReference() {
    method createSub (line 1208) | createSub(context:ReferenceContext, record?:Reference):Record {
    method add (line 1212) | add(context:ReferenceContext, attribute:Value, value:Value|Value[]) {
    method remove (line 1223) | remove(context:ReferenceContext, attribute:Value, value:Value|Value[]) {
    method toWatch (line 1235) | toWatch() {
    method toCommit (line 1241) | toCommit() {
    method compile (line 1247) | compile():any[] {
  class Remove (line 1266) | class Remove extends Insert {
    method toCommit (line 1267) | toCommit() {
    method compile (line 1273) | compile():any[] {
  class Watch (line 1298) | class Watch extends Insert {
    method compile (line 1299) | compile():(Runtime.Node|Runtime.Scan)[] {
  class CommitInsert (line 1318) | class CommitInsert extends Insert {
    method compile (line 1319) | compile():any[] {
  class CommitRemove (line 1338) | class CommitRemove extends Remove {
    method compile (line 1339) | compile():any[] {
  class Fn (line 1362) | class Fn extends DSLBase {
    method constructor (line 1364) | constructor(public context:ReferenceContext, public name:string, publi...
    method reference (line 1382) | reference():Value {
    method access (line 1386) | access(refContext:ReferenceContext, activeContext:ReferenceContext, pr...
    method getInputRegisters (line 1390) | getInputRegisters() {
    method getOutputRegisters (line 1395) | getOutputRegisters() {
    method compile (line 1404) | compile():Runtime.Constraint[] {
  class Aggregate (line 1433) | class Aggregate extends DSLBase {
    method constructor (line 1436) | constructor(public context:ReferenceContext, public aggregate:any, pub...
    method getJoinRegisters (line 1454) | getJoinRegisters():Register[] {
    method getInputRegisters (line 1464) | getInputRegisters():Register[] {
    method getOutputRegisters (line 1472) | getOutputRegisters():Register[] {
    method compile (line 1478) | compile() {
    method reference (line 1487) | reference():Reference {
    method per (line 1491) | per(...args:Reference[]) {
  class AggregateBuilder (line 1498) | class AggregateBuilder {
    method constructor (line 1502) | constructor(public context:ReferenceContext, public projection:Referen...
    method per (line 1505) | per(...args:Reference[]) {
    method checkBlock (line 1512) | checkBlock() {
    method sum (line 1517) | sum(value:Reference):any {
    method count (line 1523) | count():any {
    method sort (line 1529) | sort(...directions:Value[]):any {
  class Not (line 1541) | class Not extends LinearFlow {
    method constructor (line 1542) | constructor(func:LinearFlowFunction, parent:LinearFlow) {
  class Union (line 1552) | class Union extends DSLBase {
    method constructor (line 1558) | constructor(public context:ReferenceContext, branchFunctions: Function...
    method setBranchInputs (line 1600) | setBranchInputs(branchIx:number, inputs:Reference[]) {
    method getInputRegisters (line 1610) | getInputRegisters() {
    method getOutputRegisters (line 1616) | getOutputRegisters() {
    method resultCount (line 1621) | resultCount(result:any):number {
    method build (line 1630) | build(left: Runtime.Node, nodes:Runtime.Node[], inputs:Register[][], o...
    method compile (line 1634) | compile(join:Runtime.Node) {
  class Choose (line 1698) | class Choose extends Union {
    method build (line 1699) | build(left: Runtime.Node, nodes:Runtime.Node[], inputs:Register[][], o...
  type EAVTuple (line 1709) | type EAVTuple = [RawValue, RawValue, RawValue];
  type EAVRCTuple (line 1710) | type EAVRCTuple = [RawValue, RawValue, RawValue, number, number];
  type TestChange (line 1711) | type TestChange =  EAVTuple | EAVRCTuple;
  class Program (line 1713) | class Program {
    method constructor (line 1726) | constructor(public name:string) {
    method constants (line 1731) | constants(obj:{[key:string]: RawValue}) {
    method injectConstants (line 1743) | injectConstants(func:LinearFlowFunction):LinearFlowFunction {
    method clear (line 1754) | clear() {
    method _bind (line 1759) | _bind(name:string, flow:LinearFlow) {
    method bind (line 1767) | bind(name:string, func:LinearFlowFunction) {
    method blockChangeTransaction (line 1773) | blockChangeTransaction(added:Runtime.Block[], removed:Runtime.Block[]) {
    method input (line 1786) | input(changes:Runtime.Change[]) {
    method inputEAVs (line 1815) | inputEAVs(eavcs:(RawEAVC|RawEAV)[]) {
    method test (line 1824) | test(transaction:number, eavns:TestChange[]) {
    method _commit (line 1838) | _commit(name:string, flow:LinearFlow) {
    method commit (line 1846) | commit(name:string, func:LinearFlowFunction) {
    method attach (line 1852) | attach(id:string) {
    method _watch (line 1861) | _watch(name:string, flow:WatchFlow) {
    method watch (line 1870) | watch(name:string, func:LinearFlowFunction) {
    method asDiffs (line 1876) | asDiffs(handler:DiffConsumer) {
    method asObjects (line 1883) | asObjects<Pattern extends RawRecord>(handler:ObjectConsumer<Pattern>) {
    method load (line 1890) | load(str:string) {

FILE: src/runtime/indexes.ts
  function isResolved (line 8) | function isResolved(field:ResolvedValue): field is ID {
  function sumTimes (line 12) | function sumTimes(roundArray:RoundArray, transaction:number, round:numbe...
  type Index (line 27) | interface Index {
  class HashIndex (line 36) | class HashIndex implements Index {
    method getOrCreateHash (line 41) | getOrCreateHash(parent:any, key:any) {
    method getOrCreateArray (line 49) | getOrCreateArray(parent:any, key:any) {
    method roundArrayInsert (line 57) | roundArrayInsert(arr:RoundArray, change:Change) {
    method insert (line 83) | insert(change:Change) {
    method resolveProposal (line 120) | resolveProposal(proposal:Proposal) {
    method propose (line 124) | propose(proposal:Proposal, e:ResolvedValue, a:ResolvedValue, v:Resolve...
    method walkPropose (line 140) | walkPropose(proposal:Proposal, index:any, a:ResolvedValue, b:ResolvedV...
    method walkCheck (line 180) | walkCheck(index:any, a:ResolvedValue, b:ResolvedValue, c:ResolvedValue...
    method check (line 213) | check(e:ResolvedValue, a:ResolvedValue, v:ResolvedValue, n:ResolvedVal...
    method walkGet (line 226) | walkGet(index:any, a:ResolvedValue, b:ResolvedValue, c:ResolvedValue, ...
    method get (line 273) | get(e:ResolvedValue, a:ResolvedValue, v:ResolvedValue, n:ResolvedValue...
    method getDiffs (line 281) | getDiffs(e:ResolvedValue, a:ResolvedValue, v:ResolvedValue, n:Resolved...
  class BitMatrixIndex (line 297) | class BitMatrixIndex {
    method insert (line 299) | insert(change:Change):void {
    method propose (line 303) | propose(proposal:Proposal, e:ResolvedValue, a:ResolvedValue, v:Resolve...
    method resolveProposal (line 307) | resolveProposal(proposal:Proposal):any[][] {
    method check (line 311) | check(e:ResolvedValue, a:ResolvedValue, v:ResolvedValue, n:ResolvedVal...
    method getDiffs (line 315) | getDiffs(e:ResolvedValue, a:ResolvedValue, v:ResolvedValue, n:Resolved...
    method get (line 319) | get(e:ResolvedValue, a:ResolvedValue, v:ResolvedValue, n:ResolvedValue...
  class DistinctIndex (line 329) | class DistinctIndex {
    method getDelta (line 332) | getDelta(last:number, next:number) {
    method shouldOutput (line 341) | shouldOutput(key:string, prefixRound:number, prefixCount:number):numbe...
    method distinct (line 408) | distinct(input:Change, results:Iterator<Change>):boolean {
    method distinctKey (line 423) | distinctKey(key:string, round:number, count:number, results:Iterator<[...
    method getCounts (line 433) | getCounts(change:Change) {
    method sanityCheck (line 439) | sanityCheck() {

FILE: src/runtime/performance.ts
  type TimeReturn (line 10) | type TimeReturn = number;
  class PerformanceTracker (line 12) | class PerformanceTracker {
    method _makePropertyHolder (line 26) | _makePropertyHolder(props = propertiesToTrack) {
    method constructor (line 34) | constructor() {
    method reset (line 40) | reset() {
    method block (line 48) | block(name:string) {
    method blockEnd (line 59) | blockEnd(name:string) {
    method blockTime (line 65) | blockTime(property:string) {
    method blockTimeEnd (line 72) | blockTimeEnd(property:string) {
    method time (line 78) | time(property:string) {
    method timeEnd (line 83) | timeEnd(property:string) {
    method serialize (line 88) | serialize() {
  class NoopPerformanceTracker (line 97) | class NoopPerformanceTracker extends PerformanceTracker {
    method constructor (line 108) | constructor() {
    method reset (line 113) | reset() { }
    method time (line 115) | time(property:string) {}
    method timeEnd (line 116) | timeEnd(property:string) {}
    method block (line 118) | block(name:string) {  this.activeBlock = name; }
    method blockEnd (line 119) | blockEnd(name:string) { this.activeBlock = "";  }
    method blockTime (line 121) | blockTime(property:string) {}
    method blockTimeEnd (line 122) | blockTimeEnd(property:string) {}

FILE: src/runtime/runtime.ts
  constant TRACE (line 8) | const TRACE = false;
  constant DEBUG (line 14) | const DEBUG = false;
  function indent (line 23) | function indent(text:string, level:number) {
  function printField (line 28) | function printField(field:ScanField) {
  function printFieldArray (line 35) | function printFieldArray(fields:ScanField[]) {
  function printPrefix (line 39) | function printPrefix(prefix:Prefix) {
  function toString (line 43) | function toString(x:any):string {
  function printBlock (line 49) | function printBlock(block:Block):string {
  function maybeReverse (line 54) | function maybeReverse(value?:ID):ID|RawValue|undefined {
  function createHash (line 72) | function createHash(place = "unknown-hash") {
  function createArray (line 78) | function createArray(place = "unknown") {
  function copyArray (line 84) | function copyArray(arr:any[], place = "unknown") {
  function copyHash (line 90) | function copyHash(hash:any, place = "unknown") {
  function concatArray (line 101) | function concatArray(arr:any[], arr2:any[]) {
  function moveArray (line 112) | function moveArray(arr:any[], arr2:any[]) {
  class Iterator (line 142) | class Iterator<T> {
    method push (line 147) | push(value:T) {
    method clear (line 151) | clear() {
    method reset (line 156) | reset() {
    method next (line 160) | next():T|undefined {
    method iter (line 165) | iter():ReadOnlyIterator<T> {
  class ReadOnlyIterator (line 170) | class ReadOnlyIterator<T> extends Iterator<T> {
    method constructor (line 171) | constructor(arr:T[], length:number) {
    method push (line 177) | push(value:T) {
  type RawValue (line 213) | type RawValue = string|number;
  type ID (line 215) | type ID = number;
  function isNumber (line 217) | function isNumber(thing:any): thing is number {
  class Interner (line 221) | class Interner {
    method constructor (line 253) | constructor() {
    method _getFreeID (line 258) | _getFreeID() {
    method reference (line 262) | reference(id:ID) {
    method intern (line 268) | intern(value: RawValue): ID {
    method get (line 289) | get(value: RawValue): ID|undefined {
    method reverse (line 300) | reverse(id: ID): RawValue {
    method release (line 305) | release(id: ID|undefined) {
    method arenaIntern (line 323) | arenaIntern(arenaName:string, value:RawValue):ID {
    method releaseArena (line 353) | releaseArena(arenaName:string) {
  type Multiplicity (line 395) | type Multiplicity = number;
  function sign (line 398) | function sign (x:number) {
  type EAVNField (line 407) | type EAVNField = "e"|"a"|"v"|"n";
  class Change (line 409) | class Change {
    method constructor (line 411) | constructor(public e: ID, public a: ID, public v: ID, public n: ID, pu...
    method fromValues (line 415) | static fromValues(e: any, a: any, v: any, n: any, transaction: number,...
    method toString (line 420) | toString() {
    method equal (line 430) | equal(other:Change, withoutNode?:boolean, withoutE?:boolean) {
    method reverse (line 440) | reverse(interner:Interner = GlobalInterner) {
    method toRawEAV (line 445) | toRawEAV(interner:Interner = GlobalInterner):RawEAV {
    method clone (line 450) | clone() {
  constant BLOCK_REMOVE (line 456) | const BLOCK_REMOVE = new Change(0,0,0,0,0,0,-1);
  constant BLOCK_ADD (line 457) | const BLOCK_ADD = new Change(0,0,0,0,0,0,1);
  class RemoveChange (line 459) | class RemoveChange extends Change {
    method toString (line 460) | toString() {
    method clone (line 465) | clone() {
  class RemoveVsChange (line 471) | class RemoveVsChange extends RemoveChange {
    method toRemoveChanges (line 472) | toRemoveChanges(context:EvaluationContext, changes:Change[]) {
    method clone (line 486) | clone() {
  class RemoveAVsChange (line 492) | class RemoveAVsChange extends RemoveVsChange {
    method toRemoveChanges (line 493) | toRemoveChanges(context:EvaluationContext, changes:Change[]) {
    method clone (line 508) | clone() {
  class RawChange (line 518) | class RawChange {
    method constructor (line 519) | constructor(public e: RawValue, public a: RawValue, public v: RawValue...
    method toString (line 522) | toString() {
  type Prefix (line 597) | type Prefix = ID[];
  class Register (line 607) | class Register {
    method constructor (line 608) | constructor(public offset:number) {}
  function isRegister (line 611) | function isRegister(x: any): x is Register {
  type IgnoreRegister (line 619) | type IgnoreRegister = typeof IGNORE_REG;
  type Proposal (line 625) | interface Proposal {
  type RoundArray (line 638) | type RoundArray = number[];
  type ApplyInputState (line 640) | enum ApplyInputState {
  type Constraint (line 646) | interface Constraint {
  type ScanField (line 665) | type ScanField = Register|ID|IgnoreRegister;
  type ResolvedValue (line 667) | type ResolvedValue = ID|undefined|IgnoreRegister;
  type ResolvedEAVN (line 669) | type ResolvedEAVN = {e:ResolvedValue, a:ResolvedValue, v:ResolvedValue, ...
  class EAVN (line 671) | class EAVN {
    method constructor (line 672) | constructor(public e:ID, public a:ID, public v:ID, public n:ID) {}
  type EAV (line 675) | type EAV = [ID, ID, ID];
  type RawEAV (line 676) | type RawEAV = [RawValue, RawValue, RawValue];
  type RawEAVC (line 677) | type RawEAVC = [RawValue, RawValue, RawValue, number];
  class MoveConstraint (line 683) | class MoveConstraint {
    method constructor (line 685) | constructor(public from:Register|ID, public to:Register) { }
    method toString (line 695) | toString() {
    method setup (line 699) | setup():void {
    method resolve (line 710) | resolve(prefix:Prefix) {
    method getRegisters (line 720) | getRegisters():Register[] {
    method isAffected (line 724) | isAffected(input:Change):ApplyInputState {
    method applyInput (line 731) | applyInput(input:Change, prefix:Prefix):ApplyInputState {
    method propose (line 750) | propose(context:EvaluationContext, prefix:Prefix, transaction:number, ...
    method resolveProposal (line 759) | resolveProposal(context:EvaluationContext, prefix:Prefix, proposal:Pro...
    method accept (line 766) | accept(context:EvaluationContext, prefix:Prefix, transaction:number, r...
    method acceptInput (line 774) | acceptInput(context:EvaluationContext, input:Change, prefix:Prefix, tr...
    method getDiffs (line 778) | getDiffs(context:EvaluationContext, prefix:Prefix):RoundArray {
  class Scan (line 791) | class Scan implements Constraint {
    method constructor (line 792) | constructor(public e:ScanField,
    method toString (line 804) | toString() {
    method toKey (line 808) | toKey() {
    method resolve (line 823) | resolve(prefix:Prefix) {
    method fieldUnresolved (line 856) | fieldUnresolved(resolved:ResolvedEAVN, key: keyof ResolvedEAVN) {
    method notStaticMatch (line 864) | notStaticMatch(input:Change, key: "e"|"a"|"v"|"n") {
    method isAffected (line 868) | isAffected(input:Change):ApplyInputState {
    method applyInput (line 885) | applyInput(input:Change, prefix:Prefix):ApplyInputState {
    method propose (line 914) | propose(context:EvaluationContext, prefix:Prefix, transaction:number, ...
    method resolveProposal (line 930) | resolveProposal(context:EvaluationContext, prefix:Prefix, proposal:Pro...
    method accept (line 935) | accept(context:EvaluationContext, prefix:Prefix, transaction:number, r...
    method acceptInput (line 952) | acceptInput(context:EvaluationContext, input:Change, prefix:Prefix, tr...
    method setupRegister (line 964) | setupRegister(field:EAVNField, parts:string[]) {
    method setupIsAffected (line 974) | setupIsAffected() {
    method setupApplyInput (line 986) | setupApplyInput() {
    method setup (line 1002) | setup() {
    method getRegisters (line 1018) | getRegisters():Register[] {
    method getDiffs (line 1022) | getDiffs(context:EvaluationContext, prefix:Prefix):RoundArray {
  type ConstraintFieldMap (line 1033) | type ConstraintFieldMap = {[name:string]: ScanField};
  type ResolvedFields (line 1034) | type ResolvedFields = {[fieldName:string]: ResolvedValue};
  class FunctionConstraint (line 1036) | class FunctionConstraint implements Constraint {
    method register (line 1038) | static register(name:string, klass: typeof FunctionConstraint) {
    method fetchInfo (line 1046) | static fetchInfo(name:string):typeof FunctionConstraint {
    method create (line 1052) | static create(name:string, fields:ConstraintFieldMap, restFields:(ID|R...
    method constructor (line 1067) | constructor(public fields:ConstraintFieldMap, public restFields:(ID|Re...
    method toString (line 1089) | toString() {
    method setup (line 1096) | setup() {
    method setupResolve (line 1116) | setupResolve() {
    method setupResolveRest (line 1131) | setupResolveRest() {
    method getRegisters (line 1147) | getRegisters() {
    method resolve (line 1155) | resolve(prefix:Prefix) {
    method resolveRest (line 1173) | resolveRest(prefix:Prefix) {
    method isAffected (line 1191) | isAffected(input:Change):ApplyInputState { return ApplyInputState.none; }
    method applyInput (line 1192) | applyInput(input:Change, prefix:Prefix):ApplyInputState { return Apply...
    method propose (line 1194) | propose(context:EvaluationContext, prefix:Prefix, transaction:number, ...
    method packInputs (line 1262) | packInputs(prefix:Prefix) {
    method unpackOutputs (line 1292) | unpackOutputs(outputs:RawValue[]) {
    method getResult (line 1302) | getResult(prefix:Prefix, outputs:ID[]) {
    method checkResult (line 1316) | checkResult(prefix:Prefix, outputs:ID[]) {
    method resolveProposal (line 1332) | resolveProposal(context:EvaluationContext, prefix:Prefix, proposal:Pro...
    method accept (line 1356) | accept(context:EvaluationContext, prefix:Prefix, transaction:number, r...
    method acceptInput (line 1394) | acceptInput(context:EvaluationContext, input:Change, prefix:Prefix, tr...
    method getDiffs (line 1398) | getDiffs(context:EvaluationContext, prefix:Prefix):RoundArray {
  type FunctionSetup (line 1403) | interface FunctionSetup {
  type SingleFunctionSetup (line 1413) | interface SingleFunctionSetup extends FunctionSetup {
  type MultiFunctionSetup (line 1417) | interface MultiFunctionSetup extends FunctionSetup {
  function _makeFunction (line 1422) | function _makeFunction({name, variadic = false, args, returns, apply, es...
  function makeFunction (line 1440) | function makeFunction(args:SingleFunctionSetup) {
  function makeMultiFunction (line 1443) | function makeMultiFunction(args:MultiFunctionSetup) {
  method toBranchString (line 1461) | toBranchString():string {
  class JoinNode (line 1508) | class JoinNode extends Node {
    method constructor (line 1520) | constructor(public constraints:Constraint[]) {
    method toString (line 1565) | toString() {
    method findAffectedConstraints (line 1569) | findAffectedConstraints(input:Change, prefix:Prefix):Iterator<Constrai...
    method applyCombination (line 1585) | applyCombination(context:EvaluationContext, input:Change, prefix:Prefi...
    method unapplyConstraint (line 1617) | unapplyConstraint(constraint:Constraint, prefix:Prefix) {
    method presolveCheck (line 1623) | presolveCheck(context:EvaluationContext, input:Change, prefix:Prefix, ...
    method computeMultiplicities (line 1638) | computeMultiplicities(context: EvaluationContext, results:Iterator<Pre...
    method prefixToResults (line 1683) | prefixToResults(context:EvaluationContext, constraints:Constraint[], p...
    method genericJoin (line 1693) | genericJoin(context:EvaluationContext, prefix:Prefix, transaction:numb...
    method downStreamExec (line 1769) | downStreamExec(context:EvaluationContext, input:Change, prefix:Prefix,...
    method exec (line 1782) | exec(context:EvaluationContext, input:Change, prefix:Prefix, transacti...
  class DownstreamJoinNode (line 1850) | class DownstreamJoinNode extends JoinNode {
    method exec (line 1851) | exec(context:EvaluationContext, input:Change, prefix:Prefix, transacti...
  class NoopJoinNode (line 1856) | class NoopJoinNode extends JoinNode {
    method exec (line 1857) | exec(context:EvaluationContext, input:Change, prefix:Prefix, transacti...
  class WatchNode (line 1867) | class WatchNode extends Node {
    method constructor (line 1869) | constructor(public e:ID|Register,
    method toString (line 1880) | toString() {
    method exec (line 1884) | exec(context:EvaluationContext, input:Change, prefix:Prefix, transacti...
  class OutputWrapperNode (line 1905) | class OutputWrapperNode extends Node {
    method constructor (line 1907) | constructor(public nodes:OutputNode[]) {
    method toString (line 1911) | toString() {
    method exec (line 1918) | exec(context:EvaluationContext, input:Change, prefix:Prefix, transacti...
  type OutputNode (line 1942) | interface OutputNode {
  class InsertNode (line 1946) | class InsertNode implements OutputNode {
    method constructor (line 1950) | constructor(public e:ID|Register, public a:ID|Register, public v:ID|Re...
    method toString (line 1960) | toString() {
    method setupRegister (line 1964) | setupRegister(field:EAVNField, parts:string[]) {
    method output (line 1976) | output(change:Change, binds:Iterator<Change>, commits:Iterator<Change>) {
    method exec (line 1980) | exec(context:EvaluationContext, input:Change, prefix:Prefix, transacti...
  class CommitInsertNode (line 1997) | class CommitInsertNode extends InsertNode {
    method toString (line 1998) | toString() {
    method output (line 2002) | output(change:Change, binds:Iterator<Change>, commits:Iterator<Change>) {
  class RemoveNode (line 2007) | class RemoveNode extends InsertNode {
    method toString (line 2010) | toString() {
    method exec (line 2014) | exec(context:EvaluationContext, input:Change, prefix:Prefix, transacti...
  class CommitRemoveNode (line 2039) | class CommitRemoveNode extends CommitInsertNode {
    method toString (line 2040) | toString() {
    method exec (line 2048) | exec(context:EvaluationContext, input:Change, prefix:Prefix, transacti...
  class LinearFlow (line 2057) | class LinearFlow extends Node {
    method constructor (line 2062) | constructor(public nodes:Node[]) {
    method toString (line 2066) | toString() {
    method exec (line 2071) | exec(context:EvaluationContext, input:Change, prefix:Prefix, transacti...
  type KeyFunction (line 2101) | type KeyFunction = (prefix:Prefix) => string;
  class IntermediateIndexIterator (line 2103) | class IntermediateIndexIterator {
    method reset (line 2115) | reset(values:{[value:string]: any[]}, minRound = 0) {
    method next (line 2127) | next():Prefix|undefined {
  class IntermediateIndex (line 2165) | class IntermediateIndex {
    method CreateKeyFunction (line 2166) | static CreateKeyFunction(registers:Register[]):KeyFunction {
    method insert (line 2179) | insert(key:string, prefix:Prefix) {
    method iter (line 2205) | iter(key:string, round:number):IntermediateIndexIterator|undefined {
    method hashPrefix (line 2210) | hashPrefix(prefix:Prefix) {
  class ZeroingIterator (line 2222) | class ZeroingIterator {
    method reset (line 2229) | reset(counts:Multiplicity[], minRound:number = 0) {
    method next (line 2238) | next():number|undefined {
  class KeyOnlyIntermediateIndex (line 2279) | class KeyOnlyIntermediateIndex {
    method insert (line 2283) | insert(key:string, prefix:Prefix) {
    method has (line 2304) | has(key:string) {
    method iter (line 2308) | iter(key:string, round:number):ZeroingIterator|undefined {
  method constructor (line 2317) | constructor(public left:Node, public right:Node) {
  method exec (line 2321) | exec(context:EvaluationContext, input:Change, prefix:Prefix, transaction...
  class BinaryJoinRight (line 2347) | class BinaryJoinRight extends BinaryFlow {
    method constructor (line 2352) | constructor(public left:Node, public right:Node, public keyRegisters:R...
    method toString (line 2359) | toString() {
    method toBranchString (line 2369) | toBranchString() {
    method exec (line 2380) | exec(context:EvaluationContext, input:Change, prefix:Prefix, transacti...
    method merge (line 2400) | merge(left:Prefix, right:Prefix) {
    method onLeft (line 2413) | onLeft(context:EvaluationContext, prefix:Prefix, transaction:number, r...
    method onRight (line 2434) | onRight(context:EvaluationContext, prefix:Prefix, transaction:number, ...
  class AntiJoin (line 2456) | class AntiJoin extends BinaryFlow {
    method constructor (line 2463) | constructor(public left:Node, public right:Node, public keyRegisters:R...
    method toString (line 2468) | toString() {
    method toBranchString (line 2473) | toBranchString() {
    method exec (line 2478) | exec(context:EvaluationContext, input:Change, prefix:Prefix, transacti...
    method onLeft (line 2483) | onLeft(context:EvaluationContext, prefix:Prefix, transaction:number, r...
    method onRight (line 2506) | onRight(context:EvaluationContext, prefix:Prefix, transaction:number, ...
  class AntiJoinPresolvedRight (line 2542) | class AntiJoinPresolvedRight extends AntiJoin {
    method toString (line 2543) | toString() {
    method toBranchString (line 2546) | toBranchString() {
    method exec (line 2551) | exec(context:EvaluationContext, input:Change, prefix:Prefix, transacti...
  class UnionFlow (line 2570) | class UnionFlow extends Node {
    method constructor (line 2575) | constructor(public left:Node, branches:Node[], public keyRegisters:Reg...
    method toString (line 2584) | toString() {
    method exec (line 2593) | exec(context:EvaluationContext, input:Change, prefix:Prefix, transacti...
  class ChooseFlow (line 2639) | class ChooseFlow extends Node {
    method constructor (line 2645) | constructor(public left:Node, initialBranches:Node[], public keyRegist...
    method toString (line 2674) | toString() {
    method exec (line 2684) | exec(context:EvaluationContext, input:Change, prefix:Prefix, transacti...
  class MergeAggregateFlow (line 2737) | class MergeAggregateFlow extends BinaryJoinRight {
    method exec (line 2740) | exec(context:EvaluationContext, input:Change, prefix:Prefix, transacti...
  class AggregateOuterLookup (line 2787) | class AggregateOuterLookup extends BinaryFlow {
    method constructor (line 2794) | constructor(public left:Node, public right:Node, public keyRegisters:R...
    method toString (line 2799) | toString() {
    method exec (line 2809) | exec(context:EvaluationContext, input:Change, prefix:Prefix, transacti...
    method onLeft (line 2827) | onLeft(context:EvaluationContext, prefix:Prefix, transaction:number, r...
    method onRight (line 2851) | onRight(context:EvaluationContext, prefix:Prefix, transaction:number, ...
  method constructor (line 2870) | constructor(public groupRegisters:Register[], public projectRegisters:Re...
  method toString (line 2882) | toString() {
  method groupPrefix (line 2890) | groupPrefix(group:string, prefix:Prefix) {
  method getResultPrefix (line 2929) | getResultPrefix(prefix:Prefix, result:ID, count:Multiplicity):Prefix {
  method resolve (line 2943) | resolve(prefix:Prefix):RawValue[] {
  method stateToResult (line 2957) | stateToResult(state:any):ID {
  method exec (line 2962) | exec(context:EvaluationContext, input:Change, prefix:Prefix, transaction...
  method constructor (line 3024) | constructor(public groupRegisters:Register[], public projectRegisters:Re...
  method groupPrefix (line 3031) | groupPrefix(group:string, prefix:Prefix) {
  method resolve (line 3069) | resolve(prefix:Prefix):ID[] {
  method isGreater (line 3089) | isGreater(a:Prefix, b:Prefix):string|false {
  method prefixEqual (line 3109) | prefixEqual(a:Prefix, b:Prefix) {
  method exec (line 3120) | exec(context:EvaluationContext, input:Change, prefix:Prefix, transaction...
  method resultPrefix (line 3154) | resultPrefix(prefix:Prefix, outOffset:number, pos:number, round:number, ...
  method newResultState (line 3206) | newResultState():any {
  class Block (line 3216) | class Block {
    method constructor (line 3217) | constructor(public name:string, public nodes:Node[], public totalRegis...
    method toString (line 3226) | toString() {
    method exec (line 3231) | exec(context:EvaluationContext, input:Change, transaction:Transaction)...
  class EvaluationContext (line 3262) | class EvaluationContext {
    method constructor (line 3268) | constructor(public index:Index) {
  type ExportHandler (line 3277) | type ExportHandler = (blockChanges:{[id:number]: Change[]|undefined}) =>...
  class Transaction (line 3279) | class Transaction {
    method constructor (line 3288) | constructor(public context:EvaluationContext, public transaction:numbe...
    method output (line 3292) | output(context:EvaluationContext, change:Change) {
    method commit (line 3312) | commit(context:EvaluationContext, change:Change) {
    method export (line 3323) | export(context:EvaluationContext, blockId:number, change:Change) {
    method prepareRound (line 3328) | protected prepareRound(context:EvaluationContext, changeIx:number) {
    method collapseCommits (line 3374) | protected collapseCommits(changes:Change[], results:Change[] /* output...
    method collapseMultiplicity (line 3424) | protected collapseMultiplicity(changes:Change[], results:Change[] /* o...
    method exec (line 3460) | exec(context:EvaluationContext) {
  class BlockChangeTransaction (line 3546) | class BlockChangeTransaction extends Transaction {
    method constructor (line 3547) | constructor(public context:EvaluationContext, public transaction:numbe...
    method exec (line 3551) | exec(context:EvaluationContext) {

FILE: src/runtime/stdlib.ts
  type SumAggregateState (line 403) | type SumAggregateState = {total:number};
  class SumAggregate (line 404) | class SumAggregate extends AggregateNode {
    method add (line 406) | add(state:SumAggregateState, resolved:RawValue[]):any {
    method remove (line 410) | remove(state:SumAggregateState, resolved:RawValue[]):any {
    method getResult (line 414) | getResult(state:SumAggregateState):RawValue {
    method newResultState (line 417) | newResultState():SumAggregateState {

FILE: src/runtime/trace.ts
  function isID (line 6) | function isID(v: any) {
  function handleArgs (line 14) | function handleArgs(args:any[]) {
  function $row (line 20) | function $row(...args:any[]) {
  function $col (line 27) | function $col(...args:any[]) {
  function $text (line 34) | function $text(...args:any[]) {
  function $button (line 41) | function $button(...args:any[]) {
  function $spacer (line 53) | function $spacer(...args:any[]) {
  type TraceNode (line 63) | enum TraceNode {
  type TraceFrameType (line 77) | enum TraceFrameType {
  type Frame (line 96) | interface Frame {type:TraceFrameType}
  type ProgramFrame (line 97) | interface ProgramFrame extends Frame {transactions: TransactionFrame[]}
  type TransactionFrame (line 98) | interface TransactionFrame extends Frame {id:number, externalInputs:any[...
  class Tracer (line 100) | class Tracer {
    method constructor (line 110) | constructor(public context:EvaluationContext, shouldDraw = true) {
    method changeKey (line 117) | changeKey(change:Change) {
    method current (line 122) | current() {
    method transaction (line 126) | transaction(id:number) {
    method frame (line 131) | frame(commits:Change[]) {
    method indexChange (line 135) | indexChange(change:Change) {
    method input (line 141) | input(input:Change) {
    method block (line 147) | block(name:string) {
    method node (line 153) | node(node:Runtime.Node, inputPrefix:Prefix) {
    method capturePrefix (line 157) | capturePrefix(prefix:Prefix) {
    method _mapOutput (line 162) | _mapOutput(output:Change) {
    method maybeOutput (line 174) | maybeOutput(change:Change) {
    method postDistinct (line 185) | postDistinct() {
    method output (line 191) | output(output:Change) {
    method commit (line 198) | commit(commit:Change) {
    method distinctCheck (line 205) | distinctCheck() {
    method pop (line 224) | pop(type:TraceFrameType) {
    method draw (line 261) | draw() {
    method getInputFrame (line 326) | getInputFrame(program:ProgramFrame, input:Change) {
  class NoopTracer (line 467) | class NoopTracer extends Tracer {
    method constructor (line 471) | constructor(public context:EvaluationContext) {
    method transaction (line 475) | transaction(id:number) { }
    method frame (line 476) | frame(commits:Change[]) { }
    method input (line 477) | input(input:Change) { }
    method block (line 478) | block(name:string) { this.activeBlock = name; }
    method node (line 479) | node(node:Runtime.Node, inputPrefix:Prefix) { }
    method capturePrefix (line 480) | capturePrefix(prefix:Prefix) { }
    method maybeOutput (line 481) | maybeOutput(change:Change) { }
    method postDistinct (line 482) | postDistinct() { }
    method output (line 483) | output(output:Change) { }
    method commit (line 484) | commit(commit:Change) { }
    method distinctCheck (line 485) | distinctCheck() { return false; }
    method pop (line 486) | pop(type:TraceFrameType) { }

FILE: src/system-polyfills.js
  function r (line 4) | function r(u,c){if(!n[u]){if(!e[u]){var f="function"==typeof require&&re...
  function t (line 4) | function t(t){this._async=t,this._running=!1,this._queue=this,this._queu...
  function e (line 4) | function e(t){throw t}
  function n (line 4) | function n(){}
  function i (line 4) | function i(t){t.handled||(l.push(t),a("Potentially unhandled rejection [...
  function u (line 4) | function u(t){var e=l.indexOf(t);e>=0&&(l.splice(e,1),h("Handled previou...
  function c (line 4) | function c(t,e){p.push(t,e),null===d&&(d=o(f,0))}
  function f (line 4) | function f(){for(d=null;p.length>0;)p.shift()(p.shift())}
  function e (line 4) | function e(){return"undefined"!=typeof process&&"[object process]"===Obj...
  function n (line 4) | function n(){return"function"==typeof MutationObserver&&MutationObserver...
  function o (line 4) | function o(t){function e(){var t=n;n=void 0,t()}var n,o=document.createT...
  function t (line 4) | function t(t){var n="object"==typeof t&&null!==t&&(t.stack||t.message)?t...
  function e (line 4) | function e(t){var e=String(t);return"[object Object]"===e&&"undefined"!=...
  function n (line 4) | function n(t,e){try{return JSON.stringify(t)}catch(t){return e}}
  function e (line 4) | function e(t,e){this._handler=t===_?e:n(t)}
  function n (line 4) | function n(t){function e(t){r.resolve(t)}function n(t){r.reject(t)}funct...
  function o (line 4) | function o(t){return k(t)?t:new e(_,new x(v(t)))}
  function r (line 4) | function r(t){return new e(_,new x(new P(t)))}
  function i (line 4) | function i(){return $}
  function u (line 4) | function u(){return new e(_,new b)}
  function c (line 4) | function c(t,e){var n=new b(t.receiver,t.join().context);return new e(_,n)}
  function f (line 4) | function f(t){return a(B,null,t)}
  function s (line 4) | function s(t,e){return a(M,t,e)}
  function a (line 4) | function a(t,n,o){function r(e,r,u){u.resolved||h(o,i,e,t(n,r,e),u)}func...
  function h (line 4) | function h(t,e,n,o,r){if(U(o)){var i=m(o),u=i.state();0===u?i.fold(e,n,v...
  function p (line 4) | function p(t,e,n){for(var o=e;o<t.length;++o)l(v(t[o]),n)}
  function l (line 4) | function l(t,e){if(t!==e){var n=t.state();0===n?t.visit(t,void 0,t._unre...
  function d (line 4) | function d(t){return"object"!=typeof t||null===t?r(new TypeError("non-it...
  function y (line 4) | function y(t){var n,o,r,i=new b;for(n=0;n<t.length;++n)if(o=t[n],void 0!...
  function v (line 4) | function v(t){return k(t)?t._handler.join():U(t)?j(t):new q(t)}
  function m (line 4) | function m(t){return k(t)?t._handler.join():j(t)}
  function j (line 4) | function j(t){try{var e=t.then;return"function"==typeof e?new g(e,t):new...
  function _ (line 4) | function _(){}
  function w (line 4) | function w(){}
  function b (line 4) | function b(t,n){e.createContext(this,n),this.consumers=void 0,this.recei...
  function x (line 4) | function x(t){this.handler=t}
  function g (line 4) | function g(t,e){b.call(this),G.enqueue(new E(t,e,this))}
  function q (line 4) | function q(t){e.createContext(this),this.value=t}
  function P (line 4) | function P(t){e.createContext(this),this.id=++Y,this.value=t,this.handle...
  function R (line 4) | function R(t,e){this.rejection=t,this.context=e}
  function C (line 4) | function C(t){this.rejection=t}
  function O (line 4) | function O(){return new P(new TypeError("Promise cycle"))}
  function T (line 4) | function T(t,e){this.continuation=t,this.handler=e}
  function Q (line 4) | function Q(t,e){this.handler=e,this.value=t}
  function E (line 4) | function E(t,e,n){this._then=t,this.thenable=e,this.resolver=n}
  function L (line 4) | function L(t,e,n,o,r){try{t.call(e,n,o,r)}catch(t){o(t)}}
  function S (line 4) | function S(t,e,n,o){this.f=t,this.z=e,this.c=n,this.to=o,this.resolver=X...
  function k (line 4) | function k(t){return t instanceof e}
  function U (line 4) | function U(t){return("object"==typeof t||"function"==typeof t)&&null!==t}
  function H (line 4) | function H(t,n,o,r){return"function"!=typeof t?r.become(n):(e.enterConte...
  function N (line 4) | function N(t,n,o,r,i){return"function"!=typeof t?i.become(o):(e.enterCon...
  function J (line 4) | function J(t,n,o,r,i){return"function"!=typeof t?i.notify(n):(e.enterCon...
  function M (line 4) | function M(t,e,n){try{return t(e,n)}catch(t){return r(t)}}
  function F (line 4) | function F(t,e,n,o){try{o.become(v(t.call(n,e)))}catch(t){o.become(new P...
  function W (line 4) | function W(t,e,n,o,r){try{t.call(o,e,n,r)}catch(t){r.become(new P(t))}}
  function z (line 4) | function z(t,e,n,o){try{o.notify(t.call(n,e))}catch(t){o.notify(t)}}
  function A (line 4) | function A(t,e){e.prototype=V(t.prototype),e.prototype.constructor=e}
  function B (line 4) | function B(t,e){return e}
  function K (line 4) | function K(){}
  function D (line 4) | function D(){return"undefined"!=typeof process&&null!==process&&"functio...
  function e (line 4) | function e(){}
  function t (line 4) | function t(t){o.resolve(t)}
  function e (line 4) | function e(t){o.reject(t)}
  function n (line 4) | function n(t){o.notify(t)}

FILE: src/system.js
  function e (line 4) | function e(){!function(e){function t(e,r){if("string"!=typeof e)throw ne...

FILE: src/types.d.ts
  type Path2D (line 13) | interface Path2D {
  type Path2DConstructor (line 27) | interface Path2DConstructor {
  type Window (line 36) | interface Window { Path2D: Path2DConstructor; }
  type CanvasRenderingContext2D (line 39) | interface CanvasRenderingContext2D {

FILE: src/watchers/canvas.ts
  function asValue (line 5) | function asValue(value:RawValue|undefined) {
  function ixComparator (line 13) | function ixComparator(idMap:{[key:string]:{ix:number}}) {
  function isOperationType (line 38) | function isOperationType(val:RawValue): val is OperationType {
  constant EMPTY (line 42) | const EMPTY = {};
  type Canvas (line 44) | interface Canvas extends HTMLCanvasElement { __element?: RawValue }
  type OperationType (line 45) | type OperationType = keyof Path2D;
  type Operation (line 46) | interface Operation {type: OperationType, args:any, paths:RawValue[]}
  type PathStyle (line 48) | interface PathStyle {[key:string]: RawValue|undefined, fillStyle?:string...
  class CanvasWatcher (line 50) | class CanvasWatcher extends Watcher {
    method addCanvasInstance (line 79) | addCanvasInstance(canvasId:RawValue, instanceId:RawValue) {
    method clearCanvasInstance (line 83) | clearCanvasInstance(canvasId:RawValue, instanceId:RawValue) {
    method getCanvasInstances (line 92) | getCanvasInstances(canvasId:RawValue) {
    method getCanvasPaths (line 97) | getCanvasPaths(canvasId:RawValue) {
    method addPath (line 101) | addPath(id:RawValue) {
    method clearPath (line 106) | clearPath(id:RawValue) {
    method getPath (line 111) | getPath(id:RawValue) {
    method addOperation (line 117) | addOperation(id:RawValue, type:RawValue) {
    method clearOperation (line 122) | clearOperation(id:RawValue) {
    method getOperation (line 126) | getOperation(id:RawValue) {
    method getOperationArgs (line 132) | getOperationArgs(operation:Operation) {
    method updateCache (line 146) | updateCache(dirtyPaths:RawValue[]) {
    method rerender (line 168) | rerender(dirtyPaths:RawValue[]) {
    method setup (line 212) | setup() {

FILE: src/watchers/compiler.ts
  type CompilationContext (line 12) | interface CompilationContext {
  class CompilerWatcher (line 16) | class CompilerWatcher extends Watcher {
    method queue (line 30) | queue(blockID:string, isAdd = true) {
    method injectInto (line 65) | injectInto(prog:Program) {
    method registerWatcherFunction (line 73) | registerWatcherFunction(name:string, consumer:DiffConsumer) {
    method inContext (line 81) | inContext(flow:LinearFlow, func: () => void) {
    method compileFlow (line 108) | compileFlow(compile:CompilationContext, flow:LinearFlow, constraints: ...
    method compileBlock (line 262) | compileBlock(blockID:string) {
    method setup (line 302) | setup() {

FILE: src/watchers/console.ts
  class ConsoleWatcher (line 5) | class ConsoleWatcher extends Watcher {
    method setup (line 7) | setup() {

FILE: src/watchers/dom.ts
  type Map (line 6) | interface Map<V>{[key:string]: V}
  type Style (line 8) | interface Style extends Map<RawValue|undefined> {__size: number}
  type ElemInstance (line 9) | interface ElemInstance extends Element {__element?: RawValue, __styles?:...
  method _sendEvent (line 27) | protected _sendEvent(eavs:(RawEAV|RawEAVC)[]) {
  method getStyle (line 31) | getStyle(id:RawValue) {
  method isInstance (line 35) | isInstance(elem?:any): elem is Instance {
  method addInstance (line 41) | addInstance(id:RawValue, element:RawValue, tagname:RawValue):Instance|un...
  method clearInstance (line 48) | clearInstance(id:RawValue) {
  method getRoot (line 59) | getRoot(id:RawValue, tagname:RawValue = "div"):Instance|undefined {
  method clearRoot (line 63) | clearRoot(id:RawValue) {
  method insertChild (line 68) | insertChild(parent:Element|null, child:Instance, at = child.__sort) {
  method insertSortedChild (line 90) | insertSortedChild(parent:Element|null, child:Instance, sort?:RawValue) {
  method insertAutoSortedChild (line 97) | insertAutoSortedChild(parent:Element|null, child:Instance, autoSort?:Raw...
  method setStyleAttribute (line 111) | setStyleAttribute(styleId:RawValue, attribute:RawValue, value:RawValue, ...
  method addStyleInstance (line 137) | addStyleInstance(styleId:RawValue, instanceId:RawValue) {
  method removeStyleInstance (line 170) | removeStyleInstance(styleId:RawValue, instanceId:RawValue) {
  method setup (line 186) | setup() {

FILE: src/watchers/editor.ts
  class EditorWatcher (line 8) | class EditorWatcher extends Watcher {
    method setup (line 10) | setup() {
    method initEditor (line 154) | initEditor() {
    method fixtures (line 203) | fixtures() {
    method createEditor (line 278) | createEditor() {
    method navigation (line 296) | navigation() {
    method header (line 329) | header() {
    method nodeTree (line 424) | nodeTree() {
    method queryEditor (line 808) | queryEditor() {
    method moleculeGenerator (line 837) | moleculeGenerator() {
    method moleculeLayout (line 944) | moleculeLayout() {
    method infobox (line 1107) | infobox() {
    method completionGenerator (line 1256) | completionGenerator() {

FILE: src/watchers/file.ts
  class FileWatcher (line 5) | class FileWatcher extends Watcher {
    method setup (line 7) | setup() {

FILE: src/watchers/html.ts
  type Instance (line 5) | interface Instance extends HTMLElement {__element?: RawValue, __styles?:...
  class HTMLWatcher (line 7) | class HTMLWatcher extends DOMWatcher<Instance> {
    method addExternalRoot (line 12) | addExternalRoot(tag:string, element:HTMLElement) {
    method createInstance (line 23) | createInstance(id:RawValue, element:RawValue, tagname:RawValue):Instan...
    method getInstance (line 35) | getInstance(id:RawValue):Instance|undefined {
    method createRoot (line 39) | createRoot(id:RawValue):Instance {
    method addAttribute (line 46) | addAttribute(instance:Instance, attribute:RawValue, value:RawValue|boo...
    method removeAttribute (line 70) | removeAttribute(instance:Instance, attribute:RawValue, value:RawValue|...
    method _updateURL (line 79) | _updateURL(tagname = "url-change") {
    method _mouseEventHandler (line 105) | _mouseEventHandler(tagname:string) {
    method _captureContextMenuHandler (line 145) | _captureContextMenuHandler() {
    method _inputEventHandler (line 161) | _inputEventHandler(tagname:string) {
    method _changeEventHandler (line 181) | _changeEventHandler(tagname:string) {
    method _keyEventHandler (line 230) | _keyEventHandler(tagname:string) {
    method _focusEventHandler (line 255) | _focusEventHandler(tagname:string) {
    method _hoverEventHandler (line 272) | _hoverEventHandler(tagname:string) {
    method _hashChangeHandler (line 291) | _hashChangeHandler(tagname:string) {
    method exportListeners (line 301) | exportListeners({adds, removes}:ObjectDiffs<{listener:string, elemId:I...
    method setup (line 321) | setup() {

FILE: src/watchers/notify.ts
  class Notice (line 4) | class Notice {
    method constructor (line 9) | constructor(public program:Program, public id:RawValue, public type:Ra...
    method clear (line 14) | clear() {
  class NotifyWatcher (line 23) | class NotifyWatcher extends Watcher {
    method setup (line 30) | setup() {

FILE: src/watchers/shape.ts
  class ShapeWatcher (line 3) | class ShapeWatcher extends Watcher {
    method setup (line 4) | setup() {
    method hexagonHTML (line 17) | hexagonHTML() {
    method hexGrid (line 99) | hexGrid() {
    method hexagon (line 131) | hexagon() {
    method squarePath (line 173) | squarePath() {
    method hexagonPath (line 185) | hexagonPath() {

FILE: src/watchers/svg.ts
  type Instance (line 5) | interface Instance extends SVGElement {__element?: RawValue, __styles?: ...
  class SVGWatcher (line 8) | class SVGWatcher extends DOMWatcher<Instance> {
    method createInstance (line 12) | createInstance(id:RawValue, element:RawValue, tagname:RawValue):Instan...
    method getInstance (line 19) | getInstance(id:RawValue):Instance|undefined {
    method createRoot (line 24) | createRoot(id:RawValue) {
    method addAttribute (line 29) | addAttribute(instance:Instance, attribute:RawValue, value:RawValue):vo...
    method removeAttribute (line 34) | removeAttribute(instance:Instance, attribute:RawValue, value:RawValue)...
    method setup (line 39) | setup() {

FILE: src/watchers/system.ts
  class SystemWatcher (line 4) | class SystemWatcher extends Watcher {
    method getTime (line 7) | getTime(changes:any[], timer:ID, tick:number, date?:Date) {
    method setup (line 28) | setup() {

FILE: src/watchers/tag-browser.ts
  type Attrs (line 5) | interface Attrs extends RawMap<RawValue> {}
  function t (line 7) | function t(tag:string) {
  function collapse (line 11) | function collapse<T extends any[]>(...args:T[]):T {
  class TagBrowserWatcher (line 21) | class TagBrowserWatcher extends Watcher {
    method setup (line 24) | setup() {
    method createTagBrowser (line 84) | createTagBrowser() {

FILE: src/watchers/ui.ts
  type Attrs (line 4) | interface Attrs extends RawMap<RawValue|RawValue[]|RawEAV[]> {}
  class UIWatcher (line 6) | class UIWatcher extends Watcher {
    method _addAttrs (line 7) | protected static _addAttrs(id:string, attrs?: Attrs, eavs:RawEAV[] = [...
    method $elem (line 35) | protected static $elem(tag:string, attrs?: Attrs) {
    method _makeContainer (line 44) | protected static _makeContainer(tag:string) {
    method setup (line 92) | setup() {
    method autocomplete (line 359) | autocomplete() {

FILE: src/watchers/watcher.ts
  class Watcher (line 12) | class Watcher {
    method register (line 15) | static register(id:string, watcher:typeof Watcher) {
    method unregister (line 23) | static unregister(id:string) {
    method get (line 27) | static get(id:string) {
    method program (line 32) | get program() { return this._program; }
    method constructor (line 34) | constructor(protected _program:Program) {
    method setup (line 38) | setup() {}
  type Map (line 45) | interface Map<V> {[key:number]: V}
  type RawMap (line 46) | interface RawMap<V> {[key:string]: V, [key:number]: V}
  type RawRecord (line 47) | interface RawRecord extends RawMap<RawValue> {}
  type Diffs (line 49) | interface Diffs<V> {adds: V, removes: V}
  type EAVDiffs (line 50) | interface EAVDiffs extends Diffs<RawEAV[]> {}
  type ObjectDiffs (line 51) | interface ObjectDiffs<T extends RawRecord> extends Diffs<RawMap<T>> {}
  type DiffConsumer (line 53) | type DiffConsumer = (diffs:EAVDiffs) => void;
  type ObjectConsumer (line 54) | type ObjectConsumer<T extends RawRecord> = (diffs:ObjectDiffs<T>) => void;
  class Exporter (line 56) | class Exporter {
    method triggerOnDiffs (line 61) | triggerOnDiffs(blockId:ID, handler:DiffConsumer):void {
    method triggerOnObjects (line 71) | triggerOnObjects<Pattern extends RawRecord>(blockId:ID, handler:Object...
    method accumulateChangesAs (line 81) | accumulateChangesAs<T extends RawRecord>(changes:Change[]) {
  function _isId (line 138) | function _isId(value?:RawValue):boolean {
  function maybeIntern (line 142) | function maybeIntern(value?:RawValue):ID|RawValue|undefined {
  function asJS (line 148) | function asJS(value?:RawValue):number|string|boolean|undefined {
  function forwardDiffs (line 155) | function forwardDiffs(destination:Program, name:string = "Unnamed", debu...
  function createId (line 178) | function createId() {
  function isRawValue (line 182) | function isRawValue(x:any): x is RawValue {
  function isRawValueArray (line 186) | function isRawValueArray(x:any): x is RawValue[] {
  function isRawEAVArray (line 196) | function isRawEAVArray(x:any): x is RawEAV[] {
  function isRawEAVArraySet (line 207) | function isRawEAVArraySet(x:any): x is RawEAV[][] {
  function isRecord (line 211) | function isRecord(x:any): x is Attrs {
  function isRecordSet (line 215) | function isRecordSet(x:any): x is Attrs[] {
  type Attrs (line 219) | interface Attrs extends RawMap<RawValue|RawValue[]|RawEAV[]|RawEAV[][]|A...
  function appendAsEAVs (line 220) | function appendAsEAVs(eavs:any[], record: Attrs, id = createId()) {

FILE: test/antijoin.ts
  function createProgram (line 5) | function createProgram() {

FILE: test/distinct.ts
  function roundCountsToChanges (line 6) | function roundCountsToChanges(rcs:number[][]) {
  function distinctTest (line 14) | function distinctTest(assert:any, roundCounts: number[][], expected: any) {
  type DistinctTest (line 56) | interface DistinctTest {

FILE: test/util.ts
  type EAVTuple (line 6) | type EAVTuple = [Runtime.RawValue, Runtime.RawValue, Runtime.RawValue];
  type EAVRCTuple (line 7) | type EAVRCTuple = [Runtime.RawValue, Runtime.RawValue, Runtime.RawValue,...
  type TestChange (line 8) | type TestChange =  EAVTuple | EAVRCTuple;
  constant TEST_INPUT_NODE (line 11) | let TEST_INPUT_NODE = "test-input-node";
  function pprint (line 13) | function pprint(obj:any):string {
  class EntityId (line 23) | class EntityId {
    method constructor (line 24) | constructor(public id:Runtime.ID) {}
    method toString (line 25) | toString() {
  function o_o (line 30) | function o_o(val:Runtime.ID):EntityId|Runtime.RawValue|undefined {
  function createChanges (line 39) | function createChanges(transaction:number,eavns:TestChange[]) {
  function verify (line 47) | function verify(assert:test.Test, program:Program, input:any[], output:a...
  function time (line 200) | function time(start?:any): number | number[] | string {
  function createInputs (line 206) | function createInputs(inputString:string) {
  function createVerifier (line 241) | function createVerifier<T extends {[name:string]: () => Program}>(progra...

FILE: typings/codemirror/codemirror.d.ts
  type Editor (line 102) | interface Editor {
  type EditorFromTextArea (line 414) | interface EditorFromTextArea extends Editor {
  type DocConstructor (line 426) | interface DocConstructor {
  type Doc (line 431) | interface Doc {
  type LineHandle (line 615) | interface LineHandle {
  type ScrollInfo (line 619) | interface ScrollInfo {
  type TextMarker (line 628) | interface TextMarker {
  type LineWidget (line 639) | interface LineWidget {
  type EditorChange (line 648) | interface EditorChange {
  type EditorChangeLinkedList (line 661) | interface EditorChangeLinkedList extends CodeMirror.EditorChange {
  type EditorChangeCancellable (line 666) | interface EditorChangeCancellable extends CodeMirror.EditorChange {
  type PositionConstructor (line 675) | interface PositionConstructor {
  type Range (line 680) | interface Range{
  type Position (line 685) | interface Position {
  type EditorConfiguration (line 690) | interface EditorConfiguration {
  type TextMarkerOptions (line 847) | interface TextMarkerOptions {
  type StringStream (line 908) | interface StringStream {
  type Mode (line 1022) | interface Mode<T> {
  type ModeFactory (line 1080) | interface ModeFactory<T> {
  type LintStateOptions (line 1115) | interface LintStateOptions {
  type LintOptions (line 1124) | interface LintOptions extends LintStateOptions {
  type AnnotationsCallback (line 1131) | interface AnnotationsCallback {
  type UpdateLintingCallback (line 1138) | interface UpdateLintingCallback {
  type Annotation (line 1146) | interface Annotation {
  type MergeViewEditorConfiguration (line 1162) | interface MergeViewEditorConfiguration extends EditorConfiguration {
  type MergeViewEditor (line 1213) | interface MergeViewEditor extends Editor {
  type MergeViewDiffChunk (line 1242) | interface MergeViewDiffChunk {
  type DiffView (line 1249) | interface DiffView {
  type Options (line 1267) | interface Options {
  class Annotation (line 1274) | class Annotation {
  type Editor (line 1283) | interface Editor {

FILE: typings/commonmark/commonmark.d.ts
  type NodeWalkingStep (line 9) | interface NodeWalkingStep {
  type NodeWalker (line 20) | interface NodeWalker {
  type Position (line 31) | interface Position extends Array<Array<number>> {
  type ListData (line 34) | interface ListData {
  class Node (line 41) | class Node {
  class Parser (line 153) | class Parser {
  type ParserOptions (line 161) | interface ParserOptions {
  type HtmlRenderingOptions (line 169) | interface HtmlRenderingOptions extends XmlRenderingOptions {
  class HtmlRenderer (line 184) | class HtmlRenderer {
  type XmlRenderingOptions (line 200) | interface XmlRenderingOptions {
  class XmlRenderer (line 205) | class XmlRenderer {
Condensed preview — 68 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (912K chars).
[
  {
    "path": ".gitattributes",
    "chars": 392,
    "preview": "build/* linguist-vendored\ncsrc/core/* linguist-vendored\ncsrc/crypto/* linguist-vendored\ncsrc/http/* linguist-vendored\ncs"
  },
  {
    "path": ".gitignore",
    "chars": 688,
    "preview": "# Compiled Lua sources\nluac.out\n\n# luarocks build files\n*.src.rock\n*.zip\n*.tar.gz\n\n# Object files\n*.o\n*.os\n*.ko\n*.obj\n*."
  },
  {
    "path": ".npmignore",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "ATTRIBUTIONS.md",
    "chars": 7626,
    "preview": "# Software Attributions\n\nEve is built using the following technologies generously supplied by their attributed authors i"
  },
  {
    "path": "Dockerfile",
    "chars": 176,
    "preview": "FROM node:6-slim\nMAINTAINER Kodowa, Inc. <info@kodowa.com>\nADD / /eve\nRUN chown -R node:node /eve\nUSER node\nENV HOME /ev"
  },
  {
    "path": "LICENSE",
    "chars": 11357,
    "preview": "                                 Apache License\n                           Version 2.0, January 2004\n                   "
  },
  {
    "path": "Procfile",
    "chars": 152,
    "preview": "web: ./node_modules/.bin/tsc && cp src/*.js build/src/ && cp ./node_modules/chevrotain/lib/chevrotain.js build/src/ && n"
  },
  {
    "path": "README.md",
    "chars": 3694,
    "preview": "<p align=\"center\">\n  <img src=\"http://www.witheve.com/logo.png\" alt=\"Eve logo\" width=\"10%\" />\n</p>\n\n---\n \nEve is a progr"
  },
  {
    "path": "assets/css/app-preview.css",
    "chars": 739,
    "preview": "/*\n * app preview iframe wrapper stylesheets\n */\n\n* { box-sizing:border-box; }\nbody { background: rgb(47,47,49); color: "
  },
  {
    "path": "assets/css/base.css",
    "chars": 6089,
    "preview": "/******************************************************************************\\\n * UI Components                       "
  },
  {
    "path": "assets/css/codemirror.css",
    "chars": 8308,
    "preview": "/* BASICS */\n\n.CodeMirror {\n  /* Set height, width, borders, and global font properties here */\n  font-family: monospace"
  },
  {
    "path": "assets/css/editor.css",
    "chars": 12903,
    "preview": ".editor-view {padding: 40px; align-items: stretch;height: 100%;background: white;}\n\n/***********************************"
  },
  {
    "path": "assets/css/examples/crm.css",
    "chars": 4118,
    "preview": "h3, h4 { font-weight:normal; font-size:16px; }\n\n.container {\n  box-shadow: 0 3px 8px #bbb;\n  width: 400px;\n  height: 711"
  },
  {
    "path": "assets/css/examples/todomvc.css",
    "chars": 6335,
    "preview": ".program {\n    margin: 0 auto;\n    padding: 0;\n    font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;\n    line-h"
  },
  {
    "path": "assets/css/ide.css",
    "chars": 19557,
    "preview": ".flex-spacer { flex: 1; }\n.flex-row { display: flex; flex: 1; flex-direction: row; }\n\n@keyframes hide-delayed {\n    from"
  },
  {
    "path": "assets/css/simplescrollbars.css",
    "chars": 1347,
    "preview": ".CodeMirror-simplescroll-horizontal div, .CodeMirror-simplescroll-vertical div {\n  position: absolute;\n  background: #cc"
  },
  {
    "path": "assets/css/trace.css",
    "chars": 567,
    "preview": ".trace { position:absolute; bottom:20px; right:20px; width:75vw; background: #202020; color: #ccc;  height:70vh; font-fa"
  },
  {
    "path": "bin/eve.js",
    "chars": 3883,
    "preview": "#!/usr/bin/env node\n\"use strict\";\n\nvar path = require(\"path\");\nvar fs = require(\"fs\");\nvar minimist = require(\"minimist\""
  },
  {
    "path": "circle.yml",
    "chars": 36,
    "preview": "machine:\n  node:\n    version: 7.4.0\n"
  },
  {
    "path": "docker-compose.yml",
    "chars": 41,
    "preview": "eve:\n  build: .\n  ports:\n    - 18080:8080"
  },
  {
    "path": "index.html",
    "chars": 880,
    "preview": "<html>\n  <head>\n    <title>Eve</title>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"assets/css/codemirror.css\">\n    "
  },
  {
    "path": "package.json",
    "chars": 1309,
    "preview": "{\n  \"name\": \"witheve\",\n  \"version\": \"0.3.0-preview5\",\n  \"description\": \"Programming designed for humans\",\n  \"keywords\": "
  },
  {
    "path": "src/bootstrap.ts",
    "chars": 916,
    "preview": "import \"setimmediate\";\nimport {Program} from \"./runtime/dsl2\";\nimport * as testUtil from \"../test/util\";\nimport \"./parse"
  },
  {
    "path": "src/index.ts",
    "chars": 297,
    "preview": "export {Watcher, Program, appendAsEAVs, RawEAV, RawEAVC, RawValue, RawMap, RawRecord, createId, EAVDiffs, Diffs} from \"."
  },
  {
    "path": "src/loadWorker.js",
    "chars": 891,
    "preview": "//-------------------------------------------------------------------\n// Web worker initialization\n//-------------------"
  },
  {
    "path": "src/microReact.ts",
    "chars": 22913,
    "preview": "declare var Velocity:any;\n\nexport interface Handler<T extends Event> {\n  (evt:T, elem:uElement): void\n}\nexport interface"
  },
  {
    "path": "src/parser/errors.ts",
    "chars": 9781,
    "preview": "//--------------------------------------------------------------\n// Errors\n//-------------------------------------------"
  },
  {
    "path": "src/parser/parser.ts",
    "chars": 63884,
    "preview": "//-----------------------------------------------------------\n// Parser\n//----------------------------------------------"
  },
  {
    "path": "src/programs/perfReport.ts",
    "chars": 10196,
    "preview": "//---------------------------------------------------------------------\n// Performance Report\n//------------------------"
  },
  {
    "path": "src/runtime/dsl2.ts",
    "chars": 61380,
    "preview": "//@FIXME: This doesn't currently handle chooses/unions that rely on eachother.\n\n//--------------------------------------"
  },
  {
    "path": "src/runtime/indexes.ts",
    "chars": 14355,
    "preview": "import {Proposal, Change, ResolvedValue, createArray, createHash, IGNORE_REG, ID, EAVN, EAVNField,\n        Iterator, Reg"
  },
  {
    "path": "src/runtime/performance.ts",
    "chars": 3609,
    "preview": "//---------------------------------------------------------------------\n// Performance\n//-------------------------------"
  },
  {
    "path": "src/runtime/runtime.ts",
    "chars": 127844,
    "preview": "import {Index, HashIndex, DistinctIndex} from \"./indexes\";\nimport {Tracer, NoopTracer, TraceNode, TraceFrameType} from \""
  },
  {
    "path": "src/runtime/stdlib.ts",
    "chars": 9656,
    "preview": "import {makeFunction, makeMultiFunction, RawValue, AggregateNode} from \"./runtime\";\nimport * as dateformat from \"datefor"
  },
  {
    "path": "src/runtime/trace.ts",
    "chars": 13188,
    "preview": "import {Change, Prefix, EvaluationContext, GlobalInterner, printPrefix} from \"./runtime\";\nimport * as Runtime from \"./ru"
  },
  {
    "path": "src/system-polyfills.js",
    "chars": 12651,
    "preview": "/*\n * SystemJS Promise Polyfill\n */\n!function(t){!function(e){\"object\"==typeof exports?module.exports=e():\"function\"==ty"
  },
  {
    "path": "src/system.js",
    "chars": 61397,
    "preview": "/*\n * SystemJS v0.19.37\n */\n!function(){function e(){!function(e){function t(e,r){if(\"string\"!=typeof e)throw new TypeEr"
  },
  {
    "path": "src/systemJSConfig.js",
    "chars": 852,
    "preview": "if(typeof _watchers === \"undefined\") {\n  console.warn(\"Please run `npm run build` in order to bundle the watchers for th"
  },
  {
    "path": "src/types.d.ts",
    "chars": 1474,
    "preview": "declare module \"falafel\";\ndeclare module \"setimmediate\";\n\ndeclare module \"javascript-natural-sort\" {\n  export = naturalS"
  },
  {
    "path": "src/watchers/canvas.ts",
    "chars": 16014,
    "preview": "import {Watcher, RawMap, RawValue, RawEAV, RawEAVC, maybeIntern} from \"./watcher\";\nimport {HTMLWatcher} from \"./html\";\ni"
  },
  {
    "path": "src/watchers/compiler.ts",
    "chars": 33239,
    "preview": "//--------------------------------------------------------------------\n// The Eve compiler as a watcher\n//--------------"
  },
  {
    "path": "src/watchers/console.ts",
    "chars": 1074,
    "preview": "import * as fs from \"fs\";\nimport {Watcher} from \"./watcher\";\nimport {ID} from \"../runtime/runtime\";\n\nexport class Consol"
  },
  {
    "path": "src/watchers/dom.ts",
    "chars": 13644,
    "preview": "import {Watcher, RawValue, RawEAV, RawEAVC, _isId, asJS} from \"./watcher\";\nimport {v4 as uuid} from \"uuid\";\n\nimport natu"
  },
  {
    "path": "src/watchers/editor.ts",
    "chars": 58198,
    "preview": "//--------------------------------------------------------------------\n// Editor\n//-------------------------------------"
  },
  {
    "path": "src/watchers/file.ts",
    "chars": 2443,
    "preview": "import * as fs from \"fs\";\nimport {Watcher, RawEAV} from \"./watcher\";\nimport {ID} from \"../runtime/runtime\";\n\nexport clas"
  },
  {
    "path": "src/watchers/html.ts",
    "chars": 15924,
    "preview": "import {Watcher, RawValue, RawEAV, RawEAVC, maybeIntern, ObjectDiffs, createId, asJS} from \"./watcher\";\nimport {DOMWatch"
  },
  {
    "path": "src/watchers/index.ts",
    "chars": 431,
    "preview": "export {CanvasWatcher} from \"./canvas\";\nexport {CompilerWatcher} from \"./compiler\";\nexport {HTMLWatcher} from \"./html\";\n"
  },
  {
    "path": "src/watchers/notify.ts",
    "chars": 4536,
    "preview": "import {Program, Watcher, RawValue, RawMap, RawEAVC} from \"./watcher\";\nimport {HTMLWatcher} from \"./html\";\n\nexport class"
  },
  {
    "path": "src/watchers/shape.ts",
    "chars": 7959,
    "preview": "import {Watcher, RawValue, RawEAV, RawEAVC} from \"./watcher\";\n\nexport class ShapeWatcher extends Watcher {\n  setup() {\n "
  },
  {
    "path": "src/watchers/svg.ts",
    "chars": 2909,
    "preview": "import {Watcher, RawValue, RawEAV, RawEAVC} from \"./watcher\";\nimport {DOMWatcher, ElemInstance} from \"./dom\";\nimport {HT"
  },
  {
    "path": "src/watchers/system.ts",
    "chars": 1924,
    "preview": "import {Watcher} from \"./watcher\";\nimport {ID} from \"../runtime/runtime\";\n\nexport class SystemWatcher extends Watcher {\n"
  },
  {
    "path": "src/watchers/tag-browser.ts",
    "chars": 10377,
    "preview": "import {Watcher, Program, RawMap, RawValue, RawEAVC} from \"./watcher\";\n\nimport {UIWatcher} from \"../watchers/ui\";\n\ninter"
  },
  {
    "path": "src/watchers/ui.ts",
    "chars": 22840,
    "preview": "import {Watcher, RawMap, RawValue, RawEAV} from \"./watcher\";\nimport {v4 as uuid} from \"uuid\";\n\nexport interface Attrs ex"
  },
  {
    "path": "src/watchers/watcher.ts",
    "chars": 8173,
    "preview": "import * as path from \"path\";\nexport {RawValue, RawEAV, RawEAVC} from \"../runtime/runtime\";\nimport {ID, GlobalInterner, "
  },
  {
    "path": "syntax_diagrams.html",
    "chars": 876,
    "preview": "<!DOCTYPE html>\n<meta charset=\"utf-8\">\n<style>\n    body {\n        background-color: hsl(30, 20%, 95%)\n    }\n</style>\n\n<!"
  },
  {
    "path": "test/aggregate.ts",
    "chars": 14140,
    "preview": "import {Program} from \"../src/runtime/dsl2\";\nimport {verify} from \"./util\";\nimport * as test from \"tape\";\n\ntest(\"Aggrega"
  },
  {
    "path": "test/all.ts",
    "chars": 175,
    "preview": "import \"./foundation\";\nimport \"./distinct\";\nimport \"./antijoin\";\nimport \"./choose\";\nimport \"./union\";\nimport \"./aggregat"
  },
  {
    "path": "test/antijoin.ts",
    "chars": 7017,
    "preview": "import {Program} from \"../src/runtime/dsl2\";\nimport {verify, createVerifier} from \"./util\";\nimport * as test from \"tape\""
  },
  {
    "path": "test/choose.ts",
    "chars": 21625,
    "preview": "import {Program} from \"../src/runtime/dsl2\";\nimport {verify, createVerifier} from \"./util\";\nimport * as test from \"tape\""
  },
  {
    "path": "test/distinct.ts",
    "chars": 5244,
    "preview": "import {DistinctIndex} from \"../src/runtime/indexes\";\nimport {Change, Iterator} from \"../src/runtime/runtime\";\nimport {v"
  },
  {
    "path": "test/foundation.ts",
    "chars": 14582,
    "preview": "import {Program} from \"../src/runtime/dsl2\";\nimport {verify} from \"./util\";\nimport * as test from \"tape\";\n\ntest(\"find a "
  },
  {
    "path": "test/performance.ts",
    "chars": 1284,
    "preview": "import {Program} from \"../src/runtime/dsl2\";\nimport {verify, createChanges, time} from \"./util\";\nimport {HashIndex} from"
  },
  {
    "path": "test/stdlib/math.ts",
    "chars": 2054,
    "preview": "import {Program} from \"../../src/runtime/dsl2\";\nimport {verify} from \"../util\";\nimport * as test from \"tape\";\n\ntest(\"std"
  },
  {
    "path": "test/union.ts",
    "chars": 11802,
    "preview": "import {Program} from \"../src/runtime/dsl2\";\nimport {verify, createVerifier, pprint} from \"./util\";\nimport * as test fro"
  },
  {
    "path": "test/util.ts",
    "chars": 10142,
    "preview": "import {Program} from \"../src/runtime/dsl2\";\nimport * as Runtime from \"../src/runtime/runtime\";\nimport * as test from \"t"
  },
  {
    "path": "tsconfig.json",
    "chars": 435,
    "preview": "{\n  \"compilerOptions\": {\n    \"declaration\": true,\n    \"module\": \"commonjs\",\n    \"moduleResolution\": \"node\",\n    \"outDir\""
  },
  {
    "path": "typings/codemirror/codemirror.d.ts",
    "chars": 69750,
    "preview": "// Type definitions for CodeMirror\n// Project: https://github.com/marijnh/CodeMirror\n// Definitions by: mihailik <https:"
  },
  {
    "path": "typings/commonmark/commonmark.d.ts",
    "chars": 7091,
    "preview": "// Type definitions for commonmark.js 0.22.1\n// Project: https://github.com/jgm/commonmark.js\n// Definitions by: Nico Ja"
  }
]

About this extraction

This page contains the full source code of the witheve/Eve GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 68 files (851.0 KB), approximately 226.3k tokens, and a symbol index with 919 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!