From b51c0fdbd43ac3f5be9c7bff9e241091ca542e68 Mon Sep 17 00:00:00 2001 From: dengr1065 Date: Fri, 25 Dec 2020 23:57:57 +0200 Subject: [PATCH 01/52] Replace gulp-sass with gulp-dart-sass (#1036) --- gulp/css.js | 4 +- gulp/package.json | 2 +- gulp/yarn.lock | 258 +++++++++------------------------------- src/css/animations.scss | 24 ++-- 4 files changed, 77 insertions(+), 211 deletions(-) diff --git a/gulp/css.js b/gulp/css.js index 73a0a7cf..2b51f153 100644 --- a/gulp/css.js +++ b/gulp/css.js @@ -62,7 +62,7 @@ function gulptasksCSS($, gulp, buildFolder, browserSync) { return gulp .src("../src/css/main.scss", { cwd: __dirname }) .pipe($.plumber()) - .pipe($.sass.sync().on("error", $.sass.logError)) + .pipe($.dartSass.sync().on("error", $.dartSass.logError)) .pipe( $.postcss([ $.postcssCriticalSplit({ @@ -95,7 +95,7 @@ function gulptasksCSS($, gulp, buildFolder, browserSync) { return gulp .src("../src/css/main.scss", { cwd: __dirname }) .pipe($.plumber()) - .pipe($.sass.sync().on("error", $.sass.logError)) + .pipe($.dartSass.sync().on("error", $.dartSass.logError)) .pipe( $.postcss([ $.postcssCriticalSplit({ diff --git a/gulp/package.json b/gulp/package.json index 90dc5501..28a83253 100644 --- a/gulp/package.json +++ b/gulp/package.json @@ -77,6 +77,7 @@ "gulp-cache": "^1.1.3", "gulp-cached": "^1.1.1", "gulp-clean": "^0.4.0", + "gulp-dart-sass": "^1.0.2", "gulp-dom": "^1.0.0", "gulp-flatten": "^0.4.0", "gulp-fluent-ffmpeg": "^2.0.0", @@ -90,7 +91,6 @@ "gulp-pngquant": "^1.0.13", "gulp-postcss": "^8.0.0", "gulp-rename": "^2.0.0", - "gulp-sass": "^4.1.0", "gulp-sass-lint": "^1.4.0", "gulp-sftp": "git+https://git@github.com/webksde/gulp-sftp", "gulp-terser": "^1.2.0", diff --git a/gulp/yarn.lock b/gulp/yarn.lock index c172cbab..12959102 100644 --- a/gulp/yarn.lock +++ b/gulp/yarn.lock @@ -1816,11 +1816,6 @@ async-each@^1.0.1: resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== -async-foreach@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/async-foreach/-/async-foreach-0.1.3.tgz#36121f845c0578172de419a97dbeb1d16ec34542" - integrity sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI= - async-limiter@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" @@ -2261,13 +2256,6 @@ blob@0.0.5: resolved "https://registry.yarnpkg.com/blob/-/blob-0.0.5.tgz#d680eeef25f8cd91ad533f5b01eed48e64caf683" integrity sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig== -block-stream@*: - version "0.0.9" - resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" - integrity sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo= - dependencies: - inherits "~2.0.0" - bluebird@3.x.x, bluebird@^3.1.1, bluebird@^3.4.6, bluebird@^3.5.0, bluebird@^3.5.5: version "3.5.5" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.5.tgz#a8d0afd73251effbbd5fe384a77d73003c17a71f" @@ -2821,6 +2809,21 @@ chardet@^0.7.0: resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== +"chokidar@>=2.0.0 <4.0.0": + version "3.4.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.3.tgz#c1df38231448e45ca4ac588e6c79573ba6a57d5b" + integrity sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ== + dependencies: + anymatch "~3.1.1" + braces "~3.0.2" + glob-parent "~5.1.0" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.5.0" + optionalDependencies: + fsevents "~2.1.2" + chokidar@^2.0.0, chokidar@^2.1.8: version "2.1.8" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" @@ -3390,14 +3393,6 @@ cross-spawn@6.0.5, cross-spawn@^6.0.0, cross-spawn@^6.0.5: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-3.0.1.tgz#1256037ecb9f0c5f79e3d6ef135e30770184b982" - integrity sha1-ElYDfsufDF9549bvE14wdwGEuYI= - dependencies: - lru-cache "^4.0.1" - which "^1.2.9" - cross-spawn@^5.0.1: version "5.1.0" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" @@ -5404,16 +5399,6 @@ fsevents@~2.1.2: resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== -fstream@^1.0.0, fstream@^1.0.12: - version "1.0.12" - resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.12.tgz#4e8ba8ee2d48be4f7d0de505455548eae5932045" - integrity sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg== - dependencies: - graceful-fs "^4.1.2" - inherits "~2.0.0" - mkdirp ">=0.5 0" - rimraf "2" - function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" @@ -5454,13 +5439,6 @@ gaze@^0.5.1: dependencies: globule "~0.1.0" -gaze@^1.0.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/gaze/-/gaze-1.1.3.tgz#c441733e13b927ac8c0ff0b4c3b033f28812924a" - integrity sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g== - dependencies: - globule "^1.0.0" - generate-function@^2.0.0: version "2.3.1" resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.3.1.tgz#f069617690c10c868e73b8465746764f97c3479f" @@ -5959,6 +5937,20 @@ gulp-cli@^2.2.0: v8flags "^3.2.0" yargs "^7.1.0" +gulp-dart-sass@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/gulp-dart-sass/-/gulp-dart-sass-1.0.2.tgz#20e33c236b48d557c91e8dfe67a2aef2b8a2e328" + integrity sha512-8fLttA824mbuc0jRVlGs00zWYZXBckat6INawx5kp66Eqsz5srNWTA51t0mbfB4C8a/a/GZ9muYLwXGklgAHlw== + dependencies: + chalk "^2.3.0" + lodash.clonedeep "^4.3.2" + plugin-error "^1.0.1" + replace-ext "^1.0.0" + sass "^1.26.3" + strip-ansi "^4.0.0" + through2 "^2.0.0" + vinyl-sourcemaps-apply "^0.2.0" + gulp-dom@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/gulp-dom/-/gulp-dom-1.0.0.tgz#f834d5299c09b85e11c32505044a2ebe86ae1375" @@ -6112,20 +6104,6 @@ gulp-sass-lint@^1.4.0: sass-lint "^1.12.0" through2 "^2.0.2" -gulp-sass@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/gulp-sass/-/gulp-sass-4.1.0.tgz#486d7443c32d42bf31a6b1573ebbdaa361de7427" - integrity sha512-xIiwp9nkBLcJDpmYHbEHdoWZv+j+WtYaKD6Zil/67F3nrAaZtWYN5mDwerdo7EvcdBenSAj7Xb2hx2DqURLGdA== - dependencies: - chalk "^2.3.0" - lodash "^4.17.11" - node-sass "^4.8.3" - plugin-error "^1.0.1" - replace-ext "^1.0.0" - strip-ansi "^4.0.0" - through2 "^2.0.0" - vinyl-sourcemaps-apply "^0.2.0" - "gulp-sftp@git+https://git@github.com/webksde/gulp-sftp": version "0.1.6" resolved "git+https://git@github.com/webksde/gulp-sftp#c8dfb20e290477eeed66a867406576d0c3d4fc6b" @@ -6712,11 +6690,6 @@ imurmurhash@^0.1.4: resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= -in-publish@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/in-publish/-/in-publish-2.0.0.tgz#e20ff5e3a2afc2690320b6dc552682a9c7fadf51" - integrity sha1-4g/146KvwmkDILbcVSaCqcf631E= - indent-string@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" @@ -6752,7 +6725,7 @@ inherits@1: resolved "https://registry.yarnpkg.com/inherits/-/inherits-1.0.2.tgz#ca4309dadee6b54cc0b8d247e8d7c7a0975bdc9b" integrity sha1-ykMJ2t7mtUzAuNJH6NfHoJdb3Js= -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3, inherits@~2.0.4: +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3, inherits@~2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -7296,7 +7269,7 @@ jpegtran-bin@^5.0.0: bin-wrapper "^4.0.0" logalot "^2.0.0" -js-base64@^2.1.8, js-base64@^2.1.9: +js-base64@^2.1.9: version "2.5.1" resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.5.1.tgz#1efa39ef2c5f7980bb1784ade4a8af2de3291121" integrity sha512-M7kLczedRMYX4L8Mdh4MzyAMM9O5osx+4FcOQuTvr3A9F2D9S5JXheN0ewNbrvK2UatkTRhL5ejGmGSjNMiZuw== @@ -8234,7 +8207,7 @@ memory-fs@^0.4.0, memory-fs@^0.4.1: errno "^0.1.3" readable-stream "^2.0.1" -meow@^3.3.0, meow@^3.7.0: +meow@^3.3.0: version "3.7.0" resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" integrity sha1-cstmi0JSKCkKu/qFaJJYcwioAfs= @@ -8495,7 +8468,7 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" -mkdirp@0.5.1, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1: +mkdirp@0.5.1, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= @@ -8572,7 +8545,7 @@ mute-stream@~0.0.4: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== -nan@^2.12.1, nan@^2.13.2: +nan@^2.12.1: version "2.14.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== @@ -8645,24 +8618,6 @@ no-case@^2.2.0: dependencies: lower-case "^1.1.1" -node-gyp@^3.8.0: - version "3.8.0" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.8.0.tgz#540304261c330e80d0d5edce253a68cb3964218c" - integrity sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA== - dependencies: - fstream "^1.0.0" - glob "^7.0.3" - graceful-fs "^4.1.2" - mkdirp "^0.5.0" - nopt "2 || 3" - npmlog "0 || 1 || 2 || 3 || 4" - osenv "0" - request "^2.87.0" - rimraf "2" - semver "~5.3.0" - tar "^2.0.0" - which "1" - node-libs-browser@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" @@ -8715,29 +8670,6 @@ node-releases@^1.1.29: dependencies: semver "^5.3.0" -node-sass@^4.8.3: - version "4.12.0" - resolved "https://registry.yarnpkg.com/node-sass/-/node-sass-4.12.0.tgz#0914f531932380114a30cc5fa4fa63233a25f017" - integrity sha512-A1Iv4oN+Iel6EPv77/HddXErL2a+gZ4uBeZUy+a8O35CFYTXhgA8MgLCWBtwpGZdCvTvQ9d+bQxX/QC36GDPpQ== - dependencies: - async-foreach "^0.1.3" - chalk "^1.1.1" - cross-spawn "^3.0.0" - gaze "^1.0.0" - get-stdin "^4.0.1" - glob "^7.0.3" - in-publish "^2.0.0" - lodash "^4.17.11" - meow "^3.7.0" - mkdirp "^0.5.1" - nan "^2.13.2" - node-gyp "^3.8.0" - npmlog "^4.0.0" - request "^2.88.0" - sass-graph "^2.2.4" - stdout-stream "^1.4.0" - "true-case-path" "^1.0.2" - node-sri@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/node-sri/-/node-sri-1.1.1.tgz#041096d2b11f232b65dedc4c3ae1cb62babb54b0" @@ -8751,13 +8683,6 @@ node.extend@^1.0.10: has "^1.0.3" is "^3.2.1" -"nopt@2 || 3": - version "3.0.6" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" - integrity sha1-xkZdvwirzU2zWTF/eaxopkayj/k= - dependencies: - abbrev "1" - nopt@^4.0.1, nopt@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" @@ -8854,7 +8779,7 @@ npm-run-path@^4.0.0: dependencies: path-key "^3.0.0" -"npmlog@0 || 1 || 2 || 3 || 4", npmlog@^4.0.0, npmlog@^4.0.2: +npmlog@^4.0.2: version "4.1.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== @@ -9165,7 +9090,7 @@ os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= -osenv@0, osenv@^0.1.4: +osenv@^0.1.4: version "0.1.5" resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== @@ -10786,6 +10711,13 @@ readdirp@~3.4.0: dependencies: picomatch "^2.2.1" +readdirp@~3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e" + integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ== + dependencies: + picomatch "^2.2.1" + readline2@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35" @@ -10975,7 +10907,7 @@ request-promise-native@^1.0.5: stealthy-require "^1.1.1" tough-cookie "^2.3.3" -request@^2.87.0, request@^2.88.0: +request@^2.88.0: version "2.88.0" resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== @@ -11136,13 +11068,6 @@ rgba-regex@^1.0.0: resolved "https://registry.yarnpkg.com/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3" integrity sha1-QzdOLiyglosO8VI0YLfXMP8i7rM= -rimraf@2, rimraf@^2.4.0, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@^2.6.3: - version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" - integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== - dependencies: - glob "^7.1.3" - rimraf@2.6.3, rimraf@~2.6.2: version "2.6.3" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" @@ -11150,6 +11075,13 @@ rimraf@2.6.3, rimraf@~2.6.2: dependencies: glob "^7.1.3" +rimraf@^2.4.0, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@^2.6.3: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + rimraf@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.0.tgz#614176d4b3010b75e5c390eb0ee96f6dc0cebb9b" @@ -11249,16 +11181,6 @@ sanitize-filename@^1.6.0, sanitize-filename@^1.6.2: dependencies: truncate-utf8-bytes "^1.0.0" -sass-graph@^2.2.4: - version "2.2.4" - resolved "https://registry.yarnpkg.com/sass-graph/-/sass-graph-2.2.4.tgz#13fbd63cd1caf0908b9fd93476ad43a51d1e0b49" - integrity sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k= - dependencies: - glob "^7.0.0" - lodash "^4.0.0" - scss-tokenizer "^0.2.3" - yargs "^7.0.0" - sass-lint@^1.12.0: version "1.13.1" resolved "https://registry.yarnpkg.com/sass-lint/-/sass-lint-1.13.1.tgz#5fd2b2792e9215272335eb0f0dc607f61e8acc8f" @@ -11287,6 +11209,13 @@ sass-unused@^0.3.0: glob "^7.0.5" gonzales-pe "^4.2.3" +sass@^1.26.3: + version "1.30.0" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.30.0.tgz#60bbbbaf76ba10117e61c6c24f00161c3d60610e" + integrity sha512-26EUhOXRLaUY7+mWuRFqGeGGNmhB1vblpTENO1Z7mAzzIZeVxZr9EZoaY1kyGLFWdSOZxRMAufiN2mkbO6dAlw== + dependencies: + chokidar ">=2.0.0 <4.0.0" + sax@>=0.6.0, sax@^1.2.4, sax@~1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" @@ -11324,14 +11253,6 @@ schema-utils@^2.6.5: ajv "^6.12.0" ajv-keywords "^3.4.1" -scss-tokenizer@^0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz#8eb06db9a9723333824d3f5530641149847ce5d1" - integrity sha1-jrBtualyMzOCTT9VMGQRSYR85dE= - dependencies: - js-base64 "^2.1.8" - source-map "^0.4.2" - seek-bzip@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/seek-bzip/-/seek-bzip-1.0.5.tgz#cfe917cb3d274bcffac792758af53173eb1fabdc" @@ -11373,11 +11294,6 @@ semver@^6.0.0, semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -semver@~5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" - integrity sha1-myzl094C0XxgEq0yaqa00M9U+U8= - send@0.16.2: version "0.16.2" resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1" @@ -11746,13 +11662,6 @@ source-map-url@^0.4.0: resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= -source-map@^0.4.2: - version "0.4.4" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" - integrity sha1-66T12pwNyZneaAMti092FzZSA2s= - dependencies: - amdefine ">=0.0.4" - source-map@^0.5.0, source-map@^0.5.1, source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7, source-map@~0.5.0: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" @@ -11898,13 +11807,6 @@ statuses@~1.4.0: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" integrity sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew== -stdout-stream@^1.4.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/stdout-stream/-/stdout-stream-1.4.1.tgz#5ac174cdd5cd726104aa0c0b2bd83815d8d535de" - integrity sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA== - dependencies: - readable-stream "^2.0.1" - stealthy-require@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" @@ -12335,15 +12237,6 @@ tar-stream@~0.4.0: readable-stream "^1.0.27-1" xtend "^4.0.0" -tar@^2.0.0: - version "2.2.2" - resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.2.tgz#0ca8848562c7299b8b446ff6a4d60cdbb23edc40" - integrity sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA== - dependencies: - block-stream "*" - fstream "^1.0.12" - inherits "2" - tar@^4: version "4.4.11" resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.11.tgz#7ac09801445a3cf74445ed27499136b5240ffb73" @@ -12706,13 +12599,6 @@ trim@^0.0.1: resolved "https://registry.yarnpkg.com/trim/-/trim-0.0.1.tgz#5858547f6b290757ee95cccc666fb50084c460dd" integrity sha1-WFhUf2spB1fulczMZm+1AITEYN0= -"true-case-path@^1.0.2": - version "1.0.3" - resolved "https://registry.yarnpkg.com/true-case-path/-/true-case-path-1.0.3.tgz#f813b5a8c86b40da59606722b144e3225799f47d" - integrity sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew== - dependencies: - glob "^7.1.2" - truncate-utf8-bytes@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz#405923909592d56f78a5818434b0b78489ca5f2b" @@ -13399,7 +13285,7 @@ which-module@^2.0.0: resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= -which@1, which@^1.1.1, which@^1.2.14, which@^1.2.9, which@^1.3.1: +which@^1.1.1, which@^1.2.14, which@^1.2.9, which@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== @@ -13662,13 +13548,6 @@ yargs-parser@^18.1.2: camelcase "^5.0.0" decamelize "^1.2.0" -yargs-parser@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.0.tgz#275ecf0d7ffe05c77e64e7c86e4cd94bf0e1228a" - integrity sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo= - dependencies: - camelcase "^3.0.0" - yargs@13.2.4: version "13.2.4" resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.4.tgz#0b562b794016eb9651b98bd37acf364aa5d6dc83" @@ -13719,25 +13598,6 @@ yargs@^15.4.1: y18n "^4.0.0" yargs-parser "^18.1.2" -yargs@^7.0.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8" - integrity sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg= - dependencies: - camelcase "^3.0.0" - cliui "^3.2.0" - decamelize "^1.1.1" - get-caller-file "^1.0.1" - os-locale "^1.4.0" - read-pkg-up "^1.0.1" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^1.0.2" - which-module "^1.0.0" - y18n "^3.2.1" - yargs-parser "^5.0.0" - yargs@^7.1.0: version "7.1.1" resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.1.tgz#67f0ef52e228d4ee0d6311acede8850f53464df6" diff --git a/src/css/animations.scss b/src/css/animations.scss index 3e9b22f7..0716da70 100644 --- a/src/css/animations.scss +++ b/src/css/animations.scss @@ -1,13 +1,19 @@ -@include MakeAnimationWrappedEvenOdd(0.2s ease-in-out, "changeAnim") { - 0% { - transform: scale(1, 1); +@each $num in ("changeAnimEven", "changeAnimOdd") { + @keyframes #{$animName} { + 0% { + transform: scale(1, 1); + } + + 50% { + transform: scale(1.03, 1.03); + } + + 100% { + transform: scale(1, 1); + } } - 50% { - transform: scale(1.03, 1.03); - } - - 100% { - transform: scale(1, 1); + .#{$animName} { + animation: $animName 0.2s ease-in-out; } } From 6f486767b64074821951ef23f5a4c0708f4e3c72 Mon Sep 17 00:00:00 2001 From: dengr1065 Date: Tue, 29 Dec 2020 11:39:52 +0200 Subject: [PATCH 02/52] SCSS: Fix refactoring variable name (#1042) --- src/css/animations.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/css/animations.scss b/src/css/animations.scss index 0716da70..16ba7fd1 100644 --- a/src/css/animations.scss +++ b/src/css/animations.scss @@ -1,4 +1,4 @@ -@each $num in ("changeAnimEven", "changeAnimOdd") { +@each $animName in ("changeAnimEven", "changeAnimOdd") { @keyframes #{$animName} { 0% { transform: scale(1, 1); From 38a69fbd38ed3520d1676e266a4a8ea359b26ebd Mon Sep 17 00:00:00 2001 From: Kexogg <65514050+Kexogg@users.noreply.github.com> Date: Tue, 29 Dec 2020 14:40:46 +0500 Subject: [PATCH 03/52] Update base-ru.yaml (#1038) Fixed incorrect description of Tick Rate, added new translations. If possible, please change fallback for cyrillic font. It's literally Times New Roman (in-game) --- translations/base-ru.yaml | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/translations/base-ru.yaml b/translations/base-ru.yaml index bb77dfc9..3b16edd4 100644 --- a/translations/base-ru.yaml +++ b/translations/base-ru.yaml @@ -86,10 +86,10 @@ mainMenu: changelog: Список изменений importSavegame: Импорт openSourceHint: Это игра с открытым исходным кодом! - discordLink: Официальный Дискорд сервер! + discordLink: Официальный Дискорд сервер helpTranslate: Помоги с переводом! browserWarning: Извините, но игра работает медленно в вашем браузере! - Приобретите полную версию или загрузите Chrome чтобы ознакомится с игрой + Приобретите полную версию или загрузите Google Chrome, чтобы ознакомится с игрой в полной мере. savegameLevel: Уровень savegameLevelUnknown: Неизвестный уровень @@ -753,7 +753,7 @@ settings: general: Основные userInterface: Интерфейс advanced: Продвинутые - performance: Performance + performance: Производительность versionBadges: dev: Разработчик staging: Постановка @@ -803,11 +803,8 @@ settings: dark: Темная light: Светлая refreshRate: - title: Частота обновления - description: Если у вас монитор 144 Гц, измените частоту обновления здесь, чтобы - игра правильно выглядела при более высоких частотах обновления. - Это может уменьшить FPS, если ваш компьютер работает слишком - медленно. + title: Тикрейт + description: Определяет, сколько игровых тиков происходит в секунду. Более высокая частота тиков означает лучшую точность, но также и худшую производительность. На низких тикрейтах симуляция может быть неточной. alwaysMultiplace: title: Многократное размещение description: Если включено, все здания останутся выбранными после размещения, @@ -872,7 +869,7 @@ settings: title: Громкость Звука description: Задает громкость звуковых эффектов. musicVolume: - title: Music Volume + title: Громкость музыки description: Задает громкость музыки. lowQualityMapResources: title: Низкое качество ресурсов на карте @@ -999,7 +996,7 @@ about: Если вы хотите внести свой вклад игре - shapez.io в github.

- Эта игра не была бы возможна без большого сообщества в дискорде, которое собралось вокруг моих игр - Вам действительно стоит присоединиться к + Эта игра не была бы возможна без большого сообщества в Discord, которое собралось вокруг моих игр - Вам действительно стоит присоединиться к серверу Discord!!

Саундтрек сделал Peppsen - Он потрясающий.

From abb7ac782d8056b096fc5d8ac560d7874f772132 Mon Sep 17 00:00:00 2001 From: Gumball73 <66757746+Gumball73@users.noreply.github.com> Date: Sat, 2 Jan 2021 09:30:41 +0000 Subject: [PATCH 04/52] Update base-pt-PT.yaml (#1046) Fix some typos. --- translations/base-pt-PT.yaml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/translations/base-pt-PT.yaml b/translations/base-pt-PT.yaml index 62d3b333..300435c8 100644 --- a/translations/base-pt-PT.yaml +++ b/translations/base-pt-PT.yaml @@ -895,7 +895,7 @@ settings: lembra-te de experimentares! disableTileGrid: title: Desativar Grelha - description: Desativar a grelha pode ajudar com o desempenho. Isto também fazz o + description: Desativar a grelha pode ajudar com o desempenho. Isto também faz o jogo parecer mais limpo! clearCursorOnDeleteWhilePlacing: title: Limpar Cursor com Clique Direito @@ -905,7 +905,7 @@ settings: direito do rato enquanto colocas um edifício. lowQualityTextures: title: Texturas de baixa qualidade (Feio) - description: sa texturas de baixa qualidade para melhorar o desempenho. sto vai + description: Usa texturas de baixa qualidade para melhorar o desempenho. Isto vai tornar o jogo parecer muito feio! displayChunkBorders: title: Mostrar bordas de limites (chunk borders) @@ -928,12 +928,12 @@ settings: velociade depende da definição de velocidade de movimentação. zoomToCursor: title: Zoom towards Cursor - description: If activated the zoom will happen in the direction of your mouse - position, otherwise in the middle of the screen. + description: Se ativado o zoom será na direção da posição + do teu rato, de outra forma será para o centro do ecrã. mapResourcesScale: - title: Map Resources Size - description: Controls the size of the shapes on the map overview (when zooming - out). + title: Tamanho de Recursos no Mapa + description: Controla o tamanho das formas na visão geral do mapa (aplicando + zoom out). rangeSliderPercentage: % keybindings: title: Atalhos From d8261a0b310c891bca080f434b2bec00026926c2 Mon Sep 17 00:00:00 2001 From: tobspr Date: Sun, 17 Jan 2021 15:14:29 +0100 Subject: [PATCH 05/52] Closes #1052 --- src/js/game/hud/parts/building_placer.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/js/game/hud/parts/building_placer.js b/src/js/game/hud/parts/building_placer.js index 7dccb7a4..7d618b6b 100644 --- a/src/js/game/hud/parts/building_placer.js +++ b/src/js/game/hud/parts/building_placer.js @@ -216,8 +216,8 @@ export class HUDBuildingPlacer extends HUDBuildingPlacerLogic { const dimensions = metaBuilding.getDimensions(variant); const sprite = metaBuilding.getPreviewSprite(0, variant); const spriteWrapper = makeDiv(element, null, ["iconWrap"]); - spriteWrapper.setAttribute("data-tile-w", dimensions.x); - spriteWrapper.setAttribute("data-tile-h", dimensions.y); + spriteWrapper.setAttribute("data-tile-w", String(dimensions.x)); + spriteWrapper.setAttribute("data-tile-h", String(dimensions.y)); spriteWrapper.innerHTML = sprite.getAsHTML(iconSize * dimensions.x, iconSize * dimensions.y); From aa4949c90f78f6cf1e2702a47d23080e62ec78b8 Mon Sep 17 00:00:00 2001 From: Specter711497 <77533045+Specter711497@users.noreply.github.com> Date: Sun, 17 Jan 2021 22:16:29 +0800 Subject: [PATCH 06/52] Update base-zh-TW.yaml (#1057) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 912 - 地圖永遠部會自然生成完整的風車圖形。is not correct. - 地圖永遠不會自然生成完整的風車圖形。is correct. --- translations/base-zh-TW.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/translations/base-zh-TW.yaml b/translations/base-zh-TW.yaml index e7ce1d91..2689dd66 100644 --- a/translations/base-zh-TW.yaml +++ b/translations/base-zh-TW.yaml @@ -909,7 +909,7 @@ tips: - 不要讓東西複雜化,保持簡單則行的遠。 - 遊戲中有時需要重複利用工廠,設計時記得考量重複利用性。 - 有些圖形地圖上就找的到,不必自行堆疊。 - - 地圖永遠部會自然生成完整的風車圖形。 + - 地圖永遠不會自然生成完整的風車圖形。 - 先上色再切割會比較有效率。 - 有了模組,空間淪為假議題、凡夫俗子的憂思。 - 建立一個藍圖工廠,這對模組化很有幫助。 From 1ab3c8c05d95f26ee019d5500ddd0a3c40314a96 Mon Sep 17 00:00:00 2001 From: Fernando Date: Wed, 3 Feb 2021 05:25:15 -0300 Subject: [PATCH 07/52] translated what was missing for PT-BR (#1060) --- translations/base-pt-BR.yaml | 42 ++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/translations/base-pt-BR.yaml b/translations/base-pt-BR.yaml index db4bb0ab..1f24178d 100644 --- a/translations/base-pt-BR.yaml +++ b/translations/base-pt-BR.yaml @@ -326,17 +326,17 @@ ingame: extratores e conecte-os ao hub.

PS: Segure SHIFT enquanto arrasta a esteira para ativar o planejador de esteiras!" - 21_1_place_quad_painter: Place the quad painter and get some - circles, white and - red color! - 21_2_switch_to_wires: Switch to the wires layer by pressing - E!

Then connect all four - inputs of the painter with cables! - 21_3_place_button: Awesome! Now place a Switch and connect it - with wires! - 21_4_press_button: "Press the switch to make it emit a truthy - signal and thus activate the painter.

PS: You - don't have to connect all inputs! Try wiring only two." + 21_1_place_quad_painter: Coloque o pintor (quádruplo) e consiga alguns + circulos, pigmento branco e + vermelho! + 21_2_switch_to_wires: Troque para o nível de fios pressionando + E!

E então conecte todos as quatro + entradas do pintor com fios! + 21_3_place_button: Incrivel! Agora coloque um interruptor e o conecte + com fio! + 21_4_press_button: "Pressione o interruptor para fazé-lo emitir um sinal + verdadeiro o que ativará o pintor.

OBS: Você + não precisa conectar todas as entradas! Tente conectar somente duas." connectedMiners: one_miner: 1 Extrator n_miners: Extratores @@ -687,9 +687,9 @@ storyRewards: desc: Parabéns! Aliás, mais conteúdo vindo na versão completa! reward_balancer: title: Balanceador - desc: The multifunctional balancer has been unlocked - It can - be used to build bigger factories by splitting and merging - items onto multiple belts! + desc: O multifuncional balanceador foi desbloqueado - Ele pode + ser usado para construir fabricas maiores ao dividir e juntar + itens em múltiplas esteiras! reward_merger: title: Unificador Compacto desc: Você desbloqueou uma variante unificadora do @@ -737,13 +737,13 @@ storyRewards: lembre de se divertir! reward_wires_painter_and_levers: title: Fios e Pintor Quádruplo - desc: "You just unlocked the Wires Layer: It is a separate - layer on top of the regular layer and introduces a lot of new - mechanics!

For the beginning I unlocked you the Quad - Painter - Connect the slots you would like to paint with on - the wires layer!

To switch to the wires layer, press - E.

PS: Enable hints in - the settings to activate the wires tutorial!" + desc: "Você acabou de desbloquear o nivel de fios: Ele é uma dimensão + separada da dimensão normal e introduz varias novas mecanicas! +

Para Começar eu desbloqueae para você o pintor + (quádruplo) - Conecte os espaços que você gostaria de usar para pintar com fios no + nivel de fios!

Para entrar no nivel de fios, pressione + E.

OBS: Ligue as dicas nas + configurações para ativar o tutorial de fios!" reward_filter: title: Filtro de Itens desc: Você desbloqueou o Filtro de Itens! Ele irá rotear os From d1d91dcf3cbfb322765e7b9b334d6f93665e807e Mon Sep 17 00:00:00 2001 From: Atum <54530076+rafaelnascimento411@users.noreply.github.com> Date: Wed, 3 Feb 2021 08:25:54 +0000 Subject: [PATCH 08/52] Portuguese translation fixes (#1064) Some more fixes i came across on the Portuguese translation, typos and suggestions --- translations/base-pt-PT.yaml | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/translations/base-pt-PT.yaml b/translations/base-pt-PT.yaml index 300435c8..34511bcd 100644 --- a/translations/base-pt-PT.yaml +++ b/translations/base-pt-PT.yaml @@ -340,7 +340,7 @@ ingame: purple: Roxo cyan: Ciano white: Branco - uncolored: Sem cor + uncolored: Incolor black: Preto shapeViewer: title: Camadas @@ -366,7 +366,7 @@ ingame: desc: Para uma fábrica totalmente automatizada! savegames: title: Savegames ∞ - desc: Tantos quanto o teu corção desejar! + desc: Tantos quanto o teu coração desejar! upgrades: title: ∞ Níveis de melhoria desc: Nesta versão demo apenas tens 5! @@ -477,11 +477,11 @@ buildings: default: name: Fio Elétrico description: Tranfere sinais, que podem ser itens, cores ou um sinal binário (1 - ou 0). Fios de cores diferestes não se conectam. + ou 0). Fios de cores diferentes não se conectam. second: name: Fio Elétrico description: Tranfere sinais, que podem ser itens, cores ou um sinal binário (1 - ou 0). Fios de cores diferestes não se conectam. + ou 0). Fios de cores diferentes não se conectam. balancer: default: name: Distribuidor @@ -630,8 +630,8 @@ storyRewards: esquerda! reward_splitter: title: Divisor - desc: Desbloqueaste o dvisor uma variante do - distribuidor - Aceita uma entradae divide-a em + desc: Desbloqueaste o divisor uma variante do + distribuidor - Aceita uma entrada e divide-a em duas! reward_tunnel: title: Túnel @@ -699,9 +699,9 @@ storyRewards: desc: Parabéns! Já agora, está planeado mais conteúdo para o jogo completo! reward_balancer: title: Distribuidor - desc: The multifunctional balancer has been unlocked - It can - be used to build bigger factories by splitting and merging - items onto multiple belts! + desc: O Distribuidor foi desbloqueado - Pode ser + usado para construir fábricas maiores ao dividir e misturar + itens para vários tapetes! reward_merger: title: Misturador (compacto) desc: Desbloqueaste um misturador, uma variante do @@ -731,15 +731,15 @@ storyRewards: binário (1 ou 0). reward_logic_gates: title: Portões Lógicos - desc: Desbloqueaste os portões lógicos! N tens de te excitar + desc: Desbloqueaste os portões lógicos! Não tens de te excitar com isto, mas é realmente super fixe!

Com estes portões agora podes realizar operações AND, OR, XOR and NOT.

Como um - bónus anteriormente já de dei um transístor! + bónus anteriormente já te dei um transístor! reward_virtual_processing: title: Processamento Virtual desc: Acadei de te dar um monte de novas construções, que te vão permitir simular o processamento de formas!

Agora - podes simular um cortador,um rodador, um empilhador e muito mais na + podes simular um cortador, um rodador, um empilhador e muito mais na camada de fios! Com isto, agora tens três opções para continuares o jogo:

- Construir uma máquina automática para criar qualquer forma possível pedida pelo Edifício Central @@ -760,7 +760,7 @@ storyRewards: desc: Desbloquaste o Filtro de Itens! Vai mandar itens ou para o topo ou para a saída da esquerda dependendo depending se são iguais ao sinal da camada de fios ou não.

Também podes - passar um sinal binário (1 ou 0) para ativa-lo ou desativa-lo + passar um sinal binário (1 ou 0) para ativá-lo ou desativá-lo totalmente. reward_demo_end: title: Fim da Demo @@ -910,7 +910,7 @@ settings: displayChunkBorders: title: Mostrar bordas de limites (chunk borders) description: O jogo está dividido em partes de 16x16 quadrados, se esta - dedinição estiver ativada as bordas de cada limitece são + definição estiver ativada as bordas de cada limite são mostradas. pickMinerOnPatch: title: Selecionar extrator num quadrado de recurso @@ -927,7 +927,7 @@ settings: description: Permite-te mover o mapa movento o rato nos cantos do ecrâ. A velociade depende da definição de velocidade de movimentação. zoomToCursor: - title: Zoom towards Cursor + title: Aproximar no cursor description: Se ativado o zoom será na direção da posição do teu rato, de outra forma será para o centro do ecrã. mapResourcesScale: From 14d09a7d520b0f0b79779a79f24439a491e38e54 Mon Sep 17 00:00:00 2001 From: coderadu <47945947+coderadu@users.noreply.github.com> Date: Thu, 11 Feb 2021 14:06:19 +0200 Subject: [PATCH 09/52] Translated more and made it more understandable (#1068) --- translations/base-ro.yaml | 40 +++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/translations/base-ro.yaml b/translations/base-ro.yaml index 82771831..109b4f18 100644 --- a/translations/base-ro.yaml +++ b/translations/base-ro.yaml @@ -80,23 +80,23 @@ global: space: SPACE demoBanners: title: Versiunea Demo - intro: Ia versiunea Standalone pentru a debloca toate funcțiile! + intro: Instalează versiunea Standalone pentru a debloca toate funcțiile! mainMenu: play: Joacă - changelog: Changelog - importSavegame: Import + changelog: Jurnalul schimbărilor + importSavegame: Importă openSourceHint: Acest joc este open source! discordLink: Serverul oficial de Discord helpTranslate: Ajută să traducem! browserWarning: Scuze dar, jocul este știut să ruleze încet pe browser-ul tău! - Ia versiunea standalone sau descarcă chrome pentru experiența completă. + Instalează versiunea standalone sau descarcă chrome pentru experiența completă. savegameLevel: Nivelul savegameLevelUnknown: Nivel necunoscut continue: Continuă newGame: Joc nou madeBy: Făcut de subreddit: Reddit - savegameUnnamed: Unnamed + savegameUnnamed: Fară nume dialogs: buttons: ok: OK @@ -105,28 +105,28 @@ dialogs: later: Mai târziu restart: Restartează reset: Resetează - getStandalone: Ia Standalone-ul + getStandalone: Instalează Standalone-ul deleteGame: Știu ce fac viewUpdate: Vezi Update-ul showUpgrades: Vezi Upgrade-urile showKeybindings: Arată tastele configurate importSavegameError: - title: Eroare la Import - text: "Încercarea de import a eșuat:" + title: Eroare la Importare + text: "Încercarea de importare a eșuat:" importSavegameSuccess: - title: Savegame importat - text: Savegame-ul tău a fost importat cu succes. + title: Salvarea importată + text: Salvarea ta a fost importat cu succes. gameLoadFailure: - title: Jocul este stricat - text: "Încercarea de încărcat savegame-ul a eșuat:" + title: Jocul este corupt + text: "Încercarea de a încărca salvarea a eșuat:" confirmSavegameDelete: title: Confirmă ștergerea - text: Are you sure you want to delete the following game?

- '' at level

This can not be - undone! + text: Ești sigur că vrei să ștergi următorul joc?

+ '' la nivelul

Acest lucru nu poate fi + anulat! savegameDeletionError: title: Eroare la ștergere - text: "Nu a reușit să se ștearga savegame-ul:" + text: "Nu a reușit să se ștearga salvarii:" restartRequired: title: Restartare necesară text: Trebuie să restartezi jocul pentru a aplica setările. @@ -144,11 +144,11 @@ dialogs: featureRestriction: title: Demo Version desc: Ai încercat să accesezi o funcție () care nu este disponibilă în - demo. Consideră să iei standalone-ul pentru experiența completă! + demo. Consideră să instalezi standalone-ul pentru experiența completă! oneSavegameLimit: - title: Savegame-uri limitate - desc: Poți avea doar un savegame în același timp în versiunea demo. Te rugăm - șterge-o pe cea existentă sau ia standalone-ul! + title: Salvări limitate + desc: Poți avea doar o salvare în același timp în versiunea demo. Te rugăm + șterge-o pe cea existentă sau instalează standalone-ul! updateSummary: title: Update nou! desc: "Aici sunt schimbările de când ai jucat ultima oară:" From 8850ab6c0807c11bb2fcce4c97386f8f0c7bf6a5 Mon Sep 17 00:00:00 2001 From: RevosCZ <72229413+RevosCZ@users.noreply.github.com> Date: Thu, 4 Mar 2021 07:00:55 +0100 Subject: [PATCH 10/52] Update base-cz.yaml (#1075) * Update base-cz.yaml Nothing special, just noticed a missing gap :D * Update base-cz.yaml --- translations/base-cz.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/translations/base-cz.yaml b/translations/base-cz.yaml index 2f2909f0..70e561fa 100644 --- a/translations/base-cz.yaml +++ b/translations/base-cz.yaml @@ -291,7 +291,7 @@ ingame: interactiveTutorial: title: Tutoriál hints: - 1_1_extractor: Umístěte extraktor na nalezištěkruhového + 1_1_extractor: Umístěte extraktor na naleziště kruhového tvaru a vytěžte jej! 1_2_conveyor: "Připojte extraktor pomocí dopravníkového pásu k vašemu HUBu!

Tip: Klikněte a táhněte @@ -563,7 +563,7 @@ buildings: do levé. stacker: name: Virtuální kombinátor - description: Virtuálně Spojí tvary dohromady. Pokud nemohou být spojeny, pravý + description: Virtuálně spojí tvary dohromady. Pokud nemohou být spojeny, pravý tvar je položen na levý. painter: name: Virtuální barvič From 24240d514bdec7467b1066b98609c5f29a66395b Mon Sep 17 00:00:00 2001 From: Flipper5201 <80040357+Flipper5201@users.noreply.github.com> Date: Mon, 8 Mar 2021 11:00:45 +0100 Subject: [PATCH 11/52] massCutConfirm, line 187 (#1079) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This should translated to ( w roli ścisłości), not ( gwoli ścisłości). --- translations/base-pl.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/translations/base-pl.yaml b/translations/base-pl.yaml index 360f3cad..cd6d7a59 100644 --- a/translations/base-pl.yaml +++ b/translations/base-pl.yaml @@ -186,7 +186,7 @@ dialogs: wersję gry dla nielimitowanych znaczników! massCutConfirm: title: Potwierdź wycinanie - desc: Wycinasz sporą ilość maszyn ( gwoli ścisłości)! Czy na pewno chcesz + desc: Wycinasz sporą ilość maszyn ( w roli ścisłości)! Czy na pewno chcesz kontynuować? exportScreenshotWarning: title: Tworzenie zrzutu fabryki From b03f11772896d46b5e438838c56d081b93d5a1cf Mon Sep 17 00:00:00 2001 From: RevosCZ <72229413+RevosCZ@users.noreply.github.com> Date: Mon, 8 Mar 2021 11:01:04 +0100 Subject: [PATCH 12/52] Update base-cz.yaml (#1080) * Update base-cz.yaml Decided to solve the issue with the picture overlapping the name of buildings by shortening the words into shortcuts. * Update base-cz.yaml --- translations/base-cz.yaml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/translations/base-cz.yaml b/translations/base-cz.yaml index 70e561fa..68f01ec8 100644 --- a/translations/base-cz.yaml +++ b/translations/base-cz.yaml @@ -404,7 +404,7 @@ buildings: name: Extraktor description: Umístěte na naleziště tvaru nebo barvy pro zahájení těžby. chainable: - name: Extraktor (Navazující) + name: Extraktor (Řetěz) description: Umístěte na naleziště tvaru nebo barvy pro zahájení těžby. Lze zapojit po skupinách. underground_belt: @@ -449,10 +449,10 @@ buildings: name: Barvič description: Obarví celý tvar v levém vstupu barvou z pravého vstupu. double: - name: Barvič (dvojnásobný) + name: Barvič (2x) description: Obarví tvary z levých vstupů barvou z horního vstupu. quad: - name: Barvič (čtyřnásobný) + name: Barvič (4x) description: Umožňuje obarvit každou čtvrtinu tvaru individuálně. Jen čtvrtiny se vstupy barev s logickým signálem na vrstvě kabelů budou obarveny! @@ -475,16 +475,16 @@ buildings: name: Vyvažovač description: Multifunkční - Rovnoměrně rozděluje vstupy na výstupech. merger: - name: Spojovač (kompaktní) + name: Spojovač description: Spojí dva pásy do jednoho. merger-inverse: - name: Spojovač (kompaktní) + name: Spojovač description: Spojí dva pásy do jednoho. splitter: - name: Rozdělovač (kompaktní) + name: Rozdělovač description: Rozdělí jeden pás na dva. splitter-inverse: - name: Rozdělovač (kompaktní) + name: Rozdělovač description: Rozdělí jeden pás na dva. storage: default: @@ -558,11 +558,11 @@ buildings: name: Virtuální rotor description: Virtuálně otáčí tvary o 90 stupňů po směru hodinových ručiček. unstacker: - name: Virtuální extrahátor + name: Virt. extrahátor description: Virtuálně extrahuje nejvyšší vrstvu do pravého výstupu a zbývající do levé. stacker: - name: Virtuální kombinátor + name: Virt. kombinátor description: Virtuálně spojí tvary dohromady. Pokud nemohou být spojeny, pravý tvar je položen na levý. painter: @@ -615,8 +615,8 @@ storyRewards: proti směru hodinových ručiček. Vyberte rotor a zmáčkněte 'T' pro přepnutí mezi variantami! reward_miner_chainable: - title: Napojovací extraktor - desc: "Právě jste odemkli napojovací extraktor! Může + title: Řetězový extraktor + desc: "Právě jste odemkli řetězový extraktor! Může předat své zdroje ostatním extraktorům, čímž můžete efektivněji těžit více zdrojů!

PS: Starý extraktor bude od teď nahrazen ve vašem panelu nástrojů!" @@ -1008,7 +1008,7 @@ tips: - Můžete proplétat různé úrovně tunelů. - Snažte se postavit kompaktní továrny - vyplatí se to! - Barvič má zrcadlově otočenou variantu, kterou můžete vybrat klávesou - T + T. - Užití správné kombinace vylepšení maximalizuje efektivitu. - Na maximální úrovní, 5 extraktorů zaplní jeden celý pás. - Nezapomeňte na tunely! From 3f7b0053c331b497e74d0104358c66080e82458e Mon Sep 17 00:00:00 2001 From: hcanergun <56073681+hcanergun@users.noreply.github.com> Date: Mon, 8 Mar 2021 13:01:21 +0300 Subject: [PATCH 13/52] Update base-tr.yaml (#1083) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dödürcü was wrong for rotator there was typo it should be "Döndürücü" --- translations/base-tr.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/translations/base-tr.yaml b/translations/base-tr.yaml index 389b01e8..5dbafce6 100644 --- a/translations/base-tr.yaml +++ b/translations/base-tr.yaml @@ -438,7 +438,7 @@ buildings: name: Döndürücü (Saat Yönünün Tersİ) description: Şekilleri saat yönünün tersinde 90 derece döndürür. rotate180: - name: Dödürücü (180 Derece) + name: Döndürücü (180 Derece) description: Şekilleri 180 derece döndürür. stacker: default: @@ -701,7 +701,7 @@ storyRewards: hızını ölçmeyi sağlar.

Kabloları açana kadar bekle - o zaman çok kullanışlı olacak. reward_rotater_180: - title: Dödürücü (180 derece) + title: Döndürücü (180 derece) desc: 180 derece döndürücüyü açtınız! - Şekilleri 180 derece döndürür (Süpriz! :D) reward_display: From 0b18cedd819de69acc00c529d647b8b606a32437 Mon Sep 17 00:00:00 2001 From: anitmyan <61045441+anitmyan@users.noreply.github.com> Date: Mon, 8 Mar 2021 19:01:34 +0900 Subject: [PATCH 14/52] Update base-ja.yaml (#1085) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changed ベルトリーダ to ベルトリーダー --- translations/base-ja.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/translations/base-ja.yaml b/translations/base-ja.yaml index a49611a2..ce8488e5 100644 --- a/translations/base-ja.yaml +++ b/translations/base-ja.yaml @@ -495,7 +495,7 @@ buildings: description: 入力された信号をディスプレイに表示します。 形状、色、真偽値のいずれでも可能です。 reader: default: - name: ベルトリーダ + name: ベルトリーダー description: 平均スループットを計測できます。 アンロック後は、 最後に通過したアイテムの情報を出力します。 analyzer: default: @@ -577,8 +577,8 @@ storyRewards: desc: 分配機コンパクトバージョンが利用可能になりました! - 1つの入力を2つの出力に分配します! reward_belt_reader: - title: ベルトリーダ - desc: ベルトリーダが利用可能になりました!ベルトのスループットを計測できます。

ワイヤーのロックが解除されれば、より便利になります! + title: ベルトリーダー + desc: ベルトリーダーが利用可能になりました!ベルトのスループットを計測できます。

ワイヤーのロックが解除されれば、より便利になります! reward_cutter_quad: title: 四分割 desc: 切断機のバリエーションが利用可能になりました。 - @@ -846,7 +846,7 @@ keybindings: filter: アイテムフィルタ wire_tunnel: 交差ワイヤ display: ディスプレイ - reader: ベルトリーダ + reader: ベルトリーダー virtual_processor: 仮想切断機 transistor: トランジスタ analyzer: 形状解析機 From e53ec8d6afa0a322c4e195937ae1211c7df52141 Mon Sep 17 00:00:00 2001 From: tobspr Date: Mon, 8 Mar 2021 11:59:45 +0100 Subject: [PATCH 15/52] Update chinese translation --- translations/base-zh-CN.yaml | 676 ++++++++++++++++++----------------- 1 file changed, 344 insertions(+), 332 deletions(-) diff --git a/translations/base-zh-CN.yaml b/translations/base-zh-CN.yaml index 41be04d3..5c5a19c4 100644 --- a/translations/base-zh-CN.yaml +++ b/translations/base-zh-CN.yaml @@ -1,30 +1,36 @@ steamPage: - shortText: shapez.io 是一款在无边际的地图上建造工厂、自动化生产与组合愈加复杂的图形的游戏。 + shortText: “唯一能限制您的,只有您的想象力!” 《异形工厂》(Shapez.io) 是一款在无限拓展的地图上,通过建造各类工厂设施,来自动化生产与组合出愈加复杂图形的游戏。 discordLinkShort: 官方 Discord 服务器 intro: |- - Shapez.io 是一个休闲游戏,在其中,你将建造工厂以生产各种各样的几何图形。 - 随着等级提升,你需要生产的图形将会越来越复杂,你需要在无尽的地图中不断的扩建你的工厂。 - 如果这些还不够的话,你的生产目标是指数性增长的 - 你需要持续的增大工厂的规模! - 虽然你刚开始只需要生产图形,但你之后还可以给这些图形上色 - 你需要开采并混合颜料! - 你可以在 Steam 游戏商城购买此游戏的完整版, 但你可以先游玩试玩版并体验游戏! + “奇形怪状,放飞想象!” + “自动生产,尽情创造!” + 《异形工厂》(Shapez.io)是一款能让您尽情发挥创造力,充分享受思维乐趣的IO游戏。 + 游戏很轻松,只需建造工厂,布好设施,无需操作即能自动创造出各种各样的几何图形。 + 挑战很烧脑,随着等级提升,需要创造的图形将会越来越复杂,同时您还需要在无限扩展的地图中持续扩建优化您的工厂。 + 以为这就是全部了吗? 不!图形的生产需求将会指数性增长,持续的扩大规模和熵增带来的无序,将会是令人头痛的问题! + 这还不是全部! 一开始我们创造了图形,然后我们需要学会提取和混合来让它们五颜六色。 + 然后,还有吗? 当然,唯有思维,方能无限。 + + 欢迎免费体验试玩版:“让您的想象力插上翅膀!” + 和最聪明的玩家一起挑战,请访问 Steam 游戏商城购买《异形工厂》(Shapez.io)的完整版, title_advantages: 完整版内容 advantages: - - 12 个全新关卡 总共 26 个不同关卡 - - 18 个全新建筑 用于建造全自动工厂! - - 20 个等级升级 不停的愉快游玩! - - 导线更新包 解锁更多可能 - - 暗色模式! + - 12 个全新关卡 总共 26 个不同关卡! + - 18 个全新设施 呈现完全体的全自动工厂! + - 无限升级 又难又肝!让您一不小心就忘了时间! + - 导线更新包 发挥创造力的全新维度! + - 深色模式! 优雅且护眼的配色! - 无限数量存档 - 无限数量地图标记 - 支持作者! ❤️ - title_future: 预计更新 + title_future: 后续更新内容 planned: - - 建筑蓝图库 - - Steam 成就 - - 解密模式 - - 小地图 - - 模组 - - 沙盒模式 + - 蓝图库 + - 加入Steam成就 + - 全新DLC:解密模式 + - 增加小地图 + - 模组(Mods)支持 + - 增加沙盒模式 - ... 以及更多! title_open_source: 这个游戏是开源的! title_links: 链接 @@ -35,18 +41,18 @@ steamPage: source_code: 源代码 (GitHub) translate: 帮助汉化(翻译)组! text_open_source: |- - 任何人都可以对这个游戏做出贡献,我会活跃在游戏社区中并 尽最大可能积极参考大家对这个游戏的的全部建议和反馈。 - 请关注我的 trello board 以获取 the full roadmap! + 欢迎加入,一起创造!感谢所有对这个游戏做出贡献的玩家,作者和中国区发行小伙伴们会活跃在游戏社区中,并尽最大可能积极参考大家对这个游戏的的全部建议和反馈。 + 请关注我的 trello board 以获取完整的游戏路线图! global: loading: 加载中 error: 错误 thousandsDivider: "," decimalSeparator: . suffix: - thousands: K - millions: M - billions: B - trillions: T + thousands: 千 + millions: 百万 + billions: 亿万 + trillions: 兆 infinite: 无限 time: oneSecondAgo: 1秒前 @@ -62,150 +68,151 @@ global: hoursAndMinutesShort: 分 xMinutes: 分钟 keys: - tab: TAB - control: CTRL - alt: ALT - escape: ESC - shift: SHIFT - space: 空格 + tab: TAB键 + control: CTRL键 + alt: ALT键 + escape: ESC键 + shift: SHIFT键 + space: 空格键 demoBanners: title: 试玩版 - intro: 获取独立版以解锁所有游戏内容! + intro: 购买完整版以解锁所有游戏内容! mainMenu: play: 开始游戏 changelog: 更新日志 - importSavegame: 导入 + importSavegame: 读取存档 openSourceHint: 本游戏已开源! discordLink: 官方Discord服务器 helpTranslate: 帮助我们翻译! - browserWarning: 很抱歉, 本游戏在当前浏览器上可能运行缓慢! 使用 Chrome 或者获取独立版以得到更好的体验。 + browserWarning: 很抱歉, 本游戏在当前浏览器上可能运行缓慢! 使用 Chrome 或者购买完整版以得到更好的体验。 savegameLevel: 第关 savegameLevelUnknown: 未知关卡 continue: 继续游戏 newGame: 新游戏 madeBy: 作者: subreddit: Reddit - savegameUnnamed: 未命名 + savegameUnnamed: 存档未命名 dialogs: buttons: ok: 确认 delete: 删除 cancel: 取消 later: 以后 - restart: 重启游戏 + restart: 重新开始 reset: 重置 - getStandalone: 获取独立版 - deleteGame: 我知道我在做什么 + getStandalone: 获取完整版 + deleteGame: 我没疯!我知道我在做什么! viewUpdate: 查看更新 - showUpgrades: 显示建筑升级 + showUpgrades: 显示设施升级 showKeybindings: 显示按键设置 importSavegameError: - title: 导入错误 - text: 未能导入你的存档: + title: 读取错误 + text: 未能读取您的存档: importSavegameSuccess: - title: 导入成功 - text: 存档被成功导入 + title: 读取成功 + text: 存档被成功读取 gameLoadFailure: title: 存档损坏 - text: 未能导入你的存档: + text: 未能读取您的存档: confirmSavegameDelete: title: 确认删除 - text: 你确定要删除这个游戏吗?

+ text: 您确定要删除这个游戏吗?

'' 等级

该操作无法回退! savegameDeletionError: - title: 删除错误 - text: 未能删除你的存档 + title: 删除失败 + text: 未能删除您的存档 restartRequired: title: 需要重启游戏 - text: 你需要重启游戏以应用变更的设置。 + text: 您需要重启游戏以应用变更的设置。 editKeybinding: - title: 更改按键设置 - desc: 请按下你想要使用的按键,或者按下 ESC 键来取消设置。 + title: 更改按键设定 + desc: 请按下您想要使用的按键以设定,或者按下 ESC 键来取消设定。 resetKeybindingsConfirmation: - title: 重置所有按键 - desc: 你将要重置所有按键,请确认。 + title: 重置按键设定 + desc: 您将要重置所有按键设定,请确认。 keybindingsResetOk: - title: 重置所有按键 - desc: 成功重置所有按键! + title: 重置按键设定 + desc: 成功重置所有按键设定! featureRestriction: title: 试玩版 - desc: 你尝试使用了功能。该功能在试玩版中不可用。请考虑购买独立版以获得更好的体验。 + desc: 您尝试使用了一项功能。该功能在试玩版中不可用。请考虑购买完整版以获得更好的体验。 oneSavegameLimit: title: 存档数量限制 - desc: 试玩版中只能保存一份存档。请删除旧存档或者获取独立版! + desc: 试玩版中只能保存一份存档。请删除旧存档或者购买完整版! updateSummary: - title: 更新啦! - desc: "以下为自上次游戏以来更新的内容:" + title: 新内容更新啦! + desc: "以下为游戏最新更新内容:" upgradesIntroduction: - title: 解锁建筑升级 - desc: 不要销毁你之前建造的工厂!你生产过的所有图形都会被用来升级建筑。 升级菜单在屏幕右上角。 + title: 解锁升级 + desc: 您生产过的所有图形都能被用来解锁升级。 所以不要销毁您之前建造的工厂! + 注意:升级菜单在屏幕右上角。 massDeleteConfirm: title: 确认删除 - desc: 你将要删除很多建筑,准确来说有幢! 你确定要这么做吗? + desc: 您将要删除很多设施,准确来说有种! 您确定要这么做吗? blueprintsNotUnlocked: - title: 未解锁 - desc: 你还没有解锁蓝图功能!完成更多的关卡来解锁蓝图。 + title: 尚未解锁 + desc: 您还没有解锁蓝图功能!通过第12关的挑战后可解锁蓝图。 keybindingsIntroduction: - title: 实用按键 + title: 实用快捷键 desc: - "这个游戏有很多有用的快捷键。 以下是其中的一些,记得在按键设置中查看其他的!

- CTRL + 拖动:选择区域以复制或删除。
SHIFT: 按住以放置多个。
ALT: 反向放置传送带。
" + "这个游戏有很多有用的快捷键设定。 以下是其中的一些介绍,记得在按键设置中查看其他按键设定!

+ CTRL键 + 拖动:选择区域以复制或删除。
+ SHIFT键: 按住以放置多个同一种设施。
+ ALT键: 反向放置传送带。
" createMarker: title: 创建地图标记 - desc: 填写一个有意义的名称, 你也可以使用形状的 短代码 (你可以 点击这里 生成短代码) + desc: 填写一个有意义的名称, 还可以同时包含一个形状的 短代码 (您可以 点击这里 生成短代码) titleEdit: 编辑地图标记 markerDemoLimit: - desc: 在试玩版中你只能创建两个地图标记。请获取独立版以创建更多标记。 + desc: 在试玩版中您只能创建两个地图标记。请获取完整版以创建更多标记。 massCutConfirm: title: 确认剪切 - desc: 你将要剪切很多建筑,准确来说有幢! 你确定要这么做吗? + desc: 您将要剪切很多设施,准确来说有种! 您确定要这么做吗? exportScreenshotWarning: title: 工厂截图 - desc: 你将要导出你的工厂的截图。如果你的基地很大,截图过程将会很慢,且有可能导致游戏崩溃! + desc: 您将要导出您整个工厂基地的截图。如果您已经建设了一个规模很大的基地,生成截图的过程将会很慢,且有可能导致游戏崩溃! massCutInsufficientConfirm: title: 确认剪切 - desc: 你没有足够的图形来粘贴这个区域!你确定要剪切吗? + desc: 您没有足够的图形来粘贴这个区域!您确定要剪切吗? editSignal: title: 设置信号 - descItems: "选择一个预定义的信号:" - descShortKey: ... 或者输入图形的 短代码 (你可以 点击这里 生成短代码) + descItems: "选择一个预定义的项目:" + descShortKey: ... 或者输入图形的 短代码 (您可以 点击这里 生成短代码) renameSavegame: - title: 重命名存档 - desc: 你可以在此重命名存档。 + title: 重命名游戏存档 + desc: 您可以在此重命名游戏存档。 tutorialVideoAvailable: title: 教程 - desc: 该等级有视频教程! 你想查看这个视频吗? + desc: 这个关卡有视频攻略! 您想查看这个视频攻略? tutorialVideoAvailableForeignLanguage: title: 教程 - desc: 该等级有英语版本的视频教程! 你想查看这个视频吗?? + desc: 这个关卡有英语版本的视频攻略! 您想查看这个视频攻略吗?? ingame: keybindingsOverlay: moveMap: 移动地图 selectBuildings: 选择区域 stopPlacement: 停止放置 - rotateBuilding: 转动建筑 + rotateBuilding: 转动设施 placeMultiple: 放置多个 reverseOrientation: 反向放置 disableAutoOrientation: 关闭自动定向 - toggleHud: 开关 HUD - placeBuilding: 放置建筑 + toggleHud: 切换可视化界面(HUD) + placeBuilding: 放置设施 createMarker: 创建地图标记 delete: 销毁 pasteLastBlueprint: 粘贴上一个蓝图 - lockBeltDirection: 启用传送带规划 + lockBeltDirection: 启用传送带规划器 plannerSwitchSide: 规划器换边 cutSelection: 剪切 copySelection: 复制 clearSelection: 取消选择 - pipette: 选取器 - switchLayers: 选择层 + pipette: 吸取器 + switchLayers: 切换层 buildingPlacement: - cycleBuildingVariants: 按 键以选择建筑变体。 + cycleBuildingVariants: 按 键以选择设施的变型体。 hotkeyLabel: "快捷键: " infoTexts: - speed: 效率 + speed: 速率 range: 范围 storage: 容量 oneItemPerSecond: 1个/秒 @@ -218,65 +225,65 @@ ingame: unlockText: 解锁! buttonNextLevel: 下一关 notifications: - newUpgrade: 有新更新啦! + newUpgrade: 有新内容更新啦! gameSaved: 游戏已保存。 - freeplayLevelComplete: 等级 完成了! + freeplayLevelComplete: 第 关 完成了! shop: - title: 建筑升级 + title: 升级 buttonUnlock: 升级 tier: 级 - maximumLevel: 最高级(倍效率) + maximumLevel: 最高级(倍速率) statistics: title: 统计信息 dataSources: stored: - title: 已交付 - description: 显示基地中每种图形已交付且未使用的数量。 + title: 已存储 + description: 所有图形已存储于中心。 produced: title: 生产 - description: 显示所有正在被生产的图形数量,包括中间产物。 + description: 所有图形已在工厂内生产,包括中间产物。 delivered: - title: 送达 - description: 显示图形送达基地并交付的速度。 - noShapesProduced: 你还没有生产任何图形。 + title: 交付 + description: 图形已交付到中心基地。 + noShapesProduced: 您还没有生产任何图形。 shapesDisplayUnits: second: / 秒 minute: / 分 - hour: / 时 + hour: / 小时 settingsMenu: playtime: 游戏时间 - buildingsPlaced: 建筑数量 + buildingsPlaced: 设施数量 beltsPlaced: 传送带数量 tutorialHints: title: 需要帮助? showHint: 显示帮助 hideHint: 关闭 blueprintPlacer: - cost: 需要 + cost: 成本 waypoints: waypoints: 地图标记 - hub: 基地 - description: 左键跳转到地图标记,右键删除地图标记。

+ hub: 中心 + description: 左键点击地图标记以跳转到该处,右键点击可删除地图标记。

在当前地点创建地图标记,或者在选定位置上右键创建地图标记。 creationSuccessNotification: 成功创建地图标记。 interactiveTutorial: - title: 教程 + title: 新手教程 hints: - 1_1_extractor: 在圆形矿脉上放一个开采器来获取圆形! - 1_2_conveyor: 用传送带将你的开采器连接到基地上!

提示:用你的鼠标按下并拖动传送带! + 1_1_extractor: 在圆形上放置一个开采器来获取圆形!

提示:按下鼠标左键选中开采器 + 1_2_conveyor: 用传送带将您的开采器连接到中心基地上!

提示:选中传送带按下鼠标左键可拖动布置传送带! 1_3_expand: - 这不是一个挂机游戏!建造更多的开采器和传送带来更快地完成目标。

提示:按住 - SHIFT 键来放置多个开采器,用 R 键旋转它们。 - 2_1_place_cutter: "现在放置一个切割器,把圆切成两半!

注意:无论方向如何,切割机总是从上到下切割。" - 2_2_place_trash: 切割机可能会堵塞

使用垃圾桶清除当前 (!) 不需要的废物。 - 2_3_more_cutters: "干的好!现在放置2个以上的切割机来加快当前缓慢的过程!

提示:用0-9快捷键可以快速选择建筑!" + 您可以放置更多的开采器传送带来更有效率地完成关卡目标。

提示:按住 + SHIFT 键可放置多个开采器,注意用R 键可旋转开采器的出口方向,确保开采的图形可以顺利传送。 + 2_1_place_cutter: "现在放置一个切割器,这个设施可把圆形切成两半!

注意:无论如何放置,切割机总是从上到下切割。" + 2_2_place_trash: 使用切割机后产生的废弃图形会导致堵塞

注意使用垃圾桶清除当前 (!) 不需要的废物。 + 2_3_more_cutters: "干的好!现在放置2个以上的切割机来加快当前缓慢的过程!

提示:用快捷键0-9可以快速选择各项设施!" 3_1_rectangles: - "现在让我们开采一些矩形!建4个人开采器并将它们连接到基地。

- 提示:按住SHIFT拖到传送带会激活传送带规划!" - 21_1_place_quad_painter: 放置四口上色器并且输入圆形白色红色! - 21_2_switch_to_wires: 按 E 键选择电线层!

然后用导线连接上色器的四个输入口! + "现在让我们开采一些矩形!找到矩形地带放置4个开采器并将它们用传送带连接到中心基地。

+ 提示:选中传送带后按住SHIFT键可快速准确地规划传送带路线!" + 21_1_place_quad_painter: 放置四口上色器并且获取一些圆形白色红色! + 21_2_switch_to_wires: 按 E 键选择电线层

然后用导线连接上色器的四个输入口! 21_3_place_button: 很好!现在放置一个开关并连接导线! - 21_4_press_button: "按下开关去产生正信号来激活上色器。

注:你不用连上所有的输入口!试着只接两个。" + 21_4_press_button: "按下开关产生正信号以激活上色器

注:您不用连上所有的输入口!试着只接两个。" colors: red: 红色 green: 绿色 @@ -297,8 +304,8 @@ ingame: limited_items: 限制在 watermark: title: 试玩版 - desc: 点击这里 了解完整版内容 - get_on_steam: 在 steam 商城购买 + desc: 点击这里了解完整版内容 + get_on_steam: 在Steam商城购买 standaloneAdvantages: title: 购买完整版! no_thanks: 不需要,谢谢 @@ -307,29 +314,29 @@ ingame: title: 12 个全新关卡! desc: 总共 26 个不同关卡! buildings: - title: 18 个全新建筑 - desc: 用于建造全自动工厂! + title: 18 个全新设施! + desc: 呈现完全体的全自动工厂! savegames: title: 无限数量存档 - desc: 存档功能可以尽情使用 + desc: 放手去干,错了随时重来! upgrades: - title: 20 个等级升级 - desc: 试玩版只有 5 个等级! + title: 20个等级升级 + desc: 试玩版只有5个等级! markers: title: 无限数量地图标记 - desc: 再也不会找不到自己的工厂了 + desc: 地图再大,不会迷路! wires: - title: 导线更新包 - desc: 解锁更多可能! + title: 电线更新包 + desc: 发挥创造力的全新维度! darkmode: title: 暗色模式 - desc: 优雅且护眼的配色 + desc: 优雅且护眼的配色! support: title: 支持作者 desc: 我使用闲暇时间开发游戏! shopUpgrades: belt: - name: 传送带、平衡机、隧道 + name: 传送、分发、隧道 description: 效率 倍 → 倍 miner: name: 开采 @@ -344,107 +351,107 @@ buildings: belt: default: name: 传送带 - description: 运送物品,按住并拖动来放置多个传送带。 + description: 运送物品,选中后按住鼠标并拖动可一次性放置多个传送带。 miner: default: name: 开采器 - description: 在图形或者颜色上放置来开采他们。 + description: 放置在图形或者颜色上进行开采。 chainable: - name: 链式开采器 - description: 在图形或者颜色上放置来开采他们。可以被链接在一起。 + name: 开采器(链式) + description: 放置在图形或者颜色上进行开采。它们可以被链接在一起。 underground_belt: default: name: 隧道 - description: 可以从其他传送带或建筑底下方运送物品。 + description: 可放置在传送带设施下方以运送物品。 tier2: name: 二级隧道 - description: 可以从其他传送带或建筑底下方运送物品。 + description: 可放置在传送带设施下方以运送物品。 cutter: default: name: 切割机 - description: 将图形从上到下切开并输出。如果你只需要其中一半,记得把另一半销毁掉,否则切割机会停止工作! + description: 始终将图形从上到下切开并分别输出。如果您只需要其中一半的图形,使用垃圾桶清除另一半图形,否则切割机会停止工作! quad: name: 切割机(四向) - description: 将输入的图形切成四块。如果你只需要其中一块,记得把其他的销毁掉,否则切割机会停止工作! + description: 将输入的图形切成四块。如果您只需要其中一块图形,使用垃圾桶清除其他图形,否则切割机会停止工作! rotater: default: name: 旋转机 - description: 将图形顺时针旋转90度。 + description: 将图形顺时针旋转90度。 ccw: name: 旋转机(逆时针) - description: 将图形逆时针旋转90度。 + description: 将图形逆时针旋转90度。 rotate180: name: 旋转机 (180度) - description: 将图形旋转180度。 + description: 将图形旋转180度。 stacker: default: name: 堆叠机 - description: 将输入的图形拼贴在一起。如果不能被直接拼贴,右边的图形会被堆叠在左边的图形上面。 + description: 将输入的图形在同一层内组合在一起。如果不能被直接组合,则右边输入图形会堆叠在左边输入图形上面。 mixer: default: name: 混色器 - description: 用加法混色将两个颜色混合起来 + description: 用叠加混色法将两个颜色混合。 painter: default: name: 上色器 - description: 将整个图形涂上输入的颜色。 + description: 将整个图形涂上输入的颜色。 double: - name: 上色器(双倍) - description: 同时为两个输入的图形上色,每次上色只消耗一份颜色。 + name: 上色器(双面) + description: 使用顶部输入的颜色为左侧输入的图形上色。 quad: name: 上色器(四口) - description: 能够为图形的四个象限单独上色。只有电线层上带有正信号的插槽才可以上色! + description: 能够为图形的四个象限单独上色。记住只有通过电线层上带有正信号的插槽才可以上色! mirrored: name: 上色器 (镜像) - description: 将整个图形涂上输入的颜色。 + description: 将整个图形涂上输入的颜色。 trash: default: name: 垃圾桶 - description: 从所有四个方向上输入物品并销毁它们。永远。 + description: 可以从所有四个方向上输入物品并永远清除它们。 hub: deliver: 交付 - toUnlock: 来解锁 + toUnlock: 解锁 levelShortcut: LVL endOfDemo: 试玩版结束 wire: default: - name: 导线 - description: 传输信号,信号可以是物品,颜色或者布尔值。 不同颜色的导线不会互相连接 + name: 电线 + description: 可用来传输信号,信号可以是物品,颜色或者开关值(0或1)。 不同颜色的电线不会互相连接 second: - name: 导线 - description: 传输信号,信号可以是物品,颜色或者布尔值。 不同颜色的导线不会互相连接。 + name: 电线 + description: 可用来传输信号,信号可以是物品,颜色或者开关值(0或1)。 不同颜色的电线不会互相连接 balancer: default: name: 平衡器 - description: 多功能-将所有输入均匀地分配到所有输出上。 + description: 多功能的设施:可将所有输入均匀地分配到所有输出上。 merger: name: 合并器 (小型) - description: 将两条传送带合并为一条。 + description: 可将两条传送带合并为一条。 merger-inverse: name: 合并器 (小型) - description: 将两条传送带合并为一条。 + description: 可将两条传送带合并为一条。 splitter: - name: 分配器 (小型) - description: 将一条传送带分成为两条。 + name: 分离器 (小型) + description: 可将一条传送带分成为两条。 splitter-inverse: - name: 分配器 (小型) - description: 将一条传送带分成为两条。 + name: 分离器 (小型) + description: 可将一条传送带分成为两条。 storage: default: name: 存储器 - description: 储存多余的物品,直到指定的容量。 优先处理左边的输出,可以用作溢出门。 + description: 储存多余的物品,直到储满。 优先处理左边的输出,并可以用作溢出门。 wire_tunnel: default: - name: 交差导线 - description: 使两根导线交差,而不会连接起来。 + name: 交叉电线 + description: 使两根电线交叉而不会连接起来。 constant_signal: default: - name: 固定信号 - description: 发出固定信号,可以是图形、颜色、开关量(1 / 0)。 + name: 恒定信号 + description: 发出固定信号,可以是图形颜色开关值(1 / 0)。 lever: default: name: 开关 - description: 可以在电线层上发出开关量(1 / 0)信号。比如说它可以用来控制过滤器。 + description: 可以在电线层上发出开关值(1 / 0)信号,以达到控制部件的作用,比如可以用来控制物品过滤器。 logic_gate: default: name: 与门 @@ -461,163 +468,170 @@ buildings: transistor: default: name: 晶体管 - description: 如果侧边输入正信号,输入可以通过。(正信号:图形,颜色,开(1)信号) + description: 如果侧边输入正信号,输入可以通过并转发。(正信号:图形,颜色,开(1)信号) mirrored: name: 晶体管 - description: 如果侧边输入正信号,输入可以通过。(正信号:图形,颜色,开(1)信号) + description: 如果侧边输入正信号,输入可以通过并转发。(正信号:图形,颜色,开(1)信号) filter: default: name: 过滤器 - description: 在上面输出和信号匹配的内容,在右侧输出不匹配的内容。如果是开关量的话,开(1)信号从上面输出,关(0)信号从右侧输出 + description: 在顶侧输出和信号匹配的内容,在右侧输出不匹配的内容。如果是开关量的话,开(1)信号从顶侧输出,关(0)信号从右侧输出。 display: default: name: 显示器 - description: 在显示器上显示连接的信号(这些信号可以是:图形、颜色、开关量)。 + description: 在显示器上显示连接的信号(信号可以是:图形、颜色、开关值)。 reader: default: - name: 传送带阅读器 - description: 可以测量传送带平均吞吐量。在电线层输出最后输入物品的信号(可以在‘显示器’上显示,也可用来做过滤) + name: 传送带读取器 + description: 可以读取传送带平均吞吐量。输出最后在电线层上读取的物品(一旦解锁。) analyzer: default: name: 图形分析器 - description: 分析图形最低层的右上象限并返回其图形和颜色。 + description: 分析图形最底层的右上象限并返回其图形颜色。 comparator: default: name: 比较器 - description: 如果输入的两个信号一样将输出开(1)信号,可以比较图形,颜色,和开关量。 + description: 如果输入的两个信号一样将输出开(1)信号,可以比较图形,颜色,和开关值。 virtual_processor: default: - name: 模拟切割机 - description: 将信号中的图形切割成两半并输出信号 + name: 虚拟切割机 + description: 模拟将图形切割成两半。 rotater: name: 模拟旋转机 - description: 将信号中的图形旋转后输出信号 + description: 模拟顺时针旋转图形。 unstacker: name: 模拟拆分器 - description: 将信号中图形的最上层图形信号从右侧输出,其余的图形信号从左侧输出。 + description: 模拟提取最上层图形从右侧输出,提取其余的图形从左侧输出。 stacker: name: 模拟堆叠机 - description: 将右侧的图形叠在左侧的图形上 + description: 模拟将右侧图形叠在左侧图形上。 painter: name: 模拟上色器 - description: 使用右侧输入的颜色给底部输入的图形上色 + description: 模拟使用右侧输入的颜色给底部输入的图形上色 item_producer: default: name: 物品生成器 - description: 仅在沙盒模式下可用,在常规层上输出电线层给定信号的图形。 + description: 仅在沙盒模式下可用,在常规层上输出电线层给定的信号。 storyRewards: reward_cutter_and_trash: title: 切割图形 - desc: 你刚解锁了切割机,它会从上到下切开图形而不管它的方向! -

一定要用扔掉不用的东西,不然它会阻塞传送带, - 为此我给了你垃圾桶,它会摧毁所有放进去的东西! + desc: 恭喜!您解锁了切割机,不管如何放置,它只会从上到下切开图形! +
注意一定要用处理掉切割后废弃的图形,不然它会阻塞传送带, +
使用垃圾桶,它会清除所有放进去的图形! reward_rotater: - title: 顺时针旋转 - desc: 恭喜!你解锁了旋转机。它会顺时针旋转输入的图形90度。 + title: 旋转 + desc: 恭喜!您解锁了旋转机。它会顺时针将输入的图形旋转90度。 reward_painter: title: 上色 - desc: 恭喜!你解锁了上色器。开采一些颜色 (就像你开采图形一样) - 将其在上色器中与图形结合来将图形上色!

注意:如果你患有色盲,可以在设置中启用色盲模式! + desc: + 恭喜!您解锁了上色器。开采一些颜色 (就像您开采图形一样),将其在上色器中与图形结合来将图形上色! +
注意:如果您不幸患有色盲,可以在设置中启用色盲模式 reward_mixer: title: 混合颜色 - desc: 恭喜!你解锁了混色器。这个建筑使用加法混色将两种颜色混合起来。 + desc: 恭喜!您解锁了混色器。它使用叠加混色法将两种颜色混合起来。 reward_stacker: title: 堆叠 - desc: 恭喜!你解锁了堆叠机。堆叠机会尝试把两个输入的图形拼贴在一起。如果有重叠的部分,右边的输入会被堆叠在左边的输入上方! + desc: 恭喜!您解锁了堆叠机。它会将将输入的图形在同一层内组合在一起。 +
如果不能被直接组合,则右边输入图形会堆叠在左边输入图形上面。 reward_splitter: - title: 分离与合并 - desc: 你已经解锁了平衡器的变体分配器,它会把输入的东西分配在两边输出! + title: 分离器(小型) + desc: 您已经解锁了平衡器的变体分离器,它会把输入的东西一分为二! reward_tunnel: title: 隧道 - desc: 恭喜!你解锁了隧道。你现在可以从其他传送带或建筑底下运送物品了! + desc: 恭喜!您解锁了隧道。它可放置在传送带设施下方以运送物品。 reward_rotater_ccw: title: 逆时针旋转 - desc: 恭喜!你解锁了旋转机逆时针变体。这个变体可以逆时针旋转图形。选择旋转机然后按"T"键来选取这个变体。 + desc: + 恭喜!您解锁了旋转机逆时针变体。它可以逆时针旋转图形。 +
选择旋转机然后按"T"键来选取这个变体。 reward_miner_chainable: title: 链式开采器 desc: - "你已经解锁了链式开采器!它能转发它的资源给其他的开采器,这样你就会更有效率的开采资源了!

- 注意:新的开采器替换了工具栏里旧的开采器!" + "您已经解锁了链式开采器!它能转发资源给其他的开采器,这样您就能更有效率的开采各类资源了!

+ 注意:新的开采器已替换了工具栏里旧的开采器!" reward_underground_belt_tier_2: title: 二级隧道 - desc: 恭喜!你解锁了二级隧道。这是隧道的一个变体。二级隧道有更长的传输距离。你还可以混用不同的隧道变体! + desc: 恭喜!您解锁了二级隧道。这是隧道的一个变体。二级隧道有更长的传输距离。您还可以混用不同的隧道变体! reward_cutter_quad: title: 四向切割机 - desc: 恭喜!你解锁了切割机四向变体。它可以将输入的图形切成四块而不只是左右两块! + desc: 恭喜!您解锁了切割机四向变体。它可以将输入的图形切成四块而不只是左右两块! reward_painter_double: - title: 双倍上色器 - desc: 恭喜!你解锁了上色器双倍变体。它可以同时为两个图形上色,每次只消耗一份颜色! + title: 双面上色器 + desc: 恭喜!您解锁了上色器双面变体。它可以同时为两个图形上色,但每次只消耗一份颜色! reward_storage: title: 存储器 - desc: 你已经解锁了存储器,它能存满指定容量的物品!

- 它先从左边输出,这样你就可以用它做一个溢流门了! + desc: 您已经解锁了存储器,它能存满指定容量的物品! +
优先从左边输出,这样您就可以用它做一个溢流门了! reward_freeplay: title: 自由模式 - desc: 成功了!你解锁了自由模式!这意味着现在将随机生成图形! - 从现在起,基地将需要生产率,我强烈建议你去制造一台能够自动交付所需图形的机器!

- 基地会在电线层输出需要的图形,你需要去分析图形并在此基础上自动配置你的工厂。 + desc: + 成功了!您解锁了自由模式!挑战升级!这意味着现在将随机生成图形! + 从现在起,中心基地最为需要的是产量,我强烈建议您去制造一台能够自动交付所需图形的机器!

+ 基地会在电线层输出需要的图形,您需要去分析图形并在此基础上自动配置您的工厂。 reward_blueprints: title: 蓝图 - desc: 你现在可以复制粘贴你的工厂的一部分了!按住 CTRL - 键并拖动鼠标来选择一块区域,然后按C键复制。

粘贴并不是免费的,你需要使用蓝图图形来粘贴你的蓝图。蓝图图形是你刚刚交付的图形。 + desc: + 您现在可以复制粘贴您的工厂的一部分了!按住 CTRL键并拖动鼠标来选择一块区域,然后按C键复制。 +

粘贴并不是免费的,您需要制造蓝图图形来负担。蓝图图形是您刚刚交付的图形。 no_reward: title: 下一关 - desc: 这一关没有奖励,但是下一关有!

- 注意:你生产过的所有图形都会被用来升级建筑。 + desc: 这一关没有奖励,但是下一关有! +

注意:最高明的规划师都不会破坏原有的工厂设施,您生产过的所有图形都会被用于解锁升级。 no_reward_freeplay: title: 下一关 - desc: 恭喜你!另外,我们已经计划在独立版中加入更多内容! + desc: 恭喜您!另外,我们已经计划在完整版中加入更多内容! reward_balancer: title: 平衡器 - desc: 解锁了多功能的平衡器,它能够分割和合并多个传送带的资源,可以用来建造更大的工厂! + desc: 恭喜!您解锁了多功能平衡器,它能够分割和合并多个传送带的资源,可以用来建造更大的工厂! reward_merger: - title: 小型合并器 - desc: 你已经解锁了平衡器的变体合并器,它能合并两个输入到一个传送带上! + title: 合并器(小型) + desc: 恭喜!您解锁了平衡器的变体合并器,它能合并两个输入到同一个传送带上! reward_belt_reader: - title: 传送带阅读器 - desc: 你已经解锁了传送带阅读器!它能够测量传送带上的生产率。

- 等你解锁了电线层后,它会更有用! + title: 传送带读取器 + desc: 恭喜!您解锁了传送带读取器!它能够测量传送带上的生产率。 +

等您解锁了电线层后,它将会极其有用! reward_rotater_180: - title: 180度旋转器 - desc: 你刚刚解锁了180度旋转器!它能帮你把一个图形旋转180度(Surprise! :D) + title: 旋转机(180度) + desc: 恭喜!您解锁了旋转器(180度)!它能帮您把一个图形旋转180度(Surprise! :D) reward_display: title: 显示器 - desc: "你已经解锁了显示器,显示一个在电线层上输入的信号!

- 注意:你注意到传输带阅读器和存储器输出他们最后一次输入的物品的信号了吗?试着在显示屏上展示一下!" + desc: 恭喜!您已经解锁了显示器,它可以显示一个在电线层上连接的信号! +
注意:您注意到传送读取器存储器输出的他们最后读取的物品了吗?试着在显示屏上展示一下!" reward_constant_signal: - title: 固定信号 + title: 恒定信号 desc: - 你解锁了电线层上的固定信号建筑,比如它连接过滤器时非常有用。

- 它能发出图形、颜色、开关量(1 / 0)的固定信号。 + 恭喜!您解锁了生成于电线层之上的恒定信号,把它连接到过滤器时非常有用。 +
比如,它能发出图形、颜色、开关值(1 / 0)的固定信号。 reward_logic_gates: title: 逻辑门 - desc: 你解锁了逻辑门!它们是个好东西!

- 你可以用它们来进行'与,或,非,异或'操作。

作为奖励,我还给你解锁了晶体管! + desc: 您解锁了逻辑门!它们是个好东西!
+ 您可以用它们来进行'与,或,非,异或'操作。

作为奖励,我还给您解锁了晶体管! reward_virtual_processing: title: 模拟处理器 - desc: 我刚刚给了一大堆新建筑,让你可以模拟形状的处理过程

- 你现在可以在电线层上模拟切割机,旋转机,堆叠机和其他机器!

- 有了这些,你可以选择下面三个方向来继续游戏:

- -建立一个自动化生产基地需要图形的机器(我建议试试!)。

- -用电线层上做些酷炫的东西。

- -继续正常比赛。

- 无论你选择什么,记住要玩得开心! + desc: 我刚刚给了一大堆新设施,让您可以模拟形状的处理过程
+ 您现在可以在电线层上模拟切割机,旋转机,堆叠机和其他机器!
+ 有了这些,您可以选择下面三个方向来继续游戏:
+ -建立一个自动化机器以生产出任何中心基地需要图形(建议一试!)。
+ -用电线层做些酷炫的东西。
+ -继续正常游戏。
+ 放飞想象,尽情创造! reward_wires_painter_and_levers: - title: 电控四口上色器 - desc: "你刚刚解锁了电线层:它是正常层之上的一个层,它带来了许多新的机制!

- 首先我解锁了你的四口上色器,按E键切换到电线层,然后连接你想要染色的槽,用开关来控制开启。

- 注意:在设置中打开电线层教程!" + title: 电线 & 四口上色器 + desc: 恭喜!您解锁了电线层:它是正常层之上的一个层,它将带来了许多新的机制!

+ 首先我解锁了您的四口上色器,按E键切换到电线层,然后连接您想要染色的槽,用开关来控制开启。

+ 提示:可在设置中打开电线层教程!" reward_filter: title: 物品过滤器 desc: - 你解锁了物品过滤器!它会根据在电线层上输入的信号决定是从上面还是右边输出物品。

- 你也可以输入正负(1 / 0)信号来激活或者禁用它。 + 恭喜!您解锁了物品过滤器!它会根据在电线层上输入的信号决定是从上面还是右边输出物品。

+ 您也可以输入开关值(1 / 0)信号来激活或者禁用它。 reward_demo_end: title: 试玩结束 - desc: 你已经玩完了试玩版本! + desc: 恭喜!您已经通关了试玩版本! +
更多挑战,请至Steam商城购买完整版!谢谢支持! settings: title: 设置 categories: @@ -633,7 +647,7 @@ settings: labels: uiScale: title: 用户界面大小 - description: 改变用户界面大小。用户界面会随着设备分辨率缩放,这个设置决定缩放比例。 + description: 改变用户界面大小。用户界面会随着屏幕分辨率缩放,这个设置决定缩放比例。 scales: super_small: 最小 small: 较小 @@ -642,7 +656,7 @@ settings: huge: 最大 scrollWheelSensitivity: title: 缩放灵敏度 - description: 改变缩放灵敏度(鼠标滚轮或者触控板)。 + description: 改变屏幕缩放灵敏度(用鼠标滚轮或者触控板控制缩放)。 sensitivity: super_slow: 最低 slow: 较低 @@ -651,10 +665,10 @@ settings: super_fast: 最高 language: title: 语言 - description: 改变语言。所有的翻译皆由玩家提供,且有可能正在施工中! + description: 改变语言。官方中文版已更新,欢迎玩家继续提供更好的翻译意见。 fullscreen: title: 全屏 - description: 全屏以获得更好的游戏体验。仅在独立版中可用。 + description: 全屏可获得更好的游戏体验。仅在完整版中可用。 soundsMuted: title: 关闭音效 description: 关闭所有音效。 @@ -669,17 +683,16 @@ settings: light: 浅色 refreshRate: title: 模拟频率、刷新频率 - description: 如果你的显示器是 144Hz - 的,请在这里更改刷新频率,这样游戏可以正确地根据你的屏幕进行模拟。但是如果你的电脑性能不佳,提高刷新频率可能降低帧数。 + description: 如果您的显示器刷新频率是 144Hz,请在这里更改刷新频率,这样游戏可以正确地根据您的屏幕进行模拟。但是如果您的电脑性能不佳,提高刷新频率可能降低帧数。 alwaysMultiplace: title: 多重放置 - description: 开启这个选项之后放下建筑将不会取消建筑选择。等同于一直按下 SHIFT 键。 + description: 开启这个选项之后放下设施将不会取消设施选择。等同于一直按下 SHIFT 键。 offerHints: title: 提示与教程 - description: 是否显示提示、教程以及一些其他的帮助理解游戏的 UI 元素。 + description: 是否显示提示、教程以及一些其他的帮助理解游戏的 UI 元素。建议新手玩家开启。 movementSpeed: title: 移动速度 - description: 改变摄像头移动速度 + description: 改变摄像头的移动速度。 speeds: super_slow: 最慢 slow: 较慢 @@ -692,10 +705,10 @@ settings: description: 启用后,放置隧道时会将多余的传送带移除。 此外,拖动隧道可以快速铺设隧道,以及移除不必要的隧道。 vignette: title: 晕映 - description: 启用晕映,将屏幕角落里的颜色变深,更容易阅读文本。 + description: 启用晕映功能,可将屏幕角落里的颜色变深,更容易阅读文本。 autosaveInterval: - title: 自动保存间隔 - description: 在这里控制你的游戏多长时间保存一次,或者完全关闭这个功能。 + title: 自动存档间隔 + description: 在这里控制您的游戏多长时间自动存档一次,你也可以完全关闭这个功能。建议打开。 intervals: one_minute: 1分钟 two_minutes: 2分钟 @@ -704,17 +717,17 @@ settings: twenty_minutes: 20分钟 disabled: 关闭 compactBuildingInfo: - title: 精简建筑信息 - description: 缩小建筑信息展示框。如果打开,放置建筑时建筑将不再显示建筑说明和图片,只显示建筑速度或其他数据。 + title: 精简设施信息 + description: 缩小设施信息展示框。如果打开,放置设施时将不再显示说明和图片,只显示建造速度或其他数据。 disableCutDeleteWarnings: title: 关闭剪切/删除警告 - description: 如果打开,将不再在剪切或者删除100+建筑时显示警告信息。 + description: 如果打开,将不再在剪切或者删除100+实体时显示警告信息。 enableColorBlindHelper: title: 色盲模式 - description: 提供一些分辨颜色的工具。目前当鼠标移至颜色资源上方时,屏幕上方会显示颜色名称。 + description: 提供多种工具,帮助色盲玩家可正常进行游戏。 rotationByBuilding: - title: 记忆建筑方向 - description: 每一类建筑都会记住各自上一次的旋转方向。如果你经常在不同建筑类型之间切换,这个设置会让游戏更加舒适。 + title: 记忆设施方向 + description: 每一类设施都会记住各自上一次的旋转方向。如果您经常在不同设施类型之间切换,这个设置会让游戏操控更加便捷。 soundVolume: title: 音效音量 description: 设置音效的音量 @@ -722,50 +735,49 @@ settings: title: 音乐音量 description: 设置音乐的音量 lowQualityMapResources: - title: 简陋的地图资源 - description: 放大时简化地图上资源的渲染以提高性能。它看起来更干净,所以一定要试试! + title: 低质量地图资源 + description: 放大时简化地图上资源的渲染以提高性能。开启甚至会让画面看起来更干净,低配置电脑玩家建议开启! disableTileGrid: title: 禁用网格 - description: 禁用平铺网格有助于提高性能。这也让游戏看起来更干净! + description: 禁用平铺网格有助于提高性能。这也让游戏画面看起来更干净! clearCursorOnDeleteWhilePlacing: title: 右键取消 - description: 默认情况下取消当前的所有操作,如果禁用的话,你可以在保持将放置建筑的情况下删除已有的建筑。 + description: 默认启用。在选择要放置的设施时,单击鼠标右键即可取消。如果禁用,则可以通过在放置设施时单击鼠标右键来删除设施。 lowQualityTextures: title: 低质量纹理(丑陋) - description: 使用低质量纹理保存游戏性能。但是游戏看起来很丑! + description: 使用低质量纹理提高游戏性能。但是这样游戏会看起来很丑! displayChunkBorders: title: 显示大块的边框 - description: 游戏将16x16的小块分成一个大块,如果打开这个设置将会显示每个大块的边框。 + description: 游戏将每一个大块分成16*16的小块,如果启用将会显示每个大块的边框。 pickMinerOnPatch: title: 在资源块上选择开采器 description: 默认开启,当在资源块上使用选取器时会选择开采器。 simplifiedBelts: title: 简单的传送带(简陋) - description: 为了保存性能,除非鼠标放在传送带上,不然不会渲染传送带上的物品。 - 除非你特别需要性能,否则我不推荐在这种设置下玩游戏。 + description: 除非鼠标放在传送带上,不然不会渲染传送带上的物品。启用可提升游戏性能。但除非特别需要性能,否则不推荐启用。 enableMousePan: - title: 鼠标平移 + title: 鼠标平移屏幕 description: 在鼠标滑到屏幕边缘时可以移动地图。移动速度取决于移动速度设置。 zoomToCursor: title: 鼠标位置缩放 - description: 打开后在鼠标位置进行缩放,否则在屏幕中间进行缩放。 + description: 启用后在鼠标所在位置进行屏幕缩放,否则在屏幕中间进行缩放。 mapResourcesScale: title: 地图资源图形尺寸 description: 控制地图总览时图形的尺寸(指缩小视野时)。 rangeSliderPercentage: % keybindings: - title: 按键设置 - hint: 提示:使用 CTRL、SHIFT、ALT!这些建在放置建筑时有不同的效果。 - resetKeybindings: 重置按键设置 + title: 按键设定 + hint: 提示:使用 CTRL、SHIFT、ALT!这些键在放置设施时有不同的效果。 + resetKeybindings: 重置按键设定 categoryLabels: general: 通用 ingame: 游戏 navigation: 视角 placement: 放置 massSelect: 批量选择 - buildings: 建筑快捷键 - placementModifiers: 放置建筑修饰键 + buildings: 设施快捷键 + placementModifiers: 放置设施修饰键 mappings: confirm: 确认 back: 返回 @@ -773,7 +785,7 @@ keybindings: mapMoveRight: 右 mapMoveDown: 下 mapMoveLeft: 左 - centerMap: 回到基地 + centerMap: 回到中心基地 mapZoomIn: 放大 mapZoomOut: 缩小 createMarker: 创建地图标记 @@ -792,39 +804,39 @@ keybindings: trash: 垃圾桶 rotateWhilePlacing: 顺时针旋转 rotateInverseModifier: "修饰键: 改为逆时针旋转" - cycleBuildingVariants: 选择建筑变体 + cycleBuildingVariants: 切换所选择设施变体 confirmMassDelete: 确认批量删除 - cycleBuildings: 选择建筑 + cycleBuildings: 切换所选择设施 massSelectStart: 开始批量选择 massSelectSelectMultiple: 选择多个区域 - massSelectCopy: 复制 + massSelectCopy: 复制区域 placementDisableAutoOrientation: 取消自动定向 placeMultiple: 继续放置 - placeInverse: 反向放置传送带 + placeInverse: 反向自动传送带方向 pasteLastBlueprint: 粘贴上一张蓝图 - massSelectCut: 剪切 + massSelectCut: 剪切区域 exportScreenshot: 导出截图 mapMoveFaster: 快速移动 lockBeltDirection: 启用传送带规划 switchDirectionLockSide: 规划器:换边 - pipette: 选取器 + pipette: 吸取器 menuClose: 关闭菜单 - switchLayers: 选择层 - wire: 导线 + switchLayers: 切换层 + wire: 电线 balancer: 平衡器 storage: 存储器 - constant_signal: 固定信号 + constant_signal: 恒定信号 logic_gate: 逻辑门 - lever: Switch (regular) + lever: 控制杆 filter: 过滤器 - wire_tunnel: 交差导线 - display: 显示 - reader: 传送带阅读器 + wire_tunnel: 电线隧道 + display: 显示器 + reader: 传送带读取器 virtual_processor: 模拟切割机 transistor: 晶体管 analyzer: 图形分析器 comparator: 比较器 - item_producer: 物品生产器 (沙盒) + item_producer: 物品生产器 (沙盒模式) copyWireValue: "电线:复制指定电线上的值" about: title: 关于游戏 @@ -832,76 +844,76 @@ about: 本游戏由 Tobias Springer(我)开发,并且已经开源。

- 如果你想参与开发,请查看 shapez.io on github

+ 如果您想参与开发,请查看 shapez.io on github

- 这个游戏的开发少不了热情的 Discord 社区。请加入我们的 Discord 服务器

+ 这个游戏的开发获得了 Discord 社区内热情玩家的巨大支持。诚挚邀请您加入我们的 Discord 服务器

本游戏的音乐由 Peppsen 制作——他是个很棒的伙伴。

- 最后,我想感谢我最好的朋友 Niklas ——如果没有与他的异星工厂(factorio)的游戏体验,shapez.io将不会存在。 + 最后,我想感谢我最好的朋友 Niklas ——如果没有他的《异星工厂》(factorio)带给我的体验和启发,《异形工厂》(shapez.io)将不会存在。 changelog: title: 版本日志 demo: features: restoringGames: 恢复存档 - importingGames: 倒入存档 + importingGames: 导入存档 oneGameLimit: 最多一个存档 - customizeKeybindings: 按键设置 + customizeKeybindings: 按键设定 exportingBase: 导出工厂截图 settingNotAvailable: 在试玩版中不可用。 tips: - - 基地接受所有输入的图形! - - 确保都是模块化的工厂,不然后面会很麻烦的! - - 不要建设的太靠近基地,不然后面会非常混乱的! - - 如果堆叠不起作用,那就换种方案。 - - 你可以通过 R 键切换传送带规化方向。 - - 按住 CTRL 键拖动传送带将不会自动改变它的方向。 - - 只要所有建筑等级一致,效率也将一致。 + - 基地接受所有创造后输入的图形!并不限于现有的图形! + - 让你的工厂尽量模块化,不然后期你会面对大麻烦! + - 不要让设施太过靠近基地,不然可能会乱成一锅粥! + - 如果堆叠不起作用,尝试切换输入的图形来重新组合。 + - 您可以通过 R 键切换传送带规化方向。 + - 按住 CTRL 键拖动传送带将始终保持它现有的传送方向。 + - 只要所有设施等级一致,效率也将一致。 - 串行执行比并行执行更有效。 - - 在后面的游戏中你会解锁更多建筑的变种! - - 你可以使用T键切换不同的变种。 + - 在后面的游戏中您会解锁更多设施的变种! + - 您可以使用T键切换不同的设施变种。 - 对称是关键! - - 你可以使用隧道构建不同层次的通道。 - - 试着建造紧凑型工厂,它会给你带来好处的! - - 你可以按T来切换上色器的镜像变体。 - - 正确的建筑比例将使效率最大化。 + - 您可以使用隧道构建不同层次的通道。 + - 试着建造紧凑型工厂,它会给您带来好处的! + - 您可以按T来切换上色器的镜像变体。 + - 正确的设施比例将使效率最大化。 - 在传送带和开采器等级一致时,5个开采器就可以占满一条传送带的运量。 - 别忘了隧道! - - 你不必为了充分发挥效率而平均分配物品。 - - 按住SHIFT键将激活传送带规划,能让你更容易的放置长线的传送带。 - - 切割机总是垂直切割,而不管图形方向如何。 - - 混合三原色能够获得白色。 - - 存储缓冲区优先处理第一个输出。 - - 你值得花时间来构建可重复的设计! - - 按住CTRL键能够放置多个建筑。 - - 你可以按住ALT来反向你将放置传送带的方向。 + - 您不必为了充分发挥效率而平均分配物品。 + - 按住SHIFT键将激活传送带路线规划,这样可以更有效地规划如何放置长距离的传送带。 + - 切割机总是垂直切割图形,而不管图形方向如何。 + - 还记得吗?混合三原色能够获得白色。 + - 存储缓冲区优先处理左侧的输出。 + - 您值得花时间来构建可重复的设计! + - 按住CTRL键能够放置多个设施。 + - 您可以按住ALT来反向放置传送带的方向。 - 效率是关键! - 离基地越远图形越复杂。 - 机器的速度是有限的,把它们分开可以获得最高的效率。 - - 使用平衡器最大化你的效率。 - - 组织很重要。尽量不要过多地穿过传送带。 - - 提前规划,省的后面混乱! - - 不要删除旧的工厂,你会需要他们生产的东西升级建筑来提高效率。 - - 在寻求帮助之前,试着自己完成20级!! - - 不要把事情复杂化,试着保持简单,你会成功的。 - - 你可能需要在游戏的后期重复使用工厂。把你的工厂规划成可重复使用的。 - - 有时,你可以在地图上找到你需要的图形,而不用堆叠机去合成它。 + - 使用平衡器最大化您的效率。 + - 有条不紊!尽量不要过多地穿过传送带。 + - 凡事预则立!不预则废! + - 尽量不要删除旧的设施和生产线,您会需要他们生产的东西来升级设施并提高效率。 + - 先给自己定一个小目标:自己完成20级!!不去看别人的攻略! + - 不要把问题复杂化,试着保持简单,您会成功的。 + - 您可能需要在游戏的后期重复使用工厂。把您的工厂规划成可重复使用的。 + - 有时,您可以在地图上直接找到您需要的图形,并不需要使用堆叠机去合成它。 - 风车图形不会自动产生 - - 在切割前,给你的图形上色可以获得最高的效率。 - - 模块化,可以使你提高效率。 + - 在切割前,给您的图形上色可以获得最高的效率。 + - 模块化,可以使您提高效率。 - 记得做一个单独的蓝图工厂。 - - 仔细看看调色器,你就会调色了。 + - 仔细看看调色器,您就会调色了。 - CTRL+点击能够选择一块区域。 - - 建得离基地太近会妨碍以后的工作。 - - 升级列表中每个形状旁边的固定图标可以将其固定到屏幕上。 - - 地图无限大,你可以随意布置。 - - 尝试下Factorio!这是我最喜欢的游戏。 - - 四输入切割机从右上角进行顺时针切割! - - 在主菜单你可以下载你保存的游戏进度文件! + - 设施建得离基地太近很可能会妨碍以后的工作。 + - 使用升级列表中每个形状旁边的固定图标将其固定到屏幕上。 + - 地图无限,放飞想象,尽情创造。 + - 向您推荐Factorio!这是我最喜欢的游戏。向神作致敬! + - 四向切割机从右上开始进行顺时针切割! + - 在主界面您可以下载您的游戏存档文件! - 这个游戏有很多有用的快捷键!一定要到快捷键页面看看。 - - 这个游戏有很多设置,一定要检查一下! - - 总览时基地的标记边上有个指向它所在方向的指针! - - 想清理传送带,就剪切那块区域并在相同位置放置他们。 + - 这个游戏有很多设置可以提高游戏效率,请一定要了解一下! + - 中心基地有个指向它所在方向的小指南指针! + - 想清理传送带,可剪切那块区域然后将其在相同位置粘贴。 - 按F4显示FPS。 - - 按两次F4显示你鼠标所在的块。 - - 你可以点击固定在屏幕左侧的图形来解除固定。 + - 按两次F4显示您鼠标和镜头所在的块。 + - 您可以点击被固定在屏幕左侧的图形来解除固定。 From 1ee03d739846636f7bc67d5430ee1dddc10de628 Mon Sep 17 00:00:00 2001 From: Tobias Springer Date: Tue, 9 Mar 2021 10:07:19 +0100 Subject: [PATCH 16/52] Adjustments to support chinese versions --- .gitignore | 1 + gulp/css.js | 1 - gulp/gulpfile.js | 63 ++-- gulp/js.js | 48 ++- gulp/package.json | 1 + gulp/standalone.js | 356 +++++++++------------ gulp/steampipe/scripts/app.vdf.template | 8 +- gulp/steampipe/scripts/china-linux.vdf | 12 + gulp/steampipe/scripts/china-windows.vdf | 12 + gulp/steampipe/scripts/linux.vdf | 2 +- gulp/steampipe/scripts/windows.vdf | 2 +- gulp/webpack.config.js | 3 +- gulp/webpack.production.config.js | 3 + gulp/yarn.lock | 51 ++- res/logo_cn.png | Bin 0 -> 34370 bytes src/css/states/main_menu.scss | 4 + src/js/core/background_resources_loader.js | 2 +- src/js/globals.d.ts | 2 + src/js/states/about.js | 4 +- src/js/states/main_menu.js | 50 ++- src/js/states/mobile_warning.js | 10 +- src/js/states/preload.js | 21 +- src/js/states/settings.js | 25 +- yarn.lock | 35 +- 24 files changed, 422 insertions(+), 294 deletions(-) create mode 100644 gulp/steampipe/scripts/china-linux.vdf create mode 100644 gulp/steampipe/scripts/china-windows.vdf create mode 100644 res/logo_cn.png diff --git a/.gitignore b/.gitignore index a0e08a62..f7557646 100644 --- a/.gitignore +++ b/.gitignore @@ -46,6 +46,7 @@ res_built gulp/runnable-texturepacker.jar tmp_standalone_files +tmp_standalone_files_china # Local config config.local.js diff --git a/gulp/css.js b/gulp/css.js index 2b51f153..46e44247 100644 --- a/gulp/css.js +++ b/gulp/css.js @@ -21,7 +21,6 @@ function gulptasksCSS($, gulp, buildFolder, browserSync) { const plugins = [postcssAssetsPlugin(cachebust)]; if (prod) { plugins.unshift( - $.postcssUnprefix(), $.postcssPresetEnv({ browsers: ["> 0.1%"], }) diff --git a/gulp/gulpfile.js b/gulp/gulpfile.js index 7b0416ca..f2f4174e 100644 --- a/gulp/gulpfile.js +++ b/gulp/gulpfile.js @@ -136,7 +136,7 @@ gulp.task("main.webserver", () => { ); }); -function serve({ standalone }) { +function serve({ standalone, chineseVersion = false }) { browserSync.init({ server: buildFolder, port: 3005, @@ -200,7 +200,11 @@ function serve({ standalone }) { if (standalone) { gulp.series("js.standalone-dev.watch")(() => true); } else { - gulp.series("js.dev.watch")(() => true); + if (chineseVersion) { + gulp.series("china.js.dev.watch")(() => true); + } else { + gulp.series("js.dev.watch")(() => true); + } } } @@ -284,30 +288,28 @@ gulp.task( ); // Builds everything (standalone-prod) -gulp.task( - "step.standalone-prod.code", - gulp.series("sounds.fullbuildHQ", "translations.fullBuild", "js.standalone-prod") -); -gulp.task("step.standalone-prod.mainbuild", gulp.parallel("step.baseResources", "step.standalone-prod.code")); -gulp.task( - "step.standalone-prod.all", - gulp.series("step.standalone-prod.mainbuild", "css.prod-standalone", "html.standalone-prod") -); -gulp.task( - "build.standalone-prod", - gulp.series("utils.cleanup", "step.standalone-prod.all", "step.postbuild") -); -// OS X build and release upload -gulp.task( - "build.darwin64-prod", - gulp.series( - "build.standalone-prod", - "standalone.prepare", - "standalone.package.prod.darwin64", - "standalone.uploadRelease.darwin64" - ) -); +for (const prefix of ["", "china."]) { + gulp.task( + prefix + "step.standalone-prod.code", + gulp.series("sounds.fullbuildHQ", "translations.fullBuild", prefix + "js.standalone-prod") + ); + + gulp.task( + prefix + "step.standalone-prod.mainbuild", + gulp.parallel("step.baseResources", prefix + "step.standalone-prod.code") + ); + + gulp.task( + prefix + "step.standalone-prod.all", + gulp.series(prefix + "step.standalone-prod.mainbuild", "css.prod-standalone", "html.standalone-prod") + ); + + gulp.task( + prefix + "build.standalone-prod", + gulp.series("utils.cleanup", prefix + "step.standalone-prod.all", "step.postbuild") + ); +} // Deploying! gulp.task( @@ -320,7 +322,12 @@ gulp.task( ); gulp.task("main.deploy.prod", gulp.series("utils.requireCleanWorkingTree", "build.prod", "ftp.upload.prod")); gulp.task("main.deploy.all", gulp.series("main.deploy.staging", "main.deploy.prod")); -gulp.task("main.standalone", gulp.series("build.standalone-prod", "standalone.package.prod")); +gulp.task("regular.main.standalone", gulp.series("build.standalone-prod", "standalone.package.prod")); +gulp.task( + "china.main.standalone", + gulp.series("china.build.standalone-prod", "china.standalone.package.prod") +); +gulp.task("standalone.all", gulp.series("regular.main.standalone", "china.main.standalone")); // Live-development gulp.task( @@ -331,5 +338,9 @@ gulp.task( "main.serveStandalone", gulp.series("build.standalone.dev", () => serve({ standalone: true })) ); +gulp.task( + "china.main.serveDev", + gulp.series("build.dev", () => serve({ standalone: false, chineseVersion: true })) +); gulp.task("default", gulp.series("main.serveDev")); diff --git a/gulp/js.js b/gulp/js.js index 28c037bd..cfaedb8c 100644 --- a/gulp/js.js +++ b/gulp/js.js @@ -6,7 +6,6 @@ function requireUncached(module) { } function gulptasksJS($, gulp, buildFolder, browserSync) { - //// DEV gulp.task("js.dev.watch", () => { @@ -30,6 +29,36 @@ function gulptasksJS($, gulp, buildFolder, browserSync) { .pipe(gulp.dest(buildFolder)); }); + //// DEV CHINA + + gulp.task("china.js.dev.watch", () => { + return gulp + .src("../src/js/main.js") + .pipe( + $.webpackStream( + requireUncached("./webpack.config.js")({ + watch: true, + chineseVersion: true, + }) + ) + ) + .pipe(gulp.dest(buildFolder)) + .pipe(browserSync.stream()); + }); + + gulp.task("china.js.dev", () => { + return gulp + .src("../src/js/main.js") + .pipe( + $.webpackStream( + requireUncached("./webpack.config.js")({ + chineseVersion: true, + }) + ) + ) + .pipe(gulp.dest(buildFolder)); + }); + //// STAGING gulp.task("js.staging.transpiled", () => { @@ -162,6 +191,23 @@ function gulptasksJS($, gulp, buildFolder, browserSync) { ) .pipe(gulp.dest(buildFolder)); }); + + gulp.task("china.js.standalone-prod", () => { + return gulp + .src("../src/js/main.js") + .pipe( + $.webpackStream( + requireUncached("./webpack.production.config.js")({ + enableAssert: false, + environment: "prod", + es6: true, + standalone: true, + chineseVersion: true, + }) + ) + ) + .pipe(gulp.dest(buildFolder)); + }); } module.exports = { diff --git a/gulp/package.json b/gulp/package.json index 28a83253..0e1052b1 100644 --- a/gulp/package.json +++ b/gulp/package.json @@ -34,6 +34,7 @@ "fastdom": "^1.0.9", "flatted": "^2.0.1", "fs-extra": "^8.1.0", + "gifsicle": "^5.2.0", "gulp-audiosprite": "^1.1.0", "howler": "^2.1.2", "html-loader": "^0.5.5", diff --git a/gulp/standalone.js b/gulp/standalone.js index 8d247672..21c64595 100644 --- a/gulp/standalone.js +++ b/gulp/standalone.js @@ -10,226 +10,168 @@ const execSync = require("child_process").execSync; function gulptasksStandalone($, gulp) { const electronBaseDir = path.join(__dirname, "..", "electron"); - const tempDestDir = path.join(__dirname, "..", "tmp_standalone_files"); - const tempDestBuildDir = path.join(tempDestDir, "built"); + for (const { tempDestDir, suffix, taskPrefix } of [ + { tempDestDir: path.join(__dirname, "..", "tmp_standalone_files"), suffix: "", taskPrefix: "" }, + { + tempDestDir: path.join(__dirname, "..", "tmp_standalone_files_china"), + suffix: "china", + taskPrefix: "china.", + }, + ]) { + const tempDestBuildDir = path.join(tempDestDir, "built"); - gulp.task("standalone.prepare.cleanup", () => { - return gulp.src(tempDestDir, { read: false, allowEmpty: true }).pipe($.clean({ force: true })); - }); + gulp.task(taskPrefix + "standalone.prepare.cleanup", () => { + return gulp.src(tempDestDir, { read: false, allowEmpty: true }).pipe($.clean({ force: true })); + }); - gulp.task("standalone.prepare.copyPrefab", () => { - // const requiredFiles = $.glob.sync("../electron/"); - const requiredFiles = [ - path.join(electronBaseDir, "lib", "**", "*.node"), - path.join(electronBaseDir, "node_modules", "**", "*.*"), - path.join(electronBaseDir, "node_modules", "**", ".*"), - path.join(electronBaseDir, "favicon*"), + gulp.task(taskPrefix + "standalone.prepare.copyPrefab", () => { + // const requiredFiles = $.glob.sync("../electron/"); + const requiredFiles = [ + path.join(electronBaseDir, "lib", "**", "*.node"), + path.join(electronBaseDir, "node_modules", "**", "*.*"), + path.join(electronBaseDir, "node_modules", "**", ".*"), + path.join(electronBaseDir, "favicon*"), - // fails on platforms which support symlinks - // https://github.com/gulpjs/gulp/issues/1427 - // path.join(electronBaseDir, "node_modules", "**", "*"), - ]; - return gulp.src(requiredFiles, { base: electronBaseDir }).pipe(gulp.dest(tempDestBuildDir)); - }); + // fails on platforms which support symlinks + // https://github.com/gulpjs/gulp/issues/1427 + // path.join(electronBaseDir, "node_modules", "**", "*"), + ]; + return gulp.src(requiredFiles, { base: electronBaseDir }).pipe(gulp.dest(tempDestBuildDir)); + }); - gulp.task("standalone.prepare.writePackageJson", cb => { - fs.writeFileSync( - path.join(tempDestBuildDir, "package.json"), - JSON.stringify( - { - devDependencies: { - electron: "6.1.12", + gulp.task(taskPrefix + "standalone.prepare.writePackageJson", cb => { + fs.writeFileSync( + path.join(tempDestBuildDir, "package.json"), + JSON.stringify( + { + devDependencies: { + electron: "6.1.12", + }, }, - }, - null, - 4 + null, + 4 + ) + ); + cb(); + }); + + gulp.task(taskPrefix + "standalone.prepareVDF", cb => { + const hash = buildutils.getRevision(); + + const steampipeDir = path.join(__dirname, "steampipe", "scripts"); + const templateContents = fs + .readFileSync(path.join(steampipeDir, "app.vdf.template"), { encoding: "utf-8" }) + .toString(); + + const convertedContents = templateContents.replace("$DESC$", "Commit " + hash); + fs.writeFileSync(path.join(steampipeDir, "app.vdf"), convertedContents); + + cb(); + }); + + gulp.task(taskPrefix + "standalone.prepare.minifyCode", () => { + return gulp.src(path.join(electronBaseDir, "*.js")).pipe(gulp.dest(tempDestBuildDir)); + }); + + gulp.task(taskPrefix + "standalone.prepare.copyGamefiles", () => { + return gulp.src("../build/**/*.*", { base: "../build" }).pipe(gulp.dest(tempDestBuildDir)); + }); + + gulp.task(taskPrefix + "standalone.killRunningInstances", cb => { + try { + execSync("taskkill /F /IM shapezio.exe"); + } catch (ex) { + console.warn("Failed to kill running instances, maybe none are up."); + } + cb(); + }); + + gulp.task( + taskPrefix + "standalone.prepare", + gulp.series( + taskPrefix + "standalone.killRunningInstances", + taskPrefix + "standalone.prepare.cleanup", + taskPrefix + "standalone.prepare.copyPrefab", + taskPrefix + "standalone.prepare.writePackageJson", + taskPrefix + "standalone.prepare.minifyCode", + taskPrefix + "standalone.prepare.copyGamefiles" ) ); - cb(); - }); - gulp.task("standalone.prepareVDF", cb => { - const hash = buildutils.getRevision(); + /** + * + * @param {'win32'|'linux'} platform + * @param {'x64'|'ia32'} arch + * @param {function():void} cb + */ + function packageStandalone(platform, arch, cb) { + const tomlFile = fs.readFileSync(path.join(__dirname, ".itch.toml")); - const steampipeDir = path.join(__dirname, "steampipe", "scripts"); - const templateContents = fs - .readFileSync(path.join(steampipeDir, "app.vdf.template"), { encoding: "utf-8" }) - .toString(); - - const convertedContents = templateContents.replace("$DESC$", "Commit " + hash); - fs.writeFileSync(path.join(steampipeDir, "app.vdf"), convertedContents); - - cb(); - }); - - gulp.task("standalone.prepare.minifyCode", () => { - return gulp.src(path.join(electronBaseDir, "*.js")).pipe(gulp.dest(tempDestBuildDir)); - }); - - gulp.task("standalone.prepare.copyGamefiles", () => { - return gulp.src("../build/**/*.*", { base: "../build" }).pipe(gulp.dest(tempDestBuildDir)); - }); - - gulp.task("standalone.killRunningInstances", cb => { - try { - execSync("taskkill /F /IM shapezio.exe"); - } catch (ex) { - console.warn("Failed to kill running instances, maybe none are up."); - } - cb(); - }); - - gulp.task( - "standalone.prepare", - gulp.series( - "standalone.killRunningInstances", - "standalone.prepare.cleanup", - "standalone.prepare.copyPrefab", - "standalone.prepare.writePackageJson", - "standalone.prepare.minifyCode", - "standalone.prepare.copyGamefiles" - ) - ); - - /** - * - * @param {'win32'|'linux'|'darwin'} platform - * @param {'x64'|'ia32'} arch - * @param {function():void} cb - * @param {boolean=} isRelease - */ - function packageStandalone(platform, arch, cb, isRelease = true) { - const tomlFile = fs.readFileSync(path.join(__dirname, ".itch.toml")); - - packager({ - dir: tempDestBuildDir, - appCopyright: "Tobias Springer", - appVersion: getVersion(), - buildVersion: "1.0.0", - arch, - platform, - asar: true, - executableName: "shapezio", - icon: path.join(electronBaseDir, "favicon"), - name: "shapez.io-standalone", - out: tempDestDir, - overwrite: true, - appBundleId: "io.shapez.standalone", - appCategoryType: "public.app-category.games", - ...(isRelease && - platform === "darwin" && { - osxSign: { - "identity": process.env.SHAPEZ_CLI_APPLE_CERT_NAME, - "hardened-runtime": true, - "hardenedRuntime": true, - "entitlements": "entitlements.plist", - "entitlements-inherit": "entitlements.plist", - "signature-flags": "library", - }, - osxNotarize: { - appleId: process.env.SHAPEZ_CLI_APPLE_ID, - appleIdPassword: "@keychain:SHAPEZ_CLI_APPLE_ID", - }, - }), - }).then( - appPaths => { - console.log("Packages created:", appPaths); - appPaths.forEach(appPath => { - if (!fs.existsSync(appPath)) { - console.error("Bad app path gotten:", appPath); - return; - } - - fs.writeFileSync( - path.join(appPath, "LICENSE"), - fs.readFileSync(path.join(__dirname, "..", "LICENSE")) - ); - - fs.writeFileSync(path.join(appPath, ".itch.toml"), tomlFile); - - if (platform === "linux") { - fs.writeFileSync( - path.join(appPath, "play.sh"), - '#!/usr/bin/env bash\n./shapezio --no-sandbox "$@"\n' - ); - fs.chmodSync(path.join(appPath, "play.sh"), 0o775); - } - - if (process.platform === "win32" && platform === "darwin") { - console.warn( - "Cross-building for macOS on Windows: dereferencing symlinks.\n".red + - "This will nearly double app size and make code signature invalid. Sorry!\n" - .red.bold + - "For more information, see " + - "https://github.com/electron/electron-packager/issues/71".underline - ); - - // Clear up framework folders - fs.writeFileSync( - path.join(appPath, "play.sh"), - '#!/usr/bin/env bash\n./shapez.io-standalone.app/Contents/MacOS/shapezio --no-sandbox "$@"\n' - ); - fs.chmodSync(path.join(appPath, "play.sh"), 0o775); - fs.chmodSync( - path.join(appPath, "shapez.io-standalone.app", "Contents", "MacOS", "shapezio"), - 0o775 - ); - - const finalPath = path.join(appPath, "shapez.io-standalone.app"); - - const frameworksDir = path.join(finalPath, "Contents", "Frameworks"); - const frameworkFolders = fs - .readdirSync(frameworksDir) - .filter(fname => fname.endsWith(".framework")); - - for (let i = 0; i < frameworkFolders.length; ++i) { - const folderName = frameworkFolders[i]; - const frameworkFolder = path.join(frameworksDir, folderName); - console.log(" -> ", frameworkFolder); - - const filesToDelete = fs - .readdirSync(frameworkFolder) - .filter(fname => fname.toLowerCase() !== "versions"); - filesToDelete.forEach(fname => { - console.log(" -> Deleting", fname); - fs.unlinkSync(path.join(frameworkFolder, fname)); - }); - - const frameworkSourceDir = path.join(frameworkFolder, "Versions", "A"); - fse.copySync(frameworkSourceDir, frameworkFolder); + packager({ + dir: tempDestBuildDir, + appCopyright: "Tobias Springer", + appVersion: getVersion(), + buildVersion: "1.0.0", + arch, + platform, + asar: true, + executableName: "shapezio", + icon: path.join(electronBaseDir, "favicon"), + name: "shapez.io-standalone" + suffix, + out: tempDestDir, + overwrite: true, + appBundleId: "io.shapez.standalone", + appCategoryType: "public.app-category.games", + }).then( + appPaths => { + console.log("Packages created:", appPaths); + appPaths.forEach(appPath => { + if (!fs.existsSync(appPath)) { + console.error("Bad app path gotten:", appPath); + return; } - } - }); - cb(); - }, - err => { - console.error("Packaging error:", err); - cb(); - } + fs.writeFileSync( + path.join(appPath, "LICENSE"), + fs.readFileSync(path.join(__dirname, "..", "LICENSE")) + ); + + fs.writeFileSync(path.join(appPath, ".itch.toml"), tomlFile); + + if (platform === "linux") { + fs.writeFileSync( + path.join(appPath, "play.sh"), + '#!/usr/bin/env bash\n./shapezio --no-sandbox "$@"\n' + ); + fs.chmodSync(path.join(appPath, "play.sh"), 0o775); + } + }); + + cb(); + }, + err => { + console.error("Packaging error:", err); + cb(); + } + ); + } + + gulp.task(taskPrefix + "standalone.package.prod.win64", cb => packageStandalone("win32", "x64", cb)); + gulp.task(taskPrefix + "standalone.package.prod.linux64", cb => + packageStandalone("linux", "x64", cb) + ); + + gulp.task( + taskPrefix + "standalone.package.prod", + gulp.series( + taskPrefix + "standalone.prepare", + gulp.parallel( + taskPrefix + "standalone.package.prod.win64", + taskPrefix + "standalone.package.prod.linux64" + ) + ) ); } - - gulp.task("standalone.package.prod.win64", cb => packageStandalone("win32", "x64", cb)); - gulp.task("standalone.package.prod.win32", cb => packageStandalone("win32", "ia32", cb)); - gulp.task("standalone.package.prod.linux64", cb => packageStandalone("linux", "x64", cb)); - gulp.task("standalone.package.prod.linux32", cb => packageStandalone("linux", "ia32", cb)); - gulp.task("standalone.package.prod.darwin64", cb => packageStandalone("darwin", "x64", cb)); - gulp.task("standalone.package.prod.darwin64.unsigned", cb => - packageStandalone("darwin", "x64", cb, false) - ); - - gulp.task( - "standalone.package.prod", - gulp.series( - "standalone.prepare", - gulp.parallel( - "standalone.package.prod.win64", - "standalone.package.prod.linux64", - "standalone.package.prod.darwin64" - ) - ) - ); } module.exports = { gulptasksStandalone }; diff --git a/gulp/steampipe/scripts/app.vdf.template b/gulp/steampipe/scripts/app.vdf.template index a13a9db3..32634060 100644 --- a/gulp/steampipe/scripts/app.vdf.template +++ b/gulp/steampipe/scripts/app.vdf.template @@ -2,14 +2,16 @@ { "appid" "1318690" "desc" "$DESC$" - "buildoutput" "C:\work\shapez\shapez.io\gulp\steampipe\steamtemp" + "buildoutput" "C:\work\shapez.io\gulp\steampipe\steamtemp" "contentroot" "" "setlive" "" "preview" "0" "local" "" "depots" { - "1318691" "C:\work\shapez\shapez.io\gulp\steampipe\scripts\windows.vdf" - "1318692" "C:\work\shapez\shapez.io\gulp\steampipe\scripts\linux.vdf" + "1318691" "C:\work\shapez.io\gulp\steampipe\scripts\windows.vdf" + "1318694" "C:\work\shapez.io\gulp\steampipe\scripts\china-windows.vdf" + "1318692" "C:\work\shapez.io\gulp\steampipe\scripts\linux.vdf" + "1318695" "C:\work\shapez.io\gulp\steampipe\scripts\china-linux.vdf" } } diff --git a/gulp/steampipe/scripts/china-linux.vdf b/gulp/steampipe/scripts/china-linux.vdf new file mode 100644 index 00000000..a1c56a96 --- /dev/null +++ b/gulp/steampipe/scripts/china-linux.vdf @@ -0,0 +1,12 @@ +"DepotBuildConfig" +{ + "DepotID" "1318695" + "contentroot" "C:\work\shapez.io\tmp_standalone_files_china\shapez.io-standalone-linux-x64" + "FileMapping" + { + "LocalPath" "*" + "DepotPath" "." + "recursive" "1" + } + "FileExclusion" "*.pdb" +} \ No newline at end of file diff --git a/gulp/steampipe/scripts/china-windows.vdf b/gulp/steampipe/scripts/china-windows.vdf new file mode 100644 index 00000000..8acc894d --- /dev/null +++ b/gulp/steampipe/scripts/china-windows.vdf @@ -0,0 +1,12 @@ +"DepotBuildConfig" +{ + "DepotID" "1318694" + "contentroot" "C:\work\shapez.io\tmp_standalone_files_china\shapez.io-standalone-win32-x64" + "FileMapping" + { + "LocalPath" "*" + "DepotPath" "." + "recursive" "1" + } + "FileExclusion" "*.pdb" +} \ No newline at end of file diff --git a/gulp/steampipe/scripts/linux.vdf b/gulp/steampipe/scripts/linux.vdf index 60dfcca5..df1a86cc 100644 --- a/gulp/steampipe/scripts/linux.vdf +++ b/gulp/steampipe/scripts/linux.vdf @@ -1,7 +1,7 @@ "DepotBuildConfig" { "DepotID" "1318692" - "contentroot" "C:\work\shapez\shapez.io\tmp_standalone_files\shapez.io-standalone-linux-x64" + "contentroot" "C:\work\shapez.io\tmp_standalone_files\shapez.io-standalone-linux-x64" "FileMapping" { "LocalPath" "*" diff --git a/gulp/steampipe/scripts/windows.vdf b/gulp/steampipe/scripts/windows.vdf index 7d0db436..bf0e8721 100644 --- a/gulp/steampipe/scripts/windows.vdf +++ b/gulp/steampipe/scripts/windows.vdf @@ -1,7 +1,7 @@ "DepotBuildConfig" { "DepotID" "1318691" - "contentroot" "C:\work\shapez\shapez.io\tmp_standalone_files\shapez.io-standalone-win32-x64" + "contentroot" "C:\work\shapez.io\tmp_standalone_files\shapez.io-standalone-win32-x64" "FileMapping" { "LocalPath" "*" diff --git a/gulp/webpack.config.js b/gulp/webpack.config.js index 6e1d7388..3f666e73 100644 --- a/gulp/webpack.config.js +++ b/gulp/webpack.config.js @@ -6,7 +6,7 @@ const { getRevision, getVersion, getAllResourceImages } = require("./buildutils" const lzString = require("lz-string"); const CircularDependencyPlugin = require("circular-dependency-plugin"); -module.exports = ({ watch = false, standalone = false }) => { +module.exports = ({ watch = false, standalone = false, chineseVersion = false }) => { return { mode: "development", devtool: "cheap-source-map", @@ -34,6 +34,7 @@ module.exports = ({ watch = false, standalone = false }) => { G_TRACKING_ENDPOINT: JSON.stringify( lzString.compressToEncodedURIComponent("http://localhost:10005/v1") ), + G_CHINA_VERSION: JSON.stringify(chineseVersion), G_IS_DEV: "true", G_IS_RELEASE: "false", G_IS_MOBILE_APP: "false", diff --git a/gulp/webpack.production.config.js b/gulp/webpack.production.config.js index c26bca68..1779a76f 100644 --- a/gulp/webpack.production.config.js +++ b/gulp/webpack.production.config.js @@ -16,12 +16,15 @@ module.exports = ({ standalone = false, isBrowser = true, mobileApp = false, + chineseVersion = false, }) => { const globalDefs = { assert: enableAssert ? "window.assert" : "false && window.assert", assertAlways: "window.assert", abstract: "window.assert(false, 'abstract method called');", G_IS_DEV: "false", + + G_CHINA_VERSION: JSON.stringify(chineseVersion), G_IS_RELEASE: environment === "prod" ? "true" : "false", G_IS_STANDALONE: standalone ? "true" : "false", G_IS_BROWSER: isBrowser ? "true" : "false", diff --git a/gulp/yarn.lock b/gulp/yarn.lock index 12959102..854ca274 100644 --- a/gulp/yarn.lock +++ b/gulp/yarn.lock @@ -3402,7 +3402,7 @@ cross-spawn@^5.0.1: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^7.0.0: +cross-spawn@^7.0.0, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -4746,6 +4746,21 @@ execa@^4.0.0: signal-exit "^3.0.2" strip-final-newline "^2.0.0" +execa@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.0.0.tgz#4029b0007998a841fbd1032e5f4de86a3c1e3376" + integrity sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + executable@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/executable/-/executable-4.1.1.tgz#41532bff361d3e57af4d763b70582db18f5d133c" @@ -5517,6 +5532,11 @@ get-stream@^5.0.0, get-stream@^5.1.0: dependencies: pump "^3.0.0" +get-stream@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.0.tgz#3e0012cb6827319da2706e601a1583e8629a6718" + integrity sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg== + get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" @@ -5539,6 +5559,16 @@ gifsicle@^5.0.0: execa "^4.0.0" logalot "^2.0.0" +gifsicle@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/gifsicle/-/gifsicle-5.2.0.tgz#b06b25ed7530f033f6ed2c545d6f9b546cc182fb" + integrity sha512-vOIS3j0XoTCxq9pkGj43gEix82RkI5FveNgaFZutjbaui/HH+4fR8Y56dwXDuxYo8hR4xOo6/j2h1WHoQW6XLw== + dependencies: + bin-build "^3.0.0" + bin-wrapper "^4.0.0" + execa "^5.0.0" + logalot "^2.0.0" + glob-all@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/glob-all/-/glob-all-3.1.0.tgz#8913ddfb5ee1ac7812656241b03d5217c64b02ab" @@ -6520,6 +6550,11 @@ human-signals@^1.1.1: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -8772,7 +8807,7 @@ npm-run-path@^2.0.0: dependencies: path-key "^2.0.0" -npm-run-path@^4.0.0: +npm-run-path@^4.0.0, npm-run-path@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== @@ -8985,6 +9020,13 @@ onetime@^5.1.0: dependencies: mimic-fn "^2.1.0" +onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + open@^0.0.5: version "0.0.5" resolved "https://registry.yarnpkg.com/open/-/open-0.0.5.tgz#42c3e18ec95466b6bf0dc42f3a2945c3f0cad8fc" @@ -11469,6 +11511,11 @@ signal-exit@^3.0.0, signal-exit@^3.0.2: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= +signal-exit@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" + integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== + simple-swizzle@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" diff --git a/res/logo_cn.png b/res/logo_cn.png new file mode 100644 index 0000000000000000000000000000000000000000..5ef18416dfe923dc4dbfa223b31490bb494d12f2 GIT binary patch literal 34370 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

xDIoi#!9E^-F&Kb+gr7gQ>?d6*Rg~*EYDUD z=6@+fg}#+h1&sTo#dkFYY#N689)ipvp>IUdz&H=q-x3{*@khbyobI1P`Dj4J40zu; zR2}Qf+Vrgt_H)b1iSJW?$Bh%>0qak6PZiEw)OuaW|}=3vBuo z_E#Yt_Gzh2LBjog$fF$K`9?~J+e=(rIDzd9cP}SP(=;tdB{|mAr7{oV5cI#PRRY!t zi#m_M)_NQ6aA8V3P?90OGuPdl$&M_z70|*Ppsxr>7GIp|zxMlBwVvk%wxOa%Opedf zT%ksAa@L6i7K9tb-4#m<7eJh$Q-?mZ3+>UsHnA=|sN+XA{^Z z#Coa)_d7DvF?t?e2{3!Eul=n!D3r=YL|_vYX92vDL173Z&x@n?Oz?qfc81;Y*M^tz zI`+}bd`>j~x#VD_9m?FND zJ#k3w$q=rK-48#HUWa_+{KuV_=VU%7=_N((Q)L!F*n8NzD)(!R?15tbbQWen|8ke{ zQs~8giZ5{Dd($kp)(F9Ozk1U~-Tu(rUhH*V5t?e=EI>Ou(G55i2}a{mU>4X|0DXCW z9xR0b-v8w%m2@05p026yJi<{0&`3EMI8WaW6_>XqkFk0?H&(0{4lKJ4 zX$)0`wxpG2;Pnb&`aAMn zC$fCU@z}|1>VUr8-sCTSVrjI#!!Des{*2pa>S8^4>A0S2e0v1f_3?a5iu>d5Agcv^ z!J(p6&&Xp)fgzz&w%;-5S=G1X^c1|f3XPGwnic)h6b2^fR z!;+;E(Rs_EJXDP^zOFVYxF^I1waZqBF3d?`+6=RxUK7QJws9@L=;8#uq;F|g^I9h8 zw6V%8#KgoTxQHDQL++XPQ5lyFXEhny*Vk@Z_1{Uxg~mzzmJ`us73bfn3vcAW2idUV zTLJHy7f<SEJpACP{PABP`&-r|4{*gLThAWxzJH6o<{n~9~Ms&Wo(D}7B2W>`Sqc8I?!7)VW z>Sphfb>gK>oU4JXR+AY7ftbU;e|UVH_Z=VohtI?Hz*deMPh+w*+xnT>%;l8&3N)|V zp`k_>ZURcQ=VW5*MftYCSH_WX6ot@kO6UC?m5cd@a2^J#$J+BlJ)V zyr&-20mM;TUVYQdW;j~j4pi2Vy8{oA}htevDc`DkH>H3nRt#N zBs)AZ63lU=`#?Sd3{4`pLucZn2*ePt>d=;zz^vQ6LGTva=M+RZ=uo29@hn-tG@M1h z%SY4CqfqfU`D2wd$)%Ex6TL!$D+4Uk_{$sOAIP|jfAn2O`)Zu;Js~iD4(OVdym_^1 zKV2F^44Wc($BQ4ilgm{>$(;~IS?b`r1O0^0N@RQjdB2aZ$dGWhat~6Sy-YSE^XI$ol`Z{|8awF01{Kw9eq34 z-#4?;X`Y^$(_tonpv~v6T&^+;W1skgi4Z*4pjwN_p_&)XqOIFC3&_y{O-($EryX1g z!^z4KS}3{XlhKs)7+gu@Q7}PYsGNmbP*G5}ECj5=alc!v8|uBD!x9%;78Ww*;)>$Bo1TF#BMRRKF!W~&?!3G^PBA{k?$MR0VGbQ9^r&mjLPEdeV;GE1&& zS0f`MRX`2sZ*ZWNPmPM9j#&7tk0z~F9f;ZlpBRYL?#*sK0mnDXXcc3Ix@T#6f2*}= zv7(@uh%X@2EmA~1Y=IxzpTuTCkua2`AAXJjr-t_GJzU@Vsf+o)OHWUm=GZMbX-zK1 zGZ91P`14dh4}ioA_H$a2#uK{pi_CcywO7{8lgn}T0Mz_at*pk}HZsa*{ z^K`0?F_HJ;ER2iL*WVv%TCFuz)%xsKKRyQ?`bKW2rO-U@bmgNpeZI6S&*C;=L<@2#8i7tDzL@8+$=(I~}vj&s0Ss0=`*o>LTkwCb4*q@D~7S+2OB zF|UG4^CNIdwQHqkOSEFH?Vy8xk7tQGo&6SD`MC==?bx&_qRLpLAq)WBZaZPRR*e%) zfFE|2X4{naRWMIImQ!hEW4Ou0MFyF-s!_mOryIXmIXTTeSpvHli#~Q=b7NEr{Hmy{ zV>A$KDDzca{vHpoH7;W*^KU)}0P8{<>u(Nb%fJZzB0q~aTzBR#-{ zGX~wNa8winLhleN8nZY*h-{LJ%D=SfrhoVBnsTnL^16)OGZHuv3U7FHnlnNcJ!=&JuV#0u495GWJ*UoU{w=~#ON;DI-2n)eNAF38g!oPn{jz7Ap_fpHcoC4{tLk8kb zp1IS3G4F=oY^x3)t%ZfotSs&m5}b1c*;peWKw~RLmD9!oI3}@1}(*xMkOZ`qhg`- z8(@N=+abDpbYHy!`nR36wY1yGs+~4GYp@IgKTRs}pdCi^P4E+sZ@~`?m>|eC0j~L) z>fjMe)FY+c`>TW8S~bG=aO+d){9dNwf@$8$;A=14dpHcO%ax)*UAwii2yAFGXT%U9 z`UyOxS3VM7QFUPJBDVvChK;OO%K)mGaeI4KD?A0fH&tFM!33|Vv1;s9HOSbmb)u>1 zUSt3Ps>@#?MQp3p7Hkt`2Lr?_r4ga5(E{8>v?HMUo|_wd;CR|65t91MW&Vk0AMt%; z@LQ~%dcsgVxgCEGXYP2Vy(&Cu9ZBqnj$R?W#t6fxE#rKK| zc%hn-X^~c}U&e1e#`g2Y^C?trA1^7nU3|MQE9SanZt{P`--SJs# z@&nRW8uf_C@VZxeR?ZiNvU%!@38noC?J(%e5;9-`ZeYXW<+NR=S)oBV0C~psKqnwg z>bhrzADWD&T^4krGjP$`YzZa0ZkU&AT8NAN2HBN;524$XbA-&T($9J+a&@J-@0~6U z&Mt>X=Sv>GdutB9)W^^w>5*2I_IX#&V8EE9{aalKA)O9XZt+W9jekL0=u(7-#tey0 zWFwo!IAIU(C3$|4yX=CF`%IVeze>G^p~B48YZ~IZQb8xF^AHyp zCQ?DK$xC$LsPMj44G`fv2dqa#L<|6eyX+7pjc!QCXMnw=B7wc>!#m-O0QLpsDvLaP zWVDOmE$G9MqKS0j>#Hj%AAa0!f93{L!ZhsY)V_qn_tW@#nU$3+8T<&hz$W|@SdacO zi809N9K&r63&Db^9P$oG#XyX>ZoS}cJcizwE?|Gs_N3iwIXLRK93Vg+mkg&y^Q#Ms z17D+(5}-_9iP_Kwz-GMC^_Sk99G9T;+fWvj`LW%!`wgLPng^Kflt>eNESP^L>{IDw zyWHSOy)vN7a+`Wawe$gc`e0jEnK{j zYyv#wW_~D|oCXCTsL_bHLTw%GVEw7ErElJYbZ}H zg^v-_KP4alGAU*1I=F=lAZ7L~0(u6KAt7)JO@CecvkW4h;KFkursgX_Rgs`~pKmx* zHEEO$v5FUp^ERxoqPDBf&R!%apKB!updjN@k{8~FLVM(K-U;7w>Q$bz$7QXf{ez*_6>Msk3&Y#{ve!?VXEehb0 z1HG2SwwE02jo^F1oHSpP`rKMHAt*;14J#%#nlri&yJy4OD-bUN6K=A$ISXt9d*IM&So7{W{wu7gyKHunn1UfcHpC z?I8?UAQ7evE78IIOCWa6@zqtb!Y7RBu~hR;AMBROI5;>a7wd)tqao0v<3Q);oM4I? z>UfyofKzaioy!QvqSlU(m^XXU6nt<(e)hof@Nz0jcseWpVJ%A>x+K)k-A%7?)V>WN zuq7)l%381;pbq5&;wpny#!!4+txR4#PnW;gvkQP_)J@dsCVVL(WHlJs6sej5_kXhU zLdYbuIBaIO95@kZX@N%PwDltIjxx_{WF^GwchZ8MmVG~3b zt)i#^5S%$Z_cU1Y00x1VyRjj=`W5pY%bzGn&c=xC(>)xK3mipMOK>aDb2$LOo?)1v zTV;gGdgzv18y^>`6_+%g!cs&Gom_v!VDTM)4Ttsh^+SubHlNTSAzxSE9T!Psiue*D zc0kUN6i#ntS8qrG!G4TqyO{L-dTSo|ZS0Rm2We<#JE&bTK(FVA!=oj>o( zQ_IJ><7hokxma7Dss#W;y!rbN6T#u01|n1?|B?fWu!?w2|TA z{^ONiL>^!1j-2mn$z8K%h)i0GR7tXmxj!IbWX+J*I>k{Vu2HJ8vqgcfGyDT==OmIK zENdH^nAKJN_v+p!tF3n(6(Pwc_Te}Q6?M$0t{6~ar$dx@PLg22MCz%W!$3WVwKiKp zRy|M|*g{W^|3dLmM*uXdfIyiJyx?}K@__RtAO$zC*3oa=hlpEQ=h?y-Ha5ehxG|bh z2ZJgBQiGH|FUPfFIs$8$aFfSFHX|N3l=(DXw3ly9K({XOYN`6KL~78)B0_khBW3s_ zBmx53-}rck@<6*AEA2a4@I0J{s;;6Ek=b4Wwf9F)={MnN9Q=nIDh(k30M-DyubH7?$7OP?50tULXIJOhv?U{u(^7z# zYOTZo^+nRot`wFWQZa-J$eh?CPnAPhahRx`f+1^zWiy-V6jI- z3k5Qu8B32^IYJvL8=E$77=O*XjKeY^JJlGfRAg0GjfeYt<5uIRr{0_ha+sjEN9HSo zKnG6${!DSHrh{wcZ=gRW?@OyW-843%8@)&!#-p-Io?4%M#DEB~z}usg^6XEACAP8> zf@ldq8ip+NHEjcWo^G&80g$Nz^9hCv#hu|yku>^c>b0F5y~y}41wvwfnflWcF{j-+ zrOXmN9xO!UYJUi_tZ{xyGt6oOW~%LC=IIER%}E(j!j1X*RgjmLS8kS(QVCu`Xry6i zTY$2(v;<9L%I7X$C@JMZ(>(H|z^zrOE|uU4c~9d?Pqsw*?C5~Gw(0lnOp)AfoeWVxt(FHu0FBuTSLSpmtEtltE(#4 zgIRy^H<|N5Lu>1-ntQbtm>?~(xJqHE-lm-g@>a;I(=bj?0K^-6fD?_oz$SF(eO-Q}|B$fN`ZhTN(y#L9XbgNJ zB6fzJBmU;bQ{HMJJGqF<+H%<*Ux0a~77^=@alb)F0yH-|XyLz_TXhNJvEnr%0!c3H zXEiCZok%{;JY=yUWgE{G$Wx27P`)s`KSOmQRC7=OWvlvhu>+WlFp%tGZ~7D4H|Wh;m3>6Br)NIG5=%x2np@oejKC?R zwXxpUPHi+b1_c`{D}0~^^;&*Jv`)8*xKN0v*8&l8YEDf;vTU0)Z zC=gXKvBX(kt;d}3XueX^+8U?lTfnzlgpi!3f#t*H)JwoZ0sWccyO%*ZL z+oN~)qB@*E2GP}lR$WXnp8^9a&`qTdztmypAKuloH;q6G96)nyfqqJx5nsooZzsFm z$|+Z4Unv98T@*hs$nCsI6@0(>H(sl)(M5*Yy^SVWf%aYvaJ(%jKF$lSQV?63(x_MPlK#nJ@u+bQ%PQqyjp?!rRR)_Il0mOT($iI(j1zICN$GdyeB0{SR z9=!Flug6+&+Ro0d%6^3>G7M(DS3=K~i&xexW47F2>=^<|T=9d)c5I|aTPS_KaYd50 zm2Fl2!3TdKem1}~jbqeh<5vF6@_)4@CnI8GV`F7zHq@@mAjn=6!dMVLJ@`*#(Eg?) zq2SYzU8c`TFDEgRuSY(?k+kVfh@dcSmcfc|<9P}Fl{tTqJ1HgVA*nFIdfQv&2~CGn zQH2fCh^%v3YWJl2^ZPu0JiRvWMi*BM6ZkI2^$y6S#Kduig)tYWIJZXa8;Dok0~3WC z1lrZbDM$05Zx&&tEp$HmK`U!QM<#B`3g5j1}HpIpFT0=^wjR%d*SihbZuU% zd}%b|dgQJH8V%?q{%%T?J*hf8 zIXd^doxd^AUd(QXcC{fe)_b0(Dre-1V=RVYFr!;mS2qg~O@xUlfF+LB>ZNgWIxW2F z$Ml1?@{_h%MiHs|k;-P?7X(qy!n-Ryt{?$2lfG>y76f)VM-!)YnWu@Ykh zLv%U88Dq_y^FSl}*&{<~`dPR|&J#a&;%hHmTf2k`#i=rLtk1c{TAR-~FdFY@vA?B~ z!u%KIZE}74A)%ChOt{I+yeNk7^XM!H@GvC}kw={pEkK9w7K5dJSNRN0uBL`{CrTAnOmuG^6|y)K85EN_xdw100i7iwCJtaZaaBgYLc9|$a_~q%)TUujYQhdJ-wq=7y7`c-;(ISZn4hcsj2G= z9IU$hP9m)?q2%eX{)_odvx#)gGM#$)#iiQUeEev&Rma?-7BSG8r?C=R9Pyy_+7Wms z3v{hY+n6fU(Eges(zgrD$hp2A$pCSX1ccy4E>W^XPlM==A%W<`4M2G)5Gq7ors*u5 zSaw*bIAcwcZ5tr+S5?BzeU8@C$NX1Ds(X^9)}YmE*Z=L%Mgh_r<&D9Ca2-lt?q0=$JxyXsbs8Lh#4vNccn zfw5f$Ev$dZq(Rzfao1#lJqcO(E56oEq2Skx`*)7i(z@&7h>MvO`_D`ubr%M!Oc$6a z@iDXV1Tin>!5R)SK1N{~!9p!^(7B&3iG!pJ8({*(AJOl2HEOu%>H{!7K0a9yQPgR?MU(Edfy|R#(y7B$8=~AzuPaCOd?BVX8w2R>H4zb+wP{_`SW} z`S~>qAiS{MFs;y}WBk^bO7yUoh^88L-!&;d+>l8ej)^<>XBC_1$YC51!^{RS6&Rot zJH$}QwDZ`$S}awN0@7q*-oA}5`w?MhPkdMGIV_N!yybEwsOTwF$=?E+j`JphK2`nr z_GXt6(p{~~uAK11dB=~x+UZ96p_FZu{uZ?8K{mGYWT+89T8Z^A^V&1oT>aTf z#1jaltE;PzvF9HiCL(<)8g&_G5ByCRo9E`2fgntT_Ayrl1FMXgSF-tB%I5U#`9S5O zrXN;^)8y9LWE-USq_2Iw-4fN+6;QG{?b!akC@|8);gRrdEz`PSGMt{Q)+MQ{-F&Fm zl1v3pvU)pMmiZ0DB_<(-=Yh@|-P+6Z4FevcVqHahzH)T5s<3(q9YKrM%@?U9D#n0w zGS=X)`l{beF#Y<=P_+81kxwbCO}?ye4a7J-Hk=XguC)sxxNrpf&4i%p>1a?VEouYE zlliUWR-j7N_`r&U$E80|2?86jTHd5Nv}B4u>gPGe=uxvAF&)o~Bu669$gDzRQXB$^ zo(t7|AC`DSAHvYqe0 zx;jgLMj=D5ufUJMOtNF+;Gh&06~zgMDUeJI03Cg4YHihnP@y zOy3HVb7~Q#X=s!Pr{|@LpuoTBB(fR(YEHPJtU3$Ve-pGUl{GUj%+J&4)Y%$U-@jUq zC-UEF^PtGZ&!S>LQxe)TuM3E`wrNqi5n8rMGON}~O3MvrHwG%10)_T>A!E-Cp+qjr z`4ME4rSaJ^j=P8$ja$xV9C=3w z1X?k^U)@GaJA)=ke}BvWX`dzIHZJrIPa~XQ=-G}&*HAYzPkif_U!yia(4M+;dL!K< zh7#Jji*)n|T<@}<{DFHY(h3R+;p)Hi8FA+rtr^QYd6S2OgMhsMGF5nk&~6?+Nmkt2 zrg0FC?1T#AQV6Z-K=exGORP}UC2-F<`H7BsKk()I*fX-1| z-=V^YT9F4zDEa^aiRs5YS+tDeEhNS#xteUqlBjRz7}(RDx>TS=<3ZY0D*Zox5_Oz# zjYyR>Hjym&iJ3uy0H)$!X_AZD9ikUF`@dG@arkf*iG3glM#Y`y7Am6m_i2eC*Q*W| zu)-*=y9X(0Wc3hploCSe=Stltp=hy9;jPA+5*T!-^z`%sB8#;_1*k>kLoKBPb#fSu zeb?404~PLAYX~{PfHD#-ITAcj(AeUK7R*PEELl4wyde_9{eDqXC6ibvI=_MiN6I#a zGO()yYLRXD`1sfxot<_xm7Ba#ceI9c6vC1&@921;I{!znm;N6n#_K#@mD{c!E$&2) z>r?WI9W+->(cb9?NlU-ai%Uxv?IWjvav|i3Wr3vQ%&w;+k;m*m#0m6?CRA}VHj9AO z4@e|E?hpdIB(rPgM%8M&zYyQ#8Y49gv7bIeSbr|+KLOe~tk95dPEukUxsOC~Z;8*% zB0@_h8T=0i4O4ksrN0yNnrq|m;|KogiHHI&wG?H4plSIP;*&{$Iz2n9&5Q|wvu9$V zn->A6_h~!sPA65b$wew8Bt+JxW8lLi&Cykm%93eWSFcx`a(iLen>s>5Ytx~77x-XO zzb;K4P^h7IvXx+_&1^|@-217Od1e~Mwd^A2-)HlsQLTUxV6v_R?9;qKa;P^VjiN*m z`t>bLJ$^h7MDdQy>GF@#l*=A12FoY|JSIIh#|J%m7}vcjt2HX&R3aO|3LNZXYj(}X zO&Qq%3(yM2om(e9*+wtuj(V-v;|zP@At-%3(|;ex=;~^U2(8)uI<};3NTAFff@`fK z)#3z%nO9|~_xqp`HJkfmnML*)q`dIFyfgj&Da)&=3@cWNn8s6JcvJSIFj?amwj!yS ziH!90*$5%Z5WeVSR7h3fk9nu&glsRhj}}Km8}j^tpTng zW!?S#4>hIyKoqVcE%!-+lQe#>y4Uj`HyvHCZ0(gbg0gv5{K8>6Z4wb=J-Alp^^P_8 z>EoxDH=#iJ8ifq+?r+bZZhu<=P~w3eulW5l4%S*ZnHFVUnnPqLgq`!q!Uwp2I60q~ zy1oK1dsAE6;Y-K%%{42B7I*O}k1+ty2>KM{h6dPrrD$PhTZR(Nb1)^5dzXQX?S{9V zk;!D=$FW9`(`K$L?%K_+1kddEPdG*Xi=?hu7+qF;;ARibLO<1j4iiWw)x8KVZK=Mm zy$cR#>QmIz>H@6)HPs+`H9Sv%VZI0FsN8g@=}hSfbmh8q1NXSFk1R38h<|bLYS6?C zQ2d_nf!n{`1Fn5GMGsrOLeD<_V!m=Yt}ivV@_$M%$9OT zwmWb9uzZ)G&N6=BELmqBCw#3iB$0uVJP6Q+&{KKc<-e2gTWd1|;j_O438~l$3}FZe zi-NLuy;3fUw;Nwb;};gRfKbY3Wo!%*?9rOBoxW}CliR*SVHMjZAN) zmAN}nh7PpuoM|6bx_oAMkK#=1-%G0K0u};cmUf>)xz-Vd5u-s^gE8B-rZ2w$gr#a~7RXwO> zbKmBh>&PnDlq<-`X(_{PXQ4<-0y6-w+EK9>@+2f@1i`4D>%D0i$)mJL@H;v$Ri+i#r&=(0@#{qK?HGN zR@OUiuj>-4PWC$(P}GE+1RMl%sqCHn1c~d9EQp|8K)rW*e*Cm@zU!S@0u-$kroASj zDCy1Q-_E^!&uMW9YDkDAquD?UsEKNfO?^j0L}ao+y*l*D_!I@*$XT>d$z}mBiJ?X5 z2*ze3D3T;(0RequeYxosMQlY8I0*q{hb+=@Mm(a3!;m0r7Lq z{T%>i6g6fU|HLm3YYcxVpc!K(Kd|en?hxK?%mCsxmy&k%ja@LDaF`=tmec_6>2k65 z$R&`*kBy-$S=_wYCu!i>PU?bwpf+<;e~7YXc4t0^r0jE2i7{lfgf{{1-T(Dy99;H5 z6WL+1!V%KJ42T&Ejl2q269~g{0K2q#H!RV_mzI{yR+?NVBH<(v0bP2|vr7ZVJ`5d8 zoYw1xz-!=$adXe7$>cfYo?xLV>)p)K^BHycRnUW))tRM449%i4_iIb=s62qk*iHjg zMA*^vOKgDZfP|QIEOa%44fRVsF%d7}?4yYslcu@3xiqUTu~^OIeMojXvm&hEOC!tm z0f&m_LzZ5vXRR*KTybdJaGpe4@q{{E_P6f;E;=KoSW zSd}s2&`>0#xy7nV>fXNX$HX~IpU}n0+1$x-MJ>01qw;%FR&L>SLHVYplEEFxgQWLY zK>?v@Kmje}%NIGOeE_3JIDdCzZaWTOaf*k9S+1GR*#a#wayufTWDKS-!Q|Qe>uoy( zM+!WHH9+S^QtGsRYznP29Ev}LW*jXamyFs*j*ibZT~boI)Ps3w9Hor5EdgUvSC9KE znDhd%1@Uj=2-yK?I?&zO$dSwjOastEZlgPX@ogq2!NK>r-{^za||m7R`>Jaa3Vnt zJI}<-3c+C~q=hoQUQ@T#=FSOUcjfB=LDm&W-uaoDuZheMA6#*GJeYuQlR$`+;Wq-l zGGUr!4(LOHky897vlp5T0@PYuEh^AT6MWfX@^NMb@XNQsge`j*(VQ!6cWubMY1 zLjKyao6s326VvDfizJdU3DA$*C!FJ3HWWbX%B;gjla}0z3Oq zMN)V5*R(S{$W#M}xeYQVcL;C9148v$JSIwgi{~;cuB%(Drl_o}DvR8B>9@{(>GKCt z+oUk%c9vO#5s@B53sa+5t^`(Kot$^L8(vc%a4lh zLb{qNJR(-s_CI>Xt8jjURCMk*f@S5zcUWOwHo>Ye5sm{7|w;%B~W5)Bod-^ z7DW2uMnImq-XmcXxM7 zHz*(=64Kq>EnU(n-BNx1^ONh^4}0wuGxywc&n${}L$1e~h7<1$g~=7b z4zT1PMA4zrv(>d-;)TAK)>Ueni_Z}uNB(F1f)(yh_5e`f;N!FMZUpMq;Oy%DoNig? zja;5fHcceCt{3XXEs9ri9mgNoIXSm@d;+tboapXwae&3SRH9h0zC?u5vW`m?-ylwI z37nfR5?q793dBksE&06+kh$4-4sH_DMvbT{J+I))+`|L6**VvwXeWA-ciC(qgg?&l zVZNcx%+3xq+AlBULoa-F%#u^ES?jc+84+2T8!#E2Lq(R~f%1t-LWR1VB6V|EtbLoB zS`3dI{KnjrYa&{b z^$k1eG|({h{PSi!dZ-(%jUbEVhL zGGa{!qEhfdQw4Gp08x6Smp=6TT}Eq;uk!=(&b5*2DHC$WeoCf{kr`ymvV~4k=iKGZ z*(3yeH4^_>MI0gemjhcJ{vs=8zOIu9fyD*PbaGb?Kteh53?KYnk|3oAoLydae%d>X z7nX~F=nh3)qM%ge!vWTF2pr)d0ti^i2DnDNq`|LwW{zE*hebjmtJXf>8U=+nV$kBR zAmAhz7Z+43{MWuPCeZ5{BH1xHyE(RuNTMBN#cMwhe)r6oByO|D`*P7@dFuBZP5sAj zKwTA@E8kM_K}Zy|RXnMkT@T2r8a6IQxX-;-bJOkQ`Zt-}}7yb9D6nqfO=K?32cxnn#!m zH}0v{8sIyA6b!96SSa7tie3Gjo72$lGu`9QYG8EjN>^*3~XT>T1{clv#e_{K;BdKS#0Ku{hZg_I(jXfDhd2>TZK zD^@Wo5eSQhC85+~C{zgoqbN{wQYBOx^C0y6Xu*(PCB!nwNOo~1(YW*@eo|6gfP_Zb zY|}{(8+U&rFtq1Ke;jctQw0p=6RdU5!d|P3e~{<#d5e zO+_iWJixQj=gMJP)ekOYde!XceDE_`7TZoQmeyHlgb{^Hinn5-&;OtD6jnK}bU)ba z53Z_S_5R567Ua!?8C9w2GPWTLY0rhw;%!7@f-$IhkxmSvLSLyz&w;FOT5tF`Mg<+en8u4f_O^W_vhc zYI5?+ARa=gy`7!hVx1T`ZF+a%@%z^ZKZ*gzNX`D&iU&c`j-6n$3`-6aJ)0?IOV@$r%^2{xj!j zV9wb9O9zlnmE|cZLaCV$oo_seQgb~bUs2(%a~rnvT9( zFU;-in5HHz>-rgV7$~O+-ZB84+0o%)0-%_nBqFH<{%i2&oW^aH_znvwsmO47EKpSA zX36}TacUW1#YC7n%uqttffCLc7>DT(&2)%r%KDSC$FzXCJtdUk6iPh|H8K3;{`s=_ z?E25vsYk$-2V`^*tyY66BczGeQTx>o-}VkF&&db_+~o$4F-uhR-F$}s`6ox}Xbyv( zjAU`0jj36k$l8f5BVihN-^b(Dm}a^5Umqm?8iJ&&W2@oYeyBP6Ofd-;cqlK`q{95d z!v4a@FNHeRHLrubm!>lS+S zuSKvAkEND4LugsYhMt8Yp@fRx^-07vuLB|qvS|VI4{Qg0m~e{`V|e-bDYywik&AV+ zRRMS;@HRD5BVZ{BWoy(p1CV(fyGMK4dGMn#tV)1%$q=5T}SZm@dYz z2UOMYAwCT$4h`H>U-?(xZ0G~^XDg~a^~RX{0Kd6`i%T8QjDC?P3WR7fCk-dpKS)&5 z1>t~NUT7b@r$Cnk1QFojkcZ65kx|I@jt=-7yZLglM&eWXlA@H%Db;Sm@|$jU(o9=v z;^N{?r?VbsK77$DY?;XTbG<_Hvev4l4}1zJ4WUh*q?pX~>{*blRJ%bsJRWS6M^`bl zoJGqX6jX?7uC}UjwO{Mdha`$>KFsdmD5Ju|y@|S=126KJoTCPR+x9BFw%_Z{h7~1^Pt|+dP?$OUr*9IaSewTiNE1$9g zT3s8AEfC`O@~d833g2n_e=6^f4{NJH5hFVPqvw}bRaRMBVIaW7#lu4bavX*46NYi; z5V^ho5|ZB`a0dbjP$grdV4w1|IQ(6|T z1J54Tm(IyZ#_>1CNmJN1uXYS21yXCRr{Akn#uvTbrgx8OLSreQobl+Av?H=5M2ZDo zm}!F@dniGxl7cS%XbL+P_yx|th(E6RU+a0NssBJ6es>G~?$_sAEpEqWBIh*y17}s* zX*CwZSy>W_NKrhet=<1UNG zoJ*a;hICL-&;j2_`WJ+lZEv~mDIqc0dVnxC&y2Z$EOj7$+W^NuG8|)Bg|jbjMcy8?1=|F-K||U z9Oyc>t2;DpAoyt3iZW1ksJV(AzF&mJa zjQWh4mGMzgQ3Mqq+x1{<@`P;HOesK!1qmuw@!>*H$9B|6`j`)R$s>2ne0}wZUJ%)7 zUvcRdtMnPIS$Fd>;QY!yQ3QmcFS>n@rn--B!Y3D?4ctZAMxTuQS*wkG6EpCO=$G7@ z%YjHElKOXCi1?q$7-pUR4?20_uunf`d(CU9cTd+|xJql$a``*qek zpBz~TRk!(6`jNTl?Gr!`is;L`C=iG0S?HboK##gaZ?zaB(r%Ce;XsNWi_OU+JW~xF zU0Y+Bs(ecR2|)};U0ofA|DPoJ9j4vdy9dyULL0RoJEVnyd+L;W{LMz5WONHRPecZv zCCU@%LF8O^sK*Q{N(rm7w)5qcFVd))kkOc$&EyjDX1JDFKy}9Nz_{b;u>4loEaCmP z`RZSTNd(+`t+)>o#w;K*0WKkqkRXt(`|C~&GmL|ubj2S79}x2g`cR*n0eQmS{+_+| zuYj*cXv)fGc`q`m3OIg(c7zzVhz|#r!pp#Ix@`2oLsVm%e6AH~4lP4H$_bL~6J<55 zY9CMiu2wBUwVYCu{DlPLAKnRixD$LJ6e*I0IxpV2dw_rGTyTaNhmY%y9A6gvnJnJZ zyJSrqFa1uyky4iVKkR*pHfBY|U$W#>F!e8~jt90Wge(E2LQKXeD8k}O1X4+;zXDR2 zOqG?cDNy^d@D97J9388Ce^Qc3|3uMDOHCYaZ20z4qg8E40|3!zsYqKA1tONCIk$Qh`z6| z(|VwFw_ZFfQ%)H@6Fq7_6kRE;o~C1q25w0Xa7CG|e|oVX5*C>m>vU9WuD#M_o>f@- z;ZJT3o(cNx3Rj`@!k6X%HkOP?tOv5lL#U6 z?ru9ObL+@b-0HHP-Zl(|vJ0_=Le{NpeL#<50*p9Y5tqaC*i`9%cy*c`=4=HRM1;@t z7wO6vhtKtWd|J!(TX{}u)JJ-I#XBa`p`l58zwns!*T_QhzTuHCr#5|aUmb#i0H zeE6)pr+(4|LaauRxl3R+dPDlZMfozi8 z$PHDR=X=(>-=V#B?J-J^aAAn5^2Xc7*!yRC3ZU)iYIwH$wkk+(q{o@6um*iCa>8C>d?`V+ z+-NU5QyyyLd^6r<;y-NteV&qvO9pPUn*i5fdA6h$|1seKiE6od(hxyH?T|@!4>@4^ z1G{**1T!eI|B$%Y!!=W#|B|xg1C2{;Vs>@(=Mqp_PIMopGU2H7fy^2`O8>*wX~z4$ zd*4h|c3o;4NGnWgi9P^q8B}x_REc9LC2GenX}1ZW1@fsL2c$613&~2PeV{ zor5QQ5Puc6E$QJM|M)9vAb@2L{G9+!Db>s83#=j>83MfC&3_`PryoeQmuFMzz~Y%K z5doo`caO1x^$gFky{)aRT1oQI(2y^)9PF>lS&44~0s`iJDE8%iiE1S{>b1Rq*mJwS zDR*S$(g}iHOz6(>6<<^vYW_x=)haKJFCS-TV-q`;#w*Er8=MQowPX&FJ8H<`;Xw7y zoqi{HNgwk%&vIgC9tfiP6SJL`YJ)=%o{OB9#?z;N;y^CdeH{JV=(v<0cHps+bm`r* zC+S(-JKeBcZ2q>0tD)*tu#qY)BQy5Pfx|S>EwY@|70}R^0ldsUmZn$Pdh`la0y_ZY z@NRzK%p3UFFY)%7Ln^WXakDDsFEp}bdeYG$q${)6hY!jguAR_Pp8JMmv&Fn-NV7HZ zecfrmKwb{>O}$V?(wE!Zk=wLF3bZ%jQ{%n*PYa5jA(^GLQS`7dP8~VHjj8(O-#brt zRpwh2teB49k)3?60!BL9E;Lp@6_55%3e73CDjI-RqQk$0uA1ZR^n;~IlAeIsHhu9N z($HiZba`w#qDURp4g+cv-*^VH9N(gtAt>@U5)aD<^N~%7RlKzWEYq?X{hK<1E zOan4P9}7t_Tu#Hjo{zkQ@5Xfq!#NYlLe4EwwO(EZp7YkV?v}&tVrs5|JEn$uagnk= zTO3sU!bppF`s(SquH=NNJhHL^8QBWA#nuej2oJ!Un#cyD%FD+l5~{ylqI&(z2*rD<=|f zU<%ZjqhVmAemp|!wT8_sRo0Z1l{IM``u<(Xzm*^!1;uuamvQb{HJzl?Hf8;br%#NP zF^pAh9AU<=PEO6$iK_DfuN_zqExm3|w{O-gJS9QRwZSk7O4Z?>8hUm|R|ov&@yhS8 zQQST2($7q?GLrcGB9c zDyqKY_*(Ifia$6Kf5u^7Bhe(H@RiNiZJXMOdt9mRNG(lr0wd zSQHgmW*$BImp0}vEoS%?`dE0}&ObdqG5WR&*7Nlij3waGIP0Wd5r^aagu~LjhC;_z z8I&@XkRsqf6qjvC=;?pXq?!jUK8!9O6}@IqO{v~P8QZbZ^@`{)|IoupQ!@#q5sB^) zF}Z@8?`QNr?oo`&Y~*96)R7=@m{oH46r8+)8I++3ea(Bk&Cug19Par8hUE|c20^|s zb9=WKj>?lI6h+A^-0^(X9r>96Q%R^vZcgrsgzfF+{o@1Im$;8|G#NS`MkJ9Ie)C?S zElxvYWB=`Y*s)C)BkNQ=@4`N}m~#pj_0S$AhY!Z20O?|9n}JYw=UQu*`4O zJ&I-8W;=AGXhphv-!S31^z9l21z9I`yHL%$bhw6@;*u< z=H`r0k!Z4ViGFyyTdy%pgpC}=N9X1n3Tc61;b!~g#)bAoXidE~Pi0h8)W+H5GPH@A zrcu~f_eFfT@I8Sj0-mEq_CO3 zdpCKxy7N%~>!N}BlEMWMnTbK$PM6YZK=pCd9-nQr+TpVxA~G{W3eo9G zTVYlKH*+P<8=UV(Xekl+3?c7-m$(hj49Hq8L-RQtEX|tSh3OJE>+#d>3csq3vdD3R z`)(wJ$iOO73-)wu7`b)C?3-{ta!e(5^IQGPC9rr+wJ{$@!<7iEUT3Z4CEV8DZ8Q*n z0J0l&OiZ6u_8hkL;#AQMxmRw=Q(4uj&|jHxQBs$`Z@tqU;c;{4SEjzNk$Z)guS2`% z$%(?1tT<~C13Mx!s?E3mvmQ;F z4xk;}j6a}BOFR!n4%mBbc1M-aBjTBgi;`8{KF`q^5lzgGlh$tUJ(tD5wOHCvO5xJp z-u?>oMqZttW3uR40p)>h{@w*_LH<3^V3XsZq+yjb+{b}7Red>Mp!O#2_1Vv$m_}y> zpWEKQ-}yOSXuS+7wFuomEls|H2`fw$1G8~ao?lhF2F;tY;Vk>2FjHVg_IfMDm0{=` zgCHX=5-8%m4(>rGJ&J=x`8lmdh(wonVapxk_z(?puu{ZutRGaG@OCI2Q` z%0KP_qsh|TOZ%DW{E?QXrbiO0de1zy;N-zuu0_~bo`N$_65W@LB=RseF=6ZUos-U6 zs8>Go{6}+Rw?X&e${kkJKk=Hzg?)PNc*uCL7CF-NGo( zTP$~!XokZ>QjBA{el zSAi!LCT^1Gc-0%fsHjL1R1cXY!DB&uC%RIS5?`ExAmgrZ^|!zs_MmP2=g*I>Z!+{V z`k*Z^u9avqK=%mca-Q0b{d^SyFejoL;`P#epuk_Vb7w!%e@vQ;gIB*a_0$v`f|yU> zAjfIebN%9PBpNEEBfnOX;HkpoU zDDze}3ofm{&Pm%2nAF?0^+t_xRJVM8Osw84j?-5!0SYh~V4;Z(202~OxTAmFu^^oZIv{OE@9tuV~29Siy|)xL8IfJ{7ilRaWupT6gYd%#vqCscfE5% z4UzSioLV09nWs9q)_i?iEB~MyXJ$Du-Yev;nJnvmwrIyr@M91y(Z#H3#lwo(1^g_# z+gC?2*e^RaY_Eq|Z_~C?LBRN~2M&HafyJlMAuNideaY*&W}F%ao`SG3HWhTFd6Xjz z+WvW5SX@J-J78RyS#DGJ%R@=Xq7y7t%u_Jfemu zz@azpsY#Pj%abNYhr#q7!B$1sm~*vlz+LQv=*H=x&w^gB%H!L@*~vd!17g~`bu$9E zg;`E+G@+vW(C4vJuLI?qei9=MoSamH-k@zqt#eAAo%w#inv;=2b~)gYI3w4DTj8@3`*v8tu`_poyxa{f^43+&EWPwP)}avw%C<#Et zq_W?}hsyN6949TC4m?k}a~g?u(ay~4+ar1o7+hLX55a^S&tsu92cVop=(dAXT=#Ti zI|eZj_8h&uq;C$SYS!i?3SW5+jFVK_{V^n?J2zatJ0Z2Vbu(GWKrOfazVR*8RGlBG z=_lx-lIC5R#3Xy`A0}%)xMBfJIrN>;(tpf2@#RX}8&*Sw-XXLuY6|ttsUBu3T`NlX zt~bU8rjHJsXYVsGW+s-FN}VYw`{=8-<;d-Bkp)pOuU$NUVc2JoN5(Ctb zl$|>K##Tp<7P8TI-*^=$Eu2?2TvGlP5Qox676SpZ(V(6y6B83I;+R*q3PD)l_rE|v ze(KH>2kHW}K=WqDGSD{o;TixgTCj0+^e~o9qpv$AraNC#sJP0=4G|B&(EkN4o|*aF z02RLe?7JY@<`!?~=jcTTDJ3YK%zh6k@9&o&yE1IMN84s)=5%#knx66+A-n$>t@r0 z$HkGe5#HFAl)BB!WDRT@ECW5Qg>xr)f|d66<%F@5Kkr4Ku6X=S)=Gr*uX)>OvzL$n zFp}9|3(b11h4S(E``lb1B3b=T?iVu*n6d8c(9^x_tyrCr&YAP>PC)FN*2#~mzb-Tn z4q9d7j#kC|`ra&{n^`3@%j8Lh&M?JgA0iS=DQPWIt6wyK!wqx7_Q^t>~h z5Ur>o9UdyQlU{L-6HP|Tm$B`D4z({^ayII$JDA8=JkO8}o72@dZZG78hh8IkTpqZZ zleJlSBPRu%vM_|G-#%E%3t5pt2M^HVV$@A!aQA`hhME{PU1$2%*Rv~iA6Zg_bqj*J zBVT_FM;_VQ1c|>sS!?FGG6HuA;SHh+7K8bN-_%u(7^ga4g&fC*NL)l=MILVIqmZU9 zhi-L*yw9!v*vQUALC|zarj5lEJ?Hwyyk{j;Lv!kcwZDVI*_DGTJC=K~$sGx7$fM{D z?bo8lvb&?oo$^5vTDwliu@{q+l2KHibx<3GKuegwsM&TTJSt;s`za}V4tr-R=Cl)D zdW~ilO(0LDNkWy~X|=aW_V*|Isux%7On+v3=6Lgfkc7$LBTDw8FNRt_wHLs`UBGXY zV+w67o8>i54Ska@#;vro8T4q?o!(>sX7sPOrNXrs)RPh=LP5%YPlSVFIaSi2;%L0@ z_7Unx&5rO(Yx!b|^?o8dUSUQ?+R_Sl#P0D0qrY&PvCAc_EC>WPydJ$Kw4IGLtEgV$ zUh-qr+pmcS_dsJrRrnR_>MYmaQUBQ$BT4-0GXRoDKrJD8fAMzY?!<_Oh9=eREq>rD z8!gopxmV^aw7$Fom?s`(p(p8*Ax@H(p|U~Sa*kEJn7FqU^0R%`U&VUJ*rK<+OSn&waxbKIoFMF=cQAeOXd3&pOXCjy+d@YK!V2(%O4W zPEY5Fg_di-qhe-d-3O{e16fvKnR-&UWyJm49cUWdUsd=)vwctf z_IAGWXr-m};(99@loH-*aN+BAgPWyz1aE%EDO62PK(6+JC`bDWxP1rpR!YBss;9gL z?tSTwf+?kjNSw)6J?Sy03p5c08$SL79GZC{yJb4*glD%qEm!2+6S|=Y_b@d$DgiqC z$MahQ(VX*?Jb$=XJEyI(Z9l5;5A zyij)Ab^H)I_O{e`F)vzZuZzLP6eeZ5h!MY1vLAA1#bBkMukXsN$U@tdCq?g_qBy2X z7HoIjPJtGPQ_!w&$~sS9BQ)B_InQ-IQ$x|@+196itT+Dm?fgF)&5Q=Q+cCK*aQqb}erDKtn~@SPY*p$94=qgO%pt6f9U7te!heO2-c} zQl&W1BEQc8n^d#$R{oAOM}-e1msnir;d~mSJXc7rs+BGjQ|Q4rjrl;9D9(W1u9X7& zkP;@Ca1MR)$7){2Rc{ffK@&v_d8WL9(bW6vQ$&jcpQlA5M$t2wr{>klU-?K2A{lushLp;~!C`UnDqUq=N z$2yBsP_V*o?#$QU3u>6BgdGAF&3WhMxwxI@_V@RM%#JdBjwbazw14%(APxTNO|{nK z)!%AgR&2SrzWrGjG>i3ScGHy5{?>*jxb_F7v9dN*y0RSl;)5;iY7IIM0vZ2-uBN@0hLAFMH?eWq9A7TUS(7Ejuvq-6OaKl-T&hC1a$t zVr_|Np{1A(roZLJQzbp5gapdOrz=Nq5M`!FFB}frQ(G2gAU~&0tCXh3+%FD}t1Hswfm|FZZCj`WBARY=c4%P7!U~x~! zJtOLHm6nZ&=wLiP*kfw^ywEt-EOI>(>)+sT)hNGohcw$GZ-M?&-l+kk{|1HVvi8(0 zX*0bJBZ{xwFBhL@TE9a}zEY*N!=&sM+j;#}`U67<1RDA|>VQ;MgP&vypt7iUyil7= z!1<|y*NP!+sE>Q&m~z=gBA|U(s-H9cNsaJu+%BawWHVIl?|$xs^7&bBe#}12tk` z3-ec{ZRyeb_G-L$)PW`u_HW~7L>U6aD#qfid0Jc+t%4Tk*Fh8|`h&?=A5LnBgbpb` z1WSdsXMUwsoccwG6qNGT=!dXYIXoQ!XOiBb8!cf}kqpCryy=bQay0aLJKwN90 z6dAuW)s!Z6JZEQsF9M?m3hklT4&V_c_f+1vXtH?wX|E!x_8o$W?)_zh${Ep>im%yy ztHX2HEY~XZ7az9qJxAHMV6$VueKNN8X2U`b*`JRv2BU8<;X4>OcU+xql?99&i%|VL z=_*nX?x1dsUkSBIF6(62#(lxv(LZ5dHjQ+qJ5Z(eE%-F_H0C_2(QTrD|CS&3a`*7w zj-DW@EFV*CM20~zq5@Os%`%l`i-}c@V^0eqT7bfo z53v?X_0a8YOMjLA?DxLs+`_z?Ua@-^sk!Cj8Fv9PlUH z;R~;<)!uT2$t}e+H-+|uBgHmqjU|M^o)nTF)NIxhhU^56625Z)E3) zzhqc}PP)D)t+VZkka}t9jU+(%PqSfUjmK(+l>TTubu>}R4w^_uo__immer1R(F>wGr~Xts_7q)=~$pOW$63ffqQ3`MTz|l$lcp#KfRr zj*a8g*>LvHTj)zV2q9*lvS=&a1Zq{Gl`V&QLjx5L7{x_=y^Oan;oZhYIwKXoB6#Y12)T3iS#*W z=swlc^Wku^Jjr|c7C5&^e9QiNHow{Zw4mUgxnK4x1|xy8zM}olVa^e+?qA@(-{L5O zkat;wTwg{(rVV$KRrLOo{3jj8Os(k0Lm9wY!e|?b-=y zleFt#!a|OYDQ(4Q8DkdvO0%g}nQNWhJPou$7=T1`%)_r=%%DMF1FcG22-3$%qzF`0 zqOomMT`-Ll)F#>NI4&Ev{V5q`fgxTHET1#eywlU0)gfY*AQPUtfQbh(H5%^yA0jDS30G z!v&Uu)kv5#NETSi6X$^=a*lJ!5AJk|X{I|yoz^k3u^HaqY5E#1B_31Xx0fwW9D|6& zsW8l8o!xF*q~YI^#43nmCI z!#@3VD=ql6ab@A+H68fKORR%Sw4P4>~pgxgO>7j}Uw6zvJcp+3Y1ap{Hj2H9u*g z<1;8M8vq>_D-9}q0!~P)I^TfN_tSPw4BWSqV%dJly!;|vB$Pb1J;s_H4Lr8E2s=`T zzy4WWU20Yuvj)=q@Hr}v{mYkJzP)naydD77vc)KW%WTiQ=d(*1nL+Ad#9d<ZZxL(lf#PE{7l#{v`%tb*ovxcAPu3* zP(U=`4IJ}TD365yjp^|4*5(m`l%qv0h!i7BSNSa}KE|jf%}k(A2vmO(uSWO+3dE;RPo4iz ze#-RTqpwnztaR%IJX$_bZ-KB>!B^Bc3Gs0@=wf}ktuePvcm#Z;i-G2JvW7vBd6sN1 z4?E%j=`n4hOwi7~me@w-!`@xLlH8K4D? zJ?(b~cNIETmtaLDQ%F~VuU?B@>an%o-N2Dt`t+K9*B&HRl>J-Iue#nECY_fq9KR>? z^cpP-8CzfWfMj@XD!0W4XsI5Yoq4)xCcGQ=7rWHD4{euFwua#TTp@azS)3egNw0+k zQVOx`>T|PD?*;^=b`zWWQg~s$P{t2U&oMAj)lLH$UQ3>&Cv54bZ+hYTU9sQE85u_k zusq*HgowUV(i1fNc}Q~D2knfF7Nq`)&rcp?&E1TctulY}lvPBQ&6Y4*WTwOJTj8pH zc+?vuGo4C{)DSdddBdRIbV!SZ@fPrrP+V_ULq{ppfC+fXq;ZJPu{(2B+uVjM{K$w% z{mw;*&96-#UgEHak8ZHsFLmijpZtfx*Y_M`X090R&1Q- zyILQ3Zt+0yvfYk3jxY{86wDK+~_D7aKX9gZN5~7()qzqc@OnUZ%`DSB+p|NX5K>7VY<;KHMIfQnJ|GGx5^MI;74$`9Bv1}y8j|=&JGv2!Vi8?TKtV#pumUp^^JxV&+}&pFIljYa4lVKB&qzg zrzj8;raCWyPb@S^7mdgEIE@~IWRQA*beetGQR5c zUK>|ByAOuX;L@-b?q9@xT6ZQ(IDaqqs$p-gw&%@1_r}S^e#A^MT6q1#@XNVCtPY8m z%4RSL$W}K20AYV<--p%Iz&+RMr8Bh*__+XQBW855|Nm*O=!PzsY(^@-aCe+Y%?Tw> zkg#uPXv7Oz(|zMKsv~;sB{TH`{4T6j77a1yKR2<9u!W_~kq}-+)&G z*AX=Y9)!2g$+jvUJ9gHV$(VV?)^&}Y$2k1@2`Gpw|_q2B=mKf5Ko}J}FKK zfQM8Mw#WYeA#3BiMUX6Hm42mBN<>o@dIvN-)Q~%~K)xJ7RJI(G7+KgvoaKsZgrJ=-ymx_$SS&R$w4_7j$PS{vEPs z1XwTy>EpO_1L@T-Id0%+Gby!DaVA;P+iI!^6zLa zv5yHigJ7Nx-d9lm`w#iD?O2`y^Vbs3IluUmBQ59V3$qHj}-B*x6; zCNCC2Mle*stKCkqxxilvA=9_^mY1&Q=l%UR7>7u!~jyFW_|9$NS4Ojx!r1OYa ze+?DQO&*c+6nyL~PS~H|3;OaMKTG`2lr)8dId+g1rrkY^ee^cr73WH3Sg(@tR+$PI z%2$<@ULzk9{dc0PDZ$gS)a}ipDr zd|sJbWNDCJOylalqJF5!4@iCkdoEj%B?g^E)X@1b3II0==ZyV$Rpb5GyEhgZ}-$8)3sc zrvlUu_R_*EyOPxH@ejMUZ>KzD-<-@-31&zaX%HK*zW#S9!U&!%f>zB_(eX?2$VTW{Le!2K^8JCACWrcNAG|v8K%@L25U{Y#@?pj&JMZ z@sA`lPzo5L#(z&spb=7ta{So#aja`rK5Q&UL3Dh+j||z)Wjlp^MT5$^0L`w src.startsWith("ui/") && src.indexOf(".gif") < 0), ]; const essentialMainMenuSounds = [ diff --git a/src/js/globals.d.ts b/src/js/globals.d.ts index 642745ca..4a903437 100644 --- a/src/js/globals.d.ts +++ b/src/js/globals.d.ts @@ -19,6 +19,8 @@ declare const G_BUILD_VERSION: string; declare const G_ALL_UI_IMAGES: Array; declare const G_IS_RELEASE: boolean; +declare const G_CHINA_VERSION : boolean; + // Polyfills declare interface String { replaceAll(search: string, replacement: string): string; diff --git a/src/js/states/about.js b/src/js/states/about.js index db06d8de..b8f465b7 100644 --- a/src/js/states/about.js +++ b/src/js/states/about.js @@ -15,7 +15,9 @@ export class AboutState extends TextualGameState { getMainContentHTML() { return `

- shapez.io Logo + shapez.io Logo
${T.about.body diff --git a/src/js/states/main_menu.js b/src/js/states/main_menu.js index dc8d30ce..2e20b05b 100644 --- a/src/js/states/main_menu.js +++ b/src/js/states/main_menu.js @@ -42,7 +42,12 @@ export class MainMenuState extends GameState { return `
- + ${ + G_CHINA_VERSION + ? "" + : `` + } + ${ G_IS_STANDALONE || G_IS_DEV @@ -58,7 +63,9 @@ export class MainMenuState extends GameState { @@ -77,11 +84,17 @@ export class MainMenuState extends GameState {
-