mirror of
https://github.com/EDCD/coriolis.git
synced 2025-12-08 22:33:24 +00:00
Compare commits
47 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b49eb06101 | ||
|
|
eeb4a86a13 | ||
|
|
3a265b2804 | ||
|
|
5ebabd6e6e | ||
|
|
6e6c337bbb | ||
|
|
31b56354e0 | ||
|
|
fd1adbe55c | ||
|
|
3d0259c304 | ||
|
|
6f1b86118e | ||
|
|
b3fcfa7808 | ||
|
|
4ead80a37c | ||
|
|
72dc73e090 | ||
|
|
bb19dc25c0 | ||
|
|
1729636657 | ||
|
|
92809d1d24 | ||
|
|
4e81c828df | ||
|
|
f5bd7d2ecb | ||
|
|
a989bd5b5d | ||
|
|
1bedbb1909 | ||
|
|
9775e1c742 | ||
|
|
19228a9c56 | ||
|
|
363bf7fd2a | ||
|
|
15748066c9 | ||
|
|
c3fe0a0cef | ||
|
|
1544deb350 | ||
|
|
f060eb1b62 | ||
|
|
32795ea678 | ||
|
|
d744d15132 | ||
|
|
bfcef18c02 | ||
|
|
b04c2ed2f5 | ||
|
|
f51998b1c2 | ||
|
|
d7000bfebf | ||
|
|
3e2b3e33fb | ||
|
|
87dd52c043 | ||
|
|
05bc8ebb93 | ||
|
|
09b945d29e | ||
|
|
67b5d749df | ||
|
|
a19fd69d0b | ||
|
|
cfb65396ab | ||
|
|
a4a0f96502 | ||
|
|
1390339024 | ||
|
|
43d19f1dbb | ||
|
|
c20439264a | ||
|
|
61c3941618 | ||
|
|
da277e4eaa | ||
|
|
51d24a1105 | ||
|
|
138931c0cf |
@@ -6,7 +6,8 @@
|
||||
{
|
||||
"name": "Coriolis.io",
|
||||
"url": "http://localhost:3300/outfit/anaconda/48A6A6A5A8A8A5C2c0o0o0o1m1m0q0q0404-0l0b0100034k5n052d04--0303326b.AwRj4zNKqA==.CwBhCYzBGW9qCTSqs5xA?bn=Test%20My%20Ship",
|
||||
"code": "48A6A6A5A8A8A5C2c0o0o0o1m1m0q0q0404-0l0b0100034k5n052d04--0303326b.AwRj4zNKqA==.CwBhCYzBGW9qCTSqs5xA",
|
||||
"old-code": "48A6A6A5A8A8A5C2c0o0o0o1m1m0q0q0404-0l0b0100034k5n052d04--0303326b.AwRj4zNKqA==.CwBhCYzBGW9qCTSqs5xA",
|
||||
"code": "4putkFklkdzsuf52c0o0o0o1m1m0q0q0404-0l0b0100034k5n052d04--0303326b.AwRj4zNKqA==.CwBhCYzBGW9qCTSqs5xA",
|
||||
"shipId": "anaconda"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -2,31 +2,31 @@
|
||||
{
|
||||
"shipId": "anaconda",
|
||||
"buildName": "Imported Anaconda",
|
||||
"buildCode": "08E7E6E5E8E8E5C------1717--------05044j-03--2h--00.Iw18ZlA=.Aw18ZlA=",
|
||||
"buildCode": "0pyttFolodDsyf5------1717--------05044j-03--2h--00.Iw18ZlA=.Aw18ZlA=",
|
||||
"buildText": "[Anaconda]\nS: 1F/F Pulse Laser\nS: 1F/F Pulse Laser\n\nBH: 1I Lightweight Alloy\nRB: 8E Power Plant\nTM: 7E Thrusters\nFH: 6E Frame Shift Drive\nEC: 5E Life Support\nPC: 8E Power Distributor\nSS: 8E Sensors\nFS: 5C Fuel Tank (Capacity: 32)\n\n7: 6E Cargo Rack (Capacity: 64)\n6: 5E Cargo Rack (Capacity: 32)\n6: 6E Shield Generator\n5: 4E Cargo Rack (Capacity: 16)\n4: 1E Basic Discovery Scanner\n2: 1E Cargo Rack (Capacity: 2)\n"
|
||||
},
|
||||
{
|
||||
"shipId": "anaconda",
|
||||
"buildName": "Imported Anaconda",
|
||||
"buildCode": "08E7E6E5E8E8E5C------1717--------05044j-03--2h--00.Iw18ZlA=.Aw18ZlA=",
|
||||
"buildCode": "0pyttFolodDsyf5------1717--------05044j-03--2h--00.Iw18ZlA=.Aw18ZlA=",
|
||||
"buildText": "\n\n \t[Anaconda]\nS: 1F/F Pulse Laser\nS: 1F/F Pulse Laser\n\nBH: 1I Lightweight Alloy\nRB: 8E Power Plant\nTM: 7E Thrusters\nFH: 6E Frame Shift Drive\nEC: 5E Life Support\nPC: 8E Power Distributor\nSS: 8E Sensors\nFS: 5C Fuel Tank (Capacity: 32)\n\n7: 6E Cargo Rack (Capacity: 64)\n6: 5E Cargo Rack (Capacity: 32)\n6: 6E Shield Generator\n5: 4E Cargo Rack (Capacity: 16)\n4: 1E Basic Discovery Scanner\n2: 1E Cargo Rack (Capacity: 2)\n"
|
||||
},
|
||||
{
|
||||
"shipId": "cobra_mk_iii",
|
||||
"buildName": "Imported Cobra Mk III",
|
||||
"buildCode": "04A4C4E3D2A3D4C1712222503040202490f242h.Iw1-kA==.Aw1-kA==",
|
||||
"buildCode": "0patcFeldd5sdf41712222503040202490f242h.Iw1-kA==.Aw1-kA==",
|
||||
"buildText": "[Cobra Mk III]\nM: 1F/F Pulse Laser\nM: 1G/G Burst Laser\nS: 1E/T Fragment Cannon\nS: 1G/T Multi-cannon\nU: 0I Point Defence\nU: 0A Shield Booster\n\nBH: 1I Lightweight Alloy\nRB: 4A Power Plant\nTM: 4C Thrusters\nFH: 4E Frame Shift Drive\nEC: 3D Life Support\nPC: 2A Power Distributor\nSS: 3D Sensors\nFS: 4C Fuel Tank (Capacity: 16)\n\n4: 3E Cargo Rack (Capacity: 8)\n4: 3E Cargo Rack (Capacity: 8)\n4: 4E Shield Generator\n2: 2C Auto Field-Maintenance Unit\n2: 1E Standard Docking Computer\n2: 1E Basic Discovery Scanner\n---\nShield: 112.29 MJ\nPower : 10.45 MW retracted (67%)\n 12.16 MW deployed (78%)\n 15.60 MW available\nCargo : 16 T\nFuel : 16 T\nMass : 235.5 T empty\n 267.5 T full\nRange : 10.69 LY unladen\n 10.05 LY laden\nPrice : 2,929,040 CR\nRe-Buy: 146,452 CR @ 95% insurance\n"
|
||||
},
|
||||
{
|
||||
"shipId": "type_9_heavy",
|
||||
"buildName": "Imported Type-9 Heavy",
|
||||
"buildCode": "35A7D6A5A4D4D5C7e2k2f2h110001020306054j03022f01242i.Iw18eQ==.Aw18eQ==",
|
||||
"buildCode": "3pftsFklkdisif57e2k2f2h110001020306054j03022f01242i.Iw18eQ==.Aw18eQ==",
|
||||
"buildText": "[Type-9 Heavy]\nM: 2D/G Fragment Cannon\nM: 2I/F Mine Launcher\nM: 2B/FD Missile Rack\nS: 1I/FS Torpedo Pylon\nS: 1F/F Burst Laser\nU: 0I Chaff Launcher\nU: 0F Electronic Countermeasure\nU: 0I Heat Sink Launcher\nU: 0I Point Defence\n\nBH: 1I Mirrored Surface Composite\nRB: 5A Power Plant\nTM: 7D Thrusters\nFH: 6A Frame Shift Drive\nEC: 5A Life Support\nPC: 4D Power Distributor\nSS: 4D Sensors\nFS: 5C Fuel Tank (Capacity: 32)\n\n8: 7E Cargo Rack (Capacity: 128)\n7: 6E Cargo Rack (Capacity: 64)\n6: 6E Shield Generator\n5: 4E Cargo Rack (Capacity: 16)\n4: 3E Cargo Rack (Capacity: 8)\n4: 1C Advanced Discovery Scanner\n3: 2E Cargo Rack (Capacity: 4)\n3: 1E Standard Docking Computer\n2: 1C Detailed Surface Scanner\n"
|
||||
},
|
||||
{
|
||||
"shipId": "vulture",
|
||||
"buildName": "Imported Vulture",
|
||||
"buildCode": "44A5A4A3D5A4D3C1e1e0e0j04044a0n532jf1.Iw19kA==.Aw19kA==",
|
||||
"buildCode": "4patfFalddksif31e1e0e0j04044a0n532jf1.Iw19kA==.Aw19kA==",
|
||||
"buildText": "[Vulture]\nL: 3E/G Pulse Laser\nL: 3E/G Pulse Laser\nU: 0A Frame Shift Wake Scanner\nU: 0A Kill Warrant Scanner\nU: 0A Shield Booster\nU: 0A Shield Booster\n\nBH: 1I Reactive Surface Composite\nRB: 4A Power Plant\nTM: 5A Thrusters\nFH: 4A Frame Shift Drive\nEC: 3D Life Support\nPC: 5A Power Distributor\nSS: 4D Sensors\nFS: 3C Fuel Tank (Capacity: 8)\n\n5: 5A Shield Generator\n4: 4A Auto Field-Maintenance Unit\n2: 2A Shield Cell Bank\n1: 1A Fuel Scoop\n1: 1C Fuel Tank (Capacity: 2)"
|
||||
}
|
||||
]
|
||||
@@ -1,50 +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=="
|
||||
"Cargo": "0p0tdFal8d8s8f4-----04040303430101.Iw1-kA==.Aw1-kA==",
|
||||
"Miner": "0p5tdFal8d8s8f42l2l---040403451q0101.Iw1-kA==.Aw1-kA==",
|
||||
"Hopper": "0p0tdFal8d0s8f41717---030302024300-.Iw1-kA==.Aw1-kA=="
|
||||
},
|
||||
"type_7_transport": {
|
||||
"Cargo": "02A5D5A4D3D3D5C--------0505040403480101.Iw18aQ==.Aw18aQ==",
|
||||
"Miner": "04D5D5A4D2D3D5C--2l2l----0505041v03450000.Iw18aQ==.Aw18aQ=="
|
||||
"Cargo": "0p0tiFfliddsdf5--------0505040403480101.Iw18aQ==.Aw18aQ==",
|
||||
"Miner": "0pdtiFflid8sdf5--2l2l----0505041v03450000.Iw18aQ==.Aw18aQ=="
|
||||
},
|
||||
"federal_dropship": {
|
||||
"Cargo": "04D5D5A5D3D4D4C-1717------05040448020201.Iw18aQ==.Aw18aQ=="
|
||||
"Cargo": "0pdtiFflnddsif4-1717------05040448020201.Iw18aQ==.Aw18aQ=="
|
||||
},
|
||||
"asp": {
|
||||
"Miner": "25A5A5A4D4A5A5C0s0s24242l2l---04054a1q02022o27.Iw18WQ==.Aw18WQ=="
|
||||
"Miner": "2pftfFflidfskf50s0s24242l2l---04054a1q02022o27.Iw18WQ==.Aw18WQ=="
|
||||
},
|
||||
"imperial_clipper": {
|
||||
"Cargo": "03A5D5A5D4D5D4C--0s0s----0605450302020101.Iw18aQ==.Aw18aQ==",
|
||||
"Dream": "26A6A5A5D6A5A4C0v0v0s0s0404040n4k5n5d2b29292o-.Iw18aQ==.Aw18aQ==",
|
||||
"Current": "04A6A5A5D4A5A4C----------------.Iw18aQ==.Aw18aQ=="
|
||||
"Cargo": "0p5tiFflndisnf4--0s0s----0605450302020101.Iw18aQ==.Aw18aQ==",
|
||||
"Dream": "2pktkFflndpskf40v0v0s0s0404040n4k5n5d2b29292o-.Iw18aQ==.Aw18aQ==",
|
||||
"Current": "0patkFflndfskf4----------------.Iw18aQ==.Aw18aQ=="
|
||||
},
|
||||
"type_9_heavy": {
|
||||
"Current": "04A7D6A5D5D4D6C---------0706054a0303020224.Iw18eQ==.Aw18eQ=="
|
||||
"Current": "0patsFklndnsif6---------0706054a0303020224.Iw18eQ==.Aw18eQ=="
|
||||
},
|
||||
"python": {
|
||||
"Cargo": "04A6D5A4D6D6D5C---------050505040448020201.Iw18eQ==.Aw18eQ==",
|
||||
"Miner": "06A6A5A4D6A6A5C0v0v0v2m2m0404--050505Ce4a1v02022o.Iw18eQ==.Aw18eQ==",
|
||||
"Dream": "27A6A5A4D7A6A5C0v0v0v27270404040m5n5n4f2d2d032t0201.Iw18eQ==.Aw18eQ==",
|
||||
"Missile": "07E6E5E4E7E6E5C2f2g2d2ePh----04044j03---002h.Iw18eQ==.Aw18eQ=="
|
||||
"Cargo": "0patnFflidsssf5---------050505040448020201.Iw18eQ==.Aw18eQ==",
|
||||
"Miner": "0pktkFflidpspf50v0v0v2m2m0404--050505Ce4a1v02022o.Iw18eQ==.Aw18eQ==",
|
||||
"Dream": "2pptkFfliduspf50v0v0v27270404040m5n5n4f2d2d032t0201.Iw18eQ==.Aw18eQ==",
|
||||
"Missile": "0pttoFjljdystf52f2g2d2ePh----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="
|
||||
"Dream": "4putpFklndzsuf52c0o0o0o1m1m0q0q0404040l0b0100004k5n5n112d2d040303326b.Iw18ZlA=.Aw18ZlA=",
|
||||
"Cargo": "0patnFklndnsxf5----------------0605050504040445030301.Iw18ZlA=.Aw18ZlA=",
|
||||
"Current": "0patnFklndksxf5----------------0605050504040403034524.Iw18ZlA=.Aw18ZlA=",
|
||||
"Explorer": "0patnFklndksxf5--------0202------f7050505040s372f2i4524.Iw18ZlA=.Aw18ZlA=",
|
||||
"Test": "4putkFklkdzsuf52c0o0o0o1m1m0q0q0404-0l0b0100034k5n052d04--0303326b.Iw18ZlA=.Aw18ZlA="
|
||||
},
|
||||
"diamondback_explorer": {
|
||||
"Explorer": "02A4D5A3D3D3D5C---0202--320p432i2f.Iw1-kA==.Aw1-kA=="
|
||||
"Explorer": "0p0tdFfldddsdf5---0202--320p432i2f.Iw1-kA==.Aw1-kA=="
|
||||
},
|
||||
"vulture": {
|
||||
"Bounty Hunter": "34A4C4A3D5A4A3C1e1e0404-0l4a5d27662j.Iw19kA==.Aw19kA=="
|
||||
"Bounty Hunter": "3patcFalddksff31e1e0404-0l4a5d27662j.Iw19kA==.Aw19kA=="
|
||||
},
|
||||
"fer_de_lance": {
|
||||
"Attack": "25A5C4A4D6A4A3C1r0s0s0s0s000404-04-4a-5d27-.Iw18aQ==.Aw18aQ=="
|
||||
"Attack": "2pfthFalidpsff31r0s0s0s0s000404-04-4a-5d27-.Iw18aQ==.Aw18aQ=="
|
||||
},
|
||||
"eagle": {
|
||||
"Figther": "42A3A3A1D2A2A2C0p0p24-40532j.Iw19A===.Aw19A==="
|
||||
"Figther": "4p0t5F5l3d5s5f20p0p24-40532j-.Iw1-EA==.Aw1-EA=="
|
||||
}
|
||||
}
|
||||
@@ -3348,8 +3348,8 @@
|
||||
"references": [
|
||||
{
|
||||
"name": "Coriolis.io",
|
||||
"url": "http://localhost:3300/outfit/eagle/42A3A3A1D2A2A2C0p0p24-40532j.Iw19A===.Aw19A===?bn=Figther",
|
||||
"code": "42A3A3A1D2A2A2C0p0p24-40532j.AwRj49iA.AwgsIkEZigmIA===",
|
||||
"url": "http://localhost:3300/outfit/eagle/42A3A3A1D2A2A2C0p0p24-40532j-.Iw1-EA==.Aw1-EA==?bn=Figther",
|
||||
"code": "42A3A3A1D2A2A2C0p0p24-40532j-.Iw1-EA==.Aw1-EA==",
|
||||
"shipId": "eagle"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -10,7 +10,7 @@ import { getLanguage } from '../src/app/i18n/Language';
|
||||
|
||||
describe('Import Modal', function() {
|
||||
|
||||
let MockRouter = require('../src/app/Router');
|
||||
let MockRouter = require('../src/app/Router').default;
|
||||
const Persist = require('../src/app/stores/Persist').default;
|
||||
const ModalImport = require('../src/app/components/ModalImport').default;
|
||||
const mockContext = {
|
||||
@@ -25,8 +25,6 @@ describe('Import Modal', function() {
|
||||
onWindowResize: jest.genMockFunction()
|
||||
};
|
||||
|
||||
MockRouter.go = jest.genMockFunction();
|
||||
|
||||
let modal, render, ContextProvider = Utils.createContextProvider(mockContext);
|
||||
|
||||
/**
|
||||
@@ -140,9 +138,10 @@ describe('Import Modal', function() {
|
||||
|
||||
expect(modal.state.importValid).toBeTruthy();
|
||||
expect(modal.state.errorMsg).toEqual(null);
|
||||
expect(modal.state.singleBuild).toBe(true);
|
||||
clickProceed();
|
||||
expect(MockRouter.go.mock.calls.length).toBe(1);
|
||||
expect(MockRouter.go.mock.calls[0][0]).toBe('/outfit/anaconda/48A6A6A5A8A8A5C2c0o0o0o1m1m0q0q0404-0l0b0100034k5n052d04--0303326b.AwRj4zNKqA==.CwBhCYzBGW9qCTSqs5xA?bn=Test%20My%20Ship');
|
||||
expect(MockRouter.go.mock.calls[0][0]).toBe('/outfit/anaconda/4putkFklkdzsuf52c0o0o0o1m1m0q0q0404-0l0b0100034k5n052d04--0303326b.AwRj4zNKqA==.CwBhCYzBGW9qCTSqs5xA?bn=Test%20My%20Ship');
|
||||
});
|
||||
|
||||
it('catches an invalid build', function() {
|
||||
|
||||
@@ -2,7 +2,7 @@ import Ship from '../src/app/shipyard/Ship';
|
||||
import { Ships } from 'coriolis-data/dist';
|
||||
import * as ModuleUtils from '../src/app/shipyard/ModuleUtils';
|
||||
|
||||
describe("Ship Factory", function() {
|
||||
describe("Ship", function() {
|
||||
|
||||
it("can build all ships", function() {
|
||||
for (let s in Ships) {
|
||||
@@ -115,8 +115,7 @@ describe("Ship Factory", function() {
|
||||
|
||||
anaconda.use(anaconda.internal[1], ModuleUtils.internal('4j')); // 6E Shield Generator
|
||||
|
||||
expect(anaconda.internal[2].c).toEqual(null, 'Anaconda default shield generator slot is empty');
|
||||
expect(anaconda.internal[2].m).toEqual(null, 'Anaconda default shield generator slot id is null');
|
||||
expect(anaconda.internal[2].m).toEqual(null, 'Anaconda default shield generator slot is empty');
|
||||
expect(anaconda.internal[1].m.id).toEqual('4j', 'Slot 1 should have SG 4j in it');
|
||||
expect(anaconda.internal[1].m.grp).toEqual('sg','Slot 1 should have SG 4j in it');
|
||||
|
||||
@@ -133,8 +132,7 @@ describe("Ship Factory", function() {
|
||||
|
||||
anaconda.use(anaconda.internal[3], ModuleUtils.internal('32'));
|
||||
|
||||
expect(anaconda.internal[4].c).toEqual(null, 'Anaconda original fuel scoop slot is empty');
|
||||
expect(anaconda.internal[4].m).toEqual(null, 'Anaconda original fuel scoop slot id is null');
|
||||
expect(anaconda.internal[4].m).toEqual(null, 'Anaconda original fuel scoop slot is empty');
|
||||
expect(anaconda.internal[3].m.id).toEqual('32', 'Slot 1 should have FS 32 in it');
|
||||
expect(anaconda.internal[3].m.grp).toEqual('fs','Slot 1 should have FS 32 in it');
|
||||
});
|
||||
@@ -150,8 +148,7 @@ describe("Ship Factory", function() {
|
||||
|
||||
anaconda.use(anaconda.internal[3], ModuleUtils.internal('23'));
|
||||
|
||||
expect(anaconda.internal[4].c).toEqual(null, 'Anaconda original refinery slot is empty');
|
||||
expect(anaconda.internal[4].m).toEqual(null, 'Anaconda original refinery slot id is null');
|
||||
expect(anaconda.internal[4].m).toEqual(null, 'Anaconda original refinery slot is empty');
|
||||
expect(anaconda.internal[3].m.id).toEqual('23', 'Slot 1 should have RF 23 in it');
|
||||
expect(anaconda.internal[3].m.grp).toEqual('rf','Slot 1 should have RF 23 in it');
|
||||
});
|
||||
|
||||
18
package.json
18
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "coriolis_shipyard",
|
||||
"version": "2.0.0-Beta-1",
|
||||
"version": "2.0.0",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/cmmcleod/coriolis"
|
||||
@@ -20,7 +20,7 @@
|
||||
"prod-stop": "kill -QUIT $(cat nginx.pid)",
|
||||
"build": "npm run clean && NODE_ENV=production webpack -d -p --config webpack.config.prod.js",
|
||||
"rsync": "rsync -ae \"ssh -i $CORIOLIS_PEM\" --delete build/ $CORIOLIS_USER@$CORIOLIS_HOST:~/wwws",
|
||||
"deploy": "npm run lint && npm test && npm run build:prod && npm run rsync"
|
||||
"deploy": "npm run lint && npm test && npm run build && npm run rsync"
|
||||
},
|
||||
"jest": {
|
||||
"scriptPreprocessor": "<rootDir>/node_modules/babel-jest",
|
||||
@@ -43,7 +43,7 @@
|
||||
"<rootDir>/node_modules/d3",
|
||||
"<rootDir>/node_modules/lz-string",
|
||||
"<rootDir>/node_modules/jsen",
|
||||
"<rootDir>/node_modules/coriolis-data",
|
||||
"coriolis-data",
|
||||
"<rootDir>/src/app/shipyard",
|
||||
"<rootDir>/src/app/i18n",
|
||||
"<rootDir>/src/app/utils",
|
||||
@@ -68,13 +68,13 @@
|
||||
"extract-text-webpack-plugin": "^0.9.1",
|
||||
"file-loader": "^0.8.4",
|
||||
"html-webpack-plugin": "^1.7.0",
|
||||
"jest-cli": "*",
|
||||
"jest-cli": "^0.9.2",
|
||||
"jsen": "^0.6.0",
|
||||
"json-loader": "^0.5.3",
|
||||
"less": "^2.5.3",
|
||||
"less-loader": "^2.2.1",
|
||||
"react-addons-test-utils": "^0.14.7",
|
||||
"react-testutils-additions": "^0.16.0",
|
||||
"react-addons-test-utils": "^15.0.1",
|
||||
"react-testutils-additions": "^15.1.0",
|
||||
"rimraf": "^2.4.3",
|
||||
"style-loader": "^0.13.0",
|
||||
"url-loader": "^0.5.6",
|
||||
@@ -85,11 +85,11 @@
|
||||
"babel-polyfill": "*",
|
||||
"classnames": "^2.2.0",
|
||||
"coriolis-data": "cmmcleod/coriolis-data",
|
||||
"d3": "^3.5.9",
|
||||
"d3": "3.5.16",
|
||||
"fbemitter": "^2.0.0",
|
||||
"lz-string": "^1.4.4",
|
||||
"react": "^0.14.7",
|
||||
"react-dom": "^0.14.7",
|
||||
"react": "^15.0.1",
|
||||
"react-dom": "^15.0.1",
|
||||
"superagent": "^1.4.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,17 +21,18 @@ import ErrorDetails from './pages/ErrorDetails';
|
||||
export default class Coriolis extends React.Component {
|
||||
|
||||
static childContextTypes = {
|
||||
language: React.PropTypes.object.isRequired,
|
||||
sizeRatio: React.PropTypes.number.isRequired,
|
||||
route: React.PropTypes.object.isRequired,
|
||||
openMenu: React.PropTypes.func.isRequired,
|
||||
closeMenu: React.PropTypes.func.isRequired,
|
||||
showModal: React.PropTypes.func.isRequired,
|
||||
hideModal: React.PropTypes.func.isRequired,
|
||||
tooltip: React.PropTypes.func.isRequired,
|
||||
termtip: React.PropTypes.func.isRequired,
|
||||
language: React.PropTypes.object.isRequired,
|
||||
noTouch: React.PropTypes.bool.isRequired,
|
||||
onCommand: React.PropTypes.func.isRequired,
|
||||
onWindowResize: React.PropTypes.func.isRequired,
|
||||
onCommand: React.PropTypes.func.isRequired
|
||||
openMenu: React.PropTypes.func.isRequired,
|
||||
route: React.PropTypes.object.isRequired,
|
||||
showModal: React.PropTypes.func.isRequired,
|
||||
sizeRatio: React.PropTypes.number.isRequired,
|
||||
termtip: React.PropTypes.func.isRequired,
|
||||
tooltip: React.PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -54,9 +55,10 @@ export default class Coriolis extends React.Component {
|
||||
|
||||
this.emitter = new EventEmitter();
|
||||
this.state = {
|
||||
noTouch: !('ontouchstart' in window || navigator.msMaxTouchPoints || navigator.maxTouchPoints),
|
||||
page: null,
|
||||
language: getLanguage(Persist.getLangCode()),
|
||||
route: null,
|
||||
route: {},
|
||||
sizeRatio: Persist.getSizeRatio()
|
||||
};
|
||||
|
||||
@@ -237,17 +239,18 @@ export default class Coriolis extends React.Component {
|
||||
*/
|
||||
getChildContext() {
|
||||
return {
|
||||
language: this.state.language,
|
||||
route: this.state.route,
|
||||
sizeRatio: this.state.sizeRatio,
|
||||
openMenu: this._openMenu,
|
||||
closeMenu: this._closeMenu,
|
||||
showModal: this._showModal,
|
||||
hideModal: this._hideModal,
|
||||
tooltip: this._tooltip,
|
||||
termtip: this._termtip,
|
||||
language: this.state.language,
|
||||
noTouch: this.state.noTouch,
|
||||
onCommand: this._onCommand,
|
||||
onWindowResize: this._onWindowResize,
|
||||
onCommand: this._onCommand
|
||||
openMenu: this._openMenu,
|
||||
route: this.state.route,
|
||||
showModal: this._showModal,
|
||||
sizeRatio: this.state.sizeRatio,
|
||||
termtip: this._termtip,
|
||||
tooltip: this._tooltip
|
||||
};
|
||||
}
|
||||
|
||||
@@ -266,7 +269,7 @@ export default class Coriolis extends React.Component {
|
||||
|
||||
window.onerror = this._onError.bind(this);
|
||||
window.addEventListener('resize', () => this.emitter.emit('windowResize'));
|
||||
document.body.addEventListener('scroll', () => this._tooltip());
|
||||
document.getElementById('coriolis').addEventListener('scroll', () => this._tooltip());
|
||||
document.addEventListener('keydown', this._keyDown);
|
||||
Persist.addListener('language', this._onLanguageChange);
|
||||
Persist.addListener('sizeRatio', this._onSizeRatioChange);
|
||||
@@ -281,11 +284,16 @@ export default class Coriolis extends React.Component {
|
||||
render() {
|
||||
let currentMenu = this.state.currentMenu;
|
||||
|
||||
return <div onClick={this._closeMenu}>
|
||||
return <div style={{ minHeight: '100%' }} onClick={this._closeMenu} className={ this.state.noTouch ? 'no-touch' : null }>
|
||||
<Header appCacheUpdate={this.state.appCacheUpdate} currentMenu={currentMenu} />
|
||||
{ this.state.error ? this.state.error : this.state.page ? React.createElement(this.state.page, { currentMenu }) : <NotFoundPage/> }
|
||||
{ this.state.modal }
|
||||
{ this.state.tooltip }
|
||||
<footer>
|
||||
<div className="right cap">
|
||||
<a href="https://github.com/cmmcleod/coriolis/releases/" target="_blank" title="Coriolis Github Project">{window.CORIOLIS_VERSION} - {window.CORIOLIS_DATE}</a>
|
||||
</div>
|
||||
</footer>
|
||||
</div>;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
import Persist from './stores/Persist';
|
||||
|
||||
let standalone = undefined;
|
||||
|
||||
/**
|
||||
* Determine if the app is running in mobile/tablet 'standalone' mode
|
||||
* @return {Boolean} True if the app is in standalone mode
|
||||
*/
|
||||
function isStandAlone() {
|
||||
try {
|
||||
return window.navigator.standalone || (window.external && window.external.msIsSiteMode && window.external.msIsSiteMode());
|
||||
} catch (ex) {
|
||||
return false;
|
||||
if (standalone === undefined) {
|
||||
try {
|
||||
standalone = window.navigator.standalone || (window.external && window.external.msIsSiteMode && window.external.msIsSiteMode());
|
||||
} catch (ex) {
|
||||
standalone = false;
|
||||
}
|
||||
}
|
||||
return standalone;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -44,14 +49,14 @@ Router.start = function() {
|
||||
if (isStandAlone()) {
|
||||
let state = Persist.getState();
|
||||
// If a previous state has been stored, load that state
|
||||
if (state && state.name && state.params) {
|
||||
Router(this.props.initialPath || '/');
|
||||
if (state && state.path) {
|
||||
Router.replace(state.path, null, true);
|
||||
} else {
|
||||
Router('/');
|
||||
Router.replace('/', null, true);
|
||||
}
|
||||
} else {
|
||||
let url = location.pathname + location.search;
|
||||
Router.replace(url, null, true, true);
|
||||
Router.replace(url, null, true);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -68,6 +73,9 @@ Router.go = function(path, state) {
|
||||
let ctx = new Context(path, state);
|
||||
Router.dispatch(ctx);
|
||||
if (!ctx.unhandled) {
|
||||
if (isStandAlone()) {
|
||||
Persist.setState(ctx);
|
||||
}
|
||||
history.pushState(ctx.state, ctx.title, ctx.canonicalPath);
|
||||
}
|
||||
return ctx;
|
||||
@@ -85,7 +93,12 @@ Router.go = function(path, state) {
|
||||
Router.replace = function(path, state, dispatch) {
|
||||
gaTrack(path);
|
||||
let ctx = new Context(path, state);
|
||||
if (dispatch) Router.dispatch(ctx);
|
||||
if (dispatch) {
|
||||
Router.dispatch(ctx);
|
||||
}
|
||||
if (isStandAlone()) {
|
||||
Persist.setState(ctx);
|
||||
}
|
||||
history.replaceState(ctx.state, ctx.title, ctx.canonicalPath);
|
||||
return ctx;
|
||||
};
|
||||
@@ -227,7 +240,7 @@ Route.prototype.match = function(path, params) {
|
||||
*/
|
||||
function gaTrack(path) {
|
||||
if (window.ga) {
|
||||
window.ga('send', 'pageview', { page: path });
|
||||
window.ga('send', 'pageview', path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import { stopCtxPropagation } from '../utils/UtilityFunctions';
|
||||
import cn from 'classnames';
|
||||
import { MountFixed, MountGimballed, MountTurret } from './SvgIcons';
|
||||
|
||||
const PRESS_THRESHOLD = 5000; // mouse/touch down threshold
|
||||
const PRESS_THRESHOLD = 500; // mouse/touch down threshold
|
||||
|
||||
/**
|
||||
* Available modules menu
|
||||
@@ -173,6 +173,7 @@ export default class AvailableModulesMenu extends TranslatedComponent {
|
||||
* @param {SyntheticEvent} event Event
|
||||
*/
|
||||
_touchStart(showDiff, event) {
|
||||
event.preventDefault();
|
||||
let rect = event.currentTarget.getBoundingClientRect();
|
||||
this.touchTimeout = setTimeout(showDiff.bind(this, rect), PRESS_THRESHOLD);
|
||||
}
|
||||
@@ -183,10 +184,10 @@ export default class AvailableModulesMenu extends TranslatedComponent {
|
||||
* @param {SyntheticEvent} event Event
|
||||
*/
|
||||
_touchEnd(select, event) {
|
||||
event.preventDefault();
|
||||
if (this.touchTimeout !== null) { // If timeout has not fired (been nulled out) yet
|
||||
select();
|
||||
}
|
||||
event.preventDefault();
|
||||
this._hideDiff();
|
||||
}
|
||||
|
||||
|
||||
@@ -208,7 +208,7 @@ export default class BarChart extends TranslatedComponent {
|
||||
<g className='x axis' ref={(elem) => d3.select(elem).call(this.xAxis)} transform={`translate(0,${innerHeight})`}>
|
||||
<text className='cap' y='30' dy='.1em' x={innerWidth / 2} style={{ textAnchor: 'middle' }}>
|
||||
<tspan>{title}</tspan>
|
||||
{ unit ? <tspan className='metric'>{` (${unit})`}</tspan> : null }
|
||||
{ unit ? <tspan className='metric'> ({unit})</tspan> : null }
|
||||
</text>
|
||||
</g>
|
||||
<g className='y axis' ref={(elem) => { let e = d3.select(elem); e.call(this.yAxis); e.selectAll('text').each(insertLinebreaks); }} />
|
||||
|
||||
@@ -304,8 +304,8 @@ export default class CostSection extends TranslatedComponent {
|
||||
<tr className='main'>
|
||||
<th colSpan='2' className='sortable le' onClick={this._sortCostBy.bind(this,'m')}>
|
||||
{translate('module')}
|
||||
{shipDiscount && <u className='cap optional-hide' style={{ marginLeft: '0.5em' }}>{`[${translate('ship')} -${formats.pct(shipDiscount)}]`}</u>}
|
||||
{moduleDiscount && <u className='cap optional-hide' style={{ marginLeft: '0.5em' }}>{`[${translate('modules')} -${formats.pct(moduleDiscount)}]`}</u>}
|
||||
{shipDiscount ? <u className='cap optional-hide' style={{ marginLeft: '0.5em' }}>{`[${translate('ship')} -${formats.pct(shipDiscount)}]`}</u> : null}
|
||||
{moduleDiscount ? <u className='cap optional-hide' style={{ marginLeft: '0.5em' }}>{`[${translate('modules')} -${formats.pct(moduleDiscount)}]`}</u> : null}
|
||||
</th>
|
||||
<th className='sortable le' onClick={this._sortCostBy.bind(this, 'cr')} >{translate('credits')}</th>
|
||||
</tr>
|
||||
@@ -363,7 +363,7 @@ export default class CostSection extends TranslatedComponent {
|
||||
<th colSpan='2' className='sortable le' onClick={this._sortRetrofitBy.bind(this, 'buyName')}>{translate('buy')}</th>
|
||||
<th colSpan='2' className='sortable le' onClick={this._sortRetrofitBy.bind(this, 'cr')}>
|
||||
{translate('net cost')}
|
||||
{moduleDiscount < 1 && <u className='cap optional-hide' style={{ marginLeft: '0.5em' }}>{`[${translate('modules')} -${formats.pct(moduleDiscount)}]`}</u>}
|
||||
{moduleDiscount ? <u className='cap optional-hide' style={{ marginLeft: '0.5em' }}>{`[${translate('modules')} -${formats.pct(moduleDiscount)}]`}</u> : null}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -400,7 +400,7 @@ export default class CostSection extends TranslatedComponent {
|
||||
let retrofitCosts = [];
|
||||
let retrofitTotal = 0, i, l, item;
|
||||
|
||||
if (ship.bulkheads.index != retrofitShip.bulkheads.index) {
|
||||
if (ship.bulkheads.m.index != retrofitShip.bulkheads.m.index) {
|
||||
item = {
|
||||
buyClassRating: ship.bulkheads.m.class + ship.bulkheads.m.rating,
|
||||
buyName: ship.bulkheads.m.name,
|
||||
|
||||
@@ -38,7 +38,7 @@ export default class HardpointSlot extends Slot {
|
||||
|
||||
return <div className='details' draggable='true' onDragStart={drag} onDragEnd={drop}>
|
||||
<div className={'cb'}>
|
||||
<div className={'l'}>{classRating + ' ' + translate(m.name || m.grp)}</div>
|
||||
<div className={'l'}>{classRating} {translate(m.name || m.grp)}</div>
|
||||
<div className={'r'}>{m.mass}{u.T}</div>
|
||||
</div>
|
||||
<div className={'cb'}>
|
||||
|
||||
@@ -94,6 +94,7 @@ export default class HardpointsSlotSection extends SlotSection {
|
||||
return <div className='select hardpoint' onClick={(e) => e.stopPropagation()} onContextMenu={stopCtxPropagation}>
|
||||
<ul>
|
||||
<li className='lc' onClick={this._empty}>{translate('empty all')}</li>
|
||||
<li className='optional-hide' style={{ textAlign: 'center', marginTop: '1em' }}>{translate('PHRASE_ALT_ALL')}</li>
|
||||
</ul>
|
||||
<div className='select-group cap'>{translate('pl')}</div>
|
||||
<ul>
|
||||
|
||||
@@ -362,37 +362,51 @@ export default class Header extends TranslatedComponent {
|
||||
|
||||
return (
|
||||
<div className='menu-list no-wrap cap' onClick={ (e) => e.stopPropagation() }>
|
||||
<div style={{ lineHeight: '2em' }}>
|
||||
{translate('language')}
|
||||
<select className='cap' value={Persist.getLangCode()} onChange={this._setLanguage}>
|
||||
{this.languageOptions}
|
||||
</select>
|
||||
<br/>
|
||||
<span className='cap ptr' onClick={this._toggleTooltips} >
|
||||
{translate('tooltips')}
|
||||
<div className={cn({ disabled: !tips, 'primary-disabled': tips })} style={{ marginLeft: '0.5em', display: 'inline-block' }}>{(tips ? '✓' : '✗')}</div>
|
||||
</span>
|
||||
<br/>
|
||||
{translate('insurance')}
|
||||
<select className='cap' value={Persist.getInsurance()} onChange={this._setInsurance}>
|
||||
{this.insuranceOptions}
|
||||
</select>
|
||||
<br/>
|
||||
{translate('ship')} {translate('discount')}
|
||||
<input type='text' size='10' value={this.state.shipDiscount} onChange={this._changeShipDiscount} onFocus={selectAll} onBlur={this._setShipDiscount} onKeyDown={this._kpShipDiscount}/>
|
||||
<u className='primary-disabled'>%</u>
|
||||
<br/>
|
||||
{translate('module')} {translate('discount')}
|
||||
<input type='text' size='10' value={this.state.moduleDiscount} onChange={this._changeModuleDiscount} onFocus={selectAll} onBlur={this._setModuleDiscount} onKeyDown={this._kpModuleDiscount}/>
|
||||
<u className='primary-disabled'>%</u>
|
||||
</div>
|
||||
<table style={{ width: '100%', background: 'none', borderSpacing: '0 0.5em' }}>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{translate('language')}</td>
|
||||
<td className='ri'>
|
||||
<select className='cap' dir='rtl' value={Persist.getLangCode()} onChange={this._setLanguage}>
|
||||
{this.languageOptions}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr className='cap ptr' onClick={this._toggleTooltips} >
|
||||
<td>{translate('tooltips')}</td>
|
||||
<td className={cn('ri', { disabled: !tips, 'primary-disabled': tips })}>{(tips ? '✓' : '✗')}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{translate('insurance')}</td>
|
||||
<td className='ri'>
|
||||
<select className='cap' dir='rtl' value={Persist.getInsurance()} onChange={this._setInsurance}>
|
||||
{this.insuranceOptions}
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{translate('ship')} {translate('discount')}</td>
|
||||
<td className='ri'>
|
||||
<input type='text' size='10' value={this.state.shipDiscount} onChange={this._changeShipDiscount} onFocus={selectAll} onBlur={this._setShipDiscount} onKeyDown={this._kpShipDiscount}/>
|
||||
<u className='primary-disabled'>%</u>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{translate('module')} {translate('discount')}</td>
|
||||
<td className='ri'>
|
||||
<input type='text' size='10' value={this.state.moduleDiscount} onChange={this._changeModuleDiscount} onFocus={selectAll} onBlur={this._setModuleDiscount} onKeyDown={this._kpModuleDiscount}/>
|
||||
<u className='primary-disabled'>%</u>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<hr />
|
||||
<ul>
|
||||
<ul style={{ width: '100%' }}>
|
||||
{translate('builds')} & {translate('comparisons')}
|
||||
<li><Link href="#" className='block' onClick={this._showBackup.bind(this)}>{translate('backup')}</Link></li>
|
||||
<li><Link href="#" className='block' onClick={this._showDetailedExport.bind(this)}>{translate('detailed export')}</Link></li>
|
||||
<li><Link href="#" className='block' onClick={this._showImport.bind(this)}>{translate('import')}</Link></li>
|
||||
<li><Link href="#" onClick={this._showDeleteAll.bind(this)}>{translate('delete all')}</Link></li>
|
||||
<li><Link href="#" className='block' onClick={this._showDeleteAll.bind(this)}>{translate('delete all')}</Link></li>
|
||||
</ul>
|
||||
<hr />
|
||||
<table style={{ width: 300, backgroundColor: 'transparent' }}>
|
||||
@@ -462,32 +476,28 @@ export default class Header extends TranslatedComponent {
|
||||
let translate = this.context.language.translate;
|
||||
let openedMenu = this.props.currentMenu;
|
||||
let hasBuilds = Persist.hasBuilds();
|
||||
|
||||
if (this.props.appCacheUpdate) {
|
||||
return <div id="app-update" onClick={() => window.location.reload() }>{translate('PHRASE_UPDATE_RDY')}</div>;
|
||||
}
|
||||
|
||||
return (
|
||||
<header>
|
||||
{this.props.appCacheUpdate && <div id="app-update" onClick={() => window.location.reload() }>{translate('PHRASE_UPDATE_RDY')}</div>}
|
||||
<Link className='l' href='/' style={{ marginRight: '1em' }} title='Home'><CoriolisLogo className='icon xl' /></Link>
|
||||
|
||||
<div className='l menu'>
|
||||
<div className={cn('menu-header', { selected: openedMenu == 's' })} onClick={this._openShips}>
|
||||
<Rocket className='warning' /><span className='menu-item-label'>{' ' + translate('ships')}</span>
|
||||
<Rocket className='warning' /><span className='menu-item-label'>{translate('ships')}</span>
|
||||
</div>
|
||||
{openedMenu == 's' ? this._getShipsMenu() : null}
|
||||
</div>
|
||||
|
||||
<div className='l menu'>
|
||||
<div className={cn('menu-header', { selected: openedMenu == 'b', disabled: !hasBuilds })} onClick={hasBuilds && this._openBuilds}>
|
||||
<Hammer className={cn('warning', { 'warning-disabled': !hasBuilds })} /><span className='menu-item-label'>{' ' + translate('builds')}</span>
|
||||
<Hammer className={cn('warning', { 'warning-disabled': !hasBuilds })} /><span className='menu-item-label'>{translate('builds')}</span>
|
||||
</div>
|
||||
{openedMenu == 'b' ? this._getBuildsMenu() : null}
|
||||
</div>
|
||||
|
||||
<div className='l menu'>
|
||||
<div className={cn('menu-header', { selected: openedMenu == 'comp', disabled: !hasBuilds })} onClick={hasBuilds && this._openComp}>
|
||||
<StatsBars className={cn('warning', { 'warning-disabled': !hasBuilds })} /><span className='menu-item-label'>{' ' + translate('compare')}</span>
|
||||
<StatsBars className={cn('warning', { 'warning-disabled': !hasBuilds })} /><span className='menu-item-label'>{translate('compare')}</span>
|
||||
</div>
|
||||
{openedMenu == 'comp' ? this._getComparisonsMenu() : null}
|
||||
</div>
|
||||
|
||||
@@ -22,14 +22,14 @@ export default class InternalSlot extends Slot {
|
||||
|
||||
return <div className='details' draggable='true' onDragStart={drag} onDragEnd={drop}>
|
||||
<div className={'cb'}>
|
||||
<div className={'l'}>{classRating + ' ' + translate(m.name || m.grp)}</div>
|
||||
<div className={'l'}>{classRating} {translate(m.name || m.grp)}</div>
|
||||
<div className={'r'}>{m.mass || m.cargo || m.fuel || 0}{u.T}</div>
|
||||
</div>
|
||||
<div className={'cb'}>
|
||||
{ m.optmass ? <div className={'l'}>{translate('optimal mass') + ': '}{m.optmass}{u.T}</div> : null }
|
||||
{ m.maxmass ? <div className={'l'}>{translate('max mass') + ': '}{m.maxmass}{u.T}</div> : null }
|
||||
{ m.bins ? <div className={'l'}>{m.bins + ' '}<u>{translate('bins')}</u></div> : null }
|
||||
{ m.bays ? <div className={'l'}>{translate('bays') + ': ' + m.bays}</div> : null }
|
||||
{ m.optmass ? <div className={'l'}>{translate('optimal mass')}: {m.optmass}{u.T}</div> : null }
|
||||
{ m.maxmass ? <div className={'l'}>{translate('max mass')}: {m.maxmass}{u.T}</div> : null }
|
||||
{ m.bins ? <div className={'l'}>{m.bins} <u>{translate('bins')}</u></div> : null }
|
||||
{ m.bays ? <div className={'l'}>{translate('bays')}: {m.bays}</div> : null }
|
||||
{ m.rate ? <div className={'l'}>{translate('rate')}: {m.rate}{u.kgs} {translate('refuel time')}: {formats.time(this.props.fuel * 1000 / m.rate)}</div> : null }
|
||||
{ m.ammo ? <div className={'l'}>{translate('ammo')}: {formats.gen(m.ammo)}</div> : null }
|
||||
{ m.cells ? <div className={'l'}>{translate('cells')}: {m.cells}</div> : null }
|
||||
@@ -38,10 +38,10 @@ export default class InternalSlot extends Slot {
|
||||
{ m.range ? <div className={'l'}>{translate('range')} {m.range}{u.km}</div> : null }
|
||||
{ m.time ? <div className={'l'}>{translate('time')}: {formats.time(m.time)}</div> : null }
|
||||
{ m.maximum ? <div className={'l'}>{translate('max')}: {(m.maximum)}</div> : null }
|
||||
{ m.rangeLS ? <div className={'l'}>{m.rangeLS}{u.Ls}</div> : null }
|
||||
{ m.rangeLS ? <div className={'l'}>{translate('range')}: {m.rangeLS}{u.Ls}</div> : null }
|
||||
{ m.rangeLS === null ? <div className={'l'}><Infinite/>{u.Ls}</div> : null }
|
||||
{ m.rangeRating ? <div className={'l'}>{translate('range')}: {m.rangeRating}</div> : null }
|
||||
{ m.armouradd ? <div className={'l'}>+{m.armouradd} <u>{translate('armour')}</u></div> : null }
|
||||
{ m.armouradd ? <div className={'l'}>+{m.armouradd} <u className='cap'>{translate('armour')}</u></div> : null }
|
||||
</div>
|
||||
</div>;
|
||||
} else {
|
||||
|
||||
@@ -76,7 +76,7 @@ export default class InternalSlotSection extends SlotSection {
|
||||
let clobber = event.getModifierState('Alt');
|
||||
let ship = this.props.ship;
|
||||
ship.internal.forEach((slot) => {
|
||||
if (clobber || !slot.c) {
|
||||
if (clobber || !slot.m) {
|
||||
ship.use(slot, ModuleUtils.findInternal('hr', Math.min(slot.maxClass, 5), 'D')); // Hull reinforcements top out at 5D
|
||||
}
|
||||
});
|
||||
@@ -138,6 +138,7 @@ export default class InternalSlotSection extends SlotSection {
|
||||
<li className='lc' onClick={this._fillWithCargo}>{translate('cargo')}</li>
|
||||
<li className='lc' onClick={this._fillWithCells}>{translate('scb')}</li>
|
||||
<li className='lc' onClick={this._fillWithArmor}>{translate('hr')}</li>
|
||||
<li className='optional-hide' style={{ textAlign: 'center', marginTop: '1em' }}>{translate('PHRASE_ALT_ALL')}</li>
|
||||
</ul>
|
||||
</div>;
|
||||
}
|
||||
|
||||
@@ -235,13 +235,13 @@ export default class LineChart extends TranslatedComponent {
|
||||
<g className='x axis' ref={(elem) => d3.select(elem).call(this.xAxis)} transform={`translate(0,${innerHeight})`}>
|
||||
<text className='cap' y='30' dy='.1em' x={innerWidth / 2} style={{ textAnchor: 'middle' }}>
|
||||
<tspan>{xLabel}</tspan>
|
||||
<tspan className='metric'>{` (${xUnit})`}</tspan>
|
||||
<tspan className='metric'> ({xUnit})</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g className='y axis' ref={(elem) => d3.select(elem).call(this.yAxis)}>
|
||||
<text className='cap' transform='rotate(-90)' y='-50' dy='.1em' x={innerHeight / -2} style={{ textAnchor: 'middle' }}>
|
||||
<tspan>{yLabel}</tspan>
|
||||
<tspan className='metric'>{` (${yUnit})`}</tspan>
|
||||
<tspan className='metric'> ({yUnit})</tspan>
|
||||
</text>
|
||||
</g>
|
||||
<g ref={(g) => this.tipContainer = d3.select(g)} style={{ display: 'none' }}>
|
||||
|
||||
@@ -271,8 +271,8 @@ export default class PowerBands extends TranslatedComponent {
|
||||
<line x1={pctScale(0.5)} x2={pctScale(0.5)} y1='0' y2={state.innerHeight} className={pwrWarningClass} />
|
||||
<text dy='0.5em' x='-3' y={state.retY} className='primary upp' textAnchor='end' onMouseOver={this.context.termtip.bind(null, 'retracted')} onMouseLeave={this._hidetip}>{translate('ret')}</text>
|
||||
<text dy='0.5em' x='-3' y={state.depY} className='primary upp' textAnchor='end' onMouseOver={this.context.termtip.bind(null, 'deployed', { orientation: 's', cap: 1 })} onMouseLeave={this._hidetip}>{translate('dep')}</text>
|
||||
<text dy='0.5em' x={innerWidth + 5} y={state.retY} className={getClass(retSelected, retSum, available)}>{f2(Math.max(0, retSum)) + ' (' + pct1(Math.max(0, retSum / available)) + ')'}</text>
|
||||
<text dy='0.5em' x={innerWidth + 5} y={state.depY} className={getClass(depSelected, depSum, available)}>{f2(Math.max(0, depSum)) + ' (' + pct1(Math.max(0, depSum / available)) + ')'}</text>
|
||||
<text dy='0.5em' x={innerWidth + 5} y={state.retY} className={getClass(retSelected, retSum, available)}>{f2(Math.max(0, retSum))} ({pct1(Math.max(0, retSum / available))})</text>
|
||||
<text dy='0.5em' x={innerWidth + 5} y={state.depY} className={getClass(depSelected, depSum, available)}>{f2(Math.max(0, depSum))} ({pct1(Math.max(0, depSum / available))})</text>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
|
||||
@@ -33,6 +33,7 @@ export default class StandardSlot extends TranslatedComponent {
|
||||
|
||||
if (this.props.selected) {
|
||||
menu = <AvailableModulesMenu
|
||||
className='standard'
|
||||
modules={modules}
|
||||
shipMass={ship.ladenMass}
|
||||
m={m}
|
||||
@@ -47,16 +48,17 @@ export default class StandardSlot extends TranslatedComponent {
|
||||
<div className={cn('details-container', { warning: warning && warning(slot.m) })}>
|
||||
<div className={'sz'}>{slot.maxClass}</div>
|
||||
<div>
|
||||
<div className='l'>{classRating + ' ' + translate(m.grp)}</div>
|
||||
<div className={'r'}>{m.mass || m.fuel}{units.T}</div>
|
||||
<div className='l'>{classRating} {translate(m.grp == 'bh' ? m.grp : m.name || m.grp)}</div>
|
||||
<div className={'r'}>{m.mass || m.fuel || 0}{units.T}</div>
|
||||
<div className={'cb'}>
|
||||
{ m.optmass ? <div className='l'>{translate('optimal mass') + ': '}{m.optmass}{units.T}</div> : null }
|
||||
{ m.maxmass ? <div className='l'>{translate('max mass') + ': '}{m.maxmass}{units.T}</div> : null }
|
||||
{ m.grp == 'bh' && m.name ? <div className='l'>{translate(m.name)}</div> : null }
|
||||
{ m.optmass ? <div className='l'>{translate('optimal mass')}: {m.optmass}{units.T}</div> : null }
|
||||
{ m.maxmass ? <div className='l'>{translate('max mass')}: {m.maxmass}{units.T}</div> : null }
|
||||
{ m.range ? <div className='l'>{translate('range')}: {m.range}{units.km}</div> : null }
|
||||
{ m.time ? <div className='l'>{translate('time')}: {formats.time(m.time)}</div> : null }
|
||||
{ m.eff ? <div className='l'>{translate('efficiency')}: {m.eff}</div> : null }
|
||||
{ m.pGen ? <div className='l'>{translate('power')}: {m.pGen}{units.MW}</div> : null }
|
||||
{ m.maxfuel ? <div className='l'>{translate('max') + ' ' + translate('fuel') + ': '}{m.maxfuel}{units.T}</div> : null }
|
||||
{ m.maxfuel ? <div className='l'>{translate('max')} {translate('fuel')}: {m.maxfuel}{units.T}</div> : null }
|
||||
{ m.weaponcapacity ? <div className='l'>{translate('WEP')}: {m.weaponcapacity}{units.MJ} / {m.weaponrecharge}{units.MW}</div> : null }
|
||||
{ m.systemcapacity ? <div className='l'>{translate('SYS')}: {m.systemcapacity}{units.MJ} / {m.systemrecharge}{units.MW}</div> : null }
|
||||
{ m.enginecapacity ? <div className='l'>{translate('ENG')}: {m.enginecapacity}{units.MJ} / {m.enginerecharge}{units.MW}</div> : null }
|
||||
|
||||
@@ -4,6 +4,7 @@ import SlotSection from './SlotSection';
|
||||
import StandardSlot from './StandardSlot';
|
||||
import { diffDetails } from '../utils/SlotFunctions';
|
||||
import * as ModuleUtils from '../shipyard/ModuleUtils';
|
||||
import * as ShipRoles from '../shipyard/ShipRoles';
|
||||
import { stopCtxPropagation } from '../utils/UtilityFunctions';
|
||||
|
||||
/**
|
||||
@@ -18,21 +19,8 @@ export default class StandardSlotSection extends SlotSection {
|
||||
*/
|
||||
constructor(props, context) {
|
||||
super(props, context, 'standard', 'standard');
|
||||
|
||||
this._optimizeStandard = this._optimizeStandard.bind(this);
|
||||
this._optimizeCargo = this._optimizeCargo.bind(this);
|
||||
this._optimizeExplorer = this._optimizeExplorer.bind(this);
|
||||
this._hideDiff = this._hideDiff.bind(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill all standard slots with the specificed rating (using max class)
|
||||
* @param {String} rating [A-E]
|
||||
*/
|
||||
_fill(rating) {
|
||||
this.props.ship.useStandard(rating);
|
||||
this.props.onChange();
|
||||
this._close();
|
||||
this._selectBulkhead = this._selectBulkhead.bind(this);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -45,85 +33,42 @@ export default class StandardSlotSection extends SlotSection {
|
||||
}
|
||||
|
||||
/**
|
||||
* Trader build
|
||||
* Fill all standard slots with the specificed rating (using max class)
|
||||
* @param {Boolean} shielded True if shield generator should be included
|
||||
* @param {integer} bulkheadIndex Bulkhead to use see Constants.BulkheadNames
|
||||
*/
|
||||
_optimizeCargo() {
|
||||
let ship = this.props.ship;
|
||||
ship.internal.forEach((slot) => ship.use(slot, ModuleUtils.findInternal('cr', slot.maxClass, 'E')));
|
||||
ship.useLightestStandard();
|
||||
_multiPurpose(shielded, bulkheadIndex) {
|
||||
ShipRoles.multiPurpose(this.props.ship, shielded, bulkheadIndex);
|
||||
this.props.onChange();
|
||||
this._close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Explorer build
|
||||
* Trader Build
|
||||
* @param {Boolean} shielded True if shield generator should be included
|
||||
*/
|
||||
_optimizeExplorer() {
|
||||
let ship = this.props.ship,
|
||||
intLength = ship.internal.length,
|
||||
heatSinkCount = 2, // Fit 2 heat sinks if possible
|
||||
afmUnitCount = 2, // Fit 2 AFM Units if possible
|
||||
sgSlot,
|
||||
fuelScoopSlot,
|
||||
sg = ship.getAvailableModules().lightestShieldGenerator(ship.hullMass);
|
||||
_optimizeCargo(shielded) {
|
||||
ShipRoles.trader(this.props.ship, shielded);
|
||||
this.props.onChange();
|
||||
this._close();
|
||||
}
|
||||
|
||||
ship.setSlotEnabled(ship.cargoHatch, false)
|
||||
.use(ship.internal[--intLength], ModuleUtils.internal('2f')) // Advanced Discovery Scanner
|
||||
.use(ship.internal[--intLength], ModuleUtils.internal('2i')); // Detailed Surface Scanner
|
||||
|
||||
for (let i = 0; i < intLength; i++) {
|
||||
let slot = ship.internal[i];
|
||||
let nextSlot = (i + 1) < intLength ? ship.internal[i + 1] : null;
|
||||
if (!fuelScoopSlot && (!slot.eligible || slot.eligible.fs)) { // Fit best possible Fuel Scoop
|
||||
fuelScoopSlot = slot;
|
||||
ship.use(fuelScoopSlot, ModuleUtils.findInternal('fs', slot.maxClass, 'A'));
|
||||
ship.setSlotEnabled(fuelScoopSlot, true);
|
||||
|
||||
// Mount a Shield generator if possible AND an AFM Unit has been mounted already (Guarantees at least 1 AFM Unit)
|
||||
} else if (!sgSlot && afmUnitCount < 2 && sg.class <= slot.maxClass && (!slot.eligible || slot.eligible.sg) && (!nextSlot || nextSlot.maxClass < sg.class)) {
|
||||
sgSlot = slot;
|
||||
ship.use(sgSlot, sg);
|
||||
ship.setSlotEnabled(sgSlot, true);
|
||||
} else if (afmUnitCount > 0 && (!slot.eligible || slot.eligible.am)) {
|
||||
afmUnitCount--;
|
||||
let am = ModuleUtils.findInternal('am', slot.maxClass, afmUnitCount ? 'B' : 'A');
|
||||
ship.use(slot, am);
|
||||
ship.setSlotEnabled(slot, false); // Disabled power for AFM Unit
|
||||
} else {
|
||||
ship.use(slot, null);
|
||||
}
|
||||
}
|
||||
|
||||
ship.hardpoints.forEach((s) => {
|
||||
if (s.maxClass == 0 && heatSinkCount) { // Mount up to 2 heatsinks
|
||||
ship.use(s, ModuleUtils.hardpoints('02'));
|
||||
ship.setSlotEnabled(s, heatSinkCount == 2); // Only enable a single Heatsink
|
||||
heatSinkCount--;
|
||||
} else {
|
||||
ship.use(s, null);
|
||||
}
|
||||
});
|
||||
|
||||
if (sgSlot) {
|
||||
// The SG and Fuel scoop to not need to be powered at the same time
|
||||
if (sgSlot.m.power > fuelScoopSlot.m.power) { // The Shield generator uses the most power
|
||||
ship.setSlotEnabled(fuelScoopSlot, false);
|
||||
} else { // The Fuel scoop uses the most power
|
||||
ship.setSlotEnabled(sgSlot, false);
|
||||
}
|
||||
}
|
||||
|
||||
ship.useLightestStandard({ pd: '1D', ppRating: 'A' });
|
||||
/**
|
||||
* Explorer role
|
||||
* @param {Boolean} planetary True if Planetary Vehicle Hangar (PVH) should be included
|
||||
*/
|
||||
_optimizeExplorer(planetary) {
|
||||
ShipRoles.explorer(this.props.ship, planetary);
|
||||
this.props.onChange();
|
||||
this._close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the specified bulkhead
|
||||
* @param {number} bulkheadIndex 0 - 4
|
||||
* @param {Object} bulkhead Bulkhead module details
|
||||
*/
|
||||
_selectBulkhead(bulkheadIndex) {
|
||||
this.props.ship.useBulkhead(bulkheadIndex);
|
||||
_selectBulkhead(bulkhead) {
|
||||
this.props.ship.useBulkhead(bulkhead.index);
|
||||
this.context.tooltip();
|
||||
this.props.onChange();
|
||||
this._close();
|
||||
@@ -136,32 +81,12 @@ export default class StandardSlotSection extends SlotSection {
|
||||
this._optimizeStandard();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the bulkhead diff tooltip
|
||||
* @param {number} bhIndex Potential Bulkhead alternative
|
||||
* @param {SyntheticEvent} event Event
|
||||
*/
|
||||
_bhDiff(bhIndex, event) {
|
||||
let ship = this.props.ship;
|
||||
this.context.tooltip(
|
||||
diffDetails.call(ship, this.context.language, ModuleUtils.bulkheads(ship.id, bhIndex), ship.bulkheads.m),
|
||||
event.currentTarget.getBoundingClientRect()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide the diff tooltip
|
||||
*/
|
||||
_hideDiff() {
|
||||
this.context.tooltip();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the slot React Components
|
||||
* @return {Array} Array of Slots
|
||||
*/
|
||||
_getSlots() {
|
||||
let { translate, units } = this.context.language;
|
||||
let { translate, units, formats } = this.context.language;
|
||||
let { ship, currentMenu } = this.props;
|
||||
let slots = new Array(8);
|
||||
let open = this._openMenu;
|
||||
@@ -171,41 +96,15 @@ export default class StandardSlotSection extends SlotSection {
|
||||
let avail = ship.getAvailableModules().standard;
|
||||
let bh = ship.bulkheads;
|
||||
|
||||
slots[0] = (
|
||||
<div key='bh' className={cn('slot', { selected: currentMenu === bh })} onClick={open.bind(this, bh)}>
|
||||
<div className={'details-container'}>
|
||||
<div className={'details'}>
|
||||
<div className={'sz'}>8</div>
|
||||
<div>
|
||||
<div className={'l'}>{translate('bh')}</div>
|
||||
<div className={'r'}>{bh.m.mass}{units.T}</div>
|
||||
<div className={'cl l'}>{translate(bh.m.name)}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{currentMenu === bh &&
|
||||
<div className='select' onClick={ e => e.stopPropagation() }>
|
||||
<ul>
|
||||
<li onClick={selBulkhead.bind(this, 0)} onMouseOver={this._bhDiff.bind(this, 0)} onMouseLeave={this._hideDiff} className={cn('lc', { active: bh.index == 0 })}>
|
||||
{translate('Lightweight Alloy')}
|
||||
</li>
|
||||
<li onClick={selBulkhead.bind(this, 1)} onMouseOver={this._bhDiff.bind(this, 1)} onMouseLeave={this._hideDiff} className={cn('lc', { active: bh.index == 1 })}>
|
||||
{translate('Reinforced Alloy')}
|
||||
</li>
|
||||
<li onClick={selBulkhead.bind(this, 2)} onMouseOver={this._bhDiff.bind(this, 2)} onMouseLeave={this._hideDiff} className={cn('lc', { active: bh.index == 2 })}>
|
||||
{translate('Military Grade Composite')}
|
||||
</li>
|
||||
<li onClick={selBulkhead.bind(this, 3)} onMouseOver={this._bhDiff.bind(this, 3)} onMouseLeave={this._hideDiff} className={cn('lc', { active: bh.index == 3 })}>
|
||||
{translate('Mirrored Surface Composite')}
|
||||
</li>
|
||||
<li onClick={selBulkhead.bind(this, 4)} onMouseOver={this._bhDiff.bind(this, 4)} onMouseLeave={this._hideDiff} className={cn('lc', { active: bh.index == 4 })}>
|
||||
{translate('Reactive Surface Composite')}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
);
|
||||
slots[0] = <StandardSlot
|
||||
key='bh'
|
||||
slot={bh}
|
||||
modules={ship.getAvailableModules().bulkheads}
|
||||
onOpen={open.bind(this, bh)}
|
||||
onSelect={this._selectBulkhead}
|
||||
selected={currentMenu == bh}
|
||||
ship={ship}
|
||||
/>;
|
||||
|
||||
slots[1] = <StandardSlot
|
||||
key='pp'
|
||||
@@ -226,7 +125,7 @@ export default class StandardSlotSection extends SlotSection {
|
||||
onSelect={select.bind(this, st[1])}
|
||||
selected={currentMenu == st[1]}
|
||||
ship={ship}
|
||||
warning={m => m.maxmass < ship.ladenMass}
|
||||
warning={m => m.maxmass < (ship.ladenMass - st[1].mass + m.mass)}
|
||||
/>;
|
||||
|
||||
|
||||
@@ -292,21 +191,19 @@ export default class StandardSlotSection extends SlotSection {
|
||||
* @return {React.Component} Section menu
|
||||
*/
|
||||
_getSectionMenu(translate) {
|
||||
let _fill = this._fill;
|
||||
|
||||
let planetaryDisabled = this.props.ship.internal.length < 4;
|
||||
return <div className='select' onClick={(e) => e.stopPropagation()} onContextMenu={stopCtxPropagation}>
|
||||
<ul>
|
||||
<li className='lc' onClick={this._optimizeStandard}>{translate('optimize')}</li>
|
||||
<li className='c' onClick={_fill.bind(this, 'E')}>E</li>
|
||||
<li className='c' onClick={_fill.bind(this, 'D')}>D</li>
|
||||
<li className='c' onClick={_fill.bind(this, 'C')}>C</li>
|
||||
<li className='c' onClick={_fill.bind(this, 'B')}>B</li>
|
||||
<li className='c' onClick={_fill.bind(this, 'A')}>A</li>
|
||||
<li className='lc' onClick={this._optimizeStandard}>{translate('Maximize Jump Range')}</li>
|
||||
</ul>
|
||||
<div className='select-group cap'>{translate('roles')}</div>
|
||||
<ul>
|
||||
<li className='lc' onClick={this._optimizeCargo}>{translate('Trader')}</li>
|
||||
<li className='lc' onClick={this._optimizeExplorer}>{translate('Explorer')}</li>
|
||||
<li className='lc' onClick={this._multiPurpose.bind(this, false, 0)}>{translate('Multi-purpose')}</li>
|
||||
<li className='lc' onClick={this._multiPurpose.bind(this, true, 2)}>{translate('Combat')}</li>
|
||||
<li className='lc' onClick={this._optimizeCargo.bind(this, false)}>{translate('Trader')}</li>
|
||||
<li className='lc' onClick={this._optimizeCargo.bind(this, true)}>{translate('Shielded Trader')}</li>
|
||||
<li className='lc' onClick={this._optimizeExplorer.bind(this, false)}>{translate('Explorer')}</li>
|
||||
<li className={cn('lc', { disabled: planetaryDisabled })} onClick={!planetaryDisabled && this._optimizeExplorer.bind(this, true)}>{translate('Planetary Explorer')}</li>
|
||||
</ul>
|
||||
</div>;
|
||||
}
|
||||
|
||||
@@ -94,6 +94,7 @@ export default class UtilitySlotSection extends SlotSection {
|
||||
return <div className='select' onClick={(e) => e.stopPropagation()} onContextMenu={stopCtxPropagation}>
|
||||
<ul>
|
||||
<li className='lc' onClick={this._empty}>{translate('empty all')}</li>
|
||||
<li className='optional-hide' style={{ textAlign: 'center', marginTop: '1em' }}>{translate('PHRASE_ALT_ALL')}</li>
|
||||
</ul>
|
||||
<div className='select-group cap'>{translate('sb')}</div>
|
||||
<ul>
|
||||
|
||||
@@ -52,18 +52,18 @@ export function getLanguage(langCode) {
|
||||
},
|
||||
translate,
|
||||
units: {
|
||||
CR: <u>{' ' + translate('CR')}</u>, // Credits
|
||||
kg: <u>{' ' + translate('kg')}</u>, // Kilograms
|
||||
kgs: <u>{' ' + translate('kg/s')}</u>, // Kilograms per second
|
||||
km: <u>{' ' + translate('km')}</u>, // Kilometers
|
||||
Ls: <u>{' ' + translate('Ls')}</u>, // Light Seconds
|
||||
LY: <u>{' ' + translate('LY')}</u>, // Light Years
|
||||
MJ: <u>{' ' + translate('MJ')}</u>, // Mega Joules
|
||||
'm/s': <u>{' ' + translate('m/s')}</u>, // Meters per second
|
||||
MW: <u>{' ' + translate('MW')}</u>, // Mega Watts (same as Mega Joules per second)
|
||||
CR: <u> {translate('CR')}</u>, // Credits
|
||||
kg: <u> {translate('kg')}</u>, // Kilograms
|
||||
kgs: <u> {translate('kg/s')}</u>, // Kilograms per second
|
||||
km: <u> {translate('km')}</u>, // Kilometers
|
||||
Ls: <u> {translate('Ls')}</u>, // Light Seconds
|
||||
LY: <u> {translate('LY')}</u>, // Light Years
|
||||
MJ: <u> {translate('MJ')}</u>, // Mega Joules
|
||||
'm/s': <u> {translate('m/s')}</u>, // Meters per second
|
||||
MW: <u> {translate('MW')}</u>, // Mega Watts (same as Mega Joules per second)
|
||||
ps: <u>{translate('/s')}</u>, // per second
|
||||
pm: <u>{translate('/min')}</u>, // per minute
|
||||
T: <u>{' ' + translate('T')}</u>, // Metric Tons
|
||||
T: <u> {translate('T')}</u>, // Metric Tons
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -15,76 +15,20 @@ export const formats = {
|
||||
|
||||
export const terms = {
|
||||
// Phrases
|
||||
PHRASE_BACKUP_DESC: 'Export aller Coriolis-Daten, um sie zu sichern oder oder um sie zu einem anderen Browser/Gerät zu übertragen.', // Backup of all Coriolis data to save or transfer to another browser/device
|
||||
PHRASE_BACKUP_DESC: 'Export aller Coriolis-Daten, um sie zu sichern oder um sie zu einem anderen Browser/Gerät zu übertragen.', // Backup of all Coriolis data to save or transfer to another browser/device
|
||||
PHRASE_CONFIRMATION: 'Sind Sie sicher?', // Are You Sure?
|
||||
PHRASE_EXPORT_DESC: 'Ein detaillierter JSON-Export Ihrer Konfiguration für die Verwendung in anderen Websites und Tools', // A detailed JSON export of your build for use in other sites and tools
|
||||
PHRASE_FASTEST_RANGE: null, // Consecutive max range jumps
|
||||
PHRASE_FASTEST_RANGE: 'aufeinanderfolgende maximale Reichweite/Sprünge', // Consecutive max range jumps
|
||||
PHRASE_IMPORT: 'JSON hier einfügen oder importieren', // Paste JSON or import here
|
||||
PHRASE_LADEN: null, // Ship Mass + Fuel + Cargo
|
||||
PHRASE_LADEN: 'Schiffsmasse + Treibstoff + Fracht', // Ship Mass + Fuel + Cargo
|
||||
PHRASE_NO_BUILDS: 'Keine Konfigurationen zum Vergleich ausgewählt!', // No builds added to comparison!
|
||||
PHRASE_NO_RETROCH: 'Keine Umrüständerungen', // No Retrofitting changes
|
||||
PHRASE_SELECT_BUILDS: 'Ausstattung zum Vergleich auswählen', // Select Builds to Compare
|
||||
PHRASE_SG_RECHARGE: null, // Time from 50% to 100% Charge
|
||||
PHRASE_SG_RECOVER: null, // Recovery (to 50%) after collapse
|
||||
PHRASE_UNLADEN: null, // Ship Mass excluding Fuel and Cargo
|
||||
PHRASE_SG_RECHARGE: 'Zeit von 50% bis 100% der Ladung', // Time from 50% to 100% Charge
|
||||
PHRASE_SG_RECOVER: 'Erneuerung (zu 50%) nach Zusammenbruch', // Recovery (to 50%) after collapse
|
||||
PHRASE_UNLADEN: 'Schiffsmasse ohne Treibstoff und Fracht', // Ship Mass excluding Fuel and Cargo
|
||||
PHRASE_UPDATE_RDY: 'Update verfügbar! Klicken zum Aktualisieren', // Update Available! Click to Refresh
|
||||
|
||||
// Modules / Module Types - These should match the in-game translation (if any)
|
||||
'Basic Discovery Scanner': 'einfacher Aufklärungsscanner', // Basic Discovery Scanner
|
||||
'Cargo Hatch': 'Frachtluke', // Cargo Hatch
|
||||
'Chaff Launcher': 'Düppel-Werfer', // Chaff Launcher
|
||||
'Detailed Surface Scanner': 'Detailoberflächenscanner', // Detailed Surface Scanner
|
||||
'Electronic Countermeasure': 'elektronische Gegenmaßnahme', // Electronic Countermeasure
|
||||
'Heat Sink Launcher': 'Kühlkörperwerfer', // Heat Sink Launcher
|
||||
'Intermediate Discovery Scanner': 'mittlerer Aufklärungsscanner', // Intermediate Discovery Scanner
|
||||
'Point Defence': 'Punktverteidigung',
|
||||
'Standard Docking Computer': 'Standard-Landecomputer', // Standard Docking Computer
|
||||
am: 'automatische Feldwartungs-Einheit', // Auto Field-Maintenance Unit
|
||||
bh: 'Rumpfhüllenverstärkung', // Bulkheads
|
||||
bl: 'Strahlenlaser', // Beam Laser
|
||||
c: 'Kanone', // Cannon
|
||||
cc: 'Krallensteuerung: Sammler', // Collector Limpet Controller
|
||||
cm: 'Gegenmaßnahme', // Countermeasure
|
||||
cr: 'Frachtgestell', // Cargo Rack
|
||||
cs: 'Frachtscanner', // Cargo Scanner
|
||||
dc: 'Standard-Landecomputer', // Docking Computer
|
||||
fc: 'Splitterkanone', // Fragment Cannon
|
||||
fi: 'FSA-Unterbrecher', // FSD Interdictor
|
||||
fs: 'Treibstoffsammler', // Fuel Scoop
|
||||
fsd: 'Frameshiftantrieb', // Frame Shift Drive
|
||||
ft: 'Treibstofftank', // Fuel Tank
|
||||
fx: 'Krallensteuerung Treibstoffstransfer', // Fuel Transfer Limpet Controller
|
||||
hb: 'Krallen-Steuereinheit (Ladelukenöffner)', // Hatch Breaker Limpet Controller
|
||||
hr: 'Rumpfhüllenverstärkung (Paket)', // Hull Reinforcement Package
|
||||
kw: 'Tötungsbefehl-Scanner', // Kill Warrant Scanner
|
||||
ls: 'Lebenserhaltung', // life support
|
||||
mc: 'Mehrfachgeschütz', // Multi-cannon
|
||||
ml: 'Abbaulaser', // Mining Laser
|
||||
mr: 'Raketenbatterie', // Missile Rack
|
||||
nl: 'Minenwerfer', // Mine Launcher
|
||||
pa: 'Plasmabeschleuniger', // Plasma Accelerator
|
||||
pc: 'Krallensteuerung: Erzsucher', // Prospector Limpet Controller
|
||||
pd: 'Energieverteiler', // power distributor
|
||||
pl: 'Impulslaser', // Pulse Laser
|
||||
pp: 'Kraftwerk', // Power Plant
|
||||
psg: 'Prismaschildgenerator', // Prismatic Shield Generator
|
||||
rf: 'Raffinerie', // Refinery
|
||||
rg: 'Schienenkanone', // Rail Gun
|
||||
s: 'Sensoren', // Sensors
|
||||
sb: 'Schild-Booster', // Shield Booster
|
||||
sc: 'Scanner', // Scanner
|
||||
scb: 'Schildzellenbank', // Shield Cell Bank
|
||||
sg: 'Schildgenerator', // Shield Generator
|
||||
t: 'Schubdüsen', // Thrusters
|
||||
tp: 'Torpedoaufhängung', // Torpedo Pylon
|
||||
ul: 'Salvenlaser', // Burst Laser
|
||||
ws: 'Frameshift-Sogwolkenscanner', // Frame Shift Wake Scanner
|
||||
// Bulkheads - These should match the in-game translation (if any)
|
||||
'Lightweight Alloy': 'leichte Legierung',
|
||||
'Reinforced Alloy': 'verstärkte Legierung',
|
||||
'Military Grade Composite': 'Militär-Komposit',
|
||||
'Mirrored Surface Composite': 'Gespiegelte-Oberfläche-Komposit',
|
||||
'Reactive Surface Composite': 'Reaktive-Oberfläche-Komposit',
|
||||
// Units / Metrics
|
||||
LY: 'Lj', // Light Years
|
||||
T: 't', // Tons (Metric Ton - 1000kg)
|
||||
@@ -94,109 +38,108 @@ export const terms = {
|
||||
L: 'G', // Large Hardpoint size (single character)
|
||||
H: 'R', // Huge Hardpoint size (single character)
|
||||
U: 'W', // Utility Hardpoint size (single character) - Kill warrant scanner, etc
|
||||
small: 'klein', // Small ship size
|
||||
medium: 'mittel', // Medium ship size
|
||||
large: 'groß', // Large Ship Size
|
||||
|
||||
// Terms
|
||||
'build name': 'Ausstattungsname', // Ship build/configuration/design name
|
||||
'compare all': 'Alles vergleichen',
|
||||
'create new': 'Neu erstellen',
|
||||
'damage per second': null,
|
||||
'delete all': 'Alles Löschen',
|
||||
'detailed export': 'detailierter Export',
|
||||
'edit data': 'bearbeiten',
|
||||
'empty all': 'leer alles',
|
||||
'Enter Name': 'Namen eingeben',
|
||||
'fastest range': null, // Fastet totaljump range - sum of succesive jumps
|
||||
'fuel level': null, // Percent of fuel (T) in the tank
|
||||
'full tank': 'Tank voll',
|
||||
'internal compartments': 'Innenbereich',
|
||||
'jump range': 'Sprungreichweite',
|
||||
'mass lock factor': 'Massensperrefaktor',
|
||||
'max mass': 'maximale Masse',
|
||||
'net cost': 'Nettokosten',
|
||||
'none created': 'Leer',
|
||||
'optimal mass': null, // Lowest weight / best weight for jump distance, etc
|
||||
'refuel time': 'Auftankzeit', // Time to refuel the tank when scooping
|
||||
'reload costs': null,
|
||||
'retrofit costs': 'Änderungskosten', // The cost difference when upgrading / downgrading a component
|
||||
'retrofit from': 'Nachrüsten von', // Retrofit from Build A against build B
|
||||
'T-Load': 'T-Lad', // Thermal load abbreviation
|
||||
'total range': null,
|
||||
'unit cost': null,
|
||||
'utility mounts': 'Werkzeug-Steckplätze',
|
||||
about: 'Über', // Link to about page / about Coriolis.io
|
||||
about: 'über', // Link to about page / about Coriolis.io
|
||||
action: 'Aktion',
|
||||
added: 'hinzugefügt',
|
||||
ammo: 'Munition', // Ammunition
|
||||
armour: 'Panzerung',
|
||||
available: 'verfügbar',
|
||||
available: 'verfügbar', // Available options
|
||||
backup: 'Sicherungsdatei',
|
||||
base: null,
|
||||
bays: null,
|
||||
base: 'Basis', // Base speed, boost, etc - Base ship stats
|
||||
bays: 'Lagerraum',
|
||||
bins: 'Behälter', // Number of Mining Refinery bins
|
||||
build: 'Ausstattung', // Shorthand for the build/configuration/design name
|
||||
'build name': 'Ausstattungsname', // Ship build/configuration/design name
|
||||
builds: 'Ausstattungen', // Ship build/configuration/design names
|
||||
buy: 'kaufen',
|
||||
cancel: 'Abbrechen',
|
||||
cancel: 'abbrechen',
|
||||
cargo: 'Fracht',
|
||||
cells: 'Zellen', // Number of cells in a shield cell bank
|
||||
close: 'Schließen',
|
||||
close: 'schließen',
|
||||
compare: 'vergleichen',
|
||||
'compare all': 'alles vergleichen',
|
||||
comparison: 'Vergleich',
|
||||
comparisons: 'Vergleiche',
|
||||
cost: 'Preis', // Cost / price of a module or price of a ship
|
||||
costs: 'Kosten', // Costs / prices of a modules or prices of ships
|
||||
create: 'erstellen',
|
||||
'create new': 'neu erstellen',
|
||||
credits: 'Credits',
|
||||
damage: 'Schaden',
|
||||
delete: 'Löschen',
|
||||
dep: 'Ausg', // Weapons/Hardpoints Deployed abbreviation
|
||||
deployed: 'Ausgefahren', // Weapons/Hardpoints Deployed
|
||||
disabled: 'Deaktiviert',
|
||||
'damage per second': 'Schaden pro Sekunde',
|
||||
delete: 'löschen',
|
||||
'delete all': 'alles löschen',
|
||||
dep: 'ausg', // Weapons/Hardpoints Deployed abbreviation
|
||||
deployed: 'ausgefahren', // Weapons/Hardpoints Deployed
|
||||
'detailed export': 'detailierter Export',
|
||||
disabled: 'deaktiviert',
|
||||
discount: 'Rabatt',
|
||||
'edit data': 'bearbeiten',
|
||||
efficiency: 'Effizienz', // Power Plant efficiency
|
||||
empty: 'leer',
|
||||
'empty all': 'alles entfernen',
|
||||
ENG: 'ANT', // Abbreviation - Engine recharge rate for power distributor
|
||||
'Enter Name': 'Namen eingeben',
|
||||
Explorer: 'Forscher',
|
||||
export: 'Export',
|
||||
'fastest range': 'maximale Reichweite', // Fastet totaljump range - sum of succesive jumps
|
||||
forum: 'Forum',
|
||||
fuel: 'Treibstoff',
|
||||
'fuel level': 'Tankfüllstand', // Percent of fuel (T) in the tank
|
||||
'full tank': 'Tank voll',
|
||||
hardpoints: 'Waffenaufhängungen',
|
||||
hull: 'Hülle', // Ships hull
|
||||
hull: 'Rumpf', // Ships hull
|
||||
import: 'importieren',
|
||||
insurance: 'Versicherung',
|
||||
jump: null, // Single jump range
|
||||
'internal compartments': 'Innenbereich',
|
||||
jump: 'Sprung', // Single jump range
|
||||
'jump range': 'Sprungreichweite',
|
||||
jumps: 'Sprünge',
|
||||
laden: 'beladen',
|
||||
language: 'Sprache',
|
||||
maneuverability: 'Manövrierbarkeit',
|
||||
manufacturer: null,
|
||||
manufacturer: 'Hersteller',
|
||||
mass: 'Masse',
|
||||
MLF: null, // Mass Lock Factor Abbreviation
|
||||
MNV: null, // Maneuverability abbreviation
|
||||
module: 'modul',
|
||||
modules: 'module',
|
||||
'mass lock factor': 'Massensperrefaktor',
|
||||
'max mass': 'maximale Masse',
|
||||
MLF: 'MSF', // Mass Lock Factor Abbreviation
|
||||
module: 'Modul',
|
||||
modules: 'Module',
|
||||
'net cost': 'Nettokosten',
|
||||
no: 'Nein',
|
||||
'none created': 'nicht erstellt',
|
||||
ok: 'OK',
|
||||
optimize: null,
|
||||
'optimal mass': 'optimale Masse', // Lowest weight / best weight for jump distance, etc
|
||||
optimize: 'optimieren',
|
||||
pen: 'Durchdr.', // Armour peneration abbreviation
|
||||
permalink: 'Permanentlink',
|
||||
power: 'Energie', // Power = Energy / second. Power generated by the power plant, or power consumed (MW / Mega Watts). Used in the power plant section
|
||||
pri: 'Prio', // Priority abbreviation for power management
|
||||
proceed: 'Fortfahren',
|
||||
PWR: 'En', // Power Abbreviation. See Power
|
||||
qty: null, // Quantity abbreviation
|
||||
proceed: 'fortfahren',
|
||||
qty: 'Menge', // Quantity abbreviation
|
||||
range: 'Reichweite',
|
||||
rate: 'Rate',
|
||||
recharge: null, // Shield Recharge time from 50% -> 100%
|
||||
recovery: null, // Shield recovery time (after losing shields/turning on -> 50%)
|
||||
recharge: 'aufladen', // Shield Recharge time from 50% -> 100%
|
||||
recovery: 'Erneuerung', // Shield recovery time (after losing shields/turning on -> 50%)
|
||||
'refuel time': 'Auftankzeit', // Time to refuel the tank when scooping
|
||||
reload: 'aktualisieren', // Reload weapon/hardpoint
|
||||
'reload costs': 'Nachladekosten',
|
||||
rename: 'umbenennen',
|
||||
repair: 'reparieren',
|
||||
reset: 'zurücksetzen',
|
||||
ret: 'Eing', // Retracted abbreviation
|
||||
retracted: 'Eingefahren', // Weapons/Hardpoints retracted
|
||||
ret: 'eing', // Retracted abbreviation
|
||||
retracted: 'eingefahren', // Weapons/Hardpoints retracted
|
||||
'retrofit costs': 'Änderungskosten', // The cost difference when upgrading / downgrading a component
|
||||
'retrofit from': 'nachrüsten von', // Retrofit from Build A against build B
|
||||
ROF: 'Kad', // Rate of Fire abbreviation
|
||||
roles: null, // Commander/Ship build roles - e.g. Trader, Bounty-Hunter, Explorer, etc
|
||||
save: 'Speichern',
|
||||
sell: 'Verkaufen',
|
||||
roles: 'Rollen', // Commander/Ship build roles - e.g. Trader, Bounty-Hunter, Explorer, etc
|
||||
save: 'speichern',
|
||||
sell: 'verkaufen',
|
||||
settings: 'Einstellungen', // Coriolis application settings
|
||||
shields: 'Schilde',
|
||||
ship: 'Schiff',
|
||||
@@ -205,16 +148,19 @@ export const terms = {
|
||||
size: 'Größe',
|
||||
skip: 'überspringen', // Skip past something / ignore it
|
||||
speed: 'Geschwindigkeit',
|
||||
standard: 'Standard', // Standard / Common modules (FSD, power plant, life support, etc)
|
||||
standard: 'Grundausstattung', // Standard / Common modules (FSD, power plant, life support, etc)
|
||||
Stock: 'Standard', // Thermal-load abbreviation
|
||||
strength: null, // Strength in reference to Shield Strength
|
||||
subtotal: null,
|
||||
strength: 'Stärke', // Strength in reference to Shield Strength
|
||||
subtotal: 'Zwischensumme',
|
||||
time: 'Dauer', // time it takes to complete something
|
||||
tooltips: null, // Tooltips setting - show/hide
|
||||
total: 'Gesamt',
|
||||
Trader: null, // Trader role
|
||||
tooltips: 'Tooltips', // Tooltips setting - show/hide
|
||||
total: 'gesamt',
|
||||
'total range': 'Gesamtbereich',
|
||||
Trader: 'Händler', // Trader role
|
||||
type: 'Typ',
|
||||
unladen: 'Unbeladen', // No cargo or fuel
|
||||
'unit cost': 'Kosten pro Einheit',
|
||||
unladen: 'unbeladen', // No cargo or fuel
|
||||
'utility mounts': 'Werkzeug-Steckplätze',
|
||||
WEP: 'WAF', // Abbreviation - Weapon recharge rate for power distributor
|
||||
yes: 'Ja'
|
||||
yes: 'ja'
|
||||
};
|
||||
|
||||
@@ -14,20 +14,22 @@ export const formats = {
|
||||
};
|
||||
|
||||
export const terms = {
|
||||
PHRASE_ALT_ALL: 'Alt + Click to fill all slots',
|
||||
PHRASE_BACKUP_DESC: 'Backup of all Coriolis data to save or transfer to another browser/device',
|
||||
PHRASE_CONFIRMATION: 'Are You Sure?',
|
||||
PHRASE_CONFIRMATION: 'Are you sure?',
|
||||
PHRASE_EXPORT_DESC: 'A detailed JSON export of your build for use in other sites and tools',
|
||||
PHRASE_FASTEST_RANGE: 'Consecutive max range jumps',
|
||||
PHRASE_IMPORT: 'Paste JSON or import here',
|
||||
PHRASE_LADEN: 'Ship Mass + Fuel + Cargo',
|
||||
PHRASE_LADEN: 'Ship mass + fuel + cargo',
|
||||
PHRASE_NO_BUILDS: 'No builds added to comparison!',
|
||||
PHRASE_NO_RETROCH: 'No Retrofitting changes',
|
||||
PHRASE_SELECT_BUILDS: 'Select Builds to Compare',
|
||||
PHRASE_SG_RECHARGE: 'Time from 50% to 100% Charge',
|
||||
PHRASE_SELECT_BUILDS: 'Select builds to compare',
|
||||
PHRASE_SG_RECHARGE: 'Time from 50% to 100% charge',
|
||||
PHRASE_SG_RECOVER: 'Recovery (to 50%) after collapse',
|
||||
PHRASE_UNLADEN: 'Ship Mass excluding Fuel and Cargo',
|
||||
PHRASE_UPDATE_RDY: 'Update Available! Click to Refresh',
|
||||
PHRASE_UNLADEN: 'Ship mass excluding fuel and cargo',
|
||||
PHRASE_UPDATE_RDY: 'Update Available! Click to refresh',
|
||||
|
||||
// Other languages fallback to these values
|
||||
// Only Translate to other languages if the name is different in-game
|
||||
am: 'Auto Field-Maintenance Unit',
|
||||
bh: 'Bulkheads',
|
||||
@@ -60,7 +62,7 @@ export const terms = {
|
||||
pl: 'Pulse Laser',
|
||||
pp: 'Power Plant',
|
||||
psg: 'Prismatic Shield Generator',
|
||||
pv: 'Planetary Vehicle Hanger',
|
||||
pv: 'Planetary Vehicle Hangar',
|
||||
rf: 'Refinery',
|
||||
rg: 'Rail Gun',
|
||||
s: 'Sensors',
|
||||
|
||||
@@ -15,119 +15,42 @@ export const formats = {
|
||||
|
||||
export const terms = {
|
||||
// Phrases
|
||||
PHRASE_BACKUP_DESC: 'Exportation détaillée des données Coriolis pour l\'utilisation dans d\'autres sites et outils', // Backup of all Coriolis data to save or transfer to another browser/device
|
||||
PHRASE_BACKUP_DESC: 'Copie des données Coriolis pour l\'utilisation dans d\'autres sites et outils', // Backup of all Coriolis data to save or transfer to another browser/device
|
||||
PHRASE_CONFIRMATION: 'Êtes-vous sûr?', // Are You Sure?
|
||||
PHRASE_EXPORT_DESC: 'Un export détaillé en JSON de votre configuration pour l\'utilisation dans d\'autres sites et outils', // A detailed JSON export of your build for use in other sites and tools
|
||||
PHRASE_FASTEST_RANGE: 'Portée maximale en cas de sauts successifs', // Consecutive max range jumps
|
||||
PHRASE_IMPORT: 'Coller JSON ou importer ici', // Paste JSON or import here
|
||||
PHRASE_NO_BUILDS: 'Défaut de configuration pour comparaison', // No builds added to comparison!
|
||||
PHRASE_NO_RETROCH: 'configuration non modifiée', // No Retrofitting changes
|
||||
PHRASE_SELECT_BUILDS: 'Sélectionner configurations à comparer', // Select Builds to Compare
|
||||
PHRASE_LADEN: 'Masse du Vaisseau + Carburant + Cargo', // Ship Mass + Fuel + Cargo
|
||||
PHRASE_NO_BUILDS: 'Aucune configuration ajoutée pour la comparaison', // No builds added to comparison!
|
||||
PHRASE_NO_RETROCH: 'Aucun changement de configuration', // No Retrofitting changes
|
||||
PHRASE_SELECT_BUILDS: 'Sélectionner les configurations à comparer', // Select Builds to Compare
|
||||
PHRASE_SG_RECHARGE: 'Temps de charge de 50% à 100 %', // Time from 50% to 100% Charge
|
||||
PHRASE_SG_RECOVER: 'Temps de redémarrage après perte du bouclier', // Recovery (to 50%) after collapse
|
||||
PHRASE_UNLADEN: 'Masse du Vaisseau hors Carburant et Cargo', // Ship Mass excluding Fuel and Cargo
|
||||
PHRASE_UPDATE_RDY: 'Mise à jour disponible ! Cliquez pour rafraichir', // Update Available! Click to Refresh
|
||||
|
||||
// Modules / Module Types - These should match the in-game translation (if any)
|
||||
am: 'Unité de maintenance de terrain auto', // Auto Field-Maintenance Unit
|
||||
'Basic Discovery Scanner': 'Détecteur de découverte simple', // Basic Discovery Scanner
|
||||
bh: 'Coque', // Bulkheads
|
||||
bl: 'Rayon Laser', // Beam Laser
|
||||
'Cargo Hatch': 'Ecoutille de soute', // Cargo Hatch
|
||||
c: 'Canon', // Cannon
|
||||
cc: 'Contrôleur de collecteurs', // Collector Limpet Controller
|
||||
cm: 'Contre-mesure', // Countermeasure
|
||||
'Chaff Launcher': 'Lanceur de paillettes', // Chaff Launcher
|
||||
cr: 'Compartiment de soute', // Cargo Rack
|
||||
cs: 'Scanner de soute', // Cargo Scanner
|
||||
dc: 'Ordinateur d\'appontage', // Docking Computer
|
||||
'Detailed Surface Scanner': 'Détecteur de surface détaillé', // Detailed Surface Scanner
|
||||
'Electronic Countermeasure': 'Contre mesure électronique', // Electronic Countermeasure
|
||||
fc: 'Canon à fragmentation', // Fragment Cannon
|
||||
fi: 'Intercepteur de réacteur FSD', // FSD Interdictor
|
||||
fs: 'Récupérateur de carburant', // Fuel Scoop
|
||||
fsd: 'Réacteur FSD', // Frame Shift Drive
|
||||
ft: 'Réservoir de carburant', // Fuel Tank
|
||||
fx: 'Drone de ravitaillement', // Fuel Transfer Limpet Controller
|
||||
'Heat Sink Launcher': 'Ejecteur de dissipateur thermique', // Heat Sink Launcher
|
||||
hb: 'Contrôle de patelle perce-soute', // Hatch Breaker Limpet Controller
|
||||
hr: 'Renfort de soute', // Hull Reinforcement Package
|
||||
'Intermediate Discovery Scanner': 'Détecteur de découverte intermédiaire', // Intermediate Discovery Scanner
|
||||
kw: 'Détecteur d\'avis de recherche', // Kill Warrant Scanner
|
||||
ls: 'Support vital', // life support
|
||||
mc: 'Canon multiple', // Multi-cannon
|
||||
ml: 'Laser minier', // Mining Laser
|
||||
mr: 'Lance missiles', // Missile Rack
|
||||
nl: 'Lance-mines', // Mine Launcher
|
||||
pa: 'accélérateur plasma', // Plasma Accelerator
|
||||
pc: 'Drône de minage', // Prospector Limpet Controller
|
||||
pd: 'distributeur d\'énérgie', // power distributor
|
||||
pl: 'Laser à impulsion', // Pulse Laser
|
||||
'Point Defence': 'Défense ponctuelle',
|
||||
pp: 'centrale d\'énergie', // Power Plant
|
||||
psg: 'générateur de bouclier prisme', // Prismatic Shield Generator
|
||||
rf: 'Raffinerie', // Refinery
|
||||
rg: 'Canon électromagnétique', // Rail Gun
|
||||
s: 'détecteurs', // Sensors
|
||||
sb: 'Survolteur de bouclier', // Shield Booster
|
||||
sc: 'scanner', // Scanner
|
||||
scb: 'Réserve de cellules d\'énergie', // Shield Cell Bank
|
||||
sg: 'Générateur de bouclier', // Shield Generator
|
||||
'Standard Docking Computer': 'ordinateur d\'appontage standard', // Standard Docking Computer
|
||||
t: 'propulseurs', // Thrusters
|
||||
tp: 'Tube lance-torpille', // Torpedo Pylon
|
||||
ul: 'Laser à rafale', // Burst Laser
|
||||
ws: 'Détecteur de sillage FSD', // Frame Shift Wake Scanner
|
||||
|
||||
// Bulkheads - These should match the in-game translation (if any)
|
||||
'Lightweight Alloy': 'alliage léger',
|
||||
'Reinforced Alloy': 'alliage renforcé',
|
||||
'Military Grade Composite': 'Composite militaire',
|
||||
'Mirrored Surface Composite': 'Composite à surface mirroir',
|
||||
'Reactive Surface Composite': 'Composite à surface réactive',
|
||||
|
||||
// Units / Metrics
|
||||
Ls: 'SL', // Light seconds
|
||||
LY: 'AL', // Light Years
|
||||
|
||||
// Sizes
|
||||
S: 'P', // Small Hardpoint (single Character)
|
||||
L: 'G', // Large Hardpoint size (single character)
|
||||
large: 'grand', // Large Ship Size
|
||||
medium: 'moyen', // Medium ship size
|
||||
S: 'P', // Small Hardpoint (single Character)
|
||||
small: 'petit', // Small ship size
|
||||
|
||||
// Terms
|
||||
'build name': 'Nom de la configuration', // Ship build/configuration/design name
|
||||
'compare all': 'tout comparer',
|
||||
'create new': 'Créer nouveau',
|
||||
'damage per second': null,
|
||||
'delete all': 'tout supprimer',
|
||||
'detailed export': 'export détaillé',
|
||||
'edit data': 'Editer donnée',
|
||||
'empty all': null,
|
||||
'Enter Name': 'Entrer nom',
|
||||
'fastest range': null, // Fastet totaljump range - sum of succesive jumps
|
||||
'fuel level': null, // Percent of fuel (T) in the tank
|
||||
'full tank': 'Réservoir plein',
|
||||
'internal compartments': 'compartiments internes',
|
||||
'jump range': 'Distance de saut',
|
||||
'mass lock factor': 'facteur inhibition de masse',
|
||||
'max mass': 'masse max',
|
||||
'net cost': 'coûts nets',
|
||||
'none created': 'Rien de créé',
|
||||
'optimal mass': null, // Lowest weight / best weight for jump distance, etc
|
||||
'refuel time': 'Temps de remplissage', // Time to refuel the tank when scooping
|
||||
'reload costs': null,
|
||||
'retrofit costs': 'Valeur de rachat', // The cost difference when upgrading / downgrading a component
|
||||
'retrofit from': 'Racheter de', // Retrofit from Build A against build B
|
||||
'T-Load': 'degrés', // Thermal load abbreviation
|
||||
'total range': null,
|
||||
'unit cost': null,
|
||||
'utility mounts': 'Support utilitaire',
|
||||
about: 'à propos', // Link to about page / about Coriolis.io
|
||||
added: 'ajouté',
|
||||
ammo: 'munition', // Ammunition
|
||||
armour: 'Armure',
|
||||
available: 'Disponibilité',
|
||||
available: 'Disponibilité', // Available options
|
||||
backup: 'sauvegarde',
|
||||
base: null,
|
||||
bays: null,
|
||||
bays: 'baies',
|
||||
bins: 'bacs', // Number of Mining Refinery bins
|
||||
build: 'Configuration', // Shorthand for the build/configuration/design name
|
||||
'build name': 'Nom de la configuration', // Ship build/configuration/design name
|
||||
builds: 'Configurations', // Ship build/configuration/design names
|
||||
buy: 'Acheter',
|
||||
cancel: 'Annuler',
|
||||
@@ -135,58 +58,77 @@ export const terms = {
|
||||
cells: 'Cellule', // Number of cells in a shield cell bank
|
||||
close: 'fermer',
|
||||
compare: 'comparer',
|
||||
'compare all': 'tout comparer',
|
||||
comparison: 'comparaison',
|
||||
comparisons: 'comparaisons',
|
||||
cost: 'coût', // Cost / price of a module or price of a ship
|
||||
costs: 'coûts', // Costs / prices of a modules or prices of ships
|
||||
create: 'Créer',
|
||||
'create new': 'Créer nouveau',
|
||||
credits: 'crédits',
|
||||
damage: 'Dégâts',
|
||||
damage: 'dégât',
|
||||
'damage per second': 'dégât par seconde',
|
||||
delete: 'supprimer',
|
||||
'delete all': 'tout supprimer',
|
||||
dep: 'depl', // Weapons/Hardpoints Deployed abbreviation
|
||||
deployed: 'déployé', // Weapons/Hardpoints Deployed
|
||||
'detailed export': 'export détaillé',
|
||||
disabled: 'désactivé',
|
||||
discount: 'ristourne',
|
||||
'edit data': 'Editer donnée',
|
||||
efficiency: 'rendement', // Power Plant efficiency
|
||||
empty: 'Vide',
|
||||
Explorer: null,
|
||||
'empty all': 'vide tout',
|
||||
'Enter Name': 'Entrer nom',
|
||||
Explorer: 'explorateur',
|
||||
'fastest range': 'gamme la plus rapide', // Fastet totaljump range - sum of succesive jumps
|
||||
fuel: 'carburant',
|
||||
'fuel level': 'niveau de carburant', // Percent of fuel (T) in the tank
|
||||
'full tank': 'Réservoir plein',
|
||||
hardpoints: 'Points d\'emport',
|
||||
hull: 'Coque', // Ships hull
|
||||
import: 'Importer',
|
||||
insurance: 'Assurance',
|
||||
jump: null, // Single jump range
|
||||
'internal compartments': 'compartiments internes',
|
||||
jump: 'saut', // Single jump range
|
||||
'jump range': 'Distance de saut',
|
||||
jumps: 'Sauts',
|
||||
laden: 'chargé',
|
||||
language: 'Langage',
|
||||
maneuverability: null,
|
||||
manufacturer: null,
|
||||
maneuverability: 'maniabilité',
|
||||
manufacturer: 'fabricant',
|
||||
mass: 'Masse',
|
||||
MLF: null, // Mass Lock Factor Abbreviation
|
||||
MNV: null, // Maneuverability abbreviation
|
||||
module: null,
|
||||
modules: null,
|
||||
'mass lock factor': 'facteur inhibition de masse',
|
||||
'max mass': 'masse max',
|
||||
MLF: 'FIM', // Mass Lock Factor Abbreviation
|
||||
'net cost': 'coûts nets',
|
||||
no: 'non',
|
||||
'none created': 'Rien de créé',
|
||||
ok: 'D\'accord',
|
||||
optimize: null,
|
||||
'optimal mass': 'masse optimale', // Lowest weight / best weight for jump distance, etc
|
||||
optimize: 'optimiser',
|
||||
pen: 'pén.', // Armour peneration abbreviation
|
||||
permalink: 'lien durable',
|
||||
power: 'énergie', // Power = Energy / second. Power generated by the power plant, or power consumed (MW / Mega Watts). Used in the power plant section
|
||||
proceed: 'continuer',
|
||||
PWR: 'P', // Power Abbreviation. See Power
|
||||
qty: null, // Quantity abbreviation
|
||||
qty: 'quantité', // Quantity abbreviation
|
||||
range: 'portée',
|
||||
rate: 'cadence',
|
||||
recharge: null, // Shield Recharge time from 50% -> 100%
|
||||
recovery: null, // Shield recovery time (after losing shields/turning on -> 50%)
|
||||
recharge: 'recharger', // Shield Recharge time from 50% -> 100%
|
||||
recovery: 'récupération', // Shield recovery time (after losing shields/turning on -> 50%)
|
||||
'refuel time': 'Temps de remplissage', // Time to refuel the tank when scooping
|
||||
reload: 'recharger', // Reload weapon/hardpoint
|
||||
'reload costs': 'recharger coûts',
|
||||
rename: 'renommer',
|
||||
repair: 'réparer',
|
||||
reset: 'Réinitialisation',
|
||||
ret: 'esc', // Retracted abbreviation
|
||||
retracted: 'escamoté', // Weapons/Hardpoints retracted
|
||||
'retrofit costs': 'Valeur de rachat', // The cost difference when upgrading / downgrading a component
|
||||
'retrofit from': 'Racheter de', // Retrofit from Build A against build B
|
||||
ROF: 'cadence', // Rate of Fire abbreviation
|
||||
roles: null, // Commander/Ship build roles - e.g. Trader, Bounty-Hunter, Explorer, etc
|
||||
roles: 'rôles', // Commander/Ship build roles - e.g. Trader, Bounty-Hunter, Explorer, etc
|
||||
save: 'sauvegarder',
|
||||
sell: 'vendre',
|
||||
settings: 'paramètres', // Coriolis application settings
|
||||
@@ -198,12 +140,16 @@ export const terms = {
|
||||
skip: 'Suivant', // Skip past something / ignore it
|
||||
speed: 'vitesse',
|
||||
Stock: 'de base', // Thermal-load abbreviation
|
||||
strength: null, // Strength in reference to Shield Strength
|
||||
subtotal: null,
|
||||
strength: 'force', // Strength in reference to Shield Strength
|
||||
subtotal: 'Sous-Total',
|
||||
'T-Load': 'degrés', // Thermal load abbreviation
|
||||
time: 'temps', // time it takes to complete something
|
||||
tooltips: null, // Tooltips setting - show/hide
|
||||
Trader: null, // Trader role
|
||||
tooltips: 'infobulles', // Tooltips setting - show/hide
|
||||
'total range': 'plage totale',
|
||||
Trader: 'commerçant', // Trader role
|
||||
'unit cost': 'coût unitaire',
|
||||
unladen: 'Non chargé', // No cargo or fuel
|
||||
'utility mounts': 'Support utilitaire',
|
||||
WEP: 'ARM', // Abbreviation - Weapon recharge rate for power distributor
|
||||
yes: 'oui'
|
||||
};
|
||||
|
||||
@@ -18,90 +18,22 @@ export const terms = {
|
||||
PHRASE_BACKUP_DESC: 'Сохраните все данные перед переносом в другой браузер или устройство', // Backup of all Coriolis data to save or transfer to another browser/device
|
||||
PHRASE_CONFIRMATION: 'Вы уверены?', // Are You Sure?
|
||||
PHRASE_EXPORT_DESC: 'Детальный JSON-экспорт вашей сборки для использования в других местах и инструментах', // A detailed JSON export of your build for use in other sites and tools
|
||||
PHRASE_FASTEST_RANGE: null, // Consecutive max range jumps
|
||||
PHRASE_FASTEST_RANGE: 'Последовательные максимальные дальности прыжков', // Consecutive max range jumps
|
||||
PHRASE_IMPORT: 'Для импорта вставьте код в эту форму', // Paste JSON or import here
|
||||
PHRASE_LADEN: null, // Ship Mass + Fuel + Cargo
|
||||
PHRASE_LADEN: 'Корабль Масса + топлива + Грузы', // Ship Mass + Fuel + Cargo
|
||||
PHRASE_NO_BUILDS: 'Нечего сравнивать', // No builds added to comparison!
|
||||
PHRASE_NO_RETROCH: 'нет ранних версий сборкиконфигурации', // No Retrofitting changes
|
||||
PHRASE_SELECT_BUILDS: 'Выберите конфигурацию для сравнения', // Select Builds to Compare
|
||||
PHRASE_SG_RECHARGE: null, // Time from 50% to 100% Charge
|
||||
PHRASE_SG_RECOVER: null, // Recovery (to 50%) after collapse
|
||||
PHRASE_UNLADEN: null, // Ship Mass excluding Fuel and Cargo
|
||||
PHRASE_SG_RECHARGE: 'восстановление с 60% до 100% объема щита', // Time from 50% to 100% Charge
|
||||
PHRASE_SG_RECOVER: 'восстановление [до 60%] после падения\сбития', // Recovery (to 50%) after collapse
|
||||
PHRASE_UNLADEN: 'Судно Масса без учета топлива и грузов', // Ship Mass excluding Fuel and Cargo
|
||||
PHRASE_UPDATE_RDY: 'Доступно обновление. Нажмите для обновления.', // Update Available! Click to Refresh
|
||||
|
||||
// Modules / Module Types - These should match the in-game translation (if any)
|
||||
'Advanced Discovery Scanner': null, // Advanced Discovery Scanner
|
||||
'Basic Discovery Scanner': 'Стандартный исследовательский сканер', // Basic Discovery Scanner
|
||||
'Cargo Hatch': 'Грузовой люк', // Cargo Hatch
|
||||
'Chaff Launcher': 'Постановщик помех', // Chaff Launcher
|
||||
'Detailed Surface Scanner': 'Подробный сканер поверхности', // Detailed Surface Scanner
|
||||
'Electronic Countermeasure': 'Электронная противомера', // Electronic Countermeasure
|
||||
'Heat Sink Launcher': 'Теплоотводная ПУ', // Heat Sink Launcher
|
||||
'Intermediate Discovery Scanner': 'Средний исследовательский сканер', // Intermediate Discovery Scanner
|
||||
'Point Defence': 'Противоракетная защита',
|
||||
'Standard Docking Computer': 'Стандартный стыковочный компьютер', // Standard Docking Computer
|
||||
am: 'Ремонтный модуль', // Auto Field-Maintenance Unit
|
||||
bh: 'Корпус', // Bulkheads
|
||||
bl: 'Лучевой лазер', // Beam Laser
|
||||
bsg: null, // Bi-Weave Shield Generator
|
||||
c: 'Пушка', // Cannon
|
||||
cc: 'Контроллер "дрон-сборщик"', // Collector Limpet Controller
|
||||
cm: 'Контрмеры', // Countermeasure
|
||||
cr: 'Грузовой отсек', // Cargo Rack
|
||||
cs: 'Сканер груза', // Cargo Scanner
|
||||
dc: 'Стыковочный компьютер', // Docking Computer
|
||||
fc: 'Осколочное Орудие', // Fragment Cannon
|
||||
fi: 'Перехватчик FSD', // FSD Interdictor
|
||||
fs: 'Топливосборщик', // Fuel Scoop
|
||||
fsd: 'Двигатель FSD', // Frame Shift Drive
|
||||
ft: 'Топливный бак', // Fuel Tank
|
||||
fx: 'Контроллер "Дрон-заправщик"', // Fuel Transfer Limpet Controller
|
||||
hb: 'Контроллер "дрон-взломщик"', // Hatch Breaker Limpet Controller
|
||||
hr: 'Набор усиления корпуса', // Hull Reinforcement Package
|
||||
kw: 'Полицейский сканер', // Kill Warrant Scanner
|
||||
ls: 'Система жизнеобеспечения', // life support
|
||||
mc: 'Многоствольное орудие', // Multi-cannon
|
||||
ml: 'Бурильный лазер', // Mining Laser
|
||||
mr: 'Ракетная установка', // Missile Rack
|
||||
nl: 'Минноукладчик', // Mine Launcher
|
||||
pa: 'Ускоритель плазмы', // Plasma Accelerator
|
||||
pas: null, // Planetary Approach Suite
|
||||
pc: 'Контроллер "Дрон-исследователь"', // Prospector Limpet Controller
|
||||
pd: 'Распределитель энергии', // power distributor
|
||||
pl: 'Импульсный лазер', // Pulse Laser
|
||||
pp: 'Реактор', // Power Plant
|
||||
psg: 'Генератор призматического щита', // Prismatic Shield Generator
|
||||
pv: null, // Planetary Vehicle Hanger
|
||||
rf: 'Переработка', // Refinery
|
||||
rg: 'Рельсотрон', // Rail Gun
|
||||
s: 'Сенсоры', // Sensors
|
||||
sb: 'Усилитель щита', // Shield Booster
|
||||
sc: 'Сканер', // Scanner
|
||||
scb: 'Батареи перезарядки щита', // Shield Cell Bank
|
||||
sg: 'Генератор щита', // Shield Generator
|
||||
t: 'Двигатели', // Thrusters
|
||||
tp: 'Торпедный аппарат', // Torpedo Pylon
|
||||
ul: 'Мультиимпульсный лазер', // Burst Laser
|
||||
ws: 'FSD Сканнер', // Frame Shift Wake Scanner
|
||||
|
||||
// Bulkheads - These should match the in-game translation (if any)
|
||||
'Lightweight Alloy': 'Легкий сплав',
|
||||
'Reinforced Alloy': 'Усиленный сплав',
|
||||
'Military Grade Composite': 'Военный композит',
|
||||
'Mirrored Surface Composite': 'Зеркальный композит',
|
||||
'Reactive Surface Composite': 'Динамическая защита',
|
||||
|
||||
// Units / Metrics
|
||||
'/min': null, // Per minute
|
||||
'/s': null, // Per second
|
||||
kg: null, // Kilogram
|
||||
'kg/s': null, // Kilograms per second
|
||||
km: null, // Kilometer
|
||||
'/s': '/с', // Per second
|
||||
'm/s': 'м/с', // Meters / Second
|
||||
Ls: 'Св.сек', // Light seconds
|
||||
LY: 'Св.лет', // Light Years
|
||||
MJ: null, // Mega Joules
|
||||
MW: null, // Mega Watts
|
||||
CR: 'кр.', // Credits abbreviation
|
||||
|
||||
// Sizes
|
||||
@@ -110,24 +42,25 @@ export const terms = {
|
||||
L: 'б', // Large Hardpoint size (single character)
|
||||
H: 'O', // Huge Hardpoint size (single character)
|
||||
U: 'B', // Utility Hardpoint size (single character) - Kill warrant scanner, etc
|
||||
|
||||
small: 'Малый', // Small ship size
|
||||
medium: 'Средний', // Medium ship size
|
||||
large: 'большой', // Large Ship Size
|
||||
// Insurance
|
||||
alpha: 'Альфа', // Alpha backer insurance level
|
||||
beta: 'Бета', // Beta back insurance level
|
||||
standard: 'Стандартный', // Standard insurance level
|
||||
|
||||
// Terms
|
||||
'build name': 'название сборки', // Ship build/configuration/design name
|
||||
'compare all': 'сравнить все',
|
||||
'create new': 'Создать новый',
|
||||
'damage per second': null,
|
||||
'damage per second': 'урон в секунду',
|
||||
'delete all': 'Удалить все',
|
||||
'detailed export': 'Подробный экспорт',
|
||||
'edit data': 'Редактирование',
|
||||
'empty all': null,
|
||||
'empty all': 'пусто все',
|
||||
'Enter Name': 'Введите имя',
|
||||
'fastest range': null, // Fastet totaljump range - sum of succesive jumps
|
||||
'fuel level': null, // Percent of fuel (T) in the tank
|
||||
'fastest range': 'быстрый диапазон', // Fastet totaljump range - sum of succesive jumps
|
||||
'fuel level': 'уровень топлива', // Percent of fuel (T) in the tank
|
||||
'full tank': 'Полный бак',
|
||||
'internal compartments': 'внутренние отсеки',
|
||||
'jump range': 'Дальность прыжка',
|
||||
@@ -135,24 +68,18 @@ export const terms = {
|
||||
'max mass': 'Максимальная масса',
|
||||
'net cost': 'разница в цене',
|
||||
'none created': 'не создано',
|
||||
'optimal mass': null, // Lowest weight / best weight for jump distance, etc
|
||||
'refuel time': 'Время дозаправки', // Time to refuel the tank when scooping
|
||||
'reload costs': null,
|
||||
'retrofit costs': 'цена модификации', // The cost difference when upgrading / downgrading a component
|
||||
'retrofit from': 'модификация от', // Retrofit from Build A against build B
|
||||
'T-Load': 'Тепл.', // Thermal load abbreviation
|
||||
'total range': null,
|
||||
'unit cost': null,
|
||||
'utility mounts': 'Вспомогательное оборудование',
|
||||
about: 'О ...', // Link to about page / about Coriolis.io
|
||||
action: 'Действие',
|
||||
added: 'Добавлено',
|
||||
ammo: 'Боекомплект', // Ammunition
|
||||
armour: 'Броня',
|
||||
available: 'доступно',
|
||||
available: 'доступно', // Available options
|
||||
backup: 'Резервная копия',
|
||||
base: null,
|
||||
bays: null,
|
||||
bins: 'контейнеры', // Number of Mining Refinery bins
|
||||
boost: 'форсаж',
|
||||
build: 'cборка', // Shorthand for the build/configuration/design name
|
||||
@@ -179,7 +106,6 @@ export const terms = {
|
||||
efficiency: 'Эффективность', // Power Plant efficiency
|
||||
empty: 'пусто',
|
||||
ENG: 'ДВГ', // Abbreviation - Engine recharge rate for power distributor
|
||||
Explorer: null,
|
||||
export: 'Экспорт',
|
||||
forum: 'Форум',
|
||||
fuel: 'Топливо',
|
||||
@@ -187,32 +113,26 @@ export const terms = {
|
||||
hull: 'Корпус', // Ships hull
|
||||
import: 'импортировать ',
|
||||
insurance: 'Страховка',
|
||||
jump: null, // Single jump range
|
||||
|
||||
jumps: 'Прыжков',
|
||||
laden: 'Груженый',
|
||||
language: 'Язык',
|
||||
maneuverability: 'Моневренность',
|
||||
manufacturer: null,
|
||||
|
||||
mass: 'Масса',
|
||||
max: 'Макс',
|
||||
MLF: null, // Mass Lock Factor Abbreviation
|
||||
MNV: null, // Maneuverability abbreviation
|
||||
module: null,
|
||||
modules: null,
|
||||
|
||||
no: 'Нет',
|
||||
ok: null,
|
||||
optimize: null,
|
||||
pen: 'ПБ', // Armour peneration abbreviation
|
||||
permalink: 'Постоянная ссылка',
|
||||
power: 'Мощность', // Power = Energy / second. Power generated by the power plant, or power consumed (MW / Mega Watts). Used in the power plant section
|
||||
pri: 'Осн', // Priority abbreviation for power management
|
||||
proceed: 'продолжить',
|
||||
PWR: 'Эн', // Power Abbreviation. See Power
|
||||
qty: null, // Quantity abbreviation
|
||||
range: 'Дальность',
|
||||
rate: 'скорость',
|
||||
recharge: null, // Shield Recharge time from 50% -> 100%
|
||||
recovery: null, // Shield recovery time (after losing shields/turning on -> 50%)
|
||||
recharge: 'перезарядка', // Shield Recharge time from 50% -> 100%
|
||||
recovery: 'включение', // Shield recovery time (after losing shields/turning on -> 50%)
|
||||
reload: 'Перезагрузить', // Reload weapon/hardpoint
|
||||
rename: 'Переименовать',
|
||||
repair: 'Починка',
|
||||
@@ -220,7 +140,7 @@ export const terms = {
|
||||
ret: 'Убр.', // Retracted abbreviation
|
||||
retracted: 'Убрано', // Weapons/Hardpoints retracted
|
||||
ROF: 'В/сек', // Rate of Fire abbreviation
|
||||
roles: null, // Commander/Ship build roles - e.g. Trader, Bounty-Hunter, Explorer, etc
|
||||
|
||||
save: 'Сохранить',
|
||||
sell: 'Продать',
|
||||
settings: 'Настройки', // Coriolis application settings
|
||||
@@ -233,13 +153,9 @@ export const terms = {
|
||||
speed: 'скорость',
|
||||
standard: 'Стандартный', // Standard / Common modules (FSD, power plant, life support, etc)
|
||||
Stock: 'Стандартная комплектация', // Thermal-load abbreviation
|
||||
strength: null, // Strength in reference to Shield Strength
|
||||
subtotal: null,
|
||||
SYS: 'СИСТЕМЫ', // Abbreviation - System recharge rate for power distributor
|
||||
time: 'Время', // time it takes to complete something
|
||||
tooltips: null, // Tooltips setting - show/hide
|
||||
total: 'Всего',
|
||||
Trader: null, // Trader role
|
||||
type: 'Тип',
|
||||
unladen: 'Пустой', // No cargo or fuel
|
||||
URL: 'Ссылка', // Link, Uniform Resource Locator
|
||||
|
||||
@@ -53,6 +53,7 @@ export default class ComparisonPage extends Page {
|
||||
super(props, context);
|
||||
this._sortShips = this._sortShips.bind(this);
|
||||
this._buildsSelected = this._buildsSelected.bind(this);
|
||||
this._updateDiscounts = this._updateDiscounts.bind(this);
|
||||
this.state = this._initState(context);
|
||||
}
|
||||
|
||||
@@ -161,6 +162,7 @@ export default class ComparisonPage extends Page {
|
||||
let b = new Ship(id, data.properties, data.slots); // Create a new Ship instance
|
||||
b.buildFrom(code); // Populate components from code
|
||||
b.buildName = name;
|
||||
b.applyDiscounts(Persist.getShipDiscount(), Persist.getModuleDiscount());
|
||||
return b;
|
||||
};
|
||||
|
||||
@@ -383,6 +385,21 @@ export default class ComparisonPage extends Page {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Update all ship costs on disount change
|
||||
*/
|
||||
_updateDiscounts() {
|
||||
let shipDiscount = Persist.getShipDiscount();
|
||||
let moduleDiscount = Persist.getModuleDiscount();
|
||||
let builds = [];
|
||||
|
||||
for (let b of this.state.builds) {
|
||||
builds.push(b.applyDiscounts(shipDiscount, moduleDiscount));
|
||||
}
|
||||
|
||||
this.setState({ builds });
|
||||
}
|
||||
|
||||
/**
|
||||
* Update state based on context changes
|
||||
* @param {Object} nextProps Incoming/Next properties
|
||||
@@ -399,6 +416,7 @@ export default class ComparisonPage extends Page {
|
||||
*/
|
||||
componentWillMount() {
|
||||
this.resizeListener = this.context.onWindowResize(this._updateDimensions);
|
||||
this.persistListener = Persist.addListener('discounts', this._updateDiscounts);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -413,6 +431,7 @@ export default class ComparisonPage extends Page {
|
||||
*/
|
||||
componentWillUnmount() {
|
||||
this.resizeListener.remove();
|
||||
this.persistListener.remove();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -8,17 +8,18 @@ import { shallowEqual } from '../utils/UtilityFunctions';
|
||||
export default class Page extends React.Component {
|
||||
|
||||
static contextTypes = {
|
||||
route: React.PropTypes.object.isRequired,
|
||||
language: React.PropTypes.object.isRequired,
|
||||
sizeRatio: React.PropTypes.number.isRequired,
|
||||
openMenu: React.PropTypes.func.isRequired,
|
||||
closeMenu: React.PropTypes.func.isRequired,
|
||||
showModal: React.PropTypes.func.isRequired,
|
||||
hideModal: React.PropTypes.func.isRequired,
|
||||
tooltip: React.PropTypes.func.isRequired,
|
||||
termtip: React.PropTypes.func.isRequired,
|
||||
language: React.PropTypes.object.isRequired,
|
||||
noTouch: React.PropTypes.bool.isRequired,
|
||||
onCommand: React.PropTypes.func.isRequired,
|
||||
onWindowResize: React.PropTypes.func.isRequired,
|
||||
onCommand: React.PropTypes.func.isRequired
|
||||
openMenu: React.PropTypes.func.isRequired,
|
||||
route: React.PropTypes.object.isRequired,
|
||||
showModal: React.PropTypes.func.isRequired,
|
||||
sizeRatio: React.PropTypes.number.isRequired,
|
||||
termtip: React.PropTypes.func.isRequired,
|
||||
tooltip: React.PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
static propTypes = {
|
||||
|
||||
@@ -27,6 +27,38 @@ function countInt(slot) {
|
||||
this.maxCargo += crEligible ? ModuleUtils.findInternal('cr', slot.maxClass, 'E').cargo : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate Ship summary and aggregated properties
|
||||
* @param {String} shipId Ship Id
|
||||
* @param {Object} shipData Ship Default Data
|
||||
* @return {Object} Ship summary and aggregated properties
|
||||
*/
|
||||
function shipSummary(shipId, shipData) {
|
||||
let summary = {
|
||||
id: shipId,
|
||||
hpCount: 0,
|
||||
intCount: 0,
|
||||
maxCargo: 0,
|
||||
hp: [0, 0, 0, 0, 0], // Utility, Small, Medium, Large, Huge
|
||||
int: [0, 0, 0, 0, 0, 0, 0, 0] // Sizes 1 - 8
|
||||
};
|
||||
Object.assign(summary, shipData.properties);
|
||||
let ship = new Ship(shipId, shipData.properties, shipData.slots);
|
||||
|
||||
// Build Ship
|
||||
ship.buildWith(shipData.defaults); // Populate with stock/default components
|
||||
ship.hardpoints.forEach(countHp.bind(summary)); // Count Hardpoints by class
|
||||
ship.internal.forEach(countInt.bind(summary)); // Count Internal Compartments by class
|
||||
summary.retailCost = ship.totalCost; // Record Stock/Default/retail cost
|
||||
ship.optimizeMass({ pd: '1D' }); // Optimize Mass with 1D PD for maximum possible jump range
|
||||
summary.maxJumpRange = ship.unladenRange; // Record Jump Range
|
||||
ship.optimizeMass({ th: ship.standard[1].maxClass + 'A', fsd: '2D', ft: '1C' }); // Optmize mass with Max Thrusters
|
||||
summary.topSpeed = ship.topSpeed;
|
||||
summary.topBoost = ship.topBoost;
|
||||
|
||||
return summary;
|
||||
}
|
||||
|
||||
/**
|
||||
* The Shipyard summary page
|
||||
*/
|
||||
@@ -41,20 +73,30 @@ export default class ShipyardPage extends Page {
|
||||
*/
|
||||
constructor(props, context) {
|
||||
super(props, context);
|
||||
this.state = {
|
||||
title: 'Coriolis - Shipyard',
|
||||
shipPredicate: 'name',
|
||||
shipDesc: true
|
||||
};
|
||||
|
||||
if (!ShipyardPage.cachedShipSummaries) {
|
||||
ShipyardPage.cachedShipSummaries = [];
|
||||
for (let s in Ships) {
|
||||
ShipyardPage.cachedShipSummaries.push(this._shipSummary(s, Ships[s]));
|
||||
ShipyardPage.cachedShipSummaries.push(shipSummary(s, Ships[s]));
|
||||
}
|
||||
}
|
||||
|
||||
this.shipSummaries = ShipyardPage.cachedShipSummaries;
|
||||
this.state = {
|
||||
title: 'Coriolis - Shipyard',
|
||||
shipPredicate: 'name',
|
||||
shipDesc: true,
|
||||
shipSummaries: ShipyardPage.cachedShipSummaries
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Higlight the current ship in the table
|
||||
* @param {String} shipId Ship Id
|
||||
* @param {SyntheticEvent} event Event
|
||||
*/
|
||||
_highlightShip(shipId, event) {
|
||||
event.stopPropagation();
|
||||
this.setState({ shipId });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -76,38 +118,6 @@ export default class ShipyardPage extends Page {
|
||||
this.setState({ shipPredicate, shipDesc, shipPredicateIndex });
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate Ship summary and aggregated properties
|
||||
* @param {String} shipId Ship Id
|
||||
* @param {Object} shipData Ship Default Data
|
||||
* @return {Object} Ship summary and aggregated properties
|
||||
*/
|
||||
_shipSummary(shipId, shipData) {
|
||||
let summary = {
|
||||
id: shipId,
|
||||
hpCount: 0,
|
||||
intCount: 0,
|
||||
maxCargo: 0,
|
||||
hp: [0, 0, 0, 0, 0], // Utility, Small, Medium, Large, Huge
|
||||
int: [0, 0, 0, 0, 0, 0, 0, 0] // Sizes 1 - 8
|
||||
};
|
||||
Object.assign(summary, shipData.properties);
|
||||
let ship = new Ship(shipId, shipData.properties, shipData.slots);
|
||||
|
||||
// Build Ship
|
||||
ship.buildWith(shipData.defaults); // Populate with stock/default components
|
||||
ship.hardpoints.forEach(countHp.bind(summary)); // Count Hardpoints by class
|
||||
ship.internal.forEach(countInt.bind(summary)); // Count Internal Compartments by class
|
||||
summary.retailCost = ship.totalCost; // Record Stock/Default/retail cost
|
||||
ship.optimizeMass({ pd: '1D' }); // Optimize Mass with 1D PD for maximum possible jump range
|
||||
summary.maxJumpRange = ship.unladenRange; // Record Jump Range
|
||||
ship.optimizeMass({ th: ship.standard[1].maxClass + 'A' }); // Optmize mass with Max Thrusters
|
||||
summary.topSpeed = ship.topSpeed;
|
||||
summary.topBoost = ship.topBoost;
|
||||
|
||||
return summary;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the table row summary for the ship
|
||||
* @param {Object} s Ship summary
|
||||
@@ -118,8 +128,14 @@ export default class ShipyardPage extends Page {
|
||||
* @return {React.Component} Table Row
|
||||
*/
|
||||
_shipRowElement(s, translate, u, fInt, fRound) {
|
||||
return <tr key={s.id} className='highlight'>
|
||||
<td className='le'><Link href={'/outfit/' + s.id}>{s.name}</Link></td>
|
||||
let noTouch = this.context.noTouch;
|
||||
|
||||
return <tr
|
||||
key={s.id}
|
||||
style={{ height: '1.5em' }}
|
||||
className={cn({ highlighted: noTouch && this.state.shipId === s.id })}
|
||||
onMouseEnter={noTouch && this._highlightShip.bind(this, s.id)}
|
||||
>
|
||||
<td className='le'>{s.manufacturer}</td>
|
||||
<td className='cap'>{translate(SizeMap[s.class])}</td>
|
||||
<td>{s.agility}</td>
|
||||
@@ -155,17 +171,27 @@ export default class ShipyardPage extends Page {
|
||||
* @return {React.Component} The page contents
|
||||
*/
|
||||
renderPage() {
|
||||
let { translate, formats, units } = this.context.language;
|
||||
let { sizeRatio, language, termtip, noTouch } = this.context;
|
||||
let { translate, formats, units } = language;
|
||||
let hide = this.context.tooltip.bind(null, null);
|
||||
let fInt = formats.int;
|
||||
let fRound = formats.round;
|
||||
let shipSummaries = this.shipSummaries;
|
||||
let shipPredicate = this.state.shipPredicate;
|
||||
let shipPredicateIndex = this.state.shipPredicateIndex;
|
||||
let shipRows = [];
|
||||
let hide = this.context.tooltip.bind(null, null);
|
||||
let tip = this.context.termtip;
|
||||
let { shipSummaries, shipPredicate, shipPredicateIndex } = this.state;
|
||||
let sortShips = (predicate, index) => this._sortShips.bind(this, predicate, index);
|
||||
|
||||
let filters = {
|
||||
// 'class': { 1: 1, 2: 1}
|
||||
};
|
||||
|
||||
shipSummaries = shipSummaries.filter(s => {
|
||||
for (let prop in filters) {
|
||||
if (!(s[prop] in filters[prop])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
// Sort shipsOverview
|
||||
shipSummaries.sort((a, b) => {
|
||||
let valA = a[shipPredicate], valB = b[shipPredicate];
|
||||
@@ -194,26 +220,51 @@ export default class ShipyardPage extends Page {
|
||||
}
|
||||
});
|
||||
|
||||
let i = 0;
|
||||
let shipRows = new Array(shipSummaries.length);
|
||||
let detailRows = new Array(shipSummaries.length);
|
||||
|
||||
for (let s of shipSummaries) {
|
||||
shipRows.push(this._shipRowElement(s, translate, units, fInt, fRound));
|
||||
detailRows[i] = this._shipRowElement(s, translate, units, fInt, fRound);
|
||||
shipRows[i] = (
|
||||
<tr
|
||||
key={i}
|
||||
style={{ height: '1.5em' }}
|
||||
className={cn({ highlighted: noTouch && this.state.shipId === s.id })}
|
||||
onMouseEnter={noTouch && this._highlightShip.bind(this, s.id)}
|
||||
>
|
||||
<td className='le'><Link href={'/outfit/' + s.id}>{s.name}</Link></td>
|
||||
</tr>
|
||||
);
|
||||
i++;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='page' style={{ fontSize: this.context.sizeRatio + 'em' }}>
|
||||
<div className='scroll-x'>
|
||||
<table style={{ fontSize:'0.85em', whiteSpace:'nowrap', margin: '0 auto' }} align='center'>
|
||||
<div className='page' style={{ fontSize: sizeRatio + 'em' }}>
|
||||
<div style={{ whiteSpace: 'nowrap', margin: '0 auto', fontSize: '0.8em', position: 'relative', display: 'inline-block', maxWidth: '100%' }}>
|
||||
<table style={{ width: '12em', position: 'absolute', zIndex: 1 }}>
|
||||
<thead>
|
||||
<tr className='main'>
|
||||
<th style={{ height: '2.6em', padding: '2px 0.4em 1px' }} className='sortable le rgt' onClick={sortShips('name')}>{translate('ship')}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody onMouseLeave={this._highlightShip.bind(this, null)}>
|
||||
{shipRows}
|
||||
</tbody>
|
||||
</table>
|
||||
<div style={{ overflowX: 'scroll', maxWidth: '100%' }}>
|
||||
<table style={{ marginLeft: 'calc(12em - 1px)', zIndex: 0 }}>
|
||||
<thead>
|
||||
<tr className='main'>
|
||||
<th rowSpan={2} className='sortable le' onClick={sortShips('name')}>{translate('ship')}</th>
|
||||
<th rowSpan={2} className='sortable' onClick={sortShips('manufacturer')}>{translate('manufacturer')}</th>
|
||||
<th rowSpan={2} className='sortable' onClick={sortShips('class')}>{translate('size')}</th>
|
||||
<th rowSpan={2} className='sortable' onMouseEnter={tip.bind(null, 'maneuverability')} onMouseLeave={hide} onClick={sortShips('agility')}>{translate('mnv')}</th>
|
||||
<th rowSpan={2} className='sortable' onMouseEnter={termtip.bind(null, 'maneuverability')} onMouseLeave={hide} onClick={sortShips('agility')}>{translate('mnv')}</th>
|
||||
<th colSpan={4}>{translate('base')}</th>
|
||||
<th colSpan={4}>{translate('max')}</th>
|
||||
<th colSpan={5} className='sortable' onClick={sortShips('hpCount')}>{translate('hardpoints')}</th>
|
||||
<th colSpan={8} className='sortable' onClick={sortShips('intCount')}>{translate('internal compartments')}</th>
|
||||
<th rowSpan={2} className='sortable' onClick={sortShips('hullMass')}>{translate('hull')}</th>
|
||||
<th rowSpan={2} className='sortable' onMouseEnter={tip.bind(null, 'mass lock factor')} onMouseLeave={hide} onClick={sortShips('masslock')} >{translate('MLF')}</th>
|
||||
<th rowSpan={2} className='sortable' onMouseEnter={termtip.bind(null, 'mass lock factor')} onMouseLeave={hide} onClick={sortShips('masslock')} >{translate('MLF')}</th>
|
||||
<th rowSpan={2} className='sortable' onClick={sortShips('retailCost')}>{translate('cost')}</th>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -243,10 +294,11 @@ export default class ShipyardPage extends Page {
|
||||
<th className='sortable' onClick={sortShips('int', 7)} >8</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{shipRows}
|
||||
<tbody onMouseLeave={this._highlightShip.bind(this, null)}>
|
||||
{detailRows}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -43,7 +43,7 @@ export const ModuleGroupToName = {
|
||||
rf: 'Refinery',
|
||||
scb: 'Shield Cell Bank',
|
||||
sg: 'Shield Generator',
|
||||
pv: 'Planetary Vehicle Hanger',
|
||||
pv: 'Planetary Vehicle Hangar',
|
||||
psg: 'Prismatic Shield Generator',
|
||||
dc: 'Docking Computer',
|
||||
fx: 'Fuel Transfer Limpet Controller',
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
|
||||
import { BulkheadNames } from './Constants';
|
||||
|
||||
/**
|
||||
* Filter eligble modules based on parameters
|
||||
* @param {Array} arr Available modules array
|
||||
@@ -19,12 +21,13 @@ export default class ModuleSet {
|
||||
/**
|
||||
* Instantiate the module set
|
||||
* @param {Object} modules All Modules
|
||||
* @param {number} mass Ship mass
|
||||
* @param {Array} maxStandardArr Array of standard slots classes/sizes
|
||||
* @param {Array} maxInternal Array of internal slots classes/sizes
|
||||
* @param {Array} maxHardPoint Array of hardpoint slots classes/sizes
|
||||
* @param {Object} shipData Ship Specifications Data (see coriolis-data/Ships)
|
||||
*/
|
||||
constructor(modules, mass, maxStandardArr, maxInternal, maxHardPoint) {
|
||||
constructor(modules, shipData) {
|
||||
let maxInternal = isNaN(shipData.slots.internal[0]) ? shipData.slots.internal[0].class : shipData.slots.internal[0];
|
||||
let mass = shipData.properties.hullMass + 6.5;
|
||||
let maxStandardArr = shipData.slots.standard;
|
||||
let maxHardPoint = shipData.slots.hardpoints[0];
|
||||
let stnd = modules.standard;
|
||||
this.mass = mass;
|
||||
this.standard = {};
|
||||
@@ -33,6 +36,10 @@ export default class ModuleSet {
|
||||
this.hpClass = {};
|
||||
this.intClass = {};
|
||||
|
||||
this.bulkheads = shipData.bulkheads.map((b, i) => {
|
||||
return Object.assign({ grp: 'bh', name: BulkheadNames[i], index: i, class: '', rating: '' }, b);
|
||||
});
|
||||
|
||||
this.standard[0] = filter(stnd.pp, maxStandardArr[0], 0, mass); // Power Plant
|
||||
this.standard[2] = filter(stnd.fsd, maxStandardArr[2], 0, mass); // FSD
|
||||
this.standard[4] = filter(stnd.pd, maxStandardArr[4], 0, mass); // Power Distributor
|
||||
@@ -53,6 +60,15 @@ export default class ModuleSet {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the specified bulkhead
|
||||
* @param {integer} index Bulkhead index
|
||||
* @return {Object} Bulkhead module details
|
||||
*/
|
||||
getBulkhead(index) {
|
||||
return this.bulkheads[index] || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the modules that areeligible for an internal slot
|
||||
* @param {integer} c The max class module that can be mounted in the slot
|
||||
@@ -135,7 +151,7 @@ export default class ModuleSet {
|
||||
let sg = this.internal.sg[0];
|
||||
|
||||
for (let s of this.internal.sg) {
|
||||
if (s.mass < sg.mass && s.minmass <= hullMass && s.maxmass > hullMass) {
|
||||
if (s.mass < sg.mass && s.maxmass > hullMass) {
|
||||
sg = s;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ export function standard(type, id) {
|
||||
|
||||
/**
|
||||
* Finds the hardpoint with the specified ID
|
||||
* @param {string} id Hardpoint ID
|
||||
* @param {String} id Hardpoint ID
|
||||
* @return {Object} Hardpoint module or null
|
||||
*/
|
||||
export function hardpoints(id) {
|
||||
@@ -46,7 +46,7 @@ export function hardpoints(id) {
|
||||
|
||||
/**
|
||||
* Finds the internal module with the specified ID
|
||||
* @param {string} id Internal module ID
|
||||
* @param {String} id Internal module ID
|
||||
* @return {Object} Internal module or null
|
||||
*/
|
||||
export function internal(id) {
|
||||
@@ -65,11 +65,11 @@ export function internal(id) {
|
||||
* Finds an internal module based on Class, Rating, Group and/or name.
|
||||
* At least one ofGroup name or unique module name must be provided
|
||||
*
|
||||
* @param {string} groupName [Optional] Full name or abbreviated name for module group
|
||||
* @param {String} groupName [Optional] Full name or abbreviated name for module group
|
||||
* @param {integer} clss module Class
|
||||
* @param {string} rating module Rating
|
||||
* @param {string} name [Optional] Long/unique name for module -e.g. 'Advanced Discover Scanner'
|
||||
* @return {String} The id of the module if found, null if not found
|
||||
* @param {String} rating module Rating
|
||||
* @param {String} name [Optional] Long/unique name for module -e.g. 'Advanced Discover Scanner'
|
||||
* @return {Object} The module if found, null if not found
|
||||
*/
|
||||
export function findInternal(groupName, clss, rating, name) {
|
||||
let groups = {};
|
||||
@@ -103,10 +103,10 @@ export function findInternal(groupName, clss, rating, name) {
|
||||
* Finds an internal Module ID based on Class, Rating, Group and/or name.
|
||||
* At least one ofGroup name or unique module name must be provided
|
||||
*
|
||||
* @param {string} groupName [Optional] Full name or abbreviated name for module group
|
||||
* @param {String} groupName [Optional] Full name or abbreviated name for module group
|
||||
* @param {integer} clss module Class
|
||||
* @param {string} rating Module Rating
|
||||
* @param {string} name [Optional] Long/unique name for module -e.g. 'Advanced Discover Scanner'
|
||||
* @param {String} rating Module Rating
|
||||
* @param {String} name [Optional] Long/unique name for module -e.g. 'Advanced Discover Scanner'
|
||||
* @return {String} The id of the module if found, null if not found
|
||||
*/
|
||||
export function findInternalId(groupName, clss, rating, name) {
|
||||
@@ -118,12 +118,12 @@ export function findInternalId(groupName, clss, rating, name) {
|
||||
* Finds a hardpoint Module based on Class, Rating, Group and/or name.
|
||||
* At least one ofGroup name or unique module name must be provided
|
||||
*
|
||||
* @param {string} groupName [Optional] Full name or abbreviated name for module group
|
||||
* @param {String} groupName [Optional] Full name or abbreviated name for module group
|
||||
* @param {integer} clss Module Class
|
||||
* @param {string} rating [Optional] module Rating
|
||||
* @param {string} name [Optional] Long/unique name for module -e.g. 'Heat Sink Launcher'
|
||||
* @param {string} mount Mount type - [F]ixed, [G]imballed, [T]urret
|
||||
* @param {string} missile [Optional] Missile type - [D]umbfire, [S]eeker
|
||||
* @param {String} rating [Optional] module Rating
|
||||
* @param {String} name [Optional] Long/unique name for module -e.g. 'Heat Sink Launcher'
|
||||
* @param {String} mount Mount type - [F]ixed, [G]imballed, [T]urret
|
||||
* @param {String} missile [Optional] Missile type - [D]umbfire, [S]eeker
|
||||
* @return {String} The id of the module if found, null if not found
|
||||
*/
|
||||
export function findHardpoint(groupName, clss, rating, name, mount, missile) {
|
||||
@@ -158,12 +158,12 @@ export function findHardpoint(groupName, clss, rating, name, mount, missile) {
|
||||
* Finds a hardpoint module ID based on Class, Rating, Group and/or name.
|
||||
* At least one of Group name or unique module name must be provided
|
||||
*
|
||||
* @param {string} groupName [Optional] Full name or abbreviated name for module group
|
||||
* @param {String} groupName [Optional] Full name or abbreviated name for module group
|
||||
* @param {integer} clss module Class
|
||||
* @param {string} rating module Rating
|
||||
* @param {string} name [Optional] Long/unique name for module -e.g. 'Heat Sink Launcher'
|
||||
* @param {string} mount Mount type - [F]ixed, [G]imballed, [T]urret
|
||||
* @param {string} missile [Optional] Missile type - [D]umbfire, [S]eeker
|
||||
* @param {String} rating module Rating
|
||||
* @param {String} name [Optional] Long/unique name for module -e.g. 'Heat Sink Launcher'
|
||||
* @param {String} mount Mount type - [F]ixed, [G]imballed, [T]urret
|
||||
* @param {String} missile [Optional] Missile type - [D]umbfire, [S]eeker
|
||||
* @return {String} The id of the module if found, null if not found
|
||||
*/
|
||||
export function findHardpointId(groupName, clss, rating, name, mount, missile) {
|
||||
@@ -171,24 +171,9 @@ export function findHardpointId(groupName, clss, rating, name, mount, missile) {
|
||||
return h ? h.id : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks up the bulkhead module for a specific ship and bulkhead
|
||||
* @param {string} shipId Unique ship Id/Key
|
||||
* @param {string|number} index Index for the specified bulkhead
|
||||
* @return {Object} The bulkhead module object
|
||||
*/
|
||||
export function bulkheads(shipId, index) {
|
||||
let bulkhead = Ships[shipId].bulkheads[index];
|
||||
bulkhead.class = 1;
|
||||
bulkhead.rating = 'I';
|
||||
bulkhead.name = BulkheadNames[index];
|
||||
|
||||
return bulkhead;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the bulkhead index for the given bulkhead name
|
||||
* @param {string} bulkheadName Bulkhead name in english
|
||||
* @param {String} bulkheadName Bulkhead name in english
|
||||
* @return {number} Bulkhead index
|
||||
*/
|
||||
export function bulkheadIndex(bulkheadName) {
|
||||
@@ -198,7 +183,7 @@ export function bulkheadIndex(bulkheadName) {
|
||||
|
||||
/**
|
||||
* Determine if a module group is a shield generator
|
||||
* @param {string} g Module Group name
|
||||
* @param {String} g Module Group name
|
||||
* @return {Boolean} True if the group is a shield generator
|
||||
*/
|
||||
export function isShieldGenerator(g) {
|
||||
@@ -211,11 +196,9 @@ export function isShieldGenerator(g) {
|
||||
*
|
||||
* 6.5 T is the lightest possible mass of standard components that any ship can use
|
||||
*
|
||||
* @param {string} shipId Unique ship Id/Key
|
||||
* @param {String} shipId Unique ship Id/Key
|
||||
* @return {ModuleSet} The set of modules the ship can install
|
||||
*/
|
||||
export function forShip(shipId) {
|
||||
let ship = Ships[shipId];
|
||||
let maxInternal = isNaN(ship.slots.internal[0]) ? ship.slots.internal[0].class : ship.slots.internal[0];
|
||||
return new ModuleSet(Modules, ship.properties.hullMass + 6.5, ship.slots.standard, maxInternal, ship.slots.hardpoints[0]);
|
||||
return new ModuleSet(Modules, Ships[shipId]);
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ export function toDetailedBuild(buildName, ship) {
|
||||
}],
|
||||
components: {
|
||||
standard: {
|
||||
bulkheads: BulkheadNames[ship.bulkheads.index],
|
||||
bulkheads: BulkheadNames[ship.bulkheads.m.index],
|
||||
cargoHatch: { enabled: Boolean(ship.cargoHatch.enabled), priority: ship.cargoHatch.priority + 1 },
|
||||
powerPlant: { class: standard[0].m.class, rating: standard[0].m.rating, enabled: Boolean(standard[0].enabled), priority: standard[0].priority + 1 },
|
||||
thrusters: { class: standard[1].m.class, rating: standard[1].m.rating, enabled: Boolean(standard[1].enabled), priority: standard[1].priority + 1 },
|
||||
|
||||
@@ -294,8 +294,8 @@ export default class Ship {
|
||||
*/
|
||||
getStandardString() {
|
||||
if(!this.serialized.standard) {
|
||||
this.serialized.standard = this.bulkheads.index + this.standard.reduce((arr, slot, i) => {
|
||||
arr[i] = slot.m ? slot.m.class + slot.m.rating : '-';
|
||||
this.serialized.standard = this.bulkheads.m.index + this.standard.reduce((arr, slot, i) => {
|
||||
arr[i] = slot.m ? slot.m.id : '-';
|
||||
return arr;
|
||||
}, new Array(this.standard.length)).join('');
|
||||
}
|
||||
@@ -739,7 +739,7 @@ export default class Ship {
|
||||
updateTopSpeed() {
|
||||
let speeds = Calc.speed(this.unladenMass + this.fuelCapacity, this.speed, this.boost, this.standard[1].m, this.pipSpeed);
|
||||
this.topSpeed = speeds['4 Pips'];
|
||||
this.topBoost = speeds.boost;
|
||||
this.topBoost = this.canBoost() ? speeds.boost : 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -855,8 +855,7 @@ export default class Ship {
|
||||
*/
|
||||
useBulkhead(index, preventUpdate) {
|
||||
let oldBulkhead = this.bulkheads.m;
|
||||
this.bulkheads.index = index;
|
||||
this.bulkheads.m = ModuleUtils.bulkheads(this.id, index);
|
||||
this.bulkheads.m = this.availCS.getBulkhead(index);
|
||||
this.bulkheads.discountedCost = this.bulkheads.m.cost * this.moduleCostMultiplier;
|
||||
this.armourMultiplier = ArmourMultiplier[index];
|
||||
this.updateStats(this.bulkheads, this.bulkheads.m, oldBulkhead, preventUpdate);
|
||||
@@ -880,7 +879,7 @@ export default class Ship {
|
||||
|
||||
/**
|
||||
* Use the lightest standard ModuleUtils unless otherwise specified
|
||||
* @param {Object} m Module overrides
|
||||
* @param {Object} m Module override set (standard type => module ID)
|
||||
* @return {this} The ship instance (for chaining operations)
|
||||
*/
|
||||
useLightestStandard(m) {
|
||||
@@ -889,16 +888,18 @@ export default class Ship {
|
||||
let standard = this.standard,
|
||||
// Find lightest Power Distributor that can still boost;
|
||||
pd = m.pd ? ModuleUtils.standard(4, m.pd) : this.availCS.lightestPowerDist(this.boostEnergy),
|
||||
fsd = m.fsd || standard[2].maxClass + 'A',
|
||||
ls = m.ls || standard[3].maxClass + 'D',
|
||||
s = m.s || standard[5].maxClass + 'D',
|
||||
fsd = ModuleUtils.standard(2, m.fsd || standard[2].maxClass + 'A'),
|
||||
ls = ModuleUtils.standard(3, m.ls || standard[3].maxClass + 'D'),
|
||||
s = ModuleUtils.standard(5, m.s || standard[5].maxClass + 'D'),
|
||||
ft = m.ft ? ModuleUtils.standard(6, m.ft) : standard[6].m, // Use existing fuel tank unless specified
|
||||
updated;
|
||||
|
||||
this.useBulkhead(0)
|
||||
.use(standard[2], ModuleUtils.standard(2, fsd)) // FSD
|
||||
.use(standard[3], ModuleUtils.standard(3, ls)) // Life Support
|
||||
.use(standard[5], ModuleUtils.standard(5, s)) // Sensors
|
||||
.use(standard[4], pd); // Power Distributor
|
||||
.use(standard[2], fsd) // FSD
|
||||
.use(standard[3], ls) // Life Support
|
||||
.use(standard[5], s) // Sensors
|
||||
.use(standard[4], pd) // Power Distributor
|
||||
.use(standard[6], ft); // Fuel Tank
|
||||
|
||||
// Thrusters and Powerplant must be determined after all other ModuleUtils are mounted
|
||||
// Loop at least once to determine absolute lightest PD and TH
|
||||
|
||||
126
src/app/shipyard/ShipRoles.js
Normal file
126
src/app/shipyard/ShipRoles.js
Normal file
@@ -0,0 +1,126 @@
|
||||
import * as ModuleUtils from './ModuleUtils';
|
||||
import { canMount } from '../utils/SlotFunctions';
|
||||
|
||||
/**
|
||||
* Standard / typical role for multi-purpose or combat (if shielded with better bulkheads)
|
||||
* @param {Ship} ship Ship instance
|
||||
* @param {Boolean} shielded True if shield generator should be included
|
||||
* @param {integer} bulkheadIndex Bulkhead to use see Constants.BulkheadNames
|
||||
*/
|
||||
export function multiPurpose(ship, shielded, bulkheadIndex) {
|
||||
ship.useStandard('A')
|
||||
.use(ship.standard[3], ModuleUtils.standard(3, ship.standard[3].maxClass + 'D')) // D Life Support
|
||||
.use(ship.standard[5], ModuleUtils.standard(5, ship.standard[5].maxClass + 'D')) // D Sensors
|
||||
.useBulkhead(bulkheadIndex);
|
||||
|
||||
if (shielded) {
|
||||
ship.internal.some(function(slot) {
|
||||
if (canMount(slot, 'sg')) { // Assuming largest slot can hold an eligible shield
|
||||
ship.use(slot, ModuleUtils.findInternal('sg', slot.maxClass, 'A'));
|
||||
ship.setSlotEnabled(slot, true);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Trader Role
|
||||
* @param {Ship} ship Ship instance
|
||||
* @param {Boolean} shielded True if shield generator should be included
|
||||
* @param {Object} standardOpts [Optional] Standard module optional overrides
|
||||
*/
|
||||
export function trader(ship, shielded, standardOpts) {
|
||||
let sg = shielded ? ship.getAvailableModules().lightestShieldGenerator(ship.hullMass) : null;
|
||||
|
||||
for (let i = ship.internal.length; i--;) {
|
||||
let slot = ship.internal[i];
|
||||
if (sg && canMount(slot, 'sg', sg.class)) {
|
||||
ship.use(slot, sg);
|
||||
sg = null;
|
||||
} else {
|
||||
ship.use(slot, ModuleUtils.findInternal('cr', slot.maxClass, 'E'));
|
||||
}
|
||||
}
|
||||
|
||||
ship.useLightestStandard(standardOpts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Explorer Role
|
||||
* @param {Ship} ship Ship instance
|
||||
* @param {Boolean} planetary True if Planetary Vehicle Hangar (PVH) should be included
|
||||
*/
|
||||
export function explorer(ship, planetary) {
|
||||
let standardOpts = { ppRating: 'A' },
|
||||
intLength = ship.internal.length,
|
||||
heatSinkCount = 2, // Fit 2 heat sinks if possible
|
||||
afmUnitCount = 2, // Fit 2 AFM Units if possible
|
||||
shieldNext = planetary,
|
||||
sgSlot,
|
||||
fuelScoopSlot,
|
||||
pvhSlot,
|
||||
sg = ship.getAvailableModules().lightestShieldGenerator(ship.hullMass);
|
||||
|
||||
if (!planetary) { // Non-planetary explorers don't really need to boost
|
||||
standardOpts.pd = '1D';
|
||||
}
|
||||
|
||||
ship.setSlotEnabled(ship.cargoHatch, false)
|
||||
.use(ship.internal[--intLength], ModuleUtils.internal('2f')); // Advanced Discovery Scanner
|
||||
|
||||
if (!planetary || intLength > 3) { // Don't mount a DDS on planetary explorer ships too small for both a PVH and DDS
|
||||
ship.use(ship.internal[--intLength], ModuleUtils.internal('2i')); // Detailed Surface Scanner
|
||||
}
|
||||
|
||||
for (let i = 0; i < intLength; i++) {
|
||||
let slot = ship.internal[i];
|
||||
let nextSlot = (i + 1) < intLength ? ship.internal[i + 1] : null;
|
||||
// Fit best possible Fuel Scoop
|
||||
if (!fuelScoopSlot && canMount(slot, 'fs')) {
|
||||
fuelScoopSlot = slot;
|
||||
ship.use(slot, ModuleUtils.findInternal('fs', slot.maxClass, 'A'));
|
||||
ship.setSlotEnabled(slot, true);
|
||||
// Mount a Shield generator if possible AND an AFM Unit has been mounted already (Guarantees at least 1 AFM Unit)
|
||||
} else if (!sgSlot && shieldNext && canMount(slot, 'sg', sg.class) && !canMount(nextSlot, 'sg', sg.class)) {
|
||||
sgSlot = slot;
|
||||
shieldNext = false;
|
||||
ship.use(slot, sg);
|
||||
ship.setSlotEnabled(slot, true);
|
||||
// if planetary explorer and the next slot cannot mount a PVH or the next modul to mount is a SG
|
||||
} else if (planetary && !pvhSlot && canMount(slot, 'pv') && (shieldNext || !canMount(nextSlot, 'pv', 2))) {
|
||||
pvhSlot = slot;
|
||||
ship.use(slot, ModuleUtils.findInternal('pv', Math.min(Math.floor(pvhSlot.maxClass / 2) * 2, 6), 'G'));
|
||||
ship.setSlotEnabled(slot, false); // Disabled power for PVH
|
||||
shieldNext = !sgSlot;
|
||||
} else if (afmUnitCount > 0 && canMount(slot, 'am')) {
|
||||
afmUnitCount--;
|
||||
ship.use(slot, ModuleUtils.findInternal('am', slot.maxClass, 'A'));
|
||||
ship.setSlotEnabled(slot, false); // Disabled power for AFM Unit
|
||||
shieldNext = !sgSlot;
|
||||
} else {
|
||||
ship.use(slot, null);
|
||||
}
|
||||
}
|
||||
|
||||
for (let s of ship.hardpoints) {
|
||||
if (s.maxClass == 0 && heatSinkCount) { // Mount up to 2 heatsinks
|
||||
ship.use(s, ModuleUtils.hardpoints('02'));
|
||||
ship.setSlotEnabled(s, heatSinkCount == 2); // Only enable a single Heatsink
|
||||
heatSinkCount--;
|
||||
} else {
|
||||
ship.use(s, null);
|
||||
}
|
||||
}
|
||||
|
||||
if (sgSlot) {
|
||||
// The SG and Fuel scoop to not need to be powered at the same time
|
||||
if (sgSlot.m.power > fuelScoopSlot.m.power) { // The Shield generator uses the most power
|
||||
ship.setSlotEnabled(fuelScoopSlot, false);
|
||||
} else { // The Fuel scoop uses the most power
|
||||
ship.setSlotEnabled(sgSlot, false);
|
||||
}
|
||||
}
|
||||
|
||||
ship.useLightestStandard(standardOpts);
|
||||
}
|
||||
@@ -2,6 +2,21 @@ import React from 'react';
|
||||
import cn from 'classnames';
|
||||
import { isShieldGenerator } from '../shipyard/ModuleUtils';
|
||||
import { Infinite } from '../components/SvgIcons';
|
||||
import Persist from '../stores/Persist';
|
||||
|
||||
/**
|
||||
* Determine if a slot can mount a module of a particular class and group
|
||||
* @param {Object} slot Slot object
|
||||
* @param {String} group Module group/type abbrivation/code
|
||||
* @param {Integer} clazz [Optional] Module Class/Size
|
||||
* @return {Boolean} True if the slot can mount the module
|
||||
*/
|
||||
export function canMount(slot, group, clazz) {
|
||||
if (slot && (!slot.eligible || slot.eligible[group]) && (clazz === undefined || slot.maxClass >= clazz)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the translate name for the module mounted in the specified
|
||||
@@ -76,7 +91,9 @@ const PROP_BLACKLIST = {
|
||||
eddbID: 1,
|
||||
edID: 1,
|
||||
id: 1,
|
||||
index: 1,
|
||||
'class': 1,
|
||||
rating: 1,
|
||||
maxfuel: 1,
|
||||
fuelmul: 1,
|
||||
fuelpower: 1,
|
||||
@@ -161,7 +178,7 @@ function diff(format, mVal, mmVal) {
|
||||
return <Infinite/>;
|
||||
} else {
|
||||
let diff = mVal - mmVal;
|
||||
if (!diff || !mVal || diff == mVal || Math.abs(diff) == Infinity) {
|
||||
if (!diff || mVal === undefined || diff == mVal || Math.abs(diff) == Infinity) {
|
||||
return format(mVal);
|
||||
}
|
||||
return `${format(mVal)} (${diff > 0 ? '+' : ''}${format(diff)})`;
|
||||
@@ -190,7 +207,7 @@ export function diffDetails(language, m, mm) {
|
||||
let mAffectsShield = isShieldGenerator(m.grp) || m.grp == 'sb';
|
||||
let mmAffectsShield = isShieldGenerator(mm.grp) || mm.grp == 'sb';
|
||||
|
||||
propDiffs.push(<div key='cost'>{translate('cost')}: <span className={diffClass(m.cost, mm.cost, true) }>{formats.int(m.cost || 0)}{units.CR}</span></div>);
|
||||
propDiffs.push(<div key='cost'>{translate('cost')}: <span className={diffClass(m.cost, mm.cost, true) }>{m.cost ? Math.round(m.cost * (1 - Persist.getModuleDiscount())) : 0}{units.CR}</span></div>);
|
||||
propDiffs.push(<div key='mass'>{translate('mass')}: <span className={diffClass(mMass, mm.mass, true)}>{diff(formats.round, mMass, mmMass)}{units.T}</span></div>);
|
||||
|
||||
for (let p in m) {
|
||||
@@ -218,7 +235,7 @@ export function diffDetails(language, m, mm) {
|
||||
}
|
||||
let sgDiffClass = Math.round((newShield - shield) * 100) / 100 == 0 ? 'muted' : (newShield > shield ? 'secondary' : 'warning');
|
||||
|
||||
propDiffs.push(<div key='shields'>{`${translate('shields')}: `}<span className={sgDiffClass}>{diff(formats.int, newShield, shield)}{units.MJ}</span></div>);
|
||||
propDiffs.push(<div key='shields'>{translate('shields')}: <span className={sgDiffClass}>{diff(formats.int, newShield, shield)}{units.MJ}</span></div>);
|
||||
}
|
||||
|
||||
if (m.grp == 'pd') {
|
||||
@@ -248,10 +265,10 @@ export function diffDetails(language, m, mm) {
|
||||
let ladenRange = this.calcLadenRange(massDiff + capDiff, m.fuel, fsd);
|
||||
|
||||
if (maxRange != this.unladenRange) {
|
||||
propDiffs.push(<div key='maxRange'>{`${translate('max')} ${translate('jump range')}: `}<span className={maxRange > this.unladenRange ? 'secondary' : 'warning'}>{formats.round(maxRange)}{units.LY}</span></div>);
|
||||
propDiffs.push(<div key='maxRange'>{translate('max')} {translate('jump range')}: <span className={maxRange > this.unladenRange ? 'secondary' : 'warning'}>{formats.round(maxRange)}{units.LY}</span></div>);
|
||||
}
|
||||
if (ladenRange != this.ladenRange) {
|
||||
propDiffs.push(<div key='unladenRange'>{`${translate('laden')} ${translate('jump range')}: `}<span className={ladenRange > this.ladenRange ? 'secondary' : 'warning'}>{formats.round(ladenRange)}{units.LY}</span></div>);
|
||||
propDiffs.push(<div key='unladenRange'>{translate('laden')} {translate('jump range')}: <span className={ladenRange > this.ladenRange ? 'secondary' : 'warning'}>{formats.round(ladenRange)}{units.LY}</span></div>);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,12 +25,11 @@
|
||||
</head>
|
||||
<body style="background-color:#000;">
|
||||
<section id="coriolis"></section>
|
||||
<footer>
|
||||
<div class="right cap">
|
||||
<a href="https://github.com/cmmcleod/coriolis/releases/" target="_blank" title="Coriolis Github Project">{%= o.htmlWebpackPlugin.options.version %} - {%= new Date().toISOString().slice(0, 10) %}</a>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
window.CORIOLIS_GAPI_KEY = '{%= o.htmlWebpackPlugin.options.gapiKey %}';
|
||||
window.CORIOLIS_VERSION = '{%= o.htmlWebpackPlugin.options.version %}';
|
||||
window.CORIOLIS_DATE = '{%= new Date().toISOString().slice(0, 10) %}';
|
||||
</script>
|
||||
<script src="{%= o.htmlWebpackPlugin.files.chunks.lib.entry %}" charset="utf-8" crossorigin="anonymous"></script>
|
||||
<script src="{%= o.htmlWebpackPlugin.files.chunks.app.entry %}" charset="utf-8" crossorigin="anonymous"></script>
|
||||
<script>
|
||||
@@ -41,7 +40,6 @@
|
||||
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
||||
ga('create', '{%= o.htmlWebpackPlugin.options.uaTracking %}', 'auto');
|
||||
{% } %}
|
||||
window.CORIOLIS_GAPI_KEY = '{%= o.htmlWebpackPlugin.options.gapiKey %}';
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -23,9 +23,7 @@ html, body {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
text-rendering: optimizeLegibility;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
body {
|
||||
@@ -42,17 +40,23 @@ div, a, li {
|
||||
|
||||
#coriolis {
|
||||
width: 100%;
|
||||
min-height: 95%;
|
||||
height: 100%;
|
||||
overflow-y: scroll;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
.page {
|
||||
margin: 0;
|
||||
padding: 0.5em 0;
|
||||
padding: 0.5em;
|
||||
width: 100%;
|
||||
min-height: 100%;
|
||||
clear: both;
|
||||
text-align: center;
|
||||
box-sizing: border-box;
|
||||
|
||||
.largePhone({
|
||||
padding: 0.5em 0.25em;
|
||||
});
|
||||
}
|
||||
|
||||
.l {
|
||||
|
||||
@@ -97,6 +97,7 @@ header {
|
||||
|
||||
input {
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
text-align: right;
|
||||
font-size: 1em;
|
||||
font-family: @fStandard;
|
||||
@@ -171,7 +172,7 @@ header {
|
||||
&:visited {
|
||||
color: @warning;
|
||||
}
|
||||
&:hover {
|
||||
.no-touch &:hover {
|
||||
color: teal;
|
||||
}
|
||||
&.active {
|
||||
|
||||
@@ -78,7 +78,7 @@ select {
|
||||
stroke-width: 0.5em;
|
||||
stroke: @primary-disabled;
|
||||
|
||||
&:hover {
|
||||
.no-touch &:hover {
|
||||
border-color: @primary;
|
||||
color: @primary;
|
||||
stroke: @primary;
|
||||
@@ -95,14 +95,14 @@ select {
|
||||
color: @warning-disabled;
|
||||
stroke: @warning-disabled;
|
||||
|
||||
&:hover {
|
||||
.no-touch &:hover {
|
||||
border-color: @warning;
|
||||
color: @warning;
|
||||
stroke: @warning;
|
||||
}
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
&.disabled, &.disabled:hover {
|
||||
cursor: not-allowed;
|
||||
border-color: @disabled;
|
||||
color: @disabled;
|
||||
@@ -150,4 +150,10 @@ select {
|
||||
}
|
||||
}
|
||||
|
||||
&.standard {
|
||||
ul {
|
||||
width: 16.25em;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
.user-select-none();
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
.no-touch &:hover {
|
||||
color: @primary;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,10 @@ thead {
|
||||
&.lft {
|
||||
border-left: 1px solid @primary-bg;
|
||||
}
|
||||
|
||||
&.rgt {
|
||||
border-right: 1px solid @primary-bg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,23 +47,26 @@ tbody tr {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
td {
|
||||
line-height: 1.4em;
|
||||
padding: 0 0.3em;
|
||||
|
||||
&.val {
|
||||
border: 1px solid @primary-disabled;
|
||||
}
|
||||
&.lbl {
|
||||
border: 1px solid @primary-disabled;
|
||||
text-transform: uppercase;
|
||||
color: @primary-bg;
|
||||
background-color: @primary-disabled;
|
||||
}
|
||||
.no-touch &.highlight:hover, .no-touch &.highlighted {
|
||||
background-color: @warning-bg;
|
||||
}
|
||||
}
|
||||
|
||||
td {
|
||||
line-height: 1.4em;
|
||||
padding: 0 0.3em;
|
||||
|
||||
&.val {
|
||||
border: 1px solid @primary-disabled;
|
||||
}
|
||||
|
||||
&.lbl {
|
||||
border: 1px solid @primary-disabled;
|
||||
text-transform: uppercase;
|
||||
color: @primary-bg;
|
||||
background-color: @primary-disabled;
|
||||
}
|
||||
|
||||
&.tl {
|
||||
text-align: left;
|
||||
padding-left: 0.7em;
|
||||
|
||||
79
src/migrate.html
Normal file
79
src/migrate.html
Normal file
@@ -0,0 +1,79 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Coriolis: Migrate to HTTPS</title>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
|
||||
function fromJsonToObject(str) {
|
||||
try {
|
||||
var o = JSON.parse(str);
|
||||
if (o instanceof Object && !(o instanceof Array)) {
|
||||
return o;
|
||||
}
|
||||
} catch (e) { }
|
||||
return {};
|
||||
}
|
||||
|
||||
function listener(event) {
|
||||
var origin = event.origin || event.originalEvent.origin;
|
||||
var source = event.source;
|
||||
var data = event.message;
|
||||
|
||||
if (window.location.href.indexOf('coriolis') != -1 && origin !== "http://coriolis.io") {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
var builds = fromJsonToObject(localStorage.getItem('builds'));
|
||||
var comparisons = fromJsonToObject(localStorage.getItem('comparisons'));
|
||||
|
||||
// merge builds
|
||||
if (typeof data.builds == 'object') {
|
||||
|
||||
for (var bName in data.builds) {
|
||||
// Build existing in http and does not existing in HTTPS
|
||||
if (data.builds.hasOwnProperty(bName) && !builds[bName]) {
|
||||
build[bName] = data.builds[bName];
|
||||
}
|
||||
}
|
||||
|
||||
localStorage.setItem('builds', JSON.stringify(builds));
|
||||
}
|
||||
// merge comparisons
|
||||
if (typeof data.comparisons == 'object') {
|
||||
|
||||
for (var comp in data.comparisons) {
|
||||
// Comparison existing in http and does not existing in HTTPS
|
||||
if (data.comparisons.hasOwnProperty(comp) && !data.comparisons[comp]) {
|
||||
comparisons[comp] = data.comparisons[comp];
|
||||
}
|
||||
}
|
||||
localStorage.setItem('comparisons', JSON.stringify(comparisons));
|
||||
}
|
||||
|
||||
source.postMessage({
|
||||
success: true,
|
||||
buildCount: Object.keys(builds).length,
|
||||
comparisonCount: Object.keys(comparisons).length
|
||||
}, origin);
|
||||
|
||||
} catch (e) {
|
||||
source.postMessage({ success: false, error: e }, origin);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (window.addEventListener){
|
||||
window.addEventListener("message", listener, false);
|
||||
} else {
|
||||
window.attachEvent("onmessage", listener);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
@@ -74,6 +74,7 @@ module.exports = {
|
||||
}),
|
||||
new CopyDirPlugin(path.join(__dirname, 'src/schemas'), 'schemas'),
|
||||
new CopyDirPlugin(path.join(__dirname, 'src/images/logo/*'), ''),
|
||||
new CopyDirPlugin(path.join(__dirname, 'src/migrate.html'), ''),
|
||||
new AppCachePlugin({
|
||||
network: ['*'],
|
||||
settings: ['prefer-online'],
|
||||
|
||||
Reference in New Issue
Block a user