feat(meta-compile,meta-decompile): мультиязычный ML для синонима и подсказки реквизита (v1.18/v0.4)

Раундтрип-находка (класс-1 синоним + класс-3 подсказка). Корпус: у реквизитов 21677 мультиязычных
синонимов (ru+en) и 16063 непустых подсказки (10689 мультиязычных). meta-compile писал ВСЁ ML только ru
(Emit-MLText брал строку) и хардкодил <ToolTip/> пустым → массовая потеря en + подсказок.

- meta-compile (дуал-порт): Emit-MLText/emit_mltext принимают строку (→ru) ИЛИ объект {lang:content}
  (→<v8:item> на язык, в порядке ключей) через новый Emit-MLItems/emit_ml_items. Parse object-форма
  реквизита пробрасывает synonym/tooltip без стрингификации; Emit-Attribute эмитит <ToolTip> из tooltip.
- meta-decompile: Get-MLValue → строка (ru-only) | {ru,en} (мультиязычно, порядок из XML); object-форма
  реквизита при кастомном синониме ИЛИ наличии подсказки.
- spec meta-dsl-spec.md v2.3: §4.2 (tooltip) + §4.4 ML-значения (строка/{ru,en}), консистентно с form-compile.
- тест-кейс catalog-attr-ml (мультиязычный синоним + подсказка, обе формы).

Валидация: PS==PY паритет; полный прогон −228748 строк (447285→218537, >половины); регресс 35/35 (ps+py);
1С-cert зелёный.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-07-01 17:18:01 +03:00
parent ed42d5e9cb
commit 58bc95264e
10 changed files with 584 additions and 23 deletions
@@ -331,17 +331,30 @@ function Esc-Xml {
return $s.Replace('&','&amp;').Replace('<','&lt;').Replace('>','&gt;').Replace('"','&quot;')
}
# ML-значение: строка → один <v8:item> ru; объект {lang: content} → item на язык (в порядке ключей).
function Emit-MLItems {
param([string]$indent, $val)
if ($val -is [System.Collections.IDictionary]) {
foreach ($k in $val.Keys) {
X "$indent<v8:item>"; X "$indent`t<v8:lang>$k</v8:lang>"; X "$indent`t<v8:content>$(Esc-Xml "$($val[$k])")</v8:content>"; X "$indent</v8:item>"
}
} elseif ($val -is [System.Management.Automation.PSCustomObject]) {
foreach ($p in $val.PSObject.Properties) {
X "$indent<v8:item>"; X "$indent`t<v8:lang>$($p.Name)</v8:lang>"; X "$indent`t<v8:content>$(Esc-Xml "$($p.Value)")</v8:content>"; X "$indent</v8:item>"
}
} else {
X "$indent<v8:item>"; X "$indent`t<v8:lang>ru</v8:lang>"; X "$indent`t<v8:content>$(Esc-Xml "$val")</v8:content>"; X "$indent</v8:item>"
}
}
function Emit-MLText {
param([string]$indent, [string]$tag, [string]$text)
if (-not $text) {
param([string]$indent, [string]$tag, $text)
# Пусто (null / пустая строка) → самозакрывающийся тег.
if (($null -eq $text) -or (($text -is [string]) -and ($text -eq ''))) {
X "$indent<$tag/>"
return
}
X "$indent<$tag>"
X "$indent`t<v8:item>"
X "$indent`t`t<v8:lang>ru</v8:lang>"
X "$indent`t`t<v8:content>$(Esc-Xml $text)</v8:content>"
X "$indent`t</v8:item>"
Emit-MLItems "$indent`t" $text
X "$indent</$tag>"
}
@@ -611,12 +624,13 @@ function Parse-AttributeShorthand {
return $parsed
}
# Object form
# Object form. synonym/tooltip — сквозной проброс (строка ИЛИ объект {ru,en}), НЕ стрингифаим.
$name = "$($val.name)"
return @{
name = $name
type = Build-TypeStr $val
synonym = if ($val.synonym) { "$($val.synonym)" } else { Split-CamelCase $name }
synonym = if ($null -ne $val.synonym) { $val.synonym } else { Split-CamelCase $name }
tooltip = $val.tooltip
comment = if ($val.comment) { "$($val.comment)" } else { "" }
flags = @(if ($val.flags) { $val.flags } else { @() })
fillChecking = if ($val.fillChecking) { "$($val.fillChecking)" } else { "" }
@@ -962,7 +976,7 @@ function Emit-Attribute {
X "$indent`t`t<PasswordMode>false</PasswordMode>"
X "$indent`t`t<Format/>"
X "$indent`t`t<EditFormat/>"
X "$indent`t`t<ToolTip/>"
Emit-MLText "$indent`t`t" "ToolTip" $parsed.tooltip
X "$indent`t`t<MarkNegatives>false</MarkNegatives>"
X "$indent`t`t<Mask/>"
$multiLine = if ($parsed.multiLine -eq $true -or $parsed.flags -contains "multiline") { "true" } else { "false" }
@@ -197,15 +197,27 @@ lines = []
def X(text):
lines.append(text)
# ML-значение: строка → один <v8:item> ru; dict {lang: content} → item на язык (в порядке ключей).
def emit_ml_items(indent, val):
if isinstance(val, dict):
for k, v in val.items():
X(f'{indent}<v8:item>')
X(f'{indent}\t<v8:lang>{k}</v8:lang>')
X(f'{indent}\t<v8:content>{esc_xml(str(v))}</v8:content>')
X(f'{indent}</v8:item>')
else:
X(f'{indent}<v8:item>')
X(f'{indent}\t<v8:lang>ru</v8:lang>')
X(f'{indent}\t<v8:content>{esc_xml(str(val))}</v8:content>')
X(f'{indent}</v8:item>')
def emit_mltext(indent, tag, text):
if not text:
# Пусто (None / '') → самозакрывающийся тег.
if text is None or (isinstance(text, str) and text == ''):
X(f'{indent}<{tag}/>')
return
X(f'{indent}<{tag}>')
X(f'{indent}\t<v8:item>')
X(f'{indent}\t\t<v8:lang>ru</v8:lang>')
X(f'{indent}\t\t<v8:content>{esc_xml(text)}</v8:content>')
X(f'{indent}\t</v8:item>')
emit_ml_items(f'{indent}\t', text)
X(f'{indent}</{tag}>')
# ---------------------------------------------------------------------------
@@ -615,12 +627,13 @@ def parse_attribute_shorthand(val):
parsed['type'] = colon_parts[1].strip()
parsed['synonym'] = split_camel_case(parsed['name'])
return parsed
# Object form
# Object form. synonym/tooltip — сквозной проброс (строка ИЛИ dict {ru,en}), НЕ стрингифаим.
name = str(val.get('name', ''))
return {
'name': name,
'type': build_type_str(val),
'synonym': str(val['synonym']) if val.get('synonym') else split_camel_case(name),
'synonym': val['synonym'] if val.get('synonym') is not None else split_camel_case(name),
'tooltip': val.get('tooltip'),
'comment': str(val['comment']) if val.get('comment') else '',
'flags': list(val.get('flags', [])),
'fillChecking': str(val['fillChecking']) if val.get('fillChecking') else '',
@@ -957,7 +970,7 @@ def emit_attribute(indent, parsed, context):
X(f'{indent}\t\t<PasswordMode>false</PasswordMode>')
X(f'{indent}\t\t<Format/>')
X(f'{indent}\t\t<EditFormat/>')
X(f'{indent}\t\t<ToolTip/>')
emit_mltext(f'{indent}\t\t', 'ToolTip', parsed.get('tooltip'))
X(f'{indent}\t\t<MarkNegatives>false</MarkNegatives>')
X(f'{indent}\t\t<Mask/>')
multi_line = 'true' if (parsed.get('multiLine') is True or 'multiline' in parsed.get('flags', [])) else 'false'
@@ -1,4 +1,4 @@
# meta-decompile v0.3 — XML объекта метаданных 1С → JSON-черновик формата meta-compile
# meta-decompile v0.4 — XML объекта метаданных 1С → JSON-черновик формата meta-compile
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
#
# Пилот: только Catalog. Инверс meta-compile (omit-on-default: ключ эмитим только
@@ -105,6 +105,26 @@ function Get-MLru {
if ($it) { return $it.InnerText }
return $null
}
# ML-значение → строка (если единственный item ru) ЛИБО [ordered]{lang:content} (мультиязычно, порядок из XML).
# null если контента нет. Компактная строка для ru-only, объект для мультиязычных.
function Get-MLValue {
param($node)
if (-not $node) { return $null }
$items = @($node.SelectNodes('v8:item', $nsm))
if ($items.Count -eq 0) { return $null }
if ($items.Count -eq 1) {
$lang = $items[0].SelectSingleNode('v8:lang', $nsm).InnerText
$content = $items[0].SelectSingleNode('v8:content', $nsm).InnerText
if ($lang -eq 'ru') { return $content }
}
$o = [ordered]@{}
foreach ($it in $items) {
$l = $it.SelectSingleNode('v8:lang', $nsm).InnerText
$c = $it.SelectSingleNode('v8:content', $nsm).InnerText
$o[$l] = $c
}
return $o
}
# Авто-синоним: точное зеркало Split-CamelCase из meta-compile (стр.354). Совпало → ключ опускаем.
# ВАЖНО: логика должна совпадать байт-в-байт с компилятором, иначе ложные «синоним==авто» → диффы.
function Split-CamelWords {
@@ -175,12 +195,18 @@ function Attr-ToDsl {
if ($ix) { if ($ix.InnerText -eq 'Index') { $flags += 'index' } elseif ($ix.InnerText -eq 'IndexWithAdditionalOrder') { $flags += 'indexAdditional' } }
$ml = $ap.SelectSingleNode('md:MultiLine', $nsm); if ($ml -and $ml.InnerText -eq 'true') { $flags += 'multiline' }
$syn = Get-MLru ($ap.SelectSingleNode('md:Synonym', $nsm))
# Кастомный синоним (есть и ≠ авто) → object-форма (shorthand его не выражает).
if ($syn -and $syn -ne (Split-CamelWords $nm)) {
# Синоним/подсказка (строка ru-only ИЛИ {ru,en}). Кастомный синоним ИЛИ наличие подсказки → object-форма.
$synVal = Get-MLValue ($ap.SelectSingleNode('md:Synonym', $nsm))
$synCustom = $false
if ($synVal -is [string]) { if ($synVal -ne (Split-CamelWords $nm)) { $synCustom = $true } }
elseif ($null -ne $synVal) { $synCustom = $true } # {ru,en} = всегда кастом
$ttVal = Get-MLValue ($ap.SelectSingleNode('md:ToolTip', $nsm))
if ($synCustom -or ($null -ne $ttVal)) {
$o = [ordered]@{ name = $nm }
if ($ts) { $o['type'] = $ts }
$o['synonym'] = $syn
if ($synCustom) { $o['synonym'] = $synVal }
if ($null -ne $ttVal) { $o['tooltip'] = $ttVal }
if ($flags.Count -gt 0) { $o['flags'] = [System.Collections.ArrayList]@($flags) }
return $o
}
+13 -1
View File
@@ -1,6 +1,6 @@
# Meta DSL — спецификация JSON-формата для объектов метаданных 1С
Версия: 2.2
Версия: 2.3
## Обзор
@@ -124,12 +124,15 @@ JSON DSL для описания объектов метаданных конф
"name": "Имя",
"type": "String(100)",
"synonym": "Мой синоним",
"tooltip": "Всплывающая подсказка",
"comment": "Комментарий",
"fillChecking": "ShowError",
"indexing": "Index"
}
```
**`synonym` и `tooltip` — ML-значения** (см. §4.4): строка → русский текст; объект `{ "ru": "…", "en": "…" }` → мультиязычный (`<v8:item>` на язык, в порядке ключей). `tooltip``<ToolTip>` реквизита; нет ключа → `<ToolTip/>` (пусто). `synonym` не задан → авто из имени (§2).
Тип можно задать единой строкой (`"type": "String(100)"`) или раздельными полями:
```json
@@ -157,6 +160,15 @@ JSON DSL для описания объектов метаданных конф
Флаги разделяются запятой после `|`.
### 4.4 ML-значения (многоязычный текст)
Текстовые поля, попадающие в `<v8:item>`-структуру 1С (`synonym`, `tooltip`), принимают две формы:
- **строка** → один язык `ru`: `"synonym": "Наименование"`;
- **объект `{ lang: content }`** → по `<v8:item>` на язык, **в порядке ключей**: `"tooltip": { "ru": "Подсказка", "en": "Hint" }`.
Пустая строка `""` / отсутствие ключа → самозакрывающийся тег (`<ToolTip/>`). Консистентно с формой `title`/`tooltip` в form-compile.
---
## 5. Табличные части
@@ -0,0 +1,12 @@
{
"name": "Справочник с ML-синонимом и подсказкой реквизита",
"input": {
"type": "Catalog", "name": "Контрагенты",
"attributes": [
{ "name": "ИНН", "type": "String(12)", "synonym": { "ru": "ИНН", "en": "TIN" }, "tooltip": "Идентификационный номер налогоплательщика" },
{ "name": "Комментарий", "type": "String(200)", "tooltip": { "ru": "Произвольный комментарий", "en": "Free-form comment" } }
]
},
"validatePath": "Catalogs/Контрагенты",
"expect": { "files": ["Catalogs/Контрагенты.xml"] }
}
@@ -0,0 +1,198 @@
<?xml version="1.0" encoding="UTF-8"?>
<MetaDataObject xmlns="http://v8.1c.ru/8.3/MDClasses" xmlns:app="http://v8.1c.ru/8.2/managed-application/core" xmlns:cfg="http://v8.1c.ru/8.1/data/enterprise/current-config" xmlns:cmi="http://v8.1c.ru/8.2/managed-application/cmi" xmlns:ent="http://v8.1c.ru/8.1/data/enterprise" xmlns:lf="http://v8.1c.ru/8.2/managed-application/logform" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows" xmlns:xen="http://v8.1c.ru/8.3/xcf/enums" xmlns:xpr="http://v8.1c.ru/8.3/xcf/predef" xmlns:xr="http://v8.1c.ru/8.3/xcf/readable" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.17">
<Catalog uuid="UUID-001">
<InternalInfo>
<xr:GeneratedType name="CatalogObject.Контрагенты" category="Object">
<xr:TypeId>UUID-002</xr:TypeId>
<xr:ValueId>UUID-003</xr:ValueId>
</xr:GeneratedType>
<xr:GeneratedType name="CatalogRef.Контрагенты" category="Ref">
<xr:TypeId>UUID-004</xr:TypeId>
<xr:ValueId>UUID-005</xr:ValueId>
</xr:GeneratedType>
<xr:GeneratedType name="CatalogSelection.Контрагенты" category="Selection">
<xr:TypeId>UUID-006</xr:TypeId>
<xr:ValueId>UUID-007</xr:ValueId>
</xr:GeneratedType>
<xr:GeneratedType name="CatalogList.Контрагенты" category="List">
<xr:TypeId>UUID-008</xr:TypeId>
<xr:ValueId>UUID-009</xr:ValueId>
</xr:GeneratedType>
<xr:GeneratedType name="CatalogManager.Контрагенты" category="Manager">
<xr:TypeId>UUID-010</xr:TypeId>
<xr:ValueId>UUID-011</xr:ValueId>
</xr:GeneratedType>
</InternalInfo>
<Properties>
<Name>Контрагенты</Name>
<Synonym>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Контрагенты</v8:content>
</v8:item>
</Synonym>
<Comment/>
<Hierarchical>false</Hierarchical>
<HierarchyType>HierarchyFoldersAndItems</HierarchyType>
<LimitLevelCount>false</LimitLevelCount>
<LevelCount>2</LevelCount>
<FoldersOnTop>true</FoldersOnTop>
<UseStandardCommands>true</UseStandardCommands>
<Owners/>
<SubordinationUse>ToItems</SubordinationUse>
<CodeLength>9</CodeLength>
<DescriptionLength>25</DescriptionLength>
<CodeType>String</CodeType>
<CodeAllowedLength>Variable</CodeAllowedLength>
<CodeSeries>WholeCatalog</CodeSeries>
<CheckUnique>false</CheckUnique>
<Autonumbering>true</Autonumbering>
<DefaultPresentation>AsDescription</DefaultPresentation>
<Characteristics/>
<PredefinedDataUpdate>Auto</PredefinedDataUpdate>
<EditType>InDialog</EditType>
<QuickChoice>false</QuickChoice>
<ChoiceMode>BothWays</ChoiceMode>
<InputByString>
<xr:Field>Catalog.Контрагенты.StandardAttribute.Description</xr:Field>
<xr:Field>Catalog.Контрагенты.StandardAttribute.Code</xr:Field>
</InputByString>
<SearchStringModeOnInputByString>Begin</SearchStringModeOnInputByString>
<FullTextSearchOnInputByString>DontUse</FullTextSearchOnInputByString>
<ChoiceDataGetModeOnInputByString>Directly</ChoiceDataGetModeOnInputByString>
<DefaultObjectForm/>
<DefaultFolderForm/>
<DefaultListForm/>
<DefaultChoiceForm/>
<DefaultFolderChoiceForm/>
<AuxiliaryObjectForm/>
<AuxiliaryFolderForm/>
<AuxiliaryListForm/>
<AuxiliaryChoiceForm/>
<AuxiliaryFolderChoiceForm/>
<IncludeHelpInContents>false</IncludeHelpInContents>
<BasedOn/>
<DataLockFields/>
<DataLockControlMode>Automatic</DataLockControlMode>
<FullTextSearch>Use</FullTextSearch>
<ObjectPresentation/>
<ExtendedObjectPresentation/>
<ListPresentation/>
<ExtendedListPresentation/>
<Explanation/>
<CreateOnInput>DontUse</CreateOnInput>
<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>
<DataHistory>DontUse</DataHistory>
<UpdateDataHistoryImmediatelyAfterWrite>false</UpdateDataHistoryImmediatelyAfterWrite>
<ExecuteAfterWriteDataHistoryVersionProcessing>false</ExecuteAfterWriteDataHistoryVersionProcessing>
</Properties>
<ChildObjects>
<Attribute uuid="UUID-012">
<Properties>
<Name>ИНН</Name>
<Synonym>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>ИНН</v8:content>
</v8:item>
<v8:item>
<v8:lang>en</v8:lang>
<v8:content>TIN</v8:content>
</v8:item>
</Synonym>
<Comment/>
<Type>
<v8:Type>xs:string</v8:Type>
<v8:StringQualifiers>
<v8:Length>12</v8:Length>
<v8:AllowedLength>Variable</v8:AllowedLength>
</v8:StringQualifiers>
</Type>
<PasswordMode>false</PasswordMode>
<Format/>
<EditFormat/>
<ToolTip>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Идентификационный номер налогоплательщика</v8:content>
</v8:item>
</ToolTip>
<MarkNegatives>false</MarkNegatives>
<Mask/>
<MultiLine>false</MultiLine>
<ExtendedEdit>false</ExtendedEdit>
<MinValue xsi:nil="true"/>
<MaxValue xsi:nil="true"/>
<FillFromFillingValue>false</FillFromFillingValue>
<FillValue xsi:type="xs:string"/>
<FillChecking>DontCheck</FillChecking>
<ChoiceFoldersAndItems>Items</ChoiceFoldersAndItems>
<ChoiceParameterLinks/>
<ChoiceParameters/>
<QuickChoice>Auto</QuickChoice>
<CreateOnInput>Auto</CreateOnInput>
<ChoiceForm/>
<LinkByType/>
<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>
<Use>ForItem</Use>
<Indexing>DontIndex</Indexing>
<FullTextSearch>Use</FullTextSearch>
<DataHistory>Use</DataHistory>
</Properties>
</Attribute>
<Attribute uuid="UUID-013">
<Properties>
<Name>Комментарий</Name>
<Synonym>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Комментарий</v8:content>
</v8:item>
</Synonym>
<Comment/>
<Type>
<v8:Type>xs:string</v8:Type>
<v8:StringQualifiers>
<v8:Length>200</v8:Length>
<v8:AllowedLength>Variable</v8:AllowedLength>
</v8:StringQualifiers>
</Type>
<PasswordMode>false</PasswordMode>
<Format/>
<EditFormat/>
<ToolTip>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Произвольный комментарий</v8:content>
</v8:item>
<v8:item>
<v8:lang>en</v8:lang>
<v8:content>Free-form comment</v8:content>
</v8:item>
</ToolTip>
<MarkNegatives>false</MarkNegatives>
<Mask/>
<MultiLine>false</MultiLine>
<ExtendedEdit>false</ExtendedEdit>
<MinValue xsi:nil="true"/>
<MaxValue xsi:nil="true"/>
<FillFromFillingValue>false</FillFromFillingValue>
<FillValue xsi:type="xs:string"/>
<FillChecking>DontCheck</FillChecking>
<ChoiceFoldersAndItems>Items</ChoiceFoldersAndItems>
<ChoiceParameterLinks/>
<ChoiceParameters/>
<QuickChoice>Auto</QuickChoice>
<CreateOnInput>Auto</CreateOnInput>
<ChoiceForm/>
<LinkByType/>
<ChoiceHistoryOnInput>Auto</ChoiceHistoryOnInput>
<Use>ForItem</Use>
<Indexing>DontIndex</Indexing>
<FullTextSearch>Use</FullTextSearch>
<DataHistory>Use</DataHistory>
</Properties>
</Attribute>
</ChildObjects>
</Catalog>
</MetaDataObject>
@@ -0,0 +1,252 @@
<?xml version="1.0" encoding="utf-8"?>
<MetaDataObject xmlns="http://v8.1c.ru/8.3/MDClasses" xmlns:app="http://v8.1c.ru/8.2/managed-application/core" xmlns:cfg="http://v8.1c.ru/8.1/data/enterprise/current-config" xmlns:cmi="http://v8.1c.ru/8.2/managed-application/cmi" xmlns:ent="http://v8.1c.ru/8.1/data/enterprise" xmlns:lf="http://v8.1c.ru/8.2/managed-application/logform" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows" xmlns:xen="http://v8.1c.ru/8.3/xcf/enums" xmlns:xpr="http://v8.1c.ru/8.3/xcf/predef" xmlns:xr="http://v8.1c.ru/8.3/xcf/readable" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.17">
<Configuration uuid="UUID-001">
<InternalInfo>
<xr:ContainedObject>
<xr:ClassId>UUID-002</xr:ClassId>
<xr:ObjectId>UUID-003</xr:ObjectId>
</xr:ContainedObject>
<xr:ContainedObject>
<xr:ClassId>UUID-004</xr:ClassId>
<xr:ObjectId>UUID-005</xr:ObjectId>
</xr:ContainedObject>
<xr:ContainedObject>
<xr:ClassId>UUID-006</xr:ClassId>
<xr:ObjectId>UUID-007</xr:ObjectId>
</xr:ContainedObject>
<xr:ContainedObject>
<xr:ClassId>UUID-008</xr:ClassId>
<xr:ObjectId>UUID-009</xr:ObjectId>
</xr:ContainedObject>
<xr:ContainedObject>
<xr:ClassId>UUID-010</xr:ClassId>
<xr:ObjectId>UUID-011</xr:ObjectId>
</xr:ContainedObject>
<xr:ContainedObject>
<xr:ClassId>UUID-012</xr:ClassId>
<xr:ObjectId>UUID-013</xr:ObjectId>
</xr:ContainedObject>
<xr:ContainedObject>
<xr:ClassId>UUID-014</xr:ClassId>
<xr:ObjectId>UUID-015</xr:ObjectId>
</xr:ContainedObject>
</InternalInfo>
<Properties>
<Name>TestConfig</Name>
<Synonym>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>TestConfig</v8:content>
</v8:item>
</Synonym>
<Comment />
<NamePrefix />
<ConfigurationExtensionCompatibilityMode>Version8_3_24</ConfigurationExtensionCompatibilityMode>
<DefaultRunMode>ManagedApplication</DefaultRunMode>
<UsePurposes>
<v8:Value xsi:type="app:ApplicationUsePurpose">PlatformApplication</v8:Value>
</UsePurposes>
<ScriptVariant>Russian</ScriptVariant>
<DefaultRoles />
<Vendor></Vendor>
<Version></Version>
<UpdateCatalogAddress />
<IncludeHelpInContents>false</IncludeHelpInContents>
<UseManagedFormInOrdinaryApplication>false</UseManagedFormInOrdinaryApplication>
<UseOrdinaryFormInManagedApplication>false</UseOrdinaryFormInManagedApplication>
<AdditionalFullTextSearchDictionaries />
<CommonSettingsStorage />
<ReportsUserSettingsStorage />
<ReportsVariantsStorage />
<FormDataSettingsStorage />
<DynamicListsUserSettingsStorage />
<URLExternalDataStorage />
<Content />
<DefaultReportForm />
<DefaultReportVariantForm />
<DefaultReportSettingsForm />
<DefaultReportAppearanceTemplate />
<DefaultDynamicListSettingsForm />
<DefaultSearchForm />
<DefaultDataHistoryChangeHistoryForm />
<DefaultDataHistoryVersionDataForm />
<DefaultDataHistoryVersionDifferencesForm />
<DefaultCollaborationSystemUsersChoiceForm />
<RequiredMobileApplicationPermissions />
<UsedMobileApplicationFunctionalities>
<app:functionality>
<app:functionality>Biometrics</app:functionality>
<app:use>true</app:use>
</app:functionality>
<app:functionality>
<app:functionality>Location</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>BackgroundLocation</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>BluetoothPrinters</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>WiFiPrinters</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>Contacts</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>Calendars</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>PushNotifications</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>LocalNotifications</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>InAppPurchases</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>PersonalComputerFileExchange</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>Ads</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>NumberDialing</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>CallProcessing</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>CallLog</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>AutoSendSMS</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>ReceiveSMS</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>SMSLog</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>Camera</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>Microphone</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>MusicLibrary</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>PictureAndVideoLibraries</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>AudioPlaybackAndVibration</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>BackgroundAudioPlaybackAndVibration</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>InstallPackages</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>OSBackup</app:functionality>
<app:use>true</app:use>
</app:functionality>
<app:functionality>
<app:functionality>ApplicationUsageStatistics</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>BarcodeScanning</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>BackgroundAudioRecording</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>AllFilesAccess</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>Videoconferences</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>NFC</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>DocumentScanning</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>SpeechToText</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>Geofences</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>IncomingShareRequests</app:functionality>
<app:use>false</app:use>
</app:functionality>
<app:functionality>
<app:functionality>AllIncomingShareRequestsTypesProcessing</app:functionality>
<app:use>false</app:use>
</app:functionality>
</UsedMobileApplicationFunctionalities>
<StandaloneConfigurationRestrictionRoles />
<MobileApplicationURLs />
<AllowedIncomingShareRequestTypes />
<MainClientApplicationWindowMode>Normal</MainClientApplicationWindowMode>
<DefaultInterface />
<DefaultStyle />
<DefaultLanguage>Language.Русский</DefaultLanguage>
<BriefInformation />
<DetailedInformation />
<Copyright />
<VendorInformationAddress />
<ConfigurationInformationAddress />
<DataLockControlMode>Managed</DataLockControlMode>
<ObjectAutonumerationMode>NotAutoFree</ObjectAutonumerationMode>
<ModalityUseMode>DontUse</ModalityUseMode>
<SynchronousPlatformExtensionAndAddInCallUseMode>DontUse</SynchronousPlatformExtensionAndAddInCallUseMode>
<InterfaceCompatibilityMode>TaxiEnableVersion8_2</InterfaceCompatibilityMode>
<DatabaseTablespacesUseMode>DontUse</DatabaseTablespacesUseMode>
<CompatibilityMode>Version8_3_24</CompatibilityMode>
<DefaultConstantsForm />
</Properties>
<ChildObjects>
<Language>Русский</Language>
<Catalog>Контрагенты</Catalog>
</ChildObjects>
</Configuration>
</MetaDataObject>
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<ClientApplicationInterface xmlns="http://v8.1c.ru/8.2/managed-application/core" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="InterfaceLayouter">
<top>
<panel id="UUID-001">
<uuid>UUID-002</uuid>
</panel>
</top>
<left>
<panel id="UUID-003">
<uuid>UUID-004</uuid>
</panel>
</left>
<panelDef id="UUID-004"/>
<panelDef id="UUID-005"/>
<panelDef id="UUID-006"/>
<panelDef id="UUID-002"/>
<panelDef id="UUID-007"/>
</ClientApplicationInterface>
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<MetaDataObject xmlns="http://v8.1c.ru/8.3/MDClasses" xmlns:app="http://v8.1c.ru/8.2/managed-application/core" xmlns:cfg="http://v8.1c.ru/8.1/data/enterprise/current-config" xmlns:cmi="http://v8.1c.ru/8.2/managed-application/cmi" xmlns:ent="http://v8.1c.ru/8.1/data/enterprise" xmlns:lf="http://v8.1c.ru/8.2/managed-application/logform" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows" xmlns:xen="http://v8.1c.ru/8.3/xcf/enums" xmlns:xpr="http://v8.1c.ru/8.3/xcf/predef" xmlns:xr="http://v8.1c.ru/8.3/xcf/readable" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.17">
<Language uuid="UUID-001">
<Properties>
<Name>Русский</Name>
<Synonym>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Русский</v8:content>
</v8:item>
</Synonym>
<Comment/>
<LanguageCode>ru</LanguageCode>
</Properties>
</Language>
</MetaDataObject>