Coriolis was created using assets and imagery from Elite: Dangerous, with the permission of Frontier Developments plc, for non-commercial purposes. It is not endorsed by nor reflects the views or opinions of Frontier Developments and no employee of Frontier Developments was involved in the making of it.
diff --git a/app/js/app.js b/app/js/app.js
index eeff358e..2cd84058 100755
--- a/app/js/app.js
+++ b/app/js/app.js
@@ -1,6 +1,6 @@
-angular.module('app', ['ui.router', 'ct.ui.router.extras.sticky', 'ui.sortable', 'shipyard', 'ngLodash', 'app.templates'])
-.run(['$rootScope', '$location', '$window', '$document', '$state', 'commonArray', 'shipSize', 'hardPointClass', 'GroupMap', 'Persist', 'Discounts',
-function($rootScope, $location, $window, $doc, $state, CArr, sz, hpc, GroupMap, Persist, Discounts) {
+angular.module('app', ['ui.router', 'ct.ui.router.extras.sticky', 'ui.sortable', 'shipyard', 'ngLodash', 'app.templates', 'pascalprecht.translate'])
+.run(['$rootScope', '$location', '$window', '$document', '$state', '$translate', 'localeFormat', 'Persist', 'Discounts',
+function($rootScope, $location, $window, $doc, $state, $translate, localeFormat, Persist, Discounts) {
// App is running as a standalone web app on tablet/mobile
var isStandAlone;
// This was causing issues on Windows phones ($window.external was causing Angular js to throw an exception). Backup is to try this and set isStandAlone to false if this fails.
@@ -21,7 +21,6 @@ function($rootScope, $location, $window, $doc, $state, CArr, sz, hpc, GroupMap,
$rootScope.prevState = { name: from.name, params: fromParams };
if (to.url) { // Only track states that have a URL
-
if ($window.ga) {
ga('send', 'pageview', { page: $location.path() });
}
@@ -33,46 +32,57 @@ function($rootScope, $location, $window, $doc, $state, CArr, sz, hpc, GroupMap,
}
});
+ $rootScope.language = {
+ opts: {
+ en: 'English',
+ de: 'Deutsh',
+ es: 'Español',
+ fr: 'Français',
+ ru: 'ру́сский язы́к'
+ },
+ current: Persist.getLangCode()
+ };
+
+ $rootScope.localeFormat = d3.locale(localeFormat.get($rootScope.language.current));
+ updateNumberFormat();
+
// Global Reference variables
- $rootScope.CArr = CArr;
- $rootScope.SZ = sz;
- $rootScope.HPC = hpc;
- $rootScope.GMAP = GroupMap;
- $rootScope.insurance = { opts: [{ name: 'Standard', pct: 0.05 }, { name: 'Alpha', pct: 0.025 }, { name: 'Beta', pct: 0.0375 }] };
- $rootScope. discounts = { opts: Discounts };
- $rootScope.STATUS = ['', 'DISABLED', 'OFF', 'ON'];
+ $rootScope.insurance = { opts: [{ name: 'standard', pct: 0.05 }, { name: 'alpha', pct: 0.025 }, { name: 'beta', pct: 0.0375 }] };
+ $rootScope.discounts = { opts: Discounts };
+ $rootScope.STATUS = ['', 'disabled', 'off', 'on'];
$rootScope.STATUS_CLASS = ['', 'disabled', 'warning', 'secondary-disabled'];
$rootScope.title = 'Coriolis';
+ $rootScope.changeLanguage = function() {
+ $translate.use($rootScope.language.current);
+ $rootScope.localeFormat = d3.locale(localeFormat.get($rootScope.language.current));
+ updateNumberFormat();
+ $rootScope.$broadcast('languageChanged', $rootScope.language.current);
+ };
+
+ // Formatters
+ $rootScope.fRPct = d3.format('%');
+ $rootScope.fTime = function(d) { return Math.floor(d / 60) + ':' + ('00' + Math.floor(d % 60)).substr(-2, 2); };
+
+ function updateNumberFormat() {
+ var locale = $rootScope.localeFormat;
+ var fGen = $rootScope.fGen = locale.numberFormat('n');
+ $rootScope.fCrd = locale.numberFormat(',.0f');
+ $rootScope.fPwr = locale.numberFormat(',.2f');
+ $rootScope.fRound = function(d) { return fGen(d3.round(d, 2)); };
+ $rootScope.fPct = locale.numberFormat('.2%');
+ $rootScope.f1Pct = locale.numberFormat('.1%');
+ }
+
/**
* Returns the name of the component mounted in the specified slot
* @param {Object} slot The slot object
* @return {String} The component name
*/
$rootScope.cName = function(slot) {
- return slot.c ? slot.c.name ? slot.c.name : GroupMap[slot.c.grp] : null;
+ return $translate.instant(slot.c ? slot.c.name ? slot.c.name : slot.c.grp : null);
};
- // Formatters
- $rootScope.fCrd = d3.format(',.0f');
- $rootScope.fPwr = d3.format(',.2f');
- $rootScope.fRound = function(d) { return d3.round(d, 2); };
- $rootScope.fRound4 = function(d) { return d3.round(d, 4); };
- $rootScope.fPct = d3.format('.2%');
- $rootScope.f1Pct = d3.format('.1%');
- $rootScope.fRPct = d3.format('%');
- $rootScope.fTime = function(d) { return Math.floor(d / 60) + ':' + ('00' + Math.floor(d % 60)).substr(-2, 2); };
-
- if (isStandAlone) {
- var state = Persist.getState();
- // If a previous state has been stored, load that state
- if (state && state.name && state.params) {
- $state.go(state.name, state.params, { location: 'replace' });
- } else {
- $state.go('shipyard', null, { location: 'replace' }); // Default to home page
- }
- }
-
// Global Event Listeners
$doc.bind('keyup', function(e) {
if (e.keyCode == 27) { // Escape Key
@@ -98,4 +108,14 @@ function($rootScope, $location, $window, $doc, $state, CArr, sz, hpc, GroupMap,
}, false);
}
+ if (isStandAlone) {
+ var state = Persist.getState();
+ // If a previous state has been stored, load that state
+ if (state && state.name && state.params) {
+ $state.go(state.name, state.params, { location: 'replace' });
+ } else {
+ $state.go('shipyard', null, { location: 'replace' }); // Default to home page
+ }
+ }
+
}]);
diff --git a/app/js/config.js b/app/js/config.js
index bdaad36b..a54fa661 100755
--- a/app/js/config.js
+++ b/app/js/config.js
@@ -1,9 +1,17 @@
/**
* Sets up the routes and handlers before the Angular app is kicked off.
*/
-angular.module('app').config(['$provide', '$stateProvider', '$urlRouterProvider', '$locationProvider', 'ShipsDB', function($provide, $stateProvider, $urlRouterProvider, $locationProvider, ships) {
+angular.module('app').config(['$provide', '$stateProvider', '$urlRouterProvider', '$locationProvider', '$translateProvider', 'ShipsDB', function($provide, $stateProvider, $urlRouterProvider, $locationProvider, $translateProvider, ships) {
// Use HTML5 push and replace state if possible
$locationProvider.html5Mode({ enabled: true, requireBase: false });
+
+ // Use English as default/fallback language
+ $translateProvider
+ .useSanitizeValueStrategy('escapeParameters')
+ .useStorage('Persist')
+ .fallbackLanguage('en')
+ .determinePreferredLanguage();
+
/**
* Set up all states and their routes.
*/
diff --git a/app/js/controllers/controller-comparison.js b/app/js/controllers/controller-comparison.js
index d9914256..198bdde5 100755
--- a/app/js/controllers/controller-comparison.js
+++ b/app/js/controllers/controller-comparison.js
@@ -1,4 +1,4 @@
-angular.module('app').controller('ComparisonController', ['lodash', '$rootScope', '$filter', '$scope', '$state', '$stateParams', 'Utils', 'ShipFacets', 'ShipsDB', 'Ship', 'Persist', 'Serializer', function(_, $rootScope, $filter, $scope, $state, $stateParams, Utils, ShipFacets, Ships, Ship, Persist, Serializer) {
+angular.module('app').controller('ComparisonController', ['lodash', '$rootScope', '$filter', '$scope', '$state', '$stateParams', '$translate', 'Utils', 'ShipFacets', 'ShipsDB', 'Ship', 'Persist', 'Serializer', function(_, $rootScope, $filter, $scope, $state, $stateParams, $translate, Utils, ShipFacets, Ships, Ship, Persist, Serializer) {
$rootScope.title = 'Coriolis - Compare';
$scope.predicate = 'name'; // Sort by ship name as default
$scope.desc = false;
@@ -155,7 +155,7 @@ angular.module('app').controller('ComparisonController', ['lodash', '$rootScope'
return 'Error - ' + err.statusText;
}
);
- $state.go('modal.export', { promise: promise, title: 'Forum BBCode' });
+ $state.go('modal.export', { promise: promise, title: $translate.instant('FORUM') + ' BBCode' });
};
/**
@@ -184,6 +184,10 @@ angular.module('app').controller('ComparisonController', ['lodash', '$rootScope'
$scope.showBuilds = false;
});
+ $scope.$on('languageChanged', function() {
+ $scope.tblUpdate = !$scope.tblUpdate; // Simple switch to trigger the table to update
+ });
+
/* Initialization */
if ($scope.compareMode) {
if ($scope.name == 'all') {
@@ -226,7 +230,7 @@ angular.module('app').controller('ComparisonController', ['lodash', '$rootScope'
}
}
// Replace fmt with actual format function as defined in rootScope and retain original index
- facets.forEach(function(f, i) { f.fmt = $rootScope[f.fmt]; f.index = i; });
+ facets.forEach(function(f, i) { f.index = i; });
// Remove default facets, mark as active, and add them back in selected order
_.pullAt(facets, defaultFacets).forEach(function(f) { f.active = true; facets.unshift(f); });
$scope.builds = $filter('orderBy')($scope.builds, $scope.predicate, $scope.desc);
diff --git a/app/js/controllers/controller-outfit.js b/app/js/controllers/controller-outfit.js
index 9987d607..e6da0fa3 100755
--- a/app/js/controllers/controller-outfit.js
+++ b/app/js/controllers/controller-outfit.js
@@ -1,4 +1,4 @@
-angular.module('app').controller('OutfitController', ['$window', '$rootScope', '$scope', '$state', '$stateParams', 'ShipsDB', 'Ship', 'Components', 'Serializer', 'Persist', 'calcTotalRange', 'calcSpeed', function($window, $rootScope, $scope, $state, $p, Ships, Ship, Components, Serializer, Persist, calcTotalRange, calcSpeed) {
+angular.module('app').controller('OutfitController', ['$window', '$rootScope', '$scope', '$state', '$stateParams', '$translate', 'ShipsDB', 'Ship', 'Components', 'Serializer', 'Persist', 'calcTotalRange', 'calcSpeed', function($window, $rootScope, $scope, $state, $p, $translate, Ships, Ship, Components, Serializer, Persist, calcTotalRange, calcSpeed) {
var win = angular.element($window); // Angularized window object for event triggering
var data = Ships[$p.shipId]; // Retrieve the basic ship properties, slots and defaults
var ship = new Ship($p.shipId, data.properties, data.slots); // Create a new Ship instance
@@ -65,11 +65,11 @@ angular.module('app').controller('OutfitController', ['$window', '$rootScope', '
$scope.jrChart = {
labels: {
xAxis: {
- title: 'Cargo',
+ title: 'cargo',
unit: 'T'
},
yAxis: {
- title: 'Jump Range',
+ title: 'jump range',
unit: 'LY'
}
}
@@ -87,11 +87,11 @@ angular.module('app').controller('OutfitController', ['$window', '$rootScope', '
$scope.trChart = {
labels: {
xAxis: {
- title: 'Cargo',
+ title: 'cargo',
unit: 'T'
},
yAxis: {
- title: 'Total Range',
+ title: 'total range',
unit: 'LY'
}
}
@@ -110,11 +110,11 @@ angular.module('app').controller('OutfitController', ['$window', '$rootScope', '
$scope.speedChart = {
labels: {
xAxis: {
- title: 'Cargo',
+ title: 'cargo',
unit: 'T'
},
yAxis: {
- title: 'Speed',
+ title: 'speed',
unit: 'm/s'
}
}
@@ -258,8 +258,8 @@ angular.module('app').controller('OutfitController', ['$window', '$rootScope', '
if ($scope.buildName) {
$state.go('modal.export', {
- title: $scope.buildName + ' Export',
- description: 'A detailed JSON export of your build for use in other sites and tools',
+ title: $scope.buildName + ' ' + $translate.instant('export'),
+ description: $translate.instant('PHRASE_EXPORT_DESC'),
data: Serializer.toDetailedBuild($scope.buildName, ship, $scope.code || Serializer.fromShip(ship))
});
}
@@ -366,15 +366,14 @@ angular.module('app').controller('OutfitController', ['$window', '$rootScope', '
function updateRetrofitCosts() {
var costs = $scope.retrofitList = [];
- var cName = $rootScope.cName;
var total = 0, i, l, item;
if (ship.bulkheads.id != retrofitShip.bulkheads.id) {
item = {
buyClassRating: ship.bulkheads.c.class + ship.bulkheads.c.rating,
- buyName: cName(ship.bulkheads),
+ buyName: ship.bulkheads.c.name,
sellClassRating: retrofitShip.bulkheads.c.class + retrofitShip.bulkheads.c.rating,
- sellName: cName(retrofitShip.bulkheads),
+ sellName: retrofitShip.bulkheads.c.name,
netCost: ship.bulkheads.discountedCost - retrofitShip.bulkheads.discountedCost
};
costs.push(item);
@@ -388,12 +387,12 @@ angular.module('app').controller('OutfitController', ['$window', '$rootScope', '
if (slotGroup[i].id != retroSlotGroup[i].id) {
item = { netCost: 0 };
if (slotGroup[i].id) {
- item.buyName = cName(slotGroup[i]);
+ item.buyName = slotGroup[i].c.name || slotGroup[i].c.grp;
item.buyClassRating = slotGroup[i].c.class + slotGroup[i].c.rating;
item.netCost = slotGroup[i].discountedCost;
}
if (retroSlotGroup[i].id) {
- item.sellName = cName(retroSlotGroup[i]);
+ item.sellName = retroSlotGroup[i].c.name || retroSlotGroup[i].c.grp;
item.sellClassRating = retroSlotGroup[i].c.class + retroSlotGroup[i].c.rating;
item.netCost -= retroSlotGroup[i].discountedCost;
}
@@ -423,6 +422,11 @@ angular.module('app').controller('OutfitController', ['$window', '$rootScope', '
$scope.selectedSlot = null;
});
+ // Hide any open menu/slot/etc if the background is clicked
+ $scope.$on('languageChanged', function() {
+ $scope.selectedSlot = null;
+ });
+
// Hide any open menu/slot/etc if the background is clicked
$scope.$on('discountChange', function() {
ship.applyDiscounts($rootScope.discounts.ship, $rootScope.discounts.components);
diff --git a/app/js/directives/directive-area-chart.js b/app/js/directives/directive-area-chart.js
index 0ade7b93..2d78d41e 100755
--- a/app/js/directives/directive-area-chart.js
+++ b/app/js/directives/directive-area-chart.js
@@ -1,4 +1,4 @@
-angular.module('app').directive('areaChart', ['$window', function($window) {
+angular.module('app').directive('areaChart', ['$window', '$translate', function($window, $translate) {
return {
restrict: 'A',
scope: {
@@ -47,18 +47,19 @@ angular.module('app').directive('areaChart', ['$window', function($window) {
// Create Y Axis SVG Elements
var yTxt = vis.append('g').attr('class', 'y axis')
.append('text')
+ .attr('class', 'cap')
.attr('transform', 'rotate(-90)')
.attr('y', -50)
.attr('dy', '.1em')
.style('text-anchor', 'middle')
- .text(labels.yAxis.title + ' (' + labels.yAxis.unit + ')');
+ .text($translate.instant(labels.yAxis.title) + ' (' + $translate.instant(labels.yAxis.unit) + ')');
// Create X Axis SVG Elements
var xLbl = vis.append('g').attr('class', 'x axis');
var xTxt = xLbl.append('text')
.attr('y', 30)
.attr('dy', '.1em')
.style('text-anchor', 'middle')
- .text(labels.xAxis.title + ' (' + labels.xAxis.unit + ')');
+ .text($translate.instant(labels.xAxis.title) + ' (' + $translate.instant(labels.xAxis.unit) + ')');
// Create and Add tooltip
var tip = vis.append('g').style('display', 'none');
@@ -150,8 +151,8 @@ angular.module('app').directive('areaChart', ['$window', function($window) {
tip.attr('transform', 'translate(' + x(x0) + ',' + y(y0) + ')');
tip.selectAll('rect').attr('x', flip ? '-5.75em' : '0.5em').style('text-anchor', flip ? 'end' : 'start');
tip.selectAll('text.label').attr('x', flip ? '-2em' : '1em').style('text-anchor', flip ? 'end' : 'start');
- tip.select('text.label.x').text(fmtLong(x0) + ' ' + labels.xAxis.unit);
- tip.select('text.label.y').text(fmtLong(y0) + ' ' + labels.yAxis.unit);
+ tip.select('text.label.x').text(fmtLong(x0) + ' ' + $translate.instant(labels.xAxis.unit));
+ tip.select('text.label.y').text(fmtLong(y0) + ' ' + $translate.instant(labels.yAxis.unit));
}
scope.$on('$destroy', function() {
diff --git a/app/js/directives/directive-bar-chart.js b/app/js/directives/directive-bar-chart.js
index eab99af9..41ea0f7a 100755
--- a/app/js/directives/directive-bar-chart.js
+++ b/app/js/directives/directive-bar-chart.js
@@ -1,4 +1,4 @@
-angular.module('app').directive('barChart', ['$window', function($window) {
+angular.module('app').directive('barChart', ['$window', '$translate', '$rootScope', function($window, $translate, $rootScope) {
function bName(build) {
return build.buildName + '\n' + build.name;
@@ -25,15 +25,15 @@ angular.module('app').directive('barChart', ['$window', function($window) {
link: function(scope, element) {
var color = d3.scale.ordinal().range([ '#7b6888', '#6b486b', '#3182bd', '#a05d56', '#d0743c']),
labels = scope.facet.lbls,
- fmt = scope.facet.fmt,
+ fmt = null,
+ unit = null,
properties = scope.facet.props,
- unit = scope.facet.unit,
margin = { top: 10, right: 20, bottom: 35, left: 150 },
y0 = d3.scale.ordinal(),
y1 = d3.scale.ordinal(),
x = d3.scale.linear(),
yAxis = d3.svg.axis().scale(y0).outerTickSize(0).orient('left'),
- xAxis = d3.svg.axis().scale(x).ticks(5).outerTickSize(0).orient('bottom').tickFormat(d3.format('.2s'));
+ xAxis = d3.svg.axis().scale(x).ticks(5).outerTickSize(0).orient('bottom');
// Create chart
var svg = d3.select(element[0]).append('svg');
@@ -43,7 +43,7 @@ angular.module('app').directive('barChart', ['$window', function($window) {
var tip = d3.tip()
.attr('class', 'd3-tip')
.html(function(property, propertyIndex) {
- return (labels ? (labels[propertyIndex] + ': ') : '') + fmt(property.value) + ' ' + unit;
+ return (labels ? ($translate.instant(labels[propertyIndex]) + ': ') : '') + fmt(property.value) + ' ' + unit;
});
vis.call(tip);
@@ -53,13 +53,13 @@ angular.module('app').directive('barChart', ['$window', function($window) {
vis.selectAll('g.y.axis g text').each(insertLinebreaks);
// Create X Axis SVG Elements
var xAxisLbl = vis.append('g')
- .attr('class', 'x axis')
+ .attr('class', 'x axis cap')
.append('text')
.attr('y', 30)
.attr('dy', '.1em')
- .style('text-anchor', 'middle')
- .text(scope.facet.title + (unit ? (' (' + unit + ')') : ''));
+ .style('text-anchor', 'middle');
+ updateFormats();
/**
* Watch for changes in the comparison array (ships added/removed, sorting)
@@ -117,6 +117,16 @@ angular.module('app').directive('barChart', ['$window', function($window) {
}
+ function updateFormats() {
+ fmt = $rootScope[scope.facet.fmt];
+ unit = $translate.instant(scope.facet.unit);
+ xAxisLbl.text($translate.instant(scope.facet.title) + (unit ? (' (' + $translate.instant(unit) + ')') : ''));
+ xAxis.tickFormat($rootScope.localeFormat.numberFormat('.2s'));
+ render();
+ }
+
+ scope.$on('languageChanged', updateFormats);
+
scope.$on('$destroy', function() {
angular.element($window).unbind('orientationchange resize render', render);
tip.destroy(); // Remove the tooltip from the DOM
diff --git a/app/js/directives/directive-comparison-table.js b/app/js/directives/directive-comparison-table.js
index 7219b988..731f9d16 100755
--- a/app/js/directives/directive-comparison-table.js
+++ b/app/js/directives/directive-comparison-table.js
@@ -1,7 +1,7 @@
-angular.module('app').directive('comparisonTable', ['$state', function($state) {
+angular.module('app').directive('comparisonTable', ['$state', '$translate', '$rootScope', function($state, $translate, $rootScope) {
function tblHeader(facets) {
- var r1 = ['
| Ship | Build | '];
+ var r1 = ['
|---|
| ', $translate.instant('SHIP'), ' | ', $translate.instant('BUILD'), ' | '];
var r2 = [];
for (var i = 0, l = facets.length; i < l; i++) {
if (facets[i].active) {
@@ -14,11 +14,11 @@ angular.module('app').directive('comparisonTable', ['$state', function($state) {
r1.push(' prop="', p[0], '" class="prop"');
} else {
for (var j = 0; j < pl; j++) {
- r2.push('', f.lbls[j], ' | ');
+ r2.push('', $translate.instant(f.lbls[j]), ' | ');
}
}
- r1.push('>', f.title, '');
+ r1.push('>', $translate.instant(f.title), '');
}
}
r1.push('
|---|
');
@@ -46,7 +46,7 @@ angular.module('app').directive('comparisonTable', ['$state', function($state) {
var f = facets[j];
var p = f.props;
for (var k = 0, pl = p.length; k < pl; k++) {
- body.push('| ', f.fmt(b[p[k]]), ' ', f.unit, ' | ');
+ body.push('', $rootScope[f.fmt](b[p[k]]), ' ', $translate.instant(f.unit), ' | ');
}
}
}
diff --git a/app/js/directives/directive-component-select.js b/app/js/directives/directive-component-select.js
index 16389109..19416e61 100755
--- a/app/js/directives/directive-component-select.js
+++ b/app/js/directives/directive-component-select.js
@@ -1,4 +1,4 @@
-angular.module('app').directive('componentSelect', function() {
+angular.module('app').directive('componentSelect', ['$translate', function($translate) {
// Generting the HTML in this manner is MUCH faster than using an angular template.
@@ -36,7 +36,7 @@ angular.module('app').directive('componentSelect', function() {
if (o.name) {
- list.push(' ' + o.name);
+ list.push(' ' + $translate.instant(o.name));
}
list.push('');
@@ -64,11 +64,11 @@ angular.module('app').directive('componentSelect', function() {
if (groups) {
// At present time slots with grouped options (Hardpoints and Internal) can be empty
- list.push('EMPTY
');
+ list.push('', $translate.instant('empty'), '
');
for (var g in groups) {
var grp = groups[g];
var grpCode = grp[Object.keys(grp)[0]].grp; // Nasty operation to get the grp property of the first/any single component
- list.push('', g, '
');
+ list.push('', $translate.instant(g), '
');
appendGroup(list, grp, cid, mass, scope.warning);
list.push('
');
}
@@ -87,4 +87,4 @@ angular.module('app').directive('componentSelect', function() {
}
}
};
-});
+}]);
diff --git a/app/js/directives/directive-header.js b/app/js/directives/directive-header.js
index 2f707d30..4681f39f 100755
--- a/app/js/directives/directive-header.js
+++ b/app/js/directives/directive-header.js
@@ -38,9 +38,9 @@ angular.module('app').directive('shipyardHeader', ['lodash', '$rootScope', '$sta
e.stopPropagation();
scope.openedMenu = null;
$state.go('modal.export', {
- title: 'Backup',
+ title: 'backup',
data: Persist.getAll(),
- description: 'Backup of all Coriolis data to save or transfer to another browser/device'
+ description: 'PHRASE_BACKUP_DESC'
});
};
@@ -49,9 +49,9 @@ angular.module('app').directive('shipyardHeader', ['lodash', '$rootScope', '$sta
e.stopPropagation();
scope.openedMenu = null;
$state.go('modal.export', {
- title: 'Detailed Export',
+ title: 'detailed export',
data: Serializer.toDetailedExport(scope.allBuilds),
- description: 'Detailed export of all builds for use with other tools and sites'
+ description: 'PHRASE_EXPORT_DESC'
});
};
diff --git a/app/js/directives/directive-line-chart.js b/app/js/directives/directive-line-chart.js
index 9b5000b9..2385897a 100644
--- a/app/js/directives/directive-line-chart.js
+++ b/app/js/directives/directive-line-chart.js
@@ -1,4 +1,4 @@
-angular.module('app').directive('lineChart', ['$window', function($window) {
+angular.module('app').directive('lineChart', ['$window', '$translate', '$rootScope', function($window, $translate, $rootScope) {
return {
restrict: 'A',
scope: {
@@ -12,8 +12,7 @@ angular.module('app').directive('lineChart', ['$window', function($window) {
config = scope.config,
labels = config.labels,
margin = { top: 15, right: 15, bottom: 35, left: 60 },
- fmt = d3.format('.3r'),
- fmtLong = d3.format('.2f'),
+ fmtLong = null,
func = seriesConfig.func,
drag = d3.behavior.drag(),
dragging = false,
@@ -21,8 +20,8 @@ angular.module('app').directive('lineChart', ['$window', function($window) {
x = d3.scale.linear(),
y = d3.scale.linear(),
// Define Axes
- xAxis = d3.svg.axis().scale(x).outerTickSize(0).orient('bottom').tickFormat(d3.format('.2r')),
- yAxis = d3.svg.axis().scale(y).ticks(6).outerTickSize(0).orient('left').tickFormat(fmt),
+ xAxis = d3.svg.axis().scale(x).outerTickSize(0).orient('bottom'),
+ yAxis = d3.svg.axis().scale(y).ticks(6).outerTickSize(0).orient('left'),
data = [];
// Create chart
@@ -36,18 +35,20 @@ angular.module('app').directive('lineChart', ['$window', function($window) {
// Create Y Axis SVG Elements
var yTxt = vis.append('g').attr('class', 'y axis')
.append('text')
+ .attr('class', 'cap')
.attr('transform', 'rotate(-90)')
.attr('y', -50)
.attr('dy', '.1em')
.style('text-anchor', 'middle')
- .text(labels.yAxis.title + ' (' + labels.yAxis.unit + ')');
+ .text($translate.instant(labels.yAxis.title) + ' (' + $translate.instant(labels.yAxis.unit) + ')');
// Create X Axis SVG Elements
var xLbl = vis.append('g').attr('class', 'x axis');
var xTxt = xLbl.append('text')
+ .attr('class', 'cap')
.attr('y', 30)
.attr('dy', '.1em')
.style('text-anchor', 'middle')
- .text(labels.xAxis.title + ' (' + labels.xAxis.unit + ')');
+ .text($translate.instant(labels.xAxis.title) + ' (' + $translate.instant(labels.xAxis.unit) + ')');
// Create and Add tooltip
var tipWidth = (Math.max(labels.yAxis.unit.length, labels.xAxis.unit.length) * 1.25) + 2;
@@ -72,6 +73,8 @@ angular.module('app').directive('lineChart', ['$window', function($window) {
})
.on('drag', moveTip);
+ updateFormats();
+
/**
* Watch for changes in the series data (mass changes, etc)
*/
@@ -177,10 +180,21 @@ angular.module('app').directive('lineChart', ['$window', function($window) {
var tip = tips.selectAll('g.tooltip').attr('transform', function(d, i) { return 'translate(' + x(x0) + ',' + y(series ? y0[series[i]] : y0) + ')'; });
tip.selectAll('rect').attr('x', flip ? (-tipWidth - 0.5) + 'em' : '0.5em').style('text-anchor', flip ? 'end' : 'start');
tip.selectAll('text.label').attr('x', flip ? '-1em' : '1em').style('text-anchor', flip ? 'end' : 'start');
- tip.selectAll('text.label.x').text(fmtLong(x0) + ' ' + labels.xAxis.unit);
- tips.selectAll('text.label.y').text(function(d, i) { return fmtLong(series ? y0[series[i]] : y0) + ' ' + labels.yAxis.unit; });
+ tip.selectAll('text.label.x').text(fmtLong(x0) + ' ' + $translate.instant(labels.xAxis.unit));
+ tips.selectAll('text.label.y').text(function(d, i) { return fmtLong(series ? y0[series[i]] : y0) + ' ' + $translate.instant(labels.yAxis.unit); });
}
+ function updateFormats() {
+ xTxt.text($translate.instant(labels.xAxis.title) + ' (' + $translate.instant(labels.xAxis.unit) + ')');
+ yTxt.text($translate.instant(labels.yAxis.title) + ' (' + $translate.instant(labels.yAxis.unit) + ')');
+ fmtLong = $rootScope.localeFormat.numberFormat('.2f');
+ xAxis.tickFormat($rootScope.localeFormat.numberFormat('.2r'));
+ yAxis.tickFormat($rootScope.localeFormat.numberFormat('.3r'));
+ render();
+ }
+
+ scope.$on('languageChanged', updateFormats);
+
scope.$on('$destroy', function() {
angular.element($window).unbind('orientationchange resize render', render);
});
diff --git a/app/js/directives/directive-power-bands.js b/app/js/directives/directive-power-bands.js
index 4ab6f28b..0b959c07 100644
--- a/app/js/directives/directive-power-bands.js
+++ b/app/js/directives/directive-power-bands.js
@@ -1,4 +1,4 @@
-angular.module('app').directive('powerBands', ['$window', function($window) {
+angular.module('app').directive('powerBands', ['$window', '$translate', '$rootScope', function($window, $translate, $rootScope) {
return {
restrict: 'A',
scope: {
@@ -35,16 +35,17 @@ angular.module('app').directive('powerBands', ['$window', function($window) {
// Create Y Axis SVG Elements
vis.append('g').attr('class', 'watt axis');
vis.append('g').attr('class', 'pct axis');
- vis.append('text').attr('x', -35).attr('y', 16).attr('class', 'primary').text('RET');
- vis.append('text').attr('x', -35).attr('y', barHeight + 18).attr('class', 'primary').text('DEP');
-
- var retLbl = vis.append('text').attr('y', 16);
- var depLbl = vis.append('text').attr('y', barHeight + 18);
+ var retLbl = vis.append('text').attr('x', -35).attr('y', 16).attr('class', 'primary upp');
+ var depLbl = vis.append('text').attr('x', -35).attr('y', barHeight + 18).attr('class', 'primary upp');
+ var retVal = vis.append('text').attr('y', 16);
+ var depVal = vis.append('text').attr('y', barHeight + 18);
// Watch for changes to data and events
scope.$watchCollection('available', render);
angular.element($window).bind('orientationchange resize pwrchange', render);
+ updateFormats();
+
function render() {
bands = scope.bands;
@@ -84,8 +85,8 @@ angular.module('app').directive('powerBands', ['$window', function($window) {
}
}
- updateLabel(retLbl, w, retBandsSelected, retBandsSelected ? retractedSum : maxBand.retractedSum, available);
- updateLabel(depLbl, w, depBandsSelected, depBandsSelected ? deployedSum : maxBand.deployedSum, available);
+ updateLabel(retVal, w, retBandsSelected, retBandsSelected ? retractedSum : maxBand.retractedSum, available);
+ updateLabel(depVal, w, depBandsSelected, depBandsSelected ? deployedSum : maxBand.deployedSum, available);
retracted.selectAll('rect').data(bands).enter().append('rect')
.attr('height', barHeight)
@@ -151,6 +152,18 @@ angular.module('app').directive('powerBands', ['$window', function($window) {
return '';
}
+ function updateFormats() {
+ retLbl.text($translate.instant('ret'));
+ depLbl.text($translate.instant('dep'));
+ wattFmt = $rootScope.localeFormat.numberFormat('.2f');
+ pctFmt = $rootScope.localeFormat.numberFormat('.1%');
+ wattAxis.tickFormat($rootScope.localeFormat.numberFormat('.2r'));
+ pctAxis.tickFormat($rootScope.localeFormat.numberFormat('%'));
+ render();
+ }
+
+ scope.$on('languageChanged', updateFormats);
+
scope.$on('$destroy', function() {
angular.element($window).unbind('orientationchange resize pwrchange', render);
});
diff --git a/app/js/directives/directive-slot-hardpoint.js b/app/js/directives/directive-slot-hardpoint.js
index 262cc561..dbfa50b8 100755
--- a/app/js/directives/directive-slot-hardpoint.js
+++ b/app/js/directives/directive-slot-hardpoint.js
@@ -3,8 +3,7 @@ angular.module('app').directive('slotHardpoint', ['$rootScope', function($r) {
restrict: 'A',
scope: {
hp: '=',
- size: '=',
- lbl: '='
+ size: '='
},
templateUrl: 'views/_slot-hardpoint.html',
link: function(scope) {
diff --git a/app/js/directives/directive-slot-internal.js b/app/js/directives/directive-slot-internal.js
index 2b67a7e8..afc148d6 100755
--- a/app/js/directives/directive-slot-internal.js
+++ b/app/js/directives/directive-slot-internal.js
@@ -3,7 +3,6 @@ angular.module('app').directive('slotInternal', ['$rootScope', function($r) {
restrict: 'A',
scope: {
c: '=slot',
- lbl: '=',
fuel: '='
},
templateUrl: 'views/_slot-internal.html',
diff --git a/app/js/factory-utils.js b/app/js/factory-utils.js
index 452772a4..9eeba68d 100755
--- a/app/js/factory-utils.js
+++ b/app/js/factory-utils.js
@@ -1,7 +1,7 @@
/**
* BBCode Generator functions for embedding in the Elite Dangerous Forums
*/
-angular.module('app').factory('Utils', ['$window', '$state', '$http', '$q', function($window, $state, $http, $q) {
+angular.module('app').factory('Utils', ['$window', '$state', '$http', '$q', '$translate', '$rootScope', function($window, $state, $http, $q, $translate, $rootScope) {
var shortenAPI = 'https://www.googleapis.com/urlshortener/v1/url?key=';
@@ -24,11 +24,11 @@ angular.module('app').factory('Utils', ['$window', '$state', '$http', '$q', func
p = f.props;
if (p.length == 1) {
- l.push('[th][B][COLOR=#FF8C0D]', f.title, '[/COLOR][/B][/th]');
+ l.push('[th][B][COLOR=#FF8C0D]', $translate.instant(f.title).toUpperCase(), '[/COLOR][/B][/th]');
colCount++;
} else {
for (j = 0; j < p.length; j++) {
- l.push('[th][B][COLOR=#FF8C0D]', f.title, '\n', f.lbls[j], '[/COLOR][/B][/th]');
+ l.push('[th][B][COLOR=#FF8C0D]', $translate.instant(f.title).toUpperCase(), '\n', $translate.instant(f.lbls[j]).toUpperCase(), '[/COLOR][/B][/th]');
colCount++;
}
}
@@ -46,7 +46,7 @@ angular.module('app').factory('Utils', ['$window', '$state', '$http', '$q', func
f = facets[j];
p = f.props;
for (k = 0, pl = p.length; k < pl; k++) {
- l.push('[td="align: right"]', f.fmt(b[p[k]]), ' [size=-2]', f.unit, '[/size][/td]');
+ l.push('[td="align: right"]', $rootScope[f.fmt](b[p[k]]), ' [size=-2]', $translate.instant(f.unit), '[/size][/td]');
}
}
}
diff --git a/app/js/i18n/de.js b/app/js/i18n/de.js
new file mode 100644
index 00000000..ee35a9cc
--- /dev/null
+++ b/app/js/i18n/de.js
@@ -0,0 +1,235 @@
+angular.module('app').config(['$translateProvider', 'localeFormatProvider', function($translateProvider, localeFormatProvider) {
+
+ // Declare number format settings
+ localeFormatProvider.addFormat('de', {
+ decimal: ',',
+ thousands: '.',
+ grouping: [3],
+ currency: ['', ' €'],
+ dateTime: '%A, der %e. %B %Y, %X',
+ date: '%d.%m.%Y',
+ time: '%H:%M:%S',
+ periods: ['AM', 'PM'], // unused
+ days: ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'],
+ shortDays: ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'],
+ months: ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'],
+ shortMonths: ['Jan', 'Feb', 'Mrz', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez']
+ });
+
+ $translateProvider.translations('de', {
+ PHRASE_EXPORT_DESC: 'Ein detaillierter JSON-Export Ihrer Konfiguration für die Verwendung in anderen Websites und Tools',
+ 'A-Rated': 'A-Klasse',
+ about: 'Über',
+ action: 'Aktion',
+ added: 'Hinzugefügt',
+ Advanced: 'Fortgeschritten',
+ 'Advanced Discovery Scanner': 'Fortgeschrittener Aufklärungsscanner',
+ agility: 'Beweglichkeit',
+ alpha: 'Alpha',
+ ammo: 'Munition',
+ PHRASE_CONFIRMATION: 'Sind Sie sicher?',
+ armour: 'Panzerung',
+ am: 'Automatische Feldwartungseinheit',
+ available: 'Verfügbar',
+ backup: 'Sicherungsdatei',
+ 'Basic Discovery Scanner': 'Einfacher Aufklärungsscanner',
+ bl: 'Strahlenlaser',
+ beta: 'Beta',
+ bins: 'Behälter',
+ boost: 'Boost',
+ build: 'Konfiguration',
+ 'build name': 'Konfigurationsname',
+ builds: 'Konfigurationen',
+ bh: 'Rumpfhüllenverstärkung',
+ ul: 'Salvenlaser',
+ buy: 'Kaufen',
+ cancel: 'Abbrechen',
+ c: 'Kanone',
+ capital: 'kapital',
+ cargo: 'Fracht',
+ 'Cargo Hatch': 'Frachtluke',
+ cr: 'Frachtgestell',
+ cs: 'Frachtscanner',
+ cells: 'Zellen',
+ 'Chaff Launcher': 'Düppel-Werfer',
+ close: 'Schließen',
+ cc: 'Krallensteuerung: Sammler',
+ compare: 'Vergleichen',
+ 'compare all': 'Alles Vergleichen',
+ comparison: 'Vergleich',
+ comparisons: 'Vergleiche',
+ component: 'Komponente',
+ cost: 'Kostet',
+ costs: 'Kosten',
+ cm: 'Gegenmaßnahme',
+ CR: 'CR',
+ create: 'Erstellen',
+ 'create new': 'Neu Erstellen',
+ credits: 'Credits',
+ Cytoscrambler: 'Zytostreuer',
+ damage: 'Schaden',
+ delete: 'Löschen',
+ 'delete all': 'Alles Löschen',
+ dep: 'ausg',
+ deployed: 'Ausgefahren',
+ 'detailed export': 'Detailiertes Exportieren',
+ 'Detailed Surface Scanner': 'Detailoberflächenscanner',
+ disabled: 'Deaktiviert',
+ discount: 'Rabatt',
+ Distruptor: 'Disruptor',
+ dc: 'Standard-Landecomputer',
+ done: 'Fertig',
+ DPS: 'DPS',
+ 'edit data': 'Bearbeiten',
+ efficiency: 'Effizienz',
+ 'Electronic Countermeasure': 'Elektronische Gegenmaßnahme',
+ empty: 'leer',
+ Enforcer: 'Vollstrecker',
+ ENG: 'ANT',
+ 'enter name': 'Namen eingeben',
+ EPS: 'EPS',
+ export: 'exportieren',
+ fixed: 'Fest',
+ forum: 'Forum',
+ fc: 'Splitterkanone',
+ fd: 'Frameshift-Antrieb',
+ ws: 'Sogwolkenscanner',
+ FSD: 'FSA',
+ fi: 'FSA-Unterbrecher',
+ fuel: 'Treibstoff',
+ fs: 'Treibstoffsammler',
+ ft: 'Treibstofftank',
+ fx: 'Krallensteuerung Treibstoffstransfer',
+ 'full tank': 'Tank voll',
+ Gimballed: 'Kardanisch',
+ H: 'R',
+ hardpoints: 'Waffenaufhängungen',
+ hb: 'Krallen-Steuereinheit (Ladelukenöffner)',
+ 'Heat Sink Launcher': 'Kühlkörperwerfer',
+ huge: 'Riesig',
+ hull: 'Hülle',
+ hr: 'Rumpfhüllenverstärkung (Paket)',
+ 'Imperial Hammer': 'Imperialer Hammer',
+ import: 'Importieren',
+ 'import all': 'Alles Importieren',
+ insurance: 'Versicherung',
+ 'Intermediate Discover Scanner': 'Mittlerer Aufklärungsscanner',
+ 'internal compartments': 'Innenbereichkabine',
+ 'jump range': 'Sprungreichweite',
+ jumps: 'Sprünge',
+ kw: 'Tötungsbefehlscanner',
+ L: 'G',
+ laden: 'Beladen',
+ language: 'Sprache',
+ large: 'Groß',
+ ls: 'Lebenserhaltung',
+ 'Lightweight Alloy': 'Leichte Legierung',
+ 'lock factor': 'Massensperrefaktor',
+ LS: 'LS',
+ LY: 'LJ',
+ M: 'M',
+ 'm/s': 'M/Sec.',
+ mass: 'Masse',
+ max: 'max',
+ 'max mass': 'maximale Masse',
+ medium: 'Mittel',
+ 'Military Grade Composite': 'Militär-Komposit',
+ nl: 'Minenwerfer',
+ 'Mining Lance': 'Lanzenabbaulaser',
+ ml: 'Abbaulaser',
+ 'Mirrored Surface Composite': 'Gespiegelte-Oberfläche-Komposit',
+ mr: 'Raketenbatterie',
+ mc: 'Mehrfachgeschütz',
+ 'net cost': 'Nettokosten',
+ no: 'Nein',
+ PHRASE_NO_BUILDS: 'Keine Konfigurationen zum Vergleich ausgewählt!',
+ PHRASE_NO_RETROCH: 'Keine Umrüständerungen',
+ none: 'Nichts',
+ 'none created': 'Nichts erstellt',
+ off: 'Aus',
+ on: 'An',
+ optimal: 'optimal',
+ 'optimal mass': 'optimale Masse',
+ 'optimize mass': 'Masse optimieren',
+ overwrite: 'Überschreiben',
+ Pacifier: 'Friedensstifter',
+ 'Pack-Hound': 'Schwarmwerfer',
+ PHRASE_IMPORT: 'JSON hier einfügen oder importieren',
+ pen: 'Durchdr.',
+ penetration: 'Durchdringung',
+ permalink: 'Permalink',
+ pa: 'Plasmabeschleuniger',
+ 'Point Defence': 'Punktverteidigung',
+ power: 'Energie',
+ pd: 'Energieverteiler',
+ pp: 'Kraftwerk',
+ pri: 'Prio',
+ priority: 'Priorität',
+ psg: 'Prismaschildgenerator',
+ proceed: 'Fortfahren',
+ pc: 'Krallensteuerung: Erzsucher',
+ pl: 'Impulslaser',
+ PWR: 'En.',
+ rg: 'Schienenkanone',
+ range: 'Reichweite',
+ rate: 'Rate',
+ 'Reactive Surface Composite': 'Reaktive-Oberfläche-Komposit',
+ recharge: 'Aufladen',
+ rf: 'Raffinerie',
+ 'refuel time': 'Auftankzeit',
+ 'Reinforced Alloy': 'Verstärkte Legierung',
+ reload: 'Aktualisieren',
+ rename: 'Umbenennen',
+ repair: 'Reparieren',
+ reset: 'Zurücksetzen',
+ ret: 'Eing',
+ retracted: 'Eingefahren',
+ 'retrofit costs': 'Nachrüstkosten',
+ 'retrofit from': 'Nachrüsten von',
+ ROF: 'Kad',
+ S: 'K',
+ save: 'Speichern',
+ sc: 'Scanner',
+ PHRASE_SELECT_BUILDS: 'Wähle Konfigurationen zum Vergleichen',
+ sell: 'Verkaufen',
+ s: 'Sensoren',
+ settings: 'Konfigurationen',
+ sb: 'Schildverstärker',
+ scb: 'Schildzellenbank',
+ sg: 'Schildgenerator',
+ shields: 'Schilde',
+ ship: 'Schiff',
+ ships: 'Schiffe',
+ shortened: 'Gekürzt',
+ size: 'Größe',
+ skip: 'Überspringen',
+ small: 'Klein',
+ speed: 'Geschwindigkeit',
+ standard: 'Standard',
+ 'Standard Docking Computer': 'Standard-Landecomputer',
+ Stock: 'Standard',
+ SYS: 'SYS',
+ T: 'T',
+ T_LOAD: 'T-Lad',
+ 'The Retributor': 'Retributor',
+ t: 'Schubdüsen',
+ time: 'Dauer',
+ tp: 'Torpedoaufhängung',
+ total: 'Gesamt',
+ 'total range': 'Maximale Reichweite',
+ turret: 'Geschützturm',
+ type: 'Typ',
+ U: 'W',
+ unladen: 'Unbeladen',
+ PHRASE_UPDATE_RDY: 'Update verfügbar! Klicken zum Aktualisieren',
+ URL: 'URL',
+ utility: 'Werkzeug',
+ 'utility mounts': 'Werkzeug-Steckplätze',
+ version: 'Version',
+ WEP: 'WAF',
+ yes: 'Ja',
+ PHRASE_BACKUP_DESC: 'Sicherung aller Coriolis Daten zu speichern oder auf einen anderen Browser / Gerät'
+ })
+ .registerAvailableLanguageKeys(['de'], { 'de_DE': 'de' });
+
+}]);
diff --git a/app/js/i18n/en.js b/app/js/i18n/en.js
new file mode 100644
index 00000000..a8d03c7c
--- /dev/null
+++ b/app/js/i18n/en.js
@@ -0,0 +1,57 @@
+angular.module('app').config(['$translateProvider', function($translateProvider) {
+
+ $translateProvider
+ .translations('en', {
+ am: 'Auto Field-Maintenance Unit',
+ bl: 'Beam Laser',
+ bh: 'bulkheads',
+ ul: 'Burst Laser',
+ c: 'Cannon',
+ cr: 'Cargo Rack',
+ cs: 'Cargo Scanner',
+ cc: 'Collector Limpet Controller',
+ cm: 'Countermeasure',
+ dc: 'Docking Computer',
+ fc: 'Fragment Cannon',
+ fd: 'Frame Shift Drive',
+ ws: 'Frame Shift Wake Scanner',
+ fi: 'FSD Interdictor',
+ fs: 'Fuel Scoop',
+ ft: 'Fuel Tank',
+ fx: 'Fuel Transfer Limpet Controller',
+ hb: 'Hatch Breaker Limpet Controller',
+ hr: 'Hull Reinforcement Package',
+ kw: 'Kill Warrant Scanner',
+ ls: 'life support',
+ nl: 'Mine Launcher',
+ ml: 'Mining Laser',
+ mr: 'Missile Rack',
+ mc: 'Multi-cannon',
+ pa: 'Plasma Accelerator',
+ pd: 'power distributor',
+ pp: 'power plant',
+ psg: 'Prismatic Shield Generator',
+ pc: 'Prospector Limpet Controller',
+ pl: 'Pulse Laser',
+ rg: 'Rail Gun',
+ rf: 'Refinery',
+ sc: 'scanner',
+ s: 'sensors',
+ sb: 'Shield Booster',
+ scb: 'Shield Cell Bank',
+ sg: 'Shield Generator',
+ T_LOAD: 't-load',
+ t: 'thrusters',
+ tp: 'Torpedo Pylon',
+ PHRASE_NO_BUILDS: 'No builds added to comparison!',
+ PHRASE_NO_RETROCH: 'No Retrofitting changes',
+ PHRASE_IMPORT: 'Paste JSON or import here',
+ PHRASE_SELECT_BUILDS: 'Select Builds to Compare',
+ PHRASE_EXPORT_DESC: 'A detailed JSON export of your build for use in other sites and tools',
+ PHRASE_CONFIRMATION: 'Are You Sure?',
+ PHRASE_UPDATE_RDY: 'Update Available! Click to Refresh',
+ PHRASE_BACKUP_DESC: 'Backup of all Coriolis data to save or transfer to another browser/device'
+ })
+ .registerAvailableLanguageKeys(['en'], { 'en_US': 'en', 'en_UK': 'en', 'en_GB': 'en', 'en_CA': 'en' });
+
+}]);
diff --git a/app/js/i18n/es.js b/app/js/i18n/es.js
new file mode 100644
index 00000000..214b38d8
--- /dev/null
+++ b/app/js/i18n/es.js
@@ -0,0 +1,265 @@
+angular.module('app').config(['$translateProvider', 'localeFormatProvider', function($translateProvider, localeFormatProvider) {
+
+ // Declare number format settings
+ localeFormatProvider.addFormat('es', {
+ decimal: ',',
+ thousands: '.',
+ grouping: [3],
+ currency: ['', ' €'],
+ dateTime: '%A, %e de %B de %Y, %X',
+ date: '%d/%m/%Y',
+ time: '%H:%M:%S',
+ periods: ['AM', 'PM'],
+ days: ['domingo', 'lunes', 'martes', 'miércoles', 'jueves', 'viernes', 'sábado'],
+ shortDays: ['dom', 'lun', 'mar', 'mié', 'jue', 'vie', 'sáb'],
+ months: ['enero', 'febrero', 'marzo', 'abril', 'mayo', 'junio', 'julio', 'agosto', 'septiembre', 'octubre', 'noviembre', 'diciembre'],
+ shortMonths: ['ene', 'feb', 'mar', 'abr', 'may', 'jun', 'jul', 'ago', 'sep', 'oct', 'nov', 'dic']
+ });
+
+ $translateProvider.translations('es', {
+ PHRASE_EXPORT_DESC: 'Ein detaillierter JSON-Export Ihrer Konfiguration für die Verwendung in anderen Websites und Tools',
+ A_RATED: 'A-Klasse',
+ ABOUT: 'Über',
+ ACTION: 'Aktion',
+ ADDED: 'Hinzugefügt',
+ ADDER: 'Adder',
+ ADVANCED: 'Fortgeschritten',
+ 'Advanced Discovery Scanner': 'Fortgeschrittener Aufklärungsscanner',
+ 'Advanced Plasma Laser': 'Fortgeschrittener Plasma-Laser',
+ AGILITY: 'Beweglichkeit',
+ ALPHA: 'Alpha',
+ AMMO: 'Munition',
+ ANACONDA: 'Anaconda',
+ PHRASE_CONFIRMATION: 'Sind Sie sicher?',
+ ARMOUR: 'Panzerung',
+ ASP_EXPLORER: 'Asp Explorer',
+ am: 'Automatische Feldwartungseinheit',
+ AVAILABLE: 'Verfügbar',
+ BACKUP: 'Sicherungsdatei',
+ 'Basic Discovery Scanner': 'Einfacher Aufklärungsscanner',
+ bl: 'Strahlenlaser',
+ BELUGA_LINER: 'Beluga Liner',
+ BETA: 'beta',
+ BINS: 'Behälter',
+ BOOST: 'Boost',
+ BUILD: 'Konfiguration',
+ BUILD_NAME: 'Konfigurationsname',
+ BUILDS: 'Konfigurationen',
+ BULKHEADS: 'Rumpfhüllenverstärkung',
+ ul: 'Salvenlaser',
+ BUY: 'Kaufen',
+ CANCEL: 'Abbrechen',
+ c: 'Kanone',
+ CAPITAL: 'kapital',
+ CARGO: 'Fracht',
+ CARGO_HATCH: 'Frachtluke',
+ cr: 'Frachtgestell',
+ cs: 'Frachtscanner',
+ CELLS: 'Zellen',
+ CHAFF_LAUNCHER: 'Düppel-Werfer',
+ CLOSE: 'Schließen',
+ COBRA_MK_III: 'Cobra MK III',
+ COBRA_MK_IV: 'Cobra MK IV',
+ cc: 'Krallensteuerung: Sammler',
+ COMPARE: 'Vergleichen',
+ COMPARE_ALL: 'Alles Vergleichen',
+ COMPARISON: 'Vergleich',
+ COMPARISONS: 'Vergleiche',
+ COMPONENT: 'Komponente',
+ COST: 'Kostet',
+ COSTS: 'Kosten',
+ cm: 'Gegenmaßnahme',
+ CR: 'CR',
+ CREATE: 'Erstellen',
+ CREATE_NEW: 'Neu Erstellen',
+ CREDITS: 'Credits',
+ Cytoscrambler: 'Zytostreuer',
+ DAMAGE: 'Schaden',
+ DELETE: 'Löschen',
+ DELETE_ALL: 'Alles Löschen',
+ DEP: 'Ausg',
+ DEPLOYED: 'Ausgefahren',
+ DETAILED_EXPORT: 'Detailiertes Exportieren',
+ 'Detailed Surface Scanner': 'Detailoberflächenscanner',
+ DIAMONDBACK_EXPLORER: 'Diamondback-Erkunder',
+ DIAMONDBACK_SCOUT: 'Diamondback-Aufklärer',
+ DISABLED: 'Deaktiviert',
+ DISCOUNT: 'Rabatt',
+ Distruptor: 'Disruptor',
+ dc: 'Standard-Landecomputer',
+ DOLPHIN: 'Dolphin',
+ DONE: 'Fertig',
+ DPS: 'DPS',
+ EAGLE: 'Eagle',
+ EDIT_DATA: 'Bearbeiten',
+ EFFICIENCY: 'Effizienz',
+ 'Electronic Countermeasure': 'Elektronische Gegenmaßnahme',
+ EMPTY: 'leer',
+ ENFORCER: 'Vollstrecker',
+ ENG: 'FAH',
+ PHRASE_ENTER_BUILD_NAME: '',
+ EPS: 'en/s',
+ EXPORT: 'Exportieren',
+ FEDERAL_CORVETTE: 'Föderale Korvette',
+ FEDERAL_DROPSHIP: 'Föderales Abwurfschiff',
+ FEDERAL_DROPSHIP_MK_II: 'Föderales Abwurfschiff Mk II',
+ FEDERAL_GUNSHIP: 'Föderales Kanonenschiff',
+ FER_DE_LANCE: 'Fer-de-Lance',
+ FIXED: '',
+ FORUM: 'Forum',
+ fc: 'Splitterkanone',
+ fd: 'Frameshift-Antrieb',
+ ws: 'Sogwolkenscanner',
+ FSD: 'FSA',
+ fi: 'FSA-Unterbrecher',
+ FUEL: 'Treibstoff',
+ fs: 'Treibstoffsammler',
+ ft: 'Treibstofftank',
+ fx: 'Krallensteuerung Treibstoffstransfer',
+ FULL_TANK: 'Tank voll',
+ GIMBALLED: 'Kardianisch',
+ H: 'H',
+ HARDPOINTS: 'Waffenaufhängungen',
+ hb: 'Krallen-Steuereinheit (Ladelukenöffner)',
+ HAULER: 'Hauler',
+ 'Heat Sink Launcher': 'Kühlkörperwerfer',
+ HUGE: 'Riesig',
+ HULL: 'Hülle',
+ hr: 'Rumpfhüllenverstärkung (Paket)',
+ IMPERIAL_CLIPPER: 'Imperialer Clipper',
+ IMPERIAL_COURIER: 'Imperialer Kurier',
+ IMPERIAL_CUTTER: 'Imperialer Cutter',
+ IMPERIAL_EAGLE: 'Imperialer Eagle',
+ IMPERIAL_HAMMER: 'Imperialer Hammer',
+ IMPORT: 'Importieren',
+ IMPORT_ALL: 'Alles Importieren',
+ INSURANCE: 'Versicherung',
+ 'Intermediate Discover Scanner': 'Mittlerer Aufklärungsscanner',
+ INTERNAL_COMPARTMENTS: 'Innenbereichkabine',
+ JUMP_RANGE: 'Sprungreichweite',
+ JUMPS: 'Sprünge',
+ kw: 'Tötungsbefehlscanner',
+ KRAIT: 'Krait',
+ L: 'L',
+ LADEN: 'Beladen',
+ LANGUAGE: 'Sprache',
+ LARGE: 'Groß',
+ ls: 'Lebenserhaltung',
+ 'Lightweight Alloy': 'Leichte Legierung',
+ LOCK_FACTOR: 'Massensperrefaktor',
+ LS: 'LS',
+ LY: 'LJ',
+ M: 'M',
+ 'm/s': 'M/Sec.',
+ MASS: 'Masse',
+ MAX: 'max',
+ MAX_MASS: 'maximale Masse',
+ MEDIUM: 'Mittel',
+ 'Military Grade Composite': 'Militär-Komposit',
+ nl: 'Minenwerfer',
+ 'Mining Lance': 'Lanzenabbaulaser',
+ ml: 'Abbaulaser',
+ 'Mirrored Surface Composite': 'Gespiegelte-Oberfläche-Komposit',
+ mr: 'Raketenbatterie',
+ mc: 'Mehrfachgeschütz',
+ NET_COST: 'Nettokosten',
+ NO: 'Nein',
+ NO_RETROFITTING_CHANGES: 'Keine Umrüständerungen',
+ NONE: 'Nichts',
+ NONE_CREATED: 'Nichts erstellt',
+ OFF: 'Aus',
+ ON: 'An',
+ OPTIMAL: 'optimal',
+ OPTIMAL_MASS: 'optimale Masse',
+ OPTIMIZE_MASS: 'Masse optimieren',
+ ORCA: 'Orca',
+ OVERWRITE: 'Überschreiben',
+ Pacifier: 'Friedensstifter',
+ 'Pack-Hound': 'Schwarmwerfer',
+ PANTHER_CLIPPER: 'Panter Clipper',
+ PHRASE_IMPORT: 'JSON hier einfügen oder hier importieren',
+ PEN: 'Durchdr',
+ PENETRATION: 'Durchdringung',
+ PERMALINK: 'Permalink',
+ pa: 'Plasmabeschleuniger',
+ POINT_DEFENCE: 'Punktverteidigung',
+ POWER: 'Energie',
+ pd: 'Energieverteiler',
+ pp: 'Kraftwerk',
+ PRI: 'Prio',
+ PRIORITY: 'Priorität',
+ psg: 'Prismaschildgenerator',
+ PROCEED: 'Fortfahren',
+ pc: 'Krallensteuerung: Erzsucher',
+ pl: 'Impulslaser',
+ PWR: 'En',
+ PYTHON: 'Python',
+ rg: 'Schienenkanone',
+ RANGE: 'Reichweite',
+ RATE: 'Rate',
+ 'Reactive Surface Composite': 'Reaktive-Oberfläche-Komposit',
+ RECHARGE: 'Aufladen',
+ rf: 'Raffinerie',
+ REFUEL_TIME: 'Auftankzeit',
+ 'Reinforced Alloy': 'Verstärkte Legierungen',
+ RELOAD: 'Aktualisieren',
+ RENAME: 'Umbenennen',
+ REPAIR: 'Reparieren',
+ RESET: 'Zurücksetzen',
+ RET: 'eing',
+ RETRACTED: 'Eingefahren',
+ RETROFIT_COSTS: 'Nachrüstkosten',
+ RETROFIT_FROM: 'Nachrüsten von',
+ ROF: 'Kad',
+ S: 'S',
+ SAVE: 'Speichern',
+ sc: 'Scanner',
+ PHRASE_SELECT_BUILDS: 'Wähle Konfigurationen zum Vergleichen',
+ SELL: 'Verkaufen',
+ s: 'Sensoren',
+ SETTINGS: 'Konfiguration',
+ sb: 'Schildverstärker',
+ scb: 'Schildzellenbank',
+ sg: 'Schildgenerator',
+ SHIELDS: 'Schilde',
+ SHIP: 'Schiff',
+ SHIPS: 'Schiffe',
+ SHORTENED: 'Gekürzt',
+ SIDEWINDER: 'Sidewinder',
+ SIZE: 'Größe',
+ SKIP: 'Überspringen',
+ SMALL: 'S',
+ SPEED: 'Geschwindigkeit',
+ STANDARD: 'Standard',
+ STANDARD_DOCKING_COMPUTER: 'Landecomputer',
+ STOCK: 'Standard',
+ SYS: 'SYS',
+ T: 'T',
+ T_LOAD: 'T-Lad',
+ THE_HUNTER: 'The Hunter',
+ 'The Retributor': 'Retributor',
+ t: 'Schubdüsen',
+ TIME: 'Dauer',
+ tp: 'Torpedoaufhängung',
+ TOTAL: 'Gesamt',
+ TOTAL_RANGE: 'Maximale Reichweite',
+ TURRET: 'Geschützturm',
+ TYPE: 'Typ',
+ TYPE_6_TRANSPORTER: 'Typ-6 Transporter',
+ TYPE_7_TRANSPORTER: 'Typ-7 Transporter',
+ TYPE_9_HEAVY: 'Typ-9 Transporter (schwer)',
+ U: 'U',
+ UNLADEN: 'Unbeladen',
+ UPDATE_NOTIFICATION: 'Update verfügbar! Klicken zum Aktualisieren',
+ URL: 'URL',
+ UTILITY: 'Werkzeug',
+ UTILITY_MOUNTS: 'Werkzeug-Steckplatz',
+ VERSION: 'Version',
+ VIPER: 'Viper',
+ VULTURE: 'Vulture',
+ WEP: 'WAF',
+ YES: 'Ja'
+ })
+ .registerAvailableLanguageKeys(['es'], { 'es_ES': 'es' });
+
+}]);
diff --git a/app/js/i18n/fr.js b/app/js/i18n/fr.js
new file mode 100644
index 00000000..fff703a9
--- /dev/null
+++ b/app/js/i18n/fr.js
@@ -0,0 +1,265 @@
+angular.module('app').config(['$translateProvider', 'localeFormatProvider', function($translateProvider, localeFormatProvider) {
+
+ // Declare number format settings
+ localeFormatProvider.addFormat('fr', {
+ decimal: ',',
+ thousands: '.',
+ grouping: [3],
+ currency: ['', ' €'],
+ dateTime: '%A, le %e %B %Y, %X',
+ date: '%d/%m/%Y',
+ time: '%H:%M:%S',
+ periods: ['AM', 'PM'], // unused
+ days: ['dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi'],
+ shortDays: ['dim.', 'lun.', 'mar.', 'mer.', 'jeu.', 'ven.', 'sam.'],
+ months: ['janvier', 'février', 'mars', 'avril', 'mai', 'juin', 'juillet', 'août', 'septembre', 'octobre', 'novembre', 'décembre'],
+ shortMonths: ['janv.', 'févr.', 'mars', 'avr.', 'mai', 'juin', 'juil.', 'août', 'sept.', 'oct.', 'nov.', 'déc.']
+ });
+
+ $translateProvider.translations('fr', {
+ PHRASE_EXPORT_DESC: 'Ein detaillierter JSON-Export Ihrer Konfiguration für die Verwendung in anderen Websites und Tools',
+ A_RATED: 'A-Klasse',
+ ABOUT: 'Über',
+ ACTION: 'Aktion',
+ ADDED: 'Hinzugefügt',
+ ADDER: 'Adder',
+ ADVANCED: 'Fortgeschritten',
+ 'Advanced Discovery Scanner': 'Fortgeschrittener Aufklärungsscanner',
+ 'Advanced Plasma Laser': 'Fortgeschrittener Plasma-Laser',
+ AGILITY: 'Beweglichkeit',
+ ALPHA: 'Alpha',
+ AMMO: 'Munition',
+ ANACONDA: 'Anaconda',
+ PHRASE_CONFIRMATION: 'Sind Sie sicher?',
+ ARMOUR: 'Panzerung',
+ ASP_EXPLORER: 'Asp Explorer',
+ am: 'Automatische Feldwartungseinheit',
+ AVAILABLE: 'Verfügbar',
+ BACKUP: 'Sicherungsdatei',
+ 'Basic Discovery Scanner': 'Einfacher Aufklärungsscanner',
+ bl: 'Strahlenlaser',
+ BELUGA_LINER: 'Beluga Liner',
+ BETA: 'beta',
+ BINS: 'Behälter',
+ BOOST: 'Boost',
+ BUILD: 'Konfiguration',
+ BUILD_NAME: 'Konfigurationsname',
+ BUILDS: 'Konfigurationen',
+ BULKHEADS: 'Rumpfhüllenverstärkung',
+ ul: 'Salvenlaser',
+ BUY: 'Kaufen',
+ CANCEL: 'Abbrechen',
+ c: 'Kanone',
+ CAPITAL: 'kapital',
+ CARGO: 'Fracht',
+ CARGO_HATCH: 'Frachtluke',
+ cr: 'Frachtgestell',
+ cs: 'Frachtscanner',
+ CELLS: 'Zellen',
+ CHAFF_LAUNCHER: 'Düppel-Werfer',
+ CLOSE: 'Schließen',
+ COBRA_MK_III: 'Cobra MK III',
+ COBRA_MK_IV: 'Cobra MK IV',
+ cc: 'Krallensteuerung: Sammler',
+ COMPARE: 'Vergleichen',
+ COMPARE_ALL: 'Alles Vergleichen',
+ COMPARISON: 'Vergleich',
+ COMPARISONS: 'Vergleiche',
+ COMPONENT: 'Komponente',
+ COST: 'Kostet',
+ COSTS: 'Kosten',
+ cm: 'Gegenmaßnahme',
+ CR: 'CR',
+ CREATE: 'Erstellen',
+ CREATE_NEW: 'Neu Erstellen',
+ CREDITS: 'Credits',
+ Cytoscrambler: 'Zytostreuer',
+ DAMAGE: 'Schaden',
+ DELETE: 'Löschen',
+ DELETE_ALL: 'Alles Löschen',
+ DEP: 'Ausg',
+ DEPLOYED: 'Ausgefahren',
+ DETAILED_EXPORT: 'Detailiertes Exportieren',
+ 'Detailed Surface Scanner': 'Detailoberflächenscanner',
+ DIAMONDBACK_EXPLORER: 'Diamondback-Erkunder',
+ DIAMONDBACK_SCOUT: 'Diamondback-Aufklärer',
+ DISABLED: 'Deaktiviert',
+ DISCOUNT: 'Rabatt',
+ Distruptor: 'Disruptor',
+ dc: 'Standard-Landecomputer',
+ DOLPHIN: 'Dolphin',
+ DONE: 'Fertig',
+ DPS: 'DPS',
+ EAGLE: 'Eagle',
+ EDIT_DATA: 'Bearbeiten',
+ EFFICIENCY: 'Effizienz',
+ 'Electronic Countermeasure': 'Elektronische Gegenmaßnahme',
+ EMPTY: 'leer',
+ ENFORCER: 'Vollstrecker',
+ ENG: 'FAH',
+ PHRASE_ENTER_BUILD_NAME: '',
+ EPS: 'en/s',
+ EXPORT: 'Exportieren',
+ FEDERAL_CORVETTE: 'Föderale Korvette',
+ FEDERAL_DROPSHIP: 'Föderales Abwurfschiff',
+ FEDERAL_DROPSHIP_MK_II: 'Föderales Abwurfschiff Mk II',
+ FEDERAL_GUNSHIP: 'Föderales Kanonenschiff',
+ FER_DE_LANCE: 'Fer-de-Lance',
+ FIXED: '',
+ FORUM: 'Forum',
+ fc: 'Splitterkanone',
+ fd: 'Frameshift-Antrieb',
+ ws: 'Sogwolkenscanner',
+ FSD: 'FSA',
+ fi: 'FSA-Unterbrecher',
+ FUEL: 'Treibstoff',
+ fs: 'Treibstoffsammler',
+ ft: 'Treibstofftank',
+ fx: 'Krallensteuerung Treibstoffstransfer',
+ FULL_TANK: 'Tank voll',
+ GIMBALLED: 'Kardianisch',
+ H: 'H',
+ HARDPOINTS: 'Waffenaufhängungen',
+ hb: 'Krallen-Steuereinheit (Ladelukenöffner)',
+ HAULER: 'Hauler',
+ 'Heat Sink Launcher': 'Kühlkörperwerfer',
+ HUGE: 'Riesig',
+ HULL: 'Hülle',
+ hr: 'Rumpfhüllenverstärkung (Paket)',
+ IMPERIAL_CLIPPER: 'Imperialer Clipper',
+ IMPERIAL_COURIER: 'Imperialer Kurier',
+ IMPERIAL_CUTTER: 'Imperialer Cutter',
+ IMPERIAL_EAGLE: 'Imperialer Eagle',
+ IMPERIAL_HAMMER: 'Imperialer Hammer',
+ IMPORT: 'Importieren',
+ IMPORT_ALL: 'Alles Importieren',
+ INSURANCE: 'Versicherung',
+ 'Intermediate Discover Scanner': 'Mittlerer Aufklärungsscanner',
+ INTERNAL_COMPARTMENTS: 'Innenbereichkabine',
+ JUMP_RANGE: 'Sprungreichweite',
+ JUMPS: 'Sprünge',
+ kw: 'Tötungsbefehlscanner',
+ KRAIT: 'Krait',
+ L: 'L',
+ LADEN: 'Beladen',
+ LANGUAGE: 'Sprache',
+ LARGE: 'Groß',
+ ls: 'Lebenserhaltung',
+ 'Lightweight Alloy': 'Leichte Legierung',
+ LOCK_FACTOR: 'Massensperrefaktor',
+ LS: 'LS',
+ LY: 'LJ',
+ M: 'M',
+ 'm/s': 'M/Sec.',
+ MASS: 'Masse',
+ MAX: 'max',
+ MAX_MASS: 'maximale Masse',
+ MEDIUM: 'Mittel',
+ 'Military Grade Composite': 'Militär-Komposit',
+ nl: 'Minenwerfer',
+ 'Mining Lance': 'Lanzenabbaulaser',
+ ml: 'Abbaulaser',
+ 'Mirrored Surface Composite': 'Gespiegelte-Oberfläche-Komposit',
+ mr: 'Raketenbatterie',
+ mc: 'Mehrfachgeschütz',
+ NET_COST: 'Nettokosten',
+ NO: 'Nein',
+ NO_RETROFITTING_CHANGES: 'Keine Umrüständerungen',
+ NONE: 'Nichts',
+ NONE_CREATED: 'Nichts erstellt',
+ OFF: 'Aus',
+ ON: 'An',
+ OPTIMAL: 'optimal',
+ OPTIMAL_MASS: 'optimale Masse',
+ OPTIMIZE_MASS: 'Masse optimieren',
+ ORCA: 'Orca',
+ OVERWRITE: 'Überschreiben',
+ Pacifier: 'Friedensstifter',
+ 'Pack-Hound': 'Schwarmwerfer',
+ PANTHER_CLIPPER: 'Panter Clipper',
+ PHRASE_IMPORT: 'JSON hier einfügen oder hier importieren',
+ PEN: 'Durchdr',
+ PENETRATION: 'Durchdringung',
+ PERMALINK: 'Permalink',
+ pa: 'Plasmabeschleuniger',
+ POINT_DEFENCE: 'Punktverteidigung',
+ POWER: 'Energie',
+ pd: 'Energieverteiler',
+ pp: 'Kraftwerk',
+ PRI: 'Prio',
+ PRIORITY: 'Priorität',
+ psg: 'Prismaschildgenerator',
+ PROCEED: 'Fortfahren',
+ pc: 'Krallensteuerung: Erzsucher',
+ pl: 'Impulslaser',
+ PWR: 'En',
+ PYTHON: 'Python',
+ rg: 'Schienenkanone',
+ RANGE: 'Reichweite',
+ RATE: 'Rate',
+ 'Reactive Surface Composite': 'Reaktive-Oberfläche-Komposit',
+ RECHARGE: 'Aufladen',
+ rf: 'Raffinerie',
+ REFUEL_TIME: 'Auftankzeit',
+ 'Reinforced Alloy': 'Verstärkte Legierungen',
+ RELOAD: 'Aktualisieren',
+ RENAME: 'Umbenennen',
+ REPAIR: 'Reparieren',
+ RESET: 'Zurücksetzen',
+ RET: 'eing',
+ RETRACTED: 'Eingefahren',
+ RETROFIT_COSTS: 'Nachrüstkosten',
+ RETROFIT_FROM: 'Nachrüsten von',
+ ROF: 'Kad',
+ S: 'S',
+ SAVE: 'Speichern',
+ sc: 'Scanner',
+ PHRASE_SELECT_BUILDS: 'Wähle Konfigurationen zum Vergleichen',
+ SELL: 'Verkaufen',
+ s: 'Sensoren',
+ SETTINGS: 'Konfiguration',
+ sb: 'Schildverstärker',
+ scb: 'Schildzellenbank',
+ sg: 'Schildgenerator',
+ SHIELDS: 'Schilde',
+ SHIP: 'Schiff',
+ SHIPS: 'Schiffe',
+ SHORTENED: 'Gekürzt',
+ SIDEWINDER: 'Sidewinder',
+ SIZE: 'Größe',
+ SKIP: 'Überspringen',
+ SMALL: 'S',
+ SPEED: 'Geschwindigkeit',
+ STANDARD: 'Standard',
+ STANDARD_DOCKING_COMPUTER: 'Landecomputer',
+ STOCK: 'Standard',
+ SYS: 'SYS',
+ T: 'T',
+ T_LOAD: 'T-Lad',
+ THE_HUNTER: 'The Hunter',
+ 'The Retributor': 'Retributor',
+ t: 'Schubdüsen',
+ TIME: 'Dauer',
+ tp: 'Torpedoaufhängung',
+ TOTAL: 'Gesamt',
+ TOTAL_RANGE: 'Maximale Reichweite',
+ TURRET: 'Geschützturm',
+ TYPE: 'Typ',
+ TYPE_6_TRANSPORTER: 'Typ-6 Transporter',
+ TYPE_7_TRANSPORTER: 'Typ-7 Transporter',
+ TYPE_9_HEAVY: 'Typ-9 Transporter (schwer)',
+ U: 'U',
+ UNLADEN: 'Unbeladen',
+ UPDATE_NOTIFICATION: 'Update verfügbar! Klicken zum Aktualisieren',
+ URL: 'URL',
+ UTILITY: 'Werkzeug',
+ UTILITY_MOUNTS: 'Werkzeug-Steckplatz',
+ VERSION: 'Version',
+ VIPER: 'Viper',
+ VULTURE: 'Vulture',
+ WEP: 'WAF',
+ YES: 'Ja'
+ })
+ .registerAvailableLanguageKeys(['fr'], { 'fr_FR': 'fr', 'fr_CA': 'fr' });
+
+}]);
diff --git a/app/js/i18n/ru.js b/app/js/i18n/ru.js
new file mode 100644
index 00000000..f68c4e46
--- /dev/null
+++ b/app/js/i18n/ru.js
@@ -0,0 +1,257 @@
+angular.module('app').config(['$translateProvider', 'localeFormatProvider', function($translateProvider, localeFormatProvider) {
+
+ // Declare number format settings
+ localeFormatProvider.addFormat('ru', {
+ decimal: ',',
+ thousands: '\xa0',
+ grouping: [3],
+ currency: ['', ' руб.'],
+ dateTime: '%A, %e %B %Y г. %X',
+ date: '%d.%m.%Y',
+ time: '%H:%M:%S',
+ periods: ['AM', 'PM'],
+ days: ['воскресенье', 'понедельник', 'вторник', 'среда', 'четверг', 'пятница', 'суббота'],
+ shortDays: ['вс', 'пн', 'вт', 'ср', 'чт', 'пт', 'сб'],
+ months: ['января', 'февраля', 'марта', 'апреля', 'мая', 'июня', 'июля', 'августа', 'сентября', 'октября', 'ноября', 'декабря'],
+ shortMonths: ['янв', 'фев', 'мар', 'апр', 'май', 'июн', 'июл', 'авг', 'сен', 'окт', 'ноя', 'дек']
+ });
+
+ $translateProvider.translations('ru', {
+ PHRASE_EXPORT_DESC: '',
+ A_RATED: 'А-Класса',
+ ABOUT: 'О сайте',
+ ACTION: 'Действие',
+ ADDED: 'Добавлено',
+ ADVANCED: 'Продвинутый',
+ 'Advanced Discovery Scanner': 'Продвинутый исследовательский сканер',
+ 'Advanced Plasma Laser': 'Продвинутый плазменный лазер',
+ AGILITY: 'Маневренность',
+ ALPHA: 'Альфа',
+ AMMO: 'Боекомплект',
+ ANACONDA: 'Анаконда',
+ PHRASE_CONFIRMATION: 'Вы уверены?',
+ ARMOUR: 'Броня',
+ ASP_EXPLORER: 'Асп Эксплорер',
+ am: 'Устройство авторемонта',
+ AVAILABLE: 'доступно',
+ BACKUP: 'Поддержка / запас / бэкап',
+ 'Basic Discovery Scanner': 'Базовый исследовательский сканер',
+ bl: 'Лучевой лазер',
+ BELUGA_LINER: 'Лайнер Белуга',
+ BETA: 'Бета',
+ BINS: '',
+ BOOST: 'форсаж',
+ BUILD: 'cборка',
+ BUILD_NAME: 'название сборки',
+ BUILDS: 'cборки',
+ BULKHEADS: 'Переборки',
+ ul: 'пульс-лазер',
+ BUY: 'купить',
+ CANCEL: 'отменить',
+ c: 'Пушка',
+ CAPITAL: 'Крупный',
+ CARGO: 'Груз',
+ CARGO_HATCH: 'Грузовой трюм',
+ cr: 'Грузовой модуль',
+ cs: 'Сканер груза',
+ CELLS: 'Ячейки',
+ 'Chaff Launcher': 'Постановщик помех',
+ CLOSE: 'закрыть',
+ COBRA_MK_III: 'Кобра МК-III',
+ COBRA_MK_IV: 'Кобра МК-IV',
+ cc: 'Контроллер "дрон-сборщик"',
+ COMPARE: 'сравнить ',
+ COMPARE_ALL: 'сравнить все',
+ COMPARISON: 'сравнение',
+ COMPARISONS: 'сравнения',
+ COMPONENT: 'Компонент',
+ COST: 'Стоимость/Цена',
+ COSTS: 'Расходы',
+ cm: 'Контрмеры',
+ CR: 'кр.',
+ CREATE: 'создать',
+ CREATE_NEW: 'Создать снова',
+ CREDITS: 'Кредиты',
+ Cytoscrambler: 'Weapon PP - In game name',
+ DAMAGE: 'Урон',
+ DELETE: 'Удалить',
+ DELETE_ALL: 'Удалить все',
+ DEP: 'Вып.',
+ DEPLOYED: 'Готово',
+ DETAILED_EXPORT: 'Подробный экспорт',
+ 'Detailed Surface Scanner': 'Подробный сканер поверхности',
+ DIAMONDBACK_EXPLORER: 'Даймондбэк Эксплорер',
+ DIAMONDBACK_SCOUT: 'Даймондбэк Скаут',
+ DISABLED: 'Отключено',
+ DISCOUNT: 'Скидка',
+ Distruptor: 'Дисраптор',
+ dc: 'Стыковочный компьютер',
+ DOLPHIN: 'Дельфин',
+ DONE: 'готово',
+ DPS: 'Урон в секунду',
+ EAGLE: 'Орел',
+ EDIT_DATA: 'Редактирование',
+ EFFICIENCY: 'Эффективность',
+ 'Electronic Countermeasure': 'Электронное противодействие',
+ EMPTY: 'пусто',
+ ENFORCER: 'Weapon PP - In game name',
+ ENG: 'ДВГ',
+ PHRASE_ENTER_NAME: '',
+ EPS: 'э/с',
+ EXPORT: 'Экспорт',
+ FEDERAL_CORVETTE: 'Федеральный Корвет',
+ FEDERAL_DROPSHIP: 'Федеральный Десантный Корабль',
+ FEDERAL_DROPSHIP_MK_II: 'Федеральный Десантный Корабль мод.II',
+ FEDERAL_GUNSHIP: 'Федеральный Боевой Корабль',
+ FER_DE_LANCE: 'Фер-де-Ланс',
+ FIXED: 'Фиксированое',
+ FORUM: 'Форум',
+ fc: 'Осколочное Орудие',
+ fd: 'ФСД',
+ ws: 'Сканер следа',
+ FSD: 'ФСД',
+ fi: 'ФСД Перехватчик',
+ FUEL: 'Топливо',
+ fs: 'Топливозаборник',
+ ft: 'Топливный бак',
+ fx: 'Устройство передачи топлива',
+ FULL_TANK: 'Полный бак',
+ GIMBALLED: 'Доводимое',
+ HARDPOINTS: 'точки установки вооружения',
+ hb: 'Контроллер "дрон-взломщик"',
+ HAULER: 'Хаулер',
+ 'Heat Sink Launcher': 'Охладитель',
+ HULL: 'Корпус',
+ hr: 'Набор усиления корпуса',
+ IMPERIAL_CLIPPER: 'Имперский Клипер',
+ IMPERIAL_COURIER: 'Имперский Курьер',
+ IMPERIAL_CUTTER: 'Имперский Куттер',
+ IMPERIAL_EAGLE: 'Имперский Орёл',
+ IMPERIAL_HAMMER: 'Имперский Молот',
+ IMPORT: 'импортировать ',
+ IMPORT_ALL: 'импортировать все',
+ INSURANCE: 'Страховка',
+ 'Intermediate Discover Scanner': 'Средний Исследовательский Сканер',
+ INTERNAL_COMPARTMENTS: 'внутренние отсеки',
+ JUMP_RANGE: 'Дальность прыжка',
+ JUMPS: 'Прыжки',
+ kw: 'Сканер преступников',
+ KRAIT: 'Крэйт',
+ LADEN: 'Груженый',
+ LANGUAGE: 'Язык',
+ ls: 'Система жизнеобеспечения',
+ 'Lightweight Alloy': 'Легкий сплав',
+ LOCK_FACTOR: 'Блокирующий Фактор (Фактор массы)',
+ LS: 'Св.сек',
+ LY: 'Св.лет',
+ 'm/s': 'м/с',
+ MASS: 'Масса',
+ MAX: 'Макс',
+ MAX_MASS: 'Максимальная масса',
+ MEDIUM: 'Средний',
+ 'Military Grade Composite': 'Композит боевого класса',
+ nl: 'Миномет',
+ 'Mining Lance': 'Бурильная сулица',
+ ml: 'Шахтерский лазер',
+ 'Mirrored Surface Composite': 'Композит с зеркальной поверхностью',
+ mr: 'Ракетная установка',
+ mc: 'Многоствольная пушка',
+ NET_COST: 'разница в цене',
+ NO: 'Нет',
+ PHRASE_NO_BUILDS: '',
+ NO_RETROFITTING_CHANGES: 'нет ранних версий сборки\конфигурации',
+ NONE: 'ни один',
+ NONE_CREATED: 'не создано',
+ OFF: 'выкл.',
+ ON: 'вкл.',
+ OPTIMAL: 'Оптимальный',
+ OPTIMAL_MASS: 'Оптимальная масса',
+ OPTIMIZE_MASS: 'Оптимизировать массу',
+ ORCA: 'Орка',
+ OVERWRITE: 'перезаписать',
+ Pacifier: 'Миротворец',
+ 'Pack-Hound': 'Ракеты "Собачья стая" or original name(eng)',
+ PANTHER_CLIPPER: 'Клипер Пантера',
+ PHRASE_IMPORT: 'Для импорта вставьте код в эту форму',
+ PEN: 'Класс бронепробития. short - "прбт."',
+ PENETRATION: 'Пробитие',
+ PERMALINK: 'Постоянная ссылка',
+ pa: 'Ускоритель плазмы',
+ 'Point Defence': 'Противоракетная защита',
+ POWER: 'Мощность/сила/энергия',
+ pd: 'Распределитель энергии',
+ pp: 'Силовая установка / реактор',
+ PRI: 'Осн',
+ PRIORITY: 'Приоритет',
+ psg: 'Генератор призматического щита',
+ PROCEED: 'продолжить',
+ pc: 'Контроллер "Дрон-исследователь"',
+ pl: 'Импульсный лазер',
+ PWR: 'Е',
+ PYTHON: 'Питон',
+ rg: 'Рельсовая пушка',
+ RANGE: 'Дальность',
+ RATE: 'скорость',
+ 'Reactive Surface Composite': 'Композитно-реактивная поверхность',
+ RECHARGE: 'Перезарядка',
+ rf: 'Переработка',
+ REFUEL_TIME: 'Время дозаправки',
+ 'Reinforced Alloy': 'Усиленный сплав',
+ RELOAD: 'Перезарядить',
+ RENAME: 'Переименовать',
+ REPAIR: 'Починка',
+ RESET: 'Сброс',
+ RET: 'сокр',
+ RETRACTED: 'Убрано',
+ RETROFIT_COSTS: 'цена модификации',
+ RETROFIT_FROM: 'модификация от',
+ ROF: 'скорость стрельбы',
+ SAVE: 'Сохранить',
+ sc: 'Сканер',
+ PHRASE_SELECT_BUILDS: 'Выберите конфигурацию для сравнения',
+ SELL: 'Продать',
+ s: 'Сенсоры',
+ SETTINGS: 'Настройки',
+ sb: 'Усилитель щита',
+ scb: 'Батареи перезарядки щита',
+ sg: 'Генератор щита',
+ SHIELDS: 'Щиты',
+ SHIP: 'Корабль',
+ SHIPS: 'Корабли',
+ SHORTENED: 'Укороченный',
+ SIDEWINDER: 'Сайдвиндер',
+ SIZE: 'размер',
+ SKIP: 'пропустить',
+ SMALL: 'Малый',
+ SPEED: 'скорость',
+ STANDARD: 'Стандартный',
+ 'Standard Docking Computer': 'Стандартный стыковочный компьютер',
+ STOCK: 'Стандартная комплектация',
+ SYS: 'Сис',
+ T: 'Т',
+ T_LOAD: 'Тепловая нагрузка',
+ THE_HUNTER: 'Охотник',
+ 'The Retributor': 'Орудие Возмездия',
+ t: 'Ускорители',
+ TIME: 'Время',
+ tp: 'Торпедная установка',
+ TOTAL: 'Всего',
+ TOTAL_RANGE: 'Полный радиус',
+ TURRET: 'Туррель',
+ TYPE: 'Тип',
+ TYPE_6_TRANSPORTER: 'Перевозчик Тип-6',
+ TYPE_7_TRANSPORTER: 'Перевозчик Тип-7',
+ TYPE_9_HEAVY: 'Перевозчик Тип-9 Тяжелый',
+ UNLADEN: 'Пустой',
+ UPDATE_NOTIFICATION: 'Доступно обновление. Нажмите для обновления.',
+ URL: 'Ссылка',
+ UTILITY: '',
+ UTILITY_MOUNTS: 'Вспомогательное оборудование',
+ VERSION: 'Версия',
+ VIPER: 'Вайпер',
+ VULTURE: 'Вультура',
+ YES: 'Да'
+ })
+ .registerAvailableLanguageKeys(['ru'], { 'ru_RU': 'ru' });
+
+}]);
diff --git a/app/js/provider-locale-format.js b/app/js/provider-locale-format.js
new file mode 100644
index 00000000..598cd813
--- /dev/null
+++ b/app/js/provider-locale-format.js
@@ -0,0 +1,36 @@
+
+angular.module('app').provider('localeFormat', function localeFormatProvider() {
+ var formats = {
+ en: {
+ decimal: '.',
+ thousands: ',',
+ grouping: [3],
+ currency: ['$', ''],
+ dateTime: '%a %b %e %X %Y',
+ date: '%m/%d/%Y',
+ time: '%H:%M:%S',
+ periods: ['AM', 'PM'],
+ days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
+ shortDays: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
+ months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
+ shortMonths: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
+ }
+ };
+
+ function LocaleFormat(formatMap) {
+ this.formatMap = formatMap;
+
+ this.get = function(lang) {
+ return this.formatMap[lang] ? this.formatMap[lang] : this.formatMap.en;
+ };
+ }
+
+ this.addFormat = function(langCode, formatDetails) {
+ formats[langCode] = formatDetails;
+ };
+
+ this.$get = [function() {
+ return new LocaleFormat(formats);
+ }];
+
+});
diff --git a/app/js/service-persist.js b/app/js/service-persist.js
index 38da1bfe..43fb48bf 100755
--- a/app/js/service-persist.js
+++ b/app/js/service-persist.js
@@ -4,6 +4,7 @@
angular.module('app').service('Persist', ['$window', 'lodash', function($window, _) {
var LS_KEY_BUILDS = 'builds';
var LS_KEY_COMPARISONS = 'comparisons';
+ var LS_KEY_LANG = 'NG_TRANSLATE_LANG_KEY';
var LS_KEY_COST_TAB = 'costTab';
var LS_KEY_INSURANCE = 'insurance';
var LS_KEY_DISCOUNTS = 'discounts';
@@ -31,6 +32,22 @@ angular.module('app').service('Persist', ['$window', 'lodash', function($window,
hasBuilds: buildCount > 0,
hasComparisons: Object.keys(this.comparisons).length > 0
};
+
+ this.put = function(name, value) {
+ if (!this.lsEnabled) {
+ return;
+ }
+ localStorage.setItem(name, value);
+ };
+
+ this.get = function(name) {
+ return this.lsEnabled ? localStorage.getItem(name) : null;
+ };
+
+ this.getLangCode = function() {
+ return this.lsEnabled ? localStorage.getItem(LS_KEY_LANG) : 'en';
+ };
+
/**
* Persist a ship build in local storage.
*
diff --git a/app/js/shipyard/module-shipyard.js b/app/js/shipyard/module-shipyard.js
index 8afb1ecd..45fd8392 100755
--- a/app/js/shipyard/module-shipyard.js
+++ b/app/js/shipyard/module-shipyard.js
@@ -7,7 +7,7 @@
* @requires ngLodash
*/
angular.module('shipyard', ['ngLodash'])
- // Create 'angularized' references to DB.This will aid testing
+ // Create 'angularized' references to DB. This will aid testing
.constant('ShipsDB', DB.ships)
.constant('ComponentsDB', DB.components)
.value('ArmourMultiplier', [
@@ -17,16 +17,7 @@ angular.module('shipyard', ['ngLodash'])
1.945, // Mirrored
1.945 // Reactive
])
- .value('commonArray', [
- 'Power Plant',
- 'Thrusters',
- 'Frame Shift Drive',
- 'Life Support',
- 'Power Distributor',
- 'Sensors',
- 'Fuel Tank'
- ])
- // Map to lookup group labels/names for component grp
+ // Map to lookup group labels/names for component grp, used for JSON Serialization
.value('GroupMap', {
// Common
pp: 'Power Plant',
@@ -81,20 +72,6 @@ angular.module('shipyard', ['ngLodash'])
'Gimballed': 'G',
'Turret': 'T'
})
- .value('shipSize', [
- 'N/A',
- 'Small',
- 'Medium',
- 'Large',
- 'Capital'
- ])
- .value('hardPointClass', [
- 'Utility',
- 'Small',
- 'Medium',
- 'Large',
- 'Huge'
- ])
/**
* Array of all Ship properties (facets) organized into groups
* used for ship comparisons.
@@ -103,91 +80,89 @@ angular.module('shipyard', ['ngLodash'])
*/
.value('ShipFacets', [
{ // 0
- title: 'Agility',
+ title: 'agility',
props: ['agility'],
unit: '',
fmt: 'fCrd'
},
{ // 1
- title: 'Speed',
+ title: 'speed',
props: ['speed', 'boost'],
- lbls: ['Thrusters', 'Boost'],
+ lbls: ['thrusters', 'boost'],
unit: 'm/s',
fmt: 'fRound'
},
{ // 2
- title: 'Armour',
+ title: 'armour',
props: ['armour'],
unit: '',
fmt: 'fCrd'
},
{ // 3
- title: 'Shields',
+ title: 'shields',
props: ['shieldStrength'],
unit: 'MJ',
fmt: 'fRound'
},
{ // 4
- title: 'Jump Range',
+ title: 'jump range',
props: ['unladenRange', 'fullTankRange', 'ladenRange'],
- lbls: ['Max', 'Full Tank', 'Laden'],
+ lbls: ['max', 'full tank', 'laden'],
unit: 'LY',
fmt: 'fRound'
},
{ // 5
- title: 'Mass',
+ title: 'mass',
props: ['unladenMass', 'ladenMass'],
- lbls: ['Unladen', 'Laden'],
+ lbls: ['unladen', 'laden'],
unit: 'T',
fmt: 'fRound'
},
{ // 6
- title: 'Cargo',
+ title: 'cargo',
props: ['cargoCapacity'],
unit: 'T',
fmt: 'fRound'
},
{ // 7
- title: 'Fuel',
+ title: 'fuel',
props: ['fuelCapacity'],
unit: 'T',
fmt: 'fRound'
},
{ // 8
- title: 'Power',
+ title: 'power',
props: ['powerRetracted', 'powerDeployed', 'powerAvailable'],
- lbls: ['Retracted', 'Deployed', 'Available'],
+ lbls: ['retracted', 'deployed', 'available'],
unit: 'MW',
fmt: 'fPwr'
},
{ // 9
- title: 'Cost',
+ title: 'cost',
props: ['totalCost'],
unit: 'CR',
fmt: 'fCrd'
},
{ // 10
- title: 'Total Range',
+ title: 'total range',
props: ['unladenTotalRange', 'ladenTotalRange'],
- lbls: ['Unladen', 'Laden'],
+ lbls: ['unladen', 'laden'],
unit: 'LY',
fmt: 'fRound'
},
{ // 11
title: 'DPS',
props: ['totalDps'],
- lbls: ['Dps'],
+ lbls: ['DPS'],
unit: '',
fmt: 'fRound'
}
])
/**
* Set of all available / theoretical discounts
- *
- * @type {Object}
*/
.value('Discounts', {
- 'None': 1,
+ '0%': 1,
'5%': 0.95,
'10%': 0.90,
'15%': 0.85,
diff --git a/app/js/shipyard/service-components.js b/app/js/shipyard/service-components.js
index 1b412aa7..4876fa19 100755
--- a/app/js/shipyard/service-components.js
+++ b/app/js/shipyard/service-components.js
@@ -1,4 +1,10 @@
-angular.module('shipyard').service('Components', ['lodash', 'ComponentsDB', 'ShipsDB', 'ComponentSet', function(_, C, Ships, ComponentSet) {
+angular.module('shipyard').service('Components', ['lodash', 'ComponentsDB', 'ShipsDB', 'ComponentSet', 'GroupMap', function(_, C, Ships, ComponentSet, GroupMap) {
+
+ var GrpNameToCodeMap = {};
+
+ for (var grp in GroupMap) {
+ GrpNameToCodeMap[GroupMap[grp]] = grp;
+ }
this.cargoScoop = function() {
return { name: 'Cargo Hatch', class: 1, rating: 'H', power: 0.6 };
@@ -36,10 +42,11 @@ angular.module('shipyard').service('Components', ['lodash', 'ComponentsDB', 'Shi
var groups = {};
if (groupName) {
- if (!C.internal[groupName]) {
+ var grpCode = GrpNameToCodeMap[groupName];
+ if (grpCode && !C.internal[grpCode]) {
throw 'Invalid internal group: ' + groupName;
}
- groups[groupName] = C.internal[groupName];
+ groups[grpCode] = C.internal[grpCode];
} else if (name) {
groups = C.internal;
} else {
@@ -62,10 +69,11 @@ angular.module('shipyard').service('Components', ['lodash', 'ComponentsDB', 'Shi
var groups = {};
if (groupName) {
- if (!C.hardpoints[groupName]) {
+ var grpCode = GrpNameToCodeMap[groupName];
+ if (grpCode && !C.hardpoints[grpCode]) {
throw 'Invalid internal group: ' + groupName;
}
- groups[groupName] = C.hardpoints[groupName];
+ groups[grpCode] = C.hardpoints[grpCode];
} else if (name) {
groups = C.hardpoints;
} else {
diff --git a/app/less/app.less b/app/less/app.less
index 840a8868..c0cb83ec 100755
--- a/app/less/app.less
+++ b/app/less/app.less
@@ -84,6 +84,14 @@ div, a, li {
text-align: center;
}
+.cap {
+ text-transform: capitalize;
+}
+
+.upp {
+ text-transform: uppercase;
+}
+
.scroll-x {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
@@ -114,6 +122,7 @@ h3 {
u { // Unit (Mj, Km, etc)
font-size: 0.8em;
text-decoration: none;
+ text-transform: none;
}
a, a:visited {
diff --git a/app/less/buttons.less b/app/less/buttons.less
index c2cdb2a5..5b565a68 100755
--- a/app/less/buttons.less
+++ b/app/less/buttons.less
@@ -5,6 +5,7 @@ button {
fill: @primary;
}
border: none;
+ text-transform: capitalize;
font-family: @fStandard;
vertical-align: middle;
padding: 0.5em;
diff --git a/app/less/header.less b/app/less/header.less
index 948d6d66..c36cbf0a 100755
--- a/app/less/header.less
+++ b/app/less/header.less
@@ -50,6 +50,7 @@ header {
padding : 0 1em;
cursor: pointer;
color: @warning;
+ text-transform: capitalize;
// Less than 600px screen width: hide text
&.disabled {
diff --git a/app/less/select.less b/app/less/select.less
index 84431173..93abae7c 100755
--- a/app/less/select.less
+++ b/app/less/select.less
@@ -113,6 +113,10 @@ select {
}
}
+ .lc {
+ text-overflow: ellipsis;
+ }
+
.c {
display: inline-block;
width: 2em;
diff --git a/app/less/slot.less b/app/less/slot.less
index 360db1aa..4a4c7fa6 100755
--- a/app/less/slot.less
+++ b/app/less/slot.less
@@ -36,6 +36,7 @@
}
.l {
+ text-transform: capitalize;
margin-right: 0.8em;
}
@@ -55,6 +56,7 @@
}
.empty {
+ text-transform: uppercase;
font-size: 1.3em;
color: lighten(@primary-bg, 12%);
text-align: center;
diff --git a/app/views/_header.html b/app/views/_header.html
index f1d4f5b0..e8fe87bd 100755
--- a/app/views/_header.html
+++ b/app/views/_header.html
@@ -1,5 +1,5 @@
@@ -7,8 +7,8 @@
@@ -16,7 +16,7 @@