pool.dero.io Dero pool source for mining Dero.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

437 lines
14KB

  1. <!DOCTYPE html>
  2. <html>
  3. <head lang="en">
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1">
  6. <title>Sumokoin Mining Pool</title>
  7. <!-- favicon -->
  8. <link rel="shortcut icon" type="image/x-icon" href="/favicon.ico">
  9. <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
  10. <script src="//cdnjs.cloudflare.com/ajax/libs/jquery-timeago/1.4.0/jquery.timeago.min.js"></script>
  11. <script src="//cdnjs.cloudflare.com/ajax/libs/jquery-sparklines/2.1.2/jquery.sparkline.min.js"></script>
  12. <link href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
  13. <script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
  14. <link href="//netdna.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css" rel="stylesheet">
  15. <link href="//fonts.googleapis.com/css?family=Inconsolata" rel="stylesheet" type="text/css">
  16. <script src="config.js"></script>
  17. <script src="custom.js"></script>
  18. <style>
  19. @import url(//fonts.googleapis.com/css?family=Montserrat:400,700);
  20. #coinName{
  21. text-transform: capitalize;
  22. }
  23. body {
  24. padding-top: 65px;
  25. padding-bottom: 80px;
  26. overflow-y: scroll;
  27. }
  28. .container{
  29. font-size: 1.2em;
  30. }
  31. #loading{
  32. font-size: 2em;
  33. }
  34. .stats {
  35. margin-bottom: 10px;
  36. margin-top: 5px;
  37. }
  38. .stats:last-child{
  39. width: auto;
  40. }
  41. .stats > h3 > i{
  42. font-size: 0.80em;
  43. width: 21px;
  44. }
  45. .stats > div{
  46. padding: 5px 0;
  47. }
  48. .stats > div > .fa {
  49. width: 25px;
  50. }
  51. .stats > div > span:first-of-type{
  52. font-weight: bold;
  53. }
  54. #stats_updated{
  55. opacity: 0;
  56. float: right;
  57. margin-left: 30px;
  58. color: #e8e8e8;
  59. line-height: 47px;
  60. font-size: 0.9em;
  61. }
  62. footer{
  63. position: fixed;
  64. bottom: 0;
  65. width: 100%;
  66. background-color: #f5f5f5;
  67. }
  68. footer > div{
  69. margin: 10px auto;
  70. text-align: center;
  71. }
  72. .sumo-orange{
  73. color: orange;
  74. }
  75. .navbar-header .navbar-brand {
  76. text-transform: uppercase;
  77. font-family: Montserrat,"Helvetica Neue",Helvetica,Arial,sans-serif;
  78. font-weight: 700;
  79. }
  80. .navbar-header .navbar-brand span{
  81. font-size: 70%;
  82. padding-left: 23px;
  83. }
  84. .navbar-header .navbar-brand:focus {
  85. outline: 0;
  86. }
  87. </style>
  88. <link href="custom.css" rel="stylesheet">
  89. </head>
  90. <body>
  91. <script>
  92. var docCookies = {
  93. getItem: function (sKey) {
  94. return decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")) || null;
  95. },
  96. setItem: function (sKey, sValue, vEnd, sPath, sDomain, bSecure) {
  97. if (!sKey || /^(?:expires|max\-age|path|domain|secure)$/i.test(sKey)) { return false; }
  98. var sExpires = "";
  99. if (vEnd) {
  100. switch (vEnd.constructor) {
  101. case Number:
  102. sExpires = vEnd === Infinity ? "; expires=Fri, 31 Dec 9999 23:59:59 GMT" : "; max-age=" + vEnd;
  103. break;
  104. case String:
  105. sExpires = "; expires=" + vEnd;
  106. break;
  107. case Date:
  108. sExpires = "; expires=" + vEnd.toUTCString();
  109. break;
  110. }
  111. }
  112. document.cookie = encodeURIComponent(sKey) + "=" + encodeURIComponent(sValue) + sExpires + (sDomain ? "; domain=" + sDomain : "") + (sPath ? "; path=" + sPath : "") + (bSecure ? "; secure" : "");
  113. return true;
  114. },
  115. removeItem: function (sKey, sPath, sDomain) {
  116. if (!sKey || !this.hasItem(sKey)) { return false; }
  117. document.cookie = encodeURIComponent(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT" + ( sDomain ? "; domain=" + sDomain : "") + ( sPath ? "; path=" + sPath : "");
  118. return true;
  119. },
  120. hasItem: function (sKey) {
  121. return (new RegExp("(?:^|;\\s*)" + encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")).test(document.cookie);
  122. }
  123. };
  124. function getTransactionUrl(id) {
  125. return transactionExplorer.replace('{symbol}', lastStats.config.symbol.toLowerCase()).replace('{id}', id);
  126. }
  127. $.fn.update = function(txt){
  128. var el = this[0];
  129. if (el.textContent !== txt)
  130. el.textContent = txt;
  131. return this;
  132. };
  133. function updateTextClasses(className, text){
  134. var els = document.getElementsByClassName(className);
  135. for (var i = 0; i < els.length; i++){
  136. var el = els[i];
  137. if (el.textContent !== text)
  138. el.textContent = text;
  139. }
  140. }
  141. function updateText(elementId, text){
  142. var el = document.getElementById(elementId);
  143. if (el.textContent !== text){
  144. el.textContent = text;
  145. }
  146. return el;
  147. }
  148. var currentPage;
  149. var lastStats;
  150. function getReadableCoins(coins, digits, withoutSymbol){
  151. var amount = (parseInt(coins || 0) / lastStats.config.coinUnits).toFixed(digits || lastStats.config.coinUnits.toString().length - 1);
  152. return amount + (withoutSymbol ? '' : (' ' + lastStats.config.symbol));
  153. }
  154. function formatDate(time){
  155. if (!time) return '';
  156. return new Date(parseInt(time) * 1000).toLocaleString();
  157. }
  158. function formatPaymentLink(hash){
  159. return '<a target="explorer" href="' + getTransactionUrl(hash) + '">' + hash + '</a>';
  160. }
  161. function getPaymentRowElement(payment, jsonString){
  162. var row = document.createElement('tr');
  163. row.setAttribute('data-json', jsonString);
  164. row.setAttribute('data-time', payment.time);
  165. row.setAttribute('id', 'paymentRow' + payment.time);
  166. row.innerHTML = getPaymentCells(payment);
  167. return row;
  168. }
  169. function parsePayment(time, serializedPayment){
  170. var parts = serializedPayment.split(':');
  171. return {
  172. time: parseInt(time),
  173. hash: parts[0],
  174. amount: parts[1],
  175. fee: parts[2],
  176. mixin: parts[3],
  177. recipients: parts[4]
  178. };
  179. }
  180. function renderPayments(paymentsResults){
  181. var $paymentsRows = $('#payments_rows');
  182. for (var i = 0; i < paymentsResults.length; i += 2){
  183. var payment = parsePayment(paymentsResults[i + 1], paymentsResults[i]);
  184. var paymentJson = JSON.stringify(payment);
  185. var existingRow = document.getElementById('paymentRow' + payment.time);
  186. if (existingRow && existingRow.getAttribute('data-json') !== paymentJson){
  187. $(existingRow).replaceWith(getPaymentRowElement(payment, paymentJson));
  188. }
  189. else if (!existingRow){
  190. var paymentElement = getPaymentRowElement(payment, paymentJson);
  191. var inserted = false;
  192. var rows = $paymentsRows.children().get();
  193. for (var f = 0; f < rows.length; f++) {
  194. var pTime = parseInt(rows[f].getAttribute('data-time'));
  195. if (pTime < payment.time){
  196. inserted = true;
  197. $(rows[f]).before(paymentElement);
  198. break;
  199. }
  200. }
  201. if (!inserted)
  202. $paymentsRows.append(paymentElement);
  203. }
  204. }
  205. }
  206. function pulseLiveUpdate(){
  207. var stats_update = document.getElementById('stats_updated');
  208. stats_update.style.transition = 'opacity 100ms ease-out';
  209. stats_update.style.opacity = 1;
  210. setTimeout(function(){
  211. stats_update.style.transition = 'opacity 7000ms linear';
  212. stats_update.style.opacity = 0;
  213. }, 500);
  214. }
  215. window.onhashchange = function(){
  216. routePage();
  217. };
  218. function fetchLiveStats() {
  219. $.ajax({
  220. url: api + '/live_stats',
  221. dataType: 'json',
  222. cache: 'false'
  223. }).done(function(data){
  224. pulseLiveUpdate();
  225. lastStats = data;
  226. updateIndex();
  227. currentPage.update();
  228. }).always(function () {
  229. fetchLiveStats();
  230. });
  231. }
  232. function fetchHealthState() {
  233. $.ajax({
  234. url: api + '/health',
  235. dataType: 'json',
  236. cache: 'false'
  237. }).done(function(data){
  238. if (data.status == "OK") {
  239. $('#health_warning').hide(100);
  240. } else {
  241. $('#health_warning').show(100);
  242. }
  243. });
  244. }
  245. // Every 5 seconds check the health status.
  246. setInterval(fetchHealthState, 5000);
  247. fetchHealthState();
  248. function floatToString(float) {
  249. return float.toFixed(6).replace(/[0\.]+$/, '');
  250. }
  251. var xhrPageLoading;
  252. function routePage(loadedCallback) {
  253. if (currentPage) currentPage.destroy();
  254. $('#page').html('');
  255. $('#loading').show();
  256. if (xhrPageLoading)
  257. xhrPageLoading.abort();
  258. $('.hot_link').parent().removeClass('active');
  259. var $link = $('a.hot_link[href="' + (window.location.hash || '#') + '"]');
  260. $link.parent().addClass('active');
  261. var page = $link.data('page');
  262. xhrPageLoading = $.ajax({
  263. url: 'pages/' + page,
  264. cache: false,
  265. success: function (data) {
  266. $('#loading').hide();
  267. $('#page').show().html(data);
  268. currentPage.update();
  269. if (loadedCallback) loadedCallback();
  270. }
  271. });
  272. }
  273. function updateIndex(){
  274. //updateText('coinName', lastStats.config.coin);
  275. updateText('poolVersion', lastStats.config.version);
  276. }
  277. function getBlockchainUrl(id) {
  278. return blockchainExplorer.replace('{symbol}', lastStats.config.symbol.toLowerCase()).replace('{id}', id);
  279. }
  280. $(function(){
  281. $("head").append("<link rel='stylesheet' href=" + themeCss + ">");
  282. $.get(api + '/stats', function(data){
  283. lastStats = data;
  284. updateIndex();
  285. routePage(fetchLiveStats);
  286. });
  287. });
  288. </script>
  289. <div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
  290. <div class="container">
  291. <div class="navbar-header">
  292. <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
  293. <span class="sr-only">Toggle navigation</span>
  294. <span class="icon-bar"></span>
  295. <span class="icon-bar"></span>
  296. <span class="icon-bar"></span>
  297. </button>
  298. <a class="navbar-brand page-scroll" href="/">
  299. <i class="fa fa-circle sumo-orange"></i> Sumokoin Pool
  300. </a>
  301. </div>
  302. <div class="collapse navbar-collapse">
  303. <ul class="nav navbar-nav">
  304. <li class="active"><a class="hot_link" data-page="home.html" href="#">
  305. <i class="fa fa-home"></i> Home
  306. </a></li>
  307. <li><a class="hot_link" data-page="pool_blocks.html" href="#pool_blocks">
  308. <i class="fa fa-cubes"></i> Pool Blocks
  309. </a></li>
  310. <li><a class="hot_link" data-page="payments.html" href="#payments">
  311. <i class="fa fa-paper-plane-o"></i> Payments
  312. </a></li>
  313. <li><a class="hot_link" data-page="worker_stats.html" href="#worker_stats">
  314. <i class="fa fa-tachometer"></i> Worker Stats
  315. </a></li>
  316. <li class="dropdown">
  317. <a class="dropdown-toggle" data-toggle="dropdown" href="#"><i class="fa fa-comments"></i> Support
  318. <span class="caret"></span>
  319. </a>
  320. <ul class="dropdown-menu">
  321. <li>
  322. <a class="hot_link" data-page="getting_started.html" href="#getting_started">
  323. <i class="fa fa-rocket"></i> Getting Started </a>
  324. </li>
  325. <li>
  326. <a class="hot_link" data-page="support.html" href="#support">
  327. <i class="fa fa-comments"></i> Contact </a>
  328. </li>
  329. </ul>
  330. </li>
  331. <li><a class="hot_link" data-page="settings.html" href="#settings">
  332. <i class="fa fa-cog"></i> Settings
  333. </a></li>
  334. </ul>
  335. <div id="stats_updated">Stats Updated &nbsp;<i class="fa fa-bolt"></i></div>
  336. </div>
  337. </div>
  338. </div>
  339. <div class="container">
  340. <div id="page"></div>
  341. <p id="loading" class="text-center"><i class="fa fa-circle-o-notch fa-spin"></i></p>
  342. </div>
  343. <footer>
  344. <div id="health_warning">
  345. This pool is not healthy! Contact the admin for support.
  346. </div>
  347. <div class="text-muted">
  348. Powered by <a target="_blank"
  349. href="https://github.com/SadBatman/cryptonote-sumokoin-pool/"><i class="fa fa-github"></i> cryptonote-sumokoin-pool</a>
  350. <span id="poolVersion"></span>
  351. open sourced under the <a href="http://www.gnu.org/licenses/gpl-2.0.html">GPL</a>
  352. </div>
  353. </footer>
  354. </body>
  355. </html>