diff --git a/.gitignore b/.gitignore
index 8ab76b4..30b6da8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,5 +3,4 @@ node_modules/
build/
.idea/
logs/
-website/
*.swp
diff --git a/lib/api.js b/lib/api.js
index 9c64546..de246aa 100644
--- a/lib/api.js
+++ b/lib/api.js
@@ -7,10 +7,12 @@
// Load required modules
let fs = require('fs');
+let path = require('path');
let http = require('http');
let https = require('https');
let url = require("url");
let async = require('async');
+let mime = require('mime');
let apiInterfaces = require('./apiInterfaces.js')(config.daemon, config.wallet);
let authSid = Math.round(Math.random() * 10000000000) + '' + Math.round(Math.random() * 10000000000);
@@ -174,12 +176,29 @@ function handleServerRequest(request, response) {
handleTestTelegramNotification(urlParts, response);
break;
- // Default response
+ // Default response — serve static website files
default:
- response.writeHead(404, {
- 'Access-Control-Allow-Origin': '*'
+ let websiteRoot = path.join(__dirname, '..', 'website');
+ let requestedPath = urlParts.pathname === '/' ? '/index.html' : urlParts.pathname;
+ let filePath = path.join(websiteRoot, requestedPath);
+ // Prevent directory traversal outside websiteRoot
+ if (!filePath.startsWith(websiteRoot)) {
+ response.writeHead(403, { 'Access-Control-Allow-Origin': '*' });
+ response.end('Forbidden');
+ break;
+ }
+ fs.readFile(filePath, function(err, data) {
+ if (err) {
+ response.writeHead(404, { 'Access-Control-Allow-Origin': '*' });
+ response.end('Not found');
+ return;
+ }
+ response.writeHead(200, {
+ 'Access-Control-Allow-Origin': '*',
+ 'Content-Type': mime.lookup(filePath) || 'application/octet-stream'
+ });
+ response.end(data);
});
- response.end('Invalid API call');
break;
}
}
diff --git a/website/admin.html b/website/admin.html
new file mode 100644
index 0000000..8e46fcf
--- /dev/null
+++ b/website/admin.html
@@ -0,0 +1,150 @@
+
+
+
+ ' +
+ '
' +
+ '
' +
+ '
' + base + ' to ' + target + '
' +
+ '
' + price + '
' +
+ '
Source: ' + source + '
' +
+ '
' +
+ '
'
+ );
+}
+
+/**
+ * Market Charts
+ **/
+
+// Create charts
+function market_CreateCharts (stats) {
+ if (!stats || !stats.charts) return;
+ let data = stats.charts;
+ let graphData = {
+ price: market_GetGraphData(data.price),
+ profit: market_GetGraphData(data.profit)
+ };
+
+ for (let graphType in graphData) {
+ if (graphData[graphType].values.length > 1) {
+ let $chart = $(`#chart${stats.config.coin}_${graphType}`);
+ let bgcolor = null,
+ bordercolor = null,
+ borderwidth = null;
+ let colorelem = $chart.siblings('a.chart-style');
+ if (colorelem.length == 1) {
+ bgcolor = colorelem.css('background-color');
+ bordercolor = colorelem.css('border-left-color');
+ borderwidth = parseFloat(colorelem.css('width'));
+ }
+ if (bgcolor === null) bgcolor = 'rgba(3, 169, 244, .4)';
+ if (bordercolor === null) bordercolor = '#03a9f4';
+ if (borderwidth === null || isNaN(borderwidth)) borderwidth = 1;
+ let chartObj = new Chart(document.getElementById(`chart${stats.config.coin}_${graphType}`), {
+ type: 'line',
+ data: {
+ labels: graphData[graphType].names,
+ datasets: [{
+ data: graphData[graphType].values,
+ dataType: graphType,
+ fill: true,
+ backgroundColor: bgcolor,
+ borderColor: bordercolor,
+ borderWidth: borderwidth
+ }]
+ },
+ options: {
+ animation: false,
+ responsive: true,
+ maintainAspectRatio: false,
+ legend: {
+ display: false
+ },
+ elements: {
+ point: {
+ radius: 0,
+ hitRadius: 10,
+ hoverRadius: 5
+ }
+ },
+ scales: {
+ xAxes: [{
+ display: false,
+ ticks: {
+ display: false
+ },
+ gridLines: {
+ display: false
+ }
+ }],
+ yAxes: [{
+ display: false,
+ ticks: {
+ display: false,
+ beginAtZero: true,
+ userCallback: function (label, index, labels) {
+ if (Math.floor(label) === label) return label;
+ }
+ },
+ gridLines: {
+ display: false
+ }
+ }]
+ },
+ layout: {
+ padding: {
+ top: 5,
+ left: 10,
+ right: 10,
+ bottom: 10
+ }
+ },
+ tooltips: {
+ callbacks: {
+ label: function (tooltipItem, data) {
+ let dataType = data.datasets[tooltipItem.datasetIndex].dataType || '';
+ let label = tooltipItem.yLabel;
+ if (dataType == 'price') label = parseFloat(tooltipItem.yLabel)
+ .toFixed(4);
+ else if (dataType == 'profit') label = parseFloat(tooltipItem.yLabel)
+ .toFixed(10);
+ return ' ' + label;
+ }
+ }
+ }
+ }
+ });
+ $chart.closest('.marketChart')
+ .show();
+ }
+ }
+}
+
+// Get chart data
+function market_GetGraphData (rawData) {
+ let graphData = {
+ names: [],
+ values: []
+ };
+ if (rawData) {
+ for (let i = 0, xy; xy = rawData[i]; i++) {
+ graphData.names.push(new Date(xy[0] * 1000)
+ .toLocaleString());
+ graphData.values.push(xy[1]);
+ }
+ }
+ return graphData;
+}
+
+
+
+// Calculate current estimation
+function market_CalcEstimateProfit (marketPrices) {
+ let rateUnit = Math.pow(1000, parseInt($('#calcHashUnit')
+ .data('mul')));
+ let hashRate = parseFloat($('#calcHashRate')
+ .val()) * rateUnit;
+ let coin = lastStats.config.coin
+ try {
+ if ($(`#calcHashAmount${coin}`)
+ .length == 0) {
+ let template = $(`#calcHashResultTemplate`)
+ .html()
+ Mustache.parse(template)
+ let rendered = Mustache.render(template, {
+ coin: coin
+ })
+ $(`#calcHashHolder`)
+ .append(rendered)
+ }
+ let profit = ( hashRate * 86400 / lastStats.network.adjustedDifficulty ) * ( lastStats.lastblock.reward - (lastStats.lastblock.reward * (lastStats.config.networkFee + lastStats.config.fee) / 100) )
+ if (profit) {
+ updateText(`calcHashAmount${coin}1`, getReadableCoin(lastStats, profit));
+ updateText(`calcHashAmount${coin}2`, market_GetCurrencyPriceText(lastStats, profit, marketPrices));
+ //return;
+ } else {
+ updateText(`calcHashAmount${coin}1`, '');
+ updateText(`calcHashAmount${coin}2`, '');
+ }
+ } catch (e) {
+ updateText(`calcHashAmount${coin}1`, '');
+ updateText(`calcHashAmount${coin}2`, '');
+ }
+
+
+
+ Object.keys(mergedStats)
+ .forEach(key => {
+ try {
+ if ($(`#calcHashAmount${key}`)
+ .length == 0) {
+ let template = $(`#calcHashResultTemplate`)
+ .html()
+ Mustache.parse(template)
+ let rendered = Mustache.render(template, {
+ coin: key
+ })
+ $(`#calcHashHolder`)
+ .append(rendered)
+ }
+
+ let profit = (hashRate * 86400 / mergedStats[key].network.difficulty) * (mergedStats[key].lastblock.reward - (mergedStats[key].lastblock.reward * mergedStats[key].config.networkFee / 100));
+ if (profit) {
+ updateText(`calcHashAmount${key}1`, getReadableCoin(mergedStats[key], profit));
+ updateText(`calcHashAmount${key}2`, market_GetCurrencyPriceText(mergedStats[key], profit, marketPrices));
+ return;
+ } else {
+ updateText(`calcHashAmount${key}1`, '');
+ updateText(`calcHashAmount${key}2`, '');
+ }
+ } catch (e) {
+ updateText(`calcHashAmount${key}1`, '');
+ updateText(`calcHashAmount${key}2`, '');
+ }
+ })
+}
+
+
+// Get price in specified currency
+function market_GetCurrencyPriceText (stats, coinsRaw, marketPrices) {
+ if (!priceCurrency || !marketPrices[stats.config.coin] || !marketPrices[stats.config.coin][priceCurrency]) return;
+ let priceInCurrency = (Math.trunc(getReadableCoin(stats, coinsRaw, 2, true) * marketPrices[stats.config.coin][priceCurrency] * 100) / 100);
+ return priceInCurrency + ' ' + priceCurrency;
+}
+
+function market_InitTemplate (ranOnce, chartsInitialized, loadedData, marketPrices, intervalChartsUpdate, currencyPairs, xhrMarketGets) {
+ priceSource = lastStats.config.priceSource || 'cryptonator';
+ priceCurrency = lastStats.config.priceCurrency || 'USD';
+
+ let coin = lastStats.config.coin
+ if ($(`#blocksTabs li:contains(${coin})`)
+ .length == 0) {
+ chartsInitialized[coin] = false
+ loadedData[coin] = false
+ marketPrices[coin] = {}
+ let template = $('#siblingTabTemplate')
+ .html();
+ Mustache.parse(template)
+ let rendered = Mustache.render(template, {
+ coin: lastStats.config.coin,
+ symbol: `(${lastStats.config.symbol})`,
+ active: 'active'
+ });
+ $('#blocksTabs')
+ .append(rendered)
+
+ let template1 = $('#siblingMarketTemplate')
+ .html()
+ Mustache.parse(template1)
+ let rendered1 = Mustache.render(template1, {
+ coin: coin,
+ active: 'active'
+ })
+ $(`#tab-content`)
+ .append(rendered1)
+
+
+ let template2 = $('#siblingCalculatorTemplate')
+ .html()
+ Mustache.parse(template2)
+ let rendered2 = Mustache.render(template2, {
+ coin: coin
+ })
+ $(`#calculator`)
+ .append(rendered2)
+
+ updateText(`priceChartCurrency${lastStats.config.coin}`, priceCurrency);
+ updateText(`profitChartProfit${lastStats.config.coin}`, priceCurrency);
+
+ if (lastStats.charts && !chartsInitialized[coin]) {
+ intervalChartsUpdate[coin] = setInterval(market_CreateCharts(lastStats), 60 * 1000);
+ market_CreateCharts(lastStats);
+ chartsInitialized[coin] = true;
+ }
+
+ }
+
+ market_LoadMarketData(api, lastStats, loadedData, currencyPairs, xhrMarketGets, marketPrices);
+
+
+ Object.keys(mergedStats)
+ .forEach(key => {
+ if ($(`#blocksTabs li:contains(${key})`)
+ .length === 0) {
+ chartsInitialized[key] = false;
+ loadedData[key] = false
+ marketPrices[key] = {}
+ let template1 = $('#siblingMarketTemplate')
+ .html()
+ Mustache.parse(template1)
+ let rendered1 = Mustache.render(template1, {
+ coin: key
+ })
+ $('#tab-content')
+ .append(rendered1)
+
+ let template = $('#siblingTabTemplate')
+ .html();
+ Mustache.parse(template)
+ let rendered = Mustache.render(template, {
+ coin: key,
+ symbol: `(${mergedStats[key].config.symbol})`
+ });
+ $('#blocksTabs')
+ .append(rendered)
+
+ }
+
+ updateText(`priceChartCurrency${mergedStats[key].config.coin}`, priceCurrency);
+ updateText(`profitChartProfit${mergedStats[key].config.coin}`, priceCurrency);
+
+ market_LoadMarketData(mergedApis[key].api, mergedStats[key], loadedData, currencyPairs, xhrMarketGets, marketPrices);
+
+ if (mergedStats[key].charts && !chartsInitialized[key]) {
+ intervalChartsUpdate[key] = setInterval(market_CreateCharts(mergedStats[key]), 60 * 1000);
+ market_CreateCharts(mergedStats[key]);
+ chartsInitialized[key] = true;
+ }
+
+ })
+
+ market_CalcEstimateProfit(marketPrices);
+
+ sortElementList($(`#blocksTabs`), $(`#blocksTabs>li`), mergedStats)
+
+ if (!ranOnce)
+ ranOnce = RunOnce()
+}
+
+/*
+***************************************************************
+workerstats methods
+***************************************************************
+*/
+
+function workerstats_Setup (stats, api, addressTimeout, xhrAddressPoll, xhrGetPayments, xhrGetBlockRewards) {
+
+ // Enable time ago on last submitted share
+ $(`#yourLastShare${stats.config.coin}`)
+ .timeago();
+
+ $(`#lookUp${stats.config.coin}`)
+ .click(function () {
+ var address = $(`#yourStatsInput${stats.config.coin}`)
+ .val()
+ .trim();
+
+ if (getCurrentAddress(stats.config.coin) != address) {
+ docCookies.setItem(`mining_address_${stats.config.coin}`, address, Infinity);
+
+ var urlWalletAddress = location.search.split('walletMerged=')[1] || 0;
+ if (urlWalletAddress) {
+ window.location.href = "/#worker_stats";
+ return;
+ } else {
+ docCookies.setItem(`mining_address_${stats.config.coin}`, address, Infinity);
+ loadLiveStats(true, mergedStats);
+ }
+ }
+
+ $(`#addressError${stats.config.coin}, .yourStats${stats.config.coin}, .yourWorkers${stats.config.coin}, .userChart${stats.config.coin}`)
+ .hide();
+ $(`#workersReport_rows_${stats.config.coin}`)
+ .empty();
+ $(`#paymentsReport_rows_${stats.config.coin}`)
+ .empty();
+ $(`#recentBlock_rows_${stats.config.coin}`)
+ .empty();
+
+ $(`#lookUp${stats.config.coin} > span:first-child`)
+ .hide();
+ $(`#lookUp${stats.config.coin} > span:last-child`)
+ .show();
+
+
+ if (addressTimeout[stats.config.coin]) clearTimeout(addressTimeout[stats.config.coin]);
+
+
+ if (xhrAddressPoll[stats.config.coin])
+ xhrAddressPoll[stats.config.coin].abort();
+
+ $(`#lookUp${stats.config.coin} > span:last-child`)
+ .hide();
+ $(`#lookUp${stats.config.coin} > span:first-child`)
+ .show();
+
+ if (!address) {
+ $(`#yourStatsInput${stats.config.coin}`)
+ .focus();
+ return;
+ }
+
+ workerstats_FetchAddressStats(false, stats, api, xhrAddressPoll);
+
+ });
+
+ var address = getCurrentAddress(stats.config.coin);
+ if (address) {
+ $(`#yourStatsInput${stats.config.coin}`)
+ .val(address);
+ $(`#lookUp${stats.config.coin}`)
+ .click();
+ } else {
+ $(`#lookUp${stats.config.coin} > span:last-child`)
+ .hide();
+ $(`#lookUp${stats.config.coin} > span:first-child`)
+ .show();
+ $(`#addressError${stats.config.coin}, .yourStats${stats.config.coin}, .yourWorkers${stats.config.coin}, .userChart${stats.config.coin}`)
+ .hide();
+ }
+
+ $(`#yourStatsInput${stats.config.coin}`)
+ .keyup(function (e) {
+ if (e.keyCode === 13)
+ $(`#lookUp${stats.config.coin}`)
+ .click();
+ });
+
+
+ // Handle sort on workers table
+ //$(`#workersReport${stats.config.coin} th.sort`).on('click', sortTable);
+ $(`.workerStats th.sort`)
+ .on('click', sortTable);
+
+ // Load more payments button
+ $(`#loadMorePayments${stats.config.coin}`)
+ .click(function (xhrGetPayments) {
+ if (xhrGetPayments[stats.config.coin])
+ xhrGetPayments[stats.config.coin].abort();
+
+ xhrGetPayments[stats.config.coin] = $.ajax({
+ url: `${api}/get_payments`,
+ data: {
+ time: $(`#paymentsReport_rows_${stats.config.coin}`)
+ .children()
+ .last()
+ .data('time'),
+ address: address
+ },
+ dataType: 'json',
+ cache: 'false',
+ success: function (data) {
+ workerstats_RenderPayments(data, stats);
+ }
+ });
+ });
+ // Load more block rewards button
+ $(`#loadMoreBlockRewards${stats.config.coin}`)
+ .click(function (xhrGetBlockRewards) {
+ if (xhrGetBlockRewards[stats.config.coin])
+ xhrGetBlockRewards[stats.config.coin].abort();
+
+ xhrGetBlockRewards[stats.config.coin] = $.ajax({
+ url: `${api}/get_blockRewards`,
+ data: {
+ height: $(`#recentBlock_rows_${stats.config.coin}`)
+ .children()
+ .last()
+ .data('height'),
+ address: address
+ },
+ dataType: 'json',
+ cache: 'false',
+ success: function (data) {
+ workerstats_RenderBlockRewards(data, stats);
+ }
+ });
+ });
+}
+
+/**
+ * Miner statistics
+ **/
+
+// Load current miner statistics
+
+function workerstats_FetchAddressStats (longpoll, stats, api, xhrAddressPoll) {
+ let address = getCurrentAddress(stats.config.coin)
+ if (address) {
+ xhrAddressPoll[stats.config.coin] = $.ajax({
+ url: `${api}/stats_address`,
+ data: {
+ address: address,
+ longpoll: longpoll
+ },
+ dataType: 'json',
+ cache: 'false',
+ success: function (data) {
+ if (!data.stats) {
+ $(`.yourStats${stats.config.coin}, .yourWorkers${stats.config.coin}, .userChart${stats.config.coin}`)
+ .hide();
+ $(`#addressError${stats.config.coin}`)
+ .text(data.error)
+ .show();
+ docCookies.setItem(`mining_address_${stats.config.coin}`, '', Infinity);
+ loadLiveStats(true);
+ return;
+ }
+ $(`#addressError${stats.config.coin}`)
+ .hide();
+
+
+ if (data.stats.lastShare) {
+ $(`#yourLastShare${stats.config.coin}`)
+ .timeago('update', new Date(parseInt(data.stats.lastShare) * 1000)
+ .toISOString());
+ } // AQUÃ
+ else {
+ updateText(`yourLastShare${stats.config.coin}`, 'Never');
+ }
+
+
+ updateText(`yourHashrateHolder${stats.config.coin}`, (getReadableHashRateString(data.stats.hashrate) || '0 H') + '/sec');
+ if ('hashrate_1h' in data.stats) {
+ $(`#minerAvgHR${stats.config.coin}`)
+ .show();
+ updateText(`yourHR1h${stats.config.coin}`, (getReadableHashRateString(data.stats.hashrate_1h) || '0 H') + '/s');
+ updateText(`yourHR6h${stats.config.coin}`, (getReadableHashRateString(data.stats.hashrate_6h) || '0 H') + '/s');
+ updateText(`yourHR24h${stats.config.coin}`, (getReadableHashRateString(data.stats.hashrate_24h) || '0 H') + '/s');
+ } else {
+ $(`#minerAvgHR${stats.config.coin}`)
+ .hide();
+ }
+
+ updateText(`yourPaid${stats.config.coin}`, getReadableCoin(stats, data.stats.paid));
+ updateText(`paid24h${stats.config.coin}`, getReadableCoin(stats, data.stats.paid24h));
+ updateText(`paid7d${stats.config.coin}`, getReadableCoin(stats, data.stats.paid7d));
+
+
+
+
+ updateText(`yourHashes${stats.config.coin}`, (data.stats.hashes || 0)
+ .toString());
+ updateText(`yourPendingBalance${stats.config.coin}`, getReadableCoin(stats, data.stats.balance));
+
+ let allWorkers = 0, onlineWorkers = 0, offlineWorkers = 0
+ if(data && data.workers) {
+ for (var worker = 0; worker < data.workers.length; worker++) {
+ if (Date.now() / 1000 - parseInt(data.workers[worker].lastShare) > 2 * 86400)
+ continue
+ allWorkers++
+ if(data.workers[worker].hashrate === 0) {
+ offlineWorkers++
+ }
+ else {
+ onlineWorkers++
+ }
+ }
+ }
+
+ updateText(`allWorkers_${stats.config.coin}`, allWorkers)
+ updateText(`onlineWorkers_${stats.config.coin}`, onlineWorkers)
+ updateText(`offlineWorkers_${stats.config.coin}`, offlineWorkers)
+
+ let userRoundHashes = parseFloat(data.stats.roundHashes || 0);
+ let poolRoundHashes = parseFloat(stats.pool.roundHashes || 0);
+ let userRoundScore = parseFloat(data.stats.roundScore || 0);
+ let poolRoundScore = parseFloat(stats.pool.roundScore || 0);
+ let lastReward = stats.lastblock.reward - (stats.lastblock.reward * (stats.config.networkFee ? stats.config.networkFee / 100 : 0));
+
+ let poolFee = stats.config.fee;
+ if (Object.keys((stats.config.donation))
+ .length) {
+ let totalDonation = 0;
+ let ldon = stats.config.donation;
+ for (let i in ldon) {
+ totalDonation += ldon[i];
+ }
+ poolFee += totalDonation;
+ }
+ let transferFee = stats.config.transferFee;
+
+ let share_pct = userRoundHashes * 100 / poolRoundHashes;
+ let score_pct = userRoundScore * 100 / poolRoundScore;
+ updateText(`yourRoundShareProportion${stats.config.coin}`, isNaN(share_pct) ? 0.0 : Math.round(share_pct * 1000) / 1000);
+ updateText(`yourRoundScoreProportion${stats.config.coin}`, isNaN(score_pct) ? 0.0 : Math.round(score_pct * 1000) / 1000);
+ if (!lastStats.config.slushMiningEnabled) {
+ $(`#slush_round_info${stats.config.coin}`)
+ .hide();
+ }
+
+ let payoutEstimatePct = parseFloat(userRoundHashes * 100 / poolRoundHashes)
+ let payoutEstimate = Math.round(lastReward * (payoutEstimatePct / 100));
+ if (transferFee) payoutEstimate = payoutEstimate - transferFee;
+ if (payoutEstimate < 0)
+ payoutEstimate = 0;
+ updateText(`yourPayoutEstimate${stats.config.coin}`, getReadableCoin(stats, payoutEstimate));
+
+
+ workerstats_RenderPayments(data.payments, stats);
+ if (data.block_rewards)
+ workerstats_RenderBlockRewards(data.block_rewards, stats)
+
+ if (data.workers && data.workers.length > 0) {
+ workerstats_RenderWorkers(data.workers, stats);
+ $(`.yourWorkers${stats.config.coin}`)
+ .show();
+ }
+
+ $(`.yourStats${stats.config.coin}`)
+ .show();
+ workerstats_CreateCharts(data, stats);
+
+ },
+ error: function (e) {
+ if (e.statusText === 'abort') return;
+ $(`#addressError${stats.config.coin}`)
+ .text('Connection error')
+ .show();
+
+ if (addressTimeout[stats.config.coin])
+ clearTimeout(addressTimeout[stats.config.coin]);
+
+ addressTimeout[stats.config.coin] = setTimeout(function () {
+ workerstats_FetchAddressStats(false, stats, mergedApis[stats.config.coin].api);
+ }, 2000);
+ }
+ });
+ }
+}
+
+/**
+ * Charts
+ **/
+
+ let workerstats_graphSettings = {
+ type: 'line',
+ width: '100%',
+ height: '140',
+ lineColor: '#03a9f4',
+ fillColor: 'rgba(3, 169, 244, .4)',
+ spotColor: null,
+ minSpotColor: null,
+ maxSpotColor: null,
+ highlightLineColor: '#236d26',
+ spotRadius: 3,
+ chartRangeMin: 0,
+ drawNormalOnTop: false,
+ tooltipFormat: '
{{y}} – {{offset:names}}
',
+ tooltipFormatter: (sp, options, fields) => {
+ let format = $.spformat(options.mergedOptions.tooltipFormat)
+ if (options.get('tooltipValueLookups').type == 'hashrate')
+ fields.y = getReadableHashRateString(fields.y)
+ return format.render(fields, options.get('tooltipValueLookups'), options)
+ }
+};
+
+// Create charts
+function workerstats_CreateCharts (data, stats) {
+ if (data.hasOwnProperty("charts")) {
+ var graphData = {
+ hashrate: {
+ data: [workerstats_GetGraphData(stats, data.charts.hashrate), workerstats_GetGraphData(stats, data.charts.hashrateSolo)],
+ options: {
+ lineColor: 'orange'
+ }
+ }
+ }
+
+ for (var graphType in graphData) {
+ if (graphData[graphType].data[0].values.length > 1) {
+ var settings = jQuery.extend({}, workerstats_graphSettings);
+ settings.tooltipValueLookups = {
+ names: graphData[graphType].data[0].names,
+ type: graphType
+ };
+ var $chart = $(`[data-chart=user_${graphType}_${stats.config.coin}]`)
+ .show()
+ .find('.chart');
+ $chart.sparkline(graphData[graphType].data[0].values, settings);
+ if (graphData[graphType].data[1]) {
+ settings.composite = true
+ settings.lineColor = graphData[graphType].options.lineColor
+ $chart.sparkline(graphData[graphType].data[1].values, settings);
+ }
+ }
+ }
+ workerstats_createMinerCharts(data, stats)
+ }
+}
+
+function workerstats_GetEarningsData(rawData) {
+ var graphData = {
+ names: [],
+ values: []
+ };
+ if (rawData) {
+ for (var i = 0; i < rawData.length - 1; i+=2) {
+ graphData.names.push(new Date(rawData[i+1] * 1000).toDateString());
+ graphData.values.push(rawData[i]);
+ }
+ }
+ return graphData
+}
+
+let charts = {}
+
+function workerstats_createMinerCharts(data, stats) {
+ let graphData = {
+ payments: workerstats_GetEarningsData(data.stats.earnings)
+ };
+ for (var graphType in graphData) {
+ if (charts[graphType]) {
+ charts[graphType].destroy();
+ }
+ if (graphData[graphType].values) {
+ let $chart = $(`[data-chart=user_${graphType}_${stats.config.coin}]`);
+ let bgcolor = null, bordercolor = null, borderwidth = null;
+ let colorelem = $chart.siblings('a.chart-style');
+ if (colorelem.length == 1) {
+ bgcolor = colorelem.css('background-color');
+ bordercolor = colorelem.css('border-left-color');
+ borderwidth = parseFloat(colorelem.css('width'));
+ }
+ if (bgcolor === null) bgcolor = 'rgba(3, 169, 244, .4)';
+ if (bordercolor === null) bordercolor = '#03a9f4';
+ if (borderwidth === null || isNaN(borderwidth)) borderwidth = 1;
+ charts[graphType] = new Chart(document.getElementById(`chart_${graphType}_${stats.config.coin}`), {
+ type: 'bar',
+ data: {
+ labels: graphData[graphType].names,
+ datasets: [{
+ data: graphData[graphType].values,
+ dataType: graphType,
+ fill: true,
+ backgroundColor: bgcolor,
+ borderColor: bordercolor,
+ borderWidth: borderwidth
+ }]
+ },
+ options: {
+ animation: false,
+ title: {
+ display: true,
+ text: 'Miner Payments'
+ },
+ responsive: true,
+ maintainAspectRatio: false,
+ legend: {display: false},
+ elements: {point: {radius: 0, hitRadius: 10, hoverRadius: 5}},
+ scales: {
+ xAxes: [{
+ "fontSize": 12,
+ "fontFamily": "Source Sans Pro",
+ display: false,
+ ticks: {display: false},
+ gridLines: {display: false}
+ }],
+ yAxes: [{
+ display: true,
+ ticks: {
+ "fontSize": 12,
+ "fontFamily": "Source Sans Pro",
+ display: true,
+ beginAtZero: true,
+ callback: (graphType == 'payments' ? function (label, index, labels) {
+ return getReadableCoin(stats, label);
+ } : function (label, index, labels) {
+ return label;
+ })
+ },
+ gridLines: {display: false}
+ }]
+ },
+ layout: {
+ padding: {top: 15, left: 0, right: 15, bottom: 15}
+ },
+ tooltips: {
+ callbacks: {
+ label: function (tooltipItem, data) {
+ return ` ${getReadableCoin(stats, tooltipItem.yLabel)}`
+ }
+ }
+ }
+ }
+ });
+ $chart.closest(`.userPaymentChart${stats.config.coin}`).show();
+ }
+ }
+}
+
+function workerstats_GetGraphData (stats, rawData, fixValueToCoins, collate) {
+ var graphData = {
+ names: [],
+ values: []
+ };
+ collate = collate ? collate : false
+ if (rawData) {
+ let currentDate = null
+ let accumulator = -1
+ for (var i = 0, xy; xy = rawData[i]; i++) {
+ if (collate) {
+ if (currentDate === new Date(xy[0] * 1000).setHours(0, 0, 0, 0)) {
+ graphData.values[accumulator] += parseFloat(xy[1])
+ } else {
+ accumulator++
+ currentDate = new Date(xy[0] * 1000).setHours(0, 0, 0, 0)
+ graphData.names.push(new Date(currentDate).toDateString());
+ graphData.values[accumulator] = parseFloat(xy[1]);
+ }
+ }
+ else {
+ graphData.names.push(new Date(xy[0] * 1000).toLocaleString());
+ graphData.values.push(fixValueToCoins ? getReadableCoin(stats, xy[1], null, true) : xy[1]);
+ }
+ }
+ }
+ return graphData;
+}
+
+
+/**
+ * Workers report
+ **/
+
+// Get worker row id
+function workerstats_GetWorkerRowId (workerName) {
+ var id = btoa(workerName);
+ id = id.replace(/=/, '');
+ return id;
+}
+
+// Get worker row element
+function workerstats_GetWorkerRowElement (worker, jsonString, stats) {
+ var row = document.createElement('tr');
+ row.setAttribute('data-json', jsonString);
+ row.setAttribute('data-name', worker.name);
+ row.setAttribute('id', 'workerRow' + stats.config.coin + '_' + workerstats_GetWorkerRowId(worker.name));
+
+ row.innerHTML = workerstats_GetWorkerCells(worker);
+
+ return row;
+}
+
+// Get worker cells
+function workerstats_GetWorkerCells (worker) {
+ let hashrate = worker.hashrate ? worker.hashrate : 0;
+ let hashrate1h = worker.hashrate_1h || 0;
+ let hashrate6h = worker.hashrate_6h || 0;
+ let hashrate24h = worker.hashrate_24h || 0;
+ let lastShare = worker.lastShare ? worker.lastShare : 0;
+ let hashes = (worker.hashes || 0)
+ .toString();
+ let status = (hashrate <= 0) ? 'error' : 'ok';
+
+ return '
' +
+ '
' + (worker.name != 'undefined' ? worker.name : 'Undefined ') + ' ' +
+ '
' + getReadableHashRateString(hashrate) + '/s ' +
+ '
' + getReadableHashRateString(hashrate1h) + '/s ' +
+ '
' + getReadableHashRateString(hashrate6h) + '/s ' +
+ '
' + getReadableHashRateString(hashrate24h) + '/s ' +
+ '
' + (lastShare ? $.timeago(new Date(parseInt(lastShare) * 1000)
+ .toISOString()) : 'Never') + ' ' +
+ '
' + hashes + ' ';
+}
+
+// Sort workers
+function workerstats_SortWorkers (a, b) {
+ var aName = a.name.toLowerCase();
+ var bName = b.name.toLowerCase();
+ return ((aName < bName) ? -1 : ((aName > bName) ? 1 : 0));
+}
+
+// Render workers list
+function workerstats_RenderWorkers (workersData, stats) {
+ workersData = workersData.sort(workerstats_SortWorkers);
+
+ var $workersRows = $(`#workersReport_rows_${stats.config.coin}`);
+
+ for (var i = 0; i < workersData.length; i++) {
+ var existingRow = document.getElementById(`workerRow${stats.config.coin}_${workerstats_GetWorkerRowId(workersData[i].name)}`);
+ if (!existingRow) {
+ $workersRows.empty();
+ break;
+ }
+ }
+
+ let have_avg_hr = false;
+
+ for (var i = 0; i < workersData.length; i++) {
+ var worker = workersData[i];
+ if (Date.now() / 1000 - parseInt(worker.lastShare) > 2 * 86400) continue;
+ if (!have_avg_hr && 'hashrate_1h' in worker) have_avg_hr = true;
+ var workerJson = JSON.stringify(worker);
+ var existingRow = document.getElementById(`workerRow${stats.config.coin}_${workerstats_GetWorkerRowId(worker.name)}`);
+ if (existingRow && existingRow.getAttribute('data-json') !== workerJson) {
+ $(existingRow)
+ .replaceWith(workerstats_GetWorkerRowElement(worker, workerJson, stats));
+ } else if (!existingRow) {
+ var workerElement = workerstats_GetWorkerRowElement(worker, workerJson, stats);
+ $workersRows.append(workerElement);
+ }
+ }
+ if (!have_avg_hr) $(`#workersReport${stats.config.coin} .avghr`)
+ .hide();
+ else $(`#workersReport${stats.config.coin} .avghr`)
+ .show();
+}
+
+/**
+ * Payments report
+ **/
+
+// Parse payment data
+function workerstats_ParsePayment (time, serializedPayment) {
+ var parts = serializedPayment.split(':');
+ return {
+ time: parseInt(time),
+ hash: parts[0],
+ amount: parts[1],
+ fee: parts[2],
+ mixin: parts[3],
+ recipients: parts[4]
+ };
+}
+
+// Parse block_reward data
+function workerstats_ParseBlockReward (height, serializedPayment) {
+ var parts = serializedPayment.split(':');
+ return {
+ height: height,
+ rewardType: parts[0],
+ hash: parts[1],
+ time: parseInt(parts[2]),
+ difficulty: parts[3],
+ shares: parts[4],
+ blockReward: parts[5],
+ reward: parts[6],
+ percent: parts[7],
+ finderFee: parts[8]
+ };
+}
+
+// Get payment row element
+function workerstats_GetPaymentRowElement (payment, jsonString, stats) {
+ var row = document.createElement('tr');
+ row.setAttribute('data-json', jsonString);
+ row.setAttribute('data-time', payment.time);
+ row.setAttribute('id', 'paymentRow' + stats.config.coin + payment.time);
+
+ row.innerHTML = workerstats_GetPaymentCells(payment, stats);
+
+ return row;
+}
+
+// Get blockreward row element
+function workerstats_GetBlockRewardRowElement (block_reward, jsonString, stats) {
+ var row = document.createElement('tr');
+ row.setAttribute('data-json', jsonString);
+ row.setAttribute('data-height', block_reward.height);
+ row.setAttribute('id', 'blockRewardRow' + stats.config.coin + block_reward.time);
+ row.innerHTML = workerstats_GetBlockRewardCells(block_reward, stats);
+ return row;
+}
+
+// Get payment cells
+function workerstats_GetPaymentCells (payment, stats) {
+ return `
${formatDate(payment.time)} ` +
+ `
${formatPaymentLink(payment.hash, stats)} ` +
+ `
${getReadableCoin(stats, payment.amount)} ` +
+ `
${getReadableCoin(stats, payment.fee)} ` +
+ `
${payment.mixin} `;
+}
+
+// Get block_reward cells
+function workerstats_GetBlockRewardCells (block_reward, stats) {
+ function formatBlockRewardLink (block_reward, stats) {
+ return '
' + block_reward.height + ' ';
+ }
+ return `
${formatBlockRewardLink(block_reward, stats)} ` +
+ `
${formatDate(block_reward.time)} ` +
+ `
${block_reward.difficulty} ` +
+ `
${formatLuck(block_reward.difficulty, block_reward.shares, false)} ` +
+ `
${getReadableCoin(stats, block_reward.blockReward)} ` +
+ `
${getReadableCoin(stats, block_reward.reward)} ( = ${(block_reward.percent * 100).toFixed(2)}% after pool fees) ` +
+ `
${block_reward.rewardType}`;
+}
+
+// Get summary row element
+function workerstats_GetSummaryRowElement (summary, jsonString, stats) {
+ var row = document.createElement('tr');
+ row.setAttribute('data-json', jsonString);
+ row.setAttribute('data-date', summary.date);
+ row.setAttribute('id', 'summaryRow' + stats.config.coin + summary.date);
+ row.setAttribute('class', 'summary');
+
+ row.innerHTML = workerstats_GetSummaryCells(summary, stats);
+
+ return row;
+}
+
+// Get summary cells
+function workerstats_GetSummaryCells (summary, stats) {
+ var text = getTranslation('paymentSummaryMulti') ? getTranslation('paymentSummaryMulti') : 'On %DATE% you have received %AMOUNT% in %COUNT% payments';
+ if (summary.count <= 1) text = getTranslation('paymentSummarySingle') ? getTranslation('paymentSummarySingle') : 'On %DATE% you have received %AMOUNT%';
+ text = text.replace(/%DATE%/g, summary.date);
+ text = text.replace(/%COUNT%/g, summary.count);
+ text = text.replace(/%AMOUNT%/g, getReadableCoin(stats, summary.amount));
+ return '
' + text + ' ';
+}
+
+// Render payments
+function workerstats_RenderPayments (paymentsResults, stats) {
+ var $paymentsRows = $(`#paymentsReport_rows_${stats.config.coin}`);
+ var lastPaymentDate = null;
+ var summaryData = {
+ date: null,
+ time: null,
+ count: 0,
+ amount: 0
+ };
+ for (var i = 0; i < paymentsResults.length; i += 2) {
+ var payment = workerstats_ParsePayment(paymentsResults[i + 1], paymentsResults[i]);
+ var paymentJson = JSON.stringify(payment);
+ var paymentElement = workerstats_GetPaymentRowElement(payment, paymentJson, stats);
+
+ var paymentDate = new Date(parseInt(payment.time) * 1000)
+ .toLocaleDateString();
+ if (!lastPaymentDate || lastPaymentDate && paymentDate != lastPaymentDate) {
+ summaryData = {
+ date: paymentDate,
+ time: payment.time,
+ count: 0,
+ amount: 0
+ };
+ }
+
+ var existingRow = document.getElementById(`paymentRow${stats.config.coin}${payment.time}`);
+ if (existingRow && existingRow.getAttribute('data-json') !== paymentJson) {
+ $(existingRow)
+ .replaceWith(workerstats_GetPaymentRowElement(payment, paymentJson, stats));
+ } else if (!existingRow) {
+ var inserted = false;
+ var rows = $paymentsRows.children()
+ .get();
+ for (var f = 0; f < rows.length; f++) {
+ var pTime = parseInt(rows[f].getAttribute('data-time'));
+ if (pTime && pTime < payment.time) {
+ inserted = true;
+ $(rows[f])
+ .before(paymentElement);
+ break;
+ }
+ }
+ if (!inserted) {
+ $paymentsRows.append(paymentElement);
+ }
+ }
+
+ summaryData.count++;
+ summaryData.amount += parseFloat(payment.amount) + parseFloat(payment.fee);
+
+ var summaryJson = JSON.stringify(summaryData);
+ var summaryElement = workerstats_GetSummaryRowElement(summaryData, summaryJson, stats);
+
+ var existingSummary = document.getElementById(`summaryRow${stats.config.coin}${summaryData.date}`);
+ if (existingSummary && existingSummary.getAttribute('data-json') !== summaryJson) {
+ $(existingSummary)
+ .replaceWith(summaryElement);
+ } else if (!existingSummary) {
+ var inserted = false;
+ var rows = $paymentsRows.children()
+ .get();
+ for (var f = 0; f < rows.length; f++) {
+ var pTime = parseInt(rows[f].getAttribute('data-time'));
+ if (pTime && pTime === summaryData.time) {
+ inserted = true;
+ $(rows[f])
+ .before(summaryElement);
+ break;
+ }
+ }
+ if (!inserted) {
+ $paymentsRows.append(summaryElement);
+ }
+ }
+ lastPaymentDate = paymentDate;
+ }
+}
+
+// Render block_rewards
+
+function workerstats_RenderBlockRewards(blockRewardsResults, stats) {
+ var $blockRewardsRows = $(`#recentBlock_rows_${stats.config.coin}`);
+ for (var i = 0; i < blockRewardsResults.length; i += 2) {
+ var block_reward = workerstats_ParseBlockReward(blockRewardsResults[i + 1], blockRewardsResults[i]);
+ var block_rewardJson = JSON.stringify(block_reward);
+ var paymentElement = workerstats_GetBlockRewardRowElement(block_reward, block_rewardJson, stats);
+
+
+ var existingRow = document.getElementById(`blockRewardRow${stats.config.coin}${block_reward.time}`);
+ if (existingRow && existingRow.getAttribute('data-json') !== block_rewardJson) {
+ $(existingRow)
+ .replaceWith(workerstats_GetBlockRewardRowElement(block_reward, block_rewardJson, stats));
+ } else if (!existingRow) {
+ var inserted = false;
+ var rows = $blockRewardsRows.children()
+ .get();
+ for (var f = 0; f < rows.length; f++) {
+ var pTime = parseInt(rows[f].getAttribute('data-time'));
+ if (pTime && pTime < block_reward.time) {
+ inserted = true;
+ $(rows[f])
+ .before(paymentElement);
+ break;
+ }
+ }
+ if (!inserted) {
+ $blockRewardsRows.append(paymentElement);
+ }
+ }
+ }
+}
+
+function workerstats_InitTemplate (ranOnce, addressTimeout, xhrAddressPoll, xhrGetPayments, xhrGetBlockRewards) {
+ let coin = lastStats.config.coin
+ if ($(`#blocksTabs li:contains(${coin})`)
+ .length === 0) {
+ let template = $('#siblingTabTemplate')
+ .html();
+ Mustache.parse(template)
+ let rendered = Mustache.render(template, {
+ coin: lastStats.config.coin,
+ symbol: `(${lastStats.config.symbol})`,
+ active: 'active'
+ });
+ $('#blocksTabs')
+ .append(rendered)
+
+ template = $('#siblingTemplate')
+ .html()
+ Mustache.parse(template)
+ rendered = Mustache.render(template, {
+ coin: coin,
+ active: 'active'
+ })
+ $('#tab-content')
+ .append(rendered)
+ workerstats_Setup(lastStats, api, addressTimeout, xhrAddressPoll, xhrGetPayments, xhrGetBlockRewards)
+ }
+
+ Object.keys(mergedStats)
+ .forEach(key => {
+ if ($(`#blocksTabs li:contains(${key})`)
+ .length === 0) {
+ coin = key
+ let template = $('#siblingTabTemplate')
+ .html();
+ Mustache.parse(template)
+ let rendered = Mustache.render(template, {
+ coin: mergedStats[key].config.coin,
+ symbol: `(${mergedStats[key].config.symbol})`
+ });
+ $('#blocksTabs')
+ .append(rendered)
+
+ template = $('#siblingTemplate')
+ .html()
+ Mustache.parse(template)
+ rendered = Mustache.render(template, {
+ coin: coin
+ })
+ $('#tab-content')
+ .append(rendered)
+ workerstats_Setup(mergedStats[key], mergedApis[key].api, addressTimeout, xhrAddressPoll, xhrGetPayments, xhrGetBlockRewards)
+ }
+ })
+
+ sortElementList($(`#blocksTabs`), $(`#blocksTabs>li`), mergedStats)
+
+ if (!ranOnce)
+ ranOnce = RunOnce()
+}
+
+
+/*
+***************************************************************
+workerstats methods
+***************************************************************
+*/
+
+let home_GraphSettings = {
+ type: 'line',
+ width: '100%',
+ height: '140',
+ lineColor: '#03a9f4',
+ fillColor: 'rgba(3, 169, 244, .4)',
+ spotColor: null,
+ minSpotColor: null,
+ maxSpotColor: null,
+ highlightLineColor: '#236d26',
+ spotRadius: 3,
+ chartRangeMin: 0,
+ drawNormalOnTop: false,
+ tooltipFormat: '
{{y}} – {{offset:names}}
',
+ tooltipFormatter: (sp, options, fields) => {
+ let format = $.spformat(options.mergedOptions.tooltipFormat)
+ if (options.get('tooltipValueLookups').type == 'hashrate')
+ fields.y = getReadableHashRateString(fields.y)
+ return format.render(fields, options.get('tooltipValueLookups'), options)
+ }
+};
+
+function home_CreateCharts (data) {
+ if (data.hasOwnProperty("charts")) {
+ var graphData = {
+ hashrate: {
+ data: [home_GetGraphData(data.charts.hashrate), home_GetGraphData(data.charts.hashrateSolo)],
+ options: {
+ lineColor: 'orange'
+ }
+ },
+ diff: {
+ data: [home_GetGraphData(data.charts.difficulty)]
+ },
+ miners: {
+ data: [home_GetGraphData(data.charts.miners), home_GetGraphData(data.charts.minersSolo)],
+ options: {
+ lineColor: 'orange'
+ }
+ },
+ workers: {
+ data: [home_GetGraphData(data.charts.workers), home_GetGraphData(data.charts.workersSolo)],
+ options: {
+ lineColor: 'orange'
+ }
+ },
+ };
+
+ for(var graphType in graphData) {
+ if(graphData[graphType].data[0].values.length > 1) {
+ var settings = jQuery.extend({}, home_GraphSettings);
+ settings.tooltipValueLookups = {names: graphData[graphType].data[0].names, type: graphType};
+ var $chart = $('[data-chart=' + graphType + '] .chart');
+ $chart.closest('.poolChart').show();
+ $chart.sparkline(graphData[graphType].data[0].values, settings);
+ if (graphData[graphType].data[1]) {
+ settings.composite = true
+ settings.lineColor = graphData[graphType].options.lineColor
+ $chart.sparkline(graphData[graphType].data[1].values, settings);
+ }
+ }
+ }
+
+ }
+}
+
+// Get chart data
+function home_GetGraphData (rawData, fixValueToCoins) {
+ var graphData = {
+ names: [],
+ values: []
+ };
+ if (rawData) {
+ for (var i = 0, xy; xy = rawData[i]; i++) {
+ graphData.names.push(new Date(xy[0] * 1000)
+ .toLocaleString());
+ graphData.values.push(fixValueToCoins ? getReadableCoin(lastStats, xy[1], null, true) : xy[1]);
+ }
+ }
+ return graphData;
+}
+
+function home_GenerateNetworkStats (key, symbol) {
+ if ($(`#networkStats${key}`)
+ .length == 0) {
+ let template = $('#siblingTemplate')
+ .html()
+ if (template) {
+ Mustache.parse(template)
+ let rendered = Mustache.render(template, {
+ coin: key,
+ symbol: symbol
+ })
+ $(`#networkStats`)
+ .append(rendered)
+ }
+ }
+}
+
+function sortElementList (container, siblings, stats) {
+ let sorted = (a, b) => {
+ return ((a.id.toLowerCase() < b.id.toLowerCase()) ? -1 : ((a.id.toLowerCase() > b.id.toLowerCase()) ? 1 : 0))
+ }
+ if (stats && siblings.length - 1 === Object.keys(stats)
+ .length) {
+ siblings.sort(sorted)
+ .appendTo(container)
+ }
+}
+
+
+function home_InitTemplate (parentStats, siblingStats) {
+ $('#networkLastBlockFound')
+ .timeago('update', new Date(parentStats.lastblock.timestamp * 1000)
+ .toISOString());
+
+ let coin = parentStats.config.coin
+ let minerInfo = []
+ let efforts = []
+ let effortsSolo = []
+
+ if ($(`#networkStats${coin}`)
+ .length == 0) {
+ minerInfo.push({
+ blocks: parentStats.pool.totalBlocks.toString(),
+ blocksSolo: parentStats.pool.totalBlocksSolo.toString(),
+ coin: coin,
+ symbol: parentStats.config.symbol,
+ miners: parentStats.pool.miners.toString(),
+ minersSolo: parentStats.pool.minersSolo.toString()
+ })
+
+ efforts.push({
+ coin: coin,
+ effort: `${(parentStats.pool.roundHashes / parentStats.network.difficulty * 100).toFixed(1)}%`,
+ symbol: parentStats.config.symbol
+ })
+
+ effortsSolo.push({
+ coin: coin,
+ effort: `${(parentStats.pool.roundHashesSolo / parentStats.network.difficulty * 100).toFixed(1)}%`,
+ symbol: parentStats.config.symbol
+ })
+
+ let template = $('#siblingTemplate')
+ .html()
+ Mustache.parse(template)
+ let rendered = Mustache.render(template, {
+ coin: coin,
+ symbol: parentStats.config.symbol
+ })
+ $(`#networkStats`)
+ .append(rendered)
+ }
+
+ let lastBlockFound = null
+ if (parentStats.pool.lastBlockFound) {
+ lastBlockFound = parseInt(parentStats.pool.lastBlockFound);
+ }
+
+ let lastBlockFoundSolo = null
+ if (parentStats.pool.lastBlockFoundSolo) {
+ lastBlockFoundSolo = parseInt(parentStats.pool.lastBlockFoundSolo);
+ }
+
+
+ updateText(`networkHashrate${coin}`, `${getReadableHashRateString(parentStats.network.networkhashps)}/sec`)
+ updateText(`networkDifficulty${coin}`, formatNumber(parentStats.network.difficulty.toString(), ' '));
+ updateText(`blockchainHeight${coin}`, formatNumber(parentStats.network.height.toString(), ' '));
+ let rewardMinusNetworkFee = parentStats.lastblock.reward - (parentStats.lastblock.reward * (parentStats.config.networkFee ? parentStats.config.networkFee / 100 : 0))
+ updateText(`networkLastReward${coin}`, getReadableCoin(parentStats, rewardMinusNetworkFee));
+
+
+
+ Object.keys(siblingStats)
+ .forEach(key => {
+ home_GenerateNetworkStats(key, siblingStats[key].config.symbol)
+
+ minerInfo.push({
+ blocks: siblingStats[key].pool.totalBlocks.toString(),
+ blocksSolo: siblingStats[key].pool.totalBlocksSolo.toString(),
+ coin: key,
+ symbol: siblingStats[key].config.symbol,
+ miners: siblingStats[key].pool.miners.toString(),
+ minersSolo: siblingStats[key].pool.minersSolo.toString()
+ })
+
+ efforts.push({
+ coin: key,
+ effort: `${(siblingStats[key].pool.roundHashes / siblingStats[key].network.difficulty * 100).toFixed(1)}%`,
+ symbol: siblingStats[key].config.symbol
+ });
+
+ effortsSolo.push({
+ coin: key,
+ effort: `${(siblingStats[key].pool.roundHashesSolo / siblingStats[key].network.difficulty * 100).toFixed(1)}%`,
+ symbol: siblingStats[key].config.symbol
+ });
+
+ if (siblingStats[key].pool.lastBlockFound) {
+ let lastChildBlockFound = parseInt(siblingStats[key].pool.lastBlockFound)
+ if (lastChildBlockFound > lastBlockFound)
+ lastBlockFound = lastChildBlockFound
+ }
+
+ updateText(`networkHashrate${key}`, getReadableHashRateString(siblingStats[key].network.difficulty / siblingStats[key].config.coinDifficultyTarget) + '/sec');
+ updateText(`networkDifficulty${key}`, formatNumber(siblingStats[key].network.difficulty.toString(), ' '));
+ updateText(`blockchainHeight${key}`, formatNumber(siblingStats[key].network.height.toString(), ' '));
+ // updateText(`networkLastReward${key}`, getReadableCoin(siblingStats[key], siblingStats[key].lastblock.reward));
+ updateText(`poolMiners${key}`, `${siblingStats[key].pool.miners}/${siblingStats[key].pool.minersSolo}`);
+ updateText(`blocksTotal${key}`, `${siblingStats[key].pool.totalBlocks}/${siblingStats[key].pool.totalBlocksSolo}`);
+ updateText(`currentEffort${key}`, `PROP: ${(siblingStats[key].pool.roundHashes / siblingStats[key].network.difficulty * 100).toFixed(1)}%`)
+ updateText(`currentEffortSolo${key}`, `SOLO: ${(siblingStats[key].pool.roundHashesSolo / siblingStats[key].network.difficulty * 100).toFixed(1)}%`)
+ })
+
+ sortElementList($(`#networkStats`), $(`#networkStats>div`), siblingStats)
+
+ if ($(`#poolDetails > div`)
+ .length == 0) {
+ let template = $('#poolDetailTemplate')
+ .html()
+ Mustache.parse(template)
+ let rendered = Mustache.render(template, {
+ coin: parentStats.config.coin,
+ symbol: parentStats.config.symbol,
+ blocks: minerInfo
+ })
+ $(`#poolDetails`)
+ .append(rendered)
+ }
+
+ if ($(`#mainPoolStats > div`)
+ .length == 0) {
+ let template = $('#mainPoolTemplate')
+ .html()
+ Mustache.parse(template)
+ let rendered = Mustache.render(template, {
+ coin: parentStats.config.coin,
+ blocks: minerInfo,
+ efforts: efforts,
+ effortsSolo: effortsSolo
+ })
+ $(`#mainPoolStats`)
+ .append(rendered)
+ }
+
+ if (lastBlockFound) {
+ $('#poolLastBlockFound')
+ .timeago('update', new Date(lastBlockFound)
+ .toISOString());
+ } else {
+ $('#poolLastBlockFound')
+ .removeAttr('title')
+ .data('ts', '')
+ .update('Never');
+ }
+
+ if (lastBlockFoundSolo) {
+ $('#poolLastBlockFoundSolo')
+ .timeago('update', new Date(lastBlockFoundSolo)
+ .toISOString());
+ } else {
+ $('#poolLastBlockFoundSolo')
+ .removeAttr('title')
+ .data('ts', '')
+ .update('Never');
+ }
+
+ let lastHash = updateText('lastHash', parentStats.lastblock.hash)
+ if (lastHash)
+ lastHash.setAttribute('href', getBlockchainUrl(parentStats.lastblock.hash, parentStats));
+
+
+ updateText('poolHashrate', `PROP: ${getReadableHashRateString(parentStats.pool.hashrate)}/sec`);
+ updateText('poolHashrateSolo', `SOLO: ${getReadableHashRateString(parentStats.pool.hashrateSolo)}/sec`);
+
+
+ var hashPowerSolo = parentStats.pool.hashrateSolo / parentStats.network.networkhashps * 100;
+ updateText('hashPowerSolo', hashPowerSolo.toFixed(2) + '%');
+
+ var hashPower = parentStats.pool.hashrate / parentStats.network.networkhashps * 100;
+ updateText('hashPower', hashPower.toFixed(2) + '%');
+
+
+ updateText(`poolMiners${coin}`, `${parentStats.pool.miners}/${parentStats.pool.minersSolo}`);
+ updateText('blocksTotal', `${parentStats.pool.totalBlocks}/${parentStats.pool.totalBlocksSolo}`);
+
+
+ var totalFee = parentStats.config.fee;
+ var soloFee = parentStats.config.soloFee;
+ if (Object.keys(parentStats.config.donation)
+ .length) {
+ var totalDonation = 0;
+ for (var i in parentStats.config.donation) {
+ totalDonation += parentStats.config.donation[i];
+ }
+ totalFee += totalDonation;
+ soloFee += totalDonation;
+ }
+
+ updateText('finderReward', parentStats.config.finderReward + '%');
+
+ updateText('poolFee', (totalFee > 0 && totalFee != 100 ? totalFee.toFixed(2): (totalFee == 100 ? '100' : '0')) + '%/' + soloFee.toFixed(2) + '%');
+
+ updateText('paymentsInterval', getReadableTime(parentStats.config.paymentsInterval));
+ updateText('paymentsMinimum', getReadableCoin(parentStats, parentStats.config.minPaymentThreshold, 2, true));
+
+ updateText('blockSolvedTime', `PROP: ${getReadableTime(parentStats.pool.blockSolvedTime)}`);
+ updateText('blockSolvedTimeSolo', `SOLO: ${getReadableTime(parentStats.pool.blockSolvedTimeSolo)}`);
+
+ updateText(`currentEffort${coin}`, (parentStats.pool.roundHashes / parentStats.network.difficulty * 100).toFixed(1) + '%');
+}
+
diff --git a/website/js/custom.js b/website/js/custom.js
new file mode 100644
index 0000000..4bdcd2b
--- /dev/null
+++ b/website/js/custom.js
@@ -0,0 +1 @@
+/* Insert your pool's unique Javascript here */
\ No newline at end of file
diff --git a/website/lang/ca.json b/website/lang/ca.json
new file mode 100644
index 0000000..aa7f855
--- /dev/null
+++ b/website/lang/ca.json
@@ -0,0 +1,166 @@
+{
+ "miningPool": "Mining Pool",
+ "dashboard": "Tauler",
+ "gettingStarted": "Començar",
+ "yourStats": "Estadístiques personals",
+ "poolBlocks": "Blocs de la Pool",
+ "settings": "Ajustaments",
+ "faq": "FAQ",
+ "telegram": "Grup de Telegram",
+ "discord": "Discord",
+ "contactUs": "Contactar",
+ "network": "Xarxa",
+ "pool": "Pool",
+ "you": "La teva taxa",
+ "statsUpdated": "Estadístiques actualitzades",
+
+ "poolHashrate": "Taxa de la Pool (hash)",
+ "currentEffort": "Esforç actual",
+ "networkHashrate": "Taxa de la Xarxa (hash)",
+ "networkDifficulty": "Dificultat",
+ "blockchainHeight": "Altura cadena de blocs",
+ "networkLastReward": "Última recompensa",
+ "poolMiners": "Miners connectats",
+ "poolFee": "Tarifa de la Pool",
+
+ "minerStats": "Les teves estadístiques i historial de pagaments",
+ "workerStats": "Estadístiques personals",
+ "miner": "Miner",
+ "miners": "Miners",
+ "minersCount": "miners",
+ "workers": "Treballadors",
+ "workersCount": "treballadors",
+ "workerName": "Nom Treballador",
+ "lastHash": "Últim hash",
+ "hashRate": "Taxa (hash)",
+ "currentHashRate": "Taxa actual (hash)",
+ "lastShare": "Última acció enviada",
+ "totalHashes": "Total d'accions enviades",
+ "top10miners": "Top 10 Miners",
+
+ "blocksTotal": "Blocs trobats",
+ "blockSolvedTime": "Bloc trobat cada",
+ "blocksMaturityCount": "Maduresa requerida",
+ "efficiency": "Eficiència",
+ "averageLuck": "Promitg de sort",
+ "timeFound": "Data i hora",
+ "reward": "Recompensa",
+ "height": "Altura",
+ "difficulty": "Dificultat",
+ "blockHash": "Bloc Hash",
+ "effort": "Esforç",
+ "blocksFoundLast24": "Blocks found in the last 24 hours",
+ "blocksFoundLastDays": "Blocks found in the last {DAYS} days",
+
+ "payments": "Pagaments",
+ "paymentsHistory": "Historial de pagaments",
+ "paymentsTotal": "Total de pagaments",
+ "paymentsMinimum": "Pagament mínim",
+ "paymentsInterval": "Interval de pagaments",
+ "paymentsDenomination": "Unitat de denominació",
+ "timeSent": "Data",
+ "transactionHash": "Hash transacció",
+ "amount": "Import",
+ "fee": "Tarifa",
+ "mixin": "Mixin",
+ "payees": "Beneficiàris",
+ "pendingBalance": "Balanç pendent",
+ "totalPaid": "Total pagat",
+ "payoutEstimate": "Pagament estimat",
+ "paymentSummarySingle": "El %DATE% has rebut %AMOUNT%",
+ "paymentSummaryMulti": "El %DATE% has rebut %AMOUNT% en %COUNT% pagaments",
+
+ "connectionDetails": "Detalls de connexió",
+ "cnAlgorithm": "Algoritme",
+ "miningPoolHost": "Adreça de la Pool",
+ "username": "Usuari",
+ "usernameDesc": "La teva adreça del wallet",
+ "paymentId": "ID de pagament (Exchanges)",
+ "fixedDiff": "Dificultat fixa",
+ "address": "adreça",
+ "addrPaymentId": "IDPagament",
+ "addrDiff": "diff",
+ "password": "Contrassenya",
+ "passwordDesc": "Nom del seu treballador",
+ "emailNotifications": "Notificacions per E-Mail",
+ "miningPorts": "Ports de mineria",
+ "port": "Port",
+ "portDiff": "Dificultat inicial",
+ "description": "Descripció",
+ "miningApps": "Aplicacions de mineria",
+ "configGeneratorDesc": "Genera la teva configuració personalitzada per minar a la nostra Pool",
+ "addressField": "Adreça Wallet",
+ "paymentIdField": "ID de Pagament per a Exchanges (opcional)",
+ "fixedDiffField": "Dificultat fixa (opcional)",
+ "workerNameField": "Nom_Treballador",
+ "emailNotificationsField": "Notificacions per E-Mail (opcional))",
+ "generateConfig": "Generar configuració",
+ "appName": "Aplicació",
+ "appArch": "Arquitectura",
+ "appDesc": "Característiques",
+ "download": "Descarregar",
+ "showConfig": "Veure més",
+
+ "market": "Mercat / Calculadora",
+ "loadingMarket": "Carregant preus del mercat",
+ "priceIn": "Preu en",
+ "hashPer": "Hash/",
+ "estimateProfit": "Beneficis estimats",
+ "enterYourHashrate": "Entra la teva taxa (hash)",
+ "perDay": "per dia",
+
+ "verificationFields": "Camps de verificació",
+ "minerVerification": "Per tenir una mica més de seguretat que l'adreça de la cartera és vostra, us demanem que proporcioneu una de les adreces IP que utilitza el vostre miner.",
+ "minerAddress": "Adreça del moneder",
+ "minerIP": "Adreça IP del Miner",
+ "setMinimumPayout": "Estableix el nivell mínim de pagament",
+ "minerMinPayout": "Si preferiu un nivell de pagament més alt que el predeterminat del grup, aquí podeu canviar-lo per als vostres miners. L'import que indiqueu aquí es convertirà en l'import mínim dels pagaments de la vostra adreça.",
+ "minimumPayout": "Pagament mínim",
+ "enableEmailNotifications": "Activar notificacions per de correu electrònic",
+ "minerEmailNotify": "Aquesta Pool enviarà una notificació per correu electrònic quan es trobi un bloc i quan es produeixi un pagament.",
+ "emailAddress": "Adreça de correu electrònic",
+ "noMinerAddress": "No s'ha especificat cap adreça del moneder",
+ "noMinerIP": "No s'especificat cap adreça IP",
+ "noPayoutLevel": "No s'ha especificat cap nivell de pagament",
+ "noEmail": "No s'ha especificat cap adreça de correu electrònic",
+ "invalidEmail": "S'ha especificat una adreça de correu electrònic no vàlida",
+ "minerPayoutSet": "Fet! S'ha establert el nivell mínim de pagament",
+ "notificationEnabled": "Fet! S'han activat les notificacions per correu electrònic",
+ "notificationDisabled": "Fet! S'han desactivat les notificacions per correu electrònic",
+
+ "enterYourAddress": "Introduïu la vostra adreça",
+ "enterYourMinerIP": "Una adreça IP que utilitzin els miners (qualsevol)",
+ "enterYourEmail": "Introduïu la vostra adreça de correu electrònic (opcional)",
+ "lookup": "Cercar",
+ "searching": "Cercant...",
+ "loadMore": "Carregar més",
+ "set": "Establir",
+ "enable": "Activar",
+ "disable": "Desactivar",
+ "status": "Estat",
+ "updated": "Actualitzat:",
+ "source": "Origen:",
+ "error": "Error:",
+
+ "na": "N/A",
+ "estimated": "estimat",
+ "never": "Mai",
+ "second": "segon",
+ "seconds": "segons",
+ "minute": "minut",
+ "minutes": "minuts",
+ "hour": "hora",
+ "hours": "hores",
+ "day": "dia",
+ "days": "dies",
+ "week": "setmana",
+ "weeks": "setmanes",
+ "month": "mes",
+ "months": "mesos",
+ "year": "any",
+ "years": "anys",
+
+ "poweredBy": "Powered by",
+ "openSource": "open sourced under the"
+
+}
diff --git a/website/lang/en.json b/website/lang/en.json
new file mode 100644
index 0000000..ff5f742
--- /dev/null
+++ b/website/lang/en.json
@@ -0,0 +1,168 @@
+{
+ "miningPool": "Mining Pool",
+ "dashboard": "Dashboard",
+ "gettingStarted": "Getting Started",
+ "yourStats": "Worker Statistics",
+ "poolBlocks": "Pool Blocks",
+ "settings": "Settings",
+ "faq": "FAQ",
+ "telegram": "Telegram group",
+ "discord": "Discord",
+ "contactUs": "Contact Us",
+
+ "network": "Network",
+ "pool": "Pool",
+ "you": "You",
+ "statsUpdated": "Stats Updated",
+
+ "poolHashrate": "Pool Hash Rate",
+ "currentEffort": "Current Effort",
+ "networkHashrate": "Network Hash Rate",
+ "networkDifficulty": "Difficulty",
+ "blockchainHeight": "Blockchain Height",
+ "networkLastReward": "Last Reward",
+ "poolMiners": "Connected Miners",
+ "poolFee": "Pool Fee",
+
+ "minerStats": "Your Stats & Payment History",
+ "workerStats": "Workers Statistics",
+ "miner": "Miner",
+ "miners": "Miners",
+ "minersCount": "miners",
+ "workers": "Workers",
+ "workersCount": "workers",
+ "workerName": "Worker Name",
+ "lastHash": "Last Hash",
+ "hashRate": "Hash Rate",
+ "currentHashRate": "Current Hash Rate",
+ "lastShare": "Last Share Submitted",
+ "totalHashes": "Total Hashes Submitted",
+ "top10miners": "Top 10 miners",
+
+ "blocksTotal": "Blocks Found",
+ "blockSolvedTime": "Blocks Found Every",
+ "blocksMaturityCount": "Maturity Requirement",
+ "efficiency": "Efficiency",
+ "averageLuck": "Average Luck",
+ "timeFound": "Time Found",
+ "reward": "Reward",
+ "height": "Height",
+ "difficulty": "Difficulty",
+ "blockHash": "Block Hash",
+ "effort": "Effort",
+ "blocksFoundLast24": "Blocks found in the last 24 hours",
+ "blocksFoundLastDays": "Blocks found in the last {DAYS} days",
+
+ "payments": "Payments",
+ "paymentsHistory": "Payments History",
+ "paymentsTotal": "Total Payments",
+ "paymentsMinimum": "Minimum Payout",
+ "paymentsInterval": "Payment Interval",
+ "paymentsDenomination": "Denomination Unit",
+ "timeSent": "Time Sent",
+ "transactionHash": "Transaction Hash",
+ "amount": "Amount",
+ "fee": "Fee",
+ "mixin": "Mixin",
+ "payees": "Payees",
+ "pendingBalance": "Pending Balance",
+ "totalPaid": "Total Paid",
+ "payoutEstimate": "Current Payout Estimate",
+ "paymentSummarySingle": "On %DATE% you have received %AMOUNT%",
+ "paymentSummaryMulti": "On %DATE% you have received %AMOUNT% in %COUNT% payments",
+
+ "connectionDetails": "Connection Details",
+ "miningPoolHost": "Mining Pool Address",
+ "cnAlgorithm": "Algorithm",
+ "username": "Username",
+ "usernameDesc": "This is your wallet address",
+ "paymentId": "Exchange Payment ID",
+ "fixedDiff": "Difficulty locking",
+ "address": "address",
+ "addrPaymentId": "paymentID",
+ "addrDiff": "diff",
+ "password": "Password",
+ "passwordDesc": "This is your worker name",
+ "emailNotifications": "Email Notifications",
+ "miningPorts": "Mining Ports",
+ "port": "Port",
+ "portDiff": "Starting Difficulty",
+ "description": "Description",
+ "miningApps": "Mining Applications",
+ "configGeneratorDesc": "Generate your custom configuration to mine on our pool",
+ "addressField": "Wallet Address",
+ "paymentIdField": "Payment ID for exchanges (optional)",
+ "fixedDiffField": "Fixed difficulty (optional)",
+ "workerNameField": "Worker_Name",
+ "emailNotificationsField": "Email Notifications (optional)",
+ "generateConfig": "Generate configuration",
+ "appName": "App Name",
+ "appArch": "Architecture",
+ "appDesc": "Features",
+ "download": "Download",
+ "showConfig": "See more",
+
+ "market": "Market / Calculator",
+ "loadingMarket": "Loading market prices",
+ "priceIn": "Price in",
+ "hashPer": "Hash/",
+ "estimateProfit": "Estimate Mining Profits",
+ "enterYourHashrate": "Enter Your Hash Rate",
+ "perDay": "per day",
+
+ "verificationFields": "Verification fields",
+ "minerVerification": "In order to get a little more confidence that the wallet address is yours we ask you to give one of the IP addresses that is used by your miner.",
+ "minerAddress": "Miner Address",
+ "minerIP": "Miner IP address",
+ "setMinimumPayout": "Set your minimal payout level",
+ "minerMinPayout": "If you prefer a higher payout level than the pool's default then this is where you can change it for your miners. The amount you indicate here will become the minimum amount for pool payments to your address.",
+ "minimumPayout": "Minimum payout",
+ "enableEmailNotifications": "Enable email notifications",
+ "minerEmailNotify": "This pool will send out email notification when a block is found and whenever a payout happens.",
+ "emailAddress": "Email address",
+ "noMinerAddress": "No miner address specified",
+ "noMinerIP": "No miner IP address specified",
+ "noPayoutLevel": "No payout level specified",
+ "noEmail": "No email address specified",
+ "invalidEmail": "Invalid email address specified",
+ "minerPayoutSet": "Done! Your minimum payout level was set",
+ "notificationEnabled": "Done! Email notifications have been enabled",
+ "notificationDisabled": "Done! Email notifications have been disabled",
+
+ "enterYourAddress": "Enter Your Address",
+ "enterYourMinerIP": "An IP address your miners use (any)",
+ "enterYourEmail": "Enter Your E-Mail Address (optional)",
+
+ "lookup": "Lookup",
+ "searching": "Searching...",
+ "loadMore": "Load more",
+ "set": "Set",
+ "enable": "Enable",
+ "disable": "Disable",
+
+ "status": "Status",
+ "updated": "Updated:",
+ "source": "Source:",
+ "error": "Error:",
+
+ "na": "N/A",
+ "estimated": "estimated",
+ "never": "Never",
+ "second": "second",
+ "seconds": "seconds",
+ "minute": "minute",
+ "minutes": "minutes",
+ "hour": "hour",
+ "hours": "hours",
+ "day": "day",
+ "days": "days",
+ "week": "week",
+ "weeks": "weeks",
+ "month": "month",
+ "months": "months",
+ "year": "year",
+ "years": "years",
+
+ "poweredBy": "Powered by",
+ "openSource": "open sourced under the"
+}
diff --git a/website/lang/es.json b/website/lang/es.json
new file mode 100644
index 0000000..b667f6f
--- /dev/null
+++ b/website/lang/es.json
@@ -0,0 +1,168 @@
+{
+ "miningPool": "Mining Pool",
+ "dashboard": "Panel",
+ "gettingStarted": "Empezar",
+ "yourStats": "Estadísticas personales",
+ "poolBlocks": "Bloques de la Pool",
+ "settings": "Ajustes",
+ "faq": "FAQ",
+ "telegram": "Grupo de Telegram",
+ "discord": "Discord",
+ "contactUs": "Contacto",
+
+ "network": "Red",
+ "pool": "Pool",
+ "you": "Tú Tasa",
+ "statsUpdated": "Estadísticas actualizadas",
+
+ "poolHashrate": "Tasa Pool (hash)",
+ "currentEffort": "Ronda actual",
+ "networkHashrate": "Tasa Red (hash)",
+ "networkDifficulty": "Dificultad",
+ "blockchainHeight": "Altura",
+ "networkLastReward": "Última recompensa",
+ "poolMiners": "Mineros conectados",
+ "poolFee": "Tarifa Pool",
+
+ "minerStats": "Tus estadísticas e historial de pagos",
+ "workerStats": "Estadísticas personales",
+ "miner": "Minero",
+ "miners": "Mineros",
+ "minersCount": "mineros",
+ "workers": "Trabajadores",
+ "workersCount": "trabajadores",
+ "workerName": "Nombre Trabajador",
+ "lastHash": "Último hash",
+ "hashRate": "Tasa (hash)",
+ "currentHashRate": "Tasa actual (hash)",
+ "lastShare": "Última acción enviada",
+ "totalHashes": "Total de acciones enviadas",
+ "top10miners": "Top 10 Mineros",
+
+ "blocksTotal": "Bloques encontrados",
+ "blockSolvedTime": "Bloque encontrado cada",
+ "blocksMaturityCount": "Madurez requerida",
+ "efficiency": "Eficiencia",
+ "averageLuck": "Promedio de suerte",
+ "timeFound": "Fecha y hora",
+ "reward": "Recompensa",
+ "height": "Altura",
+ "difficulty": "Dificultad",
+ "blockHash": "Bloque Hash",
+ "effort": "Esfuerzo",
+ "blocksFoundLast24": "Bloques encontrados en las últimas 24 horas",
+ "blocksFoundLastDays": "Bloques encontrados en los últimos {DAYS} días",
+
+ "payments": "Pagos",
+ "paymentsHistory": "Historial de pagos",
+ "paymentsTotal": "Total de pagos",
+ "paymentsMinimum": "Pago mínimo",
+ "paymentsInterval": "Intervalo de pagos",
+ "paymentsDenomination": "Unidad de denominación",
+ "timeSent": "Fecha y hora",
+ "transactionHash": "Hash transacción",
+ "amount": "Importe",
+ "fee": "Tarifa",
+ "mixin": "Mixin",
+ "payees": "Beneficiarios",
+ "pendingBalance": "Balance pendiente",
+ "totalPaid": "Total pagado",
+ "payoutEstimate": "Pago estimado",
+ "paymentSummarySingle": "El %DATE% has recibido %AMOUNT%",
+ "paymentSummaryMulti": "El %DATE% has recibido %AMOUNT% en %COUNT% pagos",
+
+ "connectionDetails": "Detalles de conexión",
+ "miningPoolHost": "Dirección de la Pool",
+ "cnAlgorithm": "Algoritmo",
+ "username": "Usuario",
+ "usernameDesc": "Tu dirección del wallet",
+ "paymentId": "ID de pago (Exchanges)",
+ "fixedDiff": "Dificultad fija",
+ "address": "dirección",
+ "addrPaymentId": "IDPago",
+ "addrDiff": "diff",
+ "password": "Contraseña",
+ "passwordDesc": "Nombre de su trabajador",
+ "emailNotifications": "Notificaciones por E-Mail",
+ "miningPorts": "Puertos de minería",
+ "port": "Puerto",
+ "portDiff": "Dificultad inicial",
+ "description": "Descripción",
+ "miningApps": "Aplicaciones de minería",
+ "configGeneratorDesc": "Genera tu configuración personalizada para minar a nuestra Pool",
+ "addressField": "Dirección Wallet",
+ "paymentIdField": "ID de Pago para Exchanges (opcional)",
+ "fixedDiffField": "Dificultad fija (opcional)",
+ "workerNameField": "Nombre_Trabajador",
+ "emailNotificationsField": "Notificaciones por E-Mail (opcional)",
+ "generateConfig": "Generar configuración",
+ "appName": "Aplicación",
+ "appArch": "Arquitectura",
+ "appDesc": "Características",
+ "download": "Descargar",
+ "showConfig": "Ver más",
+
+ "market": "Mercado / Calculadora",
+ "loadingMarket": "Cargando precios del mercado",
+ "priceIn": "Precio en",
+ "hashPer": "Hash/",
+ "estimateProfit": "Beneficios estimados",
+ "enterYourHashrate": "Entra tu tasa (hash)",
+ "perDay": "por día",
+
+ "verificationFields": "Campos de verificación",
+ "minerVerification": "Para tener un poco más de seguridad que la dirección de la cartera es vuestra, le pedimos que proporcione una de las direcciones IP que utiliza su minero.",
+ "minerAddress": "Dirección del monedero",
+ "minerIP": "Dirección IP del Minero",
+ "setMinimumPayout": "Establece el nivel mínimo de pago",
+ "minerMinPayout": "Si prefiere un nivel de pago más alto que el predeterminado del grupo, aquí puede cambiarlo para sus mineros. El importe que indique aquí se convertirá en el importe mínimo de los pagos de su dirección.",
+ "minimumPayout": "Pago mínimo",
+ "enableEmailNotifications": "Activar notificaciones por correo electrónico",
+ "minerEmailNotify": "Esta Pool enviará una notificación por correo electrónico cuando se encuentre un bloque y cuando se produzca un pago.",
+ "emailAddress": "Dirección de correo electrónico",
+ "noMinerAddress": "No se ha especificado ninguna dirección del monedero",
+ "noMinerIP": "No se especificado ninguna dirección IP",
+ "noPayoutLevel": "No se ha especificado ningún nivel de pago",
+ "noEmail": "No se ha especificado ninguna dirección de correo electrónico",
+ "invalidEmail": "Se ha especificado una dirección de correo electrónico no válida",
+ "minerPayoutSet": "Hecho! Se ha establecido el nivel mínimo de pago",
+ "notificationEnabled": "Hecho! Se han activado las notificaciones por correo electrónico",
+ "notificationDisabled": "Hecho! Se han desactivado las notificaciones por correo electrónico",
+
+ "enterYourAddress": "Introduzca su dirección",
+ "enterYourMinerIP": "Una dirección IP que utilicen los mineros (cualquiera)",
+ "enterYourEmail": "Introduzca su dirección de correo electrónico (opcional)",
+
+ "lookup": "Buscar",
+ "searching": "Buscando...",
+ "loadMore": "Cargar más",
+ "set": "Establecer",
+ "enable": "Activar",
+ "disable": "Desactivar",
+
+ "status": "Estado",
+ "updated": "Actualizado:",
+ "source": "Origen:",
+ "error": "Error:",
+
+ "na": "N/A",
+ "estimated": "estimado",
+ "never": "Nunca",
+ "second": "segundo",
+ "seconds": "segundos",
+ "minute": "minuto",
+ "minutes": "minutos",
+ "hour": "hora",
+ "hours": "horas",
+ "day": "día",
+ "days": "dias",
+ "week": "semana",
+ "weeks": "semanas",
+ "month": "mes",
+ "months": "meses",
+ "year": "año",
+ "years": "años",
+
+ "poweredBy": "Powered by",
+ "openSource": "open sourced bajo "
+}
diff --git a/website/lang/fr.json b/website/lang/fr.json
new file mode 100644
index 0000000..84ce291
--- /dev/null
+++ b/website/lang/fr.json
@@ -0,0 +1,168 @@
+{
+ "miningPool": "Mining Pool",
+ "dashboard": "Tableau de bord",
+ "gettingStarted": "Comment démarrer",
+ "yourStats": "Vos statistiques",
+ "poolBlocks": "Blocs trouvés",
+ "settings": "Paramètres",
+ "faq": "FAQ",
+ "telegram": "Telegram",
+ "discord": "Discord",
+ "contactUs": "Nous contacter",
+
+ "network": "Réseau",
+ "pool": "Pool",
+ "you": "Vous",
+ "statsUpdated": "Statistiques mises à jour",
+
+ "poolHashrate": "Taux de Hash du Pool",
+ "currentEffort": "Effort actuel",
+ "networkHashrate": "Taux de Hash du réseau",
+ "networkDifficulty": "Difficulté",
+ "blockchainHeight": "Hauteur de la BlockChain",
+ "networkLastReward": "Dernière récompense",
+ "poolMiners": "Mineurs connectés",
+ "poolFee": "Frais du pool",
+
+ "minerStats": "Vos statistiques et Historique des paiements",
+ "workerStats": "Statistiques des travailleurs",
+ "miner": "Mineur",
+ "miners": "Mineurs",
+ "minersCount": "mineurs",
+ "workers": "Travailleurs",
+ "workersCount": "travailleurs",
+ "workerName": "Nom du travailleur",
+ "lastHash": "Dernier Hash",
+ "hashRate": "Taux de Hash",
+ "currentHashRate": "Taux de Hash actuel",
+ "lastShare": "Dernière transmission",
+ "totalHashes": "Hashes transmis",
+ "top10miners": "Top 10 mineurs",
+
+ "blocksTotal": "Blocs trouvés",
+ "blockSolvedTime": "Bloc trouvé chaque",
+ "blocksMaturityCount": "Maturité requise",
+ "efficiency": "Efficacité",
+ "averageLuck": "Chance moyenne",
+ "timeFound": "Trouvé le",
+ "reward": "Récompense",
+ "height": "Hauteur",
+ "difficulty": "Difficulté",
+ "blockHash": "Hash du bloc",
+ "effort": "Effort",
+ "blocksFoundLast24": "Blocs trouvés dans les 24 dernières heures",
+ "blocksFoundLastDays": "Blocs trouvés dans les derniers {DAYS} jours",
+
+ "payments": "Paiements",
+ "paymentsHistory": "Historique des paiements",
+ "paymentsTotal": "Nombre de paiements",
+ "paymentsMinimum": "Minimum avant paiement",
+ "paymentsInterval": "Intervale de paiement",
+ "paymentsDenomination": "Unité de dénomination",
+ "timeSent": "Envoyé le",
+ "transactionHash": "Hash de transaction",
+ "amount": "Montant",
+ "fee": "Frais",
+ "mixin": "Mixin",
+ "payees": "Payés",
+ "pendingBalance": "Balance en attente",
+ "totalPaid": "Total payé",
+ "payoutEstimate": "Estimation de paiement",
+ "paymentSummarySingle": "Le %DATE% vous avez reçu %AMOUNT%",
+ "paymentSummaryMulti": "Le %DATE% vous avez reçu %AMOUNT% en %COUNT% paiements",
+
+ "connectionDetails": "Détails de connexion",
+ "miningPoolHost": "Adresse du pool",
+ "cnAlgorithm": "Algorithme",
+ "username": "Nom d'utilisateur",
+ "usernameDesc": "C'est l'adresse de votre wallet",
+ "paymentId": "ID de paiement de l'exchange",
+ "fixedDiff": "Difficulté fixe",
+ "address": "adresse",
+ "addrPaymentId": "idPaiement",
+ "addrDiff": "diff",
+ "password": "Mot de passe",
+ "passwordDesc": "C'est l'identifiant de votre travailleur",
+ "emailNotifications": "Notifications par email",
+ "miningPorts": "Ports de minage",
+ "port": "Port",
+ "portDiff": "Difficulté de départ",
+ "description": "Description",
+ "miningApps": "Applications de minage",
+ "configGeneratorDesc": "Générer votre configuration personalisée pour miner sur notre pool",
+ "addressField": "Adresse de votre wallet",
+ "paymentIdField": "ID de paiement pour l'exchange (optionnel)",
+ "fixedDiffField": "Difficulté fixe (optionnel)",
+ "workerNameField": "Nom_du_Travailleur",
+ "emailNotificationsField": "Notifications par Email (optionnel)",
+ "generateConfig": "Générer la configuration",
+ "appName": "Nom de l'App",
+ "appArch": "Architecture",
+ "appDesc": "Fonctionalités",
+ "download": "Télécharger",
+ "showConfig": "Afficher",
+
+ "market": "Marché et calculateur",
+ "loadingMarket": "Chargement des prix du marché",
+ "priceIn": "Prix en",
+ "hashPer": "Hash/",
+ "estimateProfit": "Estimation des profits de minage",
+ "enterYourHashrate": "Entrez votre taux de Hash",
+ "perDay": "par jour",
+
+ "verificationFields": "Champs de vérification",
+ "minerVerification": "Afin de nous assurer que l'adresse du mineur est bien la vôtre, nous vous demandons d'entrer une adresse IP utilisée par votre mineur.",
+ "minerAddress": "Adresse du mineur",
+ "minerIP": "Adresse IP du mineur",
+ "setMinimumPayout": "Configurer votre niveau de paiement minimum",
+ "minerMinPayout": "Si vous préférez un montant de paiement minimum plus élevé que celui du pool c'est ici que vous pouvez le changer pour vos mineurs. Le montant que vous indiquerez ici deviendra le montant minimum pour les paiements à votre adresse.",
+ "minimumPayout": "Paiement minimum",
+ "enableEmailNotifications": "Activer les notifications par email",
+ "minerEmailNotify": "Ce pool peut vous envoyer une notification par email lorsqu'un bloc est trouvé ou bien lorsqu'un paiement vous est transmis.",
+ "emailAddress": "Adresse email",
+ "noMinerAddress": "Aucune adresse de mineur spécifiée",
+ "noMinerIP": "Aucune adresse IP pour votre mineur spécifiée",
+ "noPayoutLevel": "Aucun niveau de paiement spécifié",
+ "noEmail": "Aucune adresse email spécifiée",
+ "invalidEmail": "L'adresse email spécifiée est invalide",
+ "minerPayoutSet": "Fait! Votre niveau de paiement minimum a été configuré",
+ "notificationEnabled": "Fait! Les notifications par email ont été activées",
+ "notificationDisabled": "Fait! Les notifications par email ont été désactivées",
+
+ "enterYourAddress": "Entrez votre adresse",
+ "enterYourMinerIP": "Une adresse IP utilisée par votre mineur (peu importe)",
+ "enterYourEmail": "Votre adresse email",
+
+ "lookup": "Chercher",
+ "searching": "Recherche...",
+ "loadMore": "Charger plus",
+ "set": "Configurer",
+ "enable": "Activer",
+ "disable": "Désactiver",
+
+ "status": "Statut",
+ "updated": "Mis à jour:",
+ "source": "Source:",
+ "error": "Erreur:",
+
+ "na": "N/D",
+ "estimated": "estimé",
+ "never": "Jamais",
+ "second": "seconde",
+ "seconds": "secondes",
+ "minute": "minute",
+ "minutes": "minutes",
+ "hour": "heure",
+ "hours": "heures",
+ "day": "jour",
+ "days": "jours",
+ "week": "semaine",
+ "weeks": "weeks",
+ "month": "mois",
+ "months": "mois",
+ "year": "année",
+ "years": "années",
+
+ "poweredBy": "Propulsé par",
+ "openSource": "et libre de droits sous licence"
+}
\ No newline at end of file
diff --git a/website/lang/it.json b/website/lang/it.json
new file mode 100644
index 0000000..cbe084f
--- /dev/null
+++ b/website/lang/it.json
@@ -0,0 +1,168 @@
+{
+ "miningPool": "Mining Pool",
+ "dashboard": "Dashboard",
+ "gettingStarted": "Come Iniziare",
+ "yourStats": "Statistiche del Worker",
+ "poolBlocks": "Pool Blocks",
+ "settings": "Impostazioni",
+ "faq": "FAQ",
+ "telegram": "Gruppo Telegram",
+ "discord": "Discord",
+ "contactUs": "Contattaci",
+
+ "network": "Rete",
+ "pool": "Pool",
+ "you": "Tu",
+ "statsUpdated": "Stats Aggiornati",
+
+ "poolHashrate": "Pool Hash Rate",
+ "currentEffort": "Current Effort",
+ "networkHashrate": "Network Hash Rate",
+ "networkDifficulty": "Difficoltà",
+ "blockchainHeight": "Blockchain Height",
+ "networkLastReward": "Ultimo Reward",
+ "poolMiners": "Miners Connessi",
+ "poolFee": "Pool Fee",
+
+ "minerStats": "Stats Personali & Storia dei tuoi pagamenti",
+ "workerStats": "Statistiche del Worker",
+ "miner": "Miner",
+ "miners": "Miners",
+ "minersCount": "miners",
+ "workers": "Workers",
+ "workersCount": "workers",
+ "workerName": "Worker Name",
+ "lastHash": "Ultimo Hash",
+ "hashRate": "Hash Rate",
+ "currentHashRate": "Attuale Hash Rate",
+ "lastShare": "Ultimo Share Trasmesso",
+ "totalHashes": "Totale Hashes Trasmessi",
+ "top10miners": "Top 10 miners",
+
+ "blocksTotal": "Blocchi trovati",
+ "blockSolvedTime": "Blocco trovato ogni",
+ "blocksMaturityCount": "Maturità richiesta",
+ "efficiency": "Efficenza",
+ "averageLuck": "Fortuna",
+ "timeFound": "Orario trovato",
+ "reward": "Ricompensa",
+ "height": "Height",
+ "difficulty": "Difficoltà",
+ "blockHash": "Block Hash",
+ "effort": "Effort",
+ "blocksFoundLast24": "Blocks found in the last 24 hours",
+ "blocksFoundLastDays": "Blocks found in the last {DAYS} days",
+
+ "payments": "Pagamenti",
+ "paymentsHistory": "Storia Pagamenti",
+ "paymentsTotal": "Pagamenti totali",
+ "paymentsMinimum": "Minimo pagamento",
+ "paymentsInterval": "intervallo pagamento",
+ "paymentsDenomination": "Unità di denominazione",
+ "timeSent": "Orario Inviato",
+ "transactionHash": "Transazione Hash",
+ "amount": "Quantità",
+ "fee": "Fee",
+ "mixin": "Mixin",
+ "payees": "Pagati",
+ "pendingBalance": "In sospeso",
+ "totalPaid": "Totale pagato",
+ "payoutEstimate": "Stima del pagamento corrente",
+ "paymentSummarySingle": "In %DATE% hai ricevuto %AMOUNT%",
+ "paymentSummaryMulti": "In %DATE% hai ricevuto %AMOUNT% in %COUNT% pagamenti",
+
+ "connectionDetails": "Detagli Connessione",
+ "miningPoolHost": "Mining Pool Address",
+ "cnAlgorithm": "Algorithmo",
+ "username": "Username",
+ "usernameDesc": "questo è L'indrizzo del wallet",
+ "paymentId": "Exchange Payment ID",
+ "fixedDiff": "Difficoltà di blocco",
+ "address": "indrizzo",
+ "addrPaymentId": "paymentID",
+ "addrDiff": "diff",
+ "password": "Password",
+ "passwordDesc": "Questo è il nome del Worker",
+ "emailNotifications": "Notifiche Email",
+ "miningPorts": "Mining Ports",
+ "port": "Port",
+ "portDiff": "Difficoltà avvio",
+ "description": "Descrizione",
+ "miningApps": "Applicazioni Mining",
+ "configGeneratorDesc": "Genera La tua configurazione per minare sulla nostra pool",
+ "addressField": "Indrizzo wallet",
+ "paymentIdField": "Pagamento ID per exchanges (optionale)",
+ "fixedDiffField": "Fixed difficulty (optionale)",
+ "workerNameField": "Worker_Name",
+ "emailNotificationsField": "Notifiche email (optionale)",
+ "generateConfig": "Genera configuratione",
+ "appName": "App Name",
+ "appArch": "Architettura",
+ "appDesc": "Features",
+ "download": "Download",
+ "showConfig": "Vedi",
+
+ "market": "Market / Calculatoe",
+ "loadingMarket": "Loading market prices",
+ "priceIn": "Price in",
+ "hashPer": "Hash/",
+ "estimateProfit": "Stima dei profitti",
+ "enterYourHashrate": "Inserisci il tuo Hashrate",
+ "perDay": "al giorno",
+
+ "verificationFields": "Campi di verifica",
+ "minerVerification": "Per avere un po 'più di fiducia che l'indirizzo del tuo wallet è tuo ti chiediamo di dare uno degli indirizzi IP che viene utilizzato dal tuo miners.",
+ "minerAddress": "Miner Address",
+ "minerIP": "Miner IP address",
+ "setMinimumPayout": "Inserisci il pagamento minimo ",
+ "minerMinPayout": "Se preferisci un livello di pagamento più alto rispetto al valore predefinito del pool, è qui che puoi cambiarlo per i tuoi miner. L'importo indicato qui diventerà l'importo minimo per i pagamenti del pool al tuo indirizzo.",
+ "minimumPayout": "Payout Minimo",
+ "enableEmailNotifications": "Abilitare notifiche email",
+ "minerEmailNotify": "Questa pool invierà una notifica via email quando viene trovato un blocco e ogni volta che si verifica un pagamento.",
+ "emailAddress": "Email address",
+ "noMinerAddress": "Nessun indrizzo wallet indicato",
+ "noMinerIP": "Nessun indrizzo ip indicato del miner",
+ "noPayoutLevel": "Nessun livello specificato",
+ "noEmail": "Nessun indirizzo email specificato",
+ "invalidEmail": "Indrizzo email invalido",
+ "minerPayoutSet": "Fatto! Il tuo livello di pagamento minimo è stato impostato",
+ "notificationEnabled": "Fatto! Le notifiche email sono state abilitate",
+ "notificationDisabled": "Fatto! Le notifiche email sono state disabilitate",
+
+ "enterYourAddress": "Inserisci il tuo indrizzo",
+ "enterYourMinerIP": "Un indrizzo ip di qualsiasi tuo miner",
+ "enterYourEmail": "Inserisci il tuo indrizzo email (optionale)",
+
+ "lookup": "Consulto..",
+ "searching": "Cerco...",
+ "loadMore": "Carica Di più",
+ "set": "imposta",
+ "enable": "abilita",
+ "disable": "Disabilita",
+
+ "status": "Stato",
+ "updated": "Aggiornato:",
+ "source": "Fonte:",
+ "error": "Errore:",
+
+ "na": "N/A",
+ "estimated": "stimato",
+ "never": "mai",
+ "second": "secondo",
+ "seconds": "secondi",
+ "minute": "minuto",
+ "minutes": "minuti",
+ "hour": "ora",
+ "hours": "ore",
+ "day": "giorno",
+ "days": "giorni",
+ "week": "settimana",
+ "weeks": "settimane",
+ "month": "mese",
+ "months": "mesi",
+ "year": "anno",
+ "years": "anni",
+
+ "poweredBy": "Powered by",
+ "openSource": "open sourced under the"
+}
diff --git a/website/lang/ko.json b/website/lang/ko.json
new file mode 100644
index 0000000..229d66d
--- /dev/null
+++ b/website/lang/ko.json
@@ -0,0 +1,167 @@
+{
+ "miningPool": "Mining Pool",
+ "dashboard": "풀상황",
+ "gettingStarted": "도움말:시작",
+ "yourStats": "마이너(워커) 상황",
+ "poolBlocks": "풀블럭상태",
+ "settings": "설정",
+ "telegram": "텔레그램연결",
+ "discord": "Discord",
+ "contactUs": "문의하기",
+
+ "network": "네트워크",
+ "pool": "풀",
+ "you": "you",
+ "statsUpdated": "업데이트",
+
+ "poolHashrate": "풀의 해시레이트",
+ "currentEffort": "Current Effort",
+ "networkHashrate": "네크워크 해시레이트",
+ "networkDifficulty": "난이도",
+ "blockchainHeight": "블록체인 높이",
+ "networkLastReward": "최근 보상량",
+ "poolMiners": "연결된 마이너수",
+ "poolFee": "풀 수수료",
+
+ "minerStats": "마이너 상태와 지급상황",
+ "workerStats": "워커 상태",
+ "miner": "Miner",
+ "miners": "Miners",
+ "minersCount": "miners",
+ "workers": "Workers",
+ "workersCount": "workers",
+ "workerName": "Worker Name",
+ "lastHash": "Last Hash",
+ "hashRate": "Hash Rate",
+ "currentHashRate": "Current Hash Rate",
+ "lastShare": "Last Share Submitted",
+ "totalHashes": "Total Hashes Submitted",
+ "top10miners": "상위 10 채굴자",
+
+ "blocksTotal": "블록 발견",
+ "blockSolvedTime": "Blocks Found Every",
+ "blocksMaturityCount": "적립되기전 블럭수량",
+ "efficiency": "Efficiency",
+ "averageLuck": "Average Luck",
+ "timeFound": "블럭 발견시작",
+ "reward": "보상",
+ "height": "블럭번호",
+ "difficulty": "난이도",
+ "blockHash": "블럭 해시",
+ "effort": "풀의노력",
+ "blocksFoundLast24": "Blocks found in the last 24 hours",
+ "blocksFoundLastDays": "Blocks found in the last {DAYS} days",
+
+ "payments": "출금상황",
+ "paymentsHistory": "출금 내역",
+ "paymentsTotal": "전체 출금 수",
+ "paymentsMinimum": "최소 출금 수량",
+ "paymentsInterval": "출금 주기",
+ "paymentsDenomination": "최소 출금 단위",
+ "timeSent": "출금 시작",
+ "transactionHash": "트랜잭션 아이디",
+ "amount": "수량",
+ "fee": "수수료",
+ "mixin": "Mixin",
+ "payees": "출금대상수",
+ "pendingBalance": "적립 대기",
+ "totalPaid": "전체 출금",
+ "payoutEstimate": "Current Payout Estimate",
+ "paymentSummarySingle": "On %DATE% you have received %AMOUNT%",
+ "paymentSummaryMulti": "On %DATE% you have received %AMOUNT% in %COUNT% payments",
+
+ "connectionDetails": "연결정보",
+ "miningPoolHost": "풀 접속주소",
+ "cnAlgorithm": "채굴 알고리즘",
+ "username": "Username",
+ "usernameDesc": "This is your wallet address",
+ "paymentId": "거래소 Payment ID",
+ "fixedDiff": "고정 난이도 설정",
+ "address": "지갑주소",
+ "addrPaymentId": "paymentID",
+ "addrDiff": "난이도",
+ "password": "암호",
+ "passwordDesc": "워커 이름 설정",
+ "emailNotifications": "Email Notifications",
+ "miningPorts": "채굴 포트",
+ "port": "접속포트",
+ "portDiff": "시작 난이도",
+ "description": "설명",
+ "miningApps": "마이닝 프로그램",
+ "configGeneratorDesc": "Generate your custom configuration to mine on our pool",
+ "addressField": "지갑 주소",
+ "paymentIdField": "거래소용 Payment ID (optional)",
+ "fixedDiffField": "고정난이도 (optional)",
+ "workerNameField": "워커 이름",
+ "emailNotificationsField": "Email Notifications (optional)",
+ "generateConfig": "설정 예제 생성",
+ "appName": "프로그램 이름",
+ "appArch": "Architecture",
+ "appDesc": "Features",
+ "download": "Download",
+ "showConfig": "See more",
+
+ "market": "시장가격 / 채굴량계산기",
+ "loadingMarket": "Loading market prices",
+ "priceIn": "Price in",
+ "hashPer": "Hash/",
+ "estimateProfit": "Estimate Mining Profits",
+ "enterYourHashrate": "Enter Your Hash Rate",
+ "perDay": "per day",
+
+ "verificationFields": "Verification fields",
+ "minerVerification": "In order to get a little more confidence that the wallet address is yours we ask you to give one of the IP addresses that is used by your miner.",
+ "minerAddress": "Miner Address",
+ "minerIP": "Miner IP address",
+ "setMinimumPayout": "Set your minimal payout level",
+ "minerMinPayout": "If you prefer a higher payout level than the pool's default then this is where you can change it for your miners. The amount you indicate here will become the minimum amount for pool payments to your address.",
+ "minimumPayout": "Minimum payout",
+ "enableEmailNotifications": "Enable email notifications",
+ "minerEmailNotify": "This pool will send out email notification when a block is found and whenever a payout happens.",
+ "emailAddress": "Email address",
+ "noMinerAddress": "No miner address specified",
+ "noMinerIP": "No miner IP address specified",
+ "noPayoutLevel": "No payout level specified",
+ "noEmail": "No email address specified",
+ "invalidEmail": "Invalid email address specified",
+ "minerPayoutSet": "Done! Your minimum payout level was set",
+ "notificationEnabled": "Done! Email notifications have been enabled",
+ "notificationDisabled": "Done! Email notifications have been disabled",
+
+ "enterYourAddress": "Enter Your Address",
+ "enterYourMinerIP": "An IP address your miners use (any)",
+ "enterYourEmail": "Enter Your E-Mail Address (optional)",
+
+ "lookup": "Lookup",
+ "searching": "Searching...",
+ "loadMore": "Load more",
+ "set": "Set",
+ "enable": "Enable",
+ "disable": "Disable",
+
+ "status": "Status",
+ "updated": "Updated:",
+ "source": "Source:",
+ "error": "Error:",
+
+ "na": "N/A",
+ "estimated": "estimated",
+ "never": "Never",
+ "second": "second",
+ "seconds": "seconds",
+ "minute": "minute",
+ "minutes": "minutes",
+ "hour": "hour",
+ "hours": "hours",
+ "day": "day",
+ "days": "days",
+ "week": "week",
+ "weeks": "weeks",
+ "month": "month",
+ "months": "months",
+ "year": "year",
+ "years": "years",
+
+ "poweredBy": "Powered by",
+ "openSource": "open sourced under the"
+}
diff --git a/website/lang/languages.js b/website/lang/languages.js
new file mode 100644
index 0000000..b73a776
--- /dev/null
+++ b/website/lang/languages.js
@@ -0,0 +1 @@
+var langs = { 'en': 'English', 'es': 'Español', 'fr': 'Français', 'it': 'Italiano', 'ru': 'Русский', 'ca': 'Català', 'ko': '한국어', 'zh-CN': '简体中文' };
\ No newline at end of file
diff --git a/website/lang/ru.json b/website/lang/ru.json
new file mode 100644
index 0000000..4536f8e
--- /dev/null
+++ b/website/lang/ru.json
@@ -0,0 +1,182 @@
+{
+ "miningPool": "Майнинг пул",
+ "dashboard": "Главная",
+ "gettingStarted": "Присоединиться",
+ "yourStats": "Статистика",
+ "poolBlocks": "Блоки пула",
+ "settings": "Настройки",
+ "faq": "FAQ",
+ "telegram": "Группа Telegram",
+ "discord": "Discord",
+ "contactUs": "Почта",
+
+ "network": "Сеть",
+ "pool": "Пул",
+ "you": "Вы",
+ "statsUpdated": "Статистика обновлена",
+
+ "poolHashrate": "Скорость пула",
+ "currentEffort": "Сложность раунда",
+ "networkHashrate": "Скорость сети",
+ "networkDifficulty": "Сложность",
+ "blockchainHeight": "№ последнего блока",
+ "networkLastReward": "Последнее вознаграждение",
+ "poolMiners": "Пользователи пула",
+ "poolFee": "Комиссия пула",
+
+ "minerStats": "Ваша статистика и история платежей",
+ "workerStats": "Статистика ферм",
+ "miner": "Miner",
+ "miners": "Пользователи",
+ "minersCount": "miners",
+ "workers": "Фермы",
+ "workersCount": "фермы",
+ "workerName": "Имя фермы",
+ "lastHash": "Последний хеш",
+ "hashRate": "Скорость",
+ "currentHashRate": "Текущая скорость",
+ "lastShare": "Последняя шара принята",
+ "totalHashes": "Всего принято хешей",
+ "top10miners": "Лучшие 10 майнеров",
+ "blocksTotal": "Найдено блоков",
+ "blockSolvedTime": "Время нахождения блока",
+ "blocksMaturityCount": "Требование подтверждения",
+ "efficiency": "Эффективность",
+ "averageLuck": "Средняя удача",
+ "timeFound": "Время нахождения",
+ "reward": "Выплата",
+ "height": "№ блока",
+ "difficulty": "Сложность",
+ "blockHash": "Хеш блока",
+ "effort": "Усилие",
+ "blocksFoundLast24": "Блоки найдены за последние 24 часа",
+ "blocksFoundLastDays": "Блоки найдены за последние {DAYS} дней",
+ "propSoloConnectedMiners": "PROP / SOLO Подключенные шахтеры",
+
+ "payments": "Платежи",
+ "paymentsHistory": "История платежей",
+ "paymentsTotal": "Всего платежей",
+ "paymentsMinimum": "Минимальный платёж",
+ "paymentsInterval": "Интервал платежей",
+ "paymentsDenomination": "Единица измерения",
+ "timeSent": "Время отправления",
+ "transactionHash": "Хеш транзакции",
+ "amount": "Сумма",
+ "fee": "Комиссия",
+ "mixin": "Mixin",
+ "payees": "Получателей",
+ "pendingBalance": "Ожидающий баланс",
+ "totalPaid": "Всего выплачено",
+ "payoutEstimate": "Текущая оценка выплат",
+
+ "connectionDetails": "Детали подключения",
+ "miningPoolHost": "Адрес майнинг пула",
+ "cnAlgorithm": "Алгоритм",
+ "username": "Имя пользователя",
+ "usernameDesc": "Это адрес вашего кошелька",
+ "paymentId": "Биржевой Payment ID",
+ "fixedDiff": "Фиксированная сложность",
+ "address": "address",
+ "addrPaymentId": "paymentID",
+ "addrDiff": "diff",
+ "password": "Пароль",
+ "passwordDesc": "Это имя вашей фермы в статистике",
+ "emailNotifications": "Уведомление по почте",
+ "miningPorts": "Порты для майнинга",
+ "port": "Порт",
+ "portDiff": "Стартовая сложность",
+ "description": "Описание",
+ "miningApps": "Программы для майнинга",
+ "configGeneratorDesc": "Создайте свою собственную конфигурацию для этого пула",
+ "addressField": "Адрес вашего кошелька",
+ "paymentIdField": "Payment ID для биржи (опция)",
+ "fixedDiffField": "Фиксированная сложность (опция)",
+ "workerNameField": "Имя_Фермы",
+ "emailNotificationsField": "Уведомление по почте (опция)",
+ "generateConfig": "Создать конфигурацию",
+ "appName": "Программа",
+ "appArch": "Архитектура",
+ "appDesc": "Особенности",
+ "download": "Скачать",
+ "showConfig": "Посмотреть",
+
+ "market": "Рынок / Калькулятор",
+ "loadingMarket": "Загрузка стоимости",
+ "priceIn": "Стоимость в",
+ "hashPer": "Стоимость хеша/",
+ "estimateProfit": "Рассчёт прибыли",
+ "enterYourHashrate": "Введите вашу скорость",
+ "perDay": "/в день",
+
+ "verificationFields": "Проверочные данные",
+ "minerVerification": "Чтобы быть уверенным в том, что адрес кошелька принадлежит вам, мы просим вас указать один из IP-адресов, который используется вашими фермами.",
+ "minerAddress": "Ваш кошелёк",
+ "minerIP": "IP адрес фермы",
+ "setMinimumPayout": "Установите минимальный уровень выплат",
+ "minerMinPayout": "Вы можете установить минимальный порог оплаты, если предпочитаете более высокий уровень выплат, чем значение по умолчанию. Сумма, которую вы здесь укажете, станет минимальной суммой для платежей пула на ваш адрес.",
+ "minimumPayout": "Минимальная выплата",
+ "enableEmailNotifications": "Включить уведомление по почте",
+ "minerEmailNotify": "Пул отправит уведомление по электронной почте, когда будет найден блок или когда произведёт выплату.",
+ "emailAddress": "E-mail адрес",
+ "noMinerAddress": "Вы не ввели свой кошелёк",
+ "noMinerIP": "Вы не ввели IP адрес фермы",
+ "noPayoutLevel": "Вы не ввели уровень оплаты",
+ "noEmail": "Вы не ввели e-mail адрес",
+ "invalidEmail": "Не правильный e-mail адрес",
+ "minerPayoutSet": "Минимальный уровень оплаты успешно установлен !",
+ "notificationEnabled": "Уведомления по электронной почте успешно включены !",
+ "notificationDisabled": "Уведомления по электронной почте успешно выключены !",
+
+ "enterYourAddress": "Введите адрес своего кошелька",
+ "enterYourMinerIP": "IP-адрес, который используют ваши фермы",
+ "enterYourEmail": "Введите свой E-Mail адрес (опция)",
+
+ "lookup": "Посмотреть",
+ "searching": "Поиск ...",
+ "loadMore": "Загрузить ещё",
+ "set": "Установить",
+ "enable": "Включить",
+ "disable": "Выключить",
+
+ "status": "Статус",
+ "updated": "Обновлено:",
+ "source": "Source:",
+ "error": "Ошибка:",
+
+ "na": "N/A",
+ "estimated": "примерно",
+ "never": "Не найден",
+ "second": "секунда",
+ "seconds": "секунд",
+ "minute": "минута",
+ "minutes": "минут",
+ "hour": "час",
+ "hours": "часов",
+ "day": "день",
+ "days": "дней",
+ "week": "неделя",
+ "weeks": "недель",
+ "month": "месяц",
+ "months": "месяцев",
+ "year": "год",
+ "years": "года",
+
+ "timeagoPrefixAgo": null,
+ "timeagoPrefixFromNow": null,
+ "timeagoSuffixAgo": "назад",
+ "timeagoSuffixFromNow": "from now",
+ "timeagoSeconds": "меньше минуты",
+ "timeagoMinute": "около минуты",
+ "timeagoMinutes": "%d минут",
+ "timeagoHour": "about an hour",
+ "timeagoHours": "about %d hours",
+ "timeagoDay": " день",
+ "timeagoDays": "%d дней",
+ "timeagoMonth": "about месяц",
+ "timeagoMonths": "%d месяцев",
+ "timeagoYear": "about год",
+ "timeagoYears": "%d лет",
+
+ "poweredBy": "Powered by",
+ "openSource": "open sourced under the"
+}
\ No newline at end of file
diff --git a/website/lang/timeago/jquery.timeago.af.js b/website/lang/timeago/jquery.timeago.af.js
new file mode 100644
index 0000000..817a7fa
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.af.js
@@ -0,0 +1,30 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Afrikaans
+ jQuery.timeago.settings.strings = {
+ prefixAgo: null,
+ prefixFromNow: null,
+ suffixAgo: "gelede",
+ suffixFromNow: "van nou af",
+ seconds: "%d sekondes",
+ minute: "1 minuut",
+ minutes: "%d minute",
+ hour: "1 uur",
+ hours: "%d ure",
+ day: "1 dag",
+ days: "%d dae",
+ month: "1 maand",
+ months: "%d maande",
+ year: "1 jaar",
+ years: "%d jaar",
+ wordSeparator: " ",
+ numbers: []
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.am.js b/website/lang/timeago/jquery.timeago.am.js
new file mode 100644
index 0000000..65502c3
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.am.js
@@ -0,0 +1,30 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Amharic
+ jQuery.timeago.settings.strings = {
+ prefixAgo: null,
+ prefixFromNow: null,
+ suffixAgo: "በፊት",
+ suffixFromNow: "በኋላ",
+ seconds: "ከአንድ ደቂቃ በታች",
+ minute: "ከአንድ ደቂቃ ገደማ",
+ minutes: "ከ%d ደቂቃ",
+ hour: "ከአንድ ሰዓት ገደማ",
+ hours: "ከ%d ሰዓት ገደማ",
+ day: "ከአንድ ቀን",
+ days: "ከ%d ቀን",
+ month: "ከአንድ ወር ገደማ",
+ months: "ከ%d ወር",
+ year: "ከአንድ ዓመት ገደማ",
+ years: "ከ%d ዓመት",
+ wordSeparator: " ",
+ numbers: []
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.ar.js b/website/lang/timeago/jquery.timeago.ar.js
new file mode 100644
index 0000000..14cd18f
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.ar.js
@@ -0,0 +1,104 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ function numpf(n, a) {
+ return a[plural=n===0 ? 0 : n===1 ? 1 : n===2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 ? 4 : 5];
+ }
+
+ jQuery.timeago.settings.strings = {
+ prefixAgo: "منذ",
+ prefixFromNow: "بعد",
+ suffixAgo: null,
+ suffixFromNow: null, // null OR "من الآن"
+ second: function(value) { return numpf(value, [
+ 'أقل من ثانية',
+ 'ثانية واحدة',
+ 'ثانيتين',
+ '%d ثوانٍ',
+ '%d ثانية',
+ '%d ثانية']); },
+ seconds: function(value) { return numpf(value, [
+ 'أقل من ثانية',
+ 'ثانية واحدة',
+ 'ثانيتين',
+ '%d ثوانٍ',
+ '%d ثانية',
+ '%d ثانية']); },
+ minute: function(value) { return numpf(value, [
+ 'أقل من دقيقة',
+ 'دقيقة واحدة',
+ 'دقيقتين',
+ '%d دقائق',
+ '%d دقيقة',
+ 'دقيقة']); },
+ minutes: function(value) { return numpf(value, [
+ 'أقل من دقيقة',
+ 'دقيقة واحدة',
+ 'دقيقتين',
+ '%d دقائق',
+ '%d دقيقة',
+ 'دقيقة']); },
+ hour: function(value) { return numpf(value, [
+ 'أقل من ساعة',
+ 'ساعة واحدة',
+ 'ساعتين',
+ '%d ساعات',
+ '%d ساعة',
+ '%d ساعة']); },
+ hours: function(value) { return numpf(value, [
+ 'أقل من ساعة',
+ 'ساعة واحدة',
+ 'ساعتين',
+ '%d ساعات',
+ '%d ساعة',
+ '%d ساعة']); },
+ day: function(value) { return numpf(value, [
+ 'أقل من يوم',
+ 'يوم واحد',
+ 'يومين',
+ '%d أيام',
+ '%d يومًا',
+ '%d يوم']); },
+ days: function(value) { return numpf(value, [
+ 'أقل من يوم',
+ 'يوم واحد',
+ 'يومين',
+ '%d أيام',
+ '%d يومًا',
+ '%d يوم']); },
+ month: function(value) { return numpf(value, [
+ 'أقل من شهر',
+ 'شهر واحد',
+ 'شهرين',
+ '%d أشهر',
+ '%d شهرًا',
+ '%d شهر']); },
+ months: function(value) { return numpf(value, [
+ 'أقل من شهر',
+ 'شهر واحد',
+ 'شهرين',
+ '%d أشهر',
+ '%d شهرًا',
+ '%d شهر']); },
+ year: function(value) { return numpf(value, [
+ 'أقل من عام',
+ 'عام واحد',
+ '%d عامين',
+ '%d أعوام',
+ '%d عامًا']);
+ },
+ years: function(value) { return numpf(value, [
+ 'أقل من عام',
+ 'عام واحد',
+ 'عامين',
+ '%d أعوام',
+ '%d عامًا',
+ '%d عام']);}
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.az.js b/website/lang/timeago/jquery.timeago.az.js
new file mode 100644
index 0000000..8332c41
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.az.js
@@ -0,0 +1,30 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Azerbaijani
+ jQuery.timeago.settings.strings = {
+ prefixAgo: null,
+ prefixFromNow: null,
+ suffixAgo: 'əvvəl',
+ suffixFromNow: 'sonra',
+ seconds: 'saniyələr',
+ minute: '1 dəqiqə',
+ minutes: '%d dəqiqə',
+ hour: '1 saat',
+ hours: '%d saat',
+ day: '1 gün',
+ days: '%d gün',
+ month: '1 ay',
+ months: '%d ay',
+ year: '1 il',
+ years: '%d il',
+ wordSeparator: '',
+ numbers: []
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.bg.js b/website/lang/timeago/jquery.timeago.bg.js
new file mode 100644
index 0000000..a3bd343
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.bg.js
@@ -0,0 +1,28 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Bulgarian
+ jQuery.timeago.settings.strings = {
+ prefixAgo: "преди",
+ prefixFromNow: "след",
+ suffixAgo: null,
+ suffixFromNow: null,
+ seconds: "по-малко от минута",
+ minute: "една минута",
+ minutes: "%d минути",
+ hour: "един час",
+ hours: "%d часа",
+ day: "един ден",
+ days: "%d дни",
+ month: "един месец",
+ months: "%d месеца",
+ year: "една година",
+ years: "%d години"
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.bs.js b/website/lang/timeago/jquery.timeago.bs.js
new file mode 100644
index 0000000..cbb1780
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.bs.js
@@ -0,0 +1,55 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Bosnian
+ var numpf = function(n, f, s, t) {
+ var n10;
+ n10 = n % 10;
+ if (n10 === 1 && (n === 1 || n > 20)) {
+ return f;
+ } else if (n10 > 1 && n10 < 5 && (n > 20 || n < 10)) {
+ return s;
+ } else {
+ return t;
+ }
+ };
+
+ jQuery.timeago.settings.strings = {
+ prefixAgo: "prije",
+ prefixFromNow: "za",
+ suffixAgo: null,
+ suffixFromNow: null,
+ second: "sekund",
+ seconds: function(value) {
+ return numpf(value, "%d sekund", "%d sekunde", "%d sekundi");
+ },
+ minute: "oko minut",
+ minutes: function(value) {
+ return numpf(value, "%d minut", "%d minute", "%d minuta");
+ },
+ hour: "oko sat",
+ hours: function(value) {
+ return numpf(value, "%d sat", "%d sata", "%d sati");
+ },
+ day: "oko jednog dana",
+ days: function(value) {
+ return numpf(value, "%d dan", "%d dana", "%d dana");
+ },
+ month: "mjesec dana",
+ months: function(value) {
+ return numpf(value, "%d mjesec", "%d mjeseca", "%d mjeseci");
+ },
+ year: "prije godinu dana ",
+ years: function(value) {
+ return numpf(value, "%d godinu", "%d godine", "%d godina");
+ },
+ wordSeparator: " "
+ };
+
+}));
diff --git a/website/lang/timeago/jquery.timeago.ca.js b/website/lang/timeago/jquery.timeago.ca.js
new file mode 100644
index 0000000..e4cb5ca
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.ca.js
@@ -0,0 +1,30 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Catalan
+ jQuery.timeago.settings.strings = {
+ prefixAgo: "fa",
+ prefixFromNow: "d'aquí",
+ suffixAgo: null,
+ suffixFromNow: null,
+ seconds: "menys d'un minut",
+ minute: "un minut",
+ minutes: "%d minuts",
+ hour: "una hora",
+ hours: "%d hores",
+ day: "un dia",
+ days: "%d dies",
+ month: "un mes",
+ months: "%d mesos",
+ year: "un any",
+ years: "%d anys",
+ wordSeparator: " ",
+ numbers: []
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.cs.js b/website/lang/timeago/jquery.timeago.cs.js
new file mode 100644
index 0000000..b940f69
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.cs.js
@@ -0,0 +1,34 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Czech
+ (function() {
+ function f(n, d, a) {
+ return a[d>=0 ? 0 : a.length===2 || n<5 ? 1 : 2];
+ }
+
+ jQuery.timeago.settings.strings = {
+ prefixAgo: 'před',
+ prefixFromNow: 'za',
+ suffixAgo: null,
+ suffixFromNow: null,
+ seconds: function(n, d) {return f(n, d, ['méně než minutou', 'méně než minutu']);},
+ minute: function(n, d) {return f(n, d, ['minutou', 'minutu']);},
+ minutes: function(n, d) {return f(n, d, ['%d minutami', '%d minuty', '%d minut']);},
+ hour: function(n, d) {return f(n, d, ['hodinou', 'hodinu']);},
+ hours: function(n, d) {return f(n, d, ['%d hodinami', '%d hodiny', '%d hodin']);},
+ day: function(n, d) {return f(n, d, ['%d dnem', '%d den']);},
+ days: function(n, d) {return f(n, d, ['%d dny', '%d dny', '%d dní']);},
+ month: function(n, d) {return f(n, d, ['%d měsícem', '%d měsíc']);},
+ months: function(n, d) {return f(n, d, ['%d měsíci', '%d měsíce', '%d měsíců']);},
+ year: function(n, d) {return f(n, d, ['%d rokem', '%d rok']);},
+ years: function(n, d) {return f(n, d, ['%d lety', '%d roky', '%d let']);}
+ };
+ })();
+}));
diff --git a/website/lang/timeago/jquery.timeago.cy.js b/website/lang/timeago/jquery.timeago.cy.js
new file mode 100644
index 0000000..4c514a8
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.cy.js
@@ -0,0 +1,30 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Welsh
+ jQuery.timeago.settings.strings = {
+ prefixAgo: null,
+ prefixFromNow: null,
+ suffixAgo: "yn ôl",
+ suffixFromNow: "o hyn",
+ seconds: "llai na munud",
+ minute: "am funud",
+ minutes: "%d munud",
+ hour: "tua awr",
+ hours: "am %d awr",
+ day: "y dydd",
+ days: "%d diwrnod",
+ month: "tua mis",
+ months: "%d mis",
+ year: "am y flwyddyn",
+ years: "%d blynedd",
+ wordSeparator: " ",
+ numbers: []
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.da.js b/website/lang/timeago/jquery.timeago.da.js
new file mode 100644
index 0000000..236c34c
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.da.js
@@ -0,0 +1,28 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Danish
+ jQuery.timeago.settings.strings = {
+ prefixAgo: "for",
+ prefixFromNow: "om",
+ suffixAgo: "siden",
+ suffixFromNow: "",
+ seconds: "mindre end et minut",
+ minute: "ca. et minut",
+ minutes: "%d minutter",
+ hour: "ca. en time",
+ hours: "ca. %d timer",
+ day: "en dag",
+ days: "%d dage",
+ month: "ca. en måned",
+ months: "%d måneder",
+ year: "ca. et år",
+ years: "%d år"
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.de.js b/website/lang/timeago/jquery.timeago.de.js
new file mode 100644
index 0000000..6a877a2
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.de.js
@@ -0,0 +1,28 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // German
+ jQuery.timeago.settings.strings = {
+ prefixAgo: "vor",
+ prefixFromNow: "in",
+ suffixAgo: "",
+ suffixFromNow: "",
+ seconds: "wenigen Sekunden",
+ minute: "etwa einer Minute",
+ minutes: "%d Minuten",
+ hour: "etwa einer Stunde",
+ hours: "%d Stunden",
+ day: "etwa einem Tag",
+ days: "%d Tagen",
+ month: "etwa einem Monat",
+ months: "%d Monaten",
+ year: "etwa einem Jahr",
+ years: "%d Jahren"
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.dv.js b/website/lang/timeago/jquery.timeago.dv.js
new file mode 100644
index 0000000..0d70a49
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.dv.js
@@ -0,0 +1,32 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ /**
+ * Dhivehi time in Thaana for timeago.js
+ **/
+ jQuery.timeago.settings.strings = {
+ prefixAgo: null,
+ prefixFromNow: null,
+ suffixAgo: "ކުރިން",
+ suffixFromNow: "ފަހުން",
+ seconds: "ސިކުންތުކޮޅެއް",
+ minute: "މިނިޓެއްވަރު",
+ minutes: "%d މިނިޓު",
+ hour: "ގަޑިއެއްވަރު",
+ hours: "ގާތްގަނޑަކަށް %d ގަޑިއިރު",
+ day: "އެއް ދުވަސް",
+ days: "މީގެ %d ދުވަސް",
+ month: "މަހެއްވަރު",
+ months: "މީގެ %d މަސް",
+ year: "އަހަރެއްވަރު",
+ years: "މީގެ %d އަހަރު",
+ wordSeparator: " ",
+ numbers: []
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.el.js b/website/lang/timeago/jquery.timeago.el.js
new file mode 100644
index 0000000..2db9ebe
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.el.js
@@ -0,0 +1,28 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Greek
+ jQuery.timeago.settings.strings = {
+ prefixAgo: "πριν",
+ prefixFromNow: "σε",
+ suffixAgo: "",
+ suffixFromNow: "",
+ seconds: "λιγότερο από ένα λεπτό",
+ minute: "περίπου ένα λεπτό",
+ minutes: "%d λεπτά",
+ hour: "περίπου μία ώρα",
+ hours: "περίπου %d ώρες",
+ day: "μία μέρα",
+ days: "%d μέρες",
+ month: "περίπου ένα μήνα",
+ months: "%d μήνες",
+ year: "περίπου ένα χρόνο",
+ years: "%d χρόνια"
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.en.js b/website/lang/timeago/jquery.timeago.en.js
new file mode 100644
index 0000000..8ca50af
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.en.js
@@ -0,0 +1,30 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // English (Template)
+ jQuery.timeago.settings.strings = {
+ prefixAgo: null,
+ prefixFromNow: null,
+ suffixAgo: "ago",
+ suffixFromNow: "from now",
+ seconds: "less than a minute",
+ minute: "about a minute",
+ minutes: "%d minutes",
+ hour: "about an hour",
+ hours: "about %d hours",
+ day: "a day",
+ days: "%d days",
+ month: "about a month",
+ months: "%d months",
+ year: "about a year",
+ years: "%d years",
+ wordSeparator: " ",
+ numbers: []
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.es.js b/website/lang/timeago/jquery.timeago.es.js
new file mode 100644
index 0000000..0785b3f
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.es.js
@@ -0,0 +1,29 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Spanish
+ jQuery.timeago.settings.strings = {
+ prefixAgo: "hace",
+ prefixFromNow: "dentro de",
+ suffixAgo: "",
+ suffixFromNow: "",
+ seconds: "menos de un minuto",
+ minute: "un minuto",
+ minutes: "unos %d minutos",
+ hour: "una hora",
+ hours: "%d horas",
+ day: "un día",
+ days: "%d días",
+ month: "un mes",
+ months: "%d meses",
+ year: "un año",
+ years: "%d años"
+ };
+}));
+
diff --git a/website/lang/timeago/jquery.timeago.et.js b/website/lang/timeago/jquery.timeago.et.js
new file mode 100644
index 0000000..ac2461e
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.et.js
@@ -0,0 +1,28 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Estonian
+ jQuery.timeago.settings.strings = {
+ prefixAgo: null,
+ prefixFromNow: null,
+ suffixAgo: "tagasi",
+ suffixFromNow: "pärast",
+ seconds: function(n, d) { return d < 0 ? "vähem kui minuti aja" : "vähem kui minut aega"; },
+ minute: function(n, d) { return d < 0 ? "umbes minuti aja" : "umbes minut aega"; },
+ minutes: function(n, d) { return d < 0 ? "%d minuti" : "%d minutit"; },
+ hour: function(n, d) { return d < 0 ? "umbes tunni aja" : "umbes tund aega"; },
+ hours: function(n, d) { return d < 0 ? "%d tunni" : "%d tundi"; },
+ day: function(n, d) { return d < 0 ? "umbes päeva" : "umbes päev"; },
+ days: "%d päeva",
+ month: function(n, d) { return d < 0 ? "umbes kuu aja" : "umbes kuu aega"; },
+ months: function(n, d) { return d < 0 ? "%d kuu" : "%d kuud"; },
+ year: function(n, d) { return d < 0 ? "umbes aasta aja" : "umbes aasta aega"; },
+ years: function(n, d) { return d < 0 ? "%d aasta" : "%d aastat"; }
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.eu.js b/website/lang/timeago/jquery.timeago.eu.js
new file mode 100644
index 0000000..5c2c32c
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.eu.js
@@ -0,0 +1,28 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ jQuery.timeago.settings.strings = {
+ prefixAgo: "duela",
+ prefixFromNow: "hemendik",
+ suffixAgo: "",
+ suffixFromNow: "barru",
+ seconds: "minutu bat bainu gutxiago",
+ minute: "minutu bat",
+ minutes: "%d minutu inguru",
+ hour: "ordu bat",
+ hours: "%d ordu",
+ day: "egun bat",
+ days: "%d egun",
+ month: "hilabete bat",
+ months: "%d hilabete",
+ year: "urte bat",
+ years: "%d urte"
+ };
+}));
+
diff --git a/website/lang/timeago/jquery.timeago.fa.js b/website/lang/timeago/jquery.timeago.fa.js
new file mode 100644
index 0000000..ec8ccb9
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.fa.js
@@ -0,0 +1,32 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Persian
+ // Use DIR attribute for RTL text in Persian Language for ABBR tag .
+ // By MB.seifollahi@gmail.com
+ jQuery.timeago.settings.strings = {
+ prefixAgo: null,
+ prefixFromNow: null,
+ suffixAgo: "پیش",
+ suffixFromNow: "از حال",
+ seconds: "کمتر از یک دقیقه",
+ minute: "حدود یک دقیقه",
+ minutes: "%d دقیقه",
+ hour: "حدود یک ساعت",
+ hours: "حدود %d ساعت",
+ day: "یک روز",
+ days: "%d روز",
+ month: "حدود یک ماه",
+ months: "%d ماه",
+ year: "حدود یک سال",
+ years: "%d سال",
+ wordSeparator: " ",
+ numbers: ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹']
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.fi.js b/website/lang/timeago/jquery.timeago.fi.js
new file mode 100644
index 0000000..b5f7e69
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.fi.js
@@ -0,0 +1,38 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Finnish
+ jQuery.timeago.settings.strings = {
+ prefixAgo: null,
+ prefixFromNow: null,
+ suffixAgo: "sitten",
+ suffixFromNow: "tulevaisuudessa",
+ seconds: "alle minuutti",
+ minute: "minuutti",
+ minutes: "%d minuuttia",
+ hour: "tunti",
+ hours: "%d tuntia",
+ day: "päivä",
+ days: "%d päivää",
+ month: "kuukausi",
+ months: "%d kuukautta",
+ year: "vuosi",
+ years: "%d vuotta"
+ };
+
+ // The above is not a great localization because one would usually
+ // write "2 days ago" in Finnish as "2 päivää sitten", however
+ // one would write "2 days into the future" as "2:n päivän päästä"
+ // which cannot be achieved with localization support this simple.
+ // This is because Finnish has word suffixes (attached directly
+ // to the end of the word). The word "day" is "päivä" in Finnish.
+ // As workaround, the above localizations will say
+ // "2 päivää tulevaisuudessa" which is understandable but
+ // not as fluent.
+}));
diff --git a/website/lang/timeago/jquery.timeago.fr.js b/website/lang/timeago/jquery.timeago.fr.js
new file mode 100644
index 0000000..1bb052a
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.fr.js
@@ -0,0 +1,27 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // French
+ jQuery.timeago.settings.strings = {
+ // environ ~= about, it's optional
+ prefixAgo: "il y a",
+ prefixFromNow: "d'ici",
+ seconds: "moins d'une minute",
+ minute: "environ une minute",
+ minutes: "environ %d minutes",
+ hour: "environ une heure",
+ hours: "environ %d heures",
+ day: "environ un jour",
+ days: "environ %d jours",
+ month: "environ un mois",
+ months: "environ %d mois",
+ year: "un an",
+ years: "%d ans"
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.gl.js b/website/lang/timeago/jquery.timeago.gl.js
new file mode 100644
index 0000000..277bbf7
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.gl.js
@@ -0,0 +1,28 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Galician
+ jQuery.timeago.settings.strings = {
+ prefixAgo: "hai",
+ prefixFromNow: "dentro de",
+ suffixAgo: "",
+ suffixFromNow: "",
+ seconds: "menos dun minuto",
+ minute: "un minuto",
+ minutes: "uns %d minutos",
+ hour: "unha hora",
+ hours: "%d horas",
+ day: "un día",
+ days: "%d días",
+ month: "un mes",
+ months: "%d meses",
+ year: "un ano",
+ years: "%d anos"
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.he.js b/website/lang/timeago/jquery.timeago.he.js
new file mode 100644
index 0000000..2cd31ab
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.he.js
@@ -0,0 +1,26 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Hebrew
+ jQuery.timeago.settings.strings = {
+ prefixAgo: "לפני",
+ prefixFromNow: "עוד",
+ seconds: "פחות מדקה",
+ minute: "דקה",
+ minutes: "%d דקות",
+ hour: "שעה",
+ hours: function(number){return (number===2) ? "שעתיים" : "%d שעות";},
+ day: "יום",
+ days: function(number){return (number===2) ? "יומיים" : "%d ימים";},
+ month: "חודש",
+ months: function(number){return (number===2) ? "חודשיים" : "%d חודשים";},
+ year: "שנה",
+ years: function(number){return (number===2) ? "שנתיים" : "%d שנים";}
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.hr.js b/website/lang/timeago/jquery.timeago.hr.js
new file mode 100644
index 0000000..bd14297
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.hr.js
@@ -0,0 +1,54 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Croatian
+ var numpf = function (n, f, s, t) {
+ var n10;
+ n10 = n % 10;
+ if (n10 === 1 && (n === 1 || n > 20)) {
+ return f;
+ } else if (n10 > 1 && n10 < 5 && (n > 20 || n < 10)) {
+ return s;
+ } else {
+ return t;
+ }
+ };
+
+ jQuery.timeago.settings.strings = {
+ prefixAgo: "prije",
+ prefixFromNow: "za",
+ suffixAgo: null,
+ suffixFromNow: null,
+ second: "sekundu",
+ seconds: function (value) {
+ return numpf(value, "%d sekundu", "%d sekunde", "%d sekundi");
+ },
+ minute: "oko minutu",
+ minutes: function (value) {
+ return numpf(value, "%d minutu", "%d minute", "%d minuta");
+ },
+ hour: "oko jedan sat",
+ hours: function (value) {
+ return numpf(value, "%d sat", "%d sata", "%d sati");
+ },
+ day: "jedan dan",
+ days: function (value) {
+ return numpf(value, "%d dan", "%d dana", "%d dana");
+ },
+ month: "mjesec dana",
+ months: function (value) {
+ return numpf(value, "%d mjesec", "%d mjeseca", "%d mjeseci");
+ },
+ year: "prije godinu dana",
+ years: function (value) {
+ return numpf(value, "%d godinu", "%d godine", "%d godina");
+ },
+ wordSeparator: " "
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.hu.js b/website/lang/timeago/jquery.timeago.hu.js
new file mode 100644
index 0000000..0009de9
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.hu.js
@@ -0,0 +1,28 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Hungarian
+ jQuery.timeago.settings.strings = {
+ prefixAgo: null,
+ prefixFromNow: null,
+ suffixAgo: null,
+ suffixFromNow: null,
+ seconds: "kevesebb mint egy perce",
+ minute: "körülbelül egy perce",
+ minutes: "%d perce",
+ hour: "körülbelül egy órája",
+ hours: "körülbelül %d órája",
+ day: "körülbelül egy napja",
+ days: "%d napja",
+ month: "körülbelül egy hónapja",
+ months: "%d hónapja",
+ year: "körülbelül egy éve",
+ years: "%d éve"
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.hy.js b/website/lang/timeago/jquery.timeago.hy.js
new file mode 100644
index 0000000..3f0de6e
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.hy.js
@@ -0,0 +1,28 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Armenian
+ jQuery.timeago.settings.strings = {
+ prefixAgo: null,
+ prefixFromNow: null,
+ suffixAgo: "առաջ",
+ suffixFromNow: "հետո",
+ seconds: "վայրկյաններ",
+ minute: "մեկ րոպե",
+ minutes: "%d րոպե",
+ hour: "մեկ ժամ",
+ hours: "%d ժամ",
+ day: "մեկ օր",
+ days: "%d օր",
+ month: "մեկ ամիս",
+ months: "%d ամիս",
+ year: "մեկ տարի",
+ years: "%d տարի"
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.id.js b/website/lang/timeago/jquery.timeago.id.js
new file mode 100644
index 0000000..ca530cc
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.id.js
@@ -0,0 +1,29 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Indonesian
+ jQuery.timeago.settings.strings = {
+ prefixAgo: null,
+ prefixFromNow: null,
+ suffixAgo: "yang lalu",
+ suffixFromNow: "dari sekarang",
+ seconds: "kurang dari semenit",
+ minute: "sekitar satu menit",
+ minutes: "%d menit",
+ hour: "sekitar sejam",
+ hours: "sekitar %d jam",
+ day: "sehari",
+ days: "%d hari",
+ month: "sekitar sebulan",
+ months: "%d bulan",
+ year: "sekitar setahun",
+ years: "%d tahun"
+ };
+}));
+
diff --git a/website/lang/timeago/jquery.timeago.is.js b/website/lang/timeago/jquery.timeago.is.js
new file mode 100644
index 0000000..e3d4b1f
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.is.js
@@ -0,0 +1,29 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ jQuery.timeago.settings.strings = {
+ prefixAgo: "fyrir",
+ prefixFromNow: "eftir",
+ suffixAgo: "síðan",
+ suffixFromNow: null,
+ seconds: "minna en mínútu",
+ minute: "mínútu",
+ minutes: "%d mínútum",
+ hour: "klukkutíma",
+ hours: "um %d klukkutímum",
+ day: "degi",
+ days: "%d dögum",
+ month: "mánuði",
+ months: "%d mánuðum",
+ year: "ári",
+ years: "%d árum",
+ wordSeparator: " ",
+ numbers: []
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.it.js b/website/lang/timeago/jquery.timeago.it.js
new file mode 100644
index 0000000..e1cac84
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.it.js
@@ -0,0 +1,26 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Italian
+ jQuery.timeago.settings.strings = {
+ suffixAgo: "fa",
+ suffixFromNow: "da ora",
+ seconds: "meno di un minuto",
+ minute: "circa un minuto",
+ minutes: "%d minuti",
+ hour: "circa un'ora",
+ hours: "circa %d ore",
+ day: "un giorno",
+ days: "%d giorni",
+ month: "circa un mese",
+ months: "%d mesi",
+ year: "circa un anno",
+ years: "%d anni"
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.ja.js b/website/lang/timeago/jquery.timeago.ja.js
new file mode 100644
index 0000000..30f3308
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.ja.js
@@ -0,0 +1,29 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Japanese
+ jQuery.timeago.settings.strings = {
+ prefixAgo: "",
+ prefixFromNow: "今から",
+ suffixAgo: "前",
+ suffixFromNow: "後",
+ seconds: "1 分未満",
+ minute: "約 1 分",
+ minutes: "%d 分",
+ hour: "約 1 時間",
+ hours: "約 %d 時間",
+ day: "約 1 日",
+ days: "約 %d 日",
+ month: "約 1 ヶ月",
+ months: "約 %d ヶ月",
+ year: "約 1 年",
+ years: "約 %d 年",
+ wordSeparator: ""
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.jv.js b/website/lang/timeago/jquery.timeago.jv.js
new file mode 100644
index 0000000..0344053
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.jv.js
@@ -0,0 +1,28 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Javanesse (Boso Jowo)
+ jQuery.timeago.settings.strings = {
+ prefixAgo: null,
+ prefixFromNow: null,
+ suffixAgo: "kepungkur",
+ suffixFromNow: "seko saiki",
+ seconds: "kurang seko sakmenit",
+ minute: "kurang luwih sakmenit",
+ minutes: "%d menit",
+ hour: "kurang luwih sakjam",
+ hours: "kurang luwih %d jam",
+ day: "sedina",
+ days: "%d dina",
+ month: "kurang luwih sewulan",
+ months: "%d wulan",
+ year: "kurang luwih setahun",
+ years: "%d tahun"
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.ko.js b/website/lang/timeago/jquery.timeago.ko.js
new file mode 100644
index 0000000..23d1d37
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.ko.js
@@ -0,0 +1,31 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Korean
+ jQuery.timeago.settings.strings = {
+ prefixAgo: null,
+ prefixFromNow: null,
+ suffixAgo: "전",
+ suffixFromNow: "후",
+ seconds: "1분",
+ minute: "약 1분",
+ minutes: "%d분",
+ hour: "약 1시간",
+ hours: "약 %d시간",
+ day: "하루",
+ days: "%d일",
+ month: "약 1개월",
+ months: "%d개월",
+ year: "약 1년",
+ years: "%d년",
+ wordSeparator: " ",
+ numbers: []
+ };
+}));
+
diff --git a/website/lang/timeago/jquery.timeago.ky.js b/website/lang/timeago/jquery.timeago.ky.js
new file mode 100644
index 0000000..58dba29
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.ky.js
@@ -0,0 +1,42 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Russian
+ function numpf(n, f, s, t) {
+ // f - 1, 21, 31, ...
+ // s - 2-4, 22-24, 32-34 ...
+ // t - 5-20, 25-30, ...
+ var n10 = n % 10;
+ if ( (n10 === 1) && ( (n === 1) || (n > 20) ) ) {
+ return f;
+ } else if ( (n10 > 1) && (n10 < 5) && ( (n > 20) || (n < 10) ) ) {
+ return s;
+ } else {
+ return t;
+ }
+ }
+
+ jQuery.timeago.settings.strings = {
+ prefixAgo: null,
+ prefixFromNow: "через",
+ suffixAgo: "мурун",
+ suffixFromNow: null,
+ seconds: "1 минуттан аз",
+ minute: "минута",
+ minutes: function(value) { return numpf(value, "%d минута", "%d минута", "%d минут"); },
+ hour: "саат",
+ hours: function(value) { return numpf(value, "%d саат", "%d саат", "%d саат"); },
+ day: "күн",
+ days: function(value) { return numpf(value, "%d күн", "%d күн", "%d күн"); },
+ month: "ай",
+ months: function(value) { return numpf(value, "%d ай", "%d ай", "%d ай"); },
+ year: "жыл",
+ years: function(value) { return numpf(value, "%d жыл", "%d жыл", "%d жыл"); }
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.lt.js b/website/lang/timeago/jquery.timeago.lt.js
new file mode 100644
index 0000000..2079fcc
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.lt.js
@@ -0,0 +1,30 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ //Lithuanian
+ jQuery.timeago.settings.strings = {
+ prefixAgo: "prieš",
+ prefixFromNow: null,
+ suffixAgo: null,
+ suffixFromNow: "nuo dabar",
+ seconds: "%d sek.",
+ minute: "min.",
+ minutes: "%d min.",
+ hour: "val.",
+ hours: "%d val.",
+ day: "1 d.",
+ days: "%d d.",
+ month: "mėn.",
+ months: "%d mėn.",
+ year: "metus",
+ years: "%d metus",
+ wordSeparator: " ",
+ numbers: []
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.lv.js b/website/lang/timeago/jquery.timeago.lv.js
new file mode 100644
index 0000000..855d1a4
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.lv.js
@@ -0,0 +1,30 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ //Latvian
+ jQuery.timeago.settings.strings = {
+ prefixAgo: "pirms",
+ prefixFromNow: null,
+ suffixAgo: null,
+ suffixFromNow: "no šī brīža",
+ seconds: "%d sek.",
+ minute: "min.",
+ minutes: "%d min.",
+ hour: "st.",
+ hours: "%d st.",
+ day: "1 d.",
+ days: "%d d.",
+ month: "mēnesis.",
+ months: "%d mēnesis.",
+ year: "gads",
+ years: "%d gads",
+ wordSeparator: " ",
+ numbers: []
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.mk.js b/website/lang/timeago/jquery.timeago.mk.js
new file mode 100644
index 0000000..301a5da
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.mk.js
@@ -0,0 +1,30 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Macedonian
+ (function() {
+ jQuery.timeago.settings.strings={
+ prefixAgo: "пред",
+ prefixFromNow: "за",
+ suffixAgo: null,
+ suffixFromNow: null,
+ seconds: "%d секунди",
+ minute: "%d минута",
+ minutes: "%d минути",
+ hour: "%d час",
+ hours: "%d часа",
+ day: "%d ден",
+ days: "%d денови" ,
+ month: "%d месец",
+ months: "%d месеци",
+ year: "%d година",
+ years: "%d години"
+ };
+ })();
+}));
diff --git a/website/lang/timeago/jquery.timeago.nl.js b/website/lang/timeago/jquery.timeago.nl.js
new file mode 100644
index 0000000..2c5de89
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.nl.js
@@ -0,0 +1,30 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Dutch
+ jQuery.timeago.settings.strings = {
+ prefixAgo: null,
+ prefixFromNow: "over",
+ suffixAgo: "geleden",
+ suffixFromNow: null,
+ seconds: "minder dan een minuut",
+ minute: "ongeveer een minuut",
+ minutes: "%d minuten",
+ hour: "ongeveer een uur",
+ hours: "ongeveer %d uur",
+ day: "een dag",
+ days: "%d dagen",
+ month: "ongeveer een maand",
+ months: "%d maanden",
+ year: "ongeveer een jaar",
+ years: "%d jaar",
+ wordSeparator: " ",
+ numbers: []
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.no.js b/website/lang/timeago/jquery.timeago.no.js
new file mode 100644
index 0000000..c896337
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.no.js
@@ -0,0 +1,28 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Norwegian
+ jQuery.timeago.settings.strings = {
+ prefixAgo: "for",
+ prefixFromNow: "om",
+ suffixAgo: "siden",
+ suffixFromNow: "",
+ seconds: "mindre enn et minutt",
+ minute: "ca. et minutt",
+ minutes: "%d minutter",
+ hour: "ca. en time",
+ hours: "ca. %d timer",
+ day: "en dag",
+ days: "%d dager",
+ month: "ca. en måned",
+ months: "%d måneder",
+ year: "ca. et år",
+ years: "%d år"
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.pl.js b/website/lang/timeago/jquery.timeago.pl.js
new file mode 100644
index 0000000..4842784
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.pl.js
@@ -0,0 +1,39 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Polish
+ function numpf(n, s, t) {
+ // s - 2-4, 22-24, 32-34 ...
+ // t - 5-21, 25-31, ...
+ var n10 = n % 10;
+ if ( (n10 > 1) && (n10 < 5) && ( (n > 20) || (n < 10) ) ) {
+ return s;
+ } else {
+ return t;
+ }
+ }
+
+ jQuery.timeago.settings.strings = {
+ prefixAgo: null,
+ prefixFromNow: "za",
+ suffixAgo: "temu",
+ suffixFromNow: null,
+ seconds: "mniej niż minutę",
+ minute: "minutę",
+ minutes: function(value) { return numpf(value, "%d minuty", "%d minut"); },
+ hour: "godzinę",
+ hours: function(value) { return numpf(value, "%d godziny", "%d godzin"); },
+ day: "dzień",
+ days: "%d dni",
+ month: "miesiąc",
+ months: function(value) { return numpf(value, "%d miesiące", "%d miesięcy"); },
+ year: "rok",
+ years: function(value) { return numpf(value, "%d lata", "%d lat"); }
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.pt-br.js b/website/lang/timeago/jquery.timeago.pt-br.js
new file mode 100644
index 0000000..a8701a8
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.pt-br.js
@@ -0,0 +1,28 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Brazilian Portuguese
+ jQuery.timeago.settings.strings = {
+ prefixAgo: "há",
+ prefixFromNow: "em",
+ suffixAgo: null,
+ suffixFromNow: null,
+ seconds: "alguns segundos",
+ minute: "um minuto",
+ minutes: "%d minutos",
+ hour: "uma hora",
+ hours: "%d horas",
+ day: "um dia",
+ days: "%d dias",
+ month: "um mês",
+ months: "%d meses",
+ year: "um ano",
+ years: "%d anos"
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.pt.js b/website/lang/timeago/jquery.timeago.pt.js
new file mode 100644
index 0000000..13791a0
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.pt.js
@@ -0,0 +1,26 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Portuguese
+ jQuery.timeago.settings.strings = {
+ suffixAgo: "atrás",
+ suffixFromNow: "a partir de agora",
+ seconds: "menos de um minuto",
+ minute: "cerca de um minuto",
+ minutes: "%d minutos",
+ hour: "cerca de uma hora",
+ hours: "cerca de %d horas",
+ day: "um dia",
+ days: "%d dias",
+ month: "cerca de um mês",
+ months: "%d meses",
+ year: "cerca de um ano",
+ years: "%d anos"
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.ro.js b/website/lang/timeago/jquery.timeago.ro.js
new file mode 100644
index 0000000..fe59db9
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.ro.js
@@ -0,0 +1,29 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Romanian
+ jQuery.timeago.settings.strings = {
+ prefixAgo: "acum",
+ prefixFromNow: "in timp de",
+ suffixAgo: "",
+ suffixFromNow: "",
+ seconds: "mai putin de un minut",
+ minute: "un minut",
+ minutes: "%d minute",
+ hour: "o ora",
+ hours: "%d ore",
+ day: "o zi",
+ days: "%d zile",
+ month: "o luna",
+ months: "%d luni",
+ year: "un an",
+ years: "%d ani"
+ };
+}));
+
diff --git a/website/lang/timeago/jquery.timeago.rs.js b/website/lang/timeago/jquery.timeago.rs.js
new file mode 100644
index 0000000..b9e5188
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.rs.js
@@ -0,0 +1,54 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Serbian
+ var numpf = function (n, f, s, t) {
+ var n10;
+ n10 = n % 10;
+ if (n10 === 1 && (n === 1 || n > 20)) {
+ return f;
+ } else if (n10 > 1 && n10 < 5 && (n > 20 || n < 10)) {
+ return s;
+ } else {
+ return t;
+ }
+ };
+
+ jQuery.timeago.settings.strings = {
+ prefixAgo: "pre",
+ prefixFromNow: "za",
+ suffixAgo: null,
+ suffixFromNow: null,
+ second: "sekund",
+ seconds: function (value) {
+ return numpf(value, "%d sekund", "%d sekunde", "%d sekundi");
+ },
+ minute: "oko minut",
+ minutes: function (value) {
+ return numpf(value, "%d minut", "%d minuta", "%d minuta");
+ },
+ hour: "oko jedan sat",
+ hours: function (value) {
+ return numpf(value, "%d sat", "%d sata", "%d sati");
+ },
+ day: "jedan dan",
+ days: function (value) {
+ return numpf(value, "%d dan", "%d dana", "%d dana");
+ },
+ month: "mesec dana",
+ months: function (value) {
+ return numpf(value, "%d mesec", "%d meseca", "%d meseci");
+ },
+ year: "godinu dana",
+ years: function (value) {
+ return numpf(value, "%d godinu", "%d godine", "%d godina");
+ },
+ wordSeparator: " "
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.ru.js b/website/lang/timeago/jquery.timeago.ru.js
new file mode 100644
index 0000000..4ff3f8d
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.ru.js
@@ -0,0 +1,43 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Russian
+ function numpf(n, f, s, t) {
+ // f - 1, 21, 31, ...
+ // s - 2-4, 22-24, 32-34 ...
+ // t - 5-20, 25-30, ...
+ n = n % 100;
+ var n10 = n % 10;
+ if ( (n10 === 1) && ( (n === 1) || (n > 20) ) ) {
+ return f;
+ } else if ( (n10 > 1) && (n10 < 5) && ( (n > 20) || (n < 10) ) ) {
+ return s;
+ } else {
+ return t;
+ }
+ }
+
+ jQuery.timeago.settings.strings = {
+ prefixAgo: null,
+ prefixFromNow: "через",
+ suffixAgo: "назад",
+ suffixFromNow: null,
+ seconds: "меньше минуты",
+ minute: "минуту",
+ minutes: function(value) { return numpf(value, "%d минуту", "%d минуты", "%d минут"); },
+ hour: "час",
+ hours: function(value) { return numpf(value, "%d час", "%d часа", "%d часов"); },
+ day: "день",
+ days: function(value) { return numpf(value, "%d день", "%d дня", "%d дней"); },
+ month: "месяц",
+ months: function(value) { return numpf(value, "%d месяц", "%d месяца", "%d месяцев"); },
+ year: "год",
+ years: function(value) { return numpf(value, "%d год", "%d года", "%d лет"); }
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.rw.js b/website/lang/timeago/jquery.timeago.rw.js
new file mode 100644
index 0000000..50119e1
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.rw.js
@@ -0,0 +1,30 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Kinyarwanda
+ jQuery.timeago.settings.strings = {
+ prefixAgo: "hashize",
+ prefixFromNow: "mu",
+ suffixAgo: null,
+ suffixFromNow: null,
+ seconds: "amasegonda macye",
+ minute: "umunota",
+ minutes: "iminota %d",
+ hour: "isaha",
+ hours: "amasaha %d",
+ day: "umunsi",
+ days: "iminsi %d",
+ month: "ukwezi",
+ months: "amezi %d",
+ year: "umwaka",
+ years: "imyaka %d",
+ wordSeparator: " ",
+ numbers: []
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.si.js b/website/lang/timeago/jquery.timeago.si.js
new file mode 100644
index 0000000..6fa215e
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.si.js
@@ -0,0 +1,28 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Sinhalese (SI)
+ jQuery.timeago.settings.strings = {
+ prefixAgo: null,
+ prefixFromNow: null,
+ suffixAgo: "පෙර",
+ suffixFromNow: "පසුව",
+ seconds: "තත්පර කිහිපයකට",
+ minute: "මිනිත්තුවකට පමණ",
+ minutes: "මිනිත්තු %d කට",
+ hour: "පැයක් පමණ ",
+ hours: "පැය %d කට පමණ",
+ day: "දවසක ට",
+ days: "දවස් %d කට ",
+ month: "මාසයක් පමණ",
+ months: "මාස %d කට",
+ year: "වසරක් පමණ",
+ years: "වසරක් %d කට පමණ"
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.sk.js b/website/lang/timeago/jquery.timeago.sk.js
new file mode 100644
index 0000000..e28ab7c
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.sk.js
@@ -0,0 +1,34 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Slovak
+ (function() {
+ function f(n, d, a) {
+ return a[d>=0 ? 0 : a.length===2 || n<5 ? 1 : 2];
+ }
+
+ jQuery.timeago.settings.strings = {
+ prefixAgo: 'pred',
+ prefixFromNow: 'o',
+ suffixAgo: null,
+ suffixFromNow: null,
+ seconds: function(n, d) {return f(n, d, ['menej ako minútou', 'menej ako minútu']);},
+ minute: function(n, d) {return f(n, d, ['minútou', 'minútu']);},
+ minutes: function(n, d) {return f(n, d, ['%d minútami', '%d minúty', '%d minút']);},
+ hour: function(n, d) {return f(n, d, ['hodinou', 'hodinu']);},
+ hours: function(n, d) {return f(n, d, ['%d hodinami', '%d hodiny', '%d hodín']);},
+ day: function(n, d) {return f(n, d, ['%d dňom', '%d deň']);},
+ days: function(n, d) {return f(n, d, ['%d dňami', '%d dni', '%d dní']);},
+ month: function(n, d) {return f(n, d, ['%d mesiacom', '%d mesiac']);},
+ months: function(n, d) {return f(n, d, ['%d mesiacmi', '%d mesiace', '%d mesiacov']);},
+ year: function(n, d) {return f(n, d, ['%d rokom', '%d rok']);},
+ years: function(n, d) {return f(n, d, ['%d rokmi', '%d roky', '%d rokov']);}
+ };
+ })();
+}));
diff --git a/website/lang/timeago/jquery.timeago.sl.js b/website/lang/timeago/jquery.timeago.sl.js
new file mode 100644
index 0000000..9f0329a
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.sl.js
@@ -0,0 +1,46 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Slovenian with support for dual
+ var numpf = function (n, a) {
+ return a[n%100===1 ? 1 : n%100===2 ? 2 : n%100===3 || n%100===4 ? 3 : 0];
+ };
+
+ jQuery.timeago.settings.strings = {
+ prefixAgo: null,
+ prefixFromNow: "čez",
+ suffixAgo: "nazaj",
+ suffixFromNow: null,
+ second: "sekundo",
+ seconds: function (value) {
+ return numpf(value, ["%d sekund", "%d sekundo", "%d sekundi", "%d sekunde"]);
+ },
+ minute: "minuto",
+ minutes: function (value) {
+ return numpf(value, ["%d minut", "%d minuto", "%d minuti", "%d minute"]);
+ },
+ hour: "eno uro",
+ hours: function (value) {
+ return numpf(value, ["%d ur", "%d uro", "%d uri", "%d ure"]);
+ },
+ day: "en dan",
+ days: function (value) {
+ return numpf(value, ["%d dni", "%d dan", "%d dneva", "%d dni"]);
+ },
+ month: "en mesec",
+ months: function (value) {
+ return numpf(value, ["%d mesecev", "%d mesec", "%d meseca", "%d mesece"]);
+ },
+ year: "eno leto",
+ years: function (value) {
+ return numpf(value, ["%d let", "%d leto", "%d leti", "%d leta"]);
+ },
+ wordSeparator: " "
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.sq.js b/website/lang/timeago/jquery.timeago.sq.js
new file mode 100644
index 0000000..cb8ae70
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.sq.js
@@ -0,0 +1,26 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Albanian SQ
+ jQuery.timeago.settings.strings = {
+ suffixAgo: "më parë",
+ suffixFromNow: "tani",
+ seconds: "më pak se një minutë",
+ minute: "rreth një minutë",
+ minutes: "%d minuta",
+ hour: "rreth një orë",
+ hours: "rreth %d orë",
+ day: "një ditë",
+ days: "%d ditë",
+ month: "rreth një muaj",
+ months: "%d muaj",
+ year: "rreth një vit",
+ years: "%d vjet"
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.sr.js b/website/lang/timeago/jquery.timeago.sr.js
new file mode 100644
index 0000000..bd1efe7
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.sr.js
@@ -0,0 +1,54 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Serbian
+ var numpf = function (n, f, s, t) {
+ var n10;
+ n10 = n % 10;
+ if (n10 === 1 && (n === 1 || n > 20)) {
+ return f;
+ } else if (n10 > 1 && n10 < 5 && (n > 20 || n < 10)) {
+ return s;
+ } else {
+ return t;
+ }
+ };
+
+ jQuery.timeago.settings.strings = {
+ prefixAgo: "пре",
+ prefixFromNow: "за",
+ suffixAgo: null,
+ suffixFromNow: null,
+ second: "секунд",
+ seconds: function (value) {
+ return numpf(value, "%d секунд", "%d секунде", "%d секунди");
+ },
+ minute: "један минут",
+ minutes: function (value) {
+ return numpf(value, "%d минут", "%d минута", "%d минута");
+ },
+ hour: "један сат",
+ hours: function (value) {
+ return numpf(value, "%d сат", "%d сата", "%d сати");
+ },
+ day: "један дан",
+ days: function (value) {
+ return numpf(value, "%d дан", "%d дана", "%d дана");
+ },
+ month: "месец дана",
+ months: function (value) {
+ return numpf(value, "%d месец", "%d месеца", "%d месеци");
+ },
+ year: "годину дана",
+ years: function (value) {
+ return numpf(value, "%d годину", "%d године", "%d година");
+ },
+ wordSeparator: " "
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.sv.js b/website/lang/timeago/jquery.timeago.sv.js
new file mode 100644
index 0000000..caf09db
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.sv.js
@@ -0,0 +1,28 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Swedish
+ jQuery.timeago.settings.strings = {
+ prefixAgo: "för",
+ prefixFromNow: "om",
+ suffixAgo: "sedan",
+ suffixFromNow: "",
+ seconds: "mindre än en minut",
+ minute: "ungefär en minut",
+ minutes: "%d minuter",
+ hour: "ungefär en timme",
+ hours: "ungefär %d timmar",
+ day: "en dag",
+ days: "%d dagar",
+ month: "ungefär en månad",
+ months: "%d månader",
+ year: "ungefär ett år",
+ years: "%d år"
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.th.js b/website/lang/timeago/jquery.timeago.th.js
new file mode 100644
index 0000000..23d59d4
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.th.js
@@ -0,0 +1,30 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Thai
+ jQuery.timeago.settings.strings = {
+ prefixAgo: null,
+ prefixFromNow: null,
+ suffixAgo: "ที่แล้ว",
+ suffixFromNow: "จากตอนนี้",
+ seconds: "น้อยกว่าหนึ่งนาที",
+ minute: "ประมาณหนึ่งนาที",
+ minutes: "%d นาที",
+ hour: "ประมาณหนึ่งชั่วโมง",
+ hours: "ประมาณ %d ชั่วโมง",
+ day: "หนึ่งวัน",
+ days: "%d วัน",
+ month: "ประมาณหนึ่งเดือน",
+ months: "%d เดือน",
+ year: "ประมาณหนึ่งปี",
+ years: "%d ปี",
+ wordSeparator: "",
+ numbers: []
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.tr.js b/website/lang/timeago/jquery.timeago.tr.js
new file mode 100644
index 0000000..8e0d2d4
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.tr.js
@@ -0,0 +1,26 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Turkish
+ jQuery.timeago.settings.strings = {
+ suffixAgo: 'önce',
+ suffixFromNow: null,
+ seconds: 'birkaç saniye',
+ minute: '1 dakika',
+ minutes: '%d dakika',
+ hour: '1 saat',
+ hours: '%d saat',
+ day: '1 gün',
+ days: '%d gün',
+ month: '1 ay',
+ months: '%d ay',
+ year: '1 yıl',
+ years: '%d yıl'
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.uk.js b/website/lang/timeago/jquery.timeago.uk.js
new file mode 100644
index 0000000..489963b
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.uk.js
@@ -0,0 +1,42 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Ukrainian
+ function numpf(n, f, s, t) {
+ // f - 1, 21, 31, ...
+ // s - 2-4, 22-24, 32-34 ...
+ // t - 5-20, 25-30, ...
+ var n10 = n % 10;
+ if ( (n10 === 1) && ( (n === 1) || (n > 20) ) ) {
+ return f;
+ } else if ( (n10 > 1) && (n10 < 5) && ( (n > 20) || (n < 10) ) ) {
+ return s;
+ } else {
+ return t;
+ }
+ }
+
+ jQuery.timeago.settings.strings = {
+ prefixAgo: null,
+ prefixFromNow: "через",
+ suffixAgo: "тому",
+ suffixFromNow: null,
+ seconds: "менше хвилини",
+ minute: "хвилина",
+ minutes: function(value) { return numpf(value, "%d хвилина", "%d хвилини", "%d хвилин"); },
+ hour: "година",
+ hours: function(value) { return numpf(value, "%d година", "%d години", "%d годин"); },
+ day: "день",
+ days: function(value) { return numpf(value, "%d день", "%d дні", "%d днів"); },
+ month: "місяць",
+ months: function(value) { return numpf(value, "%d місяць", "%d місяці", "%d місяців"); },
+ year: "рік",
+ years: function(value) { return numpf(value, "%d рік", "%d роки", "%d років"); }
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.ur.js b/website/lang/timeago/jquery.timeago.ur.js
new file mode 100644
index 0000000..9d0cd40
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.ur.js
@@ -0,0 +1,30 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Urdu
+ jQuery.timeago.settings.strings = {
+ prefixAgo: null,
+ prefixFromNow: null,
+ suffixAgo: "پہلے",
+ suffixFromNow: "اب سے",
+ seconds: "کچھ سیکنڈز",
+ minute: "تقریباً ایک منٹ",
+ minutes: "%d منٹ",
+ hour: "تقریباً ایک گھنٹہ",
+ hours: "تقریباً %d گھنٹے",
+ day: "ایک دن",
+ days: "%d دن",
+ month: "تقریباً ایک مہینہ",
+ months: "%d مہینے",
+ year: "تقریباً ایک سال",
+ years: "%d سال",
+ wordSeparator: " ",
+ numbers: []
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.uz.js b/website/lang/timeago/jquery.timeago.uz.js
new file mode 100644
index 0000000..f4ce8b3
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.uz.js
@@ -0,0 +1,29 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ //Uzbek
+ jQuery.timeago.settings.strings = {
+ prefixAgo: null,
+ prefixFromNow: "keyin",
+ suffixAgo: "avval",
+ suffixFromNow: null,
+ seconds: "bir necha soniya",
+ minute: "1 daqiqa",
+ minutes: function(value) { return "%d daqiqa"; },
+ hour: "1 soat",
+ hours: function(value) { return "%d soat"; },
+ day: "1 kun",
+ days: function(value) { return "%d kun"; },
+ month: "1 oy",
+ months: function(value) { return "%d oy"; },
+ year: "1 yil",
+ years: function(value) { return "%d yil"; },
+ wordSeparator: " "
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.vi.js b/website/lang/timeago/jquery.timeago.vi.js
new file mode 100644
index 0000000..30f592a
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.vi.js
@@ -0,0 +1,30 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Vietnamese
+ jQuery.timeago.settings.strings = {
+ prefixAgo: 'cách đây',
+ prefixFromNow: null,
+ suffixAgo: null,
+ suffixFromNow: "trước",
+ seconds: "chưa đến một phút",
+ minute: "khoảng một phút",
+ minutes: "%d phút",
+ hour: "khoảng một tiếng",
+ hours: "khoảng %d tiếng",
+ day: "một ngày",
+ days: "%d ngày",
+ month: "khoảng một tháng",
+ months: "%d tháng",
+ year: "khoảng một năm",
+ years: "%d năm",
+ wordSeparator: " ",
+ numbers: []
+ };
+}));
diff --git a/website/lang/timeago/jquery.timeago.zh-CN.js b/website/lang/timeago/jquery.timeago.zh-CN.js
new file mode 100644
index 0000000..c21a287
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.zh-CN.js
@@ -0,0 +1,31 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Simplified Chinese
+ jQuery.timeago.settings.strings = {
+ prefixAgo: null,
+ prefixFromNow: null,
+ suffixAgo: "之前",
+ suffixFromNow: "之后",
+ seconds: "不到1分钟",
+ minute: "大约1分钟",
+ minutes: "%d分钟",
+ hour: "大约1小时",
+ hours: "大约%d小时",
+ day: "1天",
+ days: "%d天",
+ month: "大约1个月",
+ months: "%d月",
+ year: "大约1年",
+ years: "%d年",
+ numbers: [],
+ wordSeparator: ""
+ };
+}));
+
diff --git a/website/lang/timeago/jquery.timeago.zh-TW.js b/website/lang/timeago/jquery.timeago.zh-TW.js
new file mode 100644
index 0000000..15f5626
--- /dev/null
+++ b/website/lang/timeago/jquery.timeago.zh-TW.js
@@ -0,0 +1,30 @@
+(function (factory) {
+ if (typeof define === 'function' && define.amd) {
+ define(['jquery'], factory);
+ } else if (typeof module === 'object' && typeof module.exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function (jQuery) {
+ // Traditional Chinese, zh-tw
+ jQuery.timeago.settings.strings = {
+ prefixAgo: null,
+ prefixFromNow: null,
+ suffixAgo: "之前",
+ suffixFromNow: "之後",
+ seconds: "不到1分鐘",
+ minute: "大約1分鐘",
+ minutes: "%d分鐘",
+ hour: "大約1小時",
+ hours: "%d小時",
+ day: "大約1天",
+ days: "%d天",
+ month: "大約1個月",
+ months: "%d個月",
+ year: "大約1年",
+ years: "%d年",
+ numbers: [],
+ wordSeparator: ""
+ };
+}));
diff --git a/website/lang/zh-CN.json b/website/lang/zh-CN.json
new file mode 100644
index 0000000..4a6a00a
--- /dev/null
+++ b/website/lang/zh-CN.json
@@ -0,0 +1,169 @@
+{
+ "miningPool": "矿池",
+ "dashboard": "仪表盘",
+ "gettingStarted": "挖矿指导",
+ "yourStats": "挖矿数据",
+ "poolBlocks": "池中区块",
+ "settings": "设置",
+ "faq": "常见问题",
+ "telegram": "Telegram群组",
+ "discord": "Discord",
+ "contactUs": "联系方式",
+
+ "network": "全网",
+ "pool": "矿池",
+ "you": "用户",
+ "statsUpdated": "数据更新",
+
+ "poolHashrate": "矿池算力",
+ "currentEffort": "当前效益",
+ "networkHashrate": "全网算力",
+ "networkDifficulty": "难度",
+ "blockchainHeight": "区块高度",
+ "networkLastReward": "上次收益",
+ "poolMiners": "在线矿工",
+ "poolFee": "矿池税",
+
+ "minerStats": "用户数据及支付历史",
+ "workerStats": "设备数据",
+ "miner": "矿工",
+ "miners": "矿工",
+ "minersCount": "矿工数",
+ "workers": "挖矿设备",
+ "workersCount": "设备数",
+ "workerName": "设备名",
+ "lastHash": "上次提交",
+ "hashRate": "算力",
+ "currentHashRate": "当前算力",
+ "lastShare": "上次提交",
+ "totalHashes": "总提交",
+ "top10miners": "前十矿工",
+
+ "blocksTotal": "已发现区块",
+ "blockSolvedTime": "区块发现用时",
+ "blocksMaturityCount": "成熟要求",
+ "efficiency": "效率",
+ "averageLuck": "平均幸运值",
+ "timeFound": "发现时间",
+ "reward": "收益",
+ "height": "高度",
+ "difficulty": "难度",
+ "blockHash": "区块Hash",
+ "effort": "功夫",
+ "blocksFoundLast24": "过去24小时内发现区块",
+ "blocksFoundLastDays": "过去{DAYS}天中发现区块",
+ "propSoloConnectedMiners": "成比例的 / 独奏 连接的 矿工",
+
+ "payments": "支付",
+ "paymentsHistory": "支付历史",
+ "paymentsTotal": "总支付",
+ "paymentsMinimum": "最小支付额",
+ "paymentsInterval": "支付周期",
+ "paymentsDenomination": "面额单位",
+ "timeSent": "Time Sent",
+ "transactionHash": "交易Hash",
+ "amount": "数额",
+ "fee": "费用",
+ "mixin": "Mixin",
+ "payees": "收款人",
+ "pendingBalance": "处理中余额",
+ "totalPaid": "总计支付",
+ "payoutEstimate": "当前支付估计",
+ "paymentSummarySingle": "在%DATE%您收到%AMOUNT%",
+ "paymentSummaryMulti": "在%DATE%,通过%COUNT%笔支付,您收到%AMOUNT%",
+
+ "connectionDetails": "连接信息",
+ "miningPoolHost": "矿池地址",
+ "cnAlgorithm": "算法",
+ "username": "用户名",
+ "usernameDesc": "这是你的钱包地址",
+ "paymentId": "交易所支付ID",
+ "fixedDiff": "固定难度",
+ "address": "地址",
+ "addrPaymentId": "交易ID",
+ "addrDiff": "难度",
+ "password": "密码",
+ "passwordDesc": "这是你的设备名",
+ "emailNotifications": "邮件提醒",
+ "miningPorts": "挖矿端口",
+ "port": "端口",
+ "portDiff": "初始难度",
+ "description": "介绍",
+ "miningApps": "挖矿应用",
+ "configGeneratorDesc": "生成您定制的配置",
+ "addressField": "钱包地址",
+ "paymentIdField": "为交易所的交易ID (可选)",
+ "fixedDiffField": "固定难度 (可选)",
+ "workerNameField": "设备名",
+ "emailNotificationsField": "邮件提醒 (可选)",
+ "generateConfig": "生成配置",
+ "appName": "应用名",
+ "appArch": "架构平台",
+ "appDesc": "特征",
+ "download": "下载",
+ "showConfig": "了解更多",
+
+ "market": "市场计算器",
+ "loadingMarket": "加载市场价格",
+ "priceIn": "价格",
+ "hashPer": "Hash/",
+ "estimateProfit": "预计挖矿收益",
+ "enterYourHashrate": "确认您的算力",
+ "perDay": "每天",
+
+ "verificationFields": "验证字段",
+ "minerVerification": "为了确保钱包地址是您的,我们要求您提供您的矿工使用的IP地址之一.",
+ "minerAddress": "矿工地址",
+ "minerIP": "矿工IP地址",
+ "setMinimumPayout": "设置您的最低支付水平",
+ "minerMinPayout": "如果你喜欢比池的默认值更高的支付水平,那么这是你可以为你的矿工改变它。您在此处显示的金额将成为您的地址的最低付款金额.",
+ "minimumPayout": "最低付款金额",
+ "enableEmailNotifications": "启用电子邮件通知",
+ "minerEmailNotify": "当发现一个区块并且每当支付发生时,该池将发送电子邮件通知.",
+ "emailAddress": "邮箱地址",
+ "noMinerAddress": "没有指定矿工地址",
+ "noMinerIP": "没有指定矿工IP地址",
+ "noPayoutLevel": "没有指定最小付款金额",
+ "noEmail": "没有指定邮箱地址",
+ "invalidEmail": "指定的电子邮件地址无效",
+ "minerPayoutSet": "完成! 您的最低支出水平已设定",
+ "notificationEnabled": "完成! 电子邮件通知已启用",
+ "notificationDisabled": "完成! 电子邮件通知已被禁用",
+
+ "enterYourAddress": "输入您的地址",
+ "enterYourMinerIP": "您的矿工使用的IP地址 (任一)",
+ "enterYourEmail": "输入你的电子邮箱地址 (可选)",
+
+ "lookup": "查找",
+ "searching": "搜索中...",
+ "loadMore": "加载更多",
+ "set": "设置",
+ "enable": "允许",
+ "disable": "禁止",
+
+ "status": "状态",
+ "updated": "已更新:",
+ "source": "源:",
+ "error": "错误:",
+
+ "na": "无",
+ "estimated": "预计",
+ "never": "从不",
+ "second": "秒",
+ "seconds": "秒",
+ "minute": "分",
+ "minutes": "分",
+ "hour": "小时",
+ "hours": "小时",
+ "day": "天",
+ "days": "天",
+ "week": "周",
+ "weeks": "周",
+ "month": "月",
+ "months": "月",
+ "year": "年",
+ "years": "年",
+
+ "poweredBy": "驱动源于",
+ "openSource": "开源于"
+}
diff --git a/website/pages/admin/monitoring.html b/website/pages/admin/monitoring.html
new file mode 100644
index 0000000..f949c3e
--- /dev/null
+++ b/website/pages/admin/monitoring.html
@@ -0,0 +1,177 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/website/pages/admin/ports.html b/website/pages/admin/ports.html
new file mode 100644
index 0000000..72857fa
--- /dev/null
+++ b/website/pages/admin/ports.html
@@ -0,0 +1,85 @@
+
Current Ports Usage (0 users)
+
+
+
+
+
+
+
+
+
+
+ Port
+ Connected Users
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/website/pages/admin/statistics.html b/website/pages/admin/statistics.html
new file mode 100644
index 0000000..d683aaa
--- /dev/null
+++ b/website/pages/admin/statistics.html
@@ -0,0 +1,204 @@
+
Pool Statistics
+
+
+
+
+
+
+
+
diff --git a/website/pages/admin/tools.html b/website/pages/admin/tools.html
new file mode 100644
index 0000000..7ebd623
--- /dev/null
+++ b/website/pages/admin/tools.html
@@ -0,0 +1,124 @@
+
+
Test E-Mail notifications
+
+
+
+
+
+
+
+
+
+ Send test
+
+
+
+
+
+
+
Test Telegram Channel notifications
+
+
+
+
diff --git a/website/pages/admin/userslist.html b/website/pages/admin/userslist.html
new file mode 100644
index 0000000..b76edfc
--- /dev/null
+++ b/website/pages/admin/userslist.html
@@ -0,0 +1,131 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/website/pages/faq.html b/website/pages/faq.html
new file mode 100644
index 0000000..d56dc47
--- /dev/null
+++ b/website/pages/faq.html
@@ -0,0 +1,140 @@
+
Frequently Asked Questions (FAQ)
+
+
How do I pick which coins to merge mine?
+
The hash work of your miner application to the parent coin is also applied to the child coin you specify in the mining software pool password field.
+
+
You must mine at one parent coin, which in this case is ARQ for ArQmA.
+Specify your ArQmA wallet address and static difficulty per the Getting Started page.
+Using the pool password field in your miner to specify one of the child coin wallet addresses. See which child coins are listed on the pool's Dashboard page.
+You will need at least a wallet address from an exchange or a wallet/paper wallet application to get an coin address for the parent coin and each child coin you wish to merge mine.
+
+
You can also connect multiple rigs with the same wallet address for the parent coin, and different child coin wallet address to apply hash to that child coin also.
+
+
Specify your rig_id in your miner software.
+
Put your child coin wallet address in the pool password field and put "@rig_id" at the end.
+ It can be a direct to exchange address also.
+
For example in XMR-STAK, the pools.txt config file looks something like this:
+"rig_id" : "Johnny5",
+An example wallet for Turtle child coin is "TRTL2aedfsr23blahlongaddressfield+paymentIDsomething"
+so make it formatted for the pool password as
+"pool_password" : "TRTL2aedfsr23blahlongaddressfield+paymentIDsomething@Johnny5"
+
+
You can also use the configuration generator within the Getting Started section of the pool.
+
Also, you can segment your cpu mining on one mining application to be applied to
+the parent coin and specify your hash work one of the several child coins.
+There is no limit on how many workers you can specify. You can also customize your miner application to mine only with certain gpus to a particular parent/child combination. Probably you can run several mining applications in tandem as long as they use only resources you specify.
+
+
+
+
Where are the stats for the pool? Why hasn't anything changed?
+
The dashboard lists the coins being mined, reward for each block, current effort on each block for the merged mining. Sometimes the Pool Blocks section and Worker Statistics needs a refresh by your browser to get updated stats. Typically that is pressing CTRL+F5 to flush the cache and ask your brower for fresh data.
+
+
+
What is difficulty?
+
Difficulty is a measure of how difficult it is to find a hash below a given target. The target difficulty changes from block to block based on the network hashrate attempted by all nodes on a coin network. However, the difficulty for child coins can be dissimlar to the parent coin you start mining with
+
+
What is luck?
+
Mining is probabilistic in nature: if you find a block earlier than you statistically should on average you are lucky if it takes longer, you are unlucky. In a perfect World pool would find a block on 100% luck value. Less then 100% means the pool was lucky. More then 100% means the pool was unlucky.
+
+
+
What is share?
+
Share is a possible valid hash for the block. Shares are beings sent by your rigs to the pool to prove their work. You should set your fixed difficulty to be somewhere around your hash rate average on your miner multiplied by 28-30. Aim for your average number of accepted shares to be within the block time (30 seconds typically for child coins, 2 minutes for ARQ)
+If your shares are accepted faster, but with lower difficulty each share is worth less, but you should get at least one share in per average block time. It doesn't help the pool by spamming a large amount of low difficulty shares. It tends to tie up more resources and might get you banned.
+
+
What is block?
+ Transaction data is recorded in blocks. New transactions are being processes by miners into new blocks which are added to the end of the blockchain.
+
+How long does it take to find a block?
+It depends on amount of active miners. The more miners work on pool → the more hashrate pool has → the more blocks are found by the pool. However the more miners are active → the less reward you get from each block found.
+Probablistically, even smaller pools will less miners or hash rate will eventually get a block.
+Decentralizing the hash proof of work across several pools on any network is important for security of the coin network, for both the parent coin and the child coins.
+The block time is how long it can take on average amount effort . The average for ArQmA is 120 seconds. However, some of the child coins have block timeframes on the average of 15 to 30 seconds. Check your child coins network specification. Some blocks are solved faster than the average block time, some blocks can have a higher than average block effort time.
+Also some other pools might solve the block first, and there is a slim possibility of an orphan block on a child coin being mined.
+
+What is an orphan block?
+An orphan is a block that didn't meet the requirement as a solution to the block found. Also, there can be a situation where another pool or solo miner found the block solution first, and narrowly won the race. Blocks are confirmed by hash verfication by all the nodes on the coin's network. If there is a consensus of which node(pool,solo) found it first, then that block is added to the block chain permanenty with credit applying to that pool/solo/node.
+A few orphan blocks on child coins can happen when the parent coin's hash work doesn't meet the requirements.
+
+
+Which payouts scheme is used?
+Proportional (Share-based): Every time a block is found, its reward is split between miners according to the number of shares they submitted.
+
+How current payout estimate is calculated?
+The estimated payout is a calculated using your percentage of valid shares on the total for current round in proportion to the total shares submitted by all miners/workers in that round. This percentage is then applied to the reward of the last block found by the network and subtracting the small pool fee.. See the Worker Statistics page on the pool web page.
+
+
+I have been mining on this pool for 1 hour but still have not received any payouts. WTF?
+As soon as the block is found you will get your reward. Please wait a little bit more time. In the case of ArQmA, a block has at least 18 confirmations before the pool starts its payout cycle. Typically every 36 minutes for a completed block plus the time interval set by the pool operator on the pool's Dashboard screeen. Payments can be halted for various reasons within the automated pool software, but highly unlikely. There is usually a minimum payout for each parent coin and child coins. Payments for matured blocks that meet the minimum can also be triggered manually by a pool operator/administrator. Ask nicely in Telegram or Discord support. Please have your information all in order before you ask such as miner application, version number, gpu and cpu information, wallet addresses, and error messages reported.
+
The merge mined child coins have a different number of confirmation blocks needed, but at least the pool checks for fully verified blocks set at the interval on the Dashboard page. Not every parent block found generates a child block.
+Check the Pool Blocks page on the pool. Or configure your settings to get an email alert if you like on the Settings pool page.
+
+
+My hashrate is wrong! Why?
+Since you start to mine your hashrate grows gradually. Please wait. The pool determines your hashrate based on the amount of shares sent by your mining rigs (workers). This value could be a little bit different from reported hasrate (in your mining software).
+
+
+What is solo mining?
+Solo mining is attempting to find a block by yourself separate from the pool of proportional miners collectively solving the current block.You get almost the entire block reward minus a small fee for the pool. You can specfy your mining software by changing the wallet address with a prefix of "solo:" added to your wallet specification.
+However, if the coin network has a high hash in total (see Dashboard), the difficulty is also higher. Typically only very large mining rigs with at least 5-10% of the coin network total is needed to get timely solo blocks. However, you could get a string of blocks on lucky streak, then not find a block solution for a very long time. The more hash rate, the higher the probability(luck). You can generate a solo configuration on the Getting Started page on the pool. Tick the checkbox "solo mining". However, as solo you are also competing against the pool proportional share miners, and evvery single node on the parent coin network also.
+
+
In the case of solo merged mining specified in the pool password field, you are also competing against the main pool users on proportional shares, and the entire child coin network and the other pools on the parent network that are also merge mining. However the reward is much higher since you might get two coin blocks(or more) for the same effort.
+
+
+
+I've been banned by the pool itself. What do I do now?
+Disconnect your miner for five minutes at least. Then try again. Please pay close attention to error messages reported by the pool software to your miner client software. Typical errors are invalid parent wallet address format, or bad child coin wallet address specified in the pool password field. Check your miner logs if you have them turned on.
+
+
Did you forget to turn off nicehash option?
+
For persistent banning, check with the pool operator or Admininstrator to see if there is something else going wrong outside of your control. Links for Telegram and Discord support are on the left side of the pool web page front end.
+
+
+
+
+
How to use the Telegram Bot?
+
+
Telegram bot will report via Telegram, when your worker is connected, disconnected or banned, and payments have been made to your wallet. Also you can check pool stats directly from him.
+
+
+
Bot name :
@Pool_bot
+
+
+
Commands :
+
/stats -
Pool statistics
+
/blocks -
Blocks notifications (enable or disable)
+
/report address -
Miner statistics
+
/notify address -
Miner notifications (enable or disable)
+
+
+
Multiple addresses monitoring available.
+
+
+
+
+
\ No newline at end of file
diff --git a/website/pages/getting_started.html b/website/pages/getting_started.html
new file mode 100644
index 0000000..1ff8371
--- /dev/null
+++ b/website/pages/getting_started.html
@@ -0,0 +1,332 @@
+
+