mirror of
https://github.com/EDCD/coriolis.git
synced 2025-12-09 14:45:35 +00:00
Merge branch 'develop'
This commit is contained in:
245
package-lock.json
generated
245
package-lock.json
generated
@@ -2455,6 +2455,12 @@
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz",
|
||||
"integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ=="
|
||||
},
|
||||
"common-tags": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.0.tgz",
|
||||
"integrity": "sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==",
|
||||
"dev": true
|
||||
},
|
||||
"commondir": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
|
||||
@@ -6984,6 +6990,12 @@
|
||||
"minimalistic-crypto-utils": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"hoek": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz",
|
||||
"integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==",
|
||||
"dev": true
|
||||
},
|
||||
"home-or-tmp": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz",
|
||||
@@ -7830,6 +7842,23 @@
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
|
||||
},
|
||||
"isemail": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/isemail/-/isemail-3.1.3.tgz",
|
||||
"integrity": "sha512-5xbsG5wYADIcB+mfLsd+nst1V/D+I7EU7LEZPo2GOIMu4JzfcRs5yQoypP4avA7QtUqgxYLKBYNv4IdzBmbhdw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"punycode": "2.x.x"
|
||||
},
|
||||
"dependencies": {
|
||||
"punycode": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
|
||||
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
@@ -8952,6 +8981,17 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"joi": {
|
||||
"version": "11.4.0",
|
||||
"resolved": "https://registry.npmjs.org/joi/-/joi-11.4.0.tgz",
|
||||
"integrity": "sha512-O7Uw+w/zEWgbL6OcHbyACKSj0PkQeUgmehdoXVSxt92QFCq4+1390Rwh5moI2K/OgC7D8RHRZqHZxT2husMJHA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"hoek": "4.x.x",
|
||||
"isemail": "3.x.x",
|
||||
"topo": "2.x.x"
|
||||
}
|
||||
},
|
||||
"js-base64": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.3.2.tgz",
|
||||
@@ -9469,6 +9509,12 @@
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz",
|
||||
"integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg=="
|
||||
},
|
||||
"lodash._reinterpolate": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz",
|
||||
"integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=",
|
||||
"dev": true
|
||||
},
|
||||
"lodash.assignin": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.assignin/-/lodash.assignin-4.2.0.tgz",
|
||||
@@ -9553,6 +9599,25 @@
|
||||
"integrity": "sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=",
|
||||
"dev": true
|
||||
},
|
||||
"lodash.template": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.4.0.tgz",
|
||||
"integrity": "sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lodash._reinterpolate": "~3.0.0",
|
||||
"lodash.templatesettings": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"lodash.templatesettings": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz",
|
||||
"integrity": "sha1-K01OlbpEDZFf8IvImeRVNmZxMxY=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lodash._reinterpolate": "~3.0.0"
|
||||
}
|
||||
},
|
||||
"lodash.uniq": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
|
||||
@@ -11104,6 +11169,12 @@
|
||||
"integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=",
|
||||
"dev": true
|
||||
},
|
||||
"pretty-bytes": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-4.0.2.tgz",
|
||||
"integrity": "sha1-sr+C5zUNZcbDOqlaqlpPYyf2HNk=",
|
||||
"dev": true
|
||||
},
|
||||
"pretty-error": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.1.tgz",
|
||||
@@ -12728,6 +12799,15 @@
|
||||
"integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=",
|
||||
"dev": true
|
||||
},
|
||||
"topo": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/topo/-/topo-2.0.2.tgz",
|
||||
"integrity": "sha1-zVYVdSU5BXwNwEkaYhw7xvvh0YI=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"hoek": "4.x.x"
|
||||
}
|
||||
},
|
||||
"toposort": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/toposort/-/toposort-1.0.6.tgz",
|
||||
@@ -13403,6 +13483,171 @@
|
||||
"integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
|
||||
"dev": true
|
||||
},
|
||||
"workbox-background-sync": {
|
||||
"version": "3.4.1",
|
||||
"resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-3.4.1.tgz",
|
||||
"integrity": "sha512-Ksb2nCg/2wOyBMhSBqSbtCEwuKaf5sHgTY8HdCxbLIQSzDh9/qZqg+1P11CKlgJmHtje3EK3B8EsrzukZo10xA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"workbox-core": "^3.4.1"
|
||||
}
|
||||
},
|
||||
"workbox-broadcast-cache-update": {
|
||||
"version": "3.4.1",
|
||||
"resolved": "https://registry.npmjs.org/workbox-broadcast-cache-update/-/workbox-broadcast-cache-update-3.4.1.tgz",
|
||||
"integrity": "sha512-+WPqHFk4ER4RICAMOYrP88yBbiUQ9ZOFNruqwbl9YxGfbADV16OEGmYpIs+Az6HT6DNDCx8eQqtFiaG8N3O11Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"workbox-core": "^3.4.1"
|
||||
}
|
||||
},
|
||||
"workbox-build": {
|
||||
"version": "3.4.1",
|
||||
"resolved": "https://registry.npmjs.org/workbox-build/-/workbox-build-3.4.1.tgz",
|
||||
"integrity": "sha512-Qi04XdHjkXbRN0CV5XO1oqDWbJSIm7VYhxmxjtnVcKK8PrMT6rOUFUi9ziDI+8UQgcXbLK4ZChWf2ptZS1/MbA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"babel-runtime": "^6.26.0",
|
||||
"common-tags": "^1.4.0",
|
||||
"fs-extra": "^4.0.2",
|
||||
"glob": "^7.1.2",
|
||||
"joi": "^11.1.1",
|
||||
"lodash.template": "^4.4.0",
|
||||
"pretty-bytes": "^4.0.2",
|
||||
"workbox-background-sync": "^3.4.1",
|
||||
"workbox-broadcast-cache-update": "^3.4.1",
|
||||
"workbox-cache-expiration": "^3.4.1",
|
||||
"workbox-cacheable-response": "^3.4.1",
|
||||
"workbox-core": "^3.4.1",
|
||||
"workbox-google-analytics": "^3.4.1",
|
||||
"workbox-navigation-preload": "^3.4.1",
|
||||
"workbox-precaching": "^3.4.1",
|
||||
"workbox-range-requests": "^3.4.1",
|
||||
"workbox-routing": "^3.4.1",
|
||||
"workbox-strategies": "^3.4.1",
|
||||
"workbox-streams": "^3.4.1",
|
||||
"workbox-sw": "^3.4.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"fs-extra": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz",
|
||||
"integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.2",
|
||||
"jsonfile": "^4.0.0",
|
||||
"universalify": "^0.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"workbox-cache-expiration": {
|
||||
"version": "3.4.1",
|
||||
"resolved": "https://registry.npmjs.org/workbox-cache-expiration/-/workbox-cache-expiration-3.4.1.tgz",
|
||||
"integrity": "sha512-AzOPB+dwfxg13v4+q5jWkxsw/oim9mPIzew1anu8ALA3vB8qySaJJToXp+ZlVh/Co+sDK0tgjlB76bvSFHgZ4g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"workbox-core": "^3.4.1"
|
||||
}
|
||||
},
|
||||
"workbox-cacheable-response": {
|
||||
"version": "3.4.1",
|
||||
"resolved": "https://registry.npmjs.org/workbox-cacheable-response/-/workbox-cacheable-response-3.4.1.tgz",
|
||||
"integrity": "sha512-SO2k830JT93GitPwc5tzJI49d9VwyVxXwiCbyvo+Sqo+dcvWSrmpsyuXdzy6zuasbPrWUF0vsFj1uGtZbOym8Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"workbox-core": "^3.4.1"
|
||||
}
|
||||
},
|
||||
"workbox-core": {
|
||||
"version": "3.4.1",
|
||||
"resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-3.4.1.tgz",
|
||||
"integrity": "sha512-RqMV2so9/KLAu9aUxJ/85pvrZMUn835B8zoHmqRyGNetiDr8B1zSBeKXPZAjFlX/88KdhizNwiRlJtqlXtM4tA==",
|
||||
"dev": true
|
||||
},
|
||||
"workbox-google-analytics": {
|
||||
"version": "3.4.1",
|
||||
"resolved": "https://registry.npmjs.org/workbox-google-analytics/-/workbox-google-analytics-3.4.1.tgz",
|
||||
"integrity": "sha512-w6Osz2Rr1/4+W0gram6Yzg6NNWLvHP51RwFCNAZSpEnipr0qSEtD+yvwrdaHfiJHWhcK2yH/V6E1MV8Hrczmvw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"workbox-background-sync": "^3.4.1",
|
||||
"workbox-core": "^3.4.1",
|
||||
"workbox-routing": "^3.4.1",
|
||||
"workbox-strategies": "^3.4.1"
|
||||
}
|
||||
},
|
||||
"workbox-navigation-preload": {
|
||||
"version": "3.4.1",
|
||||
"resolved": "https://registry.npmjs.org/workbox-navigation-preload/-/workbox-navigation-preload-3.4.1.tgz",
|
||||
"integrity": "sha512-P3FHAcyZ8db2QiW/BpMkuosC1OkRsEoUaT7U3QOgg7JSjjsJoEbF7G5olNe+P+PQYdVhJA7TCuptI6dy2gLS/g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"workbox-core": "^3.4.1"
|
||||
}
|
||||
},
|
||||
"workbox-precaching": {
|
||||
"version": "3.4.1",
|
||||
"resolved": "https://registry.npmjs.org/workbox-precaching/-/workbox-precaching-3.4.1.tgz",
|
||||
"integrity": "sha512-ykU2mly9xmRrCW6iMeUWYydWiso/WSE16+7wponhI0WC53jiQSt2JvykWm0VpWFJSs6ZTSZZ1WK2gs/brRnPug==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"workbox-core": "^3.4.1"
|
||||
}
|
||||
},
|
||||
"workbox-range-requests": {
|
||||
"version": "3.4.1",
|
||||
"resolved": "https://registry.npmjs.org/workbox-range-requests/-/workbox-range-requests-3.4.1.tgz",
|
||||
"integrity": "sha512-ktgjl6liZrRTmQjPw1pBblC5umHnTb8XcvFVitdGz17B23jj6cUV4EXzEU2ilGn6jO6+MLV1Vn9SWajtLSc2Gg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"workbox-core": "^3.4.1"
|
||||
}
|
||||
},
|
||||
"workbox-routing": {
|
||||
"version": "3.4.1",
|
||||
"resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-3.4.1.tgz",
|
||||
"integrity": "sha512-6j6cXMUYfMPYTycmElxVOfBTr6WV5zAn/JUFJ7GJ5pYFIE9cqztprnrcOsWJ42+AiNIeHPbKfyIWE/rZVviMxQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"workbox-core": "^3.4.1"
|
||||
}
|
||||
},
|
||||
"workbox-strategies": {
|
||||
"version": "3.4.1",
|
||||
"resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-3.4.1.tgz",
|
||||
"integrity": "sha512-7mJuzFsgejflzjfnChXCFma1S0mi9WC6wlSU2wE50M7bJmEuf9A3j3MojpKcsTEM58hbhbnU6QF/u9iIV7+opw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"workbox-core": "^3.4.1"
|
||||
}
|
||||
},
|
||||
"workbox-streams": {
|
||||
"version": "3.4.1",
|
||||
"resolved": "https://registry.npmjs.org/workbox-streams/-/workbox-streams-3.4.1.tgz",
|
||||
"integrity": "sha512-krw+5bp+oe9Za5c6WlTWM3SgZGfExYcqRSn1gsyYgKeXmgzTwf+DOb5Lwult0KSWlJfq8B3Wk7sW8Sl7lRzSbA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"workbox-core": "^3.4.1"
|
||||
}
|
||||
},
|
||||
"workbox-sw": {
|
||||
"version": "3.4.1",
|
||||
"resolved": "https://registry.npmjs.org/workbox-sw/-/workbox-sw-3.4.1.tgz",
|
||||
"integrity": "sha512-nnm2by5oaQGXRH7x4M5/n2KqjUGVmP4P8azUmJITnYa3DWVYn/ghDg3LJ5+h4A28vYq9V6ePgATaEPfb6B5pug==",
|
||||
"dev": true
|
||||
},
|
||||
"workbox-webpack-plugin": {
|
||||
"version": "3.4.1",
|
||||
"resolved": "https://registry.npmjs.org/workbox-webpack-plugin/-/workbox-webpack-plugin-3.4.1.tgz",
|
||||
"integrity": "sha512-dwIaEJK27xbGKMQv1sbSjywxhfX74nMW1zgUP9XUtpFeykH0e5Dm1j7wbQezXU3mFoaO7xuzqwGpAFxMKc0xMA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"json-stable-stringify": "^1.0.1",
|
||||
"workbox-build": "^3.4.1"
|
||||
}
|
||||
},
|
||||
"worker-farm": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.5.1.tgz",
|
||||
|
||||
19
package.json
19
package.json
@@ -65,9 +65,16 @@
|
||||
"babel-preset-react": "*",
|
||||
"babel-preset-stage-0": "*",
|
||||
"create-react-class": "^15.6.2",
|
||||
"css-loader": "^0.28.0",
|
||||
"cross-env": "^5.1.4",
|
||||
"css-loader": "^0.28.0",
|
||||
"d3-selection": "1",
|
||||
"esdoc": "^1.1.0",
|
||||
"esdoc-custom-theme": "^1.4.2",
|
||||
"esdoc-ecmascript-proposal-plugin": "^1.0.0",
|
||||
"esdoc-jsx-plugin": "^1.0.0",
|
||||
"esdoc-publish-html-plugin": "^1.1.2",
|
||||
"esdoc-react-plugin": "^1.0.1",
|
||||
"esdoc-standard-plugin": "^1.0.0",
|
||||
"eslint": "3.19.0",
|
||||
"eslint-plugin-react": "^6.10.3",
|
||||
"expose-loader": "^0.7.3",
|
||||
@@ -91,16 +98,10 @@
|
||||
"uglify-js": "^2.4.11",
|
||||
"url-loader": "^0.5.8",
|
||||
"webpack": "^2.4.1",
|
||||
"webpack-bugsnag-plugins": "^1.1.1",
|
||||
"webpack-dev-server": "^2.4.4",
|
||||
"webpack-notifier": "^1.6.0",
|
||||
"webpack-bugsnag-plugins": "^1.1.1",
|
||||
"esdoc": "^1.1.0",
|
||||
"esdoc-ecmascript-proposal-plugin": "^1.0.0",
|
||||
"esdoc-jsx-plugin": "^1.0.0",
|
||||
"esdoc-react-plugin": "^1.0.1",
|
||||
"esdoc-standard-plugin": "^1.0.0",
|
||||
"esdoc-publish-html-plugin": "^1.1.2",
|
||||
"esdoc-custom-theme": "^1.4.2"
|
||||
"workbox-webpack-plugin": "^3.4.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"babel-polyfill": "*",
|
||||
|
||||
@@ -322,14 +322,48 @@ export default class Coriolis extends React.Component {
|
||||
*/
|
||||
componentWillMount() {
|
||||
// Listen for appcache updated event, present refresh to update view
|
||||
if (window.applicationCache) {
|
||||
window.applicationCache.addEventListener('updateready', () => {
|
||||
if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {
|
||||
this.setState({ appCacheUpdate: true }); // Browser downloaded a new app cache.
|
||||
}
|
||||
// Check that service workers are registered
|
||||
if ('serviceWorker' in navigator) {
|
||||
// Your service-worker.js *must* be located at the top-level directory relative to your site.
|
||||
// It won't be able to control pages unless it's located at the same level or higher than them.
|
||||
// *Don't* register service worker file in, e.g., a scripts/ sub-directory!
|
||||
// See https://github.com/slightlyoff/ServiceWorker/issues/468
|
||||
const self = this;
|
||||
navigator.serviceWorker.register('/service-worker.js').then(function(reg) {
|
||||
// updatefound is fired if service-worker.js changes.
|
||||
reg.onupdatefound = function() {
|
||||
// The updatefound event implies that reg.installing is set; see
|
||||
// https://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html#service-worker-container-updatefound-event
|
||||
var installingWorker = reg.installing;
|
||||
|
||||
installingWorker.onstatechange = function() {
|
||||
switch (installingWorker.state) {
|
||||
case 'installed':
|
||||
if (navigator.serviceWorker.controller) {
|
||||
// At this point, the old content will have been purged and the fresh content will
|
||||
// have been added to the cache.
|
||||
// It's the perfect time to display a "New content is available; please refresh."
|
||||
// message in the page's interface.
|
||||
console.log('New or updated content is available.');
|
||||
self.setState({ appCacheUpdate: true }); // Browser downloaded a new app cache.
|
||||
} else {
|
||||
// At this point, everything has been precached.
|
||||
// It's the perfect time to display a "Content is cached for offline use." message.
|
||||
console.log('Content is now available offline!');
|
||||
self.setState({ appCacheUpdate: true }); // Browser downloaded a new app cache.
|
||||
}
|
||||
break;
|
||||
|
||||
case 'redundant':
|
||||
console.error('The installing service worker became redundant.');
|
||||
break;
|
||||
}
|
||||
};
|
||||
};
|
||||
}).catch(function(e) {
|
||||
console.error('Error during service worker registration:', e);
|
||||
});
|
||||
}
|
||||
|
||||
window.onerror = this._onError.bind(this);
|
||||
window.addEventListener('resize', () => this.emitter.emit('windowResize'));
|
||||
document.getElementById('coriolis').addEventListener('scroll', () => this._tooltip());
|
||||
|
||||
@@ -45,7 +45,12 @@ const GRPCAT = {
|
||||
'mr': 'ordnance',
|
||||
'axmr': 'experimental',
|
||||
'rcpl': 'experimental',
|
||||
'dtl': 'experimental',
|
||||
'tbsc': 'experimental',
|
||||
'tbem': 'experimental',
|
||||
'tbrfl': 'experimental',
|
||||
'mahr': 'experimental',
|
||||
'rsl': 'experimental',
|
||||
'tp': 'ordnance',
|
||||
'nl': 'ordnance',
|
||||
'sc': 'scanners',
|
||||
@@ -93,7 +98,7 @@ const CATEGORIES = {
|
||||
'defence': ['ch', 'po', 'ec'],
|
||||
'scanners': ['sc', 'ss', 'cs', 'kw', 'ws'], // Overloaded with internal scanners
|
||||
// Experimental
|
||||
'experimental': ['axmc', 'axmr', 'rfl', 'xs', 'sfn', 'rcpl', 'tbsc'],
|
||||
'experimental': ['axmc', 'axmr', 'rfl', 'tbrfl', 'tbsc', 'tbem', 'xs', 'sfn', 'rcpl', 'dtl', 'rsl', 'mahr', ],
|
||||
|
||||
// Guardian
|
||||
'guardian': ['gpp', 'gpd', 'gpc', 'ggc', 'gsrp', 'gfsb', 'ghrp', 'gmrp', 'gsc']
|
||||
@@ -473,7 +478,7 @@ export default class AvailableModulesMenu extends TranslatedComponent {
|
||||
}
|
||||
/**
|
||||
* Handle focus if the component updates
|
||||
*
|
||||
*
|
||||
*/
|
||||
componentWillUnmount() {
|
||||
if(this.props.slotDiv) {
|
||||
|
||||
@@ -102,19 +102,19 @@ export default class Defence extends TranslatedComponent {
|
||||
|
||||
// Add effective shield from resistances
|
||||
const rawMj = shield.generator + shield.boosters + shield.cells;
|
||||
const explosiveMj = rawMj / shield.explosive.total - rawMj;
|
||||
const explosiveMj = rawMj / (shield.explosive.base) - rawMj;
|
||||
if (explosiveMj != 0) effectiveShieldExplosiveTt.push(<div key='resistance'>{translate('resistance') + ' ' + formats.int(explosiveMj)}{units.MJ}</div>);
|
||||
const kineticMj = rawMj / shield.kinetic.total - rawMj;
|
||||
const kineticMj = rawMj / (shield.kinetic.base) - rawMj;
|
||||
if (kineticMj != 0) effectiveShieldKineticTt.push(<div key='resistance'>{translate('resistance') + ' ' + formats.int(kineticMj)}{units.MJ}</div>);
|
||||
const thermalMj = rawMj / shield.thermal.total - rawMj;
|
||||
const thermalMj = rawMj / (shield.thermal.base) - rawMj;
|
||||
if (thermalMj != 0) effectiveShieldThermalTt.push(<div key='resistance'>{translate('resistance') + ' ' + formats.int(thermalMj)}{units.MJ}</div>);
|
||||
|
||||
// Add effective shield from power distributor SYS pips
|
||||
if (shield.absolute.sys != 1) {
|
||||
effectiveShieldAbsoluteTt.push(<div key='power distributor'>{translate('power distributor') + ' ' + formats.int(rawMj / shield.absolute.sys - rawMj)}{units.MJ}</div>);
|
||||
effectiveShieldExplosiveTt.push(<div key='power distributor'>{translate('power distributor') + ' ' + formats.int(rawMj / shield.explosive.sys - rawMj)}{units.MJ}</div>);
|
||||
effectiveShieldKineticTt.push(<div key='power distributor'>{translate('power distributor') + ' ' + formats.int(rawMj / shield.kinetic.sys - rawMj)}{units.MJ}</div>);
|
||||
effectiveShieldThermalTt.push(<div key='power distributor'>{translate('power distributor') + ' ' + formats.int(rawMj / shield.thermal.sys - rawMj)}{units.MJ}</div>);
|
||||
effectiveShieldAbsoluteTt.push(<div key='power distributor'>{translate('power distributor') + ' ' + formats.int(rawMj / shield.absolute.total - rawMj)}{units.MJ}</div>);
|
||||
effectiveShieldExplosiveTt.push(<div key='power distributor'>{translate('power distributor') + ' ' + formats.int(rawMj / shield.explosive.total - rawMj / shield.explosive.base)}{units.MJ}</div>);
|
||||
effectiveShieldKineticTt.push(<div key='power distributor'>{translate('power distributor') + ' ' + formats.int(rawMj / shield.kinetic.total - rawMj / shield.kinetic.base)}{units.MJ}</div>);
|
||||
effectiveShieldThermalTt.push(<div key='power distributor'>{translate('power distributor') + ' ' + formats.int(rawMj / shield.thermal.total - rawMj / shield.thermal.base)}{units.MJ}</div>);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -237,6 +237,10 @@ export default class Header extends TranslatedComponent {
|
||||
/>);
|
||||
};
|
||||
|
||||
/**
|
||||
* Uploads all ship-builds to orbis
|
||||
* @param {e} e Event
|
||||
*/
|
||||
_uploadAllBuildsToOrbis(e) {
|
||||
e.preventDefault();
|
||||
const data = Persist.getBuilds();
|
||||
|
||||
@@ -30,6 +30,7 @@ export default class ModalBatchOrbis extends TranslatedComponent {
|
||||
/**
|
||||
* Send ship to Orbis.zone
|
||||
* @param {SyntheticEvent} e React Event
|
||||
* @return {Promise} Promise sending post request to orbis
|
||||
*/
|
||||
sendToOrbis(e) {
|
||||
let agent;
|
||||
|
||||
@@ -42,6 +42,63 @@ export function weaponComparator(translate, propComparator, desc) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a tooltip that shows damage by type.
|
||||
* @param {function} translate Translation function
|
||||
* @param {Object} formats Object that holds format functions
|
||||
* @param {Calc.SDps} sdpsObject Object that holds sdps split up by type
|
||||
* @returns {Array} Tooltip
|
||||
*/
|
||||
function getSDpsTooltip(translate, formats, sdpsObject) {
|
||||
return Object.keys(sdpsObject).filter(key => sdpsObject[key])
|
||||
.map(key => {
|
||||
return (
|
||||
<div key={key}>
|
||||
{translate(key) + ' ' + formats.f1(sdpsObject[key])}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a data object used by {@link PieChart} that shows damage by type.
|
||||
* @param {function} translate Translation function
|
||||
* @param {Calc.SDps} sdpsObject Object that holds sdps split up by type
|
||||
* @returns {Object} Data object
|
||||
*/
|
||||
function getSDpsData(translate, sdpsObject) {
|
||||
return Object.keys(sdpsObject).map(key => {
|
||||
return {
|
||||
value: Math.round(sdpsObject[key]),
|
||||
label: translate(key)
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds all damage of `add` onto `addOn`.
|
||||
* @param {Calc.SDps} addOn Object that holds sdps split up by type (will be mutated)
|
||||
* @param {Calc.SDps} add Object that holds sdps split up by type
|
||||
*/
|
||||
function addSDps(addOn, add) {
|
||||
Object.keys(addOn).map(k => addOn[k] += (add[k] ? add[k] : 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the overall sdps of an sdps object.
|
||||
* @param {Calc.SDps} sdpsObject Object that holds sdps spluit up by type
|
||||
*/
|
||||
function sumSDps(sdpsObject) {
|
||||
if (sdpsObject.total) {
|
||||
return sdpsObject.total;
|
||||
}
|
||||
|
||||
return Object.keys(sdpsObject).reduce(
|
||||
(acc, k) => acc + (sdpsObject[k] ? sdpsObject[k] : 0),
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Offence information
|
||||
* Offence information consists of four panels:
|
||||
@@ -70,7 +127,7 @@ export default class Offence extends TranslatedComponent {
|
||||
this._sort = this._sort.bind(this);
|
||||
|
||||
const damage = Calc.offenceMetrics(props.ship, props.opponent, props.wep, props.opponentSys, props.engagementrange);
|
||||
this.state = {
|
||||
this.state = {
|
||||
predicate: 'n',
|
||||
desc: true,
|
||||
damage
|
||||
@@ -144,51 +201,36 @@ export default class Offence extends TranslatedComponent {
|
||||
|
||||
const timeToDrain = Calc.timeToDrainWep(ship, wep);
|
||||
|
||||
let absoluteShieldsSDps = 0;
|
||||
let explosiveShieldsSDps = 0;
|
||||
let kineticShieldsSDps = 0;
|
||||
let thermalShieldsSDps = 0;
|
||||
let absoluteArmourSDps = 0;
|
||||
let explosiveArmourSDps = 0;
|
||||
let kineticArmourSDps = 0;
|
||||
let thermalArmourSDps = 0;
|
||||
|
||||
let totalSEps = 0;
|
||||
let totalSDpsObject = {'absolute': 0, 'explosive': 0, 'kinetic': 0, 'thermal': 0};
|
||||
let shieldsSDpsObject = {'absolute': 0, 'explosive': 0, 'kinetic': 0, 'thermal': 0};
|
||||
let armourSDpsObject = {'absolute': 0, 'explosive': 0, 'kinetic': 0, 'thermal': 0};
|
||||
|
||||
const rows = [];
|
||||
for (let i = 0; i < damage.length; i++) {
|
||||
const weapon = damage[i];
|
||||
|
||||
totalSEps += weapon.seps;
|
||||
absoluteShieldsSDps += weapon.sdps.shields.absolute;
|
||||
explosiveShieldsSDps += weapon.sdps.shields.explosive;
|
||||
kineticShieldsSDps += weapon.sdps.shields.kinetic;
|
||||
thermalShieldsSDps += weapon.sdps.shields.thermal;
|
||||
absoluteArmourSDps += weapon.sdps.armour.absolute;
|
||||
explosiveArmourSDps += weapon.sdps.armour.explosive;
|
||||
kineticArmourSDps += weapon.sdps.armour.kinetic;
|
||||
thermalArmourSDps += weapon.sdps.armour.thermal;
|
||||
addSDps(totalSDpsObject, weapon.sdps.base);
|
||||
addSDps(shieldsSDpsObject, weapon.sdps.shields);
|
||||
addSDps(armourSDpsObject, weapon.sdps.armour);
|
||||
|
||||
const baseSDpsTooltipDetails = getSDpsTooltip(translate, formats, weapon.sdps.base);
|
||||
|
||||
const effectivenessShieldsTooltipDetails = [];
|
||||
effectivenessShieldsTooltipDetails.push(<div key='range'>{translate('range') + ' ' + formats.pct1(weapon.effectiveness.shields.range)}</div>);
|
||||
effectivenessShieldsTooltipDetails.push(<div key='resistance'>{translate('resistance') + ' ' + formats.pct1(weapon.effectiveness.shields.resistance)}</div>);
|
||||
effectivenessShieldsTooltipDetails.push(<div key='power distributor'>{translate('power distributor') + ' ' + formats.pct1(weapon.effectiveness.shields.sys)}</div>);
|
||||
|
||||
const effectiveShieldsSDpsTooltipDetails = [];
|
||||
if (weapon.sdps.shields.absolute) effectiveShieldsSDpsTooltipDetails.push(<div key='absolute'>{translate('absolute') + ' ' + formats.f1(weapon.sdps.shields.absolute)}</div>);
|
||||
if (weapon.sdps.shields.explosive) effectiveShieldsSDpsTooltipDetails.push(<div key='explosive'>{translate('explosive') + ' ' + formats.f1(weapon.sdps.shields.explosive)}</div>);
|
||||
if (weapon.sdps.shields.kinetic) effectiveShieldsSDpsTooltipDetails.push(<div key='kinetic'>{translate('kinetic') + ' ' + formats.f1(weapon.sdps.shields.kinetic)}</div>);
|
||||
if (weapon.sdps.shields.thermal) effectiveShieldsSDpsTooltipDetails.push(<div key='thermal'>{translate('thermal') + ' ' + formats.f1(weapon.sdps.shields.thermal)}</div>);
|
||||
const effectiveShieldsSDpsTooltipDetails = getSDpsTooltip(translate, formats, weapon.sdps.armour);
|
||||
|
||||
const effectivenessArmourTooltipDetails = [];
|
||||
effectivenessArmourTooltipDetails.push(<div key='range'>{translate('range') + ' ' + formats.pct1(weapon.effectiveness.armour.range)}</div>);
|
||||
effectivenessArmourTooltipDetails.push(<div key='resistance'>{translate('resistance') + ' ' + formats.pct1(weapon.effectiveness.armour.resistance)}</div>);
|
||||
effectivenessArmourTooltipDetails.push(<div key='hardness'>{translate('hardness') + ' ' + formats.pct1(weapon.effectiveness.armour.hardness)}</div>);
|
||||
const effectiveArmourSDpsTooltipDetails = [];
|
||||
if (weapon.sdps.armour.absolute) effectiveArmourSDpsTooltipDetails.push(<div key='absolute'>{translate('absolute') + ' ' + formats.f1(weapon.sdps.armour.absolute)}</div>);
|
||||
if (weapon.sdps.armour.explosive) effectiveArmourSDpsTooltipDetails.push(<div key='explosive'>{translate('explosive') + ' ' + formats.f1(weapon.sdps.armour.explosive)}</div>);
|
||||
if (weapon.sdps.armour.kinetic) effectiveArmourSDpsTooltipDetails.push(<div key='kinetic'>{translate('kinetic') + ' ' + formats.f1(weapon.sdps.armour.kinetic)}</div>);
|
||||
if (weapon.sdps.armour.thermal) effectiveArmourSDpsTooltipDetails.push(<div key='thermal'>{translate('thermal') + ' ' + formats.f1(weapon.sdps.armour.thermal)}</div>);
|
||||
|
||||
const effectiveArmourSDpsTooltipDetails = getSDpsTooltip(translate, formats, weapon.sdps.armour);
|
||||
|
||||
rows.push(
|
||||
<tr key={weapon.id}>
|
||||
@@ -199,27 +241,25 @@ export default class Offence extends TranslatedComponent {
|
||||
{weapon.classRating} {translate(weapon.name)}
|
||||
{weapon.engineering ? ' (' + weapon.engineering + ')' : null }
|
||||
</td>
|
||||
<td className='ri'><span onMouseOver={termtip.bind(null, baseSDpsTooltipDetails)} onMouseOut={tooltip.bind(null, null)}>{formats.f1(weapon.sdps.base.total)}</span></td>
|
||||
<td className='ri'><span onMouseOver={termtip.bind(null, effectiveShieldsSDpsTooltipDetails)} onMouseOut={tooltip.bind(null, null)}>{formats.f1(weapon.sdps.shields.total)}</span></td>
|
||||
<td className='ri'><span onMouseOver={termtip.bind(null, effectivenessShieldsTooltipDetails)} onMouseOut={tooltip.bind(null, null)}>{formats.pct1(weapon.effectiveness.shields.total)}</span></td>
|
||||
<td className='ri'><span onMouseOver={termtip.bind(null, effectiveArmourSDpsTooltipDetails)} onMouseOut={tooltip.bind(null, null)}>{formats.f1(weapon.sdps.armour.total)}</span></td>
|
||||
<td className='ri'><span onMouseOver={termtip.bind(null, effectivenessArmourTooltipDetails)} onMouseOut={tooltip.bind(null, null)}>{formats.pct1(weapon.effectiveness.armour.total)}</span></td>
|
||||
</tr>);
|
||||
}
|
||||
}
|
||||
|
||||
const totalShieldsSDps = absoluteShieldsSDps + explosiveShieldsSDps + kineticShieldsSDps + thermalShieldsSDps;
|
||||
const totalArmourSDps = absoluteArmourSDps + explosiveArmourSDps + kineticArmourSDps + thermalArmourSDps;
|
||||
const totalSDps = sumSDps(totalSDpsObject);
|
||||
const totalSDpsTooltipDetails = getSDpsTooltip(translate, formats, totalSDpsObject);
|
||||
const totalSDpsData = getSDpsData(translate, totalSDpsObject);
|
||||
|
||||
const shieldsSDpsData = [];
|
||||
shieldsSDpsData.push({ value: Math.round(absoluteShieldsSDps), label: translate('absolute') });
|
||||
shieldsSDpsData.push({ value: Math.round(explosiveShieldsSDps), label: translate('explosive') });
|
||||
shieldsSDpsData.push({ value: Math.round(kineticShieldsSDps), label: translate('kinetic') });
|
||||
shieldsSDpsData.push({ value: Math.round(thermalShieldsSDps), label: translate('thermal') });
|
||||
const totalShieldsSDps = sumSDps(shieldsSDpsObject);
|
||||
const totalShieldsSDpsTooltipDetails = getSDpsTooltip(translate, formats, shieldsSDpsObject);
|
||||
const shieldsSDpsData = getSDpsData(translate, shieldsSDpsObject);
|
||||
|
||||
const armourSDpsData = [];
|
||||
armourSDpsData.push({ value: Math.round(absoluteArmourSDps), label: translate('absolute') });
|
||||
armourSDpsData.push({ value: Math.round(explosiveArmourSDps), label: translate('explosive') });
|
||||
armourSDpsData.push({ value: Math.round(kineticArmourSDps), label: translate('kinetic') });
|
||||
armourSDpsData.push({ value: Math.round(thermalArmourSDps), label: translate('thermal') });
|
||||
const totalArmourSDps = sumSDps(armourSDpsObject);
|
||||
const totalArmourSDpsTooltipDetails = getSDpsTooltip(translate, formats, armourSDpsObject);
|
||||
const armourSDpsData = getSDpsData(translate, armourSDpsObject);
|
||||
|
||||
const timeToDepleteShields = Calc.timeToDeplete(opponentShields.total, totalShieldsSDps, totalSEps, pd.getWeaponsCapacity(), pd.getWeaponsRechargeRate() * (wep / 4));
|
||||
const timeToDepleteArmour = Calc.timeToDeplete(opponentArmour.total, totalArmourSDps, totalSEps, pd.getWeaponsCapacity(), pd.getWeaponsRechargeRate() * (wep / 4));
|
||||
@@ -231,19 +271,31 @@ export default class Offence extends TranslatedComponent {
|
||||
<thead>
|
||||
<tr className='main'>
|
||||
<th rowSpan='2' className='sortable' onClick={sortOrder.bind(this, 'n')}>{translate('weapon')}</th>
|
||||
<th colSpan='1'>{translate('overall')}</th>
|
||||
<th colSpan='2'>{translate('opponent\'s shields')}</th>
|
||||
<th colSpan='2'>{translate('opponent\'s armour')}</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th className='lft sortable' onMouseOver={termtip.bind(null, 'TT_EFFECTIVE_SDPS_SHIELDS')} onMouseOut={tooltip.bind(null, null)} onClick={sortOrder.bind(this, 'esdpss')}>{'sdps'}</th>
|
||||
<th className='lft sortable' onMouseOver={termtip.bind(null, 'TT_EFFECTIVE_SDPS_SHIELDS')} onMouseOut={tooltip.bind(null, null)} onClick={sortOrder.bind(this, 'esdpss')}>{'sdps'}</th>
|
||||
<th className='sortable' onMouseOver={termtip.bind(null, 'TT_EFFECTIVENESS_SHIELDS')} onMouseOut={tooltip.bind(null, null)}onClick={sortOrder.bind(this, 'es')}>{'eft'}</th>
|
||||
<th className='lft sortable' onMouseOver={termtip.bind(null, 'TT_EFFECTIVE_SDPS_ARMOUR')} onMouseOut={tooltip.bind(null, null)}onClick={sortOrder.bind(this, 'esdpsh')}>{'sdps'}</th>
|
||||
<th className='sortable' onMouseOver={termtip.bind(null, 'TT_EFFECTIVENESS_ARMOUR')} onMouseOut={tooltip.bind(null, null)}onClick={sortOrder.bind(this, 'eh')}>{'eft'}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{rows}
|
||||
</tbody>
|
||||
<tbody>
|
||||
{rows}
|
||||
{rows.length > 0 &&
|
||||
<tr>
|
||||
<td></td>
|
||||
<td className='ri'><span onMouseOver={termtip.bind(null, totalSDpsTooltipDetails)} onMouseOut={tooltip.bind(null, null)}>={formats.f1(totalSDps)}</span></td>
|
||||
<td className='ri'><span onMouseOver={termtip.bind(null, totalShieldsSDpsTooltipDetails)} onMouseOut={tooltip.bind(null, null)}>={formats.f1(totalShieldsSDps)}</span></td>
|
||||
<td></td>
|
||||
<td className='ri'><span onMouseOver={termtip.bind(null, totalArmourSDpsTooltipDetails)} onMouseOut={tooltip.bind(null, null)}>={formats.f1(totalArmourSDps)}</span></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div className='group quarter'>
|
||||
@@ -254,6 +306,10 @@ export default class Offence extends TranslatedComponent {
|
||||
<h2 onMouseOver={termtip.bind(null, translate('TT_EFFECTIVE_SDPS_ARMOUR'))} onMouseOut={tooltip.bind(null, null)}>{translate('PHRASE_EFFECTIVE_SDPS_ARMOUR')}<br/>{formats.f1(totalArmourSDps)}</h2>
|
||||
<h2 onMouseOver={termtip.bind(null, translate('TT_TIME_TO_REMOVE_ARMOUR'))} onMouseOut={tooltip.bind(null, null)}>{translate('PHRASE_TIME_TO_REMOVE_ARMOUR')}<br/>{timeToDepleteArmour === Infinity ? translate('never') : formats.time(timeToDepleteArmour)}</h2>
|
||||
</div>
|
||||
<div className='group quarter'>
|
||||
<h2 onMouseOver={termtip.bind(null, translate('PHRASE_OVERALL_DAMAGE'))} onMouseOut={tooltip.bind(null, null)}>{translate('overall damage')}</h2>
|
||||
<PieChart data={totalSDpsData} />
|
||||
</div>
|
||||
<div className='group quarter'>
|
||||
<h2 onMouseOver={termtip.bind(null, translate('PHRASE_SHIELD_DAMAGE'))} onMouseOut={tooltip.bind(null, null)}>{translate('shield damage sources')}</h2>
|
||||
<PieChart data={shieldsSDpsData} />
|
||||
|
||||
@@ -50,7 +50,7 @@ export default class ShipSummaryTable extends TranslatedComponent {
|
||||
const speedTooltip = canThrust ? 'TT_SUMMARY_SPEED' : 'TT_SUMMARY_SPEED_NONFUNCTIONAL';
|
||||
const canBoost = ship.canBoost(cargo, ship.fuelCapacity);
|
||||
const boostTooltip = canBoost ? 'TT_SUMMARY_BOOST' : canThrust ? 'TT_SUMMARY_BOOST_NONFUNCTIONAL' : 'TT_SUMMARY_SPEED_NONFUNCTIONAL';
|
||||
const sgMetrics = Calc.shieldMetrics(ship, pips.sys || 2);
|
||||
const sgMetrics = Calc.shieldMetrics(ship, pips.sys);
|
||||
const shipBoost = canBoost ? Calc.calcBoost(ship) : 'No Boost';
|
||||
const armourMetrics = Calc.armourMetrics(ship);
|
||||
let shieldColour = 'blue';
|
||||
@@ -149,8 +149,8 @@ export default class ShipSummaryTable extends TranslatedComponent {
|
||||
<td>{int(ship && ship.shield > 0 ? ship.shield * ((1 / (1 - (ship.shieldExplRes)))) : 0)}{u.MJ}</td>
|
||||
<td>{int(ship && ship.shield > 0 ? ship.shield * ((1 / (1 - (ship.shieldKinRes)))) : 0)}{u.MJ}</td>
|
||||
<td>{int(ship && ship.shield > 0 ? ship.shield * ((1 / (1 - (ship.shieldThermRes)))) : 0)}{u.MJ}</td>
|
||||
<td>{sgMetrics && sgMetrics.recover ? formats.time(sgMetrics.recover) : 0}</td>
|
||||
<td>{sgMetrics && sgMetrics.recharge ? formats.time(sgMetrics.recharge) : 0}</td>
|
||||
<td>{sgMetrics && sgMetrics.recover === Math.Inf ? translate('Never') : formats.time(sgMetrics.recover)}</td>
|
||||
<td>{sgMetrics && sgMetrics.recharge === Math.Inf ? translate('Never') : formats.time(sgMetrics.recharge)}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<thead>
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
"PHRASE_TIME_TO_LOSE_ARMOUR": "Armour will hold for",
|
||||
"PHRASE_MODULE_PROTECTION_EXTERNAL": "Protection for hardpoints",
|
||||
"PHRASE_MODULE_PROTECTION_INTERNAL": "Protection for all other modules",
|
||||
"PHRASE_OVERALL_DAMAGE": "Breakdown of sources for sustained DPS",
|
||||
"PHRASE_SHIELD_DAMAGE": "Breakdown of sources for sustained DPS against shields",
|
||||
"PHRASE_ARMOUR_DAMAGE": "Breakdown of sources for sustained DPS against armour",
|
||||
"PHRASE_TIME_TO_REMOVE_SHIELDS": "Will remove shields in",
|
||||
@@ -135,6 +136,7 @@
|
||||
"rf": "Refinery",
|
||||
"rfl": "Remote Release Flak Launcher",
|
||||
"rg": "Rail Gun",
|
||||
"rsl": "Research Limpet Controller",
|
||||
"s": "Sensors",
|
||||
"sb": "Shield Booster",
|
||||
"sc": "Stellar Scanners",
|
||||
@@ -150,6 +152,10 @@
|
||||
"rpl": "Repair Limpet Controller",
|
||||
"rcpl": "Recon Limpet Controller",
|
||||
"xs": "Xeno Scanner",
|
||||
"tbem": "Enzyme Missile Rack",
|
||||
"tbrfl": "Remote Release Flechette Launcher",
|
||||
"dtl": "Decontamination Limpet Controller",
|
||||
"mahr": "Meta Alloy Hull Reinforcement Package",
|
||||
"emptyrestricted": "empty (restricted)",
|
||||
"damage dealt to": "Damage dealt to",
|
||||
"damage received from": "Damage received from",
|
||||
@@ -297,6 +303,7 @@
|
||||
"opponent": "opponent",
|
||||
"opponent's shields": "opponent's shields",
|
||||
"opponent's armour": "opponent's armour",
|
||||
"overall damage": "overall damage",
|
||||
"shield damage sources": "shield damage sources",
|
||||
"armour damage sources": "armour damage sources",
|
||||
"never": "never",
|
||||
|
||||
@@ -480,37 +480,56 @@ export function shieldMetrics(ship, sys) {
|
||||
max: 1 - maxSysResistance
|
||||
};
|
||||
|
||||
/**
|
||||
* An object that stores a selection of difference damage multipliers that
|
||||
* deal with a ship's shield strength.
|
||||
* @typedef {Object} ShieldDamageMults
|
||||
* @property {number} generator Base damage multiplier of the shield
|
||||
* contributing it's base resistance.
|
||||
* @property {number} boosters Damage multiplier contributed by all
|
||||
* boosters, i.e. `rawMj / (generator * boosters)` equals shield strength
|
||||
* with 0 pips to sys.
|
||||
* @property {number} sys Damage multiplier contributed by pips to sys.
|
||||
* @property {number} base Damage multiplier with 0 pips to sys; just
|
||||
* boosters and shield generator. Equals `generator * boosters`.
|
||||
* @property {number} total Damage multiplier with current pip settings.
|
||||
* @property {number} max Damage multiplier with 4 pips to sys.
|
||||
*/
|
||||
|
||||
let sgExplosiveDmg = 1 - shieldGenerator.getExplosiveResistance();
|
||||
let sgSbExplosiveDmg = diminishDamageMult(sgExplosiveDmg * 0.7, (1 - shieldGenerator.getExplosiveResistance()) * boosterExplDmg);
|
||||
/** @type {ShieldDamageMults} */
|
||||
shield.explosive = {
|
||||
generator: sgExplosiveDmg,
|
||||
boosters: sgSbExplosiveDmg - sgExplosiveDmg,
|
||||
boosters: sgSbExplosiveDmg / sgExplosiveDmg,
|
||||
sys: (1 - sysResistance),
|
||||
base: sgSbExplosiveDmg,
|
||||
total: sgSbExplosiveDmg * (1 - sysResistance),
|
||||
max: sgSbExplosiveDmg * (1 - maxSysResistance),
|
||||
res: 1 - sgSbExplosiveDmg
|
||||
};
|
||||
|
||||
let sgKineticDmg = 1 - shieldGenerator.getKineticResistance();
|
||||
let sgSbKineticDmg = diminishDamageMult(sgKineticDmg * 0.7, (1 - shieldGenerator.getKineticResistance()) * boosterKinDmg);
|
||||
/** @type {ShieldDamageMults} */
|
||||
shield.kinetic = {
|
||||
generator: sgKineticDmg,
|
||||
boosters: sgSbKineticDmg - sgKineticDmg,
|
||||
boosters: sgSbKineticDmg / sgKineticDmg,
|
||||
sys: (1 - sysResistance),
|
||||
base: sgSbKineticDmg,
|
||||
total: sgSbKineticDmg * (1 - sysResistance),
|
||||
max: sgSbKineticDmg * (1 - maxSysResistance),
|
||||
res: 1 - sgSbKineticDmg
|
||||
};
|
||||
|
||||
let sgThermalDmg = 1 - shieldGenerator.getThermalResistance();
|
||||
let sgSbThermalDmg = diminishDamageMult(sgThermalDmg * 0.7, (1 - shieldGenerator.getThermalResistance()) * boosterThermDmg);
|
||||
/** @type {ShieldDamageMults} */
|
||||
shield.thermal = {
|
||||
generator: sgThermalDmg,
|
||||
boosters: sgSbThermalDmg - sgThermalDmg,
|
||||
boosters: sgSbThermalDmg / sgThermalDmg,
|
||||
sys: (1 - sysResistance),
|
||||
base: sgSbThermalDmg,
|
||||
total: sgSbThermalDmg * (1 - sysResistance),
|
||||
max: sgSbThermalDmg * (1 - maxSysResistance),
|
||||
res: 1 - sgSbThermalDmg
|
||||
};
|
||||
}
|
||||
return shield;
|
||||
@@ -553,7 +572,7 @@ export function armourMetrics(ship) {
|
||||
// };
|
||||
// Armour from HRPs and module armour from MRPs
|
||||
for (let slot of ship.internal) {
|
||||
if (slot.m && (slot.m.grp === 'hr' || slot.m.grp === 'ghrp')) {
|
||||
if (slot.m && (slot.m.grp === 'hr' || slot.m.grp === 'ghrp' || slot.m.grp == 'mahr')) {
|
||||
armourReinforcement += slot.m.getHullReinforcement();
|
||||
// Hull boost for HRPs is applied against the ship's base armour
|
||||
armourReinforcement += ship.baseArmour * slot.m.getModValue('hullboost') / 10000;
|
||||
@@ -612,7 +631,7 @@ export function armourMetrics(ship) {
|
||||
let armourReinforcedExplDmg = diminishDamageMult(0.7, (1 - ship.bulkheads.m.getExplosiveResistance()) * hullExplDmg);
|
||||
armour.explosive = {
|
||||
bulkheads: armourExplDmg,
|
||||
reinforcement: armourReinforcedExplDmg - armourExplDmg,
|
||||
reinforcement: armourReinforcedExplDmg / armourExplDmg,
|
||||
total: armourReinforcedExplDmg,
|
||||
res: 1 - armourReinforcedExplDmg
|
||||
};
|
||||
@@ -621,7 +640,7 @@ export function armourMetrics(ship) {
|
||||
let armourReinforcedKinDmg = diminishDamageMult(0.7, (1 - ship.bulkheads.m.getKineticResistance()) * hullKinDmg);
|
||||
armour.kinetic = {
|
||||
bulkheads: armourKinDmg,
|
||||
reinforcement: armourReinforcedKinDmg - armourKinDmg,
|
||||
reinforcement: armourReinforcedKinDmg / armourKinDmg,
|
||||
total: armourReinforcedKinDmg,
|
||||
res: 1 - armourReinforcedKinDmg
|
||||
};
|
||||
@@ -630,7 +649,7 @@ export function armourMetrics(ship) {
|
||||
let armourReinforcedThermDmg = diminishDamageMult(0.7, (1 - ship.bulkheads.m.getThermalResistance()) * hullThermDmg);
|
||||
armour.thermal = {
|
||||
bulkheads: armourThermDmg,
|
||||
reinforcement: armourReinforcedThermDmg - armourThermDmg,
|
||||
reinforcement: armourReinforcedThermDmg / armourThermDmg,
|
||||
total: armourReinforcedThermDmg,
|
||||
res: 1 - armourReinforcedThermDmg
|
||||
};
|
||||
@@ -805,20 +824,55 @@ export function _sustainedDps(ship, opponent, opponentShields, opponentArmour, e
|
||||
return { shieldsdps, armoursdps, eps };
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores SDPS split up by type.
|
||||
* @typedef {Object} SDps
|
||||
* @property {number} absolute Damage of type absolute
|
||||
* @property {number} explosive Damage of type explosive
|
||||
* @property {number} kinetic Damage of type kinetic
|
||||
* @property {number} thermal Damage of type thermal
|
||||
* @property {number} [total] Sum of all damage types
|
||||
*/
|
||||
|
||||
/**
|
||||
* An object that holds information about SDPS for a given weapon and opponent.
|
||||
* @typedef {Object} WeaponDamage
|
||||
* @property {number} eps Energy per second
|
||||
* @property {Object} damage An object that stores damage inflicted by
|
||||
* the weapon.
|
||||
* @property {Object} effectiveness An object that stores the effectiveness of
|
||||
* the weapon against the opponent given.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Stores overall SDPS and against a given opponent's shields and armour.
|
||||
* @typedef {Object} WeaponDamage~damage
|
||||
* @property {SDps} base Overall SDPS.
|
||||
* @property {SDps} shields SDPS against the given opponent's shields.
|
||||
* @property {SDps} armour SDPS against the given opponent's armour.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Calculate the sustained DPS for a weapon at a given range
|
||||
* @param {Object} m The weapon
|
||||
* @param {Object} opponent The opponent ship
|
||||
* @param {Object} opponent The opponent ship
|
||||
* @param {Object} opponentShields The opponent's shield resistances
|
||||
* @param {Object} opponentArmour The opponent's armour resistances
|
||||
* @param {int} engagementrange The range between the ship and opponent
|
||||
* @returns {Object} Sustained DPS for shield and armour
|
||||
* @returns {WeaponDamage} Sustained DPS for shield and armour
|
||||
*/
|
||||
export function _weaponSustainedDps(m, opponent, opponentShields, opponentArmour, engagementrange) {
|
||||
const opponentHasShields = opponentShields.generator ? true : false;
|
||||
const weapon = {
|
||||
eps: 0,
|
||||
damage: {
|
||||
base: {
|
||||
absolute: 0,
|
||||
explosive: 0,
|
||||
kinetic: 0,
|
||||
thermal: 0,
|
||||
total: 0,
|
||||
},
|
||||
shields: {
|
||||
absolute: 0,
|
||||
explosive: 0,
|
||||
@@ -863,6 +917,12 @@ export function _weaponSustainedDps(m, opponent, opponentShields, opponentArmour
|
||||
sDps *= dropoff;
|
||||
}
|
||||
|
||||
weapon.damage.base.absolute = sDps * m.getDamageDist().A;
|
||||
weapon.damage.base.explosive = sDps * m.getDamageDist().E;
|
||||
weapon.damage.base.kinetic = sDps * m.getDamageDist().K;
|
||||
weapon.damage.base.thermal = sDps * m.getDamageDist().T;
|
||||
weapon.damage.base.total = sDps;
|
||||
|
||||
// Piercing/hardness modifier (for armour only)
|
||||
const armourMultiple = m.getPiercing() >= opponent.hardness ? 1 : m.getPiercing() / opponent.hardness;
|
||||
weapon.effectiveness.armour.hardness = armourMultiple;
|
||||
@@ -963,7 +1023,7 @@ export function timeToDeplete(amount, dps, eps, capacity, recharge) {
|
||||
|
||||
/**
|
||||
* Applies diminishing returns to resistances.
|
||||
* @param {number} baseDamageMult The base resistance up to which no diminishing returns are applied.
|
||||
* @param {number} diminishFrom The base resistance up to which no diminishing returns are applied.
|
||||
* @param {number} damageMult Resistance as damage multiplier
|
||||
* @returns {number} Actual damage multiplier
|
||||
*/
|
||||
|
||||
@@ -56,6 +56,7 @@ export const ModuleGroupToName = {
|
||||
gfsb: 'Guardian Frame Shift Drive Booster',
|
||||
ghrp: 'Guardian Hull Reinforcement Package',
|
||||
gmrp: 'Guardian Module Reinforcement Package',
|
||||
mahr: 'Meta Alloy Hull Reinforcement Package',
|
||||
|
||||
// Hard Points
|
||||
bl: 'Beam Laser',
|
||||
@@ -85,10 +86,14 @@ export const ModuleGroupToName = {
|
||||
sfn: 'Shutdown Field Neutraliser',
|
||||
xs: 'Xeno Scanner',
|
||||
rcpl: 'Recon Limpet Controller',
|
||||
rsl: 'Research Limpet Controller',
|
||||
dtl: 'Decontamination Limpet Controller',
|
||||
gpc: 'Guardian Plasma Charger',
|
||||
ggc: 'Guardian Gauss Cannon',
|
||||
tbsc: 'Shock Cannon',
|
||||
gsc: 'Guardian Shard Cannon',
|
||||
tbem: 'Enzyme Missile Rack',
|
||||
tbrfl: 'Remote Release Flechette Launcher',
|
||||
};
|
||||
|
||||
let GrpNameToCodeMap = {};
|
||||
|
||||
@@ -937,7 +937,7 @@ export default class Ship {
|
||||
let epsChanged = n && n.getEps() || old && old.getEps();
|
||||
let hpsChanged = n && n.getHps() || old && old.getHps();
|
||||
|
||||
let armourChange = (slot === this.bulkheads) || (n && n.grp === 'hr') || (n && n.grp === 'ghrp') || (old && old.grp === 'hr') || (old && old.grp === 'ghrp') || (n && n.grp === 'mrp') || (old && old.grp === 'mrp');
|
||||
let armourChange = (slot === this.bulkheads) || (n && n.grp === 'hr') || (n && n.grp === 'ghrp') || (old && old.grp === 'hr') || (old && old.grp === 'ghrp') || (n && n.grp === 'mrp') || (old && old.grp === 'mrp') || (n && n.grp == 'mahr') || (old && old.grp == 'mahr');
|
||||
|
||||
let shieldChange = (n && n.grp === 'bsg') || (old && old.grp === 'bsg') || (n && n.grp === 'psg') || (old && old.grp === 'psg') || (n && n.grp === 'sg') || (old && old.grp === 'sg') || (n && n.grp === 'sb') || (old && old.grp === 'sb') || (old && old.grp === 'gsrp') || (n && n.grp === 'gsrp');
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!DOCTYPE html>
|
||||
<html <%= htmlWebpackPlugin.options.appCache ? 'manifest=/' + htmlWebpackPlugin.options.appCache : '' %> >
|
||||
<html manifest="/">
|
||||
<head>
|
||||
<title>Coriolis EDCD Edition</title>
|
||||
<meta charset="UTF-8">
|
||||
|
||||
44
src/sw.js
Normal file
44
src/sw.js
Normal file
@@ -0,0 +1,44 @@
|
||||
console.log('Hello from sw.js');
|
||||
|
||||
if (workbox) {
|
||||
console.log('Yay! Workbox is loaded 🎉');
|
||||
workbox.routing.registerRoute(
|
||||
new RegExp('https://fonts.(?:googleapis|gstatic).com/(.*)'),
|
||||
workbox.strategies.cacheFirst({
|
||||
cacheName: 'google-fonts',
|
||||
plugins: [
|
||||
new workbox.expiration.Plugin({
|
||||
maxEntries: 30
|
||||
}),
|
||||
new workbox.cacheableResponse.Plugin({
|
||||
statuses: [0, 200]
|
||||
})
|
||||
]
|
||||
})
|
||||
);
|
||||
workbox.routing.registerRoute(
|
||||
/\.(?:png|gif|jpg|jpeg|svg)$/,
|
||||
workbox.strategies.cacheFirst({
|
||||
cacheName: 'images',
|
||||
plugins: [
|
||||
new workbox.expiration.Plugin({
|
||||
maxEntries: 60,
|
||||
maxAgeSeconds: 30 * 24 * 60 * 60 // 30 Days
|
||||
})
|
||||
]
|
||||
})
|
||||
);
|
||||
workbox.routing.registerRoute(
|
||||
/\.(?:js|css)$/,
|
||||
workbox.strategies.staleWhileRevalidate({
|
||||
cacheName: 'static-resources'
|
||||
})
|
||||
);
|
||||
try {
|
||||
workbox.googleAnalytics.initialize();
|
||||
} catch (e) {
|
||||
console.log('Probably an ad-blocker');
|
||||
}
|
||||
} else {
|
||||
console.log('Boo! Workbox didn\'t load 😬');
|
||||
}
|
||||
@@ -3,7 +3,8 @@ const exec = require('child_process').exec;
|
||||
const webpack = require('webpack');
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
const ExtractTextPlugin = require('extract-text-webpack-plugin');
|
||||
const AppCachePlugin = require('appcache-webpack-plugin');
|
||||
const { InjectManifest } = require('workbox-webpack-plugin');
|
||||
|
||||
const { BugsnagSourceMapUploaderPlugin } = require('webpack-bugsnag-plugins');
|
||||
const pkgJson = require('./package');
|
||||
const buildDate = new Date();
|
||||
@@ -75,12 +76,11 @@ module.exports = {
|
||||
new CopyDirPlugin(path.join(__dirname, 'src/schemas'), 'schemas'),
|
||||
new CopyDirPlugin(path.join(__dirname, 'src/images/logo/*'), ''),
|
||||
new CopyDirPlugin(path.join(__dirname, 'src/.htaccess'), ''),
|
||||
new AppCachePlugin({
|
||||
network: ['*'],
|
||||
settings: ['prefer-online'],
|
||||
exclude: ['index.html', /.*\.map$/],
|
||||
output: 'coriolis.appcache'
|
||||
})
|
||||
new InjectManifest({
|
||||
swSrc: './src/sw.js',
|
||||
importWorkboxFrom: 'cdn',
|
||||
swDest: 'service-worker.js'
|
||||
}),
|
||||
],
|
||||
module: {
|
||||
rules: [
|
||||
|
||||
Reference in New Issue
Block a user