commit
						6be2d30b51
					
				
							
								
								
									
										14
									
								
								Dockerfile
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								Dockerfile
									
									
									
									
									
								
							| @ -1,14 +0,0 @@ | ||||
| FROM    centos:centos6 | ||||
| 
 | ||||
| # Enable EPEL for Node.js | ||||
| RUN     rpm -Uvh http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm | ||||
| # Install Node.js and npm | ||||
| RUN     yum install -y npm | ||||
| 
 | ||||
| # Bundle app source | ||||
| COPY . /src | ||||
| # Install app dependencies | ||||
| RUN cd /src; npm install | ||||
| 
 | ||||
| EXPOSE  3000 | ||||
| CMD ["node", "/src/bin/www"] | ||||
							
								
								
									
										12
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								package.json
									
									
									
									
									
								
							| @ -11,13 +11,13 @@ | ||||
|     "start": "node ./bin/www" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "body-parser": "1.12.0", | ||||
|     "debug": "2.1.1", | ||||
|     "express": "^4.11.2", | ||||
|     "geoip-lite": "^1.1.5", | ||||
|     "body-parser": "1.12.2", | ||||
|     "debug": "2.1.3", | ||||
|     "express": "^4.11.3", | ||||
|     "geoip-lite": "^1.1.6", | ||||
|     "jade": "^1.9.2", | ||||
|     "lodash": "^3.3.1", | ||||
|     "primus": "^2.4.12", | ||||
|     "lodash": "^3.6.0", | ||||
|     "primus": "^3.0.2", | ||||
|     "primus-emit": "^0.1.2", | ||||
|     "primus-spark-latency": "^0.1.1", | ||||
|     "serve-favicon": "^2.2.0", | ||||
|  | ||||
| @ -10,19 +10,35 @@ body { | ||||
| 	-moz-font-smoothing: antialiased; | ||||
| } | ||||
| 
 | ||||
| .stat-holder { | ||||
| .bg-success { | ||||
| 	background: #7bcc3a; | ||||
| } | ||||
| 
 | ||||
| .bg-info { | ||||
| 	background: #10a0de; | ||||
| } | ||||
| 
 | ||||
| .bg-warning { | ||||
| 	background: #FFD162; | ||||
| } | ||||
| 
 | ||||
| .bg-danger { | ||||
| 	background: #F74B4B; | ||||
| } | ||||
| 
 | ||||
| .container-fluid { | ||||
| 	padding-left: 30px; | ||||
| 	padding-right: 30px; | ||||
| } | ||||
| 
 | ||||
| .stat-holder { | ||||
| 	background: #090909; | ||||
| 	border: 1px solid rgba(255,255,255,0.05); | ||||
| } | ||||
| 
 | ||||
| .big-info { | ||||
| 	padding-bottom: 15px; | ||||
| 	padding-top: 15px; | ||||
| 	background: #090909; | ||||
| 	border: 1px solid rgba(255,255,255,0.05); | ||||
| } | ||||
| 
 | ||||
| .stats-boxes .big-info { | ||||
| 	margin-right: -30px; | ||||
| } | ||||
| 
 | ||||
| .big-info .icon-full-width i { | ||||
| @ -32,27 +48,22 @@ body { | ||||
| 	font-size: 70px; | ||||
| 	line-height: 70px; | ||||
| 	margin-right: 15px; | ||||
| 	margin-left: -15px; | ||||
| } | ||||
| 
 | ||||
| .big-info span { | ||||
| 	opacity: 0.7; | ||||
| } | ||||
| 
 | ||||
| .big-info span.small-title { | ||||
| .big-info span.small-title, | ||||
| .big-info div.small-title-miner { | ||||
| 	display: block; | ||||
| 	font-weight: 700; | ||||
| 	font-size: 14px; | ||||
| 	line-height: 20px; | ||||
| 	letter-spacing: 1px; | ||||
| 	text-transform: uppercase; | ||||
| 	color: #aaa !important; | ||||
| } | ||||
| 
 | ||||
| .big-info.chart { | ||||
| 	padding-left: 14px; | ||||
| 	padding-right: 14px; | ||||
| 	-webkit-box-sizing: border-box | ||||
| 	box-sizing: border-box; | ||||
| 	color: #aaa; | ||||
| } | ||||
| 
 | ||||
| .big-info span.big-details { | ||||
| @ -67,6 +78,46 @@ body { | ||||
| 	padding-top: 15px; | ||||
| } | ||||
| 
 | ||||
| .big-info.chart { | ||||
| 	height: 120px; | ||||
| 	-webkit-box-sizing: border-box | ||||
| 	box-sizing: border-box; | ||||
| } | ||||
| 
 | ||||
| .big-info.chart.double-chart { | ||||
| 	height: 242px; | ||||
| } | ||||
| 
 | ||||
| .blocks-holder { | ||||
| 	padding-top: 5px; | ||||
| } | ||||
| 
 | ||||
| .blocks-holder div.small-title-miner { | ||||
| 	font-size: 12px; | ||||
| 	font-weight: normal; | ||||
| 	letter-spacing: 0px; | ||||
| 	text-transform: none; | ||||
| 	white-space: nowrap; | ||||
| 	-webkit-font-smoothing: subpixel-antialiased; | ||||
| 	-moz-font-smoothing: subpixel-antialiased; | ||||
| 	color: #777; | ||||
| } | ||||
| 
 | ||||
| .blocks-holder .block-count { | ||||
| 	float: right; | ||||
| 	line-height: 18px; | ||||
| 	color: #aaa; | ||||
| } | ||||
| 
 | ||||
| .blocks-holder .block { | ||||
| 	width: 6px; | ||||
| 	height: 6px; | ||||
| 	margin: 2px 1px 6px 1px; | ||||
| 	float: left; | ||||
| 	-webkit-border-radius: 1px; | ||||
| 	border-radius: 1px; | ||||
| } | ||||
| 
 | ||||
| .jqstooltip { | ||||
| 
 | ||||
| } | ||||
| @ -195,6 +246,6 @@ table td { | ||||
| 	}*/ | ||||
| } | ||||
| 
 | ||||
| .ng-cloak { | ||||
|     display: none !important; | ||||
| [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak { | ||||
|   display: none !important; | ||||
| } | ||||
|  | ||||
| @ -14,15 +14,20 @@ function StatsCtrl($scope, $filter, socket, _, toastr) { | ||||
| 	$scope.lastDifficulty = 0; | ||||
| 	$scope.upTimeTotal = 0; | ||||
| 	$scope.avgBlockTime = 0; | ||||
| 	$scope.bestStats = {}; | ||||
| 
 | ||||
| 	$scope.lastBlocksTime = []; | ||||
| 	$scope.difficultyChange = []; | ||||
| 	$scope.transactionDensity = []; | ||||
| 	$scope.gasSpending = []; | ||||
| 	$scope.miners = []; | ||||
| 
 | ||||
| 	$scope.nodes = []; | ||||
| 	$scope.map = []; | ||||
| 
 | ||||
| 	$scope.predicate = ['-stats.block.number', 'stats.block.propagation']; | ||||
| 	$scope.reverse = false; | ||||
| 
 | ||||
| 	$scope.timeout = setInterval(function(){ | ||||
| 		$scope.$apply(); | ||||
| 	}, 1000); | ||||
| @ -131,39 +136,24 @@ function StatsCtrl($scope, $filter, socket, _, toastr) { | ||||
| 			if(bestBlock > $scope.bestBlock) | ||||
| 			{ | ||||
| 				$scope.bestBlock = bestBlock; | ||||
| 
 | ||||
| 				$scope.lastBlock = _.max($scope.nodes, function(node) { | ||||
| 				$scope.bestStats = _.max($scope.nodes, function(node) { | ||||
| 					return parseInt(node.stats.block.number); | ||||
| 				}).stats.block.received; | ||||
| 				}).stats; | ||||
| 
 | ||||
| 				$scope.lastBlocksTime = _.max($scope.nodes, function(node) { | ||||
| 					return parseInt(node.stats.block.number); | ||||
| 				}).stats.blockTimes; | ||||
| 				$scope.lastBlock = $scope.bestStats.block.received; | ||||
| 				$scope.lastBlocksTime = $scope.bestStats.blockTimes; | ||||
| 				$scope.difficultyChange = $scope.bestStats.difficulty; | ||||
| 				$scope.transactionDensity = $scope.bestStats.txDensity; | ||||
| 				$scope.gasSpending = $scope.bestStats.gasSpending; | ||||
| 				$scope.miners = $scope.bestStats.miners; | ||||
| 
 | ||||
| 				$scope.getNumber = function(num) { | ||||
| 					return new Array(num); | ||||
| 				} | ||||
| 
 | ||||
| 				jQuery('.spark-blocktimes').sparkline($scope.lastBlocksTime.reverse(), {type: 'bar', tooltipSuffix: 's'}); | ||||
| 
 | ||||
| 				$scope.difficultyChange = _.max($scope.nodes, function(node) { | ||||
| 					return parseInt(node.stats.block.number); | ||||
| 				}).stats.difficulty; | ||||
| 
 | ||||
| 				$scope.difficultyChange.pop(); | ||||
| 
 | ||||
| 				jQuery('.spark-difficulty').sparkline($scope.difficultyChange.reverse(), {type: 'bar'}); | ||||
| 
 | ||||
| 				$scope.transactionDensity = _.max($scope.nodes, function(node) { | ||||
| 					return parseInt(node.stats.block.number); | ||||
| 				}).stats.txDensity; | ||||
| 
 | ||||
| 				$scope.transactionDensity.pop(); | ||||
| 
 | ||||
| 				jQuery('.spark-transactions').sparkline($scope.transactionDensity.reverse(), {type: 'bar'}); | ||||
| 
 | ||||
| 				$scope.gasSpending = _.max($scope.nodes, function(node) { | ||||
| 					return parseInt(node.stats.block.number); | ||||
| 				}).stats.gasSpending; | ||||
| 
 | ||||
| 				$scope.gasSpending.pop(); | ||||
| 
 | ||||
| 				jQuery('.spark-gasspending').sparkline($scope.gasSpending.reverse(), {type: 'bar'}); | ||||
| 			} | ||||
| 
 | ||||
|  | ||||
| @ -189,7 +189,26 @@ angular.module('netStatsApp.filters', []) | ||||
| .filter('bubbleClass', function() { | ||||
| 	return function(node, bestBlock) { | ||||
| 		return mainClass(node, bestBlock).replace('text-', ''); | ||||
| 	} | ||||
| 	}; | ||||
| }) | ||||
| .filter('minerNameFilter', function() { | ||||
| 	return function(name) { | ||||
| 		return name.replace('0x', ''); | ||||
| 	}; | ||||
| }) | ||||
| .filter('minerBlocksClass', function() { | ||||
| 	return function(blocks) { | ||||
| 		if(blocks <= 6) | ||||
| 			return 'bg-success'; | ||||
| 
 | ||||
| 		if(blocks <= 12) | ||||
| 			return 'bg-info'; | ||||
| 
 | ||||
| 		if(blocks <= 18) | ||||
| 			return 'bg-warning'; | ||||
| 
 | ||||
| 		return 'bg-danger'; | ||||
| 	}; | ||||
| }); | ||||
| 
 | ||||
| function mainClass(node, bestBlock) | ||||
|  | ||||
| @ -10,7 +10,6 @@ | ||||
| 	$.fn.sparkline.defaults.bar.barSpacing = 2; | ||||
| 	$.fn.sparkline.defaults.bar.tooltipClassname = 'jqstooltip'; | ||||
| 	$.fn.sparkline.defaults.bar.tooltipOffsetX = 0; | ||||
| 	// $.fn.sparkline.defaults.bar.tooltipFormat = $.spformat('<div class="tooltip-arrow" style="left: 50%;"></div><div class="tooltip-inner"><span style="color: {{color}}">●</span><br>{{prefix}}{{value}}{{suffix}}</div>');
 | ||||
| 	$.fn.sparkline.defaults.bar.tooltipFormat = $.spformat('<div class="tooltip-arrow" style="left: 50%;"></div><div class="tooltip-inner">{{prefix}}{{value}}{{suffix}}</div>'); | ||||
| 	$.fn.sparkline.defaults.bar.colorMap = $.range_map({ | ||||
| 		'1:12': '#7bcc3a', | ||||
|  | ||||
							
								
								
									
										276
									
								
								views/index.jade
									
									
									
									
									
								
							
							
						
						
									
										276
									
								
								views/index.jade
									
									
									
									
									
								
							| @ -3,142 +3,148 @@ extends layout | ||||
| block content | ||||
|   div.container-fluid(ng-controller='StatsCtrl') | ||||
|     div.row(ng-cloak) | ||||
|       div.col-xs-12 | ||||
|         //- div.col-sm-12 | ||||
|           //- h1= title | ||||
|           //- p Welcome to #{title} | ||||
| 
 | ||||
|         //- div.clearfix | ||||
| 
 | ||||
|         div.col-xs-2.stat-holder | ||||
|           div.row.big-info.nodesactive(class="{{ nodesActive | nodesActiveClass : nodesTotal }}") | ||||
|             div.pull-left.icon-full-width | ||||
|               i.icon-node | ||||
|             div.pull-left | ||||
|               span.small-title active nodes | ||||
|               span.big-details {{nodesActive}}/{{nodesTotal}} | ||||
|             div.clearfix | ||||
|         div.col-xs-2.stat-holder | ||||
|           div.row.big-info.uptime(class="{{ upTimeTotal | upTimeClass }}") | ||||
|             div.pull-left.icon-full-width | ||||
|               i.icon-bulb | ||||
|             div.pull-left | ||||
|               span.small-title up-time | ||||
|               span.big-details {{ upTimeTotal | upTimeFilter }} | ||||
|             div.clearfix | ||||
|         div.col-xs-2.stat-holder | ||||
|           div.row.big-info.difficulty.text-info | ||||
|             div.pull-left.icon-full-width | ||||
|               i.icon-difficulty | ||||
|             div.pull-left | ||||
|               span.small-title difficulty | ||||
|               span.big-details {{ lastDifficulty }} | ||||
|             div.clearfix | ||||
|         div.col-xs-2.stat-holder | ||||
|           div.row.big-info.bestblock.text-info | ||||
|             div.pull-left.icon-full-width | ||||
|               i.icon-block | ||||
|             div.pull-left | ||||
|               span.small-title best block | ||||
|               span.big-details {{"#" + bestBlock}} | ||||
|             div.clearfix | ||||
|         div.col-xs-2.stat-holder | ||||
|           div.row.big-info.blocktime(class="{{ lastBlock | timeClass }}") | ||||
|             div.pull-left.icon-full-width | ||||
|               i.icon-time | ||||
|             div.pull-left | ||||
|               span.small-title last block | ||||
|               span.big-details {{ lastBlock | blockTimeFilter }} | ||||
|             div.clearfix | ||||
|         div.col-xs-2.stat-holder | ||||
|           div.row.big-info.avgblocktime(class="{{ avgBlockTime | timeClass }}") | ||||
|             div.pull-left.icon-full-width | ||||
|               i.icon-gas | ||||
|             div.pull-left | ||||
|               span.small-title avg block time | ||||
|               span.big-details {{ avgBlockTime | avgTimeFilter }} | ||||
|             div.clearfix | ||||
| 
 | ||||
|         div.clearfix | ||||
| 
 | ||||
|       div.col-xs-12 | ||||
|         div.row | ||||
|           div.col-xs-4.stats-boxes(style="padding-top: 30px;") | ||||
|             div.row | ||||
|               div.col-xs-6.stat-holder | ||||
|                 div.big-info.chart | ||||
|                   span.small-title block time | ||||
|                   span.big-details.spark-blocktimes | ||||
| 
 | ||||
|               div.col-xs-6.stat-holder | ||||
|                 div.big-info.chart | ||||
|                   span.small-title difficulty | ||||
|                   span.big-details.spark-difficulty | ||||
| 
 | ||||
|               div.col-xs-6.stat-holder | ||||
|                 div.big-info.chart | ||||
|                   span.small-title transactions | ||||
|                   span.big-details.spark-transactions | ||||
| 
 | ||||
|               div.col-xs-6.stat-holder | ||||
|                 div.big-info.chart | ||||
|                   span.small-title gas spending | ||||
|                   span.big-details.spark-gasspending | ||||
| 
 | ||||
|           div.col-xs-4 | ||||
| 
 | ||||
|           div.col-xs-4 | ||||
|             div.col-xs-12 | ||||
|               nodemap#mapHolder(data="map") | ||||
|       div.col-xs-2.stat-holder | ||||
|         div.big-info.nodesactive(class="{{ nodesActive | nodesActiveClass : nodesTotal }}") | ||||
|           div.pull-left.icon-full-width | ||||
|             i.icon-node | ||||
|           div.pull-left | ||||
|             span.small-title active nodes | ||||
|             span.big-details {{nodesActive}}/{{nodesTotal}} | ||||
|           div.clearfix | ||||
|       div.col-xs-2.stat-holder | ||||
|         div.big-info.uptime(class="{{ upTimeTotal | upTimeClass }}") | ||||
|           div.pull-left.icon-full-width | ||||
|             i.icon-bulb | ||||
|           div.pull-left | ||||
|             span.small-title up-time | ||||
|             span.big-details {{ upTimeTotal | upTimeFilter }} | ||||
|           div.clearfix | ||||
|       div.col-xs-2.stat-holder | ||||
|         div.big-info.difficulty.text-info | ||||
|           div.pull-left.icon-full-width | ||||
|             i.icon-difficulty | ||||
|           div.pull-left | ||||
|             span.small-title difficulty | ||||
|             span.big-details {{ lastDifficulty }} | ||||
|           div.clearfix | ||||
|       div.col-xs-2.stat-holder | ||||
|         div.big-info.bestblock.text-info | ||||
|           div.pull-left.icon-full-width | ||||
|             i.icon-block | ||||
|           div.pull-left | ||||
|             span.small-title best block | ||||
|             span.big-details {{"#" + bestBlock}} | ||||
|           div.clearfix | ||||
|       div.col-xs-2.stat-holder | ||||
|         div.big-info.blocktime(class="{{ lastBlock | timeClass }}") | ||||
|           div.pull-left.icon-full-width | ||||
|             i.icon-time | ||||
|           div.pull-left | ||||
|             span.small-title last block | ||||
|             span.big-details {{ lastBlock | blockTimeFilter }} | ||||
|           div.clearfix | ||||
|       div.col-xs-2.stat-holder | ||||
|         div.big-info.avgblocktime(class="{{ avgBlockTime | timeClass }}") | ||||
|           div.pull-left.icon-full-width | ||||
|             i.icon-gas | ||||
|           div.pull-left | ||||
|             span.small-title avg block time | ||||
|             span.big-details {{ avgBlockTime | avgTimeFilter }} | ||||
|           div.clearfix | ||||
| 
 | ||||
|       div.clearfix | ||||
| 
 | ||||
|       div.col-xs-12 | ||||
|         //- h1 Nodes in detail | ||||
|     div.row | ||||
|       div.col-xs-4.stats-boxes(style="padding-top: 30px;") | ||||
|         div.row | ||||
|           div.col-xs-6.stat-holder | ||||
|             div.big-info.chart | ||||
|               span.small-title block time | ||||
|               span.big-details.spark-blocktimes | ||||
| 
 | ||||
|         table.table.table-striped | ||||
|           thead | ||||
|             tr.text-info | ||||
|               th | ||||
|                 i.icon-node(data-toggle="tooltip", data-placement="top", title="Node") | ||||
|               th.th-nodename | ||||
|                 i.icon-laptop(data-toggle="tooltip", data-placement="top", title="Node type") | ||||
|               th.th-latency | ||||
|                 i.icon-clock(data-toggle="tooltip", data-placement="top", title="Node latency") | ||||
|               th | ||||
|                 i.icon-mining(data-toggle="tooltip", data-placement="top", title="Is mining") | ||||
|               th | ||||
|                 i.icon-group(data-toggle="tooltip", data-placement="top", title="Peers") | ||||
|               th | ||||
|                 i.icon-network(data-toggle="tooltip", data-placement="top", title="Pending transactions") | ||||
|               th | ||||
|                 i.icon-block(data-toggle="tooltip", data-placement="top", title="Last node block") | ||||
|               th.th-blockhash   | ||||
|               th | ||||
|                 i.icon-check-o(data-toggle="tooltip", data-placement="top", title="Block transactions") | ||||
|               th.th-blocktime | ||||
|                 i.icon-time(data-toggle="tooltip", data-placement="top", title="Last block time") | ||||
|               th | ||||
|                 i.icon-gas(data-toggle="tooltip", data-placement="top", title="Propagation time") | ||||
|               th | ||||
|                 i.icon-bulb(data-toggle="tooltip", data-placement="top", title="Up-time") | ||||
|           tbody | ||||
|             tr(ng-repeat='node in nodes', class="{{ node.stats | mainClass : bestBlock }}") | ||||
|               td(rel="{{node.id}}") | ||||
|                 span.small(data-toggle="tooltip", data-placement="top", data-original-title="{{node.geo | geoTooltip}}") {{node.info.name}} | ||||
|                 span.small  ({{node.info.ip}}) | ||||
|               td | ||||
|                 div.small(ng-bind-html="node.info.node | nodeVersion") | ||||
|                 //- div.small {{node.info.os}}, {{node.info.os_v}} | ||||
|               td.small(class="{{ node.stats | latencyClass }}") {{node.stats | latencyFilter}} | ||||
|               td(class="{{ node.stats.mining | miningClass }}") | ||||
|                 i.small(class="{{ node.stats.mining | miningIconClass }}") | ||||
|               td(class="{{ node.stats.peers | peerClass }}", style="padding-left: 11px;") {{node.stats.peers}} | ||||
|               td(style="padding-left: 15px;") {{node.stats.pending}} | ||||
|               td(class="{{ node.stats.block.number | blockClass : bestBlock }}") {{'#' + node.stats.block.number}} | ||||
|               td(class="{{ node.stats.block.number | blockClass : bestBlock }}") | ||||
|                 span.small {{node.stats.block.hash}} | ||||
|               td(style="padding-left: 14px;") {{node.stats.block.transactions.length || 0}} | ||||
|               td(class="{{ node.stats.block.timestamp | timeClass }}") {{node.stats.block.received | blockTimeFilter }} | ||||
|               td(class="{{ node.stats.block.propagation | propagationTimeClass }}") {{node.stats.block.propagation | blockPropagationFilter}} | ||||
|               td(class="{{ node.stats.uptime | upTimeClass }}") {{ node.stats.uptime | upTimeFilter }} | ||||
|           div.col-xs-6.stat-holder | ||||
|             div.big-info.chart | ||||
|               span.small-title difficulty | ||||
|               span.big-details.spark-difficulty | ||||
| 
 | ||||
|           div.col-xs-6.stat-holder | ||||
|             div.big-info.chart | ||||
|               span.small-title transactions | ||||
|               span.big-details.spark-transactions | ||||
| 
 | ||||
|           div.col-xs-6.stat-holder | ||||
|             div.big-info.chart | ||||
|               span.small-title gas spending | ||||
|               span.big-details.spark-gasspending | ||||
| 
 | ||||
|       div.col-xs-2.stats-boxes(style="padding-top: 30px;") | ||||
|         div.row | ||||
|           div.col-xs-12.stat-holder | ||||
|             div.big-info.chart.double-chart | ||||
|               span.small-title last blocks miners | ||||
|               div.blocks-holder(ng-repeat='miner in miners', data-toggle="tooltip", data-placement="right", title="{{miner.blocks}}") | ||||
|                 div.block-count ({{miner.blocks}}) | ||||
|                 div.small-title-miner {{miner.miner | minerNameFilter}} | ||||
|                 div.block(ng-repeat="i in getNumber(miner.blocks) track by $index", class="{{miner.blocks | minerBlocksClass}}") | ||||
|                 div.clearfix | ||||
| 
 | ||||
|       div.col-xs-2.stats-boxes(style="padding-top: 30px;") | ||||
|         div.row | ||||
|           //- div.col-xs-12.stat-holder | ||||
|           //-   div.big-info.chart | ||||
|           //-     span.small-title miners | ||||
|           //-     span.big-details test | ||||
| 
 | ||||
|       div.col-xs-4 | ||||
|         div.col-xs-12 | ||||
|           nodemap#mapHolder(data="map") | ||||
| 
 | ||||
|       div.clearfix | ||||
| 
 | ||||
|     div.row | ||||
|       table.table.table-striped | ||||
|         thead | ||||
|           tr.text-info | ||||
|             th | ||||
|               i.icon-node(data-toggle="tooltip", data-placement="top", title="Node name", ng-click="predicate = 'info.name'; reverse=!reverse") | ||||
|             th.th-nodename | ||||
|               i.icon-laptop(data-toggle="tooltip", data-placement="top", title="Node type") | ||||
|             th.th-latency | ||||
|               i.icon-clock(data-toggle="tooltip", data-placement="top", title="Node latency") | ||||
|             th | ||||
|               i.icon-mining(data-toggle="tooltip", data-placement="top", title="Is mining") | ||||
|             th | ||||
|               i.icon-group(data-toggle="tooltip", data-placement="top", title="Peers") | ||||
|             th | ||||
|               i.icon-network(data-toggle="tooltip", data-placement="top", title="Pending transactions") | ||||
|             th | ||||
|               i.icon-block(data-toggle="tooltip", data-placement="top", title="Last block", ng-click="predicate = ['-stats.block.number', 'stats.block.propagation']; reverse=!reverse") | ||||
|             th.th-blockhash   | ||||
|             th | ||||
|               i.icon-check-o(data-toggle="tooltip", data-placement="top", title="Block transactions") | ||||
|             th.th-blocktime | ||||
|               i.icon-time(data-toggle="tooltip", data-placement="top", title="Last block time") | ||||
|             th | ||||
|               i.icon-gas(data-toggle="tooltip", data-placement="top", title="Propagation time") | ||||
|             th | ||||
|               i.icon-bulb(data-toggle="tooltip", data-placement="top", title="Up-time") | ||||
|         tbody | ||||
|           tr(ng-repeat='node in nodes | orderBy:predicate:reverse', class="{{ node.stats | mainClass : bestBlock }}") | ||||
|             td(rel="{{node.id}}") | ||||
|               span.small(data-toggle="tooltip", data-placement="top", data-original-title="{{node.geo | geoTooltip}}") {{node.info.name}} | ||||
|               span.small  ({{node.info.ip}}) | ||||
|             td | ||||
|               div.small(ng-bind-html="node.info.node | nodeVersion") | ||||
|               //- div.small {{node.info.os}}, {{node.info.os_v}} | ||||
|             td.small(class="{{ node.stats | latencyClass }}") {{node.stats | latencyFilter}} | ||||
|             td(class="{{ node.stats.mining | miningClass }}") | ||||
|               i.small(class="{{ node.stats.mining | miningIconClass }}") | ||||
|             td(class="{{ node.stats.peers | peerClass }}", style="padding-left: 11px;") {{node.stats.peers}} | ||||
|             td(style="padding-left: 15px;") {{node.stats.pending}} | ||||
|             td(class="{{ node.stats.block.number | blockClass : bestBlock }}") {{'#' + node.stats.block.number}} | ||||
|             td(class="{{ node.stats.block.number | blockClass : bestBlock }}") | ||||
|               span.small {{node.stats.block.hash}} | ||||
|             td(style="padding-left: 14px;") {{node.stats.block.transactions.length || 0}} | ||||
|             td(class="{{ node.stats.block.timestamp | timeClass }}") {{node.stats.block.received | blockTimeFilter }} | ||||
|             td(class="{{ node.stats.block.propagation | propagationTimeClass }}") {{node.stats.block.propagation | blockPropagationFilter}} | ||||
|             td(class="{{ node.stats.uptime | upTimeClass }}") {{ node.stats.uptime | upTimeFilter }} | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user