diff --git a/app/js/controllers/controller-import.js b/app/js/controllers/controller-import.js index 43327c74..d3beea0f 100755 --- a/app/js/controllers/controller-import.js +++ b/app/js/controllers/controller-import.js @@ -1,88 +1,110 @@ -angular.module('app').controller('ImportController', ['$scope', '$stateParams', 'ShipsDB', 'Ship', 'Persist', 'Serializer', function($scope, $stateParams, Ships, Ship, Persist, Serializer) { +angular.module('app').controller('ImportController', ['lodash', '$rootScope', '$scope', '$stateParams', 'ShipsDB', 'Ship', 'Persist', 'Serializer', function(_, $rootScope, $scope, $stateParams, Ships, Ship, Persist, Serializer) { $scope.jsonValid = false; - $scope.importData = null; + $scope.importJSON = null; $scope.errorMsg = null; $scope.canEdit = true; $scope.builds = $stateParams.obj || null; $scope.ships = Ships; - $scope.validateJson = function() { - var importObj = null, shipData = null; - $scope.jsonValid = false; - $scope.errorMsg = null; - $scope.builds = null; + function validateBuild(shipId, code, name) { + var shipData = Ships[shipId]; - if (!$scope.importData) { return; } + if (!shipData) { + throw '"' + shipId + '" is not a valid Ship Id!'; + } + if (typeof name != 'string' || name.length < 3) { + throw shipData.properties.name + ' build "' + name + '" must be a string at least 3 characters long!'; + } + if (typeof code != 'string' || code.length < 10) { + throw shipData.properties.name + ' build "' + name + '" is not valid!'; + } + try { + Serializer.toShip(new Ship(shipId, shipData.properties, shipData.slots), code); + } catch (e) { + throw shipData.properties.name + ' build "' + name + '" is not valid!'; + } + } + + function detailedJsonToBuild(detailedBuild) { + var ship; + if (!detailedBuild.name) { + throw 'Build Name missing!'; + } try { - importObj = angular.fromJson($scope.importData); + ship = Serializer.fromDetailedBuild(detailedBuild); + } catch (e) { + throw detailedBuild.ship + ' Build "' + detailedBuild.name + '": Invalid data'; + } + + return { shipId: ship.id, name: detailedBuild.name, code: Serializer.fromShip(ship) }; + } + + function importBackup(importData) { + if (importData.builds && typeof importData.builds == 'object') { + for (var shipId in importData.builds) { + for (var buildName in importData.builds[shipId]) { + validateBuild(shipId, importData.builds[shipId][buildName], buildName); + } + } + $scope.builds = importData.builds; + } else { + throw 'builds must be an object!'; + } + if (importData.comparisons) { + // TODO: check ship/builds exist for comparison + $scope.comparisons = importData.comparisons; + } + if (importData.discounts instanceof Array && importData.discounts.length == 2) { + $scope.discounts = importData.discounts; + } + if (typeof importData.insurance == 'string' && importData.insurance.length > 3) { + $scope.insurance = importData.insurance; + } + } + + function importDetailedArray(importArr) { + var builds = {}; + for (var i = 0, l = importArr.length; i < l; i++) { + var build = detailedJsonToBuild(importArr[i]); + if (!builds[build.shipId]) { + builds[build.shipId] = {}; + } + builds[build.shipId][build.name] = build.code; + } + $scope.builds = builds; + } + + $scope.validateJson = function() { + var importData = null; + $scope.jsonValid = false; + $scope.errorMsg = null; + $scope.builds = $scope.discounts = $scope.comparisons = $scope.insurance = null; + + if (!$scope.importJSON) { return; } + + try { + importData = angular.fromJson($scope.importJSON); } catch (e) { $scope.errorMsg = 'Cannot Parse JSON!'; return; } - if (typeof importObj != 'object') { + if (!importData || typeof importData != 'object') { $scope.errorMsg = 'Must be an object or array!'; return; } - // Using JSON from a simple/shortform/standard export - if (importObj.builds && Object.keys(importObj.builds).length) { - for (var shipId in importObj.builds) { - shipData = Ships[shipId]; - if (shipData) { - for (var buildName in importObj.builds[shipId]) { - if (typeof importObj.builds[shipId][buildName] != 'string') { - $scope.errorMsg = shipData.properties.name + ' build "' + buildName + '" must be a string!'; - return; - } - try { - // Actually build the ship with the code to ensure it's valid - Serializer.toShip(new Ship(shipId, shipData.properties, shipData.slots), importObj.builds[shipId][buildName]); - } catch (e) { - $scope.errorMsg = shipData.properties.name + ' build "' + buildName + '" is not valid!'; - return; - } - } - } else { - $scope.errorMsg = '"' + shipId + '"" is not a valid Ship Id!'; - return; - } - $scope.builds = importObj.builds; + try { + if (importData instanceof Array) { // Must be detailed export json + importDetailedArray(importData); + } else if (importData.ship && importData.name) { // Using JSON from a single ship build export + importDetailedArray([importData]); // Convert to array with singleobject + } else { // Using Backup JSON + importBackup(importData); } - - // Using JSON from a detailed export - } else if (importObj.length && importObj[0].references && importObj[0].references.length) { - var builds = {}; - for (var i = 0, l = importObj.length; i < l; i++) { - if (typeof importObj[i].name != 'string' || typeof importObj[i].ship != 'string') { - $scope.errorMsg = 'Build [' + i + '] must have a ship and build name!'; - return; - } - for (var r = 0, rl = importObj[i].references.length; r < rl; r++) { - var ref = importObj[i].references[r]; - if (ref.name == 'Coriolis.io' && ref.code && ref.shipId) { - if (!builds[ref.shipId]) { - builds[ref.shipId] = {}; - } - try { - // Actually build the ship with the code to ensure it's valid - shipData = Ships[ref.shipId]; - Serializer.toShip(new Ship(ref.shipId, shipData.properties, shipData.slots), ref.code); - } catch (e) { - $scope.errorMsg = importObj[i].ship + ' build "' + importObj[i].name + '" is not valid!'; - return; - } - builds[ref.shipId][importObj[i].name] = ref.code; - } else { - $scope.errorMsg = importObj[i].ship + ' build "' + importObj[i].name + '" has an invalid Coriolis reference!'; - return; - } - } - } - $scope.builds = builds; - } else { - $scope.errorMsg = 'No builds in data'; + } catch (e) { + $scope.errorMsg = e; return; } @@ -93,32 +115,73 @@ angular.module('app').controller('ImportController', ['$scope', '$stateParams', return Persist.getBuild(shipId, name) !== null; }; + $scope.hasComparison = function(name) { + return Persist.getComparison(name) !== null; + }; + $scope.process = function() { - var builds = $scope.builds; - for (var shipId in builds) { - for (var buildName in builds[shipId]) { - var code = builds[shipId][buildName]; - // Update builds object such that orginal name retained, but can be renamed - builds[shipId][buildName] = { - code: code, - useName: buildName - }; + if ($scope.builds) { + var builds = $scope.builds; + for (var shipId in builds) { + for (var buildName in builds[shipId]) { + var code = builds[shipId][buildName]; + // Update builds object such that orginal name retained, but can be renamed + builds[shipId][buildName] = { + code: code, + useName: buildName + }; + } } } + + if ($scope.comparisons) { + var comparisons = $scope.comparisons; + for (var name in comparisons) { + comparisons[name].useName = name; + } + } + $scope.processed = true; }; $scope.import = function() { - var builds = $scope.builds; - for (var shipId in builds) { - for (var buildName in builds[shipId]) { - var build = builds[shipId][buildName]; - var name = build.useName.trim(); - if (name) { - Persist.saveBuild(shipId, name, build.code); + + if ($scope.builds) { + var builds = $scope.builds; + for (var shipId in builds) { + for (var buildName in builds[shipId]) { + var build = builds[shipId][buildName]; + var name = build.useName.trim(); + if (name) { + Persist.saveBuild(shipId, name, build.code); + } } } } + + if ($scope.comparisons) { + var comparisons = $scope.comparisons; + for (var comp in comparisons) { + var comparison = comparisons[comp]; + var useName = comparison.useName.trim(); + if (useName) { + Persist.saveComparison(useName, comparison.builds, comparison.facets); + } + } + } + + if ($scope.discounts) { + $rootScope.discounts.ship = $scope.discounts[0]; + $rootScope.discounts.components = $scope.discounts[1]; + $rootScope.$broadcast('discountChange'); + Persist.setDiscount($scope.discounts); + } + + if ($scope.insurance) { + $rootScope.insurance.current = $scope.insurance; + Persist.setInsurance($scope.insurance); + } + $scope.$parent.dismiss(); }; diff --git a/app/js/controllers/controller-outfit.js b/app/js/controllers/controller-outfit.js index c9f8eb3e..4bd10235 100755 --- a/app/js/controllers/controller-outfit.js +++ b/app/js/controllers/controller-outfit.js @@ -219,6 +219,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', data: Serializer.toDetailedBuild($scope.buildName, ship, $scope.code || Serializer.fromShip(ship)) }); } diff --git a/app/js/directives/directive-header.js b/app/js/directives/directive-header.js index 9b2b368a..2f707d30 100755 --- a/app/js/directives/directive-header.js +++ b/app/js/directives/directive-header.js @@ -33,11 +33,26 @@ angular.module('app').directive('shipyardHeader', ['lodash', '$rootScope', '$sta $rootScope.$broadcast('discountChange'); }; + scope.backup = function(e) { + e.preventDefault(); + e.stopPropagation(); + scope.openedMenu = null; + $state.go('modal.export', { + title: 'Backup', + data: Persist.getAll(), + description: 'Backup of all Coriolis data to save or transfer to another browser/device' + }); + }; + scope.detailedExport = function(e) { e.preventDefault(); e.stopPropagation(); scope.openedMenu = null; - $state.go('modal.export', { data: Serializer.toDetailedExport(scope.allBuilds) }); + $state.go('modal.export', { + title: 'Detailed Export', + data: Serializer.toDetailedExport(scope.allBuilds), + description: 'Detailed export of all builds for use with other tools and sites' + }); }; scope.openMenu = function(e, menu) { diff --git a/app/js/service-persist.js b/app/js/service-persist.js index 3878bff5..38da1bfe 100755 --- a/app/js/service-persist.js +++ b/app/js/service-persist.js @@ -120,7 +120,7 @@ angular.module('app').service('Persist', ['$window', 'lodash', function($window, } this.comparisons[name] = { facets: facets, - builds: _.map(builds, function(b) { return { shipId: b.id, buildName: b.buildName }; }) + builds: _.map(builds, function(b) { return { shipId: b.id || b.shipId, buildName: b.buildName }; }) }; localStorage.setItem(LS_KEY_COMPARISONS, angular.toJson(this.comparisons)); this.state.hasComparisons = true; diff --git a/app/js/service-serializer.js b/app/js/service-serializer.js index 32761c9e..d42c4c36 100755 --- a/app/js/service-serializer.js +++ b/app/js/service-serializer.js @@ -1,7 +1,7 @@ /** * Service managing seralization and deserialization of models for use in URLs and persistene. */ -angular.module('app').service('Serializer', ['lodash', 'GroupMap', 'MountMap', 'ShipsDB', 'Ship', '$state', function(_, GroupMap, MountMap, ShipsDB, Ship, $state) { +angular.module('app').service('Serializer', ['lodash', 'GroupMap', 'MountMap', 'ShipsDB', 'Ship', 'Components', '$state', function(_, GroupMap, MountMap, ShipsDB, Ship, Components, $state) { /** * Serializes the ships selected components for all slots to a URL friendly string. @@ -108,6 +108,46 @@ angular.module('app').service('Serializer', ['lodash', 'GroupMap', 'MountMap', ' return data; }; + this.fromDetailedBuild = function(detailedBuild) { + var shipId = _.findKey(ShipsDB, { properties: { name: detailedBuild.ship } }); + + if (!shipId) { + throw 'No such ship: ' + detailedBuild.ship; + } + + var comps = detailedBuild.components; + var shipData = ShipsDB[shipId]; + var ship = new Ship(shipId, shipData.properties, shipData.slots); + var bulkheads = Components.bulkheadIndex(comps.standard.bulkheads); + + if (bulkheads < 0) { + throw 'Invalid bulkheads: ' + comps.standard.bulkheads; + } + + var common = _.map( + ['powerPlant', 'thrusters', 'frameShiftDrive', 'lifeSupport', 'powerDistributor', 'sensors', 'fuelTank'], + function(c) { + if (!comps.standard[c].class || !comps.standard[c].rating) { + throw 'Invalid value for ' + c; + } + return comps.standard[c].class + comps.standard[c].rating; + } + ); + + var internal = _.map(comps.internal, function(c) { return c ? Components.findInternalId(c.group, c.class, c.rating, c.name) : 0; }); + + var hardpoints = _.map(comps.hardpoints, function(c) { + return c ? Components.findHardpointId(c.group, c.class, c.rating, c.name, MountMap[c.mount], c.missile) : 0; + }); + hardpoints = hardpoints.concat(_.map(comps.utility, function(c) { + return c ? Components.findHardpointId(c.group, c.class, c.rating, c.name, MountMap[c.mount]) : 0; + })); + + ship.buildWith({ bulkheads: bulkheads, common: common, hardpoints: hardpoints, internal: internal }); + + return ship; + }; + this.toDetailedExport = function(builds) { var data = []; @@ -180,6 +220,9 @@ angular.module('app').service('Serializer', ['lodash', 'GroupMap', 'MountMap', ' if (slot.c.mode) { o.mount = MountMap[slot.c.mode]; } + if (slot.c.missile) { + o.missile = slot.c.missile; + } return o; } return null; diff --git a/app/js/shipyard/module-shipyard.js b/app/js/shipyard/module-shipyard.js index d56b825e..d3323e0d 100755 --- a/app/js/shipyard/module-shipyard.js +++ b/app/js/shipyard/module-shipyard.js @@ -32,7 +32,7 @@ angular.module('shipyard', ['ngLodash']) // Internal fs: 'Fuel Scoop', - sc: 'Scanners', + sc: 'Scanner', am: 'Auto Field-Maintenance Unit', cr: 'Cargo Rack', fi: 'FSD Interdictor', @@ -69,7 +69,10 @@ angular.module('shipyard', ['ngLodash']) .value('MountMap', { 'F': 'Fixed', 'G': 'Gimballed', - 'T': 'Turret' + 'T': 'Turret', + 'Fixed': 'F', + 'Gimballed': 'G', + 'Turret': 'T' }) .value('shipSize', [ 'N/A', diff --git a/app/js/shipyard/service-components.js b/app/js/shipyard/service-components.js index de59dc2a..b5e8847a 100755 --- a/app/js/shipyard/service-components.js +++ b/app/js/shipyard/service-components.js @@ -32,6 +32,41 @@ angular.module('shipyard').service('Components', ['lodash', 'ComponentsDB', 'Shi return null; }; + this.findInternalId = function(groupName, clss, rating, name) { + var group = C.internal[groupName]; + + if (!group) { + throw 'Invalid internal group: ' + groupName; + } + + for (var i = 0, l = group.length; i < l; i++) { + if (group[i].class == clss && group[i].rating == rating && ((!name && !group[i].name) || group[i].name == name)) { + return group[i].id; + } + } + + return 0; + }; + + this.findHardpointId = function(groupName, clss, rating, name, mode, missile) { + var group = C.hardpoints[groupName]; + + if (!group) { + throw 'Invalid hardpoint group: ' + groupName; + } + + for (var i = 0, l = group.length; i < l; i++) { + if (group[i].class == clss && group[i].rating == rating && group[i].mode == mode + && ((!name && !group[i].name) || group[i].name == name) + && ((!missile && !group[i].missile) || group[i].missile == missile) + ) { + return group[i].id; + } + } + + return 0; + }; + /** * Looks up the bulkhead component for a specific ship and bulkhead * @param {string} shipId Unique ship Id/Key @@ -42,6 +77,10 @@ angular.module('shipyard').service('Components', ['lodash', 'ComponentsDB', 'Shi return C.bulkheads[shipId][bulkheadsId]; }; + this.bulkheadIndex = function(bulkheadName) { + return ['Lightweight Alloy', 'Reinforced Alloy', 'Military Grade Composite', 'Mirrored Surface Composite', 'Reactive Surface Composite'].indexOf(bulkheadName); + }; + /** * Creates a new ComponentSet that contains all available components * that the specified ship is eligible to use. diff --git a/app/views/_header.html b/app/views/_header.html index ca9cacae..f1d4f5b0 100755 --- a/app/views/_header.html +++ b/app/views/_header.html @@ -63,8 +63,8 @@
diff --git a/app/views/modal-import.html b/app/views/modal-import.html index 38bdeb75..4cf89df4 100755 --- a/app/views/modal-import.html +++ b/app/views/modal-import.html @@ -1,24 +1,38 @@

Import

- +
{{errorMsg}}
- + -
ShipBuild NameAction
ShipBuild NameAction
{{ships[shipId].properties.name}} + {{ hasBuild(shipId, b.useName)? 'Overwrite' : 'Create' }} Skip
+ + + + + + + + + +
ComparisonAction
+ {{ hasComparison(comparison.useName)? 'Overwrite' : 'Create' }} + Skip +
+
diff --git a/data/components/hardpoints/beam_laser.json b/data/components/hardpoints/beam_laser.json index 9b7cf306..8bc7c13b 100755 --- a/data/components/hardpoints/beam_laser.json +++ b/data/components/hardpoints/beam_laser.json @@ -1,5 +1,5 @@ { - "Beam Lasers" : [ + "Beam Laser": [ { "id": "0u", "grp": "bl", diff --git a/data/components/hardpoints/burst_laser.json b/data/components/hardpoints/burst_laser.json index 77baf857..6f87119f 100755 --- a/data/components/hardpoints/burst_laser.json +++ b/data/components/hardpoints/burst_laser.json @@ -1,5 +1,5 @@ { - "Burst Lasers": [ + "Burst Laser": [ { "id": "14", "grp": "ul", diff --git a/data/components/hardpoints/cannon.json b/data/components/hardpoints/cannon.json index 79f1df2d..855af125 100755 --- a/data/components/hardpoints/cannon.json +++ b/data/components/hardpoints/cannon.json @@ -1,5 +1,5 @@ { - "Cannons": [ + "Cannon": [ { "id": "1q", "grp": "c", diff --git a/data/components/hardpoints/cargo_scanner.json b/data/components/hardpoints/cargo_scanner.json index 2d1b9d63..b7cd02d6 100755 --- a/data/components/hardpoints/cargo_scanner.json +++ b/data/components/hardpoints/cargo_scanner.json @@ -1,5 +1,5 @@ { - "Cargo Scanners": [ + "Cargo Scanner": [ { "id": "0d", "grp": "cs", diff --git a/data/components/hardpoints/countermeasures.json b/data/components/hardpoints/countermeasures.json index c64fd1d1..10d30289 100755 --- a/data/components/hardpoints/countermeasures.json +++ b/data/components/hardpoints/countermeasures.json @@ -1,5 +1,5 @@ { - "Countermeasures": [ + "Countermeasure": [ { "id": "00", "grp": "cm", diff --git a/data/components/hardpoints/fragment_cannon.json b/data/components/hardpoints/fragment_cannon.json index 6da2e684..e008e682 100755 --- a/data/components/hardpoints/fragment_cannon.json +++ b/data/components/hardpoints/fragment_cannon.json @@ -1,5 +1,5 @@ { - "Fragment Cannons": [ + "Fragment Cannon": [ { "id": "1t", "grp": "fc", diff --git a/data/components/hardpoints/frame_shift_wake_scanner.json b/data/components/hardpoints/frame_shift_wake_scanner.json index 01e86618..2c52b587 100755 --- a/data/components/hardpoints/frame_shift_wake_scanner.json +++ b/data/components/hardpoints/frame_shift_wake_scanner.json @@ -1,5 +1,5 @@ { - "Frame Shift Wake Scanners": [ + "Frame Shift Wake Scanner": [ { "id": "0i", "grp": "ws", diff --git a/data/components/hardpoints/kill_warrant_scanner.json b/data/components/hardpoints/kill_warrant_scanner.json index b0d06423..c6b84dac 100755 --- a/data/components/hardpoints/kill_warrant_scanner.json +++ b/data/components/hardpoints/kill_warrant_scanner.json @@ -1,5 +1,5 @@ { - "Kill Warrant Scanners": [ + "Kill Warrant Scanner": [ { "id": "0n", "grp": "kw", diff --git a/data/components/hardpoints/mine_launcher.json b/data/components/hardpoints/mine_launcher.json index 2eb8b462..adb450c2 100755 --- a/data/components/hardpoints/mine_launcher.json +++ b/data/components/hardpoints/mine_launcher.json @@ -1,5 +1,5 @@ { - "Mine Launchers": [ + "Mine Launcher": [ { "id": "2j", "grp": "nl", diff --git a/data/components/hardpoints/mining_laser.json b/data/components/hardpoints/mining_laser.json index d9a82ba4..7b88a8e0 100755 --- a/data/components/hardpoints/mining_laser.json +++ b/data/components/hardpoints/mining_laser.json @@ -1,5 +1,5 @@ { - "Mining Lasers": [ + "Mining Laser": [ { "id": "2l", "grp": "ml", diff --git a/data/components/hardpoints/missile_rack.json b/data/components/hardpoints/missile_rack.json index 9f9d2523..4b7e7146 100755 --- a/data/components/hardpoints/missile_rack.json +++ b/data/components/hardpoints/missile_rack.json @@ -1,5 +1,5 @@ { - "Missile Racks": [ + "Missile Rack": [ { "id": "2f", "grp": "mr", diff --git a/data/components/hardpoints/multi_cannon.json b/data/components/hardpoints/multi_cannon.json index 1c2b9116..b69c0dea 100755 --- a/data/components/hardpoints/multi_cannon.json +++ b/data/components/hardpoints/multi_cannon.json @@ -1,5 +1,5 @@ { - "Multi-cannons": [ + "Multi-cannon": [ { "id": "26", "grp": "mc", diff --git a/data/components/hardpoints/plasma_accelerator.json b/data/components/hardpoints/plasma_accelerator.json index d7c8ddb1..b0c2c720 100755 --- a/data/components/hardpoints/plasma_accelerator.json +++ b/data/components/hardpoints/plasma_accelerator.json @@ -1,5 +1,5 @@ { - "Plasma Accelerators": [ + "Plasma Accelerator": [ { "id": "1g", "grp": "pa", diff --git a/data/components/hardpoints/pulse_laser.json b/data/components/hardpoints/pulse_laser.json index 3a4d59bf..54aadd43 100755 --- a/data/components/hardpoints/pulse_laser.json +++ b/data/components/hardpoints/pulse_laser.json @@ -1,5 +1,5 @@ { - "Pulse Lasers": [ + "Pulse Laser": [ { "id": "1d", "grp": "pl", diff --git a/data/components/hardpoints/rail_gun.json b/data/components/hardpoints/rail_gun.json index 23ce4369..fd32cfbe 100755 --- a/data/components/hardpoints/rail_gun.json +++ b/data/components/hardpoints/rail_gun.json @@ -1,5 +1,5 @@ { - "Rail Guns": [ + "Rail Gun": [ { "id": "29", "grp": "rg", diff --git a/data/components/hardpoints/shield_booster.json b/data/components/hardpoints/shield_booster.json index 435af7df..747dbafe 100755 --- a/data/components/hardpoints/shield_booster.json +++ b/data/components/hardpoints/shield_booster.json @@ -1,5 +1,5 @@ { - "Shield Boosters": [ + "Shield Booster": [ { "id": "08", "grp": "sb", diff --git a/data/components/hardpoints/torpedo_pylon.json b/data/components/hardpoints/torpedo_pylon.json index af18a74e..4617614d 100755 --- a/data/components/hardpoints/torpedo_pylon.json +++ b/data/components/hardpoints/torpedo_pylon.json @@ -1,5 +1,5 @@ { - "Torpedo Pylons": [ + "Torpedo Pylon": [ { "id": "2h", "grp": "tp", diff --git a/data/components/internal/auto_field_maintenance_unit.json b/data/components/internal/auto_field_maintenance_unit.json index 1cab6262..4b0c742d 100755 --- a/data/components/internal/auto_field_maintenance_unit.json +++ b/data/components/internal/auto_field_maintenance_unit.json @@ -1,5 +1,5 @@ { - "Auto Field-Maintenance Units": [ + "Auto Field-Maintenance Unit": [ { "id": "1f", "grp": "am", diff --git a/data/components/internal/cargo_rack.json b/data/components/internal/cargo_rack.json index 67722dc2..3cc2b72e 100755 --- a/data/components/internal/cargo_rack.json +++ b/data/components/internal/cargo_rack.json @@ -1,5 +1,5 @@ { - "Cargo Racks": [ + "Cargo Rack": [ { "id": "00", "grp": "cr", "class": 1, "rating": "E", "cost": 1000, "capacity": 2 }, { "id": "01", "grp": "cr", "class": 2, "rating": "E", "cost": 3250, "capacity": 4 }, { "id": "02", "grp": "cr", "class": 3, "rating": "E", "cost": 10563, "capacity": 8 }, diff --git a/data/components/internal/collector_limpet_controllers.json b/data/components/internal/collector_limpet_controllers.json index 715bd2fc..ece3c658 100644 --- a/data/components/internal/collector_limpet_controllers.json +++ b/data/components/internal/collector_limpet_controllers.json @@ -1,5 +1,5 @@ { - "Collector Limpet Controllers": [ + "Collector Limpet Controller": [ { "id": "Cf", "grp":"cc", "class":7, "rating":"E", "cost": 437400, "mass": 32.0, "power":0.41, "range":1.36, "maximum": 4, "time":300 }, { "id": "Cg", "grp":"cc", "class":7, "rating":"D", "cost": 874800, "mass": 32.0, "power":0.55, "range":1.02, "maximum": 4, "time":600 }, { "id": "Ch", "grp":"cc", "class":7, "rating":"C", "cost":1749600, "mass": 80.0, "power":0.69, "range":1.70, "maximum": 4, "time":510 }, diff --git a/data/components/internal/docking_computer.json b/data/components/internal/docking_computer.json index a8ee50e0..2e6790dd 100755 --- a/data/components/internal/docking_computer.json +++ b/data/components/internal/docking_computer.json @@ -1,5 +1,5 @@ { - "Docking Computers": [ + "Docking Computer": [ { "id": "24", "grp": "dc", diff --git a/data/components/internal/frame_shift_drive_interdictor.json b/data/components/internal/frame_shift_drive_interdictor.json index 25d0127e..95e50909 100755 --- a/data/components/internal/frame_shift_drive_interdictor.json +++ b/data/components/internal/frame_shift_drive_interdictor.json @@ -1,5 +1,5 @@ { - "FSD Interdictors": [ + "FSD Interdictor": [ { "id": "6p", "grp": "fi", diff --git a/data/components/internal/fuel_scoops.json b/data/components/internal/fuel_scoop.json similarity index 99% rename from data/components/internal/fuel_scoops.json rename to data/components/internal/fuel_scoop.json index f6ce03dc..96a26683 100755 --- a/data/components/internal/fuel_scoops.json +++ b/data/components/internal/fuel_scoop.json @@ -1,5 +1,5 @@ { - "Fuel Scoops": [ + "Fuel Scoop": [ { "id": "3q", "grp": "fs", diff --git a/data/components/internal/fuel_transfer_limpet_controllers.json b/data/components/internal/fuel_transfer_limpet_controllers.json index b850546e..25ee11e4 100644 --- a/data/components/internal/fuel_transfer_limpet_controllers.json +++ b/data/components/internal/fuel_transfer_limpet_controllers.json @@ -1,5 +1,5 @@ { - "Fuel Transfer Limpet Controllers": [ + "Fuel Transfer Limpet Controller": [ { "id": "Ff", "grp":"fx", "class":7, "rating":"E", "cost": 437400, "mass": 80.0, "power":0.55, "range":1.02, "maximum": 8 }, { "id": "Fg", "grp":"fx", "class":7, "rating":"D", "cost": 874800, "mass": 32.0, "power":0.41, "range":1.36, "maximum": 8 }, { "id": "Fh", "grp":"fx", "class":7, "rating":"C", "cost":1749600, "mass": 80.0, "power":0.69, "range":1.70, "maximum": 8 }, diff --git a/data/components/internal/hatch_breaker_limpet_controller.json b/data/components/internal/hatch_breaker_limpet_controller.json index 8f0361e7..c6f2d8cf 100755 --- a/data/components/internal/hatch_breaker_limpet_controller.json +++ b/data/components/internal/hatch_breaker_limpet_controller.json @@ -1,5 +1,5 @@ { - "Hatch Breaker Limpet Controllers": [ + "Hatch Breaker Limpet Controller": [ { "id": "7d", "grp": "hb", diff --git a/data/components/internal/hull_reinforcement_package.json b/data/components/internal/hull_reinforcement_package.json index 529f74bc..9bf9aa39 100755 --- a/data/components/internal/hull_reinforcement_package.json +++ b/data/components/internal/hull_reinforcement_package.json @@ -1,5 +1,5 @@ { - "Hull Reinforcement Packages": [ + "Hull Reinforcement Package": [ { "id": "2e", "grp": "hr", diff --git a/data/components/internal/pristmatic_shield_generators.json b/data/components/internal/pristmatic_shield_generator.json similarity index 97% rename from data/components/internal/pristmatic_shield_generators.json rename to data/components/internal/pristmatic_shield_generator.json index b01fa745..5c903dbc 100644 --- a/data/components/internal/pristmatic_shield_generators.json +++ b/data/components/internal/pristmatic_shield_generator.json @@ -1,5 +1,5 @@ { - "Prismatic Shield Generators": [ + "Prismatic Shield Generator": [ { "id": "p6", "grp": "psg", "class": 1, "rating": "A", "cost": 132195, "mass": 2.5, "power": 2.52, "minmass": 13, "optmass": 25, "maxmass": 63, "minmul": 2.04, "optmul": 1.44, "maxmul": 0.84 }, { "id": "p5", "grp": "psg", "class": 2, "rating": "A", "cost": 240336, "mass": 5, "power": 3.15, "minmass": 23, "optmass": 55, "maxmass": 138, "minmul": 2.04, "optmul": 1.44, "maxmul": 0.84 }, { "id": "p4", "grp": "psg", "class": 3, "rating": "A", "cost": 761868, "mass": 10, "power": 3.78, "minmass": 83, "optmass": 165, "maxmass": 413, "minmul": 2.04, "optmul": 1.44, "maxmul": 0.84 }, diff --git a/data/components/internal/prospector_limpet_controllers.json b/data/components/internal/prospector_limpet_controllers.json index ca55b587..43fdaadf 100644 --- a/data/components/internal/prospector_limpet_controllers.json +++ b/data/components/internal/prospector_limpet_controllers.json @@ -1,5 +1,5 @@ { - "Prospector Limpet Controllers": [ + "Prospector Limpet Controller": [ { "id": "Pf", "grp":"pc", "class":7, "rating":"E", "cost": 437400, "mass": 80.0, "power":0.55, "range": 5.10, "maximum": 8 }, { "id": "Pg", "grp":"pc", "class":7, "rating":"D", "cost": 874800, "mass": 32.0, "power":0.41, "range": 6.80, "maximum": 8 }, { "id": "Ph", "grp":"pc", "class":7, "rating":"C", "cost":1749600, "mass": 80.0, "power":0.69, "range": 8.50, "maximum": 8 }, diff --git a/data/components/internal/refinery.json b/data/components/internal/refinery.json index db722ed3..22c306f7 100755 --- a/data/components/internal/refinery.json +++ b/data/components/internal/refinery.json @@ -1,5 +1,5 @@ { - "Refineries": [ + "Refinery": [ { "id": "23", "grp": "rf", diff --git a/data/components/internal/scanners.json b/data/components/internal/scanner.json similarity index 88% rename from data/components/internal/scanners.json rename to data/components/internal/scanner.json index fdca28c1..93435709 100755 --- a/data/components/internal/scanners.json +++ b/data/components/internal/scanner.json @@ -1,9 +1,9 @@ { - "Scanners": [ + "Scanner": [ { "id": "2f", "grp": "sc", - "name": "Adv. Discovery Scanner", + "name": "Advanced Discovery Scanner", "class": 1, "rating": "C", "cost": 1545000, @@ -14,7 +14,7 @@ { "id": "2g", "grp": "sc", - "name": "Inter. Discovery Scanner", + "name": "Intermediate Discovery Scanner", "class": 1, "rating": "D", "cost": 505000, diff --git a/data/components/internal/shield_cell_bank.json b/data/components/internal/shield_cell_bank.json index b4fd0263..d728ce9d 100755 --- a/data/components/internal/shield_cell_bank.json +++ b/data/components/internal/shield_cell_bank.json @@ -1,5 +1,5 @@ { - "Shield Cell Banks": [ + "Shield Cell Bank": [ { "id": "65", "grp": "scb", "class": 8, "rating": "E", "cost": 697584, "mass": 160, "power": 1.44, "cells": 5, "rechargeRating": "C", "recharge": 0 }, { "id": "64", "grp": "scb", "class": 8, "rating": "D", "cost": 1743961, "mass": 64, "power": 1.92, "cells": 3, "rechargeRating": "C", "recharge": 0 }, { "id": "63", "grp": "scb", "class": 8, "rating": "C", "cost": 4359903, "mass": 160, "power": 2.4, "cells": 4, "rechargeRating": "B", "recharge": 0 }, diff --git a/data/components/internal/shield_generator.json b/data/components/internal/shield_generator.json index e0db2043..d6e3e55b 100755 --- a/data/components/internal/shield_generator.json +++ b/data/components/internal/shield_generator.json @@ -1,5 +1,5 @@ { - "Shield Generators": [ + "Shield Generator": [ { "id": "4t", "grp": "sg", "class": 8, "rating": "E", "cost": 2007241, "mass": 160, "power": 2.4, "minmass": 900, "optmass": 1800, "maxmass": 4500, "minmul": 1.3, "optmul": 0.8, "maxmul": 0.3 }, { "id": "4s", "grp": "sg", "class": 8, "rating": "D", "cost": 6021722, "mass": 64, "power": 3.2, "minmass": 900, "optmass": 1800, "maxmass": 4500, "minmul": 1.4, "optmul": 0.9, "maxmul": 0.4 }, { "id": "4r", "grp": "sg", "class": 8, "rating": "C", "cost": 18065165, "mass": 160, "power": 4, "minmass": 900, "optmass": 1800, "maxmass": 4500, "minmul": 1.5, "optmul": 1, "maxmul": 0.5 }, diff --git a/scripts/json-to-db.js b/scripts/json-to-db.js index 242d0ff8..c200e0cf 100755 --- a/scripts/json-to-db.js +++ b/scripts/json-to-db.js @@ -30,23 +30,23 @@ function writeDB(err, arr) { var shipOrder = Object.keys(arr[0]).sort(); var internalOrder = Object.keys(arr[3]).sort(); var hpOrder = [ - "Pulse Lasers", - "Burst Lasers", - "Beam Lasers", - "Multi-cannons", - "Cannons", - "Fragment Cannons", - "Rail Guns", - "Plasma Accelerators", - "Missile Racks", - "Torpedo Pylons", - "Mine Launchers", - "Mining Lasers", - "Cargo Scanners", - "Countermeasures", - "Frame Shift Wake Scanners", - "Kill Warrant Scanners", - "Shield Boosters" + "Pulse Laser", + "Burst Laser", + "Beam Laser", + "Multi-cannon", + "Cannon", + "Fragment Cannon", + "Rail Gun", + "Plasma Accelerator", + "Missile Rack", + "Torpedo Pylon", + "Mine Launcher", + "Mining Laser", + "Cargo Scanner", + "Countermeasure", + "Frame Shift Wake Scanner", + "Kill Warrant Scanner", + "Shield Booster" ]; for (var i = 0; i < internalOrder.length; i++) { diff --git a/test/fixtures/anaconda-test-detailed-export.json b/test/fixtures/anaconda-test-detailed-export.json index a54bff19..ee9027cd 100644 --- a/test/fixtures/anaconda-test-detailed-export.json +++ b/test/fixtures/anaconda-test-detailed-export.json @@ -5,8 +5,8 @@ "references": [ { "name": "Coriolis.io", - "url": "http://localhost:3300/outfit/anaconda/48A6A6A5A8A8A5C2c0o0o0o1m1m0q0q0404-0l0b0100034k5n052d04--0303326b.AwRj4yo5dig%3D.MwBhEYy6duwEziA?bn=Test", - "code": "48A6A6A5A8A8A5C2c0o0o0o1m1m0q0q0404-0l0b0100034k5n052d04--0303326b.AwRj4yo5dig=.MwBhEYy6duwEziA", + "url": "http://localhost:3300/outfit/anaconda/48A6A6A5A8A8A5C2c0o0o0o1m1m0q0q0404-0l0b0100034k5n052d04--0303326b?bn=Test", + "code": "48A6A6A5A8A8A5C2c0o0o0o1m1m0q0q0404-0l0b0100034k5n052d04--0303326b", "shipId": "anaconda" } ], @@ -205,13 +205,13 @@ "armour": 1185, "totalDps": 29, "powerAvailable": 36, - "powerRetracted": 23.33, - "powerDeployed": 34.96, + "powerRetracted": 23.93, + "powerDeployed": 35.56, "unladenRange": 18.49, "fullTankRange": 18.12, "ladenRange": 16.39, - "unladenTotalRange": 74.45, - "ladenTotalRange": 67.16, + "unladenTotalRange": 73.21, + "ladenTotalRange": 66.15, "maxJumpCount": 4, "shieldStrength": 833 } diff --git a/test/fixtures/expected-builds.json b/test/fixtures/expected-builds.json new file mode 100644 index 00000000..dd97513b --- /dev/null +++ b/test/fixtures/expected-builds.json @@ -0,0 +1,50 @@ +{ + "type_6_transporter": { + "Cargo": "02A4D4A2D2D2D4C-----04040303430101.Iw1-kA==.Aw1-kA==", + "Miner": "03A4D4A2D2D2D4C2l2l---040403451q0101.Iw1-kA==.Aw1-kA==", + "Hopper": "02A4D4A2D1A2D4C1717---030302024300-.Iw1-kA==.Aw1-kA==" + }, + "type_7_transport": { + "Cargo": "02A5D5A4D3D3D5C--------0505040403480101.Iw18aQ==.Aw18aQ==", + "Miner": "04D5D5A4D2D3D5C--2l2l----0505041v03450000.Iw18aQ==.Aw18aQ==" + }, + "federal_dropship": { + "Cargo": "04D5D5A5D3D4D4C-1717------05040448020201.Iw18aQ==.Aw18aQ==" + }, + "asp": { + "Miner": "25A5A5A4D4A5A5C0s0s24242l2l---04054a1q02022o27.Iw18WQ==.Aw18WQ==" + }, + "imperial_clipper": { + "Cargo": "03A5D5A5D4D5D4C--0s0s----0605450302020101.Iw18aQ==.Aw18aQ==", + "Dream": "26A6A5A5D6A5A4C0v0v0s0s0404040n4k5n5d2b29292o-.Iw18aQ==.Aw18aQ==", + "Current": "04A6A5A5D4A5A4C----------------.Iw18aQ==.Aw18aQ==" + }, + "type_9_heavy": { + "Current": "04A7D6A5D5D4D6C---------0706054a0303020224.Iw18eQ==.Aw18eQ==" + }, + "python": { + "Cargo": "04A6D5A4D6D6D5C---------050505040448020201.Iw18eQ==.Aw18eQ==", + "Miner": "06A6A5A4D6A6A5C0v0v0v2m2m0404--050505Ce4a1v02022o.Iw18eQ==.Aw18eQ==", + "Dream": "27A6A5A4D7A6A5C0v0v0v27270404040m5n5n4f2d2d032t0201.Iw18eQ==.Aw18eQ==", + "Missile": "07E6E5E4E7E6E5C2f2g2d2ePh----04044j03---002h.Iw18eQ==.Aw18eQ==" + }, + "anaconda": { + "Dream": "48A7A6A5D8A8A5C2c0o0o0o1m1m0q0q0404040l0b0100004k5n5n112d2d040303326b.Iw18ZlA=.Aw18ZlA=", + "Cargo": "04A6D6A5D5D8D5C----------------0605050504040445030301.Iw18ZlA=.Aw18ZlA=", + "Current": "04A6D6A5D5A8D5C----------------0605050504040403034524.Iw18ZlA=.Aw18ZlA=", + "Explorer": "04A6D6A5D5A8D5C--------0202------f7050505040s372f2i4524.Iw18ZlA=.Aw18ZlA=", + "Test": "48A6A6A5A8A8A5C2c0o0o0o1m1m0q0q0404-0l0b0100034k5n052d04--0303326b.Iw18ZlA=.Aw18ZlA=" + }, + "diamondback_explorer": { + "Explorer": "02A4D5A3D3D3D5C---0202--320p432i2f.Iw1-kA==.Aw1-kA==" + }, + "vulture": { + "Bounty Hunter": "34A4C4A3D5A4A3C1e1e0404-0l4a5d27662j.Iw19kA==.Aw19kA==" + }, + "fer_de_lance": { + "Attack": "25A5C4A4D6A4A3C1r0s0s0s0s000404-04-4a-5d27-.Iw18aQ==.Aw18aQ==" + }, + "eagle": { + "Figther": "42A3A3A1D2A2A2C0p0p24-40532j.Iw19A===.Aw19A===" + } +} \ No newline at end of file diff --git a/test/fixtures/old-valid-export.json b/test/fixtures/old-valid-export.json new file mode 100644 index 00000000..52ac702a --- /dev/null +++ b/test/fixtures/old-valid-export.json @@ -0,0 +1,50 @@ +{ + "builds": { + "type_6_transporter": { + "Cargo": "02A4D4A2D2D2D4C-----04040303430101", + "Miner": "03A4D4A2D2D2D4C2l2l---040403451q0101", + "Hopper": "02A4D4A2D1A2D4C1717---030302024300-" + }, + "type_7_transport": { + "Cargo": "02A5D5A4D3D3D5C--------0505040403480101", + "Miner": "04D5D5A4D2D3D5C--2l2l----0505041v03450000" + }, + "federal_dropship": { + "Cargo": "04D5D5A5D3D4D4C-1717------05040448020201" + }, + "asp": { + "Miner": "25A5A5A4D4A5A5C0s0s24242l2l---04054a1q02022o27" + }, + "imperial_clipper": { + "Cargo": "03A5D5A5D4D5D4C--0s0s----0605450302020101", + "Dream": "26A6A5A5D6A5A4C0v0v0s0s0404040n4k5n5d2b29292o-.AwRj4yWU1I==.CwBhCYy6YRigzLIA", + "Current": "04A6A5A5D4A5A4C----------------.AwRj4yWU1I==.CwBhCYy6YRigzLIA" + }, + "type_9_heavy": { + "Current": "04A7D6A5D5D4D6C---------0706054a0303020224.AwRj4yoo.EwBhEYy6dsg=" + }, + "python": { + "Cargo": "04A6D5A4D6D6D5C---------050505040448020201.Iw18eQ==.Aw18eQ==", + "Miner": "06A6A5A4D6A6A5C0v0v0v2m2m0404--050505Ce4a1v02022o.Iw18eQ==.IwBhBYy6dkCYg===", + "Dream": "27A6A5A4D7A6A5C0v0v0v27270404040m5n5n4f2d2d032t0201.Iw1+gDBxA===.EwBhEYy6e0WEA===" + }, + "anaconda": { + "Dream": "48A7A6A5D8A8A5C2c0o0o0o1m1m0q0q0404040l0b0100004k5n5n112d2d040303326b.AwRj4yo5dig=.MwBhCYy6du3ARiA=", + "Cargo": "04A6D6A5D5D8D5C----------------0605050504040445030301.Iw18ZlA=.Aw18ZlA=", + "Current": "04A6D6A5D5A8D5C----------------0605050504040403034524.Iw18ZlA=.Aw18ZlA=", + "Explorer": "04A6D6A5D5A8D5C--------0202------f7050505040s372f2i4524.AwRj4yVKJthA.AwhMIyungRhEA===" + }, + "diamondback_explorer": { + "Explorer": "02A4D5A3D3D3D5C---0202--320p432i2f.AwRj4zTI.AwiMIypI" + }, + "vulture": { + "Bounty Hunter": "34A4C4A3D5A4A3C1e1e0404-0l4a5d27662j.AwRj4y2I.MwBhBYy6wJmAjLIA" + }, + "fer_de_lance": { + "Attack": "25A5C4A4D6A4A3C1r0s0s0s0s000404-04-4a-5d27-.Iw18aQ==.CwBhrSu8EZyA" + }, + "eagle": { + "Figther": "42A3A3A1D2A2A2C0p0p24-40532j.AwRj49iA.AwgsIkEZigmIA===" + } + } +} \ No newline at end of file diff --git a/test/fixtures/valid-backup.json b/test/fixtures/valid-backup.json new file mode 100644 index 00000000..9067d141 --- /dev/null +++ b/test/fixtures/valid-backup.json @@ -0,0 +1,66 @@ +{ + "builds": { + "type_6_transporter": { + "Cargo": "02A4D4A2D2D2D4C-----04040303430101", + "Miner": "03A4D4A2D2D2D4C2l2l---040403451q0101", + "Hopper": "02A4D4A2D1A2D4C1717---030302024300-" + }, + "type_7_transport": { + "Cargo": "02A5D5A4D3D3D5C--------0505040403480101", + "Miner": "04D5D5A4D2D3D5C--2l2l----0505041v03450000" + }, + "federal_dropship": { + "Cargo": "04D5D5A5D3D4D4C-1717------05040448020201" + }, + "asp": { + "Miner": "25A5A5A4D4A5A5C0s0s24242l2l---04054a1q02022o27" + }, + "cobra_mk_iii": { + "Example": "24A4A4A3D3A3A4C0s0s2d2d0m0445032b2o2753.AwRj4yKA.CwBhEYyrKhmMQ===", + }, + "imperial_clipper": { + "Cargo": "03A5D5A5D4D5D4C--0s0s----0605450302020101", + "Multi-purpose": "26A4A5A5D6A5A4C0v0v272704090j0h064f2c0302020101", + "Current": "05A6D5A5D6A5A4C0v0v27270404050n4m05035d29292o01.AwRj4yrI.AwhMIyuBGNiA", + "Dream": "26A6A5A5D6A5A4C0v0v0s0s04040c0n064f5d2b02022o0d.AwRj49UlmI==.AwiMIyuo" + }, + "type_9_heavy": { + "Cargo": "04A6D6A5D4D4D5C---------07064f040303010201.AwRj4yoo.EwBhEYy6dsg=" + }, + "python": { + "Cargo": "04A6D5A4D6D6D5C---------050505044a03020201", + "Miner": "04A6D5A4D6D6D5C---2m2m----050505044d1v02022o" + }, + "anaconda": { + "Dream": "48A6A6A5A8A8A5C2c0o0o0o1m1m0q0q0404040l0b0100034k5n05050404040303326b.AwRj4yo5dig=.MwBhEYy6duwEziA=", + "Cargo": "03A7D6A5D4D8D5C----------------060505054d040403030301.AwRj4yuqg===.Aw18ZlA=" + }, + "diamondback_explorer": { + "Explorer": "02A4D5A3D3D3D5C-------320p432i2f.AwRj4zTI.AwiMIypI" + } + }, + "comparisons": { + "Test": { + "facets": [ 9, 6, 4, 1, 3, 2 ], + "builds": [ + { + "shipId": "anaconda", + "buildName": "Dream" + }, + { + "shipId": "asp", + "buildName": "Miner" + }, + { + "shipId": "diamondback_explorer", + "buildName": "Explorer" + } + ] + } + }, + "insurance": "Beta", + "discounts": [ + 1, + 1 + ] +} \ No newline at end of file diff --git a/test/fixtures/valid-detailed-export.json b/test/fixtures/valid-detailed-export.json new file mode 100644 index 00000000..778c3060 --- /dev/null +++ b/test/fixtures/valid-detailed-export.json @@ -0,0 +1,3620 @@ +[ + { + "$schema": "http://cdn.coriolis.io/schemas/ship-loadout/1.json#", + "name": "Cargo", + "ship": "Type-6 Transporter", + "references": [ + { + "name": "Coriolis.io", + "url": "http://localhost:3300/outfit/type_6_transporter/02A4D4A2D2D2D4C-----04040303430101?bn=Cargo", + "code": "02A4D4A2D2D2D4C-----04040303430101", + "shipId": "type_6_transporter" + } + ], + "components": { + "standard": { + "bulkheads": "Lightweight Alloy", + "powerPlant": { + "class": 2, + "rating": "A" + }, + "thrusters": { + "class": 4, + "rating": "D" + }, + "frameShiftDrive": { + "class": 4, + "rating": "A" + }, + "lifeSupport": { + "class": 2, + "rating": "D" + }, + "powerDistributor": { + "class": 2, + "rating": "D" + }, + "sensors": { + "class": 2, + "rating": "D" + }, + "fuelTank": { + "class": 4, + "rating": "C" + } + }, + "hardpoints": [ + null, + null + ], + "utility": [ + null, + null, + null + ], + "internal": [ + { + "class": 5, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 5, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 4, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 4, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 3, + "rating": "D", + "group": "Shield Generator" + }, + { + "class": 2, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 2, + "rating": "E", + "group": "Cargo Rack" + } + ] + }, + "stats": { + "class": 2, + "hullCost": 865782, + "speed": 220, + "boost": 350, + "agility": 3, + "baseShieldStrength": 90, + "baseArmour": 162, + "hullMass": 155, + "masslock": 8, + "shipCostMultiplier": 1, + "componentCostMultiplier": 1, + "fuelCapacity": 16, + "cargoCapacity": 104, + "ladenMass": 295.3, + "armourAdded": 0, + "shieldMultiplier": 1, + "totalCost": 3048410, + "unladenMass": 175.3, + "armour": 162, + "totalDps": 0, + "powerAvailable": 9.6, + "powerRetracted": 7.21, + "powerDeployed": 7.21, + "unladenRange": 32.48, + "fullTankRange": 30.27, + "ladenRange": 19.61, + "unladenTotalRange": 176.71, + "ladenTotalRange": 112.92, + "maxJumpCount": 6, + "shieldStrength": 86.49 + } + }, + { + "$schema": "http://cdn.coriolis.io/schemas/ship-loadout/1.json#", + "name": "Miner", + "ship": "Type-6 Transporter", + "references": [ + { + "name": "Coriolis.io", + "url": "http://localhost:3300/outfit/type_6_transporter/03A4D4A2D2D2D4C2l2l---040403451q0101?bn=Miner", + "code": "03A4D4A2D2D2D4C2l2l---040403451q0101", + "shipId": "type_6_transporter" + } + ], + "components": { + "standard": { + "bulkheads": "Lightweight Alloy", + "powerPlant": { + "class": 3, + "rating": "A" + }, + "thrusters": { + "class": 4, + "rating": "D" + }, + "frameShiftDrive": { + "class": 4, + "rating": "A" + }, + "lifeSupport": { + "class": 2, + "rating": "D" + }, + "powerDistributor": { + "class": 2, + "rating": "D" + }, + "sensors": { + "class": 2, + "rating": "D" + }, + "fuelTank": { + "class": 4, + "rating": "C" + } + }, + "hardpoints": [ + { + "class": 1, + "rating": "D", + "group": "Mining Laser", + "mount": "Fixed" + }, + { + "class": 1, + "rating": "D", + "group": "Mining Laser", + "mount": "Fixed" + } + ], + "utility": [ + null, + null, + null + ], + "internal": [ + { + "class": 5, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 5, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 4, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 4, + "rating": "A", + "group": "Shield Generator" + }, + { + "class": 3, + "rating": "A", + "group": "Refinery" + }, + { + "class": 2, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 2, + "rating": "E", + "group": "Cargo Rack" + } + ] + }, + "stats": { + "class": 2, + "hullCost": 865782, + "speed": 220, + "boost": 350, + "agility": 3, + "baseShieldStrength": 90, + "baseArmour": 162, + "hullMass": 155, + "masslock": 8, + "shipCostMultiplier": 1, + "componentCostMultiplier": 1, + "fuelCapacity": 16, + "cargoCapacity": 88, + "ladenMass": 292.5, + "armourAdded": 0, + "shieldMultiplier": 1, + "totalCost": 7109898, + "unladenMass": 188.5, + "armour": 162, + "totalDps": 0, + "powerAvailable": 12, + "powerRetracted": 9.33, + "powerDeployed": 10.33, + "unladenRange": 30.24, + "fullTankRange": 28.32, + "ladenRange": 19.8, + "unladenTotalRange": 164.89, + "ladenTotalRange": 114.03, + "maxJumpCount": 6, + "shieldStrength": 149.2 + } + }, + { + "$schema": "http://cdn.coriolis.io/schemas/ship-loadout/1.json#", + "name": "Hopper", + "ship": "Type-6 Transporter", + "references": [ + { + "name": "Coriolis.io", + "url": "http://localhost:3300/outfit/type_6_transporter/02A4D4A2D1A2D4C1717---030302024300-?bn=Hopper", + "code": "02A4D4A2D1A2D4C1717---030302024300-", + "shipId": "type_6_transporter" + } + ], + "components": { + "standard": { + "bulkheads": "Lightweight Alloy", + "powerPlant": { + "class": 2, + "rating": "A" + }, + "thrusters": { + "class": 4, + "rating": "D" + }, + "frameShiftDrive": { + "class": 4, + "rating": "A" + }, + "lifeSupport": { + "class": 2, + "rating": "D" + }, + "powerDistributor": { + "class": 1, + "rating": "A" + }, + "sensors": { + "class": 2, + "rating": "D" + }, + "fuelTank": { + "class": 4, + "rating": "C" + } + }, + "hardpoints": [ + { + "class": 1, + "rating": "F", + "group": "Pulse Laser", + "mount": "Fixed" + }, + { + "class": 1, + "rating": "F", + "group": "Pulse Laser", + "mount": "Fixed" + } + ], + "utility": [ + null, + null, + null + ], + "internal": [ + { + "class": 4, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 4, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 3, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 3, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 3, + "rating": "D", + "group": "Shield Generator" + }, + { + "class": 1, + "rating": "E", + "group": "Cargo Rack" + }, + null + ] + }, + "stats": { + "class": 2, + "hullCost": 865782, + "speed": 220, + "boost": 350, + "agility": 3, + "baseShieldStrength": 90, + "baseArmour": 162, + "hullMass": 155, + "masslock": 8, + "shipCostMultiplier": 1, + "componentCostMultiplier": 1, + "fuelCapacity": 16, + "cargoCapacity": 50, + "ladenMass": 245.6, + "armourAdded": 0, + "shieldMultiplier": 1, + "totalCost": 2861880, + "unladenMass": 179.6, + "armour": 162, + "totalDps": 6, + "powerAvailable": 9.6, + "powerRetracted": 7.28, + "powerDeployed": 8.06, + "unladenRange": 31.71, + "fullTankRange": 29.61, + "ladenRange": 23.58, + "unladenTotalRange": 172.68, + "ladenTotalRange": 136.46, + "maxJumpCount": 6, + "shieldStrength": 86.49 + } + }, + { + "$schema": "http://cdn.coriolis.io/schemas/ship-loadout/1.json#", + "name": "Cargo", + "ship": "Type-7 Transporter", + "references": [ + { + "name": "Coriolis.io", + "url": "http://localhost:3300/outfit/type_7_transport/02A5D5A4D3D3D5C--------0505040403480101?bn=Cargo", + "code": "02A5D5A4D3D3D5C--------0505040403480101", + "shipId": "type_7_transport" + } + ], + "components": { + "standard": { + "bulkheads": "Lightweight Alloy", + "powerPlant": { + "class": 2, + "rating": "A" + }, + "thrusters": { + "class": 5, + "rating": "D" + }, + "frameShiftDrive": { + "class": 5, + "rating": "A" + }, + "lifeSupport": { + "class": 4, + "rating": "D" + }, + "powerDistributor": { + "class": 3, + "rating": "D" + }, + "sensors": { + "class": 3, + "rating": "D" + }, + "fuelTank": { + "class": 5, + "rating": "C" + } + }, + "hardpoints": [ + null, + null, + null, + null + ], + "utility": [ + null, + null, + null, + null + ], + "internal": [ + { + "class": 6, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 6, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 5, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 5, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 4, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 4, + "rating": "D", + "group": "Shield Generator" + }, + { + "class": 2, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 2, + "rating": "E", + "group": "Cargo Rack" + } + ] + }, + "stats": { + "class": 3, + "hullCost": 16881511, + "speed": 180, + "boost": 300, + "agility": 2, + "baseShieldStrength": 120, + "baseArmour": 216, + "hullMass": 420, + "masslock": 10, + "shipCostMultiplier": 1, + "componentCostMultiplier": 1, + "fuelCapacity": 32, + "cargoCapacity": 216, + "ladenMass": 709.3, + "armourAdded": 0, + "shieldMultiplier": 1, + "totalCost": 23529891, + "unladenMass": 461.3, + "armour": 216, + "totalDps": 0, + "powerAvailable": 9.6, + "powerRetracted": 8.81, + "powerDeployed": 8.81, + "unladenRange": 26.41, + "fullTankRange": 24.97, + "ladenRange": 17.36, + "unladenTotalRange": 172.04, + "ladenTotalRange": 118.55, + "maxJumpCount": 7, + "shieldStrength": 89.07 + } + }, + { + "$schema": "http://cdn.coriolis.io/schemas/ship-loadout/1.json#", + "name": "Miner", + "ship": "Type-7 Transporter", + "references": [ + { + "name": "Coriolis.io", + "url": "http://localhost:3300/outfit/type_7_transport/04D5D5A4D2D3D5C--2l2l----0505041v03450000?bn=Miner", + "code": "04D5D5A4D2D3D5C--2l2l----0505041v03450000", + "shipId": "type_7_transport" + } + ], + "components": { + "standard": { + "bulkheads": "Lightweight Alloy", + "powerPlant": { + "class": 4, + "rating": "D" + }, + "thrusters": { + "class": 5, + "rating": "D" + }, + "frameShiftDrive": { + "class": 5, + "rating": "A" + }, + "lifeSupport": { + "class": 4, + "rating": "D" + }, + "powerDistributor": { + "class": 2, + "rating": "D" + }, + "sensors": { + "class": 3, + "rating": "D" + }, + "fuelTank": { + "class": 5, + "rating": "C" + } + }, + "hardpoints": [ + null, + null, + { + "class": 1, + "rating": "D", + "group": "Mining Laser", + "mount": "Fixed" + }, + { + "class": 1, + "rating": "D", + "group": "Mining Laser", + "mount": "Fixed" + } + ], + "utility": [ + null, + null, + null, + null + ], + "internal": [ + { + "class": 6, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 6, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 5, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 4, + "rating": "A", + "group": "Refinery" + }, + { + "class": 4, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 4, + "rating": "A", + "group": "Shield Generator" + }, + { + "class": 1, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 1, + "rating": "E", + "group": "Cargo Rack" + } + ] + }, + "stats": { + "class": 3, + "hullCost": 16881511, + "speed": 180, + "boost": 300, + "agility": 2, + "baseShieldStrength": 120, + "baseArmour": 216, + "hullMass": 420, + "masslock": 10, + "shipCostMultiplier": 1, + "componentCostMultiplier": 1, + "fuelCapacity": 32, + "cargoCapacity": 180, + "ladenMass": 685, + "armourAdded": 0, + "shieldMultiplier": 1, + "totalCost": 29371613, + "unladenMass": 473, + "armour": 216, + "totalDps": 0, + "powerAvailable": 11.7, + "powerRetracted": 10.66, + "powerDeployed": 11.66, + "unladenRange": 25.77, + "fullTankRange": 24.39, + "ladenRange": 17.98, + "unladenTotalRange": 167.93, + "ladenTotalRange": 122.84, + "maxJumpCount": 7, + "shieldStrength": 125.07 + } + }, + { + "$schema": "http://cdn.coriolis.io/schemas/ship-loadout/1.json#", + "name": "Cargo", + "ship": "Federal Dropship", + "references": [ + { + "name": "Coriolis.io", + "url": "http://localhost:3300/outfit/federal_dropship/04D5D5A5D3D4D4C-1717------05040448020201?bn=Cargo", + "code": "04D5D5A5D3D4D4C-1717------05040448020201", + "shipId": "federal_dropship" + } + ], + "components": { + "standard": { + "bulkheads": "Lightweight Alloy", + "powerPlant": { + "class": 4, + "rating": "D" + }, + "thrusters": { + "class": 5, + "rating": "D" + }, + "frameShiftDrive": { + "class": 5, + "rating": "A" + }, + "lifeSupport": { + "class": 5, + "rating": "D" + }, + "powerDistributor": { + "class": 3, + "rating": "D" + }, + "sensors": { + "class": 4, + "rating": "D" + }, + "fuelTank": { + "class": 4, + "rating": "C" + } + }, + "hardpoints": [ + null, + { + "class": 1, + "rating": "F", + "group": "Pulse Laser", + "mount": "Fixed" + }, + { + "class": 1, + "rating": "F", + "group": "Pulse Laser", + "mount": "Fixed" + }, + null, + null + ], + "utility": [ + null, + null, + null, + null + ], + "internal": [ + { + "class": 6, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 5, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 5, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 4, + "rating": "D", + "group": "Shield Generator" + }, + { + "class": 3, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 3, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 2, + "rating": "E", + "group": "Cargo Rack" + } + ] + }, + "stats": { + "class": 2, + "hullCost": 18969990, + "speed": 180, + "boost": 300, + "agility": 2, + "baseShieldStrength": 200, + "baseArmour": 540, + "hullMass": 580, + "masslock": 14, + "shipCostMultiplier": 1, + "componentCostMultiplier": 1, + "fuelCapacity": 16, + "cargoCapacity": 148, + "ladenMass": 798, + "armourAdded": 0, + "shieldMultiplier": 1, + "totalCost": 25139427, + "unladenMass": 634, + "armour": 540, + "totalDps": 6, + "powerAvailable": 11.7, + "powerRetracted": 8.95, + "powerDeployed": 9.73, + "unladenRange": 19.27, + "fullTankRange": 18.95, + "ladenRange": 15.43, + "unladenTotalRange": 67.34, + "ladenTotalRange": 54.75, + "maxJumpCount": 4, + "shieldStrength": 111.07 + } + }, + { + "$schema": "http://cdn.coriolis.io/schemas/ship-loadout/1.json#", + "name": "Miner", + "ship": "Asp Explorer", + "references": [ + { + "name": "Coriolis.io", + "url": "http://localhost:3300/outfit/asp/25A5A5A4D4A5A5C0s0s24242l2l---04054a1q02022o27?bn=Miner", + "code": "25A5A5A4D4A5A5C0s0s24242l2l---04054a1q02022o27", + "shipId": "asp" + } + ], + "components": { + "standard": { + "bulkheads": "Military Grade Composite", + "powerPlant": { + "class": 5, + "rating": "A" + }, + "thrusters": { + "class": 5, + "rating": "A" + }, + "frameShiftDrive": { + "class": 5, + "rating": "A" + }, + "lifeSupport": { + "class": 4, + "rating": "D" + }, + "powerDistributor": { + "class": 4, + "rating": "A" + }, + "sensors": { + "class": 5, + "rating": "A" + }, + "fuelTank": { + "class": 5, + "rating": "C" + } + }, + "hardpoints": [ + { + "class": 2, + "rating": "D", + "group": "Beam Laser", + "mount": "Gimballed" + }, + { + "class": 2, + "rating": "D", + "group": "Beam Laser", + "mount": "Gimballed" + }, + { + "class": 1, + "rating": "G", + "group": "Multi-cannon", + "mount": "Gimballed" + }, + { + "class": 1, + "rating": "G", + "group": "Multi-cannon", + "mount": "Gimballed" + }, + { + "class": 1, + "rating": "D", + "group": "Mining Laser", + "mount": "Fixed" + }, + { + "class": 1, + "rating": "D", + "group": "Mining Laser", + "mount": "Fixed" + } + ], + "utility": [ + null, + null, + null, + { + "class": 0, + "rating": "A", + "group": "Shield Booster" + } + ], + "internal": [ + { + "class": 6, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 5, + "rating": "A", + "group": "Shield Generator" + }, + { + "class": 3, + "rating": "A", + "group": "Refinery" + }, + { + "class": 3, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 3, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 2, + "rating": "A", + "group": "Fuel Scoop" + }, + { + "class": 2, + "rating": "D", + "group": "Hull Reinforcement Package" + } + ] + }, + "stats": { + "class": 2, + "hullCost": 6135658, + "speed": 250, + "boost": 340, + "agility": 6, + "baseShieldStrength": 140, + "baseArmour": 378, + "hullMass": 280, + "masslock": 11, + "shipCostMultiplier": 1, + "componentCostMultiplier": 1, + "fuelCapacity": 32, + "cargoCapacity": 80, + "ladenMass": 561.5, + "armourAdded": 30, + "shieldMultiplier": 1.2, + "totalCost": 38529401, + "unladenMass": 449.5, + "armour": 408, + "totalDps": 14, + "powerAvailable": 20.4, + "powerRetracted": 15.49, + "powerDeployed": 19.43, + "unladenRange": 27.1, + "fullTankRange": 25.58, + "ladenRange": 21.94, + "unladenTotalRange": 176.39, + "ladenTotalRange": 150.58, + "maxJumpCount": 7, + "shieldStrength": 253.58 + } + }, + { + "$schema": "http://cdn.coriolis.io/schemas/ship-loadout/1.json#", + "name": "Cargo", + "ship": "Imperial Clipper", + "references": [ + { + "name": "Coriolis.io", + "url": "http://localhost:3300/outfit/imperial_clipper/03A5D5A5D4D5D4C--0s0s----0605450302020101?bn=Cargo", + "code": "03A5D5A5D4D5D4C--0s0s----0605450302020101", + "shipId": "imperial_clipper" + } + ], + "components": { + "standard": { + "bulkheads": "Lightweight Alloy", + "powerPlant": { + "class": 3, + "rating": "A" + }, + "thrusters": { + "class": 5, + "rating": "D" + }, + "frameShiftDrive": { + "class": 5, + "rating": "A" + }, + "lifeSupport": { + "class": 5, + "rating": "D" + }, + "powerDistributor": { + "class": 4, + "rating": "D" + }, + "sensors": { + "class": 5, + "rating": "D" + }, + "fuelTank": { + "class": 4, + "rating": "C" + } + }, + "hardpoints": [ + null, + null, + { + "class": 2, + "rating": "D", + "group": "Beam Laser", + "mount": "Gimballed" + }, + { + "class": 2, + "rating": "D", + "group": "Beam Laser", + "mount": "Gimballed" + } + ], + "utility": [ + null, + null, + null, + null + ], + "internal": [ + { + "class": 7, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 6, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 4, + "rating": "A", + "group": "Shield Generator" + }, + { + "class": 4, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 3, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 3, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 2, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 2, + "rating": "E", + "group": "Cargo Rack" + } + ] + }, + "stats": { + "class": 3, + "hullCost": 21077784, + "speed": 300, + "boost": 380, + "agility": 2, + "baseShieldStrength": 180, + "baseArmour": 486, + "hullMass": 400, + "masslock": 12, + "shipCostMultiplier": 1, + "componentCostMultiplier": 1, + "fuelCapacity": 16, + "cargoCapacity": 232, + "ladenMass": 716.5, + "armourAdded": 0, + "shieldMultiplier": 1, + "totalCost": 31304924, + "unladenMass": 468.5, + "armour": 486, + "totalDps": 8, + "powerAvailable": 12, + "powerRetracted": 10.38, + "powerDeployed": 12.58, + "unladenRange": 26.01, + "fullTankRange": 25.42, + "ladenRange": 17.19, + "unladenTotalRange": 90.67, + "ladenTotalRange": 61.04, + "maxJumpCount": 4, + "shieldStrength": 191.82 + } + }, + { + "$schema": "http://cdn.coriolis.io/schemas/ship-loadout/1.json#", + "name": "Dream", + "ship": "Imperial Clipper", + "references": [ + { + "name": "Coriolis.io", + "url": "http://localhost:3300/outfit/imperial_clipper/26A6A5A5D6A5A4C0v0v0s0s0404040n4k5n5d2b29292o-.AwRj4yWU1I%3D%3D.CwBhCYy6YRigzLIA?bn=Dream", + "code": "26A6A5A5D6A5A4C0v0v0s0s0404040n4k5n5d2b29292o-.AwRj4yWU1I==.CwBhCYy6YRigzLIA", + "shipId": "imperial_clipper" + } + ], + "components": { + "standard": { + "bulkheads": "Military Grade Composite", + "powerPlant": { + "class": 6, + "rating": "A" + }, + "thrusters": { + "class": 6, + "rating": "A" + }, + "frameShiftDrive": { + "class": 5, + "rating": "A" + }, + "lifeSupport": { + "class": 5, + "rating": "D" + }, + "powerDistributor": { + "class": 6, + "rating": "A" + }, + "sensors": { + "class": 5, + "rating": "A" + }, + "fuelTank": { + "class": 4, + "rating": "C" + } + }, + "hardpoints": [ + { + "class": 3, + "rating": "C", + "group": "Beam Laser", + "mount": "Gimballed" + }, + { + "class": 3, + "rating": "C", + "group": "Beam Laser", + "mount": "Gimballed" + }, + { + "class": 2, + "rating": "D", + "group": "Beam Laser", + "mount": "Gimballed" + }, + { + "class": 2, + "rating": "D", + "group": "Beam Laser", + "mount": "Gimballed" + } + ], + "utility": [ + { + "class": 0, + "rating": "A", + "group": "Shield Booster" + }, + { + "class": 0, + "rating": "A", + "group": "Shield Booster" + }, + { + "class": 0, + "rating": "A", + "group": "Shield Booster" + }, + { + "class": 0, + "rating": "E", + "group": "Kill Warrant Scanner" + } + ], + "internal": [ + { + "class": 7, + "rating": "A", + "group": "Shield Generator" + }, + { + "class": 6, + "rating": "A", + "group": "Shield Cell Bank" + }, + { + "class": 4, + "rating": "A", + "group": "Shield Cell Bank" + }, + { + "class": 4, + "rating": "D", + "group": "Hull Reinforcement Package" + }, + { + "class": 3, + "rating": "D", + "group": "Hull Reinforcement Package" + }, + { + "class": 3, + "rating": "D", + "group": "Hull Reinforcement Package" + }, + { + "class": 2, + "rating": "A", + "group": "Fuel Scoop" + }, + null + ] + }, + "stats": { + "class": 3, + "hullCost": 21077784, + "speed": 300, + "boost": 380, + "agility": 2, + "baseShieldStrength": 180, + "baseArmour": 486, + "hullMass": 400, + "masslock": 12, + "shipCostMultiplier": 1, + "componentCostMultiplier": 1, + "fuelCapacity": 16, + "cargoCapacity": 0, + "ladenMass": 821.8, + "armourAdded": 240, + "shieldMultiplier": 1.6, + "totalCost": 145934292, + "unladenMass": 805.8, + "armour": 726, + "totalDps": 16, + "powerAvailable": 25.2, + "powerRetracted": 19.35, + "powerDeployed": 25.31, + "unladenRange": 15.19, + "fullTankRange": 14.99, + "ladenRange": 14.99, + "unladenTotalRange": 53.15, + "ladenTotalRange": 53.15, + "maxJumpCount": 4, + "shieldStrength": 489.6 + } + }, + { + "$schema": "http://cdn.coriolis.io/schemas/ship-loadout/1.json#", + "name": "Current", + "ship": "Imperial Clipper", + "references": [ + { + "name": "Coriolis.io", + "url": "http://localhost:3300/outfit/imperial_clipper/04A6A5A5D4A5A4C----------------.AwRj4yWU1I%3D%3D.CwBhCYy6YRigzLIA?bn=Current", + "code": "04A6A5A5D4A5A4C----------------.AwRj4yWU1I==.CwBhCYy6YRigzLIA", + "shipId": "imperial_clipper" + } + ], + "components": { + "standard": { + "bulkheads": "Lightweight Alloy", + "powerPlant": { + "class": 4, + "rating": "A" + }, + "thrusters": { + "class": 6, + "rating": "A" + }, + "frameShiftDrive": { + "class": 5, + "rating": "A" + }, + "lifeSupport": { + "class": 5, + "rating": "D" + }, + "powerDistributor": { + "class": 4, + "rating": "A" + }, + "sensors": { + "class": 5, + "rating": "A" + }, + "fuelTank": { + "class": 4, + "rating": "C" + } + }, + "hardpoints": [ + null, + null, + null, + null + ], + "utility": [ + null, + null, + null, + null + ], + "internal": [ + null, + null, + null, + null, + null, + null, + null, + null + ] + }, + "stats": { + "class": 3, + "hullCost": 21077784, + "speed": 300, + "boost": 380, + "agility": 2, + "baseShieldStrength": 180, + "baseArmour": 486, + "hullMass": 400, + "masslock": 12, + "shipCostMultiplier": 1, + "componentCostMultiplier": 1, + "fuelCapacity": 16, + "cargoCapacity": 0, + "ladenMass": 519, + "armourAdded": 0, + "shieldMultiplier": 1, + "totalCost": 45760171, + "unladenMass": 503, + "armour": 486, + "totalDps": 0, + "powerAvailable": 15.6, + "powerRetracted": 10.7, + "powerDeployed": 10.7, + "unladenRange": 24.25, + "fullTankRange": 23.73, + "ladenRange": 23.73, + "unladenTotalRange": 84.56, + "ladenTotalRange": 84.56, + "maxJumpCount": 4, + "shieldStrength": 0 + } + }, + { + "$schema": "http://cdn.coriolis.io/schemas/ship-loadout/1.json#", + "name": "Current", + "ship": "Type-9 Heavy", + "references": [ + { + "name": "Coriolis.io", + "url": "http://localhost:3300/outfit/type_9_heavy/04A7D6A5D5D4D6C---------0706054a0303020224.AwRj4yoo.EwBhEYy6dsg%3D?bn=Current", + "code": "04A7D6A5D5D4D6C---------0706054a0303020224.AwRj4yoo.EwBhEYy6dsg=", + "shipId": "type_9_heavy" + } + ], + "components": { + "standard": { + "bulkheads": "Lightweight Alloy", + "powerPlant": { + "class": 4, + "rating": "A" + }, + "thrusters": { + "class": 7, + "rating": "D" + }, + "frameShiftDrive": { + "class": 6, + "rating": "A" + }, + "lifeSupport": { + "class": 5, + "rating": "D" + }, + "powerDistributor": { + "class": 5, + "rating": "D" + }, + "sensors": { + "class": 4, + "rating": "D" + }, + "fuelTank": { + "class": 6, + "rating": "C" + } + }, + "hardpoints": [ + null, + null, + null, + null, + null + ], + "utility": [ + null, + null, + null, + null + ], + "internal": [ + { + "class": 8, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 7, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 6, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 5, + "rating": "A", + "group": "Shield Generator" + }, + { + "class": 4, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 4, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 3, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 3, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 1, + "rating": "E", + "group": "Docking Computer", + "name": "Standard Docking Computer" + } + ] + }, + "stats": { + "class": 3, + "hullCost": 73255168, + "speed": 130, + "boost": 200, + "agility": 0, + "baseShieldStrength": 240, + "baseArmour": 432, + "hullMass": 1000, + "masslock": 16, + "shipCostMultiplier": 1, + "componentCostMultiplier": 1, + "fuelCapacity": 64, + "cargoCapacity": 496, + "ladenMass": 1677, + "armourAdded": 0, + "shieldMultiplier": 1, + "totalCost": 104042326, + "unladenMass": 1117, + "armour": 432, + "totalDps": 0, + "powerAvailable": 15.6, + "powerRetracted": 13.13, + "powerDeployed": 13.13, + "unladenRange": 19.51, + "fullTankRange": 18.58, + "ladenRange": 13.09, + "unladenTotalRange": 152.32, + "ladenTotalRange": 106.49, + "maxJumpCount": 8, + "shieldStrength": 170.57 + } + }, + { + "$schema": "http://cdn.coriolis.io/schemas/ship-loadout/1.json#", + "name": "Cargo", + "ship": "Python", + "references": [ + { + "name": "Coriolis.io", + "url": "http://localhost:3300/outfit/python/04A6D5A4D6D6D5C---------050505040448020201.Iw18eQ%3D%3D.Aw18eQ%3D%3D?bn=Cargo", + "code": "04A6D5A4D6D6D5C---------050505040448020201.Iw18eQ==.Aw18eQ==", + "shipId": "python" + } + ], + "components": { + "standard": { + "bulkheads": "Lightweight Alloy", + "powerPlant": { + "class": 4, + "rating": "A" + }, + "thrusters": { + "class": 6, + "rating": "D" + }, + "frameShiftDrive": { + "class": 5, + "rating": "A" + }, + "lifeSupport": { + "class": 4, + "rating": "D" + }, + "powerDistributor": { + "class": 6, + "rating": "D" + }, + "sensors": { + "class": 6, + "rating": "D" + }, + "fuelTank": { + "class": 5, + "rating": "C" + } + }, + "hardpoints": [ + null, + null, + null, + null, + null + ], + "utility": [ + null, + null, + null, + null + ], + "internal": [ + { + "class": 6, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 6, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 6, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 5, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 5, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 4, + "rating": "D", + "group": "Shield Generator" + }, + { + "class": 3, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 3, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 2, + "rating": "E", + "group": "Cargo Rack" + } + ] + }, + "stats": { + "class": 2, + "hullCost": 55171395, + "speed": 230, + "boost": 280, + "agility": 6, + "baseShieldStrength": 260, + "baseArmour": 468, + "hullMass": 350, + "masslock": 17, + "shipCostMultiplier": 1, + "componentCostMultiplier": 1, + "fuelCapacity": 32, + "cargoCapacity": 276, + "ladenMass": 739, + "armourAdded": 0, + "shieldMultiplier": 1, + "totalCost": 64450599, + "unladenMass": 431, + "armour": 468, + "totalDps": 0, + "powerAvailable": 15.6, + "powerRetracted": 10.25, + "powerDeployed": 10.25, + "unladenRange": 28.25, + "fullTankRange": 26.6, + "ladenRange": 16.67, + "unladenTotalRange": 183.67, + "ladenTotalRange": 113.69, + "maxJumpCount": 7, + "shieldStrength": 214.26 + } + }, + { + "$schema": "http://cdn.coriolis.io/schemas/ship-loadout/1.json#", + "name": "Miner", + "ship": "Python", + "references": [ + { + "name": "Coriolis.io", + "url": "http://localhost:3300/outfit/python/06A6A5A4D6A6A5C0v0v0v2m2m0404--050505Ce4a1v02022o.Iw18eQ%3D%3D.IwBhBYy6dkCYg%3D%3D%3D?bn=Miner", + "code": "06A6A5A4D6A6A5C0v0v0v2m2m0404--050505Ce4a1v02022o.Iw18eQ==.IwBhBYy6dkCYg===", + "shipId": "python" + } + ], + "components": { + "standard": { + "bulkheads": "Lightweight Alloy", + "powerPlant": { + "class": 6, + "rating": "A" + }, + "thrusters": { + "class": 6, + "rating": "A" + }, + "frameShiftDrive": { + "class": 5, + "rating": "A" + }, + "lifeSupport": { + "class": 4, + "rating": "D" + }, + "powerDistributor": { + "class": 6, + "rating": "A" + }, + "sensors": { + "class": 6, + "rating": "A" + }, + "fuelTank": { + "class": 5, + "rating": "C" + } + }, + "hardpoints": [ + { + "class": 3, + "rating": "C", + "group": "Beam Laser", + "mount": "Gimballed" + }, + { + "class": 3, + "rating": "C", + "group": "Beam Laser", + "mount": "Gimballed" + }, + { + "class": 3, + "rating": "C", + "group": "Beam Laser", + "mount": "Gimballed" + }, + { + "class": 2, + "rating": "D", + "group": "Mining Laser", + "mount": "Fixed" + }, + { + "class": 2, + "rating": "D", + "group": "Mining Laser", + "mount": "Fixed" + } + ], + "utility": [ + { + "class": 0, + "rating": "A", + "group": "Shield Booster" + }, + { + "class": 0, + "rating": "A", + "group": "Shield Booster" + }, + null, + null + ], + "internal": [ + { + "class": 6, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 6, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 6, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 5, + "rating": "A", + "group": "Collector Limpet Controller" + }, + { + "class": 5, + "rating": "A", + "group": "Shield Generator" + }, + { + "class": 4, + "rating": "A", + "group": "Refinery" + }, + { + "class": 3, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 3, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 2, + "rating": "A", + "group": "Fuel Scoop" + } + ] + }, + "stats": { + "class": 2, + "hullCost": 55171395, + "speed": 230, + "boost": 280, + "agility": 6, + "baseShieldStrength": 260, + "baseArmour": 468, + "hullMass": 350, + "masslock": 17, + "shipCostMultiplier": 1, + "componentCostMultiplier": 1, + "fuelCapacity": 32, + "cargoCapacity": 208, + "ladenMass": 841, + "armourAdded": 0, + "shieldMultiplier": 1.4, + "totalCost": 119283687, + "unladenMass": 601, + "armour": 468, + "totalDps": 12, + "powerAvailable": 25.2, + "powerRetracted": 19.34, + "powerDeployed": 26.18, + "unladenRange": 20.32, + "fullTankRange": 19.46, + "ladenRange": 14.65, + "unladenTotalRange": 133.17, + "ladenTotalRange": 99.65, + "maxJumpCount": 7, + "shieldStrength": 486.35 + } + }, + { + "$schema": "http://cdn.coriolis.io/schemas/ship-loadout/1.json#", + "name": "Dream", + "ship": "Python", + "references": [ + { + "name": "Coriolis.io", + "url": "http://localhost:3300/outfit/python/27A6A5A4D7A6A5C0v0v0v27270404040m5n5n4f2d2d032t0201.Iw1%2BgDBxA%3D%3D%3D.EwBhEYy6e0WEA%3D%3D%3D?bn=Dream", + "code": "27A6A5A4D7A6A5C0v0v0v27270404040m5n5n4f2d2d032t0201.Iw1+gDBxA===.EwBhEYy6e0WEA===", + "shipId": "python" + } + ], + "components": { + "standard": { + "bulkheads": "Military Grade Composite", + "powerPlant": { + "class": 7, + "rating": "A" + }, + "thrusters": { + "class": 6, + "rating": "A" + }, + "frameShiftDrive": { + "class": 5, + "rating": "A" + }, + "lifeSupport": { + "class": 4, + "rating": "D" + }, + "powerDistributor": { + "class": 7, + "rating": "A" + }, + "sensors": { + "class": 6, + "rating": "A" + }, + "fuelTank": { + "class": 5, + "rating": "C" + } + }, + "hardpoints": [ + { + "class": 3, + "rating": "C", + "group": "Beam Laser", + "mount": "Gimballed" + }, + { + "class": 3, + "rating": "C", + "group": "Beam Laser", + "mount": "Gimballed" + }, + { + "class": 3, + "rating": "C", + "group": "Beam Laser", + "mount": "Gimballed" + }, + { + "class": 2, + "rating": "F", + "group": "Multi-cannon", + "mount": "Gimballed" + }, + { + "class": 2, + "rating": "F", + "group": "Multi-cannon", + "mount": "Gimballed" + } + ], + "utility": [ + { + "class": 0, + "rating": "A", + "group": "Shield Booster" + }, + { + "class": 0, + "rating": "A", + "group": "Shield Booster" + }, + { + "class": 0, + "rating": "A", + "group": "Shield Booster" + }, + { + "class": 0, + "rating": "D", + "group": "Kill Warrant Scanner" + } + ], + "internal": [ + { + "class": 6, + "rating": "A", + "group": "Shield Cell Bank" + }, + { + "class": 6, + "rating": "A", + "group": "Shield Cell Bank" + }, + { + "class": 6, + "rating": "A", + "group": "Shield Generator" + }, + { + "class": 5, + "rating": "D", + "group": "Hull Reinforcement Package" + }, + { + "class": 5, + "rating": "D", + "group": "Hull Reinforcement Package" + }, + { + "class": 4, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 3, + "rating": "A", + "group": "Fuel Scoop" + }, + { + "class": 3, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 2, + "rating": "E", + "group": "Cargo Rack" + } + ] + }, + "stats": { + "class": 2, + "hullCost": 55171395, + "speed": 230, + "boost": 280, + "agility": 6, + "baseShieldStrength": 260, + "baseArmour": 468, + "hullMass": 350, + "masslock": 17, + "shipCostMultiplier": 1, + "componentCostMultiplier": 1, + "fuelCapacity": 32, + "cargoCapacity": 28, + "ladenMass": 914.8, + "armourAdded": 480, + "shieldMultiplier": 1.6, + "totalCost": 225526207, + "unladenMass": 854.8, + "armour": 948, + "totalDps": 20, + "powerAvailable": 30, + "powerRetracted": 22.61, + "powerDeployed": 29.63, + "unladenRange": 14.32, + "fullTankRange": 13.89, + "ladenRange": 13.46, + "unladenTotalRange": 94.42, + "ladenTotalRange": 91.49, + "maxJumpCount": 7, + "shieldStrength": 645.57 + } + }, + { + "$schema": "http://cdn.coriolis.io/schemas/ship-loadout/1.json#", + "name": "Dream", + "ship": "Anaconda", + "references": [ + { + "name": "Coriolis.io", + "url": "http://localhost:3300/outfit/anaconda/48A7A6A5D8A8A5C2c0o0o0o1m1m0q0q0404040l0b0100004k5n5n112d2d040303326b.AwRj4yo5dig%3D.MwBhCYy6du3ARiA%3D?bn=Dream", + "code": "48A7A6A5D8A8A5C2c0o0o0o1m1m0q0q0404040l0b0100004k5n5n112d2d040303326b.AwRj4yo5dig=.MwBhCYy6du3ARiA=", + "shipId": "anaconda" + } + ], + "components": { + "standard": { + "bulkheads": "Reactive Surface Composite", + "powerPlant": { + "class": 8, + "rating": "A" + }, + "thrusters": { + "class": 7, + "rating": "A" + }, + "frameShiftDrive": { + "class": 6, + "rating": "A" + }, + "lifeSupport": { + "class": 5, + "rating": "D" + }, + "powerDistributor": { + "class": 8, + "rating": "A" + }, + "sensors": { + "class": 8, + "rating": "A" + }, + "fuelTank": { + "class": 5, + "rating": "C" + } + }, + "hardpoints": [ + { + "class": 4, + "rating": "A", + "group": "Plasma Accelerator", + "mount": "Fixed" + }, + { + "class": 3, + "rating": "D", + "group": "Beam Laser", + "mount": "Turret" + }, + { + "class": 3, + "rating": "D", + "group": "Beam Laser", + "mount": "Turret" + }, + { + "class": 3, + "rating": "D", + "group": "Beam Laser", + "mount": "Turret" + }, + { + "class": 2, + "rating": "E", + "group": "Cannon", + "mount": "Turret" + }, + { + "class": 2, + "rating": "E", + "group": "Cannon", + "mount": "Turret" + }, + { + "class": 1, + "rating": "F", + "group": "Beam Laser", + "mount": "Turret" + }, + { + "class": 1, + "rating": "F", + "group": "Beam Laser", + "mount": "Turret" + } + ], + "utility": [ + { + "class": 0, + "rating": "A", + "group": "Shield Booster" + }, + { + "class": 0, + "rating": "A", + "group": "Shield Booster" + }, + { + "class": 0, + "rating": "A", + "group": "Shield Booster" + }, + { + "class": 0, + "rating": "C", + "group": "Kill Warrant Scanner" + }, + { + "class": 0, + "rating": "C", + "group": "Cargo Scanner" + }, + { + "class": 0, + "rating": "F", + "group": "Countermeasure", + "name": "Electronic Countermeasure" + }, + { + "class": 0, + "rating": "I", + "group": "Countermeasure", + "name": "Chaff Launcher" + }, + { + "class": 0, + "rating": "I", + "group": "Countermeasure", + "name": "Chaff Launcher" + } + ], + "internal": [ + { + "class": 7, + "rating": "A", + "group": "Shield Generator" + }, + { + "class": 6, + "rating": "A", + "group": "Shield Cell Bank" + }, + { + "class": 6, + "rating": "A", + "group": "Shield Cell Bank" + }, + { + "class": 6, + "rating": "A", + "group": "Auto Field-Maintenance Unit" + }, + { + "class": 5, + "rating": "D", + "group": "Hull Reinforcement Package" + }, + { + "class": 5, + "rating": "D", + "group": "Hull Reinforcement Package" + }, + { + "class": 5, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 4, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 4, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 4, + "rating": "A", + "group": "Fuel Scoop" + }, + { + "class": 2, + "rating": "A", + "group": "FSD Interdictor" + } + ] + }, + "stats": { + "class": 3, + "hullCost": 141889932, + "speed": 180, + "boost": 240, + "agility": 2, + "baseShieldStrength": 350, + "baseArmour": 945, + "hullMass": 400, + "masslock": 23, + "shipCostMultiplier": 1, + "componentCostMultiplier": 1, + "fuelCapacity": 32, + "cargoCapacity": 64, + "ladenMass": 1379.5, + "armourAdded": 480, + "shieldMultiplier": 1.6, + "totalCost": 935449309, + "unladenMass": 1283.5, + "armour": 1425, + "totalDps": 29, + "powerAvailable": 36, + "powerRetracted": 25.88, + "powerDeployed": 37.51, + "unladenRange": 16.99, + "fullTankRange": 16.68, + "ladenRange": 15.91, + "unladenTotalRange": 67.35, + "ladenTotalRange": 64.2, + "maxJumpCount": 4, + "shieldStrength": 952 + } + }, + { + "$schema": "http://cdn.coriolis.io/schemas/ship-loadout/1.json#", + "name": "Cargo", + "ship": "Anaconda", + "references": [ + { + "name": "Coriolis.io", + "url": "http://localhost:3300/outfit/anaconda/04A6D6A5D5D8D5C----------------0605050504040445030301.Iw18ZlA%3D.Aw18ZlA%3D?bn=Cargo", + "code": "04A6D6A5D5D8D5C----------------0605050504040445030301.Iw18ZlA=.Aw18ZlA=", + "shipId": "anaconda" + } + ], + "components": { + "standard": { + "bulkheads": "Lightweight Alloy", + "powerPlant": { + "class": 4, + "rating": "A" + }, + "thrusters": { + "class": 6, + "rating": "D" + }, + "frameShiftDrive": { + "class": 6, + "rating": "A" + }, + "lifeSupport": { + "class": 5, + "rating": "D" + }, + "powerDistributor": { + "class": 5, + "rating": "D" + }, + "sensors": { + "class": 8, + "rating": "D" + }, + "fuelTank": { + "class": 5, + "rating": "C" + } + }, + "hardpoints": [ + null, + null, + null, + null, + null, + null, + null, + null + ], + "utility": [ + null, + null, + null, + null, + null, + null, + null, + null + ], + "internal": [ + { + "class": 7, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 6, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 6, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 6, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 5, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 5, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 5, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 4, + "rating": "A", + "group": "Shield Generator" + }, + { + "class": 4, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 4, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 2, + "rating": "E", + "group": "Cargo Rack" + } + ] + }, + "stats": { + "class": 3, + "hullCost": 141889932, + "speed": 180, + "boost": 240, + "agility": 2, + "baseShieldStrength": 350, + "baseArmour": 945, + "hullMass": 400, + "masslock": 23, + "shipCostMultiplier": 1, + "componentCostMultiplier": 1, + "fuelCapacity": 32, + "cargoCapacity": 452, + "ladenMass": 1035, + "armourAdded": 0, + "shieldMultiplier": 1, + "totalCost": 166562265, + "unladenMass": 551, + "armour": 945, + "totalDps": 0, + "powerAvailable": 15.6, + "powerRetracted": 11.92, + "powerDeployed": 11.92, + "unladenRange": 39.26, + "fullTankRange": 37.65, + "ladenRange": 21.21, + "unladenTotalRange": 153.79, + "ladenTotalRange": 85.82, + "maxJumpCount": 4, + "shieldStrength": 372.98 + } + }, + { + "$schema": "http://cdn.coriolis.io/schemas/ship-loadout/1.json#", + "name": "Current", + "ship": "Anaconda", + "references": [ + { + "name": "Coriolis.io", + "url": "http://localhost:3300/outfit/anaconda/04A6D6A5D5A8D5C----------------0605050504040403034524.Iw18ZlA%3D.Aw18ZlA%3D?bn=Current", + "code": "04A6D6A5D5A8D5C----------------0605050504040403034524.Iw18ZlA=.Aw18ZlA=", + "shipId": "anaconda" + } + ], + "components": { + "standard": { + "bulkheads": "Lightweight Alloy", + "powerPlant": { + "class": 4, + "rating": "A" + }, + "thrusters": { + "class": 6, + "rating": "D" + }, + "frameShiftDrive": { + "class": 6, + "rating": "A" + }, + "lifeSupport": { + "class": 5, + "rating": "D" + }, + "powerDistributor": { + "class": 5, + "rating": "A" + }, + "sensors": { + "class": 8, + "rating": "D" + }, + "fuelTank": { + "class": 5, + "rating": "C" + } + }, + "hardpoints": [ + null, + null, + null, + null, + null, + null, + null, + null + ], + "utility": [ + null, + null, + null, + null, + null, + null, + null, + null + ], + "internal": [ + { + "class": 7, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 6, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 6, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 6, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 5, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 5, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 5, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 4, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 4, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 4, + "rating": "A", + "group": "Shield Generator" + }, + { + "class": 1, + "rating": "E", + "group": "Docking Computer", + "name": "Standard Docking Computer" + } + ] + }, + "stats": { + "class": 3, + "hullCost": 141889932, + "speed": 180, + "boost": 240, + "agility": 2, + "baseShieldStrength": 350, + "baseArmour": 945, + "hullMass": 400, + "masslock": 23, + "shipCostMultiplier": 1, + "componentCostMultiplier": 1, + "fuelCapacity": 32, + "cargoCapacity": 448, + "ladenMass": 1043, + "armourAdded": 0, + "shieldMultiplier": 1, + "totalCost": 167725388, + "unladenMass": 563, + "armour": 945, + "totalDps": 0, + "powerAvailable": 15.6, + "powerRetracted": 12.49, + "powerDeployed": 12.49, + "unladenRange": 38.44, + "fullTankRange": 36.89, + "ladenRange": 21.04, + "unladenTotalRange": 150.62, + "ladenTotalRange": 85.16, + "maxJumpCount": 4, + "shieldStrength": 372.98 + } + }, + { + "$schema": "http://cdn.coriolis.io/schemas/ship-loadout/1.json#", + "name": "Explorer", + "ship": "Anaconda", + "references": [ + { + "name": "Coriolis.io", + "url": "http://localhost:3300/outfit/anaconda/04A6D6A5D5A8D5C--------0202------f7050505040s372f2i4524.AwRj4yVKJthA.AwhMIyungRhEA%3D%3D%3D?bn=Explorer", + "code": "04A6D6A5D5A8D5C--------0202------f7050505040s372f2i4524.AwRj4yVKJthA.AwhMIyungRhEA===", + "shipId": "anaconda" + } + ], + "components": { + "standard": { + "bulkheads": "Lightweight Alloy", + "powerPlant": { + "class": 4, + "rating": "A" + }, + "thrusters": { + "class": 6, + "rating": "D" + }, + "frameShiftDrive": { + "class": 6, + "rating": "A" + }, + "lifeSupport": { + "class": 5, + "rating": "D" + }, + "powerDistributor": { + "class": 5, + "rating": "A" + }, + "sensors": { + "class": 8, + "rating": "D" + }, + "fuelTank": { + "class": 5, + "rating": "C" + } + }, + "hardpoints": [ + null, + null, + null, + null, + null, + null, + null, + null + ], + "utility": [ + { + "class": 0, + "rating": "I", + "group": "Countermeasure", + "name": "Heat Sink Launcher" + }, + { + "class": 0, + "rating": "I", + "group": "Countermeasure", + "name": "Heat Sink Launcher" + }, + null, + null, + null, + null, + null, + null + ], + "internal": [ + { + "class": 7, + "rating": "C", + "group": "Fuel Tank" + }, + { + "class": 6, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 6, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 6, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 5, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 5, + "rating": "A", + "group": "Auto Field-Maintenance Unit" + }, + { + "class": 5, + "rating": "A", + "group": "Fuel Scoop" + }, + { + "class": 1, + "rating": "C", + "group": "Scanner", + "name": "Advanced Discovery Scanner" + }, + { + "class": 1, + "rating": "C", + "group": "Scanner", + "name": "Detailed Surface Scanner" + }, + { + "class": 4, + "rating": "A", + "group": "Shield Generator" + }, + { + "class": 1, + "rating": "E", + "group": "Docking Computer", + "name": "Standard Docking Computer" + } + ] + }, + "stats": { + "class": 3, + "hullCost": 141889932, + "speed": 180, + "boost": 240, + "agility": 2, + "baseShieldStrength": 350, + "baseArmour": 945, + "hullMass": 400, + "masslock": 23, + "shipCostMultiplier": 1, + "componentCostMultiplier": 1, + "fuelCapacity": 160, + "cargoCapacity": 224, + "ladenMass": 952.9, + "armourAdded": 0, + "shieldMultiplier": 1, + "totalCost": 187414830, + "unladenMass": 568.9, + "armour": 945, + "totalDps": 0, + "powerAvailable": 15.6, + "powerRetracted": 13, + "powerDeployed": 12.4, + "unladenRange": 38.04, + "fullTankRange": 30.11, + "ladenRange": 23.03, + "unladenTotalRange": 675.7, + "ladenTotalRange": 501.97, + "maxJumpCount": 20, + "shieldStrength": 372.98 + } + }, + { + "$schema": "http://cdn.coriolis.io/schemas/ship-loadout/1.json#", + "name": "Test", + "ship": "Anaconda", + "references": [ + { + "name": "Coriolis.io", + "url": "http://localhost:3300/outfit/anaconda/48A6A6A5A8A8A5C2c0o0o0o1m1m0q0q0404-0l0b0100034k5n052d04--0303326b.Iw18ZlA%3D.Aw18ZlA%3D?bn=Test", + "code": "48A6A6A5A8A8A5C2c0o0o0o1m1m0q0q0404-0l0b0100034k5n052d04--0303326b.Iw18ZlA=.Aw18ZlA=", + "shipId": "anaconda" + } + ], + "components": { + "standard": { + "bulkheads": "Reactive Surface Composite", + "powerPlant": { + "class": 8, + "rating": "A" + }, + "thrusters": { + "class": 6, + "rating": "A" + }, + "frameShiftDrive": { + "class": 6, + "rating": "A" + }, + "lifeSupport": { + "class": 5, + "rating": "A" + }, + "powerDistributor": { + "class": 8, + "rating": "A" + }, + "sensors": { + "class": 8, + "rating": "A" + }, + "fuelTank": { + "class": 5, + "rating": "C" + } + }, + "hardpoints": [ + { + "class": 4, + "rating": "A", + "group": "Plasma Accelerator", + "mount": "Fixed" + }, + { + "class": 3, + "rating": "D", + "group": "Beam Laser", + "mount": "Turret" + }, + { + "class": 3, + "rating": "D", + "group": "Beam Laser", + "mount": "Turret" + }, + { + "class": 3, + "rating": "D", + "group": "Beam Laser", + "mount": "Turret" + }, + { + "class": 2, + "rating": "E", + "group": "Cannon", + "mount": "Turret" + }, + { + "class": 2, + "rating": "E", + "group": "Cannon", + "mount": "Turret" + }, + { + "class": 1, + "rating": "F", + "group": "Beam Laser", + "mount": "Turret" + }, + { + "class": 1, + "rating": "F", + "group": "Beam Laser", + "mount": "Turret" + } + ], + "utility": [ + { + "class": 0, + "rating": "A", + "group": "Shield Booster" + }, + { + "class": 0, + "rating": "A", + "group": "Shield Booster" + }, + null, + { + "class": 0, + "rating": "C", + "group": "Kill Warrant Scanner" + }, + { + "class": 0, + "rating": "C", + "group": "Cargo Scanner" + }, + { + "class": 0, + "rating": "F", + "group": "Countermeasure", + "name": "Electronic Countermeasure" + }, + { + "class": 0, + "rating": "I", + "group": "Countermeasure", + "name": "Chaff Launcher" + }, + { + "class": 0, + "rating": "I", + "group": "Countermeasure", + "name": "Point Defence" + } + ], + "internal": [ + { + "class": 7, + "rating": "A", + "group": "Shield Generator" + }, + { + "class": 6, + "rating": "A", + "group": "Shield Cell Bank" + }, + { + "class": 6, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 5, + "rating": "D", + "group": "Hull Reinforcement Package" + }, + { + "class": 5, + "rating": "E", + "group": "Cargo Rack" + }, + null, + null, + { + "class": 4, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 4, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 4, + "rating": "A", + "group": "Fuel Scoop" + }, + { + "class": 2, + "rating": "A", + "group": "FSD Interdictor" + } + ] + }, + "stats": { + "class": 3, + "hullCost": 141889932, + "speed": 180, + "boost": 240, + "agility": 2, + "baseShieldStrength": 350, + "baseArmour": 945, + "hullMass": 400, + "masslock": 23, + "shipCostMultiplier": 1, + "componentCostMultiplier": 1, + "fuelCapacity": 32, + "cargoCapacity": 128, + "ladenMass": 1339.2, + "armourAdded": 240, + "shieldMultiplier": 1.4, + "totalCost": 882362049, + "unladenMass": 1179.2, + "armour": 1185, + "totalDps": 29, + "powerAvailable": 36, + "powerRetracted": 23.93, + "powerDeployed": 35.56, + "unladenRange": 18.49, + "fullTankRange": 18.12, + "ladenRange": 16.39, + "unladenTotalRange": 73.21, + "ladenTotalRange": 66.15, + "maxJumpCount": 4, + "shieldStrength": 833 + } + }, + { + "$schema": "http://cdn.coriolis.io/schemas/ship-loadout/1.json#", + "name": "Explorer", + "ship": "Diamondback Explorer", + "references": [ + { + "name": "Coriolis.io", + "url": "http://localhost:3300/outfit/diamondback_explorer/02A4D5A3D3D3D5C---0202--320p432i2f.AwRj4zTI.AwiMIypI?bn=Explorer", + "code": "02A4D5A3D3D3D5C---0202--320p432i2f.AwRj4zTI.AwiMIypI", + "shipId": "diamondback_explorer" + } + ], + "components": { + "standard": { + "bulkheads": "Lightweight Alloy", + "powerPlant": { + "class": 2, + "rating": "A" + }, + "thrusters": { + "class": 4, + "rating": "D" + }, + "frameShiftDrive": { + "class": 5, + "rating": "A" + }, + "lifeSupport": { + "class": 3, + "rating": "D" + }, + "powerDistributor": { + "class": 3, + "rating": "D" + }, + "sensors": { + "class": 3, + "rating": "D" + }, + "fuelTank": { + "class": 5, + "rating": "C" + } + }, + "hardpoints": [ + null, + null, + null + ], + "utility": [ + { + "class": 0, + "rating": "I", + "group": "Countermeasure", + "name": "Heat Sink Launcher" + }, + { + "class": 0, + "rating": "I", + "group": "Countermeasure", + "name": "Heat Sink Launcher" + }, + null, + null + ], + "internal": [ + { + "class": 4, + "rating": "A", + "group": "Fuel Scoop" + }, + { + "class": 4, + "rating": "C", + "group": "Auto Field-Maintenance Unit" + }, + { + "class": 3, + "rating": "D", + "group": "Shield Generator" + }, + { + "class": 1, + "rating": "C", + "group": "Scanner", + "name": "Detailed Surface Scanner" + }, + { + "class": 1, + "rating": "C", + "group": "Scanner", + "name": "Advanced Discovery Scanner" + } + ] + }, + "stats": { + "class": 1, + "hullCost": 1635691, + "speed": 242, + "boost": 316, + "agility": 5, + "baseShieldStrength": 146, + "baseArmour": 270, + "hullMass": 298, + "masslock": 7, + "shipCostMultiplier": 1, + "componentCostMultiplier": 1, + "fuelCapacity": 32, + "cargoCapacity": 0, + "ladenMass": 369.2, + "armourAdded": 0, + "shieldMultiplier": 1, + "totalCost": 12295710, + "unladenMass": 337.2, + "armour": 270, + "totalDps": 0, + "powerAvailable": 9.6, + "powerRetracted": 8.48, + "powerDeployed": 7.88, + "unladenRange": 35.99, + "fullTankRange": 33.36, + "ladenRange": 33.36, + "unladenTotalRange": 232.28, + "ladenTotalRange": 232.28, + "maxJumpCount": 7, + "shieldStrength": 92.25 + } + }, + { + "$schema": "http://cdn.coriolis.io/schemas/ship-loadout/1.json#", + "name": "Bounty Hunter", + "ship": "Vulture", + "references": [ + { + "name": "Coriolis.io", + "url": "http://localhost:3300/outfit/vulture/34A4C4A3D5A4A3C1e1e0404-0l4a5d27662j.AwRj4y2I.MwBhBYy6wJmAjLIA?bn=Bounty%20Hunter", + "code": "34A4C4A3D5A4A3C1e1e0404-0l4a5d27662j.AwRj4y2I.MwBhBYy6wJmAjLIA", + "shipId": "vulture" + } + ], + "components": { + "standard": { + "bulkheads": "Mirrored Surface Composite", + "powerPlant": { + "class": 4, + "rating": "A" + }, + "thrusters": { + "class": 4, + "rating": "C" + }, + "frameShiftDrive": { + "class": 4, + "rating": "A" + }, + "lifeSupport": { + "class": 3, + "rating": "D" + }, + "powerDistributor": { + "class": 5, + "rating": "A" + }, + "sensors": { + "class": 4, + "rating": "A" + }, + "fuelTank": { + "class": 3, + "rating": "C" + } + }, + "hardpoints": [ + { + "class": 3, + "rating": "E", + "group": "Pulse Laser", + "mount": "Gimballed" + }, + { + "class": 3, + "rating": "E", + "group": "Pulse Laser", + "mount": "Gimballed" + } + ], + "utility": [ + { + "class": 0, + "rating": "A", + "group": "Shield Booster" + }, + { + "class": 0, + "rating": "A", + "group": "Shield Booster" + }, + null, + { + "class": 0, + "rating": "C", + "group": "Kill Warrant Scanner" + } + ], + "internal": [ + { + "class": 5, + "rating": "A", + "group": "Shield Generator" + }, + { + "class": 4, + "rating": "A", + "group": "Shield Cell Bank" + }, + { + "class": 2, + "rating": "D", + "group": "Hull Reinforcement Package" + }, + { + "class": 1, + "rating": "A", + "group": "FSD Interdictor" + }, + { + "class": 1, + "rating": "A", + "group": "Fuel Scoop" + } + ] + }, + "stats": { + "class": 1, + "hullCost": 4689629, + "speed": 210, + "boost": 340, + "agility": 9, + "baseShieldStrength": 240, + "baseArmour": 288, + "hullMass": 230, + "masslock": 10, + "shipCostMultiplier": 1, + "componentCostMultiplier": 1, + "fuelCapacity": 8, + "cargoCapacity": 0, + "ladenMass": 389.6, + "armourAdded": 30, + "shieldMultiplier": 1.4, + "totalCost": 27869961, + "unladenMass": 381.6, + "armour": 318, + "totalDps": 8, + "powerAvailable": 15.6, + "powerRetracted": 14.87, + "powerDeployed": 17.51, + "unladenRange": 15.06, + "fullTankRange": 14.86, + "ladenRange": 14.86, + "unladenTotalRange": 42.5, + "ladenTotalRange": 42.5, + "maxJumpCount": 3, + "shieldStrength": 548.74 + } + }, + { + "$schema": "http://cdn.coriolis.io/schemas/ship-loadout/1.json#", + "name": "Attack", + "ship": "Fer-de-Lance", + "references": [ + { + "name": "Coriolis.io", + "url": "http://localhost:3300/outfit/fer_de_lance/25A5C4A4D6A4A3C1r0s0s0s0s000404-04-4a-5d27-.Iw18aQ%3D%3D.CwBhrSu8EZyA?bn=Attack", + "code": "25A5C4A4D6A4A3C1r0s0s0s0s000404-04-4a-5d27-.Iw18aQ==.CwBhrSu8EZyA", + "shipId": "fer_de_lance" + } + ], + "components": { + "standard": { + "bulkheads": "Military Grade Composite", + "powerPlant": { + "class": 5, + "rating": "A" + }, + "thrusters": { + "class": 5, + "rating": "C" + }, + "frameShiftDrive": { + "class": 4, + "rating": "A" + }, + "lifeSupport": { + "class": 4, + "rating": "D" + }, + "powerDistributor": { + "class": 6, + "rating": "A" + }, + "sensors": { + "class": 4, + "rating": "A" + }, + "fuelTank": { + "class": 3, + "rating": "C" + } + }, + "hardpoints": [ + { + "class": 4, + "rating": "B", + "group": "Cannon", + "mount": "Gimballed" + }, + { + "class": 2, + "rating": "D", + "group": "Beam Laser", + "mount": "Gimballed" + }, + { + "class": 2, + "rating": "D", + "group": "Beam Laser", + "mount": "Gimballed" + }, + { + "class": 2, + "rating": "D", + "group": "Beam Laser", + "mount": "Gimballed" + }, + { + "class": 2, + "rating": "D", + "group": "Beam Laser", + "mount": "Gimballed" + } + ], + "utility": [ + { + "class": 0, + "rating": "I", + "group": "Countermeasure", + "name": "Chaff Launcher" + }, + { + "class": 0, + "rating": "A", + "group": "Shield Booster" + }, + { + "class": 0, + "rating": "A", + "group": "Shield Booster" + }, + null, + { + "class": 0, + "rating": "A", + "group": "Shield Booster" + }, + null + ], + "internal": [ + { + "class": 5, + "rating": "A", + "group": "Shield Generator" + }, + null, + { + "class": 4, + "rating": "A", + "group": "Shield Cell Bank" + }, + { + "class": 2, + "rating": "D", + "group": "Hull Reinforcement Package" + }, + null + ] + }, + "stats": { + "class": 2, + "hullCost": 51232230, + "speed": 260, + "boost": 350, + "agility": 6, + "baseShieldStrength": 300, + "baseArmour": 405, + "hullMass": 250, + "masslock": 12, + "shipCostMultiplier": 1, + "componentCostMultiplier": 1, + "fuelCapacity": 8, + "cargoCapacity": 0, + "ladenMass": 467.8, + "armourAdded": 30, + "shieldMultiplier": 1.6, + "totalCost": 122716938, + "unladenMass": 459.8, + "armour": 435, + "totalDps": 20, + "powerAvailable": 20.4, + "powerRetracted": 17.71, + "powerDeployed": 23.14, + "unladenRange": 12.51, + "fullTankRange": 12.38, + "ladenRange": 12.38, + "unladenTotalRange": 35.35, + "ladenTotalRange": 35.35, + "maxJumpCount": 3, + "shieldStrength": 760.16 + } + }, + { + "$schema": "http://cdn.coriolis.io/schemas/ship-loadout/1.json#", + "name": "Figther", + "ship": "Eagle", + "references": [ + { + "name": "Coriolis.io", + "url": "http://localhost:3300/outfit/eagle/42A3A3A1D2A2A2C0p0p24-40532j.AwRj49iA.AwgsIkEZigmIA%3D%3D%3D?bn=Figther", + "code": "42A3A3A1D2A2A2C0p0p24-40532j.AwRj49iA.AwgsIkEZigmIA===", + "shipId": "eagle" + } + ], + "components": { + "standard": { + "bulkheads": "Reactive Surface Composite", + "powerPlant": { + "class": 2, + "rating": "A" + }, + "thrusters": { + "class": 3, + "rating": "A" + }, + "frameShiftDrive": { + "class": 3, + "rating": "A" + }, + "lifeSupport": { + "class": 1, + "rating": "D" + }, + "powerDistributor": { + "class": 2, + "rating": "A" + }, + "sensors": { + "class": 2, + "rating": "A" + }, + "fuelTank": { + "class": 2, + "rating": "C" + } + }, + "hardpoints": [ + { + "class": 1, + "rating": "E", + "group": "Beam Laser", + "mount": "Gimballed" + }, + { + "class": 1, + "rating": "E", + "group": "Beam Laser", + "mount": "Gimballed" + }, + { + "class": 1, + "rating": "G", + "group": "Multi-cannon", + "mount": "Gimballed" + } + ], + "utility": [ + null + ], + "internal": [ + { + "class": 3, + "rating": "A", + "group": "Shield Generator" + }, + { + "class": 2, + "rating": "A", + "group": "Shield Cell Bank" + }, + { + "class": 1, + "rating": "A", + "group": "Fuel Scoop" + } + ] + }, + "stats": { + "class": 1, + "hullCost": 10446, + "speed": 240, + "boost": 350, + "agility": 10, + "baseShieldStrength": 60, + "baseArmour": 72, + "hullMass": 50, + "masslock": 6, + "shipCostMultiplier": 1, + "componentCostMultiplier": 1, + "fuelCapacity": 4, + "cargoCapacity": 0, + "ladenMass": 92.3, + "armourAdded": 0, + "shieldMultiplier": 1, + "totalCost": 2265303, + "unladenMass": 88.3, + "armour": 72, + "totalDps": 9, + "powerAvailable": 9.6, + "powerRetracted": 9.46, + "powerDeployed": 11.17, + "unladenRange": 17.12, + "fullTankRange": 16.71, + "ladenRange": 16.71, + "unladenTotalRange": 42.4, + "ladenTotalRange": 42.4, + "maxJumpCount": 3, + "shieldStrength": 102 + } + }, + { + "$schema": "http://cdn.coriolis.io/schemas/ship-loadout/1.json#", + "name": "Missile", + "ship": "Python", + "references": [ + { + "name": "Coriolis.io", + "url": "http://localhost:3300/outfit/python/07E6E5E4E7E6E5C2f2g2d2ePh----04044j03---002h.Iw18eQ%3D%3D.Aw18eQ%3D%3D?bn=Missile", + "code": "07E6E5E4E7E6E5C2f2g2d2ePh----04044j03---002h.Iw18eQ==.Aw18eQ==", + "shipId": "python" + } + ], + "components": { + "standard": { + "bulkheads": "Lightweight Alloy", + "powerPlant": { + "class": 7, + "rating": "E" + }, + "thrusters": { + "class": 6, + "rating": "E" + }, + "frameShiftDrive": { + "class": 5, + "rating": "E" + }, + "lifeSupport": { + "class": 4, + "rating": "E" + }, + "powerDistributor": { + "class": 7, + "rating": "E" + }, + "sensors": { + "class": 6, + "rating": "E" + }, + "fuelTank": { + "class": 5, + "rating": "C" + } + }, + "hardpoints": [ + { + "class": 2, + "rating": "B", + "group": "Missile Rack", + "mount": "Fixed", + "missile": "D" + }, + { + "class": 2, + "rating": "B", + "group": "Missile Rack", + "mount": "Fixed", + "missile": "S" + }, + { + "class": 1, + "rating": "B", + "group": "Missile Rack", + "mount": "Fixed", + "missile": "D" + }, + { + "class": 1, + "rating": "B", + "group": "Missile Rack", + "mount": "Fixed", + "missile": "S" + }, + { + "class": 2, + "rating": "B", + "group": "Missile Rack", + "name": "Pack-Hound", + "mount": "Fixed", + "missile": "S" + } + ], + "utility": [ + null, + null, + null, + null + ], + "internal": [ + { + "class": 5, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 5, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 6, + "rating": "E", + "group": "Shield Generator" + }, + { + "class": 4, + "rating": "E", + "group": "Cargo Rack" + }, + null, + null, + null, + { + "class": 1, + "rating": "E", + "group": "Cargo Rack" + }, + { + "class": 1, + "rating": "E", + "group": "Scanner", + "name": "Basic Discovery Scanner" + } + ] + }, + "stats": { + "class": 2, + "hullCost": 55171395, + "speed": 230, + "boost": 280, + "agility": 6, + "baseShieldStrength": 260, + "baseArmour": 468, + "hullMass": 350, + "masslock": 17, + "shipCostMultiplier": 1, + "componentCostMultiplier": 1, + "fuelCapacity": 32, + "cargoCapacity": 82, + "ladenMass": 792, + "armourAdded": 0, + "shieldMultiplier": 1, + "totalCost": 58832186, + "unladenMass": 678, + "armour": 468, + "totalDps": 26, + "powerAvailable": 20, + "powerRetracted": 9.31, + "powerDeployed": 13.91, + "unladenRange": 8.43, + "fullTankRange": 8.09, + "ladenRange": 7.25, + "unladenTotalRange": 81.5, + "ladenTotalRange": 72.9, + "maxJumpCount": 10, + "shieldStrength": 299.48 + } + } +] \ No newline at end of file diff --git a/test/tests/test-controller-import.js b/test/tests/test-controller-import.js new file mode 100644 index 00000000..99dde417 --- /dev/null +++ b/test/tests/test-controller-import.js @@ -0,0 +1,140 @@ +describe('Import Controller', function() { + beforeEach(module('app')); + + var importController, $rootScope, $stateParams, scope; + + var eventStub = { + preventDefault: function(){ }, + stopPropagation: function(){ } + }; + + beforeEach(inject(function(_$rootScope_, $controller) { + $rootScope = _$rootScope_; + $rootScope.discounts = { + ship: 1, + components: 1 + }; + $stateParams = { }; + scope = $rootScope.$new(); + scope.$parent.dismiss = function() {}; + + var store = {}; + + spyOn(localStorage, 'getItem').and.callFake(function (key) { + return store[key]; + }); + spyOn(localStorage, 'setItem').and.callFake(function (key, value) { + return store[key] = value + ''; + }); + spyOn(localStorage, 'clear').and.callFake(function () { + store = {}; + }); + + importController = $controller('ImportController', { $rootScope: $rootScope, $scope: scope, $stateParams: $stateParams }); + })); + + describe('Import Backup', function() { + + it('imports a valid backup', function() { + var importData = __json__['fixtures/valid-backup']; + scope.importJSON = angular.toJson(importData); + scope.validateJson(); + expect(scope.jsonValid).toBeTruthy(); + expect(scope.errorMsg).toEqual(null); + scope.process(); + expect(scope.processed).toBeTruthy(); + scope.import(); + expect(angular.fromJson(localStorage.getItem('builds'))).toEqual(importData.builds); + expect(angular.fromJson(localStorage.getItem('comparisons'))).toEqual(importData.comparisons); + expect(localStorage.getItem('insurance')).toEqual(importData.insurance); + expect(angular.fromJson(localStorage.getItem('discounts'))).toEqual(importData.discounts); + }); + + it('imports an old valid backup', function() { + var importData = __json__['fixtures/old-valid-export']; + scope.importJSON = angular.toJson(importData); + scope.validateJson(); + expect(scope.jsonValid).toBeTruthy(); + expect(scope.errorMsg).toEqual(null); + scope.process(); + expect(scope.processed).toBeTruthy(); + scope.import(); + expect(angular.fromJson(localStorage.getItem('builds'))).toEqual(importData.builds); + }); + + it('catches an invalid backup', function() { + var importData = __json__['fixtures/valid-backup']; + + scope.importJSON = 'null'; + scope.validateJson(); + expect(scope.jsonValid).toBeFalsy(); + expect(scope.errorMsg).toEqual('Must be an object or array!'); + + scope.importJSON = '{ "builds": "Should not be a string" }'; + scope.validateJson(); + expect(scope.jsonValid).toBeFalsy(); + expect(scope.errorMsg).toEqual('builds must be an object!'); + + scope.importJSON = angular.toJson(importData).replace('anaconda', 'invalid_ship'); + scope.validateJson(); + expect(scope.jsonValid).toBeFalsy(); + expect(scope.errorMsg).toEqual('"invalid_ship" is not a valid Ship Id!'); + + scope.importJSON = angular.toJson(importData).replace('Dream', ''); + scope.validateJson(); + expect(scope.jsonValid).toBeFalsy(); + expect(scope.errorMsg).toEqual('Imperial Clipper build "" must be a string at least 3 characters long!'); + + }); + + }); + + describe('Import Detailed Build', function() { + + it('imports a valid build', function() { + var importData = __json__['fixtures/anaconda-test-detailed-export']; + scope.importJSON = angular.toJson(importData); + scope.validateJson(); + expect(scope.jsonValid).toBeTruthy(); + expect(scope.errorMsg).toEqual(null); + scope.process(); + expect(scope.processed).toBeTruthy(); + scope.import(); + expect(angular.fromJson(localStorage.getItem('builds'))).toEqual({ + anaconda: { 'Test': '48A6A6A5A8A8A5C2c0o0o0o1m1m0q0q0404-0l0b0100034k5n052d04--0303326b.Iw18ZlA=.Aw18ZlA=' } + }); + }); + + it('catches an invalid build', function() { + var importData = __json__['fixtures/anaconda-test-detailed-export']; + scope.importJSON = angular.toJson(importData).replace('components', 'comps'); + scope.validateJson(); + expect(scope.jsonValid).toBeFalsy(); + expect(scope.errorMsg).toEqual('Anaconda Build "Test": Invalid data'); + }); + + }); + + describe('Import Detaild Builds Array', function() { + + it('imports all builds', function() { + var importData = __json__['fixtures/valid-detailed-export']; + var expectedBuilds = __json__['fixtures/expected-builds']; + scope.importJSON = angular.toJson(importData); + scope.validateJson(); + expect(scope.jsonValid).toBeTruthy(); + expect(scope.errorMsg).toEqual(null); + scope.process(); + expect(scope.processed).toBeTruthy(); + scope.import(); + var builds = angular.fromJson(localStorage.getItem('builds')); + for (var s in builds) { + for (var b in builds[s]) { + expect(builds[s][b]).toEqual(expectedBuilds[s][b]); + } + } + }); + + }); + +}); diff --git a/test/tests/test-controller-outfit.js b/test/tests/test-controller-outfit.js index a25ed9db..3f87fd56 100644 --- a/test/tests/test-controller-outfit.js +++ b/test/tests/test-controller-outfit.js @@ -1,7 +1,7 @@ describe("Outfit Controller", function() { beforeEach(module('app')); - var outfitController, scope; + var outfitController, $rootScope, $stateParams, scope; var eventStub = { preventDefault: function(){ }, diff --git a/test/tests/test-service-serializer.js b/test/tests/test-service-serializer.js index 87565490..25000896 100644 --- a/test/tests/test-service-serializer.js +++ b/test/tests/test-service-serializer.js @@ -1,18 +1,19 @@ describe("Serializer Service", function() { beforeEach(module('app')); - var Ship, Serializer; + var Ship, + Serializer, + code = '48A6A6A5A8A8A5C2c0o0o0o1m1m0q0q0404-0l0b0100034k5n052d04--0303326b', + anaconda = DB.ships['anaconda'], + testBuild, + exportData; beforeEach(inject(function (_Ship_, _Serializer_) { Ship = _Ship_; Serializer = _Serializer_; })); - describe("Detailed Export", function() { - var code = '48A6A6A5A8A8A5C2c0o0o0o1m1m0q0q0404-0l0b0100034k5n052d04--0303326b.AwRj4yo5dig=.MwBhEYy6duwEziA', - anaconda = DB.ships['anaconda'], - testBuild, - exportData; + describe("To Detailed Build", function() { beforeEach(function() { testBuild = new Ship('anaconda', anaconda.properties, anaconda.slots); @@ -37,4 +38,20 @@ describe("Serializer Service", function() { }); + describe("From Detailed Build", function() { + + it("builds the ship correctly", function() { + var anacondaTestExport = __json__['fixtures/anaconda-test-detailed-export']; + testBuildA = new Ship('anaconda', anaconda.properties, anaconda.slots); + Serializer.toShip(testBuildA, code); + testBuildB = Serializer.fromDetailedBuild(anacondaTestExport); + + for(var p in testBuildB) { + expect(testBuildB[p]).toEqual(testBuildA[p], p + ' does not match'); + } + + }); + + }); + });