diff --git a/.clj-kondo/config.edn b/.clj-kondo/config.edn index 5ee520e29e..a2e64d312f 100644 --- a/.clj-kondo/config.edn +++ b/.clj-kondo/config.edn @@ -69,4 +69,5 @@ monger.query/with-collection clojure.core/-> } :config-paths ["rewrite-clj/rewrite-clj"] + :output {:langs true} } diff --git a/.gitignore b/.gitignore index 247ef79d1b..ba3b7293f0 100644 --- a/.gitignore +++ b/.gitignore @@ -46,6 +46,8 @@ data/WiredTiger data/diagnostic.data data/journal data/storage.bson +data/_mdb_catalog.wt.1 +data/sizeStorer.wt.1 #Calva .calva/* diff --git a/bin/restart-server b/bin/restart-server new file mode 100644 index 0000000000..42d4cc0bab --- /dev/null +++ b/bin/restart-server @@ -0,0 +1,5 @@ +#!/usr/bin/env sh + +set -eux -o pipefail +docker-compose down server +docker-compose up -d --build server diff --git a/bin/up b/bin/up index 5ea5cb7db2..1318eb0684 100644 --- a/bin/up +++ b/bin/up @@ -1,4 +1,3 @@ #!/usr/bin/env sh -docker-compose build -docker-compose up -d +docker-compose up -d --build diff --git a/docker-compose.yml b/docker-compose.yml index 78161f0755..b9a73c474d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -13,6 +13,8 @@ services: - "./resources/public:/usr/src/app/resources/public" - "./resources/dev.edn:/usr/src/app/resources/dev.edn" - "./resources/logback.xml:/usr/src/app/resources/logback.xml" + - "./project.clj:/usr/src/app/project.clj" + - "./package.json:/usr/src/app/package.json" - "./src:/usr/src/app/src" - "./test:/usr/src/app/test" - "./docker/docker-prod.edn:/usr/src/app/resources/prod.edn" # Override server configs diff --git a/package-lock.json b/package-lock.json index 57fc92e493..1b16e79221 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,6 +5,7 @@ "packages": { "": { "dependencies": { + "@fluent/bundle": "^0.18.0", "@js-joda/core": "3.2.0", "@js-joda/locale_en-us": "^4.4.0", "howler": "^2.2.3", @@ -12,10 +13,20 @@ "react-dom": "^17.0.2" }, "devDependencies": { - "shadow-cljs": "^2.16.8", + "shadow-cljs": "^2.28.21", "stylus": "^0.55.0" } }, + "node_modules/@fluent/bundle": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@fluent/bundle/-/bundle-0.18.0.tgz", + "integrity": "sha512-8Wfwu9q8F9g2FNnv82g6Ch/E1AW1wwljsUOolH5NEtdJdv0sZTuWvfCM7c3teB9dzNaJA8rn4khpidpozHWYEA==", + "license": "Apache-2.0", + "engines": { + "node": ">=14.0.0", + "npm": ">=7.0.0" + } + }, "node_modules/@js-joda/core": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/@js-joda/core/-/core-3.2.0.tgz", @@ -1001,14 +1012,15 @@ } }, "node_modules/shadow-cljs": { - "version": "2.16.8", - "resolved": "https://registry.npmjs.org/shadow-cljs/-/shadow-cljs-2.16.8.tgz", - "integrity": "sha512-2xwKMgY2tTHbcTxnvpgeCVreIOaQx3mkNo5eWztE7HkM1QAhfRoXKFn0dFHt8LJJ64dWJwIk+eTB87RKSF+x2g==", + "version": "2.28.21", + "resolved": "https://registry.npmjs.org/shadow-cljs/-/shadow-cljs-2.28.21.tgz", + "integrity": "sha512-O5VUJkTh0bWqPBSKoWnQwEe/jfvbxHkzCA7SEx8f1Eavb7nDFcoNFDkgGjJtaAyaaSw/cmABrT2EeksnXw/25g==", "dev": true, + "license": "ISC", "dependencies": { "node-libs-browser": "^2.2.1", "readline-sync": "^1.4.7", - "shadow-cljs-jar": "1.3.2", + "shadow-cljs-jar": "1.3.4", "source-map-support": "^0.4.15", "which": "^1.3.1", "ws": "^7.4.6" @@ -1021,10 +1033,11 @@ } }, "node_modules/shadow-cljs-jar": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/shadow-cljs-jar/-/shadow-cljs-jar-1.3.2.tgz", - "integrity": "sha512-XmeffAZHv8z7451kzeq9oKh8fh278Ak+UIOGGrapyqrFBB773xN8vMQ3O7J7TYLnb9BUwcqadKkmgaq7q6fhZg==", - "dev": true + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/shadow-cljs-jar/-/shadow-cljs-jar-1.3.4.tgz", + "integrity": "sha512-cZB2pzVXBnhpJ6PQdsjO+j/MksR28mv4QD/hP/2y1fsIa9Z9RutYgh3N34FZ8Ktl4puAXaIGlct+gMCJ5BmwmA==", + "dev": true, + "license": "ISC" }, "node_modules/shadow-cljs/node_modules/source-map": { "version": "0.5.7", @@ -1251,6 +1264,11 @@ } }, "dependencies": { + "@fluent/bundle": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@fluent/bundle/-/bundle-0.18.0.tgz", + "integrity": "sha512-8Wfwu9q8F9g2FNnv82g6Ch/E1AW1wwljsUOolH5NEtdJdv0sZTuWvfCM7c3teB9dzNaJA8rn4khpidpozHWYEA==" + }, "@js-joda/core": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/@js-joda/core/-/core-3.2.0.tgz", @@ -2130,14 +2148,14 @@ } }, "shadow-cljs": { - "version": "2.16.8", - "resolved": "https://registry.npmjs.org/shadow-cljs/-/shadow-cljs-2.16.8.tgz", - "integrity": "sha512-2xwKMgY2tTHbcTxnvpgeCVreIOaQx3mkNo5eWztE7HkM1QAhfRoXKFn0dFHt8LJJ64dWJwIk+eTB87RKSF+x2g==", + "version": "2.28.21", + "resolved": "https://registry.npmjs.org/shadow-cljs/-/shadow-cljs-2.28.21.tgz", + "integrity": "sha512-O5VUJkTh0bWqPBSKoWnQwEe/jfvbxHkzCA7SEx8f1Eavb7nDFcoNFDkgGjJtaAyaaSw/cmABrT2EeksnXw/25g==", "dev": true, "requires": { "node-libs-browser": "^2.2.1", "readline-sync": "^1.4.7", - "shadow-cljs-jar": "1.3.2", + "shadow-cljs-jar": "1.3.4", "source-map-support": "^0.4.15", "which": "^1.3.1", "ws": "^7.4.6" @@ -2170,9 +2188,9 @@ } }, "shadow-cljs-jar": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/shadow-cljs-jar/-/shadow-cljs-jar-1.3.2.tgz", - "integrity": "sha512-XmeffAZHv8z7451kzeq9oKh8fh278Ak+UIOGGrapyqrFBB773xN8vMQ3O7J7TYLnb9BUwcqadKkmgaq7q6fhZg==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/shadow-cljs-jar/-/shadow-cljs-jar-1.3.4.tgz", + "integrity": "sha512-cZB2pzVXBnhpJ6PQdsjO+j/MksR28mv4QD/hP/2y1fsIa9Z9RutYgh3N34FZ8Ktl4puAXaIGlct+gMCJ5BmwmA==", "dev": true }, "source-map": { diff --git a/package.json b/package.json index fb9783309b..4a94046caf 100644 --- a/package.json +++ b/package.json @@ -9,10 +9,11 @@ "release": "npm run css:release && npm run cljs:release" }, "devDependencies": { - "shadow-cljs": "^2.16.8", + "shadow-cljs": "^2.28.21", "stylus": "^0.55.0" }, "dependencies": { + "@fluent/bundle": "^0.18.0", "@js-joda/core": "3.2.0", "@js-joda/locale_en-us": "^4.4.0", "howler": "^2.2.3", diff --git a/project.clj b/project.clj index 53ce3182c8..afd920cc60 100644 --- a/project.clj +++ b/project.clj @@ -18,17 +18,16 @@ :init-ns web.dev :init (go)} - :dependencies [[org.clojure/clojure "1.11.2"] + :dependencies [[org.clojure/clojure "1.12.0"] [org.clojure/clojurescript "1.11.132" :exclusions [org.clojure/google-closure-library org.clojure/data.json org.clojure/tools.reader com.cognitect/transit-clj com.cognitect/transit-java]] - [com.google.javascript/closure-compiler-unshaded "v20211006"] - [org.clojure/core.async "1.5.644"] + [com.google.javascript/closure-compiler-unshaded "v20240317"] + [org.clojure/core.async "1.7.701"] [com.taoensso/sente "1.19.2" :exclusions [org.clojure/tools.reader]] - [com.taoensso/tempura "1.2.1"] [ring/ring-core "1.9.4"] [ring/ring-devel "1.9.4" :exclusions [org.clojure/java.classpath]] [ring/ring-anti-forgery "1.3.0"] @@ -50,7 +49,7 @@ [com.draines/postal "2.0.5"] [throttler "1.0.1"] [clj-http "3.12.3"] - [reagent "1.1.0"] + [reagent "1.3.0"] [org.clojure/tools.analyzer "1.1.0"] [org.clojure/tools.analyzer.jvm "1.2.1"] [org.clojars.frozenlock/reagent-modals "0.2.8"] @@ -65,11 +64,15 @@ [integrant "0.8.0"] [com.widdindustries/cljc.java-time "0.1.21"] [time-literals "0.1.5"] - [metosin/reitit "0.5.18"]] + [metosin/reitit "0.7.2"] + [org.flatland/ordered "1.15.12"] + [io.github.noahtheduke/fluent-clj "0.0.1"] + [net.xyzsd.fluent/fluent-base "0.70"] + [net.xyzsd.fluent/fluent-functions-cldr "0.70"]] :test-selectors {:default (fn [m] (not (:kaocha/pending m)))} - :profiles {:dev {:dependencies [[binaryage/devtools "1.0.4"] + :profiles {:dev {:dependencies [[binaryage/devtools "1.0.7"] [cider/piggieback "0.5.3"] [com.clojure-goes-fast/clj-async-profiler "0.5.1"] [rewrite-clj "1.1.45"] @@ -77,7 +80,7 @@ [instaparse "1.5.0"] [integrant/repl "0.3.2"] [lambdaisland/kaocha "1.68.1059"] - [thheller/shadow-cljs "2.16.8"]] + [thheller/shadow-cljs "2.28.21"]] :plugins [[lein-eftest "0.6.0"] [cider/cider-nrepl "0.47.1"]] :eftest {:report eftest.report.pretty/report @@ -108,6 +111,6 @@ "get-game-stats" ["run" "-m" "tasks.game-stats/all-games"] "get-user-stats" ["run" "-m" "tasks.user-stats/all-users"] "get-background-stats" ["run" "-m" "tasks.user-stats/all-backgrounds"] - "missing-translations" ^{:doc "Print translations in :en that aren't in other languages. Can be passed a language (fr, ko, ...) to filter to that language."} ["run" "-m" "tasks.translations/missing-translations"] - "undefined-translations" ^{:doc "Find usages of (tr [...]) in code that don't exist in :en translation."} ["run" "-m" "tasks.translations/undefined-translations"] - "unused-translations" ^{:doc "Find entries in :en translation that aren't used in code."} ["run" "-m" "tasks.translations/unused-translations"]}) + "missing-translations" ^{:doc "Print translations in 'en' that aren't in other languages. Can be passed a language (fr, ko, ...) to filter to that language."} ["run" "-m" "tasks.translations/missing-translations"] + "undefined-translations" ^{:doc "Find usages of (tr [...]) in code that don't exist in 'en' translation."} ["run" "-m" "tasks.translations/undefined-translations"] + "unused-translations" ^{:doc "Find entries in 'en' translation that aren't used in code."} ["run" "-m" "tasks.translations/unused-translations"]}) diff --git a/resources/dev.edn b/resources/dev.edn index a2c1df6fda..92a2575e3b 100644 --- a/resources/dev.edn +++ b/resources/dev.edn @@ -33,6 +33,7 @@ :web/email #ig/ref :web/email} :web/banned-msg {:initial "Account Banned" :mongo #ig/ref :mongodb/connection} + :web/i18n nil :frontend/version {:initial "1" :mongo #ig/ref :mongodb/connection} :sente/router nil diff --git a/resources/public/i18n/en.ftl b/resources/public/i18n/en.ftl new file mode 100644 index 0000000000..3485b42178 --- /dev/null +++ b/resources/public/i18n/en.ftl @@ -0,0 +1,1512 @@ +annotations_available-annotations = Available annotations + +annotations_clear = Clear local annotations + +annotations_click-placeholder = Notes for this click + +annotations_import-local = Import local annotation file + +annotations_load-local = Load + +annotations_no-published-annotations = No published annotations. + +annotations_publish = Publish + +annotations_save-local = Save + +annotations_turn-placeholder = Notes for this turn + +card-browser-form_faction = Faction + +card-browser-form_format = Format + +card-browser-form_search-hint = Search cards + +card-browser-form_side = Side + +card-browser-form_sort = Sort by + +card-browser-form_sort-by = {$by -> + [cost] Cost + [faction] Faction + [influence] Influence + [name] Name + [set-number] Set number + [type] Type + *[unknown] Unknown sort-by option ({$by}) +} + +card-browser-form_type = Type + +card-browser_advancement = Advancement requirement: {$requirement} + +card-browser_agenda-points = Agenda points: {$points} + +card-browser_artist-info = Artist Info + +card-browser_clear = Clear + +card-browser_cost = Cost: {$cost} + +card-browser_implementation-note = Implementation Note: {$impl} + +card-browser_inf-limit = Influence Limit: {$inf-limit} + +card-browser_influence = Influence: {$influence} + +card-browser_memory = Memory: {$memory} + +card-browser_min-deck-size = Minimum deck size: {$min-deck-size} + +card-browser_more-info = More Info + +card-browser_select-art = Select Art + +card-browser_selected-art = Selected Alt Art + +card-browser_set = Set + +card-browser_strength = Strength: {$strength} + +card-browser_trash-cost = Trash cost: {$trash-cost} + +card-browser_update-failure = Failed to Update Art + +card-browser_update-success = Updated Art + +card-type_name = {$type -> + [agenda] Agenda + [all] All + [asset] Asset + [event] Event + [hardware] Hardware + [ice] Ice + [identity] Identity + [operation] Operation + [program] Program + [resource] Resource + [upgrade] Upgrade + *[unknown] Unknown card type ({$type}) +} + +chat_block = Block User + +chat_cancel = Cancel + +chat_channels = Channels + +chat_delete = Delete Message + +chat_delete-all = Delete All Messages From User + +chat_length-exceeded = Length exceeded + +chat_message-blocked = Message blocked: {$reason-str} + +chat_placeholder = Say something... + +chat_rate-exceeded = Rate exceeded + +chat_send = Send + +chat_title = Play Netrunner in your browser + +deck-builder_add-cards = Add cards + +deck-builder_add-to-deck = Add to deck + +deck-builder_agenda-points = Agenda points + +deck-builder_cancel = Cancel + +deck-builder_card-count = {$cnt -> + [one] {$cnt} card + *[other] {$cnt} cards +} + +deck-builder_card-name = Card name + +deck-builder_clear-stats = Clear Stats + +deck-builder_completed = Completed: {$completed} + +deck-builder_confirm-delete = Confirm Delete + +deck-builder_copy = Copy + +deck-builder_create-game = Create Game + +deck-builder_deck-copy-suffix = copy + +deck-builder_deck-count = {$cnt -> + [zero] No Decks + [one] {$cnt} Deck + *[other] {$cnt} Decks +} + +deck-builder_deck-count-filtered = {$cnt -> + [zero] No Decks (filtered) + [one] {$cnt} Deck (filtered) + *[other] {$cnt} Decks (filtered) +} + +deck-builder_deck-name = Deck name + +deck-builder_deck-notes = Deck notes + +deck-builder_deck-points = Deck points + +deck-builder_decklist = Decklist + +deck-builder_decklist-inst = (Type or paste a decklist, it will be parsed) + +deck-builder_delete = Delete + +deck-builder_edit = Edit + +deck-builder_format = Format + +deck-builder_games = Games: {$games} + +deck-builder_hash = Tournament hash + +deck-builder_identity = Identity + +deck-builder_illegal = illegal + +deck-builder_import = Import + +deck-builder_import-button = Import deck + +deck-builder_import-placeholder = NRDB ID + +deck-builder_import-title = Enter a Public NRDB Deck ID or URL + +deck-builder_influence = Influence + +deck-builder_legal = legal + +deck-builder_loading-msg = Loading deck collection... + +deck-builder_lost = Lost: {$lost} + +deck-builder_max = maximum + +deck-builder_min = minimum + +deck-builder_min-deck-size = (minimum {$cnt}) + +deck-builder_new-corp = New Corp deck + +deck-builder_new-deck = New Deck + +deck-builder_new-runner = New Runner deck + +deck-builder_notes = Notes + +deck-builder_reset = Reset + +deck-builder_save = Save + +deck-builder_why = Why? + +deck-builder_won = Won: {$won} ({NUMBER($percent, style: "percent")}) + +diagrams_run-timing_approach = 6.9.2: Approach Ice Phase + +diagrams_run-timing_approach-a = You are now approaching the ice. Approach events resolve + +diagrams_run-timing_approach-b = Paid Ability Window. Corp may rez the approached ice, or non-ice cards, during this window + +diagrams_run-timing_approach-c = If approached ice is rezzed, continue to encounter phase (6.9.3) + +diagrams_run-timing_approach-d = Otherwise, proceed to the movement phase (6.9.4) + +diagrams_run-timing_disclaimer = This structure has been simplified for clarity. For complete rules, see the Null Signal Games website. + +diagrams_run-timing_encounter = 6.9.3: Encounter Ice Phase + +diagrams_run-timing_encounter-a = You are now encountering this ice. Encounter events resolve + +diagrams_run-timing_encounter-b = Paid ability window. Encountered ice may be interfaced during this window + +diagrams_run-timing_encounter-c = If there are unbroken subroutines to resolve, the corporation resolves the topmost unbroken subroutine. If they do, repeat this step + +diagrams_run-timing_encounter-d = The encounter is complete. Proceed to the movement phase (6.9.4) + +diagrams_run-timing_header = Timing Structure of a Run + +diagrams_run-timing_initiation = 6.9.1: Initiation Phase + +diagrams_run-timing_initiation-a = Runner declares a server + +diagrams_run-timing_initiation-b = Runner gains Bad Publicity credits + +diagrams_run-timing_initiation-c = Run formally begins - Run events fire + +diagrams_run-timing_initiation-d = Proceed to the outermost ice, if applicable, and begin the approach phase (6.9.2) + +diagrams_run-timing_initiation-e = Otherwise, proceed to the movement phase (6.9.4) + +diagrams_run-timing_movement = 6.9.4: Movement Phase + +diagrams_run-timing_movement-a = If you were encountering or approaching an ice, you pass it. Pass-Ice events resolve + +diagrams_run-timing_movement-b = If there are no more ice inwards from the passed ice, 'when you pass all ice on the server' events resolve + +diagrams_run-timing_movement-c = Paid ability window + +diagrams_run-timing_movement-d = The runner may jack out. If they do, proceed to the run ends phase (6.9.6) + +diagrams_run-timing_movement-e = The runner proceeds to the next position inwards, if applicable + +diagrams_run-timing_movement-f = Paid ability window. The corporation may rez non-ice cards + +diagrams_run-timing_movement-g = If you are approaching another ice, return to the approach ice phase (6.9.2) + +diagrams_run-timing_movement-h = The runner approaches the attacked server. Approach events resolve + +diagrams_run-timing_movement-i = Continue to the success phase (6.9.5) + +diagrams_run-timing_run-ends = 6.9.6: Run Ends Phase + +diagrams_run-timing_run-ends-a = Any open priority windows complete or are closed + +diagrams_run-timing_run-ends-b = The runner loses any unspent bad publicity credits + +diagrams_run-timing_run-ends-c = If the success phase was not reached and the server still exists, the run becomes unsuccessful + +diagrams_run-timing_run-ends-d = The run ends. Run ends events resolve + +diagrams_run-timing_success = 6.9.5: Success Phase + +diagrams_run-timing_success-a = The run is declared successful. Successful run events are met + +diagrams_run-timing_success-b = The runner breaches the attacked server + +diagrams_run-timing_success-c = The success phase is complete. Continue to the run ends phase (6.9.6) + +diagrams_turn_corp-action-phase = 5.6.2: Action Phase + +diagrams_turn_corp-action-phase-a = Paid ability window. Corp may rez non-ice cards or score agendas during this window + +diagrams_turn_corp-action-phase-b = If the corporation has unspent [Clicks], they take an action + +diagrams_turn_corp-action-phase-c = If an action occured, return to (a) + +diagrams_turn_corp-action-phase-d = The action phase is complete. Proceed to the discard phase (5.6.3) + +diagrams_turn_corp-discard-phase = 5.6.3: Discard phase + +diagrams_turn_corp-discard-phase-a = The corporation discards to maximum hand size, if applicable + +diagrams_turn_corp-discard-phase-b = Paid ability window. Corp may rez non-ice cards during this window + +diagrams_turn_corp-discard-phase-c = If the corporation has any [Clicks] remaining, they lose those [Clicks] + +diagrams_turn_corp-discard-phase-d = The Corporations turn formally ends. Turn end triggers resolve + +diagrams_turn_corp-discard-phase-e = Proceed to the Runner turn + +diagrams_turn_corp-draw-phase = 5.6.1: Draw Phase + +diagrams_turn_corp-draw-phase-a = Corporation gains allotted clicks (default: [click][click][click]) + +diagrams_turn_corp-draw-phase-b = Paid ability window. Corp may rez non-ice cards or score agendas during this window + +diagrams_turn_corp-draw-phase-c = Corporation recurring credits refill + +diagrams_turn_corp-draw-phase-d = The turn formally begins. Turn begins events resolve + +diagrams_turn_corp-draw-phase-e = The corporation performs their mandatory draw + +diagrams_turn_corp-draw-phase-f = Proceed to the action phase (5.6.2) + +diagrams_turn_corp-turn = Corporation Turn + +diagrams_turn_runner-action-phase = 5.7.1: Action Phase + +diagrams_turn_runner-action-phase-a = Runner gains allotted clicks (default: [click][click][click][click]) + +diagrams_turn_runner-action-phase-b = Paid ability window. Corp may rez non-ice cards + +diagrams_turn_runner-action-phase-c = Runner recurring credits refill + +diagrams_turn_runner-action-phase-d = The turn formally begins. Turn begins events resolve + +diagrams_turn_runner-action-phase-e = Paid ability window. Corp may rez non-ice cards + +diagrams_turn_runner-action-phase-f = If the Runner has unspent [Clicks], they take an action + +diagrams_turn_runner-action-phase-g = If an action occured, return to (e) + +diagrams_turn_runner-action-phase-h = The action phase is complete. Proceed to the discard phase (5.7.2) + +diagrams_turn_runner-discard-phase = 5.7.2: Discard Phase + +diagrams_turn_runner-discard-phase-a = The runner discards to maximum handsize, if applicable + +diagrams_turn_runner-discard-phase-b = Paid ability window. Corp may rez non-ice cards + +diagrams_turn_runner-discard-phase-c = If the runner has any [Clicks] remaining, they lose those [Clicks] + +diagrams_turn_runner-discard-phase-d = The Runners turn formally ends. Turn end triggers resolve + +diagrams_turn_runner-discard-phase-e = Proceed to the Corporation turn + +diagrams_turn_runner-turn = Runner Turn + +faction_name = {$faction -> + [adam] Adam + [all] All + [anarch] Anarch + [any-faction] Any Faction + [apex] Apex + [criminal] Criminal + [haas-bioroid] Haas-Bioroid + [jinteki] Jinteki + [nbn] NBN + [neutral] Neutral + [shaper] Shaper + [sunny-lebeau] Sunny Lebeau + [weyland-consortium] Weyland Consortium + *[other] Unknown faction ({$faction}) +} + +format_name = {$format -> + [all] All + [any-format] Any Format + [casual] Casual + [classic] Classic + [core-experience] Core Experience + [eternal] Eternal + [neo] Neo + [preconstructed] Preconstructed + [snapshot] Snapshot + [snapshot-plus] Snapshot Plus + [socr] SOCR + [standard] Standard + [startup] Startup + [sunset] Sunset + [system-gateway] System Gateway + [throwback] Throwback + *[other] Unknown format ({$format}) +} + +game_abilities = Abilities + +game_actions = Actions + +game_agenda-count = {$agenda-point -> + [one] {$agenda-point} Agenda Point + *[other] {$agenda-point} Agenda Points +} + +game_agenda-count-with-req = {$agenda-point -> + [one] {$agenda-point} Agenda Point + *[other] {$agenda-point} Agenda Points +} ({$agenda-point-req} required) + +game_approach-ice = Approach ice + +game_archives = Archives{"\u00A0"}({$faceup} ↑ {$facedown} ↓) + +game_attempt-reconnect = Attempt reconnect + +game_auto-pass = Auto-pass priority + +game_bad-pub-count = {$base} Bad Publicity + +game_bad-pub-count-additional = {$base} + {$additional} Bad Publicity + +game_beat-trace = Beat Trace + +game_brain-damage = {$dmg} Core Damage + +game_breach-server = Breach server + +game_card = Card + +game_card-count = {$cnt -> + [one] {$size} card + *[other] {$size} cards +} + +game_click-count = {$click -> + [one] {$click} click + *[other] {$click} clicks +} + +game_close = Close + +game_close-shuffle = Close & Shuffle + +game_concede = Concede + +game_continue = Continue + +game_continue-to = Continue to {$phase} + +game_corp-view = Corp View + +game_credit-count = {$credit -> + [one] {$credit} Credit + *[other] {$credit} Credits +} + +game_credit-count-with-run-credits = {$credit -> + [one] {$credit} Credit + *[other] {$credit} Credits +} ({$run-credit} for run) + +game_credits = credits + +game_current = Current + +game_current-phase = Current phase + +game_draw = Draw + +game_encounter-ice = Encounter ice + +game_end-turn = End Turn + +game_error = Internal Server Error. Please type /bug in the chat and follow the instructions. + +game_face-down-count = {$total -> + [one] {$total} card, {$facedown} face-down. + *[other] {$total} cards, {$facedown} face-down. +} + +game_fire-unbroken = Fire unbroken subroutines + +game_gain-credit = Gain Credit + +game_game-start = Game start: {$timestamp} + +game_grip = Grip + +game_heap = Heap ({$cnt}) + +game_hq = HQ + +game_inactivity = Game closed due to inactivity + +game_indicate-action = Indicate paid ability + +game_initiation = Initiation + +game_jack-out = Jack Out + +game_keep = Keep + +game_last-revealed = Last Revealed + +game_leave = Leave Game + +game_leave-replay = Leave Replay + +game_let-subs-fire = Let unbroken subroutines fire + +game_link-strength = Link Strength + +game_lost-connection = Lost connection to server. Reconnecting. + +game_mandatory-draw = Mandatory Draw + +game_max-hand = {$total} Max hand size + +game_minutes = m: + +game_movement = Movement + +game_mu-count = {$unused} of {$available} MU unused + +game_mulligan = Mulligan + +game_mute = Mute spectators + +game_no-current-run = No current run + +game_no-further = No further actions + +game_ok = OK + +game_play-area = Play Area + +game_prompt = {$msg -> + [advance] advance + [archives] Archives + [derez] derez + [expend] Expend + [hq] HQ + [new-remote] New Remote + [r-d] R&D + [rez] rez + [score] score + [server-1] Server 1 + [server-10] Server 10 + [server-2] Server 2 + [server-3] Server 3 + [server-4] Server 4 + [server-5] Server 5 + [server-6] Server 6 + [server-7] Server 7 + [server-8] Server 8 + [server-9] Server 9 + [trash] trash + *[unknown] Unknown game prompt ({$msg}) +} + +game_purge = Purge + +game_reconnected-to-server = Reconnected to server + +game_remove-tag = Remove Tag + +game_reveal-my-hand = Reveal My Hand + +game_rez = Rez + +game_rez-all = Rez All + +game_rfg = Removed from the game + +game_rnd = R&D + +game_run = Run + +game_run-ends = Run ends + +game_runner-view = Runner View + +game_scored-area = Scored Area + +game_seconds = s + +game_seconds-remaining = s remaining + +game_server = Server {$num} + +game_set-aside = Set aside + +game_show = Show + +game_show-decklists = Show/Hide decklists + +game_shuffle = Shuffle + +game_spec-count = {$cnt -> + [one] Spectator + *[other] {$cnt} Spectators +} + +game_spec-view = Spectator View + +game_special-mu-count = {$unused} of {$available} {$mu-type} MU unused + +game_stack = Stack + +game_start = Start Game + +game_start-turn = Start Turn + +game_stop-auto-pass = Stop auto-passing priority + +game_subs = Subroutines + +game_success = Success + +game_tag-count = {$base -> + [one] {$base} Tag + *[other] {$base} Tags +} + +game_tag-count-additional = {$total -> + [one] {$base} + {$additional} Tag + *[other] {$base} + {$additional} Tags +} + +game_take-clicks = Take Clicks + +game_time-taken = Time taken: {$time -> + [one] {$time} minute + *[other] {$time} minutes +} + +game_timeout-soon = Game will time out within 30 seconds for inactivity + +game_trace = Trace + +game_trash-like-cards = Offer to trash like cards + +game_trash-resource = Trash Resource + +game_unbeatable = Make unbeatable + +game_unimplemented = Unimplemented + +game_unknown-phase = Unknown phase + +game_unmute = Unmute spectators + +game_win-claimed = {$winner} ({$side}) wins by claim on turn {$turn} + +game_win-conceded = {$winner} ({$side}) wins by concession on turn {$turn} + +game_win-decked = {$winner} ({$side}) wins due to the Corp being decked on turn {$turn} + +game_win-flatlined = {$winner} ({$side}) wins by flatline on turn {$turn} + +game_win-other = {$winner} ({$side}) wins by {$reason} on turn {$turn} + +game_win-points = {$winner} ({$side}) wins by scoring agenda points on turn {$turn} + +ingame-settings_alt-art = Alt arts + +ingame-settings_board-overlap = Board overlap + +ingame-settings_card-backs = Card backs + +ingame-settings_card-image = Card Image + +ingame-settings_card-images = Card images + +ingame-settings_card-sorting = Sorting + +ingame-settings_card-stacking = Card settings + +ingame-settings_card-text = Card Text + +ingame-settings_display-encounter-info = Always display encounter info + +ingame-settings_game-settings = Gameplay settings + +ingame-settings_ghost-trojans = Display hosted trojans in rig + +ingame-settings_high-res = Enable high resolution card images + +ingame-settings_label-faceup-cards = Label face up cards + +ingame-settings_label-unrezzed-cards = Label unrezzed cards + +ingame-settings_log-timestamps = Log timestamps + +ingame-settings_log-timestamps-toggle = Show log timestamps + +ingame-settings_pass-on-rez = Pass priority when rezzing ice + +ingame-settings_preview-zoom = Card preview zoom + +ingame-settings_runner-board-order = Runner board order + +ingame-settings_runner-classic = Classic + +ingame-settings_runner-reverse = Reversed + +ingame-settings_save = Save + +ingame-settings_show-alt = Show alternate card arts + +ingame-settings_sides-overlap = Runner and Corp may overlap + +ingame-settings_sort-archives = Sort Archives + +ingame-settings_sort-heap = Sort Heap + +ingame-settings_stack-cards = Stack cards + +lobby_aborted = Connection aborted + +lobby_api-access = Allow API access to game information + +lobby_api-access-details = This allows access to information about your game to 3rd party extensions. Requires an API Key to be created in Settings. + +lobby_api-requires-key = (Requires an API Key in Settings) + +lobby_as-corp = As Corp + +lobby_as-runner = As Runner + +lobby_both-perspective = Both + +lobby_cancel = Cancel + +lobby_chat = Chat + +lobby_closed-msg = Game lobby closed due to inactivity + +lobby_completion-rate = Game Completion Rate + +lobby_corp-perspective = Corp Perspective + +lobby_create = Create + +lobby_deck-selected = Deck selected + +lobby_default-game-format = Default game format + +lobby_delete = Delete Game + +lobby_filter = Filter + +lobby_format = Format + +lobby_game-count = {$cnt -> + [one] {$cnt} Game + *[other] {$cnt} Games +} + +lobby_game-count-filtered = {$cnt -> + [one] {$cnt} Game (filtered) + *[other] {$cnt} Games (filtered) +} + +lobby_gateway-format = {$format -> + [beginner] Beginner + [beginner-info] This lobby is using the System Gateway beginner decks for the Corporation and Runner. These decks are recommended for your first games. Games are played to 6 agenda points. + [beginner-ul] System Gateway - Beginner Teaching Decks + [constructed] Constructed + [intermediate] Intermediate + [intermediate-info] This lobby is using the System Gateway intermediate decks for the Corporation and Runner. These decks have slightly more range than the beginner decks. Games are played to 7 agenda points. + [intermediate-ul] System Gateway - Intermediate Teaching Decks + *[unknown] Unknown Gateway Format ({$format}) +} + +lobby_hidden = Make players' hidden information visible to spectators + +lobby_hidden-details = This will reveal both players' hidden information to ALL spectators of your game, including hand and face-down cards. + +lobby_hidden-password = We recommend using a password to prevent strangers from spoiling the game. + +lobby_invalid-password = Invalid password + +lobby_join = Join + +lobby_leave = Leave + +lobby_load-replay = Load replay + +lobby_new-game = New game + +lobby_no-games = No games + +lobby_not-allowed = Not allowed + +lobby_open-decklists = Open Decklists + +lobby_open-decklists-b = (open decklists) + +lobby_options = Options + +lobby_password = Password + +lobby_password-error = Please fill a password. + +lobby_password-for = Password for + +lobby_password-protected = Password protected + +lobby_players = Players + +lobby_private = PRIVATE + +lobby_rejoin = Rejoin + +lobby_reload = Reload list + +lobby_replay-invalid-file = Select a valid replay file. + +lobby_replay-link-error = Replay link invalid. + +lobby_reset = Reset Game Name + +lobby_runner-perspective = Runner Perspective + +lobby_save-replay = Save replay + +lobby_save-replay-beta = BETA Functionality: Be aware that we might need to reset the saved replays, so make sure to download games you want to keep. Also, please keep in mind that we might need to do future changes to the site that might make replays incompatible. + +lobby_save-replay-details = This will save a replay file of this match with open information (e.g. open cards in hand). The file is available only after the game is finished. + +lobby_save-replay-unshared = Only your latest 15 unshared games will be kept, so make sure to either download or share the match afterwards. + +lobby_select-deck = Select Deck + +lobby_select-error = Cannot select that deck + +lobby_select-title = Select your deck + +lobby_side = Side + +lobby_singleton = Singleton + +lobby_singleton-b = (singleton) + +lobby_singleton-details = This will restrict decklists to only those which do not contain any duplicate cards. It is recommended you use the listed singleton-based identities. + +lobby_singleton-example = 1) Nova Initiumia: Catalyst & Impetus 2) Ampere: Cybernetics For Anyone + +lobby_singleton-restriction = This lobby is running in singleton mode. This means decklists will be restricted to only those which do not contain any duplicate cards. + +lobby_spectator-count = {$cnt -> + [one] {$cnt} Spectator + *[other] {$cnt} Spectators +} + +lobby_spectators = Allow spectators + +lobby_start = Start + +lobby_start-replay = Start replay + +lobby_swap = Swap sides + +lobby_timed-game = Start with timer + +lobby_timed-game-details = Timer is only for convenience: the game will not stop when timer runs out. + +lobby_timer-length = Timer length (minutes) + +lobby_title = Title + +lobby_title-error = Please fill a game title. + +lobby_too-little-data = Too little data + +lobby_type = {$type -> + [angel-arena] Angel Arena + [casual] Casual + [competitive] Competitive + [tournament] Tournament + *[unknown] Unknown lobby type +} + +lobby_waiting = Waiting players deck selection + +lobby_watch = Watch + +log_annotating = Annotating + +log_game-log = Game Log + +log_remote-annotations-fail = Could not get remote annotations. + +log_run-timing = Run Timing + +log_settings = Settings + +log_shared = Shared Annotations + +log_turn-timing = Turn Timing + +menu_admin = {nav_admin} + +menu_donor = Donor + +menu_logout = Jack out + +menu_moderator = Moderator + +menu_settings = {nav_settings} + +nav_about = About + +nav_admin = Admin + +nav_cards = Cards + +nav_chat = Chat + +nav_deck-builder = Deck Builder + +nav_features = Features + +nav_game-count = {$cnt -> + [one] {$cnt} Game + *[other] {$cnt} Games +} + +nav_help = Help + +nav_play = Play + +nav_settings = Settings + +nav_stats = Stats + +nav_tournaments = Tournaments + +nav_users = Users + +nav_welcome = Welcome + +preconstructed_worlds-2012-a = Worlds 2012: Ben Marsh (C) vs. Jeremy Zwirn (R) + +preconstructed_worlds-2012-a-tag = Ben Marsh (C) vs. Jeremy Zwirn (R) + +preconstructed_worlds-2012-a-ul = Worlds 2012: Weyland vs. Criminal + +preconstructed_worlds-2012-b = Worlds 2012: Jeremy Zwirn (C) vs. Ben Marsh (R) + +preconstructed_worlds-2012-b-tag = Jeremy Zwirn (C) vs. Ben Marsh (R) + +preconstructed_worlds-2012-b-ul = Worlds 2012: Haas-Bioroid vs. Criminal + +preconstructed_worlds-2012-info = Worlds 2012 was played with (up to 3 copies of) the Core Set as the only legal product. Jeremy Zwirn (Building a Better World, Gabriel Santiago) took first place against Ben Marsh (Engineering the Future, Gabriel Santiago) in the first ever Netrunner World Championship. + +preconstructed_worlds-2013-a = Worlds 2013: Jens Erickson (C) vs. Andrew Veen (R) + +preconstructed_worlds-2013-a-tag = Jens Erickson (C) vs. Andrew Veen (R) + +preconstructed_worlds-2013-a-ul = Worlds 2013: HB FastAdv vs. Shaper Katman + +preconstructed_worlds-2013-b = Worlds 2013: Andrew Veen (C) vs. Jens Erickson (R) + +preconstructed_worlds-2013-b-tag = Andrew Veen (C) vs. Jens Erickson (R) + +preconstructed_worlds-2013-b-ul = Worlds 2013: NBN Fast Adv vs. Andy Sucker + +preconstructed_worlds-2013-info = 166 players attended worlds in 2013. The tournament was held in Minneapolis, MN, USA, and consisted of 6 swiss rounds into a top 32 cut. The legal cardpool consisted of cards up to Opening Moves. + +preconstructed_worlds-2014-a = Worlds 2014: Dan D'Argenio (C) vs. Minh Tran (R) + +preconstructed_worlds-2014-a-tag = Dan D'Argenio (C) vs. Minh Tran (R) + +preconstructed_worlds-2014-a-ul = Worlds 2014: Honor and Perfection vs. Andromedium + +preconstructed_worlds-2014-b = Worlds 2014: Minh Tran (C) vs. Dan D'Argenio (R) + +preconstructed_worlds-2014-b-tag = Minh Tran (C) vs. Dan D'Argenio (R) + +preconstructed_worlds-2014-b-ul = Worlds 2014: Personal Evolution vs. Daily QT Andy + +preconstructed_worlds-2014-info = 238 players attended worlds in 2014. The tournament was held in Minneapolis, MN, USA, and consisted of 7 swiss rounds into a top 16 cut. The legal cardpool consisted of cards up to Up and Over. + +preconstructed_worlds-2015-a = Worlds 2015: Dan D'Argenio (C) vs. Timmy Wong (R) + +preconstructed_worlds-2015-a-tag = Dan D'Argenio (C) vs. Timmy Wong (R) + +preconstructed_worlds-2015-a-ul = Worlds 2015: Foodcoatshop vs. The Morning After + +preconstructed_worlds-2015-b = Worlds 2015: Timmy Wong (C) vs. Dan D'Argenio (R) + +preconstructed_worlds-2015-b-tag = Timmy Wong (C) vs. Dan D'Argenio (R) + +preconstructed_worlds-2015-b-ul = Worlds 2015: Yellow Shell vs. Radisson Cheese Plate + +preconstructed_worlds-2015-info = 269 players attended worlds in 2015. The tournament was held in Minneapolis, MN, USA, and consisted of 8 swiss rounds into a top 16 cut. The legal cardpool consisted of cards up to Data and Destiny. + +preconstructed_worlds-2016-a = Worlds 2016: Chris Dyer (C) vs. Benjamin Ni (R) + +preconstructed_worlds-2016-a-tag = Chris Dyer (C) vs. Benjamin Ni (R) + +preconstructed_worlds-2016-a-ul = Worlds 2016: Snekbite vs. Minh MaxX++ + +preconstructed_worlds-2016-b = Worlds 2016: Benjamin Ni (R) vs. Chris Dyer (C) + +preconstructed_worlds-2016-b-tag = Benjamin Ni (R) vs. Chris Dyer (C) + +preconstructed_worlds-2016-b-ul = Worlds 2016: Fiery Info vs. Papa Smurf + +preconstructed_worlds-2016-info = 278 players attended worlds in 2016. The tournament was held in Minneapolis, MN, USA, and consisted of 9 swiss rounds into a top 16 cut. The legal cardpool consisted of cards up to Escalation. + +preconstructed_worlds-2017-a = Worlds 2017: Jess Horig (C) vs. Grey Tongue (R) + +preconstructed_worlds-2017-a-tag = Jess Horig (C) vs. Grey Tongue (R) + +preconstructed_worlds-2017-a-ul = Worlds 2017: Stinson Reversed CI vs. Aesops Hayley + +preconstructed_worlds-2017-b = Worlds 2017: Grey Tongue (C) vs. Jess Horig (R) + +preconstructed_worlds-2017-b-tag = Grey Tongue (C) vs. Jess Horig (R) + +preconstructed_worlds-2017-b-ul = Worlds 2017: No-Show Rewiring CI vs. Laguna Lock Hayley + +preconstructed_worlds-2017-info = 233 players attended worlds in 2017. The tournament was held in Minneapolis, MN, USA, and consisted of 8(?) swiss rounds into a top 16 cut. The legal cardpool consisted of cards up to the Revised Core set. + +preconstructed_worlds-2018-a = Worlds 2018: Joe Schupp (C) vs. Chris Dyer (R) + +preconstructed_worlds-2018-a-tag = Joe Schupp (C) vs. Chris Dyer (R) + +preconstructed_worlds-2018-a-ul = Worlds 2018: AMERICA CtM vs. Gooseberry MaxX + +preconstructed_worlds-2018-b = Worlds 2018: Chris Dyer (C) vs. Joe Schupp (R) + +preconstructed_worlds-2018-b-tag = Chris Dyer (C) vs. Joe Schupp (R) + +preconstructed_worlds-2018-b-ul = Worlds 2018: Trust the Process vs. Dan D'Argenio KoS Val + +preconstructed_worlds-2018-info = 403(!) players attended worlds in 2018. This is the final worlds championship to be run by FFG. The tournament was held in Minneapolis, MN, USA, and consisted of 9(?) swiss rounds into a top 16 cut. The legal cardpool consisted of cards up to Reign and Reverie + +preconstructed_worlds-2019-a = Worlds 2019: Pinsel (C) vs. Testrunning (R) + +preconstructed_worlds-2019-a-tag = Pinsel (C) vs. Testrunning (R) + +preconstructed_worlds-2019-a-ul = Worlds 2019: Fully dedicated to efficiency vs. Trash Panda + +preconstructed_worlds-2019-b = Worlds 2019: Testrunning (C) vs. Pinsel (R) + +preconstructed_worlds-2019-b-tag = Testrunning (C) vs. Pinsel (R) + +preconstructed_worlds-2019-b-ul = Worlds 2019: 2 Grid for 2 Place vs. Trash Panda + +preconstructed_worlds-2019-info = 256 players played in the first ever Project NISEI Netrunner World Championship in 2019. This tournament was held in Rotterdam, NL, and consisted of 9 swiss rounds into a top 16 cut. The legal cardpool consisted of cards up to the Uprising Booster Pack + +preconstructed_worlds-2020-a = Worlds 2020: Limes (C) vs. tf34 (R) + +preconstructed_worlds-2020-a-tag = Limes (C) vs. tf34 (R) + +preconstructed_worlds-2020-a-ul = Worlds 2020: I don't like this deck vs. Engolo Freedom + +preconstructed_worlds-2020-b = Worlds 2020: tf34 (R) vs. Limes (C) + +preconstructed_worlds-2020-b-tag = tf34 (R) vs. Limes (C) + +preconstructed_worlds-2020-b-ul = Worlds 2020: Malia CTM vs. Imp-pressive Hoshiko + +preconstructed_worlds-2020-info = 294 players played in the first ever online world championship for Netrunner, run by Project NISEI 2020. Due to travel restrictions at the start of the COVID-19 pandemic, this tournament was held online via Jinteki.net, and consisted of 8 swiss rounds on two distinct day-ones, into a top 16 cut. The legal cardpool consisted of cards up to Uprising. + +preconstructed_worlds-2021-a = Worlds 2021: Patrick Gower (C) vs. Jonas (R) + +preconstructed_worlds-2021-a-tag = Patrick Gower (C) vs. Jonas (R) + +preconstructed_worlds-2021-a-ul = Worlds 2021: 44 Card PD vs. Watch Me Drip, Watch Me Maemi + +preconstructed_worlds-2021-b = Worlds 2021: Jonas (C) vs. Patrick Gower (R) + +preconstructed_worlds-2021-b-tag = Jonas (C) vs. Patrick Gower (R) + +preconstructed_worlds-2021-b-ul = Worlds 2021: Is Gagarin Good? vs. Medium to Large Maxx + +preconstructed_worlds-2021-info = 201 players played in the second online world championship for Netrunner, run by Project NISEI in 2021. Due to the ongoing disruption caused by the COVID-19 pandemic, this tournament was held online via Jinteki.net, and consisted of 8 swiss rounds on two distinct day-ones, into a top 16 cut. The legal cardpool consisted of cards up to System Gateway. + +preconstructed_worlds-2022-a = Worlds 2022: William Huang (C) vs. skry (R) + +preconstructed_worlds-2022-a-tag = William Huang (C) vs. skry (R) + +preconstructed_worlds-2022-a-ul = Worlds 2022: SNACS vs. Liberté, Égalité, Humidité + +preconstructed_worlds-2022-b = Worlds 2022: skry (C) vs. William Huang (R) + +preconstructed_worlds-2022-b-tag = skry (C) vs. William Huang (R) + +preconstructed_worlds-2022-b-ul = Worlds 2022: Dies to Doom Blade vs. ApocoLat + +preconstructed_worlds-2022-info = 158 players played in the first world championship run by Null Signal Games (formerly Project NISEI), which was the first Netrunner world championship to be run in-person since the start of the COVID-19 pandemic. The tournament was held in Toronto, Canada, and consisted of 7 rounds into a top 16 cut. The legal cardpool consisted of cards up to Midnight Sun. + +preconstructed_worlds-2023-a = Worlds 2023: William Huang (C) vs. cableCarnage (R) + +preconstructed_worlds-2023-a-tag = William Huang (C) vs. cableCarnage (R) + +preconstructed_worlds-2023-a-ul = Worlds 2023: The Worlds Grind vs. sableCarnage + +preconstructed_worlds-2023-b = Worlds 2023: cableCarnage (C) vs. William Huang (R) + +preconstructed_worlds-2023-b-tag = cableCarnage (C) vs. William Huang (R) + +preconstructed_worlds-2023-b-ul = Worlds 2023: tableCarnage vs. You *do* always come back! + +preconstructed_worlds-2023-info = 254 players played in the second Netrunner world championship run by Null Signal Games. The tournament was held in Barcelona, Spain, and consisted of 9 rounds into a top 16 cut. The legal cardpool consisted of cards up to The Automata Initiative. + +pronouns = {$pronoun -> + [any] Any + [blank] [blank] + [ey] Ey/em + [faefaer] Fae/Faer + [he] He/him + [heit] He/it + [heshe] He/She/they + [hethey] He/they + [it] It + [myodb] Prefer not to say + [ne] Ne/nem + *[none] Unspecified + [she] She/her + [sheit] She/it + [shethey] She/they + [they] They/them + [ve] Ve/ver + [xe] Xe/xem + [xi] Xi/xir + [zehir] Ze/hir + [zezir] Ze/zir +} + +set_name = {$name -> + [a23-seconds] 23 Seconds + [a-study-in-static] A Study in Static + [all] All + [all-that-remains] All That Remains + [alt-art] Alt Art + [alternate] Alternate + [ashes-cycle] Ashes Cycle + [blood-and-water] Blood and Water + [blood-money] Blood Money + [borealis-cycle] Borealis Cycle + [breaker-bay] Breaker Bay + [business-first] Business First + [championship-2019] Championship 2019 + [championship-2020] Championship 2020 + [chrome-city] Chrome City + [core-set] Core Set + [council-of-the-crest] Council of the Crest + [creation-and-control] Creation and Control + [crimson-dust] Crimson Dust + [cyber-exodus] Cyber Exodus + [daedalus-complex] Daedalus Complex + [data-and-destiny] Data and Destiny + [democracy-and-dogma] Democracy and Dogma + [double-time] Double Time + [down-the-white-nile] Down the White Nile + [downfall] Downfall + [draft] Draft + [draft-cycle] Draft Cycle + [earth-s-scion] Earth's Scion + [escalation] Escalation + [fear-and-loathing] Fear and Loathing + [fear-the-masses] Fear the Masses + [first-contact] First Contact + [flashpoint-cycle] Flashpoint Cycle + [free-mars] Free Mars + [future-proof] Future Proof + [genesis-cycle] Genesis Cycle + [gnk-2019] GNK 2019 + [honor-and-profit] Honor and Profit + [humanity-s-shadow] Humanity's Shadow + [intervention] Intervention + [kala-ghoda] Kala Ghoda + [kampala-ascendent] Kampala Ascendent + [kitara-cycle] Kitara Cycle + [kysra-alt-arts] Kysra Alt Arts + [liberation-cycle] Liberation Cycle + [lunar-cycle] Lunar Cycle + [magnum-opus] Magnum Opus + [magnum-opus-reprint] Magnum Opus Reprint + [mala-tempora] Mala Tempora + [martial-law] Martial Law + [midnight-sun] Midnight Sun + [midnight-sun-booster-pack] Midnight Sun Booster Pack + [mumbad-cycle] Mumbad Cycle + [napd-multiplayer] NAPD Multiplayer + [ntscape-navigator-alt-arts] Ntscape Navigator Alt Arts + [old-hollywood] Old Hollywood + [opening-moves] Opening Moves + [order-and-chaos] Order and Chaos + [parhelion] Parhelion + [plural-and-miniplural-alt-arts] Plural and MiniPlural Alt Arts + [previous-versions] Previous Versions + [quorum] Quorum + [rebellion-without-rehearsal] Rebellion Without Rehearsal + [red-sand-cycle] Red Sand Cycle + [reign-and-reverie] Reign and Reverie + [revised-core-set] Revised Core Set + [salsette-island] Salsette Island + [salvaged-memories] Salvaged Memories + [sansan-cycle] SanSan Cycle + [second-thoughts] Second Thoughts + [signed-championship-2020] Signed Championship 2020 + [sovereign-sight] Sovereign Sight + [spin-cycle] Spin Cycle + [station-one] Station One + [system-core-2019] System Core 2019 + [system-gateway] System Gateway + [system-update-2021] System Update 2021 + [terminal-directive-campaign] Terminal Directive Campaign + [terminal-directive-cards] Terminal Directive Cards + [terminal-directive-cycle] Terminal Directive Cycle + [the-automata-initiative] The Automata Initiative + [the-devil-and-the-dragon] The Devil and the Dragon + [the-liberated-mind] The Liberated Mind + [the-source] The Source + [the-spaces-between] The Spaces Between + [the-underway] The Underway + [the-universe-of-tomorrow] The Universe of Tomorrow + [the-valley] The Valley + [trace-amount] Trace Amount + [true-colors] True Colors + [unreleased] Unreleased + [up-and-over] Up and Over + [uprising] Uprising + [uprising-booster-pack] Uprising Booster Pack + [upstalk] Upstalk + [what-lies-ahead] What Lies Ahead + [whispers-in-nalubaale] Whispers in Nalubaale + [world-champion-2015] World Champion 2015 + [world-champion-2016] World Champion 2016 + [world-champion-2017] World Champion 2017 + *[unknown] Unknown Set {$name} +} + +settings_alt-art = Alt arts + +settings_always = Always + +settings_api-keys = API Keys + +settings_avatar = Avatar + +settings_background = Game board background + +settings_bespoke-sounds = {$sound -> + [archer] Archer + [end-of-the-line] End of the Line + [harmonics] Harmonics Suite (Bloop, Echo, Pulse, Wave) + [header] Card-Specific Sounds + *[unknown] Unknown bespoke sound ({$sound}) +} + +settings_bg = {$slug -> + [apex] Apex + [custom] Custom BG (input URL below) + [find-the-truth] Find The Truth + [freelancer] Freelancer + [monochrome] Monochrome + [mushin-no-shin] Mushin No Shin + [push-your-luck] Push Your Luck + [rumor-mill] Rumor Mill + [the-root] The Root + [traffic-jam] Traffic Jam + *[worlds2020] Worlds 2020 +} + +settings_block = Block user + +settings_blocked = Blocked users + +settings_cancel = Cancel + +settings_card-backs = Card backs + +settings_card-iamge = Card Image + +settings_card-images = Card images + +settings_card-preview-zoom = Card preview zoom + +settings_card-text = Card Text + +settings_change-avatar = Change on gravatar.com + +settings_change-email = Change email + +settings_comp-only = Competitive Lobby Only + +settings_connection = Connection + +settings_create-api-key = Create API Key + +settings_current-email = Current email + +settings_deck-stats = Deck statistics + +settings_delete-api-key = Delete + +settings_desired-email = Desired email + +settings_disable-websockets = Disable websockets - requires browser refresh after clicking Update Profile [Not Recommended!] + +settings_display-encounter-info = Always display encounter info + +settings_email = Email + +settings_email-placeholder = Email address + +settings_email-title = Change email address + +settings_enable-game-sounds = Enable game sounds + +settings_enable-lobby-sounds = Enable lobby sounds + +settings_enter-valid = Please enter a valid email address + +settings_ffg = FFG + +settings_game-stats = Game Win/Lose statistics + +settings_get-log-top = Get current log top + +settings_get-log-width = Get current log width + +settings_ghost-trojans = Display ghosts for hosted programs + +settings_high-res = Enable high-resolution card images + +settings_invalid-email = No account with that email address exists + +settings_invalid-password = Invalid login or password + +settings_language = Language + +settings_layout-options = Layout options + +settings_log-player-highlight = Log player highlight + +settings_log-player-highlight-none = None + +settings_log-player-highlight-red-blue = Corp: Blue / Runner: Red + +settings_log-size = Log size + +settings_log-timestamps = Log timestamps + +settings_none = None + +settings_nsg = NSG + +settings_pin-zoom = Keep zoomed cards on screen + +settings_player-stats-icons = Use icons for player stats + +settings_pronouns = Pronouns + +settings_reset = Reset All to Official Art + +settings_runner-classic = Runner rig layout is classic jnet (Top to bottom: Programs, Hardware, Resources) + +settings_runner-layout = Runner layout from Corp perspective + +settings_runner-reverse = Runner rig layout is reversed (Top to bottom: Resources, Hardware, Programs) + +settings_set = Set + +settings_set-all = Set all cards to + +settings_show-alt = Show alternate card arts + +settings_sides-overlap = Runner and Corp board may overlap + +settings_sounds = Sounds + +settings_stacked-cards = Card stacking (on by default) + +settings_toggle-log-timestamps = Show log timestamps + +settings_update = Update + +settings_update-profile = Update Profile + +settings_updated = Profile updated - Please refresh your browser + +settings_updating = Updating profile... + +settings_user-name = User name + +settings_volume = Volume + +side_name = {$side -> + [all] All + [any-side] Any Side + [corp] Corp + [runner] Runner + *[unknown] Unknown side ({$side}) +} + +stats_all-games = Show all games + +stats_cards-accessed = Cards Accessed + +stats_cards-click = Cards Drawn by the Basic Action + +stats_cards-drawn = Cards Drawn + +stats_cards-rezzed = Cards Rezzed + +stats_cards-sabotaged = Sabotage Count + +stats_clear-stats = Clear Stats + +stats_clicks-gained = Clicks Gained + +stats_completed = Completed: {$completed} ({NUMBER($percent, style: "percent")}) + +stats_corp-stats = Corp Stats + +stats_credits-click = Credits by the Basic Action + +stats_credits-gained = Credits Gained + +stats_credits-spent = Credits Spent + +stats_damage-done = Damage Done + +stats_download = Download replay + +stats_ended = Ended + +stats_events-played = Events Played + +stats_format = Format + +stats_game-stats = Game Stats + +stats_game-title = {$title} ({$cnt -> + [one] {$cnt} turn + *[other] {$cnt} turns +}) + +stats_launch = Launch Replay + +stats_lobby = Lobby + +stats_log-count = {$cnt -> + [one] {$cnt} Log + *[other] {$cnt} Logs +} + +stats_log-count-filtered = {$cnt -> + [one] {$cnt} Log + *[other] {$cnt} Logs +} (filtered) + +stats_lost = Lost: {$lost} ({NUMBER($percent, style: "percent")}) + +stats_no-games = No games + +stats_no-log = No log available + +stats_not-completed = Not completed: {$completed} ({NUMBER($percent, style: "percent")}) + +stats_operations-played = Operations Played + +stats_psi-game-total = Psi Game: Games Played + +stats_psi-game-total-bid-0 = Psi Game: Bid 0 + +stats_psi-game-total-bid-1 = Psi Game: Bid 1 + +stats_psi-game-total-bid-2 = Psi Game: Bid 2 + +stats_psi-game-total-wins = Psi Game: Wins + +stats_rashida-count = Rashida Count + +stats_replay-shared = Replay shared + +stats_runner-stats = Runner Stats + +stats_runs-made = Runs Made + +stats_share = Share replay + +stats_shared-games = Only show shared + +stats_shuffle-count = Shuffle Count + +stats_started = Started: {$started} + +stats_tags-gained = Tags Gained + +stats_unavailable = Replay unavailable + +stats_unique-accesses = Unique Cards Accessed + +stats_view-games = Return to stats screen + +stats_view-log = View log + +stats_win-method = Win method + +stats_winner = Winner + +stats_won = Won: {$won} ({NUMBER($percent, style: "percent")}) diff --git a/resources/public/i18n/fr.ftl b/resources/public/i18n/fr.ftl new file mode 100644 index 0000000000..c0d63822ca --- /dev/null +++ b/resources/public/i18n/fr.ftl @@ -0,0 +1,827 @@ +annotations_available-annotations = Annotations disponibles + +annotations_clear = Effacer les annotations locales + +annotations_click-placeholder = Notes pour ce clic + +annotations_import-local = Importer un fichier d'annotations locales + +annotations_load-local = Charger + +annotations_no-published-annotations = Pas d'annotations publiées + +annotations_publish = Publier + +annotations_save-local = Sauvegarder + +annotations_turn-placeholder = Notes pour ce tour + +card-browser-form_faction = Faction + +card-browser-form_format = Format + +card-browser-form_search-hint = Rechercher des cartes + +card-browser-form_side = Camp + +card-browser-form_sort = Trier par + +card-browser-form_sort-by = {$by -> + [cost] Cout + [faction] Faction + [influence] Influence + [name] Nom + [set-number] Numéro de carte + [type] Type + *[unknown] Unknown sort-by option ({$by}) +} + +card-browser-form_type = Type + +card-browser_advancement = Valeur d'avancement: {$requirement} + +card-browser_agenda-points = Points de projet: {$points} + +card-browser_clear = Réinitialiser + +card-browser_cost = Cout: {$cost} + +card-browser_inf-limit = Limite d'influence: {$inf-limit} + +card-browser_influence = Influence: {$influence} + +card-browser_memory = Mémoire: {$memory} + +card-browser_min-deck-size = Taille minimale de deck: {$min-deck-size} + +card-browser_select-art = Sélectionner l'illustration + +card-browser_selected-art = Sélectionner l'illustration alternatiive + +card-browser_set = Extension + +card-browser_strength = Force: {$strength} + +card-browser_trash-cost = Cout d'effacement: {$trash-cost} + +card-browser_update-failure = Échec de la mise à jour de l'illustration + +card-browser_update-success = Illustration mise à jour + +card-type_name = {$type -> + [agenda] Projet + [all] Tous + [asset] Avoir + [event] Évènement + [hardware] Matériel + [ice] Glace + [identity] Identité + [operation] Opération + [program] Programme + [resource] Ressource + [upgrade] Extension + *[unknown] Unknown card type ({$type}) +} + +chat_block = Bloquer l'utilisateur + +chat_cancel = Annuler + +chat_channels = Canaux + +chat_delete = Effacer le message + +chat_delete-all = Effacer tous les messages de l'utilisateur + +chat_placeholder = Dire quelque chose… + +chat_send = Envoyer + +chat_title = Joue à Netrunner dans ton navigateur + +deck-builder_add-cards = Ajouter des cartes + +deck-builder_add-to-deck = Ajouter au deck + +deck-builder_agenda-points = Points de projet + +deck-builder_cancel = Annuler + +deck-builder_card-count = {$cnt -> + [one] 1 card + *[other] {$cnt} cards +} + +deck-builder_card-name = Nom de la carte + +deck-builder_clear-stats = Effacer les statistiques + +deck-builder_completed = Terminées: {$completed} + +deck-builder_confirm-delete = Confirmer l'effacement + +deck-builder_create-game = Créer une partie + +deck-builder_deck-count = {$cnt -> + [zero] Aucun Decks + [one] {$cnt} Deck + *[other] {$cnt} Decks +} + +deck-builder_deck-count-filtered = {$cnt -> + [zero] No Decks (filtres activés) + [one] {$cnt} Deck (filtres activés) + *[other] {$cnt} Decks (filtres activés) +} + +deck-builder_deck-name = Nom du deck + +deck-builder_deck-notes = Notes sur le deck + +deck-builder_deck-points = Points du deck + +deck-builder_decklist = Liste de cartes + +deck-builder_decklist-inst = (Saisissez ou copiez une liste, elle sera analysée) + +deck-builder_delete = Effacer + +deck-builder_edit = Éditer + +deck-builder_format = Format + +deck-builder_games = Parties: {$games} + +deck-builder_hash = Hash de tournoi + +deck-builder_identity = Identité + +deck-builder_illegal = illégal + +deck-builder_import = Importer + +deck-builder_import-button = Importer + +deck-builder_import-placeholder = ID NRDB + +deck-builder_import-title = Entrer un ID de deck NRDB publique ou une URL + +deck-builder_influence = Influence + +deck-builder_legal = légal + +deck-builder_loading-msg = Chargement de la bibliothèque de decks… + +deck-builder_lost = Perdues: {$lost} + +deck-builder_max = maximum + +deck-builder_min = minimum + +deck-builder_min-deck-size = (minimum {$cnt}) + +deck-builder_new-corp = Nouveau deck Corpo + +deck-builder_new-deck = Nouveau deck + +deck-builder_new-runner = Nouveau deck Runner + +deck-builder_notes = Notes + +deck-builder_reset = Réinitialiser + +deck-builder_save = Sauvegarder + +deck-builder_why = Pourquoi ? + +deck-builder_won = Gagnées: {$won} ({NUMBER($percent, style: "percent")}) + +faction_name = {$faction -> + [adam] Adam + [all] Toutes + [anarch] Anarch + [any-faction] Toute faction + [apex] Apex + [criminal] Criminel + [haas-bioroid] Haas-Bioroid + [jinteki] Jinteki + [nbn] NBN + [neutral] Neutre + [shaper] Façonneur + [sunny-lebeau] Sunny Lebeau + [weyland-consortium] Consortium Weyland + *[other] Unknown faction +} + +format_name = {$format -> + [all] Tous + [any-format] Tout format + [casual] Casual + [classic] Classic + [core-experience] Core Experience + [eternal] Eternal + [neo] Neo + [preconstructed] Preconstructed + [snapshot] Snapshot + [snapshot-plus] Snapshot Plus + [socr] SOCR + [standard] Standard + [startup] Startup + [sunset] Sunset + [system-gateway] System Gateway + [throwback] Throwback + *[other] Unknown format +} + +game_abilities = Capacités + +game_actions = Actions + +game_agenda-count = {$agenda-point -> + [one] 1 Point de projet + *[other] {$agenda-point} Points de projet +} + +game_agenda-count-with-req = {$agenda-point -> + [one] 1 Point de projet + *[other] {$agenda-point} Points de projet +} ({$agenda-point-req} required) + +game_approach-ice = Approcher la glace + +game_archives = Archives{"\u00A0"}({$faceup} ↑ {$facedown} ↓) + +game_auto-pass = Activer le passage automatique + +game_bad-pub-count = {$base} Mauvaise Presse + +game_bad-pub-count-additional = {$base} + {$additional} Mauvaise Presse + +game_brain-damage = {$dmg} Dégât sévère + +game_breach-server = Fracturer le serveur + +game_card = Carte + +game_card-count = {$cnt -> + [one] {$cnt} carte + *[other] {$cnt} cartes +} + +game_click-count = {$click -> + [one] {$click} Clic + *[other] {$click} Clics +} + +game_close = Fermer + +game_close-shuffle = Fermer et Mélanger + +game_concede = Abandonner + +game_continue = Continuer + +game_continue-to = Continuer vers {$phase} + +game_corp-view = Vue Corpo + +game_credit-count = {$credit -> + [one] {$credit} Crédit + *[other] {$credit} Crédits +} + +game_credit-count-with-run-credits = {$credit -> + [one] {$credit} Crédit + *[other] {$credit} Crédits +} ({$run-credit} pour le piratage) + +game_credits = Crédits + +game_current = Actuel + +game_current-phase = Phase en cours + +game_draw = Piocher une carte + +game_encounter-ice = Rencontrer la glace + +game_end-turn = Terminer le tour + +game_face-down-count = {$total -> + [one] {$total} carte, {$facedown} face cachée. + *[other] {$total} cartes, {$facedown} face cachée. +} + +game_fire-unbroken = Déclencher les routines non neutralisées + +game_gain-credit = Gagner un crédit + +game_game-start = Démarrer la partie: {$timestamp} + +game_grip = Main + +game_heap = Tas ({$cnt}) + +game_hq = QG + +game_inactivity = Partie fermée pour cause d'inactivé + +game_indicate-action = Indiquer une action + +game_initiation = Initiation + +game_jack-out = Débrancher + +game_keep = Garder + +game_leave = Quitter la partie + +game_leave-replay = Quitter le replay + +game_let-subs-fire = Laisser la Corpo déclencher les routines non neutralisées + +game_link-strength = Force d'évasion + +game_mandatory-draw = Pioche obligatoire + +game_max-hand = {$total} Taille de main maximale + +game_movement = Mouvement + +game_mu-count = {$available -> + [one] {$unused} de {$available} UM inutilisée + *[other] {$unused} de {$available} UM inutilisées +} + +game_mulligan = Mulligan + +game_mute = Désactiver le son des spectateurs + +game_no-current-run = Pas de piratage en cours + +game_no-further = Pas d'autre action + +game_play-area = Zone de jeu + +game_purge = Nettoyer les pions virus + +game_remove-tag = Retirer des tags + +game_rez = Activer + +game_rfg = Retiré du jeu + +game_rnd = R&D + +game_run = Lancer un piratage + +game_run-ends = Le piratage est terminé + +game_runner-view = Vue Runner + +game_scored-area = Zone de score + +game_server = Serveur {$num} + +game_show = Montrer + +game_shuffle = Mélanger + +game_spec-count = {$cnt -> + [one] Spectateur + *[other] {$cnt} Spectateurs +} + +game_spec-view = Vue Spectateur + +game_stack = Pile + +game_start = Démarrer la partie + +game_start-turn = Commencer le tour + +game_stop-auto-pass = Désactiver le passage automatique + +game_subs = Routines + +game_success = Piratage réussi + +game_tag-count = {$base -> + [one] {$base} Tag + *[other] {$base} Tags +} + +game_tag-count-additional = {$total -> + [one] {$base} + {$additional} Tag + *[other] {$base} + {$additional} Tags +} + +game_take-clicks = Prendre des clics + +game_time-taken = Temps écoulé: {$time -> + [one] {$time} minute + *[other] {$time} minutes +} + +game_trace = Traque + +game_trash-resource = Effacer une ressource + +game_unimplemented = Non implementé + +game_unknown-phase = Phase inconnue + +game_unmute = Réactiver le son des spectateurs + +game_win-claimed = {$winner} ({$side}) gagne par réclamation au tour {$turn} + +game_win-conceded = {$winner} ({$side}) gagne par abandon au tour {$turn} + +game_win-decked = {$winner} ({$side}) gagne par épuisement du deck Corpo au tour {$turn} + +game_win-flatlined = {$winner} ({$side}) gagne par mort clinique au tour {$turn} + +game_win-other = {$winner} ({$side}) gagne par {$reason} au tour {$turn} + +game_win-points = {$winner} ({$side}) gagne aux points de projet au tour {$turn} + +lobby_aborted = Connexion interrompue + +lobby_api-access = Autoriser l'accès API aux informations de la partie + +lobby_api-requires-key = (Nécessite un clé API dans les réglages) + +lobby_as-corp = En tant que Corpo + +lobby_as-runner = En tant que Runner + +lobby_cancel = Annuler + +lobby_chat = Discuter + +lobby_closed-msg = Salle d'attente fermée pour cause d'inactivité + +lobby_completion-rate = Taux de parties achevées + +lobby_create = Créer + +lobby_deck-selected = Deck sélectionné + +lobby_delete = Effacer la partie + +lobby_filter = (filtres activés) + +lobby_format = Format + +lobby_game-count = {$cnt -> + [one] {$cnt} Partie + *[other] {$cnt} Parties +} + +lobby_game-count-filtered = {$cnt -> + [one] {$cnt} Partie (filtres activés) + *[other] {$cnt} Parties (filtres activés) +} + +lobby_hidden = Rendre les informations cachées du joueur visibles aux spectateurs + +lobby_invalid-password = Mot de passe invalide + +lobby_join = Rejoindre + +lobby_leave = Quitter + +lobby_load-replay = Charger un replay + +lobby_new-game = Nouvelle partie + +lobby_no-games = Pas de partie + +lobby_not-allowed = Interdit + +lobby_options = Options + +lobby_password = Mot de passe + +lobby_password-error = Veuillez saisir un mot de passe. + +lobby_password-for = Mot de passe pour + +lobby_password-protected = Protéger par mot de passe + +lobby_players = Joueurs + +lobby_private = PRIVÉE + +lobby_rejoin = Rejoindre + +lobby_reload = Rafraichir + +lobby_replay-invalid-file = Sélectionner un fichier de replay valide. + +lobby_replay-link-error = Lien de replay invalide. + +lobby_reset = Réinitialiser le nom de la partie + +lobby_save-replay = Sauvegarder le replay + +lobby_select-deck = Sélectionner un deck + +lobby_select-title = Sélectionner votre deck + +lobby_side = Camp + +lobby_spectator-count = {$cnt -> + [one] Spectateur + *[other] {$cnt} Spectateurs +} + +lobby_spectators = Autoriser les spectateurs + +lobby_start = Commencer + +lobby_start-replay = Lancer le replay + +lobby_swap = Changer de camp + +lobby_title = Nom de la partie + +lobby_title-error = Veuillez saisir un nom de partie. + +lobby_too-little-data = Trop peu de données + +lobby_type = {$type -> + [angel-arena] Angel Arena + [casual] Amical + [competitive] Compétition + [tournament] Tournois + *[other] Unknown lobby type +} + +lobby_waiting = En attente de la sélection des decks + +lobby_watch = Regarder + +log_annotating = Annoter + +log_game-log = Journal de partie + +log_remote-annotations-fail = Impossible d'obtenir les annotations distantes + +log_shared = Annotations partagées + +menu_admin = {nav_admin} + +menu_logout = Débrancher + +menu_moderator = Modérateur + +menu_settings = {nav_settings} + +nav_about = À propos + +nav_admin = Admin + +nav_cards = Cartes + +nav_chat = Discussion + +nav_deck-builder = Constructeur de decks + +nav_features = Caractéristiques + +nav_game-count = {$cnt -> + [one] {$cnt} Partie + *[other] {$cnt} Parties +} + +nav_help = Aide + +nav_play = Jouer + +nav_settings = Réglages + +nav_stats = Statistiques + +nav_tournaments = Tournois + +nav_users = Utilisateurs + +pronouns = {$pronoun -> + [any] N'importe quel pronom + [blank] [Laisser vide] + [ey] Ey + [faefaer] undefined + [he] Il/lui + [heit] undefined + [heshe] undefined + [hethey] Il/lui ou iel + [it] Ul + [myodb] Préfère ne pas le dire + [ne] Ol + *[none] Non indiqué + [she] Elle + [sheit] undefined + [shethey] Elle ou iel + [they] Iel + [ve] Ael + [xe] Xe + [xi] undefined + [zehir] Zehir + [zezir] Zezir +} + +settings_alt-art = Illustrations alternatives + +settings_always = Toujours + +settings_api-keys = Clés API + +settings_avatar = Avatar + +settings_background = Arrière-plan de la zone de jeu + +settings_block = Bloquer l'utilisateur·trice + +settings_blocked = Utilisateur·trice·s bloqué·e·s + +settings_cancel = Annuler + +settings_card-backs = Dos des cartes + +settings_card-images = Images des cartes + +settings_change-avatar = Changer sur gravatar.com + +settings_change-email = Changer l'e-mail + +settings_comp-only = Parties de tournoi uniquement + +settings_create-api-key = Créer une clé API + +settings_current-email = E-mail actuel + +settings_deck-stats = Statistiques de deck + +settings_delete-api-key = Effacer + +settings_desired-email = Nouvel e-mail + +settings_email = E-mail + +settings_email-placeholder = Adresse e-mail + +settings_email-title = Changer d'adresse e-mail + +settings_enable-game-sounds = Activer les sons de la partie + +settings_enable-lobby-sounds = Activer les sons de la salle d'attente + +settings_enter-valid = Veuillez saisir une adresse e-mail valide + +settings_ffg = FFG + +settings_game-stats = Statistiques des parties gagnées/perdues + +settings_get-log-top = Obtenir le top du journal actuel + +settings_get-log-width = Obtenir la largeur actuelle du journal + +settings_high-res = Activer les images des cartes en haute résolution + +settings_invalid-email = Aucun compte avec cette adresse e-mail + +settings_invalid-password = Identifiant ou mot de passe invalide + +settings_language = Langue + +settings_layout-options = Options de disposition + +settings_none = Jamais + +settings_nsg = NSG + +settings_pronouns = Pronoms + +settings_reset = Reset All to Official Art + +settings_runner-classic = Disposition jnet classique (de haut en bas : Programmes, Matériels, Ressources) + +settings_runner-layout = Disposition du Runner du point de vue de la Corpo + +settings_runner-reverse = Disposition inversée (de haut en bas : Ressources, Matériels, Programmes) + +settings_set = Set + +settings_set-all = Set all cards to + +settings_show-alt = Afficher les illustrations de carte alternatives + +settings_sounds = Sons + +settings_stacked-cards = Empiler les cartes (activé par défaut) + +settings_update = Mettre à jour + +settings_update-profile = Mettre à jour le profil + +settings_updated = Profil mis à jour - veuillez actualiser votre navigateur + +settings_updating = Mise à jour du profil… + +settings_user-name = Nom d'utilisateur·trice + +settings_volume = Volume + +side_name = {$side -> + [all] Les deux camps + [any-side] N'importe quel camp + [corp] Corpo + [runner] Runner + *[unknown] Unknown side ({$side}) +} + +stats_all-games = Montrer toutes les parties + +stats_cards-accessed = Cartes accédées + +stats_cards-click = Cartes piochées par clic + +stats_cards-drawn = Cartes piochées + +stats_cards-rezzed = Cartes activées + +stats_clear-stats = Effacer les statistiques + +stats_clicks-gained = Clicks gagnés + +stats_completed = Terminées: {$completed} ({NUMBER($percent, style: "percent")}) + +stats_corp-stats = Statistiques Corpo + +stats_credits-click = Crédits par clic + +stats_credits-gained = Crédits gagnés + +stats_credits-spent = Crédits dépensés + +stats_damage-done = Dégâts infligés + +stats_download = Télécharger le replay + +stats_ended = Terminée + +stats_format = Format + +stats_game-stats = Statistiques de jeu + +stats_game-title = {$title} ({$cnt -> + [one] {$cnt} tour + *[other] {$cnt} tours +}) + +stats_launch = Démarrer le replay + +stats_lobby = Hall + +stats_log-count = {$cnt -> + [one] {$cnt} Journal + *[other] {$cnt} Journaux +} + +stats_log-count-filtered = {$cnt -> + [one] {$cnt} Journal + *[other] {$cnt} Journaux +} (filtres activés) + +stats_lost = Perdues: {$lost} ({NUMBER($percent, style: "percent")}) + +stats_no-games = Pas de parties + +stats_no-log = Pas de journal disponible + +stats_not-completed = Inachevées: {$completed} ({NUMBER($percent, style: "percent")}) + +stats_runner-stats = Statistiques Runner + +stats_runs-made = Piratages effectués + +stats_share = Partager le replay + +stats_shared-games = Montrer seulement les parties partagées + +stats_started = Commencées: {$started} + +stats_tags-gained = Tags reçus + +stats_unavailable = Pas de replay disponible + +stats_view-games = Retourner aux statistiques + +stats_view-log = Voir le journal + +stats_win-method = Type de victoire + +stats_winner = Vainqueur + +stats_won = Gagnées: {$won} ({NUMBER($percent, style: "percent")}) diff --git a/resources/public/i18n/ja.ftl b/resources/public/i18n/ja.ftl new file mode 100644 index 0000000000..4408bd3c5e --- /dev/null +++ b/resources/public/i18n/ja.ftl @@ -0,0 +1,531 @@ +card-browser-form_faction = 派閥 + +card-browser-form_format = フォーマット + +card-browser-form_search-hint = カード名検索 + +card-browser-form_side = プレイヤーサイド + +card-browser-form_sort = 並び順 + +card-browser-form_sort-by = {$by -> + [cost] コスト + [faction] 派閥 + [influence] 影響値 + [name] カード名 + [set-number] セット番号 + [type] タイプ + *[unknown] Unknown sort-by option ({$by}) +} + +card-browser-form_type = カードタイプ + +card-browser_advancement = アドバンス要求: {$requirement} + +card-browser_agenda-points = 計画ポイント: {$points} + +card-browser_clear = クリア + +card-browser_cost = コスト: {$cost} + +card-browser_inf-limit = 影響値上限: {$inf-limit} + +card-browser_influence = 影響値: {$influence} + +card-browser_min-deck-size = 最小デッキ枚数: {$min-deck-size} + +card-browser_set = カードセット + +card-browser_strength = 強度: {$strength} + +card-browser_trash-cost = トラッシュコスト: {$trash-cost} + +card-type_name = {$type -> + [agenda] 計画書 + [all] 全部 + [asset] 資材 + [event] イベント + [hardware] ハードウェア + [ice] アイス + [identity] ID + [operation] 任務 + [program] プログラム + [resource] リソース + [upgrade] 強化 + *[unknown] Unknown card type ({$type}) +} + +deck-builder_add-cards = カードの追加 + +deck-builder_add-to-deck = 追加 + +deck-builder_agenda-points = 計画ポイント + +deck-builder_cancel = キャンセル + +deck-builder_card-name = カード名 + +deck-builder_clear-stats = 統計を削除 + +deck-builder_completed = 完了: {$completed} + +deck-builder_confirm-delete = 削除の実行 + +deck-builder_copy = コピー + +deck-builder_create-game = 対戦の開始 + +deck-builder_deck-copy-suffix = コピー + +deck-builder_deck-count = {$cnt -> + [zero] デッキ未登録 + *[other] デッキ数 {$cnt} +} + +deck-builder_deck-count-filtered = {$cnt -> + [zero] デッキ未登録 + *[other] デッキ数 {$cnt} +} (絞り込み) + +deck-builder_deck-name = デッキ名 + +deck-builder_deck-notes = メモ + +deck-builder_deck-points = デッキポイント + +deck-builder_decklist = カードリスト + +deck-builder_decklist-inst = ({"{"}枚数{"}"}[半角スペース]{"{"}カード名(英語){"}"}で入力) + +deck-builder_delete = 削除 + +deck-builder_edit = 編集 + +deck-builder_format = フォーマット + +deck-builder_games = ゲーム: {$games} + +deck-builder_hash = 大会ハッシュ + +deck-builder_illegal = 違反 + +deck-builder_import = インポート + +deck-builder_import-button = デッキのインポート + +deck-builder_import-title = 公開済みNetrunnerDB Deck ID or URL + +deck-builder_influence = 影響値 + +deck-builder_legal = 適正 + +deck-builder_loading-msg = デッキ一覧を読み込み中…… + +deck-builder_lost = 敗北: {$lost} + +deck-builder_max = 上限 + +deck-builder_min = 下限 + +deck-builder_new-corp = 新規コーポ + +deck-builder_new-runner = 新規ランナー + +deck-builder_notes = メモ + +deck-builder_reset = リセット + +deck-builder_save = 保存 + +deck-builder_won = 勝利: {$won} ({NUMBER($percent, style: "percent")}) + +faction_name = {$faction -> + [adam] アダム + [all] 全部 + [anarch] アナーク + [any-faction] undefined + [apex] エイペックス + [criminal] クリミナル + [haas-bioroid] ハース=バイオロイド + [jinteki] ジンテキ + [nbn] NBN + [neutral] 中立 + [shaper] シェイパー + [sunny-lebeau] サニー・ルボー + [weyland-consortium] ウェイランド・コンソーシアム + *[other] undefined +} + +format_name = {$format -> + [all] 全部 + [any-format] undefined + [casual] undefined + [classic] undefined + [core-experience] undefined + [eternal] エターナル + [neo] undefined + [preconstructed] undefined + [snapshot] スナップショット + [snapshot-plus] undefined + [socr] undefined + [standard] スタンダード + [startup] スタートアップ + [sunset] undefined + [system-gateway] システムゲートウェイ + [throwback] undefined + *[other] undefined +} + +game_abilities = 能力 + +game_actions = アクション + +game_agenda-count = {$agenda-point} 計画点 + +game_approach-ice = アイスにアプローチ + +game_archives = アーカイブ{"\u00A0"}({$faceup} ↑ {$facedown} ↓) + +game_auto-pass = 自動通過処理 + +game_bad-pub-count = {$base} 悪名 + +game_bad-pub-count-additional = {$base} + {$additional} 悪名 + +game_brain-damage = {$dmg} コアダメージ + +game_breach-server = サーバーに侵入 + +game_card = カード + +game_card-count = {$cnt} 枚 + +game_click-count = {$click} クリック + +game_close = 閉じる + +game_close-shuffle = 閉じてシャフルする + +game_concede = 降参する + +game_continue = 次へ進む + +game_continue-to = 次へ {$phase} + +game_corp-view = コーポ視点 + +game_credit-count = {$credit} クレジット + +game_credit-count-with-run-credits = {$credit} クレジット (ランの間のみ {$run-credit}) + +game_credits = クレジット + +game_current = 現状 + +game_current-phase = 現在のフェーズ + +game_draw = ドロー + +game_encounter-ice = エンカウント中 + +game_end-turn = ターンの終了 + +game_face-down-count = {$total} 枚(裏向き {$facedown} 枚) + +game_fire-unbroken = 未ブレイクサブルーチンを解決する + +game_gain-credit = クレジットを得る + +game_game-start = ゲーム開始: {$timestamp} + +game_grip = グリップ + +game_heap = ヒープ ({$cnt}) + +game_inactivity = 操作が行われていないルームを閉じました。 + +game_indicate-action = アクションします! + +game_initiation = ラン開始 + +game_jack-out = ジャックアウト + +game_keep = キープ + +game_leave = ルームを退出 + +game_leave-replay = リプレイから退出 + +game_let-subs-fire = 未ブレイクサブルーチン解決を許可 + +game_link-strength = リンク強度 + +game_mandatory-draw = 強制ドロー + +game_max-hand = {$total} 手札上限 + +game_movement = 移動 + +game_mu-count = {$unused} / {$available} 未使用MU + +game_mulligan = マリガン + +game_no-current-run = ラン以外 + +game_no-further = これ以上アクションしない + +game_play-area = プレイエリア + +game_purge = ウィルスカウンター破棄 + +game_remove-tag = タグを除去 + +game_rez = レゾ + +game_rfg = 除外 + +game_run = ラン + +game_run-ends = ラン終了 + +game_runner-view = ランナー視点 + +game_scored-area = 得点エリア + +game_server = サーバー {$num} + +game_show = 中を確認する + +game_shuffle = シャッフルする + +game_spec-count = 観戦中 {$cnt}人 + +game_spec-view = 観戦者視点 + +game_special-mu-count = {$unused}/{$available} 未使用 {$mu-type} MU + +game_stack = スタック + +game_start = ゲーム開始 + +game_start-turn = ターンの開始 + +game_stop-auto-pass = 自動通過処理を停止 + +game_subs = サブルーチン + +game_success = ランの成功 + +game_tag-count = {$base} タグ + +game_tag-count-additional = {$base} + {$additional} タグ + +game_take-clicks = クリックを受け取る + +game_time-taken = 経過した時間: {$time}分 + +game_trace = トレース + +game_trash-resource = リソースをトラッシュ + +game_unimplemented = 未実装 + +game_unknown-phase = 不明フェーズ + +game_win-claimed = {$winner} ({$side}) wins by claim on turn {$turn} + +game_win-conceded = {$winner} ({$side}) 降参による勝利 {$turn} ターン + +game_win-decked = {$winner} ({$side}) コーポのデッキ切れによる勝利 {$turn} ターン + +game_win-flatlined = {$winner} ({$side}) (fn [[turn]] (str "フラットラインによる勝利 {$turn} ターン + +game_win-other = {$winner} ({$side}) wins by {$reason} on turn {$turn} + +game_win-points = {$winner} ({$side}) 計画ポイントによる勝利 {$turn} ターン + +lobby_api-requires-key = (Requires an API Key in Settings) + +lobby_as-corp = コーポとして + +lobby_as-runner = ランナーとして + +lobby_cancel = キャンセル + +lobby_chat = チャット + +lobby_closed-msg = 操作が行われていないルームを閉じました。 + +lobby_completion-rate = 対戦完了率 + +lobby_create = 作成 + +lobby_deck-selected = デッキ選択完了 + +lobby_format = フォーマット + +lobby_game-count = ルーム数 {$cnt} + +lobby_game-count-filtered = ルーム数 {$cnt} (絞り込み) + +lobby_hidden = 非公開情報を観戦者に公開 + +lobby_invalid-password = 不正なパスワード + +lobby_join = 入室 + +lobby_leave = 退出 + +lobby_load-replay = リプレイ読込 + +lobby_new-game = ルーム作成 + +lobby_options = 設定 + +lobby_password = パスワード + +lobby_password-error = パスワードを修正してください。 + +lobby_password-for = パスワード + +lobby_password-protected = パスワードを設定する + +lobby_players = プレイヤー + +lobby_private = 非公開 + +lobby_rejoin = 再入室 + +lobby_reload = リロード + +lobby_save-replay = リプレイの保存 + +lobby_select-deck = デッキ選択 + +lobby_select-title = デッキを選択 + +lobby_side = サイド + +lobby_spectator-count = 観戦中 {$cnt}人 + +lobby_spectators = 観戦の許可 + +lobby_start = 開始 + +lobby_start-replay = 再生 + +lobby_swap = サイド変更 + +lobby_title = ルーム名 + +lobby_title-error = ルーム名を修正してください。 + +lobby_type = {$type -> + [angel-arena] Angel Arena + [casual] Casual + [competitive] Competitive + [tournament] Tournament + *[other] Unknown lobby type +} + +lobby_waiting = デッキ選択待ち + +lobby_watch = 観戦 + +menu_admin = {nav_admin} + +menu_logout = ジャックアウト + +menu_settings = {nav_settings} + +nav_about = このサイトについて + +nav_cards = カード + +nav_chat = チャット + +nav_deck-builder = デッキビルダー + +nav_game-count = ルーム数 {$cnt} + +nav_help = ヘルプ + +nav_play = 対戦 + +nav_settings = 設定 + +nav_stats = 統計 + +nav_tournaments = 大会 + +side_name = {$side -> + [all] 全部 + [any-side] Any Side + [corp] コーポ + [runner] ランナー + *[unknown] Unknown side ({$side}) +} + +stats_all-games = 全てのログを表示 + +stats_cards-accessed = アクセスしたカード + +stats_cards-click = クリックでしたドロー + +stats_cards-drawn = ドロー + +stats_cards-rezzed = レゾしたカード + +stats_clear-stats = 統計を削除 + +stats_clicks-gained = 得たクリック + +stats_completed = 完了: {$completed} ({NUMBER($percent, style: "percent")}) + +stats_corp-stats = コーポ統計 + +stats_credits-click = クリックで得たクレジット + +stats_credits-gained = 得たクレジット + +stats_credits-spent = 消費したクレジット + +stats_damage-done = 与えたダメージ + +stats_ended = 終了 + +stats_format = フォーマット + +stats_game-stats = 対戦統計 + +stats_game-title = {$title} (ターン数 {$cnt}) + +stats_lobby = ロビー + +stats_log-count = ログ数 {$cnt} + +stats_log-count-filtered = ログ数 {$cnt} (絞り込み) + +stats_lost = 敗北: {$lost} ({NUMBER($percent, style: "percent")}) + +stats_not-completed = 未完了: {$completed} ({NUMBER($percent, style: "percent")}) + +stats_runner-stats = ランナー統計 + +stats_runs-made = 行ったラン + +stats_shared-games = シェアログのみ表示 + +stats_started = 開始: {$started} + +stats_tags-gained = 受けたタグ + +stats_view-games = 統計画面に戻る + +stats_view-log = ログを見る + +stats_win-method = 勝利方法 + +stats_winner = 勝者 + +stats_won = 勝利: {$won} ({NUMBER($percent, style: "percent")}) diff --git a/resources/public/i18n/ko.ftl b/resources/public/i18n/ko.ftl new file mode 100644 index 0000000000..e4ecf53c00 --- /dev/null +++ b/resources/public/i18n/ko.ftl @@ -0,0 +1,713 @@ +annotations_available-annotations = 사용가능한 주석 + +annotations_clear = 로컬 주석 지우기 + +annotations_click-placeholder = 이 클릭에 대한 메모 + +annotations_import-local = 로컬 주석 파일 가져오기 + +annotations_load-local = 불러오기 + +annotations_no-published-annotations = 발행된 주석이 없음 + +annotations_publish = 발행 + +annotations_save-local = 저장 + +annotations_turn-placeholder = 이 차례에 대한 메모 + +card-browser-form_faction = 세력 + +card-browser-form_format = 포맷 + +card-browser-form_search-hint = 카드 찾기 + +card-browser-form_side = 사이드 + +card-browser-form_sort = 정렬 기준 + +card-browser-form_sort-by = {$by -> + [cost] 비용 + [faction] 세력 + [influence] 영향력 + [name] 이름 + [set-number] 세트 번호 + [type] 타입 + *[unknown] undefined +} + +card-browser-form_type = 타입 + +card-browser_advancement = 필요 발전 정도: {$requirement} + +card-browser_agenda-points = 아젠다 점수: {$points} + +card-browser_clear = 지우기 + +card-browser_cost = 비용: {$cost} + +card-browser_inf-limit = 영향력 제한: {$inf-limit} + +card-browser_influence = 영향력: {$influence} + +card-browser_memory = 메모리: {$memory} + +card-browser_min-deck-size = 최소 덱 사이즈: {$min-deck-size} + +card-browser_select-art = 아트 선택 + +card-browser_selected-art = 대체 아트가 선택됨 + +card-browser_set = 세트 + +card-browser_strength = 힘: {$strength} + +card-browser_trash-cost = 폐기 비용: {$trash-cost} + +card-browser_update-failure = 아트 갱신 실패 + +card-browser_update-success = 아트가 갱신됨 + +card-type_name = {$type -> + [agenda] 아젠다 + [all] 모두 + [asset] 자산 + [event] 이벤트 + [hardware] 하드웨어 + [ice] 아이스 + [identity] ID + [operation] 운영 + [program] 프로그램 + [resource] 리소스 + [upgrade] 개선 + *[unknown] undefined +} + +chat_block = 사용자 차단 + +chat_cancel = 취소 + +chat_channels = 채널 + +chat_delete = 메시지 삭제 + +chat_delete-all = 모든 사용자로부터 받은 메시지 삭제 + +chat_placeholder = 대화를 나누어 보세요... + +chat_send = 보내기 + +chat_title = 브라우저로 즐기는 안드로이드: 넷러너 + +deck-builder_add-cards = 카드 삽입 + +deck-builder_add-to-deck = 덱에 삽입 + +deck-builder_agenda-points = 아젠다 점수 + +deck-builder_cancel = 취소 + +deck-builder_card-name = 카드 이름 + +deck-builder_clear-stats = 기록 초기화 + +deck-builder_completed = 완료됨: {$completed} + +deck-builder_confirm-delete = 삭제 확인 + +deck-builder_create-game = 게임 생성 + +deck-builder_deck-count = {$cnt -> + [zero] 덱 없음 + *[other] {$cnt} 덱 +} + +deck-builder_deck-count-filtered = {$cnt -> + [zero] 덱 없음 (필터됨) + *[other] {$cnt} 덱 (필터됨) +} + +deck-builder_deck-name = 덱 이름 + +deck-builder_deck-notes = 덱 메모 + +deck-builder_decklist = 덱 리스트 + +deck-builder_decklist-inst = (덱 리스트를 입력하거나 붙여 넣으십시오) + +deck-builder_delete = 삭제 + +deck-builder_edit = 편집 + +deck-builder_format = 포맷 + +deck-builder_games = 게임: {$games} + +deck-builder_hash = 토너먼트 해쉬값 + +deck-builder_identity = ID + +deck-builder_illegal = 사용 불가 + +deck-builder_import = 가져오기 + +deck-builder_import-button = 덱 가져오기 + +deck-builder_import-placeholder = NetrunnerDB ID + +deck-builder_import-title = NetrunnerDB 공개 덱 ID 혹은 URL 입력 + +deck-builder_influence = 영향력 + +deck-builder_legal = 사용 가능 + +deck-builder_loading-msg = 덱 컬렉션을 불러오는 중 + +deck-builder_lost = 패배: {$lost} + +deck-builder_max = 최대 + +deck-builder_min = 최소 + +deck-builder_new-corp = 새로운 기업 덱 + +deck-builder_new-runner = 새로운 러너 덱 + +deck-builder_notes = 메모 + +deck-builder_reset = 리셋 + +deck-builder_save = 저장 + +deck-builder_why = 확인하십시오 + +deck-builder_won = 승리: {$won} ({NUMBER($percent, style: "percent")}) + +faction_name = {$faction -> + [adam] 아담 + [all] 모두 + [anarch] 아나크 + [any-faction] 모든 세력 + [apex] 에이펙스 + [criminal] 크리미널 + [haas-bioroid] 하스-바이오로이드 + [jinteki] 진테키 + [nbn] NBN + [neutral] 중립 + [shaper] 쉐이퍼 + [sunny-lebeau] 서니 르뷰 + [weyland-consortium] 웨이랜드 컨소시엄 + *[unknown] undefined +} + +format_name = {$format -> + [all] 모두 + [any-format] 모든 포맷 + [casual] 캐주얼 + [classic] 클래식 + [core-experience] 코어 익스피리언스 + [eternal] 이터널 + [neo] Neo + [preconstructed] undefined + [snapshot] 스냅샷 + [snapshot-plus] 스냅샷 플러스 + [socr] SOCR + [standard] 스탠다드 + [startup] undefined + [sunset] Sunset + [system-gateway] undefined + [throwback] undefined + *[unknown] undefined +} + +game_abilities = 능력 + +game_actions = 행동 + +game_agenda-count = {$agenda-point} 아젠다 점수 + +game_approach-ice = 아이스 접근 + +game_archives = 기록보관소{"\u00A0"}({$faceup} ↑ {$facedown} ↓) + +game_auto-pass = 자동-통과 우선 + +game_bad-pub-count = {$base} 악평 + +game_bad-pub-count-additional = {$base} + {$additional} 악평 + +game_brain-damage = 두뇌 피해 + +game_card = 카드 + +game_card-count = {$cnt} 카드 + +game_click-count = {$click} 클릭 + +game_close = 닫기 + +game_close-shuffle = 닫고 섞는다 + +game_concede = 항복하기 + +game_continue-to = 계속하기 {$phase} + +game_corp-view = 기업 보기 + +game_credit-count = {$credit} 크레딧 + +game_credit-count-with-run-credits = {$credit} 크레딧 (런 동안 {$run-credit}) + +game_credits = 크레딧 + +game_current = 동향 + +game_current-phase = 현재 단계 + +game_draw = 카드 뽑기 + +game_end-turn = 차례 종료 + +game_fire-unbroken = 깨지지 않은 서브루틴 격발 + +game_gain-credit = 크레딧 얻기 + +game_game-start = 게임 시작: {$timestamp} + +game_grip = 그립 + +game_heap = 힙({$cnt}) + +game_hq = 본부(HQ) + +game_inactivity = 활동이 없어 게임이 닫혔습니다 + +game_indicate-action = 행동 선언 + +game_initiation = 시도 + +game_jack-out = 잭 아웃 + +game_keep = 그대로 + +game_leave = 게임 떠나기 + +game_leave-replay = 리플레이 떠나기 + +game_let-subs-fire = 모든 서브루틴 격발 + +game_link-strength = 링크 강도 + +game_mandatory-draw = 강제 카드 뽑기 + +game_max-hand = {$total} 최대 핸드 크기 + +game_mu-count = {$available} 메모리 유닛 중 {$unused} 미사용 + +game_mulligan = 멀리건 + +game_mute = 관전자 무시 + +game_no-current-run = 현재 런 없음 + +game_no-further = 더 이상 행동 없음 + +game_play-area = 발동 영역 + +game_purge = 퇴치 + +game_remove-tag = 태그 제거 + +game_rez = 레즈하기 + +game_rfg = 게임에서 제거됨 + +game_rnd = 연구개발부(R&D) + +game_run = 런 + +game_runner-view = 러너 보기 + +game_scored-area = 득점 영역 + +game_server = 서버 {$num} + +game_show = 보기 + +game_shuffle = 섞기 + +game_spec-count = {$cnt} 관전자 + +game_spec-view = 관전자 보기 + +game_special-mu-count = {$available} 메모리 유닛 중 {$unused} {$mu-type} 미사용 + +game_stack = 스택 + +game_start = 게임 시작 + +game_start-turn = 차례 시작 + +game_stop-auto-pass = 자동-통과 우선 중지 + +game_subs = 서브루틴 + +game_tag-count = {$base} 태그 + +game_tag-count-additional = {$base} + {$additional} 태그 + +game_take-clicks = 클릭 가져가기 + +game_trace = 추적 + +game_trash-resource = 리소스 폐기 + +game_unimplemented = 미구현 + +game_unknown-phase = 미상 단계 + +game_unmute = 관전자 무시 해제 + +lobby_aborted = 연결에 실패함 + +lobby_cancel = 취소 + +lobby_chat = 채팅 + +lobby_closed-msg = 활동이 없어 게임 로비가 닫혔습니다. + +lobby_completion-rate = 게임 완료율 + +lobby_create = 생성 + +lobby_deck-selected = 덱 선택됨 + +lobby_delete = 게임 삭제 + +lobby_format = 포맷 + +lobby_game-count = {$cnt} 게임 + +lobby_game-count-filtered = {$cnt} 게임 (filtered) + +lobby_hidden = 관전자가 플레이어의 숨겨진 정보를 볼 수 있게 하기 + +lobby_invalid-password = 유효하지 않은 암호 + +lobby_join = 참여 + +lobby_leave = 떠나기 + +lobby_load-replay = 리플레이 불러오기 + +lobby_new-game = 새 게임 + +lobby_no-games = 게임 없음 + +lobby_not-allowed = 허용되지 않음 + +lobby_options = 옵션 + +lobby_password = 암호 + +lobby_password-error = 암호를 입력해주십시오. + +lobby_password-for = 암호 입력 + +lobby_password-protected = 암호로 보호 + +lobby_players = 플레이어 + +lobby_private = 비공개 + +lobby_rejoin = 재참여 + +lobby_reload = 리스트 갱신 + +lobby_replay-invalid-file = 유효한 리플레이 파일을 선택하십시오. + +lobby_replay-link-error = 리플레이 링크가 유효하지 않습니다. + +lobby_reset = 게임 제목 리셋 + +lobby_save-replay = 리플레이 저장 + +lobby_select-deck = 덱 선택 + +lobby_select-title = 덱을 선택하십시오 + +lobby_side = 사이드 + +lobby_spectator-count = {$cnt} 관전자 + +lobby_spectators = 관전 허용 + +lobby_start = 시작 + +lobby_start-replay = 리플레이 재생 + +lobby_swap = 사이드 바꾸기 + +lobby_title = 방 제목 + +lobby_title-error = 게임 제목을 입력해주십시오. + +lobby_too-little-data = 데이터가 너무 적음 + +lobby_type = {$type -> + [angel-arena] undefined + [casual] 캐주얼 + [competitive] = 경쟁 + [tournament] 토너먼트 + *[other] undefined +} + +lobby_waiting = 플레이어가 덱을 고르고 있습니다 + +lobby_watch = 관전 + +log_annotating = 주석 + +log_game-log = 게임 로그 + +log_remote-annotations-fail = 원격 주석을 가져올 수 없습니다. + +log_shared = 공유된 주석 + +menu_admin = 운영자 + +menu_logout = 잭 아웃 + +menu_moderator = 중재자 + +menu_settings = 설정 + +nav_about = 진테키넷 + +nav_admin = 운영자 + +nav_cards = 카드 + +nav_chat = 채팅 + +nav_deck-builder = 덱 빌더 + +nav_features = 기능 + +nav_game-count = {$cnt} 게임 + +nav_help = 도움말 + +nav_play = 플레이 + +nav_settings = 설정 + +nav_stats = 기록 + +nav_tournaments = 대회 + +nav_users = 사용자 + +pronouns = {$pronoun -> + [any] 아무렇게나 + [blank] [빈 칸] + [ey] Ey/em + [faefaer] undefined + [he] He/him + [heit] undefined + [heshe] undefined + [hethey] He/they + [it] It + [myodb] 부르지 않는걸 선호함 + [ne] Ne/nem + *[none] 미정 + [she] She/her + [sheit] undefined + [shethey] She/they + [they] They/them + [ve] Ve/ver + [xe] Xe/xem + [xi] undefined + [zehir] Ze/hir + [zezir] Ze/zir +} + +settings_alt-art = 대체 아트 + +settings_always = 항상 기록 + +settings_avatar = 아바타 + +settings_background = 게임판 배경 + +settings_block = 사용자 차단 + +settings_blocked = 차단한 사용자 + +settings_cancel = 취소 + +settings_card-backs = 카드 뒷면 + +settings_card-images = 카드 이미지 + +settings_change-avatar = gravatar.com에서 변경하기 + +settings_change-email = 이메일 변경 + +settings_comp-only = 경쟁 로비에서만 + +settings_current-email = 현재 이메일 + +settings_deck-stats = 덱 기록 + +settings_desired-email = 사용할 이메일 + +settings_email = 이메일 + +settings_email-placeholder = 이메일 주소 + +settings_email-title = 이메일 주소 변경 + +settings_enable-game-sounds = 게임 음향 활성화 + +settings_enable-lobby-sounds = 로비 음향 활성화 + +settings_enter-valid = 유효한 이메일을 입력하십시오 + +settings_ffg = FFG + +settings_game-stats = 게임 승/패 기록 + +settings_get-log-top = 현재 로그 높이 입력 + +settings_get-log-width = 현재 로그 너비 입력 + +settings_high-res = 고해상도 카드 이미지 활성화 + +settings_invalid-email = 이 이메일 주소로 등록된 계정이 없습니다 + +settings_invalid-password = 유효하지 않은 로그인 또는 암호 + +settings_language = 언어 + +settings_layout-options = 레이아웃 옵션 + +settings_none = 기록 안함 + +settings_nsg = NSG + +settings_pronouns = 인칭 대명사 + +settings_reset = 공식 아트로 되돌리기 + +settings_runner-classic = 클래식 진테키넷 러너 리그 (위에서부터: 프로그램, 하드웨어, 리소스) + +settings_runner-layout = 기업 위치 러너 레이아웃 + +settings_runner-reverse = 반전된 러너 리그 (위에서부터: 리소스, 하드웨어, 프로그램) + +settings_set = 설정 + +settings_set-all = 모든 카드를 다음과 같이 설정 + +settings_show-alt = 대체 아트 보기 + +settings_sounds = 음향 + +settings_stacked-cards = 서버 스태킹이 기본으로 설정됨 + +settings_update = 업데이트 + +settings_update-profile = 프로필 갱신 + +settings_updated = 프로필 갱신됨 - 브라우저를 새로고침 하십시오 + +settings_updating = 프로필 갱신중... + +settings_user-name = 사용자 이름 + +settings_volume = 볼륨 + +side_name = {$side -> + [all] 모두 + [any-side] 모든 사이드 + [corp] 기업 + [runner] 러너 + *[unknown] undefined +} + +stats_all-games = 모든 게임 보기 + +stats_cards-accessed = 액세스한 카드 + +stats_cards-click = 클릭으로 뽑은 카드 + +stats_cards-drawn = 뽑은 카드 + +stats_cards-rezzed = 레즈된 카드 + +stats_clear-stats = 기록 초기화 + +stats_clicks-gained = 얻은 클릭 + +stats_completed = 완료됨: {$completed} ({NUMBER($percent, style: "percent")}) + +stats_corp-stats = 기업 기록 + +stats_credits-click = 클릭으로 얻은 크레딧 + +stats_credits-gained = 얻은 크레딧 + +stats_credits-spent = 사용한 크레딧 + +stats_damage-done = 입힌 피해 + +stats_download = 리플레이 다운로드 + +stats_ended = 종료됨 + +stats_format = 포맷 + +stats_game-stats = 게임 기록 + +stats_game-title = {$title} ({$cnt} 차례) + +stats_launch = 리플레이 실행 + +stats_lobby = 로비 + +stats_log-count = {$cnt} 로그 + +stats_log-count-filtered = {$cnt} 로그 (필터됨) + +stats_lost = 패배: {$lost} ({NUMBER($percent, style: "percent")}) + +stats_no-games = 게임 없음 + +stats_no-log = 사용 가능한 로그가 없습니다 + +stats_not-completed = 완료되지 않음: {$completed} ({NUMBER($percent, style: "percent")}) + +stats_runner-stats = 러너 기록 + +stats_runs-made = 런 시도 + +stats_share = 리플레이 공유 + +stats_shared-games = 공유된 게임만 보기 + +stats_started = 시작됨: {$started} + +stats_tags-gained = 얻은 태그 + +stats_unavailable = 리플레이를 사용할 수 없음 + +stats_view-games = 기록 화면으로 돌아가기 + +stats_view-log = 로그 보기 + +stats_win-method = 승리 방법 + +stats_winner = 승자 + +stats_won = 승리: {$won} ({NUMBER($percent, style: "percent")}) diff --git a/resources/public/i18n/la-pig.ftl b/resources/public/i18n/la-pig.ftl new file mode 100644 index 0000000000..e08dca41c7 --- /dev/null +++ b/resources/public/i18n/la-pig.ftl @@ -0,0 +1,936 @@ +card-browser-form_faction = Actionfay + +card-browser-form_format = Ormatfay + +card-browser-form_search-hint = Earchsay ardscay + +card-browser-form_side = Idesay + +card-browser-form_sort = Ortsay ybay + +card-browser-form_sort-by = {$by -> + [cost] Ostcay + [faction] Actionfay + [influence] Influenceyay + [name] Amenay + [set-number] Etsay umbernay + [type] Etypay + *[unknown] undefined +} + +card-browser-form_type = Etypay + +card-browser_advancement = Advancementyay equirementray: {$requirement} + +card-browser_agenda-points = Agendayay ointspay: {$points} + +card-browser_clear = Earclay + +card-browser_cost = Ostcay: {$cost} + +card-browser_inf-limit = Influenceyay Imitlay: {$inf-limit} + +card-browser_influence = Influenceyay: {$influence} + +card-browser_memory = Emorymay: {$memory} + +card-browser_min-deck-size = Inimummay eckday izesay: {$min-deck-size} + +card-browser_select-art = Electsay Artyay + +card-browser_selected-art = Electedsay Altyay Artyay + +card-browser_set = Etsay + +card-browser_strength = Engthstr: {$strength} + +card-browser_trash-cost = Ashtray ostcay: {$trash-cost} + +card-browser_update-failure = Ailedfay otay Updateyay Artyay + +card-browser_update-success = Updatedyay Artyay + +card-type_name = {$type -> + [agenda] Agendayay + [all] Allyay + [asset] Assetyay + [event] Eventyay + [hardware] Ardwarehay + [ice] Iceyay + [identity] Identityay + [operation] Operationyay + [program] Ogrampray + [resource] Esourceray + [upgrade] Upgradeyay + *[unknown] undefined +} + +chat_block = Ockblay Useryay + +chat_cancel = Ancelcay + +chat_channels = Annelschay + +chat_delete = Eleteday Essagemay + +chat_delete-all = Eleteday Allyay Essagesmay Omfray Useryay + +chat_placeholder = Aysay omethingsay... + +chat_send = Endsay + +chat_title = Ayplay Etrunnernay inyay ouryay owserbray + +deck-builder_add-cards = Addyay ardscay + +deck-builder_add-to-deck = Addyay otay eckday + +deck-builder_agenda-points = Agendayay ointspay + +deck-builder_cancel = Ancelcay + +deck-builder_card-count = ardscay + +deck-builder_card-name = Ardcay amenay + +deck-builder_clear-stats = Earclay Atsstay + +deck-builder_completed = Ompletedcay: {$completed} + +deck-builder_confirm-delete = Onfirmcay Eleteday + +deck-builder_create-game = Eatecray Amegay + +deck-builder_deck-count = {$cnt -> + [zero] Ohnay Ecksday + [one] {$cnt} Eckday + *[other] {$cnt} Ecksday +} + +deck-builder_deck-count-filtered = {$cnt -> + [zero] Ohnay Ecksday (ilteredfay) + [one] {$cnt} Eckday (ilteredfay) + *[other] {$cnt} Ecksday (ilteredfay) +} + +deck-builder_deck-name = Eckday Amenay + +deck-builder_deck-notes = Eckday otesnay + +deck-builder_deck-points = Eckday ointspay + +deck-builder_decklist = Ecklistday + +deck-builder_decklist-inst = (Ypetay oryay astepay ayay ecklistday, ityay illway ebay arsedpay) + +deck-builder_delete = Eleteday + +deck-builder_edit = Edityay + +deck-builder_format = Ormatfay + +deck-builder_games = Amesgay: {$games} + +deck-builder_hash = Ournamenttay ashhay + +deck-builder_identity = Identityay + +deck-builder_illegal = illegalyay + +deck-builder_import = Importyay + +deck-builder_import-button = Importyay Eckday + +deck-builder_import-placeholder = Bnrday idyay + +deck-builder_import-title = Enteryay ayay ublicpay bnrday eckday idyay oryay urlyay + +deck-builder_influence = Influenceyay + +deck-builder_legal = egallay + +deck-builder_loading-msg = Oadinglay eckday ollectioncay... + +deck-builder_lost = Ostlay: {$lost} + +deck-builder_max = aximummay + +deck-builder_min = inimummay + +deck-builder_min-deck-size = Inimummay eckday izesay + +deck-builder_new-corp = Ewnay Orpcay eckday + +deck-builder_new-runner = Ewnay Unnerray eckday + +deck-builder_notes = Otesnay + +deck-builder_reset = Esetray + +deck-builder_save = Avesay + +deck-builder_why = Whyay? + +deck-builder_won = Onway: {$won} ({NUMBER($percent, style: "percent")}) + +faction_name = {$faction -> + [adam] Adamyay + [all] Allyay + [anarch] Anarchyay + [any-faction] Anyay Actionfay + [apex] Apexyay + [criminal] Iminalcrimay + [haas-bioroid] Aashay-Ioroidbay + [jinteki] Intekijay + [nbn] NBNYAY + [neutral] Eutralnay + [shaper] Apershay + [sunny-lebeau] Unnsay Ebeaulay + [weyland-consortium] Eylandway Onsortiumcay + *[unknown] undefined +} + +format_name = {$format -> + [all] Allyay + [any-format] Anyay Ormatfay + [casual] Asualcay + [classic] Assicclay + [core-experience] Orecay Experienceyay + [eternal] Eternalyay + [neo] Neoyay + [preconstructed] undefined + [snapshot] Apshotsnay + [snapshot-plus] Apshotsnay Usplay + [socr] SOCRYAY + [standard] Andardstay + [startup] Artupstay + [sunset] Sunset + [system-gateway] Emsystay Atewaygay + [throwback] undefined + *[unknown] undefined +} + +game_abilities = Abilitiesyay + +game_actions = Actionsyay + +game_agenda-count = {$agenda-point -> + [one] {$agenda-point} Agendayay Ointpay + *[other] {$agenda-point} Agendayay Ointspay +} + +game_agenda-count-with-req = {$agenda-point -> + [one] {$agenda-point} Agendayay Ointpay ({$agenda-point-req} equiredray) + *[other] {$agenda-point} Agendayay Ointspay ({$agenda-point-req} equiredray) +} + +game_approach-ice = Approachyay iceyay + +game_archives = Archivesyay{"\u00A0"}({$faceup} ↑ {$facedown} ↓) + +game_auto-pass = Autoyay-asspay ioritypriay + +game_bad-pub-count = {$base} Adbay Ublicitypay + +game_bad-pub-count-additional = {$base} + {$additional} Adbay Ublicitypay + +game_brain-damage = Ainbray Amageday + +game_breach-server = Eachbray erversay + +game_card = Ardcay + +game_card-count = {$cnt -> + [one] {$cnt} ardcay + *[other] {$cnt} ardscay +} + +game_click-count = {$click -> + [one] {$click} Ickclay + *[other] {$click} Icksclay +} + +game_close = Oseclay + +game_close-shuffle = Osecla & Uffleshay + +game_concede = Oncedecay + +game_continue = Ontinuecay + +game_continue-to = Ontinuecay otay {$phase} + +game_corp-view = Orpcay Iewvay + +game_credit-count = {$credit -> + [one] Editcray + *[other] Editscray +} + +game_credit-count-with-run-credits = {$credit -> + [one] Editcray ({$run-credit} orfay unray) + *[other] Editscray ({$run-credit} orfay unray) +} + +game_credits = editscray + +game_current = Urrentcay + +game_current-phase = Urrentcay asephay + +game_draw = Awdray + +game_encounter-ice = Encounteryay iceyay + +game_end-turn = Endyay Urntay + +game_face-down-count = {$total} ardscay, {$facedown} acefay-ownday. + +game_fire-unbroken = Irefay unbrokenyay ubroutinessay + +game_gain-credit = Aingay Editcray + +game_game-start = Amegay Artstay: {$timestamp} + +game_grip = Ipgray + +game_heap = Eaphay ({$cnt}) + +game_hq = HQYAY + +game_inactivity = Amegay osedclay ueday otay inactivityay + +game_indicate-action = Indicateyay actionyay + +game_initiation = Initiationyay + +game_jack-out = Ackjay Outyay + +game_keep = Eepkay + +game_leave = Eavelay Amegay + +game_leave-replay = Eavelay Eplayray + +game_let-subs-fire = Etlay allyay okenunbray ubroutinessay irefay + +game_link-strength = Inklay Engthstray + +game_mandatory-draw = Andatorymay Awdray + +game_max-hand = {$total} Axmay andhay izesay + +game_movement = Ovementmay + +game_mu-count = (fn [[unused available]] (str unused " ofyay " available " UMYAY unusedyay")) + +game_mulligan = Ulliganmay + +game_mute = Utemay ectatorsspay + +game_no-current-run = Onay urrentcay unray + +game_no-further = Onay urtherfay actionsyay + +game_play-area = Ayplay Areayay + +game_prompt = {$msg -> + [advance] advanceyay + [archives] Archivesyay + [derez] erezday + [expend] Expendyay + [hq] HQYAY + [new-remote] Ewnay Emoteray + [r-d] R&DYAY + [rez] ezray + [score] orescay + [server-1] Erversay 1 + [server-10] Erversay 10 + [server-2] Erversay 2 + [server-3] Erversay 3 + [server-4] Erversay 4 + [server-5] Erversay 5 + [server-6] Erversay 6 + [server-7] Erversay 7 + [server-8] Erversay 8 + [server-9] Erversay 9 + [trash] ashtray + *[unknown] undefined +} + +game_purge = Urgepay + +game_remove-tag = Emoveray Agtay + +game_rez = Ezray + +game_rfg = Emovedray omfray ethay amegay + +game_rnd = R&DYAY + +game_run = Unray + +game_run-ends = Unray endsyay + +game_runner-view = Unnerray Iewvay + +game_scored-area = Oredscay Areayay + +game_server = Erversay {$num} + +game_show = Owshay + +game_shuffle = Uffleshay + +game_spec-count = (fn [[c]] (str c " Ectatorspay" (when (> c 1) "s"))) + +game_spec-view = Ectatorspay Iewvay + +game_special-mu-count = (fn [[unused available mu-type]] (str unused " ofyay " available " " mu-type " UMYAY unusedyay")) + +game_stack = Ackstay + +game_start = Artstay Amegay + +game_start-turn = Artstay Urntay + +game_stop-auto-pass = Opstay autoyay-assingpay ioritypray + +game_subs = Ubroutinessay + +game_success = Uccesssay + +game_tag-count = (fn [[base additional total]] (str base (when (pos? additional) (str " + " additional)) " Agtay" (if (not= total 1) "s" ""))) + +game_tag-count-additional = {$additional -> + [one] {$base} + {$additional} Agtay + *[others] {$base} + {$additional} Agtays +} + +game_take-clicks = Aketay Icksclay + +game_time-taken = Imetay akentay: {$time} inutesmay + +game_trace = Acetray + +game_trash-resource = Ashtray Esourceray + +game_unimplemented = Unimplementedyay + +game_unknown-phase = Unknownyay asephay + +game_unmute = Unmuteyay ectatorsspay + +game_win-claimed = {$winner} ({$side}) insway ybay laimcay onyay urntay {$turn} + +game_win-conceded = {$winner} ({$side}) insway ybay oncessionay onyay urntay {$turn} + +game_win-decked = {$winner} ({$side}) insway ueday otay ethay Orpcay eingbay eckedday onyay urntay {$turn} + +game_win-flatlined = {$winner} ({$side}) insway ybay atlineflay onyay urntay {$turn} + +game_win-other = {$winner} ({$side}) insway ybay {$reason} onyay urntay {$turn} + +game_win-points = {$winner} ({$side}) insway ybay oringcay agendayay ointspay onyay urntay {$turn} + +lobby_aborted = Onnectioncay abortedyay + +lobby_cancel = Ancelcay + +lobby_chat = Atchay + +lobby_closed-msg = Amegay obbylay osedclay ueday otay inactivityay + +lobby_completion-rate = Amegay Ompletioncay Ateray + +lobby_create = Eatecray + +lobby_deck-selected = Eckday electedsay + +lobby_delete = Eleteday Amegay + +lobby_format = Ormatfay + +lobby_game-count = {$cnt -> + [one] {$cnt} Amegay + *[other] {$cnt} Amesgay +} + +lobby_game-count-filtered = {$cnt -> + [one] {$cnt} Amegay (ilteredfay) + *[other] {$cnt} Amesgay (ilteredfay) +} + +lobby_gateway-format = {$format -> + [beginner] eginnerbay + [beginner-info] Isthay obbylay isyay usingyay ethay emsystay atewaygay eginnerbay ecksday orfay ethay orporationcay andyay unnerray . esethay ecksday areyay ecommendedray orfay ouryay irstfay amesgay . amesgay areyay ayedplay otay 6 agendayay ointspay. + [beginner-ul] Emsystay atewaygay - eginnerbay eachingtay decks + [constructed] Onstructedcay + [intermediate] Intermediateyay + [intermediate-info] Isthay obbylay isyay usingyay ethay emsystay atewaygay intermediateyay ecksday orfay ethay orporationcay andyay unnerray. esethay ecksday avehay ightlyslay oremay angeray anthay ethay eginnerbay ecksday. amesgay areyay ayedplay otay 7 agendayay ointspay. + [intermediate-ul] Emsystay atewaygay - intermediateyay eachingtay decks + *[unknown] undefined +} + +lobby_hidden = Akemay ayersplay iddenhay informationyay isiblevay otay ectatorsspay + +lobby_invalid-password = Nvalidiay asswordpay + +lobby_join = Oinjay + +lobby_leave = Eavelay + +lobby_load-replay = Oadlay Eplayray + +lobby_new-game = Ewnay amegay + +lobby_no-games = Onay amesgay + +lobby_not-allowed = Otnay allowedyay + +lobby_options = Optionsyay + +lobby_password = Asswordpay + +lobby_password-error = Easepl illfay ayay asswordpay. + +lobby_password-for = Asswordpay orfay + +lobby_password-protected = Asswordpay otectedpray + +lobby_players = Ayersplay + +lobby_private = IVATEPRAY + +lobby_rejoin = Ejoinray + +lobby_reload = Eloadray istlay + +lobby_replay-invalid-file = Electsay ayay alidvay eplayray ilefay. + +lobby_replay-link-error = Eplayray inklay invalidyay. + +lobby_reset = Esetray Amegay Amenay + +lobby_save-replay = Avesay Eplayray + +lobby_select-deck = Electsay eckday + +lobby_select-title = Electsay ouryay eckday + +lobby_side = Idesay + +lobby_spectator-count = (fn [[cnt]] (str cnt " Ectatorspay" (when (not= cnt 1) "s"))) + +lobby_spectators = Allowyay ectatorsspay + +lobby_start = Artstay + +lobby_start-replay = Artst Eplayray + +lobby_swap = Apsway idessay + +lobby_title = Itletay + +lobby_title-error = Easeplay illfay ayay amegay itletay. + +lobby_too-little-data = Ootay ittlelay ataday + +lobby_type = {$type -> + [angel-arena] Angelyay Arenayay + [casual] Asualcay + [competitive] Ompetitivecay + [tournament] Ournamenttay + *[unknown] undefined +} + +lobby_waiting = Aitingway ayersplay eckday electionsay + +lobby_watch = Atchway + +menu_admin = {nav_admin} + +menu_donor = Onorday + +menu_logout = Ackjay outyay + +menu_moderator = Oderatormay + +menu_settings = {nav_settings} + +nav_about = Aboutyay + +nav_admin = Adminyay + +nav_cards = Ardscay + +nav_chat = Atchay + +nav_deck-builder = Eckday Uilderbay + +nav_features = Eaturesfay + +nav_game-count = {$cnt -> + [one] {$cnt} Amegay + *[other] {$cnt} Amesgay +} + +nav_help = Elphay + +nav_play = Ayplay + +nav_settings = Ettingssay + +nav_stats = Atsstay + +nav_tournaments = Ournamentstay + +nav_users = Usersyay + +pronouns = {$pronoun -> + [any] Anyay + [blank] [ankblay] + [ey] Eyay/emay + [faefaer] undefined + [he] Ehay/imhay + [heit] undefined + [heshe] undefined + [hethey] Ehay/eythay + [it] Ityay + [myodb] Eferpray otnay otay aysay + [ne] Enay/emnay + *[none] Unspecifiedyay + [she] Eshay/erhay + [sheit] undefined + [shethey] Eshay/eythay + [they] Eythay/emthay + [ve] Evay/ervay + [xe] Exay/emxay + [xi] undefined + [zehir] Ezay/irhay + [zezir] Ezay/irzay +} + +set_name = {$name -> + [a23-seconds] undefined + [a-study-in-static] undefined + [all] undefined + [all-that-remains] undefined + [alt-art] undefined + [alternate] undefined + [ashes-cycle] undefined + [blood-and-water] undefined + [blood-money] undefined + [borealis-cycle] undefined + [breaker-bay] undefined + [business-first] undefined + [championship-2019] undefined + [championship-2020] undefined + [chrome-city] undefined + [core-set] undefined + [council-of-the-crest] undefined + [creation-and-control] undefined + [crimson-dust] undefined + [cyber-exodus] undefined + [daedalus-complex] undefined + [data-and-destiny] undefined + [democracy-and-dogma] undefined + [double-time] undefined + [down-the-white-nile] undefined + [downfall] undefined + [draft] undefined + [draft-cycle] undefined + [earth-s-scion] undefined + [escalation] undefined + [fear-and-loathing] undefined + [fear-the-masses] undefined + [first-contact] undefined + [flashpoint-cycle] undefined + [free-mars] undefined + [future-proof] undefined + [genesis-cycle] undefined + [gnk-2019] undefined + [honor-and-profit] undefined + [humanity-s-shadow] undefined + [intervention] undefined + [kala-ghoda] undefined + [kampala-ascendent] undefined + [kitara-cycle] undefined + [kysra-alt-arts] undefined + [liberation-cycle] undefined + [lunar-cycle] undefined + [magnum-opus] undefined + [magnum-opus-reprint] undefined + [mala-tempora] undefined + [martial-law] undefined + [midnight-sun] undefined + [midnight-sun-booster-pack] undefined + [mumbad-cycle] undefined + [napd-multiplayer] undefined + [ntscape-navigator-alt-arts] undefined + [old-hollywood] undefined + [opening-moves] undefined + [order-and-chaos] undefined + [parhelion] undefined + [plural-and-miniplural-alt-arts] undefined + [previous-versions] undefined + [quorum] undefined + [rebellion-without-rehearsal] undefined + [red-sand-cycle] undefined + [reign-and-reverie] undefined + [revised-core-set] undefined + [salsette-island] undefined + [salvaged-memories] undefined + [sansan-cycle] undefined + [second-thoughts] undefined + [signed-championship-2020] undefined + [sovereign-sight] undefined + [spin-cycle] undefined + [station-one] undefined + [system-core-2019] undefined + [system-gateway] undefined + [system-update-2021] undefined + [terminal-directive-campaign] undefined + [terminal-directive-cards] undefined + [terminal-directive-cycle] undefined + [the-automata-initiative] undefined + [the-devil-and-the-dragon] undefined + [the-liberated-mind] undefined + [the-source] undefined + [the-spaces-between] undefined + [the-underway] undefined + [the-universe-of-tomorrow] undefined + [the-valley] undefined + [trace-amount] undefined + [true-colors] undefined + [unreleased] undefined + [up-and-over] undefined + [uprising] undefined + [uprising-booster-pack] undefined + [upstalk] undefined + [what-lies-ahead] undefined + [whispers-in-nalubaale] undefined + [world-champion-2015] undefined + [world-champion-2016] undefined + [world-champion-2017] undefined + *[unknown] undefined +} + +settings_alt-art = Altyay artsyay + +settings_always = Alwaysyay + +settings_api-keys = APIYAY Eyskay + +settings_avatar = Avataryay + +settings_background = Amegay oardbay ackgroundbay + +settings_bespoke-sounds = {$sound -> + [archer] Archeryay + [end-of-the-line] Endyay ofyf ethay Inelay + [harmonics] Armonicshay Uitesay (Oopblay, Echoyay, Ulsepay, Aveway) + [header] Ardcay-Cificspay Oundssay + *[unknown] Unknownyay espokebay oundssay ({$sound}) +} + +settings_bg = {$slug -> + [apex] Apex + [custom] Ustomcay GBay (inputyay URLyay elowbay) + [find-the-truth] Indfay Ethay Uthtray + [freelancer] Eelancerfray + [monochrome] Onochromay + [mushin-no-shin] Ushinmay Onay Inshay + [push-your-luck] Ushpay Ouryay Ucklay + [rumor-mill] Umoray Illmay + [the-root] Ethay Ootray + [traffic-jam] Affictray Amjay + *[worlds2020] Orldsway 2020 +} + +settings_block = Ockblay useryay + +settings_blocked = Ockedblay usersyay + +settings_cancel = Ancelcay + +settings_card-backs = Ardcay acksbay + +settings_card-images = Ardcay imagesyay + +settings_change-avatar = Angechay onyay gravatar.com + +settings_change-email = Angechay emailyay + +settings_comp-only = Ompetitivecay Obbylay Onlyay + +settings_create-api-key = Eatecray APIYAY Eykay + +settings_current-email = Urrentcay emailyay + +settings_deck-stats = Eckday atisticsstay + +settings_delete-api-key = Eleteday + +settings_desired-email = Esiredday emailyay + +settings_email = Emailyay + +settings_email-placeholder = Emailyay addressyay + +settings_email-title = Angechay emailyay addressyay + +settings_enable-game-sounds = Enableyay amegay oundssay + +settings_enable-lobby-sounds = Enableyay obbylay oundssay + +settings_enter-valid = Easeplay enteryay ayay alidvay emailyay addressyay + +settings_ffg = FFGYAY + +settings_game-stats = Amegay Inway/Oselay atisticsstay + +settings_get-log-top = Etgay urrentcay oglay optay + +settings_get-log-width = Etgay urrentcay oglay idthway + +settings_high-res = Enabley ighhay-esolutionray ardcay imagesyay + +settings_invalid-email = Onay accountyay ithway atthay emailyay addressyay existsyay + +settings_invalid-password = Nvalidiay oginlay oryay asswordpay + +settings_language = Anguagelay + +settings_layout-options = Ayoutlay Optionsyay + +settings_none = Onenay + +settings_nsg = NSGYAY + +settings_pronouns = Onounspray + +settings_reset = Esetray Allyay otay Officialyay Artyay + +settings_runner-classic = Unnerray igray ayoutlay isyay assicclay etjnay (Optay otay ottombay: Ogramspr, Ardwarehay, Esourcesray) + +settings_runner-layout = Unnerray ayoutlay omfray Orpcay erspectivepray + +settings_runner-reverse = Unnerray iray ayoutlay isyay eversedray (Optay otay ottombay: Esourcesray, Ardwarehay, Ogramspray) + +settings_set = Etsay + +settings_set-all = Etsay allyay ardscay otay + +settings_show-alt = Owshay alternateyay ardcay artsyay + +settings_sounds = Oundssay + +settings_stacked-cards = Ardcay ackingstay (onyay ybyay efaultday) + +settings_update = Updateyay + +settings_update-profile = Updateyay Ofilepray + +settings_updated = Ofilepray updatedyay - Leasepay efreshray ouryay owserbray + +settings_updating = Updatingyay ofilepray... + +settings_user-name = Useryay amenay + +settings_volume = Olumevay + +side_name = {$side -> + [all] Allyay + [any-side] Anyay Idesay + [corp] Orpcay + [runner] Unnerray + *[unknown] undefined +} + +stats_all-games = Owshay allyay amesgay + +stats_cards-accessed = Ardscay Accessedyay + +stats_cards-click = Ardscay Awndray ybay Ickclay + +stats_cards-drawn = Ardscay Awndray + +stats_cards-rezzed = Ardscay Ezzedray + +stats_clear-stats = Earclay Atsstay + +stats_clicks-gained = Icksclay Ainedgay + +stats_completed = Ompletedcay: {$completed} ({NUMBER($percent, style: "percent")}) + +stats_corp-stats = Orpcay Atsstay + +stats_credits-click = Editscray ybay Ickclay + +stats_credits-gained = Editscray Ainedgay + +stats_credits-spent = Editscray Entspay + +stats_damage-done = Amageday Oneday + +stats_download = Ownloadday eplayray + +stats_ended = Endedyay + +stats_format = Ormatfay + +stats_game-stats = Amegay Atsstay + +stats_game-title = {$title} ({$cnt -> + [one] {$cnt} urntay + *[other] {$cnt} urnstay +}) + +stats_launch = Aunchlay Eplayray + +stats_lobby = Obbylay + +stats_log-count = {$cnt -> + [one] {$cnt} Oglay + *[other] {$cnt} Ogslay +} + +stats_log-count-filtered = {$cnt -> + [one] {$cnt} Oglay + *[other] {$cnt} Ogslay +} (ilteredfay) + +stats_lost = Ostlay: {$lost} ({NUMBER($percent, style: "percent")}) + +stats_no-games = Onay amesgay + +stats_no-log = Onay oglay availableyay + +stats_not-completed = Otnay ompletedcay: {$completed} ({NUMBER($percent, style: "percent")}) + +stats_replay-shared = Eeplayray aredshay + +stats_runner-stats = Unnerray Atsstay + +stats_runs-made = Unsray Ademay + +stats_share = Areshay eplayray + +stats_shared-games = Onlyay owshay aredshay + +stats_started = Artedstay: {$started} + +stats_tags-gained = Agstay Ainedgay + +stats_unavailable = Eplayray unavailableyay + +stats_view-games = Eturnray otay atsstay eenscray + +stats_view-log = Iewvay oglay + +stats_win-method = Inway ethodmay + +stats_winner = Innerway + +stats_won = Onway: {$won} ({NUMBER($percent, style: "percent")}) diff --git a/resources/public/i18n/pl.ftl b/resources/public/i18n/pl.ftl new file mode 100644 index 0000000000..63c7b56fb6 --- /dev/null +++ b/resources/public/i18n/pl.ftl @@ -0,0 +1,759 @@ +annotations_available-annotations = Dostępne notatki + +annotations_clear = Wyczyść lokalne notatki + +annotations_click-placeholder = Notatki do tego kliknięcia + +annotations_import-local = Zaimportuj plik z notatkami + +annotations_load-local = Wczytaj + +annotations_no-published-annotations = Brak opublikowanych notatek. + +annotations_publish = Publikuj + +annotations_save-local = Zapisz + +annotations_turn-placeholder = Notatki do tej tury + +card-browser-form_faction = Frakcja + +card-browser-form_format = Format + +card-browser-form_search-hint = Szukaj kart + +card-browser-form_side = Strona + +card-browser-form_sort = Porządkowanie + +card-browser-form_sort-by = {$by -> + [cost] Koszt + [faction] Frakcja + [influence] Wpływ + [name] Nazwa + [set-number] Numer w zestawie + [type] Typ + *[unknown] undefined +} + +card-browser-form_type = Typ + +card-browser_advancement = Wymagany poziom rozwoju: {$requirement} + +card-browser_agenda-points = Punkty projektów: {$points} + +card-browser_clear = Wyczyść + +card-browser_cost = Koszt: {$cost} + +card-browser_inf-limit = Limit wpływu: {$inf-limit} + +card-browser_influence = Wpływ: {$influence} + +card-browser_memory = Pamięć: {$memory} + +card-browser_min-deck-size = Minimalny rozmiar talii: {$min-deck-size} + +card-browser_select-art = Wybierz grafiki + +card-browser_selected-art = Wybrano grafiki alt. + +card-browser_set = Zestaw + +card-browser_strength = Siła: {$strength} + +card-browser_trash-cost = Koszt skasowania: {$trash-cost} + +card-browser_update-failure = Nieudana aktualizacja grafiki + +card-browser_update-success = Grafiki zaktualizowane + +card-type_name = {$type -> + [agenda] Projekt + [all] Wszystkie + [asset] Aktywa + [event] Wydarzenie + [hardware] Sprzęt + [ice] Lód + [identity] Tożsamość + [operation] Operacja + [program] Program + [resource] Zasób + [upgrade] Ulepszenie + *[unknown] undefined +} + +chat_block = Zablokuj użytkownika + +chat_cancel = Anuluj + +chat_channels = Kanały + +chat_delete = Usuń wiadomość + +chat_delete-all = Usuń wszystkie wiadomości użytkownika + +chat_placeholder = Powiedz coś... + +chat_send = Wyślij + +chat_title = Graj w Netrunnera w przeglądarce + +deck-builder_add-cards = Dodaj karty + +deck-builder_add-to-deck = Dodaj do talii + +deck-builder_agenda-points = Punkty projektów + +deck-builder_cancel = Anuluj + +deck-builder_card-count = karty: {$cnt} + +deck-builder_card-name = Nazwa karty + +deck-builder_clear-stats = Usuń statystyki + +deck-builder_completed = Ukończone: {$completed} + +deck-builder_confirm-delete = Potwierdź usunięcie + +deck-builder_create-game = Stwórz stół + +deck-builder_deck-count = {$cnt -> + [zero] Brak talii + *[other] Talie: {$cnt} +} + +deck-builder_deck-count-filtered = {$cnt -> + [zero] Brak talii (filtrowane) + *[other] Talie: {$cnt} (filtrowane) +} + +deck-builder_deck-name = Nazwa talii + +deck-builder_deck-notes = Notatki + +deck-builder_deck-points = Punkty talii + +deck-builder_decklist = Lista kart + +deck-builder_decklist-inst = (Wpisz lub wklej listę kart z talii, zostanie przeanalizowana) + +deck-builder_delete = Usuń + +deck-builder_edit = Edytuj + +deck-builder_format = Format + +deck-builder_games = Gry: {$games} + +deck-builder_hash = Kod turniejowy + +deck-builder_identity = Tożsamość + +deck-builder_illegal = nielegalny + +deck-builder_import = Importuj + +deck-builder_import-button = Zaimportuj talię + +deck-builder_import-placeholder = ID z NRDB + +deck-builder_import-title = Wpisz ID lub URL talii z NRDB (musi być opublikowana) + +deck-builder_influence = Wpływ + +deck-builder_legal = legalny + +deck-builder_loading-msg = Ładowanie kolekcji talii... + +deck-builder_lost = Przegrane: {$lost} + +deck-builder_max = maks. + +deck-builder_min = min. + +deck-builder_new-corp = Nowa talia Korpo + +deck-builder_new-runner = Nowa talia Runnera + +deck-builder_notes = Notatki + +deck-builder_reset = Zresetuj + +deck-builder_save = Zapisz + +deck-builder_why = Dlaczego? + +deck-builder_won = Wygrane: {$won} ({NUMBER($percent, style: "percent")}) + +faction_name = {$faction -> + [adam] Adam + [all] Wszystkie + [anarch] Anarchowie + [any-faction] Dowolna frakcja + [apex] Apex + [criminal] Kryminale + [haas-bioroid] Haas-Bioroid + [jinteki] Jinteki + [nbn] NBN + [neutral] Neutralne + [shaper] Kształcerze + [sunny-lebeau] Sunny Lebeau + [weyland-consortium] Weyland Consortium + *[unknown] undefined +} + +format_name = {$format -> + [all] All + [any-format] Dowolny format + [casual] Niekompetytywny + [classic] Classic + [core-experience] Core Experience + [eternal] Eternal + [neo] Neo + [preconstructed] undefined + [snapshot] Snapshot + [snapshot-plus] Snapshot Plus + [socr] SOCR + [standard] Standard + [startup] Startup + [sunset] Sunset + [system-gateway] Wejście do Systemu + [throwback] undefined + *[unknown] undefined +} + +game_abilities = Opcje + +game_actions = Akcje + +game_agenda-count = Punkty projektów: {$agenda-point} + +game_approach-ice = Zbliżenie do lodu + +game_archives = Archiwum{"\u00A0"}({$faceup} ↑ {$facedown} ↓) + +game_auto-pass = Priorytet auto-mijania + +game_bad-pub-count = Zła prasa: {$base} + +game_bad-pub-count-additional = Zła prasa: {$base} + {$additional} + +game_brain-damage = Obrażenia mózgu + +game_breach-server = Przebicie do serwera + +game_card = Karta + +game_card-count = Karty: {$cnt} + +game_click-count = Kliki: {$click} + +game_close = Zamknięcie + +game_close-shuffle = Zamknięcie i przetasowanie + +game_concede = Poddanie się + +game_continue = Kontynuacja + +game_continue-to = Kontynuacja do {$phase} + +game_corp-view = Perspektyw Korpo + +game_credit-count = Kredyty: {$credit} + +game_credit-count-with-run-credits = Kredyty: {$credit} ({$run-credit} na włam) + +game_credits = kred. + +game_current = Wątek + +game_current-phase = Aktualna faza + +game_draw = Dobranie karty + +game_encounter-ice = Napotkanie lodu + +game_end-turn = Zakończenie tury + +game_face-down-count = Karty: {$total}, awersem w dół: {$facedown} + +game_fire-unbroken = Użycie niezłamanych poleceń + +game_gain-credit = Zyskanie 1 kredytu + +game_game-start = Rozpoczęcie gry: {$timestamp} + +game_grip = Garść + +game_heap = Sterta ({$cnt}) + +game_hq = KG + +game_inactivity = Gra zakończona z powodu braku aktywności + +game_indicate-action = Zgłoszenie działania + +game_initiation = Rozpoczęcie + +game_jack-out = Wylogowanie się + +game_keep = Zachowanie + +game_leave = Wyjście z gry + +game_leave-replay = Wyjście z powtórki + +game_let-subs-fire = Pozwolenie na użycie niezłamanych poleceń + +game_link-strength = Łącze + +game_mandatory-draw = Przymusowe dobranie + +game_max-hand = {$total} Maks. ilość kart + +game_movement = Ruch + +game_mu-count = Wolne: {$unused} z {$available} JP + +game_mulligan = Wymiana + +game_mute = Wyłączenie czat widowni + +game_no-current-run = Brak włamu w toku + +game_no-further = Brak dalszych działań + +game_play-area = Zagrywane + +game_purge = Usunięcie wirusów + +game_remove-tag = Usunięcie 1 namiaru + +game_rez = Aktywacja + +game_rfg = Usunięte z gry + +game_rnd = DBR + +game_run = Rozpoczęcie włamu + +game_run-ends = Włam się kończy + +game_runner-view = Perspektywa Runnera + +game_scored-area = Punktacja + +game_server = Serwer {$num} + +game_show = Pokazanie + +game_shuffle = Przetasowanie + +game_spec-count = Widownia: {$cnt} + +game_spec-view = Perspektywa widowni + +game_special-mu-count = Wolne: {$unused} z {$available} {$mu-type} JP + +game_stack = Stos + +game_start = Rozpoczęcie gry + +game_start-turn = Rozpoczęcie tury + +game_stop-auto-pass = Wyłączenie priorytetu auto-mijania + +game_subs = Polecenia + +game_success = Sukces + +game_tag-count = Namiar : {$base} + +game_tag-count-additional = Namiar : {$base} + {$additional} + +game_take-clicks = Rozpoczęcie kliknięć + +game_time-taken = Czas gry: {$time} min + +game_trace = Namiar + +game_trash-resource = Skasowanie 1 zasobu + +game_unimplemented = Niezautomatyzowana + +game_unknown-phase = Nieznana faza + +game_unmute = Włączenie czat widowni + +game_win-claimed = {$winner} ({$side}) wygrywa przez zgłoszenie wygranej w {$turn} turze + +game_win-conceded = {$winner} ({$side}) wygrywa przez poddanie się przeciwnika w {$turn} turze + +game_win-decked = {$winner} ({$side}) wygrywa, ponieważ Korpo skończyły się karty w {$turn} turze + +game_win-flatlined = {$winner} ({$side}) wygrywa przez wypłaszczenie w {$turn} turze + +game_win-other = {$winner} ({$side}) wygrywa przez {$reason} w {$turn} turze + +game_win-points = {$winner} ({$side}) wygrywa przez zdobycie punktów zwycięstwa w {$turn} turze + +lobby_aborted = Połączenie przerwane + +lobby_api-access = Zezwól na dostęp API do danych rozgrywki + +lobby_api-requires-key = (Wymaga podania klucza API w ustawieniach) + +lobby_as-corp = jako Korpo + +lobby_as-runner = jako Runner + +lobby_cancel = Anuluj + +lobby_chat = Czat + +lobby_closed-msg = Poczekalnia zamknięta z powodu braku aktywności + +lobby_completion-rate = Procent zakończonych gier + +lobby_create = Stwórz + +lobby_deck-selected = Talia wybrana + +lobby_delete = Usuń stół + +lobby_format = Format + +lobby_game-count = Gry: {$cnt} + +lobby_game-count-filtered = Gry: {$cnt} (filtrowane) + +lobby_hidden = Ukryte informacje graczy widoczne dla widzów + +lobby_invalid-password = Nieprawidłowe hasło + +lobby_join = Dołącz + +lobby_leave = Wyjdź + +lobby_load-replay = Wczytaj powtórkę + +lobby_new-game = Nowa gra + +lobby_no-games = Brak gier + +lobby_not-allowed = Niedozwolone + +lobby_options = Opcje + +lobby_password = Hasło + +lobby_password-error = Wpisz hasło + +lobby_password-for = Hasło dla + +lobby_password-protected = Ochrona hasłem + +lobby_players = Gracze + +lobby_private = PRYWATNY + +lobby_rejoin = Wróć + +lobby_reload = Odśwież listę + +lobby_replay-invalid-file = Wybierz prawidłowy plik powtórki. + +lobby_replay-link-error = Nieprawidłowy URL powtórki. + +lobby_reset = Zresetuj nazwę stołu + +lobby_save-replay = Zapisz powtórkę + +lobby_select-deck = Wybierz talię + +lobby_select-title = Wybierz talię + +lobby_side = Strona + +lobby_spectator-count = Widownia: {$cnt} + +lobby_spectators = Dozwoleni widzowie + +lobby_start = Rozpocznij + +lobby_start-replay = Rozpocznij powtórkę + +lobby_swap = Zmień stronę + +lobby_title = Tytuł + +lobby_title-error = Wpisz nazwę dla stołu. + +lobby_too-little-data = Zbyt mało danych + +lobby_type = {$type -> + [competitive] Kompetytywne + [casual] Niekompetytywne + [tournament] Wydarzenia + *[unknown] undefined +} + +lobby_waiting = Oczekiwanie na wybór talii + +lobby_watch = Oglądaj + +log_annotating = Notatki + +log_game-log = Dziennik gry + +log_remote-annotations-fail = Nieudane pobranie zdalnych notatek. + +log_shared = Udostępnione notatki + +menu_admin = {nav_admin} + +menu_logout = Wylogowanie + +menu_moderator = Moderator + +menu_settings = {nav_settings} + +nav_about = Informacje + +nav_admin = Administracja + +nav_cards = Karty + +nav_chat = Czat + +nav_deck-builder = Tworzenie talii + +nav_features = Cechy + +nav_game-count = Gry: {$cnt} + +nav_help = Pomoc + +nav_play = Graj + +nav_settings = Ustawienia + +nav_stats = Statystyki + +nav_tournaments = Turnieje + +nav_users = Użytkownicy + +pronouns = {$pronoun -> + [any] dowolne + [blank] [puste] + [ey] ey/em + [faefaer] undefined + [he] on/jego + [heit] undefined + [heshe] undefined + [hethey] on/ich + [it] ono + [myodb] bez szczegółów + [ne] ne/nem + [none] nieokreślone + [she] ona/jej + [sheit] undefined + [shethey] ona/ich + [they] oni/ich + [ve] ve/ver + [xe] xe/xem + [xi] undefined + [zehir] ze/hir + [zezir] ze/zir + *[unknown] undefined +} + +settings_alt-art = Alternatywne grafiki + +settings_always = Zawsze + +settings_api-keys = Klucze API + +settings_avatar = Awatar + +settings_background = Tło stołu + +settings_block = Zablokuj użytkownika + +settings_blocked = Zablokowani użytkownicy + +settings_cancel = Anuluj + +settings_card-backs = Rewersy kart + +settings_card-images = Obrazy kart + +settings_change-avatar = Zmień na stronie gravatar.com + +settings_change-email = Zmień adres e-mail + +settings_comp-only = Tylko w grach kompetytywnych + +settings_create-api-key = Stwórz klucz API + +settings_current-email = Aktualny e-mail + +settings_deck-stats = Statystyki talii + +settings_delete-api-key = Usuń + +settings_desired-email = Nowy e-mail + +settings_email = E-mail + +settings_email-placeholder = Adres e-mail + +settings_email-title = Zmień adres e-mail + +settings_enable-game-sounds = Włącz dźwięki gry + +settings_enable-lobby-sounds = Włącz dźwięki poczekalni + +settings_enter-valid = Podaj poprawny adres e-mail + +settings_ffg = FFG + +settings_game-stats = Statystyki wygranych/przegranych + +settings_get-log-top = Pobierz aktualną wysokość dziennika + +settings_get-log-width = Pobierz aktualną szerokość dziennika + +settings_high-res = Użyj obrazów kart o wysokiej rozdzielczości + +settings_invalid-email = Brak konta z tym adresem e-mail + +settings_invalid-password = Nieprawidłowa nazwa lub hasło + +settings_language = Język + +settings_layout-options = Opcje układu stołu + +settings_none = Nigdy + +settings_nsg = NSG + +settings_pronouns = Zaimki osobowe + +settings_reset = Zresetuj wszystko do oficjalnych grafik + +settings_runner-classic = Karty Runnera w klasycznym stylu (od góry: Programy, Sprzęt, Zasoby) + +settings_runner-layout = Układ stołu Runnera ze strony Korpo + +settings_runner-reverse = Karty Runnera w odwróconym stylu (od góry: Zasoby, Sprzęt, Programy) + +settings_set = Ustaw + +settings_set-all = Ustaw wszystkie karty na + +settings_show-alt = Pokaż alternatywne grafiki kart + +settings_sounds = Dźwięki + +settings_stacked-cards = Grupowanie kart (domyślnie włączone) + +settings_update = Aktualizuj + +settings_update-profile = Aktualizuj profil + +settings_updated = Profil zaktualizowany - odśwież okno przeglądarki + +settings_updating = Aktualizacja profilu... + +settings_user-name = Nazwa użytkownika + +settings_volume = Głośność + +side_name = {$side -> + [all] Wszystkie + [any-side] Dowolna + [corp] Korpo + [runner] Runner + *[unknown] undefined +} + +stats_all-games = Pokaż wszystkie gry + +stats_cards-accessed = Dostępy do kart + +stats_cards-click = Karty dobrane przez kliknięcia + +stats_cards-drawn = Dobrane karty + +stats_cards-rezzed = Aktywowane karty + +stats_clear-stats = Wyczyść statystyki + +stats_clicks-gained = Zyskane kliknięcia + +stats_completed = Ukończono: {$completed} ({NUMBER($percent, style: "percent")}) + +stats_corp-stats = Statystyki: Korpo + +stats_credits-click = Kredyty zyskane przez kliknięcia + +stats_credits-gained = Zyskane kredyty + +stats_credits-spent = Wydane kredyty + +stats_damage-done = Zadane obrażenia + +stats_download = Pobierz powtórkę + +stats_ended = Zakończono + +stats_format = Format + +stats_game-stats = Statystyki gier + +stats_game-title = {$title} (Tura: {$cnt}) + +stats_launch = Uruchom powtórkę + +stats_lobby = Poczekalnia + +stats_log-count = Dzienniki: {$cnt} + +stats_log-count-filtered = Dzienniki: {$cnt} (filtrowane) + +stats_lost = Przegrano: {$lost} ({NUMBER($percent, style: "percent")}) + +stats_no-games = Brak gier + +stats_no-log = Brak dziennika + +stats_not-completed = Nie ukończono: {$completed} ({NUMBER($percent, style: "percent")}) + +stats_runner-stats = Statystyki: Runner + +stats_runs-made = Rozpoczęte włamów + +stats_share = Udostępnij powtórkę + +stats_shared-games = Pokaż jedynie udostępnione + +stats_started = Rozpoczęteo: {$started} + +stats_tags-gained = Otrzymane znaczniki namiaru + +stats_unavailable = Powtórka niemożliwa + +stats_view-games = Powrót do ekranu statystyk + +stats_view-log = Obejrzyj dziennik + +stats_win-method = Sposób wygranej + +stats_winner = Wygrana + +stats_won = Wygrano: {$won} ({NUMBER($percent, style: "percent")}) diff --git a/resources/public/i18n/pt.ftl b/resources/public/i18n/pt.ftl new file mode 100644 index 0000000000..c236c45a81 --- /dev/null +++ b/resources/public/i18n/pt.ftl @@ -0,0 +1,813 @@ +annotations_available-annotations = Anotações disponíeis + +annotations_clear = Limpar anotações locais + +annotations_click-placeholder = Notas para este Click + +annotations_import-local = Importar arquivo de anotações local + +annotations_load-local = Carregar + +annotations_no-published-annotations = Sem anotações publicadas. + +annotations_publish = Publicar + +annotations_save-local = Salvar + +annotations_turn-placeholder = Notas para este turno + +card-browser-form_faction = Facção + +card-browser-form_format = Formato + +card-browser-form_search-hint = Procure cartas + +card-browser-form_side = Lado + +card-browser-form_sort = Ordenar por + +card-browser-form_sort-by = {$by -> + [cost] Custo + [faction] Facção + [influence] Influencia + [name] Nome + [set-number] Numero do set + [type] Tipo + *[unknown] undefined +} + +card-browser-form_type = Tipo + +card-browser_advancement = Avanços necessarios: {$requirement} + +card-browser_agenda-points = Pontos de Agenda: {$points} + +card-browser_clear = Limapr + +card-browser_cost = Custo: {$cost} + +card-browser_inf-limit = Limite de Influencia: {$inf-limit} + +card-browser_influence = Influencia: {$influence} + +card-browser_memory = Memória: {$memory} + +card-browser_min-deck-size = Tamanho minimo de baralho: {$min-deck-size} + +card-browser_select-art = Selecionar Arte + +card-browser_selected-art = Arte Alternativa Selecionada + +card-browser_set = Set + +card-browser_strength = Força: {$strength} + +card-browser_trash-cost = Custo de exclusão: {$trash-cost} + +card-browser_update-failure = Falha ao atualizar Arte + +card-browser_update-success = Atualizar Arte + +card-type_name = {$type -> + [agenda] Agenda + [all] Todos + [asset] Ativo + [event] Evento + [hardware] Hardware + [ice] GELO + [identity] Identidade + [operation] Operação + [program] Programa + [resource] Recurso + [upgrade] Upgrade + *[unknown] undefined +} + +chat_block = Bloquear Usuário + +chat_cancel = Cancelar + +chat_channels = Canais + +chat_delete = Deletar Mensagem + +chat_delete-all = Deletar todas as mensagens do usuário + +chat_placeholder = Diga alguma coisa... + +chat_send = Enviar + +chat_title = Jogue Android: Netrunner no seu browser + +deck-builder_add-cards = Adicionar cartas + +deck-builder_add-to-deck = Adicionar ao baralho + +deck-builder_agenda-points = Pontos de Agenda + +deck-builder_cancel = Cancelar + +deck-builder_card-name = Nome da carta + +deck-builder_clear-stats = Limpar estatísticas + +deck-builder_completed = Completas: {$completed} + +deck-builder_confirm-delete = Confirmar exclusão + +deck-builder_copy = Copiar + +deck-builder_create-game = Criar Partida + +deck-builder_deck-copy-suffix = cópia + +deck-builder_deck-count = {$cnt -> + [zero] Não há baralhos + [one] {$cnt} Baralho + *[other] {$cnt} Baralhos +} + +deck-builder_deck-count-filtered = {$cnt -> + [zero] Não há baralhos (filtrado) + [one] {$cnt} Baralho (filtrado) + *[other] {$cnt} Baralhos (filtrado) +} + +deck-builder_deck-name = Nome do Baralho + +deck-builder_deck-notes = Notas do baralho + +deck-builder_deck-points = Pontos do Baralho + +deck-builder_decklist = Lista + +deck-builder_decklist-inst = (Digite ou cole a lista do baralho, ela sera filtrada) + +deck-builder_delete = Deletar + +deck-builder_edit = Editar + +deck-builder_format = Formato + +deck-builder_games = Partidas: {$games} + +deck-builder_hash = Hash do torneio + +deck-builder_identity = Identitidade + +deck-builder_illegal = ilegal + +deck-builder_import = Importar + +deck-builder_import-button = Importar baralho + +deck-builder_import-placeholder = NRDB ID + +deck-builder_import-title = Insira um ID de baralho público do NRDB ou URL + +deck-builder_influence = Influencia + +deck-builder_legal = legal + +deck-builder_loading-msg = Carregando coleção de baralhos... + +deck-builder_lost = Derrotas: {$lost} + +deck-builder_max = maximo + +deck-builder_min = minimo + +deck-builder_new-corp = Novo baralho de Corp + +deck-builder_new-runner = Novo baralho de Runner + +deck-builder_notes = Notas + +deck-builder_reset = Resetar + +deck-builder_save = Salvar + +deck-builder_why = Por que? + +deck-builder_won = Vitórias: {$won} ({NUMBER($percent, style: "percent")}) + +faction_name = {$faction -> + [adam] Adam + [all] Todos + [anarch] Anarquista + [any-faction] Qualquer facção + [apex] Apex + [criminal] Criminosos + [haas-bioroid] Haas-Bioroid + [jinteki] Jinteki + [nbn] NBN + [neutral] Neutro + [shaper] Modeladores + [sunny-lebeau] Sunny Lebeau + [weyland-consortium] Consórcio Weyland + *[other] undefined +} + +format_name = {$format -> + [all] All + [any-format] Qualquer Formato + [casual] Casual + [classic] Classico + [core-experience] Core Experience + [eternal] Eternal + [neo] undefined + [preconstructed] undefined + [snapshot] Snapshot + [snapshot-plus] Snapshot Plus + [socr] SOCR + [standard] Standard + [startup] Startup + [sunset] undefined + [system-gateway] System Gateway + [throwback] undefined + *[other] undefined +} + +game_abilities = Habilidades + +game_actions = Ações + +game_agenda-count = {$agenda-point -> + [one] {$agenda-point} Pontos de Agenda + *[other] {$agenda-point} Pontos de Agendas +} + +game_agenda-count-with-req = {$agenda-point -> + [one] {$agenda-point} Pontos de Agenda + *[other] {$agenda-point} Pontos de Agendas +} ({$agenda-point-req} required) + +game_approach-ice = Aproximar do gelo + +game_archives = Arquivos{"\u00A0"}({$faceup} ↑ {$facedown} ↓) + +game_auto-pass = Passar prioridade automaticamente + +game_bad-pub-count = {$base} Publicidade Negativa + +game_bad-pub-count-additional = {$base} + {$additional} Publicidade Negativa + +game_brain-damage = Dano Letal + +game_breach-server = Violar servidor + +game_card = Carta + +game_card-count = {$cnt -> + [one] {$cnt} carta + *[other] {$cnt} cartas +} + +game_click-count = {$cnt -> + [one] {$cnt} click + *[other] {$cnt} click +} + +game_close = Fechar + +game_close-shuffle = Fechar & Embaralhar + +game_concede = Conceder + +game_continue = Continuar + +game_continue-to = Continuar para {$phase} + +game_corp-view = Visão de Corp + +game_credit-count = {$credit -> + [one] {$credit} Crédito + *[other] {$credit} Créditos +} + +game_credit-count-with-run-credits = {$credit -> + [one] {$credit} Crédito + *[other] {$credit} Créditos +} ({$run-credit} para corre) + +game_credits = creditos + +game_current = Current + +game_current-phase = Current phase + +game_draw = Comprar + +game_encounter-ice = Encontrar gelo + +game_end-turn = Fim do Turno + +game_face-down-count = {$total} cartas, {$facedown} virada para baixo + +game_fire-unbroken = Executar sub-rotinas + +game_gain-credit = Ganhar Crédito + +game_game-start = Começar partida: {$timestamp} + +game_grip = Mão + +game_heap = Heap ({$cnt}) + +game_hq = QG + +game_inactivity = Partida fechada por inatividade + +game_indicate-action = Indicar ação + +game_initiation = Iniciação + +game_jack-out = Ejetar + +game_keep = Manter + +game_leave = Sair da Partida + +game_leave-replay = Sair do Replay + +game_let-subs-fire = Executar sub-rotinas não quebradas + +game_link-strength = Força de Link + +game_mandatory-draw = Compra obrigatória + +game_max-hand = {$total} Tamanho de mão máximo + +game_movement = Movivemento + +game_mu-count = {$unused} de {$available} MU não utilizada + +game_mulligan = Mulligan + +game_mute = Mutar espectadores + +game_no-current-run = Sem corre no momento + +game_no-further = Sem mais ações + +game_play-area = Área de Jogo + +game_purge = Expurgar + +game_remove-tag = Remover Marca + +game_rez = Ativar + +game_rfg = Removido do jogo + +game_rnd = P&D + +game_run = Corre + +game_run-ends = Corre terminou + +game_runner-view = Visão de Runner + +game_scored-area = Área de Pontuação + +game_server = Servidor {$num} + +game_show = Mostrar + +game_shuffle = Embaralhar + +game_spec-count = {$cnt -> + [one] Espectador + *[other] Espectadores +} + +game_spec-view = Visão de Espectador + +game_special-mu-count = {$unused} de {$available} {$mu-type} MU não utilizada + +game_stack = Pilha + +game_start = Começar Partida + +game_start-turn = Iniciar Turno + +game_stop-auto-pass = Para de passar prioridade + +game_subs = Sub-rotinas + +game_success = Successo + +game_tag-count = {$base -> + [one] {$base} Marca + *[other] {$base} Marcas +} + +game_tag-count-additional = {$base -> + [one] {$base} + {$additional} Marca + *[other] {$base} + {$additional} Marcas +} + +game_take-clicks = Receber Clicks + +game_time-taken = Tempo consumido: {$time} minutos + +game_trace = Rastrear + +game_trash-resource = Excluir Recurso + +game_unimplemented = Não implementado + +game_unknown-phase = Unknown phase + +game_unmute = Desmutar espectadores + +game_win-claimed = {$winner} ({$side}) venceu por objetivo no turno {$turn} + +game_win-conceded = {$winner} ({$side}) venceu por concessão no turno {$turn} + +game_win-decked = {$winner} ({$side}) venceu pois a Corp zerou o deck no turno {$turn} + +game_win-flatlined = {$winner} ({$side}) venceu por linha reta no turno {$turn} + +game_win-other = {$winner} ({$side}) venceu por {$reason} no turno {$turn} + +game_win-points = {$winner} ({$side}) venceu por pontos de agenda no turno {$turn} + +lobby_aborted = Conecção abortada + +lobby_api-access = Permitir acesso API para informações do jogo + +lobby_api-requires-key = (Requer uma Chave de API nas Configurações) + +lobby_as-corp = Como Corp + +lobby_as-runner = Como Runner + +lobby_cancel = Cancelar + +lobby_chat = Chat + +lobby_closed-msg = Lobby fechado por inatividade + +lobby_completion-rate = Taxa de finalização de jogos + +lobby_create = Criar + +lobby_deck-selected = Baralho selecionado + +lobby_delete = Deletar Jogo + +lobby_format = Formato + +lobby_game-count = {$cnt -> + [one] {$cnt} Jogo + *[other] {$cnt} Jogos +} + +lobby_game-count-filtered = {$cnt -> + [one] {$cnt} Jogo + *[other] {$cnt} Jogos +} (filtrado) + +lobby_hidden = Tornar infomrações escondidas dos jogadores visivel para os espectadores + +lobby_invalid-password = Senha invalida + +lobby_join = Entrar + +lobby_leave = Sair + +lobby_load-replay = Carregar replay + +lobby_new-game = Novo jogo + +lobby_no-games = Não há jogos + +lobby_not-allowed = Não autorizado + +lobby_options = Opções + +lobby_password = Senha + +lobby_password-error = Por favor insira a senha do jogo. + +lobby_password-for = Senha para + +lobby_password-protected = Protegido por senha + +lobby_players = Jogadores + +lobby_private = PRIVADO + +lobby_rejoin = Re-Entrar + +lobby_reload = Recarregar lista + +lobby_replay-invalid-file = Selecione um arquivo de replay válido. + +lobby_replay-link-error = Link do replay inválido. + +lobby_reset = Resetar Nome do Jogo + +lobby_save-replay = Salvar replay + +lobby_select-deck = Selecionar baralho + +lobby_select-title = Selecione seu baralho + +lobby_side = Lado + +lobby_spectator-count = {$cnt -> + [one] Espectador + *[other] Espectadores +} + +lobby_spectators = Permitir espectadore + +lobby_start = Começar + +lobby_start-replay = Começar replay + +lobby_swap = Trocar lados + +lobby_title = Titulo + +lobby_title-error = Por favor insira o titulo do jogo. + +lobby_too-little-data = Falta de dados + +lobby_type = {$type -> + [angel-arena] undefined + [casual] Casual + [competitive] Competitivo + [tournament] Torneio + *[other] Unknown lobby type +} + +lobby_waiting = Eseprando jogador selecionar baralho + +lobby_watch = Assistir + +log_annotating = Anotações + +log_game-log = Game Log + +log_remote-annotations-fail = Não foi possível pegar anotações remotas. + +log_shared = Anotações compartilhadas + +menu_admin = {nav_admin} + +menu_donor = Doadores + +menu_logout = Ejetar + +menu_moderator = Moderadores + +menu_settings = {nav_settings} + +nav_about = Sobre + +nav_admin = Admin + +nav_cards = Cartas + +nav_chat = Chat + +nav_deck-builder = Construtor de Baralhos + +nav_features = Features + +nav_game-count = {$cnt -> + [one] {$cnt} Jogo + *[other] {$cnt} Jogos +} + +nav_help = Ajuda + +nav_play = Jogar + +nav_settings = Configurações + +nav_stats = Estatisticas + +nav_tournaments = Torneios + +nav_users = Usuários + +pronouns = {$pronoun -> + [any] Qualquer + [blank] [blank] + [ey] Ey/em + [faefaer] undefined + [he] Ele/Dele + [heit] undefined + [heshe] undefined + [hethey] Ele/Delu + [it] Elx + [myodb] Prefiro não especificar + [ne] Ne/nem + *[none] Não especificado + [she] Ela/Dela + [sheit] undefined + [shethey] Ela/Delu + [they] Elu/Delu + [ve] Ve/ver + [xe] Xe/xem + [xi] undefined + [zehir] Ze/hir + [zezir] Ze/zir +} + +settings_alt-art = Artes Alternativas + +settings_always = Sempre + +settings_api-keys = API Keys + +settings_avatar = Avatar + +settings_background = Background da partida + +settings_block = Bloquear usuário + +settings_blocked = Usuários bloqueados + +settings_cancel = Cancelar + +settings_card-backs = Verso das cartas + +settings_card-images = Imagens das Cartas + +settings_change-avatar = Trocar avatar no gravatar.com + +settings_change-email = Trocar email + +settings_comp-only = Apenas Lobby Competitivo + +settings_create-api-key = Criar API Key + +settings_current-email = Email atual + +settings_deck-stats = Estatísticas dos Decks + +settings_delete-api-key = Deletar + +settings_desired-email = Email desejado + +settings_email = Email + +settings_email-placeholder = Endereço de Email + +settings_email-title = Alterar titulo do email + +settings_enable-game-sounds = Permitir sons do jogo + +settings_enable-lobby-sounds = Permitir sons do lobby + +settings_enter-valid = Por favor, insira um endereço de email válido + +settings_ffg = FFG + +settings_game-stats = Estatísticas de Vitória/Derrota em Jogo + +settings_get-log-top = Puxando topo do log atual + +settings_get-log-width = Puxando largura atual do log + +settings_high-res = Habilitar imagem das cartas em alta resolução + +settings_invalid-email = Nenhuma conta com esse email existe + +settings_invalid-password = Usuário ou senha inválidos + +settings_language = Idioma + +settings_layout-options = Opções de layout + +settings_none = Nenhum + +settings_pronouns = Pronomes + +settings_reset = Reset All to Official Art + +settings_runner-classic = Layout do rig do Runner é o clássico da JNet (De cima para baixo: Programas, Hardware, Recursos) + +settings_runner-layout = Layout de Runner na perspectiva da Corp + +settings_runner-reverse = Layout do rig do Runner invertido (De cima para baixo: Recursos, Hardware, Programas) + +settings_set = Set + +settings_set-all = Set all cards to + +settings_show-alt = Mostrar artes alternativas das cartas + +settings_sounds = Soms + +settings_stacked-cards = Empilhar cartas (ativo automaticamente) + +settings_update = Atualizar + +settings_update-profile = Atualizar Perfil + +settings_updated = Perfil atualizar - Favor atualizar a página + +settings_updating = Atualizando perfil... + +settings_user-name = Nome de usuário + +settings_volume = Volume + +side_name = {$side -> + [all] Todos + [any-side] Qualquer lado + [corp] Corp + [runner] Runner + *[unknown] undefined +} + +stats_all-games = Mostrar todas partidas + +stats_cards-accessed = Cartas Acessadas + +stats_cards-click = Cards Compradas por Click + +stats_cards-drawn = Cards Compradas + +stats_cards-rezzed = Cartas Ativadas + +stats_clear-stats = Limpar Estatísticas + +stats_clicks-gained = Clicks ganhos + +stats_completed = Completadas: {$completed} ({NUMBER($percent, style: "percent")}) + +stats_corp-stats = Estatísticas de Corp + +stats_credits-click = Créditos por Click + +stats_credits-gained = Créditos ganos + +stats_credits-spent = Créditos gastos + +stats_damage-done = Dano Causado + +stats_download = Baixar replay + +stats_ended = Terminadas + +stats_format = Formato + +stats_game-stats = Estatísticas de Jogo + +stats_game-title = {$title} ({$cnt -> + [one] {$cnt} turno + *[other] {$cnt} turnos +}) + +stats_launch = Carregar Replay + +stats_lobby = Lobby + +stats_log-count = {$cnt -> + [one] {$cnt} Log + *[other] {$cnt} Logs +} + +stats_log-count-filtered = {$cnt -> + [one] {$cnt} Log (filtrado) + *[other] {$cnt} Logs (filtrado) +} + +stats_lost = Derrotas: {$lost} ({NUMBER($percent, style: "percent")}) + +stats_no-games = Sem partidass + +stats_no-log = Nenhum log disponível + +stats_not-completed = Não Completadas: {$completed} ({NUMBER($percent, style: "percent")}) + +stats_runner-stats = Estatísticas de Runner + +stats_runs-made = Corres Feitos + +stats_share = Compartilhar replay + +stats_shared-games = Mostrar apenas compartilhadas + +stats_started = Iniciadas: {$started} + +stats_tags-gained = Marcas Recebidas + +stats_unavailable = Replay indisponível + +stats_view-games = Retornar para Estatísticas + +stats_view-log = Visualizar log + +stats_win-method = Método de vitórias + +stats_winner = Vencedor + +stats_won = Vitórias: {$won} ({NUMBER($percent, style: "percent")}) diff --git a/resources/public/i18n/ru.ftl b/resources/public/i18n/ru.ftl new file mode 100644 index 0000000000..b8c7686b88 --- /dev/null +++ b/resources/public/i18n/ru.ftl @@ -0,0 +1,1498 @@ +annotations_available-annotations = Доступные аннотации + +annotations_clear = Очистить локальные аннотации + +annotations_click-placeholder = Заметки к этому клику + +annotations_import-local = Импортировать файл с аннотациями + +annotations_load-local = Загрузить + +annotations_no-published-annotations = Нет опубликованных аннотаций. + +annotations_publish = Опубликовать + +annotations_save-local = Сохранить + +annotations_turn-placeholder = Заметки к этому ходу + +card-browser-form_faction = Фракция + +card-browser-form_format = Формат + +card-browser-form_search-hint = Искать карты + +card-browser-form_side = Сторона + +card-browser-form_sort = Сортировать по + +card-browser-form_sort-by = {$by -> + [cost] Цена + [faction] Фракция + [influence] Влияние + [name] Название + [set-number] Номер в наборе + [type] Тип + *[unknown] undefined +} + +card-browser-form_type = Тип + +card-browser_advancement = Требование к продвижению: {$requirement} + +card-browser_agenda-points = Победные очки: {$points} + +card-browser_artist-info = Информация о художнике + +card-browser_clear = Сбросить + +card-browser_cost = Цена: {$cost} + +card-browser_inf-limit = Предел влияния: {$inf-limit} + +card-browser_influence = Влияние: {$influence} + +card-browser_memory = Память: {$memory} + +card-browser_min-deck-size = Минимальный размер колоды: {$min-deck-size} + +card-browser_more-info = Больше информации + +card-browser_select-art = Выбрать изображение + +card-browser_selected-art = Выбранное изображение + +card-browser_set = Набор + +card-browser_strength = Сила: {$strength} + +card-browser_trash-cost = Цена сноса: {$trash-cost} + +card-browser_update-failure = Ошибка обновления изображения + +card-browser_update-success = Изображение обновлено + +card-type_name = {$type -> + [agenda] Проект + [all] Все + [asset] Актив + [event] Событие + [hardware] Устройство + [ice] Лёд + [identity] Роль + [operation] Операция + [program] Программа + [resource] Ресурс + [upgrade] Улучшение + *[unknown] undefined +} + +chat_block = Заблокировать пользователя + +chat_cancel = Отмена + +chat_channels = Каналы + +chat_delete = Удалить сообщение + +chat_delete-all = Удалить все сообщения пользователя + +chat_length-exceeded = Превышена длина + +chat_message-blocked = Сообщение заблокировано: {$reason-str} + +chat_placeholder = Напишите что-нибудь... + +chat_rate-exceeded = Превышена частота + +chat_send = Отправить + +chat_title = Играть в Netrunner в браузере + +deck-builder_add-cards = Добавить карты + +deck-builder_add-to-deck = Добавить в колоду + +deck-builder_agenda-points = Победные очки + +deck-builder_cancel = Отмена + +deck-builder_card-count = {$cnt -> + *[one] {$cnt} карты + [few] {$cnt} карты + [many] {$cnt} карты + [other] {$cnt} карты +} + +deck-builder_card-name = Название карты + +deck-builder_clear-stats = Сбросить статистику + +deck-builder_completed = Зав.: {$completed} + +deck-builder_confirm-delete = Подтвердить удаление + +deck-builder_copy = Скопировать + +deck-builder_create-game = Создать игру + +deck-builder_deck-copy-suffix = копия + +deck-builder_deck-count = {$cnt -> + [zero] Нет колод + *[one] {$cnt} колода + [few] {$cnt} колоды + [many] {$cnt} колод + [other] {$cnt} колод +} + +deck-builder_deck-count-filtered = {$cnt -> + [zero] Нет колод (Фильтр) + *[one] {$cnt} колода (Фильтр) + [few] {$cnt} колоды (Фильтр) + [many] {$cnt} колод (Фильтр) + [other] {$cnt} колод (Фильтр) +} + +deck-builder_deck-name = Название колоды + +deck-builder_deck-notes = Примечания + +deck-builder_deck-points = Очки колоды + +deck-builder_decklist = Список карт + +deck-builder_decklist-inst = (Напишите или вставьте список карт, он будет распознан) + +deck-builder_delete = Удалить + +deck-builder_edit = Изменить + +deck-builder_format = Формат + +deck-builder_games = Игр: {$games} + +deck-builder_hash = Турнирный хеш + +deck-builder_identity = Роль + +deck-builder_illegal = : нелегальна + +deck-builder_import = Импортировать + +deck-builder_import-button = Импорт колоды + +deck-builder_import-title = Вставьте ID или ссылку на публичную колоду с NRDB + +deck-builder_influence = Влияние + +deck-builder_legal = : легальна + +deck-builder_loading-msg = Загрузка коллекции колод... + +deck-builder_lost = Пор.: {$lost} + +deck-builder_max = максимум + +deck-builder_min = минимум + +deck-builder_min-deck-size = Минимальный размер колоды + +deck-builder_new-corp = Создать Корпу + +deck-builder_new-deck = Новая колода + +deck-builder_new-runner = Создать Бегущего + +deck-builder_notes = Примечания + +deck-builder_reset = Сброс + +deck-builder_save = Сохранить + +deck-builder_why = Почему? + +deck-builder_won = Побед: {$won} ({NUMBER($percent, style: "percent")}) + +diagrams_run-timing_approach = 6.9.2: Фаза приближения ко льду + +diagrams_run-timing_approach-a = Вы приближаетесь ко льду. Срабатывают соответствующие эффекты карт + +diagrams_run-timing_approach-b = Окно платной способности. Корпорация может развернуть лёд, к которому приближается Бегущий, а также другие карты, помимо льдов + +diagrams_run-timing_approach-c = Если лёд, к которому приближается Бегущий, развёрнут, перейдите к фазе встречи (6.9.3) + +diagrams_run-timing_approach-d = В противном случае перейдите к фазе движения (6.9.4) + +diagrams_run-timing_disclaimer = Данная схема была упрощена для наглядности. Полные правила можно изучить на сайте Null Signal Games. + +diagrams_run-timing_encounter = 6.9.3: Фаза встречи со льдом + +diagrams_run-timing_encounter-a = Вы встретились с данным льдом. Срабатывают соответствующие эффекты карт + +diagrams_run-timing_encounter-b = Окно платной способности. Бегущий может контактировать со льдом во время этого окна + +diagrams_run-timing_encounter-c = Если остались несломанные подпрограммы, Корпорация выполняет верхнюю несломанную подпрограмму. По завершении повторите этот шаг + +diagrams_run-timing_encounter-d = Встреча завершена. Перейдите к фазе движения (6.9.4) + +diagrams_run-timing_header = Структура забега + +diagrams_run-timing_initiation = 6.9.1: Фаза инициации + +diagrams_run-timing_initiation-a = Бегущий объявляет сервер + +diagrams_run-timing_initiation-b = Бегущий получает кредиты плохой репутации + +diagrams_run-timing_initiation-c = Забег формально начинается - Срабатывают эффекты событий-забегов + +diagrams_run-timing_initiation-d = Перейдите к внешнему льду при его наличии и начните фазу приближения (6.9.2) + +diagrams_run-timing_initiation-e = В противном случае перейдите к фазе движения (6.9.4) + +diagrams_run-timing_movement = 6.9.4: Фаза движения + +diagrams_run-timing_movement-a = Если вы были во встрече со льдом или приближались ко льду, вы его проходите. Срабатывают карты с формулировкой 'при прохождении льда' + +diagrams_run-timing_movement-b = Если между вами и корнем сервера не осталось больше льдов, срабатывают карты с формулировкой 'при прохождении всех льдов на сервере' + +diagrams_run-timing_movement-c = Окно платной способности + +diagrams_run-timing_movement-d = Бегущий может отключиться. Если Бегущий отключился, перейдите к фазе завершения забега (6.9.6) + +diagrams_run-timing_movement-e = Бегущий продвигается на одну позицию по направлению к корню сервера, если это возможно + +diagrams_run-timing_movement-f = Окно платной способности. Корпорация может разворачивать карты, кроме льдов + +diagrams_run-timing_movement-g = Если вы приближаетесь ко льду, перейдите к фазе приближения ко льду (6.9.2) + +diagrams_run-timing_movement-h = Бегущий приближается к атакуемому серверу. Срабатывают соответствующие эффекты карт + +diagrams_run-timing_movement-i = Перейдите к фазе успеха (6.9.5) + +diagrams_run-timing_run-ends = 6.9.6: Фаза завершения забега + +diagrams_run-timing_run-ends-a = Все открытые окна приоритета завершаются или закрываются + +diagrams_run-timing_run-ends-b = Бегущий теряет все непотраченные кредиты плохой репутации + +diagrams_run-timing_run-ends-c = Если данной фазе не предшествовала фаза успеха, а сервер всё ещё существует, забег объявляется неуспешным + +diagrams_run-timing_run-ends-d = Забег завершается. Срабатывают карты с формулировкой 'по завершении забега' + +diagrams_run-timing_success = 6.9.5: Фаза успеха + +diagrams_run-timing_success-a = Забег объявляется успешным. Срабатывают карты с формулировкой 'при успешном забеге' + +diagrams_run-timing_success-b = Бегущий взламывает атакуемый сервер + +diagrams_run-timing_success-c = Фаза успеха завершена. Перейдите к фазе завершения забега (6.9.6) + +diagrams_turn_corp-action-phase = 5.6.2: Фаза действий + +diagrams_turn_corp-action-phase-a = Окно платной способности. Корпорация может разворачивать карты, кроме льдов, и засчитывать проекты + +diagrams_turn_corp-action-phase-b = Если у Корпорации есть непотраченные [Clicks], она совершает действие + +diagrams_turn_corp-action-phase-c = Если действие было совершено, вернитесь к (a) + +diagrams_turn_corp-action-phase-d = Фаза действий завершена. Перейдите к фазе сброса (5.6.3) + +diagrams_turn_corp-discard-phase = 5.6.3: Фаза сброса + +diagrams_turn_corp-discard-phase-a = Корпорация сбрасывает карты до максимального размера руки при необходимости + +diagrams_turn_corp-discard-phase-b = Окно платной способности. Корпорация может разворачивать карты, кроме льдов + +diagrams_turn_corp-discard-phase-c = Если у Корпорации остались [Clicks], она теряет эти [Clicks] + +diagrams_turn_corp-discard-phase-d = Ход Корпорации формально окончен. Срабатывают карты с формулировкой 'в конце хода' + +diagrams_turn_corp-discard-phase-e = Перейдите к ходу Бегущего + +diagrams_turn_corp-draw-phase = 5.6.1: Фаза добора + +diagrams_turn_corp-draw-phase-a = Корпорация получает полагающиеся клики (по умолчанию: [click][click][click]) + +diagrams_turn_corp-draw-phase-b = Окно платной способности. Корпорация может разворачивать карты, кроме льдов, и засчитывать проекты + +diagrams_turn_corp-draw-phase-c = Обновляются возобновляемые кредиты Корпорации + +diagrams_turn_corp-draw-phase-d = Ход формально начинается. Срабатывают карты с формулировкой 'в начале хода' + +diagrams_turn_corp-draw-phase-e = Корпорация берёт 1 карту с верха R&D + +diagrams_turn_corp-draw-phase-f = Перейдите к фазе действий (5.6.2) + +diagrams_turn_corp-turn = Ход Корпорации + +diagrams_turn_runner-action-phase = 5.7.1: Фаза действий + +diagrams_turn_runner-action-phase-a = Бегущий получает полагающиеся клики (по умолчанию: [click][click][click][click]) + +diagrams_turn_runner-action-phase-b = Окно платной способности. Корпорация может разворачивать карты, кроме льдов + +diagrams_turn_runner-action-phase-c = Обновляются возобновляемые кредиты Бегущего + +diagrams_turn_runner-action-phase-d = Ход формально начинается. Срабатывают карты с формулировкой 'в начале хода' + +diagrams_turn_runner-action-phase-e = Окно платной способности. Корпорация может разворачивать карты, кроме льдов + +diagrams_turn_runner-action-phase-f = Если у Бегущего есть непотраченные [Clicks], он совершает действие + +diagrams_turn_runner-action-phase-g = Если действие было совершено, вернитесь к (e) + +diagrams_turn_runner-action-phase-h = Фаза действий завершена. Перейдите к фазе сброса (5.7.2) + +diagrams_turn_runner-discard-phase = 5.7.2: Фаза сброса + +diagrams_turn_runner-discard-phase-a = Бегущий сбрасывает карты до максимального размера руки при необходимости + +diagrams_turn_runner-discard-phase-b = Окно платной способности. Корпорация может разворачивать карты, кроме льдов + +diagrams_turn_runner-discard-phase-c = Если у Бегущего остались [Clicks], он теряет эти [Clicks] + +diagrams_turn_runner-discard-phase-d = Ход Бегущего формально окончен. Срабатывают карты с формулировкой 'в конце хода' + +diagrams_turn_runner-discard-phase-e = Перейдите к ходу Корпорации + +diagrams_turn_runner-turn = Ход Бегущего + +faction_name = {$faction -> + [adam] Адам + [all] Все + [anarch] Анарх + [any-faction] Все фракции + [apex] Апекс + [criminal] Криминал + [haas-bioroid] Хаас-Биороид + [jinteki] Джинтеки + [nbn] undefined + [neutral] Нейтральные + [shaper] Шейпер + [sunny-lebeau] Санни Лебо + [weyland-consortium] Консорциум Вейланда + *[unknown] undefined +} + +format_name = {$format -> + [all] Все + [any-format] Любой формат + [casual] Свободный + [classic] Классический + [core-experience] undefined + [eternal] Вечный + [neo] Нео + [preconstructed] Чемпионский + [snapshot] undefined + [snapshot-plus] undefined + [socr] undefined + [standard] Стандарт + [startup] Стартап + [sunset] Закат + [system-gateway] Врата Системы + [throwback] undefined + *[unknown] undefined +} + +game_abilities = Способности + +game_actions = Действия + +game_agenda-count = {$cnt -> + *[one] {$cnt} победное очко + [few] {$cnt} победных очка + [many] {$cnt} победных очков + [other] {$cnt} победных очков +} + +game_approach-ice = Приближение ко льду + +game_archives = Архивы{"\u00A0"}({$faceup} ↑ {$facedown} ↓) + +game_attempt-reconnect = Переподключиться + +game_auto-pass = Автопередача приоритета + +game_bad-pub-count = {$cnt -> + *[one] {$cnt} плохая репутация + [few] {$cnt} плохих репутации + [many] {$cnt} плохих репутаций + [other] {$cnt} плохих репутаций +} + +game_bad-pub-count-additional = {$cnt -> + *[one] {$cnt} плохая репутация + {$additional} + [few] {$cnt} плохих репутации + {$additional} + [many] {$cnt} плохих репутаций + {$additional} + [other] {$cnt} плохих репутаций + {$additional} +} + +game_beat-trace = Перебить слежку + +game_brain-damage = {$cnt -> + *[one] {$cnt} критический урон + [few] {$cnt} критического урона + [many] {$cnt} критических уронов + [other] {$cnt} критических уронов +} + +game_breach-server = Взломать сервер + +game_card = Карта + +game_card-count = {$cnt -> + *[one] {$cnt} карта + [few] {$cnt} карты + [many] {$cnt} карт + [other] {$cnt} карт +} + +game_click-count = {$cnt -> + *[one] {$cnt} клик + [few] {$cnt} клика + [many] {$cnt} кликов + [other] {$cnt} кликов +} + +game_close = Закрыть + +game_close-shuffle = Закрыть и перемешать + +game_concede = Сдаться + +game_continue = Продолжить + +game_continue-to = Продолжить к фазе {$phase} + +game_corp-view = Перспектива Корпорации + +game_credit-count = {$cnt -> + *[one] {$cnt} кредит + [few] {$cnt} кредита + [many] {$cnt} кредитов + [other] {$cnt} кредитов +} + +game_credit-count-with-run-credits = {$cnt -> + *[one] {$cnt} кредит ({$run-credit} для забега) + [few] {$cnt} кредита ({$run-credit} для забега) + [many] {$cnt} кредитов ({$run-credit} для забега) + [other] {$cnt} кредитов ({$run-credit} для забега) +} + +game_credits = кредитов + +game_current = Течение + +game_current-phase = Текущая фаза + +game_draw = Взять карту + +game_encounter-ice = Встреча со льдом + +game_end-turn = Закончить ход + +game_error = Внутренняя ошибка сервера. Пожалуйста, напишите /bug в чат и следуйте инструкциям. + +game_face-down-count = {$cnt -> + *[one] {$cnt} карта, {$facedown} лицом вниз + [few] {$cnt} карты, {$facedown} лицом вниз + [many] {$cnt} карт, {$facedown} лицом вниз + [other] {$cnt} карт, {$facedown} лицом вниз +} + +game_fire-unbroken = Выполнить несломанные подпрограммы + +game_gain-credit = Получить кредит + +game_game-start = Начало игры: {$timestamp} + +game_grip = Рука + +game_heap = Куча ({$cnt}) + +game_inactivity = Игра закрыта из-за отсутствия активности + +game_indicate-action = Обозначить действие + +game_initiation = Инициация + +game_jack-out = Отключиться + +game_keep = Оставить + +game_leave = Выйти из игры + +game_leave-replay = Выйти из записи + +game_let-subs-fire = Разрешить выполнение несломанных подпрограмм + +game_link-strength = Мощность канала + +game_lost-connection = Утрачено соединени с сервером. Идёт переподключение. + +game_mandatory-draw = Карта за начало хода + +game_max-hand = {$total} Макс. размер руки + +game_minutes = м: + +game_movement = Движение + +game_mu-count = {$unused} из {$available} свободных ЯП + +game_mulligan = Пересдать + +game_mute = Выключить сообщения зрителей + +game_no-current-run = Нет активного забега + +game_no-further = Нет дальнейших действий + +game_play-area = Игровая зона + +game_prompt = {$msg -> + [advance] продвинуть + [archives] Архивы + [derez] свернуть + [expend] Израсходовать + [hq] undefined + [new-remote] Новый сервер + [r-d] undefined + [rez] развернуть + [score] засчитать + [server-1] Сервер 1 + [server-10] Сервер 10 + [server-2] Сервер 2 + [server-3] Сервер 3 + [server-4] Сервер 4 + [server-5] Сервер 5 + [server-6] Сервер 6 + [server-7] Сервер 7 + [server-8] Сервер 8 + [server-9] Сервер 9 + [trash] снести + *[unknown] undefined +} + +game_purge = Сбросить вирусы + +game_reconnected-to-server = Вы переподключены к серверу + +game_remove-tag = Снять метку + +game_rez = Развернуть + +game_rfg = Удалены из игры + +game_run = Начать забег + +game_run-ends = Забег завершается + +game_runner-view = Перспектива Бегущего + +game_scored-area = Зона зачёта + +game_seconds = с + +game_seconds-remaining = с осталось + +game_server = Сервер {$num} + +game_set-aside = Отложить в сторону + +game_show = Показать + +game_shuffle = Перемешать + +game_spec-count = {$cnt -> + *[one] {$cnt} зритель + [few] {$cnt} зрителя + [many] {$cnt} зрителей + [other] {$cnt} зрителей +} + +game_spec-view = Перспектива зрителя + +game_special-mu-count = {$unused} из {$available} {$mu-type} свободных ЯП + +game_stack = Стек + +game_start = Начать игру + +game_start-turn = Начать ход + +game_stop-auto-pass = Прекратить автопередачу приоритета + +game_subs = Подпрограммы + +game_success = Успех + +game_tag-count = {$cnt -> + *[one] {$cnt} метка + [few] {$cnt} метки + [many] {$cnt} меток + [other] {$cnt} меток +} + +game_tag-count-additional = {$cnt -> + *[one] {$cnt} метка + {$additional} + [few] {$cnt} метки + {$additional} + [many] {$cnt} меток + {$additional} + [other] {$cnt} меток + {$additional} +} + +game_take-clicks = Получить клики + +game_time-taken = Затраченное время: {$time} минут + +game_trace = Отследить + +game_trash-resource = Снести ресурс + +game_unbeatable = Сделать неперебиваемой + +game_unimplemented = Не реализовано + +game_unknown-phase = Неизвестная фаза + +game_unmute = Включить сообщения зрителей + +game_win-claimed = {$winner} ({$side}) объявляет победу на {$turn} ходу + +game_win-conceded = {$winner} ({$side}) побеждает. Соперник сдался на {$turn} ходу + +game_win-decked = {$winner} ({$side}) побеждает. Соперник не смог взять карту из R&D на {$turn} ходу + +game_win-flatlined = {$winner} ({$side}) побеждает. Соперник получил флетлайн на {$turn} ходу + +game_win-other = побеждает из-за {$reason} на {$turn} ходу + +game_win-points = {$winner} ({$side}) побеждает, засчитав победные очки на {$turn} ходу + +ingame-settings_alt-art = Альтернативные изображения + +ingame-settings_board-overlap = Пересечение столов + +ingame-settings_card-backs = Рубашки + +ingame-settings_card-image = Изображение карты + +ingame-settings_card-images = Изображения карт + +ingame-settings_card-sorting = Сортировка + +ingame-settings_card-stacking = Настройки карт + +ingame-settings_card-text = Текст карты + +ingame-settings_ghost-trojans = Показывать дубликаты троянов в риге + +ingame-settings_high-res = Включить изображения высокого разрешения + +ingame-settings_label-faceup-cards = Подписывать карты лицом вверх + +ingame-settings_label-unrezzed-cards = Подписывать неразвёрнутые карты + +ingame-settings_preview-zoom = Увеличение карт при наведении + +ingame-settings_runner-board-order = Раскладка Бегущего + +ingame-settings_runner-classic = Классическая + +ingame-settings_runner-reverse = Обратная + +ingame-settings_save = Сохранить + +ingame-settings_show-alt = Показывать альтернативные изображения карт + +ingame-settings_sides-overlap = Карты Бегущего и Корпорации могут пересекаться + +ingame-settings_sort-archives = Отсортировать Архивы + +ingame-settings_sort-heap = Отсортировать Кучу + +ingame-settings_stack-cards = Складывать одинаковые карты вместе + +lobby_aborted = Соединение разорвано + +lobby_api-access = Разрешить доступ к данным игры через API + +lobby_api-access-details = Данная опция даёт доступ к информации о вашей игре расширенияим от сторонних разработчиков. Требует создание ключа API в Настройках. + +lobby_api-requires-key = (Требуется ключ API в Настройках) + +lobby_as-corp = За Корпорацию + +lobby_as-runner = За Бегущего + +lobby_both-perspective = Перспектива обоих + +lobby_cancel = Отмена + +lobby_chat = Чат + +lobby_closed-msg = Лобби закрыто из-за отсутствия активности + +lobby_completion-rate = Процент завершённых игр + +lobby_corp-perspective = Перспектива Корпорации + +lobby_create = Создать + +lobby_deck-selected = Колода выбрана + +lobby_default-game-format = Формат по умолчанию + +lobby_delete = Удалить игру + +lobby_filter = Фильтр + +lobby_format = Формат + +lobby_game-count = {$cnt -> + *[one] {$cnt} игра + [few] {$cnt} игры + [many] {$cnt} игр + [other] {$cnt} игр +} + +lobby_game-count-filtered = {$cnt -> + *[one] {$cnt} игра (с фильтром) + [few] {$cnt} игры (с фильтром) + [many] {$cnt} игр (с фильтром) + [other] {$cnt} игр (с фильтром) +} + +lobby_gateway-format = {$format -> + [beginner] Новичок + [beginner-info] В этом лобби можно играть стартовыми колодами Корпорации и Бегущего из набора Врата Cистемы. С этих колод рекомендуется начинать знакомство с игрой. Игра ведётся до 6 победных очков. + [beginner-ul] Врата Системы - Стартовые обучающие колоды + [constructed] Свои колоды + [intermediate] Продвинутый + [intermediate-info] В этом лобби можно играть продвинутыми колодами Корпорации и Бегущего из набора Врата Cистемы. В этих колодах больше опций и механик, чем в стартовых. Игра ведётся до 7 победных очков. + [intermediate-ul] Врата Системы - Продвинутые обучающие колоды + *[unknown] undefined +} + +lobby_hidden = Раскрыть зрителям скрытую информацию + +lobby_hidden-details = Данная опция раскроет всю скрытую информацию обеих сторон для ВСЕХ зрителей вашей игры, в том числе руки и карты лицом вниз. + +lobby_hidden-password = Мы рекомендуем использовать пароль, чтобы посторонние не помешали вашей игре. + +lobby_invalid-password = Неправильный пароль + +lobby_join = Войти + +lobby_leave = Выйти + +lobby_load-replay = Загрузить запись + +lobby_new-game = Новая игра + +lobby_no-games = Нет игр + +lobby_not-allowed = Не разрешено + +lobby_options = Параметры + +lobby_password = Пароль + +lobby_password-error = Пожалуйста, введите пароль. + +lobby_password-for = Пароль для + +lobby_password-protected = Защитить паролем + +lobby_players = Игроки + +lobby_private = ЗАКРЫТАЯ + +lobby_rejoin = Перезайти + +lobby_reload = Перезагрузить список + +lobby_replay-invalid-file = Выберите подходящий файл записи. + +lobby_replay-link-error = Ссылка на запись недействительна. + +lobby_reset = Сбросить название игры + +lobby_runner-perspective = Перспектива Бегущего + +lobby_save-replay = Сохранить запись + +lobby_save-replay-beta = БЕТА функционал: У нас может возникнуть необходимость удалить сохранённые записи, поэтому обязательно скачивайте важные для вас повторы. Будущие изменения функционала сайта могут нарушить совместимость со старыми записями. + +lobby_save-replay-details = Данная опция сохранит запись игры с открытой информацией (например, о картах в руке). Файл будет доступен по завершении игры. + +lobby_save-replay-unshared = Мы храним 15 ваших последних записей, которыми вы не делились, так что не забудьте скачать повтор или поделиться им после игры. + +lobby_select-deck = Выбрать колоду + +lobby_select-error = Невозможно выбрать эту колоду + +lobby_select-title = Выберите вашу колоду + +lobby_side = Сторона + +lobby_singleton = Синглтон + +lobby_singleton-b = (синглтон) + +lobby_singleton-details = С данной опцией играть можно только колодами без повторяющихся карт. Рекомендуется использовать следующие карты ролей. + +lobby_singleton-example = 1) Nova Initiumia: Catalyst & Impetus 2) Ampere: Cybernetics For Anyone + +lobby_singleton-restriction = Данное лобби запущено в режиме "Синглтон". Играть можно только колодами без повторяющихся карт. + +lobby_spectator-count = {$cnt -> + *[one] {$cnt} зритель + [few] {$cnt} зрителя + [many] {$cnt} зрителей + [other] {$cnt} зрителей +} + +lobby_spectators = Допускать зрителей + +lobby_start = Начать + +lobby_start-replay = Запустить запись + +lobby_swap = Изменить стороны + +lobby_timed-game = Запустить таймер + +lobby_timed-game-details = Таймер носит информационный характер: игра будет продолжаться, когда время выйдет. + +lobby_timer-length = Продолжительность таймера (минут) + +lobby_title = Название + +lobby_title-error = Пожалуйста, введите название игры. + +lobby_too-little-data = Слишком мало данных + +lobby_type = {$type -> + [angel-arena] Арена Ангелов + [casual] Обычные + [competitive] Соревновательные + [tournament] Турнирные + *[unknown] undefined +} + +lobby_waiting = Игроки выбирают колоды + +lobby_watch = Смотреть + +log_annotating = Аннотации + +log_game-log = Журнал + +log_remote-annotations-fail = Не удалось загрузить аннотации. + +log_run-timing = Фазы забега + +log_settings = Настройки + +log_shared = Опубликованные аннотации + +log_turn-timing = Фазы хода + +menu_admin = {nav_admin} + +menu_donor = Спонсор + +menu_logout = Отключиться + +menu_moderator = Модератор + +menu_settings = {nav_settings} + +nav_about = О нас + +nav_admin = Администратор + +nav_cards = Карты + +nav_chat = Чат + +nav_deck-builder = Колоды + +nav_features = Возможности + +nav_game-count = {$cnt -> + *[one] {$cnt} игра + [few] {$cnt} игры + [many] {$cnt} игр + [other] {$cnt} игр +} + +nav_help = Помощь + +nav_play = Играть + +nav_settings = Настройки + +nav_stats = Статистика + +nav_tournaments = Турниры + +nav_users = Пользователи + +nav_welcome = Правила + +preconstructed_worlds-2012-a = ЧМ 2012: Бен Марш (К) против Джереми Звирна (Б) + +preconstructed_worlds-2012-a-tag = Бен Марш (К) против Джереми Звирна (Б) + +preconstructed_worlds-2012-a-ul = ЧМ 2012: Вейланд против Криминала + +preconstructed_worlds-2012-b = ЧМ 2012: Джереми Звирн (К) против Бена Марша (Б) + +preconstructed_worlds-2012-b-tag = Джереми Звирн (К) против Бена Марша (Б) + +preconstructed_worlds-2012-b-ul = ЧМ 2012: Хаас-Биороид против Криминала + +preconstructed_worlds-2012-info = Во время Чемпионата мира 2012 единственным легальным набором был Базовый (до 3 коробок). Джереми Звирн (Building a Better World, Gabriel Santiago) выиграл в финале у Бена Марша (Engineering the Future, Gabriel Santiago) и стал первым чемпионом мира по Netrunner. + +preconstructed_worlds-2013-a = ЧМ 2013: Йенс Эриксон (К) против Эндрю Вина (Б) + +preconstructed_worlds-2013-a-tag = Йенс Эриксон (К) против Эндрю Вина (Б) + +preconstructed_worlds-2013-a-ul = ЧМ 2013: HB FastAdv против Shaper Katman + +preconstructed_worlds-2013-b = ЧМ 2013: Эндрю Вин (К) против Йенса Эриксона (Б) + +preconstructed_worlds-2013-b-tag = Эндрю Вин (К) против Йенса Эриксона (Б) + +preconstructed_worlds-2013-b-ul = ЧМ 2013: NBN Fast Adv против Andy Sucker + +preconstructed_worlds-2013-info = В Чемпионате мира 2013 года участвовали 166 игроков. Турнир проходил в Миннеаполисе, штат Миннесота, США, и состоял из 6 раундов по швейцарской системе, переходящих в топ кат на 32 участника. Последний легальный набор: Opening Moves. + +preconstructed_worlds-2014-a = ЧМ 2014: Дэн Д'Ардженио (К) против Минна Трана (Б) + +preconstructed_worlds-2014-a-tag = Дэн Д'Ардженио (К) против Минна Трана (Б) + +preconstructed_worlds-2014-a-ul = ЧМ 2014: Honor and Perfection против Andromedium + +preconstructed_worlds-2014-b = ЧМ 2014: Минн Тран (К) против Дэна Д'Ардженио (Б) + +preconstructed_worlds-2014-b-tag = Минн Тран (К) против Дэна Д'Ардженио (Б) + +preconstructed_worlds-2014-b-ul = ЧМ 2014: Personal Evolution против Daily QT Andy + +preconstructed_worlds-2014-info = В Чемпионате мира 2014 года участвовали 238 игроков. Турнир проходил в Миннеаполисе, штат Миннесота, США, и состоял из 7 раундов по швейцарской системе, переходящих в топ кат на 16 участников. Последний легальный набор: Up and Over. + +preconstructed_worlds-2015-a = ЧМ 2015: Дэн Д'Ардженио (К) против Тимми Вона (Б) + +preconstructed_worlds-2015-a-tag = Дэн Д'Ардженио (К) против Тимми Вона (Б) + +preconstructed_worlds-2015-a-ul = ЧМ 2015: Foodcoatshop против The Morning After + +preconstructed_worlds-2015-b = ЧМ 2015: Тимми Вон (К) против Дэна Д'Ардженио (Б) + +preconstructed_worlds-2015-b-tag = Тимми Вон (К) против Дэна Д'Ардженио (Б) + +preconstructed_worlds-2015-b-ul = ЧМ 2015: Yellow Shell против Radisson Cheese Plate + +preconstructed_worlds-2015-info = В Чемпионате мира 2015 года участвовали 269 игроков. Турнир проходил в Миннеаполисе, штат Миннесота, США, и состоял из 8 раундов по швейцарской системе, переходящих в топ кат на 16 участников. Последний легальный набор: Data and Destiny. + +preconstructed_worlds-2016-a = ЧМ 2016: Крис Даер (К) против Бенджамина Ни (Б) + +preconstructed_worlds-2016-a-tag = Крис Даер (К) против Бенджамина Ни (Б) + +preconstructed_worlds-2016-a-ul = ЧМ 2016: Snekbite против Minh MaxX++ + +preconstructed_worlds-2016-b = ЧМ 2016: Бенджамин Ни (Б) против Криса Даера (К) + +preconstructed_worlds-2016-b-tag = Бенджамин Ни (Б) против Криса Даера (К) + +preconstructed_worlds-2016-b-ul = ЧМ 2016: Fiery Info против Papa Smurf + +preconstructed_worlds-2016-info = В Чемпионате мира 2016 года участвовали 278 игроков. Турнир проходил в Миннеаполисе, штат Миннесота, США, и состоял из 9 раундов по швейцарской системе, переходящих в топ кат на 16 участников. Последний легальный набор: Escalation. + +preconstructed_worlds-2017-a = ЧМ 2017: Джесс Хориг (К) против Грей Тон (Б) + +preconstructed_worlds-2017-a-tag = Джесс Хориг (К) против Грей Тон (Б) + +preconstructed_worlds-2017-a-ul = ЧМ 2017: Stinson Reversed CI против Aesops Hayley + +preconstructed_worlds-2017-b = ЧМ 2017: Грей Тон (К) против Джесс Хориг (Б) + +preconstructed_worlds-2017-b-tag = Грей Тон (К) против Джесс Хориг (Б) + +preconstructed_worlds-2017-b-ul = ЧМ 2017: No-Show Rewiring CI против Laguna Lock Hayley + +preconstructed_worlds-2017-info = В Чемпионате мира 2016 года участвовали 233 игрока. Турнир проходил в Миннеаполисе, штат Миннесота, США, и состоял из 8(?) раундов по швейцарской системе, переходящих в топ кат на 16 участников. Последний легальный набор: Revised Core set. + +preconstructed_worlds-2018-a = ЧМ 2018: Джо Шуп (К) против Криса Даера (Б) + +preconstructed_worlds-2018-a-tag = Джо Шуп (К) против Криса Даера (Б) + +preconstructed_worlds-2018-a-ul = ЧМ 2018: AMERICA CtM против Gooseberry MaxX + +preconstructed_worlds-2018-b = ЧМ 2018: Крис Даер (К) против Джо Шупа (Б) + +preconstructed_worlds-2018-b-tag = Крис Даер (К) против Джо Шупа (Б) + +preconstructed_worlds-2018-b-ul = ЧМ 2018: Trust the Process против Dan D'Argenio KoS Val + +preconstructed_worlds-2018-info = В Чемпионате мира 2016 года участвовали 403(!) игрока. Это последний ЧМ, прошедший под крылом FFG. Турнир проходил в Миннеаполисе, штат Миннесота, США, и состоял из 9(?) раундов по швейцарской системе, переходящих в топ кат на 16 участников. Последний легальный набор: Reign and Reverie + +preconstructed_worlds-2019-a = ЧМ 2019: Pinsel (К) против Testrunning (Б) + +preconstructed_worlds-2019-a-tag = Pinsel (К) против Testrunning (Б) + +preconstructed_worlds-2019-a-ul = ЧМ 2019: Fully dedicated to efficiency против Trash Panda + +preconstructed_worlds-2019-b = ЧМ 2019: Testrunning (К) против Pinsel (Б) + +preconstructed_worlds-2019-b-tag = Testrunning (К) против Pinsel (Б) + +preconstructed_worlds-2019-b-ul = ЧМ 2019: 2 Grid for 2 Place против Trash Panda + +preconstructed_worlds-2019-info = В первом Чемпионате мира по Netrunner, устроенным Project NISEI в 2019 году, поучаствовали 256 человек. Турнир проходил в Роттердаме, Нидерланды, и состоял из 9 раундов по швейцарской системе, переходящих в топ кат на 16 участников. Последний легальный набор: Uprising Booster Pack + +preconstructed_worlds-2020-a = ЧМ 2020: Limes (К) против tf34 (Б) + +preconstructed_worlds-2020-a-tag = Limes (К) против tf34 (Б) + +preconstructed_worlds-2020-a-ul = ЧМ 2020: I don't like this deck против Engolo Freedom + +preconstructed_worlds-2020-b = ЧМ 2020: tf34 (Б) против Limes (К) + +preconstructed_worlds-2020-b-tag = tf34 (Б) против Limes (К) + +preconstructed_worlds-2020-b-ul = ЧМ 2020: Malia CTM против Imp-pressive Hoshiko + +preconstructed_worlds-2020-info = В первом онлайн Чемпионате мира по Netrunner, проведённом Project NISEI в 2020 году, приняли участие 294 игрока. Из-за ограничений в перемещениях в начале пандемии COVID-19 турнир был проведён онлайн на jinteki.net и состоял из 8 раундов по швейцарской системе, разбитых на 2 дня для двух разных групп игроков, переходящих в топ кат на 16 участников. Последний легальный набор: Uprising. + +preconstructed_worlds-2021-a = ЧМ 2021: Патрик Гауэр (К) против Джонаса (Б) + +preconstructed_worlds-2021-a-tag = Патрик Гауэр (К) против Джонаса (Б) + +preconstructed_worlds-2021-a-ul = ЧМ 2021: 44 Card PD против Watch Me Drip, Watch Me Maemi + +preconstructed_worlds-2021-b = ЧМ 2021: Джонас (К) против Патрика Гауэра (Б) + +preconstructed_worlds-2021-b-tag = Джонас (К) против Патрика Гауэра (Б) + +preconstructed_worlds-2021-b-ul = ЧМ 2021: Is Gagarin Good? против Medium to Large Maxx + +preconstructed_worlds-2021-info = Во втором онлайн Чемпионате мира по Netrunner, проведённом Project NISEI в 2021 году, принял участие 201 игрок. Из-за продолжающихся осложнений пандемии COVID-19 турнир был проведён онлайн на jinteki.net и состоял из 8 раундов по швейцарской системе, разбитых на 2 дня для двух разных групп игроков, переходящих в топ кат на 16 участников. Последний легальный набор: System Gateway. + +preconstructed_worlds-2022-a = ЧМ 2022: Уильям Хвон (К) против skry (Б) + +preconstructed_worlds-2022-a-tag = Уильям Хвон (К) против skry (Б) + +preconstructed_worlds-2022-a-ul = ЧМ 2022: SNACS против Liberté, Égalité, Humidité + +preconstructed_worlds-2022-b = ЧМ 2022: skry (К) против Уильяма Хвона (Б) + +preconstructed_worlds-2022-b-tag = skry (К) против Уильяма Хвона (Б) + +preconstructed_worlds-2022-b-ul = ЧМ 2022: Dies to Doom Blade против ApocoLat + +preconstructed_worlds-2022-info = В 2022 году Null Signal Games, ранее известные как Project NISEI, провели первый Чемпионат мира по Netrunner оффлайн с начала пандемии COVID-19. В мероприятии приняли участие 158 игроков. Турнир проходил в Торонто, Канада, и состоял из 7 раундов по швейцарской системе, переходящих в топ кат на 16 участников. Последний легальный набор: Midnight Sun. + +preconstructed_worlds-2023-a = ЧМ 2023: Уильям Хвон (К) против cableCarnage (Б) + +preconstructed_worlds-2023-a-tag = Уильям Хвон (К) против cableCarnage (Б) + +preconstructed_worlds-2023-a-ul = ЧМ 2023: The Worlds Grind против sableCarnage + +preconstructed_worlds-2023-b = ЧМ 2023: cableCarnage (К) против Уильяма Хвона (Б) + +preconstructed_worlds-2023-b-tag = cableCarnage (К) против Уильяма Хвона (Б) + +preconstructed_worlds-2023-b-ul = ЧМ 2023: tableCarnage против You *do* always come back! + +preconstructed_worlds-2023-info = Во втором Чемпионате мира по Netrunner под крылом Null Signal Games приняли участие 254 игрока. Турнир проходил в Барселоне, Испания, и состоял из 9 раундов по швейцарской системе, переходящих в топ кат на 16 участников. Последний легальный набор: The Automata Initiative. + +pronouns = {$pronoun -> + [any] Любые + [blank] [пусто] + [ey] undefined + [faefaer] undefined + [he] Он/его + [heit] undefined + [heshe] undefined + [hethey] Он/они + [it] Оно + [myodb] Не хочу указывать + [ne] undefined + *[none] Не указаны + [she] Она/её + [sheit] undefined + [shethey] Она/они + [they] Они/их + [ve] undefined + [xe] undefined + [xi] undefined + [zehir] undefined + [zezir] undefined +} + +set_name = {$name -> + [a23-seconds] 23 Seconds + [a-study-in-static] undefined + [all] Все + [all-that-remains] undefined + [alt-art] Альтернативные арты + [alternate] Альтернативные + [ashes-cycle] undefined + [blood-and-water] undefined + [blood-money] undefined + [borealis-cycle] undefined + [breaker-bay] undefined + [business-first] undefined + [championship-2019] Championship 2019 + [championship-2020] Championship 2020 + [chrome-city] undefined + [core-set] undefined + [council-of-the-crest] undefined + [creation-and-control] undefined + [crimson-dust] undefined + [cyber-exodus] undefined + [daedalus-complex] undefined + [data-and-destiny] undefined + [democracy-and-dogma] undefined + [double-time] undefined + [down-the-white-nile] undefined + [downfall] undefined + [draft] undefined + [draft-cycle] undefined + [earth-s-scion] undefined + [escalation] undefined + [fear-and-loathing] undefined + [fear-the-masses] undefined + [first-contact] undefined + [flashpoint-cycle] undefined + [free-mars] undefined + [future-proof] undefined + [genesis-cycle] undefined + [gnk-2019] GNK 2019 + [honor-and-profit] undefined + [humanity-s-shadow] undefined + [intervention] undefined + [kala-ghoda] undefined + [kampala-ascendent] undefined + [kitara-cycle] undefined + [kysra-alt-arts] Альт-арты от Kysra + [liberation-cycle] undefined + [lunar-cycle] undefined + [magnum-opus] undefined + [magnum-opus-reprint] undefined + [mala-tempora] undefined + [martial-law] undefined + [midnight-sun] undefined + [midnight-sun-booster-pack] undefined + [mumbad-cycle] undefined + [napd-multiplayer] undefined + [ntscape-navigator-alt-arts] Альт-арты от Ntscape Navigator + [old-hollywood] undefined + [opening-moves] undefined + [order-and-chaos] undefined + [parhelion] undefined + [plural-and-miniplural-alt-arts] Альт-арты от Plural и MiniPlural + [previous-versions] Предыдущие версии + [quorum] undefined + [rebellion-without-rehearsal] undefined + [red-sand-cycle] undefined + [reign-and-reverie] undefined + [revised-core-set] undefined + [salsette-island] undefined + [salvaged-memories] undefined + [sansan-cycle] undefined + [second-thoughts] undefined + [signed-championship-2020] Signed Championship 2020 + [sovereign-sight] undefined + [spin-cycle] undefined + [station-one] undefined + [system-core-2019] System Core 2019 + [system-gateway] Врата Системы + [system-update-2021] Обновление Системы 2021 + [terminal-directive-campaign] undefined + [terminal-directive-cards] undefined + [terminal-directive-cycle] undefined + [the-automata-initiative] undefined + [the-devil-and-the-dragon] undefined + [the-liberated-mind] undefined + [the-source] undefined + [the-spaces-between] undefined + [the-underway] undefined + [the-universe-of-tomorrow] undefined + [the-valley] undefined + [trace-amount] undefined + [true-colors] undefined + [unreleased] Не выпущенные + [up-and-over] undefined + [uprising] undefined + [uprising-booster-pack] undefined + [upstalk] undefined + [what-lies-ahead] undefined + [whispers-in-nalubaale] undefined + [world-champion-2015] Чемпион мира 2015 + [world-champion-2016] Чемпион мира 2016 + [world-champion-2017] Чемпион мира 2017 + *[unknown] undefined +} + +settings_alt-art = Альтернативные изображения карт + +settings_always = Всегда + +settings_api-keys = Ключи API + +settings_avatar = Аватар + +settings_background = Фон игрового поля + +settings_bespoke-sounds = {$sound -> + [bespoke-sounds-header] Звуки для отдельных карт + [archer] Лучник + [end-of-the-line] undefined + [harmonics] Гармонические льды (Bloop, Echo, Pulse, Wave) + *[unknown] undefined +} + +settings_bg = {$slug -> + [custom-bg] Индивидуальный фон + [monochrome-bg] Монотонный + [worlds2020-bg] Чемпионат мира 2020 + *[unknown] undefined +} + +settings_block = Заблокировать пользователя + +settings_blocked = Заблокированные пользователи + +settings_cancel = Отмена + +settings_card-backs = Рубашки карт + +settings_card-iamge = Показывать изображение карты + +settings_card-images = Изображения карт + +settings_card-preview-zoom = Увеличение карт при наведении + +settings_card-text = Показывать текст карты + +settings_change-avatar = Изменить на gravatar.com + +settings_change-email = Изменить адрес электронной почты + +settings_comp-only = Только в соревновательном лобби + +settings_create-api-key = Создать ключ API + +settings_current-email = Текущий адрес + +settings_deck-stats = Учёт статистики колод + +settings_delete-api-key = Удалить + +settings_desired-email = Новый адрес + +settings_email = Электронная почта + +settings_email-placeholder = Адрес электронной почты + +settings_email-title = Изменить адрес электронной почты + +settings_enable-game-sounds = Включить звуки в игре + +settings_enable-lobby-sounds = Включить звуки в лобби + +settings_enter-valid = Пожалуйста, введите корректный адрес электронной почты + +settings_game-stats = Учёт статистики побед/поражений + +settings_get-log-top = Записать текущую высоту журнала + +settings_get-log-width = Записать текущую ширину журнала + +settings_ghost-trojans = Отображать бледные дубликаты программ-троянов, установленных на карты-носители + +settings_high-res = Включить загрузку изображений высокого разрешения + +settings_invalid-email = Учётной записи с таким адресом электронной почты не существует + +settings_invalid-password = Неправильный логин или пароль + +settings_language = Язык + +settings_layout-options = Настройки расположения + +settings_log-player-highlight = Подсвечивать игроков в журнале + +settings_log-player-highlight-none = Не подсвечивать + +settings_log-player-highlight-red-blue = Корпорация: Синий / Бегущий: Красный + +settings_log-size = Размер журнала + +settings_none = Не учитывать + +settings_pin-zoom = Оставлять последнюю увеличенную карту на экране + +settings_player-stats-icons = Использовать иконки в игровой статистике + +settings_pronouns = Местоимения + +settings_reset = Сбросить до официальных изображений + +settings_runner-classic = Классическая раскладка Бегущего (Сверху вниз: Программы, Устройства, Ресурсы) + +settings_runner-layout = Раскладка Бегущего при игре за Корпорацию + +settings_runner-reverse = Обратная раскладка Бегущего (Сверху вниз: Ресурсы, Устройства, Программы) + +settings_set = Изменить + +settings_set-all = Изменить все карты на + +settings_show-alt = Показывать альтернативные изображения карт + +settings_sides-overlap = Карты Бегущего и Корпорации могут перекрывать друг друга + +settings_sounds = Звуки + +settings_stacked-cards = Складывать вместе одинаковые карты (по умолчанию включено) + +settings_update = Сохранить + +settings_update-profile = Сохранить настройки + +settings_updated = Настройки сохранены. Пожалуйста, перезагрузите страницу браузера + +settings_updating = Сохранение настроек... + +settings_user-name = Имя пользователя + +settings_volume = Громкость + +side_name = {$side -> + [all] Все + [any-side] Обе стороны + [corp] Корпорация + [runner] Бегущий + *[unknown] undefined +} + +stats_all-games = Показать все игры + +stats_cards-accessed = Карт в доступе + +stats_cards-click = Взято карт за клики + +stats_cards-drawn = Взято карт + +stats_cards-rezzed = Развёрнуто карт + +stats_cards-sabotaged = Сброшено карт от саботажа + +stats_clear-stats = Очистить статистику + +stats_clicks-gained = Получено кликов + +stats_completed = Завершено: {$completed} ({NUMBER($percent, style: "percent")}) + +stats_corp-stats = Статистика за Корпорацию + +stats_credits-click = Получено кредитов за клики + +stats_credits-gained = Получено кредитов + +stats_credits-spent = Потрачено кредитов + +stats_damage-done = Нанесено урона + +stats_download = Скачать запись + +stats_ended = Закончено + +stats_events-played = Разыграно событий + +stats_format = Формат + +stats_game-stats = Игровая статистика + +stats_game-title = {$title} ({$cnt -> + *[one] {$cnt} ход + [few] {$cnt} хода + [many] {$cnt} ходов + [other] {$cnt} ходов +}) + +stats_launch = Запустить запись + +stats_lobby = Лобби + +stats_log-count = {$cnt -> + *[one] {$cnt} журнал + [few] {$cnt} журнала + [many] {$cnt} журналов + [other] {$cnt} журналов +} + +stats_log-count-filtered = {$cnt -> + *[one] {$cnt} журнал (отфильтровано) + [few] {$cnt} журнала (отфильтровано) + [many] {$cnt} журналов (отфильтровано) + [other] {$cnt} журналов (отфильтровано) +} + +stats_lost = Проиграно: {$lost} ({NUMBER($percent, style: "percent")}) + +stats_no-games = Нет игр + +stats_no-log = Журнал недоступен + +stats_not-completed = Не завершено: {$completed} ({NUMBER($percent, style: "percent")}) + +stats_operations-played = Разыграно операций + +stats_psi-game-total = Пси-игры: Сыграно игр + +stats_psi-game-total-bid-0 = Пси-игры: Ставка 0 + +stats_psi-game-total-bid-1 = Пси-игры: Ставка 1 + +stats_psi-game-total-bid-2 = Пси-игры: Ставка 2 + +stats_psi-game-total-wins = Пси-игры: Побед + +stats_rashida-count = Разыграно карт Rashida Jaheem + +stats_runner-stats = Статистика за Бегущего + +stats_runs-made = Совершено забегов + +stats_share = Поделиться записью + +stats_shared-games = Показать игры с публичными записями + +stats_shuffle-count = Перемешиваний колоды + +stats_started = Начато: {$started} + +stats_tags-gained = Получено меток + +stats_unavailable = Запись недоступна + +stats_unique-accesses = Уникальных карт в доступе + +stats_view-games = Вернуться к статистике + +stats_view-log = Смотреть журнал + +stats_win-method = Способ победы + +stats_winner = Победитель + +stats_won = Выиграно: {$won} ({NUMBER($percent, style: "percent")}) diff --git a/resources/public/i18n/zh-simp.ftl b/resources/public/i18n/zh-simp.ftl new file mode 100644 index 0000000000..0ca7653823 --- /dev/null +++ b/resources/public/i18n/zh-simp.ftl @@ -0,0 +1,1410 @@ +annotations_available-annotations = 可用注释 + +annotations_clear = 清除本地注释 + +annotations_click-placeholder = 关于此点击的注释 + +annotations_import-local = 导入本地注释文件 + +annotations_load-local = 加载 + +annotations_no-published-annotations = 没有已发布的注释。 + +annotations_publish = 发布 + +annotations_save-local = 保存 + +annotations_turn-placeholder = 关于此回合的注释 + +card-browser-form_faction = 派系 + +card-browser-form_format = 赛制 + +card-browser-form_search-hint = 搜索卡牌 + +card-browser-form_side = 阵营 + +card-browser-form_sort = 排序方式 + +card-browser-form_sort-by = {$by -> + [cost] 费用 + [faction] 派系 + [influence] 影响力 + [name] 牌名 + [set-number] 系列编号 + [type] 类别 + *[unknown] undefined +} + +card-browser-form_type = 类别 + +card-browser_advancement = 推进需求: {$requirement} + +card-browser_agenda-points = 议案分数: {$points} + +card-browser_artist-info = 艺术家 + +card-browser_clear = 清除 + +card-browser_cost = 费用: {$cost} + +card-browser_implementation-note = 实施笔记: {$impl} + +card-browser_inf-limit = 影响力上限: {$inf-limit} + +card-browser_influence = 影响力: {$influence} + +card-browser_memory = 内存: {$memory} + +card-browser_min-deck-size = 牌组张数下限: {$min-deck-size} + +card-browser_more-info = 更多信息 + +card-browser_select-art = 选择卡面 + +card-browser_selected-art = 已选卡面 + +card-browser_set = 系列 + +card-browser_strength = 强度: {$strength} + +card-browser_trash-cost = 销毁费用: {$trash-cost} + +card-browser_update-failure = 卡面更换失败 + +card-browser_update-success = 卡面已更换 + +card-type_name = {$type -> + [agenda] 议案 + [all] 全部 + [asset] 资产 + [event] 事件 + [hardware] 硬件 + [ice] 防火墙 + [identity] 特性(ID) + [operation] 事务 + [program] 程序 + [resource] 资源 + [upgrade] 升级 + *[unknown] undefined +} + +chat_block = 屏蔽用户 + +chat_cancel = 取消 + +chat_channels = 频道 + +chat_delete = 删除消息 + +chat_delete-all = 删除该用户发送的所有消息 + +chat_length-exceeded = 超出长度 + +chat_message-blocked = 消息堵塞: {$reason-str} + +chat_placeholder = 说点什么吧 + +chat_rate-exceeded = 超出速率 + +chat_send = 发送 + +chat_title = 在浏览器中玩《安卓纪元:矩阵潜袭》 + +deck-builder_add-cards = 添加卡牌 + +deck-builder_add-to-deck = 添加到牌组 + +deck-builder_agenda-points = 议案分数 + +deck-builder_cancel = 取消 + +deck-builder_card-name = 卡牌名称 + +deck-builder_clear-stats = 清除统计数据 + +deck-builder_completed = 完成: {$completed} + +deck-builder_confirm-delete = 确认删除 + +deck-builder_copy = 复制 + +deck-builder_create-game = 创建对战 + +deck-builder_deck-copy-suffix = 复制 + +deck-builder_deck-count = {$cnt -> + [zero] 没有牌组 + *[other] 套牌组 +} + +deck-builder_deck-count-filtered = {$cnt -> + [zero] 没有牌组(过滤后) + *[other] 套牌组(过滤后) +} + +deck-builder_deck-name = 牌组名称 + +deck-builder_deck-notes = 牌组备注 + +deck-builder_deck-points = 牌组点数 + +deck-builder_decklist = 牌表 + +deck-builder_decklist-inst = (在此输入或粘贴牌表,系统会自动解析) + +deck-builder_delete = 删除 + +deck-builder_edit = 编辑 + +deck-builder_format = 赛制 + +deck-builder_games = 局数: {$games} + +deck-builder_hash = 卡组hash(比赛用) + +deck-builder_identity = 特性(ID) + +deck-builder_illegal = 不可用 + +deck-builder_import = 导入 + +deck-builder_import-button = 导入牌组 + +deck-builder_import-placeholder = NRDB ID + +deck-builder_import-title = 请输入NRDB上公开牌组的ID或URL + +deck-builder_influence = 影响力 + +deck-builder_legal = 可用 + +deck-builder_loading-msg = 牌组加载中…… + +deck-builder_lost = 败北: {$lost} + +deck-builder_max = 最多 + +deck-builder_min = 最少 + +deck-builder_new-corp = 新建公司牌组 + +deck-builder_new-deck = 新建牌组 + +deck-builder_new-runner = 新建潜袭者牌组 + +deck-builder_notes = 备注 + +deck-builder_reset = 重置 + +deck-builder_save = 保存 + +deck-builder_why = 为什么? + +deck-builder_won = 胜利: {$won} ({NUMBER($percent, style: "percent")}) + +diagrams_run-timing_approach = 6.9.2: 接驳防火墙阶段 + +diagrams_run-timing_approach-a = 潜袭者接驳所在位置的防火墙。接驳事件结算 + +diagrams_run-timing_approach-b = 付费能力窗口。公司可以激活非防火墙卡牌和/或潜袭者接驳的防火墙。 + +diagrams_run-timing_approach-c = 如果接驳的防火墙已激活,继续到遭遇阶段(6.9.3) + +diagrams_run-timing_approach-d = 否则,进入到移动阶段(6.9.4) + +diagrams_run-timing_disclaimer = 为了清晰起见,该时序图已被简化。如需完整规则,请参阅“Null Signal Games”网站。 + +diagrams_run-timing_encounter = 6.9.3: 遭遇防火墙阶段 + +diagrams_run-timing_encounter-a = 潜袭者遭遇所在位置的防火墙。遭遇事件结算 + +diagrams_run-timing_encounter-b = 付费能力窗口。可以与所遭遇的防火墙进行交互。 + +diagrams_run-timing_encounter-c = 如果有需要结算的未破解子进程,公司会至上而下依次结算未破解子进程。 + +diagrams_run-timing_encounter-d = 遭遇完成。进入到移动阶段(6.9.4) + +diagrams_run-timing_header = 潜袭时序图 + +diagrams_run-timing_initiation = 6.9.1: 发起阶段 + +diagrams_run-timing_initiation-a = 潜袭者宣布攻击的服务器 + +diagrams_run-timing_initiation-b = 潜袭者获得负面声誉信用点 + +diagrams_run-timing_initiation-c = 潜袭正式开始 —— 潜袭事件结算 + +diagrams_run-timing_initiation-d = 如可能,接驳最外层的防火墙,并开始接驳阶段(6.9.2) + +diagrams_run-timing_initiation-e = 否则,进入到移动阶段(6.9.4) + +diagrams_run-timing_movement = 6.9.4: 移动阶段 + +diagrams_run-timing_movement-a = 如果潜袭者从接驳阶段或遭遇阶段到达此阶段,则通过防火墙。通过防火墙事件结算 + +diagrams_run-timing_movement-b = 如果潜袭者与服务器之间没有防火墙,‘当你通过服务器上的所有防火墙’事件结算 + +diagrams_run-timing_movement-c = 付费能力窗口 + +diagrams_run-timing_movement-d = 潜袭者可以退出。如这样做, 进入到潜袭结束阶段(6.9.6) + +diagrams_run-timing_movement-e = 如可能,潜袭者向内移动1位置 + +diagrams_run-timing_movement-f = 付费能力窗口。公司可以激活非防火墙卡牌 + +diagrams_run-timing_movement-g = 如果潜袭者接驳另一个防火墙,返回到接驳阶段(6.9.2) + +diagrams_run-timing_movement-h = 潜袭者接驳攻击的服务器。接驳事件结算 + +diagrams_run-timing_movement-i = 继续到成功阶段(6.9.5) + +diagrams_run-timing_run-ends = 6.9.6: 潜袭结束阶段 + +diagrams_run-timing_run-ends-a = 任何打开的优先权窗口结算或关闭 + +diagrams_run-timing_run-ends-b = 潜袭者失去未花费的负面声誉信用 + +diagrams_run-timing_run-ends-c = 如果未达到成功阶段且攻击的服务器仍然存在,潜袭声明为失败 + +diagrams_run-timing_run-ends-d = 潜袭结束。潜袭结束事件结算 + +diagrams_run-timing_success = 6.9.5: 成功阶段 + +diagrams_run-timing_success-a = 此潜袭声明为成功。潜袭成功事件结算 + +diagrams_run-timing_success-b = 潜袭者侵入服务器 + +diagrams_run-timing_success-c = 成功阶段完成。继续到潜袭结束阶段(6.9.6) + +diagrams_turn_corp-action-phase = 5.6.2: 行动阶段 + +diagrams_turn_corp-action-phase-a = 付费能力窗口。公司可以激活非防火墙卡牌和/或计分议案 + +diagrams_turn_corp-action-phase-b = 如果公司有未使用的[Clicks],进行一个行动 + +diagrams_turn_corp-action-phase-c = 如果一个行动已发生,返回到(a) + +diagrams_turn_corp-action-phase-d = 行动阶段完成。进入到弃牌阶段(5.6.3) + +diagrams_turn_corp-discard-phase = 5.6.3: 弃牌阶段 + +diagrams_turn_corp-discard-phase-a = 如可能,公司弃牌至手牌上限 + +diagrams_turn_corp-discard-phase-b = 付费能力窗口。公司可以激活非防火墙卡牌 + +diagrams_turn_corp-discard-phase-c = 如果公司有任何[Clicks]剩余,则失去这些[Clicks] + +diagrams_turn_corp-discard-phase-d = 公司回合正式结束。回合结束触发效果结算 + +diagrams_turn_corp-discard-phase-e = 进入到潜袭者回合 + +diagrams_turn_corp-draw-phase = 5.6.1: 抽牌阶段 + +diagrams_turn_corp-draw-phase-a = 公司获得可用时点(默认: [click][click][click]) + +diagrams_turn_corp-draw-phase-b = 付费能力窗口。公司可以激活非防火墙卡牌和/或计分议案 + +diagrams_turn_corp-draw-phase-c = 公司填充可再生信用点 + +diagrams_turn_corp-draw-phase-d = 回合正式开始。回合开始事件结算 + +diagrams_turn_corp-draw-phase-e = 公司执行强制抽牌 + +diagrams_turn_corp-draw-phase-f = 进入到行动阶段(5.6.2) + +diagrams_turn_corp-turn = 公司回合 + +diagrams_turn_runner-action-phase = 5.7.1: 行动阶段 + +diagrams_turn_runner-action-phase-a = 潜袭者获得可用时点(默认: [click][click][click][click]) + +diagrams_turn_runner-action-phase-b = 付费能力窗口。公司可以激活非防火墙卡牌 + +diagrams_turn_runner-action-phase-c = 潜袭者填充可再生信用点 + +diagrams_turn_runner-action-phase-d = 回合正式开始。回合开始事件结算 + +diagrams_turn_runner-action-phase-e = 付费能力窗口。公司可以激活非防火墙卡牌 + +diagrams_turn_runner-action-phase-f = 如果潜袭者有未使用的[Clicks],进行一个行动 + +diagrams_turn_runner-action-phase-g = 如果一个行动已发生,返回到(e) + +diagrams_turn_runner-action-phase-h = 行动阶段完成。进入到弃牌阶段(5.7.2) + +diagrams_turn_runner-discard-phase = 5.7.2: 弃牌阶段 + +diagrams_turn_runner-discard-phase-a = 如可能,潜袭者弃牌至手牌上限 + +diagrams_turn_runner-discard-phase-b = 付费能力窗口。公司可以激活非防火墙卡牌 + +diagrams_turn_runner-discard-phase-c = 如果潜袭者有任何[Clicks]剩余,则失去这些[Clicks] + +diagrams_turn_runner-discard-phase-d = 潜袭者回合正式结束。回合结束触发效果结算 + +diagrams_turn_runner-discard-phase-e = 进入到公司回合 + +diagrams_turn_runner-turn = 潜袭者回合 + +faction_name = {$faction -> + [adam] 亚当 + [all] 全部 + [anarch] 反叛者 + [any-faction] 任意派系 + [apex] 尖峰 + [criminal] 逆法者 + [haas-bioroid] 哈斯生化 + [jinteki] 人间会社 + [nbn] 网际传媒 + [neutral] 中立 + [shaper] 塑造者 + [sunny-lebeau] 桑妮·勒博 + [weyland-consortium] 威兰财团 + *[unknown] undefined +} + +format_name = {$format -> + [all] 全部 + [any-format] 任意赛制 + [casual] 休闲 + [classic] 经典 + [core-experience] 核心体验 + [eternal] 永久 + [neo] Neo + [preconstructed] 预构筑 + [snapshot] 快照 + [snapshot-plus] 快照+ + [socr] SOCR + [standard] 标准 + [startup] 新启 + [sunset] 落日 + [system-gateway] 核心网关 + [throwback] undefined + *[unknown] undefined +} + +game_abilities = 能力 + +game_actions = 操作 + +game_agenda-count = agenda-point 议案分数 + +game_approach-ice = 接驳防火墙 + +game_archives = 档案库{"\u00A0"}({$faceup} ↑ {$facedown} ↓) + +game_attempt-reconnect = 尝试重新连接 + +game_auto-pass = 自动让过优先权 + +game_bad-pub-count = {$base} 负面声誉 + +game_bad-pub-count-additional = {$base} 负面声誉 + {$additional} 负面声誉 + +game_beat-trace = 击败追踪 + +game_brain-damage = 脑部伤害 + +game_breach-server = 侵入服务器 + +game_card = 卡牌 + +game_card-count = {$cnt} 张卡牌。 + +game_click-count = {$click} 时点 + +game_close = 关闭 + +game_close-shuffle = 关闭并洗牌 + +game_concede = 投降 + +game_continue = 继续 + +game_continue-to = 继续 {$phase} + +game_corp-view = 公司视图 + +game_credit-count = {$credit} 信用点 + +game_credit-count-with-run-credits = {$credit} 信用点({$run-credit} 个本次潜袭专用) + +game_credits = 个信用点 + +game_current = 局势 + +game_current-phase = 当前阶段 + +game_draw = 抽牌 + +game_encounter-ice = 遭遇防火墙 + +game_end-turn = 结束回合 + +game_error = 内部服务器错误。请在聊天中键入/bug并按照说明操作。 + +game_face-down-count = {$total}张卡牌,{$facedown}张牌面朝下。 + +game_fire-unbroken = 结算未破解的子进程 + +game_gain-credit = 获得信用点 + +game_game-start = 对战开始时间: {$timestamp} + +game_grip = 操控器 + +game_heap = 堆阵 ({$cnt}) + +game_hq = 总部 + +game_inactivity = 对战因长期无活动而关闭 + +game_indicate-action = 我要响应 + +game_initiation = 发起潜袭 + +game_jack-out = 退出潜袭 + +game_keep = 保留 + +game_leave = 离开对战 + +game_leave-replay = 关闭回放 + +game_let-subs-fire = 让公司结算子进程 + +game_link-strength = 中转强度 + +game_lost-connection = 与服务器的连接中断。重新连接。 + +game_mandatory-draw = 回合开始抽牌 + +game_max-hand = {$total} 手牌上限 + +game_minutes = 分: + +game_movement = 移动 + +game_mu-count = {$unused} / {$available} 空闲内存 + +game_mulligan = 调度 + +game_mute = 禁止旁观者发言 + +game_no-current-run = 当前无潜袭进行中 + +game_no-further = 没有响应 + +game_ok = OK + +game_play-area = 出牌区 + +game_prompt = {$msg -> + [advance] 推进 + [archives] 档案库 + [derez] 关闭 + [expend] 消耗 + [hq] 总部 + [new-remote] 新远程 + [r-d] 研发中心 + [rez] 激活 + [score] 计分 + [server-1] 服务器 1 + [server-10] 服务器 10 + [server-2] 服务器 2 + [server-3] 服务器 3 + [server-4] 服务器 4 + [server-5] 服务器 5 + [server-6] 服务器 6 + [server-7] 服务器 7 + [server-8] 服务器 8 + [server-9] 服务器 9 + [trash] 销毁 + *[unknown] undefined +} + +game_purge = 清除病毒指示物 + +game_reconnected-to-server = 已重新连接到服务器 + +game_remove-tag = 移除锁定标记 + +game_rez = 激活 + +game_rfg = 移出游戏 + +game_rnd = 研发中心 + +game_run = 潜袭 + +game_run-ends = 潜袭结束 + +game_runner-view = 潜袭者视图 + +game_scored-area = 计分区 + +game_seconds = 秒 + +game_seconds-remaining = 秒剩余 + +game_server = 服务器 {$num} + +game_set-aside = 设置一旁 + +game_show = 显示 + +game_shuffle = 洗牌 + +game_spec-count = {$cnt} 位观众 + +game_spec-view = 旁观者视图 + +game_special-mu-count = {$unused} / {$available} {$mu-type} 空闲内存 + +game_stack = 存储栈 + +game_start = 开始对战 + +game_start-turn = 开始回合 + +game_stop-auto-pass = 取消自动让过优先权 + +game_subs = 子进程 + +game_success = 成功 + +game_tag-count = {$base} 锁定标记 + +game_tag-count-additional = {$base} + {$additional} 锁定标记 + +game_take-clicks = 进入行动阶段 + +game_time-taken = 对战用时:{$time}分钟 + +game_trace = 追踪强度 + +game_trash-resource = 销毁资源 + +game_unbeatable = 使不可击败 + +game_unimplemented = 功能未实现 + +game_unknown-phase = 未知阶段 + +game_unmute = 允许旁观者发言 + +game_win-claimed = {$winner} ({$side})于第{$turn}回合因声明而获胜 + +game_win-conceded = {$winner} ({$side})于第{$turn}回合因对手投降而获胜 + +game_win-decked = {$winner} ({$side})于第{$turn}回合因公司无牌可抽而获胜 + +game_win-flatlined = {$winner} ({$side})于第{$turn}回合通过杀死潜袭者而获胜 + +game_win-other = {$winner} ({$side})于第{$turn}回合因{$reason}而获胜 + +game_win-points = {$winner} ({$side})于第{$turn}回合因议案分数而获胜 + +ingame-settings_alt-art = 异画卡 + +ingame-settings_board-overlap = 面板重叠 + +ingame-settings_card-backs = 卡背 + +ingame-settings_card-image = 卡牌图像 + +ingame-settings_card-images = 卡牌图像 + +ingame-settings_card-sorting = 排序 + +ingame-settings_card-stacking = 卡牌设置 + +ingame-settings_card-text = 卡牌文本 + +ingame-settings_ghost-trojans = 对于被负载的程序显示鬼影 + +ingame-settings_high-res = 启用高分辨率卡牌图像 + +ingame-settings_label-faceup-cards = 贴标签于面朝上卡牌 + +ingame-settings_label-unrezzed-cards = 贴标签于未激活卡牌 + +ingame-settings_preview-zoom = 卡牌预览缩放 + +ingame-settings_runner-board-order = 潜袭者面板顺序 + +ingame-settings_runner-classic = 经典 + +ingame-settings_runner-reverse = 反转 + +ingame-settings_save = 保存 + +ingame-settings_show-alt = 显示异画卡 + +ingame-settings_sides-overlap = 潜袭者和公司面板可以重叠 + +ingame-settings_sort-archives = 排序档案库 + +ingame-settings_sort-heap = 排序堆阵 + +ingame-settings_stack-cards = 启用服务器堆叠 + +lobby_aborted = 连接已中断 + +lobby_api-access = 允许 API 访问游戏信息 + +lobby_api-access-details = 这允许第三方扩展访问有关你游戏的信息。需要在“设置”中创建API密钥 + +lobby_api-requires-key = (需要设置 API 密钥) + +lobby_as-corp = 作为公司 + +lobby_as-runner = 作为潜袭者 + +lobby_both-perspective = 双方视角 + +lobby_cancel = 取消 + +lobby_chat = 聊天 + +lobby_closed-msg = 房间因长期无活动而关闭 + +lobby_completion-rate = 游戏完成率 + +lobby_corp-perspective = 公司视角 + +lobby_create = 创建 + +lobby_deck-selected = 牌组已选择 + +lobby_default-game-format = 默认游戏赛制 + +lobby_delete = 删除房间 + +lobby_filter = 过滤 + +lobby_format = 赛制 + +lobby_game-count = {$cnt} 局对战 + +lobby_game-count-filtered = {$cnt} 局对战(过滤后) + +lobby_gateway-format = {$format -> + [beginner] 初学者 + [beginner-info] 此大厅为公司和潜袭者使用核心网关初学者牌组而准备。建议你在初次游戏中使用这些牌组。游戏按6点议案分数进行。 + [beginner-ul] 核心网关 - 初学者教学牌组 + [constructed] 构筑 + [intermediate] 进阶 + [intermediate-info] 此大厅为公司和潜袭者使用核心网关进阶牌组而准备。这些牌组比初学者牌组稍大。游戏按7点议案分数进行。 + [intermediate-ul] 核心网关 - 进阶教学牌组 + *[unknown] undefined +} + +lobby_hidden = 允许旁观者查看玩家的隐藏信息 + +lobby_hidden-details = 这将向游戏的所有观众揭示两名玩家的隐藏信息,包括手牌和面朝下的牌。 + +lobby_hidden-password = 我们建议使用密码来防止陌生人破坏游戏。 + +lobby_invalid-password = 密码不正确 + +lobby_join = 加入 + +lobby_leave = 离开 + +lobby_load-replay = 加载录像 + +lobby_new-game = 新建对战 + +lobby_no-games = 当前无对战 + +lobby_not-allowed = 操作被禁止 + +lobby_options = 选项 + +lobby_password = 密码 + +lobby_password-error = 请设置密码。 + +lobby_password-for = 请输入房间密码: + +lobby_password-protected = 密码保护 + +lobby_players = 玩家 + +lobby_private = 私密 + +lobby_rejoin = 重新加入 + +lobby_reload = 刷新列表 + +lobby_replay-invalid-file = 请选择有效的录像文件。 + +lobby_replay-link-error = 录像链接无效。 + +lobby_reset = 重置房间名 + +lobby_runner-perspective = 潜袭者视角 + +lobby_save-replay = 保存录像 + +lobby_save-replay-beta = 测试功能:请注意,我们可能会重置已保存的录像,因此请确保下载你想要保留的游戏。此外,请记住,我们可能会在未来对网站进行更改,这可能会使回放不兼容。 + +lobby_save-replay-details = 这将保存此游戏的回放文件,其中包含公开信息(例如公开手牌)。该文件仅在游戏结束后可用。 + +lobby_save-replay-unshared = 只会保留你最近的15个未分享游戏,因此请务必在之后下载或分享游戏。 + +lobby_select-deck = 选择牌组 + +lobby_select-error = 不能选择那个牌组 + +lobby_select-title = 请选择牌组 + +lobby_side = 阵营 + +lobby_singleton = 单张卡牌 + +lobby_singleton-b = (单张卡牌) + +lobby_singleton-details = 这将限制牌组中每种同名卡牌仅限1张。建议你使用下列基于此模式的特性ID组建的牌组。 + +lobby_singleton-example = 1) 复始:触媒&促力 2) 安培:全民的义体 + +lobby_singleton-restriction = 这局要求为单张卡牌模式。这意味着牌组中每种同名卡牌限1张。 + +lobby_spectator-count = {$cnt} 位观众 + +lobby_spectators = 允许旁观 + +lobby_start = 开始 + +lobby_start-replay = 开始回放 + +lobby_swap = 交换阵营 + +lobby_timed-game = 带有计时器 + +lobby_timed-game-details = 计时器仅为方便使用:当计时器结束时,游戏不会停止。 + +lobby_timer-length = 计时器长度(分钟) + +lobby_title = 房间名 + +lobby_title-error = 请设置房间名。 + +lobby_too-little-data = 数据不足 + +lobby_type = {$type -> + [casual] 休闲 + [competitive] 竞技 + [angel-arena] 天使竞技场 + [tournament] 比赛 + *[unknown] undefined +} + +lobby_waiting = 等待玩家选择牌组 + +lobby_watch = 观战 + +log_annotating = 注释 + +log_game-log = 游戏日志 + +log_remote-annotations-fail = 无法获取远程注释。 + +log_run-timing = 潜袭时序 + +log_settings = 设置 + +log_shared = 共享注释 + +log_turn-timing = 回合时序 + +menu_admin = 网站管理员 + +menu_donor = 捐赠人 + +menu_logout = 退出 + +menu_moderator = 管理员 + +menu_settings = {nav_settings} + +nav_about = 关于 + +nav_admin = 网站管理 + +nav_cards = 卡牌 + +nav_chat = 聊天 + +nav_deck-builder = 牌组构筑 + +nav_features = 站点功能 + +nav_game-count = {$cnt} 局对战 + +nav_help = 帮助 + +nav_play = 对战 + +nav_settings = 设置 + +nav_stats = 统计 + +nav_tournaments = 比赛 + +nav_users = 用户 + +nav_welcome = 欢迎 + +preconstructed_worlds-2012-a = Worlds 2012: Ben Marsh (C) vs. Jeremy Zwirn (R) + +preconstructed_worlds-2012-a-tag = Ben Marsh (C) vs. Jeremy Zwirn (R) + +preconstructed_worlds-2012-a-ul = Worlds 2012: Weyland vs. Criminal + +preconstructed_worlds-2012-b = Worlds 2012: Jeremy Zwirn (C) vs. Ben Marsh (R) + +preconstructed_worlds-2012-b-tag = Jeremy Zwirn (C) vs. Ben Marsh (R) + +preconstructed_worlds-2012-b-ul = Worlds 2012: Haas-Bioroid vs. Criminal + +preconstructed_worlds-2012-info = Worlds 2012 was played with (up to 3 copies of) the Core Set as the only legal product. Jeremy Zwirn (Building a Better World, Gabriel Santiago) took first place against Ben Marsh (Engineering the Future, Gabriel Santiago) in the first ever Netrunner World Championship. + +preconstructed_worlds-2013-a = Worlds 2013: Jens Erickson (C) vs. Andrew Veen (R) + +preconstructed_worlds-2013-a-tag = Jens Erickson (C) vs. Andrew Veen (R) + +preconstructed_worlds-2013-a-ul = Worlds 2013: HB FastAdv vs. Shaper Katman + +preconstructed_worlds-2013-b = Worlds 2013: Andrew Veen (C) vs. Jens Erickson (R) + +preconstructed_worlds-2013-b-tag = Andrew Veen (C) vs. Jens Erickson (R) + +preconstructed_worlds-2013-b-ul = Worlds 2013: NBN Fast Adv vs. Andy Sucker + +preconstructed_worlds-2013-info = 166 players attended worlds in 2013. The tournament was held in Minneapolis, MN, USA, and consisted of 6 swiss rounds into a top 32 cut. The legal cardpool consisted of cards up to Opening Moves. + +preconstructed_worlds-2014-a = Worlds 2014: Dan D'Argenio (C) vs. Minh Tran (R) + +preconstructed_worlds-2014-a-tag = Dan D'Argenio (C) vs. Minh Tran (R) + +preconstructed_worlds-2014-a-ul = Worlds 2014: Honor and Perfection vs. Andromedium + +preconstructed_worlds-2014-b = Worlds 2014: Minh Tran (C) vs. Dan D'Argenio (R) + +preconstructed_worlds-2014-b-tag = Minh Tran (C) vs. Dan D'Argenio (R) + +preconstructed_worlds-2014-b-ul = Worlds 2014: Personal Evolution vs. Daily QT Andy + +preconstructed_worlds-2014-info = 238 players attended worlds in 2014. The tournament was held in Minneapolis, MN, USA, and consisted of 7 swiss rounds into a top 16 cut. The legal cardpool consisted of cards up to Up and Over. + +preconstructed_worlds-2015-a = Worlds 2015: Dan D'Argenio (C) vs. Timmy Wong (R) + +preconstructed_worlds-2015-a-tag = Dan D'Argenio (C) vs. Timmy Wong (R) + +preconstructed_worlds-2015-a-ul = Worlds 2015: Foodcoatshop vs. The Morning After + +preconstructed_worlds-2015-b = Worlds 2015: Timmy Wong (C) vs. Dan D'Argenio (R) + +preconstructed_worlds-2015-b-tag = Dan D'Argenio (C) vs. Timmy Wong (R) + +preconstructed_worlds-2015-b-ul = Worlds 2015: Yellow Shell vs. Radisson Cheese Plate + +preconstructed_worlds-2015-info = 269 players attended worlds in 2015. The tournament was held in Minneapolis, MN, USA, and consisted of 8 swiss rounds into a top 16 cut. The legal cardpool consisted of cards up to Data and Destiny. + +preconstructed_worlds-2016-a = Worlds 2016: Chris Dyer (C) vs. Benjamin Ni (R) + +preconstructed_worlds-2016-a-tag = Chris Dyer (C) vs. Benjamin Ni (R) + +preconstructed_worlds-2016-a-ul = Worlds 2016: Snekbite vs. Minh MaxX++ + +preconstructed_worlds-2016-b = Worlds 2016: Benjamin Ni (R) vs. Chris Dyer (C) + +preconstructed_worlds-2016-b-tag = Benjamin Ni (R) vs. Chris Dyer (C) + +preconstructed_worlds-2016-b-ul = Worlds 2016: Fiery Info vs. Papa Smurf + +preconstructed_worlds-2016-info = 278 players attended worlds in 2016. The tournament was held in Minneapolis, MN, USA, and consisted of 9 swiss rounds into a top 16 cut. The legal cardpool consisted of cards up to Escalation. + +preconstructed_worlds-2017-a = Worlds 2017: Jess Horig (C) vs. Grey Tongue (R) + +preconstructed_worlds-2017-a-tag = Jess Horig (C) vs. Grey Tongue (R) + +preconstructed_worlds-2017-a-ul = Worlds 2017: Stinson Reversed CI vs. Aesops Hayley + +preconstructed_worlds-2017-b = Worlds 2017: Grey Tongue (C) vs. Jess Horig (R) + +preconstructed_worlds-2017-b-tag = Grey Tongue (C) vs. Jess Horig (R) + +preconstructed_worlds-2017-b-ul = Worlds 2017: No-Show Rewiring CI vs. Laguna Lock Hayley + +preconstructed_worlds-2017-info = 233 players attended worlds in 2017. The tournament was held in Minneapolis, MN, USA, and consisted of 8(?) swiss rounds into a top 16 cut. The legal cardpool consisted of cards up to the Revised Core set. + +preconstructed_worlds-2018-a = Worlds 2018: Joe Schupp (C) vs. Chris Dyer (R) + +preconstructed_worlds-2018-a-tag = Joe Schupp (C) vs. Chris Dyer (R) + +preconstructed_worlds-2018-a-ul = Worlds 2018: AMERICA CtM vs. Gooseberry MaxX + +preconstructed_worlds-2018-b = Worlds 2018: Chris Dyer (C) vs. Joe Schupp (R) + +preconstructed_worlds-2018-b-tag = Chris Dyer (C) vs. Joe Schupp (R) + +preconstructed_worlds-2018-b-ul = Worlds 2018: Trust the Process vs. Dan D'Argenio KoS Val + +preconstructed_worlds-2018-info = 403(!) players attended worlds in 2018. This is the final worlds championship to be run by FFG. The tournament was held in Minneapolis, MN, USA, and consisted of 9(?) swiss rounds into a top 16 cut. The legal cardpool consisted of cards up to Reign and Reverie + +preconstructed_worlds-2019-a = Worlds 2019: Pinsel (C) vs. Testrunning (R) + +preconstructed_worlds-2019-a-tag = Pinsel (C) vs. Testrunning (R) + +preconstructed_worlds-2019-a-ul = Worlds 2019: Fully dedicated to efficiency vs. Trash Panda + +preconstructed_worlds-2019-b = Worlds 2019: Testrunning (C) vs. Pinsel (R) + +preconstructed_worlds-2019-b-tag = Testrunning (C) vs. Pinsel (R) + +preconstructed_worlds-2019-b-ul = Worlds 2019: 2 Grid for 2 Place vs. Trash Panda + +preconstructed_worlds-2019-info = 256 players played in the first even Project NISEI Netrunner World Championship in 2019. This tournament was held in Rotterdam, NL, and consisted of 8(?) swiss rounds into a top 16 cut. The legal cardpool consisted of cards up to the Uprising Booster Pack + +preconstructed_worlds-2020-a = Worlds 2020: Limes (C) vs. tf34 (R) + +preconstructed_worlds-2020-a-tag = Limes (C) vs. tf34 (R) + +preconstructed_worlds-2020-a-ul = Worlds 2020: I don't like this deck vs. Engolo Freedom + +preconstructed_worlds-2020-b = Worlds 2020: tf34 (R) vs. Limes (C) + +preconstructed_worlds-2020-b-tag = tf34 (R) vs. Limes (C) + +preconstructed_worlds-2020-b-ul = Worlds 2020: Malia CTM vs. Imp-pressive Hoshiko + +preconstructed_worlds-2020-info = 294 players played in the first ever online world championship for Netrunner, run by Project NISEI 2020. Due to travel restrictions at the start of the COVID-19 pandemic, this tournament was held online via Jinteki.net, and consisted of 8 swiss rounds on two distinct day-ones, into a top 16 cut. The legal cardpool consisted of cards up to Uprising. + +preconstructed_worlds-2021-a = Worlds 2021: Patrick Gower (C) vs. Jonas (R) + +preconstructed_worlds-2021-a-tag = Patrick Gower (C) vs. Jonas (R) + +preconstructed_worlds-2021-a-ul = Worlds 2021: 44 Card PD vs. Watch Me Drip, Watch Me Maemi + +preconstructed_worlds-2021-b = Worlds 2021: Jonas (C) vs. Patrick Gower (R) + +preconstructed_worlds-2021-b-tag = Jonas (C) vs. Patrick Gower (R) + +preconstructed_worlds-2021-b-ul = Worlds 2021: Is Gagarin Good? vs. Medium to Large Maxx + +preconstructed_worlds-2021-info = 201 players played in the second online world championship for Netrunner, run by Project NISEI in 2021. Due to the ongoing disruption caused by the COVID-19 pandemic, this tournament was held online via Jinteki.net, and consisted of 8 swiss rounds on two distinct day-ones, into a top 16 cut. The legal cardpool consisted of cards up to System Gateway. + +preconstructed_worlds-2022-a = Worlds 2022: William Huang (C) vs. skry (R) + +preconstructed_worlds-2022-a-tag = William Huang (C) vs. skry (R) + +preconstructed_worlds-2022-a-ul = Worlds 2022: SNACS vs. Liberté, Égalité, Humidité + +preconstructed_worlds-2022-b = Worlds 2022: skry (C) vs. William Huang (R) + +preconstructed_worlds-2022-b-tag = skry (C) vs. William Huang (R) + +preconstructed_worlds-2022-b-ul = Worlds 2022: Dies to Doom Blade vs. ApocoLat + +preconstructed_worlds-2022-info = 158 players played in the first world championship run by Null Signal Games (formerly Project NISEI), which was the first Netrunner world championship to be run in-person since the start of the COVID-19 pandemic. The tournament was held in Toronto, Canada, and consisted of 8(?) rounds into a top 16 cut. The legal cardpool consisted of cards up to Midnight Sun. + +preconstructed_worlds-2023-a = Worlds 2023: William Huang (C) vs. cableCarnage (R) + +preconstructed_worlds-2023-a-tag = William Huang (C) vs. cableCarnage (R) + +preconstructed_worlds-2023-a-ul = Worlds 2023: The Worlds Grid vs. sableCarnage + +preconstructed_worlds-2023-b = Worlds 2023: cableCarnage (C) vs. William Huang (R) + +preconstructed_worlds-2023-b-tag = cableCarnage (C) vs. William Huang (R) + +preconstructed_worlds-2023-b-ul = Worlds 2023: tableCarnage vs. You *do* always come back! + +preconstructed_worlds-2023-info = 254 players played in the second Netrunner world championship run by Null Signal Games. The tournament was held in Barcelona, Spain, and consisted of 8 rounds into a top 16 cut. The legal cardpool consisted of cards up to The Automata Initiative. + +pronouns = {$pronoun -> + [any] 随意 + [blank] [空白] + [ey] Ey/em + [faefaer] undefined + [he] 他(He/him) + [heit] undefined + [heshe] undefined + [hethey] 他(He/they) + [it] 它(It) + [myodb] 不愿透露 + [ne] Ne/nem + *[none] 未设定 + [she] 她(She/her) + [sheit] undefined + [shethey] 她(She/they) + [they] They/them + [ve] Ve/ver + [xe] Xe/xem + [xi] undefined + [zehir] Ze/hir + [zezir] Ze/zir +} + +set_name = {$name -> + [a23-seconds] 二十三秒 + [a-study-in-static] 静态研究 + [all] 全部 + [all-that-remains] 遗迹之地 + [alt-art] 异画系列 + [alternate] 替代 + [ashes-cycle] 余烬循环 + [blood-and-water] 水债血偿 + [blood-money] 不义之财 + [borealis-cycle] 北极光循环 + [breaker-bay] 碎浪湾 + [business-first] 商务为先 + [championship-2019] 冠军2019 + [championship-2020] 冠军2020 + [chrome-city] 铬金城 + [core-set] 核心系列 + [council-of-the-crest] 巅峰议会 + [creation-and-control] 创造与掌控 + [crimson-dust] 绯红之尘 + [cyber-exodus] 赛博迁徙 + [daedalus-complex] 代达罗斯 + [data-and-destiny] 数据与命运 + [democracy-and-dogma] 民主与教条 + [double-time] 双重时刻 + [down-the-white-nile] 白尼罗河畔 + [downfall] 坍落 + [draft] 轮抽系列 + [draft-cycle] 轮抽循环 + [earth-s-scion] 地球子孙 + [escalation] 事态升级 + [fear-and-loathing] 恐惧与憎恶 + [fear-the-masses] 群众可畏 + [first-contact] 初遇之际 + [flashpoint-cycle] 闪点循环 + [free-mars] 自由火星 + [future-proof] 未来考验 + [genesis-cycle] 创纪元循环 + [gnk-2019] GNK 2019 + [honor-and-profit] 荣誉与利益 + [humanity-s-shadow] 人性阴影 + [intervention] 介入冲突 + [kala-ghoda] 卡拉哥达 + [kampala-ascendent] 坎帕拉盛势 + [kitara-cycle] 基塔拉循环 + [kysra-alt-arts] Kysra 异画 + [liberation-cycle] 解放循环 + [lunar-cycle] 月行循环 + [magnum-opus] 巨作 + [magnum-opus-reprint] 巨作重印版 + [mala-tempora] 脑叶癫痫 + [martial-law] 军事管制 + [midnight-sun] 极昼 + [midnight-sun-booster-pack] 极昼推广包 + [mumbad-cycle] 孟巴德循环 + [napd-multiplayer] NAPD 多人 + [ntscape-navigator-alt-arts] Ntscape Navigator 异画 + [old-hollywood] 老莱坞 + [opening-moves] 起手开局 + [order-and-chaos] 秩序与混沌 + [parhelion] 幻日 + [plural-and-miniplural-alt-arts] Plural and MiniPlural 异画 + [previous-versions] 先前版本 + [quorum] 共商出路 + [rebellion-without-rehearsal] 即兴叛乱 + [red-sand-cycle] 红砂循环 + [reign-and-reverie] 统治与幻想 + [revised-core-set] 修订版核心系列 + [salsette-island] 撒尔塞特 + [salvaged-memories] 唤醒回忆 + [sansan-cycle] 圣加州循环 + [second-thoughts] 深思熟虑 + [signed-championship-2020] 签名版冠军2020 + [sovereign-sight] 主权之光 + [spin-cycle] 扭曲真相循环 + [station-one] 一号车站 + [system-core-2019] 系统核心2019 + [system-gateway] 核心网关 + [system-update-2021] 系统革新2021 + [terminal-directive-campaign] 终极指令战役 + [terminal-directive-cards] 终极指令卡牌 + [terminal-directive-cycle] 终极指令循环 + [the-automata-initiative] 自动机倡议 + [the-devil-and-the-dragon] 恶魔与龙 + [the-liberated-mind] 自由心智 + [the-source] 代码之源 + [the-spaces-between] 往来之隙 + [the-underway] 暗底区 + [the-universe-of-tomorrow] 未来域 + [the-valley] 生科谷 + [trace-amount] 重重追踪 + [true-colors] 真实面目 + [unreleased] 未发布 + [up-and-over] 攀越之路 + [uprising] 起义 + [uprising-booster-pack] 起义推广包 + [upstalk] 上行之夜 + [what-lies-ahead] 前途未卜 + [whispers-in-nalubaale] 纳鲁巴勒低语 + [world-champion-2015] 世界冠军2015 + [world-champion-2016] 世界冠军2016 + [world-champion-2017] 世界冠军2017 + *[unknown] undefined +} + +settings_alt-art = 异画卡 + +settings_always = 总是 + +settings_api-keys = API密钥 + +settings_avatar = 头像 + +settings_background = 游戏背景 + +settings_bespoke-sounds = {$sound -> + [bespoke-sounds-header] 卡牌特定声音 + [archer] 射手 + [end-of-the-line] 穷途末路 + [harmonics] 和声组合(海洋怪声,回声,脉动,波动) + *[unknown] undefined +} + +settings_bg = {$slug -> + [apex-bg] 尖峰 + [custom-bg] 自定义背景 + [find-the-truth-bg] 找出真相 + [freelancer-bg] 自由职业者 + [monochrome-bg] 纯黑 + [mushin-no-shin-bg] 无心之心 + [push-your-luck-bg] 豪赌一把 + [rumor-mill-bg] 谣言工厂 + [the-root-bg] 根基 + [traffic-jam-bg] 交通阻塞 + [worlds2020-bg] 世界2020 + *[unknown] undefined +} + +settings_block = 屏蔽 + +settings_blocked = 黑名单 + +settings_cancel = 取消 + +settings_card-backs = 卡背 + +settings_card-iamge = 卡牌图像 + +settings_card-images = 卡牌图像 + +settings_card-preview-zoom = 卡牌预览缩放 + +settings_card-text = 卡牌文本 + +settings_change-avatar = 在gravatar.com上更换 + +settings_change-email = 更换电子邮箱 + +settings_comp-only = 仅竞技厅 + +settings_create-api-key = 创建API密钥 + +settings_current-email = 旧邮箱 + +settings_deck-stats = 牌组统计 + +settings_delete-api-key = 删除 + +settings_desired-email = 新邮箱 + +settings_email = 电子邮箱 + +settings_email-placeholder = 电子邮件地址 + +settings_email-title = 更换电子邮件地址 + +settings_enable-game-sounds = 开启游戏内音效 + +settings_enable-lobby-sounds = 开启大厅内音效 + +settings_enter-valid = 请输入合法的电子邮件地址 + +settings_ffg = FFG + +settings_game-stats = 对战胜负统计 + +settings_get-log-top = 获取当前日志框顶部坐标 + +settings_get-log-width = 获取当前日志框宽度 + +settings_ghost-trojans = 对于被负载的程序显示鬼影 + +settings_high-res = 启用高分辨率卡牌图像 + +settings_invalid-email = 没有使用该邮箱地址的账号 + +settings_invalid-password = 用户名或密码无效 + +settings_language = 语言 + +settings_layout-options = 布局选项 + +settings_log-player-highlight = 日志玩家高亮 + +settings_log-player-highlight-none = 无 + +settings_log-player-highlight-red-blue = 公司:蓝色 / 潜袭者:红色 + +settings_log-size = 日志栏尺寸 + +settings_none = 关闭 + +settings_nsg = NSG + +settings_pin-zoom = 在屏幕上保持缩放卡牌 + +settings_player-stats-icons = 使用图标显示玩家统计 + +settings_pronouns = 代词 + +settings_reset = 将所有卡牌重设为原始卡面 + +settings_runner-classic = 经典jnet布局(自上而下:程序、硬件、资源) + +settings_runner-layout = 潜袭者布局(公司视角) + +settings_runner-reverse = 反转布局(自上而下:资源、硬件、程序) + +settings_set = 设置 + +settings_set-all = 将所有卡牌设为 + +settings_show-alt = 显示异画卡 + +settings_sides-overlap = 潜袭者和公司面板可以重叠 + +settings_sounds = 音效 + +settings_stacked-cards = 默认启用服务器堆叠 + +settings_update = 更换 + +settings_update-profile = 保存设置 + +settings_updated = 设置已保存——请刷新页面 + +settings_updating = 设置保存中…… + +settings_user-name = 用户名 + +settings_volume = 音量 + +side_name = {$side -> + [all] 全部 + [any-side] 任意阵营 + [corp] 公司 + [runner] 潜袭者 + *[unknown] undefined +} + +stats_all-games = 显示所有记录 + +stats_cards-accessed = 读取卡牌数量 + +stats_cards-click = 手动抽牌数量 + +stats_cards-drawn = 抽牌数量 + +stats_cards-rezzed = 激活卡牌数量 + +stats_cards-sabotaged = 破坏次数 + +stats_clear-stats = 清除统计数据 + +stats_clicks-gained = 获得时点数量 + +stats_completed = 完成: {$completed} ({NUMBER($percent, style: "percent")}) + +stats_corp-stats = 公司统计 + +stats_credits-click = 手动获取信用点数量 + +stats_credits-gained = 获得信用点数量 + +stats_credits-spent = 支付信用点数量 + +stats_damage-done = 造成伤害量 + +stats_download = 下载录像 + +stats_ended = 结束时间 + +stats_events-played = 事件打出数量 + +stats_format = 赛制 + +stats_game-stats = 胜负统计 + +stats_game-title = {$title} ({$cnt} 个回合) + +stats_launch = 播放录像 + +stats_lobby = 大厅 + +stats_log-count = {$cnt} 条记录 + +stats_log-count-filtered = {$cnt} 条记录(过滤后) + +stats_lost = 败北: {$lost} ({NUMBER($percent, style: "percent")}) + +stats_no-games = 没有对战记录 + +stats_no-log = 无日志信息 + +stats_not-completed = 未完成: {$completed} ({NUMBER($percent, style: "percent")}) + +stats_operations-played = 事务打出数量 + +stats_psi-game-total = 灵能赌博:赌博次数 + +stats_psi-game-total-bid-0 = 灵能赌博:出价0次数 + +stats_psi-game-total-bid-1 = 灵能赌博:出价1次数 + +stats_psi-game-total-bid-2 = 灵能赌博:出价2次数 + +stats_psi-game-total-wins = 灵能赌博:胜利次数 + +stats_rashida-count = 拉什达次数 + +stats_runner-stats = 潜袭者统计 + +stats_runs-made = 潜袭次数 + +stats_share = 分享录像 + +stats_shared-games = 只显示已分享的录像 + +stats_shuffle-count = 洗牌次数 + +stats_started = 开始: {$started} + +stats_tags-gained = 获得锁定标记数量 + +stats_unavailable = 未保存录像 + +stats_unique-accesses = 读取独有卡牌数量 + +stats_view-games = 返回统计界面 + +stats_view-log = 查看记录 + +stats_win-method = 胜利方式 + +stats_winner = 胜者 + +stats_won = 胜利: {$won} ({NUMBER($percent, style: "percent")}) diff --git a/src/clj/game/core/def_helpers.clj b/src/clj/game/core/def_helpers.clj index f93c5a402d..bfda833cf6 100644 --- a/src/clj/game/core/def_helpers.clj +++ b/src/clj/game/core/def_helpers.clj @@ -243,7 +243,7 @@ (defn make-current-event-handler [title ability] - (let [card (server-card title)] + (let [card (server-card title false)] (if (has-subtype? card "Current") (let [event-keyword (if (corp? card) :agenda-stolen :agenda-scored) static-ab {:type :trash-when-expired diff --git a/src/clj/game/core/payment.clj b/src/clj/game/core/payment.clj index 02366c1cfb..d17c22c6fb 100644 --- a/src/clj/game/core/payment.clj +++ b/src/clj/game/core/payment.clj @@ -171,10 +171,7 @@ (#{:click :lose-click} cost-type) (str "spend " cost-string) (= :credit cost-type) (str "pay " cost-string) :else cost-string))) - (try (cost->string (first cost)) - (catch Throwable t - (prn cost) - (throw t))))) + (cost->string (first cost)))) (defn build-cost-string "Gets the complete cost-str for specified costs" diff --git a/src/clj/game/quotes.clj b/src/clj/game/quotes.clj index 64ddd74b28..414d6292f6 100644 --- a/src/clj/game/quotes.clj +++ b/src/clj/game/quotes.clj @@ -3,7 +3,6 @@ [clojure.edn :as edn] [clojure.java.io :as io])) - (def quotes-corp-filename "data/quotes-corp.edn") (def quotes-runner-filename "data/quotes-runner.edn") (def generic-key "Default") diff --git a/src/clj/tasks/translations.clj b/src/clj/tasks/translations.clj index 56a24cf6b3..4aa441f5f6 100644 --- a/src/clj/tasks/translations.clj +++ b/src/clj/tasks/translations.clj @@ -4,124 +4,198 @@ [clojure.java.io :as io] [clojure.pprint :as pp] [clojure.set :as set] - [clojure.string :as str] - [game.utils :refer [dissoc-in]] - [i18n.core :as tr.core] - [taoensso.encore :as encore]) + [clojure.string :as str]) (:import - [java.io File])) + (fluent.bundle FluentBundle FluentBundle$Builder FluentResource) + (fluent.functions.cldr CLDRFunctionFactory) + (fluent.syntax.AST + Attribute + CallArguments + Commentary$Comment + Commentary$GroupComment + Commentary$ResourceComment + Identifiable + Identifier + InlineExpression$FunctionReference + InlineExpression$MessageReference + InlineExpression$TermReference + InlineExpression$VariableReference + Literal$StringLiteral + Message + NamedArgument + Pattern + PatternElement$Placeable + PatternElement$TextElement + SelectExpression + Term + Variant) + (fluent.syntax.parser FTLParser FTLStream) + (java.io File) + (java.util Locale Optional))) -(defn get-nodes [lang] - (->> lang - (get (tr.core/translation-dictionary)) - (encore/node-paths) - (remove #(= :angel-arena (first %))) - (into #{} (map (comp vec butlast))))) +(set! *warn-on-reflection* true) -(defn to-keyword [s] - (cond - (keyword? s) s - (str/starts-with? s ":") (keyword (subs s 1)) - :else (keyword s))) +(def fluent-dictionary + (atom {})) + +(defn get-id + [entry] + (when (instance? Identifiable entry) + (.name ^Identifiable entry))) + +(defn build + [locale-str ^String resource] + (try + (let [locale-str (if (= "la-pig" locale-str) "en" locale-str) + locale (Locale/forLanguageTag locale-str) + builder (FluentBundle/builder locale CLDRFunctionFactory/INSTANCE) + ftl-res (FTLParser/parse (FTLStream/of resource)) + entries (into {} (keep (fn [e] (when-let [id (get-id e)] [id e]))) + (FluentResource/.entries ftl-res))] + (when (FluentResource/.hasErrors ftl-res) + (let [errors (.errors ftl-res) + err (first errors)] + (throw (ex-info (str "Error in " locale-str " adding resource: " (ex-message err)) + {:locale locale-str + :errors (mapv ex-message errors)} + err)))) + (FluentBundle$Builder/.addResource builder ftl-res) + (FluentBundle$Builder/.build builder) + entries) + (catch Throwable err + (println (str "Error in " locale-str " adding resource: " (ex-message err))) + (throw err)))) + +(let [langs (->> (io/file "resources/public/i18n") + (file-seq) + (filter #(.isFile ^java.io.File %)) + (filter #(str/ends-with? (str %) ".ftl")) + (map (fn [^java.io.File f] + (let [n (str/replace (.getName f) ".ftl" "") + content (slurp f)] + [n content]))))] + (reset! fluent-dictionary {}) + (doseq [[lang content] langs] + (swap! fluent-dictionary assoc lang (build lang content))) + (println "Loaded")) + +(defn get-messages [lang] + (->> (get @fluent-dictionary lang) + (remove #(str/starts-with? "angel-arena" (first %))) + (into {}))) + +(defn to-string [s] + (if (string? s) s (name s))) (defn missing-translations "Treat :en as the single source of truth. Compare each other language against it. Print when the other language is missing entries, and also print when the other - language has defined entries not in :en. - - Ignores :angel-arena entries because that's being phased out." + language has defined entries not in :en." [& args] - (let [en-nodes (get-nodes :en) - other-langs (keys (dissoc (tr.core/translation-dictionary) :en))] - (doseq [lang (or (seq (map to-keyword args)) other-langs) - :let [lang-nodes (get-nodes lang)]] + (let [en-keys (keys (get-messages "en"))] + (doseq [lang (or (seq (map to-string args)) + (keys (dissoc @fluent-dictionary "en"))) + :let [lang-keys (keys (get-messages lang))]] (println "Checking" lang) - (when-let [diff (seq (set/difference en-nodes lang-nodes))] + (when-let [diff (seq (set/difference + (->> en-keys + (remove #(str/starts-with? % "preconstructed_")) + (set)) + (set lang-keys)))] (println "Missing from" lang) (pp/pprint (sort diff)) (newline)) - (when-let [diff (seq (set/difference lang-nodes en-nodes))] + (when-let [diff (seq (set/difference + (set lang-keys) + (set en-keys)))] (println "Missing from :en") (pp/pprint (sort diff)) (newline))) (println "Finished!"))) (comment - (missing-translations :fr)) + (missing-translations)) + +(defn get-value + [message] + (when-let [elements (some-> message + (Message/.pattern) + (Optional/.orElse nil) + (Pattern/.elements) + (seq) + vec)] + (when (every? #(instance? PatternElement$TextElement %) elements) + (->> elements + (map PatternElement$TextElement/.value) + (str/join " "))))) (defn undefined-translations [& _args] - (let [en-nodes (->> (get (tr.core/translation-dictionary) :en) - (encore/node-paths) - (map #(vector (vec (butlast %)) (last %))) - (into {})) - files (->> (io/file "src") - (file-seq) + (let [en-map (get-messages "en") + files (->> (concat (file-seq (io/file "src/cljs")) + (file-seq (io/file "src/cljc"))) (filter #(.isFile ^File %)) (filter #(str/includes? (str %) ".clj")) - (map (juxt str slurp)))] - (doseq [[file-name contents] files - :let [used - (->> contents - (re-seq #"\(tr \[:(.*?)( \"(.*?)\")?\]") - (mapv (fn [[_ k _ default]] - [(mapv keyword (str/split k #"[/\.]")) - (when default - (str/trim default))])) - (sort))] - [k default] used - :let [en-node (get en-nodes k)] - :when (not (or (fn? en-node) - (keyword? en-node))) - :when (if (and k default) - (not= (when en-node (str/lower-case en-node)) - (str/lower-case default)) - (not en-node))] + (remove #(str/includes? (str %) "angel_arena")) + (map (juxt str slurp))) + finds + (for [[file-name contents] files + :let [used + (->> contents + (re-seq #"tr \[:([a-zA-Z0-9_-]*?)( \"(.*?)\")?\]") + (mapv (fn [[_ k _ default]] + [(keyword k) + (when default + (str/trim default))])) + (sort))] + [k default] used + :let [entry (get en-map (name k)) + message (get-value entry)] + :when (not entry) + :when (if (and k default) + (not= (when message (str/lower-case message)) + (str/lower-case default)) + true)] + {:file-name file-name + :entry k + :msg [message default]}) + grouped-finds (group-by :file-name finds)] + (doseq [file-name (keys grouped-finds) + {:keys [entry msg]} (get grouped-finds file-name)] (println file-name) - (pp/pprint [k (when (or en-node default) - [en-node default])])) + (pp/pprint [entry msg])) (println "Finished!"))) (comment (undefined-translations)) (def keys-to-dissoc - #{:missing ; default text - :card-type ; handled by tr-type - :side ; handled by tr-side - :faction ; handled by tr-faction - :format ; handled by tr-format - :lobby ; handled by tr-lobby and tr-watch-join - :pronouns ; handled by tr-pronouns - :set ; handled by tr-set - :game-prompt ; handled by tr-game-prompt - }) - -(def nested-keys-to-dissoc - #{[:card-browser :sort-by] ; handled by tr-sort - [:card-browser :influence] ; currently unused - [:deck-builder :hash] ; currently unused + #{"card-type_" ; handled by tr-type + "side_" ; handled by tr-side + "faction_" ; handled by tr-faction + "format_" ; handled by tr-format + "lobby_" ; handled by tr-lobby and tr-watch-join + "pronouns" ; handled by tr-pronouns + "set_" ; handled by tr-set + "game_prompt" ; handled by tr-game-prompt + "preconstructed_" }) -(defn dissoc-programmatic-keys [dict] - (reduce dissoc-in - (apply dissoc dict keys-to-dissoc) - nested-keys-to-dissoc)) - (defn unused-translations [& _args] - (let [regexen (->> (get (tr.core/translation-dictionary) :en) - (dissoc-programmatic-keys) - (encore/node-paths) - (map #(vec (butlast %))) - (map #(let [s (str/join "." (map name %)) - patt (str "\\(tr \\[(:" s ")( \\\"(.*?)\\\")?\\]")] + (let [regexen (->> (get-messages "en") + (keys) + (remove (fn [k] + (some #(str/starts-with? k %) + keys-to-dissoc))) + (map #(let [patt (str "tr \\[:" % "(( \\\"(.*?)\\\")| [a-zA-Z0-9_-]*?)?\\]")] [% (re-pattern patt)])) (into #{})) - files (->> (io/file "src") - (file-seq) + files (->> (concat (file-seq (io/file "src/cljs")) + (file-seq (io/file "src/cljc"))) (filter #(.isFile ^File %)) (filter #(str/includes? (str %) ".clj")) + (remove #(str/includes? (str %) "angel_arena")) (map (juxt str slurp)))] (doseq [[path regex] (sort regexen) :when (->> files @@ -133,3 +207,231 @@ (comment (unused-translations)) + +;; formatting + +(defn- indent [ctx] + (print (str/join (repeat (:indent ctx) " ")))) + +(defprotocol FTLPrinter + (-ftl-print [this ctx])) + +(extend-protocol FTLPrinter + Commentary$Comment + (-ftl-print + [this _ctx] + (print "# ") + (print (Commentary$Comment/.text this))) + + Commentary$GroupComment + (-ftl-print + [this _ctx] + (newline) + (print "## ") + (print (Commentary$GroupComment/.text this))) + + Commentary$ResourceComment + (-ftl-print + [this _ctx] + (newline) + (print "### ") + (print (Commentary$ResourceComment/.text this))) + + Literal$StringLiteral + (-ftl-print + [this _ctx] + (pr (Literal$StringLiteral/.value this))) + + Identifier + (-ftl-print + [this _ctx] + (print (Identifier/.key this))) + + InlineExpression$MessageReference + (-ftl-print + [this ctx] + (-ftl-print (InlineExpression$MessageReference/.identifier this) ctx)) + + InlineExpression$TermReference + (-ftl-print + [this ctx] + (print "{-") + (-ftl-print (InlineExpression$TermReference/.identifier this) ctx) + (when-let [attr (Optional/.orElse (InlineExpression$TermReference/.attributeID this) nil)] + (-ftl-print attr ctx)) + (when-let [args (Optional/.orElse (InlineExpression$TermReference/.arguments this) nil)] + (let [positional (not-empty (CallArguments/.positional args)) + named (not-empty (CallArguments/.named args))] + (print "(") + (let [ctx (assoc ctx :arg true)] + (when positional + (run! (fn [arg] (if (string? arg) + (print arg) + (-ftl-print arg ctx))) + (interpose ", " positional))) + (when (and positional named) + (print ", ")) + (when named + (run! (fn [arg] (if (string? arg) + (print arg) + (-ftl-print arg ctx))) + (interpose ", " named)))) + (print ")"))) + (print "}")) + + InlineExpression$FunctionReference + (-ftl-print + [this ctx] + (-ftl-print (InlineExpression$FunctionReference/.identifier this) ctx) + (when-let [args (Optional/.orElse (InlineExpression$FunctionReference/.arguments this) nil)] + (let [positional (not-empty (CallArguments/.positional args)) + named (not-empty (CallArguments/.named args))] + (print "(") + (let [ctx (assoc ctx :arg true)] + (when positional + (run! (fn [arg] (if (string? arg) + (print arg) + (-ftl-print arg ctx))) + (interpose ", " positional))) + (when (and positional named) + (print ", ")) + (when named + (run! (fn [arg] (if (string? arg) + (print arg) + (-ftl-print arg ctx))) + (interpose ", " named)))) + (print ")")))) + + NamedArgument + (-ftl-print + [this ctx] + (-ftl-print (NamedArgument/.name this) ctx) + (print ": ") + (-ftl-print (NamedArgument/.value this) ctx)) + + InlineExpression$VariableReference + (-ftl-print + [this ctx] + (print "$") + (-ftl-print (InlineExpression$VariableReference/.identifier this) ctx)) + + Variant + (-ftl-print + [this ctx] + (when (Variant/.isDefault this) + (print "*")) + (print "[") + (-ftl-print (Variant/.keyable this) ctx) + (print "]") + (print " ") + (-ftl-print (Variant/.value this) ctx)) + + SelectExpression + (-ftl-print + [this ctx] + (-ftl-print (SelectExpression/.selector this) ctx) + (print " ->") + (newline) + (run! (fn [variant] + (indent ctx) + (-ftl-print variant ctx) + (newline)) + (SelectExpression/.variants this)) + (indent (update ctx :indent #(max 0 (dec %))))) + + PatternElement$TextElement + (-ftl-print + [this ctx] + (let [s (PatternElement$TextElement/.value this)] + (print s) + (when (str/includes? s "\n") + (indent ctx)))) + + PatternElement$Placeable + (-ftl-print + [this ctx] + (print "{") + (-ftl-print (PatternElement$Placeable/.expression this) ctx) + (print "}")) + + Pattern + (-ftl-print + [this ctx] + (let [ctx (update ctx :indent inc)] + (run! (fn [pat] (-ftl-print pat ctx)) (Pattern/.elements this)))) + + Attribute + (-ftl-print + [this ctx] + (let [ctx (update ctx :indent inc)] + (indent ctx) + (print ".") + (-ftl-print (Attribute/.identifier this) ctx) + (print " = ") + (-ftl-print (Attribute/.pattern this) ctx) + (newline))) + + Term + (-ftl-print + [this ctx] + (Optional/.map (Term/.comment this) (fn [cmnt] + (-ftl-print cmnt ctx) + (newline))) + (print "-") + (-ftl-print (Term/.identifier this) ctx) + (print " = ") + (-ftl-print (Term/.value this) ctx) + (when-let [attrs (not-empty (Term/.attributes this))] + (newline) + (run! (fn [attr] (-ftl-print attr ctx)) attrs)) + (newline)) + + Message + (-ftl-print + [this ctx] + (Optional/.map (Message/.comment this) (fn [cmnt] + (-ftl-print cmnt ctx) + (newline))) + (-ftl-print (Message/.identifier this) ctx) + (print " = ") + (-ftl-print (Optional/.orElseThrow (Message/.pattern this)) ctx) + (newline)) + + FluentResource + (-ftl-print + [this ctx] + (let [entries (FluentResource/.entries this)] + (doseq [entry entries] + (-ftl-print entry ctx) + (newline))))) + +(comment + (let [res (FTLParser/parse (FTLStream/of "a = {NUMBER($percent, style:\"percent\")}") false)] + (prn res) + (-ftl-print res {:indent 0}))) + +(defn ftl-print + ([resource] + (ftl-print resource {:indent 0})) + ([resource config] + (-ftl-print resource config))) + +(defn format-i18n-files + [& args] + (let [langs (or (seq (map to-string args)) + (keys @fluent-dictionary))] + (doseq [lang langs + :let [f (io/file "resources" "public" "i18n" (str lang ".ftl")) + contents (-> (slurp f) + (str/replace "\\u" "__u") + (str/replace "\\U" "__U")) + ast (FTLParser/parse (FTLStream/of contents) false) + formatted-file (-> (with-out-str (ftl-print ast)) + (str/replace "__u" "\\u") + (str/replace "__U" "\\U") + (str/trim) + (str "\n"))]] + (spit f formatted-file)))) + +(comment + (format-i18n-files)) diff --git a/src/clj/web/api.clj b/src/clj/web/api.clj index 8d81de00a1..6609c570e6 100644 --- a/src/clj/web/api.clj +++ b/src/clj/web/api.clj @@ -53,78 +53,79 @@ (defn api-routes [] (ring/router - [["/chsk" {:get ws/handshake-handler - :post ws/post-handler + [["/chsk" {:get #'ws/handshake-handler + :post #'ws/post-handler :middleware [::forgery]}] ["/data" {:middleware [::forgery]} ["/cards" - ["" {:get data/cards-handler}] - ["/version" {:get data/cards-version-handler}] - ["/altarts" {:get data/alt-arts-handler}] - ["/lang/:lang" {:get data/lang-handler}]] - ["/news" {:get data/news-handler}] - ["/sets" {:get data/sets-handler}] - ["/mwl" {:get data/mwl-handler}] - ["/cycles" {:get data/cycles-handler}] - ["/donors" {:get data/donors-handler}] + ["" {:get #'data/cards-handler}] + ["/version" {:get #'data/cards-version-handler}] + ["/altarts" {:get #'data/alt-arts-handler}] + ["/lang/:lang" {:get #'data/card-lang-handler}]] + ["/news" {:get #'data/news-handler}] + ["/sets" {:get #'data/sets-handler}] + ["/mwl" {:get #'data/mwl-handler}] + ["/cycles" {:get #'data/cycles-handler}] + ["/donors" {:get #'data/donors-handler}] ["/decks" - ["" {:get decks/decks-handler - :post decks/decks-create-handler - :put decks/decks-save-handler}] - ["/:id" {:delete decks/decks-delete-handler}]] + ["" {:get #'decks/decks-handler + :post #'decks/decks-create-handler + :put #'decks/decks-save-handler}] + ["/:id" {:delete #'decks/decks-delete-handler}]] ["/api-keys" {:middleware [::auth]} - ["" {:get api-keys/api-keys-handler - :post api-keys/api-keys-create-handler}] - ["/:id" {:delete api-keys/api-keys-delete-handler}]]] - ["/chat/config" {:get chat/config-handler :middleware [::forgery]}] - ["/messages/:channel" {:get chat/messages-handler :middleware [::forgery]}] - ["/reset/:token" {:get pages/reset-password-page - :post auth/reset-password-handler}] - ["/replay/:gameid" {:get stats/replay-handler :middleware [::forgery]}] - ["/bug-report/:bugid" {:get stats/replay-handler :middleware [::forgery]}] - ["/register" {:post auth/register-handler :middleware [::forgery]}] - ["/check-username/:username" {:get auth/check-username-handler :middleware [::forgery]}] - ["/check-email/:email" {:get auth/check-email-handler :middleware [::forgery]}] - ["/login" {:post auth/login-handler :middleware [::forgery]}] - ["/forgot" {:post auth/forgot-password-handler :middleware [::forgery]}] + ["" {:get #'api-keys/api-keys-handler + :post #'api-keys/api-keys-create-handler}] + ["/:id" {:delete #'api-keys/api-keys-delete-handler}]] + ["/language/:lang" {:get #'data/lang-handler}]] + ["/chat/config" {:get #'chat/config-handler :middleware [::forgery]}] + ["/messages/:channel" {:get #'chat/messages-handler :middleware [::forgery]}] + ["/reset/:token" {:get #'pages/reset-password-page + :post #'auth/reset-password-handler}] + ["/replay/:gameid" {:get #'stats/replay-handler :middleware [::forgery]}] + ["/bug-report/:bugid" {:get #'stats/replay-handler :middleware [::forgery]}] + ["/register" {:post #'auth/register-handler :middleware [::forgery]}] + ["/check-username/:username" {:get #'auth/check-username-handler :middleware [::forgery]}] + ["/check-email/:email" {:get #'auth/check-email-handler :middleware [::forgery]}] + ["/login" {:post #'auth/login-handler :middleware [::forgery]}] + ["/forgot" {:post #'auth/forgot-password-handler :middleware [::forgery]}] ["/logout" {:middleware [::auth ::forgery] - :post auth/logout-handler}] + :post #'auth/logout-handler}] ["/game" {:middleware [::forgery ::cors wrap-add-cache-headers]} - ["/decklist" {:get game-api/decklist-handler}] - ["/hand" {:get game-api/hand-handler}] - ["/discard" {:get game-api/discard-handler}] - ["/deck" {:get game-api/deck-handler}] - ["/log" {:get game-api/log-handler}]] + ["/decklist" {:get #'game-api/decklist-handler}] + ["/hand" {:get #'game-api/hand-handler}] + ["/discard" {:get #'game-api/discard-handler}] + ["/deck" {:get #'game-api/deck-handler}] + ["/log" {:get #'game-api/log-handler}]] ["/profile" {:middleware [::auth ::forgery]} - ["" {:put auth/update-profile-handler}] - ["/email" {:get auth/email-handler - :put auth/change-email-handler}] + ["" {:put #'auth/update-profile-handler}] + ["/email" {:get #'auth/email-handler + :put #'auth/change-email-handler}] ["/stats" - ["/user" {:delete stats/clear-userstats-handler}] - ["/deck/{id}" {:delete stats/clear-deckstats-handler}]] + ["/user" {:delete #'stats/clear-userstats-handler}] + ["/deck/{id}" {:delete #'stats/clear-deckstats-handler}]] ["/history" - ["" {:get stats/history}] - ["/:gameid" {:get stats/fetch-log}] + ["" {:get #'stats/history}] + ["/:gameid" {:get #'stats/fetch-log}] ["/annotations" - ["/:gameid" {:get stats/fetch-annotations}] - ["/publish/:gameid" {:get stats/publish-annotations}] - ["/delete/:gameid" {:delete stats/delete-annotations}]] - ["/share/:gameid" {:get stats/share-replay}] - ["/full/:gameid" {:get stats/fetch-replay}]]] + ["/:gameid" {:get #'stats/fetch-annotations}] + ["/publish/:gameid" {:get #'stats/publish-annotations}] + ["/delete/:gameid" {:delete #'stats/delete-annotations}]] + ["/share/:gameid" {:get #'stats/share-replay}] + ["/full/:gameid" {:get #'stats/fetch-replay}]]] ["/tournament-auth/:username" {:middleware [::auth ::tournament-auth ::forgery] - :get tournament/auth}] + :get #'tournament/auth}] ["/admin" {:middleware [::auth ::admin ::forgery]} ["/news" - ["" {:post admin/news-create-handler}] - ["/:id" {:delete admin/news-delete-handler}]] - ["/version" {:get admin/version-handler - :put admin/version-update-handler}] - ["/banned" {:get admin/banned-message-handler - :put admin/banned-message-update-handler}] - ["/features" {:get admin/features-handler - :put admin/features-update-handler}]]] + ["" {:post #'admin/news-create-handler}] + ["/:id" {:delete #'admin/news-delete-handler}]] + ["/version" {:get #'admin/version-handler + :put #'admin/version-update-handler}] + ["/banned" {:get #'admin/banned-message-handler + :put #'admin/banned-message-update-handler}] + ["/features" {:get #'admin/features-handler + :put #'admin/features-update-handler}]]] {:reitit.middleware/registry {::auth auth/wrap-authentication-required ::tournament-auth auth/wrap-tournament-auth-required @@ -200,7 +201,7 @@ (defn make-dev-app [system] (ring/ring-handler - (merge-routes) + (merge-routes (base-routes) (api-routes)) (make-default-routes) (update (make-middleware system) :middleware #(vec (cons wrap-stacktrace %))))) diff --git a/src/clj/web/auth.clj b/src/clj/web/auth.clj index e7b40ad71e..0fa43f221c 100644 --- a/src/clj/web/auth.clj +++ b/src/clj/web/auth.clj @@ -1,19 +1,21 @@ (ns web.auth (:require [buddy.sign.jwt :as jwt] - [cljc.java-time.temporal.chrono-unit :as chrono] [cljc.java-time.instant :as inst] + [cljc.java-time.temporal.chrono-unit :as chrono] [clojure.string :as str] [crypto.password.bcrypt :as password] + [jinteki.i18n :as i18n] + [jinteki.utils :refer [select-non-nil-keys]] [monger.collection :as mc] [monger.operators :refer :all] [monger.result :refer [acknowledged?]] [postal.core :as mail] [ring.util.response :refer [redirect]] [web.app-state :as app-state] - [web.mongodb :refer [find-one-as-map-case-insensitive ->object-id]] - [web.user :refer [active-user? valid-username? within-char-limit-username? create-user user-keys]] - [web.utils :refer [response md5]] + [web.mongodb :refer [->object-id find-one-as-map-case-insensitive]] + [web.user :refer [active-user? create-user user-keys valid-username?]] + [web.utils :refer [md5 response]] [web.versions :refer [banned-msg]]) (:import java.security.SecureRandom)) @@ -168,7 +170,7 @@ :else (response 404 {:message "Account not found"}))) -(defn profile-keys [] +(def profile-keys [:background :pronouns :language :default-format :show-alt-art :blocked-users :alt-arts :card-resolution :deckstats :gamestats :card-zoom :pin-zoom :card-back :stacked-cards :ghost-trojans :display-encounter-info @@ -179,15 +181,22 @@ [{db :system/db {username :username :as user} :user body :body}] - (if (active-user? user) - (if (acknowledged? (mc/update db "users" - {:username username} - {"$set" {:options (select-keys body (profile-keys))}})) - (do (when (get-in @app-state/app-state [:users username]) - (swap! app-state/app-state assoc-in [:users username :options] (select-keys body (profile-keys)))) - (response 200 {:message "Refresh your browser"})) - (response 404 {:message "Account not found"})) - (response 401 {:message "Unauthorized"}))) + (let [options (select-non-nil-keys body profile-keys) + lang (:lang body)] + (if (active-user? user) + (if (acknowledged? (mc/update db "users" + {:username username} + {"$set" {:options options}})) + (do (when (get-in @app-state/app-state [:users username]) + (swap! app-state/app-state assoc-in [:users username :options] options)) + (let [resp {:message "Refresh your browser"} + resp (cond-> resp + lang + (assoc :lang lang + :content (i18n/get-content lang)))] + (response 200 resp))) + (response 404 {:message "Account not found"})) + (response 401 {:message "Unauthorized"})))) (defn generate-secure-token [size] diff --git a/src/clj/web/data.clj b/src/clj/web/data.clj index e1e5e3cf4c..fdb1ef646c 100644 --- a/src/clj/web/data.clj +++ b/src/clj/web/data.clj @@ -1,6 +1,7 @@ (ns web.data (:require [web.utils :refer [response mongo-time-to-utc-string]] [monger.collection :as mc] + [jinteki.i18n :as i18n] [monger.query :as mq] [game.core.initializing :refer [card-implemented]] [clojure.edn :as edn])) @@ -30,7 +31,7 @@ [lang] (contains? #{"de" "es" "fr" "it" "ja" "ko" "pl" "zh-simp" "zh-trad"} lang)) -(defn lang-handler [{db :system/db {lang :lang} :path-params}] +(defn card-lang-handler [{db :system/db {lang :lang} :path-params}] (if (validate-lang lang) (let [lang (case lang "zh-simp" "cards-zh-hans" @@ -40,6 +41,10 @@ (response 200 (mapv #(dissoc % :_id) (mc/find-maps db lang)))) (response 200 {}))) +(defn lang-handler [{{lang :lang} :path-params}] + (let [content (i18n/get-content lang)] + (response 200 (pr-str content)))) + (defn alt-arts-handler [{db :system/db}] (response 200 (mapv #(dissoc % :_id) (mc/find-maps db "altarts")))) diff --git a/src/clj/web/lobby.clj b/src/clj/web/lobby.clj index ce379c04a3..40a91b7921 100644 --- a/src/clj/web/lobby.clj +++ b/src/clj/web/lobby.clj @@ -12,7 +12,7 @@ [jinteki.utils :refer [select-non-nil-keys side-from-str superuser?]] [jinteki.preconstructed :refer [all-matchups]] [jinteki.validator :as validator] - [medley.core :refer [find-first random-uuid]] + [medley.core :refer [find-first]] [monger.collection :as mc] [time-literals.read-write :as read-write] [web.app-state :as app-state] @@ -390,7 +390,7 @@ (defn close-lobby! "Closes the given game lobby, booting all players and updating stats." ([db lobby] (close-lobby! db lobby nil)) - ([db {:keys [gameid players pool started on-close] :as lobby} skip-on-close] + ([db {:keys [gameid pool started on-close] :as lobby} skip-on-close] (when started (stats/game-finished db lobby) (stats/update-deck-stats db lobby) @@ -437,7 +437,7 @@ (defn find-deck [db opts] (assert (:_id opts) ":_id is required") - (mc/find-one-as-map db :decks opts)) + (mc/find-one-as-map db "decks" opts)) (defn find-deck-for-user [db deck-id user] (let [username (:username user)] @@ -695,7 +695,7 @@ new-app-state (swap! app-state/app-state assoc-in [:lobbies gameid :title] (str player-name "'s game"))] (send-lobby-state (get-in new-app-state [:lobbies (:gameid lobby)])) (broadcast-lobby-list) - (mc/insert db :moderator_actions + (mc/insert db "moderator_actions" {:moderator (:username user) :action :rename-game :game-name bad-name @@ -716,7 +716,7 @@ (when (and (superuser? user) lobby) (close-lobby! db lobby) (broadcast-lobby-list) - (mc/insert db :moderator_actions + (mc/insert db "moderator_actions" {:moderator (:username user) :action :delete-game :game-name bad-name @@ -808,8 +808,7 @@ (defmethod ws/-msg-handler :lobby/pause-updates lobby--pause-updates - [{{user :user} :ring-req - uid :uid + [{uid :uid id :id timestamp :timestamp}] (lobby-thread (app-state/pause-lobby-updates uid) @@ -817,8 +816,7 @@ (defmethod ws/-msg-handler :lobby/continue-updates lobby--continue-updates - [{{user :user} :ring-req - uid :uid + [{uid :uid id :id timestamp :timestamp}] (lobby-thread diff --git a/src/clj/web/system.clj b/src/clj/web/system.clj index 0536b6fced..81f6115bca 100644 --- a/src/clj/web/system.clj +++ b/src/clj/web/system.clj @@ -17,6 +17,7 @@ [game.quotes :refer [load-quotes!]] [integrant.core :as ig] [jinteki.cards :as cards] + [jinteki.i18n :as i18n] [medley.core :refer [deep-merge]] [monger.collection :as mc] [monger.core :as mg] @@ -24,7 +25,6 @@ [taoensso.sente :as sente] [time-literals.data-readers] [time-literals.read-write :as read-write] - ;; [web.angel-arena :as angel-arena] [web.api :refer [make-app make-dev-app]] [web.app-state :as app-state] [web.game] @@ -128,13 +128,21 @@ (defmethod ig/init-key :game/quotes [_ _opts] (load-quotes!)) +(defmethod ig/init-key :web/i18n [_ _opts] + (i18n/load-dictionary! "resources/public/i18n")) + +(defmethod ig/halt-key! :web/i18n [_ _opts] + (reset! i18n/fluent-dictionary nil)) + (defn- format-card-key->string [fmt] (assoc fmt :cards - (reduce-kv - (fn [m k v] - (assoc m (name k) v)) - {} (:cards fmt)))) + (->> (:cards fmt) + (reduce-kv + (fn [m k v] + (assoc! m (name k) v)) + (transient {})) + (persistent!)))) (defmethod ig/init-key :jinteki/cards [_ {{:keys [db]} :mongo}] (let [cards (mc/find-maps db "cards" nil) diff --git a/src/cljc/i18n/core.cljc b/src/cljc/i18n/core.cljc deleted file mode 100644 index a1d4d073da..0000000000 --- a/src/cljc/i18n/core.cljc +++ /dev/null @@ -1,29 +0,0 @@ -(ns i18n.core - (:require - [i18n.en] - [i18n.fr] - [i18n.ja] - [i18n.ko] - [i18n.la-pig] - [i18n.pl] - [i18n.pt] - [i18n.ru] - [i18n.zh-simp] - [taoensso.tempura :as tempura])) - -(defn translation-dictionary [] - {:en i18n.en/translations - :fr i18n.fr/translations - :ja i18n.ja/translations - :ko i18n.ko/translations - :la-pig i18n.la-pig/translations - :pl i18n.pl/translations - :pt i18n.pt/translations - :ru i18n.ru/translations - :zh-simp i18n.zh-simp/translations}) - -(def opts {:dict (translation-dictionary)}) - -(defn tr-impl [app-state resource & params] - (let [lang (keyword (get-in @app-state [:options :language] :en))] - (tempura/tr opts [lang :en] resource (vec params)))) diff --git a/src/cljc/i18n/en.cljc b/src/cljc/i18n/en.cljc deleted file mode 100644 index d59159d782..0000000000 --- a/src/cljc/i18n/en.cljc +++ /dev/null @@ -1,821 +0,0 @@ -(ns i18n.en) - -(def translations - {:missing ":en missing text" - :side {:corp "Corp" - :runner "Runner" - :any-side "Any Side" - :all "All"} - :faction {:all "All" - :any-faction "Any Faction" - :anarch "Anarch" - :criminal "Criminal" - :shaper "Shaper" - :adam "Adam" - :apex "Apex" - :sunny-lebeau "Sunny Lebeau" - :jinteki "Jinteki" - :haas-bioroid "Haas-Bioroid" - :nbn "NBN" - :weyland-consortium "Weyland Consortium" - :neutral "Neutral"} - :format {:all "All" - :any-format "Any Format" - :standard "Standard" - :eternal "Eternal" - :core-experience "Core Experience" - :snapshot "Snapshot" - :snapshot-plus "Snapshot Plus" - :socr "SOCR" - :sunset "Sunset" - :throwback "Throwback" - :neo "Neo" - :preconstructed "Preconstructed" - :classic "Classic" - :casual "Casual" - :system-gateway "System Gateway" - :startup "Startup"} - :preconstructed {:worlds-2012-a "Worlds 2012: Ben Marsh (C) vs. Jeremy Zwirn (R)" - :worlds-2012-a-tag "Ben Marsh (C) vs. Jeremy Zwirn (R)" - :worlds-2012-a-ul "Worlds 2012: Weyland vs. Criminal" - :worlds-2012-b "Worlds 2012: Jeremy Zwirn (C) vs. Ben Marsh (R)" - :worlds-2012-b-tag "Jeremy Zwirn (C) vs. Ben Marsh (R)" - :worlds-2012-b-ul "Worlds 2012: Haas-Bioroid vs. Criminal" - :worlds-2012-info "Worlds 2012 was played with (up to 3 copies of) the Core Set as the only legal product. Jeremy Zwirn (Building a Better World, Gabriel Santiago) took first place against Ben Marsh (Engineering the Future, Gabriel Santiago) in the first ever Netrunner World Championship." - :worlds-2013-a "Worlds 2013: Jens Erickson (C) vs. Andrew Veen (R)" - :worlds-2013-a-tag "Jens Erickson (C) vs. Andrew Veen (R)" - :worlds-2013-a-ul "Worlds 2013: HB FastAdv vs. Shaper Katman" - :worlds-2013-b "Worlds 2013: Andrew Veen (C) vs. Jens Erickson (R)" - :worlds-2013-b-tag "Andrew Veen (C) vs. Jens Erickson (R)" - :worlds-2013-b-ul "Worlds 2013: NBN Fast Adv vs. Andy Sucker" - :worlds-2013-info "166 players attended worlds in 2013. The tournament was held in Minneapolis, MN, USA, and consisted of 6 swiss rounds into a top 32 cut. The legal cardpool consisted of cards up to Opening Moves." - :worlds-2014-a "Worlds 2014: Dan D'Argenio (C) vs. Minh Tran (R)" - :worlds-2014-a-tag "Dan D'Argenio (C) vs. Minh Tran (R)" - :worlds-2014-a-ul "Worlds 2014: Honor and Perfection vs. Andromedium" - :worlds-2014-b "Worlds 2014: Minh Tran (C) vs. Dan D'Argenio (R)" - :worlds-2014-b-tag "Minh Tran (C) vs. Dan D'Argenio (R)" - :worlds-2014-b-ul "Worlds 2014: Personal Evolution vs. Daily QT Andy" - :worlds-2014-info "238 players attended worlds in 2014. The tournament was held in Minneapolis, MN, USA, and consisted of 7 swiss rounds into a top 16 cut. The legal cardpool consisted of cards up to Up and Over." - :worlds-2015-a "Worlds 2015: Dan D'Argenio (C) vs. Timmy Wong (R)" - :worlds-2015-a-tag "Dan D'Argenio (C) vs. Timmy Wong (R)" - :worlds-2015-a-ul "Worlds 2015: Foodcoatshop vs. The Morning After" - :worlds-2015-b "Worlds 2015: Timmy Wong (C) vs. Dan D'Argenio (R)" - :worlds-2015-b-tag "Timmy Wong (C) vs. Dan D'Argenio (R)" - :worlds-2015-b-ul "Worlds 2015: Yellow Shell vs. Radisson Cheese Plate" - :worlds-2015-info "269 players attended worlds in 2015. The tournament was held in Minneapolis, MN, USA, and consisted of 8 swiss rounds into a top 16 cut. The legal cardpool consisted of cards up to Data and Destiny." - :worlds-2016-a "Worlds 2016: Chris Dyer (C) vs. Benjamin Ni (R)" - :worlds-2016-a-tag "Chris Dyer (C) vs. Benjamin Ni (R)" - :worlds-2016-a-ul "Worlds 2016: Snekbite vs. Minh MaxX++" - :worlds-2016-b "Worlds 2016: Benjamin Ni (R) vs. Chris Dyer (C)" - :worlds-2016-b-tag "Benjamin Ni (R) vs. Chris Dyer (C)" - :worlds-2016-b-ul "Worlds 2016: Fiery Info vs. Papa Smurf" - :worlds-2016-info "278 players attended worlds in 2016. The tournament was held in Minneapolis, MN, USA, and consisted of 9 swiss rounds into a top 16 cut. The legal cardpool consisted of cards up to Escalation." - :worlds-2017-a "Worlds 2017: Jess Horig (C) vs. Grey Tongue (R)" - :worlds-2017-a-tag "Jess Horig (C) vs. Grey Tongue (R)" - :worlds-2017-a-ul "Worlds 2017: Stinson Reversed CI vs. Aesops Hayley" - :worlds-2017-b "Worlds 2017: Grey Tongue (C) vs. Jess Horig (R)" - :worlds-2017-b-tag "Grey Tongue (C) vs. Jess Horig (R)" - :worlds-2017-b-ul "Worlds 2017: No-Show Rewiring CI vs. Laguna Lock Hayley" - :worlds-2017-info "233 players attended worlds in 2017. The tournament was held in Minneapolis, MN, USA, and consisted of 8(?) swiss rounds into a top 16 cut. The legal cardpool consisted of cards up to the Revised Core set." - :worlds-2018-a "Worlds 2018: Joe Schupp (C) vs. Chris Dyer (R)" - :worlds-2018-a-tag "Joe Schupp (C) vs. Chris Dyer (R)" - :worlds-2018-a-ul "Worlds 2018: AMERICA CtM vs. Gooseberry MaxX" - :worlds-2018-b "Worlds 2018: Chris Dyer (C) vs. Joe Schupp (R)" - :worlds-2018-b-tag "Chris Dyer (C) vs. Joe Schupp (R)" - :worlds-2018-b-ul "Worlds 2018: Trust the Process vs. Dan D'Argenio KoS Val" - :worlds-2018-info "403(!) players attended worlds in 2018. This is the final worlds championship to be run by FFG. The tournament was held in Minneapolis, MN, USA, and consisted of 9(?) swiss rounds into a top 16 cut. The legal cardpool consisted of cards up to Reign and Reverie" - :worlds-2019-a "Worlds 2019: Pinsel (C) vs. Testrunning (R)" - :worlds-2019-a-tag "Pinsel (C) vs. Testrunning (R)" - :worlds-2019-a-ul "Worlds 2019: Fully dedicated to efficiency vs. Trash Panda" - :worlds-2019-b "Worlds 2019: Testrunning (C) vs. Pinsel (R)" - :worlds-2019-b-tag "Testrunning (C) vs. Pinsel (R)" - :worlds-2019-b-ul "Worlds 2019: 2 Grid for 2 Place vs. Trash Panda" - :worlds-2019-info "256 players played in the first ever Project NISEI Netrunner World Championship in 2019. This tournament was held in Rotterdam, NL, and consisted of 9 swiss rounds into a top 16 cut. The legal cardpool consisted of cards up to the Uprising Booster Pack" - :worlds-2020-a "Worlds 2020: Limes (C) vs. tf34 (R)" - :worlds-2020-a-tag "Limes (C) vs. tf34 (R)" - :worlds-2020-a-ul "Worlds 2020: I don't like this deck vs. Engolo Freedom" - :worlds-2020-b "Worlds 2020: tf34 (R) vs. Limes (C)" - :worlds-2020-b-tag "tf34 (R) vs. Limes (C)" - :worlds-2020-b-ul "Worlds 2020: Malia CTM vs. Imp-pressive Hoshiko" - :worlds-2020-info "294 players played in the first ever online world championship for Netrunner, run by Project NISEI 2020. Due to travel restrictions at the start of the COVID-19 pandemic, this tournament was held online via Jinteki.net, and consisted of 8 swiss rounds on two distinct day-ones, into a top 16 cut. The legal cardpool consisted of cards up to Uprising." - :worlds-2021-a "Worlds 2021: Patrick Gower (C) vs. Jonas (R)" - :worlds-2021-a-tag "Patrick Gower (C) vs. Jonas (R)" - :worlds-2021-a-ul "Worlds 2021: 44 Card PD vs. Watch Me Drip, Watch Me Maemi" - :worlds-2021-b "Worlds 2021: Jonas (C) vs. Patrick Gower (R)" - :worlds-2021-b-tag "Jonas (C) vs. Patrick Gower (R)" - :worlds-2021-b-ul "Worlds 2021: Is Gagarin Good? vs. Medium to Large Maxx" - :worlds-2021-info "201 players played in the second online world championship for Netrunner, run by Project NISEI in 2021. Due to the ongoing disruption caused by the COVID-19 pandemic, this tournament was held online via Jinteki.net, and consisted of 8 swiss rounds on two distinct day-ones, into a top 16 cut. The legal cardpool consisted of cards up to System Gateway." - :worlds-2022-a "Worlds 2022: William Huang (C) vs. skry (R)" - :worlds-2022-a-tag "William Huang (C) vs. skry (R)" - :worlds-2022-a-ul "Worlds 2022: SNACS vs. Liberté, Égalité, Humidité" - :worlds-2022-b "Worlds 2022: skry (C) vs. William Huang (R)" - :worlds-2022-b-tag "skry (C) vs. William Huang (R)" - :worlds-2022-b-ul "Worlds 2022: Dies to Doom Blade vs. ApocoLat" - :worlds-2022-info "158 players played in the first world championship run by Null Signal Games (formerly Project NISEI), which was the first Netrunner world championship to be run in-person since the start of the COVID-19 pandemic. The tournament was held in Toronto, Canada, and consisted of 7 rounds into a top 16 cut. The legal cardpool consisted of cards up to Midnight Sun." - :worlds-2023-a "Worlds 2023: William Huang (C) vs. cableCarnage (R)" - :worlds-2023-a-tag "William Huang (C) vs. cableCarnage (R)" - :worlds-2023-a-ul "Worlds 2023: The Worlds Grind vs. sableCarnage" - :worlds-2023-b "Worlds 2023: cableCarnage (C) vs. William Huang (R)" - :worlds-2023-b-tag "cableCarnage (C) vs. William Huang (R)" - :worlds-2023-b-ul "Worlds 2023: tableCarnage vs. You *do* always come back!" - :worlds-2023-info "254 players played in the second Netrunner world championship run by Null Signal Games. The tournament was held in Barcelona, Spain, and consisted of 9 rounds into a top 16 cut. The legal cardpool consisted of cards up to The Automata Initiative."} - :set {:all "All" - :draft-cycle "Draft Cycle" - :draft "Draft" - :core-set "Core Set" - :genesis-cycle "Genesis Cycle" - :what-lies-ahead "What Lies Ahead" - :trace-amount "Trace Amount" - :cyber-exodus "Cyber Exodus" - :a-study-in-static "A Study in Static" - :humanity-s-shadow "Humanity's Shadow" - :future-proof "Future Proof" - :creation-and-control "Creation and Control" - :spin-cycle "Spin Cycle" - :opening-moves "Opening Moves" - :second-thoughts "Second Thoughts" - :mala-tempora "Mala Tempora" - :true-colors "True Colors" - :fear-and-loathing "Fear and Loathing" - :double-time "Double Time" - :honor-and-profit "Honor and Profit" - :lunar-cycle "Lunar Cycle" - :upstalk "Upstalk" - :the-spaces-between "The Spaces Between" - :first-contact "First Contact" - :up-and-over "Up and Over" - :all-that-remains "All That Remains" - :the-source "The Source" - :order-and-chaos "Order and Chaos" - :sansan-cycle "SanSan Cycle" - :the-valley "The Valley" - :breaker-bay "Breaker Bay" - :chrome-city "Chrome City" - :the-underway "The Underway" - :old-hollywood "Old Hollywood" - :the-universe-of-tomorrow "The Universe of Tomorrow" - :data-and-destiny "Data and Destiny" - :mumbad-cycle "Mumbad Cycle" - :kala-ghoda "Kala Ghoda" - :business-first "Business First" - :democracy-and-dogma "Democracy and Dogma" - :salsette-island "Salsette Island" - :the-liberated-mind "The Liberated Mind" - :fear-the-masses "Fear the Masses" - :flashpoint-cycle "Flashpoint Cycle" - :23-seconds "23 Seconds" - :blood-money "Blood Money" - :escalation "Escalation" - :intervention "Intervention" - :martial-law "Martial Law" - :quorum "Quorum" - :red-sand-cycle "Red Sand Cycle" - :daedalus-complex "Daedalus Complex" - :station-one "Station One" - :earth-s-scion "Earth's Scion" - :blood-and-water "Blood and Water" - :free-mars "Free Mars" - :crimson-dust "Crimson Dust" - :terminal-directive-cycle "Terminal Directive Cycle" - :terminal-directive-cards "Terminal Directive Cards" - :terminal-directive-campaign "Terminal Directive Campaign" - :unreleased "Unreleased" - :revised-core-set "Revised Core Set" - :kitara-cycle "Kitara Cycle" - :sovereign-sight "Sovereign Sight" - :down-the-white-nile "Down the White Nile" - :council-of-the-crest "Council of the Crest" - :the-devil-and-the-dragon "The Devil and the Dragon" - :whispers-in-nalubaale "Whispers in Nalubaale" - :kampala-ascendent "Kampala Ascendent" - :reign-and-reverie "Reign and Reverie" - :magnum-opus "Magnum Opus" - :napd-multiplayer "NAPD Multiplayer" - :system-core-2019 "System Core 2019" - :ashes-cycle "Ashes Cycle" - :downfall "Downfall" - :uprising-booster-pack "Uprising Booster Pack" - :uprising "Uprising" - :magnum-opus-reprint "Magnum Opus Reprint" - :salvaged-memories "Salvaged Memories" - :system-gateway "System Gateway" - :system-update-2021 "System Update 2021" - :borealis-cycle "Borealis Cycle" - :midnight-sun-booster-pack "Midnight Sun Booster Pack" - :midnight-sun "Midnight Sun" - :parhelion "Parhelion" - :liberation-cycle "Liberation Cycle" - :the-automata-initiative "The Automata Initiative" - :rebellion-without-rehearsal "Rebellion Without Rehearsal" - :alt-art "Alt Art" - :kysra-alt-arts "Kysra Alt Arts" - :ntscape-navigator-alt-arts "Ntscape Navigator Alt Arts" - :plural-and-miniplural-alt-arts "Plural and MiniPlural Alt Arts" - :alternate "Alternate" - :world-champion-2015 "World Champion 2015" - :world-champion-2016 "World Champion 2016" - :world-champion-2017 "World Champion 2017" - :championship-2019 "Championship 2019" - :gnk-2019 "GNK 2019" - :championship-2020 "Championship 2020" - :signed-championship-2020 "Signed Championship 2020" - :previous-versions "Previous Versions"} - :card-type {:all "All" - :identity "Identity" - :agenda "Agenda" - :asset "Asset" - :upgrade "Upgrade" - :operation "Operation" - :ice "Ice" - :event "Event" - :hardware "Hardware" - :resource "Resource" - :program "Program"} - :pronouns {:none "Unspecified" - :any "Any" - :myodb "Prefer not to say" - :blank "[blank]" - :they "They/them" - :she "She/her" - :sheit "She/it" - :shethey "She/they" - :heshe "He/She/they" - :he "He/him" - :heit "He/it" - :hethey "He/they" - :faefaer "Fae/Faer" - :it "It" - :ne "Ne/nem" - :ve "Ve/ver" - :ey "Ey/em" - :zehir "Ze/hir" - :zezir "Ze/zir" - :xe "Xe/xem" - :xi "Xi/xir"} - :chat {:title "Play Netrunner in your browser" - :channels "Channels" - :send "Send" - :placeholder "Say something..." - :delete "Delete Message" - :delete-all "Delete All Messages From User" - :block "Block User" - :cancel "Cancel" - :message-blocked (fn [[reason-str]] (str "Message Blocked" (when reason-str (str ": " reason-str)))) - :length-exceeded "Length exceeded" - :rate-exceeded "Rate exceeded"} - :nav {:welcome "Welcome" - :chat "Chat" - :cards "Cards" - :deck-builder "Deck Builder" - :play "Play" - :help "Help" - :settings "Settings" - :stats "Stats" - :about "About" - :tournaments "Tournaments" - :admin "Admin" - :users "Users" - :features "Features" - :game-count (fn [[cnt]] (str cnt " Game" (when (not= cnt 1) "s")))} - :menu {:settings :en.nav/settings - :logout "Jack out" - :admin :en.nav/admin - :moderator "Moderator" - :donor "Donor"} - :card-browser {:implementation-note "Implementation Note" - :search-hint "Search cards" - :sort "Sort by" - :format "Format" - :set "Set" - :side "Side" - :faction "Faction" - :type "Type" - :clear "Clear" - :select-art "Select Art" - :selected-art "Selected Alt Art" - :update-success "Updated Art" - :update-failure "Failed to Update Art" - :memory "Memory" - :cost "Cost" - :trash-cost "Trash cost" - :strength "Strength" - :advancement "Advancement requirement" - :agenda-points "Agenda points" - :min-deck "Minimum deck size" - :inf-limit "Influence Limit" - :influence "Influence" - :artist-info "Artist Info" - :more-info "More Info" - :sort-by {:faction "Faction" - :name "Name" - :type "Type" - :influence "Influence" - :cost "Cost" - :set-number "Set number"}} - :deck-builder {:loading-msg "Loading deck collection..." - :new-corp "New Corp deck" - :new-runner "New Runner deck" - :import-button "Import deck" - :reset "Reset" - :import-title "Enter a Public NRDB Deck ID or URL" - :import "Import" - :cancel "Cancel" - :import-placeholder "NRDB ID" - :deck-count (fn [[cnt]] (str cnt (if (= 1 cnt) " Deck" " Decks"))) - :filtered "(filtered)" - :save "Save" - :confirm-delete "Confirm Delete" - :edit "Edit" - :delete "Delete" - :copy "Copy" - :deck-copy-suffix "copy" - :clear-stats "Clear Stats" - :create-game "Create Game" - :new-deck "New Deck" - :deck-name "Deck name" - :format "Format" - :identity "Identity" - :deck-notes "Deck notes" - :decklist "Decklist" - :decklist-inst "(Type or paste a decklist, it will be parsed)" - :notes "Notes" - :add-to-deck "Add to deck" - :add-cards "Add cards" - :card-name "Card name" - :no-decks "No decks" - :cards "cards" - :min "minimum" - :max "maximum" - :influence "Influence" - :agenda-points "Agenda points" - :deck-points "Deck points" - :hash "Tournament hash" - :why "Why?" - :legal "legal" - :illegal "illegal" - :games "Games" - :completed "Completed" - :won "Won" - :lost "Lost"} - :game-prompt {:trash "trash" - :advance "advance" - :score "score" - :rez "rez" - :derez "derez" - :expend "Expend" - :archives "Archives" - :hq "HQ" - :r-d "R&D" - :new-remote "New Remote" - :server-1 "Server 1" - :server-2 "Server 2" - :server-3 "Server 3" - :server-4 "Server 4" - :server-5 "Server 5" - :server-6 "Server 6" - :server-7 "Server 7" - :server-8 "Server 8" - :server-9 "Server 9" - :server-10 "Server 10"} - :lobby {:no-games "No games" - :tournament "Tournament" - :competitive "Competitive" - :casual "Casual" - :angel-arena "Angel Arena" - :new-game "New game" - :reload "Reload list" - :load-replay "Load replay" - :start-replay "Start replay" - :save-replay "Save replay" - :create "Create" - :cancel "Cancel" - :title "Title" - :side "Side" - :format "Format" - :default-game-format "Default game format" - :gateway-format {:beginner "Beginner" - :beginner-info "This lobby is using the System Gateway beginner decks for the Corporation and Runner. These decks are recommended for your first games. Games are played to 6 agenda points." - :beginner-ul "System Gateway - Beginner Teaching Decks" - :intermediate "Intermediate" - :intermediate-info "This lobby is using the System Gateway intermediate decks for the Corporation and Runner. These decks have slightly more range than the beginner decks. Games are played to 7 agenda points." - :intermediate-ul "System Gateway - Intermediate Teaching Decks" - :constructed "Constructed"} - :open-decklists "Open Decklists" - :open-decklists-b "(open decklists)" - :singleton "Singleton" - :singleton-b "(singleton)" - :singleton-details "This will restrict decklists to only those which do not contain any duplicate cards. It is recommended you use the listed singleton-based identities." - :singleton-example "1) Nova Initiumia: Catalyst & Impetus 2) Ampere: Cybernetics For Anyone" - :singleton-restriction "This lobby is running in singleton mode. This means decklists will be restricted to only those which do not contain any duplicate cards." - :options "Options" - :spectators "Allow spectators" - :hidden "Make players' hidden information visible to spectators" - :hidden-details "This will reveal both players' hidden information to ALL spectators of your game, including hand and face-down cards." - :hidden-password "We recommend using a password to prevent strangers from spoiling the game." - :password-protected "Password protected" - :password "Password" - :timed-game "Start with timer" - :timer-length "Timer length (minutes)" - :timed-game-details "Timer is only for convenience: the game will not stop when timer runs out." - :save-replay-details "This will save a replay file of this match with open information (e.g. open cards in hand). The file is available only after the game is finished." - :save-replay-unshared "Only your latest 15 unshared games will be kept, so make sure to either download or share the match afterwards." - :save-replay-beta "BETA Functionality: Be aware that we might need to reset the saved replays, so make sure to download games you want to keep. Also, please keep in mind that we might need to do future changes to the site that might make replays incompatible." - :replay-link-error "Replay link invalid." - :replay-invalid-file "Select a valid replay file." - :corp-perspective "Corp Perspective" - :runner-perspective "Runner Perspective" - :both-perspective "Both" - :start "Start" - :leave "Leave" - :swap "Swap sides" - :waiting "Waiting players deck selection" - :players "Players" - :deck-selected "Deck selected" - :select-deck "Select Deck" - :chat "Chat" - :select-error "Cannot select that deck" - :select-title "Select your deck" - :spectator-count (fn [[cnt]] (str cnt " Spectator" (when (not= cnt 1) "s"))) - :closed-msg "Game lobby closed due to inactivity" - :title-error "Please fill a game title." - :password-error "Please fill a password." - :too-little-data "Too little data" - :completion-rate "Game Completion Rate" - :watch "Watch" - :join "Join" - :rejoin "Rejoin" - :as-corp "As Corp" - :as-runner "As Runner" - :private "PRIVATE" - :reset "Reset Game Name" - :delete "Delete Game" - :password-for "Password for" - :invalid-password "Invalid password" - :not-allowed "Not allowed" - :aborted "Connection aborted" - :game-count (fn [[cnt]] (str cnt (if (= 1 cnt) " Game" " Games"))) - :api-access "Allow API access to game information" - :api-requires-key "(Requires an API Key in Settings)" - :api-access-details "This allows access to information about your game to 3rd party extensions. Requires an API Key to be created in Settings." - :filter "Filter" - :filtered "(filtered)"} - :angel-arena {:cancel-match "Cancel match" - :claim-victory "Claim victory" - :still-here "Need more time" - :abandon-run "Abandon run" - :active-corp-run "Active Corp run" - :active-runner-run "Active Runner run" - :are-you-sure "Are you sure?" - :are-you-sure-no "no" - :are-you-sure-yes "yes" - :format "Format" - :latest-runs "Latest runs" - :no-eligible-decks "No legal decks found for this side and format." - :no-games "No games" - :queue-for-match "Queue for match" - :queueing "Queueing..." - :requesting-run-data "Requesting run data..." - :select-deck "Select your deck" - :start-new-run "Start new run" - :wins "wins"} - :settings {:invalid-password "Invalid login or password" - :invalid-email "No account with that email address exists" - :updated "Profile updated - Please refresh your browser" - :updating "Updating profile..." - :get-log-width "Get current log width" - :get-log-top "Get current log top" - :email-title "Change email address" - :current-email "Current email" - :desired-email "Desired email" - :email-placeholder "Email address" - :enter-valid "Please enter a valid email address" - :update "Update" - :cancel "Cancel" - :email "Email" - :change-email "Change email" - :avatar "Avatar" - :change-avatar "Change on gravatar.com" - :pronouns "Pronouns" - :language "Language" - :sounds "Sounds" - :enable-lobby-sounds "Enable lobby sounds" - :enable-game-sounds "Enable game sounds" - :volume "Volume" - :layout-options "Layout options" - :player-stats-icons "Use icons for player stats" - :stacked-cards "Card stacking (on by default)" - :ghost-trojans "Display ghosts for hosted programs" - :sides-overlap "Runner and Corp board may overlap" - :runner-layout "Runner layout from Corp perspective" - :runner-classic "Runner rig layout is classic jnet (Top to bottom: Programs, Hardware, Resources)" - :runner-reverse "Runner rig layout is reversed (Top to bottom: Resources, Hardware, Programs)" - :log-size "Log size" - :log-player-highlight "Log player highlight" - :log-player-highlight-red-blue "Corp: Blue / Runner: Red" - :log-player-highlight-none "None" - :card-preview-zoom "Card preview zoom" - :card-iamge "Card Image" - :card-text "Card Text" - :pin-zoom "Keep zoomed cards on screen" - :background "Game board background" - :the-root-bg "The Root" - :freelancer-bg "Freelancer" - :mushin-no-shin-bg "Mushin No Shin" - :traffic-jam-bg "Traffic Jam" - :rumor-mill-bg "Rumor Mill" - :find-the-truth-bg "Find The Truth" - :push-your-luck-bg "Push Your Luck" - :apex-bg "Apex" - :worlds2020-bg "Worlds 2020" - :monochrome-bg "Monochrome" - :custom-bg "Custom BG" - :input-url-below "(input URL below)" - :card-backs "Card backs" - :game-stats "Game Win/Lose statistics" - :deck-stats "Deck statistics" - :always "Always" - :comp-only "Competitive Lobby Only" - :none "None" - :alt-art "Alt arts" - :show-alt "Show alternate card arts" - :high-res "Enable high-resolution card images" - :card-images "Card images" - :set-all "Set all cards to" - :set "Set" - :reset "Reset All to Official Art" - :blocked "Blocked users" - :user-name "User name" - :block "Block user" - :update-profile "Update Profile" - :nsg "NSG" - :ffg "FFG" - :api-keys "API Keys" - :delete-api-key "Delete" - :create-api-key "Create API Key" - :bespoke-sounds-header "Card-Specific Sounds" - :bespoke-sounds - {:archer "Archer" - :harmonics "Harmonics Suite (Bloop, Echo, Pulse, Wave)" - :end-of-the-line "End of the Line"}} - :ingame-settings {:card-stacking "Card settings" - :stack-cards "Stack cards" - :label-unrezzed-cards "Label unrezzed cards" - :label-faceup-cards "Label face up cards" - :ghost-trojans "Display hosted trojans in rig" - :card-sorting "Sorting" - :sort-archives "Sort Archives" - :sort-heap "Sort Heap" - :runner-board-order "Runner board order" - :runner-classic "Classic" - :runner-reverse "Reversed" - :board-overlap "Board overlap" - :sides-overlap "Runner and Corp may overlap" - :card-backs "Card backs" - :preview-zoom "Card preview zoom" - :card-image "Card Image" - :card-text "Card Text" - :card-images "Card images" - :high-res "Enable high resolution card images" - :alt-art "Alt arts" - :show-alt "Show alternate card arts" - :save "Save"} - :stats {:game-stats "Game Stats" - :corp-stats "Corp Stats" - :runner-stats "Runner Stats" - :clear-stats "Clear Stats" - :no-log "No log available" - :view-log "View log" - :winner "Winner" - :no-games "No games" - :all-games "Show all games" - :shared-games "Only show shared" - :started "Started" - :ended "Ended" - :completed "Completed" - :not-completed "Not completed" - :won "Won" - :lost "Lost" - :turn-count (fn [[cnt]] (str cnt " turn" (when (not= cnt 1) "s"))) - :lobby "Lobby" - :format "Format" - :win-method "Win method" - :view-games "Return to stats screen" - :share "Share replay" - :launch "Launch Replay" - :download "Download replay" - :unavailable "Replay unavailable" - :filtered "(filtered)" - :log-count (fn [[cnt]] (str cnt " Log" (when (not= cnt 1) "s"))) - :clicks-gained "Clicks Gained" - :credits-gained "Credits Gained" - :credits-spent "Credits Spent" - :credits-click "Credits by the Basic Action" - :cards-drawn "Cards Drawn" - :cards-click "Cards Drawn by the Basic Action" - :damage-done "Damage Done" - :cards-rezzed "Cards Rezzed" - :tags-gained "Tags Gained" - :runs-made "Runs Made" - :shuffle-count "Shuffle Count" - :operations-played "Operations Played" - :cards-sabotaged "Sabotage Count" - :events-played "Events Played" - :unique-accesses "Unique Cards Accessed" - :psi-game-total "Psi Game: Games Played" - :psi-game-total-wins "Psi Game: Wins" - :psi-game-total-bid-0 "Psi Game: Bid 0" - :psi-game-total-bid-1 "Psi Game: Bid 1" - :psi-game-total-bid-2 "Psi Game: Bid 2" - :rashida-count "Rashida Count" - :cards-accessed "Cards Accessed"} - :log {:game-log "Game Log" - :settings "Settings" - :annotating "Annotating" - :run-timing "Run Timing" - :turn-timing "Turn Timing" - :shared "Shared Annotations" - :remote-annotations-fail "Could not get remote annotations."} - :annotations {:turn-placeholder "Notes for this turn" - :click-placeholder "Notes for this click" - :available-annotations "Available annotations" - :no-published-annotations "No published annotations." - :import-local "Import local annotation file" - :load-local "Load" - :save-local "Save" - :publish "Publish" - :clear "Clear local annotations"} - :diagrams {:turn {:corp-turn "Corporation Turn" - :corp-draw-phase "5.6.1: Draw Phase" - :corp-draw-phase-a "Corporation gains allotted clicks (default: [click][click][click])" - :corp-draw-phase-b "Paid ability window. Corp may rez non-ice cards or score agendas during this window" - :corp-draw-phase-c "Corporation recurring credits refill" - :corp-draw-phase-d "The turn formally begins. Turn begins events resolve" - :corp-draw-phase-e "The corporation performs their mandatory draw" - :corp-draw-phase-f "Proceed to the action phase (5.6.2)" - :corp-action-phase "5.6.2: Action Phase" - :corp-action-phase-a "Paid ability window. Corp may rez non-ice cards or score agendas during this window" - :corp-action-phase-b "If the corporation has unspent [Clicks], they take an action" - :corp-action-phase-c "If an action occured, return to (a)" - :corp-action-phase-d "The action phase is complete. Proceed to the discard phase (5.6.3)" - :corp-discard-phase "5.6.3: Discard phase" - :corp-discard-phase-a "The corporation discards to maximum hand size, if applicable" - :corp-discard-phase-b "Paid ability window. Corp may rez non-ice cards during this window" - :corp-discard-phase-c "If the corporation has any [Clicks] remaining, they lose those [Clicks]" - :corp-discard-phase-d "The Corporations turn formally ends. Turn end triggers resolve" - :corp-discard-phase-e "Proceed to the Runner turn" - :runner-turn "Runner Turn" - :runner-action-phase "5.7.1: Action Phase" - :runner-action-phase-a "Runner gains allotted clicks (default: [click][click][click][click])" - :runner-action-phase-b "Paid ability window. Corp may rez non-ice cards" - :runner-action-phase-c "Runner recurring credits refill" - :runner-action-phase-d "The turn formally begins. Turn begins events resolve" - :runner-action-phase-e "Paid ability window. Corp may rez non-ice cards" - :runner-action-phase-f "If the Runner has unspent [Clicks], they take an action" - :runner-action-phase-g "If an action occured, return to (e)" - :runner-action-phase-h "The action phase is complete. Proceed to the discard phase (5.7.2)" - :runner-discard-phase "5.7.2: Discard Phase" - :runner-discard-phase-a "The runner discards to maximum handsize, if applicable" - :runner-discard-phase-b "Paid ability window. Corp may rez non-ice cards" - :runner-discard-phase-c "If the runner has any [Clicks] remaining, they lose those [Clicks]" - :runner-discard-phase-d "The Runners turn formally ends. Turn end triggers resolve" - :runner-discard-phase-e "Proceed to the Corporation turn"} - :run-timing {:header "Timing Structure of a Run" - :disclaimer "This structure has been simplified for clarity. For complete rules, see the Null Signal Games website." - :initiation "6.9.1: Initiation Phase" - :initiation-a "Runner declares a server" - :initiation-b "Runner gains Bad Publicity credits" - :initiation-c "Run formally begins - Run events fire" - :initiation-d "Proceed to the outermost ice, if applicable, and begin the approach phase (6.9.2)" - :initiation-e "Otherwise, proceed to the movement phase (6.9.4)" - :approach "6.9.2: Approach Ice Phase" - :approach-a "You are now approaching the ice. Approach events resolve" - :approach-b "Paid Ability Window. Corp may rez the approached ice, or non-ice cards, during this window" - :approach-c "If approached ice is rezzed, continue to encounter phase (6.9.3)" - :approach-d "Otherwise, proceed to the movement phase (6.9.4)" - :encounter "6.9.3: Encounter Ice Phase" - :encounter-a "You are now encountering this ice. Encounter events resolve" - :encounter-b "Paid ability window. Encountered ice may be interfaced during this window" - :encounter-c "If there are unbroken subroutines to resolve, the corporation resolves the topmost unbroken subroutine. If they do, repeat this step" - :encounter-d "The encounter is complete. Proceed to the movement phase (6.9.4)" - :movement "6.9.4: Movement Phase" - :movement-a "If you were encountering or approaching an ice, you pass it. Pass-Ice events resolve" - :movement-b "If there are no more ice inwards from the passed ice, 'when you pass all ice on the server' events resolve" - :movement-c "Paid ability window" - :movement-d "The runner may jack out. If they do, proceed to the run ends phase (6.9.6)" - :movement-e "The runner proceeds to the next position inwards, if applicable" - :movement-f "Paid ability window. The corporation may rez non-ice cards" - :movement-g "If you are approaching another ice, return to the approach ice phase (6.9.2)" - :movement-h "The runner approaches the attacked server. Approach events resolve" - :movement-i "Continue to the success phase (6.9.5)" - :success "6.9.5: Success Phase" - :success-a "The run is declared successful. Successful run events are met" - :success-b "The runner breaches the attacked server" - :success-c "The success phase is complete. Continue to the run ends phase (6.9.6)" - :run-ends "6.9.6: Run Ends Phase" - :run-ends-a "Any open priority windows complete or are closed" - :run-ends-b "The runner loses any unspent bad publicity credits" - :run-ends-c "If the success phase was not reached and the server still exists, the run becomes unsuccessful" - :run-ends-d "The run ends. Run ends events resolve"}} - :game {:ok "OK" - :error "Internal Server Error. Please type /bug in the chat and follow the instructions." - :set-aside "Set aside" - :keep "Keep" - :mulligan "Mulligan" - :close "Close" - :start "Start Game" - :remove-tag "Remove Tag" - :run "Run" - :purge "Purge" - :trash-resource "Trash Resource" - :draw "Draw" - :gain-credit "Gain Credit" - :game-start "Game start" - :start-turn "Start Turn" - :end-turn "End Turn" - :mandatory-draw "Mandatory Draw" - :take-clicks "Take Clicks" - :rez-all "Rez All" - :reveal-my-hand "Reveal My Hand" - :hq "HQ" - :grip "Grip" - :rfg "Removed from the game" - :play-area "Play Area" - :current "Current" - :scored-area "Scored Area" - :last-revealed "Last Revealed" - :archives "Archives" - :max-hand "Max hand size" - :brain-damage "Core Damage" - :trash-like-cards "Offer to trash like cards" - :tag-count (fn [[base additional total]] (str base (when (pos? additional) (str " + " additional)) " Tag" (if (not= total 1) "s" ""))) - :agenda-count (fn [[agenda-point]] (str agenda-point " Agenda Point" (when (not= agenda-point 1) "s"))) - :agenda-point-req (fn [[agenda-point-req]] (if-not (= 7 agenda-point-req) (str " (" agenda-point-req " required)") "")) - :link-strength "Link Strength" - :credit-count (fn [[credit run-credit]] (str credit " Credit" (if (not= credit 1) "s" "") (when (pos? run-credit) (str " (" run-credit " for run)")))) - :click-count (fn [[click]] (str click " Click" (if (not= click 1) "s" ""))) - :bad-pub-count (fn [[base additional]] (str base (when (pos? additional) (str " + " additional)) " Bad Publicity")) - :mu-count (fn [[unused available]] (str unused " of " available " MU unused")) - :special-mu-count (fn [[unused available mu-type]] (str unused " of " available " " mu-type " MU unused")) - :show-decklists "Show/Hide decklists" - :indicate-action "Indicate paid ability" - :spec-count (fn [[c]] (str c " Spectator" (when (> c 1) "s"))) - :spec-view "Spectator View" - :runner-view "Runner View" - :corp-view "Corp View" - :leave-replay "Leave Replay" - :leave "Leave Game" - :unmute "Unmute spectators" - :mute "Mute spectators" - :attempt-reconnect "Attempt reconnect" - :lost-connection, "Lost connection to server. Reconnecting." - :reconnected-to-server, "Reconnected to server" - :concede "Concede" - :inactivity "Game closed due to inactivity" - :server "Server" - :unimplemented "Unimplemented" - :abilities "Abilities" - :subs "Subroutines" - :let-subs-fire "Let unbroken subroutines fire" - :fire-unbroken "Fire unbroken subroutines" - :actions "Actions" - :stack "Stack" - :r&d "R&D" - :shuffle "Shuffle" - :show "Show" - :close-shuffle "Close & Shuffle" - :heap "Heap" - :card-count (fn [[size]] (str size " card" (when (not= 1 size) "s") ".")) - :face-down-count (fn [[total face-up]] (str total " cards, " (- total face-up) " face-down.")) - :up-down-count (fn [[total face-up]] (str face-up "↑ " (- total face-up) "↓")) - :initiation "Initiation" - :approach-ice "Approach ice" - :encounter-ice "Encounter ice" - :movement "Movement" - :breach-server "Breach server" - :success "Success" - :run-ends "Run ends" - :no-current-run "No current run" - :current-phase "Current phase" - :unknown-phase "Unknown phase" - :rez "Rez" - :no-further "No further actions" - :continue "Continue" - :continue-to "Continue to" - :stop-auto-pass "Stop auto-passing priority" - :auto-pass "Auto-pass priority" - :jack-out "Jack Out" - :trace "Trace" - :beat-trace "Beat Trace" - :unbeatable "Make unbeatable" - :credits "credits" - :card "Card" - :minutes "m:" - :seconds "s" - :seconds-remaining "s remaining" - :time-taken (fn [[t]] (str "Time taken: " t " minutes")) - :win-decked (fn [[turn]] (str "wins due to the Corp being decked on turn " turn)) - :win-flatlined (fn [[turn]] (str "wins by flatline on turn " turn)) - :win-conceded (fn [[turn]] (str "wins by concession on turn " turn)) - :win-claimed (fn [[turn]] (str "wins by claim on turn " turn)) - :win-points (fn [[turn]] (str "wins by scoring agenda points on turn " turn)) - :win-other (fn [[turn reason]] (str "wins by " reason " on turn " turn))}}) diff --git a/src/cljc/i18n/fr.cljc b/src/cljc/i18n/fr.cljc deleted file mode 100644 index 6e7acf8b88..0000000000 --- a/src/cljc/i18n/fr.cljc +++ /dev/null @@ -1,396 +0,0 @@ -(ns i18n.fr) - -(def translations - {:missing ":fr texte manquant" - :side {:corp "Corpo" - :runner "Runner" - :any-side "N'importe quel camp" - :all "Les deux camps"} - :faction {:all "Toutes" - :any-faction "Toute faction" - :anarch "Anarch" - :criminal "Criminel" - :shaper "Façonneur" - :adam "Adam" - :apex "Apex" - :sunny-lebeau "Sunny Lebeau" - :jinteki "Jinteki" - :haas-bioroid "Haas-Bioroid" - :nbn "NBN" - :weyland-consortium "Consortium Weyland" - :neutral "Neutre"} - :format {:all "Tous" - :any-format "Tout format" - :standard "Standard" - :eternal "Eternal" - :core-experience "Core Experience" - :snapshot "Snapshot" - :snapshot-plus "Snapshot Plus" - :socr "SOCR" - :sunset "Sunset" - :neo "Neo" - :classic "Classic" - :casual "Casual" - :system-gateway "System Gateway" - :startup "Startup"} - :card-type {:all "Tous" - :identity "Identité" - :agenda "Projet" - :asset "Avoir" - :upgrade "Extension" - :operation "Opération" - :ice "Glace" - :event "Évènement" - :hardware "Matériel" - :resource "Ressource" - :program "Programme"} - :pronouns {:none "Non indiqué" - :any "N'importe quel pronom" - :myodb "Préfère ne pas le dire" - :blank "[Laisser vide]" - :they "Iel" - :she "Elle" - :shethey "Elle ou iel" - :he "Il/lui" - :hethey "Il/lui ou iel" - :it "Ul" - :ne "Ol" - :ve "Ael" - :ey "Ey" - :zehir "Zehir" - :zezir "Zezir" - :xe "Xe"} - :chat {:title "Joue à Netrunner dans ton navigateur" - :channels "Canaux" - :send "Envoyer" - :placeholder "Dire quelque chose…" - :delete "Effacer le message" - :delete-all "Effacer tous les messages de l'utilisateur" - :block "Bloquer l'utilisateur" - :cancel "Annuler"} - :nav {:chat "Discussion" - :cards "Cartes" - :deck-builder "Constructeur de decks" - :play "Jouer" - :help "Aide" - :settings "Réglages" - :stats "Statistiques" - :about "À propos" - :tournaments "Tournois" - :admin "Admin" - :users "Utilisateurs" - :features "Caractéristiques" - :game-count (fn [[cnt]] (str cnt " Partie" (when (not= cnt 1) "s")))} - :menu {:settings :fr.nav/settings - :logout "Débrancher" - :admin :fr.nav/admin - :moderator "Modérateur"} - :card-browser {:search-hint "Rechercher des cartes" - :sort "Trier par" - :format "Format" - :set "Extension" - :side "Camp" - :faction "Faction" - :type "Type" - :clear "Réinitialiser" - :select-art "Sélectionner l'illustration" - :selected-art "Sélectionner l'illustration alternatiive" - :update-success "Illustration mise à jour" - :update-failure "Échec de la mise à jour de l'illustration" - :memory "Mémoire" - :cost "Cout" - :trash-cost "Cout d'effacement" - :strength "Force" - :advancement "Valeur d'avancement" - :agenda-points "Points de projet" - :min-deck "Taille minimale de deck" - :inf-limit "Limite d'influence" - :influence "Influence" - :sort-by {:faction "Faction" - :name "Nom" - :type "Type" - :influence "Influence" - :cost "Cout" - :set-number "Numéro de carte"}} - :deck-builder {:loading-msg "Chargement de la bibliothèque de decks…" - :new-corp "Nouveau deck Corpo" - :new-runner "Nouveau deck Runner" - :import-button "Importer" - :reset "Réinitialiser" - :import-title "Entrer un ID de deck NRDB publique ou une URL" - :import "Importer" - :cancel "Annuler" - :import-placeholder "ID NRDB" - :deck-count (fn [[cnt]] (str cnt (if (= 1 cnt) " Deck" " Decks"))) - :filtered "(filtres activés)" - :save "Sauvegarder" - :confirm-delete "Confirmer l'effacement" - :edit "Éditer" - :delete "Effacer" - :clear-stats "Effacer les statistiques" - :create-game "Créer une partie" - :deck-name "Nom du deck" - :format "Format" - :identity "Identité" - :deck-notes "Notes sur le deck" - :decklist "Liste de cartes" - :decklist-inst "(Saisissez ou copiez une liste, elle sera analysée)" - :notes "Notes" - :add-to-deck "Ajouter au deck" - :add-cards "Ajouter des cartes" - :card-name "Nom de la carte" - :no-decks "Aucun deck" - :cards "cartes" - :min "minimum" - :max "maximum" - :influence "Influence" - :agenda-points "Points de projet" - :deck-points "Points du deck" - :hash "Hash de tournoi" - :why "Pourquoi ?" - :legal "légal" - :illegal "illégal" - :games "Parties" - :completed "Terminées" - :won "Gagnées" - :lost "Perdues"} - :lobby {:no-games "Pas de partie" - :tournament "Tournois" - :competitive "Compétition" - :casual "Amical" - :new-game "Nouvelle partie" - :reload "Rafraichir" - :load-replay "Charger un replay" - :start-replay "Lancer le replay" - :save-replay "Sauvegarder le replay" - :replay-link-error "Lien de replay invalide." - :replay-invalid-file "Sélectionner un fichier de replay valide." - :create "Créer" - :cancel "Annuler" - :title "Nom de la partie" - :side "Camp" - :format "Format" - :options "Options" - :spectators "Autoriser les spectateurs" - :hidden "Rendre les informations cachées du joueur visibles aux spectateurs" - :password-protected "Protéger par mot de passe" - :password "Mot de passe" - :start "Commencer" - :leave "Quitter" - :swap "Changer de camp" - :waiting "En attente de la sélection des decks" - :players "Joueurs" - :deck-selected "Deck sélectionné" - :select-deck "Sélectionner un deck" - :chat "Discuter" - :select-title "Sélectionner votre deck" - :spectator-count (fn [[cnt]] (str cnt " Spectateur" (when (not= cnt 1) "s"))) - :closed-msg "Salle d'attente fermée pour cause d'inactivité" - :title-error "Veuillez saisir un nom de partie." - :password-error "Veuillez saisir un mot de passe." - :too-little-data "Trop peu de données" - :completion-rate "Taux de parties achevées" - :watch "Regarder" - :join "Rejoindre" - :rejoin "Rejoindre" - :as-corp "En tant que Corpo" - :as-runner "En tant que Runner" - :private "PRIVÉE" - :reset "Réinitialiser le nom de la partie" - :delete "Effacer la partie" - :password-for "Mot de passe pour" - :invalid-password "Mot de passe invalide" - :not-allowed "Interdit" - :aborted "Connexion interrompue" - :api-access "Autoriser l'accès API aux informations de la partie" - :api-requires-key "(Nécessite un clé API dans les réglages)" - :game-count (fn [[cnt]] (str cnt (if (= 1 cnt) " Partie" " Parties"))) - :filtered "(filtres activés)"} - :settings {:invalid-password "Identifiant ou mot de passe invalide" - :invalid-email "Aucun compte avec cette adresse e-mail" - :updated "Profil mis à jour - veuillez actualiser votre navigateur" - :updating "Mise à jour du profil…" - :get-log-width "Obtenir la largeur actuelle du journal" - :get-log-top "Obtenir le top du journal actuel" - :email-title "Changer d'adresse e-mail" - :current-email "E-mail actuel" - :desired-email "Nouvel e-mail " - :email-placeholder "Adresse e-mail" - :enter-valid "Veuillez saisir une adresse e-mail valide" - :update "Mettre à jour" - :cancel "Annuler" - :email "E-mail" - :change-email "Changer l'e-mail" - :avatar "Avatar" - :change-avatar "Changer sur gravatar.com" - :pronouns "Pronoms" - :language "Langue" - :sounds "Sons" - :enable-lobby-sounds "Activer les sons de la salle d'attente" - :enable-game-sounds "Activer les sons de la partie" - :volume "Volume" - :layout-options "Options de disposition" - :stacked-cards "Empiler les cartes (activé par défaut)" - :runner-layout "Disposition du Runner du point de vue de la Corpo" - :runner-classic "Disposition jnet classique (de haut en bas : Programmes, Matériels, Ressources)" - :runner-reverse "Disposition inversée (de haut en bas : Ressources, Matériels, Programmes)" - :background "Arrière-plan de la zone de jeu" - :card-backs "Dos des cartes" - :game-stats "Statistiques des parties gagnées/perdues" - :deck-stats "Statistiques de deck" - :always "Toujours" - :comp-only "Parties de tournoi uniquement" - :none "Jamais" - :alt-art "Illustrations alternatives" - :show-alt "Afficher les illustrations de carte alternatives" - :high-res "Activer les images des cartes en haute résolution" - :card-images "Images des cartes" - :set-all "Set all cards to" - :set "Set" - :reset "Reset All to Official Art" - :blocked "Utilisateur·trice·s bloqué·e·s" - :user-name "Nom d'utilisateur·trice" - :block "Bloquer l'utilisateur·trice" - :update-profile "Mettre à jour le profil" - :nsg "NSG" - :ffg "FFG" - :api-keys "Clés API" - :delete-api-key "Effacer" - :create-api-key "Créer une clé API"} - :stats {:game-stats "Statistiques de jeu" - :corp-stats "Statistiques Corpo" - :runner-stats "Statistiques Runner" - :clear-stats "Effacer les statistiques" - :no-log "Pas de journal disponible" - :view-log "Voir le journal" - :winner "Vainqueur" - :no-games "Pas de parties" - :all-games "Montrer toutes les parties" - :shared-games "Montrer seulement les parties partagées" - :started "Commencées" - :ended "Terminée" - :completed "Terminées" - :not-completed "Inachevées" - :won "Gagnées" - :lost "Perdues" - :turn-count (fn [[cnt]] (str cnt " tour" (when (not= cnt 1) "s"))) - :lobby "Hall" - :format "Format" - :win-method "Type de victoire" - :view-games "Retourner aux statistiques" - :share "Partager le replay" - :launch "Démarrer le replay" - :download "Télécharger le replay" - :unavailable "Pas de replay disponible" - :filtered "(filtres activés)" - :log-count (fn [[cnt]] (str cnt " " (if (<= cnt 1) "Journal" "Journaux"))) - :clicks-gained "Clicks gagnés" - :credits-gained "Crédits gagnés" - :credits-spent "Crédits dépensés" - :credits-click "Crédits par clic" - :cards-drawn "Cartes piochées" - :cards-click "Cartes piochées par clic" - :damage-done "Dégâts infligés" - :cards-rezzed "Cartes activées" - :tags-gained "Tags reçus" - :runs-made "Piratages effectués" - :cards-accessed "Cartes accédées"} - :log {:game-log "Journal de partie" - :annotating "Annoter" - :shared "Annotations partagées" - :remote-annotations-fail "Impossible d'obtenir les annotations distantes"} - :annotations {:turn-placeholder "Notes pour ce tour" - :click-placeholder "Notes pour ce clic" - :available-annotations "Annotations disponibles" - :no-published-annotations "Pas d'annotations publiées" - :publish "Publier" - :import-local "Importer un fichier d'annotations locales" - :load-local "Charger" - :save-local "Sauvegarder" - :clear "Effacer les annotations locales"} - :game {:keep "Garder" - :mulligan "Mulligan" - :close "Fermer" - :start "Démarrer la partie" - :remove-tag "Retirer des tags" - :run "Lancer un piratage" - :purge "Nettoyer les pions virus" - :trash-resource "Effacer une ressource" - :draw "Piocher une carte" - :gain-credit "Gagner un crédit" - :game-start "Démarrer la partie" - :start-turn "Commencer le tour" - :end-turn "Terminer le tour" - :mandatory-draw "Pioche obligatoire" - :take-clicks "Prendre des clics" - :hq "QG" - :grip "Main" - :rfg "Retiré du jeu" - :play-area "Zone de jeu" - :current "Actuel" - :scored-area "Zone de score" - :archives "Archives" - :max-hand "Taille de main maximale" - :brain-damage "Dégât sévère" - :tag-count (fn [[base additional total]] (str base (when (pos? additional) (str " + " additional)) " Tag" (if (not= total 1) "s" ""))) - :agenda-count (fn [[agenda-point]] (str agenda-point (if (= 1 agenda-point) " Point de projet" " Points de projet"))) - :link-strength "Force d'évasion" - :credit-count (fn [[credit run-credit]] (str credit " Crédit" (if (not= credit 1) "s" "") (when (pos? run-credit) (str " (" run-credit " pour le piratage)")))) - :click-count (fn [[click]] (str click " Clic" (if (not= click 1) "s" ""))) - :bad-pub-count (fn [[base additional]] (str base (when (pos? additional) (str " + " additional)) " Mauvaise Presse")) - :mu-count (fn [[unused available]] (str unused " de " available " UM inutilisée(s)")) - :special-mu-count (fn [[unused available mu-type]] (str unused " de " available " " mu-type " UM inutilisée(s)")) - :indicate-action "Indiquer une action" - :spec-count (fn [[c]] (str c " Spectateur" (when (> c 1) "s"))) - :spec-view "Vue Spectateur" - :runner-view "Vue Runner" - :corp-view "Vue Corpo" - :leave-replay "Quitter le replay" - :leave "Quitter la partie" - :unmute "Réactiver le son des spectateurs" - :mute "Désactiver le son des spectateurs" - :concede "Abandonner" - :inactivity "Partie fermée pour cause d'inactivé" - :server "Serveur" - :unimplemented "Non implementé" - :abilities "Capacités" - :let-subs-fire "Laisser la Corpo déclencher les routines non neutralisées" - :subs "Routines" - :actions "Actions" - :fire-unbroken "Déclencher les routines non neutralisées" - :stack "Pile" - :r&d "R&D" - :shuffle "Mélanger" - :show "Montrer" - :close-shuffle "Fermer et Mélanger" - :heap "Tas" - :card-count (fn [[size]] (str size " carte" (when (not= 1 size) "s") ".")) - :face-down-count (fn [[total face-up]] (str total " cartes, " (- total face-up) " face cachée.")) - :up-down-count (fn [[total face-up]] (str face-up "↑ " (- total face-up) "↓")) - :initiation "Initiation" - :approach-ice "Approcher la glace" - :encounter-ice "Rencontrer la glace" - :movement "Mouvement" - :breach-server "Fracturer le serveur" - :success "Piratage réussi" - :run-ends "Le piratage est terminé" - :no-current-run "Pas de piratage en cours" - :current-phase "Phase en cours" - :unknown-phase "Phase inconnue" - :rez "Activer" - :no-further "Pas d'autre action" - :continue "Continuer" - :continue-to "Continuer vers : " - :stop-auto-pass "Désactiver le passage automatique" - :auto-pass "Activer le passage automatique" - :jack-out "Débrancher" - :trace "Traque" - :credits "Crédits" - :card "Carte" - :time-taken (fn [[t]] (str "Temps écoulé: " t " minutes")) - :win-decked (fn [[turn]] (str "gagne par épuisement du deck Corpo au tour " turn)) - :win-flatlined (fn [[turn]] (str "gagne par mort clinique au tour " turn)) - :win-conceded (fn [[turn]] (str "gagne par abandon au tour " turn)) - :win-claimed (fn [[turn]] (str "gagne par réclamation au tour " turn)) - :win-points (fn [[turn]] (str "gagne aux points de projet au tour " turn)) - :win-other (fn [[turn reason]] (str "gagne par " reason " au tour " turn))}}) diff --git a/src/cljc/i18n/ja.cljc b/src/cljc/i18n/ja.cljc deleted file mode 100644 index ad0c4ff687..0000000000 --- a/src/cljc/i18n/ja.cljc +++ /dev/null @@ -1,399 +0,0 @@ -(ns i18n.ja) - -(def translations - {:missing ":ja missing text" - :side {:corp "コーポ" - :runner "ランナー" - :any-side "Any Side" - :all "全部"} - :faction {:all "全部" - :any-faction "Any Faction" - :anarch "アナーク" - :criminal "クリミナル" - :shaper "シェイパー" - :adam "アダム" - :apex "エイペックス" - :sunny-lebeau "サニー・ルボー" - :jinteki "ジンテキ" - :haas-bioroid "ハース=バイオロイド" - :nbn "NBN" - :weyland-consortium "ウェイランド・コンソーシアム" - :neutral "中立"} - :format {:all "全部" - :any-format "Any Format" - :standard "スタンダード" - :eternal "エターナル" - :core-experience "Core Experience" - :snapshot "スナップショット" - :snapshot-plus "Snapshot Plus" - :socr "SOCR" - :sunset "Sunset" - :neo "Neo" - :classic "Classic" - :casual "Casual" - :system-gateway "システムゲートウェイ" - :startup "スタートアップ"} - :card-type {:all "全部" - :identity "ID" - :agenda "計画書" - :asset "資材" - :upgrade "強化" - :operation "任務" - :ice "アイス" - :event "イベント" - :hardware "ハードウェア" - :resource "リソース" - :program "プログラム"} - :pronouns {:none "Unspecified" - :any "Any" - :myodb "Prefer not to say" - :blank "[blank]" - :they "They/them" - :she "She/her" - :shethey "She/they" - :he "He/him" - :hethey "He/they" - :it "It" - :ne "Ne/nem" - :ve "Ve/ver" - :ey "Ey/em" - :zehir "Ze/hir" - :zezir "Ze/zir" - :xe "Xe/xem"} - :chat {:title "Play Netrunner in your browser" - :channels "Channels" - :send "Send" - :placeholder "Say something..." - :delete "Delete Message" - :delete-all "Delete All Messages From User" - :block "Block User" - :cancel "Cancel"} - :nav {:chat "チャット" - :cards "カード" - :deck-builder "デッキビルダー" - :play "対戦" - :help "ヘルプ" - :settings "設定" - :stats "統計" - :about "このサイトについて" - :tournaments "大会" - :admin "Admin" - :users "Users" - :features "Features" - :game-count (fn [[cnt]] (str "ルーム数 " cnt))} - :menu {:settings :ja.nav/settings - :logout "ジャックアウト" - :admin :ja.nav/admin - :moderator "Moderator" - :donor "Donor"} - :card-browser {:search-hint "カード名検索" - :sort "並び順" - :format "フォーマット" - :set "カードセット" - :side "プレイヤーサイド" - :faction "派閥" - :type "カードタイプ" - :clear "クリア" - :select-art "Select Art" - :selected-art "Selected Alt Art" - :update-success "Updated Art" - :update-failure "Failed to Update Art" - :memory "MU" - :cost "コスト" - :trash-cost "トラッシュコスト" - :strength "強度" - :advancement "アドバンス要求" - :agenda-points "計画ポイント" - :min-deck "最小デッキ枚数" - :inf-limit "影響値上限" - :influence "影響値" - :sort-by {:faction "派閥" - :name "カード名" - :type "タイプ" - :influence "影響値" - :cost "コスト" - :set-number "セット番号"}} - :deck-builder {:loading-msg "デッキ一覧を読み込み中……" - :new-corp "新規コーポ" - :new-runner "新規ランナー" - :import-button "デッキのインポート" - :reset "リセット" - :import-title "公開済みNetrunnerDB Deck ID or URL" - :import "インポート" - :cancel "キャンセル" - :import-placeholder "NetrunnerDB ID" - :deck-count (fn [[cnt]] (str "デッキ数 " cnt)) - :filtered "(絞り込み)" - :save "保存" - :confirm-delete "削除の実行" - :edit "編集" - :delete "削除" - :copy "コピー" - :deck-copy-suffix "コピー" - :clear-stats "統計を削除" - :create-game "対戦の開始" - :deck-name "デッキ名" - :format "フォーマット" - :identity "ID" - :deck-notes "メモ" - :decklist "カードリスト" - :decklist-inst "({枚数}[半角スペース]{カード名(英語)}で入力)" - :notes "メモ" - :add-to-deck "追加" - :add-cards "カードの追加" - :card-name "カード名" - :no-decks "デッキ未登録" - :cards "枚" - :min "下限" - :max "上限" - :influence "影響値" - :agenda-points "計画ポイント" - :deck-points "デッキポイント" - :hash "大会ハッシュ" - :why "Why?" - :legal "適正" - :illegal "違反" - :games "ゲーム" - :completed "完了" - :won "勝利" - :lost "敗北"} - :lobby {:no-games "No games" - :tournament "Tournament" - :competitive "Competitive" - :casual "Casual" - :new-game "ルーム作成" - :reload "リロード" - :load-replay "リプレイ読込" - :start-replay "再生" - :save-replay "リプレイの保存" - :replay-link-error "Replay link invalid." - :replay-invalid-file "Select a valid replay file." - :create "作成" - :cancel "キャンセル" - :title "ルーム名" - :side "サイド" - :format "フォーマット" - :options "設定" - :spectators "観戦の許可" - :hidden "非公開情報を観戦者に公開" - :password-protected "パスワードを設定する" - :password "パスワード" - :start "開始" - :leave "退出" - :swap "サイド変更" - :waiting "デッキ選択待ち" - :players "プレイヤー" - :deck-selected "デッキ選択完了" - :select-deck "デッキ選択" - :chat "チャット" - :select-title "デッキを選択" - :spectator-count (fn [[cnt]] (str "観戦中 " cnt "人")) - :closed-msg "操作が行われていないルームを閉じました。" - :title-error "ルーム名を修正してください。" - :password-error "パスワードを修正してください。" - :too-little-data "Too little data" - :completion-rate "対戦完了率" - :watch "観戦" - :join "入室" - :rejoin "再入室" - :as-corp "コーポとして" - :as-runner "ランナーとして" - :private "非公開" - :reset "Reset Game Name" - :delete "Delete Game" - :password-for "パスワード" - :invalid-password "不正なパスワード" - :not-allowed "Not allowed" - :aborted "Connection aborted" - :api-access "Allow API access to game information" - :api-requires-key "(Requires an API Key in Settings)" - :game-count (fn [[cnt]] (str "ルーム数 " cnt)) - :filtered "(絞り込み)"} - :settings {:invalid-password "Invalid login or password" - :invalid-email "No account with that email address exists" - :updated "Profile updated - Please refresh your browser" - :updating "Updating profile..." - :get-log-width "Get current log width" - :get-log-top "Get current log top" - :email-title "Change email address" - :current-email "Current email" - :desired-email "Desired email" - :email-placeholder "Email address" - :enter-valid "Please enter a valid email address" - :update "Update" - :cancel "Cancel" - :email "Email" - :change-email "Change email" - :avatar "Avatar" - :change-avatar "Change on gravatar.com" - :pronouns "Pronouns" - :language "Language" - :sounds "Sounds" - :enable-lobby-sounds "Enable lobby sounds" - :enable-game-sounds "Enable game sounds" - :volume "Volume" - :layout-options "Layout options" - :stacked-cards "Card stacking (on by default)" - :runner-layout "Runner layout from Corp perspective" - :runner-classic "Runner rig layout is classic jnet (Top to bottom: Programs, Hardware, Resources)" - :runner-reverse "Runner rig layout is reversed (Top to bottom: Resources, Hardware, Programs)" - :background "Game board background" - :card-backs "Card backs" - :game-stats "Game Win/Lose statistics" - :deck-stats "Deck statistics" - :always "Always" - :comp-only "Competitive Lobby Only" - :none "None" - :alt-art "Alt arts" - :show-alt "Show alternate card arts" - :high-res "Enable high-resolution card images" - :card-images "Card images" - :set-all "Set all cards to" - :set "Set" - :reset "Reset All to Official Art" - :blocked "Blocked users" - :user-name "User name" - :block "Block user" - :update-profile "Update Profile" - :nsg "NSG" - :ffg "FFG" - :api-keys "API Keys" - :delete-api-key "Delete" - :create-api-key "Create API Key"} - :stats {:game-stats "対戦統計" - :corp-stats "コーポ統計" - :runner-stats "ランナー統計" - :clear-stats "統計を削除" - :no-log "No log available" - :view-log "ログを見る" - :winner "勝者" - :no-games "No games" - :all-games "全てのログを表示" - :shared-games "シェアログのみ表示" - :started "開始" - :ended "終了" - :completed "完了" - :not-completed "未完了" - :won "勝利" - :lost "敗北" - :turn-count (fn [[cnt]] (str "ターン数 " cnt)) - :lobby "ロビー" - :format "フォーマット" - :win-method "勝利方法" - :view-games "統計画面に戻る" - :share "Share Replay" - :launch "Launch Replay" - :download "Download Replay" - :unavailable "Replay unavailable" - :filtered "(絞り込み)" - :log-count (fn [[cnt]] (str "ログ数 " cnt)) - :clicks-gained "得たクリック" - :credits-gained "得たクレジット" - :credits-spent "消費したクレジット" - :credits-click "クリックで得たクレジット" - :cards-drawn "ドロー" - :cards-click "クリックでしたドロー" - :damage-done "与えたダメージ" - :cards-rezzed "レゾしたカード" - :tags-gained "受けたタグ" - :runs-made "行ったラン" - :cards-accessed "アクセスしたカード"} - :log {:game-log "Game Log" - :annotating "Annotating" - :shared "Shared Annotations" - :remote-annotations-fail "Could not get remote annotations."} - :annotations {:turn-placeholder "Notes for this turn" - :click-placeholder "Notes for this click" - :available-annotations "Available annotations" - :no-published-annotations "No published annotations." - :publish "Publish" - :import-local "Import local annotation file" - :load-local "Load" - :save-local "Save" - :clear "Clear local annotations"} - :game {:keep "キープ" - :mulligan "マリガン" - :close "閉じる" - :start "ゲーム開始" - :remove-tag "タグを除去" - :run "ラン" - :purge "ウィルスカウンター破棄" - :trash-resource "リソースをトラッシュ" - :draw "ドロー" - :gain-credit "クレジットを得る" - :game-start "ゲーム開始" - :start-turn "ターンの開始" - :end-turn "ターンの終了" - :mandatory-draw "強制ドロー" - :take-clicks "クリックを受け取る" - :hq "HQ" - :grip "グリップ" - :rfg "除外" - :play-area "プレイエリア" - :current "現状" - :scored-area "得点エリア" - :archives "アーカイブ" - :max-hand "手札上限" - :brain-damage "コアダメージ" - :tag-count (fn [[base additional total]] (str base (when (pos? additional) (str " + " additional)) " タグ")) - :agenda-count (fn [[agenda-point]] (str agenda-point " 計画点")) - :link-strength "リンク強度" - :credit-count (fn [[credit run-credit]] (str credit " クレジット") (when (pos? run-credit) (str " (ランの間のみ " run-credit ")"))) - :click-count (fn [[click]] (str click " クリック")) - :bad-pub-count (fn [[base additional]] (str base (when (pos? additional) (str "+" additional)) " 悪名")) - :mu-count (fn [[unused available]] (str unused "/" available " 未使用MU")) - :special-mu-count (fn [[unused available mu-type]] (str unused "/" available " 未使用 " mu-type " MU")) - :indicate-action "アクションします!" - :spec-count (fn [[c]] (str "観戦中 " c "人")) - :spec-view "観戦者視点" - :runner-view "ランナー視点" - :corp-view "コーポ視点" - :leave-replay "リプレイから退出" - :leave "ルームを退出" - :unmute "Unmute spectators" - :mute "Mute spectators" - :concede "降参する" - :inactivity "操作が行われていないルームを閉じました。" - :server "サーバー" - :unimplemented "未実装" - :abilities "能力" - :let-subs-fire "未ブレイクサブルーチン解決を許可" - :subs "サブルーチン" - :actions "アクション" - :fire-unbroken "未ブレイクサブルーチンを解決する" - :stack "スタック" - :r&d "R&D" - :shuffle "シャッフルする" - :show "中を確認する" - :close-shuffle "閉じてシャフルする" - :heap "ヒープ" - :card-count (fn [[size]] (str size " 枚")) - :face-down-count (fn [[total face-up]] (str total " 枚(裏向き " (- total face-up) " 枚)")) - :up-down-count (fn [[total face-up]] (str face-up "↑ " (- total face-up) "↓")) - :initiation "ラン開始" - :approach-ice "アイスにアプローチ" - :encounter-ice "エンカウント中" - :movement "移動" - :breach-server "サーバーに侵入" - :success "ランの成功" - :run-ends "ラン終了" - :no-current-run "ラン以外" - :current-phase "現在のフェーズ" - :unknown-phase "不明フェーズ" - :rez "レゾ" - :no-further "これ以上アクションしない" - :continue "次へ進む" - :continue-to "次へ:" - :stop-auto-pass "自動通過処理を停止" - :auto-pass "自動通過処理" - :jack-out "ジャックアウト" - :trace "トレース" - :credits "クレジット" - :card "カード" - :time-taken (fn [[t]] (str "経過した時間: " t "分")) - :win-decked (fn [[turn]] (str "コーポのデッキ切れによる勝利 " turn " ターン")) - :win-flatlined (fn [[turn]] (str "フラットラインによる勝利 " turn " ターン")) - :win-conceded (fn [[turn]] (str "降参による勝利 " turn " ターン")) - :win-claimed (fn [[turn]] (str "wins by claim on turn " turn)) - :win-points (fn [[turn]] (str "計画ポイントによる勝利 " turn " ターン")) - :win-other (fn [[turn reason]] (str "wins by " reason " on turn " turn))}}) diff --git a/src/cljc/i18n/ko.cljc b/src/cljc/i18n/ko.cljc deleted file mode 100644 index 7a890b445a..0000000000 --- a/src/cljc/i18n/ko.cljc +++ /dev/null @@ -1,371 +0,0 @@ -(ns i18n.ko) - -(def translations - {:missing ":ko 텍스트를 찾을 수 없음" - :side {:corp "기업" - :runner "러너" - :any-side "모든 사이드" - :all "모두"} - :faction {:all "모두" - :any-faction "모든 세력" - :anarch "아나크" - :criminal "크리미널" - :shaper "쉐이퍼" - :adam "아담" - :apex "에이펙스" - :sunny-lebeau "서니 르뷰" - :jinteki "진테키" - :haas-bioroid "하스-바이오로이드" - :nbn "NBN" - :weyland-consortium "웨이랜드 컨소시엄" - :neutral "중립"} - :format {:all "모두" - :any-format "모든 포맷" - :standard "스탠다드" - :eternal "이터널" - :core-experience "코어 익스피리언스" - :snapshot "스냅샷" - :snapshot-plus "스냅샷 플러스" - :socr "SOCR" - :sunset "Sunset" - :neo "Neo" - :classic "클래식" - :casual "캐주얼"} - :card-type {:all "모두" - :identity "ID" - :agenda "아젠다" - :asset "자산" - :upgrade "개선" - :operation "운영" - :ice "아이스" - :event "이벤트" - :hardware "하드웨어" - :resource "리소스" - :program "프로그램"} - :pronouns {:none "미정" - :any "아무렇게나" - :myodb "부르지 않는걸 선호함" - :blank "[빈 칸]" - :they "They/them" - :she "She/her" - :shethey "She/they" - :he "He/him" - :hethey "He/they" - :it "It" - :ne "Ne/nem" - :ve "Ve/ver" - :ey "Ey/em" - :zehir "Ze/hir" - :zezir "Ze/zir" - :xe "Xe/xem"} - :chat {:title "브라우저로 즐기는 안드로이드: 넷러너" - :channels "채널" - :send "보내기" - :placeholder "대화를 나누어 보세요..." - :delete "메시지 삭제" - :delete-all "모든 사용자로부터 받은 메시지 삭제" - :block "사용자 차단" - :cancel "취소"} - :nav {:chat "채팅" - :cards "카드" - :deck-builder "덱 빌더" - :play "플레이" - :help "도움말" - :settings "설정" - :stats "기록" - :about "진테키넷" - :tournaments "대회" - :admin "운영자" - :users "사용자" - :features "기능" - :game-count (fn [[cnt]] (str cnt " 게임"))} - :menu {:settings "설정" - :logout "잭 아웃" - :admin "운영자" - :moderator "중재자"} - :card-browser {:search-hint "카드 찾기" - :sort "정렬 기준" - :format "포맷" - :set "세트" - :side "사이드" - :faction "세력" - :type "타입" - :clear "지우기" - :select-art "아트 선택" - :selected-art "대체 아트가 선택됨" - :update-success "아트가 갱신됨" - :update-failure "아트 갱신 실패" - :memory "메모리" - :cost "비용" - :trash-cost "폐기 비용" - :strength "힘" - :advancement "필요 발전 정도" - :agenda-points "아젠다 점수" - :min-deck "최소 덱 사이즈" - :inf-limit "영향력 제한" - :influence "영향력" - :sort-by {:faction "세력" - :name "이름" - :type "타입" - :influence "영향력" - :cost "비용" - :set-number "세트 번호"}} - :deck-builder {:loading-msg "덱 컬렉션을 불러오는 중" - :new-corp "새로운 기업 덱" - :new-runner "새로운 러너 덱" - :import-button "덱 가져오기" - :reset "리셋" - :import-title "NetrunnerDB 공개 덱 ID 혹은 URL 입력" - :import "가져오기" - :cancel "취소" - :import-placeholder "NetrunnerDB ID" - :deck-count (fn [[cnt]] (str cnt " 덱")) - :filtered "(필터됨)" - :save "저장" - :confirm-delete "삭제 확인" - :edit "편집" - :delete "삭제" - :clear-stats "기록 초기화" - :create-game "게임 생성" - :deck-name "덱 이름" - :format "포맷" - :identity "ID" - :deck-notes "덱 메모" - :decklist "덱 리스트" - :decklist-inst "(덱 리스트를 입력하거나 붙여 넣으십시오)" - :notes "메모" - :add-to-deck "덱에 삽입" - :add-cards "카드 삽입" - :card-name "카드 이름" - :no-decks "덱 없음" - :cards "카드" - :min "최소" - :max "최대" - :influence "영향력" - :agenda-points "아젠다 점수" - :hash "토너먼트 해쉬값" - :why "확인하십시오" - :legal "사용 가능" - :illegal "사용 불가" - :games "게임" - :completed "완료됨" - :won "승리" - :lost "패배"} - :lobby {:no-games "게임 없음" - :tournament "토너먼트" - :competitive "경쟁" - :casual "캐주얼" - :new-game "새 게임" - :reload "리스트 갱신" - :load-replay "리플레이 불러오기" - :start-replay "리플레이 재생" - :save-replay "리플레이 저장" - :replay-link-error "리플레이 링크가 유효하지 않습니다." - :replay-invalid-file "유효한 리플레이 파일을 선택하십시오." - :create "생성" - :cancel "취소" - :title "방 제목" - :side "사이드" - :format "포맷" - :options "옵션" - :spectators "관전 허용" - :hidden "관전자가 플레이어의 숨겨진 정보를 볼 수 있게 하기" - :password-protected "암호로 보호" - :password "암호" - :start "시작" - :leave "떠나기" - :swap "사이드 바꾸기" - :waiting "플레이어가 덱을 고르고 있습니다" - :players "플레이어" - :deck-selected "덱 선택됨" - :select-deck "덱 선택" - :chat "채팅" - :select-title "덱을 선택하십시오" - :spectator-count (fn [[cnt]] (str cnt " 관전자")) - :closed-msg "활동이 없어 게임 로비가 닫혔습니다." - :title-error "게임 제목을 입력해주십시오." - :password-error "암호를 입력해주십시오." - :too-little-data "데이터가 너무 적음" - :completion-rate "게임 완료율" - :watch "관전" - :join "참여" - :rejoin "재참여" - :private "비공개" - :reset "게임 제목 리셋" - :delete "게임 삭제" - :password-for "암호 입력" - :invalid-password "유효하지 않은 암호" - :not-allowed "허용되지 않음" - :game-count (fn [[cnt]] (str cnt " 게임")) - :aborted "연결에 실패함"} - :settings {:invalid-password "유효하지 않은 로그인 또는 암호" - :invalid-email "이 이메일 주소로 등록된 계정이 없습니다" - :updated "프로필 갱신됨 - 브라우저를 새로고침 하십시오" - :updating "프로필 갱신중..." - :get-log-width "현재 로그 너비 입력" - :get-log-top "현재 로그 높이 입력" - :email-title "이메일 주소 변경" - :current-email "현재 이메일" - :desired-email "사용할 이메일" - :email-placeholder "이메일 주소" - :enter-valid "유효한 이메일을 입력하십시오" - :update "업데이트" - :cancel "취소" - :email "이메일" - :change-email "이메일 변경" - :avatar "아바타" - :change-avatar "gravatar.com에서 변경하기" - :pronouns "인칭 대명사" - :language "언어" - :sounds "음향" - :enable-lobby-sounds "로비 음향 활성화" - :enable-game-sounds "게임 음향 활성화" - :volume "볼륨" - :layout-options "레이아웃 옵션" - :stacked-cards "서버 스태킹이 기본으로 설정됨" - :runner-layout "기업 위치 러너 레이아웃" - :runner-classic "클래식 진테키넷 러너 리그 (위에서부터: 프로그램, 하드웨어, 리소스)" - :runner-reverse "반전된 러너 리그 (위에서부터: 리소스, 하드웨어, 프로그램)" - :background "게임판 배경" - :card-backs "카드 뒷면" - :game-stats "게임 승/패 기록" - :deck-stats "덱 기록" - :always "항상 기록" - :comp-only "경쟁 로비에서만" - :none "기록 안함" - :alt-art "대체 아트" - :show-alt "대체 아트 보기" - :high-res "고해상도 카드 이미지 활성화" - :card-images "카드 이미지" - :set-all "모든 카드를 다음과 같이 설정" - :set "설정" - :reset "공식 아트로 되돌리기" - :blocked "차단한 사용자" - :user-name "사용자 이름" - :block "사용자 차단" - :update-profile "프로필 갱신" - :nsg "NSG" - :ffg "FFG"} - :stats {:game-stats "게임 기록" - :corp-stats "기업 기록" - :runner-stats "러너 기록" - :clear-stats "기록 초기화" - :no-log "사용 가능한 로그가 없습니다" - :view-log "로그 보기" - :winner "승자" - :no-games "게임 없음" - :all-games "모든 게임 보기" - :shared-games "공유된 게임만 보기" - :started "시작됨" - :ended "종료됨" - :completed "완료됨" - :not-completed "완료되지 않음" - :won "승리" - :lost "패배" - :turn-count (fn [[cnt]] (str cnt " 차례")) - :lobby "로비" - :format "포맷" - :win-method "승리 방법" - :view-games "기록 화면으로 돌아가기" - :share "리플레이 공유" - :launch "리플레이 실행" - :download "리플레이 다운로드" - :unavailable "리플레이를 사용할 수 없음" - :filtered "(필터됨)" - :log-count (fn [[cnt]] (str cnt " 로그")) - :clicks-gained "얻은 클릭" - :credits-gained "얻은 크레딧" - :credits-spent "사용한 크레딧" - :credits-click "클릭으로 얻은 크레딧" - :cards-drawn "뽑은 카드" - :cards-click "클릭으로 뽑은 카드" - :damage-done "입힌 피해" - :cards-rezzed "레즈된 카드" - :tags-gained "얻은 태그" - :runs-made "런 시도" - :cards-accessed "액세스한 카드"} - :log {:game-log "게임 로그" - :annotating "주석" - :shared "공유된 주석" - :remote-annotations-fail "원격 주석을 가져올 수 없습니다."} - :annotations {:turn-placeholder "이 차례에 대한 메모" - :click-placeholder "이 클릭에 대한 메모" - :available-annotations "사용가능한 주석" - :no-published-annotations "발행된 주석이 없음" - :publish "발행" - :import-local "로컬 주석 파일 가져오기" - :load-local "불러오기" - :save-local "저장" - :clear "로컬 주석 지우기"} - :game {:keep "그대로" - :mulligan "멀리건" - :close "닫기" - :start "게임 시작" - :remove-tag "태그 제거" - :run "런" - :purge "퇴치" - :trash-resource "리소스 폐기" - :draw "카드 뽑기" - :gain-credit "크레딧 얻기" - :game-start "게임 시작" - :start-turn "차례 시작" - :end-turn "차례 종료" - :mandatory-draw "강제 카드 뽑기" - :take-clicks "클릭 가져가기" - :hq "본부(HQ)" - :grip "그립" - :rfg "게임에서 제거됨" - :play-area "발동 영역" - :current "동향" - :scored-area "득점 영역" - :archives "기록보관소" - :max-hand "최대 핸드 크기" - :brain-damage "두뇌 피해" - :tag-count (fn [[base additional total]] (str base (when (pos? additional) (str " + " additional)) " 태그")) - :agenda-count (fn [[agenda-point]] (str agenda-point " 아젠다 점수")) - :link-strength "링크 강도" - :credit-count (fn [[credit run-credit]] (str credit " 크레딧" (when (pos? run-credit) (str " (런 동안 " run-credit ")")))) - :click-count (fn [[click]] (str click " 클릭")) - :bad-pub-count (fn [[base additional]] (str base (when (pos? additional) (str " + " additional)) " 악평")) - :mu-count (fn [[unused available]] (str available " 메모리 유닛 중 " unused " 미사용")) - :indicate-action "행동 선언" - :spec-count (fn [[cnt]] (str cnt " 관전자")) - :spec-view "관전자 보기" - :runner-view "러너 보기" - :corp-view "기업 보기" - :leave-replay "리플레이 떠나기" - :leave "게임 떠나기" - :unmute "관전자 무시 해제" - :mute "관전자 무시" - :concede "항복하기" - :inactivity "활동이 없어 게임이 닫혔습니다" - :server "서버" - :unimplemented "미구현" - :abilities "능력" - :let-subs-fire "모든 서브루틴 격발" - :subs "서브루틴" - :actions "행동" - :fire-unbroken "깨지지 않은 서브루틴 격발" - :stack "스택" - :r&d "연구개발부(R&D)" - :shuffle "섞기" - :show "보기" - :close-shuffle "닫고 섞는다" - :heap "힙" - :card-count (fn [[size]] (str size " 카드")) - :face-down-count (fn [[total face-up]] (str total " cards, " (- total face-up) " face-down.")) - :up-down-count (fn [[total face-up]] (str face-up "↑ " (- total face-up) "↓")) - :initiation "시도" - :approach-ice "아이스 접근" - :no-current-run "현재 런 없음" - :current-phase "현재 단계" - :unknown-phase "미상 단계" - :rez "레즈하기" - :no-further "더 이상 행동 없음" - :continue-to "계속하기" - :stop-auto-pass "자동-통과 우선 중지" - :auto-pass "자동-통과 우선" - :jack-out "잭 아웃" - :trace "추적" - :credits "크레딧" - :card "카드"}}) diff --git a/src/cljc/i18n/la_pig.cljc b/src/cljc/i18n/la_pig.cljc deleted file mode 100644 index 17217a4a76..0000000000 --- a/src/cljc/i18n/la_pig.cljc +++ /dev/null @@ -1,378 +0,0 @@ -(ns i18n.la-pig) - -(def translations - {:missing ":la-pig missing text" - :side {:corp "Orpcay" - :runner "Unnerray" - :any-side "Anyay Idesay" - :all "Allyay"} - :faction {:all "Allyay" - :any-faction "Anyay Actionfay" - :anarch "Anarchyay" - :criminal "Iminalcrimay" - :shaper "Apershay" - :adam "Adamyay" - :apex "Apexyay" - :sunny-lebeau "Unnsay Ebeaulay" - :jinteki "Intekijay" - :haas-bioroid "Aashay-Ioroidbay" - :nbn "NBNYAY" - :weyland-consortium "Eylandway Onsortiumcay" - :neutral "Eutralnay"} - :format {:all "Allyay" - :any-format "Anyay Ormatfay" - :standard "Andardstay" - :eternal "Eternalyay" - :core-experience "Orecay Experienceyay" - :snapshot "Apshotsnay" - :snapshot-plus "Apshotsnay Usplay" - :socr "SOCRYAY" - :sunset "Sunset" - :neo "Neoyay" - :classic "Assicclay" - :casual "Asualcay" - :system-gateway "Emsystay Atewaygay" - :startup "Artupstay"} - :card-type {:all "Allyay" - :identity "Identityay" - :agenda "Agendayay" - :asset "Assetyay" - :upgrade "Upgradeyay" - :operation "Operationyay" - :ice "Iceyay" - :event "Eventyay" - :hardware "Ardwarehay" - :resource "Esourceray" - :program "Ogrampray"} - :pronouns {:none "Unspecifiedyay" - :any "Anyay" - :myodb "Eferpray otnay otay aysay" - :blank "[ankblay]" - :they "Eythay/emthay" - :she "Eshay/erhay" - :shethey "Eshay/eythay" - :he "Ehay/imhay" - :hethey "Ehay/eythay" - :it "Ityay" - :ne "Enay/emnay" - :ve "Evay/ervay" - :ey "Eyay/emay" - :zehir "Ezay/irhay" - :zezir "Ezay/irzay" - :xe "Exay/emxay"} - :chat {:title "Ayplay Etrunnernay inyay ouryay owserbray" - :channels "Annelschay" - :send "Endsay" - :placeholder "Aysay omethingsay..." - :delete "Eleteday Essagemay" - :delete-all "Eleteday Allyay Essagesmay Omfray Useryay" - :block "Ockblay Useryay" - :cancel "Ancelcay"} - :nav {:chat "Atchay" - :cards "Ardscay" - :deck-builder "Eckday Uilderbay" - :play "Ayplay" - :help "Elphay" - :settings "Ettingssay" - :stats "Atsstay" - :about "Aboutyay" - :tournaments "Ournamentstay" - :admin "Adminyay" - :users "Usersyay" - :features "Eaturesfay" - :game-count (fn [[cnt]] (str cnt (if (= 1 cnt) " Amegay" " Amesgay")))} - :menu {:settings :la-pig.nav/settings - :logout "Ackjay outyay" - :admin :la-pig.nav/admin - :moderator "Oderatormay" - :donor "Onorday"} - :card-browser {:search-hint "Earchsay ardscay" - :sort "Ortsay ybay" - :format "Ormatfay" - :set "Etsay" - :side "Idesay" - :faction "Actionfay" - :type "Etypay" - :clear "Earclay" - :select-art "Electsay Artyay" - :selected-art "Electedsay Altyay Artyay" - :memory "Emorymay" - :cost "Ostcay" - :trash-cost "Ashtray ostcay" - :strength "Engthstr" - :advancement "Advancementyay equirementray" - :agenda-points "Agendayay ointspay" - :min-deck "Inimummay eckday izesay" - :inf-limit "Influenceyay Imitlay" - :influence "Influenceyay" - :update-success "Updatedyay Artyay" - :update-failure "Ailedfay otay Updateyay Artyay" - :sort-by {:faction "Actionfay" - :name "Amenay" - :type "Etypay" - :influence "Influenceyay" - :cost "Ostcay" - :set-number "Etsay umbernay"}} - :deck-builder {:loading-msg "Oadinglay eckday ollectioncay..." - :new-corp "Ewnay Orpcay eckday" - :new-runner "Ewnay Unnerray eckday" - :import-button "Importyay Eckday" - :reset "Esetray" - :import-title "Enteryay ayay ublicpay bnrday eckday idyay oryay urlyay" - :import "Importyay" - :cancel "Ancelcay" - :import-placeholder "Bnrday idyay" - :deck-count (fn [[cnt]] (str cnt (if (= 1 cnt) " Eckday" " Ecksday"))) - :filtered "(ilteredfay)" - :save "Avesay" - :confirm-delete "Onfirmcay Eleteday" - :edit "Edityay" - :delete "Eleteday" - :clear-stats "Earclay Atsstay" - :create-game "Eatecray Amegay" - :deck-name "Eckday Amenay" - :format "Ormatfay" - :identity "Identityay" - :deck-notes "Eckday otesnay" - :decklist "Ecklistday" - :decklist-inst "(Ypetay oryay astepay ayay ecklistday, ityay illway ebay arsedpay)" - :notes "Otesnay" - :add-to-deck "Addyay otay eckday" - :add-cards "Addyay ardscay" - :card-name "Ardcay amenay" - :no-decks "Onay ecksday" - :cards "ardscay" - :min "inimummay" - :max "aximummay" - :influence "Influenceyay" - :agenda-points "Agendayay ointspay" - :deck-points "Eckday ointspay" - :hash "Ournamenttay ashhay" - :why "Whyay?" - :legal "egallay" - :illegal "illegalyay" - :games "Amesgay" - :completed "Ompletedcay" - :won "Onway" - :lost "Ostlay"} - :lobby {:no-games "Onay amesgay" - :tournament "Ournamenttay" - :competitive "Ompetitivecay" - :casual "Asualcay" - :new-game "Ewnay amegay" - :reload "Eloadray istlay" - :load-replay "Oadlay Eplayray" - :start-replay "Artst Eplayray" - :save-replay "Avesay Eplayray" - :replay-link-error "Eplayray inklay invalidyay." - :replay-invalid-file "Electsay ayay alidvay eplayray ilefay." - :create "Eatecray" - :cancel "Ancelcay" - :title "Itletay" - :side "Idesay" - :format "Ormatfay" - :options "Optionsyay" - :spectators "Allowyay ectatorsspay" - :hidden "Akemay ayersplay iddenhay informationyay isiblevay otay ectatorsspay" - :password-protected "Asswordpay otectedpray" - :password "Asswordpay" - :start "Artstay" - :leave "Eavelay" - :swap "Apsway idessay" - :waiting "Aitingway ayersplay eckday electionsay" - :players "Ayersplay" - :deck-selected "Eckday electedsay" - :select-deck "Electsay eckday" - :chat "Atchay" - :select-title "Electsay ouryay eckday" - :spectator-count (fn [[cnt]] (str cnt " Ectatorspay" (when (not= cnt 1) "s"))) - :closed-msg "Amegay obbylay osedclay ueday otay inactivityay" - :title-error "Easeplay illfay ayay amegay itletay." - :password-error "Easepl illfay ayay asswordpay." - :too-little-data "Ootay ittlelay ataday" - :completion-rate "Amegay Ompletioncay Ateray" - :watch "Atchway" - :join "Oinjay" - :rejoin "Ejoinray" - :private "IVATEPRAY" - :reset "Esetray Amegay Amenay" - :delete "Eleteday Amegay" - :password-for "Asswordpay orfay" - :invalid-password "Nvalidiay asswordpay" - :not-allowed "Otnay allowedyay" - :aborted "Onnectioncay abortedyay"} - :settings {:invalid-password "Nvalidiay oginlay oryay asswordpay" - :invalid-email "Onay accountyay ithway atthay emailyay addressyay existsyay" - :updated "Ofilepray updatedyay - Leasepay efreshray ouryay owserbray" - :updating "Updatingyay ofilepray..." - :get-log-width "Etgay urrentcay oglay idthway" - :get-log-top "Etgay urrentcay oglay optay" - :email-title "Angechay emailyay addressyay" - :current-email "Urrentcay emailyay" - :desired-email "Esiredday emailyay" - :email-placeholder "Emailyay addressyay" - :enter-valid "Easeplay enteryay ayay alidvay emailyay addressyay" - :update "Updateyay" - :cancel "Ancelcay" - :email "Emailyay" - :change-email "Angechay emailyay" - :avatar "Avataryay" - :change-avatar "Angechay onyay gravatar.com" - :pronouns "Onounspray" - :language "Anguagelay" - :sounds "Oundssay" - :enable-lobby-sounds "Enableyay obbylay oundssay" - :enable-game-sounds "Enableyay amegay oundssay" - :volume "Olumevay" - :layout-options "Ayoutlay Optionsyay" - :stacked-cards "Ardcay ackingstay (onyay ybyay efaultday)" - :runner-layout "Unnerray ayoutlay omfray Orpcay erspectivepray" - :runner-classic "Unnerray igray ayoutlay isyay assicclay etjnay (Optay otay ottombay: Ogramspr, Ardwarehay, Esourcesray)" - :runner-reverse "Unnerray iray ayoutlay isyay eversedray (Optay otay ottombay: Esourcesray, Ardwarehay, Ogramspray)" - :background "Amegay oardbay ackgroundbay" - :card-backs "Ardcay acksbay" - :game-stats "Amegay Inway/Oselay atisticsstay" - :deck-stats "Eckday atisticsstay" - :always "Alwaysyay" - :comp-only "Ompetitivecay Obbylay Onlyay" - :none "Onenay" - :alt-art "Altyay artsyay" - :show-alt "Owshay alternateyay ardcay artsyay" - :high-res "Enabley ighhay-esolutionray ardcay imagesyay" - :card-images "Ardcay imagesyay" - :set-all "Etsay allyay ardscay otay" - :set "Etsay" - :reset "Esetray Allyay otay Officialyay Artyay" - :blocked "Ockedblay usersyay" - :user-name "Useryay amenay" - :block "Ockblay useryay" - :update-profile "Updateyay Ofilepray" - :ffg "FFGYAY" - :nsg "NSGYAY" - :api-keys "APIYAY Eyskay" - :delete-api-key "Eleteday" - :create-api-key "Eatecray APIYAY Eykay"} - :stats {:game-stats "Amegay Atsstay" - :corp-stats "Orpcay Atsstay" - :runner-stats "Unnerray Atsstay" - :clear-stats "Earclay Atsstay" - :no-log "Onay oglay availableyay" - :view-log "Iewvay oglay" - :winner "Innerway" - :no-games "Onay amesgay" - :all-games "Owshay allyay amesgay" - :shared-games "Onlyay owshay aredshay" - :started "Artedstay" - :ended "Endedyay" - :completed "Ompletedcay" - :not-completed "Otnay ompletedcay" - :won "Onway" - :lost "Ostlay" - :turn-count (fn [[cnt]] (str cnt " urntay" (when (not= cnt 1) "s"))) - :lobby "Obbylay" - :format "Ormatfay" - :win-method "Inway ethodmay" - :view-games "Eturnray otay atsstay eenscray" - :share "Areshay eplayray" - :launch "Aunchlay Eplayray" - :download "Ownloadday eplayray" - :unavailable "Eplayray unavailableyay" - :filtered "(ilteredfay)" - :log-count (fn [[cnt]] (str cnt " Oglay" (when (not= cnt 1) "s"))) - :clicks-gained "Icksclay Ainedgay" - :credits-gained "Editscray Ainedgay" - :credits-spent "Editscray Entspay" - :credits-click "Editscray ybay Ickclay" - :cards-drawn "Ardscay Awndray" - :cards-click "Ardscay Awndray ybay Ickclay" - :damage-done "Amageday Oneday" - :cards-rezzed "Ardscay Ezzedray" - :tags-gained "Agstay Ainedgay" - :runs-made "Unsray Ademay" - :cards-accessed "Ardscay Accessedyay"} - :game {:keep "Eepkay" - :mulligan "Ulliganmay" - :close "Oseclay" - :start "Artstay Amegay" - :remove-tag "Emoveray Agtay" - :run "Unray" - :purge "Urgepay" - :trash-resource "Ashtray Esourceray" - :draw "Awdray" - :gain-credit "Aingay Editcray" - :game-start "Amegay Artstay" - :start-turn "Artstay Urntay" - :end-turn "Endyay Urntay" - :mandatory-draw "Andatorymay Awdray" - :take-clicks "Aketay Icksclay" - :hq "HQYAY" - :grip "Ipgray" - :rfg "Emovedray omfray ethay amegay" - :play-area "Ayplay Areayay" - :current "Urrentcay" - :scored-area "Oredscay Areayay" - :archives "Archivesyay" - :max-hand "Axmay andhay izesay" - :brain-damage "Ainbray Amageday" - :tag-count (fn [[base additional total]] (str base (when (pos? additional) (str " + " additional)) " Agtay" (if (not= total 1) "s" ""))) - :agenda-count (fn [[agenda-point]] (str agenda-point " Agendayay Ointpay" (when (not= agenda-point 1) "s"))) - :link-strength "Inklay Engthstray" - :credit-count (fn [[credit run-credit]] (str credit " Editcray" (if (not= credit 1) "s" "") (when (pos? run-credit) (str " (" run-credit " orfay unray)")))) - :click-count (fn [[click]] (str click " Ickclay" (if (not= click 1) "s" ""))) - :bad-pub-count (fn [[base additional]] (str base (when (pos? additional) (str " + " additional)) " Adbay Ublicitypay")) - :mu-count (fn [[unused available]] (str unused " ofyay " available " UMYAY unusedyay")) - :special-mu-count (fn [[unused available mu-type]] (str unused " ofyay " available " " mu-type " UMYAY unusedyay")) - :indicate-action "Indicateyay actionyay" - :spec-count (fn [[c]] (str c " Ectatorspay" (when (> c 1) "s"))) - :spec-view "Ectatorspay Iewvay" - :runner-view "Unnerray Iewvay" - :corp-view "Orpcay Iewvay" - :leave-replay "Eavelay Eplayray" - :leave "Eavelay Amegay" - :unmute "Unmuteyay ectatorsspay" - :mute "Utemay ectatorsspay" - :concede "Oncedecay" - :inactivity "Amegay osedclay ueday otay inactivityay" - :server "Erversay" - :unimplemented "Unimplementedyay" - :abilities "Abilitiesyay" - :let-subs-fire "Etlay allyay okenunbray ubroutinessay irefay" - :subs "Ubroutinessay" - :actions "Actionsyay" - :fire-unbroken "Irefay unbrokenyay ubroutinessay" - :stack "Ackstay" - :r&d "R&DYAY" - :shuffle "Uffleshay" - :show "Owshay" - :close-shuffle "Osecla & Uffleshay" - :heap "Eaphay" - :card-count (fn [[size]] (str size " ardcay" (when (not= 1 size) "s") ".")) - :face-down-count (fn [[total face-up]] (str total " ardscay, " (- total face-up) " acefay-ownday.")) - :up-down-count (fn [[total face-up]] (str face-up "↑ " (- total face-up) "↓")) - :initiation "Initiationyay" - :approach-ice "Approachyay iceyay" - :encounter-ice "Encounteryay iceyay" - :movement "Ovementmay" - :breach-server "Eachbray erversay" - :success "Uccesssay" - :run-ends "Unray endsyay" - :no-current-run "Onay urrentcay unray" - :current-phase "Urrentcay asephay" - :unknown-phase "Unknownyay asephay" - :rez "Ezray" - :no-further "Onay urtherfay actionsyay" - :continue-to "Ontinuecay otay" - :continue "Ontinuecay" - :stop-auto-pass "Opstay autoyay-assingpay ioritypray" - :auto-pass "Autoyay-asspay ioritypriay" - :jack-out "Ackjay Outyay" - :trace "Acetray" - :credits "editscray" - :card "Ardcay" - :time-taken (fn [[t]] (str "Imetay akentay: " t " inutesmay")) - :win-decked (fn [[turn]] (str "insway ueday otay ethay Orpcay eingbay eckedday onyay urntay " turn)) - :win-flatlined (fn [[turn]] (str "insway ybay atlineflay onyay urntay " turn)) - :win-conceded (fn [[turn]] (str "insway ybay oncessionay onyay urntay " turn)) - :win-claimed (fn [[turn]] (str "insway ybay laimcay onyay urntay " turn)) - :win-points (fn [[turn]] (str "insway ybay oringcay agendayay ointspay onyay urntay " turn)) - :win-other (fn [[turn reason]] (str "insway ybay " reason " onyay urntay " turn))}}) diff --git a/src/cljc/i18n/pl.cljc b/src/cljc/i18n/pl.cljc deleted file mode 100644 index c5981ec0b6..0000000000 --- a/src/cljc/i18n/pl.cljc +++ /dev/null @@ -1,396 +0,0 @@ -(ns i18n.pl) - -(def translations - {:missing ":pl missing text" - :side {:corp "Korpo" - :runner "Runner" - :any-side "Dowolna" - :all "Wszystkie"} - :faction {:all "Wszystkie" - :any-faction "Dowolna frakcja" - :anarch "Anarchowie" - :criminal "Kryminale" - :shaper "Kształcerze" - :adam "Adam" - :apex "Apex" - :sunny-lebeau "Sunny Lebeau" - :jinteki "Jinteki" - :haas-bioroid "Haas-Bioroid" - :nbn "NBN" - :weyland-consortium "Weyland Consortium" - :neutral "Neutralne"} - :format {:all "All" - :any-format "Dowolny format" - :standard "Standard" - :eternal "Eternal" - :core-experience "Core Experience" - :snapshot "Snapshot" - :snapshot-plus "Snapshot Plus" - :socr "SOCR" - :sunset "Sunset" - :neo "Neo" - :classic "Classic" - :casual "Niekompetytywny" - :system-gateway "Wejście do Systemu" - :startup "Startup"} - :card-type {:all "Wszystkie" - :identity "Tożsamość" - :agenda "Projekt" - :asset "Aktywa" - :upgrade "Ulepszenie" - :operation "Operacja" - :ice "Lód" - :event "Wydarzenie" - :hardware "Sprzęt" - :resource "Zasób" - :program "Program"} - :pronouns {:none "nieokreślone" - :any "dowolne" - :myodb "bez szczegółów" - :blank "[puste]" - :they "oni/ich" - :she "ona/jej" - :shethey "ona/ich" - :he "on/jego" - :hethey "on/ich" - :it "ono" - :ne "ne/nem" - :ve "ve/ver" - :ey "ey/em" - :zehir "ze/hir" - :zezir "ze/zir" - :xe "xe/xem"} - :chat {:title "Graj w Netrunnera w przeglądarce" - :channels "Kanały" - :send "Wyślij" - :placeholder "Powiedz coś..." - :delete "Usuń wiadomość" - :delete-all "Usuń wszystkie wiadomości użytkownika" - :block "Zablokuj użytkownika" - :cancel "Anuluj"} - :nav {:chat "Czat" - :cards "Karty" - :deck-builder "Tworzenie talii" - :play "Graj" - :help "Pomoc" - :settings "Ustawienia" - :stats "Statystyki" - :about "Informacje" - :tournaments "Turnieje" - :admin "Administracja" - :users "Użytkownicy" - :features "Cechy" - :game-count (fn [[cnt]] (str "Gry: " cnt))} - :menu {:settings :pl.nav/settings - :logout "Wylogowanie" - :admin :pl.nav/admin - :moderator "Moderator"} - :card-browser {:search-hint "Szukaj kart" - :sort "Porządkowanie" - :format "Format" - :set "Zestaw" - :side "Strona" - :faction "Frakcja" - :type "Typ" - :clear "Wyczyść" - :select-art "Wybierz grafiki" - :selected-art "Wybrano grafiki alt." - :update-success "Grafiki zaktualizowane" - :update-failure "Nieudana aktualizacja grafiki" - :memory "Pamięć" - :cost "Koszt" - :trash-cost "Koszt skasowania" - :strength "Siła" - :advancement "Wymagany poziom rozwoju" - :agenda-points "Punkty projektów" - :min-deck "Minimalny rozmiar talii" - :inf-limit "Limit wpływu" - :influence "Wpływ" - :sort-by {:faction "Frakcja" - :name "Nazwa" - :type "Typ" - :influence "Wpływ" - :cost "Koszt" - :set-number "Numer w zestawie"}} - :deck-builder {:loading-msg "Ładowanie kolekcji talii..." - :new-corp "Nowa talia Korpo" - :new-runner "Nowa talia Runnera" - :import-button "Zaimportuj talię" - :reset "Zresetuj" - :import-title "Wpisz ID lub URL talii z NRDB (musi być opublikowana)" - :import "Importuj" - :cancel "Anuluj" - :import-placeholder "ID z NRDB" - :deck-count (fn [[cnt]] (str "Talie: " cnt)) - :filtered "(filtrowane)" - :save "Zapisz" - :confirm-delete "Potwierdź usunięcie" - :edit "Edytuj" - :delete "Usuń" - :clear-stats "Usuń statystyki" - :create-game "Stwórz stół" - :deck-name "Nazwa talii" - :format "Format" - :identity "Tożsamość" - :deck-notes "Notatki" - :decklist "Lista kart" - :decklist-inst "(Wpisz lub wklej listę kart z talii, zostanie przeanalizowana)" - :notes "Notatki" - :add-to-deck "Dodaj do talii" - :add-cards "Dodaj karty" - :card-name "Nazwa karty" - :no-decks "Brak talii" - :cards "karty" - :min "min." - :max "maks." - :influence "Wpływ" - :agenda-points "Punkty projektów" - :deck-points "Punkty talii" - :hash "Kod turniejowy" - :why "Dlaczego?" - :legal "legalny" - :illegal "nielegalny" - :games "Gry" - :completed "Ukończone" - :won "Wygrane" - :lost "Przegrane"} - :lobby {:no-games "Brak gier" - :tournament "Wydarzenia" - :competitive "Kompetytywne" - :casual "Niekompetytywne" - :new-game "Nowa gra" - :reload "Odśwież listę" - :load-replay "Wczytaj powtórkę" - :start-replay "Rozpocznij powtórkę" - :save-replay "Zapisz powtórkę" - :replay-link-error "Nieprawidłowy URL powtórki." - :replay-invalid-file "Wybierz prawidłowy plik powtórki." - :create "Stwórz" - :cancel "Anuluj" - :title "Tytuł" - :side "Strona" - :format "Format" - :options "Opcje" - :spectators "Dozwoleni widzowie" - :hidden "Ukryte informacje graczy widoczne dla widzów" - :password-protected "Ochrona hasłem" - :password "Hasło" - :start "Rozpocznij" - :leave "Wyjdź" - :swap "Zmień stronę" - :waiting "Oczekiwanie na wybór talii" - :players "Gracze" - :deck-selected "Talia wybrana" - :select-deck "Wybierz talię" - :chat "Czat" - :select-title "Wybierz talię" - :spectator-count (fn [[cnt]] (str "Widownia: " cnt)) - :closed-msg "Poczekalnia zamknięta z powodu braku aktywności" - :title-error "Wpisz nazwę dla stołu." - :password-error "Wpisz hasło." - :too-little-data "Zbyt mało danych" - :completion-rate "Procent zakończonych gier" - :watch "Oglądaj" - :join "Dołącz" - :rejoin "Wróć" - :as-corp "jako Korpo" - :as-runner "jako Runner" - :private "PRYWATNY" - :reset "Zresetuj nazwę stołu" - :delete "Usuń stół" - :password-for "Hasło dla" - :invalid-password "Nieprawidłowe hasło" - :not-allowed "Niedozwolone" - :aborted "Połączenie przerwane" - :api-access "Zezwól na dostęp API do danych rozgrywki" - :api-requires-key "(Wymaga podania klucza API w ustawieniach)" - :game-count (fn [[cnt]] (str "Gry: " cnt)) - :filtered "(filtrowane)"} - :settings {:invalid-password "Nieprawidłowa nazwa lub hasło" - :invalid-email "Brak konta z tym adresem e-mail" - :updated "Profil zaktualizowany - odśwież okno przeglądarki" - :updating "Aktualizacja profilu..." - :get-log-width "Pobierz aktualną szerokość dziennika" - :get-log-top "Pobierz aktualną wysokość dziennika" - :email-title "Zmień adres e-mail" - :current-email "Aktualny e-mail" - :desired-email "Nowy e-mail" - :email-placeholder "Adres e-mail" - :enter-valid "Podaj poprawny adres e-mail" - :update "Aktualizuj" - :cancel "Anuluj" - :email "E-mail" - :change-email "Zmień adres e-mail" - :avatar "Awatar" - :change-avatar "Zmień na stronie gravatar.com" - :pronouns "Zaimki osobowe" - :language "Język" - :sounds "Dźwięki" - :enable-lobby-sounds "Włącz dźwięki poczekalni" - :enable-game-sounds "Włącz dźwięki gry" - :volume "Głośność" - :layout-options "Opcje układu stołu" - :stacked-cards "Grupowanie kart (domyślnie włączone)" - :runner-layout "Układ stołu Runnera ze strony Korpo" - :runner-classic "Karty Runnera w klasycznym stylu (od góry: Programy, Sprzęt, Zasoby)" - :runner-reverse "Karty Runnera w odwróconym stylu (od góry: Zasoby, Sprzęt, Programy)" - :background "Tło stołu" - :card-backs "Rewersy kart" - :game-stats "Statystyki wygranych/przegranych" - :deck-stats "Statystyki talii" - :always "Zawsze" - :comp-only "Tylko w grach kompetytywnych" - :none "Nigdy" - :alt-art "Alternatywne grafiki" - :show-alt "Pokaż alternatywne grafiki kart" - :high-res "Użyj obrazów kart o wysokiej rozdzielczości" - :card-images "Obrazy kart" - :set-all "Ustaw wszystkie karty na" - :set "Ustaw" - :reset "Zresetuj wszystko do oficjalnych grafik" - :blocked "Zablokowani użytkownicy" - :user-name "Nazwa użytkownika" - :block "Zablokuj użytkownika" - :update-profile "Aktualizuj profil" - :nsg "NSG" - :ffg "FFG" - :api-keys "Klucze API" - :delete-api-key "Usuń" - :create-api-key "Stwórz klucz API"} - :stats {:game-stats "Statystyki gier" - :corp-stats "Statystyki: Korpo" - :runner-stats "Statystyki: Runner" - :clear-stats "Wyczyść statystyki" - :no-log "Brak dziennika" - :view-log "Obejrzyj dziennik" - :winner "Wygrana" - :no-games "Brak gier" - :all-games "Pokaż wszystkie gry" - :shared-games "Pokaż jedynie udostępnione" - :started "Rozpoczęteo" - :ended "Zakończono" - :completed "Ukończono" - :not-completed "Nie ukończono" - :won "Wygrano" - :lost "Przegrano" - :turn-count (fn [[cnt]] (str "Tura: " cnt)) - :lobby "Poczekalnia" - :format "Format" - :win-method "Sposób wygranej" - :view-games "Powrót do ekranu statystyk" - :share "Udostępnij powtórkę" - :launch "Uruchom powtórkę" - :download "Pobierz powtórkę" - :unavailable "Powtórka niemożliwa" - :filtered "(filtrowane)" - :log-count (fn [[cnt]] (str "Dzienniki: " cnt)) - :clicks-gained "Zyskane kliknięcia" - :credits-gained "Zyskane kredyty" - :credits-spent "Wydane kredyty" - :credits-click "Kredyty zyskane przez kliknięcia" - :cards-drawn "Dobrane karty" - :cards-click "Karty dobrane przez kliknięcia" - :damage-done "Zadane obrażenia" - :cards-rezzed "Aktywowane karty" - :tags-gained "Otrzymane znaczniki namiaru" - :runs-made "Rozpoczęte włamów" - :cards-accessed "Dostępy do kart"} - :log {:game-log "Dziennik gry" - :annotating "Notatki" - :shared "Udostępnione notatki" - :remote-annotations-fail "Nieudane pobranie zdalnych notatek."} - :annotations {:turn-placeholder "Notatki do tej tury" - :click-placeholder "Notatki do tego kliknięcia" - :available-annotations "Dostępne notatki" - :no-published-annotations "Brak opublikowanych notatek." - :publish "Publikuj" - :import-local "Zaimportuj plik z notatkami" - :load-local "Wczytaj" - :save-local "Zapisz" - :clear "Wyczyść lokalne notatki"} - :game {:keep "Zachowanie" - :mulligan "Wymiana" - :close "Zamknięcie" - :start "Rozpoczęcie gry" - :remove-tag "Usunięcie 1 namiaru" - :run "Rozpoczęcie włamu" - :purge "Usunięcie wirusów" - :trash-resource "Skasowanie 1 zasobu" - :draw "Dobranie karty" - :gain-credit "Zyskanie 1 kredytu" - :game-start "Rozpoczęcie gry" - :start-turn "Rozpoczęcie tury" - :end-turn "Zakończenie tury" - :mandatory-draw "Przymusowe dobranie" - :take-clicks "Rozpoczęcie kliknięć" - :hq "KG" - :grip "Garść" - :rfg "Usunięte z gry" - :play-area "Zagrywane" - :current "Wątek" - :scored-area "Punktacja" - :archives "Archiwum" - :max-hand "Maks. ilość kart" - :brain-damage "Obrażenia mózgu" - :tag-count (fn [[base additional total]] (str "Namiar :" base (when (pos? additional) (str " + " additional)))) - :agenda-count (fn [[agenda-point]] (str "Punkty projektów: " agenda-point)) - :link-strength "Łącze" - :credit-count (fn [[credit run-credit]] (str "Kredyty: " credit (when (pos? run-credit) (str " (" run-credit " na włam)")))) - :click-count (fn [[click]] (str "Kliki: " click)) - :bad-pub-count (fn [[base additional]] (str "Zła prasa: " base (when (pos? additional) (str " + " additional)))) - :mu-count (fn [[unused available]] (str "Wolne: " unused " z " available " JP")) - :special-mu-count (fn [[unused available mu-type]] (str "Wolne: " unused " z " available " " mu-type " JP")) - :indicate-action "Zgłoszenie działania" - :spec-count (fn [[c]] (str "Widownia: " c)) - :spec-view "Perspektywa widowni" - :runner-view "Perspektywa Runnera" - :corp-view "Perspektyw Korpo" - :leave-replay "Wyjście z powtórki" - :leave "Wyjście z gry" - :unmute "Włączenie czat widowni" - :mute "Wyłączenie czat widowni" - :concede "Poddanie się" - :inactivity "Gra zakończona z powodu braku aktywności" - :server "Serwer" - :unimplemented "Niezautomatyzowana" - :abilities "Opcje" - :let-subs-fire "Pozwolenie na użycie niezłamanych poleceń" - :subs "Polecenia" - :actions "Akcje" - :fire-unbroken "Użycie niezłamanych poleceń" - :stack "Stos" - :r&d "DBR" - :shuffle "Przetasowanie" - :show "Pokazanie" - :close-shuffle "Zamknięcie i przetasowanie" - :heap "Sterta" - :card-count (fn [[size]] (str "Karty: " size ".")) - :face-down-count (fn [[total face-up]] (str "Karty: " total ", awersem w dół:" (- total face-up) ".")) - :up-down-count (fn [[total face-up]] (str face-up "↑ " (- total face-up) "↓")) - :initiation "Rozpoczęcie" - :approach-ice "Zbliżenie do lodu" - :encounter-ice "Napotkanie lodu" - :movement "Ruch" - :breach-server "Przebicie do serwera" - :success "Sukces" - :run-ends "Włam się kończy" - :no-current-run "Brak włamu w toku" - :current-phase "Aktualna faza" - :unknown-phase "Nieznana faza" - :rez "Aktywacja" - :no-further "Brak dalszych działań" - :continue "Kontynuacja" - :continue-to "Kontynuacja do:" - :stop-auto-pass "Wyłączenie priorytetu auto-mijania" - :auto-pass "Priorytet auto-mijania" - :jack-out "Wylogowanie się" - :trace "Namiar" - :credits "kred." - :card "Karta" - :time-taken (fn [[t]] (str "Czas gry: " t " min.")) - :win-decked (fn [[turn]] (str "wygrywa, ponieważ Korpo skończyły się karty w " turn " turze.")) - :win-flatlined (fn [[turn]] (str "wygrywa przez wypłaszczenie w " turn " turze.")) - :win-conceded (fn [[turn]] (str "wygrywa przez poddanie się przeciwnika w " turn " turze.")) - :win-claimed (fn [[turn]] (str "wygrywa przez zgłoszenie wygranej w " turn " turze.")) - :win-points (fn [[turn]] (str "wygrywa przez zdobycie punktów zwycięstwa w " turn " turze.")) - :win-other (fn [[turn reason]] (str "wygrywa przez " reason " w " turn " turze."))}}) diff --git a/src/cljc/i18n/pt.cljc b/src/cljc/i18n/pt.cljc deleted file mode 100644 index 10d838ed95..0000000000 --- a/src/cljc/i18n/pt.cljc +++ /dev/null @@ -1,396 +0,0 @@ -(ns i18n.pt) - -(def translations - {:missing ":pt missing text" - :side {:corp "Corp" - :runner "Runner" - :any-side "Qualquer lado" - :all "Todos"} - :faction {:all "Todos" - :any-faction "Qualquer facção" - :anarch "Anarquista" - :criminal "Criminosos" - :shaper "Modeladores" - :adam "Adam" - :apex "Apex" - :sunny-lebeau "Sunny Lebeau" - :jinteki "Jinteki" - :haas-bioroid "Haas-Bioroid" - :nbn "NBN" - :weyland-consortium "Consórcio Weyland" - :neutral "Neutro"} - :format {:all "All" - :any-format "Qualquer Formato" - :standard "Standard" - :eternal "Eternal" - :core-experience "Core Experience" - :snapshot "Snapshot" - :snapshot-plus "Snapshot Plus" - :socr "SOCR" - :classic "Classico" - :casual "Casual" - :system-gateway "System Gateway" - :startup "Startup"} - :card-type {:all "Todos" - :identity "Identidade" - :agenda "Agenda" - :asset "Ativo" - :upgrade "Upgrade" - :operation "Operação" - :ice "GELO" - :event "Evento" - :hardware "Hardware" - :resource "Recurso" - :program "Programa"} - :pronouns {:none "Não especificado" - :any "Qualquer" - :myodb "Prefiro não especificar" - :blank "[blank]" - :they "Elu/Delu" - :she "Ela/Dela" - :shethey "Ela/Delu" - :he "Ele/Dele" - :hethey "Ele/Delu" - :it "Elx" - :ne "Ne/nem" - :ve "Ve/ver" - :ey "Ey/em" - :zehir "Ze/hir" - :zezir "Ze/zir" - :xe "Xe/xem"} - :chat {:title "Jogue Android: Netrunner no seu browser" - :channels "Canais" - :send "Enviar" - :placeholder "Diga alguma coisa..." - :delete "Deletar Mensagem" - :delete-all "Deletar todas as mensagens do usuário" - :block "Bloquear Usuário" - :cancel "Cancelar"} - :nav {:chat "Chat" - :cards "Cartas" - :deck-builder "Construtor de Baralhos" - :play "Jogar" - :help "Ajuda" - :settings "Configurações" - :stats "Estatisticas" - :about "Sobre" - :tournaments "Torneios" - :admin "Admin" - :users "Usuários" - :features "Features" - :game-count (fn [[cnt]] (str cnt " Jogo" (when (not= cnt 1) "s")))} - :menu {:settings :pt.nav/settings - :logout "Ejetar" - :admin :pt.nav/admin - :moderator "Moderadores" - :donor "Doadores"} - :card-browser {:search-hint "Procure cartas" - :sort "Ordenar por" - :format "Formato" - :set "Set" - :side "Lado" - :faction "Facção" - :type "Tipo" - :clear "Limapr" - :select-art "Selecionar Arte" - :selected-art "Arte Alternativa Selecionada" - :update-success "Atualizar Arte" - :update-failure "Falha ao atualizar Arte" - :memory "Memória" - :cost "Custo" - :trash-cost "Custo de exclusão" - :strength "Força" - :advancement "Avanços necessarios" - :agenda-points "Pontos de Agenda" - :min-deck "Tamanho minimo de baralho" - :inf-limit "Limite de Influencia" - :influence "Influencia" - :sort-by {:faction "Facção" - :name "Nome" - :type "Tipo" - :influence "Influencia" - :cost "Custo" - :set-number "Numero do set"}} - :deck-builder {:loading-msg "Carregando coleção de baralhos..." - :new-corp "Novo baralho de Corp" - :new-runner "Novo baralho de Runner" - :import-button "Importar baralho" - :reset "Resetar" - :import-title "Insira um ID de baralho público do NRDB ou URL" - :import "Importar" - :cancel "Cancelar" - :import-placeholder "NRDB ID" - :deck-count (fn [[cnt]] (str cnt (if (= 1 cnt) " Baralho" " Baralhos"))) - :filtered "(filtered)" - :save "Salvar" - :confirm-delete "Confirmar exclusão" - :edit "Editar" - :delete "Deletar" - :copy "Copiar" - :deck-copy-suffix "cópia" - :clear-stats "Limpar estatísticas" - :create-game "Criar Partida" - :deck-name "Nome do Baralho" - :format "Formato" - :identity "Identitidade" - :deck-notes "Notas do baralho" - :decklist "Lista" - :decklist-inst "(Digite ou cole a lista do baralho, ela sera filtrada)" - :notes "Notas" - :add-to-deck "Adicionar ao baralho" - :add-cards "Adicionar cartas" - :card-name "Nome da carta" - :no-decks "Não há baralhos" - :cards "cards" - :min "minimo" - :max "maximo" - :influence "Influencia" - :agenda-points "Pontos de Agenda" - :deck-points "Pontos do Baralho" - :hash "Hash do torneio" - :why "Por que?" - :legal "legal" - :illegal "ilegal" - :games "Partidas" - :completed "Completas" - :won "Vitórias" - :lost "Derrotas"} - :lobby {:no-games "Não há jogos" - :tournament "Torneio" - :competitive "Competitivo" - :casual "Casual" - :new-game "Novo jogo" - :reload "Recarregar lista" - :load-replay "Carregar replay" - :start-replay "Começar replay" - :save-replay "Salvar replay" - :replay-link-error "Link do replay inválido." - :replay-invalid-file "Selecione um arquivo de replay válido." - :create "Criar" - :cancel "Cancelar" - :title "Titulo" - :side "Lado" - :format "Formato" - :options "Opções" - :spectators "Permitir espectadore" - :hidden "Tornar infomrações escondidas dos jogadores visivel para os espectadores" - :password-protected "Protegido por senha" - :password "Senha" - :start "Começar" - :leave "Sair" - :swap "Trocar lados" - :waiting "Eseprando jogador selecionar baralho" - :players "Jogadores" - :deck-selected "Baralho selecionado" - :select-deck "Selecionar baralho" - :chat "Chat" - :select-title "Selecione seu baralho" - :spectator-count (fn [[cnt]] (str cnt " Espectador" (when (not= cnt 1) "es"))) - :closed-msg "Lobby fechado por inatividade" - :title-error "Por favor insira o titulo do jogo." - :password-error "Por favor insira a senha do jogo." - :too-little-data "Falta de dados" - :completion-rate "Taxa de finalização de jogos" - :watch "Assistir" - :join "Entrar" - :rejoin "Re-Entrar" - :as-corp "Como Corp" - :as-runner "Como Runner" - :private "PRIVADO" - :reset "Resetar Nome do Jogo" - :delete "Deletar Jogo" - :password-for "Senha para" - :invalid-password "Senha invalida" - :not-allowed "Não autorizado" - :aborted "Conecção abortada" - :api-access "Permitir acesso API para informações do jogo" - :api-requires-key "(Requer uma Chave de API nas Configurações)" - :game-count (fn [[cnt]] (str cnt (if (= 1 cnt) " Jogo" " Jogos"))) - :filtered "(filtrado)"} - :settings {:invalid-password "Usuário ou senha inválidos" - :invalid-email "Nenhuma conta com esse email existe" - :updated "Perfil atualizar - Favor atualizar a página" - :updating "Atualizando perfil..." - :get-log-width "Puxando largura atual do log" - :get-log-top "Puxando topo do log atual" - :email-title "Alterar titulo do email" - :current-email "Email atual" - :desired-email "Email desejado" - :email-placeholder "Endereço de Email" - :enter-valid "Por favor, insira um endereço de email válido" - :update "Atualizar" - :cancel "Cancelar" - :email "Email" - :change-email "Trocar email" - :avatar "Avatar" - :change-avatar "Trocar avatar no gravatar.com" - :pronouns "Pronomes" - :language "Idioma" - :sounds "Soms" - :enable-lobby-sounds "Permitir sons do lobby" - :enable-game-sounds "Permitir sons do jogo" - :volume "Volume" - :layout-options "Opções de layout" - :stacked-cards "Empilhar cartas (ativo automaticamente)" - :runner-layout "Layout de Runner na perspectiva da Corp" - :runner-classic "Layout do rig do Runner é o clássico da JNet (De cima para baixo: Programas, Hardware, Recursos)" - :runner-reverse "Layout do rig do Runner invertido (De cima para baixo: Recursos, Hardware, Programas)" - :background "Background da partida" - :card-backs "Verso das cartas" - :game-stats "Estatísticas de Vitória/Derrota em Jogo" - :deck-stats "Estatísticas dos Decks" - :always "Sempre" - :comp-only "Apenas Lobby Competitivo" - :none "Nenhum" - :alt-art "Artes Alternativas" - :show-alt "Mostrar artes alternativas das cartas" - :high-res "Habilitar imagem das cartas em alta resolução" - :card-images "Imagens das Cartas" - :set-all "Set all cards to" - :set "Set" - :reset "Reset All to Official Art" - :blocked "Usuários bloqueados" - :user-name "Nome de usuário" - :block "Bloquear usuário" - :update-profile "Atualizar Perfil" - :ffg "FFG" - :api-keys "API Keys" - :delete-api-key "Deletar" - :create-api-key "Criar API Key"} - :stats {:game-stats "Estatísticas de Jogo" - :corp-stats "Estatísticas de Corp" - :runner-stats "Estatísticas de Runner" - :clear-stats "Limpar Estatísticas" - :no-log "Nenhum log disponível" - :view-log "Visualizar log" - :winner "Vencedor" - :no-games "Sem partidass" - :all-games "Mostrar todas partidas" - :shared-games "Mostrar apenas compartilhadas" - :started "Iniciadas" - :ended "Terminadas" - :completed "Completadas" - :not-completed "Não Completadas" - :won "Vitórias" - :lost "Derrotas" - :turn-count (fn [[cnt]] (str cnt " turno" (when (not= cnt 1) "s"))) - :lobby "Lobby" - :format "Formato" - :win-method "Método de vitórias" - :view-games "Retornar para Estatísticas" - :share "Compartilhar replay" - :launch "Carregar Replay" - :download "Baixar replay" - :unavailable "Replay indisponível" - :filtered "(filtrado)" - :log-count (fn [[cnt]] (str cnt " Log" (when (not= cnt 1) "s"))) - :clicks-gained "Clicks ganhos" - :credits-gained "Créditos ganos" - :credits-spent "Créditos gastos" - :credits-click "Créditos por Click" - :cards-drawn "Cards Compradas" - :cards-click "Cards Compradas por Click" - :damage-done "Dano Causado" - :cards-rezzed "Cartas Ativadas" - :tags-gained "Marcas Recebidas" - :runs-made "Corres Feitos" - :cards-accessed "Cartas Acessadas"} - :log {:game-log "Game Log" - :annotating "Anotações" - :shared "Anotações compartilhadas" - :remote-annotations-fail "Não foi possível pegar anotações remotas."} - :annotations {:turn-placeholder "Notas para este turno" - :click-placeholder "Notas para este Click" - :available-annotations "Anotações disponíeis" - :no-published-annotations "Sem anotações publicadas." - :publish "Publicar" - :import-local "Importar arquivo de anotações local" - :load-local "Carregar" - :save-local "Salvar" - :clear "Limpar anotações locais"} - :game {:keep "Manter" - :mulligan "Mulligan" - :close "Fechar" - :start "Começar Partida" - :remove-tag "Remover Marca" - :run "Corre" - :purge "Expurgar" - :trash-resource "Excluir Recurso" - :draw "Comprar" - :gain-credit "Ganhar Crédito" - :game-start "Começar partida" - :start-turn "Iniciar Turno" - :end-turn "Fim do Turno" - :mandatory-draw "Compra obrigatória" - :take-clicks "Receber Clicks" - :hq "QG" - :grip "Mão" - :rfg "Removido do jogo" - :play-area "Área de Jogo" - :current "Current" - :scored-area "Área de Pontuação" - :archives "Arquivos" - :max-hand "Tamanho de mão máximo" - :brain-damage "Dano Letal" - :tag-count (fn [[base additional total]] (str base (when (pos? additional) (str " + " additional)) " Marca" (if (not= total 1) "s" ""))) - :agenda-count (fn [[agenda-point]] (str agenda-point " Pontos de Agenda" (when (not= agenda-point 1) "s"))) - :link-strength "Força de Link" - :credit-count (fn [[credit run-credit]] (str credit " Crédito" (if (not= credit 1) "s" "") (when (pos? run-credit) (str " (" run-credit " para corre)")))) - :click-count (fn [[click]] (str click " Click" (if (not= click 1) "s" ""))) - :bad-pub-count (fn [[base additional]] (str base (when (pos? additional) (str " + " additional)) " Publicidade Negativa")) - :mu-count (fn [[unused available]] (str unused " of " available " MU unused")) - :special-mu-count (fn [[unused available mu-type]] (str unused " de " available " " mu-type " MU não utilizada")) - :indicate-action "Indicar ação" - :spec-count (fn [[c]] (str c " Espectador" (when (> c 1) "es"))) - :spec-view "Visão de Espectador" - :runner-view "Visão de Runner" - :corp-view "Visão de Corp" - :leave-replay "Sair do Replay" - :leave "Sair da Partida" - :unmute "Desmutar espectadores" - :mute "Mutar espectadores" - :concede "Conceder" - :inactivity "Partida fechada por inatividade" - :server "Servidor" - :unimplemented "Não implementado" - :abilities "Habilidades" - :let-subs-fire "Executar sub-rotinas não quebradas" - :subs "Sub-rotinas" - :actions "Ações" - :fire-unbroken "Executar sub-rotinas" - :stack "Pilha" - :r&d "P&D" - :shuffle "Embaralhar" - :show "Mostrar" - :close-shuffle "Fechar & Embaralhar" - :heap "Heap" - :card-count (fn [[size]] (str size " carta" (when (not= 1 size) "s") ".")) - :face-down-count (fn [[total face-up]] (str total " cartas, " (- total face-up) " virada para baixo.")) - :up-down-count (fn [[total face-up]] (str face-up "↑ " (- total face-up) "↓")) - :initiation "Iniciação" - :approach-ice "Aproximar do gelo" - :encounter-ice "Encontrar gelo" - :movement "Movivemento" - :breach-server "Violar servidor" - :success "Successo" - :run-ends "Corre terminou" - :no-current-run "Sem corre no momento" - :current-phase "Current phase" - :unknown-phase "Unknown phase" - :rez "Ativar" - :no-further "Sem mais ações" - :continue "Continuar" - :continue-to "Continuar para" - :stop-auto-pass "Para de passar prioridade" - :auto-pass "Passar prioridade automaticamente" - :jack-out "Ejetar" - :trace "Rastrear" - :credits "creditos" - :card "Carta" - :time-taken (fn [[t]] (str "Tempo consumido: " t " minutos")) - :win-decked (fn [[turn]] (str "venceu pois a Corp zerou o deck no turno " turn)) - :win-flatlined (fn [[turn]] (str "venceu por linha reta no turno " turn)) - :win-conceded (fn [[turn]] (str "venceu por concessão no turno " turn)) - :win-claimed (fn [[turn]] (str "venceu por objetivo no turno " turn)) - :win-points (fn [[turn]] (str "venceu por pontos de agenda no turno " turn)) - :win-other (fn [[turn reason]] (str "venceu por " reason " no turno " turn))}}) diff --git a/src/cljc/i18n/ru.cljc b/src/cljc/i18n/ru.cljc deleted file mode 100644 index f8797e1eb4..0000000000 --- a/src/cljc/i18n/ru.cljc +++ /dev/null @@ -1,817 +0,0 @@ -(ns i18n.ru) - -(defn ru-quant [group1 group2 group3] - (fn [[cnt]] - (let [group (if (contains? #{5 6 7 8 9 10 11 12 13 14} (rem cnt 100)) - group1 - (condp contains? (rem cnt 10) - #{0 5 6 7 8 9} group1 - #{1} group2 - #{2 3 4} group3))] - (str cnt " " group)))) - -(def translations - {:missing ":ru missing text" - :side {:corp "Корпорация" - :runner "Бегущий" - :any-side "Обе стороны" - :all "Все"} - :faction {:all "Все" - :any-faction "Все фракции" - :anarch "Анарх" - :criminal "Криминал" - :shaper "Шейпер" - :adam "Адам" - :apex "Апекс" - :sunny-lebeau "Санни Лебо" - :jinteki "Джинтеки" - :haas-bioroid "Хаас-Биороид" - :nbn "NBN" - :weyland-consortium "Консорциум Вейланда" - :neutral "Нейтральные"} - :format {:all "Все" - :any-format "Любой формат" - :standard "Стандарт" - :eternal "Вечный" - :core-experience "Core Experience" - :snapshot "Snapshot" - :snapshot-plus "Snapshot Plus" - :socr "SOCR" - :sunset "Закат" - :neo "Нео" - :preconstructed "Чемпионский" - :classic "Классический" - :casual "Свободный" - :system-gateway "Врата Системы" - :startup "Стартап"} - :preconstructed {:worlds-2012-a "ЧМ 2012: Бен Марш (К) против Джереми Звирна (Б)" - :worlds-2012-a-tag "Бен Марш (К) против Джереми Звирна (Б)" - :worlds-2012-a-ul "ЧМ 2012: Вейланд против Криминала" - :worlds-2012-b "ЧМ 2012: Джереми Звирн (К) против Бена Марша (Б)" - :worlds-2012-b-tag "Джереми Звирн (К) против Бена Марша (Б)" - :worlds-2012-b-ul "ЧМ 2012: Хаас-Биороид против Криминала" - :worlds-2012-info "Во время Чемпионата мира 2012 единственным легальным набором был Базовый (до 3 коробок). Джереми Звирн (Building a Better World, Gabriel Santiago) выиграл в финале у Бена Марша (Engineering the Future, Gabriel Santiago) и стал первым чемпионом мира по Netrunner." - :worlds-2013-a "ЧМ 2013: Йенс Эриксон (К) против Эндрю Вина (Б)" - :worlds-2013-a-tag "Йенс Эриксон (К) против Эндрю Вина (Б)" - :worlds-2013-a-ul "ЧМ 2013: HB FastAdv против Shaper Katman" - :worlds-2013-b "ЧМ 2013: Эндрю Вин (К) против Йенса Эриксона (Б)" - :worlds-2013-b-tag "Эндрю Вин (К) против Йенса Эриксона (Б)" - :worlds-2013-b-ul "ЧМ 2013: NBN Fast Adv против Andy Sucker" - :worlds-2013-info "В Чемпионате мира 2013 года участвовали 166 игроков. Турнир проходил в Миннеаполисе, штат Миннесота, США, и состоял из 6 раундов по швейцарской системе, переходящих в топ кат на 32 участника. Последний легальный набор: Opening Moves." - :worlds-2014-a "ЧМ 2014: Дэн Д'Ардженио (К) против Минна Трана (Б)" - :worlds-2014-a-tag "Дэн Д'Ардженио (К) против Минна Трана (Б)" - :worlds-2014-a-ul "ЧМ 2014: Honor and Perfection против Andromedium" - :worlds-2014-b "ЧМ 2014: Минн Тран (К) против Дэна Д'Ардженио (Б)" - :worlds-2014-b-tag "Минн Тран (К) против Дэна Д'Ардженио (Б)" - :worlds-2014-b-ul "ЧМ 2014: Personal Evolution против Daily QT Andy" - :worlds-2014-info "В Чемпионате мира 2014 года участвовали 238 игроков. Турнир проходил в Миннеаполисе, штат Миннесота, США, и состоял из 7 раундов по швейцарской системе, переходящих в топ кат на 16 участников. Последний легальный набор: Up and Over." - :worlds-2015-a "ЧМ 2015: Дэн Д'Ардженио (К) против Тимми Вона (Б)" - :worlds-2015-a-tag "Дэн Д'Ардженио (К) против Тимми Вона (Б)" - :worlds-2015-a-ul "ЧМ 2015: Foodcoatshop против The Morning After" - :worlds-2015-b "ЧМ 2015: Тимми Вон (К) против Дэна Д'Ардженио (Б)" - :worlds-2015-b-tag "Тимми Вон (К) против Дэна Д'Ардженио (Б)" - :worlds-2015-b-ul "ЧМ 2015: Yellow Shell против Radisson Cheese Plate" - :worlds-2015-info "В Чемпионате мира 2015 года участвовали 269 игроков. Турнир проходил в Миннеаполисе, штат Миннесота, США, и состоял из 8 раундов по швейцарской системе, переходящих в топ кат на 16 участников. Последний легальный набор: Data and Destiny." - :worlds-2016-a "ЧМ 2016: Крис Даер (К) против Бенджамина Ни (Б)" - :worlds-2016-a-tag "Крис Даер (К) против Бенджамина Ни (Б)" - :worlds-2016-a-ul "ЧМ 2016: Snekbite против Minh MaxX++" - :worlds-2016-b "ЧМ 2016: Бенджамин Ни (Б) против Криса Даера (К)" - :worlds-2016-b-tag "Бенджамин Ни (Б) против Криса Даера (К)" - :worlds-2016-b-ul "ЧМ 2016: Fiery Info против Papa Smurf" - :worlds-2016-info "В Чемпионате мира 2016 года участвовали 278 игроков. Турнир проходил в Миннеаполисе, штат Миннесота, США, и состоял из 9 раундов по швейцарской системе, переходящих в топ кат на 16 участников. Последний легальный набор: Escalation." - :worlds-2017-a "ЧМ 2017: Джесс Хориг (К) против Грей Тон (Б)" - :worlds-2017-a-tag "Джесс Хориг (К) против Грей Тон (Б)" - :worlds-2017-a-ul "ЧМ 2017: Stinson Reversed CI против Aesops Hayley" - :worlds-2017-b "ЧМ 2017: Грей Тон (К) против Джесс Хориг (Б)" - :worlds-2017-b-tag "Грей Тон (К) против Джесс Хориг (Б)" - :worlds-2017-b-ul "ЧМ 2017: No-Show Rewiring CI против Laguna Lock Hayley" - :worlds-2017-info "В Чемпионате мира 2016 года участвовали 233 игрока. Турнир проходил в Миннеаполисе, штат Миннесота, США, и состоял из 8(?) раундов по швейцарской системе, переходящих в топ кат на 16 участников. Последний легальный набор: Revised Core set." - :worlds-2018-a "ЧМ 2018: Джо Шуп (К) против Криса Даера (Б)" - :worlds-2018-a-tag "Джо Шуп (К) против Криса Даера (Б)" - :worlds-2018-a-ul "ЧМ 2018: AMERICA CtM против Gooseberry MaxX" - :worlds-2018-b "ЧМ 2018: Крис Даер (К) против Джо Шупа (Б)" - :worlds-2018-b-tag "Крис Даер (К) против Джо Шупа (Б)" - :worlds-2018-b-ul "ЧМ 2018: Trust the Process против Dan D'Argenio KoS Val" - :worlds-2018-info "В Чемпионате мира 2016 года участвовали 403(!) игрока. Это последний ЧМ, прошедший под крылом FFG. Турнир проходил в Миннеаполисе, штат Миннесота, США, и состоял из 9(?) раундов по швейцарской системе, переходящих в топ кат на 16 участников. Последний легальный набор: Reign and Reverie" - :worlds-2019-a "ЧМ 2019: Pinsel (К) против Testrunning (Б)" - :worlds-2019-a-tag "Pinsel (К) против Testrunning (Б)" - :worlds-2019-a-ul "ЧМ 2019: Fully dedicated to efficiency против Trash Panda" - :worlds-2019-b "ЧМ 2019: Testrunning (К) против Pinsel (Б)" - :worlds-2019-b-tag "Testrunning (К) против Pinsel (Б)" - :worlds-2019-b-ul "ЧМ 2019: 2 Grid for 2 Place против Trash Panda" - :worlds-2019-info "В первом Чемпионате мира по Netrunner, устроенным Project NISEI в 2019 году, поучаствовали 256 человек. Турнир проходил в Роттердаме, Нидерланды, и состоял из 9 раундов по швейцарской системе, переходящих в топ кат на 16 участников. Последний легальный набор: Uprising Booster Pack" - :worlds-2020-a "ЧМ 2020: Limes (К) против tf34 (Б)" - :worlds-2020-a-tag "Limes (К) против tf34 (Б)" - :worlds-2020-a-ul "ЧМ 2020: I don't like this deck против Engolo Freedom" - :worlds-2020-b "ЧМ 2020: tf34 (Б) против Limes (К)" - :worlds-2020-b-tag "tf34 (Б) против Limes (К)" - :worlds-2020-b-ul "ЧМ 2020: Malia CTM против Imp-pressive Hoshiko" - :worlds-2020-info "В первом онлайн Чемпионате мира по Netrunner, проведённом Project NISEI в 2020 году, приняли участие 294 игрока. Из-за ограничений в перемещениях в начале пандемии COVID-19 турнир был проведён онлайн на jinteki.net и состоял из 8 раундов по швейцарской системе, разбитых на 2 дня для двух разных групп игроков, переходящих в топ кат на 16 участников. Последний легальный набор: Uprising." - :worlds-2021-a "ЧМ 2021: Патрик Гауэр (К) против Джонаса (Б)" - :worlds-2021-a-tag "Патрик Гауэр (К) против Джонаса (Б)" - :worlds-2021-a-ul "ЧМ 2021: 44 Card PD против Watch Me Drip, Watch Me Maemi" - :worlds-2021-b "ЧМ 2021: Джонас (К) против Патрика Гауэра (Б)" - :worlds-2021-b-tag "Джонас (К) против Патрика Гауэра (Б)" - :worlds-2021-b-ul "ЧМ 2021: Is Gagarin Good? против Medium to Large Maxx" - :worlds-2021-info "Во втором онлайн Чемпионате мира по Netrunner, проведённом Project NISEI в 2021 году, принял участие 201 игрок. Из-за продолжающихся осложнений пандемии COVID-19 турнир был проведён онлайн на jinteki.net и состоял из 8 раундов по швейцарской системе, разбитых на 2 дня для двух разных групп игроков, переходящих в топ кат на 16 участников. Последний легальный набор: System Gateway." - :worlds-2022-a "ЧМ 2022: Уильям Хвон (К) против skry (Б)" - :worlds-2022-a-tag "Уильям Хвон (К) против skry (Б)" - :worlds-2022-a-ul "ЧМ 2022: SNACS против Liberté, Égalité, Humidité" - :worlds-2022-b "ЧМ 2022: skry (К) против Уильяма Хвона (Б)" - :worlds-2022-b-tag "skry (К) против Уильяма Хвона (Б)" - :worlds-2022-b-ul "ЧМ 2022: Dies to Doom Blade против ApocoLat" - :worlds-2022-info "В 2022 году Null Signal Games, ранее известные как Project NISEI, провели первый Чемпионат мира по Netrunner оффлайн с начала пандемии COVID-19. В мероприятии приняли участие 158 игроков. Турнир проходил в Торонто, Канада, и состоял из 7 раундов по швейцарской системе, переходящих в топ кат на 16 участников. Последний легальный набор: Midnight Sun." - :worlds-2023-a "ЧМ 2023: Уильям Хвон (К) против cableCarnage (Б)" - :worlds-2023-a-tag "Уильям Хвон (К) против cableCarnage (Б)" - :worlds-2023-a-ul "ЧМ 2023: The Worlds Grind против sableCarnage" - :worlds-2023-b "ЧМ 2023: cableCarnage (К) против Уильяма Хвона (Б)" - :worlds-2023-b-tag "cableCarnage (К) против Уильяма Хвона (Б)" - :worlds-2023-b-ul "ЧМ 2023: tableCarnage против You *do* always come back!" - :worlds-2023-info "Во втором Чемпионате мира по Netrunner под крылом Null Signal Games приняли участие 254 игрока. Турнир проходил в Барселоне, Испания, и состоял из 9 раундов по швейцарской системе, переходящих в топ кат на 16 участников. Последний легальный набор: The Automata Initiative."} - :set {:all "Все" - :draft-cycle "Draft Cycle" - :draft "Draft" - :core-set "Core Set" - :genesis-cycle "Genesis Cycle" - :what-lies-ahead "What Lies Ahead" - :trace-amount "Trace Amount" - :cyber-exodus "Cyber Exodus" - :a-study-in-static "A Study in Static" - :humanity-s-shadow "Humanity's Shadow" - :future-proof "Future Proof" - :creation-and-control "Creation and Control" - :spin-cycle "Spin Cycle" - :opening-moves "Opening Moves" - :second-thoughts "Second Thoughts" - :mala-tempora "Mala Tempora" - :true-colors "True Colors" - :fear-and-loathing "Fear and Loathing" - :double-time "Double Time" - :honor-and-profit "Honor and Profit" - :lunar-cycle "Lunar Cycle" - :upstalk "Upstalk" - :the-spaces-between "The Spaces Between" - :first-contact "First Contact" - :up-and-over "Up and Over" - :all-that-remains "All That Remains" - :the-source "The Source" - :order-and-chaos "Order and Chaos" - :sansan-cycle "SanSan Cycle" - :the-valley "The Valley" - :breaker-bay "Breaker Bay" - :chrome-city "Chrome City" - :the-underway "The Underway" - :old-hollywood "Old Hollywood" - :the-universe-of-tomorrow "The Universe of Tomorrow" - :data-and-destiny "Data and Destiny" - :mumbad-cycle "Mumbad Cycle" - :kala-ghoda "Kala Ghoda" - :business-first "Business First" - :democracy-and-dogma "Democracy and Dogma" - :salsette-island "Salsette Island" - :the-liberated-mind "The Liberated Mind" - :fear-the-masses "Fear the Masses" - :flashpoint-cycle "Flashpoint Cycle" - :23-seconds "23 Seconds" - :blood-money "Blood Money" - :escalation "Escalation" - :intervention "Intervention" - :martial-law "Martial Law" - :quorum "Quorum" - :red-sand-cycle "Red Sand Cycle" - :daedalus-complex "Daedalus Complex" - :station-one "Station One" - :earth-s-scion "Earth's Scion" - :blood-and-water "Blood and Water" - :free-mars "Free Mars" - :crimson-dust "Crimson Dust" - :terminal-directive-cycle "Terminal Directive Cycle" - :terminal-directive-cards "Terminal Directive Cards" - :terminal-directive-campaign "Terminal Directive Campaign" - :unreleased "Не выпущенные" - :revised-core-set "Revised Core Set" - :kitara-cycle "Kitara Cycle" - :sovereign-sight "Sovereign Sight" - :down-the-white-nile "Down the White Nile" - :council-of-the-crest "Council of the Crest" - :the-devil-and-the-dragon "The Devil and the Dragon" - :whispers-in-nalubaale "Whispers in Nalubaale" - :kampala-ascendent "Kampala Ascendent" - :reign-and-reverie "Reign and Reverie" - :magnum-opus "Magnum Opus" - :napd-multiplayer "NAPD Multiplayer" - :system-core-2019 "System Core 2019" - :ashes-cycle "Ashes Cycle" - :downfall "Downfall" - :uprising-booster-pack "Uprising Booster Pack" - :uprising "Uprising" - :magnum-opus-reprint "Magnum Opus Reprint" - :salvaged-memories "Salvaged Memories" - :system-gateway "Врата Системы" - :system-update-2021 "Обновление Системы 2021" - :borealis-cycle "Borealis Cycle" - :midnight-sun-booster-pack "Midnight Sun Booster Pack" - :midnight-sun "Midnight Sun" - :parhelion "Parhelion" - :liberation-cycle "Liberation Cycle" - :the-automata-initiative "The Automata Initiative" - :rebellion-without-rehearsal "Rebellion Without Rehearsal" - :alt-art "Альтернативные арты" - :kysra-alt-arts "Альт-арты от Kysra" - :ntscape-navigator-alt-arts "Альт-арты от Ntscape Navigator" - :plural-and-miniplural-alt-arts "Альт-арты от Plural и MiniPlural" - :alternate "Альтернативные" - :world-champion-2015 "Чемпион мира 2015" - :world-champion-2016 "Чемпион мира 2016" - :world-champion-2017 "Чемпион мира 2017" - :championship-2019 "Championship 2019" - :gnk-2019 "GNK 2019" - :championship-2020 "Championship 2020" - :signed-championship-2020 "Signed Championship 2020" - :previous-versions "Предыдущие версии"} - :card-type {:all "Все" - :identity "Роль" - :agenda "Проект" - :asset "Актив" - :upgrade "Улучшение" - :operation "Операция" - :ice "Лёд" - :event "Событие" - :hardware "Устройство" - :resource "Ресурс" - :program "Программа"} - :pronouns {:none "Не указаны" - :any "Любые" - :myodb "Не хочу указывать" - :blank "[пусто]" - :they "Они/их" - :she "Она/её" - :shethey "Она/они" - :he "Он/его" - :hethey "Он/они" - :it "Оно" - :ne "Ne/nem" - :ve "Ve/ver" - :ey "Ey/em" - :zehir "Ze/hir" - :zezir "Ze/zir" - :xe "Xe/xem"} - :chat {:title "Играть в Netrunner в браузере" - :channels "Каналы" - :send "Отправить" - :placeholder "Напишите что-нибудь..." - :delete "Удалить сообщение" - :delete-all "Удалить все сообщения пользователя" - :block "Заблокировать пользователя" - :cancel "Отмена" - :message-blocked (fn [[reason-str]] (str "Сообщение заблокировано" (when reason-str (str ": " reason-str)))) - :length-exceeded "Превышена длина" - :rate-exceeded "Превышена частота"} - :nav {:welcome "Правила" - :chat "Чат" - :cards "Карты" - :deck-builder "Колоды" - :play "Играть" - :help "Помощь" - :settings "Настройки" - :stats "Статистика" - :about "О нас" - :tournaments "Турниры" - :admin "Администратор" - :users "Пользователи" - :features "Возможности" - :game-count (ru-quant "игр" "игра" "игры")} - :menu {:settings :ru.nav/settings - :logout "Отключиться" - :admin :ru.nav/admin - :moderator "Модератор" - :donor "Спонсор"} - :card-browser {:implementation-note "Implementation Note" - :search-hint "Искать карты" - :sort "Сортировать по" - :format "Формат" - :set "Набор" - :side "Сторона" - :faction "Фракция" - :type "Тип" - :clear "Сбросить" - :select-art "Выбрать изображение" - :selected-art "Выбранное изображение" - :update-success "Изображение обновлено" - :update-failure "Ошибка обновления изображения" - :memory "Память" - :cost "Цена" - :trash-cost "Цена сноса" - :strength "Сила" - :advancement "Требование к продвижению" - :agenda-points "Победные очки" - :min-deck "Минимальный размер колоды" - :inf-limit "Предел влияния" - :influence "Влияние" - :artist-info "Информация о художнике" - :more-info "Больше информации" - :sort-by {:faction "Фракция" - :name "Название" - :type "Тип" - :influence "Влияние" - :cost "Цена" - :set-number "Номер в наборе"}} - :deck-builder {:loading-msg "Загрузка коллекции колод..." - :new-corp "Создать Корпу" - :new-runner "Создать Бегущего" - :import-button "Импорт колоды" - :reset "Сброс" - :import-title "Вставьте ID или ссылку на публичную колоду с NRDB" - :import "Импортировать" - :cancel "Отмена" - :import-placeholder "ID с NRDB" - :deck-count (ru-quant "колод" "колода" "колоды") - :filtered "(filtered)" - :save "Сохранить" - :confirm-delete "Подтвердить удаление" - :edit "Изменить" - :delete "Удалить" - :copy "Скопировать" - :deck-copy-suffix "копия" - :clear-stats "Сбросить статистику" - :create-game "Создать игру" - :new-deck "Новая колода" - :deck-name "Название колоды" - :format "Формат" - :identity "Роль" - :deck-notes "Примечания" - :decklist "Список карт" - :decklist-inst "(Напишите или вставьте список карт, он будет распознан)" - :notes "Примечания" - :add-to-deck "Добавить в колоду" - :add-cards "Добавить карты" - :card-name "Название карты" - :no-decks "Нет колод" - :cards "карты" - :min "минимум" - :max "максимум" - :influence "Влияние" - :agenda-points "Победные очки" - :deck-points "Очки колоды" - :hash "Турнирный хеш" - :why "Почему?" - :legal ": легальна" - :illegal ": нелегальна" - :games "Игр" - :completed "Зав." - :won "Побед" - :lost "Пор."} - :game-prompt {:trash "снести" - :advance "продвинуть" - :score "засчитать" - :rez "развернуть" - :derez "свернуть" - :expend "Израсходовать" - :archives "Архивы" - :hq "HQ" - :r-d "R&D" - :new-remote "Новый сервер" - :server-1 "Сервер 1" - :server-2 "Сервер 2" - :server-3 "Сервер 3" - :server-4 "Сервер 4" - :server-5 "Сервер 5" - :server-6 "Сервер 6" - :server-7 "Сервер 7" - :server-8 "Сервер 8" - :server-9 "Сервер 9" - :server-10 "Сервер 10"} - :lobby {:no-games "Нет игр" - :tournament "Турнирные" - :competitive "Соревновательные" - :casual "Обычные" - :angel-arena "Арена Ангелов" - :new-game "Новая игра" - :reload "Перезагрузить список" - :load-replay "Загрузить запись" - :start-replay "Запустить запись" - :save-replay "Сохранить запись" - :create "Создать" - :cancel "Отмена" - :title "Название" - :side "Сторона" - :format "Формат" - :default-game-format "Формат по умолчанию" - :gateway-format {:beginner "Новичок" - :beginner-info "В этом лобби можно играть стартовыми колодами Корпорации и Бегущего из набора Врата Cистемы. С этих колод рекомендуется начинать знакомство с игрой. Игра ведётся до 6 победных очков." - :beginner-ul "Врата Системы - Стартовые обучающие колоды" - :intermediate "Продвинутый" - :intermediate-info "В этом лобби можно играть продвинутыми колодами Корпорации и Бегущего из набора Врата Cистемы. В этих колодах больше опций и механик, чем в стартовых. Игра ведётся до 7 победных очков." - :intermediate-ul "Врата Системы - Продвинутые обучающие колоды" - :constructed "Свои колоды"} - :singleton "Синглтон" - :singleton-b "(синглтон)" - :singleton-details "С данной опцией играть можно только колодами без повторяющихся карт. Рекомендуется использовать следующие карты ролей." - :singleton-example "1) Nova Initiumia: Catalyst & Impetus 2) Ampere: Cybernetics For Anyone" - :singleton-restriction "Данное лобби запущено в режиме \"Синглтон\". Играть можно только колодами без повторяющихся карт." - :options "Параметры" - :spectators "Допускать зрителей" - :hidden "Раскрыть зрителям скрытую информацию" - :hidden-details "Данная опция раскроет всю скрытую информацию обеих сторон для ВСЕХ зрителей вашей игры, в том числе руки и карты лицом вниз." - :hidden-password "Мы рекомендуем использовать пароль, чтобы посторонние не помешали вашей игре." - :password-protected "Защитить паролем" - :password "Пароль" - :timed-game "Запустить таймер" - :timer-length "Продолжительность таймера (минут)" - :timed-game-details "Таймер носит информационный характер: игра будет продолжаться, когда время выйдет." - :save-replay-details "Данная опция сохранит запись игры с открытой информацией (например, о картах в руке). Файл будет доступен по завершении игры." - :save-replay-unshared "Мы храним 15 ваших последних записей, которыми вы не делились, так что не забудьте скачать повтор или поделиться им после игры." - :save-replay-beta "БЕТА функционал: У нас может возникнуть необходимость удалить сохранённые записи, поэтому обязательно скачивайте важные для вас повторы. Будущие изменения функционала сайта могут нарушить совместимость со старыми записями." - :replay-link-error "Ссылка на запись недействительна." - :replay-invalid-file "Выберите подходящий файл записи." - :corp-perspective "Перспектива Корпорации" - :runner-perspective "Перспектива Бегущего" - :both-perspective "Перспектива обоих" - :start "Начать" - :leave "Выйти" - :swap "Изменить стороны" - :waiting "Игроки выбирают колоды" - :players "Игроки" - :deck-selected "Колода выбрана" - :select-deck "Выбрать колоду" - :chat "Чат" - :select-error "Невозможно выбрать эту колоду" - :select-title "Выберите вашу колоду" - :spectator-count (ru-quant "зрителей" "зритель" "зрителя") - :closed-msg "Лобби закрыто из-за отсутствия активности" - :title-error "Пожалуйста, введите название игры." - :password-error "Пожалуйста, введите пароль." - :too-little-data "Слишком мало данных" - :completion-rate "Процент завершённых игр" - :watch "Смотреть" - :join "Войти" - :rejoin "Перезайти" - :as-corp "За Корпорацию" - :as-runner "За Бегущего" - :private "ЗАКРЫТАЯ" - :reset "Сбросить название игры" - :delete "Удалить игру" - :password-for "Пароль для" - :invalid-password "Неправильный пароль" - :not-allowed "Не разрешено" - :aborted "Соединение разорвано" - :game-count (ru-quant "игр" "игра" "игры") - :api-access "Разрешить доступ к данным игры через API" - :api-requires-key "(Требуется ключ API в Настройках)" - :api-access-details "Данная опция даёт доступ к информации о вашей игре расширенияим от сторонних разработчиков. Требует создание ключа API в Настройках." - :filter "Фильтр" - :filtered "(с фильтром)"} - :angel-arena {:cancel-match "Отменить матч" - :claim-victory "Объявить победу" - :still-here "Нужно больше времени" - :abandon-run "Покинуть забег" - :active-corp-run "Активный забег за Корпорацию" - :active-runner-run "Активный забег за Бегущего" - :are-you-sure "Вы уверены?" - :are-you-sure-no "нет" - :are-you-sure-yes "да" - :format "Формат" - :latest-runs "Последние забеги" - :no-eligible-decks "Не найдено легальных колод для этой стороны и формата." - :no-games "Нет игр" - :queue-for-match "Встать в очередь на матч" - :queueing "Встаём в очередь..." - :requesting-run-data "Запрашиваем данные забега..." - :select-deck "Выберите вашу колоду" - :start-new-run "Начать новый забег" - :wins (ru-quant "побед" "победа" "победы")} - :settings {:invalid-password "Неправильный логин или пароль" - :invalid-email "Учётной записи с таким адресом электронной почты не существует" - :updated "Настройки сохранены. Пожалуйста, перезагрузите страницу браузера" - :updating "Сохранение настроек..." - :get-log-width "Записать текущую ширину журнала" - :get-log-top "Записать текущую высоту журнала" - :email-title "Изменить адрес электронной почты" - :current-email "Текущий адрес" - :desired-email "Новый адрес" - :email-placeholder "Адрес электронной почты" - :enter-valid "Пожалуйста, введите корректный адрес электронной почты" - :update "Сохранить" - :cancel "Отмена" - :email "Электронная почта" - :change-email "Изменить адрес электронной почты" - :avatar "Аватар" - :change-avatar "Изменить на gravatar.com" - :pronouns "Местоимения" - :language "Язык" - :sounds "Звуки" - :enable-lobby-sounds "Включить звуки в лобби" - :enable-game-sounds "Включить звуки в игре" - :volume "Громкость" - :layout-options "Настройки расположения" - :player-stats-icons "Использовать иконки в игровой статистике" - :stacked-cards "Складывать вместе одинаковые карты (по умолчанию включено)" - :ghost-trojans "Отображать бледные дубликаты программ-троянов, установленных на карты-носители" - :sides-overlap "Карты Бегущего и Корпорации могут перекрывать друг друга" - :runner-layout "Раскладка Бегущего при игре за Корпорацию" - :runner-classic "Классическая раскладка Бегущего (Сверху вниз: Программы, Устройства, Ресурсы)" - :runner-reverse "Обратная раскладка Бегущего (Сверху вниз: Ресурсы, Устройства, Программы)" - :log-size "Размер журнала" - :log-player-highlight "Подсвечивать игроков в журнале" - :log-player-highlight-red-blue "Корпорация: Синий / Бегущий: Красный" - :log-player-highlight-none "Не подсвечивать" - :card-preview-zoom "Увеличение карт при наведении" - :card-iamge "Показывать изображение карты" - :card-text "Показывать текст карты" - :pin-zoom "Оставлять последнюю увеличенную карту на экране" - :background "Фон игрового поля" - :the-root-bg "The Root" - :freelancer-bg "Freelancer" - :mushin-no-shin-bg "Mushin No Shin" - :traffic-jam-bg "Traffic Jam" - :rumor-mill-bg "Rumor Mill" - :find-the-truth-bg "Find The Truth" - :push-your-luck-bg "Push Your Luck" - :apex-bg "Apex" - :worlds2020-bg "Чемпионат мира 2020" - :monochrome-bg "Монотонный" - :custom-bg "Индивидуальный фон" - :input-url-below "(вставьте ссылку ниже)" - :card-backs "Рубашки карт" - :game-stats "Учёт статистики побед/поражений" - :deck-stats "Учёт статистики колод" - :always "Всегда" - :comp-only "Только в соревновательном лобби" - :none "Не учитывать" - :alt-art "Альтернативные изображения карт" - :show-alt "Показывать альтернативные изображения карт" - :high-res "Включить загрузку изображений высокого разрешения" - :card-images "Изображения карт" - :set-all "Изменить все карты на" - :set "Изменить" - :reset "Сбросить до официальных изображений" - :blocked "Заблокированные пользователи" - :user-name "Имя пользователя" - :block "Заблокировать пользователя" - :update-profile "Сохранить настройки" - :nsg "NSG" - :ffg "FFG" - :api-keys "Ключи API" - :delete-api-key "Удалить" - :create-api-key "Создать ключ API" - :bespoke-sounds-header "Звуки для отдельных карт" - :bespoke-sounds - {:archer "Лучник" - :harmonics "Гармонические льды (Bloop, Echo, Pulse, Wave)" - :end-of-the-line "End of the Line"}} - :ingame-settings {:card-stacking "Настройки карт" - :stack-cards "Складывать одинаковые карты вместе" - :label-unrezzed-cards "Подписывать неразвёрнутые карты" - :label-faceup-cards "Подписывать карты лицом вверх" - :ghost-trojans "Показывать дубликаты троянов в риге" - :card-sorting "Сортировка" - :sort-archives "Отсортировать Архивы" - :sort-heap "Отсортировать Кучу" - :runner-board-order "Раскладка Бегущего" - :runner-classic "Классическая" - :runner-reverse "Обратная" - :board-overlap "Пересечение столов" - :sides-overlap "Карты Бегущего и Корпорации могут пересекаться" - :card-backs "Рубашки" - :preview-zoom "Увеличение карт при наведении" - :card-image "Изображение карты" - :card-text "Текст карты" - :card-images "Изображения карт" - :high-res "Включить изображения высокого разрешения" - :alt-art "Альтернативные изображения" - :show-alt "Показывать альтернативные изображения карт" - :save "Сохранить"} - :stats {:game-stats "Игровая статистика" - :corp-stats "Статистика за Корпорацию" - :runner-stats "Статистика за Бегущего" - :clear-stats "Очистить статистику" - :no-log "Журнал недоступен" - :view-log "Смотреть журнал" - :winner "Победитель" - :no-games "Нет игр" - :all-games "Показать все игры" - :shared-games "Показать игры с публичными записями" - :started "Начато" - :ended "Закончено" - :completed "Завершено" - :not-completed "Не завершено" - :won "Выиграно" - :lost "Проиграно" - :turn-count (ru-quant "ходов" "ход" "хода") - :lobby "Лобби" - :format "Формат" - :win-method "Способ победы" - :view-games "Вернуться к статистике" - :share "Поделиться записью" - :launch "Запустить запись" - :download "Скачать запись" - :unavailable "Запись недоступна" - :filtered "(отфильтровано)" - :log-count (ru-quant "журналов" "журнал" "журнала") - :clicks-gained "Получено кликов" - :credits-gained "Получено кредитов" - :credits-spent "Потрачено кредитов" - :credits-click "Получено кредитов за клики" - :cards-drawn "Взято карт" - :cards-click "Взято карт за клики" - :damage-done "Нанесено урона" - :cards-rezzed "Развёрнуто карт" - :tags-gained "Получено меток" - :runs-made "Совершено забегов" - :shuffle-count "Перемешиваний колоды" - :operations-played "Разыграно операций" - :cards-sabotaged "Сброшено карт от саботажа" - :events-played "Разыграно событий" - :unique-accesses "Уникальных карт в доступе" - :psi-game-total "Пси-игры: Сыграно игр" - :psi-game-total-wins "Пси-игры: Побед" - :psi-game-total-bid-0 "Пси-игры: Ставка 0" - :psi-game-total-bid-1 "Пси-игры: Ставка 1" - :psi-game-total-bid-2 "Пси-игры: Ставка 2" - :rashida-count "Разыграно карт Rashida Jaheem" - :cards-accessed "Карт в доступе"} - :log {:game-log "Журнал" - :settings "Настройки" - :annotating "Аннотации" - :run-timing "Фазы забега" - :turn-timing "Фазы хода" - :shared "Опубликованные аннотации" - :remote-annotations-fail "Не удалось загрузить аннотации."} - :annotations {:turn-placeholder "Заметки к этому ходу" - :click-placeholder "Заметки к этому клику" - :available-annotations "Доступные аннотации" - :no-published-annotations "Нет опубликованных аннотаций." - :publish "Опубликовать" - :import-local "Импортировать файл с аннотациями" - :load-local "Загрузить" - :save-local "Сохранить" - :clear "Очистить локальные аннотации"} - :diagrams {:turn {:corp-turn "Ход Корпорации" - :corp-draw-phase "5.6.1: Фаза добора" - :corp-draw-phase-a "Корпорация получает полагающиеся клики (по умолчанию: [click][click][click])" - :corp-draw-phase-b "Окно платной способности. Корпорация может разворачивать карты, кроме льдов, и засчитывать проекты" - :corp-draw-phase-c "Обновляются возобновляемые кредиты Корпорации" - :corp-draw-phase-d "Ход формально начинается. Срабатывают карты с формулировкой 'в начале хода'" - :corp-draw-phase-e "Корпорация берёт 1 карту с верха R&D" - :corp-draw-phase-f "Перейдите к фазе действий (5.6.2)" - :corp-action-phase "5.6.2: Фаза действий" - :corp-action-phase-a "Окно платной способности. Корпорация может разворачивать карты, кроме льдов, и засчитывать проекты" - :corp-action-phase-b "Если у Корпорации есть непотраченные [Clicks], она совершает действие" - :corp-action-phase-c "Если действие было совершено, вернитесь к (a)" - :corp-action-phase-d "Фаза действий завершена. Перейдите к фазе сброса (5.6.3)" - :corp-discard-phase "5.6.3: Фаза сброса" - :corp-discard-phase-a "Корпорация сбрасывает карты до максимального размера руки при необходимости" - :corp-discard-phase-b "Окно платной способности. Корпорация может разворачивать карты, кроме льдов" - :corp-discard-phase-c "Если у Корпорации остались [Clicks], она теряет эти [Clicks]" - :corp-discard-phase-d "Ход Корпорации формально окончен. Срабатывают карты с формулировкой 'в конце хода'" - :corp-discard-phase-e "Перейдите к ходу Бегущего" - :runner-turn "Ход Бегущего" - :runner-action-phase "5.7.1: Фаза действий" - :runner-action-phase-a "Бегущий получает полагающиеся клики (по умолчанию: [click][click][click][click])" - :runner-action-phase-b "Окно платной способности. Корпорация может разворачивать карты, кроме льдов" - :runner-action-phase-c "Обновляются возобновляемые кредиты Бегущего" - :runner-action-phase-d "Ход формально начинается. Срабатывают карты с формулировкой 'в начале хода'" - :runner-action-phase-e "Окно платной способности. Корпорация может разворачивать карты, кроме льдов" - :runner-action-phase-f "Если у Бегущего есть непотраченные [Clicks], он совершает действие" - :runner-action-phase-g "Если действие было совершено, вернитесь к (e)" - :runner-action-phase-h "Фаза действий завершена. Перейдите к фазе сброса (5.7.2)" - :runner-discard-phase "5.7.2: Фаза сброса" - :runner-discard-phase-a "Бегущий сбрасывает карты до максимального размера руки при необходимости" - :runner-discard-phase-b "Окно платной способности. Корпорация может разворачивать карты, кроме льдов" - :runner-discard-phase-c "Если у Бегущего остались [Clicks], он теряет эти [Clicks]" - :runner-discard-phase-d "Ход Бегущего формально окончен. Срабатывают карты с формулировкой 'в конце хода'" - :runner-discard-phase-e "Перейдите к ходу Корпорации"} - :run-timing {:header "Структура забега" - :disclaimer "Данная схема была упрощена для наглядности. Полные правила можно изучить на сайте Null Signal Games." - :initiation "6.9.1: Фаза инициации" - :initiation-a "Бегущий объявляет сервер" - :initiation-b "Бегущий получает кредиты плохой репутации" - :initiation-c "Забег формально начинается - Срабатывают эффекты событий-забегов" - :initiation-d "Перейдите к внешнему льду при его наличии и начните фазу приближения (6.9.2)" - :initiation-e "В противном случае перейдите к фазе движения (6.9.4)" - :approach "6.9.2: Фаза приближения ко льду" - :approach-a "Вы приближаетесь ко льду. Срабатывают соответствующие эффекты карт" - :approach-b "Окно платной способности. Корпорация может развернуть лёд, к которому приближается Бегущий, а также другие карты, помимо льдов" - :approach-c "Если лёд, к которому приближается Бегущий, развёрнут, перейдите к фазе встречи (6.9.3)" - :approach-d "В противном случае перейдите к фазе движения (6.9.4)" - :encounter "6.9.3: Фаза встречи со льдом" - :encounter-a "Вы встретились с данным льдом. Срабатывают соответствующие эффекты карт" - :encounter-b "Окно платной способности. Бегущий может контактировать со льдом во время этого окна" - :encounter-c "Если остались несломанные подпрограммы, Корпорация выполняет верхнюю несломанную подпрограмму. По завершении повторите этот шаг" - :encounter-d "Встреча завершена. Перейдите к фазе движения (6.9.4)" - :movement "6.9.4: Фаза движения" - :movement-a "Если вы были во встрече со льдом или приближались ко льду, вы его проходите. Срабатывают карты с формулировкой 'при прохождении льда'" - :movement-b "Если между вами и корнем сервера не осталось больше льдов, срабатывают карты с формулировкой 'при прохождении всех льдов на сервере'" - :movement-c "Окно платной способности" - :movement-d "Бегущий может отключиться. Если Бегущий отключился, перейдите к фазе завершения забега (6.9.6)" - :movement-e "Бегущий продвигается на одну позицию по направлению к корню сервера, если это возможно" - :movement-f "Окно платной способности. Корпорация может разворачивать карты, кроме льдов" - :movement-g "Если вы приближаетесь ко льду, перейдите к фазе приближения ко льду (6.9.2)" - :movement-h "Бегущий приближается к атакуемому серверу. Срабатывают соответствующие эффекты карт" - :movement-i "Перейдите к фазе успеха (6.9.5)" - :success "6.9.5: Фаза успеха" - :success-a "Забег объявляется успешным. Срабатывают карты с формулировкой 'при успешном забеге'" - :success-b "Бегущий взламывает атакуемый сервер" - :success-c "Фаза успеха завершена. Перейдите к фазе завершения забега (6.9.6)" - :run-ends "6.9.6: Фаза завершения забега" - :run-ends-a "Все открытые окна приоритета завершаются или закрываются" - :run-ends-b "Бегущий теряет все непотраченные кредиты плохой репутации" - :run-ends-c "Если данной фазе не предшествовала фаза успеха, а сервер всё ещё существует, забег объявляется неуспешным" - :run-ends-d "Забег завершается. Срабатывают карты с формулировкой 'по завершении забега'"}} - :game {:ok "OK" - :error "Внутренняя ошибка сервера. Пожалуйста, напишите /bug в чат и следуйте инструкциям." - :set-aside "Отложить в сторону" - :keep "Оставить" - :mulligan "Пересдать" - :close "Закрыть" - :start "Начать игру" - :remove-tag "Снять метку" - :run "Начать забег" - :purge "Сбросить вирусы" - :trash-resource "Снести ресурс" - :draw "Взять карту" - :gain-credit "Получить кредит" - :game-start "Начало игры" - :start-turn "Начать ход" - :end-turn "Закончить ход" - :mandatory-draw "Карта за начало хода" - :take-clicks "Получить клики" - :hq "HQ" - :grip "Рука" - :rfg "Удалены из игры" - :play-area "Игровая зона" - :current "Течение" - :scored-area "Зона зачёта" - :archives "Архивы" - :max-hand "Макс. размер руки" - :brain-damage (ru-quant "критических уронов" "критический урон" "критического урона") - :tag-count (let [tag-quant (ru-quant "меток" "метка" "метки")] (fn [[base additional]] (str (tag-quant [base]) (when (pos? additional) (str " + " additional))))) - :agenda-count (ru-quant "победных очков" "победное очко" "победных очка") - :link-strength "Мощность канала" - :credit-count (let [credit-quant (ru-quant "кредитов" "кредит" "кредита")] (fn [[credit run-credit]] (str (credit-quant [credit]) (when (pos? run-credit) (str " (" run-credit " для забега)"))))) - :click-count (ru-quant "кликов" "клик" "клика") - :bad-pub-count (let [bp-quant (ru-quant "плохих репутаций" "плохая репутация" "плохих репутации")] (fn [[base additional]] (str (bp-quant [base]) (when (pos? additional) (str " + " additional))))) - :mu-count (fn [[unused available]] (str unused " из " available " свободных ЯП")) - :special-mu-count (fn [[unused available mu-type]] (str unused " из " available " " mu-type " свободных ЯП")) - :indicate-action "Обозначить действие" - :spec-count (ru-quant "зрителей" "зритель" "зрителя") - :spec-view "Перспектива зрителя" - :runner-view "Перспектива Бегущего" - :corp-view "Перспектива Корпорации" - :leave-replay "Выйти из записи" - :leave "Выйти из игры" - :unmute "Включить сообщения зрителей" - :mute "Выключить сообщения зрителей" - :attempt-reconnect "Переподключиться" - :lost-connection, "Утрачено соединени с сервером. Идёт переподключение." - :reconnected-to-server, "Вы переподключены к серверу" - :concede "Сдаться" - :inactivity "Игра закрыта из-за отсутствия активности" - :server "Сервер" - :unimplemented "Не реализовано" - :abilities "Способности" - :subs "Подпрограммы" - :let-subs-fire "Разрешить выполнение несломанных подпрограмм" - :fire-unbroken "Выполнить несломанные подпрограммы" - :actions "Действия" - :stack "Стек" - :r&d "R&D" - :shuffle "Перемешать" - :show "Показать" - :close-shuffle "Закрыть и перемешать" - :heap "Куча" - :card-count (ru-quant "карт" "карта" "карты") - :face-down-count (let [facedown-quant (ru-quant "карт" "карта" "карты")] (fn [[total face-up]] (str (facedown-quant [total]) ", " (- total face-up) " лицом вниз."))) - :up-down-count (fn [[total face-up]] (str face-up "↑ " (- total face-up) "↓")) - :initiation "Инициация" - :approach-ice "Приближение ко льду" - :encounter-ice "Встреча со льдом" - :movement "Движение" - :breach-server "Взломать сервер" - :success "Успех" - :run-ends "Забег завершается" - :no-current-run "Нет активного забега" - :current-phase "Текущая фаза" - :unknown-phase "Неизвестная фаза" - :rez "Развернуть" - :no-further "Нет дальнейших действий" - :continue "Продолжить" - :continue-to "Продолжить к фазе:" - :stop-auto-pass "Прекратить автопередачу приоритета" - :auto-pass "Автопередача приоритета" - :jack-out "Отключиться" - :trace "Отследить" - :beat-trace "Перебить слежку" - :unbeatable "Сделать неперебиваемой" - :credits "кредитов" - :card "Карта" - :minutes "м:" - :seconds "с" - :seconds-remaining "с осталось" - :time-taken (fn [[t]] (str "Затраченное время: " t " минут")) - :win-decked (fn [[turn]] (str "побеждает. Соперник не смог взять карту из R&D на " turn " ходу")) - :win-flatlined (fn [[turn]] (str "побеждает. Соперник получил флетлайн на " turn " ходу")) - :win-conceded (fn [[turn]] (str "побеждает. Соперник сдался на " turn " ходу")) - :win-claimed (fn [[turn]] (str "объявляет победу на " turn " ходу")) - :win-points (fn [[turn]] (str "побеждает, засчитав победные очки на " turn " ходу")) - :win-other (fn [[turn reason]] (str "побеждает из-за " reason " на " turn " ходу"))}}) diff --git a/src/cljc/i18n/zh_simp.cljc b/src/cljc/i18n/zh_simp.cljc deleted file mode 100644 index 969a6fb9ab..0000000000 --- a/src/cljc/i18n/zh_simp.cljc +++ /dev/null @@ -1,807 +0,0 @@ -(ns i18n.zh-simp) - -(def translations - {:missing ":zh-simp missing text" - :side {:corp "公司" - :runner "潜袭者" - :any-side "任意阵营" - :all "全部"} - :faction {:all "全部" - :any-faction "任意派系" - :anarch "反叛者" - :criminal "逆法者" - :shaper "塑造者" - :adam "亚当" - :apex "尖峰" - :sunny-lebeau "桑妮·勒博" - :jinteki "人间会社" - :haas-bioroid "哈斯生化" - :nbn "网际传媒" - :weyland-consortium "威兰财团" - :neutral "中立"} - :format {:all "全部" - :any-format "任意赛制" - :standard "标准" - :eternal "永久" - :core-experience "核心体验" - :snapshot "快照" - :snapshot-plus "快照+" - :socr "SOCR" - :sunset "落日" - :neo "Neo" - :preconstructed "预构筑" - :classic "经典" - :casual "休闲" - :system-gateway "核心网关" - :startup "新启"} - :preconstructed {:worlds-2012-a "Worlds 2012: Ben Marsh (C) vs. Jeremy Zwirn (R)" - :worlds-2012-a-tag "Ben Marsh (C) vs. Jeremy Zwirn (R)" - :worlds-2012-a-ul "Worlds 2012: Weyland vs. Criminal" - :worlds-2012-b "Worlds 2012: Jeremy Zwirn (C) vs. Ben Marsh (R)" - :worlds-2012-b-tag "Jeremy Zwirn (C) vs. Ben Marsh (R)" - :worlds-2012-b-ul "Worlds 2012: Haas-Bioroid vs. Criminal" - :worlds-2012-info "Worlds 2012 was played with (up to 3 copies of) the Core Set as the only legal product. Jeremy Zwirn (Building a Better World, Gabriel Santiago) took first place against Ben Marsh (Engineering the Future, Gabriel Santiago) in the first ever Netrunner World Championship." - :worlds-2013-a "Worlds 2013: Jens Erickson (C) vs. Andrew Veen (R)" - :worlds-2013-a-tag "Jens Erickson (C) vs. Andrew Veen (R)" - :worlds-2013-a-ul "Worlds 2013: HB FastAdv vs. Shaper Katman" - :worlds-2013-b "Worlds 2013: Andrew Veen (C) vs. Jens Erickson (R)" - :worlds-2013-b-tag "Andrew Veen (C) vs. Jens Erickson (R)" - :worlds-2013-b-ul "Worlds 2013: NBN Fast Adv vs. Andy Sucker" - :worlds-2013-info "166 players attended worlds in 2013. The tournament was held in Minneapolis, MN, USA, and consisted of 6 swiss rounds into a top 32 cut. The legal cardpool consisted of cards up to Opening Moves." - :worlds-2014-a "Worlds 2014: Dan D'Argenio (C) vs. Minh Tran (R)" - :worlds-2014-a-tag "Dan D'Argenio (C) vs. Minh Tran (R)" - :worlds-2014-a-ul "Worlds 2014: Honor and Perfection vs. Andromedium" - :worlds-2014-b "Worlds 2014: Minh Tran (C) vs. Dan D'Argenio (R)" - :worlds-2014-b-tag "Minh Tran (C) vs. Dan D'Argenio (R)" - :worlds-2014-b-ul "Worlds 2014: Personal Evolution vs. Daily QT Andy" - :worlds-2014-info "238 players attended worlds in 2014. The tournament was held in Minneapolis, MN, USA, and consisted of 7 swiss rounds into a top 16 cut. The legal cardpool consisted of cards up to Up and Over." - :worlds-2015-a "Worlds 2015: Dan D'Argenio (C) vs. Timmy Wong (R)" - :worlds-2015-a-tag "Dan D'Argenio (C) vs. Timmy Wong (R)" - :worlds-2015-a-ul "Worlds 2015: Foodcoatshop vs. The Morning After" - :worlds-2015-b "Worlds 2015: Timmy Wong (C) vs. Dan D'Argenio (R)" - :worlds-2015-b-tag "Dan D'Argenio (C) vs. Timmy Wong (R)" - :worlds-2015-b-ul "Worlds 2015: Yellow Shell vs. Radisson Cheese Plate" - :worlds-2015-info "269 players attended worlds in 2015. The tournament was held in Minneapolis, MN, USA, and consisted of 8 swiss rounds into a top 16 cut. The legal cardpool consisted of cards up to Data and Destiny." - :worlds-2016-a "Worlds 2016: Chris Dyer (C) vs. Benjamin Ni (R)" - :worlds-2016-a-tag "Chris Dyer (C) vs. Benjamin Ni (R)" - :worlds-2016-a-ul "Worlds 2016: Snekbite vs. Minh MaxX++" - :worlds-2016-b "Worlds 2016: Benjamin Ni (R) vs. Chris Dyer (C)" - :worlds-2016-b-tag "Benjamin Ni (R) vs. Chris Dyer (C)" - :worlds-2016-b-ul "Worlds 2016: Fiery Info vs. Papa Smurf" - :worlds-2016-info "278 players attended worlds in 2016. The tournament was held in Minneapolis, MN, USA, and consisted of 9 swiss rounds into a top 16 cut. The legal cardpool consisted of cards up to Escalation." - :worlds-2017-a "Worlds 2017: Jess Horig (C) vs. Grey Tongue (R)" - :worlds-2017-a-tag "Jess Horig (C) vs. Grey Tongue (R)" - :worlds-2017-a-ul "Worlds 2017: Stinson Reversed CI vs. Aesops Hayley" - :worlds-2017-b "Worlds 2017: Grey Tongue (C) vs. Jess Horig (R)" - :worlds-2017-b-tag "Grey Tongue (C) vs. Jess Horig (R)" - :worlds-2017-b-ul "Worlds 2017: No-Show Rewiring CI vs. Laguna Lock Hayley" - :worlds-2017-info "233 players attended worlds in 2017. The tournament was held in Minneapolis, MN, USA, and consisted of 8(?) swiss rounds into a top 16 cut. The legal cardpool consisted of cards up to the Revised Core set." - :worlds-2018-a "Worlds 2018: Joe Schupp (C) vs. Chris Dyer (R)" - :worlds-2018-a-tag "Joe Schupp (C) vs. Chris Dyer (R)" - :worlds-2018-a-ul "Worlds 2018: AMERICA CtM vs. Gooseberry MaxX" - :worlds-2018-b "Worlds 2018: Chris Dyer (C) vs. Joe Schupp (R)" - :worlds-2018-b-tag "Chris Dyer (C) vs. Joe Schupp (R)" - :worlds-2018-b-ul "Worlds 2018: Trust the Process vs. Dan D'Argenio KoS Val" - :worlds-2018-info "403(!) players attended worlds in 2018. This is the final worlds championship to be run by FFG. The tournament was held in Minneapolis, MN, USA, and consisted of 9(?) swiss rounds into a top 16 cut. The legal cardpool consisted of cards up to Reign and Reverie" - :worlds-2019-a "Worlds 2019: Pinsel (C) vs. Testrunning (R)" - :worlds-2019-a-tag "Pinsel (C) vs. Testrunning (R)" - :worlds-2019-a-ul "Worlds 2019: Fully dedicated to efficiency vs. Trash Panda" - :worlds-2019-b "Worlds 2019: Testrunning (C) vs. Pinsel (R)" - :worlds-2019-b-tag "Testrunning (C) vs. Pinsel (R)" - :worlds-2019-b-ul "Worlds 2019: 2 Grid for 2 Place vs. Trash Panda" - :worlds-2019-info "256 players played in the first even Project NISEI Netrunner World Championship in 2019. This tournament was held in Rotterdam, NL, and consisted of 8(?) swiss rounds into a top 16 cut. The legal cardpool consisted of cards up to the Uprising Booster Pack" - :worlds-2020-a "Worlds 2020: Limes (C) vs. tf34 (R)" - :worlds-2020-a-tag "Limes (C) vs. tf34 (R)" - :worlds-2020-a-ul "Worlds 2020: I don't like this deck vs. Engolo Freedom" - :worlds-2020-b "Worlds 2020: tf34 (R) vs. Limes (C)" - :worlds-2020-b-tag "tf34 (R) vs. Limes (C)" - :worlds-2020-b-ul "Worlds 2020: Malia CTM vs. Imp-pressive Hoshiko" - :worlds-2020-info "294 players played in the first ever online world championship for Netrunner, run by Project NISEI 2020. Due to travel restrictions at the start of the COVID-19 pandemic, this tournament was held online via Jinteki.net, and consisted of 8 swiss rounds on two distinct day-ones, into a top 16 cut. The legal cardpool consisted of cards up to Uprising." - :worlds-2021-a "Worlds 2021: Patrick Gower (C) vs. Jonas (R)" - :worlds-2021-a-tag "Patrick Gower (C) vs. Jonas (R)" - :worlds-2021-a-ul "Worlds 2021: 44 Card PD vs. Watch Me Drip, Watch Me Maemi" - :worlds-2021-b "Worlds 2021: Jonas (C) vs. Patrick Gower (R)" - :worlds-2021-b-tag "Jonas (C) vs. Patrick Gower (R)" - :worlds-2021-b-ul "Worlds 2021: Is Gagarin Good? vs. Medium to Large Maxx" - :worlds-2021-info "201 players played in the second online world championship for Netrunner, run by Project NISEI in 2021. Due to the ongoing disruption caused by the COVID-19 pandemic, this tournament was held online via Jinteki.net, and consisted of 8 swiss rounds on two distinct day-ones, into a top 16 cut. The legal cardpool consisted of cards up to System Gateway." - :worlds-2022-a "Worlds 2022: William Huang (C) vs. skry (R)" - :worlds-2022-a-tag "William Huang (C) vs. skry (R)" - :worlds-2022-a-ul "Worlds 2022: SNACS vs. Liberté, Égalité, Humidité" - :worlds-2022-b "Worlds 2022: skry (C) vs. William Huang (R)" - :worlds-2022-b-tag "skry (C) vs. William Huang (R)" - :worlds-2022-b-ul "Worlds 2022: Dies to Doom Blade vs. ApocoLat" - :worlds-2022-info "158 players played in the first world championship run by Null Signal Games (formerly Project NISEI), which was the first Netrunner world championship to be run in-person since the start of the COVID-19 pandemic. The tournament was held in Toronto, Canada, and consisted of 8(?) rounds into a top 16 cut. The legal cardpool consisted of cards up to Midnight Sun." - :worlds-2023-a "Worlds 2023: William Huang (C) vs. cableCarnage (R)" - :worlds-2023-a-tag "William Huang (C) vs. cableCarnage (R)" - :worlds-2023-a-ul "Worlds 2023: The Worlds Grid vs. sableCarnage" - :worlds-2023-b "Worlds 2023: cableCarnage (C) vs. William Huang (R)" - :worlds-2023-b-tag "cableCarnage (C) vs. William Huang (R)" - :worlds-2023-b-ul "Worlds 2023: tableCarnage vs. You *do* always come back!" - :worlds-2023-info "254 players played in the second Netrunner world championship run by Null Signal Games. The tournament was held in Barcelona, Spain, and consisted of 8 rounds into a top 16 cut. The legal cardpool consisted of cards up to The Automata Initiative."} - :set {:all "全部" - :draft-cycle "轮抽循环" - :draft "轮抽系列" - :core-set "核心系列" - :genesis-cycle "创纪元循环" - :what-lies-ahead "前途未卜" - :trace-amount "重重追踪" - :cyber-exodus "赛博迁徙" - :a-study-in-static "静态研究" - :humanity-s-shadow "人性阴影" - :future-proof "未来考验" - :creation-and-control "创造与掌控" - :spin-cycle "扭曲真相循环" - :opening-moves "起手开局" - :second-thoughts "深思熟虑" - :mala-tempora "脑叶癫痫" - :true-colors "真实面目" - :fear-and-loathing "恐惧与憎恶" - :double-time "双重时刻" - :honor-and-profit "荣誉与利益" - :lunar-cycle "月行循环" - :upstalk "上行之夜" - :the-spaces-between "往来之隙" - :first-contact "初遇之际" - :up-and-over "攀越之路" - :all-that-remains "遗迹之地" - :the-source "代码之源" - :order-and-chaos "秩序与混沌" - :sansan-cycle "圣加州循环" - :the-valley "生科谷" - :breaker-bay "碎浪湾" - :chrome-city "铬金城" - :the-underway "暗底区" - :old-hollywood "老莱坞" - :the-universe-of-tomorrow "未来域" - :data-and-destiny "数据与命运" - :mumbad-cycle "孟巴德循环" - :kala-ghoda "卡拉哥达" - :business-first "商务为先" - :democracy-and-dogma "民主与教条" - :salsette-island "撒尔塞特" - :the-liberated-mind "自由心智" - :fear-the-masses "群众可畏" - :flashpoint-cycle "闪点循环" - :23-seconds "二十三秒" - :blood-money "不义之财" - :escalation "事态升级" - :intervention "介入冲突" - :martial-law "军事管制" - :quorum "共商出路" - :red-sand-cycle "红砂循环" - :daedalus-complex "代达罗斯" - :station-one "一号车站" - :earth-s-scion "地球子孙" - :blood-and-water "水债血偿" - :free-mars "自由火星" - :crimson-dust "绯红之尘" - :terminal-directive-cycle "终极指令循环" - :terminal-directive-cards "终极指令卡牌" - :terminal-directive-campaign "终极指令战役" - :unreleased "未发布" - :revised-core-set "修订版核心系列" - :kitara-cycle "基塔拉循环" - :sovereign-sight "主权之光" - :down-the-white-nile "白尼罗河畔" - :council-of-the-crest "巅峰议会" - :the-devil-and-the-dragon "恶魔与龙" - :whispers-in-nalubaale "纳鲁巴勒低语" - :kampala-ascendent "坎帕拉盛势" - :reign-and-reverie "统治与幻想" - :magnum-opus "巨作" - :napd-multiplayer "NAPD 多人" - :system-core-2019 "系统核心2019" - :ashes-cycle "余烬循环" - :downfall "坍落" - :uprising-booster-pack "起义推广包" - :uprising "起义" - :magnum-opus-reprint "巨作重印版" - :salvaged-memories "唤醒回忆" - :system-gateway "核心网关" - :system-update-2021 "系统革新2021" - :borealis-cycle "北极光循环" - :midnight-sun-booster-pack "极昼推广包" - :midnight-sun "极昼" - :parhelion "幻日" - :liberation-cycle "解放循环" - :the-automata-initiative "自动机倡议" - :rebellion-without-rehearsal "即兴叛乱" - :alt-art "异画系列" - :kysra-alt-arts "Kysra 异画" - :ntscape-navigator-alt-arts "Ntscape Navigator 异画" - :plural-and-miniplural-alt-arts "Plural and MiniPlural 异画" - :alternate "替代" - :world-champion-2015 "世界冠军2015" - :world-champion-2016 "世界冠军2016" - :world-champion-2017 "世界冠军2017" - :championship-2019 "冠军2019" - :gnk-2019 "GNK 2019" - :championship-2020 "冠军2020" - :signed-championship-2020 "签名版冠军2020" - :previous-versions "先前版本"} - :card-type {:all "全部" - :identity "特性(ID)" - :agenda "议案" - :asset "资产" - :upgrade "升级" - :operation "事务" - :ice "防火墙" - :event "事件" - :hardware "硬件" - :resource "资源" - :program "程序"} - :pronouns {:none "未设定" - :any "随意" - :myodb "不愿透露" - :blank "[空白]" - :they "They/them" - :she "她(She/her)" - :shethey "她(She/they)" - :he "他(He/him)" - :hethey "他(He/they)" - :it "它(It)" - :ne "Ne/nem" - :ve "Ve/ver" - :ey "Ey/em" - :zehir "Ze/hir" - :zezir "Ze/zir" - :xe "Xe/xem"} - :chat {:title "在浏览器中玩《安卓纪元:矩阵潜袭》" - :channels "频道" - :send "发送" - :placeholder "说点什么吧" - :delete "删除消息" - :delete-all "删除该用户发送的所有消息" - :block "屏蔽用户" - :cancel "取消" - :message-blocked (fn [[reason-str]] (str "消息堵塞" (when reason-str (str ": " reason-str)))) - :length-exceeded "超出长度" - :rate-exceeded "超出速率"} - :nav {:welcome "欢迎" - :chat "聊天" - :cards "卡牌" - :deck-builder "牌组构筑" - :play "对战" - :help "帮助" - :settings "设置" - :stats "统计" - :about "关于" - :tournaments "比赛" - :admin "网站管理" - :users "用户" - :features "站点功能" - :game-count (fn [[cnt]] (str cnt "局对战"))} - :menu {:settings :zh-simp.nav/settings - :logout "退出" - :admin "网站管理员" - :moderator "管理员" - :donor "捐赠人"} - :card-browser {:implementation-note "实施笔记" - :search-hint "搜索卡牌" - :sort "排序方式" - :format "赛制" - :set "系列" - :side "阵营" - :faction "派系" - :type "类别" - :clear "清除" - :select-art "选择卡面" - :selected-art "已选卡面" - :update-success "卡面已更换" - :update-failure "卡面更换失败" - :memory "内存" - :cost "费用" - :trash-cost "销毁费用" - :strength "强度" - :advancement "推进需求" - :agenda-points "议案分数" - :min-deck "牌组张数下限" - :inf-limit "影响力上限" - :influence "影响力" - :artist-info "艺术家" - :more-info "更多信息" - :sort-by {:faction "派系" - :name "牌名" - :type "类别" - :influence "影响力" - :cost "费用" - :set-number "系列编号"}} - :deck-builder {:loading-msg "牌组加载中……" - :new-corp "新建公司牌组" - :new-runner "新建潜袭者牌组" - :import-button "导入牌组" - :reset "重置" - :import-title "请输入NRDB上公开牌组的ID或URL" - :import "导入" - :cancel "取消" - :import-placeholder "NRDB ID" - :deck-count (fn [[cnt]] (str cnt "套牌组")) - :filtered "(过滤后)" - :save "保存" - :confirm-delete "确认删除" - :edit "编辑" - :delete "删除" - :copy "复制" - :deck-copy-suffix "复制" - :clear-stats "清除统计数据" - :create-game "创建对战" - :new-deck "新建牌组" - :deck-name "牌组名称" - :format "赛制" - :identity "特性(ID)" - :deck-notes "牌组备注" - :decklist "牌表" - :decklist-inst "(在此输入或粘贴牌表,系统会自动解析)" - :notes "备注" - :add-to-deck "添加到牌组" - :add-cards "添加卡牌" - :card-name "卡牌名称" - :no-decks "没有牌组" - :cards "张卡牌" - :min "最少" - :max "最多" - :influence "影响力" - :agenda-points "议案分数" - :deck-points "牌组点数" - :hash "卡组hash(比赛用)" - :why "为什么?" - :legal "可用" - :illegal "不可用" - :games "局数" - :completed "完成" - :won "胜利" - :lost "败北"} - :game-prompt {:trash "销毁" - :advance "推进" - :score "计分" - :rez "激活" - :derez "关闭" - :expend "消耗" - :archives "档案库" - :hq "总部" - :r-d "研发中心" - :new-remote "新远程" - :server-1 "服务器 1" - :server-2 "服务器 2" - :server-3 "服务器 3" - :server-4 "服务器 4" - :server-5 "服务器 5" - :server-6 "服务器 6" - :server-7 "服务器 7" - :server-8 "服务器 8" - :server-9 "服务器 9" - :server-10 "服务器 10"} - :lobby {:no-games "当前无对战" - :tournament "比赛" - :competitive "竞技" - :casual "休闲" - :angel-arena "天使竞技场" - :new-game "新建对战" - :reload "刷新列表" - :load-replay "加载录像" - :start-replay "开始回放" - :save-replay "保存录像" - :create "创建" - :cancel "取消" - :title "房间名" - :side "阵营" - :format "赛制" - :default-game-format "默认游戏赛制" - :gateway-format {:beginner "初学者" - :beginner-info "此大厅为公司和潜袭者使用核心网关初学者牌组而准备。建议你在初次游戏中使用这些牌组。游戏按6点议案分数进行。" - :beginner-ul "核心网关 - 初学者教学牌组" - :intermediate "进阶" - :intermediate-info "此大厅为公司和潜袭者使用核心网关进阶牌组而准备。这些牌组比初学者牌组稍大。游戏按7点议案分数进行。" - :intermediate-ul "核心网关 - 进阶教学牌组" - :constructed "构筑"} - :singleton "单张卡牌" - :singleton-b "(单张卡牌)" - :singleton-details "这将限制牌组中每种同名卡牌仅限1张。建议你使用下列基于此模式的特性ID组建的牌组。" - :singleton-example "1) 复始:触媒&促力 2) 安培:全民的义体" - :singleton-restriction "这局要求为单张卡牌模式。这意味着牌组中每种同名卡牌限1张。" - :options "选项" - :spectators "允许旁观" - :hidden "允许旁观者查看玩家的隐藏信息" - :hidden-details "这将向游戏的所有观众揭示两名玩家的隐藏信息,包括手牌和面朝下的牌。" - :hidden-password "我们建议使用密码来防止陌生人破坏游戏。" - :password-protected "密码保护" - :password "密码" - :timed-game "带有计时器" - :timer-length "计时器长度(分钟)" - :timed-game-details "计时器仅为方便使用:当计时器结束时,游戏不会停止。" - :save-replay-details "这将保存此游戏的回放文件,其中包含公开信息(例如公开手牌)。该文件仅在游戏结束后可用。" - :save-replay-unshared "只会保留你最近的15个未分享游戏,因此请务必在之后下载或分享游戏。" - :save-replay-beta "测试功能:请注意,我们可能会重置已保存的录像,因此请确保下载你想要保留的游戏。此外,请记住,我们可能会在未来对网站进行更改,这可能会使回放不兼容。" - :replay-link-error "录像链接无效。" - :replay-invalid-file "请选择有效的录像文件。" - :corp-perspective "公司视角" - :runner-perspective "潜袭者视角" - :both-perspective "双方视角" - :start "开始" - :leave "离开" - :swap "交换阵营" - :waiting "等待玩家选择牌组" - :players "玩家" - :deck-selected "牌组已选择" - :select-deck "选择牌组" - :chat "聊天" - :select-error "不能选择那个牌组" - :select-title "请选择牌组" - :spectator-count (fn [[cnt]] (str cnt "位观众")) - :closed-msg "房间因长期无活动而关闭" - :title-error "请设置房间名。" - :password-error "请设置密码。" - :too-little-data "数据不足" - :completion-rate "游戏完成率" - :watch "观战" - :join "加入" - :rejoin "重新加入" - :as-corp "作为公司" - :as-runner "作为潜袭者" - :private "私密" - :reset "重置房间名" - :delete "删除房间" - :password-for "请输入房间密码:" - :invalid-password "密码不正确" - :not-allowed "操作被禁止" - :aborted "连接已中断" - :game-count (fn [[cnt]] (str cnt "局对战")) - :api-access "允许 API 访问游戏信息" - :api-requires-key "(需要设置 API 密钥)" - :api-access-details "这允许第三方扩展访问有关你游戏的信息。需要在“设置”中创建API密钥" - :filter "过滤" - :filtered "(过滤后)"} - :angel-arena {:cancel-match "取消匹配" - :claim-victory "宣告胜利" - :still-here "需要更多时间" - :abandon-run "放弃比赛" - :active-corp-run "活跃的公司比赛" - :active-runner-run "活跃的潜袭者比赛" - :are-you-sure "你确定吗?" - :are-you-sure-no "否" - :are-you-sure-yes "是" - :format "赛制" - :latest-runs "最新比赛" - :no-eligible-decks "未找到此阵营与赛制的合法牌组。" - :no-games "没有游戏" - :queue-for-match "排队等待比赛" - :queueing "排队..." - :requesting-run-data "请求潜袭数据..." - :select-deck "选择你的牌组" - :start-new-run "开始新的潜袭" - :wins "胜利"} - :settings {:invalid-password "用户名或密码无效" - :invalid-email "没有使用该邮箱地址的账号" - :updated "设置已保存——请刷新页面" - :updating "设置保存中……" - :get-log-width "获取当前日志框宽度" - :get-log-top "获取当前日志框顶部坐标" - :email-title "更换电子邮件地址" - :current-email "旧邮箱" - :desired-email "新邮箱" - :email-placeholder "电子邮件地址" - :enter-valid "请输入合法的电子邮件地址" - :update "更换" - :cancel "取消" - :email "电子邮箱" - :change-email "更换电子邮箱" - :avatar "头像" - :change-avatar "在gravatar.com上更换" - :pronouns "代词" - :language "语言" - :sounds "音效" - :enable-lobby-sounds "开启大厅内音效" - :enable-game-sounds "开启游戏内音效" - :volume "音量" - :layout-options "布局选项" - :player-stats-icons "使用图标显示玩家统计" - :stacked-cards "默认启用服务器堆叠" - :ghost-trojans "对于被负载的程序显示鬼影" - :sides-overlap "潜袭者和公司面板可以重叠" - :runner-layout "潜袭者布局(公司视角)" - :runner-classic "经典jnet布局(自上而下:程序、硬件、资源)" - :runner-reverse "反转布局(自上而下:资源、硬件、程序)" - :log-size "日志栏尺寸" - :log-player-highlight "日志玩家高亮" - :log-player-highlight-red-blue "公司:蓝色 / 潜袭者:红色" - :log-player-highlight-none "无" - :card-preview-zoom "卡牌预览缩放" - :card-iamge "卡牌图像" - :card-text "卡牌文本" - :pin-zoom "在屏幕上保持缩放卡牌" - :background "游戏背景" - :the-root-bg "根基" - :freelancer-bg "自由职业者" - :mushin-no-shin-bg "无心之心" - :traffic-jam-bg "交通阻塞" - :rumor-mill-bg "谣言工厂" - :find-the-truth-bg "找出真相" - :push-your-luck-bg "豪赌一把" - :apex-bg "尖峰" - :worlds2020-bg "世界2020" - :monochrome-bg "纯黑" - :custom-bg "自定义背景" - :input-url-below "(在下方输入URL)" - :card-backs "卡背" - :game-stats "对战胜负统计" - :deck-stats "牌组统计" - :always "总是" - :comp-only "仅竞技厅" - :none "关闭" - :alt-art "异画卡" - :show-alt "显示异画卡" - :high-res "启用高分辨率卡牌图像" - :card-images "卡牌图像" - :set-all "将所有卡牌设为" - :set "设置" - :reset "将所有卡牌重设为原始卡面" - :blocked "黑名单" - :user-name "用户名" - :block "屏蔽" - :update-profile "保存设置" - :nsg "NSG" - :ffg "FFG" - :api-keys "API密钥" - :delete-api-key "删除" - :create-api-key "创建API密钥" - :bespoke-sounds-header "卡牌特定声音" - :bespoke-sounds - {:archer "射手" - :harmonics "和声组合(海洋怪声,回声,脉动,波动)" - :end-of-the-line "穷途末路"}} - :ingame-settings {:card-stacking "卡牌设置" - :stack-cards "启用服务器堆叠" - :label-unrezzed-cards "贴标签于未激活卡牌" - :label-faceup-cards "贴标签于面朝上卡牌" - :ghost-trojans "对于被负载的程序显示鬼影" - :card-sorting "排序" - :sort-archives "排序档案库" - :sort-heap "排序堆阵" - :runner-board-order "潜袭者面板顺序" - :runner-classic "经典" - :runner-reverse "反转" - :board-overlap "面板重叠" - :sides-overlap "潜袭者和公司面板可以重叠" - :card-backs "卡背" - :preview-zoom "卡牌预览缩放" - :card-image "卡牌图像" - :card-text "卡牌文本" - :card-images "卡牌图像" - :high-res "启用高分辨率卡牌图像" - :alt-art "异画卡" - :show-alt "显示异画卡" - :save "保存"} - :stats {:game-stats "胜负统计" - :corp-stats "公司统计" - :runner-stats "潜袭者统计" - :clear-stats "清除统计数据" - :no-log "无日志信息" - :view-log "查看记录" - :winner "胜者" - :no-games "没有对战记录" - :all-games "显示所有记录" - :shared-games "只显示已分享的录像" - :started "开始" - :ended "结束时间" - :completed "完成" - :not-completed "未完成" - :won "胜利" - :lost "败北" - :turn-count (fn [[cnt]] (str cnt "个回合")) - :lobby "大厅" - :format "赛制" - :win-method "胜利方式" - :view-games "返回统计界面" - :share "分享录像" - :launch "播放录像" - :download "下载录像" - :unavailable "未保存录像" - :filtered "(过滤后)" - :log-count (fn [[cnt]] (str cnt "条记录")) - :clicks-gained "获得时点数量" - :credits-gained "获得信用点数量" - :credits-spent "支付信用点数量" - :credits-click "手动获取信用点数量" - :cards-drawn "抽牌数量" - :cards-click "手动抽牌数量" - :damage-done "造成伤害量" - :cards-rezzed "激活卡牌数量" - :tags-gained "获得锁定标记数量" - :runs-made "潜袭次数" - :shuffle-count "洗牌次数" - :operations-played "事务打出数量" - :cards-sabotaged "破坏次数" - :events-played "事件打出数量" - :unique-accesses "读取独有卡牌数量" - :psi-game-total "灵能赌博:赌博次数" - :psi-game-total-wins "灵能赌博:胜利次数" - :psi-game-total-bid-0 "灵能赌博:出价0次数" - :psi-game-total-bid-1 "灵能赌博:出价1次数" - :psi-game-total-bid-2 "灵能赌博:出价2次数" - :rashida-count "拉什达次数" - :cards-accessed "读取卡牌数量"} - :log {:game-log "游戏日志" - :settings "设置" - :annotating "注释" - :run-timing "潜袭时序" - :turn-timing "回合时序" - :shared "共享注释" - :remote-annotations-fail "无法获取远程注释。"} - :annotations {:turn-placeholder "关于此回合的注释" - :click-placeholder "关于此点击的注释" - :available-annotations "可用注释" - :no-published-annotations "没有已发布的注释。" - :import-local "导入本地注释文件" - :load-local "加载" - :save-local "保存" - :publish "发布" - :clear "清除本地注释"} - :diagrams {:turn {:corp-turn "公司回合" - :corp-draw-phase "5.6.1: 抽牌阶段" - :corp-draw-phase-a "公司获得可用时点(默认: [click][click][click])" - :corp-draw-phase-b "付费能力窗口。公司可以激活非防火墙卡牌和/或计分议案" - :corp-draw-phase-c "公司填充可再生信用点" - :corp-draw-phase-d "回合正式开始。回合开始事件结算" - :corp-draw-phase-e "公司执行强制抽牌" - :corp-draw-phase-f "进入到行动阶段(5.6.2)" - :corp-action-phase "5.6.2: 行动阶段" - :corp-action-phase-a "付费能力窗口。公司可以激活非防火墙卡牌和/或计分议案" - :corp-action-phase-b "如果公司有未使用的[Clicks],进行一个行动" - :corp-action-phase-c "如果一个行动已发生,返回到(a)" - :corp-action-phase-d "行动阶段完成。进入到弃牌阶段(5.6.3)" - :corp-discard-phase "5.6.3: 弃牌阶段" - :corp-discard-phase-a "如可能,公司弃牌至手牌上限" - :corp-discard-phase-b "付费能力窗口。公司可以激活非防火墙卡牌" - :corp-discard-phase-c "如果公司有任何[Clicks]剩余,则失去这些[Clicks]" - :corp-discard-phase-d "公司回合正式结束。回合结束触发效果结算" - :corp-discard-phase-e "进入到潜袭者回合" - :runner-turn "潜袭者回合" - :runner-action-phase "5.7.1: 行动阶段" - :runner-action-phase-a "潜袭者获得可用时点(默认: [click][click][click][click])" - :runner-action-phase-b "付费能力窗口。公司可以激活非防火墙卡牌" - :runner-action-phase-c "潜袭者填充可再生信用点" - :runner-action-phase-d "回合正式开始。回合开始事件结算" - :runner-action-phase-e "付费能力窗口。公司可以激活非防火墙卡牌" - :runner-action-phase-f "如果潜袭者有未使用的[Clicks],进行一个行动" - :runner-action-phase-g "如果一个行动已发生,返回到(e)" - :runner-action-phase-h "行动阶段完成。进入到弃牌阶段(5.7.2)" - :runner-discard-phase "5.7.2: 弃牌阶段" - :runner-discard-phase-a "如可能,潜袭者弃牌至手牌上限" - :runner-discard-phase-b "付费能力窗口。公司可以激活非防火墙卡牌" - :runner-discard-phase-c "如果潜袭者有任何[Clicks]剩余,则失去这些[Clicks]" - :runner-discard-phase-d "潜袭者回合正式结束。回合结束触发效果结算" - :runner-discard-phase-e "进入到公司回合"} - :run-timing {:header "潜袭时序图" - :disclaimer "为了清晰起见,该时序图已被简化。如需完整规则,请参阅“Null Signal Games”网站。" - :initiation "6.9.1: 发起阶段" - :initiation-a "潜袭者宣布攻击的服务器" - :initiation-b "潜袭者获得负面声誉信用点" - :initiation-c "潜袭正式开始 —— 潜袭事件结算" - :initiation-d "如可能,接驳最外层的防火墙,并开始接驳阶段(6.9.2)" - :initiation-e "否则,进入到移动阶段(6.9.4)" - :approach "6.9.2: 接驳防火墙阶段" - :approach-a "潜袭者接驳所在位置的防火墙。接驳事件结算" - :approach-b "付费能力窗口。公司可以激活非防火墙卡牌和/或潜袭者接驳的防火墙。" - :approach-c "如果接驳的防火墙已激活,继续到遭遇阶段(6.9.3)" - :approach-d "否则,进入到移动阶段(6.9.4)" - :encounter "6.9.3: 遭遇防火墙阶段" - :encounter-a "潜袭者遭遇所在位置的防火墙。遭遇事件结算" - :encounter-b "付费能力窗口。可以与所遭遇的防火墙进行交互。" - :encounter-c "如果有需要结算的未破解子进程,公司会至上而下依次结算未破解子进程。" - :encounter-d "遭遇完成。进入到移动阶段(6.9.4)" - :movement "6.9.4: 移动阶段" - :movement-a "如果潜袭者从接驳阶段或遭遇阶段到达此阶段,则通过防火墙。通过防火墙事件结算" - :movement-b "如果潜袭者与服务器之间没有防火墙,‘当你通过服务器上的所有防火墙’事件结算" - :movement-c "付费能力窗口" - :movement-d "潜袭者可以退出。如这样做, 进入到潜袭结束阶段(6.9.6)" - :movement-e "如可能,潜袭者向内移动1位置" - :movement-f "付费能力窗口。公司可以激活非防火墙卡牌" - :movement-g "如果潜袭者接驳另一个防火墙,返回到接驳阶段(6.9.2)" - :movement-h "潜袭者接驳攻击的服务器。接驳事件结算" - :movement-i "继续到成功阶段(6.9.5)" - :success "6.9.5: 成功阶段" - :success-a "此潜袭声明为成功。潜袭成功事件结算" - :success-b "潜袭者侵入服务器" - :success-c "成功阶段完成。继续到潜袭结束阶段(6.9.6)" - :run-ends "6.9.6: 潜袭结束阶段" - :run-ends-a "任何打开的优先权窗口结算或关闭" - :run-ends-b "潜袭者失去未花费的负面声誉信用" - :run-ends-c "如果未达到成功阶段且攻击的服务器仍然存在,潜袭声明为失败" - :run-ends-d "潜袭结束。潜袭结束事件结算"}} - :game {:ok "OK" - :error "内部服务器错误。请在聊天中键入/bug并按照说明操作。" - :set-aside "设置一旁" - :keep "保留" - :mulligan "调度" - :close "关闭" - :start "开始对战" - :remove-tag "移除锁定标记" - :run "潜袭" - :purge "清除病毒指示物" - :trash-resource "销毁资源" - :draw "抽牌" - :gain-credit "获得信用点" - :game-start "对战开始时间" - :start-turn "开始回合" - :end-turn "结束回合" - :mandatory-draw "回合开始抽牌" - :take-clicks "进入行动阶段" - :hq "总部" - :grip "操控器" - :rfg "移出游戏" - :play-area "出牌区" - :current "局势" - :scored-area "计分区" - :archives "档案库" - :max-hand "手牌上限" - :brain-damage "脑部伤害" - :tag-count (fn [[base additional total]] (str base (when (pos? additional) (str " + " additional)) " 锁定标记")) - :agenda-count (fn [[agenda-point]] (str agenda-point " 议案分数")) - :link-strength "中转强度" - :credit-count (fn [[credit run-credit]] (str credit " 信用点" (when (pos? run-credit) (str " (" run-credit "个本次潜袭专用)")))) - :click-count (fn [[click]] (str click " 时点")) - :bad-pub-count (fn [[base additional]] (str base (when (pos? additional) (str " + " additional)) " 负面声誉")) - :mu-count (fn [[unused available]] (str unused " / " available " 空闲内存")) - :special-mu-count (fn [[unused available mu-type]] (str unused " / " available " " mu-type " 空闲内存")) - :indicate-action "我要响应" - :spec-count (fn [[c]] (str c " 位观众")) - :spec-view "旁观者视图" - :runner-view "潜袭者视图" - :corp-view "公司视图" - :leave-replay "关闭回放" - :leave "离开对战" - :unmute "允许旁观者发言" - :mute "禁止旁观者发言" - :attempt-reconnect "尝试重新连接" - :lost-connection, "与服务器的连接中断。重新连接。" - :reconnected-to-server, "已重新连接到服务器" - :concede "投降" - :inactivity "对战因长期无活动而关闭" - :server "服务器" - :unimplemented "功能未实现" - :abilities "能力" - :subs "子进程" - :let-subs-fire "让公司结算子进程" - :fire-unbroken "结算未破解的子进程" - :actions "操作" - :stack "存储栈" - :r&d "研发中心" - :shuffle "洗牌" - :show "显示" - :close-shuffle "关闭并洗牌" - :heap "堆阵" - :card-count (fn [[size]] (str size "张卡牌。")) - :face-down-count (fn [[total face-up]] (str total "张卡牌," (- total face-up) "张牌面朝下。")) - :up-down-count (fn [[total face-up]] (str face-up "↑ " (- total face-up) "↓")) - :initiation "发起潜袭" - :approach-ice "接驳防火墙" - :encounter-ice "遭遇防火墙" - :movement "移动" - :breach-server "侵入服务器" - :success "成功" - :run-ends "潜袭结束" - :no-current-run "当前无潜袭进行中" - :current-phase "当前阶段" - :unknown-phase "未知阶段" - :rez "激活" - :no-further "没有响应" - :continue "继续" - :continue-to "继续:" - :stop-auto-pass "取消自动让过优先权" - :auto-pass "自动让过优先权" - :jack-out "退出潜袭" - :trace "追踪强度" - :beat-trace "击败追踪" - :unbeatable "使不可击败" - :credits "个信用点" - :card "卡牌" - :minutes "分:" - :seconds "秒" - :seconds-remaining "秒剩余" - :time-taken (fn [[t]] (str "对战用时:" t "分钟")) - :win-decked (fn [[turn]] (str "于第" turn "回合因公司无牌可抽而获胜")) - :win-flatlined (fn [[turn]] (str "于第" turn "回合通过杀死潜袭者而获胜")) - :win-conceded (fn [[turn]] (str "于第" turn "回合因对手投降而获胜")) - :win-claimed (fn [[turn]] (str "于第" turn "回合因声明而获胜")) - :win-points (fn [[turn]] (str "于第" turn "回合因议案分数而获胜")) - :win-other (fn [[turn reason]] (str "于第" turn "回合因" reason "而获胜"))}}) diff --git a/src/cljc/jinteki/i18n.cljc b/src/cljc/jinteki/i18n.cljc new file mode 100644 index 0000000000..1066155ce1 --- /dev/null +++ b/src/cljc/jinteki/i18n.cljc @@ -0,0 +1,68 @@ +(ns jinteki.i18n + (:refer-clojure :exclude [format]) + (:require + [noahtheduke.fluent :as fluent] + #?@(:clj [[clojure.java.io :as io] + [clojure.string :as str]]) + #?(:cljs + [reagent.core :as r]))) + +(defonce fluent-dictionary + #?(:clj (atom nil) + :cljs (r/atom {}))) + +(defn insert-lang! [lang content] + (swap! fluent-dictionary assoc lang {:content content + :ftl (let [lang (if (= "la-pig" lang) "en" lang)] + (fluent/build lang content))})) + +#?(:clj + (defn load-dictionary! + [dir] + (let [langs (->> (io/file dir) + (file-seq) + (filter #(.isFile ^java.io.File %)) + (filter #(str/ends-with? (str %) ".ftl")) + (map (fn [^java.io.File f] + (let [n (str/replace (.getName f) ".ftl" "") + content (slurp f)] + [n content])))) + errors (volatile! [])] + (doseq [[lang content] langs] + (try (insert-lang! lang content) + (catch Throwable t + (println "Error inserting i18n data for" lang) + (println (ex-message t)) + (vswap! errors conj lang)))) + @errors))) + +#?(:clj + (comment + (load-dictionary! "resources/public/i18n"))) + +(defn get-content + [lang] + (get-in @fluent-dictionary [lang :content])) + +(defn get-bundle + [lang] + (get-in @fluent-dictionary [lang :ftl])) + +(defn get-translation + [bundle id params] + (when bundle + (when-let [ret (fluent/format bundle id params)] + (when-not (identical? "undefined" ret) + ret)))) + +(defn format + ([lang-cursor resource] (format lang-cursor resource nil)) + ([lang-cursor resource params] + (let [lang (or @lang-cursor "en") + resource (if (vector? resource) resource [resource]) + [raw-id fallback] resource + id (name raw-id) + bundle (get-bundle lang)] + (or (get-translation bundle id params) + fallback + (get-translation (get-bundle "en") id params))))) diff --git a/src/cljs/nr/account.cljs b/src/cljs/nr/account.cljs index eaef19038f..682b761e04 100644 --- a/src/cljs/nr/account.cljs +++ b/src/cljs/nr/account.cljs @@ -5,6 +5,7 @@ [clojure.string :as s] [goog.dom :as gdom] [jinteki.cards :refer [all-cards]] + [medley.core :as m] [nr.ajax :refer [DELETE GET POST PUT]] [nr.appstate :refer [app-state]] [nr.auth :refer [valid-email?]] @@ -13,87 +14,110 @@ [nr.translations :refer [tr tr-format]] [nr.utils :refer [format-date-time ISO-ish-formatter non-game-toast set-scroll-top slug->format store-scroll-top]] + [jinteki.i18n :as i18n] [reagent-modals.modals :as reagent-modals] [reagent.core :as r])) (defn post-response [s response] (case (:status response) - 401 (non-game-toast (tr [:settings.invalid-password "Invalid login or password"]) "error" nil) - 404 (non-game-toast (tr [:settings.invalid-email "No account with that email address exists"]) "error" nil) + 401 (non-game-toast (tr [:settings_invalid-password "Invalid login or password"]) "error" nil) + 404 (non-game-toast (tr [:settings_invalid-email "No account with that email address exists"]) "error" nil) ;; else - (non-game-toast (tr [:settings.updated "Profile updated - Please refresh your browser"]) "success" nil)) + (do (when-let [json (:json response)] + (when (and (:lang json) (:content json)) + (i18n/insert-lang! (:lang json) (:content json)))) + (non-game-toast (tr [:settings_updated "Profile updated - Please refresh your browser"]) "success" nil))) (swap! s assoc :flash-message "")) -(defn post-options [url callback] - (let [params (:options @app-state)] - (go (let [response ( js/document .-location (.reload true)) (swap! email-state assoc :flash-message message)))))))} (when-let [email (:email @s)] - [:p [:label.email (tr [:settings.current-email "Current email"]) ": "] + [:p [:label.email (tr [:settings_current-email "Current email"]) ": "] [:input.email {:type "text" :value email :name "current-email" :read-only true}]]) - [:p [:label.email (tr [:settings.desired-email "Desired email"]) ": "] + [:p [:label.email (tr [:settings_desired-email "Desired email"]) ": "] [:input.email {:type "text" - :placeholder (tr [:settings.email-placeholder "Email address"]) + :placeholder (tr [:settings_email-placeholder "Email address"]) :name "email" :on-change #(let [value (-> % .-target .-value)] (swap! email-state assoc :email value)) :on-blur #(if (valid-email? (-> % .-target .-value)) (swap! email-state assoc :flash-message "") (swap! email-state assoc - :flash-message (tr [:settings.enter-valid "Please enter a valid email address"])))}]] + :flash-message (tr [:settings_enter-valid "Please enter a valid email address"])))}]] [:p.float-right (let [disabled (not (valid-email? (:email @email-state)))] [:button {:disabled disabled :class (when disabled "disabled")} - (tr [:settings.update "Update"])]) + (tr [:settings_update "Update"])]) [:button {:on-click #(do (.preventDefault %) (reagent-modals/close-modal!))} - (tr [:settings.cancel "Cancel"])]]]]))) + (tr [:settings_cancel "Cancel"])]]]]))) (defn- update-api-keys-response [response s] (let [status (:status response)] @@ -235,7 +259,7 @@ (defn- api-keys [s] (r/with-let [keys-cursor (r/cursor s [:api-keys])] [:section - [:h3 (tr [:settings.api-keys "API Keys"])] + [:h3 (tr [:settings_api-keys "API Keys"])] [:div.news-box.panel.blue-shade [:ul.list (doall @@ -246,13 +270,49 @@ [:button.delete {:on-click #(do (.preventDefault %) (delete-api-key (:_id d) s))} - (tr [:settings.delete-api-key "Delete"])]] + (tr [:settings_delete-api-key "Delete"])]] [:span.date (format-date-time ISO-ish-formatter (:date d))] [:span.title (:api-key d "")]]))]] [:button {:on-click #(do (.preventDefault %) (create-api-key s))} - (tr [:settings.create-api-key "Create API Key"])]])) + (tr [:settings_create-api-key "Create API Key"])]])) + +(def pronoun-list + [["Unspecified" "none"] + ["Any" "any"] + ["Prefer not to say" "myodb"] + ["[blank]" "blank"] + ["They/them" "they"] + ["She/her" "she"] + ["She/it" "sheit"] + ["She/they" "shethey"] + ["He/him" "he"] + ["He/it" "heit"] + ["He/they" "hethey"] + ["He/She/they" "heshe"] + ["It" "it"] + ["Fae/faer" "faefaer"] + ["Ne/nem" "ne"] + ["Ve/ver" "ve"] + ["Ey/em" "ey"] + ["Ze/hir" "zehir"] + ["Ze/zir" "zezir"] + ["Xe/xem" "xe"] + ["Xi/xir" "xi"]]) + +(def background-list + [["Apex" "apex"] + ["Custom BG (input URL below)" "custom"] + ["Find The Truth" "find-the-truth"] + ["Freelancer" "freelancer"] + ["Monochrome" "monochrome"] + ["Mushin No Shin" "mushin-no-shin"] + ["Push Your Luck" "push-your-luck"] + ["Rumor Mill" "rumor-mill"] + ["The Root" "the-root"] + ["Traffic Jam" "traffic-jam"] + ["Worlds 2020" "worlds2020"]]) (defn account-content [_ _ scroll-top] (r/create-class @@ -262,49 +322,33 @@ :reagent-render (fn [user s _] [:div#profile-form.panel.blue-shade.content-page {:ref "profile-form"} - [:h2 (tr [:nav.settings "Settings"])] - [:form {:on-submit #(handle-post % "/profile" s)} - [:button.float-right (tr [:settings.update-profile "Update Profile"])] + [:h2 (tr [:nav_settings "Settings"])] + [:form {:on-submit #(handle-post % s)} + [:button.float-right (tr [:settings_update-profile "Update Profile"])] [:section - [:h3 (tr [:settings.email "Email"])] - [:a {:href "" :on-click #(do - (.preventDefault %) - (reagent-modals/modal! [change-email s]))} (tr [:settings.change-email "Change email"])]] + [:h3 (tr [:settings_email "Email"])] + [:a {:href "" + :on-click #(do + (.preventDefault %) + (reagent-modals/modal! [change-email s]))} + (tr [:settings_change-email "Change email"])]] [:section - [:h3 (tr [:settings.avatar "Avatar"])] + [:h3 (tr [:settings_avatar "Avatar"])] [avatar @user {:opts {:size 38}}] - [:a {:href "http://gravatar.com" :target "_blank"} (tr [:settings.change-avatar "Change on gravatar.com"])]] + [:a {:href "http://gravatar.com" :target "_blank"} + (tr [:settings_change-avatar "Change on gravatar.com"])]] [:section - [:h3 (tr [:settings.pronouns "Pronouns"])] + [:h3 (tr [:settings_pronouns "Pronouns"])] [:select {:value (:pronouns @s "none") :on-change #(swap! s assoc :pronouns (.. % -target -value))} (doall - (for [option [{:name (tr [:pronouns.none "Unspecified"]) :ref "none"} - {:name (tr [:pronouns.any "Any"]) :ref "any"} - {:name (tr [:pronouns.myodb "Prefer not to say"]) :ref "myodb"} - {:name (tr [:pronouns.blank "[blank]"]) :ref "blank"} - {:name (tr [:pronouns.they "They/them"]) :ref "they"} - {:name (tr [:pronouns.she "She/her"]) :ref "she"} - {:name (tr [:pronouns.sheit "She/it"]) :ref "sheit"} - {:name (tr [:pronouns.shethey "She/they"]) :ref "shethey"} - {:name (tr [:pronouns.he "He/him"]) :ref "he"} - {:name (tr [:pronouns.heit "He/it"]) :ref "heit"} - {:name (tr [:pronouns.hethey "He/they"]) :ref "hethey"} - {:name (tr [:pronouns.heshe "He/She/they"]) :ref "heshe"} - {:name (tr [:pronouns.it "It"]) :ref "it"} - {:name (tr [:pronouns.ne "Fae/faer"]) :ref "faefaer"} - {:name (tr [:pronouns.ne "Ne/nem"]) :ref "ne"} - {:name (tr [:pronouns.ve "Ve/ver"]) :ref "ve"} - {:name (tr [:pronouns.ey "Ey/em"]) :ref "ey"} - {:name (tr [:pronouns.zehir "Ze/hir"]) :ref "zehir"} - {:name (tr [:pronouns.zezir "Ze/zir"]) :ref "zezir"} - {:name (tr [:pronouns.xe "Xe/xem"]) :ref "xe"} - {:name (tr [:pronouns.xi "Xi/xir"]) :ref "xi"}]] - [:option {:value (:ref option) :key (:ref option)} (:name option)]))] + (for [[title ref] pronoun-list] + [:option {:value ref :key ref} + (tr [:pronouns title] {:pronoun ref})]))] [:div "If your personal pronouns are not represented, you can request them " [:a {:href "https://github.com/mtgred/netrunner/issues"} "here"]]] [:section - [:h3 (tr [:settings.language "Language"])] + [:h3 (tr [:settings_language "Language"])] [:select {:value (:language @s "en") :on-change #(swap! s assoc :language (.. % -target -value))} (doall @@ -317,36 +361,37 @@ {:name "日本語" :ref "ja"} {:name "한국어" :ref "ko"} {:name "Polski" :ref "pl"} - {:name "Igpay Atinlay" :ref "la-pig"} {:name "Português" :ref "pt"} - {:name "Русский" :ref "ru"}]] + {:name "Русский" :ref "ru"} + {:name "Igpay Atinlay" :ref "la-pig"}]] [:option {:value (:ref option) :key (:ref option)} (:name option)]))]] [:section - [:h3 (tr [:settings.sounds "Sounds"])] + [:h3 (tr [:settings_sounds "Sounds"])] [:div [:label [:input {:type "checkbox" :value true :checked (:lobby-sounds @s) - :on-change #(swap! s assoc-in [:lobby-sounds] (.. % -target -checked))}] - (tr [:settings.enable-lobby-sounds "Enable lobby sounds"])]] + :on-change #(swap! s assoc :lobby-sounds (.. % -target -checked))}] + (tr [:settings_enable-lobby-sounds "Enable lobby sounds"])]] [:div [:label [:input {:type "checkbox" :value true :checked (:sounds @s) - :on-change #(swap! s assoc-in [:sounds] (.. % -target -checked))}] - (tr [:settings.enable-game-sounds "Enable game sounds"])]] - [:div (tr [:settings.volume "Volume"]) + :on-change #(swap! s assoc :sounds (.. % -target -checked))}] + (tr [:settings_enable-game-sounds "Enable game sounds"])]] + [:div (tr [:settings_volume "Volume"]) [:input {:type "range" :min 1 :max 100 :step 1 :on-mouse-up #(play-sfx [(random-sound)] {:volume (int (.. % -target -value))}) - :on-change #(swap! s assoc-in [:volume] (.. % -target -value)) + :on-change #(swap! s assoc :volume (.. % -target -value)) :value (or (:volume @s) 50) :disabled (not (or (:sounds @s) (:lobby-sounds @s)))}]]] [:section - [:h3 (tr [:settings.bespoke-sounds-header "Card-Specific Sounds"])] + [:h3 (tr [:settings_bespoke-sounds "Card-Specific Sounds"] {:sound "header"})] (doall - (for [grouping (distinct (map :grouping (vals bespoke-sounds)))] + (for [grouping (distinct (map :grouping (vals bespoke-sounds))) + :let [group-name (name grouping)]] ^{:key grouping} [:div [:label [:input {:type "checkbox" @@ -354,61 +399,63 @@ :checked (get-in @s [:bespoke-sounds grouping]) :on-change #(let [checked (.. % -target -checked)] (when checked - (play-sfx [(select-random-from-grouping grouping)] {:volume (or (:volume @s) 50) :force true})) + (play-sfx [(select-random-from-grouping grouping)] + {:volume (or (:volume @s) 50) + :force true})) (swap! s assoc-in [:bespoke-sounds grouping] checked))}] - (tr [(keyword (str "settings.bespoke-sounds." (name grouping))) (name grouping)])]]))] + (tr [:settings_bespoke-sounds group-name] {:sound group-name})]]))] [:section - [:h3 (tr [:lobby.default-game-format "Default game format"])] + [:h3 (tr [:lobby_default-game-format "Default game format"])] [:select.format {:value (or (:default-format @s) "standard") - :on-change #(swap! s assoc-in [:default-format] (.. % -target -value))} + :on-change #(swap! s assoc :default-format (.. % -target -value))} (doall (for [[k v] slug->format] ^{:key k} [:option {:value k} (tr-format v)]))]] [:section - [:h3 (tr [:settings.layout-options "Layout options"])] + [:h3 (tr [:settings_layout-options "Layout options"])] [:div [:label [:input {:type "checkbox" :value true :checked (:player-stats-icons @s) - :on-change #(swap! s assoc-in [:player-stats-icons] (.. % -target -checked))}] - (tr [:settings.player-stats-icons "Use icons for player stats"])]] + :on-change #(swap! s assoc :player-stats-icons (.. % -target -checked))}] + (tr [:settings_player-stats-icons "Use icons for player stats"])]] [:div [:label [:input {:type "checkbox" :value true :checked (:stacked-cards @s) - :on-change #(swap! s assoc-in [:stacked-cards] (.. % -target -checked))}] - (tr [:settings.stacked-cards "Card stacking (on by default)"])]] + :on-change #(swap! s assoc :stacked-cards (.. % -target -checked))}] + (tr [:settings_stacked-cards "Card stacking (on by default)"])]] [:div [:label [:input {:type "checkbox" :value true :checked (:ghost-trojans @s) - :on-change #(swap! s assoc-in [:ghost-trojans] (.. % -target -checked))}] - (tr [:settings.display-encounter-info "Display ghosts for hosted programs"])]] + :on-change #(swap! s assoc :ghost-trojans (.. % -target -checked))}] + (tr [:settings_ghost-trojans "Display ghosts for hosted programs"])]] [:div [:label [:input {:type "checkbox" :value true :checked (:display-encounter-info @s) - :on-change #(swap! s assoc-in [:display-encounter-info] (.. % -target -checked))}] - (tr [:settings.display-encounter-info "Always display encounter info dialog"])]] + :on-change #(swap! s assoc :display-encounter-info (.. % -target -checked))}] + (tr [:settings_display-encounter-info "Always display encounter info"])]] [:div [:label [:input {:type "checkbox" :value true :checked (:sides-overlap @s) - :on-change #(swap! s assoc-in [:sides-overlap] (.. % -target -checked))}] - (tr [:settings.sides-overlap "Runner and Corp board may overlap"])]] + :on-change #(swap! s assoc :sides-overlap (.. % -target -checked))}] + (tr [:settings_sides-overlap "Runner and Corp board may overlap"])]] [:div [:label [:input {:type "checkbox" :value true :checked (:log-timestamps @s) - :on-change #(swap! s assoc-in [:log-timestamps] (.. % -target -checked))}] - (tr [:settings.log-timestamps "Show log timestamps"])]] + :on-change #(swap! s assoc :log-timestamps (.. % -target -checked))}] + (tr [:settings_toggle-log-timestamps "Show log timestamps"])]] [:br] - [:h4 (tr [:settings.runner-layout "Runner layout from Corp perspective"])] + [:h4 (tr [:settings_runner-layout "Runner layout from Corp perspective"])] [:div [:div.radio [:label [:input {:name "runner-board-order" @@ -416,7 +463,7 @@ :value "jnet" :checked (= "jnet" (:runner-board-order @s)) :on-change #(swap! s assoc :runner-board-order (.. % -target -value))}] - (tr [:settings.runner-classic "Runner rig layout is classic jnet (Top to bottom: Programs, Hardware, Resources)"])]] + (tr [:settings_runner-classic "Runner rig layout is classic jnet (Top to bottom: Programs, Hardware, Resources)"])]] [:div.radio [:label [:input {:name "runner-board-order" @@ -424,15 +471,15 @@ :value "irl" :checked (= "irl" (:runner-board-order @s)) :on-change #(swap! s assoc :runner-board-order (.. % -target -value))}] - (tr [:settings.runner-reverse "Runner rig layout is reversed (Top to bottom: Resources, Hardware, Programs)"])]]] + (tr [:settings_runner-reverse "Runner rig layout is reversed (Top to bottom: Resources, Hardware, Programs)"])]]] [:br] - [:h4 (tr [:settings.log-size "Log size"])] + [:h4 (tr [:settings_log-size "Log size"])] [:div [log-width-option s] [log-top-option s]] [:br] - [:h4 (tr [:settings.log-player-highlight "Log player highlight"])] + [:h4 (tr [:settings_log-player-highlight "Log player highlight"])] [:div [:div.radio [:label [:input {:name "log-player-highlight" @@ -440,7 +487,7 @@ :value "blue-red" :checked (= "blue-red" (:log-player-highlight @s)) :on-change #(swap! s assoc :log-player-highlight (.. % -target -value))}] - (tr [:settings.log-player-highlight-red-blue "Corp: Blue / Runner: Red"])]] + (tr [:settings_log-player-highlight-red-blue "Corp: Blue / Runner: Red"])]] [:div.radio [:label [:input {:name "log-player-highlight" @@ -448,42 +495,30 @@ :value "none" :checked (= "none" (:log-player-highlight @s)) :on-change #(swap! s assoc :log-player-highlight (.. % -target -value))}] - (tr [:settings.log-player-highlight-none "None"])]]]] + (tr [:settings_log-player-highlight-none "None"])]]]] (let [custom-bg-selected (= (:background @s) "custom-bg" ) - custom-bg-url (r/atom (:custom-bg-url @s))] + custom-bg-url (r/cursor s [:custom-bg-url])] [:section - [:h3 (tr [:settings.background "Game board background"])] - (doall (for [option [{:name (tr [:settings.the-root-bg "The Root"]) :ref "lobby-bg"} - {:name (tr [:settings.freelancer-bg "Freelancer"]) :ref "freelancer-bg"} - {:name (tr [:settings.mushin-no-shin-bg "Mushin No Shin"]) :ref "mushin-no-shin-bg"} - {:name (tr [:settings.traffic-jam-bg "Traffic Jam"]) :ref "traffic-jam-bg"} - {:name (tr [:settings.rumor-mill-bg "Rumor Mill"]) :ref "rumor-mill-bg"} - {:name (tr [:settings.find-the-truth-bg "Find The Truth"]) :ref "find-the-truth-bg"} - {:name (tr [:settings.push-your-luck-bg "Push Your Luck"]) :ref "push-your-luck-bg"} - {:name (tr [:settings.apex-bg "Apex"]) :ref "apex-bg"} - {:name (tr [:settings.worlds2020-bg "Worlds 2020"]) :ref "worlds2020"} - {:name (tr [:settings.monochrome-bg "Monochrome"]) :ref "monochrome-bg"} - {:name (str (tr [:settings.custom-bg "Custom BG"]) (when custom-bg-selected (tr [:settings.input-url-below " (input URL below)"]))) - :ref "custom-bg"}]] - [:div.radio {:key (:name option)} + [:h3 (tr [:settings_background "Game board background"])] + (doall (for [[title slug] background-list] + [:div.radio {:key slug} [:label [:input {:type "radio" :name "background" - :value (:ref option) - :on-change #(swap! s assoc-in [:background] (.. % -target -value)) - :checked (= (:background @s) (:ref option))}] - (:name option)]])) + :value slug + :on-change #(swap! s assoc :background (.. % -target -value)) + :checked (= (:background @s) slug)}] + (tr [:settings_bg title] {:slug slug})]])) [:div [:input {:type "text" :hidden (not custom-bg-selected) - :on-change #(do (swap! s assoc-in [:custom-bg-url] (.. % -target -value)) - (reset! custom-bg-url (.. % -target -value))) + :on-change #(swap! s assoc :custom-bg-url (.. % -target -value)) :value @custom-bg-url}]]]) [:section - [:h3 (tr [:settings.card-backs "Card backs"])] - (doall (for [option [{:name (tr [:settings.nsg "NSG"]) :ref "nsg"} - {:name (tr [:settings.ffg "FFG"]) :ref "ffg"}]] + [:h3 (tr [:settings_card-backs "Card backs"])] + (doall (for [option [{:name (tr [:settings_nsg "NSG"]) :ref "nsg"} + {:name (tr [:settings_ffg "FFG"]) :ref "ffg"}]] [:div.radio {:key (:name option)} [:label [:input {:type "radio" :name "card-back" @@ -493,9 +528,9 @@ (:name option)]]))] [:section - [:h3 (tr [:settings.card-preview-zoom "Card preview zoom"])] - (doall (for [option [{:name (tr [:settings.card-iamge "Card Image"]) :ref "image"} - {:name (tr [:settings.card-text "Card Text"]) :ref "text"}]] + [:h3 (tr [:settings_card-preview-zoom "Card preview zoom"])] + (doall (for [option [{:name (tr [:settings_card-iamge "Card Image"]) :ref "image"} + {:name (tr [:settings_card-text "Card Text"]) :ref "text"}]] [:div.radio {:key (:name option)} [:label [:input {:type "radio" :name "card-zoom" @@ -508,68 +543,68 @@ [:label [:input {:type "checkbox" :name "pin-zoom" :checked (:pin-zoom @s) - :on-change #(swap! s assoc-in [:pin-zoom] (.. % -target -checked))}] - (tr [:settings.pin-zoom "Keep zoomed cards on screen"])]]] + :on-change #(swap! s assoc :pin-zoom (.. % -target -checked))}] + (tr [:settings_pin-zoom "Keep zoomed cards on screen"])]]] [:section - [:h3 (tr [:settings.game-stats " Game Win/Lose statistics "])] - (doall (for [option [{:name (tr [:settings.always "Always"]) :ref "always"} - {:name (tr [:settings.comp-only "Competitive Lobby Only"]) :ref "competitive"} - {:name (tr [:settings.none "None"]) :ref "none"}]] + [:h3 (tr [:settings_game-stats " Game Win/Lose statistics "])] + (doall (for [option [{:name (tr [:settings_always "Always"]) :ref "always"} + {:name (tr [:settings_comp-only "Competitive Lobby Only"]) :ref "competitive"} + {:name (tr [:settings_none "None"]) :ref "none"}]] [:div {:key (:name option)} [:label [:input {:type "radio" :name "gamestats" :value (:ref option) - :on-change #(swap! s assoc-in [:gamestats] (.. % -target -value)) + :on-change #(swap! s assoc :gamestats (.. % -target -value)) :checked (= (:gamestats @s) (:ref option))}] (:name option)]]))] [:section - [:h3 (tr [:settings.deck-stats " Deck statistics "])] - (doall (for [option [{:name (tr [:settings.always "Always"]) :ref "always"} - {:name (tr [:settings.comp-only "Competitive Lobby Only"]) :ref "competitive"} - {:name (tr [:settings.none "None"]) :ref "none"}]] + [:h3 (tr [:settings_deck-stats " Deck statistics "])] + (doall (for [option [{:name (tr [:settings_always "Always"]) :ref "always"} + {:name (tr [:settings_comp-only "Competitive Lobby Only"]) :ref "competitive"} + {:name (tr [:settings_none "None"]) :ref "none"}]] [:div {:key (:name option)} [:label [:input {:type "radio" :name "deckstats" :value (:ref option) - :on-change #(swap! s assoc-in [:deckstats] (.. % -target -value)) + :on-change #(swap! s assoc :deckstats (.. % -target -value)) :checked (= (:deckstats @s) (:ref option))}] (:name option)]]))] [:section {:id "high-res"} - [:h3 (tr [:settings.card-images "Card images"])] + [:h3 (tr [:settings_card-images "Card images"])] [:div [:label [:input {:type "checkbox" :name "use-high-res" :checked (= "high" (:card-resolution @s)) - :on-change #(swap! s assoc-in [:card-resolution] (if (.. % -target -checked) "high" "default"))}] - (tr [:settings.high-res "Enable high-resolution card images"])]]] + :on-change #(swap! s assoc :card-resolution (if (.. % -target -checked) "high" "default"))}] + (tr [:settings_high-res "Enable high-resolution card images"])]]] [:section {:id "alt-art"} - [:h3 (tr [:settings.alt-art "Alt arts"])] + [:h3 (tr [:settings_alt-art "Alt arts"])] [:div [:label [:input {:type "checkbox" :name "show-alt-art" :checked (:show-alt-art @s) - :on-change #(swap! s assoc-in [:show-alt-art] (.. % -target -checked))}] - (tr [:settings.show-alt "Show alternate card arts"])]] + :on-change #(swap! s assoc :show-alt-art (.. % -target -checked))}] + (tr [:settings_show-alt "Show alternate card arts"])]] [:br] (when (and (:special @user) (:show-alt-art @s) (:alt-info @app-state)) [:div {:id "my-alt-art"} [:div {:id "set-all"} - (tr [:settings.set-all "Set all cards to"]) ": " + (tr [:settings_set-all "Set all cards to"]) ": " [:select {:ref "all-art-select" :value (:all-art-select @s) - :on-change #(swap! s assoc-in [:all-art-select] (-> % .-target .-value))} + :on-change #(swap! s assoc :all-art-select (-> % .-target .-value))} (doall (for [t (all-alt-art-types)] (when (not= "prev" t) [:option {:value t :key t} (alt-art-name t)])))] [:button {:type "button" :on-click #(reset-card-art s)} - (tr [:settings.set "Set"])]] + (tr [:settings_set "Set"])]] [:div.reset-all (let [disabled (empty? (:alt-arts @s))] [:button @@ -577,23 +612,24 @@ :disabled disabled :class (if disabled "disabled" "") :on-click #(clear-card-art s)} - (tr [:settings.reset "Reset All to Official Art"])])]])] + (tr [:settings_reset "Reset All to Official Art"])])]])] [:section - [:h3 (tr [:settings.blocked "Blocked users"])] + [:h3 (tr [:settings_blocked "Blocked users"])] [:div - [:input {:on-change #(swap! s assoc-in [:block-user-input] (-> % .-target .-value)) + [:input {:on-change #(swap! s assoc :block-user-input (-> % .-target .-value)) :on-key-down (fn [e] (when (= e.keyCode 13) (.preventDefault e) (add-user-to-block-list user s))) :ref "block-user-input" :value (:block-user-input @s) - :type "text" :placeholder (tr [:settings.user-name "User name"])}] + :type "text" + :placeholder (tr [:settings_user-name "User name"])}] [:button.block-user-btn {:type "button" :name "block-user-button" :on-click #(add-user-to-block-list user s)} - (tr [:settings.block "Block user"])]] + (tr [:settings_block "Block user"])]] (doall (for [bu (:blocked-users @s)] [:div.line {:key bu} [:button.small.unblock-user {:type "button" @@ -601,13 +637,13 @@ [:span.blocked-user-name (str " " bu)]]))] [:section - [:h3 (tr [:settings.connection "Connection"])] + [:h3 (tr [:settings_connection "Connection"])] [:div [:label [:input {:type "checkbox" :name "disable-websockets" :checked (:disable-websockets @s) - :on-change #(swap! s assoc-in [:disable-websockets] (.. % -target -checked))}] - (tr [:settings.disable-websockets "Disable websockets - requires browser refresh after clicking Update Profile [Not Recommended!]"])]]] + :on-change #(swap! s assoc :disable-websockets (.. % -target -checked))}] + (tr [:settings_disable-websockets "Disable websockets - requires browser refresh after clicking Update Profile [Not Recommended!]"])]]] [api-keys s] @@ -617,38 +653,17 @@ (defn account [] (let [user (r/cursor app-state [:user]) scroll-top (atom 0) - state (r/atom {:flash-message "" - :background (get-in @app-state [:options :background]) - :custom-bg-url (get-in @app-state [:options :custom-bg-url]) - :card-back (get-in @app-state [:options :card-back]) - :card-zoom (get-in @app-state [:options :card-zoom]) - :pin-zoom (get-in @app-state [:options :pin-zoom]) - :pronouns (get-in @app-state [:options :pronouns]) - :bespoke-sounds (get-in @app-state [:options :bespoke-sounds]) - :language (get-in @app-state [:options :language]) - :sounds (get-in @app-state [:options :sounds]) - :default-format (get-in @app-state [:options :default-format]) - :lobby-sounds (get-in @app-state [:options :lobby-sounds]) - :volume (get-in @app-state [:options :sounds-volume]) - :show-alt-art (get-in @app-state [:options :show-alt-art]) - :alt-arts (get-in @app-state [:options :alt-arts]) - :all-art-select "wc2015" - :card-resolution (get-in @app-state [:options :card-resolution]) - :stacked-cards (get-in @app-state [:options :stacked-cards]) - :ghost-trojans (get-in @app-state [:options :ghost-trojans]) - :display-encounter-info (get-in @app-state [:options :display-encounter-info]) - :sides-overlap (get-in @app-state [:options :sides-overlap]) - :pass-on-rez (get-in @app-state [:options :pass-on-rez]) - :log-timestamps (get-in @app-state [:options :log-timestamps]) - :player-stats-icons (get-in @app-state [:options :player-stats-icons]) - :runner-board-order (get-in @app-state [:options :runner-board-order]) - :log-width (get-in @app-state [:options :log-width]) - :log-top (get-in @app-state [:options :log-top]) - :log-player-highlight (get-in @app-state [:options :log-player-highlight]) - :gamestats (get-in @app-state [:options :gamestats]) - :deckstats (get-in @app-state [:options :deckstats]) - :blocked-users (sort (get-in @app-state [:options :blocked-users])) - :disable-websockets (get-in @app-state [:options :disable-websockets])})] + state (r/atom + (-> (:options @app-state) + (select-keys [:pronouns :bespoke-sounds :language :sounds :default-format + :lobby-sounds :volume :background :custom-bg-url :card-back :card-zoom + :pin-zoom :show-alt-art :card-resolution :pass-on-rez + :player-stats-icons :stacked-cards :ghost-trojans + :display-encounter-info :sides-overlap :log-timestamps + :runner-board-order :log-width :log-top :log-player-highlight + :blocked-users :alt-arts :gamestats :deckstats :disable-websockets]) + (assoc :flash-message "" + :all-art-select "wc2015")))] (go (let [response (format time-span-string tristate-button]] [nr.ws :as ws] @@ -79,8 +79,8 @@ [:div.buttons [:div.button-row [tristate-button - (tr [:angel-arena.queueing "Queueing..."]) - (tr [:angel-arena.queue-for-match "Queue for match"]) + (tr [:angel-arena_queueing "Queueing..."]) + (tr [:angel-arena_queue-for-match "Queue for match"]) (= (:_id deck) @queueing) (and @queueing (not= (:_id deck) @queueing)) @@ -92,11 +92,11 @@ "Average waiting time: " (time-span-string (get-in @queue-times [@chosen-format side]))] [:div.button-row (if @abandon - [:span (tr [:angel-arena.are-you-sure "Are you sure?"]) " " + [:span (tr [:angel-arena_are-you-sure "Are you sure?"]) " " [:button.small {:on-click #(do (ws/ws-send! [:angel-arena/abandon-run {:deck-id (:_id deck)}]) - (fetch-runs))} (tr [:angel-arena.are-you-sure-yes "yes"])] - [:button.small {:on-click #(reset! abandon false)} (tr [:angel-arena.are-you-sure-no "no"])]] - [cond-button (tr [:angel-arena.abandon-run "Abandon run"]) + (fetch-runs))} (tr [:angel-arena_are-you-sure-yes "yes"])] + [:button.small {:on-click #(reset! abandon false)} (tr [:angel-arena_are-you-sure-no "no"])]] + [cond-button (tr [:angel-arena_abandon-run "Abandon run"]) (not @queueing) #(reset! abandon true)])]])) @@ -117,7 +117,7 @@ (defn- deckselect-modal [{:keys [side decks]}] [:div - [:h3 (tr [:angel-arena.select-deck "Select your deck"])] + [:h3 (tr [:angel-arena_select-deck "Select your deck"])] [:div.deck-collection.lobby-deck-selector (let [same-side? (fn [deck] (= (capitalize (name side)) (get-in deck [:identity :side]))) @@ -132,7 +132,7 @@ (sort-by :date >))] (if (empty? eligible-decks) [:div.infobox.one-line.blue-shade - [:p (tr [:angel-arena.no-eligible-decks "No legal decks found for this side and format."])]] + [:p (tr [:angel-arena_no-eligible-decks "No legal decks found for this side and format."])]] (doall (for [deck eligible-decks] ^{:key (:_id deck)} @@ -149,7 +149,7 @@ (defn- new-run-button-bar [side decks] [:div.button-bar - [cond-button (tr [:angel-arena.start-new-run "Start new run"]) + [cond-button (tr [:angel-arena_start-new-run "Start new run"]) (not @queueing) #(reagent-modals/modal! [deckselect-modal {:side side :decks decks}])]]) @@ -227,9 +227,9 @@ (fn [] (if-not @runs [:div.game-panel.angel-arena - [:h3 (tr [:angel-arena.requesting-run-data "Requesting run data..."])]] + [:h3 (tr [:angel-arena_requesting-run-data "Requesting run data..."])]] [:div.game-panel.angel-arena - [:h3 (tr [:angel-arena.format "Format"])] + [:h3 (tr [:angel-arena_format "Format"])] [:div.format-bar (doall (for [form @arena-supported-formats] @@ -237,7 +237,7 @@ [:span.tab {:on-click #(reset! chosen-format form) :class [(when (= @chosen-format form) "current")]} (get slug->format (name form))]))] - [:h3 (tr [:angel-arena.active-corp-run "Active Corp run"])] + [:h3 (tr [:angel-arena_active-corp-run "Active Corp run"])] (if (get-in @runs [@chosen-format :corp]) (let [deck (first (filter #(= (str (:_id %)) (get-in @runs [@chosen-format :corp :deck-id])) @@ -248,7 +248,7 @@ [deck-buttons :corp deck]]) [:div.run [new-run-button-bar :corp decks]]) - [:h3 (tr [:angel-arena.active-runner-run "Active Runner run"])] + [:h3 (tr [:angel-arena_active-runner-run "Active Runner run"])] (if (get-in @runs [@chosen-format :runner]) (let [deck (first (filter #(= (str (:_id %)) (get-in @runs [@chosen-format :runner :deck-id])) @@ -259,7 +259,7 @@ [deck-buttons :runner deck]]) [:div.run [new-run-button-bar :runner decks]]) - [:h3 (tr [:angel-arena.latest-runs "Latest runs"])] + [:h3 (tr [:angel-arena_latest-runs "Latest runs"])] [latest-runs-view]]))})) (defn- player-view @@ -279,7 +279,7 @@ (faction-icon faction identity) side - (str " (" (tr-side side) ")"))) + (str " (" (tr [:side_name] {:side side}) ")"))) (when-let [{:keys [wins losses]} (:run-info player)] [:span.standings wins "-" losses])])) @@ -293,22 +293,22 @@ (not current-game))) [:button {:on-click #(do (join "watch") (resume-sound))} - (tr [:lobby.watch "Watch"])]) + (tr [:lobby_watch "Watch"])]) (when (and (not current-game) started (= 1 (count players)) (some #(= (get-in % [:user :username]) (:username user)) original-players)) [:button {:on-click #(do (join "rejoin") (resume-sound))} - (tr [:lobby.rejoin "Rejoin"])]) + (tr [:lobby_rejoin "Rejoin"])]) (let [c (:spectator-count game)] [:h4 (str (when (:save-replay game) "🟢") (:title game) - (when (pos? c) (str " (" (tr [:lobby.spectator-count] c) ")")))]) + (when (pos? c) (str " (" (tr [:lobby_spectator-count] {:cnt c}) ")")))]) [:div {:class "game-format"} - [:span.format-label (tr [:lobby.default-game-format "Default game format"]) ": "] + [:span.format-label (tr [:lobby_default-game-format "Default game format"]) ": "] [:span.format-type (tr-format (slug->format format "Unknown"))]] (into [:div] @@ -325,14 +325,14 @@ (r/with-let [room-games (r/track (fn [] (filter #(= "angel-arena" (:room %)) @games)))] [:div.game-list (if (empty? @room-games) - [:h4 (tr [:angel-arena.no-games "No games"])] + [:h4 (tr [:angel-arena_no-games "No games"])] (let [groups (->> @room-games (group-by #(apply max (get-player-wins %))) (sort-by first >))] (doall (for [[wins games] groups] [:div.win-group {:key wins} - [:div.win-divider {:key (str wins "-divider")} wins " " (tr [:angel-arena.wins "wins"])] + [:div.win-divider {:key (str wins "-divider")} wins " " (tr [:angel-arena_wins "wins"])] (doall (for [game games] ^{:key (:gameid game)} diff --git a/src/cljs/nr/angel_arena/log.cljs b/src/cljs/nr/angel_arena/log.cljs index 4693fa6a80..0a3152aece 100644 --- a/src/cljs/nr/angel_arena/log.cljs +++ b/src/cljs/nr/angel_arena/log.cljs @@ -30,8 +30,8 @@ [:div.infobox "Your opponent has left the game. You can wait for them to return, you may claim this game as a victory, or cancel the match." [:div.button-bar.centered - [:button {:on-click claim-victory} (tr [:angel-arena.claim-victory "Claim victory"])] - [:button {:on-click cancel-match} (tr [:angel-arena.cancel-match "Cancel match"])]]])] + [:button {:on-click claim-victory} (tr [:angel-arena_claim-victory "Claim victory"])] + [:button {:on-click cancel-match} (tr [:angel-arena_cancel-match "Cancel match"])]]])] "inactive-pre-start" [:div.angel-arena-time-warning @@ -39,7 +39,7 @@ [:div.infobox "There was no activity in this game yet. You may cancel the match, if your opponent does not respond." [:div.button-bar.centered - [:button {:on-click cancel-match} (tr [:angel-arena.cancel-match "Cancel match"])]]])] + [:button {:on-click cancel-match} (tr [:angel-arena_cancel-match "Cancel match"])]]])] "inactive-warning" (let [time-inactive (/ (- (js/Date.now) (js/Date. warning-time)) 1000) @@ -55,7 +55,7 @@ (time-span-string (js/Math.floor time-remaining)) "."] (when (pos? inactivities-remaining) [:div.button-bar.centered - [:button {:on-click more-time} (tr [:angel-arena.still-here "Need more time"])]])] + [:button {:on-click more-time} (tr [:angel-arena_still-here "Need more time"])]])] (if (not-spectator?) [:div.angel-arena-time-warning [:div.infobox @@ -80,7 +80,7 @@ ". Your opponent can decide to either claim victory or cancel the match.")] (when (pos? inactivities-remaining) [:div.button-bar.centered - [:button {:on-click more-time} (tr [:angel-arena.still-here "Need more time"])]])] + [:button {:on-click more-time} (tr [:angel-arena_still-here "Need more time"])]])] (if (not-spectator?) [:div.angel-arena-time-warning [:div.infobox @@ -88,8 +88,8 @@ (time-span-string (js/Math.floor time-inactive)) ". You can decide to either claim victory or cancel the match.")] [:div.button-bar.centered - [:button {:on-click claim-victory} (tr [:angel-arena.claim-victory "Claim victory"])] - [:button {:on-click cancel-match} (tr [:angel-arena.cancel-match "Cancel match"])]]] + [:button {:on-click claim-victory} (tr [:angel-arena_claim-victory "Claim victory"])] + [:button {:on-click cancel-match} (tr [:angel-arena_cancel-match "Cancel match"])]]] [:div.angel-arena-time-warning [:div.infobox (str (:username inactive-user) " has been inactive for " diff --git a/src/cljs/nr/appstate.cljs b/src/cljs/nr/appstate.cljs index 6c5bcf0199..4279e1f734 100644 --- a/src/cljs/nr/appstate.cljs +++ b/src/cljs/nr/appstate.cljs @@ -1,6 +1,10 @@ (ns nr.appstate - (:require [jinteki.utils :refer [str->int]] - [reagent.core :as r])) + (:require + [cljs.core.async :refer [int]] + [nr.ajax :refer [GET]] + [reagent.core :as r])) (defn- get-local-value "Read the value of the given key from localStorage. Return the default-value if no matching key found" @@ -32,9 +36,9 @@ :custom-bg-url (get-local-value "custom_bg_url" "https://nullsignal.games/wp-content/uploads/2022/07/Mechanics-of-Midnight-Sun-Header.png") :card-back (get-local-value "card-back" "nsg") :card-zoom (get-local-value "card-zoom" "image") - :pin-zoom (get-local-value "pin-zoom" false) + :pin-zoom (= (get-local-value "pin-zoom" "false") "true") :pronouns "none" - :language "en" + :language (get-local-value "language" js/navigator.language) :default-format (get-local-value "default-format" "standard") :show-alt-art true :card-resolution "default" @@ -69,5 +73,10 @@ :español [] :italia [] :polska [] :português [] :sverige [] :stimhack-league [] :русский []} :games [] :current-game nil})) +(go (let [lang (get-in @app-state [:options :language] "en") + response (slug get-image-path image-or-face influence-dots - non-game-toast render-icons restricted-span rotated-span set-scroll-top slug->format - store-scroll-top]] + non-game-toast render-icons restricted-span rotated-span + set-scroll-top slug->format store-scroll-top]] [reagent.core :as r])) (defonce cards-channel (chan)) @@ -41,7 +42,7 @@ latest-cards (if need-update? (:json (> latest-cards (insert-starter-ids) @@ -253,8 +254,8 @@ (if (= 200 (:status response)) (let [new-alts (get-in response [:json :altarts] {})] (swap! app-state assoc-in [:user :options :alt-arts] new-alts) - (non-game-toast (tr [:card-browser.update-success "Updated Art"]) "success" nil)) - (non-game-toast (tr [:card-browser.update-failure "Failed to Update Art"]) "error" nil))) + (non-game-toast (tr [:card-browser_update-success "Updated Art"]) "success" nil)) + (non-game-toast (tr [:card-browser_update-failure "Failed to Update Art"]) "error" nil))) (defn- future-selected-alt-art [card] (let [future-code (keyword (:future-version card)) @@ -291,7 +292,7 @@ is-old-card (assoc alts code-kw (:code card)) :else (dissoc alts code-kw))] ; remove the key entirely if the newest card is selected (swap! app-state assoc-in [:options :alt-arts] new-alts) - (nr.account/post-options "/profile" (partial post-response)))) + (nr.account/post-options (partial post-response)))) (defn- text-class-for-status [status] @@ -305,36 +306,42 @@ (let [title (tr-data :title card) icon (faction-icon (:faction card) title) uniq (when (:uniqueness card) "◇ ") - subtypes (or (tr-data :keywords card) (or (when (seq (:subtypes card)) (s/join " - " (tr-data :subtypes card))) (tr-data :subtype card))) - impl (when (and (:implementation card) (not= (:implementation card) "full")) (:implementation card))] + subtypes (or (tr-data :keywords card) + (when (seq (:subtypes card)) + (s/join " - " (tr-data :subtypes card))) + (tr-data :subtype card)) + impl (when (and (:implementation card) + (not= (:implementation card) "full")) + (:implementation card))] [:div [:h4 uniq title icon (when-let [influence (:factioncost card)] (when-let [faction (:faction card)] [:span.influence - {:class (slugify faction)} + {:class (slugify faction) + :title (str (tr [:card-browser_influence "Influence"] {:influence influence}))} (influence-dots influence)]))] (when-let [memory (:memoryunits card)] (if (< memory 3) [:div.anr-icon {:class (str "mu" memory)} ""] - [:div.heading (str (tr [:card-browser.memory "Memory"]) ": " memory) [:span.anr-icon.mu]])) + [:div.heading (tr [:card-browser_memory "Memory"] {:memory memory}) [:span.anr-icon.mu]])) (when-let [cost (:cost card)] - [:div.heading (str (tr [:card-browser.cost "Cost"]) ": " cost)]) + [:div.heading (tr [:card-browser_cost "Cost"] {:cost cost})]) (when-let [trash-cost (:trash card)] - [:div.heading (str (tr [:card-browser.trash-cost "Trash cost"]) ": " trash-cost)]) + [:div.heading (tr [:card-browser_trash-cost "Trash cost"] {:trash-cost trash-cost})]) (when-let [strength (:strength card)] - [:div.heading (str (tr [:card-browser.strength "Strength"]) ": " strength)]) + [:div.heading (tr [:card-browser_strength "Strength"] {:strength strength})]) (when-let [requirement (:advancementcost card)] - [:div.heading (str (tr [:card-browser.advancement "Advancement requirement"]) ": " requirement)]) + [:div.heading (tr [:card-browser_advancement "Advancement requirement"] {:requirement requirement})]) (when-let [agenda-point (:agendapoints card)] - [:div.heading (str (tr [:card-browser.agenda-points "Agenda points"]) ": " agenda-point)]) + [:div.heading (tr [:card-browser_agenda-points "Agenda points"] {:points agenda-point})]) (when-let [min-deck-size (:minimumdecksize card)] - [:div.heading (str (tr [:card-browser.min-deck "Minimum deck size"]) ": " min-deck-size)]) + [:div.heading (tr [:card-browser_min-deck-size "Minimum deck size"] {:min-deck-size min-deck-size})]) (when-let [influence-limit (:influencelimit card)] - [:div.heading (str (tr [:card-browser.inf-limit "Influence limit"]) ": " influence-limit)]) + [:div.heading (tr [:card-browser_inf-limit "Influence limit"] {:inf-limit influence-limit})]) (when impl - [:div.heading (str (tr [:card-browser.implementation-note "Implementation note"]) ": " impl)]) + [:div.heading (tr [:card-browser_implementation-note "Implementation note"] {:impl impl})]) [:div.text.card-body [:p [:span.type (tr-type (:type card))] @@ -362,11 +369,11 @@ (str " [" (alt-art-name art) "]")))))] (when (show-alt-art?) (if (selected-alt-art card) - [:div.selected-alt (tr [:card-browser.selected-art "Selected Alt Art"])] + [:div.selected-alt (tr [:card-browser_selected-art "Selected Alt Art"])] (when (or (:art card) (:previous-versions card) (:future-version card)) [:button.alt-art-selector {:on-click #(select-alt-art card)} - (tr [:card-browser.select-art "Select Art"])])))])]])) + (tr [:card-browser_select-art "Select Art"])])))])]])) (defn types [side] (let [runner-types ["Identity" "Program" "Hardware" "Resource" "Event"] @@ -433,7 +440,6 @@ (defn selected-set-name [state] (-> (:set-filter @state) - (s/replace "    " "") (s/replace " Cycle" ""))) (defn handle-scroll [_ state] @@ -506,25 +512,25 @@ (defn query-builder [state] (let [query (:search-query @state)] [:div.search-box - [:span.e.search-icon {:dangerouslySetInnerHTML #js {:__html ""}}] + [:span.e.search-icon {:dangerouslySetInnerHTML (r/unsafe-html "")}] (when-not (empty? query) - [:span.e.search-clear {:dangerouslySetInnerHTML #js {:__html ""} + [:span.e.search-clear {:dangerouslySetInnerHTML (r/unsafe-html "") :on-click #(swap! state assoc :search-query "")}]) [:input.search {:on-change #(handle-search % state) :type "text" - :placeholder (tr [:card-browser.search-hint "Search cards"]) + :placeholder (tr [:card-browser-form_search-hint "Search cards"]) :value query}]])) (defn sort-by-builder [state] [:div - [:h4 (tr [:card-browser.sort "Sort by"])] + [:h4 (tr [:card-browser-form_sort "Sort by"])] [:select {:value (:sort-field @state) :on-change #(swap! state assoc :sort-field (.. % -target -value))} (doall - (for [field ["Faction" "Name" "Type" "Influence" "Cost" "Set number"]] - [:option {:value field - :key field - :dangerouslySetInnerHTML #js {:__html (tr-sort field)}}]))]]) + (for [field ["Faction" "Name" "Type" "Influence" "Cost" "Set number"]] + [:option {:value field + :key field} + (tr [:card-browser-form_sort-by field] {:by (clean-input field)})]))]]) (defn simple-filter-builder [title state state-key options translator] @@ -536,12 +542,8 @@ (for [option (cons "All" options)] ^{:key option} [:option {:value option - :key option - :dangerouslySetInnerHTML #js {:__html (translator option)}}]))]]) - -(defn format-set-name [pack-name] - (str "    " pack-name)) - + :key option} + (translator option)]))]]) (defn dropdown-builder [state] @@ -554,29 +556,40 @@ cycles-list (filter #(not (= (:size %) 1)) cycles-list-all) sets-list (map #(if (not (or (:bigbox %) (= (:id %) (:cycle_code %)))) - (update-in % [:name] format-set-name) + (assoc % :indent true) %) @sets) - set-names (map :name - (sort-by (juxt :cycle_position :position) - (concat cycles-list sets-list))) - alt-art-sets (cons "Alt Art" - (map #(format-set-name (:name %)) - (sort-by :position (:alt-info @app-state)))) + set-names (sort-by (juxt :cycle_position :position) + (concat cycles-list sets-list)) + alt-art-sets (delay + (->> (:alt-info @app-state) + (sort-by :position) + (map #(assoc % :indent true)) + (cons {:name "Alt Art"}))) sets-to-display (if (show-alt-art? true) - (concat set-names alt-art-sets) + (concat set-names @alt-art-sets) set-names) formats (-> format->slug keys butlast)] [:div - (doall - (for [[title state-key options translator] - [[(tr [:card-browser.format "Format"]) :format-filter formats tr-format] - [(tr [:card-browser.set "Set"]) :set-filter sets-to-display tr-set] - [(tr [:card-browser.side "Side"]) :side-filter ["Corp" "Runner"] tr-side] - [(tr [:card-browser.faction "Faction"]) :faction-filter (factions (:side-filter @state)) tr-faction] - [(tr [:card-browser.type "Type"]) :type-filter (types (:side-filter @state)) tr-type]]] - ^{:key title} - [simple-filter-builder title state state-key options translator]))])) + [simple-filter-builder (tr [:card-browser-form_format "Format"]) + state :format-filter formats tr-format] + [:div + [:h4 (tr [:card-browser_set "Set"])] + [:select {:value (:set-filter @state) + :on-change #(swap! state assoc :set-filter (.. % -target -value))} + (doall + (for [{n :name indent :indent} (cons {:name "All"} sets-to-display)] + ^{:key n} + [:option {:value n :key n} + (if indent + (str "* " (tr-set n)) + (tr-set n))]))]] + [simple-filter-builder (tr [:card-browser-form_side "Side"]) + state :side-filter ["Corp" "Runner"] tr-side] + [simple-filter-builder (tr [:card-browser-form_faction "Faction"]) + state :faction-filter (factions (:side-filter @state)) tr-faction] + [simple-filter-builder (tr [:card-browser-form_type "Type"]) + state :type-filter (types (:side-filter @state)) tr-type]])) (defn clear-filters [state] [:p [:button @@ -589,7 +602,7 @@ :type-filter "All" :side-filter "All" :faction-filter "All")} - (tr [:card-browser.clear "Clear"])]]) + (tr [:card-browser_clear "Clear"])]]) (defn art-info [state] (let [selected (r/cursor state [:selected-card])] @@ -601,10 +614,10 @@ link (:artist-link info)] (when blurb [:div.panel.green-shade.artist-blurb - [:h4 (tr [:card-browser.artist-info "Artist Info"])] + [:h4 (tr [:card-browser_artist-info "Artist Info"])] [:div blurb] (when link - [:a {:href link} (tr [:card-browser.more-info "More Info"])])]))))) + [:a {:href link} (tr [:card-browser_more-info "More Info"])])]))))) (defn card-browser [] (let [state (r/atom {:search-query "" diff --git a/src/cljs/nr/chat.cljs b/src/cljs/nr/chat.cljs index 1c34a696ce..13dc01cd95 100644 --- a/src/cljs/nr/chat.cljs +++ b/src/cljs/nr/chat.cljs @@ -34,9 +34,9 @@ (defmethod ws/event-msg-handler :chat/blocked [{{:keys [reason]} :?data}] (let [reason-str (case reason - :rate-exceeded (tr [:chat.rate-exceeded "Rate exceeded"]) - :length-exceeded (tr [:chat.length-exceeded "Length exceeded"]))] - (non-game-toast (tr [:chat.message-blocked] reason-str) + :rate-exceeded (tr [:chat_rate-exceeded "Rate exceeded"]) + :length-exceeded (tr [:chat_length-exceeded "Length exceeded"]))] + (non-game-toast (tr [:chat_message-blocked] {:reason-str reason-str}) "warning" nil))) (defn current-block-list [] @@ -106,7 +106,7 @@ (= -1 (.indexOf current-blocked-list blocked-user))) (let [new-block-list (conj current-blocked-list blocked-user)] (swap! app-state assoc-in [:options :blocked-users] new-block-list) - (account/post-options "/profile" (partial post-response blocked-user)))))))) + (account/post-options (partial post-response blocked-user)))))))) (defn send-msg [s channel] (authenticated @@ -137,12 +137,12 @@ (when-not (illegal-message s) (send-msg s channel)))} [:input {:type "text" :ref #(swap! chat-state assoc :msg-input %) - :placeholder (tr [:chat/placeholder "Say something..."]) :accessKey "l" :value (:msg @s) + :placeholder (tr [:chat_placeholder "Say something..."]) :accessKey "l" :value (:msg @s) :on-change #(swap! s assoc :msg (-> % .-target .-value))}] (let [disabled (illegal-message s)] [:button {:disabled disabled :class (if disabled "disabled" "")} - (tr [:chat/send "Send"])])]) + (tr [:chat_send "Send"])])]) (defn channel-view [{:keys [channel active-channel]} s] [:div.block-link {:class (if (= active-channel channel) "active" "") @@ -179,15 +179,15 @@ (when (or (:isadmin user) (:ismoderator user)) [:div {:on-click #(do (delete-message message) - (hide-block-menu msg-state))} (tr [:chat.delete "Delete Message"])]) + (hide-block-menu msg-state))} (tr [:chat_delete "Delete Message"])]) (when (or (:isadmin user) (:ismoderator user)) [:div {:on-click #(do (delete-all-messages (:username message)) - (hide-block-menu msg-state))} (tr [:chat.delete-all "Delete All Messages From User"])]) + (hide-block-menu msg-state))} (tr [:chat_delete-all "Delete All Messages From User"])]) [:div {:on-click #(do (block-user (:username message)) - (hide-block-menu msg-state))} (tr [:chat.block "Block User"])] - [:div {:on-click #(hide-block-menu msg-state)} (tr [:chat.cancel "Cancel"])]])) + (hide-block-menu msg-state))} (tr [:chat_block "Block User"])] + [:div {:on-click #(hide-block-menu msg-state)} (tr [:chat_cancel "Cancel"])]])) [:span.date (format-date-time day-word-with-time-formatter (:date message))]] [:div {:on-mouse-over #(card-preview-mouse-over % (:zoom-ch @s)) @@ -265,7 +265,7 @@ (fn [s curr-msg old scroll-top] [:div#chat.chat-app [:div.blue-shade.panel.channel-list - [:h4 (tr [:chat.channels "Channels"])] + [:h4 (tr [:chat_channels "Channels"])] (doall (for [ch [:general :america :europe :asia-pacific :united-kingdom :français :español :italia :polska @@ -298,7 +298,7 @@ (fn [] [:div.container [:div.home-bg] - [:h1 (tr [:chat.title "Play Netrunner in your browser"])] + [:h1 (tr [:chat_title "Play Netrunner in your browser"])] [news] [chat s curr-msg old scroll-top] [:div#version [:span (str "Version " (or (get @app-state :app-version) "Unknown"))]]]))) diff --git a/src/cljs/nr/deck_status.cljs b/src/cljs/nr/deck_status.cljs index 5d018f018b..176375f1c3 100644 --- a/src/cljs/nr/deck_status.cljs +++ b/src/cljs/nr/deck_status.cljs @@ -33,11 +33,11 @@ [{:keys [format] :as deck-status} tooltip? violation-details?] (let [format (or format :standard) status (check-deck-status deck-status) - message (str (tr-format (get slug->format (:format deck-status) "Standard")) + message [:<> (tr-format (get slug->format (:format deck-status) "Standard")) " " (if (= "invalid" status) - (tr [:deck-builder.illegal "illegal"]) - (tr [:deck-builder.legal "legal"])))] + (tr [:deck-builder_illegal "illegal"]) + (tr [:deck-builder_legal "legal"]))]] [:<> [:span.deck-status.shift-tooltip {:class status} message (when tooltip? @@ -46,7 +46,7 @@ (when (and tooltip? (= "invalid" status)) [:span.deck-status.shift-tooltip.invalid-explanation {:class status} - (tr [:deck-builder.why "Why?"]) + (tr [:deck-builder_why "Why?"]) [:span.status-tooltip.blue-shade [:span.invalid reason]]]))])) diff --git a/src/cljs/nr/deckbuilder.cljs b/src/cljs/nr/deckbuilder.cljs index f8ef057169..a2dd97cef0 100644 --- a/src/cljs/nr/deckbuilder.cljs +++ b/src/cljs/nr/deckbuilder.cljs @@ -1,8 +1,8 @@ (ns nr.deckbuilder (:require-macros [cljs.core.async.macros :refer [go]]) (:require - [cljs.core.async :refer [! chan put! timeout close! go-loop] :as async] - [clojure.string :refer [join lower-case split split-lines] :as s] + [cljs.core.async :refer [! chan put! timeout go-loop] :as async] + [clojure.string :refer [join lower-case split split-lines] :as str] [jinteki.cards :refer [all-cards] :as cards] [jinteki.utils :refer [INFINITY str->int] :as utils] [jinteki.validator :as validator] @@ -14,12 +14,11 @@ [nr.translations :refer [tr tr-faction tr-format tr-side tr-type tr-data]] [nr.utils :refer [alliance-dots banned-span cond-button deck-points-card-span dots-html format->slug format-date-time - influence-dot influence-dots mdy-formatter non-game-toast num->percent - restricted-span rotated-span set-scroll-top slug->format store-scroll-top render-message]] + influence-dot influence-dots mdy-formatter non-game-toast + restricted-span rotated-span set-scroll-top slug->format store-scroll-top render-message safe-divide]] [nr.ws :as ws] [reagent-modals.modals :as reagent-modals] - [reagent.core :as r] - [clojure.string :as str])) + [reagent.core :as r])) (def select-channel (chan)) (def zoom-channel (chan)) @@ -110,7 +109,7 @@ [param] (if (and param (= 2 (count param))) - (let [[k v] (map s/trim param) + (let [[k v] (map str/trim param) allowed-keys ["id" "art"]] (if (some #{k} allowed-keys) [(keyword k) v] @@ -136,12 +135,12 @@ (defn parse-line "Parse a single line of a deck string" [line] - (let [clean (s/trim line) + (let [clean (str/trim line) [_ qty-str card-name card-params] (re-matches #"(\d+)[^\s]*\s+(([^\[]+)|(\[(.*)\]))" clean)] (if (and qty-str (not (js/isNaN (str->int qty-str))) card-name) - (let [result (assoc {} :qty (str->int qty-str) :card (s/trim card-name))] + (let [result (assoc {} :qty (str->int qty-str) :card (str/trim card-name))] (add-params result card-params)) nil))) @@ -231,8 +230,7 @@ (-> (:deckname @db-dom) js/$ .select)))) (defn end-edit [s] - (swap! s assoc :edit false) - (swap! s assoc :query "") + (swap! s assoc :edit false :query "") (-> (:viewport @db-dom) js/$ (.removeClass "edit"))) (defn cancel-edit [s] @@ -241,7 +239,7 @@ selected (or (:old-deck @s) (first decks))] (end-edit s) (load-decks decks) - (put! select-channel selected))) + (when selected (put! select-channel selected)))) (defn delete-deck [s] (swap! s assoc :delete true) @@ -284,7 +282,7 @@ (map add-deck cards))) (defn new-deck - ([s side] (new-deck s side (tr [:deck-builder.new-deck "New Deck"]) "standard" [] nil)) + ([s side] (new-deck s side (tr [:deck-builder_new-deck "New Deck"]) "standard" [] nil)) ([s side name format cards id] (let [old-deck (:deck @s) identities (->> (side-identities side format) @@ -302,7 +300,7 @@ (defn name-copy [deck] (let [deckname (:name deck) - suffix (tr [:deck-builder.deck-copy-suffix "copy"]) + suffix (tr [:deck-builder_deck-copy-suffix "copy"]) pattern (re-pattern (str "(.*)\\-" suffix "(\\d*)$"))] (if-let [[_ basename num] (re-find pattern deckname)] (str basename "-" suffix (if (str/blank? num) 1 (-> num str->int inc))) @@ -319,10 +317,10 @@ (defn import-deck-modal [] (r/with-let [s (r/atom {})] [:div - [:h3 (tr [:deck-builder.import-title "Enter a Public NRDB Deck ID or URL"])] + [:h3 (tr [:deck-builder_import-title "Enter a Public NRDB Deck ID or URL"])] [:p [:input.url {:type "text" :id "nrdb-input" - :placeholder (tr [:deck-builder.import-placeholder "NRDB ID"]) + :placeholder (tr [:deck-builder_import-placeholder "NRDB ID"]) :value (:msg @s) :on-key-press #(when (= 13 (.. % -charCode)) (send-import s)) @@ -333,8 +331,9 @@ {:disabled disabled :class (when disabled "disabled") :on-click #(send-import s)} - (tr [:deck-builder.import "Import"])]) - [:button {:on-click #(reagent-modals/close-modal!)} (tr [:deck-builder.cancel "Cancel"])]]])) + (tr [:deck-builder_import "Import"])]) + [:button {:on-click #(reagent-modals/close-modal!)} + (tr [:deck-builder_cancel "Cancel"])]]])) (defn load-decks-from-json [json] @@ -516,10 +515,10 @@ :selected 0})] (fn [s] [:div - [:h3 (tr [:deck-builder.add-cards "Add cards"])] + [:h3 (tr [:deck-builder_add-cards "Add cards"])] [:form.card-search {:on-submit #(handle-add s card-state %)} [:input.lookup {:type "text" - :placeholder (tr [:deck-builder.card-name "Card name"]) + :placeholder (tr [:deck-builder_card-name "Card name"]) :value (:query @card-state) :on-change #(swap! card-state assoc :query (.. % -target -value)) :on-key-down #(handle-keydown card-state %)}] @@ -530,7 +529,7 @@ [:button (let [disabled (empty? (:matches @card-state))] {:disabled disabled :class (when disabled "disabled")}) - (tr [:deck-builder.add-to-deck "Add to deck"])] + (tr [:deck-builder_add-to-deck "Add to deck"])] (let [query (:query @card-state) matches (match (get-in @s [:deck :identity]) query) exact-match (= (:title (first matches)) query)] @@ -559,8 +558,9 @@ (defn deck-name ([deck] (deck-name deck 40)) ([deck limit] - (let [deck-name (:name deck)] - (str (s/trim (subs deck-name 0 limit)) + (when-let [deck-name (:name deck)] + (prn :deck-name deck-name) + (str (str/trim (subs deck-name 0 limit)) (when (< limit (count deck-name)) "..."))))) (defn deck-date [deck] @@ -578,10 +578,10 @@ losses (or (:loses stats) 0)] [:p ; adding key :games to handle legacy stats before adding started vs completed - " " (tr [:deck-builder.games "Games"]) ": " (+ started games) - " - " (tr [:deck-builder.completed "Completed"]) ": " (+ completed games) - " - " (tr [:deck-builder.won "Won"]) ": " wins " (" (num->percent wins (+ wins losses)) "%)" - " - " (tr [:deck-builder.lost "Lost"]) ": " losses])))) + " " (tr [:deck-builder_games "Games"] {:games (+ started games)}) + " - " (tr [:deck-builder_completed "Completed"] {:completed (+ completed games)}) + " - " (tr [:deck-builder_won "Won"] {:won wins :percent (safe-divide wins (+ wins losses))}) + " - " (tr [:deck-builder_lost "Lost"] {:lost losses})])))) (defn deck-entry [s deck] (r/with-let [state-deck (r/cursor s [:deck])] @@ -639,24 +639,21 @@ faction-filter (r/cursor state [:faction-filter]) fmt-filter (r/cursor state [:format-filter])] (when-not (:edit @state) - (cond + (if (not @decks-loaded) [:div.deck-collection - [:h4 (tr [:deck-builder.loading-msg "Loading deck collection..."])]] - (empty? @decks) - [:div.deck-collection - [:h4 (tr [:deck-builder.no-decks "No decks"])]] - :else + [:h4 (tr [:deck-builder_loading-msg "Loading deck collection..."])]] (let [filtered-decks (->> @decks (filter-side side-filter) (filter-faction faction-filter) (filter-format fmt-filter)) - n (count filtered-decks) - deck-str (tr [:deck-builder.deck-count] n)] + n (count filtered-decks)] [:<> [:div.deck-count - [:h4 (str deck-str (when (filter-selected side-filter faction-filter fmt-filter) - (str " " (tr [:deck-builder.filtered "(filtered)"]))))]] + [:h4 + (if (filter-selected side-filter faction-filter fmt-filter) + (tr [:deck-builder_deck-count-filtered "Deck Count (filtered)"] {:cnt n}) + (tr [:deck-builder_deck-count "Deck Count"] {:cnt n}))]] [decks-list filtered-decks state scroll-top]]))))) (defn line-span @@ -728,7 +725,7 @@ (let [deck-points (validator/deck-point-count deck) point-limit (validator/format-point-limit (:format deck))] [:span.deck-status.shift-tooltip - [:span (str (tr [:deck-builder.deck-points "Deck points"]) ": ")] + [:span (str (tr [:deck-builder_deck-points "Deck points"]) ": ")] [:span {:class (if (> deck-points point-limit) "invalid" "legal")} @@ -758,14 +755,15 @@ (:restricted status) restricted-span (:rotated status) rotated-span (:points status) (deck-points-card-span (:points status))))] - (let [count (validator/card-count cards) + (let [cnt (validator/card-count cards) min-count (validator/min-deck-size id)] - [:div count (str " " (tr [:deck-builder.cards "cards"])) - (when (< count min-count) - [:span.invalid (str " (" (tr [:deck-builder.min "minimum"]) " " min-count ")")])]) + [:div (tr [:deck-builder_card-count "cards"] {:cnt cnt}) + " " + (when (< cnt min-count) + [:span.invalid (tr [:deck-builder_min-deck-size "minimum"] {:cnt min-count})])]) (let [inf (validator/influence-count deck) id-limit (validator/id-inf-limit id)] - [:div (str (tr [:deck-builder.influence "Influence"]) ": ") + [:div (tr [:deck-builder_influence "Influence"]) ": " ;; we don't use valid? and mwl-legal? functions here, since it concerns influence only [:span {:class (if (> inf id-limit) (if (> inf id-limit) @@ -780,11 +778,11 @@ (when (= (:side id) "Corp") (let [min-point (validator/min-agenda-points deck) points (validator/agenda-points deck)] - [:div (str (tr [:deck-builder.agenda-points "Agenda points"]) ": " points) + [:div (tr [:deck-builder_agenda-points "Agenda points"]) ": " points (when (< points min-point) - [:span.invalid " (" (tr [:deck-builder.min "minimum"]) " " min-point ")"]) + [:span.invalid " (" (tr [:deck-builder_min "minimum"]) " " min-point ")"]) (when (> points (inc min-point)) - [:span.invalid " (" (tr [:deck-builder.max "maximum"]) " " (inc min-point) ")"])])) + [:span.invalid " (" (tr [:deck-builder_max "maximum"]) " " (inc min-point) ")"])])) (when (validator/format-point-limit (:format deck)) [:div [deck-points-span deck]]) [:div [deck-status-span deck true true false]]]])) @@ -796,7 +794,7 @@ (for [group (sort-by first (group-by #(get-in % [:card :type]) cards))] ^{:key (or (first group) "Unknown")} [:div.group - [:h4 (str (tr-type (or (first group) "Unknown")) " (" (validator/card-count (last group)) ")") ] + [:h4 (tr-type (or (first group) "Unknown")) " (" (validator/card-count (last group)) ")" ] (doall (for [line (sort-by #(get-in % [:card :title]) (last group))] ^{:key (or (get-in line [:card :code]) line)} @@ -823,14 +821,14 @@ (defn edit-buttons [s] [:div.button-bar - [:button {:on-click #(save-deck s)} (tr [:deck-builder.save "Save"])] - [:button {:on-click #(cancel-edit s)} (tr [:deck-builder.cancel "Cancel"])]]) + [:button {:on-click #(save-deck s)} (tr [:deck-builder_save "Save"])] + [:button {:on-click #(cancel-edit s)} (tr [:deck-builder_cancel "Cancel"])]]) (defn delete-buttons [s] [:div.button-bar - [:button {:on-click #(handle-delete s)} (tr [:deck-builder.confirm-delete "Confirm Delete"])] - [:button {:on-click #(end-delete s)} (tr [:deck-builder.cancel "Cancel"])]]) + [:button {:on-click #(handle-delete s)} (tr [:deck-builder_confirm-delete "Confirm Delete"])] + [:button {:on-click #(end-delete s)} (tr [:deck-builder_cancel "Cancel"])]]) (defn- reset-deck-filters [state] (swap! state assoc @@ -841,15 +839,15 @@ (defn view-buttons [s deck] [:div.button-bar - [cond-button (tr [:deck-builder.edit "Edit"]) + [cond-button (tr [:deck-builder_edit "Edit"]) (not (:locked deck)) #(edit-deck s)] - [:button {:on-click #(delete-deck s)} (tr [:deck-builder.delete "Delete"])] - [:button {:on-click #(do (reset-deck-filters s) (copy-deck s))} (tr [:deck-builder.copy "Copy"])] + [:button {:on-click #(delete-deck s)} (tr [:deck-builder_delete "Delete"])] + [:button {:on-click #(do (reset-deck-filters s) (copy-deck s))} (tr [:deck-builder_copy "Copy"])] (when (and (:stats deck) (not= "none" (get-in @app-state [:options :deckstats]))) [:button {:on-click #(clear-deck-stats s)} - (tr [:deck-builder.clear-stats "Clear Stats"])]) + (tr [:deck-builder_clear-stats "Clear Stats"])]) ;; (let [disabled (or (:editing-game @app-state false) ;; (:gameid @app-state false) ;; (and (not= (:format deck) "casual") @@ -861,7 +859,7 @@ ;; ) ;; :disabled disabled ;; :class (when disabled "disabled")} - ;; (tr [:deck-builder.create-game "Create Game"])]) + ;; (tr [:deck-builder_create-game "Create Game"])]) ]) (defn view-toggles @@ -899,10 +897,10 @@ (defn deck-name-editor [s] [:div - [:h3 (tr [:deck-builder.deck-name "Deck name"])] + [:h3 (tr [:deck-builder_deck-name "Deck name"])] [:input.deckname {:type "text" - :placeholder (tr [:deck-builder.deck-name "Deck name"]) + :placeholder (tr [:deck-builder_deck-name "Deck name"]) :ref #(swap! db-dom assoc :deckname %) :value (get-in @s [:deck :name]) :on-change #(swap! s assoc-in [:deck :name] (.. % -target -value))}]]) @@ -919,7 +917,7 @@ (defn format-editor [s] [:div - [:h3 (tr [:deck-builder.format "Format"])] + [:h3 (tr [:deck-builder_format "Format"])] [:select.format {:value (get-in @s [:deck :format] "standard") :on-change #(change-format s (.. % -target -value))} (doall @@ -942,7 +940,7 @@ (defn identity-editor [s] [:div - [:h3 (tr [:deck-builder.identity "Identity"])] + [:h3 (tr [:deck-builder_identity "Identity"])] [:select.identity {:value (identity-option-string (get-in @s [:deck :identity])) :on-change #(swap! s assoc-in [:deck :identity] (create-identity s %))} (let [idents (side-identities (get-in @s [:deck :identity :side]) (get-in @s [:deck :format]))] @@ -974,7 +972,7 @@ (defn notes-textbox [s] [:textarea.notes-edit - {:placeholder (tr [:deck-builder.deck-notes "Deck notes"]) + {:placeholder (tr [:deck-builder_deck-notes "Deck notes"]) :ref #(swap! db-dom assoc :deck-notes %) :value (get-in @s [:deck :notes]) :on-change #(swap! s assoc-in [:deck :notes] (.. % -target -value))}]) @@ -987,24 +985,24 @@ [identity-editor s] [card-lookup s] [:div - [:h3 (tr [:deck-builder.decklist "Decklist"]) - [:span.small (tr [:deck-builder.decklist-inst "(Type or paste a decklist, it will be parsed)"])]]] + [:h3 (tr [:deck-builder_decklist "Decklist"]) + [:span.small (tr [:deck-builder_decklist-inst "(Type or paste a decklist, it will be parsed)"])]]] [edit-textbox s] [:div - [:h3 (tr [:deck-builder.notes "Notes"])]] + [:h3 (tr [:deck-builder_notes "Notes"])]] [notes-textbox s]]) (defn collection-buttons [s user decks-loaded] [:div.button-bar - [cond-button (tr [:deck-builder.new-corp "New Corp deck"]) + [cond-button (tr [:deck-builder_new-corp "New Corp deck"]) (and @user @decks-loaded) #(do (reset-deck-filters s) (new-deck s "Corp"))] - [cond-button (tr [:deck-builder.new-runner "New Runner deck"]) + [cond-button (tr [:deck-builder_new-runner "New Runner deck"]) (and @user @decks-loaded) #(do (reset-deck-filters s) (new-deck s "Runner"))] - [cond-button (tr [:deck-builder.import-button "Import deck"]) (and @user @decks-loaded) + [cond-button (tr [:deck-builder_import-button "Import deck"]) (and @user @decks-loaded) #(reagent-modals/modal! [import-deck-modal] {:shown (fn [] (.focus (.getElementById js/document "nrdb-input")))})]]) @@ -1018,10 +1016,9 @@ (callback state)))} (doall (for [option options] - ^{:key option} [:option.deckfilter-option {:value option - :key option - :dangerouslySetInnerHTML #js {:__html (translator option)}}]))]) + :key option} + (translator option)]))]) (defn- handle-side-changed [state] (swap! state assoc :faction-filter all-factions-filter)) @@ -1040,10 +1037,9 @@ [:button {:class (if-not @decks-loaded "disabled" "") :on-click #(reset-deck-filters state)} - (tr [:deck-builder.reset "Reset"])]])) + (tr [:deck-builder_reset "Reset"])]])) -(defn- zoom-card-view [card state] - [card state] +(defn- zoom-card-view [card] (when-let [url (image-url card)] [:div.card-preview.blue-shade [:img {:src url @@ -1061,7 +1057,7 @@ (let [art (:art line) id (:id line) updated-card (add-params-to-card (:card line) id art)] - [zoom-card-view updated-card s]))]])) + [zoom-card-view updated-card]))]])) (defn- class-for-state [s] (r/with-let [edit (r/cursor s [:edit]) @@ -1118,7 +1114,7 @@ [edit-panel s]]]])}))) (go (let [cards (! cards-channel cards))) @@ -1128,6 +1124,6 @@ (defmethod ws/event-msg-handler :decks/import-success [{data :?data}] (non-game-toast data "success" nil) - (go (let [json (:json ( "[" (tr [:lobby_private "PRIVATE"]) "] "]) + (:title game) + (let [c (count (:spectators game))] + (when (pos? c) + [:<> " (" (tr [:lobby_spectator-count] {:cnt c}) ")"]))]) (defn- precon-span [precon] (when precon - [:span.format-precon (str ": " (tr (:tr-tag (matchup-by-key precon))))])) + [:span.format-precon ": " (tr (:tr-tag (matchup-by-key precon)))])) (defn- precon-under-span [precon] (when precon @@ -187,14 +189,14 @@ (defn- open-decklists-span [precon open-decklists] (when (and open-decklists (not precon)) - [:span.open-decklists (str " " (tr [:lobby.open-decklists-b] "(open decklists)"))])) + [:span.open-decklists (str " " (tr [:lobby_open-decklists-b] "(open decklists)"))])) (defn game-format [{fmt :format singleton? :singleton precon :precon open-decklists :open-decklists}] [:div {:class "game-format"} - [:span.format-label (tr [:lobby.format "Format"]) ": "] + [:span.format-label (tr [:lobby_format "Format"]) ": "] [:span.format-type (tr-format (slug->format fmt "Unknown"))] [precon-span precon] - [:span.format-singleton (str (when singleton? (str " " (tr [:lobby.singleton-b "(singleton)"]))))] + [:span.format-singleton (str (when singleton? (str " " (tr [:lobby_singleton-b "(singleton)"]))))] [open-decklists-span precon open-decklists] [precon-under-span precon]]) diff --git a/src/cljs/nr/gameboard/actions.cljs b/src/cljs/nr/gameboard/actions.cljs index 15c4459384..1b14c192ba 100644 --- a/src/cljs/nr/gameboard/actions.cljs +++ b/src/cljs/nr/gameboard/actions.cljs @@ -51,19 +51,19 @@ (declare toast) (defn handle-timeout [gameid] (when (= gameid (current-gameid app-state)) - (toast (tr [:game.inactivity "Game closed due to inactivity"]) "error" {:time-out 0 :close-button true}) + (toast (tr [:game_inactivity "Game closed due to inactivity"]) "error" {:time-out 0 :close-button true}) (leave-game!))) (defn handle-timeout-soon [gameid] (when (= gameid (current-gameid app-state)) (play-sfx ["time-out"]) - (toast (tr [:game.timeout-soon "Game will time out within 30 seconds for inactivity"]) + (toast (tr [:game_timeout-soon "Game will time out within 30 seconds for inactivity"]) "error" {:time-out 29000 :close-button true}))) (defn handle-error [] - (toast (tr [:game.error "Internal Server Error. Please type /bug in the chat and follow the instructions."]) + (toast (tr [:game_error "Internal Server Error. Please type /bug in the chat and follow the instructions."]) "error" {:time-out 0 :close-button true}) diff --git a/src/cljs/nr/gameboard/board.cljs b/src/cljs/nr/gameboard/board.cljs index adb1216a97..52187566fc 100644 --- a/src/cljs/nr/gameboard/board.cljs +++ b/src/cljs/nr/gameboard/board.cljs @@ -25,7 +25,7 @@ [nr.gameboard.right-pane :refer [content-pane]] [nr.gameboard.state :refer [game-state not-spectator? replay-side]] [nr.sounds :refer [update-audio]] - [nr.translations :refer [tr tr-side tr-game-prompt]] + [nr.translations :refer [tr tr-game-prompt tr-side]] [nr.utils :refer [banned-span checkbox-button cond-button get-image-path image-or-face map-longest render-icons render-message]] [nr.ws :as ws] @@ -310,7 +310,7 @@ (defn remote->name [server] (let [num (remote->num server)] - (str (tr [:game.server "Server"]) " " num))) + (tr [:game_server "Server"] {:num num}))) (defn zone->sort-key [zone] (case (if (keyword? zone) zone (last zone)) @@ -372,9 +372,9 @@ (case implemented (:full "full") nil [:div.panel.blue-shade.implementation {:style {:right (get-in @app-state [:options :log-width])}} - (case implemented - nil [:span.unimplemented (tr [:game.unimplemented "Unimplemented"])] - [:span.impl-msg implemented])])))) + (if implemented + [:span.impl-msg implemented] + [:span.unimplemented (tr [:game_unimplemented "Unimplemented"])])])))) (defn card-zoom-display [zoom-card img-side] @@ -540,16 +540,16 @@ [:button.win-right {:on-click #(close-card-menu) :type "button"} "✘"] (when (or (seq runner-abilities) (seq subroutines)) - [:span.float-center (tr [:game.abilities "Abilities"]) ":"]) + [:span.float-center (tr [:game_abilities "Abilities"]) ":"]) [:ul (list-abilities :runner card runner-abilities) (when (seq subroutines) - [card-menu-item (tr [:game.let-subs-fire "Let unbroken subroutines fire"]) + [card-menu-item (tr [:game_let-subs-fire "Let unbroken subroutines fire"]) #(do (send-command "system-msg" {:msg (str "indicates to fire all unbroken subroutines on " title)}) (close-card-menu))])] (when (seq subroutines) - [:span.float-center (tr [:game.subs "Subroutines"]) ":"]) + [:span.float-center (tr [:game_subs "Subroutines"]) ":"]) (doall (map-indexed (fn [i sub] @@ -572,7 +572,7 @@ [:div.panel.blue-shade.corp-abilities.active-menu {:style {:display "inline"}} [:button.win-right {:on-click #(close-card-menu) :type "button"} "✘"] (when (seq corp-abilities) - [:span.float-center (tr [:game.abilities "Abilities"]) ":"]) + [:span.float-center (tr [:game_abilities "Abilities"]) ":"]) [:ul (list-abilities :corp card corp-abilities)]])) (defn encounter-info-div @@ -590,10 +590,10 @@ [:div.panel.blue-shade.encounter-info {:style {:display "inline"}} [:span.active.float-center (get-title ice)] [:span.info {:style {:display "block"}} (join " - " subtypes)] - [:span.float-center (tr [:card-browser.strength] "Strength") ": " current-strength] + [:span.float-center (tr [:card-browser_strength "Strength"] {:strength current-strength})] [:hr] (when (seq subroutines) - [:span.float-center (tr [:game.subs "Subroutines"]) ":"]) + [:span.float-center (tr [:game_subs "Subroutines"]) ":"]) (doall (map-indexed (fn [i sub] @@ -634,7 +634,7 @@ [:div.panel.blue-shade.abilities.active-menu {:style {:display "inline"}} [:button.win-right {:on-click #(close-card-menu) :type "button"} "✘"] (when (seq actions) - [:span.float-center (tr [:game.actions "Actions"]) ":"]) + [:span.float-center (tr [:game_actions "Actions"]) ":"]) (when (seq actions) [:ul (doall @@ -648,7 +648,7 @@ "score" false false)] ^{:key action} - [card-menu-item (capitalize (tr-game-prompt action)) + [card-menu-item (tr-game-prompt action) #(do (send-command action {:card card}) (if keep-menu-open (swap! card-menu assoc :keep-menu-open keep-menu-open) @@ -657,17 +657,17 @@ (when (or (seq abilities) (and (active? card) (seq (remove #(or (:fired %) (:broken %)) subroutines)))) - [:span.float-center (tr [:game.abilities "Abilities"]) ":"]) + [:span.float-center (tr [:game_abilities "Abilities"]) ":"]) [:ul (when (seq abilities) (list-abilities :ability card abilities)) (when (and (active? card) (seq (remove #(or (:fired %) (:broken %)) subroutines))) - [card-menu-item (tr [:game.fire-unbroken "Fire unbroken subroutines"]) + [card-menu-item (tr [:game_fire-unbroken "Fire unbroken subroutines"]) #(do (send-command "unbroken-subroutines" {:card card}) (close-card-menu))])] (when (seq subroutines) - [:span.float-center (tr [:game.subs "Subroutines"]) ":"]) + [:span.float-center (tr [:game_subs "Subroutines"]) ":"]) (when (seq subroutines) [:ul (doall @@ -858,12 +858,12 @@ (.stopPropagation event)) (defn label [cursor opts] - (let [fn (or (get-in opts [:opts :fn]) count) + (let [fn (or (:fn opts) count) classes (str (when (pos? (count cursor)) "darkbg ") - (get-in opts [:opts :classes]))] + (:classes opts))] [:div.header {:class classes} - (str (get-in opts [:opts :name]) - (when (not (get-in opts [:opts :hide-cursor])) (str " (" (fn cursor) ")")))])) + (:name opts) + (when-not (:hide-cursor opts) (str " (" (fn cursor) ")"))])) (defn- this-user? [user] @@ -899,10 +899,10 @@ [:div.panel.blue-shade.hand (drop-area (if (= :corp side) "HQ" "the Grip") {:class (when (> size 6) "squeeze")}) [build-hand-card-view filled-hand size "card-wrapper"] - [label filled-hand {:opts {:name (if (= :corp side) - (tr [:game.hq "HQ"]) - (tr [:game.grip "Grip"])) - :fn (fn [_] (str size "/" (:total @hand-size)))}}]] + [label filled-hand {:name (if (= :corp side) + (tr [:game_hq "HQ"]) + (tr [:game_grip "Grip"])) + :fn (fn [_] (str size "/" (:total @hand-size)))}]] (when popup [:div.panel.blue-shade.hand-expand {:on-click #(-> (:hand-popup @s) js/$ .fadeToggle)} @@ -910,10 +910,10 @@ (when popup [:div.panel.blue-shade.popup {:ref #(swap! s assoc :hand-popup %) :class popup-direction} [:div - [:a {:on-click #(close-popup % (:hand-popup @s) nil false false)} (tr [:game.close "Close"])] - [:label (tr [:game.card-count] size)] + [:a {:on-click #(close-popup % (:hand-popup @s) nil false false)} (tr [:game_close "Close"])] + [:label (tr [:game_card-count] size)] (let [{:keys [total]} @hand-size] - (stat-controls :hand-size [:div.hand-size (str total " " (tr [:game.max-hand "Max hand size"]))])) + (stat-controls :hand-size [:div.hand-size (tr [:game_max-hand "Max hand size"] {:total total})])) [build-hand-card-view filled-hand size "card-popup-wrapper"]]])])))) (defn show-deck [event ref] @@ -923,15 +923,17 @@ (defn identity-view [render-side identity hand-count] (let [is-runner (= :runner render-side) - title (if is-runner (tr [:game.grip "Grip"]) (tr [:game.hq "HQ"]))] + title (if is-runner (tr [:game_grip "Grip"]) (tr [:game_hq "HQ"]))] [:div.blue-shade.identity [card-view @identity] [:div.header {:class "darkbg server-label"} - (str title " (" hand-count ")")]])) + title " (" hand-count ")"]])) (defn deck-view [render-side player-side identity deck deck-count] (let [is-runner (= :runner render-side) - title (if is-runner (tr [:game.stack "Stack"]) (tr [:game.r&d "R&D"])) + title (if is-runner + (tr [:game_stack "Stack"]) + (tr [:game_rnd "R&D"])) ref (if is-runner "stack" "rd") menu-ref (keyword (str ref "-menu")) content-ref (keyword (str ref "-content"))] @@ -952,15 +954,17 @@ (when (and (= render-side player-side) (not (is-replay?))) [:div.panel.blue-shade.menu {:ref #(swap! board-dom assoc menu-ref %)} [:div {:on-click #(do (send-command "shuffle") - (-> (menu-ref @board-dom) js/$ .fadeOut))} (tr [:game.shuffle "Shuffle"])] - [:div {:on-click #(show-deck % ref)} (tr [:game.show "Show"])]]) + (-> (menu-ref @board-dom) js/$ .fadeOut))} + (tr [:game_shuffle "Shuffle"])] + [:div {:on-click #(show-deck % ref)} + (tr [:game_show "Show"])]]) (when (and (= render-side player-side) (not (is-replay?))) [:div.panel.blue-shade.popup {:ref #(swap! board-dom assoc content-ref %)} [:div [:a {:on-click #(close-popup % (content-ref @board-dom) "stops looking at their deck" false true)} - (tr [:game.close "Close"])] + (tr [:game_close "Close"])] [:a {:on-click #(close-popup % (content-ref @board-dom) "stops looking at their deck" true true)} - (tr [:game.close-shuffle "Close & Shuffle"])]] + (tr [:game_close-shuffle "Close & Shuffle"])]] (doall (for [card @deck] ^{:key (:cid card)} @@ -977,11 +981,12 @@ (if (some graveyard-highlight-card? @discard) "graveyard-highlight-bg" "darkbg"))} - (str (tr [:game.heap "Heap"]) " (" (count @discard) ")")]] + (tr [:game_heap "Heap"] {:cnt (count @discard)})]] [:div.panel.blue-shade.popup {:ref #(swap! s assoc :popup %) :class (if (= player-side :runner) "me" "opponent")} [:div - [:a {:on-click #(close-popup % (:popup @s) nil false false)} (tr [:game.close "Close"])]] + [:a {:on-click #(close-popup % (:popup @s) nil false false)} + (tr [:game_close "Close"])]] (doall (for [card (if (sort-heap?) (sort-heap @discard) @discard)] ^{:key (:cid card)} @@ -1009,16 +1014,20 @@ "darkbg"))} (let [total (count @discard) face-up (count (filter faceup? @discard))] - (str (tr [:game.archives "Archives"]) - ;; use non-breaking space to keep counts on same line - " (" (tr [:game.up-down-count] total face-up) ")"))]] + (tr [:game_archives "Archives"] + {:faceup face-up + :facedown (- total face-up)}))]] [:div.panel.blue-shade.popup {:ref #(swap! s assoc :popup %) :class (if (= (:side @game-state) :runner) "opponent" "me")} [:div - [:a {:on-click #(close-popup % (:popup @s) nil false false)} (tr [:game.close "Close"])] - [:label (let [total (count @discard) - face-up (count (filter faceup? @discard))] - (tr [:game.face-down-count] total face-up))]] + [:a {:on-click #(close-popup % (:popup @s) nil false false)} + (tr [:game_close "Close"])] + [:label (let [d @discard + total (count d) + face-up (count (filter faceup? d))] + (tr [:game_face-down-count] + {:total total + :facedown (- total face-up)}))]] (doall (for [[idx c] (map-indexed vector (if (sort-archives?) (sort-archives @discard) @discard))] ^{:key idx} @@ -1039,13 +1048,13 @@ :style {:left (when (> size 1) (* (/ 128 size) i))}} [:div [card-view card nil noclick]]]) @cards)) - [label @cards {:opts {:name name}}] + [label @cards {:name name}] (when popup [:div.panel.blue-shade.popup {:ref #(swap! dom assoc :rfg-popup %) :class "opponent"} [:div - [:a {:on-click #(close-popup % (:rfg-popup @dom) nil false false)} (tr [:game.close "Close"])] - [:label (tr [:game.card-count] size)]] + [:a {:on-click #(close-popup % (:rfg-popup @dom) nil false false)} (tr [:game_close "Close"])] + [:label (tr [:game_card-count] {:cnt size})]] (doall (for [c @cards] ^{:key (:cid c)} @@ -1065,11 +1074,12 @@ [card-view card] [facedown-card (:side card)])]) @cards)) - [label @cards {:opts {:name name}}]])))) + [label @cards {:name name}]])))) (defn scored-view [scored agenda-point agenda-point-req me?] (let [size (count @scored) - ctrl (if me? stat-controls (fn [key content] content))] + ctrl (if me? stat-controls (fn [key content] content)) + point-req @agenda-point-req] [:div.panel.blue-shade.scored.squeeze (doall (map-indexed (fn [i card] @@ -1077,10 +1087,14 @@ :style {:left (when (> size 1) (* (/ 128 (dec size)) i))}} [:div [card-view card]]]) @scored)) - [label @scored {:opts {:name (tr [:game.scored-area "Scored Area"])}}] + [label @scored {:name (tr [:game_scored-area "Scored Area"])}] [:div.stats-area - (ctrl :agenda-point [:div (tr [:game.agenda-count] @agenda-point) - (tr [:game.agenda-point-req (if-not (= 7 agenda-point-req) (str " (" agenda-point-req " required)") "")] @agenda-point-req)])]])) + (ctrl :agenda-point [:div (if (= 7 point-req) + (tr [:game_agenda-count] + {:agenda-point @agenda-point}) + (tr [:game_agenda-count-with-req] + {:agenda-point @agenda-point + :agenda-point-req point-req}))])]])) (defn run-arrow [run] [:div.run-arrow [:div {:class (cond @@ -1133,7 +1147,7 @@ (and (< 1 (count content)) (not is-first))) "shift"))} [card-view card flipped]])))) - [label content (update-in opts [:opts] assoc :classes "server-label" :hide-cursor true)]]])) + [label content (assoc opts :classes "server-label" :hide-cursor true)]]])) (defn stacked-label [cursor similar-servers opts] (let [similar-server-names (->> similar-servers @@ -1141,7 +1155,7 @@ (map remote->name)) full-server-names (cons (get-in opts [:opts :name]) similar-server-names) numbers (map #(second (split % " ")) full-server-names)] - [label full-server-names (update-in opts [:opts] assoc + [label full-server-names (assoc opts :classes "server-label" :name (str "Servers " (join ", " numbers)) :hide-cursor true)])) @@ -1289,52 +1303,46 @@ (defn build-win-box "Builds the end of game pop up game end" [game-state] - (let [win-shown (r/atom false)] + (let [win-shown (r/atom false) + corp-stats (r/cursor game-state [:stats :corp]) + runner-stats (r/cursor game-state [:stats :runner])] (fn [game-state] (when (and (:winner @game-state) (not @win-shown)) (let [winner (:winner @game-state) winning-user (:winning-user @game-state) turn (:turn @game-state) - reason (:reason @game-state) - time (get-in @game-state [:stats :time :elapsed])] + reason (capitalize (:reason @game-state)) + time (get-in @game-state [:stats :time :elapsed]) + args {:winner winning-user + :side winner + :reason reason + :turn turn}] [:div.win.centered.blue-shade [:div - winning-user - " (" (capitalize (tr-side winner)) ") " - (cond - (= "Decked" (capitalize reason)) - (tr [:game.win-decked] turn) - - (= "Flatline" (capitalize reason)) - (tr [:game.win-flatlined] turn) - - (= "Concede" (capitalize reason)) - (tr [:game.win-conceded] turn) - - (= "Claim" (capitalize reason)) - (tr [:game.win-claimed] turn) - - (= "Agenda" (capitalize reason)) - (tr [:game.win-points] turn) - - :else - (tr [:game.win-other] turn reason))] - [:div (tr [:game.time-taken] time)] + (case reason + "Decked" (tr [:game_win-decked] args) + "Flatline" (tr [:game_win-flatlined] args) + "Concede" (tr [:game_win-conceded] args) + "Claim" (tr [:game_win-claimed] args) + "Agenda" (tr [:game_win-points] args) + #_:else (tr [:game_win-other] args))] + [:div (tr [:game_time-taken] {:time time})] [:br] - [build-game-stats (get-in @game-state [:stats :corp]) (get-in @game-state [:stats :runner])] + [build-game-stats @corp-stats @runner-stats] (when (not= :spectator (:side @game-state)) - [:br] - [:div {:class "end-of-game-buttons"} - (when (= :corp (:side @game-state)) - [:button#rez-all - {:on-click #(ws/ws-send! [:game/say {:gameid (current-gameid app-state) - :msg "/rez-all"}])} - (tr [:game.rez-all "Rez All"])]) - [:button#reveal-hand - {:on-click #(ws/ws-send! [:game/say {:gameid (current-gameid app-state) - :msg "/show-hand"}])} - (tr [:game.reveal-my-hand "Reveal My Hand"])]]) + [:<> + [:br] + [:div {:class "end-of-game-buttons"} + (when (= :corp (:side @game-state)) + [:button#rez-all + {:on-click #(ws/ws-send! [:game/say {:gameid (current-gameid app-state) + :msg "/rez-all"}])} + (tr [:game_rez-all "Rez All"])]) + [:button#reveal-hand + {:on-click #(ws/ws-send! [:game/say {:gameid (current-gameid app-state) + :msg "/show-hand"}])} + (tr [:game_reveal-my-hand "Reveal My Hand"])]]]) [:button.win-right {:on-click #(reset! win-shown true) :type "button"} "✘"]]))))) (defn- build-in-game-decklists @@ -1350,8 +1358,8 @@ [:table.decklists.table [:tbody [:tr.win.th - [:td.win.th (tr [:side.corp "Corp"])] [:td.win.th] - [:td.win.th (tr [:side.runner "Runner"])] [:td.win.th]] + [:td.win.th [tr-side "Corp"]] [:td.win.th] + [:td.win.th [tr-side "Runner"]] [:td.win.th]] (doall (map-indexed (fn [i [corp runner]] [:tr {:key i} @@ -1435,15 +1443,16 @@ (if (or (= :spectator @my-side) (and @my-keep @op-keep)) [cond-button (if (= :spectator @my-side) - (tr [:game.close "Close"]) (tr [:game.start "Start Game"])) + (tr [:game_close "Close"]) + (tr [:game_start "Start Game"])) true #(swap! app-state assoc :start-shown true)] - (list ^{:key "keepbtn"} [cond-button (tr [:game.keep "Keep"]) + (list ^{:key "keepbtn"} [cond-button (tr [:game_keep "Keep"]) (= "mulligan" (:prompt-type @prompt-state)) #(send-command "choice" {:choice {:uuid (->> (:choices @prompt-state) (filter (fn [c] (= "Keep" (:value c)))) first :uuid)}})] - ^{:key "mullbtn"} [cond-button (tr [:game.mulligan "Mulligan"]) + ^{:key "mullbtn"} [cond-button (tr [:game_mulligan "Mulligan"]) (= "mulligan" (:prompt-type @prompt-state)) #(do (send-command "choice" {:choice {:uuid (->> (:choices @prompt-state) (filter (fn [c] (= "Mulligan" (:value c)))) @@ -1475,27 +1484,27 @@ (nth run-ice (dec pos)))))) (def phase->title - {"initiation" (tr [:game.initiation "Initiation"]) - "approach-ice" (tr [:game.approach-ice "Approach ice"]) - "encounter-ice" (tr [:game.encounter-ice "Encounter ice"]) - "movement" (tr [:game.movement "Movement"]) - "success" (tr [:game.success "Success"])}) + {"initiation" (tr [:game_initiation "Initiation"]) + "approach-ice" (tr [:game_approach-ice "Approach ice"]) + "encounter-ice" (tr [:game_encounter-ice "Encounter ice"]) + "movement" (tr [:game_movement "Movement"]) + "success" (tr [:game_success "Success"])}) (defn phase->next-phase-title ([run] (phase->next-phase-title (:phase @run) (:position @run))) ([phase position] (case phase - "initiation" (tr [:game.approach-ice "Approach ice"]) + "initiation" (tr [:game_approach-ice "Approach ice"]) "approach-ice" (if (rezzed? (get-current-ice)) - (tr [:game.encounter-ice "Encounter ice"]) - (tr [:game.movement "Movement"])) - "encounter-ice" (tr [:game.movement "Movement"]) + (tr [:game_encounter-ice "Encounter ice"]) + (tr [:game_movement "Movement"])) + "encounter-ice" (tr [:game_movement "Movement"]) "movement" (if (zero? position) - (tr [:game.success "Success"]) - (tr [:game.approach-ice "Approach ice"])) - "success" (tr [:game.run-ends "Run ends"]) + (tr [:game_success "Success"]) + (tr [:game_approach-ice "Approach ice"])) + "success" (tr [:game_run-ends "Run ends"]) ;; Error - (tr [:game.no-current-run "No current run"])))) + (tr [:game_no-current-run "No current run"])))) (defn corp-run-div [run encounters] @@ -1507,18 +1516,18 @@ [:div {:style {:text-align "center"} :on-mouse-over #(card-highlight-mouse-over % ice button-channel) :on-mouse-out #(card-highlight-mouse-out % ice button-channel)} - (tr [:game.encounter-ice "Encounter ice"]) ": " (render-message (get-title ice))] + (tr [:game_encounter-ice "Encounter ice"]) ": " (render-message (get-title ice))] [:hr] (when (or (:button @app-state) (get-in @app-state [:options :display-encounter-info])) [encounter-info-div ice])]) (when @run - [:h4 (tr [:game.current-phase "Current phase"]) ":" [:br] (get phase->title (:phase @run) (tr [:game.unknown-phase "Unknown phase"]))]) + [:h4 (tr [:game_current-phase "Current phase"]) ":" [:br] (get phase->title (:phase @run) (tr [:game_unknown-phase "Unknown phase"]))]) (cond (and (= "approach-ice" (:phase @run)) ice) [cond-button - (str (tr [:game.rez "Rez"]) " " (get-title ice)) + (str (tr [:game_rez "Rez"]) " " (get-title ice)) (not (rezzed? ice)) #(send-command "rez" {:card ice :press-continue (get-in @app-state [:options :pass-on-rez])})] @@ -1526,7 +1535,7 @@ (or (= "encounter-ice" (:phase @run)) @encounters) [cond-button - (tr [:game.fire-unbroken "Fire unbroken subroutines"]) + (tr [:game_fire-unbroken "Fire unbroken subroutines"]) (and (seq (:subroutines ice)) (some #(and (not (:broken %)) (not (:fired %)) @@ -1540,16 +1549,16 @@ (= 1 (:encounter-count @encounters)))] [cond-button (if pass-ice? - (str (tr [:game.continue-to "Continue to"]) " " (phase->next-phase-title run)) - (tr [:game.continue "Continue"])) + (tr [:game_continue-to "Continue to"] {:phase (phase->next-phase-title run)}) + (tr [:game_continue "Continue"])) (not= "corp" (:no-action @encounters)) #(send-command "continue")]) ;;Non-encounter continue button [cond-button (if (or (:next-phase @run) (zero? (:position @run))) - (tr [:game.no-further "No further actions"]) - (str (tr [:game.continue-to "Continue to"]) " " (phase->next-phase-title run))) + (tr [:game_no-further "No further actions"]) + (tr [:game_continue-to "Continue to"] {:phase (phase->next-phase-title run)})) (and (not= "initiation" (:phase @run)) (not= "success" (:phase @run)) (not= "corp" (:no-action @run))) @@ -1559,8 +1568,8 @@ (<= (:encounter-count @encounters) 1) (not= "success" (:phase @run))) [checkbox-button - (tr [:game.stop-auto-pass "Stop auto-passing priority"]) - (tr [:game.auto-pass "Auto-pass priority"]) + (tr [:game_stop-auto-pass "Stop auto-passing priority"]) + (tr [:game_auto-pass "Auto-pass priority"]) (:corp-auto-no-action @run) #(send-command "toggle-auto-no-action")])])) @@ -1578,12 +1587,12 @@ [:div {:style {:text-align "center"} :on-mouse-over #(card-highlight-mouse-over % ice button-channel) :on-mouse-out #(card-highlight-mouse-out % ice button-channel)} - (tr [:game.encounter-ice "Encounter ice"]) ": " (render-message (get-title ice))] + (tr [:game_encounter-ice "Encounter ice"]) ": " (render-message (get-title ice))] [:hr] (when (or (:button @app-state) (get-in @app-state [:options :display-encounter-info])) [encounter-info-div ice])]) (when @run - [:h4 (tr [:game.current-phase "Current phase"]) ":" [:br] (get phase->title phase)]) + [:h4 (tr [:game_current-phase "Current phase"]) ":" [:br] (get phase->title phase)]) (cond (:next-phase @run) @@ -1597,20 +1606,20 @@ (not (zero? (:position @run))) (not @encounters)) [cond-button - (str (tr [:game.continue-to "Continue to"]) " " (phase->next-phase-title run)) + (tr [:game_continue-to "Continue to"] {:phase (phase->next-phase-title run)}) (not= "runner" (:no-action @run)) #(send-command "continue")] (and (zero? (:position @run)) (not @encounters) (= "movement" phase)) - [cond-button (tr [:game.breach-server "Breach server"]) + [cond-button (tr [:game_breach-server "Breach server"]) (not= "runner" (:no-action @run)) #(send-command "continue")]) (when @encounters [cond-button - (tr [:game.let-subs-fire "Let unbroken subroutines fire"]) + (tr [:game_let-subs-fire "Let unbroken subroutines fire"]) (and (seq (:subroutines ice)) (some #(and (not (:broken %)) (not (:fired %)) @@ -1622,15 +1631,15 @@ (when @encounters [cond-button (if pass-ice? - (str (tr [:game.continue-to "Continue to"]) " " (phase->next-phase-title run)) - (tr [:game.continue "Continue"])) + (tr [:game_continue-to "Continue to"] {:phase (phase->next-phase-title run)}) + (tr [:game_continue "Continue"])) (not= "runner" (:no-action @encounters)) #(send-command "continue")]) (when (and @run (not= "success" phase)) [cond-button - (tr [:game.jack-out "Jack Out"]) + (tr [:game_jack-out "Jack Out"]) (and (= "movement" phase) (not (:cannot-jack-out @run)) (not= "runner" (:no-action @run))) @@ -1651,10 +1660,10 @@ (if (nil? strength) (if (= "corp" player) ;; This is a trace prompt for the corp, show runner link + credits - [:div.info (tr [:side.runner "Runner"]) ": " link [:span {:class "anr-icon link"}] + [:div.info [tr-side "Runner"] ": " link [:span {:class "anr-icon link"}] " + " runner-credits [:span {:class "anr-icon credit"}]] ;; Trace in which the runner pays first, showing base trace strength and corp credits - [:div.info (tr [:game.trace "Trace"]) ": " (if bonus (+ base bonus) base) + [:div.info (tr [:game_trace "Trace"]) ": " (if bonus (+ base bonus) base) " + " corp-credits [:span {:class "anr-icon credit"}]]) ;; This is a trace prompt for the responder to the trace, show strength (if (= "corp" player) @@ -1667,27 +1676,27 @@ (if (= "corp" player) (let [strength (if bonus (+ base bonus) base)] [:span (str strength " + ")]) - [:span link " " [:span {:class "anr-icon link"}] (str " + " )]) + [:span link " " [:span {:class "anr-icon link"}] " + " ]) (if (= "corp" player) - [:span link " " [:span {:class "anr-icon link"}] (str " + " )] + [:span link " " [:span {:class "anr-icon link"}] " + " ] (let [strength (if bonus (+ base bonus) base)] - [:span (str strength " + ")])))) + [:span strength " + "])))) [:select#credit {:value @!value :on-change #(reset! !value (.. % -target -value)) :onKeyUp #(when (= "Enter" (.-key %)) (-> "#trace-submit" js/$ .click) (.stopPropagation %))} (doall (for [i (range (inc choices))] - [:option {:value i :key i} i]))] (str " " (tr [:game.credits "credits"]))] + [:option {:value i :key i} i]))] (tr [:game_credits "credits"])] (when (or unbeatable beat-trace) (let [beat-str (if unbeatable - (tr [:game.unbeatable "Make Unbeatable"]) - (tr [:game.beat-trace "Beat Trace"]))] + (tr [:game_unbeatable "Make Unbeatable"]) + (tr [:game_beat-trace "Beat Trace"]))] [:button#trace-unbeatable {:on-click #(reset! !value (or unbeatable beat-trace))} [:div (str beat-str " (" (or unbeatable beat-trace)) [:span {:class "anr-icon credit"}] ")"]])) [:button#trace-submit {:on-click #(send-command "choice" {:choice (-> "#credit" js/$ .val str->int)})} - (tr [:game.ok "OK"])]])) + (tr [:game_ok "OK"])]])) (defn prompt-div [me {:keys [card msg prompt-type choices] :as prompt-state}] @@ -1710,7 +1719,7 @@ [:div {:style {:text-align "center"} :on-mouse-over #(card-highlight-mouse-over % card button-channel) :on-mouse-out #(card-highlight-mouse-out % card button-channel)} - (tr [:game.card "Card"]) ": " (render-message (get-title card))] + (tr [:game_card "Card"]) ": " (render-message (get-title card))] [:div.prompt-card-preview [card-view card false]])) [:hr]]) [:h4 (render-message msg)] @@ -1728,7 +1737,7 @@ [:option {:key i :value i} i]))]] [:button#number-submit {:on-click #(send-command "choice" {:choice (-> "#credit" js/$ .val str->int)})} - (tr [:game.ok "OK"])]]) + (tr [:game_ok "OK"])]]) ;; trace prompts require their own logic (= prompt-type "trace") @@ -1747,7 +1756,7 @@ [:option {:key i :value i} i]))]] [:button#credit-submit {:on-click #(send-command "choice" {:choice (-> "#credit" js/$ .val str->int)})} - (tr [:game.ok "OK"])]]) + (tr [:game_ok "OK"])]]) ;; auto-complete text box (:card-title choices) @@ -1758,7 +1767,7 @@ (-> "#card-submit" js/$ .click) (.stopPropagation %))}]] [:button#card-submit {:on-click #(send-command "choice" {:choice (-> "#card-title" js/$ .val)})} - (tr [:game.ok "OK"])]] + (tr [:game_ok "OK"])]] ;; choice of specified counters on card (:counter choices) @@ -1770,10 +1779,10 @@ (-> "#counter-submit" js/$ .click) (.stopPropagation %))} (doall (for [i (range (inc num-counters))] - [:option {:key i :value i} i]))] (str " " (tr [:game.credits "credits"]))] + [:option {:key i :value i} i]))] (tr [:game_credits "credits"])] [:button#counter-submit {:on-click #(send-command "choice" {:choice (-> "#credit" js/$ .val str->int)})} - (tr [:game.ok "OK"])]]) + (tr [:game_ok "OK"])]]) ;; otherwise choice of all present choices :else @@ -1798,27 +1807,27 @@ (not @end-turn)) [:button {:on-click #(do (close-card-menu) (send-command "end-turn"))} - (tr [:game.end-turn "End Turn"])]) + (tr [:game_end-turn "End Turn"])]) (when @end-turn [:button {:on-click #(do (swap! app-state assoc :start-shown true) (send-command "start-turn"))} - (tr [:game.start-turn "Start Turn"])])) + (tr [:game_start-turn "Start Turn"])])) (when (and (= (keyword @active-player) side) (or @runner-phase-12 @corp-phase-12)) [:button {:on-click #(send-command "end-phase-12")} (if (= side :corp) - (tr [:game.mandatory-draw "Mandatory Draw"]) - (tr [:game.take-clicks "Take Clicks"]))]) + (tr [:game_mandatory-draw "Mandatory Draw"]) + (tr [:game_take-clicks "Take Clicks"]))]) (when (= side :runner) [:div - [cond-button (tr [:game.remove-tag "Remove Tag"]) + [cond-button (tr [:game_remove-tag "Remove Tag"]) (and (not (or @runner-phase-12 @corp-phase-12)) (playable? (get-in @me [:basic-action-card :abilities 5])) (pos? (get-in @me [:tag :base]))) #(send-command "remove-tag")] [:div.run-button.menu-container - [cond-button (tr [:game.run "Run"]) + [cond-button (tr [:game_run "Run"]) (and (not (or @runner-phase-12 @corp-phase-12)) (pos? (:click @me))) #(do (send-command "generate-runnable-zones") @@ -1838,22 +1847,22 @@ (send-command "run" {:server label}))]) servers)))]]]]) (when (= side :corp) - [cond-button (tr [:game.purge "Purge"]) + [cond-button (tr [:game_purge "Purge"]) (and (not (or @runner-phase-12 @corp-phase-12)) (playable? (get-in @me [:basic-action-card :abilities 6]))) #(send-command "purge")]) (when (= side :corp) - [cond-button (tr [:game.trash-resource "Trash Resource"]) + [cond-button (tr [:game_trash-resource "Trash Resource"]) (and (not (or @runner-phase-12 @corp-phase-12)) (playable? (get-in @me [:basic-action-card :abilities 5])) (is-tagged? game-state)) #(send-command "trash-resource")]) - [cond-button (tr [:game.draw "Draw"]) + [cond-button (tr [:game_draw "Draw"]) (and (not (or @runner-phase-12 @corp-phase-12)) (playable? (get-in @me [:basic-action-card :abilities 1])) (pos? (:deck-count @me))) #(send-command "draw")] - [cond-button (tr [:game.gain-credit "Gain Credit"]) + [cond-button (tr [:game_gain-credit "Gain Credit"]) (and (not (or @runner-phase-12 @corp-phase-12)) (playable? (get-in @me [:basic-action-card :abilities 0]))) #(send-command "credit")]]) @@ -1938,10 +1947,9 @@ (when (and @remaining (not @hidden)) [:span.float-center.timer {:class (warning-class @remaining)} - (str - (when-not (:pos @remaining) "-") - (:minutes @remaining) (tr [:game.minutes "m:"]) - (:seconds @remaining) (tr [:game.seconds-remaining "s remaining"]))]))}))) + (when-not (:pos @remaining) "-") + (:minutes @remaining) (tr [:game_minutes "m:"]) + (:seconds @remaining) (tr [:game_seconds-remaining "s remaining"])]))}))) (defn- time-since "Helper method for match duration. Computes how much time since game start" @@ -1974,20 +1982,17 @@ (fn [] (when (not @hidden) [:span.float-center.timer - (str - (:minutes @duration) (tr [:game.minutes "m:"]) - (:seconds @duration) (tr [:game.seconds "s"]))]) - )}))) + (:minutes @duration) (tr [:game_minutes "m:"]) + (:seconds @duration) (tr [:game_seconds "s"])]))}))) (defn starting-timestamp [start-date timer] ;; I don't like using js/Date, but `toLocalTimeString` ;; is just too convenient - (let [start-time-string (str (tr [:game.game-start "Game start"]) - ": " (.toLocaleTimeString (js/Date. start-date))) - hide-timer (r/atom false)] + (let [hide-timer (r/atom false)] (fn [] [:div.panel.blue-shade.timestamp - [:span.float-center start-time-string] + [:span.float-center + (tr [:game_game-start "Game start"] {:timestamp (js/Date. start-date)})] [:<> [:span.pm {:on-click #(swap! hide-timer not)} (if @hide-timer "+" "-")] @@ -2279,15 +2284,15 @@ [:div (when-not (:replay @game-state) [starting-timestamp @start-date @timer]) - [rfg-view op-rfg (tr [:game.rfg "Removed from the game"]) true] - [rfg-view me-rfg (tr [:game.rfg "Removed from the game"]) true] - [rfg-view op-set-aside (tr [:game.set-aside "Set aside"]) false] - [rfg-view me-set-aside (tr [:game.set-aside "Set aside"]) false] - [play-area-view op-user (tr [:game.play-area "Play Area"]) op-play-area] - [play-area-view me-user (tr [:game.play-area "Play Area"]) me-play-area] - [rfg-view op-current (tr [:game.current "Current"]) false] - [rfg-view me-current (tr [:game.current "Current"]) false] - [rfg-view last-revealed (tr [:game.last-revealed "Last Revealed"]) false true]]) + [rfg-view op-rfg (tr [:game_rfg "Removed from the game"]) true] + [rfg-view me-rfg (tr [:game_rfg "Removed from the game"]) true] + [rfg-view op-set-aside (tr [:game_set-aside "Set aside"]) false] + [rfg-view me-set-aside (tr [:game_set-aside "Set aside"]) false] + [play-area-view op-user (tr [:game_play-area "Play Area"]) op-play-area] + [play-area-view me-user (tr [:game_play-area "Play Area"]) me-play-area] + [rfg-view op-current (tr [:game_current "Current"]) false] + [rfg-view me-current (tr [:game_current "Current"]) false] + [rfg-view last-revealed (tr [:game_last-revealed "Last Revealed"]) false true]]) (when (or (not= @side :spectator) (and (spectator-view-hidden?) (spectate-side))) [button-pane {:side me-side :active-player active-player :run run :encounters encounters diff --git a/src/cljs/nr/gameboard/diagrams.cljs b/src/cljs/nr/gameboard/diagrams.cljs index 62f2db9c83..2df8142929 100644 --- a/src/cljs/nr/gameboard/diagrams.cljs +++ b/src/cljs/nr/gameboard/diagrams.cljs @@ -14,92 +14,92 @@ (defn turn-timing-pane [] (fn [] [:div.diagram - [:section [:h3 (tr [:diagrams.turn.corp-turn "Corporation Turn"])]] + [:section [:h3 (tr [:diagrams_turn_corp-turn "Corporation Turn"])]] [:section - [:h4 (tr [:diagrams.turn.corp-draw-phase "5.6.1: Draw Phase"])] - (bullet 0 (render-icons (tr [:diagrams.turn.corp-draw-phase-a "Corporation gains allotted clicks (default: [click][click][click])"]))) - (bullet 1 (tr [:diagrams.turn.corp-draw-phase-b "Paid ability window. Corp may rez non-ice cards or score agendas during this window"])) - (bullet 2 (tr [:diagrams.turn.corp-draw-phase-c "Corporation recurring credits refill"])) - (bullet 3 (tr [:diagrams.turn.corp-draw-phase-d "The turn formally begins. Turn begins events resolve"])) - (bullet 4 (tr [:diagrams.turn.corp-draw-phase-e "The corporation performs their mandatory draw"])) - (bullet 5 (tr [:diagrams.turn.corp-draw-phase-f "Proceed to the action phase (5.6.2)"]))] + [:h4 (tr [:diagrams_turn_corp-draw-phase "5.6.1: Draw Phase"])] + (bullet 0 (render-icons (tr [:diagrams_turn_corp-draw-phase-a "Corporation gains allotted clicks (default: [click][click][click])"]))) + (bullet 1 (tr [:diagrams_turn_corp-draw-phase-b "Paid ability window. Corp may rez non-ice cards or score agendas during this window"])) + (bullet 2 (tr [:diagrams_turn_corp-draw-phase-c "Corporation recurring credits refill"])) + (bullet 3 (tr [:diagrams_turn_corp-draw-phase-d "The turn formally begins. Turn begins events resolve"])) + (bullet 4 (tr [:diagrams_turn_corp-draw-phase-e "The corporation performs their mandatory draw"])) + (bullet 5 (tr [:diagrams_turn_corp-draw-phase-f "Proceed to the action phase (5.6.2)"]))] [:section - [:h4 (tr [:diagrams.turn.corp-action-phase "5.6.2: Action Phase"])] - (bullet 0 (tr [:diagrams.turn.corp-action-phase-a "Paid ability window. Corp may rez non-ice cards or score agendas during this window"])) - (bullet 1 (render-icons (tr [:diagrams.turn.corp-action-phase-b "If the corporation has unspent [Clicks], they take an action"]))) - (bullet 2 (tr [:diagrams.turn.corp-action-phase-c "If an action occured, return to (a)"])) - (bullet 3 (tr [:diagrams.turn.corp-action-phase-d "The action phase is complete. Proceed to the discard phase (5.6.3)"]))] + [:h4 (tr [:diagrams_turn_corp-action-phase "5.6.2: Action Phase"])] + (bullet 0 (tr [:diagrams_turn_corp-action-phase-a "Paid ability window. Corp may rez non-ice cards or score agendas during this window"])) + (bullet 1 (render-icons (tr [:diagrams_turn_corp-action-phase-b "If the corporation has unspent [Clicks], they take an action"]))) + (bullet 2 (tr [:diagrams_turn_corp-action-phase-c "If an action occured, return to (a)"])) + (bullet 3 (tr [:diagrams_turn_corp-action-phase-d "The action phase is complete. Proceed to the discard phase (5.6.3)"]))] [:section - [:h4 (tr [:diagrams.turn.corp-discard-phase "5.6.3: Discard phase"])] - (bullet 0 (tr [:diagrams.turn.corp-discard-phase-a "The corporation discards to maximum hand size, if applicable"])) - (bullet 1 (tr [:diagrams.turn.corp-discard-phase-b "Paid ability window. Corp may rez non-ice cards during this window"])) - (bullet 2 (render-icons (tr [:diagrams.turn.corp-discard-phase-c "If the corporation has any [Clicks] remaining, they lose those [Clicks]"]))) - (bullet 3 (tr [:diagrams.turn.corp-discard-phase-d "The Corporations turn formally ends. Turn end triggers resolve"])) - (bullet 4 (tr [:diagrams.turn.corp-discard-phase-e "Proceed to the Runner turn"]))] + [:h4 (tr [:diagrams_turn_corp-discard-phase "5.6.3: Discard phase"])] + (bullet 0 (tr [:diagrams_turn_corp-discard-phase-a "The corporation discards to maximum hand size, if applicable"])) + (bullet 1 (tr [:diagrams_turn_corp-discard-phase-b "Paid ability window. Corp may rez non-ice cards during this window"])) + (bullet 2 (render-icons (tr [:diagrams_turn_corp-discard-phase-c "If the corporation has any [Clicks] remaining, they lose those [Clicks]"]))) + (bullet 3 (tr [:diagrams_turn_corp-discard-phase-d "The Corporations turn formally ends. Turn end triggers resolve"])) + (bullet 4 (tr [:diagrams_turn_corp-discard-phase-e "Proceed to the Runner turn"]))] - [:section [:h3 (tr [:diagrams.turn.runner-turn "Runner Turn"])]] + [:section [:h3 (tr [:diagrams_turn_runner-turn "Runner Turn"])]] [:section - [:h4 (tr [:diagrams.turn.runner-action-phase "5.7.1: Action Phase"])] - (bullet 0 (render-icons (tr [:diagrams.turn.runner-action-phase-a "Runner gains allotted clicks (default: [click][click][click][click])"]))) - (bullet 1 (tr [:diagrams.turn.runner-action-phase-b "Paid ability window. Corp may rez non-ice cards"])) - (bullet 2 (tr [:diagrams.turn.runner-action-phase-c "Runner recurring credits refill"])) - (bullet 3 (tr [:diagrams.turn.runner-action-phase-d "The turn formally begins. Turn begins events resolve"])) - (bullet 4 (tr [:diagrams.turn.runner-action-phase-e "Paid ability window. Corp may rez non-ice cards"])) - (bullet 5 (render-icons (tr [:diagrams.turn.runner-action-phase-f "If the Runner has unspent [Clicks], they take an action"]))) - (bullet 6 (tr [:diagrams.turn.runner-action-phase-g "If an action occured, return to (e)"])) - (bullet 7 (tr [:diagrams.turn.runner-action-phase-h "The action phase is complete. Proceed to the discard phase (5.7.2)"]))] + [:h4 (tr [:diagrams_turn_runner-action-phase "5.7.1: Action Phase"])] + (bullet 0 (render-icons (tr [:diagrams_turn_runner-action-phase-a "Runner gains allotted clicks (default: [click][click][click][click])"]))) + (bullet 1 (tr [:diagrams_turn_runner-action-phase-b "Paid ability window. Corp may rez non-ice cards"])) + (bullet 2 (tr [:diagrams_turn_runner-action-phase-c "Runner recurring credits refill"])) + (bullet 3 (tr [:diagrams_turn_runner-action-phase-d "The turn formally begins. Turn begins events resolve"])) + (bullet 4 (tr [:diagrams_turn_runner-action-phase-e "Paid ability window. Corp may rez non-ice cards"])) + (bullet 5 (render-icons (tr [:diagrams_turn_runner-action-phase-f "If the Runner has unspent [Clicks], they take an action"]))) + (bullet 6 (tr [:diagrams_turn_runner-action-phase-g "If an action occured, return to (e)"])) + (bullet 7 (tr [:diagrams_turn_runner-action-phase-h "The action phase is complete. Proceed to the discard phase (5.7.2)"]))] [:section - [:h4 (tr [:diagrams.turn.runner-discard-phase "5.7.2: Discard Phase"])] - (bullet 0 (tr [:diagrams.turn.runner-discard-phase-a "The runner discards to maximum handsize, if applicable"])) - (bullet 1 (tr [:diagrams.turn.runner-discard-phase-b "Paid ability window. Corp may rez non-ice cards"])) - (bullet 2 (render-icons (tr [:diagrams.turn.runner-discard-phase-c "If the runner has any [Clicks] remaining, they lose those [Clicks]"]))) - (bullet 3 (tr [:diagrams.turn.runner-discard-phase-d "The Runners turn formally ends. Turn end triggers resolve"])) - (bullet 4 (tr [:diagrams.turn.runner-discard-phase-e "Proceed to the Corporation turn"]))]])) + [:h4 (tr [:diagrams_turn_runner-discard-phase "5.7.2: Discard Phase"])] + (bullet 0 (tr [:diagrams_turn_runner-discard-phase-a "The runner discards to maximum handsize, if applicable"])) + (bullet 1 (tr [:diagrams_turn_runner-discard-phase-b "Paid ability window. Corp may rez non-ice cards"])) + (bullet 2 (render-icons (tr [:diagrams_turn_runner-discard-phase-c "If the runner has any [Clicks] remaining, they lose those [Clicks]"]))) + (bullet 3 (tr [:diagrams_turn_runner-discard-phase-d "The Runners turn formally ends. Turn end triggers resolve"])) + (bullet 4 (tr [:diagrams_turn_runner-discard-phase-e "Proceed to the Corporation turn"]))]])) (defn run-timing-pane [] (fn [] [:div.diagram [:section - [:h3 (tr [:diagrams.run-timing.header "Timing Structure of a Run"])] - [:div (tr [:diagrams.run-timing.disclaimer "This structure has been simplified for clarity. For complete rules, see the Null Signal Games website."])]] + [:h3 (tr [:diagrams_run-timing_header "Timing Structure of a Run"])] + [:div (tr [:diagrams_run-timing_disclaimer "This structure has been simplified for clarity. For complete rules, see the Null Signal Games website."])]] [:section - [:h4 (tr [:diagrams.run-timing.initiation "6.9.1: Initiation Phase"])] - (bullet 0 (tr [:diagrams.run-timing.initiation-a "Runner declares a server"])) - (bullet 1 (tr [:diagrams.run-timing.initiation-b "Runner gains Bad Publicity credits"])) - (bullet 2 (tr [:diagrams.run-timing.initiation-c "Run formally begins - Run events fire"])) - (bullet 3 (tr [:diagrams.run-timing.initiation-d "Proceed to the outermost ice, if applicable, and begin the approach phase (6.9.2)"])) - (bullet 4 (tr [:diagrams.run-timing.initiation-e "Otherwise, proceed to the movement phase (6.9.4)"]))] + [:h4 (tr [:diagrams_run-timing_initiation "6.9.1: Initiation Phase"])] + (bullet 0 (tr [:diagrams_run-timing_initiation-a "Runner declares a server"])) + (bullet 1 (tr [:diagrams_run-timing_initiation-b "Runner gains Bad Publicity credits"])) + (bullet 2 (tr [:diagrams_run-timing_initiation-c "Run formally begins - Run events fire"])) + (bullet 3 (tr [:diagrams_run-timing_initiation-d "Proceed to the outermost ice, if applicable, and begin the approach phase (6.9.2)"])) + (bullet 4 (tr [:diagrams_run-timing_initiation-e "Otherwise, proceed to the movement phase (6.9.4)"]))] [:section - [:h4 (tr [:diagrams.run-timing.approach "6.9.2: Approach Ice Phase"])] - (bullet 0 (tr [:diagrams.run-timing.approach-a "You are now approaching the ice. Approach events resolve"])) - (bullet 1 (tr [:diagrams.run-timing.approach-b "Paid Ability Window. Corp may rez the approached ice, or non-ice cards, during this window"])) - (bullet 2 (tr [:diagrams.run-timing.approach-c "If approached ice is rezzed, continue to encounter phase (6.9.3)"])) - (bullet 3 (tr [:diagrams.run-timing.approach-d "Otherwise, proceed to the movement phase (6.9.4)"]))] + [:h4 (tr [:diagrams_run-timing_approach "6.9.2: Approach Ice Phase"])] + (bullet 0 (tr [:diagrams_run-timing_approach-a "You are now approaching the ice. Approach events resolve"])) + (bullet 1 (tr [:diagrams_run-timing_approach-b "Paid Ability Window. Corp may rez the approached ice, or non-ice cards, during this window"])) + (bullet 2 (tr [:diagrams_run-timing_approach-c "If approached ice is rezzed, continue to encounter phase (6.9.3)"])) + (bullet 3 (tr [:diagrams_run-timing_approach-d "Otherwise, proceed to the movement phase (6.9.4)"]))] [:section - [:h4 (tr [:diagrams.run-timing.encounter "6.9.3: Encounter Ice Phase"])] - (bullet 0 (tr [:diagrams.run-timing.encounter-a "You are now encountering this ice. Encounter events resolve"])) - (bullet 1 (tr [:diagrams.run-timing.encounter-b "Paid ability window. Encountered ice may be interfaced during this window"])) - (bullet 2 (tr [:diagrams.run-timing.encounter-c "If there are unbroken subroutines to resolve, the corporation resolves the topmost unbroken subroutine. If they do, repeat this step"])) - (bullet 3 (tr [:diagrams.run-timing.encounter-d "The encounter is complete. Proceed to the movement phase (6.9.4)"]))] + [:h4 (tr [:diagrams_run-timing_encounter "6.9.3: Encounter Ice Phase"])] + (bullet 0 (tr [:diagrams_run-timing_encounter-a "You are now encountering this ice. Encounter events resolve"])) + (bullet 1 (tr [:diagrams_run-timing_encounter-b "Paid ability window. Encountered ice may be interfaced during this window"])) + (bullet 2 (tr [:diagrams_run-timing_encounter-c "If there are unbroken subroutines to resolve, the corporation resolves the topmost unbroken subroutine. If they do, repeat this step"])) + (bullet 3 (tr [:diagrams_run-timing_encounter-d "The encounter is complete. Proceed to the movement phase (6.9.4)"]))] [:section - [:h4 (tr [:diagrams.run-timing.movement "6.9.4: Movement Phase"])] - (bullet 0 (tr [:diagrams.run-timing.movement-a "If you were encountering or approaching an ice, you pass it. Pass-Ice events resolve"])) - (bullet 1 (tr [:diagrams.run-timing.movement-b "If there are no more ice inwards from the passed ice, 'when you pass all ice on the server' events resolve"])) - (bullet 2 (tr [:diagrams.run-timing.movement-c "Paid ability window"])) - (bullet 3 (tr [:diagrams.run-timing.movement-d "The runner may jack out. If they do, proceed to the run ends phase (6.9.6)"])) - (bullet 4 (tr [:diagrams.run-timing.movement-e "The runner proceeds to the next position inwards, if applicable"])) - (bullet 5 (tr [:diagrams.run-timing.movement-f "Paid ability window. The corporation may rez non-ice cards"])) - (bullet 6 (tr [:diagrams.run-timing.movement-g "If you are approaching another ice, return to the approach ice phase (6.9.2)"])) - (bullet 7 (tr [:diagrams.run-timing.movement-h "The runner approaches the attacked server. Approach events resolve"])) - (bullet 8 (tr [:diagrams.run-timing.movement-i "Continue to the success phase (6.9.5)"]))] + [:h4 (tr [:diagrams_run-timing_movement "6.9.4: Movement Phase"])] + (bullet 0 (tr [:diagrams_run-timing_movement-a "If you were encountering or approaching an ice, you pass it. Pass-Ice events resolve"])) + (bullet 1 (tr [:diagrams_run-timing_movement-b "If there are no more ice inwards from the passed ice, 'when you pass all ice on the server' events resolve"])) + (bullet 2 (tr [:diagrams_run-timing_movement-c "Paid ability window"])) + (bullet 3 (tr [:diagrams_run-timing_movement-d "The runner may jack out. If they do, proceed to the run ends phase (6.9.6)"])) + (bullet 4 (tr [:diagrams_run-timing_movement-e "The runner proceeds to the next position inwards, if applicable"])) + (bullet 5 (tr [:diagrams_run-timing_movement-f "Paid ability window. The corporation may rez non-ice cards"])) + (bullet 6 (tr [:diagrams_run-timing_movement-g "If you are approaching another ice, return to the approach ice phase (6.9.2)"])) + (bullet 7 (tr [:diagrams_run-timing_movement-h "The runner approaches the attacked server. Approach events resolve"])) + (bullet 8 (tr [:diagrams_run-timing_movement-i "Continue to the success phase (6.9.5)"]))] [:section - [:h4 (tr [:diagrams.run-timing.success "6.9.5: Success Phase"])] - (bullet 0 (tr [:diagrams.run-timing.success-a "The run is declared successful. Successful run events are met"])) - (bullet 1 (tr [:diagrams.run-timing.success-b "The runner breaches the attacked server"])) - (bullet 2 (tr [:diagrams.run-timing.success-c "The success phase is complete. Continue to the run ends phase (6.9.6)"]))] + [:h4 (tr [:diagrams_run-timing_success "6.9.5: Success Phase"])] + (bullet 0 (tr [:diagrams_run-timing_success-a "The run is declared successful. Successful run events are met"])) + (bullet 1 (tr [:diagrams_run-timing_success-b "The runner breaches the attacked server"])) + (bullet 2 (tr [:diagrams_run-timing_success-c "The success phase is complete. Continue to the run ends phase (6.9.6)"]))] [:section - [:h4 (tr [:diagrams.run-timing.run-ends "6.9.6: Run Ends Phase"])] - (bullet 0 (tr [:diagrams.run-timing.run-ends-a "Any open priority windows complete or are closed"])) - (bullet 1 (tr [:diagrams.run-timing.run-ends-b "The runner loses any unspent bad publicity credits"])) - (bullet 2 (tr [:diagrams.run-timing.run-ends-c "If the success phase was not reached and the server still exists, the run becomes unsuccessful"])) - (bullet 3 (tr [:diagrams.run-timing.run-ends-d "The run ends. Run ends events resolve"]))]])) + [:h4 (tr [:diagrams_run-timing_run-ends "6.9.6: Run Ends Phase"])] + (bullet 0 (tr [:diagrams_run-timing_run-ends-a "Any open priority windows complete or are closed"])) + (bullet 1 (tr [:diagrams_run-timing_run-ends-b "The runner loses any unspent bad publicity credits"])) + (bullet 2 (tr [:diagrams_run-timing_run-ends-c "If the success phase was not reached and the server still exists, the run becomes unsuccessful"])) + (bullet 3 (tr [:diagrams_run-timing_run-ends-d "The run ends. Run ends events resolve"]))]])) diff --git a/src/cljs/nr/gameboard/log.cljs b/src/cljs/nr/gameboard/log.cljs index a7c1276520..d5a718e542 100644 --- a/src/cljs/nr/gameboard/log.cljs +++ b/src/cljs/nr/gameboard/log.cljs @@ -61,14 +61,14 @@ [:button.indicate-action {:on-click #(do (.preventDefault %) (send-command "indicate-action")) :key "Indicate action"} - (tr [:game.indicate-action "Indicate paid ability"])])) + (tr [:game_indicate-action "Indicate paid ability"])])) (defn show-decklists [] (when (get-in @app-state [:current-game :open-decklists]) [:button.show-decklists {:on-click #(do (.preventDefault %) (swap! app-state update-in [:display-decklists] not)) :key "Show Decklists"} - (tr [:game.show-decklists "Show/Hide decklists"])])) + (tr [:game_show-decklists "Show/Hide decklists"])])) (defn fuzzy-match-score "Matches if all characters in input appear in target in order. @@ -174,7 +174,7 @@ (reset-command-menu state) (send-msg state))} [:input#log-input - {:placeholder (tr [:chat.placeholder "Say something..."]) + {:placeholder (tr [:chat_placeholder "Say something..."]) :type "text" :autoComplete "off" :ref #(reset! !input-ref %) diff --git a/src/cljs/nr/gameboard/player_stats.cljs b/src/cljs/nr/gameboard/player_stats.cljs index 4f5de33ded..15bbfb930f 100644 --- a/src/cljs/nr/gameboard/player_stats.cljs +++ b/src/cljs/nr/gameboard/player_stats.cljs @@ -42,7 +42,7 @@ (let [{:keys [available used only-for]} memory unused (- available used) label (if icon? [:<> unused "/" available " " [:span.anr-icon.mu]] - (tr [:game.mu-count] unused available))] + (tr [:game_mu-count] {:unused unused :available available}))] (ctrl :memory [:div label (when (neg? unused) [:div.warning "!"])])))))) (defn- display-special-memory @@ -59,16 +59,18 @@ mu-type-name (capitalize (name mu-type))]] ^{:key mu-type-name} [:div (if icon? [:<> unused "/" available " " mu-type-name " " [:span.anr-icon.mu]] - (tr [:game.special-mu-count] unused available mu-type-name))]))]))) + (tr [:game_special-mu-count] + {:unused unused + :available available + :mu-type mu-type-name}))]))]))) (defmulti stats-area (fn [player] (get-in @player [:identity :side]))) -(defmethod stats-area "Runner" [runner] +(defmethod stats-area "Runner" [_runner] (let [ctrl (stat-controls-for-side :runner)] (fn [runner] - (let [{:keys [user click credit run-credit memory link tag trash-like-cards - brain-damage active]} @runner + (let [{:keys [click credit run-credit memory link tag trash-like-cards brain-damage]} @runner base-credit (- credit run-credit) plus-run-credit (when (pos? run-credit) (str "+" run-credit)) icons? (get-in @app-state [:options :player-stats-icons] true)] @@ -82,31 +84,40 @@ (ctrl :link [:div link " " [:span.anr-icon.link]])] [display-special-memory memory true]] [:<> - (ctrl :click [:div (tr [:game.click-count] click)]) - (ctrl :credit [:div (tr [:game.credit-count] credit run-credit)]) + (ctrl :click [:div (tr [:game_click-count] click)]) + (ctrl :credit [:div (if (pos? run-credit) + (tr [:game_credit-count-with-run-credits] + {:credit credit + :run-credit run-credit}) + (tr [:game_credit-count] {:credit credit}))]) [display-memory memory] [display-special-memory memory] - (ctrl :link [:div (str link " " (tr [:game.link-strength "Link Strength"]))])]) + (ctrl :link [:div (str link " " (tr [:game_link-strength "Link Strength"]))])]) (let [{:keys [base total is-tagged]} tag additional (- total base) show-tagged (or is-tagged (pos? total))] - (ctrl :tag [:div (tr [:game.tag-count] base additional total) + (ctrl :tag [:div (if (pos? additional) + (tr [:game_tag-count-additional] + {:base base + :additional additional + :total total}) + (tr [:game_tag-count] {:base base})) (when show-tagged [:div.warning "!"])])) (ctrl :brain-damage - [:div (str brain-damage " " (tr [:game.brain-damage "Core Damage"]))]) + [:div (tr [:game_brain-damage "Core Damage"] {:dmg brain-damage})]) (when (= (:side @game-state) :runner) (let [toggle-offer-trash #(send-command "set-property" {:key :trash-like-cards :value (.. % -target -checked)})] [:div [:label [:input {:type "checkbox" :value true :checked trash-like-cards :on-click toggle-offer-trash}] - (tr [:game.trash-like-cards "Offer to trash like cards"])]]))])))) + (tr [:game_trash-like-cards "Offer to trash like cards"])]]))])))) (defmethod stats-area "Corp" [corp] (let [ctrl (stat-controls-for-side :corp)] (fn [corp] - (let [{:keys [user click credit bad-publicity active trash-like-cards]} @corp + (let [{:keys [click credit bad-publicity active trash-like-cards]} @corp icons? (get-in @app-state [:options :player-stats-icons] true)] [:div.stats-area (if icons? @@ -114,17 +125,21 @@ (ctrl :click [:div click " " [:span.anr-icon.click]]) (ctrl :credit [:div credit " " [:span.anr-icon.credit]])] [:<> - (ctrl :click [:div (tr [:game.click-count] click)]) - (ctrl :credit [:div (tr [:game.credit-count] credit -1)])]) + (ctrl :click [:div (tr [:game_click-count] click)]) + (ctrl :credit [:div (tr [:game_credit-count] {:credit credit})])]) (let [{:keys [base additional]} bad-publicity] - (ctrl :bad-publicity [:div (tr [:game.bad-pub-count] base additional)])) + (ctrl :bad-publicity [:div (if (pos? additional) + (tr [:game_bad-pub-count] {:base base}) + (tr [:game_bad-pub-count-additional] + {:base base + :additional additional}))])) (when (= (:side @game-state) :corp) (let [toggle-offer-trash #(send-command "set-property" {:key :trash-like-cards :value (.. % -target -checked)})] [:div [:label [:input {:type "checkbox" :value true :checked trash-like-cards :on-click toggle-offer-trash}] - (tr [:game.trash-like-cards "Offer to trash like cards"])]]))])))) + (tr [:game_trash-like-cards "Offer to trash like cards"])]]))])))) (defn stats-view [player] diff --git a/src/cljs/nr/gameboard/replay.cljs b/src/cljs/nr/gameboard/replay.cljs index 2345fe0f84..d14e796bf3 100644 --- a/src/cljs/nr/gameboard/replay.cljs +++ b/src/cljs/nr/gameboard/replay.cljs @@ -366,7 +366,7 @@ (get-in @game-state [:runner :user :username]))))))) ; Error handling does not work, as GET tries to parse something despite the connection ; timing out -- lostgeek (2021/02/14) - (non-game-toast (tr [:log.remote-annotations-fail "Could not get remote annotations."]) + (non-game-toast (tr [:log_remote-annotations-fail "Could not get remote annotations."]) "error" {:time-out 3 :close-button true}))))) (defn load-remote-annotations [pos] @@ -449,7 +449,7 @@ (defn notes-pane [] [:div.notes - [:div.turn [:textarea#notes-turn {:placeholder (tr [:annotations.turn-placeholder "Notes for this turn"]) + [:div.turn [:textarea#notes-turn {:placeholder (tr [:annotations_turn-placeholder "Notes for this turn"]) :on-change #(update-notes)}]] (letfn [(create-buttons [types] @@ -465,18 +465,18 @@ (create-buttons [:blunder :mistake :inaccuracy :good :brilliant]) [:div.notes-separator] (create-buttons [:a :b :c :d])]) - [:div.click [:textarea#notes-click {:placeholder (tr [:annotations.click-placeholder "Notes for this click"]) + [:div.click [:textarea#notes-click {:placeholder (tr [:annotations_click-placeholder "Notes for this click"]) :on-change #(update-notes)}]]]) (defn notes-shared-pane [] (let [annotation-options (r/atom {:file ""})] [:div.notes-shared (when (not= "local-replay" (:gameid @game-state)) [:div.remote-annotations - [:h4 (tr [:annotations.available-annotations "Available annotations"]) " " + [:h4 (tr [:annotations_available-annotations "Available annotations"]) " " [:button.small {:type "button" :on-click #(get-remote-annotations (:gameid @game-state))} "⟳"]] (if (empty? (:remote-annotations @replay-status)) - (tr [:annotations.no-published-annotations "No published annotations."]) + (tr [:annotations_no-published-annotations "No published annotations."]) [:ul (doall (for [[n anno] (map-indexed vector (:remote-annotations @replay-status))] @@ -489,18 +489,18 @@ :on-click #(delete-remote-annotations n)} "X"])]))]) [:div.button-row [:button {:type "button" - :on-click #(publish-annotations)} (tr [:annotations.publish "Publish"])]] + :on-click #(publish-annotations)} (tr [:annotations_publish "Publish"])]] [:hr]]) - [:h4 (tr [:annotations.import-local "Import local annotation file"])] + [:h4 (tr [:annotations_import-local "Import local annotation file"])] [:input {:field :file :type :file :on-change #(swap! replay-status assoc :annotations-file (aget (.. % -target -files) 0))}] [:div.button-row [:button {:type "button" :on-click #(load-annotations-file)} - (tr [:annotations.load-local "Load"])] + (tr [:annotations_load-local "Load"])] [:button {:type "button" :on-click #(save-annotations-file)} - (tr [:annotations.save-local "Save"])] + (tr [:annotations_save-local "Save"])] [:button {:type "button" :on-click #(swap! replay-status assoc :annotations {:turns {:corp {} :runner {}} :clicks {}})} - (tr [:annotations.clear "Clear"])]]])) + (tr [:annotations_clear "Clear"])]]])) diff --git a/src/cljs/nr/gameboard/right_pane.cljs b/src/cljs/nr/gameboard/right_pane.cljs index c8adeb3642..b37bf5b602 100644 --- a/src/cljs/nr/gameboard/right_pane.cljs +++ b/src/cljs/nr/gameboard/right_pane.cljs @@ -14,27 +14,27 @@ (defonce available-tabs {:log {:hiccup [log-pane] - :label (tr [:log.game-log "Game Log"])} + :label (tr [:log_game-log "Game Log"])} :notes {:hiccup [notes-pane] - :label (tr [:log.annotating "Annotating"])} + :label (tr [:log_annotating "Annotating"])} :notes-shared {:hiccup [notes-shared-pane] - :label (tr [:log.shared "Shared Annotations"])} + :label (tr [:log_shared "Shared Annotations"])} :run-timing {:hiccup [run-timing-pane] - :label (tr [:log.run-timing "Run Timing"])} + :label (tr [:log_run-timing "Run Timing"])} :turn-timing {:hiccup [turn-timing-pane] - :label (tr [:log.turn-timing "Turn Timing"])} + :label (tr [:log_turn-timing "Turn Timing"])} :settings {:hiccup [settings-pane] - :label (tr [:log.settings "Settings"])}}) + :label (tr [:log_settings "Settings"])}}) (defn- resize-card-zoom "Resizes the card zoom based on the values in the app-state" @@ -58,8 +58,9 @@ (.css "height" "auto") (.css "width" width)))) -(defn- pane-resize [event ui] +(defn- pane-resize "Resize the card zoom to fit the available space" + [event ui] (let [width (.. ui -size -width) top (.. ui -position -top)] (swap! app-state assoc-in [:options :log-width] width) ;;XXX: rename @@ -78,11 +79,12 @@ (put! zoom-channel false)) (defn- tab-selector [selected-tab] - (fn [] - [:div.panel.panel-top.blue-shade.selector - (doall (for [[tab {:keys [label]}] (seq @loaded-tabs)] - [:a {:key tab - :on-click #(reset! selected-tab tab)} label]))])) + [:div.panel.panel-top.blue-shade.selector + (doall (for [[tab {:keys [label]}] (seq @loaded-tabs)] + (do (prn label) + [:a {:key tab + :on-click #(reset! selected-tab tab)} + label])))]) (defn load-tab [tab] (let [{:keys [hiccup label]} diff --git a/src/cljs/nr/gameboard/settings.cljs b/src/cljs/nr/gameboard/settings.cljs index 90738a3492..b758acb325 100644 --- a/src/cljs/nr/gameboard/settings.cljs +++ b/src/cljs/nr/gameboard/settings.cljs @@ -8,66 +8,66 @@ (fn [] [:div.settings [:section - [:h4 (tr [:ingame-settings.card-stacking "Card settings"])] + [:h4 (tr [:ingame-settings_card-stacking "Card settings"])] [:div [:label [:input {:type "checkbox" :value true :checked (get-in @app-state [:options :stacked-cards]) :on-change #(swap! app-state assoc-in [:options :stacked-cards] (.. % -target -checked))}] - (tr [:ingame-settings.stack-cards "Stack cards"])]] + (tr [:ingame-settings_stack-cards "Stack cards"])]] [:div [:label [:input {:type "checkbox" :value true :checked (get-in @app-state [:options :labeled-unrezzed-cards]) :on-change #(swap! app-state assoc-in [:options :labeled-unrezzed-cards] (.. % -target -checked))}] - (tr [:ingame-settings.label-unrezzed-cards "Label unrezzed cards"])]] + (tr [:ingame-settings_label-unrezzed-cards "Label unrezzed cards"])]] [:div [:label [:input {:type "checkbox" :value true :checked (get-in @app-state [:options :labeled-cards]) :on-change #(swap! app-state assoc-in [:options :labeled-cards] (.. % -target -checked))}] - (tr [:ingame-settings.label-faceup-cards "Label face up cards"])]] + (tr [:ingame-settings_label-faceup-cards "Label face up cards"])]] [:div [:label [:input {:type "checkbox" :value true :checked (get-in @app-state [:options :ghost-trojans]) :on-change #(swap! app-state assoc-in [:options :ghost-trojans] (.. % -target -checked))}] - (tr [:ingame-settings.ghost-trojans "Display hosted trojans in rig"])]] + (tr [:ingame-settings_ghost-trojans "Display hosted trojans in rig"])]] [:div [:label [:input {:type "checkbox" :value true :checked (get-in @app-state [:options :display-encounter-info]) :on-change #(swap! app-state assoc-in [:options :display-encounter-info] (.. % -target -checked))}] - (tr [:ingame-settings.display-encounter-info "Always display encounter info"])]]] + (tr [:ingame-settings_display-encounter-info "Always display encounter info"])]]] [:section - [:h4 (tr [:ingame-settings.game-settings "Gameplay Settings"])] + [:h4 (tr [:ingame-settings_game-settings "Gameplay Settings"])] [:div [:label [:input {:type "checkbox" :value true :checked (get-in @app-state [:options :pass-on-rez]) :on-change #(swap! app-state assoc-in [:options :pass-on-rez] (.. % -target -checked))}] - (tr [:ingame-settings.game-settings "Pass priority when rezzing ice"])]]] + (tr [:ingame-settings_pass-on-rez "Pass priority when rezzing ice"])]]] [:section - [:h4 (tr [:ingame-settings.card-sorting "Sorting"])] + [:h4 (tr [:ingame-settings_card-sorting "Sorting"])] [:div [:label [:input {:type "checkbox" :value true :checked (get-in @app-state [:options :archives-sorted]) :on-change #(swap! app-state assoc-in [:options :archives-sorted] (.. % -target -checked))}] - (tr [:ingame-settings.sort-archives "Sort Archives"])]] + (tr [:ingame-settings_sort-archives "Sort Archives"])]] [:div [:label [:input {:type "checkbox" :value true :checked (get-in @app-state [:options :heap-sorted]) :on-change #(swap! app-state assoc-in [:options :heap-sorted] (.. % -target -checked))}] - (tr [:ingame-settings.sort-heap "Sort Heap"])]]] + (tr [:ingame-settings_sort-heap "Sort Heap"])]]] [:section - [:h4 (tr [:ingame-settings.runner-board-order "Runner board order"])] - (doall (for [option [{:name (tr [:ingame-settings.runner-classic "classic"]) :ref "jnet"} - {:name (tr [:ingame-settings.runner-reverse "reversed"]) :ref "irl"}]] + [:h4 (tr [:ingame-settings_runner-board-order "Runner board order"])] + (doall (for [option [{:name (tr [:ingame-settings_runner-classic "classic"]) :ref "jnet"} + {:name (tr [:ingame-settings_runner-reverse "reversed"]) :ref "irl"}]] [:div.radio {:key (:name option)} [:label [:input {:type "radio" :name "runner-board-order" @@ -76,27 +76,27 @@ :checked (= (get-in @app-state [:options :runner-board-order]) (:ref option))}] (:name option)]]))] [:section - [:h4 (tr [:ingame-settings.log-timestamps "Log timestamps"])] + [:h4 (tr [:ingame-settings_log-timestamps "Log timestamps"])] [:div [:label [:input {:type "checkbox" :value true :checked (get-in @app-state [:options :log-timestamps]) :on-change #(swap! app-state assoc-in [:options :log-timestamps] (.. % -target -checked))}] - (tr [:ingame-settings.log-timestamps "Show log timestamps"])]]] + (tr [:ingame-settings_log-timestamps-toggle "Show log timestamps"])]]] [:section - [:h4 (tr [:ingame-settings.board-overlap "Board overlap"])] + [:h4 (tr [:ingame-settings_board-overlap "Board overlap"])] [:div [:label [:input {:type "checkbox" :value true :checked (get-in @app-state [:options :sides-overlap]) :on-change #(swap! app-state assoc-in [:options :sides-overlap] (.. % -target -checked))}] - (tr [:ingame-settings.sides-overlap "Runner and Corp may overlap"])]]] + (tr [:ingame-settings_sides-overlap "Runner and Corp may overlap"])]]] [:section - [:h4 (tr [:ingame-settings.card-backs "Card backs"])] - (doall (for [option [{:name (tr [:settings.nsg "NSG"]) :ref "nsg"} - {:name (tr [:settings.ffg "FFG"]) :ref "ffg"}]] + [:h4 (tr [:ingame-settings_card-backs "Card backs"])] + (doall (for [option [{:name (tr [:settings_nsg "NSG"]) :ref "nsg"} + {:name (tr [:settings_ffg "FFG"]) :ref "ffg"}]] [:div.radio {:key (:name option)} [:label [:input {:type "radio" :name "card-back" @@ -106,9 +106,9 @@ (:name option)]]))] [:section - [:h4 (tr [:ingame-settings.preview-zoom "Card preview zoom"])] - (doall (for [option [{:name (tr [:ingame-settings.card-image "Card Image"]) :ref "image"} - {:name (tr [:ingame-settings.card-text "Card Text"]) :ref "text"}]] + [:h4 (tr [:ingame-settings_preview-zoom "Card preview zoom"])] + (doall (for [option [{:name (tr [:ingame-settings_card-image "Card Image"]) :ref "image"} + {:name (tr [:ingame-settings_card-text "Card Text"]) :ref "text"}]] [:div.radio {:key (:name option)} [:label [:input {:type "radio" :name "card-zoom" @@ -120,23 +120,23 @@ :name "pin-zoom" :checked (get-in @app-state [:options :pin-zoom]) :on-change #(swap! app-state assoc-in [:options :pin-zoom] (.. % -target -checked))}] - (tr [:settings.pin-zoom "Keep zoomed cards on screen"])]] + (tr [:settings_pin-zoom "Keep zoomed cards on screen"])]] [:section - [:h4 (tr [:ingame-settings.card-images "Card images"])] + [:h4 (tr [:ingame-settings_card-images "Card images"])] [:div [:label [:input {:type "checkbox" :name "use-high-res" :checked (= "high" (get-in @app-state [:options :card-resolution])) :on-change #(swap! app-state assoc-in [:options :card-resolution] (if (.. % -target -checked) "high" "default"))}] - (tr [:ingame-settings.high-res "Enable high resolution card images"])]]] + (tr [:ingame-settings_high-res "Enable high resolution card images"])]]] [:section - [:h4 (tr [:ingame-settings.alt-art "Alt arts"])] + [:h4 (tr [:ingame-settings_alt-art "Alt arts"])] [:div [:label [:input {:type "checkbox" :name "show-alt-art" :checked (get-in @app-state [:options :show-alt-art]) :on-change #(swap! app-state assoc-in [:options :show-alt-art] (.. % -target -checked))}] - (tr [:ingame-settings.show-alt "Show alternate card arts"])]]] - [:button {:on-click #(post-options "/profile" (constantly nil))} (tr [:ingame-settings.save "Save"])]])) + (tr [:ingame-settings_show-alt "Show alternate card arts"])]]] + [:button {:on-click #(post-options (constantly nil))} (tr [:ingame-settings_save "Save"])]])) diff --git a/src/cljs/nr/lobby.cljs b/src/cljs/nr/lobby.cljs index b5fc0856d2..b4857ca84e 100644 --- a/src/cljs/nr/lobby.cljs +++ b/src/cljs/nr/lobby.cljs @@ -38,7 +38,7 @@ (defmethod ws/event-msg-handler :lobby/timeout [{{:keys [gameid]} :?data}] (when (= gameid (:gameid @app-state)) - (non-game-toast (tr [:lobby.closed-msg "Game lobby closed due to inactivity"]) + (non-game-toast (tr [:lobby_closed-msg "Game lobby closed due to inactivity"]) "error" {:time-out 0 :close-button true}) (swap! app-state assoc :gameid nil))) @@ -81,7 +81,7 @@ (assoc init-state :replay-jump-to jump-to) init-state)))})) 404 - (non-game-toast (tr [:lobby.replay-link-error "Replay link invalid."]) + (non-game-toast (tr [:lobby_replay-link-error "Replay link invalid."]) "error" {:time-out 0 :close-button true})))))))) (defn leave-game [] @@ -135,12 +135,12 @@ filtered-games (filter-games @user room-games @visible-formats)] [:<> [:div.game-count - [:h4 (str (tr [:lobby.game-count] (count filtered-games)) - (when (not= (count slug->format) (count @visible-formats)) - (str " " (tr [:lobby.filtered "(filtered)"]))))]] + [:h4 (if (= (count slug->format) (count @visible-formats)) + (tr [:lobby_game-count] {:cnt (count filtered-games)}) + (tr [:lobby_game-count-filtered] {:cnt (count filtered-games)}))]] [:div.game-list (if (empty? filtered-games) - [:h4 (tr [:lobby.no-games "No games"])] + [:h4 (tr [:lobby_no-games "No games"])] (doall (for [game filtered-games] ^{:key (:gameid game)} @@ -169,7 +169,7 @@ (-> slug slug->format tr-format)]])) (defn new-game-button [s games gameid user] - [cond-button (tr [:lobby.new-game "New game"]) + [cond-button (tr [:lobby_new-game "New game"]) ;; TODO: rewrite this check (and (not (or @gameid (:editing @s) @@ -187,10 +187,10 @@ (defn reload-lobby-button [] [:button.reload-button {:type "button" :on-click #(ws/ws-send! [:lobby/list])} - (tr [:lobby.reload "Reload list"])]) + (tr [:lobby_reload "Reload list"])]) (defn load-replay-button [s games gameid user] - [cond-button (tr [:lobby.load-replay "Load replay"]) + [cond-button (tr [:lobby_load-replay "Load replay"]) ;; TODO: rewrite this check (and (not (or @gameid (:editing @s) @@ -207,15 +207,14 @@ [:div.rooms [:div#filter.dropdown [:a.dropdown-toggle {:href "" :data-toggle "dropdown"} - (tr [:lobby.filter "Filter"]) + (tr [:lobby_filter "Filter"]) [:b.caret]] [:div.dropdown-menu.blue-shade (doall (for [[k] slug->format] ^{:key k} [format-toggle k (contains? visible-formats k)]))]] - [room-tab user s games "casual" (tr [:lobby.casual "Casual"])] - ;; [room-tab user s games "angel-arena" (tr [:lobby.angel-arena "Angel Arena"])] - [room-tab user s games "competitive" (tr [:lobby.tournament "Tournament"])]] + [room-tab user s games "casual" (tr [:lobby_type "Casual"] {:type "casual"})] + [room-tab user s games "competitive" (tr [:lobby_type "Tournament"] {:type "tournament"})]] (when-not (= "angel-arena" (:room @s)) [:div.lobby-buttons [new-game-button s games current-game user] diff --git a/src/cljs/nr/lobby_chat.cljs b/src/cljs/nr/lobby_chat.cljs index 4f12fb08a6..55b04c86cb 100644 --- a/src/cljs/nr/lobby_chat.cljs +++ b/src/cljs/nr/lobby_chat.cljs @@ -41,7 +41,7 @@ :reagent-render (fn [current-game messages] [:div.chat-box - [:h3 (tr [:lobby.chat "Chat"])] + [:h3 (tr [:lobby_chat "Chat"])] (into [:div.message-list {:ref #(swap! state assoc :message-list %)}] (map (fn [{:keys [user text timestamp]}] @@ -56,8 +56,8 @@ [:div [:form.msg-box {:on-submit #(do (.preventDefault %) (send-message state current-game))} - [:input {:placeholder (tr [:chat.placeholder "Say something..."]) + [:input {:placeholder (tr [:chat_placeholder "Say something..."]) :type "text" :value @current-input :on-change #(swap! state assoc :msg (-> % .-target .-value))}] - [:button (tr [:chat.send "Send"])]]]])}))) + [:button (tr [:chat_send "Send"])]]]])}))) diff --git a/src/cljs/nr/navbar.cljs b/src/cljs/nr/navbar.cljs index 41ed5f3b1d..ad2ce80216 100644 --- a/src/cljs/nr/navbar.cljs +++ b/src/cljs/nr/navbar.cljs @@ -9,49 +9,49 @@ goog.history.Html5History)) (def navbar-links - [{:title (tr [:nav/welcome "Welcome"]) + [{:title (tr [:nav_welcome "Welcome"]) :cls "landing" :route "/"} - {:title (tr [:nav/chat "Chat"]) + {:title (tr [:nav_chat "Chat"]) :cls "chat" :route "/chat"} - {:title (tr [:nav/cards "Cards"]) + {:title (tr [:nav_cards "Cards"]) :cls "card" :route "/cards"} - {:title (tr [:nav/deck-builder "Deck Builder"]) + {:title (tr [:nav_deck-builder "Deck Builder"]) :cls "deckbuilder" :route "/deckbuilder"} - {:title (tr [:nav/play "Play"]) + {:title (tr [:nav_play "Play"]) :cls "play" :route "/play"} - {:title (tr [:nav/help "Help"]) + {:title (tr [:nav_help "Help"]) :cls "help" :route "/help"} - {:title (tr [:nav/settings "Settings"]) + {:title (tr [:nav_settings "Settings"]) :cls "settings" :route "/account" :show? :user} - {:title (tr [:nav/stats "Stats"]) + {:title (tr [:nav_stats "Stats"]) :cls "stats" :route "/stats" :show? :user} - {:title (tr [:nav/about "About"]) + {:title (tr [:nav_about "About"]) :cls "about" :route "/about"} - {:title (tr [:nav/tournaments "Tournaments"]) + {:title (tr [:nav_tournaments "Tournaments"]) :cls "tournaments" :route "/tournament" :show? #(:tournament-organizer (:user %))} - {:title (tr [:nav/admin "Admin"]) + {:title (tr [:nav_admin "Admin"]) :cls "admin" :route "/admin" :show? #(:isadmin (:user %))} - {:title (tr [:nav/users "Users"]) + {:title (tr [:nav_users "Users"]) :cls "users" :route "/users" :show? #(or (:isadmin (:user %)) (:ismoderator (:user %)))} - {:title (tr [:nav/features "Features"]) + {:title (tr [:nav_features "Features"]) :cls "features" :route "/features" :show? #(:isadmin (:user %))}]) diff --git a/src/cljs/nr/new_game.cljs b/src/cljs/nr/new_game.cljs index dfc1a3f9d7..dd49b3fddc 100644 --- a/src/cljs/nr/new_game.cljs +++ b/src/cljs/nr/new_game.cljs @@ -4,7 +4,7 @@ [jinteki.preconstructed :refer [all-matchups matchup-by-key]] [nr.appstate :refer [app-state]] [nr.auth :refer [authenticated] :as auth] - [nr.translations :refer [tr tr-string tr-format tr-side]] + [nr.translations :refer [tr tr-format tr-side]] [nr.utils :refer [slug->format]] [nr.ws :as ws] [reagent.core :as r])) @@ -30,10 +30,10 @@ (fn [_] (cond (empty? (:title @state)) - (swap! state assoc :flash-message (tr [:lobby.title-error "Please fill a game title."])) + (swap! state assoc :flash-message (tr [:lobby_title-error "Please fill a game title."])) (and (:protected @options) (empty? (:password @options))) - (swap! state assoc :flash-message (tr [:lobby.password-error "Please fill a password."])) + (swap! state assoc :flash-message (tr [:lobby_password-error "Please fill a password."])) :else (let [new-game (select-keys (merge @state @options) new-game-keys)] (swap! lobby-state assoc :editing false) @@ -43,24 +43,24 @@ [:div.button-bar [:button {:type "button" :on-click #(create-game state lobby-state options)} - (tr [:lobby.create "Create"])] + (tr [:lobby_create "Create"])] [:button {:type "button" :on-click #(do (.preventDefault %) (swap! lobby-state assoc :editing false))} - (tr [:lobby.cancel "Cancel"])]]) + (tr [:lobby_cancel "Cancel"])]]) (defn title-section [title-state] [:section - [:h3 (tr [:lobby.title "Title"])] + [:h3 (tr [:lobby_title "Title"])] [:input.game-title {:on-change #(reset! title-state (.. % -target -value)) :value @title-state - :placeholder (tr [:lobby.title "Title"]) + :placeholder (tr [:lobby_title "Title"]) :maxLength "100"}]]) (defn side-section [side-state] [:section - [:h3 (tr [:lobby.side "Side"])] + [:h3 (tr [:lobby_side "Side"])] (doall (for [option ["Any Side" "Corp" "Runner"]] ^{:key option} @@ -77,13 +77,13 @@ [:label [:input {:type "checkbox" :checked (:singleton @options) :on-change #(swap! options assoc :singleton (.. % -target -checked))}] - (tr [:lobby.singleton "Singleton"])]) + (tr [:lobby_singleton "Singleton"])]) (defn open-decklists [options] [:label [:input {:type "checkbox" :checked (:open-decklists @options) :on-change #(swap! options assoc :open-decklists (.. % -target -checked))}] - (tr [:lobby.open-decklists "Open Decklists"])]) + (tr [:lobby_open-decklists "Open Decklists"])]) (defn gateway-constructed-choice [fmt-state gateway-type] [:div @@ -97,7 +97,7 @@ :value option :on-change #(reset! gateway-type (.. % -target -value)) :checked (= @gateway-type option)}] - (str (tr-string "lobby.gateway-format" option) " ")]]))]) + (str (tr [:lobby_gateway-format] {:format option}) " ")]]))]) (defn precon-choice [fmt-state precon] [:div @@ -115,7 +115,7 @@ (defn format-section [fmt-state options gateway-type precon] [:section - [:h3 (tr [:lobby.default-game-format "Default game format"])] + [:h3 (tr [:lobby_default-game-format "Default game format"])] [:select.format {:value (or @fmt-state "standard") :on-change #(reset! fmt-state (.. % -target -value))} @@ -128,15 +128,15 @@ [precon-choice fmt-state precon] [:div.infobox.blue-shade {:style {:display (if (:singleton @options) "block" "none")}} - [:p (tr [:lobby.singleton-details "This will restrict decklists to only those which do not contain any duplicate cards. It is recommended you use the listed singleton-based identities."])] - [:p (tr [:lobby.singleton-example "1) Nova Initiumia: Catalyst & Impetus 2) Ampere: Cybernetics For Anyone"])]]]) + [:p (tr [:lobby_singleton-details "This will restrict decklists to only those which do not contain any duplicate cards. It is recommended you use the listed singleton-based identities."])] + [:p (tr [:lobby_singleton-example "1) Nova Initiumia: Catalyst & Impetus 2) Ampere: Cybernetics For Anyone"])]]]) (defn allow-spectators [options] [:p [:label [:input {:type "checkbox" :checked (:allow-spectator @options) :on-change #(swap! options assoc :allow-spectator (.. % -target -checked))}] - (tr [:lobby.spectators "Allow spectators"])]]) + (tr [:lobby_spectators "Allow spectators"])]]) (defn toggle-hidden-info [options] [:<> @@ -145,11 +145,11 @@ [:input {:type "checkbox" :checked (:spectatorhands @options) :on-change #(swap! options assoc :spectatorhands (.. % -target -checked)) :disabled (not (:allow-spectator @options))}] - (tr [:lobby.hidden "Make players' hidden information visible to spectators"])]] + (tr [:lobby_hidden "Make players' hidden information visible to spectators"])]] [:div.infobox.blue-shade {:style {:display (if (:spectatorhands @options) "block" "none")}} - [:p (tr [:lobby.hidden-details "This will reveal both players' hidden information to ALL spectators of your game, including hand and face-down cards."])] - [:p (tr [:lobby.hidden-password "We recommend using a password to prevent strangers from spoiling the game."])]]]) + [:p (tr [:lobby_hidden-details "This will reveal both players' hidden information to ALL spectators of your game, including hand and face-down cards."])] + [:p (tr [:lobby_hidden-password "We recommend using a password to prevent strangers from spoiling the game."])]]]) (defn password-input [options] [:<> @@ -160,12 +160,12 @@ (swap! options assoc :protected checked) (when (not checked) (swap! options assoc :password "")))}] - (tr [:lobby.password-protected "Password protected"])]] + (tr [:lobby_password-protected "Password protected"])]] (when (:protected @options) [:p [:input.game-title {:on-change #(swap! options assoc :password (.. % -target -value)) :value (:password @options) - :placeholder (tr [:lobby.password "Password"]) + :placeholder (tr [:lobby_password "Password"]) :maxLength "30"}]])]) (defn add-timer [options] @@ -178,7 +178,7 @@ :on-change #(let [checked (.. % -target -checked)] (swap! options assoc :timed checked) (swap! options assoc :timer (if checked 35 nil)))}] - (tr [:lobby.timed-game "Start with timer"])]]) + (tr [:lobby_timed-game "Start with timer"])]]) (when (:timed @options) [:p [:input.game-title {:on-change #(let [value (str->int (.. % -target -value))] @@ -186,10 +186,10 @@ (swap! options assoc :timer value))) :type "number" :value (:timer @options) - :placeholder (tr [:lobby.timer-length "Timer length (minutes)"])}]]) + :placeholder (tr [:lobby_timer-length "Timer length (minutes)"])}]]) [:div.infobox.blue-shade {:style {:display (if (:timed @options) "block" "none")}} - [:p (tr [:lobby.timed-game-details "Timer is only for convenience: the game will not stop when timer runs out."])]]]) + [:p (tr [:lobby_timed-game-details "Timer is only for convenience: the game will not stop when timer runs out."])]]]) (defn save-replay [options] [:<> @@ -198,12 +198,12 @@ [:input {:type "checkbox" :checked (:save-replay @options) :on-change #(swap! options assoc :save-replay (.. % -target -checked))}] - (str "🟢 " (tr [:lobby.save-replay "Save replay"]))]] + "🟢 " (tr [:lobby_save-replay "Save replay"])]] [:div.infobox.blue-shade {:style {:display (if (:save-replay @options) "block" "none")}} - [:p (tr [:lobby.save-replay-details "This will save a replay file of this match with open information (e.g. open cards in hand). The file is available only after the game is finished."])] - [:p (tr [:lobby.save-replay-unshared "Only your latest 15 unshared games will be kept, so make sure to either download or share the match afterwards."])] - [:p (tr [:lobby.save-replay-beta "BETA Functionality: Be aware that we might need to reset the saved replays, so make sure to download games you want to keep. Also, please keep in mind that we might need to do future changes to the site that might make replays incompatible."])]]]) + [:p (tr [:lobby_save-replay-details "This will save a replay file of this match with open information (e.g. open cards in hand). The file is available only after the game is finished."])] + [:p (tr [:lobby_save-replay-unshared "Only your latest 15 unshared games will be kept, so make sure to either download or share the match afterwards."])] + [:p (tr [:lobby_save-replay-beta "BETA Functionality: Be aware that we might need to reset the saved replays, so make sure to download games you want to keep. Also, please keep in mind that we might need to do future changes to the site that might make replays incompatible."])]]]) (defn api-access [options user] [:<> @@ -214,16 +214,16 @@ :type "checkbox" :checked (:api-access @options) :on-change #(swap! options assoc :api-access (.. % -target -checked))}] - (tr [:lobby.api-access "Allow API access to game information"]) + (tr [:lobby_api-access "Allow API access to game information"]) (when (not has-keys) - (str " " (tr [:lobby.api-requires-key "(Requires an API Key in Settings)"])))]]) + [:<> " " (tr [:lobby_api-requires-key "(Requires an API Key in Settings)"])])]]) [:div.infobox.blue-shade {:style {:display (if (:api-access @options) "block" "none")}} - [:p (tr [:lobby.api-access-details "This allows access to information about your game to 3rd party extensions. Requires an API Key to be created in Settings."])]]]) + [:p (tr [:lobby_api-access-details "This allows access to information about your game to 3rd party extensions. Requires an API Key to be created in Settings."])]]]) (defn options-section [options user] [:section - [:h3 (tr [:lobby.options "Options"])] + [:h3 (tr [:lobby_options "Options"])] [allow-spectators options] [toggle-hidden-info options] [open-decklists options] diff --git a/src/cljs/nr/password_game.cljs b/src/cljs/nr/password_game.cljs index 1e015afa54..a4cb2d48eb 100644 --- a/src/cljs/nr/password_game.cljs +++ b/src/cljs/nr/password_game.cljs @@ -1,7 +1,7 @@ (ns nr.password-game (:require [nr.auth :refer [authenticated]] - [nr.translations :refer [tr tr-watch-join]] + [nr.translations :refer [tr tr-room-type]] [nr.ws :as ws] [reagent.core :as r] [taoensso.sente :as sente])) @@ -20,10 +20,10 @@ 8000 #(if (sente/cb-success? %) (case % - 403 (swap! state assoc :error-msg (tr [:lobby.invalid-password "Invalid password"])) - 404 (swap! state assoc :error-msg (tr [:lobby.not-allowed "Not allowed"])) + 403 (swap! state assoc :error-msg (tr [:lobby_invalid-password "Invalid password"])) + 404 (swap! state assoc :error-msg (tr [:lobby_not-allowed "Not allowed"])) 200 (swap! lobby-state assoc :editing false :password-game nil)) - (swap! state assoc :error-msg (tr [:lobby.aborted "Connection aborted"]))))))) + (swap! state assoc :error-msg (tr [:lobby_aborted "Connection aborted"]))))))) (defn password-game [lobby-state] (r/with-let [game (r/cursor lobby-state [:password-game :game]) @@ -33,12 +33,12 @@ :error-msg nil})] (fn [lobby-state] [:div.password-prompt - [:h3 (str (tr [:lobby.password-for "Password for"]) + [:h3 (str (tr [:lobby_password-for "Password for"]) " " (:title @game))] [:p [:input.game-title {:on-change #(swap! state assoc :password (.. % -target -value)) :value (:password @state) - :placeholder (tr [:lobby.password "Password"]) + :placeholder (tr [:lobby_password "Password"]) :maxLength "30" :on-key-press (fn [e] (when (= 13 (.. e -charCode)) @@ -46,10 +46,10 @@ [:p [:button {:type "button" :on-click #(join-game lobby-state state @game @action @request-side)} - (tr-watch-join @action)] + (tr-room-type @action)] [:span.fake-link {:on-click #(do (swap! lobby-state dissoc :password-game) (reset! state {:error-msg nil :password nil}))} - (tr [:lobby.cancel "Cancel"])]] + (tr [:lobby_cancel "Cancel"])]] (when-let [error-msg (:error-msg @state)] [:p.flash-message error-msg])]))) diff --git a/src/cljs/nr/pending_game.cljs b/src/cljs/nr/pending_game.cljs index eb1f8ddbd7..088ecb1a65 100644 --- a/src/cljs/nr/pending_game.cljs +++ b/src/cljs/nr/pending_game.cljs @@ -30,13 +30,13 @@ :deck-id (:_id deck)}] 1500 #(when (sente/cb-error? %) - (non-game-toast (tr [:lobby.select-error "Cannot select that deck"]) "error"))) + (non-game-toast (tr [:lobby_select-error "Cannot select that deck"]) "error"))) (reagent-modals/close-modal!)) (defn select-deck-modal [user current-game] (r/with-let [decks (r/cursor app-state [:decks])] [:div - [:h3 (tr [:lobby.select-title "Select your deck"])] + [:h3 (tr [:lobby_select-title "Select your deck"])] [:div.deck-collection.lobby-deck-selector (let [fmt (:format @current-game) players (:players @current-game) @@ -74,7 +74,7 @@ (defn start-button [current-game user gameid players] (when (first-user? @players @user) - [cond-button (tr [:lobby.start "Start"]) + [cond-button (tr [:lobby_start "Start"]) (or (every? :deck @players) (is-preconstructed? current-game)) #(ws/ws-send! [:game/start {:gameid @gameid}])])) @@ -87,7 +87,7 @@ 8000 #(when (sente/cb-success? %) (swap! app-state assoc :editing false :current-game nil))))} - (tr [:lobby.leave "Leave"])]) + (tr [:lobby_leave "Leave"])]) (defn precon-info-box [current-game] (when-let [precon (:precon @current-game)] @@ -97,16 +97,16 @@ (defn singleton-info-box [current-game] (when (:singleton @current-game) [:div.infobox.blue-shade - [:p (tr [:lobby.singleton-restriction "This lobby is running in singleton mode. This means decklists will be restricted to only those which do not contain any duplicate cards."])]])) + [:p (tr [:lobby_singleton-restriction "This lobby is running in singleton mode. This means decklists will be restricted to only those which do not contain any duplicate cards."])]])) (defn swap-sides-button [user gameid players] (when (first-user? @players @user) (if (< 1 (count @players)) [:button {:on-click #(ws/ws-send! [:lobby/swap {:gameid @gameid}])} - (tr [:lobby.swap "Swap sides"])] + (tr [:lobby_swap "Swap sides"])] [:div.dropdown [:button.dropdown-toggle {:data-toggle "dropdown"} - (tr [:lobby.swap "Swap sides"]) + (tr [:lobby_swap "Swap sides"]) [:b.caret]] (into [:ul.dropdown-menu.blue-shade] @@ -135,7 +135,7 @@ [:span.label (if this-player (deck-name (:deck player) 25) - (tr [:lobby.deck-selected "Deck selected"]))]]) + (tr [:lobby_deck-selected "Deck selected"]))]]) (when-let [deck (:deck player)] [:div.float-right [deck-format-status-span deck (:format @current-game "standard") true]]) (when (and (is-constructed? current-game) @@ -143,11 +143,11 @@ (not (= (:side player) (tr-side "Any Side")))) [:span.fake-link.deck-load {:on-click #(reagent-modals/modal! [select-deck-modal user current-game])} - (tr [:lobby.select-deck "Select Deck"])])])) + (tr [:lobby_select-deck "Select Deck"])])])) (defn player-list [user current-game players] [:<> - [:h3 (tr [:lobby.players "Players"])] + [:h3 (tr [:lobby_players "Players"])] (into [:div.players] (map (fn [player] [player-item user current-game player]) @@ -157,31 +157,31 @@ (let [{:keys [allow-spectator api-access password save-replay spectatorhands timer]} @current-game] [:<> - [:h3 (tr [:lobby.options "Options"])] + [:h3 (tr [:lobby_options "Options"])] [:ul.options (when allow-spectator - [:li (tr [:lobby.spectators "Allow spectators"])]) + [:li (tr [:lobby_spectators "Allow spectators"])]) (when timer [:li "Game timer set for " timer " minutes"]) (when spectatorhands - [:li (tr [:lobby.hidden "Make players' hidden information visible to spectators"])]) + [:li (tr [:lobby_hidden "Make players' hidden information visible to spectators"])]) (when password - [:li (tr [:lobby.password-protected "Password protected"])]) + [:li (tr [:lobby_password-protected "Password protected"])]) (when save-replay [:<> - [:li (str "🟢 " (tr [:lobby.save-replay "Save replay"]))] + [:li (str "🟢 " (tr [:lobby_save-replay "Save replay"]))] [:div.infobox.blue-shade {:style {:display (if save-replay "block" "none")}} - [:p (tr [:lobby.save-replay-details "This will save a replay file of this match with open information (e.g. open cards in hand). The file is available only after the game is finished."])] - [:p (tr [:lobby.save-replay-unshared "Only your latest 15 unshared games will be kept, so make sure to either download or share the match afterwards."])] - [:p (tr [:lobby.save-replay-beta "BETA Functionality: Be aware that we might need to reset the saved replays, so make sure to download games you want to keep. Also, please keep in mind that we might need to do future changes to the site that might make replays incompatible."])]]]) + [:p (tr [:lobby_save-replay-details "This will save a replay file of this match with open information (e.g. open cards in hand). The file is available only after the game is finished."])] + [:p (tr [:lobby_save-replay-unshared "Only your latest 15 unshared games will be kept, so make sure to either download or share the match afterwards."])] + [:p (tr [:lobby_save-replay-beta "BETA Functionality: Be aware that we might need to reset the saved replays, so make sure to download games you want to keep. Also, please keep in mind that we might need to do future changes to the site that might make replays incompatible."])]]]) (when api-access - [:li (tr [:lobby.api-access "Allow API access to game information"])])]])) + [:li (tr [:lobby_api-access "Allow API access to game information"])])]])) (defn spectator-list [current-game] (let [{:keys [allow-spectator spectators]} @current-game] (when allow-spectator [:div.spectators - [:h3 (tr [:lobby.spectator-count "Spectators"] (count spectators))] + [:h3 (tr [:lobby_spectator-count "Spectators"] {:cnt (count spectators)})] (for [spectator spectators :let [_id (get-in spectator [:user :_id])]] ^{:key _id} @@ -208,7 +208,7 @@ (when-not (or (every? :deck @players) (not (is-constructed? current-game))) [:div.flash-message - (tr [:lobby.waiting "Waiting players deck selection"])]) + (tr [:lobby_waiting "Waiting players deck selection"])]) [player-list user current-game players] [options-list current-game] [spectator-list current-game] diff --git a/src/cljs/nr/player_view.cljs b/src/cljs/nr/player_view.cljs index 668e3d89fd..c8f757f576 100644 --- a/src/cljs/nr/player_view.cljs +++ b/src/cljs/nr/player_view.cljs @@ -10,10 +10,10 @@ (r/with-let [started (get-in player [:user :stats :games-started]) completed (get-in player [:user :stats :games-completed]) completion-rate (str (notnum->zero (num->percent completed started)) "%") - completion-rate (if (< started 10) (tr [:lobby.too-little-data "Too little data"]) completion-rate)] + completion-rate (if (< started 10) (tr [:lobby_too-little-data "Too little data"]) completion-rate)] [:span.user-status (get-in player [:user :username]) [:div.status-tooltip.blue-shade - [:div (tr [:lobby.completion-rate "Game Completion Rate"]) ": " completion-rate]]])) + [:div (tr [:lobby_completion-rate "Game Completion Rate"]) ": " completion-rate]]])) (defn player-view diff --git a/src/cljs/nr/replay_game.cljs b/src/cljs/nr/replay_game.cljs index 100dcec06b..1dc26a58ad 100644 --- a/src/cljs/nr/replay_game.cljs +++ b/src/cljs/nr/replay_game.cljs @@ -39,14 +39,14 @@ [:button {:type "button" :on-click #(do (.preventDefault %) (create-game state))} - (tr [:lobby.start-replay "Start replay"])] + (tr [:lobby_start-replay "Start replay"])] [:button {:type "button" :on-click #(do (.preventDefault %) (swap! lobby-state dissoc :replay))} - (tr [:lobby.cancel "Cancel"])]] + (tr [:lobby_cancel "Cancel"])]] (when (:flash-message @state) [:p.flash-message - (tr [:lobby.replay-invalid-file "Select a valid replay file."])]) + (tr [:lobby_replay-invalid-file "Select a valid replay file."])]) [:div [:input {:field :file :type :file :on-change #(swap! state assoc :replay-file (aget (.. % -target -files) 0))}]]]))) diff --git a/src/cljs/nr/sounds.cljs b/src/cljs/nr/sounds.cljs index 96117f6a06..4ac9eaaab6 100644 --- a/src/cljs/nr/sounds.cljs +++ b/src/cljs/nr/sounds.cljs @@ -1,6 +1,7 @@ (ns nr.sounds (:require ["howler" :as howler :refer [Howl]] + [flatland.ordered.map :refer [ordered-map]] [jinteki.utils :refer [str->int]] [nr.appstate :refer [app-state]])) @@ -10,12 +11,13 @@ [sound (new Howl args)])) (defonce bespoke-sounds - {"archer" {:grouping :archer :default "rez-ice"} + (ordered-map + "archer" {:grouping :archer :default "rez-ice"} "bloop" {:grouping :harmonics :default "rez-ice"} "echo" {:grouping :harmonics :default "rez-ice"} "end-of-the-line" {:grouping :end-of-the-line :default "play-instant"} "pulse" {:grouping :harmonics :default "rez-ice"} - "wave" {:grouping :harmonics :default "rez-ice"}}) + "wave" {:grouping :harmonics :default "rez-ice"})) (defn select-random-from-grouping [key] diff --git a/src/cljs/nr/stats.cljs b/src/cljs/nr/stats.cljs index b48caab608..be7b4257af 100644 --- a/src/cljs/nr/stats.cljs +++ b/src/cljs/nr/stats.cljs @@ -2,16 +2,15 @@ (:require-macros [cljs.core.async.macros :refer [go]]) (:require [cljs.core.async :refer [zero num->percent player-highlight-option-class + notnum->zero safe-divide player-highlight-option-class render-message render-player-highlight set-scroll-top store-scroll-top]] [nr.ws :as ws] [reagent.core :as r])) @@ -49,27 +48,27 @@ (defn game-details [state] (let [game (:view-game @state)] [:div.games.panel - [:p.return-button [:button {:on-click #(swap! state dissoc :view-game)} (tr [:stats.view-games "Return to stats screen"])]] + [:p.return-button [:button {:on-click #(swap! state dissoc :view-game)} (tr [:stats_view-games "Return to stats screen"])]] [:h4 (:title game) (when (:has-replay game) (if (:replay-shared game) " ⭐" " 🟢"))] [:div [:div.game-details-table - [:div (str (tr [:stats.lobby "Lobby"]) ": " (capitalize (tr-lobby (:room game))))] - [:div (str (tr [:stats.format "Format"]) ": " (capitalize (tr-format (:format game))))] - [:div (str (tr [:stats.winner "Winner"]) ": " (capitalize (tr-side (:winner game))))] - [:div (str (tr [:stats.win-method "Win method"]) ": " (:reason game))] - [:div (str (tr [:stats.started "Started"]) ": " (format-date-time day-word-with-time-formatter (:start-date game)))] - [:div (str (tr [:stats.ended "Ended"]) ": " (format-date-time day-word-with-time-formatter (:end-date game)))]] + [:div (str (tr [:stats_lobby "Lobby"]) ": " (tr-room-type (:room game)))] + [:div (str (tr [:stats_format "Format"]) ": " (tr-format (:format game)))] + [:div (str (tr [:stats_winner "Winner"]) ": " (tr-side (:winner game)))] + [:div (str (tr [:stats_win-method "Win method"]) ": " (:reason game))] + [:div (str (tr [:stats_started "Started"]) ": " (format-date-time day-word-with-time-formatter (:start-date game)))] + [:div (str (tr [:stats_ended "Ended"]) ": " (format-date-time day-word-with-time-formatter (:end-date game)))]] (when (:stats game) [build-game-stats (get-in game [:stats :corp]) (get-in game [:stats :runner])]) [:p (when (and (:has-replay game) (not (:replay-shared game))) - [:button {:on-click #(share-replay state (:gameid game))} (tr [:stats.share "Share replay"])]) + [:button {:on-click #(share-replay state (:gameid game))} (tr [:stats_share "Share replay"])]) (if (:has-replay game) [:span - [:button {:on-click #(launch-replay game)} (tr [:stats.launch "Launch Replay"])] - [:a.button {:href (str "/profile/history/full/" (:gameid game)) :download (str (:title game) ".json")} (tr [:stats.download "Download replay"])]] - (tr [:stats.unavailable "Replay unavailable"]))] + [:button {:on-click #(launch-replay game)} (tr [:stats_launch "Launch Replay"])] + [:a.button {:href (str "/profile/history/full/" (:gameid game)) :download (str (:title game) ".json")} (tr [:stats_download "Download replay"])]] + (tr [:stats_unavailable "Replay unavailable"]))] (when (:replay-shared game) [:p [:input.share-link {:type "text" :read-only true :value (replay-link game)}]])]])) @@ -82,40 +81,41 @@ (defn stat-view [{:keys [start-key complete-key win-key lose-key stats]}] (r/with-let [started (notnum->zero (start-key stats)) completed (notnum->zero (complete-key stats)) - pc (notnum->zero (num->percent completed started)) + pc (safe-divide completed started) win (notnum->zero (win-key stats)) lose (notnum->zero (lose-key stats)) - pw (notnum->zero (num->percent win (+ win lose))) - pl (notnum->zero (num->percent lose (+ win lose))) + pw (safe-divide win (+ win lose)) + pl (safe-divide lose (+ win lose)) incomplete (notnum->zero (- started completed)) - pi (notnum->zero (num->percent incomplete started))] + pi (safe-divide incomplete started) + gamestats (r/cursor app-state [:options :gamestats])] [:section - [:div (tr [:stats.started "Started"]) ": " started] - [:div (tr [:stats.completed "Completed"]) ": " completed " (" pc "%)"] - [:div (tr [:stats.not-completed "Not completed"]) ": " incomplete " (" pi "%)"] - (when-not (= "none" (get-in @app-state [:options :gamestats])) - [:div [:div (tr [:stats.won "Won"]) ": " win " (" pw "%)"] - [:div (tr [:stats.lost "Lost"]) ": " lose " (" pl "%)"]])])) + [:div (tr [:stats_started "Started"] {:started started})] + [:div (tr [:stats_completed "Completed"] {:completed completed :percent pc})] + [:div (tr [:stats_not-completed "Not completed"] {:completed incomplete :percent pi})] + (when-not (= "none" @gamestats) + [:div [:div (tr [:stats_won "Won"] {:won win :percent pw})] + [:div (tr [:stats_lost "Lost"] {:lost lose :percent pl})]])])) (defn stats-panel [stats] [:div.games.panel [:div.games [:div - [:h3 (tr [:stats.game-stats "Game Stats"])] + [:h3 (tr [:stats_game-stats "Game Stats"])] [stat-view {:stats @stats :start-key :games-started :complete-key :games-completed :win-key :wins :lose-key :loses}]] [:div - [:h3 (tr [:stats.corp-stats "Corp Stats"])] + [:h3 (tr [:stats_corp-stats "Corp Stats"])] [stat-view {:stats @stats :start-key :games-started-corp :complete-key :games-completed-corp :win-key :wins-corp :lose-key :loses-corp}]] [:div - [:h3 (tr [:stats.runner-stats "Runner Stats"])] + [:h3 (tr [:stats_runner-stats "Runner Stats"])] [stat-view {:stats @stats :start-key :games-started-runner :complete-key :games-completed-runner :win-key :wins-runner :lose-key :loses-runner}]]] - [:p [:button {:on-click #(clear-user-stats)} (tr [:stats.clear-stats "Clear Stats"])]]] ) + [:p [:button {:on-click #(clear-user-stats)} (tr [:stats_clear-stats "Clear Stats"])]]] ) (defn left-panel [state stats] (if (:view-game @state) @@ -146,7 +146,7 @@ [:div.username (get-in msg [:user :username])] [:div (render-message (:text msg))]]]))) (:log game))) - [:h4 (tr [:stats.no-log "No log available"])])]]))})) + [:h4 (tr [:stats_no-log "No log available"])])]]))})) (def faction-icon-memo (memoize faction-icon)) @@ -170,10 +170,13 @@ {:on-click #(do (fetch-log state game) (reset! log-scroll-top 0))} - (tr [:stats.view-log "View log"])] + (tr [:stats_view-log "View log"])] [:h4.log-title - {:title (when replay-shared "Replay shared")} - title " (" (tr [:stats.turn-count] turn-count) ")" (when has-replay (if replay-shared " ⭐" " 🟢"))] + (when replay-shared + {:title (tr [:stats_replay-shared "Replay shared"])}) + (tr [:stats_game-title] {:title title + :cnt turn-count}) + (when has-replay (if replay-shared " ⭐" " 🟢"))] [:div.log-date (format-date-time day-word-with-time-formatter start-date)] @@ -190,7 +193,7 @@ (faction-icon-memo (:faction runner-id) (:title runner-id)) " " (:title runner-id)]] (when winner - [:h4 (tr [:stats.winner "Winner"]) ": " (tr-side winner) (str user-win)])])) + [:h4 (tr [:stats_winner "Winner"]) ": " (tr-side winner) (str user-win)])])) (defn history [_state list-scroll-top _log-scroll-top] (r/create-class @@ -206,12 +209,13 @@ [:div.controls [:button {:on-click #(swap! state update :filter-replays not)} (if (:filter-replays @state) - (tr [:stats.all-games "Show all games"]) - (tr [:stats.shared-games "Only show shared"]))] - [:span.log-count (str (tr [:stats.log-count] cnt) (when (:filter-replays @state) - (str " " (tr [:stats.filtered "(filtered)"]))))]] + (tr [:stats_all-games "Show all games"]) + (tr [:stats_shared-games "Only show shared"]))] + [:span.log-count (if (:filter-replays @state) + (tr [:stats_log-count-filtered] {:cnt cnt}) + (tr [:stats_log-count] {:cnt cnt}))]] (if (empty? games) - [:h4 (tr [:stats.no-games "No games"])] + [:h4 (tr [:stats_no-games "No games"])] (doall (for [game games] ^{:key (:gameid game)} diff --git a/src/cljs/nr/status_bar.cljs b/src/cljs/nr/status_bar.cljs index 23b5835ae6..9b9108c877 100644 --- a/src/cljs/nr/status_bar.cljs +++ b/src/cljs/nr/status_bar.cljs @@ -12,9 +12,9 @@ (defn current-game-count [user games connected?] (r/with-let [c (r/track (fn [] (count (filter-games @user @games (:visible-formats @app-state)))))] [:div.float-right - (tr [:nav/game-count] @c) + (tr [:nav_game-count] {:cnt @c}) (when (not @connected?) - [:a.reconnect-button {:on-click #(ws/chsk-reconnect!)} (tr [:game.attempt-reconnect "Attempt reconnect"])])])) + [:a.reconnect-button {:on-click #(ws/chsk-reconnect!)} (tr [:game_attempt-reconnect "Attempt reconnect"])])])) (defn in-game-buttons [user current-game gameid] (when (and (:started @current-game) @@ -24,40 +24,40 @@ [:div.float-right (when is-player [:a.concede-button {:on-click #(concede)} - (tr [:game.concede "Concede"])]) + (tr [:game_concede "Concede"])]) [:a.leave-button {:on-click #(leave-game)} (if (:replay @current-game) - (tr [:game.leave-replay "Leave replay"]) - (tr [:game.leave "Leave game"]))] + (tr [:game_leave-replay "Leave replay"]) + (tr [:game_leave "Leave game"]))] (when is-player [:a.mute-button {:on-click #(mute-spectators)} (if (:mute-spectators @current-game) - (tr [:game.unmute "Unmute spectators"]) - (tr [:game.mute "Mute spectators"]))])]))) + (tr [:game_unmute "Unmute spectators"]) + (tr [:game_mute "Mute spectators"]))])]))) (defn replay-and-spectator-buttons [gameid] (when (not (nil? @gameid)) [:div.float-right [:a {:on-click #(leave-game)} (if (= "local-replay" @gameid) - (tr [:game.leave-replay "Leave replay"]) - (tr [:game.leave "Leave game"]))] + (tr [:game_leave-replay "Leave replay"]) + (tr [:game_leave "Leave game"]))] (when (= "local-replay" @gameid) [:a.replay-button {:on-click #(set-replay-side :corp)} - (tr [:game.corp-view "Corp View"])]) + (tr [:game_corp-view "Corp View"])]) (when (= "local-replay" @gameid) [:a.replay-button {:on-click #(set-replay-side :runner)} - (tr [:game.runner-view "Runner View"])]) + (tr [:game_runner-view "Runner View"])]) (when (= "local-replay" @gameid) [:a.replay-button {:on-click #(set-replay-side :spectator)} - (tr [:game.spec-view "Spectator View"])])])) + (tr [:game_spec-view "Spectator View"])])])) (defn spectator-list [current-game] (when-let [game @current-game] (when (:started game) (let [c (count (:spectators game))] (when (pos? c) - [:div.spectators-count.float-right (tr [:game.spec-count] c) + [:div.spectators-count.float-right (tr [:game_spec-count] c) [:div.blue-shade.spectators (for [p (:spectators game)] ^{:key (get-in p [:user :_id])} diff --git a/src/cljs/nr/translations.cljs b/src/cljs/nr/translations.cljs index 272c132cc1..99a9077fae 100644 --- a/src/cljs/nr/translations.cljs +++ b/src/cljs/nr/translations.cljs @@ -1,35 +1,38 @@ (ns nr.translations (:require [clojure.string :as str] - [i18n.core :as tr] - [jinteki.utils :refer [slugify]] - [nr.appstate :refer [app-state]])) + [jinteki.i18n :as i18n] + [nr.appstate :refer [app-state]] + [reagent.core :as r])) -(defn tr [resource & params] - (apply tr/tr-impl app-state resource params)) +(def language-cursor + (r/cursor app-state [:options :language])) -(defn tr-string [prefix s] - (let [side (str/lower-case (str/replace (or s "") " " "-")) - kw (keyword (str prefix "." side))] - (tr [kw "Unknown"]))) +(defn tr + ([resource] (tr resource nil)) + ([resource params] + (i18n/format language-cursor resource params))) -(defn tr-string-s [prefix s] - (let [s-trim (-> (or s "") - (str/replace "    " "")) - side (slugify s-trim) - kw (keyword (str prefix "." side))] - (str/replace (or s "") s-trim (tr [kw s-trim])))) +(defn clean-input + [s] + (assert (seq s) "Given empty string") + (-> (or s "") + (str/replace " " "-") + (str/replace "&" "-") + (str/lower-case))) -(defn tr-type [s] (tr-string "card-type" s)) -(defn tr-side [s] (tr-string "side" s)) -(defn tr-faction [s] (tr-string "faction" s)) -(defn tr-format [s] (tr-string "format" s)) -(defn tr-sort [s] (tr-string "card-browser.sort-by" s)) -(defn tr-lobby [s] (tr-string "lobby" s)) -(defn tr-pronouns [s] (tr-string "pronouns" s)) -(defn tr-watch-join [s] (tr-string "lobby" s)) -(defn tr-set [s] (tr-string-s "set" s)) -(defn tr-game-prompt [s] (tr-string-s "game-prompt" s)) +(defn tr-type [s] (tr [:card-type_name s] {:type (clean-input s)})) +(defn tr-side [s] (tr [:side_name s] {:side (clean-input s)})) +(defn tr-faction [s] (tr [:faction_name s] {:faction (clean-input s)})) +(defn tr-format [s] (tr [:format_name s] {:format (clean-input s)})) +(defn tr-room-type [s] (tr [:lobby_type s] {:type (clean-input s)})) +(defn tr-pronouns [s] (tr [:pronouns s] {:pronoun (clean-input s)})) +(defn tr-set [s] + (let [s (if (#{"0" "1" "2" "3" "4" "5" "6" "7" "8" "9"} (first s)) + (str "a" s) + s)] + (tr [:set_name s] {:name (clean-input s)}))) +(defn tr-game-prompt [s] (tr [:game_prompt s] {:msg (clean-input s)})) (defn tr-data [k data] (or (get-in data [:localized k]) (k data))) diff --git a/src/cljs/nr/utils.cljs b/src/cljs/nr/utils.cljs index 016d7c52bf..325bcb27ef 100644 --- a/src/cljs/nr/utils.cljs +++ b/src/cljs/nr/utils.cljs @@ -4,13 +4,13 @@ [cljc.java-time.format.date-time-formatter :as formatter] [cljc.java-time.zoned-date-time :as zdt] [cljc.java-time.zone-id :as zone] - [cljc.java-time.instant :as inst] [clojure.string :refer [join] :as s] [goog.object :as gobject] [goog.string :as gstring] [goog.string.format] [nr.appstate :refer [app-state]] [nr.translations :refer [tr-data]] + [flatland.ordered.map :refer [ordered-map]] [reagent.dom :as rd])) ;; Dot definitions @@ -120,7 +120,8 @@ (apply map-longest f default (map rest colls)))))) (def slug->format - {"standard" "Standard" + (ordered-map + "standard" "Standard" "throwback" "Throwback" "startup" "Startup" "system-gateway" "System Gateway" @@ -130,10 +131,11 @@ "snapshot" "Snapshot" "snapshot-plus" "Snapshot Plus" "neo" "Neo" - "casual" "Casual"}) + "casual" "Casual")) (def format->slug - {"Standard" "standard" + (ordered-map + "Standard" "standard" "Throwback" "throwback" "Startup" "startup" "System Gateway" "system-gateway" @@ -143,7 +145,7 @@ "Snapshot" "snapshot" "Snapshot Plus" "snapshot-plus" "Neo" "neo" - "Casual" "casual"}) + "Casual" "casual")) (defn regex-escape "Escape characters in a string which have special meanings in regexes" @@ -329,13 +331,11 @@ (defn render-player-highlight ([message corp runner] (render-player-highlight message corp runner nil)) ([message corp runner timestamp] - (render-input message (player-highlight-patterns corp runner timestamp))) - ) + (render-input message (player-highlight-patterns corp runner timestamp)))) (defn player-highlight-option-class [] - (case (get-in @app-state [:options :log-player-highlight]) - "blue-red" "log-player-highlight-red-blue" - nil)) + (when (= "blue-red" (get-in @app-state [:options :log-player-highlight])) + "log-player-highlight-red-blue")) (defn cond-button [text cond f] @@ -361,6 +361,11 @@ [input] (if (pos? (int input)) input 0)) +(defn safe-divide + "Divide two numbers iff the second number is positive" + [num1 num2] + (if (pos? num2) (/ (double num1) (double num2)) 0.0)) + (defn num->percent "Converts an input number to a percent of the second input number for display" [num1 num2] diff --git a/src/cljs/nr/ws.cljs b/src/cljs/nr/ws.cljs index 63a78b2986..3773dbf635 100644 --- a/src/cljs/nr/ws.cljs +++ b/src/cljs/nr/ws.cljs @@ -62,14 +62,14 @@ (when (and (:open? old-state) (not (:open? new-state))) (reset! lock true) - (non-game-toast (tr [:game.lost-connection, "Lost connection to server. Reconnecting."]) "error" {:time-out 0 :close-button true})) + (non-game-toast (tr [:game_lost-connection "Lost connection to server. Reconnecting."]) "error" {:time-out 0 :close-button true})) (when (and (not (:open? old-state)) (:open? new-state)) (.clear js/toastr) (ws-send! [:lobby/list]) (when (get-in @app-state [:current-game :started]) (resync)) - (non-game-toast (tr [:game.reconnected-to-server, "Reconnected to server"]) "success" nil)))) + (non-game-toast (tr [:game_reconnected-to-server "Reconnected to server"]) "success" nil)))) (defonce router_ (atom nil)) (defn stop-router! [] (when-let [stop-fn @router_] (stop-fn))) diff --git a/test/cljc/jinteki/i18n_test.clj b/test/cljc/jinteki/i18n_test.clj new file mode 100644 index 0000000000..55449bd088 --- /dev/null +++ b/test/cljc/jinteki/i18n_test.clj @@ -0,0 +1,7 @@ +(ns jinteki.i18n-test + (:require + [clojure.test :refer [deftest is]] + [jinteki.i18n :as sut])) + +(deftest check-translations-test + (is (empty? (sut/load-dictionary! "resources/public/i18n"))))