Compare commits

...

37 Commits

Author SHA1 Message Date
David Sangrey
8f5375f732 Merge pull request #760 from alex-williams/Issue_758_adding_ax_nanite_torps_and_enhanced_missile_racks
Adds the Advanced MC's, AX MC's, AX MR's and Nanite Torpedo
2024-05-20 12:49:53 -04:00
Alex Williams
3156b6a533 Adds the Advanced MC's, AX MC's, AX MR's and Nanite Torpedo 2024-05-17 08:45:15 +01:00
Alex Williams
18d7ada65f Merge pull request #755 from leonardofelin/pt-br_translations
Updated PT-BR translation with Planetary Approach Suite
2024-05-14 17:18:40 +01:00
leonardofelin
8593e18de4 Updated PT-BR translation with Planetary Approach Suite 2024-05-14 13:13:56 -03:00
leonardofelin
284b0b3ce2 Update pt.json - Brazilian Portuguese translations (#752)
* Update pt.json

Update Brazilian Portuguese translations:
- Updated Modules
- Engineering & Experimental Effect
- Corrections

* Update Portuguese Brazilian

Fixed Tab/Spaces indentation
2024-05-14 13:25:51 +02:00
David Sangrey
c3cb2cfa3b Add SCO Module Check (#748)
* Add SCO Module Check

Goes hand-in-hand with https://github.com/EDCD/coriolis-data/pull/98

* [748] Updated Filter Function

This time, readable!
2024-05-12 13:51:17 +02:00
Alex Williams
5d54eb8862 Adding python_nx to SHIP_FD_NAME_TO_CORIOLIS_NAME to fix import issue with Python Mk II 2024-05-12 13:48:28 +02:00
Felix Linker
9fc6508be4 coriolis-data specified as relative dependency again 2024-04-29 08:24:34 +02:00
Aleksandr
ef82cf4a00 [744] add support of experimental weapon stabilizer (#745) 2024-04-29 08:23:20 +02:00
Felix Linker
9766f78e21 Move eddb.io links to inara.cz 2023-04-07 19:25:16 +01:00
Felix Linker
6d8bd6ca44 Dependency update 2023-04-07 19:18:28 +01:00
Sam Clayton
875af31ffe Update to Webpack 5 (fixes crypto error on build) (#738)
* Updating react-number-editor dependency from stale named branch

* Remove references to deprecated react-addons-perf package

* Issue #25 Webpack updated to current version, many
dependencies updated, Babel & Webpack configs updated.
Add dev & prod Dockerfiles and update README with Docker instructions
Created webpack.common.js.
Coriolis-data now specified as github dependency

* Bump bugfix versions of react & react-dom only

* Workbox dependency upgrade for webpack 5 compat

* Stab at upgrading workbox dep
Far more fatal webpack errors :(

* Automate reinstall/rebuild with npm script

* Working build again w updated deps
Disabled/commented out all bugsnag references
Added production-like Docker build for troubleshooting issues that don't
 appear in dev server

* Remove deprecated @babel/polyfill import & dependency

* Fix to service worker to v5 of workbox
and align with webpack 5 plugin

* Disabling recent round of polyfills. Don't think
they're necessary.

* Whitespace in package.json

* Add Buffer as Webpack plugin. Fix indenting.
Fix deprecated call to Buffer.

* Remove bugsnag and deprecated babel code that was
 commented out, per convo with Felix

---------

Co-authored-by: Sam Clayton <sam@goranku.com>
2023-03-01 21:55:23 +01:00
Felix Linker
93adcb3daf Merge pull request #730 from Sid127/edomh-v1
Initial EDOMH integration
2022-12-27 13:19:05 +01:00
Felix Linker
ec9a07b143 Merge pull request #732 from EDCD/dependabot/npm_and_yarn/decode-uri-component-0.2.2
Bump decode-uri-component from 0.2.0 to 0.2.2
2022-12-26 13:37:46 +01:00
dependabot[bot]
bb8eeb4d3f Bump decode-uri-component from 0.2.0 to 0.2.2
Bumps [decode-uri-component](https://github.com/SamVerschueren/decode-uri-component) from 0.2.0 to 0.2.2.
- [Release notes](https://github.com/SamVerschueren/decode-uri-component/releases)
- [Commits](https://github.com/SamVerschueren/decode-uri-component/compare/v0.2.0...v0.2.2)

---
updated-dependencies:
- dependency-name: decode-uri-component
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-09 17:17:50 +00:00
Sid Pranjale
8b7a7192a4 Initial EDOMH integration 2022-11-27 14:55:56 +05:30
Felix Linker
6688a1fbe3 Merge pull request #728 from AndricReal/patch-1
Update of russian localisation
2022-11-27 10:11:55 +01:00
AndricReal
2ea5fe5d58 Update ru.json
Corrected translation
2022-11-20 16:08:27 +05:00
Felix Linker
efd644c6f1 Merge pull request #726 from Sid127/matlist-fix
Matlist fix
2022-11-11 20:18:22 +01:00
Sid Pranjale
17c6ec1f97 Do nothing if a module has no experimentals
This fixes materials not being shown for modules that can be engineered but not having experimental effects
2022-11-09 21:19:02 +05:30
Felix Linker
9bc6e36f14 Remove/replace react 16 dependencies 2022-10-29 11:53:36 +02:00
Felix Linker
062815054c Add package-lock 2022-10-29 11:43:02 +02:00
Felix Linker
7bc40d24d8 Merge pull request #708 from Sid127/develop
Quick fix for missing group info in JSON exports
2022-10-21 17:13:11 +02:00
Felix Linker
d9da250f50 Merge pull request #709 from Sid127/uuids-fix
Add mats for experimental effects to mat list
2022-10-21 17:11:39 +02:00
Sid Pranjale
801969dc07 Add mats for experimental effects to mat list 2022-10-09 16:34:04 +05:30
Sid Pranjale
6bf820934f Quick fix for missing group info in JSON exports 2022-10-09 11:45:18 +05:30
Felix Linker
887dbc25f8 Merge remote-tracking branch 'unknowngamer/master' into develop 2022-10-02 11:53:56 +02:00
Felix Linker
50de77d613 Merge remote-tracking branch 'origin/master' into develop 2022-10-02 11:53:48 +02:00
Felix Linker
13561ee21a Merge pull request #704 from green1052/develop
Add Korean translate
2022-10-02 11:44:48 +02:00
green1052
333feaa6bf Add Korean translate
Co-authored-by: jackfrost <jackfrost5446@naver.com>
2022-10-01 15:35:56 +09:00
Rob
1e37fd15eb Fix link to data wiki 2022-08-26 07:28:17 +01:00
ItsUnknownGamer
f82b0212b5 shield recovery time depending on distributor draw 2022-03-04 17:44:49 +01:00
Felix Linker
32138f5546 Merge pull request #689 from Sid127/develop
Minor modifications for Multi-limpet Controllers
2022-01-05 10:53:54 +01:00
Sid
85ddce14a5 Minor modifications for Multi-limpet Controllers 2022-01-05 13:09:34 +05:30
Felix Linker
7e44772f2e Hotfix 2021-12-30 17:06:02 +01:00
Felix Linker
e90bfe9b68 Multi limpet controllers have max of 1 2021-12-30 14:21:21 +01:00
Felix Linker
64002e1ae0 Add translation for multi limpet controllers 2021-12-30 13:53:07 +01:00
40 changed files with 14221 additions and 458 deletions

View File

@@ -7,6 +7,8 @@
"@babel/plugin-syntax-dynamic-import", "@babel/plugin-syntax-dynamic-import",
"@babel/plugin-syntax-import-meta", "@babel/plugin-syntax-import-meta",
["@babel/plugin-proposal-class-properties", { "loose": true }], ["@babel/plugin-proposal-class-properties", { "loose": true }],
"@babel/plugin-proposal-do-expressions",
"@babel/plugin-proposal-function-bind",
"@babel/plugin-proposal-json-strings", "@babel/plugin-proposal-json-strings",
[ [
"@babel/plugin-proposal-decorators", "@babel/plugin-proposal-decorators",
@@ -28,7 +30,7 @@
} }
], ],
"@babel/plugin-proposal-nullish-coalescing-operator", "@babel/plugin-proposal-nullish-coalescing-operator",
"@babel/plugin-proposal-do-expressions", ["@babel/plugin-proposal-private-methods", { "loose": true }],
"@babel/plugin-proposal-function-bind" ["@babel/plugin-proposal-private-property-in-object", { "loose": true }]
] ]
} }

7
.dockerignore Normal file
View File

@@ -0,0 +1,7 @@
Dockerfile
.dockerignore
.gitignore
README.md
build
node_modules

14
.gitattributes vendored Normal file
View File

@@ -0,0 +1,14 @@
# Set the default behavior, in case people don't have core.autocrlf set, in order to prevent line ending inconsistency.
* text=auto
# Explicitly declare text files you want to always be normalized and converted
# to native line endings on checkout.
*.jsx text
*.js text
# Declare files that will always have CRLF line endings on checkout.
# *.sln text eol=crlf
# Denote all files that are truly binary and should not be modified.
*.png binary
*.jpg binary

1
.gitignore vendored
View File

@@ -10,4 +10,3 @@ env
.project .project
.vscode/ .vscode/
docs/ docs/
package-lock.json

1
.npmrc
View File

@@ -1 +0,0 @@
package-lock=false

25
Dockerfile Normal file
View File

@@ -0,0 +1,25 @@
#syntax=docker/dockerfile:1.4
# Run this from within this directory. Change the location of coriolis-data repo and image name/tag as needed.
# docker buildx build --build-context data=../coriolis-data --tag coriolis .
FROM node:18-alpine
# TODO: For a production build, we may want to just build the bundle and copy that in. No need for local copy of source.
WORKDIR /app
ADD . .
COPY --from=data . /coriolis-data/
# Git is required before install if any modules (like coriolis-data) are loaded from github
RUN apk update
RUN apk add git
WORKDIR /app/coriolis-data
RUN npm install
WORKDIR /app
RUN npm install
# Bundle for production config with webpack & log
RUN npm run build > >(tee -a stdout.log) 2> >(tee -a stderr.log >&2)
# Optimally, this will start a static asset server like nginx/apache. Currently, this will start dev webpack server.
CMD ["npm", "start"]
EXPOSE 3300

23
Dockerfile-dev Normal file
View File

@@ -0,0 +1,23 @@
#syntax=docker/dockerfile:1.4
# Run this from within this directory. Change the location of coriolis-data repo and image name/tag as needed.
# docker buildx build --build-context data=../coriolis-data --tag coriolis -f ./Dockerfile-dev .
FROM node:18-alpine
WORKDIR /app
ADD . .
COPY --from=data . /coriolis-data/
# Install git & any other desired in-container dev tools
# Git is required before install if any modules (like coriolis-data) are loaded from github
RUN apk update
RUN apk add git
WORKDIR /app/coriolis-data
RUN npm install
WORKDIR /app
RUN npm install
CMD ["npm", "start"]
EXPOSE 3300

32
Dockerfile-local-prod Normal file
View File

@@ -0,0 +1,32 @@
#syntax=docker/dockerfile:1.4
# Run this from within this directory. Change the location of coriolis-data repo and image name/tag as needed.
# docker buildx build --build-context data=../coriolis-data --tag coriolis:0.0.7-local-prod -f Dockerfile-local-prod .
# docker run -d -p 80:8080 coriolis:0.0.7-local-prod
FROM node:18-alpine
# TODO: For a production build, we may want to just build the bundle and copy that in. No need for local copy of source.
WORKDIR /app
ADD . .
# COPY --from=data . /coriolis-data/
# Git is required before install if any modules (like coriolis-data is now referenced in the package.json) are loaded from github
RUN apk update
RUN apk add git
# WORKDIR /app/coriolis-data
# RUN npm install
# WORKDIR /app
# RUN npm install
# Bundle for production config with webpack & log
# In this version of the dockerfile, I'm deferring automated webpack build so I can monitor a manual build
# RUN npm run build > >(tee -a stdout.log) 2> >(tee -a stderr.log >&2)
RUN npm install -g http-server
# Optimally, this will start a static asset server like nginx/apache. Currently, this will start dev webpack server.
# CMD ["http-server", "/app/build", "-c-1"]
CMD ["/bin/ash"]
# CMD [""]
EXPOSE 8080

View File

@@ -14,7 +14,16 @@ Coriolis was created using assets and imagery from Elite: Dangerous, with the pe
## Development ## Development
To get a local instance of coriolis running, perform the following steps in a shell: This release includes the ability to run the app as a Docker container.
```sh
> git clone https://github.com/EDCD/coriolis.git
> git clone https://github.com/EDCD/coriolis-data.git
> cd coriolis
> docker buildx build --build-context data=../coriolis-data --tag coriolis .
> docker run -d -p 3300:3300 coriolis
```
Or to run an instance of coriolis without Docker Desktop, perform the following steps in a shell:
```sh ```sh
> git clone https://github.com/EDCD/coriolis.git > git clone https://github.com/EDCD/coriolis.git
> git clone https://github.com/EDCD/coriolis-data.git > git clone https://github.com/EDCD/coriolis-data.git
@@ -29,7 +38,7 @@ You will then have a development server running on `localhost:3300`.
### Ship and Module Database ### Ship and Module Database
See the [Data wiki](https://github.com/cmmcleod/coriolis-data/wiki) for details on structure, etc. See the [Data wiki](https://github.com/EDCD/coriolis-data/wiki) for details on structure, etc.
## Deployment ## Deployment

View File

@@ -3,24 +3,13 @@ var WebpackDevServer = require("webpack-dev-server");
var config = require('./webpack.config.dev'); var config = require('./webpack.config.dev');
new WebpackDevServer(webpack(config), { new WebpackDevServer(webpack(config), {
publicPath: config.output.publicPath,
hot: true, hot: true,
disableHostCheck: true,
headers: { "Access-Control-Allow-Origin": "*" }, headers: { "Access-Control-Allow-Origin": "*" },
historyApiFallback: { historyApiFallback: {
rewrites: [ rewrites: [
// For some reason connect-history-api-fallback does not allow '.' in the URL for history fallback... // For some reason connect-history-api-fallback does not allow '.' in the URL for history fallback...
{ from: /\/outfit\//, to: '/index.html' } { from: /\/outfit\//, to: '/index.html' }
] ]
},
stats: {
assets: true,
colors: true,
version: false,
hash: false,
timings: true,
chunks: false,
chunkModules: false
} }
}).listen(3300, "0.0.0.0", function (err, result) { }).listen(3300, "0.0.0.0", function (err, result) {
if (err) { if (err) {

12992
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,14 +1,19 @@
{ {
"name": "coriolis_shipyard", "name": "coriolis_shipyard",
"version": "3.0.0", "version": "3.0.1",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/EDCD/coriolis" "url": "https://github.com/EDCD/coriolis"
}, },
"homepage": "https://coriolis.io", "homepage": "https://coriolis.io",
"bugs": "https://github.com/EDCD/coriolis/issues", "bugs": "https://github.com/EDCD/coriolis/issues",
"contributors": [
{ "name": "cmdrmcdonald" },
{ "name": "willb321" },
{ "name": "felixlinker" }
],
"private": true, "private": true,
"engine": "node >= 4.8.1", "engine": "node >= 10.13.0",
"license": "MIT", "license": "MIT",
"scripts": { "scripts": {
"extract-translations": "grep -hroE \"(translate\\('[^']+'\\))|(tip.bind\\(null, '[^']+')\" src/* | grep -oE \"'[^']+'\" | grep -oE \"[^']+\" | sort -u -f", "extract-translations": "grep -hroE \"(translate\\('[^']+'\\))|(tip.bind\\(null, '[^']+')\" src/* | grep -oE \"'[^']+'\" | grep -oE \"[^']+\" | sort -u -f",
@@ -18,7 +23,8 @@
"test": "jest", "test": "jest",
"prod-serve": "nginx -p $(pwd) -c nginx.conf", "prod-serve": "nginx -p $(pwd) -c nginx.conf",
"prod-stop": "kill -QUIT $(cat nginx.pid)", "prod-stop": "kill -QUIT $(cat nginx.pid)",
"build": "npm run clean && cross-env NODE_ENV=production webpack -p --config webpack.config.prod.js", "buildfresh": "rimraf node_modules && rm package-lock.json && npm install && npm run build > >(tee -a stdout.log) 2> >(tee -a stderr.log >&2)",
"build": "npm run clean && cross-env NODE_ENV=production webpack --config webpack.config.prod.js",
"rsync": "rsync -ae \"ssh -i $CORIOLIS_PEM\" --delete build/ $CORIOLIS_USER@$CORIOLIS_HOST:~/wwws", "rsync": "rsync -ae \"ssh -i $CORIOLIS_PEM\" --delete build/ $CORIOLIS_USER@$CORIOLIS_HOST:~/wwws",
"deploy": "npm run lint && npm test && npm run build && npm run rsync" "deploy": "npm run lint && npm test && npm run build && npm run rsync"
}, },
@@ -55,7 +61,7 @@
] ]
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.0.0", "@babel/core": "^7.20.12",
"@babel/plugin-proposal-class-properties": "^7.0.0", "@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/plugin-proposal-decorators": "^7.0.0", "@babel/plugin-proposal-decorators": "^7.0.0",
"@babel/plugin-proposal-do-expressions": "^7.0.0", "@babel/plugin-proposal-do-expressions": "^7.0.0",
@@ -74,15 +80,12 @@
"@babel/plugin-syntax-import-meta": "^7.0.0", "@babel/plugin-syntax-import-meta": "^7.0.0",
"@babel/preset-env": "^7.0.0", "@babel/preset-env": "^7.0.0",
"@babel/preset-react": "^7.0.0", "@babel/preset-react": "^7.0.0",
"appcache-webpack-plugin": "^1.4.0", "@rollup/plugin-node-resolve": "^15.0.1",
"babel-core": "^7.0.0-bridge.0",
"babel-eslint": "^10.0.1",
"babel-jest": "^23.6.0",
"babel-loader": "^8.0.0", "babel-loader": "^8.0.0",
"copy-webpack-plugin": "^4.5.2", "copy-webpack-plugin": "^10.2.4",
"create-react-class": "^15.6.3", "create-react-class": "^15.6.3",
"cross-env": "^5.2.0", "cross-env": "^5.2.0",
"css-loader": "^1.0.0", "css-loader": "^6.7.3",
"d3-selection": "^1.3.2", "d3-selection": "^1.3.2",
"esdoc": "^1.1.0", "esdoc": "^1.1.0",
"esdoc-custom-theme": "^1.4.2", "esdoc-custom-theme": "^1.4.2",
@@ -93,54 +96,66 @@
"esdoc-standard-plugin": "^1.0.0", "esdoc-standard-plugin": "^1.0.0",
"eslint": "^5.6.0", "eslint": "^5.6.0",
"eslint-plugin-react": "^7.11.1", "eslint-plugin-react": "^7.11.1",
"expose-loader": "^0.7.5", "expose-loader": "^3.1.0",
"express": "^4.16.3", "express": "^4.18.2",
"extract-text-webpack-plugin": "^4.0.0-beta.0", "html-webpack-plugin": "^5.5.0",
"file-loader": "^2.0.0", "jsen": "^0.6.6",
"html-webpack-plugin": "^3.0.7",
"jest-cli": "^23.6.0",
"jsen": "^0.6.4",
"json-loader": "^0.5.4", "json-loader": "^0.5.4",
"less": "^3.8.1", "less": "^3.8.1",
"less-loader": "^4.1.0", "less-loader": "^11.1.0",
"react-addons-perf": "^15.4.2", "mini-css-extract-plugin": "^2.7.2",
"react-container-dimensions": "^1.4.1", "react-container-dimensions": "^1.4.1",
"react-testutils-additions": "^16.0.0", "react-testutils-additions": "^15.0.0",
"react-transition-group": "^2.5.0", "react-transition-group": "^2.5.0",
"rimraf": "^2.6.1", "rimraf": "^4.1.2",
"rollup": "^0.66.2", "rollup": "^3.17.2",
"rollup-plugin-node-resolve": "^3.4.0", "style-loader": "^3.3.1",
"style-loader": "^0.23.0", "uglify-js": "^3.17.4",
"uglify-js": "^3.4.9", "webpack": "^5.75.0",
"url-loader": "^1.1.1", "webpack-cli": "^5.0.1",
"webpack": "^4.20.2", "webpack-dev-server": "^4.11.1",
"webpack-bugsnag-plugins": "^1.2.2", "webpack-merge": "^5.8.0",
"webpack-cli": "^3.1.1", "webpack-notifier": "^1.15.0",
"webpack-dev-server": "^3.1.9", "workbox-cacheable-response": "^6.5.4",
"webpack-notifier": "^1.6.0", "workbox-expiration": "^6.5.4",
"workbox-webpack-plugin": "^3.6.1" "workbox-precaching": "^6.5.4",
"workbox-routing": "^6.5.4",
"workbox-strategies": "^6.5.4",
"workbox-webpack-plugin": "^6.5.4"
}, },
"sideEffects": false, "sideEffects": false,
"dependencies": { "dependencies": {
"@babel/polyfill": "^7.0.0", "assert": "^1.5.0",
"auto-bind": "^5.0.1",
"base64url": "^3.0.1",
"browserify-zlib-next": "^1.0.1", "browserify-zlib-next": "^1.0.1",
"buffer": "^5.7.0",
"classnames": "^2.2.6", "classnames": "^2.2.6",
"constants-browserify": "^1.0.0",
"core-js": "^3.28.0",
"coriolis-data": "../coriolis-data", "coriolis-data": "../coriolis-data",
"crypto-browserify": "^3.12.0",
"d3": "^5.7.0", "d3": "^5.7.0",
"detect-browser": "^3.0.1", "detect-browser": "^3.0.1",
"fbemitter": "^2.1.1", "fbemitter": "^2.1.1",
"https-browserify": "^1.0.0",
"lodash": "^4.17.11", "lodash": "^4.17.11",
"lz-string": "^1.4.4", "lz-string": "^1.4.4",
"pako": "^1.0.6", "os-browserify": "^0.3.0",
"pako": "^2.1.0",
"path-browserify": "^1.0.1",
"prop-types": "^15.6.2", "prop-types": "^15.6.2",
"react": "^15.5.4", "react": "^15.6.2",
"react-dom": "^15.5.4", "react-dom": "^15.6.2",
"react-extras": "^0.7.1",
"react-fuzzy": "^0.5.2", "react-fuzzy": "^0.5.2",
"react-ga": "^2.5.3", "react-ga": "^2.5.3",
"react-number-editor": "Athanasius/react-number-editor.git#miggy", "react-number-editor": "^4.0.3",
"recharts": "^1.2.0", "recharts": "^1.2.0",
"register-service-worker": "^1.5.2", "register-service-worker": "^1.7.2",
"superagent": "^3.8.3" "stream-browserify": "^3.0.0",
"stream-http": "^3.2.0",
"superagent": "^3.8.3",
"url": "^0.11.0",
"vm-browserify": "^1.1.2"
} }
} }

View File

@@ -1,4 +1,4 @@
import nodeResolve from "rollup-plugin-node-resolve"; import nodeResolve from "@rollup/plugin-node-resolve";
export default { export default {
entry: "d3-funcs.js", entry: "d3-funcs.js",

View File

@@ -214,7 +214,7 @@ Options -MultiViews
# </Files> # </Files>
AddType application/x-web-app-manifest+json webapp AddType application/x-web-app-manifest+json webapp
AddType text/cache-manifest appcache manifest # AddType text/cache-manifest appcache manifest
# Media files # Media files
AddType audio/mp4 f4a f4b m4a AddType audio/mp4 f4a f4b m4a

View File

@@ -93,7 +93,7 @@ export default class Coriolis extends React.Component {
_importBuild(r) { _importBuild(r) {
try { try {
// Need to decode and gunzip the data, then build the ship // Need to decode and gunzip the data, then build the ship
const data = zlib.inflate(new Buffer(r.params.data, 'base64'), { to: 'string' }); const data = zlib.inflate(new Buffer.from(r.params.data, 'base64'), { to: 'string' });
const json = JSON.parse(data); const json = JSON.parse(data);
console.info('Ship import data: '); console.info('Ship import data: ');
console.info(json); console.info(json);
@@ -149,13 +149,6 @@ export default class Coriolis extends React.Component {
*/ */
_onError(msg, scriptUrl, line, col, errObj) { _onError(msg, scriptUrl, line, col, errObj) {
console && console.error && console.error(arguments); // eslint-disable-line no-console console && console.error && console.error(arguments); // eslint-disable-line no-console
if (errObj) {
if (errObj instanceof Error) {
bugsnagClient.notify(errObj); // eslint-disable-line
} else if (errObj instanceof String) {
bugsnagClient.notify(msg, errObj); // eslint-disable-line
}
}
this.setState({ this.setState({
error: <ErrorDetails error={{ message: msg, details: { scriptUrl, line, col, error: JSON.stringify(errObj) } }}/>, error: <ErrorDetails error={{ message: msg, details: { scriptUrl, line, col, error: JSON.stringify(errObj) } }}/>,
page: null, page: null,

View File

@@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { autoBind } from 'react-extras'; import autoBind from 'auto-bind';
/** /**
* Announcement component * Announcement component

View File

@@ -4,7 +4,7 @@ import * as ModuleUtils from '../shipyard/ModuleUtils';
import TranslatedComponent from './TranslatedComponent'; import TranslatedComponent from './TranslatedComponent';
import { stopCtxPropagation } from '../utils/UtilityFunctions'; import { stopCtxPropagation } from '../utils/UtilityFunctions';
import cn from 'classnames'; import cn from 'classnames';
import { MountFixed, MountGimballed, MountTurret } from './SvgIcons'; import { CoriolisLogo, MountFixed, MountGimballed, MountTurret } from './SvgIcons';
import FuzzySearch from 'react-fuzzy'; import FuzzySearch from 'react-fuzzy';
const PRESS_THRESHOLD = 500; // mouse/touch down threshold const PRESS_THRESHOLD = 500; // mouse/touch down threshold
@@ -20,6 +20,7 @@ const GRPCAT = {
'cc': 'limpet controllers', 'cc': 'limpet controllers',
'fx': 'limpet controllers', 'fx': 'limpet controllers',
'hb': 'limpet controllers', 'hb': 'limpet controllers',
'mlc': 'limpet controllers',
'pc': 'limpet controllers', 'pc': 'limpet controllers',
'rpl': 'limpet controllers', 'rpl': 'limpet controllers',
'pce': 'passenger cabins', 'pce': 'passenger cabins',
@@ -38,13 +39,17 @@ const GRPCAT = {
'ml': 'lasers', 'ml': 'lasers',
'c': 'projectiles', 'c': 'projectiles',
'mc': 'projectiles', 'mc': 'projectiles',
'advmc': 'projectiles',
'axmc': 'experimental', 'axmc': 'experimental',
'axmce': 'experimental',
'ntp': 'experimental',
'fc': 'projectiles', 'fc': 'projectiles',
'rfl': 'experimental', 'rfl': 'experimental',
'pa': 'projectiles', 'pa': 'projectiles',
'rg': 'projectiles', 'rg': 'projectiles',
'mr': 'ordnance', 'mr': 'ordnance',
'axmr': 'experimental', 'axmr': 'experimental',
'axmre': 'experimental',
'rcpl': 'experimental', 'rcpl': 'experimental',
'dtl': 'experimental', 'dtl': 'experimental',
'tbsc': 'experimental', 'tbsc': 'experimental',
@@ -83,6 +88,8 @@ const GRPCAT = {
// Assists // Assists
'dc': 'flight assists', 'dc': 'flight assists',
'sua': 'flight assists', 'sua': 'flight assists',
// Stabilizers
'ews': 'weapon stabilizers',
}; };
// Order here is the order in which items will be shown in the modules menu // Order here is the order in which items will be shown in the modules menu
const CATEGORIES = { const CATEGORIES = {
@@ -92,7 +99,7 @@ const CATEGORIES = {
'fi': ['fi'], 'fi': ['fi'],
'fuel': ['ft', 'fs'], 'fuel': ['ft', 'fs'],
'hangars': ['fh', 'pv'], 'hangars': ['fh', 'pv'],
'limpet controllers': ['cc', 'fx', 'hb', 'pc', 'rpl'], 'limpet controllers': ['cc', 'fx', 'hb', 'pc', 'rpl', 'mlc'],
'passenger cabins': ['pce', 'pci', 'pcm', 'pcq'], 'passenger cabins': ['pce', 'pci', 'pcm', 'pcq'],
'rf': ['rf'], 'rf': ['rf'],
'shields': ['sg', 'bsg', 'psg', 'scb'], 'shields': ['sg', 'bsg', 'psg', 'scb'],
@@ -101,16 +108,17 @@ const CATEGORIES = {
// Hardpoints // Hardpoints
'lasers': ['pl', 'ul', 'bl'], 'lasers': ['pl', 'ul', 'bl'],
'projectiles': ['mc', 'c', 'fc', 'pa', 'rg'], 'projectiles': ['mc', 'advmc', 'c', 'fc', 'pa', 'rg'],
'ordnance': ['mr', 'tp', 'nl'], 'ordnance': ['mr', 'tp', 'nl'],
// Utilities // Utilities
'sb': ['sb'], 'sb': ['sb'],
'hs': ['hs'], 'hs': ['hs'],
'csl': ['csl'],
'defence': ['ch', 'po', 'ec'], 'defence': ['ch', 'po', 'ec'],
'scanners': ['sc', 'ss', 'cs', 'kw', 'ws'], // Overloaded with internal scanners 'scanners': ['sc', 'ss', 'cs', 'kw', 'ws'], // Overloaded with internal scanners
// Experimental // Experimental
'experimental': ['axmc', 'axmr', 'rfl', 'tbrfl', 'tbsc', 'tbem', 'xs', 'sfn', 'rcpl', 'dtl', 'rsl', 'mahr',], 'experimental': ['axmc', 'axmce', 'axmr', 'axmre', 'ntp','rfl', 'tbrfl', 'tbsc', 'tbem', 'xs', 'sfn', 'rcpl', 'dtl', 'rsl', 'mahr',],
'weapon stabilizers': ['ews'],
// Guardian // Guardian
'guardian': ['gpp', 'gpd', 'gpc', 'ggc', 'gsrp', 'gfsb', 'ghrp', 'gmrp', 'gsc'], 'guardian': ['gpp', 'gpd', 'gpc', 'ggc', 'gsrp', 'gfsb', 'ghrp', 'gmrp', 'gsc'],
@@ -249,6 +257,24 @@ export default class AvailableModulesMenu extends TranslatedComponent {
return { list, currentGroup, fuzzy, trackingFocus }; return { list, currentGroup, fuzzy, trackingFocus };
} }
/**
* Return Is expiremental capacity reached
* @return {boolean} Is experimental capacity reached
*/
_experimentalCapacityReached() {
const ship = this.props.ship;
const ews = ship.internal.filter(o => o.m && o.m.grp === 'ews');
let expCap;
if(ews.length < 1){
expCap = 4;
} else{
expCap = ews[0].m.class == 3 ? 5 : 6;
}
return expCap <= this.props.ship.hardpoints.filter(o => o.m && o.m.experimental).length;
}
/** /**
* Generate React Components for Module Group * Generate React Components for Module Group
* @param {Ship} ship Ship the selection is for * @param {Ship} ship Ship the selection is for
@@ -285,7 +311,9 @@ export default class AvailableModulesMenu extends TranslatedComponent {
// If the mounted module is experimental as well, we can replace it so // If the mounted module is experimental as well, we can replace it so
// the maximum does not apply // the maximum does not apply
} else if (m.experimental && (!mountedModule || !mountedModule.experimental)) { } else if (m.experimental && (!mountedModule || !mountedModule.experimental)) {
disabled = 4 <= ship.hardpoints.filter(o => o.m && o.m.experimental).length; disabled = this._experimentalCapacityReached();
} else if (m.grp === 'mlc' && (!mountedModule || mountedModule.grp !== 'mlc')) {
disabled = 1 <= ship.internal.filter(o => o.m && o.m.grp === 'mlc').length;
} }
let active = mountedModule && mountedModule.id === m.id; let active = mountedModule && mountedModule.id === m.id;
let classes = cn(m.name ? 'lc' : 'c', { let classes = cn(m.name ? 'lc' : 'c', {
@@ -382,6 +410,7 @@ export default class AvailableModulesMenu extends TranslatedComponent {
if (this.props.modules instanceof Array) { if (this.props.modules instanceof Array) {
return; return;
} }
const mountedModule = this.props.m;
return ( return (
<FuzzySearch <FuzzySearch
list={this.state.fuzzy} list={this.state.fuzzy}
@@ -393,11 +422,20 @@ export default class AvailableModulesMenu extends TranslatedComponent {
onSelect={e => this.props.onSelect.bind(null, e.m)()} onSelect={e => this.props.onSelect.bind(null, e.m)()}
resultsTemplate={(props, state, styles, clickHandler) => { resultsTemplate={(props, state, styles, clickHandler) => {
return state.results.map((val, i) => { return state.results.map((val, i) => {
let disabled;
if(val.m.experimental && (!mountedModule || !mountedModule.experimental)) {
disabled = this._experimentalCapacityReached();
} else{
disabled = false;
}
const handler = disabled ? null : () => clickHandler(i);
return ( return (
<div <div
key={i} key={i}
className={'lc'} className={cn('lc', {disabled})}
onClick={() => clickHandler(i)} onClick={handler}
> >
{val.name} {val.name}
</div> </div>
@@ -516,6 +554,15 @@ export default class AvailableModulesMenu extends TranslatedComponent {
return 1; return 1;
} }
} }
// Sort multi limpet controllers by name
if (a.grp === 'mlc') {
if (a.name[0] <= b.name[0]) {
return -1;
}
if (a.name[0] > b.name[0]) {
return 1;
}
}
// Rating ordered from highest (A) to lowest (E) // Rating ordered from highest (A) to lowest (E)
if (a.rating < b.rating) { if (a.rating < b.rating) {
return -1; return -1;

View File

@@ -32,7 +32,7 @@ export default class CostSection extends TranslatedComponent {
this._buildRetrofitShip = this._buildRetrofitShip.bind(this); this._buildRetrofitShip = this._buildRetrofitShip.bind(this);
this._onBaseRetrofitChange = this._onBaseRetrofitChange.bind(this); this._onBaseRetrofitChange = this._onBaseRetrofitChange.bind(this);
this._defaultRetrofitName = this._defaultRetrofitName.bind(this); this._defaultRetrofitName = this._defaultRetrofitName.bind(this);
this._eddbShoppingList = this._eddbShoppingList.bind(this); this._eddbShoppingList = this._inaraShoppingList.bind(this);
let data = Ships[props.ship.id]; // Retrieve the basic ship properties, slots and defaults let data = Ships[props.ship.id]; // Retrieve the basic ship properties, slots and defaults
let retrofitName = this._defaultRetrofitName(props.ship.id, props.buildName); let retrofitName = this._defaultRetrofitName(props.ship.id, props.buildName);
@@ -328,9 +328,9 @@ export default class CostSection extends TranslatedComponent {
} }
/** /**
* Open up a window for EDDB with a shopping list of our retrofit components * Open up a window for inara with a shopping list of our retrofit components
*/ */
_eddbShoppingList() { _inaraShoppingList() {
const { retrofitCosts } = this.state; const { retrofitCosts } = this.state;
const { ship } = this.props; const { ship } = this.props;
@@ -338,7 +338,7 @@ export default class CostSection extends TranslatedComponent {
const modIds = retrofitCosts.filter(item => item.retroItem.incCost && item.buyId && !item.buyPp).map(item => item.buyId).filter((v, i, a) => a.indexOf(v) === i); const modIds = retrofitCosts.filter(item => item.retroItem.incCost && item.buyId && !item.buyPp).map(item => item.buyId).filter((v, i, a) => a.indexOf(v) === i);
// Open up the relevant URL // Open up the relevant URL
window.open('https://eddb.io/station?m=' + modIds.join(',')); window.open('https://inara.cz/inapi/corisearch.php?m=' + modIds.join(','));
} }
/** /**
@@ -387,7 +387,7 @@ export default class CostSection extends TranslatedComponent {
<tbody> <tbody>
{rows} {rows}
<tr className='ri'> <tr className='ri'>
<td className='lbl' ><button onClick={this._eddbShoppingList} onMouseOver={termtip.bind(null, 'PHRASE_REFIT_SHOPPING_LIST')} onMouseOut={tooltip.bind(null, null)}><ShoppingIcon className='lg' style={{ fill: 'black' }}/></button></td> <td className='lbl' ><button onClick={this._inaraShoppingList} onMouseOver={termtip.bind(null, 'PHRASE_REFIT_SHOPPING_LIST')} onMouseOut={tooltip.bind(null, null)}><ShoppingIcon className='lg' style={{ fill: 'black' }}/></button></td>
<td colSpan='3' className='lbl' >{translate('cost')}</td> <td colSpan='3' className='lbl' >{translate('cost')}</td>
<td colSpan='2' className={cn('val', retrofitTotal > 0 ? 'warning' : 'secondary-disabled')} style={{ borderBottom:'none' }}> <td colSpan='2' className={cn('val', retrofitTotal > 0 ? 'warning' : 'secondary-disabled')} style={{ borderBottom:'none' }}>
{int(retrofitTotal)}{units.CR} {int(retrofitTotal)}{units.CR}

View File

@@ -3,6 +3,8 @@ import PropTypes from 'prop-types';
import TranslatedComponent from './TranslatedComponent'; import TranslatedComponent from './TranslatedComponent';
import request from 'superagent'; import request from 'superagent';
import Persist from '../stores/Persist'; import Persist from '../stores/Persist';
const zlib = require('zlib');
const base64url = require('base64url');
/** /**
* Permalink modal * Permalink modal
@@ -56,7 +58,6 @@ export default class ModalShoppingList extends TranslatedComponent {
continue; continue;
} }
if (module.m.blueprint.special) { if (module.m.blueprint.special) {
console.log(module.m.blueprint.special);
blueprints.push({ uuid: module.m.blueprint.special.uuid, number: 1 }); blueprints.push({ uuid: module.m.blueprint.special.uuid, number: 1 });
} }
for (const g in module.m.blueprint.grades) { for (const g in module.m.blueprint.grades) {
@@ -146,6 +147,64 @@ export default class ModalShoppingList extends TranslatedComponent {
} }
} }
/**
* Send all blueprints to EDOMH. This is a modified copy of registerBPs because this.state.blueprints was empty when I tried to modify sendToEDEng and I couldn't figure out why
* @param {Event} event React event
*/
sendToEDOMH(event) {
event.preventDefault();
const ship = this.props.ship;
let blueprints = [];
//create the json
for (const module of ship.costList) {
if (module.type === 'SHIP') {
continue;
}
if (module.m && module.m.blueprint) {
if (!module.m.blueprint.grade || !module.m.blueprint.grades) {
continue;
}
if (module.m.blueprint.special) {
blueprints.push({
"item": module.m.symbol,
"blueprint": module.m.blueprint.special.edname
});
}
for (const g in module.m.blueprint.grades) {
if (!module.m.blueprint.grades.hasOwnProperty(g)) {
continue;
}
if (g < module.m.blueprint.grade) {
continue;
}
blueprints.push({
"item": module.m.symbol,
"blueprint": module.m.blueprint.fdname,
"grade": module.m.blueprint.grade,
"highestGradePercentage":1.0
});
}
}
}
//create JSON to encode
let baseJson = {
"version":1,
"name":ship.name, // TO-DO: Import build name and put that here correctly
"items": blueprints
}
let JSONString = JSON.stringify(baseJson)
let deflated = zlib.deflateSync(JSONString)
//actually encode
let link = base64url.encode(deflated)
link = "edomh://coriolis/?" + link;
window.open(link, "_self")
}
/** /**
* Convert mats object to string * Convert mats object to string
*/ */
@@ -177,6 +236,18 @@ export default class ModalShoppingList extends TranslatedComponent {
mats[i] = module.m.blueprint.grades[g].components[i] * this.state.matsPerGrade[g]; mats[i] = module.m.blueprint.grades[g].components[i] * this.state.matsPerGrade[g];
} }
} }
if (module.m.blueprint.special) {
for (const j in module.m.blueprint.special.components) {
if (!module.m.blueprint.special.components.hasOwnProperty(j)) {
continue;
}
if (mats[j]) {
mats[j] += module.m.blueprint.special.components[j];
} else {
mats[j] = module.m.blueprint.special.components[j];
}
}
}
} }
} }
} }
@@ -229,6 +300,7 @@ export default class ModalShoppingList extends TranslatedComponent {
const compatible = this.checkBrowserIsCompatible(); const compatible = this.checkBrowserIsCompatible();
this.cmdrChangeHandler = this.cmdrChangeHandler.bind(this); this.cmdrChangeHandler = this.cmdrChangeHandler.bind(this);
this.sendToEDEng = this.sendToEDEng.bind(this); this.sendToEDEng = this.sendToEDEng.bind(this);
this.sendToEDOMH = this.sendToEDOMH.bind(this);
return <div className='modal' onClick={ (e) => e.stopPropagation() }> return <div className='modal' onClick={ (e) => e.stopPropagation() }>
<h2>{translate('PHRASE_SHOPPING_MATS')}</h2> <h2>{translate('PHRASE_SHOPPING_MATS')}</h2>
<label>{translate('Grade 1 rolls ')}</label> <label>{translate('Grade 1 rolls ')}</label>
@@ -257,6 +329,7 @@ export default class ModalShoppingList extends TranslatedComponent {
<p hidden={!this.state.failed} id={'failed'} className={'l'}>{translate('PHRASE_FAIL_EDENGINEER')}</p> <p hidden={!this.state.failed} id={'failed'} className={'l'}>{translate('PHRASE_FAIL_EDENGINEER')}</p>
<p hidden={compatible} id={'browserbad'} className={'l'}>{translate('PHRASE_FIREFOX_EDENGINEER')}</p> <p hidden={compatible} id={'browserbad'} className={'l'}>{translate('PHRASE_FIREFOX_EDENGINEER')}</p>
<button className={'l cb dismiss cap'} disabled={!!this.state.failed || !compatible} onClick={this.sendToEDEng}>{translate('Send to EDEngineer')}</button> <button className={'l cb dismiss cap'} disabled={!!this.state.failed || !compatible} onClick={this.sendToEDEng}>{translate('Send to EDEngineer')}</button>
<button style={{marginTop: 5}} className={'l cb dismiss cap'} disabled={!!this.state.failed} onClick={this.sendToEDOMH}>{translate('Send to EDOMH')}</button>
<button className={'r dismiss cap'} onClick={this.context.hideModal}>{translate('close')}</button> <button className={'r dismiss cap'} onClick={this.context.hideModal}>{translate('close')}</button>
</div>; </div>;
} }

View File

@@ -2,7 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import TranslatedComponent from './TranslatedComponent'; import TranslatedComponent from './TranslatedComponent';
import { Pip } from './SvgIcons'; import { Pip } from './SvgIcons';
import { autoBind } from 'react-extras'; import autoBind from 'auto-bind';
/** /**
* Pips displays SYS/ENG/WEP pips and allows users to change them with key presses by clicking on the relevant area. * Pips displays SYS/ENG/WEP pips and allows users to change them with key presses by clicking on the relevant area.

View File

@@ -8,6 +8,7 @@ import * as RU from './ru';
import * as PL from './pl'; import * as PL from './pl';
import * as PT from './pt'; import * as PT from './pt';
import * as CN from './cn'; import * as CN from './cn';
import * as KO from './ko';
import * as d3 from 'd3'; import * as d3 from 'd3';
let fallbackTerms = EN.terms; let fallbackTerms = EN.terms;
@@ -29,6 +30,7 @@ export function getLanguage(langCode) {
case 'pl': lang = PL; break; case 'pl': lang = PL; break;
case 'pt': lang = PT; break; case 'pt': lang = PT; break;
case 'cn': lang = CN; break; case 'cn': lang = CN; break;
case 'ko': lang = KO; break;
default: default:
lang = EN; lang = EN;
} }
@@ -97,5 +99,6 @@ export const Languages = {
ru: 'ру́сский', ru: 'ру́сский',
pl: 'polski', pl: 'polski',
pt: 'português', pt: 'português',
cn: '中文' cn: '中文',
ko: '한국어'
}; };

View File

@@ -398,6 +398,7 @@
"No modded components.": "没有改装的部件", "No modded components.": "没有改装的部件",
"Sending...": "发送中...", "Sending...": "发送中...",
"Send to EDEngineer": "发送至EDEngineer", "Send to EDEngineer": "发送至EDEngineer",
"Send to EDOMH": "发送至EDOMH",
"PHASE_UPLOAD_ORBIS": "上传到orbis.zone测试阶段", "PHASE_UPLOAD_ORBIS": "上传到orbis.zone测试阶段",
"orbis username": "orbis.zone的Email或用户名", "orbis username": "orbis.zone的Email或用户名",
"orbis password": "orbis.zone的密码", "orbis password": "orbis.zone的密码",

View File

@@ -93,6 +93,7 @@
"ch": "Chaff Launcher", "ch": "Chaff Launcher",
"cr": "Cargo Rack", "cr": "Cargo Rack",
"cs": "Manifest Scanner", "cs": "Manifest Scanner",
"csl": "Caustic Sink Launcher",
"dc": "Docking Computer", "dc": "Docking Computer",
"ec": "Electronic Countermeasure", "ec": "Electronic Countermeasure",
"fc": "Fragment Cannon", "fc": "Fragment Cannon",
@@ -108,10 +109,15 @@
"kw": "Kill Warrant Scanner", "kw": "Kill Warrant Scanner",
"ls": "Life Support", "ls": "Life Support",
"mc": "Multi-cannon", "mc": "Multi-cannon",
"advmc": "Multi-cannon (Advanced)",
"axmc": "AX Multi-cannon", "axmc": "AX Multi-cannon",
"axmce": "AX Multi-cannon (Enhanced)",
"ml": "Mining Laser", "ml": "Mining Laser",
"mlc": "Multi Limpet Controller",
"mr": "Missile Rack", "mr": "Missile Rack",
"axmr": "AX Missile Rack", "axmr": "AX Missile Rack",
"axmre": "AX Missile Rack (Enhanced)",
"ews": "Experimental Weapon Stabilizer",
"mrp": "Module Reinforcement Package", "mrp": "Module Reinforcement Package",
"nl": "Mine Launcher", "nl": "Mine Launcher",
"pa": "Plasma Accelerator", "pa": "Plasma Accelerator",
@@ -156,8 +162,10 @@
"sua": "Supercruise Assist", "sua": "Supercruise Assist",
"t": "thrusters", "t": "thrusters",
"tp": "Torpedo Pylon", "tp": "Torpedo Pylon",
"ntp": "Nanite Torpedo Pylon",
"ul": "Burst Laser", "ul": "Burst Laser",
"Send To EDEngineer": "Send To EDEngineer", "Send To EDEngineer": "Send To EDEngineer",
"Send To EDOMH": "Send To EDOMH",
"ws": "Frame Shift Wake Scanner", "ws": "Frame Shift Wake Scanner",
"rpl": "Repair Limpet Controller", "rpl": "Repair Limpet Controller",
"rcpl": "Recon Limpet Controller", "rcpl": "Recon Limpet Controller",

16
src/app/i18n/ko.js Normal file
View File

@@ -0,0 +1,16 @@
export const formats = {
decimal: '.',
thousands: ',',
grouping: [3],
currency: ['₩', ''],
dateTime: '%a %b %e %X %Y',
date: '%Y/%m/%d',
time: '%H:%M:%S',
periods: ['오전', '오후'],
days: ['일요일', '월요일', '화요일', '수요일', '목요일', '금요일', '토요일'],
shortDays: ['일', '월', '화', '수', '목', '금', '토'],
months: ['1월', '2월', '3월', '4월', '5월', '6월', '7월', '8월', '9월', '10월', '11월', '12월'],
shortMonths: ['1월', '2월', '3월', '4월', '5월', '6월', '7월', '8월', '9월', '10월', '11월', '12월']
};
export { default as terms } from './ko.json';

369
src/app/i18n/ko.json Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -13,7 +13,7 @@
"PHRASE_SG_RECOVER": "Восстановление с 0% до 50% объема щита, учитывая полный аккумулятор СИС в начале", "PHRASE_SG_RECOVER": "Восстановление с 0% до 50% объема щита, учитывая полный аккумулятор СИС в начале",
"PHRASE_UNLADEN": "Масса корабля без учета топлива и грузов", "PHRASE_UNLADEN": "Масса корабля без учета топлива и грузов",
"PHRASE_UPDATE_RDY": "Доступна новая версия. Нажмите для обновления.", "PHRASE_UPDATE_RDY": "Доступна новая версия. Нажмите для обновления.",
"PHRASE_ENGAGEMENT_RANGE": "Дистанция между кораблем и целью", "PHRASE_ENGAGEMENT_RANGE": "Дистанция между кораблём и целью",
"PHRASE_SELECT_BLUEPRINT": "Нажмите чтобы выбрать чертеж", "PHRASE_SELECT_BLUEPRINT": "Нажмите чтобы выбрать чертеж",
"PHRASE_BLUEPRINT_WORST": "Худшие основные значения для чертежа", "PHRASE_BLUEPRINT_WORST": "Худшие основные значения для чертежа",
"PHRASE_BLUEPRINT_FIFTY": "50% значения для чертежа", "PHRASE_BLUEPRINT_FIFTY": "50% значения для чертежа",
@@ -24,9 +24,9 @@
"PHRASE_BLUEPRINT_RESET": "Сбросить все модификаторы и чертеж", "PHRASE_BLUEPRINT_RESET": "Сбросить все модификаторы и чертеж",
"PHRASE_SELECT_SPECIAL": "Нажмите, чтобы выбрать экспериментальный эффект", "PHRASE_SELECT_SPECIAL": "Нажмите, чтобы выбрать экспериментальный эффект",
"PHRASE_NO_SPECIAL": "Без экспериментального эффекта", "PHRASE_NO_SPECIAL": "Без экспериментального эффекта",
"PHRASE_SHOPPING_LIST": "Станции, что продают эту сборку", "PHRASE_SHOPPING_LIST": "Станции, на которых продают эту сборку",
"PHRASE_SHOPPING_MATS": "Материалы которые нужны для сборки", "PHRASE_SHOPPING_MATS": "Материалы которые нужны для сборки",
"PHRASE_REFIT_SHOPPING_LIST": "Станции, что продают необходимые модули", "PHRASE_REFIT_SHOPPING_LIST": "Станции, на которых продают необходимые модули",
"PHRASE_TOTAL_EFFECTIVE_SHIELD": "Общий урон, что может быть нанесен в каждым типе, если используются все щитонакопители", "PHRASE_TOTAL_EFFECTIVE_SHIELD": "Общий урон, что может быть нанесен в каждым типе, если используются все щитонакопители",
"PHRASE_TIME_TO_LOSE_SHIELDS": "Щиты продержатся", "PHRASE_TIME_TO_LOSE_SHIELDS": "Щиты продержатся",
"PHRASE_TIME_TO_RECOVER_SHIELDS": "Щиты восстановятся за", "PHRASE_TIME_TO_RECOVER_SHIELDS": "Щиты восстановятся за",
@@ -37,36 +37,36 @@
"PHRASE_EFFECTIVE_ARMOUR": "Эффективная сила брони против разных типов урона", "PHRASE_EFFECTIVE_ARMOUR": "Эффективная сила брони против разных типов урона",
"PHRASE_DAMAGE_TAKEN": "% общих повреждений полученных в разных типах урона", "PHRASE_DAMAGE_TAKEN": "% общих повреждений полученных в разных типах урона",
"PHRASE_TIME_TO_LOSE_ARMOUR": "Броня продержится", "PHRASE_TIME_TO_LOSE_ARMOUR": "Броня продержится",
"PHRASE_MODULE_PROTECTION_EXTERNAL": "Защита гнезд", "PHRASE_MODULE_PROTECTION_EXTERNAL": "Защита гнёзд",
"PHRASE_MODULE_PROTECTION_INTERNAL": "Защита всех остальных модулей", "PHRASE_MODULE_PROTECTION_INTERNAL": "Защита всех остальных модулей",
"PHRASE_OVERALL_DAMAGE": "Разбивка источников устойчивого ДПС", "PHRASE_OVERALL_DAMAGE": "Разбивка источников устойчивого УвС",
"PHRASE_SHIELD_DAMAGE": "Подробности источников поддерживаемого ДПС против щитов", "PHRASE_SHIELD_DAMAGE": "Подробности источников поддерживаемого УвС против щитов",
"PHRASE_ARMOUR_DAMAGE": "Подробности источников поддерживаемого ДПС против брони", "PHRASE_ARMOUR_DAMAGE": "Подробности источников поддерживаемого УвС против брони",
"PHRASE_TIME_TO_REMOVE_SHIELDS": "Снимет щиты за", "PHRASE_TIME_TO_REMOVE_SHIELDS": "Снимет щиты за",
"PHRASE_MULTI_CREW_CAPACITOR_POINTS": "Щелкните правой кновкой мыши чтобы объединить в группу.", "PHRASE_MULTI_CREW_CAPACITOR_POINTS": "Щелкните правой кновкой мыши чтобы объединить в группу.",
"TT_TIME_TO_REMOVE_SHIELDS": "Непрерывным огнем из всех орудий", "TT_TIME_TO_REMOVE_SHIELDS": "Непрерывным огнём из всех орудий",
"PHRASE_TIME_TO_REMOVE_ARMOUR": "Снимет броню за", "PHRASE_TIME_TO_REMOVE_ARMOUR": "Снимет броню за",
"TT_TIME_TO_REMOVE_ARMOUR": "Непрерывным огнем из всех орудий", "TT_TIME_TO_REMOVE_ARMOUR": "Непрерывным огнём из всех орудий",
"PHRASE_TIME_TO_DRAIN_WEP": "Опустошит ОРУ за", "PHRASE_TIME_TO_DRAIN_WEP": "Опустошит ОРУ за",
"TT_TIME_TO_DRAIN_WEP": "Время, за которое опустошится аккумулятор ОРУ при стрельбе из всех орудий", "TT_TIME_TO_DRAIN_WEP": "Время, за которое опустошится аккумулятор ОРУ при стрельбе из всех орудий",
"TT_TIME_TO_LOSE_SHIELDS": "Против поддерживаемой стрельбы из всех орудий противника", "TT_TIME_TO_LOSE_SHIELDS": "Против поддерживаемой стрельбы из всех орудий противника",
"TT_TIME_TO_LOSE_ARMOUR": "Против поддерживаемой стрельбы из всех орудий противника", "TT_TIME_TO_LOSE_ARMOUR": "Против поддерживаемой стрельбы из всех орудий противника",
"TT_MODULE_ARMOUR": "Броня, защищающая модули от урона", "TT_MODULE_ARMOUR": "Броня, защищающая модули от урона",
"TT_MODULE_PROTECTION_EXTERNAL": "Процент урона, перенаправленного от гнезд на наборы для усиления модулей", "TT_MODULE_PROTECTION_EXTERNAL": "Процент урона, перенаправленного от гнезд на наборы для усиления модулей",
"TT_MODULE_PROTECTION_INTERNAL": "Процент урона, перенаправленного от модулей вне гнезд на наборы для усиления модулей", "TT_MODULE_PROTECTION_INTERNAL": "Процент урона, перенаправленного от модулей вне гнёзд на наборы для усиления модулей",
"TT_EFFECTIVE_SDPS_SHIELDS": "Реальный поддерживаемый ДПС пока аккумулятор ОРУ не пуст", "TT_EFFECTIVE_SDPS_SHIELDS": "Реальный поддерживаемый УвС пока ёмкость ОРУ не пуста",
"TT_EFFECTIVENESS_SHIELDS": "Эффективность в сравнении с попаданием по цели с 0-сопротивляемостью без пунктов в СИС на 0 метрах", "TT_EFFECTIVENESS_SHIELDS": "Эффективность в сравнении с попаданием по цели с 0-сопротивляемостью без пунктов в СИС на 0 метрах",
"TT_EFFECTIVE_SDPS_ARMOUR": "Реальный поддерживаемый ДПС пока аккумулятор ОРУ не пуст", "TT_EFFECTIVE_SDPS_ARMOUR": "Реальный поддерживаемый УвС пока аккумулятор ОРУ не пуст",
"TT_EFFECTIVENESS_ARMOUR": "Эффективность в сравнении с попаданием по цели с 0-сопротивляемостью на 0 метрах", "TT_EFFECTIVENESS_ARMOUR": "Эффективность в сравнении с попаданием по цели с 0-сопротивляемостью на 0 метрах",
"PHRASE_EFFECTIVE_SDPS_SHIELDS": ДПС против щитов", "PHRASE_EFFECTIVE_SDPS_SHIELDS": УвС против щитов",
"PHRASE_EFFECTIVE_SDPS_ARMOUR": ДПС против брони", "PHRASE_EFFECTIVE_SDPS_ARMOUR": УвС против брони",
"TT_SUMMARY_SPEED": "С полным топливным баком и 4 пунктами в ДВГ", "TT_SUMMARY_SPEED": "С полным топливным баком и 4 пунктами в ДВГ",
"TT_SUMMARY_SPEED_NONFUNCTIONAL": "Маневровые двигатели выключены или превышена максимальная масса с топливом и грузом", "TT_SUMMARY_SPEED_NONFUNCTIONAL": "Маневровые двигатели выключены или превышена максимальная масса с топливом и грузом",
"TT_SUMMARY_BOOST": "С полным топливным баком и 4 пунктами в ДВГ", "TT_SUMMARY_BOOST": "С полным топливным баком и 4 пунктами в ДВГ",
"TT_SUMMARY_BOOST_INTERVAL": "Время заполнения с 4 пунктами в СИС", "TT_SUMMARY_BOOST_INTERVAL": "Время заполнения с 4 пунктами в СИС",
"TT_SUMMARY_BOOST_NONFUNCTIONAL": "Распределитель питания не может обеспечить достаточно энергии для форсажа", "TT_SUMMARY_BOOST_NONFUNCTIONAL": "Распределитель питания не может обеспечить достаточно энергии для форсажа",
"TT_SUMMARY_SHIELDS": "Чистая сила щита, включая усилители", "TT_SUMMARY_SHIELDS": "Чистая сила щита, включая усилители",
"TT_SUMMARY_SHIELDS_SCB": "Прочность щита, включая бустеры и SCB", "TT_SUMMARY_SHIELDS_SCB": "Прочность щита, включая бустеры и щитонакопители",
"TT_SUMMARY_SHIELDS_NONFUNCTIONAL": "Шитогенератор отсутствует или выключен", "TT_SUMMARY_SHIELDS_NONFUNCTIONAL": "Шитогенератор отсутствует или выключен",
"TT_SUMMARY_INTEGRITY": "Целостность корабля, включая переборки и наборы для усиления корпуса", "TT_SUMMARY_INTEGRITY": "Целостность корабля, включая переборки и наборы для усиления корпуса",
"TT_SUMMARY_HULL_MASS": "Масса корпуса без каких-либо модулей", "TT_SUMMARY_HULL_MASS": "Масса корпуса без каких-либо модулей",
@@ -88,22 +88,23 @@
"bl": "Пучковый лазер", "bl": "Пучковый лазер",
"bsg": "Двухпоточный щитогенератор", "bsg": "Двухпоточный щитогенератор",
"c": "Пушка", "c": "Пушка",
"causres": "Каустическое сопротивление", "causres": "Сопротивление едк.урону",
"Caustic resistance": "Каустическое сопротивление", "Caustic resistance": "Сопротивление едк.урону",
"cc": "Контроллер магнитного снаряда для сбора", "cc": "Контроллер дронов-сборщиков",
"ch": "Разбрасыватель дипольных отражателей", "ch": "Разбрасыватель дипольных отражателей",
"cr": "Грузовой стеллаж", "cr": "Грузовой стеллаж",
"cs": "Сканер содержимого", "cs": "Сканер содержимого",
"csl": "Антикор катапульта",
"dc": "Стыковочный компьютер", "dc": "Стыковочный компьютер",
"ec": "Электр. противодействие", "ec": "Радиоэлектронное подавление",
"fc": "Залповое орудие", "fc": "Залповое орудие",
"fh": "Ангар для истребителя", "fh": "Ангар для истребителя",
"fi": "FSD-перехватчик", "fi": "FSD-перехватчик",
"fs": "Топливозаборник", "fs": "Топливозаборник",
"fsd": "Рамочно-сместительный двигатель", "fsd": "Рамочно-сместительный двигатель",
"ft": "Топливный бак", "ft": "Топливный бак",
"fx": "Контроллер магнитного снаряда для топлива", "fx": "Контроллер дронов-заправщиков",
"hb": "Контроллер магнитного снаряда для взлома трюма", "hb": "Контроллер дронов-взломщиков трюмов",
"hr": "Набор для усиления корпуса", "hr": "Набор для усиления корпуса",
"hs": "Теплоотводная катапульта", "hs": "Теплоотводная катапульта",
"kw": "Сканер преступников", "kw": "Сканер преступников",
@@ -111,13 +112,14 @@
"mc": "Многоствольное орудие", "mc": "Многоствольное орудие",
"axmc": "Многоствольное орудие АИ", "axmc": "Многоствольное орудие АИ",
"ml": "Проходочный лазер", "ml": "Проходочный лазер",
"mr": "Ракетный лоток", "mr": "Блок ракет",
"axmr": "Блок ракет АИ", "axmr": "Блок ракет АИ",
"ews": "Стабилизатор экспериментального вооружения",
"mrp": "Набор для усиления модуля", "mrp": "Набор для усиления модуля",
"nl": "Мины", "nl": "Мины",
"pa": "Ускоритель плазмы", "pa": "Ускоритель плазмы",
"pas": "Комплект для сближения с планетой", "pas": "Комплект для сближения с планетой",
"pc": "Контроллер магнитного снаряда для геологоразведки", "pc": "Контроллер дронов-геологоразведчиков",
"pce": "Каюта пассажира эконом-класса", "pce": "Каюта пассажира эконом-класса",
"passenger capacity": "Количество пассажиров", "passenger capacity": "Количество пассажиров",
"pci": "Каюта пассажира бизнес-класса", "pci": "Каюта пассажира бизнес-класса",
@@ -143,36 +145,38 @@
"gsc": "Осколочное орудие Стражей", "gsc": "Осколочное орудие Стражей",
"psg": "Призматический щитогенератор", "psg": "Призматический щитогенератор",
"pv": "Гараж для планетарного транспорта", "pv": "Гараж для планетарного транспорта",
"rf": "Устройство переработки", "rf": "Очиститель",
"rfl": "Зенитная установка (снаряды с дистанционным подрывом)", "rfl": "Зенитная установка (снаряды с дистанционным подрывом)",
"rg": "Электромагнитная пушка", "rg": "Рельсотрон",
"rsl": "Дроны-исследователи", "rsl": "Контроллер дронов-исследователей",
"s": "Сенсоры", "s": "Сенсоры",
"sb": "Усилитель щита", "sb": "Усилитель щита",
"sc": "Сканер обнаружения", "sc": "Сканер обнаружения",
"scb": "Щитонакопитель", "scb": "Щитонакопитель",
"sfn": "Нейтрализатор глушащего поля", "sfn": "Нейтрализатор отключающего поля",
"sg": "Щитогенератор", "sg": "Щитогенератор",
"ss": "Сканер поверхностей", "ss": "Сканер поверхностей",
"sua": "Помощь в гиперкрейсерском режиме", "sua": "Помощь в гиперкрейсерском режиме",
"t": "Маневровые двигатели", "t": "Маневровые двигатели",
"tp": "Торпедная стойка", "tp": "Торпедная установка",
"ul": "Пульсирующие лазеры", "ul": "Пульсирующий лазер",
"Send To EDEngineer": "Отправить в EDEngineer", "Send To EDEngineer": "Отправить в EDEngineer",
"Send To EDOMH": "Отправить в EDOMH",
"ws": "Сканер следа FSD", "ws": "Сканер следа FSD",
"rpl": "Дроны-ремонтники", "rpl": "Контроллер дронов-ремонтников",
"rcpl": "Дроны-разведчики", "rcpl": "Контроллер дронов-разведчиков",
"xs": "Сканер «инопланетянин»", "xs": "Ксено-сканер",
"tbem": "Блок энзимных ракет", "tbem": "Блок энзимных ракет",
"tbrfl": "Установка для стрельбы стреловидными снарядами с дистанционным подрывом", "tbrfl": "Установка для стрельбы стреловидными снарядами с дистанционным подрывом",
"dtl": "Дроны-очистители", "dtl": "Контроллер дронов-очистителей",
"mahr": "Набор для усиления корпуса из Метасплава", "mlc": "Мультиконтроллер",
"mahr": "Метасплавное усиление корпуса",
"emptyrestricted": "пусто (ограниченно)", "emptyrestricted": "пусто (ограниченно)",
"damage dealt to": "Урон нанесен", "damage dealt to": "Урон нанесён",
"damage received from": "Урон получен от", "damage received from": "Урон получен от",
"against shields": "Против щитов", "against shields": "Против щитов",
"against hull": "Против корпуса", "against hull": "Против корпуса",
"total effective shield": "Общие эффективные щиты", "total effective shield": "Общая эффективность щита",
"ammunition": "Припасы", "ammunition": "Припасы",
"secs": "с", "secs": "с",
"bays": "Ячейки", "bays": "Ячейки",
@@ -201,7 +205,7 @@
"shield cells": "Щитонакопители", "shield cells": "Щитонакопители",
"recovery": "включение", "recovery": "включение",
"recharge": "перезарядка", "recharge": "перезарядка",
"engine pips": "Пункты в двигателе", "engine pips": "Ячейки питания на ДВГ",
"4b": "4 пункта и Форсаж", "4b": "4 пункта и Форсаж",
"speed": "скорость", "speed": "скорость",
"pitch": "Тангаж", "pitch": "Тангаж",
@@ -287,12 +291,12 @@
"explosive": "Взрывч.", "explosive": "Взрывч.",
"kinetic": "Механич.", "kinetic": "Механич.",
"thermal": "Тепл.", "thermal": "Тепл.",
"caustic": "Каустич.", "caustic": "Едкий",
"generator": "Генератор", "generator": "Генератор",
"boosters": "Усилители", "boosters": "Усилители",
"cells": "Ячейки", "cells": "Ячейки",
"shield addition": Обавления к щиту", "shield addition": обавления к щиту",
"jump addition": Обавления к прыжку", "jump addition": обавления к прыжку",
"bulkheads": "Переборки", "bulkheads": "Переборки",
"reinforcement": "Усилители", "reinforcement": "Усилители",
"power and costs": "Энергия и стоимость", "power and costs": "Энергия и стоимость",
@@ -374,9 +378,9 @@
"/s": "/с", "/s": "/с",
"/min": "/мин", "/min": "/мин",
"m/s": "м/с", "m/s": "м/с",
"Ls": "Св.сек", "Ls": "Св.с",
"LY": "Св.лет", "LY": "Св.лет",
"CR": "кр.", "CR": "КР.",
"S": "М", "S": "М",
"M": "С", "M": "С",
"L": "Б", "L": "Б",
@@ -435,7 +439,7 @@
"deployed": "Открыты", "deployed": "Открыты",
"disabled": "Отключено", "disabled": "Отключено",
"discount": "Скидка", "discount": "Скидка",
"DPS": "УВС", "DPS": "УвС",
"efficiency": "Эффективность", "efficiency": "Эффективность",
"empty": "пусто", "empty": "пусто",
"ENG": "ДВГ", "ENG": "ДВГ",
@@ -449,7 +453,7 @@
"jumps": "Прыжков", "jumps": "Прыжков",
"laden": "Груж", "laden": "Груж",
"language": "Язык", "language": "Язык",
"maneuverability": "Маневренность", "maneuverability": "Манёвренность",
"max": "Макс", "max": "Макс",
"no": "Нет", "no": "Нет",
"pen": "ПБ", "pen": "ПБ",
@@ -462,7 +466,7 @@
"repair": "Починка", "repair": "Починка",
"ret": "Убр", "ret": "Убр",
"retracted": "Убрано", "retracted": "Убрано",
"ROF": "В\/сек", "ROF": "В\/с",
"save": "Сохранить", "save": "Сохранить",
"sell": "Продать", "sell": "Продать",
"settings": "Настройки", "settings": "Настройки",
@@ -492,7 +496,7 @@
"module": "модуль", "module": "модуль",
"announcements": "объявления", "announcements": "объявления",
"resistance": "сопротивление", "resistance": "сопротивление",
"Lightweight Alloy": егкие сплавы", "Lightweight Alloy": ёгкие сплавы",
"base": "базовые", "base": "базовые",
"core module classes": "основные модули", "core module classes": "основные модули",
"Group highlighted ships": "Сгруппировать выделенные корабли", "Group highlighted ships": "Сгруппировать выделенные корабли",
@@ -511,7 +515,7 @@
"maximum speed": "максимальная скорость", "maximum speed": "максимальная скорость",
"maximum range": "максимальная дальность", "maximum range": "максимальная дальность",
"shortlink": "короткая ссылка", "shortlink": "короткая ссылка",
"guardian": "стражи", "guardian": "Стражи",
"engineers": "инженеры", "engineers": "инженеры",
"component": "компонент", "component": "компонент",
"amount": "кол-во", "amount": "кол-во",
@@ -520,35 +524,35 @@
"Heat Sink Launcher": "Теплоотводная катапульта", "Heat Sink Launcher": "Теплоотводная катапульта",
"scanners": "сканеры", "scanners": "сканеры",
"experimental": "экспериментальное", "experimental": "экспериментальное",
"mining": "шахтерство", "mining": "добыча ресурсов",
"lasers": "лазеры", "lasers": "лазеры",
"ordnance": "артиллерия", "ordnance": "артиллерия",
"projectiles": "с боеприпасами", "projectiles": "с боеприпасами",
"hangars": "ангары", "hangars": "ангары",
"limpet controllers": "контроллеры снарядов", "limpet controllers": "контроллеры дронов",
"passenger cabins": "каюты пассажиров", "passenger cabins": "каюты пассажиров",
"structural reinforcement": "структурные усиления", "structural reinforcement": "усиление конструктива",
"flight assists": "помощники в полете", "flight assists": "помощь в полёте",
"modifications": "модификации", "modifications": "модификации",
"wep_reload": "перезарядка", "wep_reload": "перезарядка",
"optimal multiplier": "оптимальный усилитель", "optimal multiplier": "оптимальный усилитель",
"Cargo Hatch": "Грузовой люк", "Cargo Hatch": "Грузовой люк",
"Chaff Launcher": "Разбрасыватель дипольных отражателей", "Chaff Launcher": "Разбрасыватель дипольных отражателей",
"Point Defence": "Точечная оборона", "Point Defence": "Точечная оборона",
"Electronic Countermeasure": "Электронное противодействие", "Electronic Countermeasure": "Радиоэлектронное подавление",
"Xeno Scanner": "Сканер «инопланетянин»", "Xeno Scanner": "Ксено-сканер",
"Shutdown Field Neutraliser": "Нейтрализатор глушащего поля", "Shutdown Field Neutraliser": "Нейтрализатор отключающего поля",
"Disruptor": "Диверсант", "Disruptor": "«Диверсант»",
"Pacifier": "Миротворец", "Pacifier": "«Миротворец»",
"Advanced Plasma Accelerator": "Улучшенный ускоритель плазмы", "Advanced Plasma Accelerator": "Улучшенный ускоритель плазмы",
"Cytoscrambler": "Дезинтегратор", "Cytoscrambler": "«Дезинтегратор»",
"Retributor": "Каратель", "Retributor": "«Каратель»",
"Enforcer": "Убийца", "Enforcer": "«Убийца»",
"Imperial Hammer": "Имперский молот", "Imperial Hammer": "«Имперский молот»",
"Rocket Propelled FSD Disruptor": "Ракетный FSD-разрушитель", "Rocket Propelled FSD Disruptor": "Ракетный FSD-разрушитель",
"Pack-Hound": "Гончие", "Pack-Hound": "«Гончие»",
"Shock Mine Launcher": "Установщик шоковых мин", "Shock Mine Launcher": "Установщик шоковых мин",
"Mining Lance": "Копье шахтера", "Mining Lance": "«Копьё шахтера»",
"Corrosion Resistant": "Коррозийно-устойчивый стеллаж", "Corrosion Resistant": "Коррозийно-устойчивый стеллаж",
"Standard Docking Computer": "Стандартный стыковочный компьютер", "Standard Docking Computer": "Стандартный стыковочный компьютер",
"Advanced Docking Computer": "Улучшенный стыковочный компьютер", "Advanced Docking Computer": "Улучшенный стыковочный компьютер",
@@ -557,20 +561,20 @@
"Guardian Power Distributor": "Рапределитель питания Стражей", "Guardian Power Distributor": "Рапределитель питания Стражей",
"Enhanced Performance": "Усиленные маневровые двигатели", "Enhanced Performance": "Усиленные маневровые двигатели",
"Guardian Hybrid Power Plant": "Гибридная силовая установка Стражей", "Guardian Hybrid Power Plant": "Гибридная силовая установка Стражей",
"Reinforced Alloy": "Укрепленные сплавы", "Reinforced Alloy": "Укреплённые сплавы",
"Military Grade Composite": "Композит военного класса", "Military Grade Composite": "Композит военного класса",
"Mirrored Surface Composite": "Композит с зеркальной поверхностью", "Mirrored Surface Composite": "Композит с зеркальной поверхностью",
"Reactive Surface Composite": "Композит с реактивной поверхностью", "Reactive Surface Composite": "Композит с реактивной поверхностью",
"Proto Light Alloys": "Опытные легкие сплавы", "Proto Light Alloys": "Опытные лёгкие сплавы",
"Ammo capacity": "Вместимость магазина", "Ammo capacity": "Вместимость магазина",
"Lightweight": "Облегченный", "Lightweight": "Облегчённый",
"Reinforced": "Усиленный", "Reinforced": "Усиленный",
"Shielded": "Защищенный", "Shielded": "Защищённый",
"Fast scan": "Быстрое сканирование", "Fast scan": "Быстрое сканирование",
"Long range": "Дальнего действия", "Long range": "Дальнего действия",
"Wide angle": "Широкоугольный", "Wide angle": "Широкоугольный",
"Blast resistant": "Взрывостойкий", "Blast resistant": "Взрывостойкий",
"Heavy duty": "Надежный", "Heavy duty": "Надёжный",
"Kinetic resistant": "Противокинетический", "Kinetic resistant": "Противокинетический",
"Resistance augmented": "С универсальной защитой", "Resistance augmented": "С универсальной защитой",
"Thermal resistant": "Термостойкий", "Thermal resistant": "Термостойкий",
@@ -622,7 +626,7 @@
"Penetrator Munitions": "Бронебойные боеголовки", "Penetrator Munitions": "Бронебойные боеголовки",
"Mass lock munition": "Боеприпасы с гравитационным захватом", "Mass lock munition": "Боеприпасы с гравитационным захватом",
"Mass Lock Munition": "Боеприпасы с гравитационным захватом", "Mass Lock Munition": "Боеприпасы с гравитационным захватом",
"Reverberating cascade": "Отраженный залп", "Reverberating cascade": "Отражённый залп",
"Shift-lock canister": "Рамоблокирующая кассета", "Shift-lock canister": "Рамоблокирующая кассета",
"Ion disruptor": "Ионный дестабилизатор", "Ion disruptor": "Ионный дестабилизатор",
"Radiant Canister": "Светящаяся кассета", "Radiant Canister": "Светящаяся кассета",
@@ -639,7 +643,7 @@
"Reflective Plating": "Отражающая броня", "Reflective Plating": "Отражающая броня",
"Angled Plating": "Угловая броня", "Angled Plating": "Угловая броня",
"Layered Plating": "Многослойная броня", "Layered Plating": "Многослойная броня",
"Deep Plating": "Утолщенная броня", "Deep Plating": "Утолщённая броня",
"Expanded Probe Scanning Radius": "Увеличение радиуса сканирования зондов", "Expanded Probe Scanning Radius": "Увеличение радиуса сканирования зондов",
"High charge capacity": "Высокоёмкий", "High charge capacity": "Высокоёмкий",
"Charge enhanced": "Быстрозаряжающийся", "Charge enhanced": "Быстрозаряжающийся",
@@ -666,8 +670,8 @@
"Combat": "Боец", "Combat": "Боец",
"Trader": "Торговец", "Trader": "Торговец",
"Explorer": "Исследователь", "Explorer": "Исследователь",
"Planetary Explorer": "Планетарный исследователь", "Planetary Explorer": "Исследователь планет",
"Miner": "Шахтер", "Miner": "Старатель",
"Racer": "Гонщик", "Racer": "Гонщик",
"Aberrant Shield Pattern Analysis": "Анализ аномального поведения щита", "Aberrant Shield Pattern Analysis": "Анализ аномального поведения щита",
@@ -691,7 +695,7 @@
"Chemical Manipulators": "Манипуляторы для работы с химикатами", "Chemical Manipulators": "Манипуляторы для работы с химикатами",
"Chemical Processors": "Оборудование для химобработки", "Chemical Processors": "Оборудование для химобработки",
"Chromium": "Хром", "Chromium": "Хром",
"Classified Scan Databanks": "Засекреченные базы данных сканированоя", "Classified Scan Databanks": "Засекреченные базы данных сканирования",
"Classified Scan Fragment": "Засекреченные фрагменты данных сканирования", "Classified Scan Fragment": "Засекреченные фрагменты данных сканирования",
"Compound Shielding": "Многоступенчатая защита", "Compound Shielding": "Многоступенчатая защита",
"Conductive Ceramics": "Проводящая керамика", "Conductive Ceramics": "Проводящая керамика",
@@ -702,7 +706,7 @@
"Cracked Industrial Firmware": "Взломанные промышленные микропрограммы", "Cracked Industrial Firmware": "Взломанные промышленные микропрограммы",
"Datamined Wake Exceptions": "Исключения из глубинного анализа данных следа", "Datamined Wake Exceptions": "Исключения из глубинного анализа данных следа",
"Decoded Emission Data": "Расшифрованные данные об излучении", "Decoded Emission Data": "Расшифрованные данные об излучении",
"Distorted Shield Cycle Recordings": "Поврежденные цикличные записи щита", "Distorted Shield Cycle Recordings": "Повреждённые цикличные записи щита",
"Divergent Scan Data": "Неформатные данные сканирования", "Divergent Scan Data": "Неформатные данные сканирования",
"Eccentric Hyperspace Trajectories": "Аномальные траектории в гиперпространстве", "Eccentric Hyperspace Trajectories": "Аномальные траектории в гиперпространстве",
"Electrochemical Arrays": "Электрохимические массивы", "Electrochemical Arrays": "Электрохимические массивы",
@@ -717,7 +721,7 @@
"Heat Dispersion Plate": "Теплорассеивающая пластина", "Heat Dispersion Plate": "Теплорассеивающая пластина",
"Heat Exchangers": "Теплообменные агрегаты", "Heat Exchangers": "Теплообменные агрегаты",
"Heat Vanes": "Тепловые заслонки", "Heat Vanes": "Тепловые заслонки",
"High Density Composites": "Высокоплотные композиты", "High Density Composites": "Высокоплотностные композиты",
"Hybrid Capacitors": "Гибридные конденсаторы", "Hybrid Capacitors": "Гибридные конденсаторы",
"Imperial Shielding": "Имперская защита", "Imperial Shielding": "Имперская защита",
"Improvised Components": "Кустарные компоненты", "Improvised Components": "Кустарные компоненты",
@@ -731,8 +735,8 @@
"Mercury": "Ртуть", "Mercury": "Ртуть",
"Military Grade Alloys": "Сплавы военного назначения", "Military Grade Alloys": "Сплавы военного назначения",
"Military Supercapacitors": "Военные суперконденсаторы", "Military Supercapacitors": "Военные суперконденсаторы",
"Modified Consumer Firmware": "Измененные пользовательские микропрограммы", "Modified Consumer Firmware": "Изменённые пользовательские микропрограммы",
"Modified Embedded Firmware": "Измененные встроенные микропрограммы", "Modified Embedded Firmware": "Изменённые встроенные микропрограммы",
"Molybdenum": "Молибден", "Molybdenum": "Молибден",
"Nickel": "Никель", "Nickel": "Никель",
"Niobium": "Ниобий", "Niobium": "Ниобий",
@@ -741,7 +745,7 @@
"Phase Alloys": "Фазовые сплавы", "Phase Alloys": "Фазовые сплавы",
"Phosphorus": "Фосфор", "Phosphorus": "Фосфор",
"Polymer Capacitors": "Полимерные конденсаторы", "Polymer Capacitors": "Полимерные конденсаторы",
"Precipitated Alloys": "Осажденные сплавы", "Precipitated Alloys": "Осаждённые сплавы",
"Proprietary Composites": "Патентованные композиты", "Proprietary Composites": "Патентованные композиты",
"Proto Heat Radiators": "Прототипы теплоизлучателей", "Proto Heat Radiators": "Прототипы теплоизлучателей",
"Proto Radiolic Alloys": "Сплавы для изготовления зондов", "Proto Radiolic Alloys": "Сплавы для изготовления зондов",
@@ -749,15 +753,15 @@
"Ruthenium": "Рутений", "Ruthenium": "Рутений",
"Salvaged Alloys": "Захваченные сплавы", "Salvaged Alloys": "Захваченные сплавы",
"Security Firmware Patch": "Обновление для защитной микропрограммы", "Security Firmware Patch": "Обновление для защитной микропрограммы",
"Selenium": "Селениум", "Selenium": "Селен",
"Shield Emitters": "Щитоизлучатели", "Shield Emitters": "Щитоизлучатели",
"Shielding Sensors": "Сенсоры системы экранирования", "Shielding Sensors": "Сенсоры системы экранирования",
"Specialised Legacy Firmware": "Специальные микропрограммы предыдущего поколения", "Specialised Legacy Firmware": "Специальные микропрограммы предыдущего поколения",
"Strange Wake Solutions": "Странные расчеты следа", "Strange Wake Solutions": "Странные расчёты следа",
"Sulphur": "Сера", "Sulphur": "Сера",
"Tagged Encryption Codes": "Меченные шифровальные коды", "Tagged Encryption Codes": "Меченные шифровальные коды",
"Technetium": "Технеций", "Technetium": "Технеций",
"Tellurium": "Теллурий", "Tellurium": "Теллур",
"Thermic Alloys": "Термические сплавы", "Thermic Alloys": "Термические сплавы",
"Tin": "Олово", "Tin": "Олово",
"Tungsten": "Вольфрам", "Tungsten": "Вольфрам",

View File

@@ -1,12 +1,6 @@
import '@babel/polyfill';
import React from 'react'; import React from 'react';
import { render } from 'react-dom'; import { render } from 'react-dom';
import '../less/app.less'; import '../less/app.less';
import Coriolis from './Coriolis'; import Coriolis from './Coriolis';
// import TapEventPlugin from 'react/lib/TapEventPlugin';
// import EventPluginHub from 'react/lib/EventPluginHub';
// onTouchTap not ready for primetime yet, too many issues with preventing default
// EventPluginHub.injection.injectEventPluginsByName({ TapEventPlugin });
render(<Coriolis />, document.getElementById('coriolis')); render(<Coriolis />, document.getElementById('coriolis'));

View File

@@ -1,5 +1,4 @@
import React from 'react'; import React from 'react';
// import Perf from 'react-addons-perf';
import { Ships } from 'coriolis-data/dist'; import { Ships } from 'coriolis-data/dist';
import cn from 'classnames'; import cn from 'classnames';
import Page from './Page'; import Page from './Page';
@@ -58,7 +57,6 @@ export default class OutfittingPage extends Page {
*/ */
constructor(props, context) { constructor(props, context) {
super(props, context); super(props, context);
// window.Perf = Perf;
this.state = this._initState(props, context); this.state = this._initState(props, context);
this._keyDown = this._keyDown.bind(this); this._keyDown = this._keyDown.bind(this);
this._exportBuild = this._exportBuild.bind(this); this._exportBuild = this._exportBuild.bind(this);
@@ -679,9 +677,9 @@ export default class OutfittingPage extends Page {
} }
/** /**
* Open up a window for EDDB with a shopping list of our components * Open up a window for inara with a shopping list of our components
*/ */
_eddbShoppingList() { _inaraShoppingList() {
const ship = this.state.ship; const ship = this.state.ship;
const shipId = Ships[ship.id].eddbID; const shipId = Ships[ship.id].eddbID;
@@ -694,7 +692,7 @@ export default class OutfittingPage extends Page {
// Open up the relevant URL // Open up the relevant URL
window.open( window.open(
'https://eddb.io/station?s=' + shipId + '&m=' + modIds.join(',') 'https://inara.cz/inapi/corisearch.php?s=' + shipId + '&m=' + modIds.join(',')
); );
} }
@@ -914,7 +912,7 @@ export default class OutfittingPage extends Page {
<Download className="lg" /> <Download className="lg" />
</button> </button>
<button <button
onClick={this._eddbShoppingList} onClick={this._inaraShoppingList}
onMouseOver={termtip.bind(null, 'PHRASE_SHOPPING_LIST')} onMouseOver={termtip.bind(null, 'PHRASE_SHOPPING_LIST')}
onMouseOut={hide} onMouseOut={hide}
> >

View File

@@ -383,7 +383,8 @@ export function shieldMetrics(ship, sys) {
// Our initial regeneration comes from the SYS capacitor store, which is replenished as it goes // Our initial regeneration comes from the SYS capacitor store, which is replenished as it goes
// 0.6 is a magic number from FD: each 0.6 MW of energy from the power distributor recharges 1 MJ/s of regeneration // 0.6 is a magic number from FD: each 0.6 MW of energy from the power distributor recharges 1 MJ/s of regeneration
let capacitorDrain = (shieldGenerator.getBrokenRegenerationRate() * 0.6) - sysRechargeRate; let capacitorDrain = (shieldGenerator.getBrokenRegenerationRate() * shieldGenerator.getDistDraw()) - sysRechargeRate;
let capacitorLifetime = powerDistributor.getSystemsCapacity() / capacitorDrain; let capacitorLifetime = powerDistributor.getSystemsCapacity() / capacitorDrain;
let recover = 16; let recover = 16;
@@ -399,7 +400,7 @@ export function shieldMetrics(ship, sys) {
recover = Math.Infinity; recover = Math.Infinity;
} else { } else {
// Recover remaining shields at the rate of the power distributor's recharge // Recover remaining shields at the rate of the power distributor's recharge
recover += remainingShieldToRecover / (sysRechargeRate / 0.6); recover += remainingShieldToRecover / (sysRechargeRate / shieldGenerator.getDistDraw());
} }
} }
@@ -408,7 +409,7 @@ export function shieldMetrics(ship, sys) {
// Our initial regeneration comes from the SYS capacitor store, which is replenished as it goes // Our initial regeneration comes from the SYS capacitor store, which is replenished as it goes
// 0.6 is a magic number from FD: each 0.6 MW of energy from the power distributor recharges 1 MJ/s of regeneration // 0.6 is a magic number from FD: each 0.6 MW of energy from the power distributor recharges 1 MJ/s of regeneration
capacitorDrain = (shieldGenerator.getRegenerationRate() * 0.6) - sysRechargeRate; capacitorDrain = (shieldGenerator.getRegenerationRate() * shieldGenerator.getDistDraw()) - sysRechargeRate;
capacitorLifetime = powerDistributor.getSystemsCapacity() / capacitorDrain; capacitorLifetime = powerDistributor.getSystemsCapacity() / capacitorDrain;
let recharge = 0; let recharge = 0;
@@ -424,7 +425,7 @@ export function shieldMetrics(ship, sys) {
recharge = Math.Inf; recharge = Math.Inf;
} else { } else {
// Recharge remaining shields at the rate of the power distributor's recharge // Recharge remaining shields at the rate of the power distributor's recharge
recharge += remainingShieldToRecharge / (sysRechargeRate / 0.6); recharge += remainingShieldToRecharge / (sysRechargeRate / shieldGenerator.getDistDraw());
} }
} }

View File

@@ -58,6 +58,8 @@ export const ModuleGroupToName = {
gmrp: 'Guardian Module Reinforcement Package', gmrp: 'Guardian Module Reinforcement Package',
mahr: 'Meta Alloy Hull Reinforcement Package', mahr: 'Meta Alloy Hull Reinforcement Package',
sua: 'Supercruise Assist', sua: 'Supercruise Assist',
mlc: "Multi Limpet Controller",
rpl: "Repair Limpet Controller",
// Hard Points // Hard Points
bl: 'Beam Laser', bl: 'Beam Laser',

View File

@@ -13,6 +13,19 @@ function filter(arr, maxClass, minClass, mass) {
return arr.filter(m => m.class <= maxClass && m.class >= minClass && (m.maxmass === undefined || mass <= m.maxmass)); return arr.filter(m => m.class <= maxClass && m.class >= minClass && (m.maxmass === undefined || mass <= m.maxmass));
} }
/**
* Filter SCO Modules to only return legal size.
* @param {Array} arr Array of available FSD modules.
* @param {number} maxSize Maximum allowable size for SCO modules.
* @return {Array} Subset of modules filtered based on legal size amd type.
*/
function sco_filter(arr, maxSize) {
return arr.filter(module => {
return !(module.hasOwnProperty('name') && module['name'] === "Frame Shift Drive (SCO)" && module['class'] < maxSize);
});
}
/** /**
* The available module set for a specific ship * The available module set for a specific ship
*/ */
@@ -41,6 +54,7 @@ export default class ModuleSet {
this.standard[0] = filter(stnd.pp, maxStandardArr[0], 0, mass); // Power Plant 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[2] = filter(stnd.fsd, maxStandardArr[2], 0, mass); // FSD
this.standard[2] = sco_filter(this.standard[2], maxStandardArr[2]) // FSD - Filter SCO Modules
this.standard[4] = filter(stnd.pd, maxStandardArr[4], 0, mass); // Power Distributor this.standard[4] = filter(stnd.pd, maxStandardArr[4], 0, mass); // Power Distributor
this.standard[6] = filter(stnd.ft, maxStandardArr[6], 0, mass); // Fuel Tank this.standard[6] = filter(stnd.ft, maxStandardArr[6], 0, mass); // Fuel Tank
// Thrusters, filter modules by class only (to show full list of ratings for that class) // Thrusters, filter modules by class only (to show full list of ratings for that class)

View File

@@ -10,7 +10,7 @@ import { Ships, Modifications } from 'coriolis-data/dist';
import { chain } from 'lodash'; import { chain } from 'lodash';
const zlib = require('zlib'); const zlib = require('zlib');
const UNIQUE_MODULES = ['psg', 'sg', 'bsg', 'rf', 'fs', 'fh', 'gfsb', 'dc']; const UNIQUE_MODULES = ['psg', 'sg', 'bsg', 'rf', 'fs', 'fh', 'gfsb', 'dc', 'ews'];
// Constants for modifications struct // Constants for modifications struct
const SLOT_ID_DONE = -1; const SLOT_ID_DONE = -1;

View File

@@ -34,6 +34,7 @@ export const SHIP_FD_NAME_TO_CORIOLIS_NAME = {
'Krait_Light': 'krait_phantom', 'Krait_Light': 'krait_phantom',
'Orca': 'orca', 'Orca': 'orca',
'Python': 'python', 'Python': 'python',
'Python_nx': 'python_nx',
'SideWinder': 'sidewinder', 'SideWinder': 'sidewinder',
'Type6': 'type_6_transporter', 'Type6': 'type_6_transporter',
'Type7': 'type_7_transport', 'Type7': 'type_7_transport',

View File

@@ -40,22 +40,12 @@
window.dataLayer = window.dataLayer || []; window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);} function gtag(){dataLayer.push(arguments);}
gtag('js', new Date()); gtag('js', new Date());
gtag('config', 'UA-55840909-18'); gtag('config', 'UA-55840909-18');
</script> </script>
</head>
<body style="background-color:#000;">
<section id="coriolis">
</section>
</body>
<!-- Bugsnag --> </html>
<script src="https://d2wy8f7a9ursnm.cloudfront.net/v5.0.0/bugsnag.min.js"></script>
<script>
window.bugsnagClient = bugsnag('ba9fae819372850fb660755341fa6ef5', {appVersion: window.BUGSNAG_VERSION || undefined})
window.Bugsnag = window.bugsnagClient
</script>
</head>
<body style="background-color:#000;">
<section id="coriolis">
</section>
</body>
</html>

View File

@@ -24,12 +24,6 @@
type="image/png" type="image/png"
href="/192x192.png" href="/192x192.png"
/> />
<!-- Bugsnag -->
<script src="https://d2wy8f7a9ursnm.cloudfront.net/v5.0.0/bugsnag.min.js"></script>
<script>
window.bugsnagClient = bugsnag('ba9fae819372850fb660755341fa6ef5', {appVersion: window.BUGSNAG_VERSION || undefined})
window.Bugsnag = window.bugsnagClient
</script>
<!-- Apple/iOS headers --> <!-- Apple/iOS headers -->
<meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-capable" content="yes" />

View File

@@ -1,46 +1,54 @@
import {precacheAndRoute, createHandlerBoundToURL} from 'workbox-precaching';
import {NavigationRoute, registerRoute} from 'workbox-routing';
import {StaleWhileRevalidate, CacheFirst} from 'workbox-strategies';
import {CacheableResponsePlugin} from 'workbox-cacheable-response'
import {ExpirationPlugin} from 'workbox-expiration';
console.log('Hello from sw.js'); console.log('Hello from sw.js');
if (workbox) { // See https://developer.chrome.com/docs/workbox/migration/migrate-from-v4/ for guide to changes made
console.log('Yay! Workbox is loaded 🎉'); console.log('Yay! Workbox is loaded 🎉');
workbox.precaching.precacheAndRoute(self.__precacheManifest); precacheAndRoute(self.__WB_MANIFEST || []);
workbox.routing.registerNavigationRoute('/index.html'); const handler = createHandlerBoundToURL('/index.html');
const navigationRoute = new NavigationRoute(handler
// , {allowlist: [...], denylist: [...],}
);
registerRoute(navigationRoute);
workbox.routing.registerRoute(
/\.(?:png|jpg|jpeg|svg|gif)$/,
new workbox.strategies.CacheFirst({
plugins: [
new workbox.cacheableResponse.Plugin({
statuses: [0, 200]
})
]
})
);
workbox.routing.registerRoute( registerRoute(
/\.(?:js|css)$/, /\.(?:png|jpg|jpeg|svg|gif)$/,
new workbox.strategies.StaleWhileRevalidate({ new CacheFirst({
cacheName: 'static-resources', plugins: [
}) new CacheableResponsePlugin({
); statuses: [0, 200]
})
]
})
);
workbox.routing.registerRoute( registerRoute(
new RegExp('https://fonts.(?:googleapis|gstatic).com/(.*)'), /\.(?:js|css)$/,
new workbox.strategies.CacheFirst({ new StaleWhileRevalidate({
cacheName: 'google-fonts', cacheName: 'static-resources',
plugins: [ })
new workbox.expiration.Plugin({ );
maxEntries: 30
}), registerRoute(
new workbox.cacheableResponse.Plugin({ new RegExp('https://fonts.(?:googleapis|gstatic).com/(.*)'),
statuses: [0, 200] new CacheFirst({
}) cacheName: 'google-fonts',
] plugins: [
}) new ExpirationPlugin({
); maxEntries: 30
} else { }),
console.log('Boo! Workbox didn\'t load 😬'); new CacheableResponsePlugin({
} statuses: [0, 200]
})
]
})
);
self.addEventListener('message', event => { self.addEventListener('message', event => {
if (!event.data) { if (!event.data) {

81
webpack.common.js Normal file
View File

@@ -0,0 +1,81 @@
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const pkgJson = require('./package');
const buildDate = new Date();
module.exports = {
entry: {
main: './src/app/index.js'
},
resolve: {
// When requiring, you don't need to add these extensions
extensions: ['.js', '.jsx', '.json', '.less'],
fallback: {
// Consider replacing brwoserify-zlib-next c. 2016 package with pako, which it's just a wrapper for
/* Some of these polyfills may not even be necessary, and were added in an attempt to deal with build issues
while upgrading to Webpack v5 */
"zlib": require.resolve("browserify-zlib-next"),
"assert": require.resolve("assert/"),
"buffer": require.resolve("buffer/"),
"stream": require.resolve("stream-browserify"),
/*
"url": require.resolve("url/"),
"path": require.resolve("path-browserify"),
"crypto": require.resolve("crypto-browserify"),
"os": require.resolve("os-browserify/browser"),
"https": require.resolve("https-browserify"),
"http": require.resolve("stream-http"),
"vm": require.resolve("vm-browserify"),
"constants": require.resolve("constants-browserify"),
// "fs": false
*/
}
},
optimization: {
usedExports: true
},
output: {
path: path.join(__dirname, 'build'),
chunkFilename: '[name].bundle.js',
// assetModuleFilename: '[contenthash][ext]',
publicPath: '/',
clean: true // we already do rimraf on the build dir, but this should obviate that
},
plugins: [
// new webpack.optimize.CommonsChunkPlugin({
// name: 'lib',
// filename: 'lib.js'
// }),
new HtmlWebpackPlugin({
inject: true,
template: path.join(__dirname, 'src/index.ejs'),
version: pkgJson.version,
// gapiKey: process.env.CORIOLIS_GAPI_KEY || '',
date: buildDate,
}),
new MiniCssExtractPlugin({
filename: 'app.css',
}),
// Solve missing Buffer polyfill that breaks module engineering
new webpack.ProvidePlugin({
Buffer: ['buffer', 'Buffer'],
}),
],
module: {
rules: [
{ test: /\.css$/, use: [MiniCssExtractPlugin.loader, 'css-loader' ]},
{
test: /\.less$/,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'less-loader' ]
},
{ test: /\.(js|jsx)$/, use: ['babel-loader'], include: path.join(__dirname, 'src') },
{
test: /\.(jpe?g|svg|png|gif|ico|eot|ttf|woff|woff2?)(\?v=\d+\.\d+\.\d+)?$/i,
type: 'asset/resource',
},
]
}
};

View File

@@ -1,69 +1,27 @@
const path = require('path');
const webpack = require('webpack'); const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin'); const { merge } = require('webpack-merge');
const ExtractTextPlugin = require('extract-text-webpack-plugin'); const common = require('./webpack.common.js');
const WebpackNotifierPlugin = require('webpack-notifier');
const pkgJson = require('./package');
const buildDate = new Date();
const CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = { const CopyWebpackPlugin = require('copy-webpack-plugin');
const WebpackNotifierPlugin = require('webpack-notifier');
module.exports = merge(common, {
devtool: 'source-map', devtool: 'source-map',
devServer: { devServer: {
headers: { 'Access-Control-Allow-Origin': '*' } headers: { 'Access-Control-Allow-Origin': '*' }
}, },
mode: 'development', mode: 'development',
entry: {
main: './src/app/index.js',
},
resolve: {
// When requiring, you don't need to add these extensions
extensions: ['.js', '.jsx', '.json', '.less']
},
optimization: { optimization: {
minimize: false, minimize: false,
usedExports: true
},
output: {
path: path.join(__dirname, 'build'),
chunkFilename: '[name].bundle.js',
publicPath: '/'
}, },
plugins: [ plugins: [
new CopyWebpackPlugin(['src/.htaccess', 'src/iframe.html', 'src/xdLocalStoragePostMessageApi.min.js']), new CopyWebpackPlugin({
// new webpack.optimize.CommonsChunkPlugin({ patterns: [
// name: 'lib', 'src/.htaccess',
// filename: 'lib.js' 'src/iframe.html',
// }), 'src/xdLocalStoragePostMessageApi.min.js'
new HtmlWebpackPlugin({ ]}),
inject: true,
template: path.join(__dirname, 'src/index.ejs'),
version: pkgJson.version,
date: buildDate,
gapiKey: process.env.CORIOLIS_GAPI_KEY || ''
}),
new ExtractTextPlugin({
filename: 'app.css',
disable: false,
allChunks: true
}),
new WebpackNotifierPlugin({ alwaysNotify: true }), new WebpackNotifierPlugin({ alwaysNotify: true }),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin() new webpack.NoEmitOnErrorsPlugin()
], ]
module: { });
rules: [
{ test: /\.css$/, loader: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader' }) },
{
test: /\.less$/,
loader: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader!less-loader' })
},
{ test: /\.(js|jsx)$/, loaders: ['babel-loader'], include: path.join(__dirname, 'src') },
{ test: /\.woff(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff' },
{ test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff' },
{ test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/octet-stream' },
{ test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader' },
{ test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=image/svg+xml' }
]
}
};

View File

@@ -1,54 +1,37 @@
const path = require('path'); const { merge } = require('webpack-merge');
const webpack = require('webpack'); const common = require('./webpack.common.js');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const { InjectManifest } = require('workbox-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const { BugsnagSourceMapUploaderPlugin, BugsnagBuildReporterPlugin } = require('webpack-bugsnag-plugins');
const pkgJson = require('./package');
const buildDate = new Date();
module.exports = { const path = require('path');
devtool: 'source-map', const CopyWebpackPlugin = require('copy-webpack-plugin');
entry: { const MiniCssExtractPlugin = require('mini-css-extract-plugin');
main: './src/app/index.js' const { InjectManifest } = require('workbox-webpack-plugin');
},
resolve: { module.exports = merge(common, {
extensions: ['.js', '.jsx', '.json', '.less'] // devtool: 'source-map',
},
output: {
path: path.join(__dirname, 'build'),
chunkFilename: '[name].bundle.js',
publicPath: '/',
globalObject: 'this'
},
mode: 'production', mode: 'production',
optimization: { optimization: {
minimize: true, minimize: true,
usedExports: true },
output: {
globalObject: 'this'
}, },
plugins: [ plugins: [
new CopyWebpackPlugin(['src/.htaccess', { from: 'src/schemas', to: 'schemas' }, { new CopyWebpackPlugin({
from: 'src/images/logo/*', patterns: [
flatten: true, 'src/.htaccess',
to: '' 'src/iframe.html',
}, 'src/iframe.html', 'src/xdLocalStoragePostMessageApi.min.js']), 'src/xdLocalStoragePostMessageApi.min.js',
// new webpack.optimize.CommonsChunkPlugin({ { from: 'src/schemas', to: 'schemas' },
// name: 'lib', {
// filename: 'lib.[chunkhash:6].js' from: 'src/images/logo/*',
// }), to: '[name][ext]'
new HtmlWebpackPlugin({ }
inject: true, ]}),
template: path.join(__dirname, 'src/index.ejs'), /* new HtmlWebpackPlugin({
uaTracking: process.env.CORIOLIS_UA_TRACKING || '', // uaTracking: process.env.CORIOLIS_UA_TRACKING || '',
gapiKey: process.env.CORIOLIS_GAPI_KEY || '', }), */
date: buildDate, new MiniCssExtractPlugin({
version: pkgJson.version filename: '[contenthash:6].css',
}),
new ExtractTextPlugin({
filename: '[hash:6].css',
disable: false,
allChunks: true
}), }),
// new BugsnagBuildReporterPlugin({ // new BugsnagBuildReporterPlugin({
// apiKey: 'ba9fae819372850fb660755341fa6ef5', // apiKey: 'ba9fae819372850fb660755341fa6ef5',
@@ -59,25 +42,11 @@ module.exports = {
// overwrite: true, // overwrite: true,
// appVersion: `${pkgJson.version}-${buildDate.toISOString()}` // appVersion: `${pkgJson.version}-${buildDate.toISOString()}`
// }), // }),
new InjectManifest({ new InjectManifest({
swSrc: './src/sw.js', swSrc: './src/sw.js',
importWorkboxFrom: 'cdn',
swDest: 'service-worker.js' swDest: 'service-worker.js'
}), }),
],
module: { ]
rules: [ });
{ test: /\.css$/, loader: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader' }) },
{
test: /\.less$/,
loader: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader!less-loader' })
},
{ test: /\.(js|jsx)$/, loader: 'babel-loader?cacheDirectory=true', include: path.join(__dirname, 'src') },
{ test: /\.woff(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff' },
{ test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/font-woff' },
{ test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=application/octet-stream' },
{ test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader' },
{ test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'url-loader?limit=10000&mimetype=image/svg+xml' }
]
}
};