Explorar o código

Added markdown processing to webpack

* Added help page based on markdown
* Moved some vue files related to flow
luis %!s(int64=7) %!d(string=hai) anos
pai
achega
6102cd232d

+ 16 - 8
browser/vue-flow/package.json

@@ -6,16 +6,24 @@
   "license": "MIT",
   "private": true,
   "scripts": {
-    "docker":
-      "docker build --rm -t hexasoftware.com:5000/flow-proto -f ./docker/Dockerfile .",
+    "docker": "docker build --rm -t hexasoftware.com:5000/flow-proto -f ./docker/Dockerfile .",
     "docker-pull": "docker push hexasoftware.com:5000/flow-proto",
     "dev": "cross-env NODE_ENV=development webpack-dev-server --hot",
     "build": "cross-env NODE_ENV=production webpack --hide-modules"
   },
   "dependencies": {
-    "vue": "^2.5.11"
+    "github-markdown-css": "^2.10.0",
+    "vue": "^2.5.11",
+    "vue-router": "^3.0.1",
+    "vue2-smooth-scroll": "^1.0.1",
+    "vuex": "^3.0.1",
+    "vuex-router-sync": "^5.0.0"
   },
-  "browserslist": ["> 1%", "last 2 versions", "not ie <= 8"],
+  "browserslist": [
+    "> 1%",
+    "last 2 versions",
+    "not ie <= 8"
+  ],
   "devDependencies": {
     "babel-core": "^6.26.0",
     "babel-eslint": "^8.2.1",
@@ -38,17 +46,17 @@
     "file-loader": "^1.1.4",
     "flow": "^0.2.3",
     "flow-bin": "^0.62.0",
+    "highlight-loader": "^0.7.2",
+    "html-loader": "^0.5.5",
     "html-webpack-plugin": "^2.30.1",
+    "markdown-loader": "^2.0.2",
+    "marked": "^0.3.12",
     "node-sass": "^4.7.2",
-    "pug": "^2.0.0-rc.4",
     "reset-css": "^2.2.1",
     "sass-loader": "^6.0.6",
     "vue-loader": "^13.0.5",
-    "vue-router": "^3.0.1",
     "vue-svg-loader": "^0.4.0",
     "vue-template-compiler": "^2.4.4",
-    "vuex": "^3.0.1",
-    "vuex-router-sync": "^5.0.0",
     "webpack": "^3.6.0",
     "webpack-dev-server": "^2.9.1"
   }

+ 1 - 5
browser/vue-flow/src/assets/dark-theme.css

@@ -2,7 +2,7 @@
   --header-background: #212121;
   --header-color: #eee;
   --background: #303030;
-  --background-transparent: rgba(48, 48, 48, 0.7);
+  --background-transparent: rgba(48, 48, 48, 1);
   --background-secondary: #424242;
   --background-tertiary: #323232;
 
@@ -54,7 +54,3 @@
 .dark .flow-node__activity {
   fill: var(--background-secondary);
 }
-
-.dark .app-info {
-  opacity: 0.1;
-}

+ 21 - 3
browser/vue-flow/src/assets/default-theme.css

@@ -40,6 +40,11 @@
   color: var(--primary-inverse) !important;
 }
 
+a {
+  color: var(--primary);
+  text-decoration: none;
+}
+
 button.active:hover::after,
 .primary-inverse:hover::after {
   content: " ";
@@ -49,7 +54,7 @@ button.active:hover::after,
   bottom: 0;
   left: 0;
   transition: all var(--transition-speed);
-  opacity: 0.4;
+  opacity: 0.2;
   background: #000;
 }
 
@@ -93,7 +98,10 @@ input {
   transition: all var(--transition-speed);
 }
 
-h3 {
+.flow-main h1,
+.flow-main h2,
+.flow-main h3,
+.flow-main h4 {
   font-weight: bold;
   color: var(--primary);
 }
@@ -389,7 +397,17 @@ h3 {
   color: var(--normal);
 }
 
-/* End notification */
+/***************************
+ * MARKDOWN
+ ****************/
+.markdown-body pre {
+  background: #333;
+  color: #eee;
+}
+
+.markdown-body pre * {
+  text-shadow: 0 -1px 1px #000;
+}
 
 .fade-enter-active,
 .fade-leave-active {

+ 16 - 0
browser/vue-flow/src/assets/doc/appinfo.md

@@ -0,0 +1,16 @@
+#### Editor
+
+* **Collaboration**: Using the same url address, others can join the session
+* **Pan**: Drag with Middle mouse or Ctrl+left mouse button
+* **Zoom**: Mouse wheel up and down to zoom in and out
+* **Reset**: Reset view by pressing on the reset button
+
+#### Flow
+
+* **New Node**: Create a node by dragging a fn from left panel into area
+* **Remove Node**: Middle click in a node to remove a node
+* **Inspect node**: Double click on a node to get detailed information
+* **Move Node**: Mouse click and drag
+* **Links**: Press [shift] and Drag from a node/socket to a socket highlighted in green
+* **Links(alternative)**: Toggle socket visualisation in the panel and Drag from a socket to a socket highlighted in green
+* **Remove Link**: Simple click on the link when it turns red

+ 44 - 0
browser/vue-flow/src/assets/doc/help.md

@@ -0,0 +1,44 @@
+# Flow
+
+> A flow works by requesting the previous nodes the results of its operation,
+> so the starting node will be the node we want the result of, unattached nodes wont be executed`
+
+All nodes are Go functions.
+Here's an example of a Flow app with a node having a single string output:
+
+```go
+package main
+
+import (
+  "flow/registry"
+  "flowserver"
+  "net/http"
+)
+
+func main() {
+
+  r := registry.New()
+  r.Add("hello", func() string {
+    return "hello world"
+  })
+
+  http.ListenAndServe(":5000", flowserver.New(r,"storename"))
+
+}
+```
+
+<a target="_blank" :href="'http://'+ location.host +'/c1.html'">sample1</a><br>
+Every function can be registered including from external packages as shown in
+<a target="_blank" :href="'http://'+ location.host +'/c2.html'">sample2</a><br>
+Describing functions:
+<a target="_blank" :href="'http://'+ location.host +'/c3.html'">sample3</a><br>
+
+![img/c2.jpg](img/c2.jpg)
+
+```go
+package main
+
+func main() {
+
+}
+```

BIN=BIN
browser/vue-flow/src/assets/doc/img/c2.jpg


BIN=BIN
browser/vue-flow/src/assets/doc/img/c3.jpg


BIN=BIN
browser/vue-flow/src/assets/doc/img/sample.png


+ 12 - 7
browser/vue-flow/src/components/main.vue

@@ -60,9 +60,10 @@
     <hx-modal class="app-modal__info" v-if="helpModal" @close="helpModal=false">
       <h4 slot="header">INFO</h4>
       <app-info slot="body"/>
-      <div slot="footer">
+      <template slot="footer">
+        <a href="help" target="_blank">More information</a>
         <button class="primary-inverse" @click="helpModal=false">OK</button>
-      </div>
+      </template>
 
     </hx-modal>
   </div>
@@ -72,12 +73,12 @@ import {mapGetters, mapActions} from 'vuex'
 import FlowEditor from '@/components/flow/editor'
 import FlowPanzoom from '@/components/flow/panzoom'
 import FlowNotifications from '@/components/flow/notifications'
-import FlowInspector from './panel-inspector'
-import FlowFuncs from './panel-funcs'
+import FlowInspector from '@/components/flow/panel-inspector'
+import FlowFuncs from '@/components/flow/panel-funcs'
 import HxSplit from '@/components/shared/hx-split'
 import HxModal from '@/components/shared/hx-modal'
-import AppChat from '@/components/chat'
-import AppInfo from '@/components/app-info'
+import AppChat from '@/components/flow/chat'
+import AppInfo from '@/components/flow/modal-info'
 import 'reset-css/reset.css'
 
 import '@/assets/dark-theme.css'
@@ -115,7 +116,7 @@ export default {
     // Handle incoming things
     this.$flowService.on('sessionJoin', (v) => {
       if (v.id !== this.$route.params.sessId) {
-        this.$router.push('/' + this.$route.params.context + '/' + v.id) // Swap to ID
+        this.$router.push('/' + this.$route.params.context + '/s:' + v.id) // Swap to ID
       }
     })
     this.$flowService.on('sessionLog', (v) => {
@@ -276,6 +277,10 @@ export default {
   flex:1;
 }
 
+.hx-modal__header h4{
+  color: var(--normal) !important;
+}
+
 /*
 .flow-modal__info {
   padding-bottom:20px;

+ 130 - 0
browser/vue-flow/src/components/app-help.vue

@@ -0,0 +1,130 @@
+<template>
+  <div class="app-help">
+    <div class="app-help__menu">
+      <hx-tree :items="menu" container=".app-help__container"/>
+    </div>
+    <div class="app-help__container">
+      <div
+        class="app-help__content markdown-body"
+        v-html="content"/>
+    </div>
+  </div>
+</template>
+<script>
+import helpmd from '@/assets/doc/help.md'
+import HxTree from '@/components/shared/hx-tree'
+import 'github-markdown-css'
+import 'highlight.js/styles/monokai.css'
+
+export default {
+  components: {HxTree},
+  data () {
+    return {
+      menu: [],
+      content: helpmd
+    }
+  },
+  mounted () {
+    const elist = this.$el.querySelectorAll('h1,h2,h3,h4')
+
+    let curH1
+    let curH2
+    let curH3
+    Array.from(elist).forEach(e => {
+      const item = {name: e.innerText, link: '#' + e.getAttribute('id'), children: []}
+
+      switch (e.tagName) {
+        case 'H1':
+          curH1 = item
+          this.menu.push(curH1)
+          break
+        case 'H2':
+          curH2 = item
+          curH1.children.push(curH2)
+          break
+        case 'H3':
+          curH3 = item
+          curH2.children.push(curH3)
+          break
+        case 'H4':
+          curH3.children.push(item)
+      }
+    })
+  }
+}
+</script>
+<style>
+.app-help {
+  display:flex;
+  flex-flow:row;
+  align-items: stretch;
+  width:100%;
+}
+
+.app-help__menu {
+  flex-grow:0;
+  min-width:170px;
+  height:100vh;
+  padding-top:100px;
+  border-right: solid 1px rgba(150,150,150,0.5);
+  overflow-y:auto;
+}
+
+.app-help__menu ul{
+  list-style: none;
+  padding:0;
+  margin:0;
+  font-weight:normal;
+  padding-left:15px;
+  font-size:14px;
+  border:none;
+}
+
+.app-help__menu > ul {
+  font-weight:bold;
+  font-size:24px;
+}
+
+.app-help__menu > ul > li > a{
+  border-bottom: solid 1px ;
+}
+
+.app-help__menu > ul >li>ul{
+  padding:0;
+}
+
+.app-help__menu > ul >li>ul ul{
+  border-left: dashed 1px rgba(100,100,100,0.2);
+}
+
+.app-help__menu ul li {
+  line-height:40px;
+}
+
+.app-help__menu ul li a {
+  white-space: nowrap;
+  text-decoration: none;
+  width:100%;
+  color: #333;
+  transition: all 0.3s;
+  border-bottom: solid 2px transparent;
+}
+
+.app-help__menu ul li a:hover {
+  border-bottom: solid 2px var(--primary);
+}
+
+.app-help__container {
+  overflow-y:auto;
+
+}
+
+.app-help__content {
+  flex:1;
+  padding:40px;
+  padding-left:10%;
+  padding-right: calc(100% - 1200px);
+  padding-right: 20%;
+}
+
+</style>

browser/vue-flow/src/components/chat.vue → browser/vue-flow/src/components/flow/chat.vue


+ 24 - 7
browser/vue-flow/src/components/app-info.vue

@@ -1,6 +1,7 @@
 <template>
-  <div class="app-info">
-    <section class="app-info__section app-info--view">
+  <div class="app-info markdown-body" v-html="content">
+
+    <!--<section class="app-info__section app-info--view">
       <h4>Editor</h4>
       <ul>
         <li><b>Collaboration</b>: Using the same url address, others can join the session</li>
@@ -58,15 +59,19 @@
     </ul>
     <br>
     <small>&copy; Luis Figueiredo (luisf@hexasoftware.com)</small>
+    -->
   </div>
 </template>
 <script>
+import md from '@/assets/doc/appinfo.md'
+import 'github-markdown-css'
+import 'highlight.js/styles/monokai.css'
+
 export default {
 
-  computed: {
-    location () {
-      console.log(window.location)
-      return window.location
+  data () {
+    return {
+      content: md
     }
   }
 }
@@ -74,8 +79,20 @@ export default {
 <style>
 .app-info {
   flex:1;
+  padding-top:20px;
+}
+
+.hx-modal__container {
+  width:70%;
+  height:90vh;
 }
 
+.markdown-body a {
+  color: var(--primary);
+  text-decoration: none;
+}
+
+/*
 .app-info--info {
   font-size:14px;
 }
@@ -95,6 +112,6 @@ export default {
 
 .app-info__section li {
   padding:4px;
-}
+}*/
 
 </style>

browser/vue-flow/src/components/panel-funcs.vue → browser/vue-flow/src/components/flow/panel-funcs.vue


browser/vue-flow/src/components/panel-inspector.vue → browser/vue-flow/src/components/flow/panel-inspector.vue


+ 11 - 1
browser/vue-flow/src/components/shared/hx-modal.vue

@@ -1,6 +1,6 @@
 <template>
   <transition name="hx-modal">
-    <div class="hx-modal__mask" @click="$emit('close')">
+    <div class="hx-modal__mask" @click="$emit('close')" tabindex="1" @keydown.esc="$emit('close')">
       <div class="hx-modal__wrapper" >
         <div class="hx-modal__container" @click.stop>
           <div class="hx-modal__header">
@@ -24,10 +24,16 @@
   </transition>
 </template>
 <script>
+export default {
+  mounted () {
+    this.$el.focus()
+  }
+}
 </script>
 <style lang="css" >
 
 .hx-modal__mask {
+  outline:none;
   position: fixed;
   z-index: 9998;
   top: 0;
@@ -70,6 +76,10 @@
 }
 
 .hx-modal__footer {
+  display:flex;
+  width:100%;
+  justify-content: space-between;
+  align-items: center;
   text-align:right;
   flex-basis:40px;
 }

+ 46 - 0
browser/vue-flow/src/components/shared/hx-tree.vue

@@ -0,0 +1,46 @@
+<template>
+  <ul class="hx-tree">
+    <template v-for="e of items">
+      <li
+        class="hx-tree__item"
+        :key="e.name">
+        <a
+          v-if="e.link[0] == '#'"
+          :href="e.link"
+          v-smooth-scroll="{container:container}">{{ e.name }}</a>
+        <a
+          v-else
+          :href="e.link"
+        >{{ e.name }}</a>
+      </li>
+      <li :key="e.name + 'list'">
+        <hx-tree
+          :items="e.children"
+          :container="container"/>
+      </li>
+    </template>
+  </ul>
+</template>
+
+<script>
+import Vue from 'vue'
+import vueSmoothScroll from 'vue2-smooth-scroll'
+Vue.use(vueSmoothScroll)
+
+export default {
+  name: 'HxTree',
+  props: {
+    items: { type: Array, default: () => [] },
+    container: { type: String, default: undefined }
+  },
+  mounted () {
+    console.log('Type of:', typeof (this.container))
+  }
+
+}
+</script>
+<style>
+.hx-tree a {
+  cursor:pointer;
+}
+</style>

+ 9 - 4
browser/vue-flow/src/router/index.js

@@ -1,15 +1,20 @@
 import Vue from 'vue'
 import Router from 'vue-router'
-import FlowMain from '@/components/main'
+import AppFlow from '@/components/app-flow'
+import AppHelp from '@/components/app-help'
 
 Vue.use(Router)
 
 export default new Router({
   mode: 'history',
   routes: [
-    { path: '/', component: FlowMain },
-    { path: '/:context', component: FlowMain },
-    { path: '/:context/:sessId', component: FlowMain }
+    { path: '/', component: AppFlow },
+    { path: '/:context', component: AppFlow },
+    { path: '/:context/help', component: AppHelp },
+    { path: '/:context/s\\::sessId', component: AppFlow },
+    // Backward compatibilitie
+    { path: '/:context/:sessId', redirect: '/:context/s\\::sessId' }
+
   ]
 
 })

+ 13 - 2
browser/vue-flow/webpack.config.js

@@ -1,7 +1,7 @@
 var path = require('path')
 var webpack = require('webpack')
 var HtmlWebpackPlugin = require('html-webpack-plugin')
-// var CopyWebpackPlugin = require('copy-webpack-plugin')
+var CopyWebpackPlugin = require('copy-webpack-plugin')
 
 var outfile = 'index.js'
 
@@ -11,7 +11,6 @@ module.exports = {
     path: path.resolve(__dirname, './dist'),
     publicPath: '',
     filename: outfile
-    // libraryTarget: 'commonjs2'
   },
   module: {
     rules: [
@@ -91,9 +90,21 @@ module.exports = {
         options: {
           name: '[name]-[hash].[ext]'
         }
+      },
+      {
+        test: /\.md$/,
+        loader: 'html-loader!highlight-loader!markdown-loader'
       }
+      /*,
+      {
+        test: /\.md$/,
+        use: 'raw-loader'
+      } */
     ]
   },
+  plugins: [
+    new CopyWebpackPlugin(['static'])
+  ],
   resolve: {
     alias: {
       '@': path.join(__dirname, 'src'),

+ 151 - 206
browser/vue-flow/yarn.lock

@@ -124,23 +124,17 @@ acorn-dynamic-import@^2.0.0:
   dependencies:
     acorn "^4.0.3"
 
-acorn-globals@^3.0.0:
-  version "3.1.0"
-  resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-3.1.0.tgz#fd8270f71fbb4996b004fa880ee5d46573a731bf"
-  dependencies:
-    acorn "^4.0.4"
-
 acorn-jsx@^3.0.0:
   version "3.0.1"
   resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b"
   dependencies:
     acorn "^3.0.4"
 
-acorn@^3.0.4, acorn@^3.1.0, acorn@~3.3.0:
+acorn@^3.0.4:
   version "3.3.0"
   resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a"
 
-acorn@^4.0.3, acorn@^4.0.4, acorn@~4.0.2:
+acorn@^4.0.3:
   version "4.0.13"
   resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.13.tgz#105495ae5361d697bd195c825192e1ad7f253787"
 
@@ -281,10 +275,6 @@ arrify@^1.0.0, arrify@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
 
-asap@~2.0.3:
-  version "2.0.6"
-  resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
-
 asn1.js@^4.0.0:
   version "4.9.2"
   resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.9.2.tgz#8117ef4f7ed87cd8f89044b5bff97ac243a16c9a"
@@ -311,6 +301,10 @@ assert@^1.1.1:
   dependencies:
     util "0.10.3"
 
+ast-types@0.9.6:
+  version "0.9.6"
+  resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.9.6.tgz#102c9e9e9005d3e7e3829bf0c4fa24ee862ee9b9"
+
 async-each@^1.0.0:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d"
@@ -1198,16 +1192,20 @@ chalk@^2.0.0, chalk@^2.1.0, chalk@^2.3.0:
     escape-string-regexp "^1.0.5"
     supports-color "^4.0.0"
 
-character-parser@^2.1.1:
-  version "2.2.0"
-  resolved "https://registry.yarnpkg.com/character-parser/-/character-parser-2.2.0.tgz#c7ce28f36d4bcd9744e5ffc2c5fcde1c73261fc0"
-  dependencies:
-    is-regex "^1.0.3"
-
 chardet@^0.4.0:
   version "0.4.2"
   resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2"
 
+cheerio@^0.19.0:
+  version "0.19.0"
+  resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-0.19.0.tgz#772e7015f2ee29965096d71ea4175b75ab354925"
+  dependencies:
+    css-select "~1.0.0"
+    dom-serializer "~0.1.0"
+    entities "~1.1.1"
+    htmlparser2 "~3.8.1"
+    lodash "^3.2.0"
+
 chokidar@^1.6.0, chokidar@^1.7.0:
   version "1.7.0"
   resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468"
@@ -1250,13 +1248,6 @@ clean-css@4.1.x:
   dependencies:
     source-map "0.5.x"
 
-clean-css@^3.3.0:
-  version "3.4.28"
-  resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-3.4.28.tgz#bf1945e82fc808f55695e6ddeaec01400efd03ff"
-  dependencies:
-    commander "2.8.x"
-    source-map "0.4.x"
-
 cli-cursor@^2.1.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5"
@@ -1356,12 +1347,6 @@ commander@2.12.x, commander@^2.9.0, commander@~2.12.1:
   version "2.12.2"
   resolved "https://registry.yarnpkg.com/commander/-/commander-2.12.2.tgz#0f5946c427ed9ec0d91a46bb9def53e54650e555"
 
-commander@2.8.x:
-  version "2.8.1"
-  resolved "https://registry.yarnpkg.com/commander/-/commander-2.8.1.tgz#06be367febfda0c330aa1e2a072d3dc9762425d4"
-  dependencies:
-    graceful-readlink ">= 1.0.0"
-
 commondir@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
@@ -1416,13 +1401,6 @@ consolidate@^0.14.0:
   dependencies:
     bluebird "^3.1.1"
 
-constantinople@^3.0.1:
-  version "3.1.0"
-  resolved "https://registry.yarnpkg.com/constantinople/-/constantinople-3.1.0.tgz#7569caa8aa3f8d5935d62e1fa96f9f702cd81c79"
-  dependencies:
-    acorn "^3.1.0"
-    is-expression "^2.0.1"
-
 constants-browserify@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75"
@@ -1606,6 +1584,15 @@ css-select@^1.1.0:
     domutils "1.5.1"
     nth-check "~1.0.1"
 
+css-select@~1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.0.0.tgz#b1121ca51848dd264e2244d058cee254deeb44b0"
+  dependencies:
+    boolbase "~1.0.0"
+    css-what "1.0"
+    domutils "1.4"
+    nth-check "~1.0.0"
+
 css-selector-tokenizer@^0.7.0:
   version "0.7.0"
   resolved "https://registry.yarnpkg.com/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz#e6988474ae8c953477bf5e7efecfceccd9cf4c86"
@@ -1614,6 +1601,10 @@ css-selector-tokenizer@^0.7.0:
     fastparse "^1.1.1"
     regexpu-core "^1.0.0"
 
+css-what@1.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/css-what/-/css-what-1.0.0.tgz#d7cc2df45180666f99d2b14462639469e00f736c"
+
 css-what@2.1:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.0.tgz#9467d032c38cfaefb9f2d79501253062f87fa1bd"
@@ -1846,17 +1837,13 @@ doctrine@^2.1.0:
   dependencies:
     esutils "^2.0.2"
 
-doctypes@^1.1.0:
-  version "1.1.0"
-  resolved "https://registry.yarnpkg.com/doctypes/-/doctypes-1.1.0.tgz#ea80b106a87538774e8a3a4a5afe293de489e0a9"
-
 dom-converter@~0.1:
   version "0.1.4"
   resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.1.4.tgz#a45ef5727b890c9bffe6d7c876e7b19cb0e17f3b"
   dependencies:
     utila "~0.3"
 
-dom-serializer@0:
+dom-serializer@0, dom-serializer@~0.1.0:
   version "0.1.0"
   resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.0.tgz#073c697546ce0780ce23be4a28e293e40bc30c82"
   dependencies:
@@ -1881,13 +1868,25 @@ domhandler@2.1:
   dependencies:
     domelementtype "1"
 
+domhandler@2.3:
+  version "2.3.0"
+  resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.3.0.tgz#2de59a0822d5027fabff6f032c2b25a2a8abe738"
+  dependencies:
+    domelementtype "1"
+
 domutils@1.1:
   version "1.1.6"
   resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.1.6.tgz#bddc3de099b9a2efacc51c623f28f416ecc57485"
   dependencies:
     domelementtype "1"
 
-domutils@1.5.1:
+domutils@1.4:
+  version "1.4.3"
+  resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.4.3.tgz#0865513796c6b306031850e175516baf80b72a6f"
+  dependencies:
+    domelementtype "1"
+
+domutils@1.5, domutils@1.5.1:
   version "1.5.1"
   resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf"
   dependencies:
@@ -1958,6 +1957,10 @@ enhanced-resolve@^3.4.0:
     object-assign "^4.0.1"
     tapable "^0.2.7"
 
+entities@1.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/entities/-/entities-1.0.0.tgz#b2987aa3821347fcde642b24fdfc9e4fb712bf26"
+
 entities@~1.1.1:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0"
@@ -2035,6 +2038,13 @@ es6-symbol@3.1.1, es6-symbol@^3.1.1, es6-symbol@~3.1.1:
     d "1"
     es5-ext "~0.10.14"
 
+es6-templates@^0.2.3:
+  version "0.2.3"
+  resolved "https://registry.yarnpkg.com/es6-templates/-/es6-templates-0.2.3.tgz#5cb9ac9fb1ded6eb1239342b81d792bbb4078ee4"
+  dependencies:
+    recast "~0.11.12"
+    through "~2.3.6"
+
 es6-weak-map@^2.0.1:
   version "2.0.2"
   resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.2.tgz#5e3ab32251ffd1538a1f8e5ffa1357772f92d96f"
@@ -2247,6 +2257,10 @@ esprima@^4.0.0:
   version "4.0.0"
   resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804"
 
+esprima@~3.1.0:
+  version "3.1.3"
+  resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633"
+
 esquery@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.0.tgz#cfba8b57d7fba93f17298a8a006a04cda13d80fa"
@@ -2659,6 +2673,10 @@ getpass@^0.1.1:
   dependencies:
     assert-plus "^1.0.0"
 
+github-markdown-css@^2.10.0:
+  version "2.10.0"
+  resolved "https://registry.yarnpkg.com/github-markdown-css/-/github-markdown-css-2.10.0.tgz#0612fed22816b33b282f37ef8def7a4ecabfe993"
+
 glob-base@^0.3.0:
   version "0.3.0"
   resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4"
@@ -2749,10 +2767,6 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.2:
   version "4.1.11"
   resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
 
-"graceful-readlink@>= 1.0.0":
-  version "1.0.1"
-  resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725"
-
 handle-thing@^1.2.5:
   version "1.2.5"
   resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-1.2.5.tgz#fd7aad726bf1a5fd16dfc29b2f7a6601d27139c4"
@@ -2858,6 +2872,23 @@ he@1.1.x, he@^1.1.0:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd"
 
+he@^0.5.0:
+  version "0.5.0"
+  resolved "https://registry.yarnpkg.com/he/-/he-0.5.0.tgz#2c05ffaef90b68e860f3fd2b54ef580989277ee2"
+
+highlight-loader@^0.7.2:
+  version "0.7.2"
+  resolved "https://registry.yarnpkg.com/highlight-loader/-/highlight-loader-0.7.2.tgz#6271a5617cf0dc3e1d01774167ea975d7ace5a9d"
+  dependencies:
+    cheerio "^0.19.0"
+    he "^0.5.0"
+    highlight.js "^9.1.0"
+    loader-utils "^0.2.12"
+
+highlight.js@^9.1.0:
+  version "9.12.0"
+  resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.12.0.tgz#e6d9dbe57cbefe60751f02af336195870c90c01e"
+
 hmac-drbg@^1.0.0:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
@@ -2902,7 +2933,17 @@ html-entities@^1.2.0:
   version "1.2.1"
   resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.2.1.tgz#0df29351f0721163515dfb9e5543e5f6eed5162f"
 
-html-minifier@^3.2.3:
+html-loader@^0.5.5:
+  version "0.5.5"
+  resolved "https://registry.yarnpkg.com/html-loader/-/html-loader-0.5.5.tgz#6356dbeb0c49756d8ebd5ca327f16ff06ab5faea"
+  dependencies:
+    es6-templates "^0.2.3"
+    fastparse "^1.1.1"
+    html-minifier "^3.5.8"
+    loader-utils "^1.1.0"
+    object-assign "^4.1.1"
+
+html-minifier@^3.2.3, html-minifier@^3.5.8:
   version "3.5.8"
   resolved "https://registry.yarnpkg.com/html-minifier/-/html-minifier-3.5.8.tgz#5ccdb1f73a0d654e6090147511f6e6b2ee312700"
   dependencies:
@@ -2935,6 +2976,16 @@ htmlparser2@~3.3.0:
     domutils "1.1"
     readable-stream "1.0"
 
+htmlparser2@~3.8.1:
+  version "3.8.3"
+  resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.8.3.tgz#996c28b191516a8be86501a7d79757e5c70c1068"
+  dependencies:
+    domelementtype "1"
+    domhandler "2.3"
+    domutils "1.5"
+    entities "1.0"
+    readable-stream "1.1"
+
 http-deceiver@^1.2.7:
   version "1.2.7"
   resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87"
@@ -3155,20 +3206,6 @@ is-equal-shallow@^0.1.3:
   dependencies:
     is-primitive "^2.0.0"
 
-is-expression@^2.0.1:
-  version "2.1.0"
-  resolved "https://registry.yarnpkg.com/is-expression/-/is-expression-2.1.0.tgz#91be9d47debcfef077977e9722be6dcfb4465ef0"
-  dependencies:
-    acorn "~3.3.0"
-    object-assign "^4.0.1"
-
-is-expression@^3.0.0:
-  version "3.0.0"
-  resolved "https://registry.yarnpkg.com/is-expression/-/is-expression-3.0.0.tgz#39acaa6be7fd1f3471dc42c7416e61c24317ac9f"
-  dependencies:
-    acorn "~4.0.2"
-    object-assign "^4.0.1"
-
 is-extendable@^0.1.1:
   version "0.1.1"
   resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89"
@@ -3270,7 +3307,7 @@ is-primitive@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575"
 
-is-promise@^2.0.0, is-promise@^2.1.0:
+is-promise@^2.1.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa"
 
@@ -3278,7 +3315,7 @@ is-property@^1.0.0:
   version "1.0.2"
   resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84"
 
-is-regex@^1.0.3, is-regex@^1.0.4:
+is-regex@^1.0.4:
   version "1.0.4"
   resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491"
   dependencies:
@@ -3348,10 +3385,6 @@ js-base64@^2.1.8, js-base64@^2.1.9:
   version "2.4.0"
   resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.4.0.tgz#9e566fee624751a1d720c966cd6226d29d4025aa"
 
-js-stringify@^1.0.1:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/js-stringify/-/js-stringify-1.0.2.tgz#1736fddfd9724f28a3682adc6230ae7e4e9679db"
-
 js-tokens@^3.0.0, js-tokens@^3.0.2:
   version "3.0.2"
   resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
@@ -3433,13 +3466,6 @@ jsprim@^1.2.2:
     json-schema "0.2.3"
     verror "1.10.0"
 
-jstransformer@1.0.0:
-  version "1.0.0"
-  resolved "https://registry.yarnpkg.com/jstransformer/-/jstransformer-1.0.0.tgz#ed8bf0921e2f3f1ed4d5c1a44f68709ed24722c3"
-  dependencies:
-    is-promise "^2.0.0"
-    promise "^7.0.1"
-
 killable@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.0.tgz#da8b84bd47de5395878f95d64d02f2449fe05e6b"
@@ -3506,7 +3532,7 @@ loader-runner@^2.3.0:
   version "2.3.0"
   resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2"
 
-loader-utils@^0.2.15, loader-utils@^0.2.16:
+loader-utils@^0.2.12, loader-utils@^0.2.15, loader-utils@^0.2.16:
   version "0.2.17"
   resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348"
   dependencies:
@@ -3562,6 +3588,10 @@ lodash.uniq@^4.5.0:
   version "4.5.0"
   resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
 
+lodash@^3.2.0:
+  version "3.10.1"
+  resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6"
+
 lodash@^4.0.0, lodash@^4.14.0, lodash@^4.17.2, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.3.0, lodash@~4.17.4:
   version "4.17.4"
   resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
@@ -3612,6 +3642,17 @@ map-obj@^1.0.0, map-obj@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d"
 
+markdown-loader@^2.0.2:
+  version "2.0.2"
+  resolved "https://registry.yarnpkg.com/markdown-loader/-/markdown-loader-2.0.2.tgz#1cdcf11307658cd611046d7db34c2fe80542af7c"
+  dependencies:
+    loader-utils "^1.1.0"
+    marked "^0.3.9"
+
+marked@^0.3.12, marked@^0.3.9:
+  version "0.3.12"
+  resolved "https://registry.yarnpkg.com/marked/-/marked-0.3.12.tgz#7cf25ff2252632f3fe2406bde258e94eee927519"
+
 math-expression-evaluator@^1.2.14:
   version "1.2.17"
   resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz#de819fdbcd84dccd8fae59c6aeb79615b9d266ac"
@@ -3964,7 +4005,7 @@ npm-run-path@^2.0.0:
     gauge "~2.7.3"
     set-blocking "~2.0.0"
 
-nth-check@~1.0.1:
+nth-check@~1.0.0, nth-check@~1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.1.tgz#9929acdf628fc2c41098deab82ac580cf149aae4"
   dependencies:
@@ -3982,7 +4023,7 @@ oauth-sign@~0.8.1, oauth-sign@~0.8.2:
   version "0.8.2"
   resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
 
-object-assign@^4.0.1, object-assign@^4.1.0:
+object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1:
   version "4.1.1"
   resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
 
@@ -4560,7 +4601,7 @@ pretty-error@^2.0.2:
     renderkid "^2.0.1"
     utila "~0.4"
 
-private@^0.1.6, private@^0.1.7:
+private@^0.1.6, private@^0.1.7, private@~0.1.5:
   version "0.1.8"
   resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff"
 
@@ -4580,12 +4621,6 @@ promise-inflight@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3"
 
-promise@^7.0.1:
-  version "7.3.1"
-  resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf"
-  dependencies:
-    asap "~2.0.3"
-
 proxy-addr@~2.0.2:
   version "2.0.2"
   resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.2.tgz#6571504f47bb988ec8180253f85dd7e14952bdec"
@@ -4611,99 +4646,6 @@ public-encrypt@^4.0.0:
     parse-asn1 "^5.0.0"
     randombytes "^2.0.1"
 
-pug-attrs@^2.0.2:
-  version "2.0.2"
-  resolved "https://registry.yarnpkg.com/pug-attrs/-/pug-attrs-2.0.2.tgz#8be2b2225568ffa75d1b866982bff9f4111affcb"
-  dependencies:
-    constantinople "^3.0.1"
-    js-stringify "^1.0.1"
-    pug-runtime "^2.0.3"
-
-pug-code-gen@^2.0.0:
-  version "2.0.0"
-  resolved "https://registry.yarnpkg.com/pug-code-gen/-/pug-code-gen-2.0.0.tgz#96aea39a9e62f1ec5d2b6a5b42a29d528c70b43d"
-  dependencies:
-    constantinople "^3.0.1"
-    doctypes "^1.1.0"
-    js-stringify "^1.0.1"
-    pug-attrs "^2.0.2"
-    pug-error "^1.3.2"
-    pug-runtime "^2.0.3"
-    void-elements "^2.0.1"
-    with "^5.0.0"
-
-pug-error@^1.3.2:
-  version "1.3.2"
-  resolved "https://registry.yarnpkg.com/pug-error/-/pug-error-1.3.2.tgz#53ae7d9d29bb03cf564493a026109f54c47f5f26"
-
-pug-filters@^2.1.5:
-  version "2.1.5"
-  resolved "https://registry.yarnpkg.com/pug-filters/-/pug-filters-2.1.5.tgz#66bf6e80d97fbef829bab0aa35eddff33fc964f3"
-  dependencies:
-    clean-css "^3.3.0"
-    constantinople "^3.0.1"
-    jstransformer "1.0.0"
-    pug-error "^1.3.2"
-    pug-walk "^1.1.5"
-    resolve "^1.1.6"
-    uglify-js "^2.6.1"
-
-pug-lexer@^3.1.0:
-  version "3.1.0"
-  resolved "https://registry.yarnpkg.com/pug-lexer/-/pug-lexer-3.1.0.tgz#fd087376d4a675b4f59f8fef422883434e9581a2"
-  dependencies:
-    character-parser "^2.1.1"
-    is-expression "^3.0.0"
-    pug-error "^1.3.2"
-
-pug-linker@^3.0.3:
-  version "3.0.3"
-  resolved "https://registry.yarnpkg.com/pug-linker/-/pug-linker-3.0.3.tgz#25f59eb750237f0368e59c3379764229c0189c41"
-  dependencies:
-    pug-error "^1.3.2"
-    pug-walk "^1.1.5"
-
-pug-load@^2.0.9:
-  version "2.0.9"
-  resolved "https://registry.yarnpkg.com/pug-load/-/pug-load-2.0.9.tgz#ee217c914cc1d9324d44b86c32d1df241d36de7a"
-  dependencies:
-    object-assign "^4.1.0"
-    pug-walk "^1.1.5"
-
-pug-parser@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/pug-parser/-/pug-parser-4.0.0.tgz#c9f52322e4eabe4bf5beeba64ed18373bb627801"
-  dependencies:
-    pug-error "^1.3.2"
-    token-stream "0.0.1"
-
-pug-runtime@^2.0.3:
-  version "2.0.3"
-  resolved "https://registry.yarnpkg.com/pug-runtime/-/pug-runtime-2.0.3.tgz#98162607b0fce9e254d427f33987a5aee7168bda"
-
-pug-strip-comments@^1.0.2:
-  version "1.0.2"
-  resolved "https://registry.yarnpkg.com/pug-strip-comments/-/pug-strip-comments-1.0.2.tgz#d313afa01bcc374980e1399e23ebf2eb9bdc8513"
-  dependencies:
-    pug-error "^1.3.2"
-
-pug-walk@^1.1.5:
-  version "1.1.5"
-  resolved "https://registry.yarnpkg.com/pug-walk/-/pug-walk-1.1.5.tgz#90e943acbcf7021e6454cf1b32245891cba6f851"
-
-pug@^2.0.0-rc.4:
-  version "2.0.0-rc.4"
-  resolved "https://registry.yarnpkg.com/pug/-/pug-2.0.0-rc.4.tgz#b7b08f6599bd5302568042b7436984fb28c80a13"
-  dependencies:
-    pug-code-gen "^2.0.0"
-    pug-filters "^2.1.5"
-    pug-lexer "^3.1.0"
-    pug-linker "^3.0.3"
-    pug-load "^2.0.9"
-    pug-parser "^4.0.0"
-    pug-runtime "^2.0.3"
-    pug-strip-comments "^1.0.2"
-
 pump@^1.0.0:
   version "1.0.3"
   resolved "https://registry.yarnpkg.com/pump/-/pump-1.0.3.tgz#5dfe8311c33bbf6fc18261f9f34702c47c08a954"
@@ -4866,6 +4808,15 @@ readable-stream@1.0:
     isarray "0.0.1"
     string_decoder "~0.10.x"
 
+readable-stream@1.1:
+  version "1.1.13"
+  resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.13.tgz#f6eef764f514c89e2b9e23146a75ba106756d23e"
+  dependencies:
+    core-util-is "~1.0.0"
+    inherits "~2.0.1"
+    isarray "0.0.1"
+    string_decoder "~0.10.x"
+
 readdirp@^2.0.0:
   version "2.1.0"
   resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78"
@@ -4875,6 +4826,15 @@ readdirp@^2.0.0:
     readable-stream "^2.0.2"
     set-immediate-shim "^1.0.1"
 
+recast@~0.11.12:
+  version "0.11.23"
+  resolved "https://registry.yarnpkg.com/recast/-/recast-0.11.23.tgz#451fd3004ab1e4df9b4e4b66376b2a21912462d3"
+  dependencies:
+    ast-types "0.9.6"
+    esprima "~3.1.0"
+    private "~0.1.5"
+    source-map "~0.5.0"
+
 redent@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde"
@@ -5096,7 +5056,7 @@ resolve-from@^3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748"
 
-resolve@^1.1.6, resolve@^1.2.0, resolve@^1.3.3, resolve@^1.4.0:
+resolve@^1.2.0, resolve@^1.3.3, resolve@^1.4.0:
   version "1.5.0"
   resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36"
   dependencies:
@@ -5357,16 +5317,16 @@ source-map-support@^0.4.15:
   dependencies:
     source-map "^0.5.6"
 
-source-map@0.4.x, source-map@^0.4.2:
+source-map@0.5.x, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.0, source-map@~0.5.1:
+  version "0.5.7"
+  resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
+
+source-map@^0.4.2:
   version "0.4.4"
   resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b"
   dependencies:
     amdefine ">=0.0.4"
 
-source-map@0.5.x, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1:
-  version "0.5.7"
-  resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
-
 source-map@^0.6.1, source-map@~0.6.1:
   version "0.6.1"
   resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
@@ -5611,10 +5571,6 @@ text-table@~0.2.0:
   version "0.2.0"
   resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
 
-three@^0.89.0:
-  version "0.89.0"
-  resolved "https://registry.yarnpkg.com/three/-/three-0.89.0.tgz#4442d819a6168871b8d2cb37ad12a24310c170f5"
-
 through2@^2.0.0:
   version "2.0.3"
   resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be"
@@ -5622,7 +5578,7 @@ through2@^2.0.0:
     readable-stream "^2.1.5"
     xtend "~4.0.1"
 
-through@^2.3.6:
+through@^2.3.6, through@~2.3.6:
   version "2.3.8"
   resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
 
@@ -5658,10 +5614,6 @@ to-fast-properties@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
 
-token-stream@0.0.1:
-  version "0.0.1"
-  resolved "https://registry.yarnpkg.com/token-stream/-/token-stream-0.0.1.tgz#ceeefc717a76c4316f126d0b9dbaa55d7e7df01a"
-
 toposort@^1.0.0:
   version "1.0.6"
   resolved "https://registry.yarnpkg.com/toposort/-/toposort-1.0.6.tgz#c31748e55d210effc00fdcdc7d6e68d7d7bb9cec"
@@ -5728,7 +5680,7 @@ uglify-js@3.3.x:
     commander "~2.12.1"
     source-map "~0.6.1"
 
-uglify-js@^2.6.1, uglify-js@^2.8.29:
+uglify-js@^2.8.29:
   version "2.8.29"
   resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd"
   dependencies:
@@ -5867,10 +5819,6 @@ vm-browserify@0.0.4:
   dependencies:
     indexof "0.0.1"
 
-void-elements@^2.0.1:
-  version "2.0.1"
-  resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec"
-
 vue-eslint-parser@^2.0.1:
   version "2.0.2"
   resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-2.0.2.tgz#8d603545e9d7c134699075bd1772af1ffd86b744"
@@ -5933,6 +5881,10 @@ vue-template-es2015-compiler@^1.6.0:
   version "1.6.0"
   resolved "https://registry.yarnpkg.com/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.6.0.tgz#dc42697133302ce3017524356a6c61b7b69b4a18"
 
+vue2-smooth-scroll@^1.0.1:
+  version "1.0.1"
+  resolved "https://registry.yarnpkg.com/vue2-smooth-scroll/-/vue2-smooth-scroll-1.0.1.tgz#6a97639aaa1157aa8f3ad2e5b50dc9a3ba4a0b02"
+
 vue@^2.5.11:
   version "2.5.13"
   resolved "https://registry.yarnpkg.com/vue/-/vue-2.5.13.tgz#95bd31e20efcf7a7f39239c9aa6787ce8cf578e1"
@@ -6074,13 +6026,6 @@ window-size@0.1.0:
   version "0.1.0"
   resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d"
 
-with@^5.0.0:
-  version "5.1.1"
-  resolved "https://registry.yarnpkg.com/with/-/with-5.1.1.tgz#fa4daa92daf32c4ea94ed453c81f04686b575dfe"
-  dependencies:
-    acorn "^3.1.0"
-    acorn-globals "^3.0.0"
-
 wordwrap@0.0.2:
   version "0.0.2"
   resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f"

+ 3 - 4
go/src/flow/operation.go

@@ -10,6 +10,7 @@ import (
 	"fmt"
 	"log"
 	"reflect"
+	"runtime/debug"
 	"sync"
 )
 
@@ -67,9 +68,9 @@ func (f *Flow) asTrigger(id string, fn executorFunc) executorFunc {
 		var res Data
 		func() {
 			defer func() {
-
 				if r := recover(); r != nil {
 					log.Println("Panic:", r)
+					debug.PrintStack()
 					err = fmt.Errorf("%v", r)
 				}
 			}()
@@ -173,7 +174,6 @@ func (f *Flow) processInputs(ctx OpCtx, op *operation, fnval reflect.Value, para
 				return
 			}
 			if fr == nil {
-				log.Println("Zero value", inTyp)
 				callParam[i] = reflect.Zero(inTyp)
 				return
 			}
@@ -186,7 +186,6 @@ func (f *Flow) processInputs(ctx OpCtx, op *operation, fnval reflect.Value, para
 				callErrors += fmt.Sprintf("Input %d invalid\n", i)
 				return
 			case !res.Type().ConvertibleTo(inTyp):
-				log.Println("Conversible")
 				if inTyp.Kind() != reflect.String {
 					callErrors += fmt.Sprintf("Input %d type: %v(%v) cannot be converted to %v\n", i, res.Type(), res.Interface(), inTyp)
 					log.Println(f)
@@ -324,7 +323,7 @@ func (f *Flow) DefIn(id string, paramID int) Operation {
 		inputs: nil,
 		setter: nil,
 		executor: f.asTrigger(id, func(ctx OpCtx, params ...Data) (Data, error) {
-			if paramID < 0 || paramID > len(params) {
+			if paramID < 0 || paramID >= len(params) {
 				return nil, ErrInput
 			}
 			return params[paramID], nil

+ 10 - 3
go/src/flowserver/cmd/demo1/main.go

@@ -32,9 +32,16 @@ func main() {
 	mux := http.NewServeMux()
 	mux.HandleFunc("/", assetFunc)
 
-	mux.Handle("/default/", c.Build(flowserver.New(defaultops.New(), "default").ServeHTTP))
-	mux.Handle("/gonumops/", c.Build(flowserver.New(gonumops.New(), "gonumops").ServeHTTP))
-	mux.Handle("/devops/", c.Build(flowserver.New(devops.New(), "devops").ServeHTTP))
+	mux.Handle("/default/", c.Build(
+		http.StripPrefix("/default", flowserver.New(defaultops.New(), "default")),
+	))
+	mux.Handle("/gonumops/", c.Build(
+		http.StripPrefix("/gonumops", flowserver.New(gonumops.New(), "gonumops")),
+	))
+
+	mux.Handle("/devops/", c.Build(
+		http.StripPrefix("/devops", flowserver.New(devops.New(), "devops")),
+	))
 
 	// Context registry
 	http.ListenAndServe(addr, mux)

+ 15 - 4
go/src/flowserver/flowserver.go

@@ -7,8 +7,8 @@ import (
 	"net/http/httputil"
 	"net/url"
 	"os"
-	"strings"
 
+	"github.com/gohxs/prettylog"
 	"github.com/gohxs/webu"
 )
 
@@ -35,7 +35,10 @@ func New(r *registry.R, store string) *FlowServer {
 		if err != nil {
 			return nil
 		}
-		mux.Handle("/", httputil.NewSingleHostReverseProxy(proxyURL))
+
+		rp := httputil.NewSingleHostReverseProxy(proxyURL)
+		rp.ErrorLog = prettylog.New("rproxy")
+		mux.Handle("/", rp)
 	} else {
 		mux.Handle("/", webu.StaticHandler("web", "index.html"))
 	}
@@ -44,12 +47,20 @@ func New(r *registry.R, store string) *FlowServer {
 }
 
 func (f *FlowServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	f.mux.ServeHTTP(w, r)
 	// Manual routing here
 	// Grab last part of path
+	/*prefixToRemove := ""
+
 	urlParts := strings.Split(r.URL.Path, "/")
-	prefixToRemove := strings.Join(urlParts[:len(urlParts)-1], "/")
-	http.StripPrefix(prefixToRemove, f.mux).ServeHTTP(w, r)
+	if len(urlParts) > 1 {
+		//prefixToRemove = strings.Join(urlParts[:len(urlParts)-1], "/")
+		prefixToRemove = strings.TrimRight("/"+urlParts[1], "/")
+		log.Println("Will remove", prefixToRemove)
+	}
+	//	}
 
+	http.StripPrefix(prefixToRemove, f.mux).ServeHTTP(w, r)*/
 }
 
 // ListenAndServe starts the httpserver