From f8cd7dd681bc0c1233877376e76b3b9290826e9e Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Sat, 11 Jul 2026 20:15:57 +0300 Subject: [PATCH] =?UTF-8?q?feat(meta-validate):=20=D0=B2=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=B4=D0=B0=D1=86=D0=B8=D1=8F=20=D0=BA=D0=BE=D0=BC=D0=B0=D0=BD?= =?UTF-8?q?=D0=B4=20=D0=BE=D0=B1=D1=8A=D0=B5=D0=BA=D1=82=D0=B0=20=E2=80=94?= =?UTF-8?q?=20=D0=B3=D1=80=D1=83=D0=BF=D0=BF=D0=B0=20+=20=D0=BF=D1=80?= =?UTF-8?q?=D0=B0=D0=B2=D0=B8=D0=BB=D0=BE=20=D0=BF=D0=B0=D1=80=D0=B0=D0=BC?= =?UTF-8?q?=D0=B5=D1=82=D1=80=D0=B0=20(=D0=A4=D0=B0=D0=B7=D0=B0=201.1,=20v?= =?UTF-8?q?1.7)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Check 15: команды в ChildObjects — Group обязателен и валиден (allowlist групп раздела/формы + CommandGroup.<Имя>); секционная группа (NavigationPanel*/ActionsPanel*) несовместима с commandParameterType; UUID/Name команды. Зеркало правил meta-compile v1.65 (команды раньше не валидировались вообще → пустой/неверный Group уходил в load-ошибку). ps1+py идентично. Тесты: valid-catalog-commands (preRun, группы раздела+формы) + 2 expectError-fixture (пустая группа; секц.группа+параметр). meta-validate 16/16 ps1+py. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../meta-validate/scripts/meta-validate.ps1 | 47 +++- .../meta-validate/scripts/meta-validate.py | 52 +++- .../meta-validate/error-command-no-group.json | 6 + .../error-command-section-param.json | 6 + .../Catalogs/ТестКоманд.xml | 115 ++++++++ .../Catalogs/ТестКоманд.xml | 115 ++++++++ .../Catalogs/ТестКоманд.xml | 136 ++++++++++ .../Commands/Обновить/Ext/CommandModule.bsl | 6 + .../Commands/Печать/Ext/CommandModule.bsl | 6 + .../Catalogs/ТестКоманд/Ext/ObjectModule.bsl | 0 .../valid-catalog-commands/Configuration.xml | 252 ++++++++++++++++++ .../Ext/ClientApplicationInterface.xml | 18 ++ .../Languages/Русский.xml | 16 ++ .../meta-validate/valid-catalog-commands.json | 18 ++ 14 files changed, 791 insertions(+), 2 deletions(-) create mode 100644 tests/skills/cases/meta-validate/error-command-no-group.json create mode 100644 tests/skills/cases/meta-validate/error-command-section-param.json create mode 100644 tests/skills/cases/meta-validate/fixtures/catalog-command-no-group/Catalogs/ТестКоманд.xml create mode 100644 tests/skills/cases/meta-validate/fixtures/catalog-command-section-param/Catalogs/ТестКоманд.xml create mode 100644 tests/skills/cases/meta-validate/snapshots/valid-catalog-commands/Catalogs/ТестКоманд.xml create mode 100644 tests/skills/cases/meta-validate/snapshots/valid-catalog-commands/Catalogs/ТестКоманд/Commands/Обновить/Ext/CommandModule.bsl create mode 100644 tests/skills/cases/meta-validate/snapshots/valid-catalog-commands/Catalogs/ТестКоманд/Commands/Печать/Ext/CommandModule.bsl create mode 100644 tests/skills/cases/meta-validate/snapshots/valid-catalog-commands/Catalogs/ТестКоманд/Ext/ObjectModule.bsl create mode 100644 tests/skills/cases/meta-validate/snapshots/valid-catalog-commands/Configuration.xml create mode 100644 tests/skills/cases/meta-validate/snapshots/valid-catalog-commands/Ext/ClientApplicationInterface.xml create mode 100644 tests/skills/cases/meta-validate/snapshots/valid-catalog-commands/Languages/Русский.xml create mode 100644 tests/skills/cases/meta-validate/valid-catalog-commands.json diff --git a/.claude/skills/meta-validate/scripts/meta-validate.ps1 b/.claude/skills/meta-validate/scripts/meta-validate.ps1 index cd99b51b..fa508288 100644 --- a/.claude/skills/meta-validate/scripts/meta-validate.ps1 +++ b/.claude/skills/meta-validate/scripts/meta-validate.ps1 @@ -1,4 +1,4 @@ -# meta-validate v1.6 — Validate 1C metadata object structure +# meta-validate v1.7 — Validate 1C metadata object structure # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [Parameter(Mandatory)] @@ -240,6 +240,11 @@ $childObjectRules = @{ "EventSubscription" = @() } +# Группы командного интерфейса (зеркало meta-compile): раздела — без commandParameterType; формы — с параметром. +$sectionCommandGroups = @("NavigationPanelImportant","NavigationPanelOrdinary","NavigationPanelSeeAlso","ActionsPanelCreate","ActionsPanelReports","ActionsPanelTools") +$formCommandGroups = @("FormCommandBarImportant","FormCommandBarCreateBasedOn","FormNavigationPanelImportant","FormNavigationPanelGoTo","FormNavigationPanelSeeAlso") +$validCommandGroups = $sectionCommandGroups + $formCommandGroups + # Valid enum property values $validPropertyValues = @{ "CodeType" = @("String","Number") @@ -1346,6 +1351,46 @@ if ($mdType -eq "DocumentJournal" -and $childObjNode) { } } +if ($script:stopped) { & $finalize; exit 1 } + +# --- Check 15: Commands — Group обязателен/валиден; секц.группа несовместима с CommandParameterType --- + +if ($childObjNode) { + $commands = $childObjNode.SelectNodes("md:Command", $ns) + $check15Ok = $true + $cmdCount = 0 + foreach ($cmd in $commands) { + if ($script:stopped) { break } + $cmdCount++ + $cuuid = $cmd.GetAttribute("uuid") + $cmdProps = $cmd.SelectSingleNode("md:Properties", $ns) + $cmdNameNode = if ($cmdProps) { $cmdProps.SelectSingleNode("md:Name", $ns) } else { $null } + $cmdName = if ($cmdNameNode -and $cmdNameNode.InnerText) { $cmdNameNode.InnerText } else { "(unnamed)" } + if (-not $cuuid -or $cuuid -notmatch $guidPattern) { + Report-Error "15. Command '$cmdName': missing or invalid uuid"; $check15Ok = $false + } + if ($cmdName -eq "(unnamed)") { + Report-Error "15. Command (uuid=$cuuid): missing or empty Name"; $check15Ok = $false + } + $groupNode = if ($cmdProps) { $cmdProps.SelectSingleNode("md:Group", $ns) } else { $null } + $groupVal = if ($groupNode) { $groupNode.InnerText.Trim() } else { "" } + if (-not $groupVal) { + Report-Error "15. Command '$cmdName': не задана группа (Group) — 1С отвергает при загрузке"; $check15Ok = $false + } elseif (($validCommandGroups -notcontains $groupVal) -and ($groupVal -notmatch '^CommandGroup\.')) { + Report-Error "15. Command '$cmdName': неизвестная группа '$groupVal'. Валидные: $($validCommandGroups -join ', '); либо CommandGroup.<Имя>"; $check15Ok = $false + } elseif ($sectionCommandGroups -contains $groupVal) { + $cptNode = if ($cmdProps) { $cmdProps.SelectSingleNode("md:CommandParameterType", $ns) } else { $null } + $hasCpt = $cptNode -and (($cptNode.SelectNodes("v8:Type", $ns).Count -gt 0) -or ($cptNode.SelectNodes("v8:TypeSet", $ns).Count -gt 0)) + if ($hasCpt) { + Report-Error "15. Command '$cmdName': тип параметра (CommandParameterType) недоступен для команд командного интерфейса раздела ('$groupVal')"; $check15Ok = $false + } + } + } + if ($check15Ok -and $cmdCount -gt 0) { + Report-OK "15. Commands: $cmdCount command(s), groups valid" + } +} + # --- Final output --- & $finalize diff --git a/.claude/skills/meta-validate/scripts/meta-validate.py b/.claude/skills/meta-validate/scripts/meta-validate.py index 87f7c8cb..ac0eaa04 100644 --- a/.claude/skills/meta-validate/scripts/meta-validate.py +++ b/.claude/skills/meta-validate/scripts/meta-validate.py @@ -1,4 +1,4 @@ -# meta-validate v1.6 — Validate 1C metadata object structure (Python port) +# meta-validate v1.7 — Validate 1C metadata object structure (Python port) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import os @@ -240,6 +240,13 @@ child_object_rules = { "EventSubscription": [], } +# Группы командного интерфейса (зеркало meta-compile): раздела — без commandParameterType; формы — с параметром. +SECTION_COMMAND_GROUPS = ["NavigationPanelImportant", "NavigationPanelOrdinary", "NavigationPanelSeeAlso", + "ActionsPanelCreate", "ActionsPanelReports", "ActionsPanelTools"] +FORM_COMMAND_GROUPS = ["FormCommandBarImportant", "FormCommandBarCreateBasedOn", + "FormNavigationPanelImportant", "FormNavigationPanelGoTo", "FormNavigationPanelSeeAlso"] +VALID_COMMAND_GROUPS = SECTION_COMMAND_GROUPS + FORM_COMMAND_GROUPS + # Valid enum property values valid_property_values = { "CodeType": ["String", "Number"], @@ -1252,6 +1259,49 @@ if md_type == "DocumentJournal" and child_obj_node is not None: elif col_count == 0: report_ok("14. DocumentJournal Columns: none") +if stopped: + finalize() + sys.exit(1) + +# ── Check 15: Commands — Group обязателен/валиден; секц.группа несовместима с CommandParameterType ── + +if child_obj_node is not None: + commands = find_all(child_obj_node, "md:Command") + check15_ok = True + cmd_count = 0 + for cmd in commands: + if stopped: + break + cmd_count += 1 + cuuid = cmd.get("uuid", "") + cmd_props = find(cmd, "md:Properties") + cmd_name_node = find(cmd_props, "md:Name") if cmd_props is not None else None + cmd_name = inner_text(cmd_name_node) if (cmd_name_node is not None and inner_text(cmd_name_node)) else "(unnamed)" + if not cuuid or not guid_pattern.match(cuuid): + report_error(f"15. Command '{cmd_name}': missing or invalid uuid") + check15_ok = False + if cmd_name == "(unnamed)": + report_error(f"15. Command (uuid={cuuid}): missing or empty Name") + check15_ok = False + group_node = find(cmd_props, "md:Group") if cmd_props is not None else None + group_val = inner_text(group_node).strip() if group_node is not None else "" + if not group_val: + report_error(f"15. Command '{cmd_name}': не задана группа (Group) — 1С отвергает при загрузке") + check15_ok = False + elif group_val not in VALID_COMMAND_GROUPS and not group_val.startswith("CommandGroup."): + report_error(f"15. Command '{cmd_name}': неизвестная группа '{group_val}'. " + f"Валидные: {', '.join(VALID_COMMAND_GROUPS)}; либо CommandGroup.<Имя>") + check15_ok = False + elif group_val in SECTION_COMMAND_GROUPS: + cpt_node = find(cmd_props, "md:CommandParameterType") if cmd_props is not None else None + has_cpt = cpt_node is not None and (len(find_all(cpt_node, "v8:Type")) > 0 or len(find_all(cpt_node, "v8:TypeSet")) > 0) + if has_cpt: + report_error(f"15. Command '{cmd_name}': тип параметра (CommandParameterType) недоступен " + f"для команд командного интерфейса раздела ('{group_val}')") + check15_ok = False + if check15_ok and cmd_count > 0: + report_ok(f"15. Commands: {cmd_count} command(s), groups valid") + # ── Final output ────────────────────────────────────────────── finalize() diff --git a/tests/skills/cases/meta-validate/error-command-no-group.json b/tests/skills/cases/meta-validate/error-command-no-group.json new file mode 100644 index 00000000..a9a7b9dd --- /dev/null +++ b/tests/skills/cases/meta-validate/error-command-no-group.json @@ -0,0 +1,6 @@ +{ + "name": "Валидатор ловит команду без группы (пустой Group)", + "setup": "fixture:catalog-command-no-group", + "params": { "objectPath": "Catalogs/ТестКоманд.xml" }, + "expectError": true +} diff --git a/tests/skills/cases/meta-validate/error-command-section-param.json b/tests/skills/cases/meta-validate/error-command-section-param.json new file mode 100644 index 00000000..0228c8a9 --- /dev/null +++ b/tests/skills/cases/meta-validate/error-command-section-param.json @@ -0,0 +1,6 @@ +{ + "name": "Валидатор ловит секционную группу команды + commandParameterType", + "setup": "fixture:catalog-command-section-param", + "params": { "objectPath": "Catalogs/ТестКоманд.xml" }, + "expectError": true +} diff --git a/tests/skills/cases/meta-validate/fixtures/catalog-command-no-group/Catalogs/ТестКоманд.xml b/tests/skills/cases/meta-validate/fixtures/catalog-command-no-group/Catalogs/ТестКоманд.xml new file mode 100644 index 00000000..6837f4dc --- /dev/null +++ b/tests/skills/cases/meta-validate/fixtures/catalog-command-no-group/Catalogs/ТестКоманд.xml @@ -0,0 +1,115 @@ + + + + + + 3cdf7826-a007-4b57-b642-76a5580e5817 + 05277e8d-89bb-480b-8553-11dae4c0f7a3 + + + 4fb61896-02c8-4858-9f8d-e55395c779f0 + 1b5f89ca-683c-493a-adb0-2f46daaaa20d + + + 3e13d099-e6f5-4d85-b111-82981622fd0a + 3d90f58f-18d0-4dcd-818f-b578c54dd55c + + + 33cc0cf3-2241-41cf-8979-da215ab282e6 + 6d5a7d96-6ad7-461d-af62-bb63b57a06a1 + + + f65a6d7a-57df-4e94-aece-d9c31ccaa832 + a71dd300-6b90-4c3a-8cb9-bc984baa3b5e + + + + ТестКоманд + + + ru + Тест команд + + + + false + HierarchyFoldersAndItems + false + 2 + true + true + + ToItems + 9 + 25 + String + Variable + WholeCatalog + false + true + AsDescription + + Auto + InDialog + false + BothWays + + Catalog.ТестКоманд.StandardAttribute.Description + Catalog.ТестКоманд.StandardAttribute.Code + + Begin + DontUse + Directly + + + + + + + + + + + false + + + Managed + Use + + + + + + Use + Auto + DontUse + false + false + + + + + Печать + + + ru + Печать + + + + + + d5p1:CatalogRef.ТестКоманд + + Single + false + Auto + + + + Auto + + + + + diff --git a/tests/skills/cases/meta-validate/fixtures/catalog-command-section-param/Catalogs/ТестКоманд.xml b/tests/skills/cases/meta-validate/fixtures/catalog-command-section-param/Catalogs/ТестКоманд.xml new file mode 100644 index 00000000..33dc5ee8 --- /dev/null +++ b/tests/skills/cases/meta-validate/fixtures/catalog-command-section-param/Catalogs/ТестКоманд.xml @@ -0,0 +1,115 @@ + + + + + + 3cdf7826-a007-4b57-b642-76a5580e5817 + 05277e8d-89bb-480b-8553-11dae4c0f7a3 + + + 4fb61896-02c8-4858-9f8d-e55395c779f0 + 1b5f89ca-683c-493a-adb0-2f46daaaa20d + + + 3e13d099-e6f5-4d85-b111-82981622fd0a + 3d90f58f-18d0-4dcd-818f-b578c54dd55c + + + 33cc0cf3-2241-41cf-8979-da215ab282e6 + 6d5a7d96-6ad7-461d-af62-bb63b57a06a1 + + + f65a6d7a-57df-4e94-aece-d9c31ccaa832 + a71dd300-6b90-4c3a-8cb9-bc984baa3b5e + + + + ТестКоманд + + + ru + Тест команд + + + + false + HierarchyFoldersAndItems + false + 2 + true + true + + ToItems + 9 + 25 + String + Variable + WholeCatalog + false + true + AsDescription + + Auto + InDialog + false + BothWays + + Catalog.ТестКоманд.StandardAttribute.Description + Catalog.ТестКоманд.StandardAttribute.Code + + Begin + DontUse + Directly + + + + + + + + + + + false + + + Managed + Use + + + + + + Use + Auto + DontUse + false + false + + + + + Печать + + + ru + Печать + + + + NavigationPanelOrdinary + + d5p1:CatalogRef.ТестКоманд + + Single + false + Auto + + + + Auto + + + + + diff --git a/tests/skills/cases/meta-validate/snapshots/valid-catalog-commands/Catalogs/ТестКоманд.xml b/tests/skills/cases/meta-validate/snapshots/valid-catalog-commands/Catalogs/ТестКоманд.xml new file mode 100644 index 00000000..58e825af --- /dev/null +++ b/tests/skills/cases/meta-validate/snapshots/valid-catalog-commands/Catalogs/ТестКоманд.xml @@ -0,0 +1,136 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + UUID-006 + UUID-007 + + + UUID-008 + UUID-009 + + + UUID-010 + UUID-011 + + + + ТестКоманд + + + ru + Тест команд + + + + false + HierarchyFoldersAndItems + false + 2 + true + true + + ToItems + 9 + 25 + String + Variable + WholeCatalog + false + true + AsDescription + + Auto + InDialog + false + BothWays + + Catalog.ТестКоманд.StandardAttribute.Description + Catalog.ТестКоманд.StandardAttribute.Code + + Begin + DontUse + Directly + + + + + + + + + + + false + + + Managed + Use + + + + + + Use + Auto + DontUse + false + false + + + + + Печать + + + ru + Печать + + + + FormCommandBarImportant + + d5p1:CatalogRef.ТестКоманд + + Single + false + Auto + + + + Auto + + + + + Обновить + + + ru + Обновить + + + + NavigationPanelOrdinary + + Single + false + Auto + + + + Auto + + + + + diff --git a/tests/skills/cases/meta-validate/snapshots/valid-catalog-commands/Catalogs/ТестКоманд/Commands/Обновить/Ext/CommandModule.bsl b/tests/skills/cases/meta-validate/snapshots/valid-catalog-commands/Catalogs/ТестКоманд/Commands/Обновить/Ext/CommandModule.bsl new file mode 100644 index 00000000..d7ec0aeb --- /dev/null +++ b/tests/skills/cases/meta-validate/snapshots/valid-catalog-commands/Catalogs/ТестКоманд/Commands/Обновить/Ext/CommandModule.bsl @@ -0,0 +1,6 @@ +&НаКлиенте +Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды) + + // Вставьте обработчик команды. + +КонецПроцедуры diff --git a/tests/skills/cases/meta-validate/snapshots/valid-catalog-commands/Catalogs/ТестКоманд/Commands/Печать/Ext/CommandModule.bsl b/tests/skills/cases/meta-validate/snapshots/valid-catalog-commands/Catalogs/ТестКоманд/Commands/Печать/Ext/CommandModule.bsl new file mode 100644 index 00000000..d7ec0aeb --- /dev/null +++ b/tests/skills/cases/meta-validate/snapshots/valid-catalog-commands/Catalogs/ТестКоманд/Commands/Печать/Ext/CommandModule.bsl @@ -0,0 +1,6 @@ +&НаКлиенте +Процедура ОбработкаКоманды(ПараметрКоманды, ПараметрыВыполненияКоманды) + + // Вставьте обработчик команды. + +КонецПроцедуры diff --git a/tests/skills/cases/meta-validate/snapshots/valid-catalog-commands/Catalogs/ТестКоманд/Ext/ObjectModule.bsl b/tests/skills/cases/meta-validate/snapshots/valid-catalog-commands/Catalogs/ТестКоманд/Ext/ObjectModule.bsl new file mode 100644 index 00000000..e69de29b diff --git a/tests/skills/cases/meta-validate/snapshots/valid-catalog-commands/Configuration.xml b/tests/skills/cases/meta-validate/snapshots/valid-catalog-commands/Configuration.xml new file mode 100644 index 00000000..7baaca3b --- /dev/null +++ b/tests/skills/cases/meta-validate/snapshots/valid-catalog-commands/Configuration.xml @@ -0,0 +1,252 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + UUID-006 + UUID-007 + + + UUID-008 + UUID-009 + + + UUID-010 + UUID-011 + + + UUID-012 + UUID-013 + + + UUID-014 + UUID-015 + + + + TestConfig + + + ru + TestConfig + + + + + Version8_3_24 + ManagedApplication + + PlatformApplication + + Russian + + + + + false + false + false + + + + + + + + + + + + + + + + + + + + + + Biometrics + true + + + Location + false + + + BackgroundLocation + false + + + BluetoothPrinters + false + + + WiFiPrinters + false + + + Contacts + false + + + Calendars + false + + + PushNotifications + false + + + LocalNotifications + false + + + InAppPurchases + false + + + PersonalComputerFileExchange + false + + + Ads + false + + + NumberDialing + false + + + CallProcessing + false + + + CallLog + false + + + AutoSendSMS + false + + + ReceiveSMS + false + + + SMSLog + false + + + Camera + false + + + Microphone + false + + + MusicLibrary + false + + + PictureAndVideoLibraries + false + + + AudioPlaybackAndVibration + false + + + BackgroundAudioPlaybackAndVibration + false + + + InstallPackages + false + + + OSBackup + true + + + ApplicationUsageStatistics + false + + + BarcodeScanning + false + + + BackgroundAudioRecording + false + + + AllFilesAccess + false + + + Videoconferences + false + + + NFC + false + + + DocumentScanning + false + + + SpeechToText + false + + + Geofences + false + + + IncomingShareRequests + false + + + AllIncomingShareRequestsTypesProcessing + false + + + + + + Normal + + + Language.Русский + + + + + + Managed + NotAutoFree + DontUse + DontUse + TaxiEnableVersion8_2 + DontUse + Version8_3_24 + + + + Русский + ТестКоманд + + + \ No newline at end of file diff --git a/tests/skills/cases/meta-validate/snapshots/valid-catalog-commands/Ext/ClientApplicationInterface.xml b/tests/skills/cases/meta-validate/snapshots/valid-catalog-commands/Ext/ClientApplicationInterface.xml new file mode 100644 index 00000000..3c1161b2 --- /dev/null +++ b/tests/skills/cases/meta-validate/snapshots/valid-catalog-commands/Ext/ClientApplicationInterface.xml @@ -0,0 +1,18 @@ + + + + + UUID-002 + + + + + UUID-004 + + + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/meta-validate/snapshots/valid-catalog-commands/Languages/Русский.xml b/tests/skills/cases/meta-validate/snapshots/valid-catalog-commands/Languages/Русский.xml new file mode 100644 index 00000000..37c60d78 --- /dev/null +++ b/tests/skills/cases/meta-validate/snapshots/valid-catalog-commands/Languages/Русский.xml @@ -0,0 +1,16 @@ + + + + + Русский + + + ru + Русский + + + + ru + + + \ No newline at end of file diff --git a/tests/skills/cases/meta-validate/valid-catalog-commands.json b/tests/skills/cases/meta-validate/valid-catalog-commands.json new file mode 100644 index 00000000..3280a144 --- /dev/null +++ b/tests/skills/cases/meta-validate/valid-catalog-commands.json @@ -0,0 +1,18 @@ +{ + "name": "Каталог с валидными командами (группы раздела/формы) проходит валидацию", + "setup": "empty-config", + "preRun": [ + { + "script": "meta-compile/scripts/meta-compile", + "input": { + "type": "Catalog", "name": "ТестКоманд", "useStandardCommands": true, + "commands": { + "Печать": { "group": "FormCommandBarImportant", "commandParameterType": "CatalogRef.ТестКоманд" }, + "Обновить": { "group": "NavigationPanelOrdinary" } + } + }, + "args": { "-JsonPath": "{inputFile}", "-OutputDir": "{workDir}" } + } + ], + "params": { "objectPath": "Catalogs/ТестКоманд" } +}