From bd39378cbafe33b7e0be5af870ebc18329f82df2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D0=BE=D0=91=D0=BE=D0=91=D0=BE?= <119269640+b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0@users.noreply.github.com> Date: Fri, 5 Jun 2026 12:58:20 +0500 Subject: [PATCH 1/6] Fix keyboard shortcuts under non-Latin keyboard layouts --- .../coley/recaf/ui/config/Binding.java | 7 ++- .../recaf/ui/pane/WorkspaceBuilderPane.java | 3 +- .../coley/recaf/ui/window/RecafScene.java | 4 ++ .../recaf/util/LayoutIndependentKeys.java | 63 +++++++++++++++++++ 4 files changed, 73 insertions(+), 4 deletions(-) create mode 100644 recaf-ui/src/main/java/software/coley/recaf/util/LayoutIndependentKeys.java diff --git a/recaf-ui/src/main/java/software/coley/recaf/ui/config/Binding.java b/recaf-ui/src/main/java/software/coley/recaf/ui/config/Binding.java index b2ac1e058..813274517 100644 --- a/recaf-ui/src/main/java/software/coley/recaf/ui/config/Binding.java +++ b/recaf-ui/src/main/java/software/coley/recaf/ui/config/Binding.java @@ -11,6 +11,8 @@ import java.util.HashSet; import java.util.LinkedHashSet; import java.util.Set; +import software.coley.recaf.util.LayoutIndependentKeys; + import java.util.stream.Collectors; import java.util.stream.Stream; @@ -153,8 +155,7 @@ public String toString() { */ public boolean match(@Nonnull KeyEvent event) { if (size() == 1) - // Simple 1-key check - return event.getCode().getName().equalsIgnoreCase(get(0)); + return LayoutIndependentKeys.resolveKeyCode(event).getName().equalsIgnoreCase(get(0)); else if (size() > 1) { // Checking binds with masks Set bindSet = new HashSet<>(this); @@ -181,7 +182,7 @@ public static Set namesOf(@Nonnull KeyEvent event) { eventSet.add(nameOf(KeyCode.ALT)); if (event.isShiftDown()) eventSet.add(nameOf(KeyCode.SHIFT)); - eventSet.add(nameOf(event.getCode())); + eventSet.add(nameOf(LayoutIndependentKeys.resolveKeyCode(event))); return eventSet; } diff --git a/recaf-ui/src/main/java/software/coley/recaf/ui/pane/WorkspaceBuilderPane.java b/recaf-ui/src/main/java/software/coley/recaf/ui/pane/WorkspaceBuilderPane.java index c74b0708d..fba76aaa5 100644 --- a/recaf-ui/src/main/java/software/coley/recaf/ui/pane/WorkspaceBuilderPane.java +++ b/recaf-ui/src/main/java/software/coley/recaf/ui/pane/WorkspaceBuilderPane.java @@ -33,6 +33,7 @@ import software.coley.recaf.ui.control.FontIconView; import software.coley.recaf.ui.dnd.DragAndDrop; import software.coley.recaf.util.DirectoryChooserBuilder; +import software.coley.recaf.util.LayoutIndependentKeys; import software.coley.recaf.util.ErrorDialogs; import software.coley.recaf.util.FileChooserBuilder; import software.coley.recaf.util.IOUtil; @@ -335,7 +336,7 @@ public WorkspaceBuilderPane(@Nonnull PathLoadingManager pathLoadingManager, * Key press event. */ private void handlePaste(KeyEvent e) { - if (e.isControlDown() && e.getCode() == KeyCode.V) { + if (LayoutIndependentKeys.isModified(e, KeyCode.V)) { Clipboard clipboard = Clipboard.getSystemClipboard(); // Handle files diff --git a/recaf-ui/src/main/java/software/coley/recaf/ui/window/RecafScene.java b/recaf-ui/src/main/java/software/coley/recaf/ui/window/RecafScene.java index 42ed377b1..397f24b7b 100644 --- a/recaf-ui/src/main/java/software/coley/recaf/ui/window/RecafScene.java +++ b/recaf-ui/src/main/java/software/coley/recaf/ui/window/RecafScene.java @@ -2,6 +2,8 @@ import javafx.scene.Parent; import javafx.scene.Scene; +import javafx.scene.input.KeyEvent; +import software.coley.recaf.util.LayoutIndependentKeys; /** * Scene extension for adding additional style-sheets. @@ -15,6 +17,7 @@ public class RecafScene extends Scene { */ public RecafScene(Parent root) { super(root); + addEventFilter(KeyEvent.KEY_PRESSED, LayoutIndependentKeys::normalizeEvent); addStyleSheets(); } @@ -28,6 +31,7 @@ public RecafScene(Parent root) { */ public RecafScene(Parent root, double width, double height) { super(root, width, height); + addEventFilter(KeyEvent.KEY_PRESSED, LayoutIndependentKeys::normalizeEvent); addStyleSheets(); } diff --git a/recaf-ui/src/main/java/software/coley/recaf/util/LayoutIndependentKeys.java b/recaf-ui/src/main/java/software/coley/recaf/util/LayoutIndependentKeys.java new file mode 100644 index 000000000..d62d0aacc --- /dev/null +++ b/recaf-ui/src/main/java/software/coley/recaf/util/LayoutIndependentKeys.java @@ -0,0 +1,63 @@ +package software.coley.recaf.util; + +import jakarta.annotation.Nonnull; +import javafx.event.Event; +import javafx.scene.Node; +import javafx.scene.control.TextInputControl; +import javafx.scene.input.KeyCode; +import javafx.scene.input.KeyEvent; +import org.fxmisc.richtext.GenericStyledArea; + +public final class LayoutIndependentKeys { + private LayoutIndependentKeys() { + } + + @Nonnull + public static KeyCode resolveKeyCode(@Nonnull KeyEvent event) { + KeyCode resolved = resolveFromControlCharacter(event); + return resolved != null ? resolved : event.getCode(); + } + + public static boolean isModified(@Nonnull KeyEvent event, @Nonnull KeyCode code) { + if (resolveKeyCode(event) != code) + return false; + return event.isControlDown() || event.isMetaDown(); + } + + public static void normalizeEvent(@Nonnull KeyEvent event) { + if (event.isConsumed()) + return; + KeyCode resolved = resolveFromControlCharacter(event); + if (resolved == null || event.getCode() == resolved) + return; + if (!(event.getTarget() instanceof Node target) || !isTextInput(target)) + return; + event.consume(); + Event.fireEvent(target, new KeyEvent( + event.getEventType(), + event.getCharacter(), + event.getText(), + resolved, + event.isShiftDown(), + event.isControlDown(), + event.isAltDown(), + event.isMetaDown() + )); + } + + private static boolean isTextInput(@Nonnull Node target) { + return target instanceof TextInputControl || target instanceof GenericStyledArea; + } + + private static KeyCode resolveFromControlCharacter(@Nonnull KeyEvent event) { + if (!event.isControlDown() && !event.isMetaDown()) + return null; + String character = event.getCharacter(); + if (character.isEmpty()) + return null; + char c = character.charAt(0); + if (c < 1 || c > 26) + return null; + return NodeEvents.getKeycode((char) ('a' + c - 1)); + } +} From c4006da5c9067d0b30bc34df838536c9b9e53b1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D0=BE=D0=91=D0=BE=D0=91=D0=BE?= <119269640+b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0@users.noreply.github.com> Date: Wed, 10 Jun 2026 09:02:40 +0500 Subject: [PATCH 2/6] Remove scene-level key normalization from RecafScene and LayoutIndependentKeys --- .../coley/recaf/ui/window/RecafScene.java | 4 --- .../recaf/util/LayoutIndependentKeys.java | 29 ------------------- 2 files changed, 33 deletions(-) diff --git a/recaf-ui/src/main/java/software/coley/recaf/ui/window/RecafScene.java b/recaf-ui/src/main/java/software/coley/recaf/ui/window/RecafScene.java index 397f24b7b..42ed377b1 100644 --- a/recaf-ui/src/main/java/software/coley/recaf/ui/window/RecafScene.java +++ b/recaf-ui/src/main/java/software/coley/recaf/ui/window/RecafScene.java @@ -2,8 +2,6 @@ import javafx.scene.Parent; import javafx.scene.Scene; -import javafx.scene.input.KeyEvent; -import software.coley.recaf.util.LayoutIndependentKeys; /** * Scene extension for adding additional style-sheets. @@ -17,7 +15,6 @@ public class RecafScene extends Scene { */ public RecafScene(Parent root) { super(root); - addEventFilter(KeyEvent.KEY_PRESSED, LayoutIndependentKeys::normalizeEvent); addStyleSheets(); } @@ -31,7 +28,6 @@ public RecafScene(Parent root) { */ public RecafScene(Parent root, double width, double height) { super(root, width, height); - addEventFilter(KeyEvent.KEY_PRESSED, LayoutIndependentKeys::normalizeEvent); addStyleSheets(); } diff --git a/recaf-ui/src/main/java/software/coley/recaf/util/LayoutIndependentKeys.java b/recaf-ui/src/main/java/software/coley/recaf/util/LayoutIndependentKeys.java index d62d0aacc..016f53e45 100644 --- a/recaf-ui/src/main/java/software/coley/recaf/util/LayoutIndependentKeys.java +++ b/recaf-ui/src/main/java/software/coley/recaf/util/LayoutIndependentKeys.java @@ -1,12 +1,8 @@ package software.coley.recaf.util; import jakarta.annotation.Nonnull; -import javafx.event.Event; -import javafx.scene.Node; -import javafx.scene.control.TextInputControl; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyEvent; -import org.fxmisc.richtext.GenericStyledArea; public final class LayoutIndependentKeys { private LayoutIndependentKeys() { @@ -24,31 +20,6 @@ public static boolean isModified(@Nonnull KeyEvent event, @Nonnull KeyCode code) return event.isControlDown() || event.isMetaDown(); } - public static void normalizeEvent(@Nonnull KeyEvent event) { - if (event.isConsumed()) - return; - KeyCode resolved = resolveFromControlCharacter(event); - if (resolved == null || event.getCode() == resolved) - return; - if (!(event.getTarget() instanceof Node target) || !isTextInput(target)) - return; - event.consume(); - Event.fireEvent(target, new KeyEvent( - event.getEventType(), - event.getCharacter(), - event.getText(), - resolved, - event.isShiftDown(), - event.isControlDown(), - event.isAltDown(), - event.isMetaDown() - )); - } - - private static boolean isTextInput(@Nonnull Node target) { - return target instanceof TextInputControl || target instanceof GenericStyledArea; - } - private static KeyCode resolveFromControlCharacter(@Nonnull KeyEvent event) { if (!event.isControlDown() && !event.isMetaDown()) return null; From 099aeba94d31bc151b8b3e75c059c7697e085ce7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D0=BE=D0=91=D0=BE=D0=91=D0=BE?= <119269640+b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0@users.noreply.github.com> Date: Wed, 10 Jun 2026 09:17:43 +0500 Subject: [PATCH 3/6] Add missing Russian translations and sync ru_RU.lang with en_US.lang --- .../main/resources/translations/ru_RU.lang | 264 +++++++++++++++++- 1 file changed, 259 insertions(+), 5 deletions(-) diff --git a/recaf-ui/src/main/resources/translations/ru_RU.lang b/recaf-ui/src/main/resources/translations/ru_RU.lang index 39807cf1b..fc9a63f06 100644 --- a/recaf-ui/src/main/resources/translations/ru_RU.lang +++ b/recaf-ui/src/main/resources/translations/ru_RU.lang @@ -5,6 +5,7 @@ lang.name=Русский ## Main and context menus menu.analysis=Анализ menu.analysis.summary=Просмотр сводки +menu.analysis.areas=Области приложения menu.analysis.deobfuscation=Деобфускация menu.analysis.list-comments=Просмотр комментариев menu.analysis.comment=Комментарий @@ -14,12 +15,17 @@ menu.config=Настройки menu.config.edit=Редактировать menu.config.export=Экспорт menu.config.import=Импорт +menu.config.profile=Профиль +menu.config.profile.new=Создать +menu.config.profile.delete=Удалить +menu.config.filter-prompt=Фильтр параметров конфигурации... menu.file=Файл menu.file.attach=Подключиться к удалённому menu.file.addtoworkspace=Добавить в рабочее пространство menu.file.decompileall=Декомпилировать все классы menu.file.decompileall.path=Путь вывода: menu.file.openworkspace=Открыть рабочее пространство +menu.file.promoteprimary=Сделать основным ресурсом menu.file.openurl=Открыть по URL menu.file.exportapp=Экспорт приложения menu.file.exportworkspace=Экспорт конфигурации рабочего пространства @@ -72,6 +78,15 @@ menu.refactor.move=Переместить menu.refactor.rename=Переименовать menu.search=Поиск menu.search.string=Строки +menu.search.string-table=Таблица строк +menu.search.string-table.min=Мин. длина +menu.search.string-table.max=Макс. длина +menu.search.string-table.column.string=Строка +menu.search.string-table.column.length=Длина +menu.search.string-table.column.locations=Места +menu.search.string-table.placeholder=Нажмите «Поиск», чтобы показать результаты +menu.search.string-table.empty=Строки не найдены. +menu.search.string-table.failed=При поиске произошла ошибка. menu.search.number=Числа menu.search.class.member-declarations=Объявления членов menu.search.class.member-references=Ссылки на членов @@ -79,6 +94,45 @@ menu.search.class.type-references=Ссылки на типы menu.search.class.instruction=Дизассемблирование инструкций menu.search.method-overrides=Переопределения методов menu.search.method-references=Ссылки на методы +menu.search.method-similar=Найти похожие методы +menu.search.method-similar.reference=Эталон +menu.search.method-similar.threshold=Порог +menu.search.method-similar.advanced=Дополнительные параметры +menu.search.method-similar.advanced.parameters=Параметры +menu.search.method-similar.advanced.return=Тип возвращаемого значения +menu.search.method-similar.column.method=Метод +menu.search.method-similar.column.class=Объявляющий класс +menu.search.method-similar.column.similarity=Схожесть +menu.search.method-similar.placeholder=Поиск похожих методов... +menu.search.method-similar.empty=Похожие методы не найдены. +menu.search.method-similar.failed=При поиске произошла ошибка. +menu.search.method-similar.parameter.exact_count_and_order=Тот же порядок +menu.search.method-similar.parameter.exact_count_any_order=Любая перестановка +menu.search.method-similar.parameter.anything=Любые +menu.search.method-similar.return.exact_type=Тот же +menu.search.method-similar.return.any_assignable=Потомок или ближайший родитель +menu.search.class-similar=Найти похожие классы +menu.search.class-similar.reference=Эталон +menu.search.class-similar.threshold=Порог +menu.search.class-similar.advanced=Дополнительные параметры +menu.search.class-similar.advanced.parameters=Параметры +menu.search.class-similar.advanced.return=Тип возвращаемого значения +menu.search.class-similar.advanced.method-order=Порядок методов +menu.search.class-similar.advanced.field-order=Порядок полей +menu.search.class-similar.advanced.scope=Область поиска +menu.search.class-similar.advanced.targets=Целевые ресурсы +menu.search.class-similar.column.class=Класс +menu.search.class-similar.column.resource=Ресурс +menu.search.class-similar.column.similarity=Схожесть +menu.search.class-similar.placeholder=Поиск похожих классов... +menu.search.class-similar.empty=Похожие классы не найдены. +menu.search.class-similar.failed=При поиске произошла ошибка. +menu.search.class-similar.order.ordered=С сохранением порядка +menu.search.class-similar.order.permutation=Любая перестановка +menu.search.class-similar.order.ignore_order=Без учёта порядка +menu.search.class-similar.scope.self_resource=Тот же ресурс +menu.search.class-similar.scope.all_non_internal=Все ресурсы +menu.search.class-similar.scope.target_resources=Выбранные ресурсы menu.search.field-references=Ссылки на поля menu.search.noresults=Нет результатов menu.mappings=Маппинги @@ -87,6 +141,7 @@ menu.mappings.apply-advanced=Расширенное применение menu.mappings.export=Экспорт menu.mappings.export.unsupported=%s (Не поддерживается) menu.mappings.generate=Сгенерировать +menu.mappings.similarity=Маппинг по схожести menu.mappings.view=Текущие маппинги menu.scripting=Скрипты menu.scripting.list=Скрипты @@ -97,6 +152,7 @@ menu.scripting.edit=Редактировать menu.scripting.browse=Просмотр скриптов menu.scripting.save=Сохранить скрипт menu.scripting.execute=Выполнить +menu.scripting.stop=Остановить menu.scripting.editor=Редактор скриптов menu.scripting.author=Автор menu.scripting.version=Версия @@ -106,6 +162,7 @@ menu.view.hierarchy.children=Дочерние menu.view.hierarchy.parents=Родительские menu.view.methodcfg=Граф потока управления menu.view.methodcallgraph=Граф вызовов +menu.view.methodcallgraph.tree=Дерево графа вызовов menu.view.methodcallgraph.calls=Вызовы menu.view.methodcallgraph.callers=Вызывающие menu.view.methodcallgraph.focus=Сфокусироваться на методе @@ -128,6 +185,7 @@ menu.mode.file.audio=Аудио menu.mode.file.video=Видео menu.mode.file.pe=Windows PE menu.mode.file.elf=ELF +menu.mode.file.arsc=Ресурсы Android menu.mode.diff.decompile=Декомпилировать menu.mode.diff.disassemble=Дизассемблировать menu.vm=Виртуализировать @@ -170,9 +228,28 @@ dialog.unknownextension=Неизвестное расширение файла. ## Search dialog.search.type=Имя типа -dialog.search.member-owner=Тип владельца члена -dialog.search.member-name=Имя члена -dialog.search.member-descriptor=Дескриптор члена +dialog.search.member-owner=Класс-владелец +dialog.search.member-name=Имя поля или метода +dialog.search.member-descriptor=Дескриптор +dialog.search.options=Параметры поиска +dialog.search.options.search-classes=Искать классы +dialog.search.options.search-files=Искать файлы +dialog.search.options.member-type=Тип элемента +dialog.search.options.modifiers=Модификаторы: +dialog.search.options.fields=Поля +dialog.search.options.methods=Методы +dialog.search.options.static-state=Статический +dialog.search.options.static=Статический +dialog.search.options.not-static=Не статический +dialog.search.options.final-state=Final +dialog.search.options.final=Final +dialog.search.options.not-final=Не final +dialog.search.options.include-packages=Включать пакеты +dialog.search.options.exclude-packages=Исключать пакеты +dialog.search.options.include-directories=Включать каталоги +dialog.search.options.exclude-directories=Исключать каталоги +dialog.search.options.package-prefixes.tooltip=Префиксы внутренних пакетов через запятую. Пустое значение — все пакеты. +dialog.search.options.directory-prefixes.tooltip=Префиксы внутренних каталогов через запятую. Пустое значение — все каталоги. ## File chooser dialog.title.primary=Основной ресурс @@ -195,8 +272,15 @@ dialog.filefilter.workspace=Рабочие пространства dialog.title.create-workspace=Создать рабочее пространство dialog.title.update-workspace=Обработать ввод рабочего пространства dialog.title.close-workspace=Закрыть рабочее пространство? +dialog.title.promote-resource-workspace=Сделать основным ресурсом? dialog.option.create-workspace=Создать новое рабочее пространство dialog.option.update-workspace=Добавить в рабочее пространство +dialog.header.promote-resource-workspace=Создать новое рабочее пространство с этим ресурсом как основным? +dialog.content.promote-resource-workspace=Текущее рабочее пространство будет закрыто, а выбранный ресурс станет новым основным. + +Все открытые вкладки будут закрыты. + +Сохранённые изменения в рабочем пространстве останутся. ## Select class/file dialog.title.select-class=Выбрать класс @@ -204,6 +288,7 @@ dialog.title.select-file=Выбрать файл ## Create class/file dialog.title.create-class=Создать класс +dialog.title.create-config-profile=Создать профиль конфигурации dialog.header.create-class-error=Имя класса уже существует.\nПожалуйста, выберите другое имя. @@ -318,6 +403,12 @@ dialog.error.exportfile.content=Ошибка: dialog.error.exportworkspace.title=Не удалось экспортировать рабочее пространство dialog.error.exportworkspace.header=Произошла ошибка при записи в место назначения dialog.error.exportworkspace.content=Ошибка: +dialog.error.exportconfig.title=Не удалось экспортировать конфигурацию +dialog.error.exportconfig.header=Ошибка при записи профиля конфигурации +dialog.error.exportconfig.content=Ошибка: +dialog.error.importconfig.title=Не удалось импортировать конфигурацию +dialog.error.importconfig.header=Ошибка при чтении профиля конфигурации +dialog.error.importconfig.content=Ошибка: dialog.error.loadworkspace.title=Не удалось загрузить рабочее пространство dialog.error.loadworkspace.header=Произошла ошибка при чтении из выбранных файлов dialog.error.loadworkspace.content=Ошибка: @@ -423,7 +514,7 @@ kotlinmetadata.title=@Metadata kotlinmetadata.orderwarning=Важно: Элементы не отображаются в том же порядке, что и определены в файле класса ## Logging -logging.title=Журналирование +logging.title=Логирование ## Assembler assembler.problem.0=Нет проблем @@ -490,6 +581,7 @@ deobf.tree.generic.anticrasher=Anti-Crasher deobf.tree.generic.optimize=Оптимизация deobf.tree.generic.restoration=Восстановление deobf.tree.specific=Специфичные +deobf.tree.plugin-provided=Плагин deobf.apply=Трансформировать рабочее пространство ## Mapping application @@ -525,6 +617,7 @@ mapgen.filter.includeclass=Включить на классах mapgen.filter.includefield=Включить на полях mapgen.filter.includemethod=Включить на методах mapgen.filter.includevariable=Включить на переменных +mapgen.filter.includeemptypackagenames=Включать пакеты нулевой ширины mapgen.filter.includewhitespacenames=Включить пробелы mapgen.filter.includenonasciinames=Включить не-ASCII mapgen.filter.includekeywords=Включить ключевые слова @@ -539,12 +632,45 @@ mapgen.configure=Настроить mapgen.configure.nothing=Нечего настраивать mapgen.generate=Сгенерировать mapgen.apply=Применить +mapsim=Маппинг по схожести +mapsim.target=Ресурс для сравнения +mapsim.target.none=Нет доступных ресурсов для сравнения +mapsim.threshold.class=Порог для классов (%) +mapsim.threshold.class.tooltip=Минимальный порог схожести классов в процентах (0–100). +mapsim.threshold.gap=Разрыв уверенности для классов (%) +mapsim.threshold.gap.tooltip=Минимальный разрыв схожести между лучшим и вторым кандидатом в процентах (0–100). +mapsim.threshold.member=Порог для элементов (%) +mapsim.threshold.member.tooltip=Минимальный порог схожести полей и методов в процентах (0–100). +mapsim.threshold.shortlist.max-candidates=Ёмкость списка кандидатов +mapsim.threshold.shortlist.max-candidates.tooltip=Сколько кандидатов сохранять после предварительного отбора. Больше кандидатов — дольше по времени, но выше шанс найти совпадение. +mapsim.threshold.shortlist.gap=Разрыв кандидатов (%) +mapsim.threshold.shortlist.gap.tooltip=Разрыв оценки на этапе предварительного отбора: если кандидат лучше минимум на это значение, более слабые отбрасываются. +mapsim.generate=Сгенерировать +mapsim.apply=Применить +mapsim.progress.generating=Генерация маппингов по схожести... +mapsim.progress.applying=Применение маппингов по схожести... +mapsim.summary.empty=Маппинги по схожести не сгенерированы +mapsim.summary.result=Сопоставлено классов: %d +mapsim.preview.source=Исходный класс +mapsim.preview.target=Целевой класс +mapsim.preview.noselection=// Выберите класс для предпросмотра маппингов по схожести +mapsim.preview.unmapped=// Для выбранного класса нет подходящего совпадения +mapsim.tree.unmapped=(не сопоставлено) ## Mapping view mapprog=Прогресс маппинга mapprog.metric.size=Размер файла класса mapprog.metric.membercount=Поля и методы класса +## Arsc view +arscviewer.complex-entries-suffix=записей +arscviewer.unknown-resource=(не разрешено) +arscviewer.no-resources-placeholder=Записи ресурсов не декодированы. +arscviewer.no-complex-values-placeholder=Выберите составной ресурс, чтобы просмотреть записи карты. +arscviewer.xml-placeholder=Выберите XML-ресурс для предпросмотра. +arscviewer.loading=Декодирование ресурсов Android... +binaryxml.loading=Декодирование бинарного XML... + ##### Tree tree.classes=Классы tree.files=Файлы @@ -565,10 +691,132 @@ service.analysis.info-summary-config=Суммаризация рабочего service.analysis.info-summary-config.summarize-on-open=Суммаризировать содержимое рабочего пространства при открытии service.analysis.graph-calls-config=Граф вызовов service.analysis.graph-inheritance-config=Граф наследования +service.analysis.phantom-generator-config=Генератор фантомов service.analysis.phantom-generator-config.generate-workspace-phantoms=Генерировать и добавлять фантомы в рабочие пространства +service.analysis.phantom-generator-config.lenient-conflicting-hierarchies=Генерировать фантомные иерархии супертипов, даже если порядок может быть неверным service.analysis.search-config=Поиск +service.analysis.areas=Области приложения +service.analysis.areas.loading=Анализ областей приложения... +service.analysis.areas.error=Не удалось выполнить анализ областей +service.analysis.areas.empty=Области приложения не найдены +service.analysis.areas.status=%d классов, %d групп, %d связей +service.analysis.areas.warning.short=обнаружена доминирующая область +service.analysis.areas.warning.spaghetti=В этом ресурсе есть доминирующая область. Группировка, скорее всего, ненадёжная. +service.analysis.areas.warning.dominant=Обнаружена доминирующая область. Точность группировки может быть ниже. +service.analysis.areas.preview.header=Крупнейшие группы +service.analysis.areas.groups=Группы +service.analysis.areas.explorer=Обозреватель +service.analysis.areas.explorer.ranked=Группы по рейтингу +service.analysis.areas.explorer.filtered=Отфильтровано глобальным поиском и переключателями горячих точек. +service.analysis.areas.classes=Классы +service.analysis.areas.classes.selected=Классы в выбранной области. +service.analysis.areas.details=Подробности +service.analysis.areas.graph=Граф связей +service.analysis.areas.graph.focused=Сфокусированный граф +service.analysis.areas.graph.focused.group=Сфокусированный граф: %s +service.analysis.areas.graph.empty.select=Выберите группу для построения сфокусированного графа. +service.analysis.areas.graph.empty.no-links=Для этой группы нет прямых связей типа %s. +service.analysis.areas.links.inbound=Входящие связи +service.analysis.areas.links.outbound=Исходящие связи +service.analysis.areas.overview=Обзор +service.analysis.areas.overview.program=Обзор программы +service.analysis.areas.search.prompt=Поиск групп или классов +service.analysis.areas.selection.none=Ничего не выбрано +service.analysis.areas.details.select-group=Выберите группу для просмотра подробностей. +service.analysis.areas.details.use-overview=Используйте карточки обзора или список обозревателя для просмотра области. +service.analysis.areas.details.focused-neighborhood=Сфокусированное окружение: %s. +service.analysis.areas.edge.selected=Выбранная связь +service.analysis.areas.edge.source=Источник +service.analysis.areas.edge.target=Цель +service.analysis.areas.edge.weight=Вес +service.analysis.areas.edge.count=Связей +service.analysis.areas.filter.entry-points=Точки входа +service.analysis.areas.filter.large=Крупные +service.analysis.areas.filter.high-fan-in=Много входящих +service.analysis.areas.filter.high-fan-out=Много исходящих +service.analysis.areas.mode.inbound=Входящие +service.analysis.areas.mode.outbound=Исходящие +service.analysis.areas.mode.both=Оба +service.analysis.areas.summary.group=Группа №%d +service.analysis.areas.summary.kind=Формирование +service.analysis.areas.summary.purpose=Назначение +service.analysis.areas.summary.confidence=Уверенность +service.analysis.areas.summary.classes=Классы +service.analysis.areas.summary.entry=Содержит точку входа +service.analysis.areas.summary.entry-short=Точка входа +service.analysis.areas.summary.visible-inbound=Видимые входящие +service.analysis.areas.summary.visible-outbound=Видимые исходящие +service.analysis.areas.summary.hidden-inbound=Скрытые входящие +service.analysis.areas.summary.hidden-outbound=Скрытые исходящие +service.analysis.areas.summary.hidden-edges=Скрытые связи +service.analysis.areas.summary.ungrouped=Классы без группы +service.analysis.areas.none.groups=Нет групп +service.analysis.areas.none.classes=Нет классов +service.analysis.areas.none.links=Нет связей +service.analysis.areas.result.none=Результат анализа не загружен. +service.analysis.areas.section.matching=Подходящие группы +service.analysis.areas.section.matching.empty=Нет групп, подходящих под текущие фильтры. +service.analysis.areas.section.largest=Крупнейшие группы +service.analysis.areas.section.largest.empty=Группы отсутствуют. +service.analysis.areas.section.entry-points=Группы с точками входа +service.analysis.areas.section.entry-points.empty=В результате нет групп с точками входа. +service.analysis.areas.section.high-fan-in=Наибольший fan-in +service.analysis.areas.section.high-fan-in.empty=Входящие связи не найдены. +service.analysis.areas.section.high-fan-out=Наибольший fan-out +service.analysis.areas.section.high-fan-out.empty=Исходящие связи не найдены. +service.analysis.areas.metric.analyzed-classes=Проанализировано классов +service.analysis.areas.metric.group-count=Количество групп +service.analysis.areas.metric.link-count=Количество связей +service.analysis.areas.metric.average-group-size=Средний размер группы +service.analysis.areas.metric.median-group-size=Медианный размер группы +service.analysis.areas.metric.mode-group-size=Мода размера группы +service.analysis.areas.metric.average-link-count=Среднее число связей +service.analysis.areas.metric.median-link-count=Медианное число связей +service.analysis.areas.metric.mode-link-count=Мода числа связей +service.analysis.areas.metric.average-confidence=Средняя уверенность +service.analysis.areas.metric.median-confidence=Медианная уверенность +service.analysis.areas.metric.low-confidence-groups=Группы с низкой уверенностью +service.analysis.areas.metric.top-purpose=Главное назначение +service.analysis.areas.metric.second-purpose=Второе назначение +service.analysis.areas.metric.distinct-purposes=Различных назначений +service.analysis.areas.group.meta=%d классов | вх. %d | исх. %d | %s +service.analysis.areas.entry.short=Вх. +service.analysis.areas.class-count.single=%d класс +service.analysis.areas.class-count.multiple=%d классов +service.analysis.areas.legend=Легенда +service.analysis.areas.legend.purpose=Цвета назначений +service.analysis.areas.legend.edge=Цвета связей +service.analysis.areas.legend.edge.inbound=Входящие к фокусу +service.analysis.areas.legend.edge.outbound=Исходящие из фокуса +service.analysis.areas.legend.edge.selected=Выбранная связь +service.analysis.areas.purpose.all=Все назначения +service.analysis.areas.column.group=Группа +service.analysis.areas.column.size=Размер +service.analysis.areas.column.kind=Тип +service.analysis.areas.column.purpose=Назначение +service.analysis.areas.column.confidence=Уверенность +service.analysis.areas.column.entry=Вход +service.analysis.areas.column.in=Вх. +service.analysis.areas.column.out=Исх. +service.analysis.areas.column.related=Связанные +service.analysis.areas.column.weight=Вес +service.analysis.areas.column.edges=Связи +service.analysis.area-analysis-config=Анализ областей приложения +service.analysis.area-analysis-config.include-external-reference-scores=Учитывать внешние ссылки при анализе областей +service.analysis.area-analysis-config.merge-scc-groups=Объединять сильно связные компоненты в одну группу областей +service.analysis.area-analysis-config.max-merged-child-size=Макс. размер объединяемой группы +service.analysis.area-analysis-config.max-merge-operations=Макс. число операций слияния +service.analysis.area-analysis-config.spaghetti-threshold-percent=Порог «спaghetti» (%) service.analysis.entry-points=Точки входа +service.analysis.entry-points.kind.jvm-main-method=Java main(String[]) +service.analysis.entry-points.kind.android-activity=Activity Android +service.analysis.entry-points.kind.mc.fabric=Инициализатор мода Fabric +service.analysis.entry-points.kind.mc.forge=Инициализатор мода Forge service.analysis.entry-points.none=Точки входа не найдены +service.analysis.hashing=Хеширование +service.analysis.hashing.type=Тип +service.analysis.hashing.value=Хеш +service.analysis.permissions=Разрешения service.analysis.anti-decompile=Анти-декомпиляция service.analysis.anti-decompile.illegal-attr=Недопустимые атрибуты service.analysis.anti-decompile.illegal-name=Недопустимые имена @@ -843,9 +1091,13 @@ service.ui.member-format-config.name-type-display=Отображение име service.ui.tab-completion-config=Автодополнение табуляцией service.ui.text-format-config=Формат текста service.ui.tab-completion-config.enabled-in-assembler=Включено в ассемблере +service.ui.tab-completion-config.enabled-in-java-source=Включено в исходниках Java service.ui.tab-completion-config.max-completion-length=Максимальная длина дополнения service.ui.tab-completion-config.max-completion-rows=Отображаемые строки дополнения service.ui.tab-completion-config.popup-position=Предпочитаемая позиция всплывающего окна дополнения относительно курсора +service.ui.tab-completion-config.adaptive-ranking-enabled=Адаптивный рейтинг автодополнения +service.ui.tab-completion-config.adaptive-ranking-learning-enabled=Обучать рейтинг автодополнения +service.ui.tab-completion-config.reset-ranking=Сбросить выученный рейтинг Java-дополнений service.ui.text-format-config.escape=Включить экранирование текста service.ui.text-format-config.max-length=Максимальная длина отображения текста service.ui.text-format-config.shorten=Включить сокращение текста @@ -890,6 +1142,8 @@ string.match.starts-ic=строка.startsWithIgnoreCase(значение) misc.acknowledge=Принять misc.all=Все misc.none=Нет +misc.yes=Да +misc.no=Нет misc.done=Готово misc.ignored=Игнорировано misc.enabled=Включено @@ -951,4 +1205,4 @@ tutorial.5.decrypt=int key = Thread.currentThread().getStackTrace()[1].getMethod tutorial.5.finished=Правый клик на типе возврата этого метода "Chapter6" и выберите 'Перейти к классу'.\n\nВы можете альтернативно использовать [Control + Click] на ссылках, чтобы избежать необходимости проходить через контекстное меню каждый раз. tutorial.6.class=Когда вы правым кликом на классе, поле или методе, вы можете увидеть, какой другой код ссылается на выбранную вами вещь.\n\n - Классы: Поиск > Ссылки на типы/члены\n - Поля: Ссылки на поля\n - Методы: Ссылки на методы\n\nВы можете найти эти опции поиска в меню 'Поиск' в строке меню вверху UI, вместе с другими вещами, такими как поиск строк и числовых литералов. tutorial.6.method=Попробуйте найти, что ссылается на этот метод. -tutorial.7.class=Поздравляем, это конец обучения!\n\nНажмите [Control + S] ещё раз в последний раз, чтобы отметить обучение как завершённое.\n\nПозже будет добавлено больше в обучение, но это должно покрыть все самые важные функции для вашего обычного случая использования. В то же время, не стесняйтесь исследовать другие функции самостоятельно! \ No newline at end of file +tutorial.7.class=Поздравляем, это конец обучения!\n\nНажмите [Control + S] ещё раз в последний раз, чтобы отметить обучение как завершённое.\n\nПозже будет добавлено больше в обучение, но это должно покрыть все самые важные функции для вашего обычного случая использования. В то же время, не стесняйтесь исследовать другие функции самостоятельно! From cfee4991a1de8fed8fb8bc5bfbfcb78b8f22ad57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D0=BE=D0=91=D0=BE=D0=91=D0=BE?= <119269640+b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0@users.noreply.github.com> Date: Wed, 10 Jun 2026 11:23:56 +0500 Subject: [PATCH 4/6] Fix ambiguous Russian translation wording --- .../main/resources/translations/ru_RU.lang | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/recaf-ui/src/main/resources/translations/ru_RU.lang b/recaf-ui/src/main/resources/translations/ru_RU.lang index fc9a63f06..d9f057795 100644 --- a/recaf-ui/src/main/resources/translations/ru_RU.lang +++ b/recaf-ui/src/main/resources/translations/ru_RU.lang @@ -20,7 +20,7 @@ menu.config.profile.new=Создать menu.config.profile.delete=Удалить menu.config.filter-prompt=Фильтр параметров конфигурации... menu.file=Файл -menu.file.attach=Подключиться к удалённому +menu.file.attach=Удалённое подключение menu.file.addtoworkspace=Добавить в рабочее пространство menu.file.decompileall=Декомпилировать все классы menu.file.decompileall.path=Путь вывода: @@ -88,8 +88,8 @@ menu.search.string-table.placeholder=Нажмите «Поиск», чтобы menu.search.string-table.empty=Строки не найдены. menu.search.string-table.failed=При поиске произошла ошибка. menu.search.number=Числа -menu.search.class.member-declarations=Объявления членов -menu.search.class.member-references=Ссылки на членов +menu.search.class.member-declarations=Объявления полей и методов +menu.search.class.member-references=Ссылки на поля и методы menu.search.class.type-references=Ссылки на типы menu.search.class.instruction=Дизассемблирование инструкций menu.search.method-overrides=Переопределения методов @@ -388,7 +388,7 @@ dialog.conv.title.expression=Числовое выражение ## Quick nav dialog.quicknav=Быстрая навигация dialog.quicknav.tab.classes=Классы -dialog.quicknav.tab.members=Члены +dialog.quicknav.tab.members=Поля и методы dialog.quicknav.tab.files=Файлы dialog.quicknav.tab.text=Текст dialog.quicknav.tab.commented=Комментарии @@ -495,10 +495,10 @@ find.regexreplace=Текст замены ## Fields and methods fieldsandmethods.title=Поля и методы -fieldsandmethods.empty=Класс не имеет членов -fieldsandmethods.showoutlinedsynths=Показать синтетические (сгенерированные компилятором) члены -fieldsandmethods.showoutlinedvisibility=Фильтр по видимости члена -fieldsandmethods.showoutlinedmembertype=Фильтр по типу члена +fieldsandmethods.empty=У класса нет полей и методов +fieldsandmethods.showoutlinedsynths=Показать синтетические (сгенерированные компилятором) поля и методы +fieldsandmethods.showoutlinedvisibility=Фильтр по видимости +fieldsandmethods.showoutlinedmembertype=Фильтр по типу fieldsandmethods.nametypemode=Режим отображения имени/типа fieldsandmethods.sortalphabetically=Сортировать по алфавиту fieldsandmethods.sortbyvisibility=Сортировать по видимости @@ -548,9 +548,9 @@ search.text=Текстовое содержимое search.textmode=Режим совпадения текста search.number=Числовое значение search.numbermode=Режим совпадения числа -search.refowner=Владелец члена -search.refname=Имя члена -search.refdesc=Дескриптор типа члена +search.refowner=Класс-владелец +search.refname=Имя поля или метода +search.refdesc=Дескриптор типа ## Help help.system=Система @@ -906,7 +906,7 @@ service.decompile.impl.decompiler-cfr-config.instanceofpattern=Пересозд service.decompile.impl.decompiler-cfr-config.j14classobj=Обратить построение объекта класса java 1.4 service.decompile.impl.decompiler-cfr-config.labelledblocks=Разрешить код, использующий помеченные блоки (обработка необычных переходов вперёд) service.decompile.impl.decompiler-cfr-config.lenient=Быть немного более снисходительным в ситуациях, где обычно выбрасывается исключение -service.decompile.impl.decompiler-cfr-config.liftconstructorinit=Поднять код инициализации, общий для всех конструкторов, в инициализацию членов +service.decompile.impl.decompiler-cfr-config.liftconstructorinit=Поднять код инициализации, общий для всех конструкторов, в инициализацию полей service.decompile.impl.decompiler-cfr-config.obfattr=Отменить обфускацию атрибутов service.decompile.impl.decompiler-cfr-config.obfcontrol=Отменить обфускацию потока управления service.decompile.impl.decompiler-cfr-config.override=Генерировать аннотации @Override (если метод виден как реализующий метод интерфейса или переопределяющий метод базового класса) @@ -927,7 +927,7 @@ service.decompile.impl.decompiler-cfr-config.removeinnerclasssynthetics=Удал service.decompile.impl.decompiler-cfr-config.renamedupmembers=Переименовать неоднозначные/дублирующиеся поля service.decompile.impl.decompiler-cfr-config.renameenumidents=Переименовать идентификаторы ENUM, которые не соответствуют их 'ожидаемым' строковым именам service.decompile.impl.decompiler-cfr-config.renameillegalidents=Переименовать идентификаторы, которые не являются допустимыми java идентификаторами -service.decompile.impl.decompiler-cfr-config.renamesmallmembers=Переименовать маленькие члены. Примечание - это СЛОМАЕТ доступ на основе рефлексии, поэтому не включено автоматически +service.decompile.impl.decompiler-cfr-config.renamesmallmembers=Переименовать короткие поля и методы. Примечание - это СЛОМАЕТ доступ на основе рефлексии, поэтому не включено автоматически service.decompile.impl.decompiler-cfr-config.sealed=Декомпилировать конструкции 'sealed' service.decompile.impl.decompiler-cfr-config.showinferrable=Украсить методы явными типами, если они не подразумеваются аргументами service.decompile.impl.decompiler-cfr-config.showversion=Показать используемую версию CFR в заголовке (удобно отключить при регрессионном тестировании) @@ -965,8 +965,8 @@ service.decompile.impl.decompiler-procyon-config.mergeVariables=Объединя service.decompile.impl.decompiler-procyon-config.retainPointlessSwitches=Сохранять бесполезные switch service.decompile.impl.decompiler-procyon-config.retainRedundantCasts=Сохранять бесполезные приведения service.decompile.impl.decompiler-procyon-config.showDebugLineNumbers=Показать номера строк отладки -service.decompile.impl.decompiler-procyon-config.showSyntheticMembers=Показать синтетические члены -service.decompile.impl.decompiler-procyon-config.simplifyMemberReferences=Упрощать ссылки на члены +service.decompile.impl.decompiler-procyon-config.showSyntheticMembers=Показать синтетические поля и методы +service.decompile.impl.decompiler-procyon-config.simplifyMemberReferences=Упрощать ссылки на поля и методы service.decompile.impl.decompiler-procyon-config.textBlockLineMinimum=Минимум строк текстового блока service.decompile.impl.decompiler-vineflower-config=Vineflower service.decompile.impl.decompiler-vineflower-config.logging-level=Уровень логирования @@ -1012,7 +1012,7 @@ service.decompile.impl.decompiler-vineflower-config.explicit-generics=Явные service.decompile.impl.decompiler-vineflower-config.inline-simple-lambdas=Инлайнить простые лямбды service.decompile.impl.decompiler-vineflower-config.log-level=Уровень логирования service.decompile.impl.decompiler-vineflower-config.max-time-per-method=[УСТАРЕЛО] Максимальное время обработки метода -service.decompile.impl.decompiler-vineflower-config.rename-members=Переименовать члены +service.decompile.impl.decompiler-vineflower-config.rename-members=Переименовать поля и методы service.decompile.impl.decompiler-vineflower-config.user-renamer-class=Класс переименования пользователя service.decompile.impl.decompiler-vineflower-config.new-line-separator=[УСТАРЕЛО] Разделитель новой строки service.decompile.impl.decompiler-vineflower-config.indent-string=Строка отступа @@ -1203,6 +1203,6 @@ tutorial.5.class=Этот класс обфусцирован! Если вы п tutorial.5.main=В этой главе вам нужно открыть ассемблер на обфусцированном методе.\n\nИспользуйте вкладку 'Поля и методы' и правый клик на обфусцированном методе, затем откройте ассемблер.\n\nОбфусцированный метод в настоящее время реализован неправильно. Правильная реализация может быть найдена в комментарии ниже в следующем методе.\n\nСкопируйте код из того комментария.\n\nВ ассемблере для обфусцированного метода нажмите 'Java в байткод'. Слева редактор, который принимает исходный код Java. Справа редактор, который покажет вам эквивалентный байткод Java. Вставьте код, который вы скопировали, в левую сторону (заменив существующий код там и удалив '*' перед каждой строкой).\n\nПри правильном выполнении вы должны увидеть справа метод, содержащий байткод, сгенерированный из компиляции кода слева. Вы можете скопировать инструкции из этого сгенерированного метода и вставить их в ассемблер выше. Чтобы было ясно, вы копируете только инструкции, а не весь сгенерированный метод. Если вы правильно скопировали логику расшифровки и сохранили изменения в ассемблере, следующая глава будет раскрыта. tutorial.5.decrypt=int key = Thread.currentThread().getStackTrace()[1].getMethodName().hashCode();\nchar[] chars = text.toCharArray();\nfor (int i = 0; i < chars.length; i++) chars[i] ^= key;\nreturn String.valueOf(chars); tutorial.5.finished=Правый клик на типе возврата этого метода "Chapter6" и выберите 'Перейти к классу'.\n\nВы можете альтернативно использовать [Control + Click] на ссылках, чтобы избежать необходимости проходить через контекстное меню каждый раз. -tutorial.6.class=Когда вы правым кликом на классе, поле или методе, вы можете увидеть, какой другой код ссылается на выбранную вами вещь.\n\n - Классы: Поиск > Ссылки на типы/члены\n - Поля: Ссылки на поля\n - Методы: Ссылки на методы\n\nВы можете найти эти опции поиска в меню 'Поиск' в строке меню вверху UI, вместе с другими вещами, такими как поиск строк и числовых литералов. +tutorial.6.class=Когда вы правым кликом на классе, поле или методе, вы можете увидеть, какой другой код ссылается на выбранную вами вещь.\n\n - Классы: Поиск > Ссылки на типы и поля/методы\n - Поля: Ссылки на поля\n - Методы: Ссылки на методы\n\nВы можете найти эти опции поиска в меню 'Поиск' в строке меню вверху UI, вместе с другими вещами, такими как поиск строк и числовых литералов. tutorial.6.method=Попробуйте найти, что ссылается на этот метод. tutorial.7.class=Поздравляем, это конец обучения!\n\nНажмите [Control + S] ещё раз в последний раз, чтобы отметить обучение как завершённое.\n\nПозже будет добавлено больше в обучение, но это должно покрыть все самые важные функции для вашего обычного случая использования. В то же время, не стесняйтесь исследовать другие функции самостоятельно! From 712d7b155def28bd5fcb932fa828a9e359e97239 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D0=BE=D0=91=D0=BE=D0=91=D0=BE?= <119269640+b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0@users.noreply.github.com> Date: Tue, 16 Jun 2026 16:33:02 +1000 Subject: [PATCH 5/6] Fix --- recaf-ui/src/main/resources/translations/ru_RU.lang | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/recaf-ui/src/main/resources/translations/ru_RU.lang b/recaf-ui/src/main/resources/translations/ru_RU.lang index d9f057795..598097f24 100644 --- a/recaf-ui/src/main/resources/translations/ru_RU.lang +++ b/recaf-ui/src/main/resources/translations/ru_RU.lang @@ -276,11 +276,7 @@ dialog.title.promote-resource-workspace=Сделать основным ресу dialog.option.create-workspace=Создать новое рабочее пространство dialog.option.update-workspace=Добавить в рабочее пространство dialog.header.promote-resource-workspace=Создать новое рабочее пространство с этим ресурсом как основным? -dialog.content.promote-resource-workspace=Текущее рабочее пространство будет закрыто, а выбранный ресурс станет новым основным. - -Все открытые вкладки будут закрыты. - -Сохранённые изменения в рабочем пространстве останутся. +dialog.content.promote-resource-workspace=Текущее рабочее пространство будет закрыто, а выбранный ресурс станет новым основным.\n\nВсе открытые вкладки будут закрыты.\n\nСохранённые изменения в рабочем пространстве останутся. ## Select class/file dialog.title.select-class=Выбрать класс From 1a3448a99ee14f7faabaec6fb8f8177a14239b41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D0=BE=D0=91=D0=BE=D0=91=D0=BE?= <119269640+b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0@users.noreply.github.com> Date: Tue, 16 Jun 2026 16:41:24 +1000 Subject: [PATCH 6/6] Fix --- .../main/resources/translations/ru_RU.lang | 42 +++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/recaf-ui/src/main/resources/translations/ru_RU.lang b/recaf-ui/src/main/resources/translations/ru_RU.lang index 598097f24..b4f9181ff 100644 --- a/recaf-ui/src/main/resources/translations/ru_RU.lang +++ b/recaf-ui/src/main/resources/translations/ru_RU.lang @@ -1110,29 +1110,29 @@ service.ui.language-config=Язык service.ui.language-config.current=Текущий язык ### Matcher translations -number.match.equal=значение == n -number.match.not=значение != n -number.match.gt=значение > n -number.match.gte=значение >= n -number.match.lt=значение < n -number.match.lte=значение <= n -number.match.gt-lt=мин < значение < макс -number.match.gte-lt=мин <= значение < макс -number.match.gt-lte=мин < значение <= макс -number.match.gte-lte=мин <= значение <= макс -number.match.any-of=числа.contains(значение) +number.match.equal=value == n +number.match.not=value != n +number.match.gt=value > n +number.match.gte=value >= n +number.match.lt=value < n +number.match.lte=value <= n +number.match.gt-lt=min < value < max +number.match.gte-lt=min <= value < max +number.match.gt-lte=min < value <= max +number.match.gte-lte=min <= value <= max +number.match.any-of=numbers.contains(value) string.match.anything=Всё string.match.zilch=Ничего -string.match.contains=строка.contains(значение) -string.match.contains-ic=строка.containsIgnoreCase(значение) -string.match.ends=строка.endsWith(значение) -string.match.ends-ic=строка.endsWithIgnoreCase(значение) -string.match.equal=строка.equals(значение) -string.match.equal-ic=строка.equalsIgnoreCase(значение) -string.match.regex-full=строка.matches(значение) -string.match.regex-partial=строка.matchesPartially(значение) -string.match.starts=строка.startsWith(значение) -string.match.starts-ic=строка.startsWithIgnoreCase(значение) +string.match.contains=str.contains(value) +string.match.contains-ic=str.containsIgnoreCase(value) +string.match.ends=str.endsWith(value) +string.match.ends-ic=str.endsWithIgnoreCase(value) +string.match.equal=str.equals(value) +string.match.equal-ic=str.equalsIgnoreCase(value) +string.match.regex-full=str.matches(value) +string.match.regex-partial=str.matchesPartially(value) +string.match.starts=str.startsWith(value) +string.match.starts-ic=str.startsWithIgnoreCase(value) ### Misc stuff misc.acknowledge=Принять