Improve ui & performance
This commit is contained in:
@@ -8,14 +8,21 @@
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
@keyframes example {
|
||||
0% {background-color: inherit;}
|
||||
25% {background-color: #3f51b5;}
|
||||
50% {background-color: #3f51b5;}
|
||||
100% {background-color: inherit;}
|
||||
}
|
||||
</style>
|
||||
<script src="http://localhost:35729/livereload.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="example"></div>
|
||||
|
||||
<!-- Dependencies -->
|
||||
<script src="./node_modules/react/umd/react.development.js"></script>
|
||||
<script src="./node_modules/react-dom/umd/react-dom.development.js"></script>
|
||||
<!-- <script src="./node_modules/react/umd/react.development.js"></script>
|
||||
<script src="./node_modules/react-dom/umd/react-dom.development.js"></script> -->
|
||||
|
||||
<!-- Main -->
|
||||
<script src="./build/bundle.js"></script>
|
||||
|
||||
441
app/package-lock.json
generated
441
app/package-lock.json
generated
@@ -650,6 +650,42 @@
|
||||
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
|
||||
"integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA=="
|
||||
},
|
||||
"body": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/body/-/body-5.1.0.tgz",
|
||||
"integrity": "sha1-5LoM5BCkaTYyM2dgnstOZVMSUGk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"continuable-cache": "^0.3.1",
|
||||
"error": "^7.0.0",
|
||||
"raw-body": "~1.1.0",
|
||||
"safe-json-parse": "~1.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"bytes": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-1.0.0.tgz",
|
||||
"integrity": "sha1-NWnt6Lo0MV+rmcPpLLBMciDeH6g=",
|
||||
"dev": true
|
||||
},
|
||||
"raw-body": {
|
||||
"version": "1.1.7",
|
||||
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-1.1.7.tgz",
|
||||
"integrity": "sha1-HQJ8K/oRasxmI7yo8AAWVyqH1CU=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"bytes": "1",
|
||||
"string_decoder": "0.10"
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "0.10.31",
|
||||
"resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
|
||||
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"body-parser": {
|
||||
"version": "1.18.3",
|
||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz",
|
||||
@@ -1084,6 +1120,12 @@
|
||||
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
|
||||
"integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
|
||||
},
|
||||
"continuable-cache": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/continuable-cache/-/continuable-cache-0.3.1.tgz",
|
||||
"integrity": "sha1-vXJ6f67XfnH/OYWskzUakSczrQ8=",
|
||||
"dev": true
|
||||
},
|
||||
"cookie": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
|
||||
@@ -1204,36 +1246,6 @@
|
||||
"resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz",
|
||||
"integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA="
|
||||
},
|
||||
"cytoscape": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.3.1.tgz",
|
||||
"integrity": "sha512-3IIh63Oz/dtiO1ibPb9CWHBPo90JZg/74EI+vDL/hamaP01bQ7Yx1r9oiS4AyTedvlUCio5j7Bu3NtRWxJHryw==",
|
||||
"requires": {
|
||||
"heap": "^0.2.6",
|
||||
"lodash.debounce": "^4.0.8"
|
||||
}
|
||||
},
|
||||
"cytoscape-cola": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/cytoscape-cola/-/cytoscape-cola-2.3.0.tgz",
|
||||
"integrity": "sha512-xblxlCH8JXGLdH6XMUBJY3xBUJuL1rLy8bLMGvqkvoPHSbBfV+/klMWoqwervVKWOmFHPwUdihtxy8stG4RM5g==",
|
||||
"requires": {
|
||||
"webcola": "^3.3.6"
|
||||
}
|
||||
},
|
||||
"cytoscape-dagre": {
|
||||
"version": "2.2.2",
|
||||
"resolved": "https://registry.npmjs.org/cytoscape-dagre/-/cytoscape-dagre-2.2.2.tgz",
|
||||
"integrity": "sha512-zsg36qNwua/L2stJSWkcbSDcvW3E6VZf6KRe6aLnQJxuXuz89tMqI5EVYVKEcNBgzTEzFMFv0PE3T0nD4m6VDw==",
|
||||
"requires": {
|
||||
"dagre": "^0.8.2"
|
||||
}
|
||||
},
|
||||
"cytoscape-expand-collapse": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/cytoscape-expand-collapse/-/cytoscape-expand-collapse-3.1.2.tgz",
|
||||
"integrity": "sha512-yClfo0z2IqEkhlOipUh85k1kJGSgxaSKs4e30KO1mDIXPKOnvL/iQhVXmNt9+KmuIGg9YtNt09P0j3F4BN3WsA=="
|
||||
},
|
||||
"d": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "http://registry.npmjs.org/d/-/d-1.0.0.tgz",
|
||||
@@ -1242,39 +1254,6 @@
|
||||
"es5-ext": "^0.10.9"
|
||||
}
|
||||
},
|
||||
"d3-dispatch": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-1.0.5.tgz",
|
||||
"integrity": "sha512-vwKx+lAqB1UuCeklr6Jh1bvC4SZgbSqbkGBLClItFBIYH4vqDJCA7qfoy14lXmJdnBOdxndAMxjCbImJYW7e6g=="
|
||||
},
|
||||
"d3-drag": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-1.2.3.tgz",
|
||||
"integrity": "sha512-8S3HWCAg+ilzjJsNtWW1Mutl74Nmzhb9yU6igspilaJzeZVFktmY6oO9xOh5TDk+BM2KrNFjttZNoJJmDnkjkg==",
|
||||
"requires": {
|
||||
"d3-dispatch": "1",
|
||||
"d3-selection": "1"
|
||||
}
|
||||
},
|
||||
"d3-selection": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-1.3.2.tgz",
|
||||
"integrity": "sha512-OoXdv1nZ7h2aKMVg3kaUFbLLK5jXUFAMLD/Tu5JA96mjf8f2a9ZUESGY+C36t8R1WFeWk/e55hy54Ml2I62CRQ=="
|
||||
},
|
||||
"d3-timer": {
|
||||
"version": "1.0.9",
|
||||
"resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-1.0.9.tgz",
|
||||
"integrity": "sha512-rT34J5HnQUHhcLvhSB9GjCkN0Ddd5Y8nCwDBG2u6wQEeYxT/Lf51fTFFkldeib/sE/J0clIe0pnCfs6g/lRbyg=="
|
||||
},
|
||||
"dagre": {
|
||||
"version": "0.8.4",
|
||||
"resolved": "https://registry.npmjs.org/dagre/-/dagre-0.8.4.tgz",
|
||||
"integrity": "sha512-Dj0csFDrWYKdavwROb9FccHfTC4fJbyF/oJdL9LNZJ8WUvl968P6PAKEriGqfbdArVJEmmfA+UyumgWEwcHU6A==",
|
||||
"requires": {
|
||||
"graphlib": "^2.1.7",
|
||||
"lodash": "^4.17.4"
|
||||
}
|
||||
},
|
||||
"date-now": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz",
|
||||
@@ -1500,11 +1479,6 @@
|
||||
"minimalistic-crypto-utils": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"emitter-component": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/emitter-component/-/emitter-component-1.1.1.tgz",
|
||||
"integrity": "sha1-Bl4tvtaVm/RwZ57avq95gdEAOrY="
|
||||
},
|
||||
"emojis-list": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz",
|
||||
@@ -1589,6 +1563,16 @@
|
||||
"prr": "~1.0.1"
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
"version": "7.0.2",
|
||||
"resolved": "https://registry.npmjs.org/error/-/error-7.0.2.tgz",
|
||||
"integrity": "sha1-pfdf/02ZJhJt2sDqXcOOaJFTywI=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"string-template": "~0.2.1",
|
||||
"xtend": "~4.0.0"
|
||||
}
|
||||
},
|
||||
"es5-ext": {
|
||||
"version": "0.10.46",
|
||||
"resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.46.tgz",
|
||||
@@ -2044,21 +2028,25 @@
|
||||
"dependencies": {
|
||||
"abbrev": {
|
||||
"version": "1.1.1",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
|
||||
"optional": true
|
||||
},
|
||||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"bundled": true
|
||||
"resolved": false,
|
||||
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
|
||||
},
|
||||
"aproba": {
|
||||
"version": "1.2.0",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
|
||||
"optional": true
|
||||
},
|
||||
"are-we-there-yet": {
|
||||
"version": "1.1.4",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"delegates": "^1.0.0",
|
||||
@@ -2067,11 +2055,13 @@
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true
|
||||
"resolved": false,
|
||||
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
@@ -2079,29 +2069,35 @@
|
||||
},
|
||||
"chownr": {
|
||||
"version": "1.0.1",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=",
|
||||
"optional": true
|
||||
},
|
||||
"code-point-at": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true
|
||||
"resolved": false,
|
||||
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"bundled": true
|
||||
"resolved": false,
|
||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
|
||||
},
|
||||
"console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true
|
||||
"resolved": false,
|
||||
"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4="
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
|
||||
"optional": true
|
||||
},
|
||||
"debug": {
|
||||
"version": "2.6.9",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
@@ -2109,22 +2105,26 @@
|
||||
},
|
||||
"deep-extend": {
|
||||
"version": "0.5.1",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha512-N8vBdOa+DF7zkRrDCsaOXoCs/E2fJfx9B9MrKnnSiHNh4ws7eSys6YQE4KvT1cecKmOASYQBhbKjeuDD9lT81w==",
|
||||
"optional": true
|
||||
},
|
||||
"delegates": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
|
||||
"optional": true
|
||||
},
|
||||
"detect-libc": {
|
||||
"version": "1.0.3",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=",
|
||||
"optional": true
|
||||
},
|
||||
"fs-minipass": {
|
||||
"version": "1.2.5",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"minipass": "^2.2.1"
|
||||
@@ -2132,12 +2132,14 @@
|
||||
},
|
||||
"fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
|
||||
"optional": true
|
||||
},
|
||||
"gauge": {
|
||||
"version": "2.7.4",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"aproba": "^1.0.3",
|
||||
@@ -2152,7 +2154,8 @@
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.1.2",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
@@ -2165,12 +2168,14 @@
|
||||
},
|
||||
"has-unicode": {
|
||||
"version": "2.0.1",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
|
||||
"optional": true
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.4.21",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha512-En5V9za5mBt2oUA03WGD3TwDv0MKAruqsuxstbMUZaj9W9k/m1CV/9py3l0L5kw9Bln8fdHQmzHSYtvpvTLpKw==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"safer-buffer": "^2.1.0"
|
||||
@@ -2178,7 +2183,8 @@
|
||||
},
|
||||
"ignore-walk": {
|
||||
"version": "3.0.1",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"minimatch": "^3.0.4"
|
||||
@@ -2186,7 +2192,8 @@
|
||||
},
|
||||
"inflight": {
|
||||
"version": "1.0.6",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"once": "^1.3.0",
|
||||
@@ -2195,39 +2202,46 @@
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"bundled": true
|
||||
"resolved": false,
|
||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
|
||||
},
|
||||
"ini": {
|
||||
"version": "1.3.5",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
|
||||
"optional": true
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
|
||||
"requires": {
|
||||
"number-is-nan": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
|
||||
"optional": true
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "3.0.4",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"bundled": true
|
||||
"resolved": false,
|
||||
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
|
||||
},
|
||||
"minipass": {
|
||||
"version": "2.2.4",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha512-hzXIWWet/BzWhYs2b+u7dRHlruXhwdgvlTMDKC6Cb1U7ps6Ac6yQlR39xsbjWJE377YTCtKwIXIpJ5oP+j5y8g==",
|
||||
"requires": {
|
||||
"safe-buffer": "^5.1.1",
|
||||
"yallist": "^3.0.0"
|
||||
@@ -2235,7 +2249,8 @@
|
||||
},
|
||||
"minizlib": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha512-4T6Ur/GctZ27nHfpt9THOdRZNgyJ9FZchYO1ceg5S8Q3DNLCKYy44nCZzgCJgcvx2UM8czmqak5BCxJMrq37lA==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"minipass": "^2.2.1"
|
||||
@@ -2243,19 +2258,22 @@
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.1",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
|
||||
"optional": true
|
||||
},
|
||||
"needle": {
|
||||
"version": "2.2.0",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha512-eFagy6c+TYayorXw/qtAdSvaUpEbBsDwDyxYFgLZ0lTojfH7K+OdBqAF7TAFwDokJaGpubpSGG0wO3iC0XPi8w==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"debug": "^2.1.2",
|
||||
@@ -2265,7 +2283,8 @@
|
||||
},
|
||||
"node-pre-gyp": {
|
||||
"version": "0.10.0",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha512-G7kEonQLRbcA/mOoFoxvlMrw6Q6dPf92+t/l0DFSMuSlDoWaI9JWIyPwK0jyE1bph//CUEL65/Fz1m2vJbmjQQ==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"detect-libc": "^1.0.2",
|
||||
@@ -2282,7 +2301,8 @@
|
||||
},
|
||||
"nopt": {
|
||||
"version": "4.0.1",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"abbrev": "1",
|
||||
@@ -2291,12 +2311,14 @@
|
||||
},
|
||||
"npm-bundled": {
|
||||
"version": "1.0.3",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha512-ByQ3oJ/5ETLyglU2+8dBObvhfWXX8dtPZDMePCahptliFX2iIuhyEszyFk401PZUNQH20vvdW5MLjJxkwU80Ow==",
|
||||
"optional": true
|
||||
},
|
||||
"npm-packlist": {
|
||||
"version": "1.1.10",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha512-AQC0Dyhzn4EiYEfIUjCdMl0JJ61I2ER9ukf/sLxJUcZHfo+VyEfz2rMJgLZSS1v30OxPQe1cN0LZA1xbcaVfWA==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"ignore-walk": "^3.0.1",
|
||||
@@ -2305,7 +2327,8 @@
|
||||
},
|
||||
"npmlog": {
|
||||
"version": "4.1.2",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"are-we-there-yet": "~1.1.2",
|
||||
@@ -2316,33 +2339,39 @@
|
||||
},
|
||||
"number-is-nan": {
|
||||
"version": "1.0.1",
|
||||
"bundled": true
|
||||
"resolved": false,
|
||||
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
|
||||
"optional": true
|
||||
},
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"os-homedir": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
|
||||
"optional": true
|
||||
},
|
||||
"os-tmpdir": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
|
||||
"optional": true
|
||||
},
|
||||
"osenv": {
|
||||
"version": "0.1.5",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"os-homedir": "^1.0.0",
|
||||
@@ -2351,17 +2380,20 @@
|
||||
},
|
||||
"path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
|
||||
"optional": true
|
||||
},
|
||||
"process-nextick-args": {
|
||||
"version": "2.0.0",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
|
||||
"optional": true
|
||||
},
|
||||
"rc": {
|
||||
"version": "1.2.7",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha512-LdLD8xD4zzLsAT5xyushXDNscEjB7+2ulnl8+r1pnESlYtlJtVSoCMBGr30eDRJ3+2Gq89jK9P9e4tCEH1+ywA==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"deep-extend": "^0.5.1",
|
||||
@@ -2372,14 +2404,16 @@
|
||||
"dependencies": {
|
||||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.6",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"core-util-is": "~1.0.0",
|
||||
@@ -2393,7 +2427,8 @@
|
||||
},
|
||||
"rimraf": {
|
||||
"version": "2.6.2",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"glob": "^7.0.5"
|
||||
@@ -2401,36 +2436,43 @@
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.1.1",
|
||||
"bundled": true
|
||||
"resolved": false,
|
||||
"integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
|
||||
},
|
||||
"safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
||||
"optional": true
|
||||
},
|
||||
"sax": {
|
||||
"version": "1.2.4",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
|
||||
"optional": true
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.5.0",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==",
|
||||
"optional": true
|
||||
},
|
||||
"set-blocking": {
|
||||
"version": "2.0.0",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
|
||||
"optional": true
|
||||
},
|
||||
"signal-exit": {
|
||||
"version": "3.0.2",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
|
||||
"optional": true
|
||||
},
|
||||
"string-width": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
|
||||
"requires": {
|
||||
"code-point-at": "^1.0.0",
|
||||
"is-fullwidth-code-point": "^1.0.0",
|
||||
@@ -2439,7 +2481,8 @@
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
@@ -2447,19 +2490,22 @@
|
||||
},
|
||||
"strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"strip-json-comments": {
|
||||
"version": "2.0.1",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
|
||||
"optional": true
|
||||
},
|
||||
"tar": {
|
||||
"version": "4.4.1",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha512-O+v1r9yN4tOsvl90p5HAP4AEqbYhx4036AGMm075fH9F8Qwi3oJ+v4u50FkT/KkvywNGtwkk0zRI+8eYm1X/xg==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"chownr": "^1.0.1",
|
||||
@@ -2473,12 +2519,14 @@
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
|
||||
"optional": true
|
||||
},
|
||||
"wide-align": {
|
||||
"version": "1.1.2",
|
||||
"bundled": true,
|
||||
"resolved": false,
|
||||
"integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==",
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"string-width": "^1.0.2"
|
||||
@@ -2486,11 +2534,13 @@
|
||||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true
|
||||
"resolved": false,
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
||||
},
|
||||
"yallist": {
|
||||
"version": "3.0.2",
|
||||
"bundled": true
|
||||
"resolved": false,
|
||||
"integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k="
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -2578,19 +2628,6 @@
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz",
|
||||
"integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA=="
|
||||
},
|
||||
"graphlib": {
|
||||
"version": "2.1.7",
|
||||
"resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.7.tgz",
|
||||
"integrity": "sha512-TyI9jIy2J4j0qgPmOOrHTCtpPqJGN/aurBwc6ZT+bRii+di1I+Wv3obRhVrmBEXet+qkMaEX67dXrwsd3QQM6w==",
|
||||
"requires": {
|
||||
"lodash": "^4.17.5"
|
||||
}
|
||||
},
|
||||
"hammerjs": {
|
||||
"version": "2.0.8",
|
||||
"resolved": "https://registry.npmjs.org/hammerjs/-/hammerjs-2.0.8.tgz",
|
||||
"integrity": "sha1-BO93hiz/K7edMPdpIJWTAiK/YPE="
|
||||
},
|
||||
"handle-thing": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.0.tgz",
|
||||
@@ -2673,11 +2710,6 @@
|
||||
"minimalistic-assert": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"heap": {
|
||||
"version": "0.2.6",
|
||||
"resolved": "https://registry.npmjs.org/heap/-/heap-0.2.6.tgz",
|
||||
"integrity": "sha1-CH4fELBGky/IWU3Z5tN4r8nR5aw="
|
||||
},
|
||||
"hmac-drbg": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
|
||||
@@ -3139,11 +3171,6 @@
|
||||
"css-vendor": "^0.3.8"
|
||||
}
|
||||
},
|
||||
"keycharm": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/keycharm/-/keycharm-0.2.0.tgz",
|
||||
"integrity": "sha1-+m6i5DuQpoAohD0n8gddNajD5vk="
|
||||
},
|
||||
"keycode": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/keycode/-/keycode-2.2.0.tgz",
|
||||
@@ -3167,6 +3194,12 @@
|
||||
"invert-kv": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"livereload-js": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-2.4.0.tgz",
|
||||
"integrity": "sha512-XPQH8Z2GDP/Hwz2PCDrh2mth4yFejwA1OZ/81Ti3LgKyhDcEjsSsqFWZojHG0va/duGd+WyosY7eXLDoOyqcPw==",
|
||||
"dev": true
|
||||
},
|
||||
"loader-runner": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.3.1.tgz",
|
||||
@@ -3957,14 +3990,6 @@
|
||||
"object-assign": "^4.1.1"
|
||||
}
|
||||
},
|
||||
"propagating-hammerjs": {
|
||||
"version": "1.4.6",
|
||||
"resolved": "https://registry.npmjs.org/propagating-hammerjs/-/propagating-hammerjs-1.4.6.tgz",
|
||||
"integrity": "sha1-/tAOmwB2f/1C0U9bUxvEk+tnLjc=",
|
||||
"requires": {
|
||||
"hammerjs": "^2.0.6"
|
||||
}
|
||||
},
|
||||
"proxy-addr": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz",
|
||||
@@ -4107,17 +4132,6 @@
|
||||
"pure-color": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"react-cytoscape": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/react-cytoscape/-/react-cytoscape-1.0.6.tgz",
|
||||
"integrity": "sha512-bCBLyctKVDuxe9W2b/TaBGwk+Q1/AX33k+ocD94r0Pq4KQGAJNS91m3Z/czSOkDHcK1VmbImxnH2Q75J5lxeiQ==",
|
||||
"requires": {
|
||||
"cytoscape": "^3.2.5",
|
||||
"cytoscape-cola": "^2.0.0",
|
||||
"cytoscape-dagre": "^2.1.0",
|
||||
"fsevents": "*"
|
||||
}
|
||||
},
|
||||
"react-dom": {
|
||||
"version": "16.3.3",
|
||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.3.3.tgz",
|
||||
@@ -4320,6 +4334,12 @@
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||
},
|
||||
"safe-json-parse": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-json-parse/-/safe-json-parse-1.0.1.tgz",
|
||||
"integrity": "sha1-PnZyPjjf3aE8mx0poeB//uSzC1c=",
|
||||
"dev": true
|
||||
},
|
||||
"safe-regex": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
|
||||
@@ -4873,6 +4893,12 @@
|
||||
"resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz",
|
||||
"integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI="
|
||||
},
|
||||
"string-template": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/string-template/-/string-template-0.2.1.tgz",
|
||||
"integrity": "sha1-QpMuWYo1LQH8IuwzZ9nYTuxsmt0=",
|
||||
"dev": true
|
||||
},
|
||||
"string-width": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
|
||||
@@ -4992,6 +5018,37 @@
|
||||
"setimmediate": "^1.0.4"
|
||||
}
|
||||
},
|
||||
"tiny-lr": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-1.1.1.tgz",
|
||||
"integrity": "sha512-44yhA3tsaRoMOjQQ+5v5mVdqef+kH6Qze9jTpqtVufgYjYt08zyZAwNwwVBj3i1rJMnR52IxOW0LK0vBzgAkuA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"body": "^5.1.0",
|
||||
"debug": "^3.1.0",
|
||||
"faye-websocket": "~0.10.0",
|
||||
"livereload-js": "^2.3.0",
|
||||
"object-assign": "^4.1.0",
|
||||
"qs": "^6.4.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "3.2.6",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
|
||||
"integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
|
||||
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"to-array": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz",
|
||||
@@ -5244,18 +5301,6 @@
|
||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
|
||||
},
|
||||
"vis": {
|
||||
"version": "4.21.0",
|
||||
"resolved": "https://registry.npmjs.org/vis/-/vis-4.21.0.tgz",
|
||||
"integrity": "sha1-3XFji/9/ZJXQC8n0DCU1JhM97Ws=",
|
||||
"requires": {
|
||||
"emitter-component": "^1.1.1",
|
||||
"hammerjs": "^2.0.8",
|
||||
"keycharm": "^0.2.0",
|
||||
"moment": "^2.18.1",
|
||||
"propagating-hammerjs": "^1.4.6"
|
||||
}
|
||||
},
|
||||
"vm-browserify": {
|
||||
"version": "0.0.4",
|
||||
"resolved": "http://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz",
|
||||
@@ -5290,16 +5335,6 @@
|
||||
"minimalistic-assert": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"webcola": {
|
||||
"version": "3.3.8",
|
||||
"resolved": "https://registry.npmjs.org/webcola/-/webcola-3.3.8.tgz",
|
||||
"integrity": "sha512-WVDTdHS1SaqYCUJGPdbOhqj44mchDyTC78tozUdqJllwYeJ2554+BWkJfc5kNphT8foip2StCMw1FWsIvGmv9w==",
|
||||
"requires": {
|
||||
"d3-dispatch": "^1.0.3",
|
||||
"d3-drag": "^1.0.4",
|
||||
"d3-timer": "^1.0.5"
|
||||
}
|
||||
},
|
||||
"webpack": {
|
||||
"version": "4.28.2",
|
||||
"resolved": "https://registry.npmjs.org/webpack/-/webpack-4.28.2.tgz",
|
||||
@@ -5481,6 +5516,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"webpack-livereload-plugin": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/webpack-livereload-plugin/-/webpack-livereload-plugin-2.2.0.tgz",
|
||||
"integrity": "sha512-sx9xA5mHoNOUgLQI0PmXT3KV9ecsVmUaTgr+fsoL69qAOHw/7VzkL1+ZMDQ8n0dPbWounswK6cBRSgMod7Nhgg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"portfinder": "^1.0.17",
|
||||
"tiny-lr": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"webpack-log": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz",
|
||||
|
||||
@@ -10,31 +10,27 @@
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"@material-ui/icons": "^3.0.1"
|
||||
"@material-ui/icons": "^3.0.1",
|
||||
"webpack-livereload-plugin": "^2.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/node": "^10.12.18",
|
||||
"awesome-typescript-loader": "^5.2.1",
|
||||
"source-map-loader": "^0.2.4",
|
||||
"typescript": "^3.2.2",
|
||||
"webpack": "^4.28.2",
|
||||
"webpack-cli": "^3.1.2",
|
||||
"webpack-dev-server": "^3.1.14",
|
||||
"@material-ui/core": "^3.7.1",
|
||||
"@types/node": "^10.12.18",
|
||||
"@types/react": "^16.7.18",
|
||||
"@types/react-dom": "^16.0.11",
|
||||
"@types/socket.io-client": "^1.4.32",
|
||||
"@types/vis": "^4.21.9",
|
||||
"cytoscape": "^3.3.1",
|
||||
"cytoscape-dagre": "^2.2.2",
|
||||
"cytoscape-expand-collapse": "^3.1.2",
|
||||
"awesome-typescript-loader": "^5.2.1",
|
||||
"jquery": "^3.3.1",
|
||||
"lodash.throttle": "^4.1.1",
|
||||
"react": "^16.3.2",
|
||||
"react-cytoscape": "^1.0.6",
|
||||
"react-dom": "^16.3.3",
|
||||
"react-json-view": "^1.19.1",
|
||||
"socket.io-client": "^2.2.0",
|
||||
"vis": "^4.21.0"
|
||||
"source-map-loader": "^0.2.4",
|
||||
"typescript": "^3.2.2",
|
||||
"webpack": "^4.28.2",
|
||||
"webpack-cli": "^3.1.2",
|
||||
"webpack-dev-server": "^3.1.14"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import * as q from '../../backend/src/Model'
|
||||
|
||||
import { Tree } from './components/Tree'
|
||||
import TitleBar from './components/TitleBar'
|
||||
import { Sidebar } from './components/Sidebar'
|
||||
import Sidebar from './components/Sidebar/Sidebar'
|
||||
|
||||
import { withTheme, Theme } from '@material-ui/core/styles'
|
||||
|
||||
@@ -12,6 +12,7 @@ class State {
|
||||
}
|
||||
|
||||
interface Props {
|
||||
name: string
|
||||
theme: Theme
|
||||
}
|
||||
|
||||
@@ -21,34 +22,47 @@ class App extends React.Component<Props, State> {
|
||||
this.state = {
|
||||
selectedNode: undefined,
|
||||
}
|
||||
}
|
||||
|
||||
console.log('asd', this.props)
|
||||
this.theme = this.props.theme
|
||||
this.styles = {
|
||||
primaryText: {
|
||||
backgroundColor: this.theme.palette.background.default,
|
||||
padding: `${this.theme.spacing.unit}px ${this.theme.spacing.unit * 2}px`,
|
||||
color: this.theme.palette.text.primary,
|
||||
private getStyles(): {[s: string]: React.CSSProperties} {
|
||||
const { theme } = this.props
|
||||
return {
|
||||
left: {
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.primary,
|
||||
height: 'calc(100vh - 64px)',
|
||||
float: 'left',
|
||||
width: '60vw',
|
||||
overflowY: 'scroll',
|
||||
overflowX: 'hidden',
|
||||
display: 'block',
|
||||
},
|
||||
primaryColor: {
|
||||
backgroundColor: this.theme.palette.background.default,
|
||||
// padding: `${this.theme.spacing.unit}px ${this.theme.spacing.unit * 2}px`,
|
||||
color: this.theme.palette.common.white,
|
||||
right: {
|
||||
height: 'calc(100vh - 64px)',
|
||||
backgroundColor: theme.palette.background.default,
|
||||
color: theme.palette.text.primary,
|
||||
float: 'right', width: '40vw',
|
||||
overflowY: 'scroll',
|
||||
overflowX: 'hidden',
|
||||
display: 'block',
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
private theme: Theme
|
||||
private styles: any
|
||||
|
||||
public render() {
|
||||
return <div style={this.styles.primaryColor}>
|
||||
return <div>
|
||||
<TitleBar />
|
||||
<Tree didSelectNode={(node: q.TreeNode) => {
|
||||
this.setState({ selectedNode: node })
|
||||
console.log('did select', node)
|
||||
}} />
|
||||
</div>
|
||||
<div>
|
||||
<div style={this.getStyles().left}>
|
||||
<Tree didSelectNode={(node: q.TreeNode) => {
|
||||
this.setState({ selectedNode: node })
|
||||
}} />
|
||||
</div>
|
||||
<div style={this.getStyles().right}>
|
||||
<Sidebar node={this.state.selectedNode} />
|
||||
</div>
|
||||
</div>
|
||||
</div >
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
import * as React from 'react'
|
||||
import * as q from '../../../backend/src/Model'
|
||||
import Drawer from '@material-ui/core/Drawer'
|
||||
import TextField from '@material-ui/core/TextField'
|
||||
import Paper from '@material-ui/core/Paper'
|
||||
import { ValueRenderer } from './ValueRenderer'
|
||||
|
||||
interface Props {
|
||||
node?: q.TreeNode | undefined
|
||||
}
|
||||
|
||||
interface State {
|
||||
node?: q.TreeNode | undefined
|
||||
}
|
||||
|
||||
export class Sidebar extends React.Component<Props, State> {
|
||||
private updateNode: (node?: q.TreeNode | undefined) => void
|
||||
constructor(props: any) {
|
||||
super(props)
|
||||
this.state = {}
|
||||
this.updateNode = (node) => {
|
||||
if (!node) {
|
||||
this.setState(this.state)
|
||||
} else {
|
||||
this.setState({ node })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public componentWillReceiveProps(nextProps: Props) {
|
||||
this.props.node && this.props.node.removeListener('update', this.updateNode)
|
||||
nextProps.node && nextProps.node.on('update', this.updateNode)
|
||||
nextProps.node && this.updateNode(nextProps.node)
|
||||
}
|
||||
|
||||
private open() {
|
||||
return this.props.node !== undefined
|
||||
}
|
||||
|
||||
public render() {
|
||||
return <Drawer open={this.open()} variant="permanent" anchor="right">
|
||||
{this.renderNode()}
|
||||
</Drawer>
|
||||
}
|
||||
|
||||
private renderNode() {
|
||||
const style: React.CSSProperties = { display: 'block', width: '40vw' }
|
||||
const topicStyle: React.CSSProperties = { width: '100%' }
|
||||
|
||||
if (!this.state.node) {
|
||||
return null
|
||||
}
|
||||
|
||||
return <div style={style}>
|
||||
<TextField style={topicStyle}
|
||||
label="Topic"
|
||||
value={this.state.node.path()}
|
||||
margin="normal"
|
||||
variant="outlined"
|
||||
/>
|
||||
<Paper>
|
||||
<ValueRenderer node={this.state.node} />
|
||||
</Paper>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
41
app/src/components/Sidebar/NodeStats.tsx
Normal file
41
app/src/components/Sidebar/NodeStats.tsx
Normal file
@@ -0,0 +1,41 @@
|
||||
import * as React from 'react'
|
||||
import * as q from '../../../../backend/src/Model'
|
||||
// import Drawer from '@material-ui/core/Drawer'
|
||||
import { Typography } from '@material-ui/core'
|
||||
import { withStyles, Theme, StyleRulesCallback } from '@material-ui/core/styles'
|
||||
|
||||
interface Props {
|
||||
node: q.TreeNode,
|
||||
classes: any,
|
||||
theme: Theme
|
||||
}
|
||||
|
||||
interface State {
|
||||
node?: q.TreeNode | undefined
|
||||
}
|
||||
|
||||
class NodeStats extends React.Component<Props, State> {
|
||||
constructor(props: any) {
|
||||
super(props)
|
||||
}
|
||||
|
||||
public static styles: StyleRulesCallback<string> = (theme: Theme) => {
|
||||
return {
|
||||
}
|
||||
}
|
||||
|
||||
public render() {
|
||||
const leafes = this.props.node.leafes()
|
||||
const leafMessages = leafes
|
||||
.map(leaf => leaf.messages)
|
||||
.reduce((a, b) => a + b)
|
||||
|
||||
return <Typography>
|
||||
<p>Messages: #{this.props.node.messages}</p>
|
||||
<p>Subtopics: {leafes.length}</p>
|
||||
<p>Messages Subtopics: #{leafMessages}</p>
|
||||
</Typography>
|
||||
}
|
||||
}
|
||||
|
||||
export default withStyles(NodeStats.styles, { withTheme: true })(NodeStats)
|
||||
105
app/src/components/Sidebar/Sidebar.tsx
Normal file
105
app/src/components/Sidebar/Sidebar.tsx
Normal file
@@ -0,0 +1,105 @@
|
||||
import * as React from 'react'
|
||||
import * as q from '../../../../backend/src/Model'
|
||||
// import Drawer from '@material-ui/core/Drawer'
|
||||
import ExpansionPanel from '@material-ui/core/ExpansionPanel'
|
||||
import ExpansionPanelSummary from '@material-ui/core/ExpansionPanelSummary'
|
||||
import ExpansionPanelDetails from '@material-ui/core/ExpansionPanelDetails'
|
||||
import ExpandMore from '@material-ui/icons/ExpandMore'
|
||||
import ValueRenderer from './ValueRenderer'
|
||||
import NodeStats from './NodeStats'
|
||||
import Topic from './Topic'
|
||||
import { Typography } from '@material-ui/core'
|
||||
import { withStyles, Theme, StyleRulesCallback } from '@material-ui/core/styles'
|
||||
|
||||
interface Props {
|
||||
node?: q.TreeNode | undefined,
|
||||
classes: any,
|
||||
theme: Theme
|
||||
}
|
||||
|
||||
interface State {
|
||||
node?: q.TreeNode | undefined
|
||||
}
|
||||
|
||||
class Sidebar extends React.Component<Props, State> {
|
||||
private updateNode: (node?: q.TreeNode | undefined) => void
|
||||
constructor(props: any) {
|
||||
super(props)
|
||||
this.state = {}
|
||||
this.updateNode = (node) => {
|
||||
if (!node) {
|
||||
this.setState(this.state)
|
||||
} else {
|
||||
this.setState({ node })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static styles: StyleRulesCallback<string> = (theme: Theme) => {
|
||||
return {
|
||||
drawer: {
|
||||
display: 'block',
|
||||
height: '100%',
|
||||
},
|
||||
valuePaper: {
|
||||
margin: `${theme.spacing.unit}px ${theme.spacing.unit}px ${theme.spacing.unit}px ${theme.spacing.unit}px`,
|
||||
},
|
||||
heading: {
|
||||
fontSize: theme.typography.pxToRem(15),
|
||||
fontWeight: theme.typography.fontWeightRegular,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
public componentWillReceiveProps(nextProps: Props) {
|
||||
this.props.node && this.props.node.removeListener('update', this.updateNode)
|
||||
nextProps.node && nextProps.node.on('update', this.updateNode)
|
||||
nextProps.node && this.updateNode(nextProps.node)
|
||||
}
|
||||
|
||||
private open(): boolean {
|
||||
return true
|
||||
}
|
||||
|
||||
public render() {
|
||||
return <div className={this.props.classes.drawer}>
|
||||
{this.renderNode()}
|
||||
</div>
|
||||
}
|
||||
|
||||
private renderNode() {
|
||||
const { classes } = this.props
|
||||
if (!this.state.node) {
|
||||
return null
|
||||
}
|
||||
|
||||
return <div>
|
||||
<ExpansionPanel key="topic" defaultExpanded={true}>
|
||||
<ExpansionPanelSummary expandIcon={<ExpandMore />}>
|
||||
<Typography className={classes.heading}>Topic</Typography>
|
||||
</ExpansionPanelSummary>
|
||||
<ExpansionPanelDetails>
|
||||
<Topic node={this.state.node} />
|
||||
</ExpansionPanelDetails>
|
||||
</ExpansionPanel>
|
||||
<ExpansionPanel key="value" defaultExpanded={true}>
|
||||
<ExpansionPanelSummary expandIcon={<ExpandMore />}>
|
||||
<Typography className={classes.heading}>Value</Typography>
|
||||
</ExpansionPanelSummary>
|
||||
<ExpansionPanelDetails>
|
||||
<ValueRenderer node={this.state.node} />
|
||||
</ExpansionPanelDetails>
|
||||
</ExpansionPanel>
|
||||
<ExpansionPanel key="stats" defaultExpanded={true}>
|
||||
<ExpansionPanelSummary expandIcon={<ExpandMore />}>
|
||||
<Typography className={classes.heading}>Stats</Typography>
|
||||
</ExpansionPanelSummary>
|
||||
<ExpansionPanelDetails>
|
||||
<NodeStats node={this.state.node} />
|
||||
</ExpansionPanelDetails>
|
||||
</ExpansionPanel>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
export default withStyles(Sidebar.styles, { withTheme: true })(Sidebar)
|
||||
52
app/src/components/Sidebar/Topic.tsx
Normal file
52
app/src/components/Sidebar/Topic.tsx
Normal file
@@ -0,0 +1,52 @@
|
||||
import * as React from 'react'
|
||||
import * as q from '../../../../backend/src/Model'
|
||||
import { withStyles, Theme, StyleRulesCallback } from '@material-ui/core/styles'
|
||||
import Button from '@material-ui/core/Button'
|
||||
|
||||
interface Props {
|
||||
classes: any
|
||||
theme: Theme
|
||||
node: q.TreeNode
|
||||
selected?: q.TreeNode
|
||||
}
|
||||
|
||||
class Topic extends React.Component<Props, {}> {
|
||||
public static styles: StyleRulesCallback<string> = (theme: Theme) => ({
|
||||
button: {
|
||||
textTransform: 'none',
|
||||
padding: '3px 5px 3px 5px',
|
||||
minWidth: '30px',
|
||||
},
|
||||
})
|
||||
|
||||
public render() {
|
||||
const { node } = this.props
|
||||
let i = 0
|
||||
const breadCrumps = node.branch()
|
||||
.map(node => node.sourceEdge)
|
||||
.filter(edge => Boolean(edge))
|
||||
.map(edge =>
|
||||
[<Button
|
||||
onClick={() => this.setState({ node: edge!.target })}
|
||||
size="small"
|
||||
color="secondary"
|
||||
className={this.props.classes.button}
|
||||
key={edge!.hash()}
|
||||
>
|
||||
{edge!.name}
|
||||
</Button>],
|
||||
)
|
||||
|
||||
if (breadCrumps.length === 0) {
|
||||
return null
|
||||
}
|
||||
|
||||
const joinedBreadCrumps = breadCrumps.reduce((prev, current) =>
|
||||
prev.concat([<span key={i += 1}>/</span>]).concat(current),
|
||||
)
|
||||
|
||||
return <span style={{ lineHeight: '2.2em' }}>{joinedBreadCrumps}</span>
|
||||
}
|
||||
}
|
||||
|
||||
export default withStyles(Topic.styles, { withTheme: true })(Topic)
|
||||
@@ -1,16 +1,18 @@
|
||||
import * as React from 'react'
|
||||
import * as q from '../../../backend/src/Model'
|
||||
import * as q from '../../../../backend/src/Model'
|
||||
import { default as ReactJson } from 'react-json-view'
|
||||
import { withTheme, Theme } from '@material-ui/core/styles'
|
||||
|
||||
interface Props {
|
||||
node?: q.TreeNode | undefined
|
||||
theme: Theme
|
||||
}
|
||||
|
||||
interface State {
|
||||
node?: q.TreeNode | undefined
|
||||
}
|
||||
|
||||
export class ValueRenderer extends React.Component<Props, State> {
|
||||
class ValueRenderer extends React.Component<Props, State> {
|
||||
private updateNode: (node?: q.TreeNode | undefined) => void
|
||||
constructor(props: any) {
|
||||
super(props)
|
||||
@@ -30,6 +32,10 @@ export class ValueRenderer extends React.Component<Props, State> {
|
||||
nextProps.node && this.updateNode(nextProps.node)
|
||||
}
|
||||
|
||||
private style = (theme: Theme) => {
|
||||
|
||||
}
|
||||
|
||||
public render() {
|
||||
const node = this.props.node
|
||||
if (!node || !node.message) {
|
||||
@@ -48,7 +54,14 @@ export class ValueRenderer extends React.Component<Props, State> {
|
||||
} else if (typeof json === 'number') {
|
||||
return this.renderRawValue(node.message.value)
|
||||
} else {
|
||||
return <ReactJson src={json} />
|
||||
const theme = this.props.theme.palette.type === 'dark' ? 'monokai' : 'bright:inverted'
|
||||
return <ReactJson
|
||||
style={{ width: '100%' }}
|
||||
src={json}
|
||||
theme={theme}
|
||||
onEdit={(val) => {
|
||||
console.log(val)
|
||||
}} />
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,6 +75,8 @@ export class ValueRenderer extends React.Component<Props, State> {
|
||||
padding: '12px 5px 12px 5px',
|
||||
}
|
||||
|
||||
return <pre><code style={style}>{value}</code></pre>
|
||||
return <pre style={style}><code>{value}</code></pre>
|
||||
}
|
||||
}
|
||||
|
||||
export default withTheme()(ValueRenderer)
|
||||
3
app/src/components/Sidebar/index.ts
Normal file
3
app/src/components/Sidebar/index.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import Sidebar from './Sidebar'
|
||||
|
||||
export { Sidebar }
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as React from 'react'
|
||||
import * as io from 'socket.io-client'
|
||||
import * as q from '../../../backend/src/Model'
|
||||
import { TreeNode } from './TreeNode'
|
||||
import TreeNode from './TreeNode'
|
||||
import List from '@material-ui/core/List'
|
||||
|
||||
const throttle = require('lodash.throttle')
|
||||
@@ -18,10 +18,14 @@ class TreeState {
|
||||
export interface TreeNodeProps {
|
||||
didSelectNode?: (node: q.TreeNode) => void
|
||||
}
|
||||
declare const performance: any
|
||||
|
||||
export class Tree extends React.Component<TreeNodeProps, TreeState> {
|
||||
private socket: SocketIOClient.Socket
|
||||
private renderDuration: number = 300
|
||||
private renderDuration: number = 200
|
||||
private updateTimer?: any
|
||||
private lastUpdate: number = 0
|
||||
private perf:number = 0
|
||||
|
||||
constructor(props: any) {
|
||||
super(props)
|
||||
@@ -30,21 +34,36 @@ export class Tree extends React.Component<TreeNodeProps, TreeState> {
|
||||
this.socket = io('http://localhost:3000')
|
||||
}
|
||||
|
||||
public componentDidMount() {
|
||||
let updateState = throttle((state: any) => {
|
||||
this.setState(state)
|
||||
updateState.cancel()
|
||||
updateState = throttle(() => {
|
||||
this.setState(state)
|
||||
}, Math.max(this.renderDuration * 5, 300), { trailing: true })
|
||||
}, 1000)
|
||||
public time(): number {
|
||||
const time = performance.now() - this.perf
|
||||
this.perf = performance.now()
|
||||
|
||||
return time
|
||||
}
|
||||
|
||||
public throttledStateUpdate(state: any) {
|
||||
if (this.updateTimer) {
|
||||
return
|
||||
}
|
||||
|
||||
const updateInterval = Math.max(this.renderDuration * 5, 200)
|
||||
const timeUntilNextUpdate = updateInterval - (performance.now() - this.lastUpdate)
|
||||
|
||||
this.updateTimer = setTimeout(() => {
|
||||
this.lastUpdate = performance.now()
|
||||
this.updateTimer && clearTimeout(this.updateTimer)
|
||||
this.updateTimer = undefined
|
||||
this.setState(state)
|
||||
}, Math.max(0, timeUntilNextUpdate))
|
||||
}
|
||||
|
||||
public componentDidMount() {
|
||||
this.socket.on('message', (msg: any) => {
|
||||
const edges = msg.topic.split('/')
|
||||
const node = q.TreeNodeFactory.fromEdgesAndValue(edges, Buffer.from(msg.payload, 'base64').toString())
|
||||
this.state.tree.updateWithNode(node.firstNode())
|
||||
|
||||
updateState({ msg, tree: this.state.tree })
|
||||
this.throttledStateUpdate({ msg, tree: this.state.tree })
|
||||
})
|
||||
}
|
||||
|
||||
@@ -56,10 +75,14 @@ export class Tree extends React.Component<TreeNodeProps, TreeState> {
|
||||
return <div>
|
||||
<List>
|
||||
<TreeNode
|
||||
isRoot={true}
|
||||
didSelectNode={this.props.didSelectNode}
|
||||
treeNode={this.state.tree}
|
||||
name="/" collapsed={false}
|
||||
performanceCallback={ms => this.renderDuration = ms}
|
||||
key="rootNode"
|
||||
performanceCallback={(ms: number) => {
|
||||
this.renderDuration = ms
|
||||
}}
|
||||
/>
|
||||
</List>
|
||||
</div>
|
||||
|
||||
@@ -1,15 +1,21 @@
|
||||
import * as React from 'react'
|
||||
import * as q from '../../../backend/src/Model'
|
||||
import List from '@material-ui/core/List'
|
||||
import ListItem from '@material-ui/core/ListItem'
|
||||
import Collapse from '@material-ui/core/Collapse'
|
||||
import { List, ListItem, Collapse, Typography } from '@material-ui/core'
|
||||
import { withTheme, Theme } from '@material-ui/core/styles'
|
||||
const throttle = require('lodash.throttle')
|
||||
import Slide from '@material-ui/core/Slide'
|
||||
import { isElementInViewport } from './helper/isElementInViewport'
|
||||
const collapseLimit = 3
|
||||
declare var performance: any
|
||||
|
||||
export interface TreeNodeProps {
|
||||
isRoot?: boolean
|
||||
treeNode: q.TreeNode
|
||||
name?: string | undefined
|
||||
collapsed?: boolean | undefined
|
||||
performanceCallback?: ((ms: number) => void) | undefined
|
||||
didSelectNode?: (node: q.TreeNode) => void
|
||||
theme: Theme
|
||||
}
|
||||
|
||||
interface TreeNodeState {
|
||||
@@ -19,28 +25,59 @@ interface TreeNodeState {
|
||||
edgeCount: number
|
||||
}
|
||||
|
||||
const collapseLimit = 0
|
||||
declare var performance: any
|
||||
|
||||
export class TreeNode extends React.Component<TreeNodeProps, TreeNodeState> {
|
||||
class TreeNode extends React.Component<TreeNodeProps, TreeNodeState> {
|
||||
private dirty: boolean = true
|
||||
private willUpdateTime: number = performance.now()
|
||||
private titleRef = React.createRef<HTMLElement>()
|
||||
private markAsDirty = () => {
|
||||
this.dirty = true
|
||||
if (!this.props.isRoot) {
|
||||
this.indicateUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
constructor(props: TreeNodeProps, state: TreeNodeState) {
|
||||
super(props, state)
|
||||
private indicateUpdate = throttle(() => {
|
||||
const title: any = this.titleRef.current
|
||||
if (title && isElementInViewport(title)) {
|
||||
title.style.animation = 'example 0.5s'
|
||||
setTimeout(() => {
|
||||
title.style.animation = ''
|
||||
}, 500)
|
||||
}
|
||||
}, 500)
|
||||
|
||||
constructor(props: TreeNodeProps) {
|
||||
super(props)
|
||||
const edgeCount = Object.keys(props.treeNode.edges).length
|
||||
const collapsed = edgeCount > collapseLimit
|
||||
|
||||
this.props.treeNode.on('update', () => {
|
||||
this.dirty = true
|
||||
})
|
||||
|
||||
this.state = { collapsed, edgeCount, collapsedOverride: props.collapsed, title: props.name }
|
||||
}
|
||||
|
||||
public componentDidMount() {
|
||||
this.props.treeNode.on('update', this.markAsDirty)
|
||||
}
|
||||
|
||||
public componentWillUnmount() {
|
||||
this.props.treeNode.removeListener('update', this.markAsDirty)
|
||||
}
|
||||
|
||||
private getStyles() {
|
||||
const { theme } = this.props
|
||||
return {
|
||||
collapsedSubnodes: {
|
||||
color: theme.palette.text.secondary,
|
||||
},
|
||||
container: {
|
||||
display: 'block',
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
public setState(state: any) {
|
||||
this.dirty = true
|
||||
this.dirty = this.state.collapsed !== state.collapsed
|
||||
|| this.state.collapsedOverride !== state.collapsedOverride
|
||||
|| this.state.edgeCount !== state.edgeCount
|
||||
|
||||
super.setState(state)
|
||||
}
|
||||
|
||||
@@ -49,7 +86,6 @@ export class TreeNode extends React.Component<TreeNodeProps, TreeNodeState> {
|
||||
}
|
||||
|
||||
public componentDidUpdate() {
|
||||
this.dirty = false
|
||||
if (this.props.performanceCallback) {
|
||||
const renderTime = performance.now() - this.willUpdateTime
|
||||
this.props.performanceCallback(renderTime)
|
||||
@@ -73,18 +109,25 @@ export class TreeNode extends React.Component<TreeNodeProps, TreeNodeState> {
|
||||
private renderNodes() {
|
||||
const edges = Object.values(this.props.treeNode.edges)
|
||||
const listItemStyle = {
|
||||
padding: '3px 8px 3px 8px',
|
||||
padding: '3px 8px 0px 8px',
|
||||
}
|
||||
|
||||
const listStyle = {
|
||||
padding: '3px 8px 3px 16px',
|
||||
padding: '3px 8px 0px 16px',
|
||||
}
|
||||
|
||||
if (edges.length > 0) {
|
||||
const listItems = edges
|
||||
.map(edge => edge.target)
|
||||
.map(node => <ListItem style={listItemStyle} button key={node.hash()}>
|
||||
<TreeNode didSelectNode={this.props.didSelectNode} treeNode={node} />
|
||||
</ListItem>)
|
||||
.map(node => (
|
||||
<ListItem key={node.hash()} style={listItemStyle} button>
|
||||
<TreeNode
|
||||
theme={this.props.theme}
|
||||
didSelectNode={this.props.didSelectNode}
|
||||
treeNode={node}
|
||||
/>
|
||||
</ListItem>
|
||||
))
|
||||
|
||||
return <Collapse in={!this.collapsed()} timeout="auto" unmountOnExit>
|
||||
<List style={listStyle}>{listItems}</List>
|
||||
@@ -100,13 +143,10 @@ export class TreeNode extends React.Component<TreeNodeProps, TreeNodeState> {
|
||||
}
|
||||
const name = this.state.title || (this.props.treeNode.sourceEdge && this.props.treeNode.sourceEdge.name)
|
||||
|
||||
return <span style={style} onClick={() => this.toggle()}>{name}</span>
|
||||
}
|
||||
|
||||
private getStyle(): React.CSSProperties {
|
||||
return {
|
||||
display: 'block',
|
||||
}
|
||||
return <span style={style} onClick={() => {
|
||||
this.toggle()
|
||||
this.props.didSelectNode && this.props.didSelectNode(this.props.treeNode)
|
||||
}>{name}</span>
|
||||
}
|
||||
|
||||
public componentWillReceiveProps() {
|
||||
@@ -128,7 +168,7 @@ export class TreeNode extends React.Component<TreeNodeProps, TreeNodeState> {
|
||||
? <span
|
||||
style={style}
|
||||
onMouseOver={() => this.props.didSelectNode && this.props.didSelectNode(this.props.treeNode)}
|
||||
> = {this.props.treeNode.message.toString()}</span>
|
||||
> = {this.props.treeNode.message.value.toString()}</span>
|
||||
: null
|
||||
}
|
||||
|
||||
@@ -137,23 +177,33 @@ export class TreeNode extends React.Component<TreeNodeProps, TreeNodeState> {
|
||||
}
|
||||
|
||||
private renderTitleLine() {
|
||||
const style = {
|
||||
const style: React.CSSProperties = {
|
||||
lineHeight: '1em',
|
||||
whiteSpace: 'nowrap',
|
||||
width: '15em',
|
||||
}
|
||||
return <div style={style}>{this.renderExpander()} {this.renderSourceEdge()} {this.renderCollapsedSubnodes()} {this.renderValue()}</div>
|
||||
return <div
|
||||
ref={this.titleRef}
|
||||
>
|
||||
<Typography style={style}>
|
||||
{this.renderExpander()} {this.renderSourceEdge()} {this.renderCollapsedSubnodes()} {this.renderValue()}
|
||||
</Typography>
|
||||
</div>
|
||||
}
|
||||
|
||||
public render() {
|
||||
this.dirty = false
|
||||
|
||||
const nodeStyle: React.CSSProperties = {
|
||||
display: 'block',
|
||||
}
|
||||
|
||||
return <div style={this.getStyle()}>
|
||||
{this.renderTitleLine()}
|
||||
<div style={nodeStyle}>
|
||||
{this.clear()}
|
||||
<div style={this.subnodesStyle()}>
|
||||
{this.collapsed() ? null : this.renderNodes()}
|
||||
return <div key={this.props.treeNode.hash()} style={ this.getStyles().container }>
|
||||
{ this.renderTitleLine() }
|
||||
<div style = { nodeStyle }>
|
||||
{ this.clear() }
|
||||
<div style = { this.subnodesStyle() }>
|
||||
{ this.collapsed() ? null : this.renderNodes() }
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -178,10 +228,8 @@ export class TreeNode extends React.Component<TreeNodeProps, TreeNodeState> {
|
||||
return null
|
||||
}
|
||||
|
||||
const style = {
|
||||
color: '#333',
|
||||
}
|
||||
return <span style={style}>({this.props.treeNode.leafes().length} nodes)</span>
|
||||
const messages = this.props.treeNode.leafes().map(leaf => leaf.messages).reduce((a, b) => a + b)
|
||||
return <span style={this.getStyles().collapsedSubnodes}>({this.props.treeNode.leafes().length} nodes, {messages} messages)</span>
|
||||
}
|
||||
|
||||
private subnodesStyle(): React.CSSProperties {
|
||||
@@ -190,3 +238,5 @@ export class TreeNode extends React.Component<TreeNodeProps, TreeNodeState> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default withTheme()(TreeNode)
|
||||
|
||||
12
app/src/components/helper/isElementInViewport.ts
Normal file
12
app/src/components/helper/isElementInViewport.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
declare const window: any
|
||||
declare const document: any
|
||||
|
||||
export function isElementInViewport(el: any) {
|
||||
const rect = el.getBoundingClientRect()
|
||||
return (
|
||||
rect.top >= 0 &&
|
||||
rect.left >= 0 &&
|
||||
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */
|
||||
rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */
|
||||
)
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
var LiveReloadPlugin = require('webpack-livereload-plugin');
|
||||
|
||||
module.exports = {
|
||||
entry: "./src/index.tsx",
|
||||
output: {
|
||||
@@ -30,6 +32,10 @@ module.exports = {
|
||||
]
|
||||
},
|
||||
|
||||
plugins: [
|
||||
new LiveReloadPlugin({})
|
||||
],
|
||||
|
||||
// When importing a module whose path matches one of the following, just
|
||||
// assume a corresponding global variable exists and use that instead.
|
||||
// This is important because it allows us to avoid bundling all of our
|
||||
|
||||
Reference in New Issue
Block a user