diff --git a/DebugVarEdit.exe b/DebugVarEdit.exe
index a6ad9fc..ce7ce4d 100644
Binary files a/DebugVarEdit.exe and b/DebugVarEdit.exe differ
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..38c8444
--- /dev/null
+++ b/README.md
@@ -0,0 +1,136 @@
+# DebugVarEdit — Утилита для генерации отладочных переменных C-проекта
+
+**DebugVarEdit** — графическое приложение для Windows, предназначенное для настройки и генерации отладочных переменных (`debug_vars.c`) на основе исходного C-проекта. Работает с `makefile` проекта, сохраняет изменения в XML и позволяет удобно редактировать переменные и их типы через интерфейс.
+
+Программа — один исполняемый файл `DebugVarEdit.exe`, не требующий установки и дополнительных зависимостей.
+
+> Требуется Windows 7 или новее.
+---
+
+## Как использовать
+
+1. Запустите **DebugVarEdit.exe.**
+
+2. Укажите пути:
+ - **Путь к XML** — новый или существующий файл настроек переменных;
+ - **Путь к проекту** — путь к корню проека (папка, которая является корнем для проекта в Code Composer);
+ - **Путь к makefile** — путь к `makefile` относительно корня проекта;
+ - **Путь для debug_vars.c** — папка, куда будет сгенерирован файл `debug_vars.c` с переменными.
+
+3. Нажмите **Сканировать переменные**:
+ - Программа проанализирует исходники, указанные в makefile, и найдёт все переменные.
+ - Результат сохранится в двух XML-файлах:
+ - `structs.xml` — информация обо всех структурах и typedef;
+ - `<ваш_файл>.xml` — список всех найденных переменных.
+
+4. Нажмите **Добавить переменные**:
+ - В **левой таблице** отображаются все найденные переменные.
+ Для добавления переменной в проект дважды кликните по ней или нажмите кнопку `>`, чтобы переместить в правую таблицу.
+ - В **правой таблице** находятся переменные, выбранные для использования.
+ Чтобы убрать переменную из проекта, переместите её обратно в левую таблицу двойным кликом или кнопкой `<`.
+ - После выбора переменных нажмите **Применить**, чтобы обновить основной список переменных и включить их в проект.
+
+5. Настройте параметры выбранных переменных:
+ - **En** — включение или отключение переменной для генерации;
+ - **Base Type** — базовый тип переменной (например, int8, uint16 и т.д.);
+ - **IQ Type** — формат IQ, если применимо;
+ - **Return Type** — формат возвращаемого значения (IQ-тип или целочисленный);
+ - **Shortname** — короткое имя переменной для для терминалки.
+
+ Все параметры выбираются из выпадающих списков, которые можно настроить, чтобы отображались только нужные опции.
+
+6. Нажмите **Сгенерировать файл** для создания файла `debug_vars.c` с выбранными переменными.
+---
+
+## Возможности
+
+- Загрузка и сохранение настроек переменных в XML-файлах.
+- Автоматическое определение исходных файлов с переменными для удобства работы.
+- Редактирование переменных: включение, короткого имени и типов через удобные списки.
+- Подсветка ошибок при вводе (неправильные имена, слишком длинные короткие имена).
+- Быстрая фильтрация переменных по столбцам.
+- Автоматическая генерация файла debug_vars.c с выбранными переменными.
+- Возможность сразу открыть сгенерированный файл в редакторе.
+- Умное автодополнение имён переменных и полей структур.
+
+
+---
+
+## Пример XML-файла
+
+```xml
+
+
+
+ true
+ true
+ myv
+ pt_float
+ t_iq24
+ t_iq24
+ float
+ Src/main/main.c
+ true
+ false
+
+
+
+```
+
+---
+
+# Для разработчиков
+
+### Структура проекта:
+
+```bash
+Src
+├── DebugVarEdit_GUI.py # Главное окно
+├── VariableTable.py # Таблица выбранных переменных
+├── VariableSelector.py # Окно выбора переменных
+├── selectTable.py # Таблица переменных в окне выбора переменных
+├── scanVarGUI.py # Отображение процесса сканирования переменных
+├── scanVar.py # Сканирование переменных среди .c/.h файлов
+├── generateVars.py # Генерация debug_vars.c
+├── myXML.py # Утилиты для XML
+├── parseMakefile.py # Парсинг makefile на .c/.h файлы
+├── setupVars.py # Подготовка переменных для окна выбора переменных
+├── libclang.dll # Бибилиотека clang
+├── icon.ico # Иконка
+build
+├── build_and_clean.py # Билдинг проекта в .exe (через nuitka или pyinstaller)
+```
+
+### Зависимости
+
+Для запуска приложения:
+- **Python 3.7+**
+- **clang** — используется для парсинга C-кода (требуется `libclang.dll`)
+- **PySide2** — GUI-фреймворк
+- **lxml** — работа с XML
+> Python 3.7 и PySide2 рекомендуется для совместимости с Windows 7
+
+Для сборки `.exe`:
+- **Nuitka** — создает полностью автономный `.exe` без внешних зависимостей
+- **PyInstaller** — создает `.exe` с зависимостью от `pythonXX.dll` (Python должен быть установлен)
+
+
+### Сборка:
+Если вы хотите собрать `DebugVarEdit.exe` самостоятельно из исходников, используйте скрипт **build/build_and_clean.py**. Он автоматически собирает проект с помощью Nuitka или PyInstaller:
+- Собирает проект в `DebugVarEdit.exe` в корневой папке.
+- Включает:
+ - все необходимые `.dll` (например, `libclang.dll`),
+ - иконку (`icon.ico`),
+ - плагины PySide2.
+- Очищает временные папки после сборки:
+ - `build_temp`
+ - `__pycache__`
+ - `DebugVarEdit_GUI.*`
+
+> Все пути, имена файлов, временные папки и выбор между Nuitka и PyInstaller можно настроить в начале файла `build_and_clean.py`.
+
+### Установка зависимостей
+
+```bash
+pip install PySide2 lxml nuitka pyinstaller
+```
\ No newline at end of file
diff --git a/Src/DebugVarEdit_GUI.py b/Src/DebugVarEdit_GUI.py
index 2e62963..cfae260 100644
--- a/Src/DebugVarEdit_GUI.py
+++ b/Src/DebugVarEdit_GUI.py
@@ -4,7 +4,7 @@
import sys
import os
import subprocess
-import xml.etree.ElementTree as ET
+import lxml.etree as ET
from generateVars import type_map
from enum import IntEnum
import threading
@@ -31,12 +31,18 @@ var_edit_title = "Редактор переменных для отладки"
xml_path_title = "Путь к XML:"
proj_path_title = "Путь к проекту:"
makefile_path_title = "Пусть к makefile (относительно проекта)"
-output_path_title = "Папка для debug_vars.c:"
+output_path_title = "Путь для для debug_vars.c:"
scan_title = "Сканировать переменные"
build_title = "Сгенерировать файл"
add_vars_title = "Добавить переменные"
open_output_title = "Открыть файл"
+def set_sub_elem_text(parent, tag, text):
+ el = parent.find(tag)
+ if el is None:
+ el = ET.SubElement(parent, tag)
+ el.text = str(text)
+
# 3. UI: таблица с переменными
class VarEditor(QWidget):
def __init__(self):
@@ -242,8 +248,8 @@ class VarEditor(QWidget):
QMessageBox.critical(self, "Ошибка при генерации", str(e))
- def update(self):
- if self._updating:
+ def update(self, force=0):
+ if self._updating and (force==0):
return # Уже в процессе обновления — выходим, чтобы избежать рекурсии
self._updating = True
@@ -407,8 +413,7 @@ class VarEditor(QWidget):
return
try:
- self.update_all_paths()
- self.update()
+ self.update(1)
except Exception as e:
self.makefile_path = None
@@ -443,10 +448,21 @@ class VarEditor(QWidget):
self.write_to_xml()
self.update()
-
def write_to_xml(self, dummy=None):
+ t0 = time.time()
self.update_all_paths()
-
+ def get_val(name, default=''):
+ return str(v_table[name] if v_table and name in v_table else v.get(name, default))
+
+ def element_differs(elem, values: dict):
+ for tag, new_val in values.items():
+ current_elem = elem.find(tag)
+ current_val = (current_elem.text or '').strip()
+ new_val_str = str(new_val or '').strip()
+ if current_val != new_val_str:
+ return True
+ return False
+
if not self.xml_path or not os.path.isfile(self.xml_path):
print("XML файл не найден или путь пустой")
return
@@ -470,7 +486,6 @@ class VarEditor(QWidget):
if self.makefile_path and os.path.isfile(self.makefile_path):
rel_makefile = myXML.make_relative_path(self.makefile_path, self.proj_path)
- root.set("makefile_path", rel_makefile)
# Если результат — абсолютный путь, не записываем
if not os.path.isabs(rel_makefile):
root.set("makefile_path", rel_makefile)
@@ -481,6 +496,7 @@ class VarEditor(QWidget):
if not os.path.isabs(rel_struct):
root.set("structs_path", rel_struct)
+ t1 = time.time()
vars_elem = root.find('variables')
if vars_elem is None:
@@ -495,6 +511,7 @@ class VarEditor(QWidget):
'extern': var_elem.findtext('extern', ''),
'static': var_elem.findtext('static', '')
}
+ var_elements_by_name = {ve.attrib.get('name'): ve for ve in vars_elem.findall('var')}
# Читаем переменные из таблицы (активные/изменённые)
table_vars = {v['name']: v for v in self.table.read_data()}
@@ -503,63 +520,73 @@ class VarEditor(QWidget):
# Объединённый список переменных для записи
all_names = list(all_vars_by_name.keys())
+ t2 = time.time()
for name in all_names:
v = all_vars_by_name[name]
v_table = table_vars.get(name)
var_elem = None
- # Ищем уже существующий в XML
- for ve in vars_elem.findall('var'):
- if ve.attrib.get('name') == name:
- var_elem = ve
- break
- if var_elem is None:
- var_elem = ET.SubElement(vars_elem, 'var', {'name': name})
-
- def set_sub_elem_text(parent, tag, text):
- el = parent.find(tag)
- if el is None:
- el = ET.SubElement(parent, tag)
- el.text = str(text)
-
- pt_type_val = v_table['pt_type'] if v_table and 'pt_type' in v_table else v.get('pt_type', '')
-
+ pt_type_val = get_val('pt_type').lower()
if 'arr' in pt_type_val or 'struct' in pt_type_val or 'union' in pt_type_val:
continue
show_var_val = str(v.get('show_var', 'false')).lower()
- enable_val = str(v_table['enable'] if v_table and 'enable' in v_table else v.get('enable', 'false')).lower()
-
- set_sub_elem_text(var_elem, 'show_var', show_var_val)
- set_sub_elem_text(var_elem, 'enable', enable_val)
+ enable_val = get_val('enable').lower()
# Тут подтягиваем из таблицы, если есть, иначе из v
- shortname_val = v_table['shortname'] if v_table and 'shortname' in v_table else v.get('shortname', '')
- iq_type_val = v_table['iq_type'] if v_table and 'iq_type' in v_table else v.get('iq_type', '')
- ret_type_val = v_table['return_type'] if v_table and 'return_type' in v_table else v.get('return_type', '')
+ shortname_val = get_val('shortname')
+ iq_type_val = get_val('iq_type')
+ ret_type_val = get_val('return_type')
- set_sub_elem_text(var_elem, 'shortname', shortname_val)
- set_sub_elem_text(var_elem, 'pt_type', pt_type_val)
- set_sub_elem_text(var_elem, 'iq_type', iq_type_val)
- set_sub_elem_text(var_elem, 'return_type', ret_type_val)
- set_sub_elem_text(var_elem, 'type', v.get('type', ''))
# file/extern/static: из original_info, либо из v
file_val = v.get('file') or original_info.get(name, {}).get('file', '')
extern_val = v.get('extern') or original_info.get(name, {}).get('extern', '')
static_val = v.get('static') or original_info.get(name, {}).get('static', '')
- set_sub_elem_text(var_elem, 'file', file_val)
- set_sub_elem_text(var_elem, 'extern', extern_val)
- set_sub_elem_text(var_elem, 'static', static_val)
+ values_to_write = {
+ 'show_var': show_var_val,
+ 'enable': enable_val,
+ 'shortname': shortname_val,
+ 'pt_type': pt_type_val,
+ 'iq_type': iq_type_val,
+ 'return_type': ret_type_val,
+ 'type': v.get('type', ''),
+ 'file': file_val,
+ 'extern': extern_val,
+ 'static': static_val
+ }
+ # Ищем уже существующий в XML
+ var_elem = var_elements_by_name.get(name)
+ # Если элемента нет, это новая переменная — сразу пишем
+ if var_elem is None:
+ var_elem = ET.SubElement(vars_elem, 'var', {'name': name})
+ var_elements_by_name[name] = var_elem
+ write_all = True # обязательно записать все поля
+ else:
+ write_all = element_differs(var_elem, values_to_write)
+
+ if not write_all:
+ continue # Пропускаем, если нет изменений
+
+ for tag, text in values_to_write.items():
+ set_sub_elem_text(var_elem, tag, text)
+
+ t3 = time.time()
# Преобразуем дерево в строку
- self.table.check()
myXML.fwrite(root, self.xml_path)
-
+ self.table.check()
+ t4 = time.time()
+ '''print(f"[T1] parse + set paths: {t1 - t0:.3f} сек")
+ print(f"[T2] prepare variables: {t2 - t1:.3f} сек")
+ print(f"[T3] loop + updates: {t3 - t2:.3f} сек")
+ print(f"[T4] write to file: {t4 - t3:.3f} сек")
+ print(f"[TOTAL] write_to_xml total: {t4 - t0:.3f} сек")'''
except Exception as e:
print(f"Ошибка при сохранении XML: {e}")
+
def __open_output_file_with_program(self):
output_path = self.get_output_path()
if not output_path:
diff --git a/Src/VariableSelector.py b/Src/VariableSelector.py
index 12f3be8..b6999c6 100644
--- a/Src/VariableSelector.py
+++ b/Src/VariableSelector.py
@@ -1,5 +1,5 @@
import re
-import xml.etree.ElementTree as ET
+import lxml.etree as ET
from PySide2.QtWidgets import (
QDialog, QTreeWidget, QTreeWidgetItem, QVBoxLayout, QPushButton,
QLineEdit, QLabel, QHeaderView, QCompleter, QCheckBox, QHBoxLayout, QSizePolicy
@@ -52,12 +52,15 @@ class VariableSelectorDialog(QDialog):
self.btn_left.clicked.connect(self.on_move_left)
# Создаем кнопки, они остаются в диалоге
- self.btn_add = QPushButton("Добавить выбранные")
- self.btn_delete = QPushButton("Удалить выбранные")
+ self.btn_accept = QPushButton("Применить")
# Создаем экземпляр вашего готового виджета
self.vars_widget = selectTable.VariableSelectWidget(self)
+ self.vars_widget.tree.itemDoubleClicked.connect(self.on_left_tree_double_click)
+ self.vars_widget.setObjectName("LeftTable")
self.selected_vars_widget = selectTable.VariableSelectWidget(self)
+ self.selected_vars_widget.tree.itemDoubleClicked.connect(self.on_rigth_tree_double_click)
+ self.selected_vars_widget.setObjectName("RightTable")
# --- Лэйауты ---
@@ -86,8 +89,7 @@ class VariableSelectorDialog(QDialog):
# Кнопки "Добавить выбранные" и "Удалить выбранные" под таблицами
buttons_layout = QVBoxLayout()
- buttons_layout.addWidget(self.btn_add)
- buttons_layout.addWidget(self.btn_delete)
+ buttons_layout.addWidget(self.btn_accept)
main_layout.addLayout(buttons_layout)
# Важно, если окно — QDialog или QWidget, установи layout
@@ -96,8 +98,7 @@ class VariableSelectorDialog(QDialog):
# Соединяем сигналы кнопок с методами диалога
- self.btn_add.clicked.connect(self.on_add_clicked)
- self.btn_delete.clicked.connect(self.on_delete_clicked)
+ self.btn_accept.clicked.connect(self.on_apply_clicked)
# Соединяем чекбокс с методом виджета
self.autocomplete_checkbox.stateChanged.connect(self.vars_widget.set_autocomplete)
@@ -119,6 +120,7 @@ class VariableSelectorDialog(QDialog):
for var in data:
if var['name'] in selected:
var['show_var'] = 'true'
+ var['enable'] = 'true'
if 'children' in var:
mark_selected_show_var(var['children'])
mark_selected_show_var(self.expanded_vars)
@@ -159,15 +161,15 @@ class VariableSelectorDialog(QDialog):
t5 = time.perf_counter()
self.selected_vars_widget.filter_tree()
-
- def on_add_clicked(self):
- # Получаем все переменные из правой таблицы (selected_vars_widget)
- var_names = self.selected_vars_widget.get_all_var_names()
+ def on_apply_clicked(self):
+ # Получаем имена всех переменных из правой таблицы (selected_vars_widget)
+ right_var_names = set(self.selected_vars_widget.get_all_var_names())
all_items = self.selected_vars_widget.get_all_items()
if not all_items:
return
- def add_to_var_map_recursively(item):
+ # Устанавливаем show_var=true и enable=true для переменных из правой таблицы
+ def add_or_update_var(item):
name = item.text(0)
type_str = item.text(1)
@@ -180,9 +182,15 @@ class VariableSelectorDialog(QDialog):
extern_val = item.data(0, Qt.UserRole + 2)
static_val = item.data(0, Qt.UserRole + 3)
new_var = {
- 'name': name, 'type': type_str, 'show_var': 'true',
- 'enable': 'true', 'shortname': name, 'pt_type': '', 'iq_type': '',
- 'return_type': 't_iq_none', 'file': file_val,
+ 'name': name,
+ 'type': type_str,
+ 'show_var': 'true',
+ 'enable': 'true',
+ 'shortname': name,
+ 'pt_type': '',
+ 'iq_type': '',
+ 'return_type': 't_iq_none',
+ 'file': file_val,
'extern': str(extern_val).lower() if extern_val else 'false',
'static': str(static_val).lower() if static_val else 'false',
}
@@ -190,71 +198,74 @@ class VariableSelectorDialog(QDialog):
self.var_map[name] = new_var
for item in all_items:
- add_to_var_map_recursively(item)
+ add_or_update_var(item)
- self.accept()
+ # Сбрасываем show_var и enable у всех переменных, которых нет в правой таблице
+ for var in self.all_vars:
+ if var['name'] not in right_var_names:
+ var['show_var'] = 'false'
+ var['enable'] = 'false'
+ # Обновляем expanded_vars чтобы отразить новые show_var и enable
+ def update_expanded_vars(data):
+ for v in data:
+ name = v['name']
+ if name in self.var_map:
+ v['show_var'] = self.var_map[name]['show_var']
+ v['enable'] = self.var_map[name]['enable']
+ if 'children' in v:
+ update_expanded_vars(v['children'])
+ update_expanded_vars(self.expanded_vars)
- def on_delete_clicked(self):
- # Получаем все элементы (QTreeWidgetItem) из правой таблицы
- all_items = self.selected_vars_widget.get_all_items()
- if not all_items:
- return
-
- affected_names = []
-
- def disable_var_recursively(item):
- name = item.text(0)
- if name in self.var_map:
- self.var_map[name]['show_var'] = 'false'
- self.var_map[name]['enable'] = 'false'
- affected_names.append(name)
-
- # Рекурсивно отключаем детей
- for i in range(item.childCount()):
- child = item.child(i)
- disable_var_recursively(child)
-
- for item in all_items:
- disable_var_recursively(item)
-
- # Обновляем XML и таблицу
- self.update_xml_vars(affected_names, 'false', 'false')
+ # Обновляем отображение в виджетах
self.update_vars_widget()
+ # Закрываем диалог
+ self.accept()
- def update_xml_vars(self, names, show, enable):
- """Обновляет флаги show_var и enable в XML файле, только если у переменной нет вложенных структур."""
- if not self.xml_path:
- return
- root, tree = myXML.safe_parse_xml(self.xml_path)
- if root is None:
- return
- vars_section = root.find('variables')
- if vars_section is None:
- return
-
- for var_elem in vars_section.findall('var'):
- if var_elem.attrib.get('name') in names:
- # Проверяем наличие вложенных структур или объединений
- has_nested_structs = any(
- var_elem.find(tag) is not None for tag in ('struct', 'union')
- )
- if not has_nested_structs:
- def set_text(tag, value):
- el = var_elem.find(tag)
- if el is None:
- el = ET.SubElement(var_elem, tag)
- el.text = value
- set_text('show_var', show)
- set_text('enable', enable)
-
- myXML.fwrite(root, self.xml_path)
def save_checkbox_state(self):
self.settings.setValue("autocomplete_enabled", self.autocomplete_checkbox.isChecked())
+
+
+
+ # Обнови on_left_tree_double_click:
+ def on_left_tree_double_click(self, item, column):
+ selected_names = [item.text(0)]
+ if not selected_names:
+ return
+
+ def mark_selected_show_var(data):
+ for var in data:
+ if var['name'] in selected_names:
+ var['show_var'] = 'true'
+ var['enable'] = 'true'
+ if 'children' in var:
+ mark_selected_show_var(var['children'])
+ mark_selected_show_var(self.expanded_vars)
+
+ self.update_vars_widget()
+
+ # Добавь обработчик двойного клика справа (если нужно):
+ def on_rigth_tree_double_click(self, item, column):
+ selected_names = [item.text(0)]
+ if not selected_names:
+ return
+
+ def mark_selected_hide_var(data):
+ for var in data:
+ if var['name'] in selected_names:
+ var['show_var'] = 'false'
+ if 'children' in var:
+ mark_selected_hide_var(var['children'])
+ mark_selected_hide_var(self.expanded_vars)
+
+ self.update_vars_widget()
+
+
+
def keyPressEvent(self, event):
if event.key() == Qt.Key_Delete:
self.delete_selected_vars()
@@ -314,7 +325,6 @@ class VariableSelectorDialog(QDialog):
QMessageBox.warning(self, "Ошибка", "Путь к XML не задан, невозможно удалить переменные.")
return
- import xml.etree.ElementTree as ET
root, tree = myXML.safe_parse_xml(self.xml_path)
if root is None:
return
diff --git a/Src/VariableTable.py b/Src/VariableTable.py
index e22ce9e..7680083 100644
--- a/Src/VariableTable.py
+++ b/Src/VariableTable.py
@@ -1,11 +1,14 @@
from PySide2.QtWidgets import (
QTableWidget, QTableWidgetItem, QCheckBox, QComboBox, QLineEdit, QCompleter,
- QAbstractItemView, QHeaderView, QLabel
+ QAbstractItemView, QHeaderView, QLabel,
+ QDialog, QVBoxLayout, QHBoxLayout, QPushButton, QScrollArea, QWidget
)
from PySide2.QtGui import QColor, QBrush, QPalette
from PySide2.QtCore import Qt
from enum import IntEnum
from generateVars import type_map
+import time
+from typing import Dict, List
class rows(IntEnum):
No = 0
@@ -17,6 +20,46 @@ class rows(IntEnum):
ret_type = 6
short_name = 7
+class FilterDialog(QDialog):
+ def __init__(self, parent, options, selected, title="Выберите значения"):
+ super().__init__(parent)
+ self.setWindowTitle(title)
+ self.resize(250, 300)
+ self.selected = set(selected)
+
+ layout = QVBoxLayout(self)
+
+ scroll = QScrollArea(self)
+ scroll.setWidgetResizable(True)
+ container = QWidget()
+ scroll.setWidget(container)
+
+ self.checkboxes = []
+ vbox = QVBoxLayout(container)
+
+ for opt in options:
+ cb = QCheckBox(opt)
+ cb.setChecked(opt in self.selected)
+ vbox.addWidget(cb)
+ self.checkboxes.append(cb)
+
+ layout.addWidget(scroll)
+
+ btn_layout = QHBoxLayout()
+ btn_ok = QPushButton("OK")
+ btn_cancel = QPushButton("Отмена")
+ btn_layout.addWidget(btn_ok)
+ btn_layout.addWidget(btn_cancel)
+
+ layout.addLayout(btn_layout)
+
+ btn_ok.clicked.connect(self.accept)
+ btn_cancel.clicked.connect(self.reject)
+
+ def get_selected(self):
+ return [cb.text() for cb in self.checkboxes if cb.isChecked()]
+
+
class VariableTableWidget(QTableWidget):
def __init__(self, parent=None):
@@ -27,7 +70,7 @@ class VariableTableWidget(QTableWidget):
'En',
'Name',
'Origin Type',
- 'Pointer Type',
+ 'Base Type',
'IQ Type',
'Return Type',
'Short Name'
@@ -36,9 +79,18 @@ class VariableTableWidget(QTableWidget):
self.var_list = []
self.type_options = list(dict.fromkeys(type_map.values()))
- self.display_type_options = [t.replace('pt_', '') for t in self.type_options]
- self.iq_types = ['iq_none', 'iq'] + [f'iq{i}' for i in range(1, 31)]
+ self.pt_types_all = [t.replace('pt_', '') for t in self.type_options]
+ self.iq_types_all = ['iq_none', 'iq'] + [f'iq{i}' for i in range(1, 31)]
+ # Задаём базовые iq-типы (без префикса 'iq_')
+ self.iq_types = ['iq_none', 'iq24', 'iq19', 'iq15', 'iq10']
+ # Фильтруем типы из type_map.values() исключая те, что содержат 'arr' или 'ptr'
+ self.type_options = [t for t in set(type_map.values()) if 'arr' not in t and 'ptr' not in t]
+ # Формируем display_type_options без префикса 'pt_'
+ self.pt_types = [t.replace('pt_', '') for t in self.type_options]
+ self._iq_type_filter = list(self.iq_types) # Текущий фильтр iq типов (по умолчанию все)
+ self._pt_type_filter = list(self.pt_types)
+ self._ret_type_filter = list(self.iq_types)
header = self.horizontalHeader()
# Для остальных колонок — растяжение (Stretch), чтобы они заняли всю оставшуюся ширину
@@ -60,12 +112,13 @@ class VariableTableWidget(QTableWidget):
self.setColumnWidth(rows.type, 100)
self._resizing = False
self.horizontalHeader().sectionResized.connect(self.on_section_resized)
+ self.horizontalHeader().sectionClicked.connect(self.on_header_clicked)
def populate(self, vars_list, structs, on_change_callback):
self.var_list = vars_list
self.type_options = list(dict.fromkeys(type_map.values()))
- self.display_type_options = [t.replace('pt_', '') for t in self.type_options]
+ self.pt_types = [t.replace('pt_', '') for t in self.type_options]
iq_types = ['iq_none', 'iq'] + [f'iq{i}' for i in range(1, 31)]
# --- ДО: удаляем отображение структур и union-переменных
@@ -116,9 +169,9 @@ class VariableTableWidget(QTableWidget):
# pt_type
pt_combo = QComboBox()
- pt_combo.addItems(self.display_type_options)
+ pt_combo.addItems(self.pt_types)
value = var['pt_type'].replace('pt_', '')
- if value not in self.display_type_options:
+ if value not in self.pt_types:
pt_combo.addItem(value)
pt_combo.setCurrentText(value)
pt_combo.currentTextChanged.connect(on_change_callback)
@@ -135,14 +188,17 @@ class VariableTableWidget(QTableWidget):
iq_combo.setCurrentText(value)
iq_combo.currentTextChanged.connect(on_change_callback)
iq_combo.setStyleSheet(style_with_padding)
+ iq_combo.wheelEvent = lambda e: e.ignore()
self.setCellWidget(row, rows.iq_type, iq_combo)
# return_type
ret_combo = QComboBox()
ret_combo.addItems(self.iq_types)
- ret_combo.setCurrentText(var.get('return_type', ''))
+ value = var['return_type'].replace('t_', '')
+ ret_combo.setCurrentText(value)
ret_combo.currentTextChanged.connect(on_change_callback)
ret_combo.setStyleSheet(style_with_padding)
+ ret_combo.wheelEvent = lambda e: e.ignore()
self.setCellWidget(row, rows.ret_type, ret_combo)
# short_name
@@ -155,25 +211,28 @@ class VariableTableWidget(QTableWidget):
self.check()
def check(self):
- warning_color = (QColor("#FFFACD")) # Жёлтый для длинных shortname
- error_color = (QColor("#FFB6C1")) # Светло-красный для отсутствующих переменных
+ warning_color = QColor("#FFFACD")
+ error_color = QColor("#FFB6C1")
tooltip_shortname = "Short Name длиннее 10 символов — будет обрезано при генерации"
- tooltip_missing = f'Имя переменной не найдено среди переменных. Добавьте её через кнопку "Добавить переменные"'
+ tooltip_missing = 'Имя переменной не найдено среди переменных. Добавьте её через кнопку "Добавить переменные"'
+ var_names_set = {v.get('name') for v in self.var_list if v.get('name')}
+
+ t0 = time.time()
+ self.setUpdatesEnabled(False)
for row in range(self.rowCount()):
- # Получаем имя переменной (столбец `name`)
+ t1 = time.time()
name_widget = self.cellWidget(row, rows.name)
+ t2 = time.time()
name = name_widget.text() if name_widget else ""
- # Получаем shortname
short_name_edit = self.cellWidget(row, rows.short_name)
+ t3 = time.time()
shortname = short_name_edit.text() if short_name_edit else ""
- # Флаги ошибок
long_shortname = len(shortname) > 10
- found = any(v.get('name') == name for v in self.var_list)
-
- # Выбираем цвет и подсказку
+ found = name in var_names_set
+
color = None
tooltip = ""
if not found:
@@ -184,6 +243,10 @@ class VariableTableWidget(QTableWidget):
tooltip = tooltip_shortname
self.highlight_row(row, color, tooltip)
+ t4 = time.time()
+
+ self.setUpdatesEnabled(True)
+ #print(f"Row {row}: cellWidget(name) {t2-t1:.4f}s, cellWidget(shortname) {t3-t2:.4f}s, highlight_row {t4-t3:.4f}s")
def read_data(self):
@@ -209,6 +272,52 @@ class VariableTableWidget(QTableWidget):
})
return result
+
+
+ def on_header_clicked(self, logicalIndex):
+ if logicalIndex == rows.pt_type:
+ dlg = FilterDialog(self, self.pt_types_all, self._pt_type_filter, "Выберите Pointer Types")
+ if dlg.exec_():
+ self._pt_type_filter = dlg.get_selected()
+ self.update_comboboxes({rows.pt_type: self._pt_type_filter})
+
+ elif logicalIndex == rows.iq_type:
+ dlg = FilterDialog(self, self.iq_types_all, self._iq_type_filter, "Выберите IQ типы")
+ if dlg.exec_():
+ self._iq_type_filter = dlg.get_selected()
+ self.update_comboboxes({rows.iq_type: self._iq_type_filter})
+
+ elif logicalIndex == rows.ret_type:
+ dlg = FilterDialog(self, self.iq_types_all, self._ret_type_filter, "Выберите IQ типы")
+ if dlg.exec_():
+ self._ret_type_filter = dlg.get_selected()
+ self.update_comboboxes({rows.ret_type: self._ret_type_filter})
+
+
+
+ def update_comboboxes(self, columns_filters: Dict[int, List[str]]):
+ """
+ Обновляет combobox-ячейки в указанных столбцах таблицы.
+
+ :param columns_filters: dict, где ключ — индекс столбца,
+ значение — список допустимых вариантов для combobox.
+ """
+ for row in range(self.rowCount()):
+ for col, allowed_items in columns_filters.items():
+ combo = self.cellWidget(row, col)
+ if combo:
+ current = combo.currentText()
+ combo.blockSignals(True)
+ combo.clear()
+ combo.addItems(allowed_items)
+ if current in allowed_items:
+ combo.setCurrentText(current)
+ else:
+ combo.setCurrentIndex(0)
+ combo.blockSignals(False)
+
+
+
def on_section_resized(self, logicalIndex, oldSize, newSize):
if self._resizing:
return # предотвращаем рекурсию
@@ -256,20 +365,22 @@ class VariableTableWidget(QTableWidget):
item = self.item(row, col)
widget = self.cellWidget(row, col)
- # Подсветка обычной item-ячейки (например, тип переменной)
if item is not None:
- if color:
+ current_bg = item.background().color() if item.background() else None
+ if color and current_bg != color:
item.setBackground(QBrush(color))
item.setToolTip(tooltip)
- else:
+ elif not color and current_bg is not None:
item.setBackground(QBrush(Qt.NoBrush))
item.setToolTip("")
-
- # Подсветка виджетов — здесь главная доработка
elif widget is not None:
- # Надёжная подсветка: через styleSheet
- widget.setStyleSheet(css_color)
- widget.setToolTip(tooltip if color else "")
+ if widget.styleSheet() != css_color:
+ widget.setStyleSheet(css_color)
+ current_tip = widget.toolTip()
+ if color and current_tip != tooltip:
+ widget.setToolTip(tooltip)
+ elif not color and current_tip:
+ widget.setToolTip("")
def get_selected_var_names(self):
selected_indexes = self.selectedIndexes()
diff --git a/Src/generateVars.py b/Src/generateVars.py
index 65393d3..f06a774 100644
--- a/Src/generateVars.py
+++ b/Src/generateVars.py
@@ -6,7 +6,7 @@
import sys
import os
import re
-import xml.etree.ElementTree as ET
+import lxml.etree as ET
from pathlib import Path
from xml.dom import minidom
import myXML
diff --git a/Src/myXML.py b/Src/myXML.py
index 7ce0c85..d35faba 100644
--- a/Src/myXML.py
+++ b/Src/myXML.py
@@ -1,5 +1,5 @@
import os
-import xml.etree.ElementTree as ET
+from lxml import etree
def make_absolute_path(path, base_path):
if not os.path.isabs(path) and os.path.isdir(base_path):
@@ -33,44 +33,38 @@ def make_relative_path(abs_path, base_path):
return abs_path.replace("\\", "/")
def indent_xml(elem, level=0):
- indent = " "
- i = "\n" + level * indent
+ # Убираем strip() — они медленные, и текст мы всё равно перезаписываем
+ i = "\n" + level * " "
if len(elem):
- if not elem.text or not elem.text.strip():
- elem.text = i + indent
+ elem.text = elem.text or i + " "
for child in elem:
indent_xml(child, level + 1)
- if not elem.tail or not elem.tail.strip():
- elem.tail = i
+ elem[-1].tail = elem[-1].tail or i
else:
- if level and (not elem.tail or not elem.tail.strip()):
- elem.tail = i
+ elem.tail = elem.tail or i
def fwrite(root, xml_full_path):
- indent_xml(root)
- ET.ElementTree(root).write(xml_full_path, encoding="utf-8", xml_declaration=True)
+ #indent_xml(root)
+ #ET.ElementTree(root).write(xml_full_path, encoding="utf-8", xml_declaration=True)
+ rough_string = etree.tostring(root, encoding="utf-8")
+ parsed = etree.fromstring(rough_string)
+ with open(xml_full_path, "wb") as f:
+ f.write(etree.tostring(parsed, pretty_print=True, encoding="utf-8", xml_declaration=True))
-def safe_parse_xml(xml_path):
- """
- Безопасно парсит XML-файл.
- Возвращает кортеж (root, tree) или (None, None) при ошибках.
- """
+def safe_parse_xml(xml_path):
if not xml_path or not os.path.isfile(xml_path):
print(f"Файл '{xml_path}' не найден или путь пустой")
return None, None
-
try:
if os.path.getsize(xml_path) == 0:
return None, None
-
- tree = ET.parse(xml_path)
+ tree = etree.parse(xml_path)
root = tree.getroot()
return root, tree
-
- except ET.ParseError as e:
+ except etree .XMLSyntaxError as e:
print(f"Ошибка парсинга XML файла '{xml_path}': {e}")
return None, None
except Exception as e:
diff --git a/Src/scanVars.py b/Src/scanVars.py
index 05f4646..a8270ea 100644
--- a/Src/scanVars.py
+++ b/Src/scanVars.py
@@ -9,7 +9,7 @@ import re
import clang.cindex
from clang import cindex
from clang.cindex import Config
-import xml.etree.ElementTree as ET
+import lxml.etree as ET
from xml.dom import minidom
from parseMakefile import parse_makefile
from collections import deque
@@ -545,7 +545,7 @@ def read_vars_from_xml(xml_path):
'shortname': var_elem.findtext('shortname', name),
'pt_type': var_elem.findtext('pt_type', ''),
'iq_type': var_elem.findtext('iq_type', ''),
- 'return_type': var_elem.findtext('return_type', 'pt_iq_none'),
+ 'return_type': var_elem.findtext('return_type', 't_iq_none'),
'type': var_elem.findtext('type', 'unknown'),
'file': var_elem.findtext('file', ''),
'extern': get_bool('extern'),
@@ -608,7 +608,7 @@ def generate_xml_output(proj_path, xml_path, unique_vars, h_files_needed, vars_n
'shortname': info.get('shortname', name),
'pt_type': info.get('pt_type', ''),
'iq_type': info.get('iq_type', ''),
- 'return_type': info.get('return_type', 'pt_iq_none'),
+ 'return_type': info.get('return_type', 't_iq_none'),
'type': info.get('type', 'unknown'),
'file': info.get('file', ''),
'extern': info.get('extern', False),
@@ -627,7 +627,7 @@ def generate_xml_output(proj_path, xml_path, unique_vars, h_files_needed, vars_n
ET.SubElement(var_elem, "shortname").text = info.get('shortname', name)
ET.SubElement(var_elem, "pt_type").text = info.get('pt_type', '')
ET.SubElement(var_elem, "iq_type").text = info.get('iq_type', '')
- ET.SubElement(var_elem, "return_type").text = info.get('return_type', 'pt_iq_none')
+ ET.SubElement(var_elem, "return_type").text = info.get('return_type', 't_iq_none')
ET.SubElement(var_elem, "type").text = info.get('type', 'unknown')
rel_file = make_relative_if_possible(info.get('file', ''), proj_path).replace("\\", "/")
diff --git a/Src/selectTable.py b/Src/selectTable.py
index dde4266..e0d9456 100644
--- a/Src/selectTable.py
+++ b/Src/selectTable.py
@@ -63,82 +63,8 @@ def split_path(path):
return tokens
-# Функция парсит имя с индексами в (базовое_имя, список_индексов)
-def parse_name_with_indices(name):
- # Регулярка для имени и индексов:
- # имя - подряд букв/цифр/подчёркиваний,
- # индексы в квадратных скобках
- base_match = re.match(r'^([a-zA-Z_]\w*)', name)
- if not base_match:
- return name, [] # если не совпало, возвращаем как есть
-
- base_name = base_match.group(1)
- indices = re.findall(r'\[(\d+)\]', name)
- indices = list(map(int, indices))
- return base_name, indices
-
-def match_path_part(search_part, node_part):
- # Если часть — индекс (вида [N]), требуем точное совпадение
- if search_part.startswith('[') and search_part.endswith(']'):
- return search_part == node_part
-
- # Если search_part содержит '[', значит поиск неполный индекс
- if '[' in search_part:
- return node_part.startswith(search_part)
-
- # Иначе — обычное имя: допускаем совпадение по префиксу
- return node_part.startswith(search_part)
-
-
-
-def show_matching_path(item, path_parts, level=0):
- node_name = item.text(0).lower()
- node_parts = split_path(node_name)
-
- if 'project' in node_name:
- a = 1
-
- if level >= len(path_parts):
- # Путь полностью пройден — показываем только этот узел (без раскрытия всех детей)
- item.setHidden(False)
- item.setExpanded(False)
- return True
-
- if level >= len(node_parts):
- # Уровень поиска больше длины пути узла — скрываем
- item.setHidden(False)
-
- search_part = path_parts[level]
- node_part = node_parts[level]
-
- if search_part == node_part:
- # Точное совпадение — показываем узел, идём вглубь только по совпадениям
- item.setHidden(False)
- matched_any = False
- for i in range(item.childCount()):
- child = item.child(i)
- if show_matching_path(child, path_parts, level + 1):
- matched_any = True
- item.setExpanded(matched_any)
- return matched_any or item.childCount() == 0
-
- elif node_part.startswith(search_part):
- # Неполное совпадение — показываем только этот узел, детей скрываем, не раскрываем
- item.setHidden(False)
- item.setExpanded(False)
- return True
-
- elif search_part in node_part and (level == len(path_parts)-1):
- # Неполное совпадение — показываем только этот узел, детей скрываем, не раскрываем
- item.setHidden(False)
- item.setExpanded(False)
- return True
-
- else:
- # Несовпадение — скрываем
- item.setHidden(True)
- return False
-
+def is_lazy_item(item):
+ return item.childCount() == 1 and item.child(0).text(0) == 'lazy_marker'
class VariableSelectWidget(QWidget):
@@ -152,10 +78,10 @@ class VariableSelectWidget(QWidget):
self._vars_hash = None
# --- UI Элементы ---
- self.search_input = QLineEdit()
+ self.search_input = QLineEdit(self)
self.search_input.setPlaceholderText("Поиск...")
- self.tree = QTreeWidget()
+ self.tree = QTreeWidget(self)
self.tree.setHeaderLabels(["Имя переменной", "Тип"])
self.tree.setSelectionMode(QTreeWidget.ExtendedSelection)
self.tree.setRootIsDecorated(True)
@@ -166,7 +92,7 @@ class VariableSelectWidget(QWidget):
""")
self.tree.itemExpanded.connect(self.on_item_expanded)
- self.completer = QCompleter()
+ self.completer = QCompleter(self)
self.completer.setCompletionMode(QCompleter.PopupCompletion)
self.completer.setCaseSensitivity(Qt.CaseInsensitive)
self.completer.setFilterMode(Qt.MatchContains)
@@ -179,9 +105,10 @@ class VariableSelectWidget(QWidget):
layout.addWidget(self.tree)
# --- Соединения ---
- self.search_input.textChanged.connect(self.on_search_text_changed)
+ #self.search_input.textChanged.connect(self.on_search_text_changed)
+ self.search_input.textChanged.connect(lambda text: self.on_search_text_changed(text))
self.search_input.installEventFilter(self)
- self.completer.activated[str].connect(self.insert_completion)
+ self.completer.activated[str].connect(lambda text: self.insert_completion(text))
# --- Публичные методы для управления виджетом снаружи ---
@@ -221,7 +148,7 @@ class VariableSelectWidget(QWidget):
self.tree.setColumnWidth(0, 400)
def on_item_expanded(self, item):
- if self.is_lazy_item(item):
+ if is_lazy_item(item):
item.removeChild(item.child(0))
var = item.data(0, Qt.UserRole + 100)
if var:
@@ -265,9 +192,59 @@ class VariableSelectWidget(QWidget):
item.setData(0, Qt.UserRole + 100, var) # Сохраняем var целиком
+ def show_matching_path(self, item, path_parts, level=0):
+ node_name = item.text(0).lower()
+ node_parts = split_path(node_name)
+
+ if 'project' in node_name:
+ a = 1
+
+ if level >= len(path_parts):
+ # Путь полностью пройден — показываем только этот узел (без раскрытия всех детей)
+ item.setHidden(False)
+ item.setExpanded(False)
+ return True
+
+ if level >= len(node_parts):
+ # Уровень поиска больше длины пути узла — скрываем
+ item.setHidden(False)
+
+ search_part = path_parts[level]
+ node_part = node_parts[level]
+
+ if search_part == node_part:
+ # Точное совпадение — показываем узел, идём вглубь только по совпадениям
+ item.setHidden(False)
+ matched_any = False
+ self.on_item_expanded(item)
+ for i in range(item.childCount()):
+ child = item.child(i)
+ if self.show_matching_path(child, path_parts, level + 1):
+ matched_any = True
+ item.setExpanded(matched_any)
+ return matched_any or item.childCount() == 0
+
+ elif node_part.startswith(search_part):
+ # Неполное совпадение — показываем только этот узел, детей скрываем, не раскрываем
+ item.setHidden(False)
+ item.setExpanded(False)
+ return True
+
+ elif search_part in node_part and (level == len(path_parts)-1):
+ # Неполное совпадение — показываем только этот узел, детей скрываем, не раскрываем
+ item.setHidden(False)
+ item.setExpanded(False)
+ return True
+
+ else:
+ # Несовпадение — скрываем
+ item.setHidden(True)
+ return False
+
def filter_tree(self):
text = self.search_input.text().strip().lower()
+ print(f"[{self.objectName()}] Filtering tree with text: '{text}'")
path_parts = split_path(text) if text else []
if '.' not in text and '->' not in text and '[' not in text and text != '':
@@ -282,7 +259,7 @@ class VariableSelectWidget(QWidget):
else:
for i in range(self.tree.topLevelItemCount()):
item = self.tree.topLevelItem(i)
- show_matching_path(item, path_parts, 0)
+ self.show_matching_path(item, path_parts, 0)
@@ -381,6 +358,8 @@ class VariableSelectWidget(QWidget):
self.completer.setModel(QStringListModel(completions))
self.completer.complete()
+ print(f"[{self.objectName()}] Updating completions for text: '{text}' -> {len(completions)} completions found.")
+ print(f" Completions: {completions[:5]}") # Вывести первые 5 для проверки
return completions
@@ -487,7 +466,12 @@ class VariableSelectWidget(QWidget):
self.completer.complete()
return True
- def on_search_text_changed(self, text):
+ def on_search_text_changed(self, text):
+ sender_widget = self.sender()
+ sender_name = sender_widget.objectName() if sender_widget else "Unknown Sender"
+ print(f"[{self.objectName()}] (Sender: {sender_name}) Search text changed: '{text}'")
+
+ self.completer.setWidget(self.search_input)
self.filter_tree()
if text == None:
text = self.search_input.text().strip()
@@ -500,6 +484,18 @@ class VariableSelectWidget(QWidget):
else:
self.completer.popup().hide()
+ def focusInEvent(self, event):
+ if self.completer.widget() != self.search_input:
+ self.completer.setWidget(self.search_input)
+ super().focusInEvent(event)
+
+ def _custom_focus_in_event(self, event):
+ # Принудительно установить виджет для completer при получении фокуса
+ if self.completer.widget() != self.search_input:
+ self.completer.setWidget(self.search_input)
+ super(QLineEdit, self.search_input).focusInEvent(event) # Вызвать оригинальный обработчик
+
+
def build_completion_list(self):
completions = []
@@ -593,9 +589,6 @@ class VariableSelectWidget(QWidget):
leaf_items.append(item)
return leaf_items
- def is_lazy_item(self, item):
- return item.childCount() == 1 and item.child(0).text(0) == 'lazy_marker'
-
def get_all_var_names(self):
"""Возвращает имена всех конечных (leaf) переменных, исключая битовые поля и группы."""
@@ -611,3 +604,7 @@ class VariableSelectWidget(QWidget):
"""Возвращает имена только конечных (leaf) переменных из выделенных."""
return [item.text(0) for item in self.get_selected_items() if item.text(0)]
+ def closeEvent(self, event):
+ self.completer.setWidget(None)
+ self.completer.deleteLater()
+ super().closeEvent(event)
\ No newline at end of file
diff --git a/Src/setupVars.py b/Src/setupVars.py
index 6cff6ad..b830081 100644
--- a/Src/setupVars.py
+++ b/Src/setupVars.py
@@ -1,7 +1,7 @@
import sys
import os
import re
-import xml.etree.ElementTree as ET
+import lxml.etree as ET
from generateVars import map_type_to_pt, get_iq_define, type_map
from enum import IntEnum
import scanVars
@@ -138,7 +138,7 @@ def parse_vars(filename, typedef_map=None):
'shortname': var.findtext('shortname', name),
'pt_type': pt_type,
'iq_type': iq_type,
- 'return_type': var.findtext('return_type', ''),
+ 'return_type': var.findtext('return_type', 't_iq_none'),
'type': var_type,
'file': var.findtext('file', ''),
'extern': var.findtext('extern', 'false') == 'true',
diff --git a/build/build_and_clean.py b/build/build_and_clean.py
index 406e644..5c4c137 100644
--- a/build/build_and_clean.py
+++ b/build/build_and_clean.py
@@ -2,13 +2,11 @@ import subprocess
import shutil
import os
from pathlib import Path
-from PIL import Image # нужна библиотека Pillow для конвертации PNG в ICO
import PySide2
from PyInstaller.utils.hooks import collect_data_files
-# install:
+# install: pip install PySide2 lxml nuitka pyinstaller
# - PyInstaller
# - nuitka
-# - Pillow
# - PySide2
# - clang
@@ -25,6 +23,11 @@ SPEC_PATH = WORK_PATH
ICON_PATH = SRC_PATH / "icon.png"
ICON_ICO_PATH = SRC_PATH / "icon.ico"
+TEMP_FOLDERS = [
+ "build_temp",
+ "__pycache__",
+ "DebugVarEdit_GUI\..*$"
+]
# === Пути к DLL и прочим зависимостям ===
LIBS = {
"libclang.dll": SRC_PATH / "libclang.dll"
@@ -48,7 +51,7 @@ for name, path in LIBS.items():
print(f"WARNING: {path.name} не найден — он не будет включён в сборку")
def clean_temp():
- for folder in ["build_temp", "__pycache__", "DebugVarEdit_GUI.build", "DebugVarEdit_GUI.dist", "DebugVarEdit_GUI.onefile-build"]:
+ for folder in TEMP_FOLDERS:
path = Path(folder)
if path.exists():
shutil.rmtree(path, ignore_errors=True)
diff --git a/structs.xml b/structs.xml
index bb15e3c..648c043 100644
--- a/structs.xml
+++ b/structs.xml
@@ -2,20180 +2,20180 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
+
+
+
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/vars.xml b/vars.xml
index 37648e1..e6873e1 100644
--- a/vars.xml
+++ b/vars.xml
@@ -1,10 +1,10 @@
-
+
true
true
- ADC0finishAddr
+ ADC0finish
pt_int16
t_iq_none
t_iq_none
@@ -12,451 +12,451 @@
Src/myXilinx/x_example_all.c
false
false
-
+
false
false
ADC0startAddr
pt_int16
t_iq_none
-
+ t_iq_none
int
Src/myXilinx/x_example_all.c
false
false
-
+
false
- false
+ true
ADC1finishAddr
pt_int16
t_iq_none
-
+ t_iq_none
int
Src/myXilinx/x_example_all.c
false
false
-
+
false
false
ADC1startAddr
pt_int16
t_iq_none
-
+ t_iq_none
int
Src/myXilinx/x_example_all.c
false
false
-
+
false
false
ADC2finishAddr
pt_int16
t_iq_none
-
+
int
Src/myXilinx/x_example_all.c
false
false
-
+
false
false
ADC2startAddr
pt_int16
t_iq_none
-
+
int
Src/myXilinx/x_example_all.c
false
false
-
+
false
false
ADDR_FOR_ALL
pt_int16
t_iq_none
-
+
int
Src/myXilinx/RS_Functions.c
false
false
-
+
false
false
BUSY
pt_int16
t_iq_none
-
+
int
Src/myLibs/CAN_Setup.c
false
false
-
+
false
false
Bender
pt_arr_struct
t_iq_none
-
+
BENDER[2]
Src/myLibs/bender.c
false
false
-
+
false
false
CAN_answer_wait
pt_arr_int16
t_iq_none
-
+
int[32]
Src/myLibs/CAN_Setup.c
false
false
-
+
false
false
CAN_count_cycle_input_units
pt_arr_int16
t_iq_none
-
+
int[8]
Src/myLibs/CAN_Setup.c
false
false
-
+
false
false
CAN_no_answer
pt_arr_int16
t_iq_none
-
+
int[32]
Src/myLibs/CAN_Setup.c
false
false
-
+
false
false
CAN_refresh_cicle
pt_arr_int16
t_iq_none
-
+
int[32]
Src/myLibs/CAN_Setup.c
false
false
-
+
false
false
CAN_request_sent
pt_arr_int16
t_iq_none
-
+
int[32]
Src/myLibs/CAN_Setup.c
false
false
-
+
false
false
CAN_timeout
pt_arr_int16
t_iq_none
-
+
int[32]
Src/myLibs/CAN_Setup.c
false
false
-
+
false
false
CAN_timeout_cicle
pt_arr_int16
t_iq_none
-
+
int[32]
Src/myLibs/CAN_Setup.c
false
false
-
+
false
false
CNTRL_ADDR
pt_int16
t_iq_none
-
+
int
Src/myXilinx/RS_Functions.c
false
false
-
+
false
false
CNTRL_ADDR_UNIVERSAL
pt_int16
t_iq_none
-
+
const int
Src/myXilinx/RS_Functions.c
false
false
-
+
false
false
CONST_15
pt_int32
t_iq
-
+
_iq
Src/myLibs/mathlib.c
false
false
-
+
false
false
CONST_23
pt_int32
t_iq
-
+
_iq
Src/myLibs/mathlib.c
false
false
-
+
false
false
CanOpenUnites
pt_arr_int16
t_iq_none
-
+
int[30]
Src/myLibs/CAN_Setup.c
false
false
-
+
false
false
CanTimeOutErrorTR
pt_int16
t_iq_none
-
+
int
Src/myLibs/CAN_Setup.c
false
false
-
+
false
false
Controll
pt_union
t_iq_none
-
+
XControll_reg
Src/myXilinx/Spartan2E_Functions.c
false
false
-
+
false
false
Dpwm
pt_int16
t_iq_none
-
+
int
Src/main/PWMTMSHandle.c
false
false
-
+
false
false
Dpwm2
pt_int16
t_iq_none
-
+
int
Src/main/PWMTMSHandle.c
false
false
-
+
false
false
Dpwm4
pt_int16
t_iq_none
-
+
int
Src/main/PWMTMSHandle.c
false
false
-
+
false
false
EvaTimer1InterruptCount
pt_int16
t_iq_none
-
+
int
Src/main/281xEvTimersInit.c
false
false
-
+
false
false
EvaTimer2InterruptCount
pt_int16
t_iq_none
-
+
int
Src/main/281xEvTimersInit.c
false
false
-
+
false
false
EvbTimer3InterruptCount
pt_int16
t_iq_none
-
+
int
Src/main/281xEvTimersInit.c
false
false
-
+
false
false
EvbTimer4InterruptCount
pt_int16
t_iq_none
-
+
int
Src/main/281xEvTimersInit.c
false
false
-
+
false
false
Fpwm
pt_int16
t_iq_none
-
+
int
Src/main/PWMTMSHandle.c
false
false
-
+
false
false
Gott
pt_arr_int8
t_iq_none
-
+
char[8][16]
Src/myLibs/bender.c
false
true
-
+
false
false
IN0finishAddr
pt_int16
t_iq_none
-
+
int
Src/myXilinx/x_example_all.c
false
false
-
+
false
false
IN0startAddr
pt_int16
t_iq_none
-
+
int
Src/myXilinx/x_example_all.c
false
false
-
+
false
false
IN1finishAddr
pt_int16
t_iq_none
-
+
int
Src/myXilinx/x_example_all.c
false
false
-
+
false
false
IN1startAddr
pt_int16
t_iq_none
-
+
int
Src/myXilinx/x_example_all.c
false
false
-
+
false
false
IN2finishAddr
pt_int16
t_iq_none
-
+
int
Src/myXilinx/x_example_all.c
false
false
-
+
false
false
IN2startAddr
pt_int16
t_iq_none
-
+
int
Src/myXilinx/x_example_all.c
false
false
-
+
true
true
@@ -468,131 +468,131 @@
Src/main/params_i_out.c
false
false
-
+
false
false
I_OUT_1_6_NOMINAL_IQ
pt_int32
t_iq_none
-
+
long
Src/main/params_i_out.c
false
false
-
+
false
false
I_OUT_1_8_NOMINAL_IQ
pt_int32
t_iq_none
-
+
long
Src/main/params_i_out.c
false
false
-
+
false
false
I_OUT_NOMINAL
pt_float
t_iq_none
-
+
float
Src/main/params_i_out.c
false
false
-
+
false
false
I_OUT_NOMINAL_IQ
pt_int32
t_iq_none
-
+
long
Src/main/params_i_out.c
false
false
-
+
false
false
I_ZPT_NOMINAL_IQ
pt_int32
t_iq_none
-
+
long
Src/main/params_i_out.c
false
false
-
+
false
false
Id_out_max_full
pt_int32
t_iq
-
+
_iq
Src/VectorControl/regul_power.c
false
false
-
+
false
false
Id_out_max_low_speed
pt_int32
t_iq
-
+
_iq
Src/VectorControl/regul_power.c
false
false
-
+
false
false
Iq_out_max
pt_int32
t_iq
-
+
_iq
Src/main/params_i_out.c
false
false
-
+
false
false
Iq_out_nom
pt_int32
t_iq
-
+
_iq
Src/main/params_i_out.c
false
false
-
+
false
false
K_LEM_ADC
pt_arr_uint32
t_iq_none
-
+
const unsigned long[20]
Src/main/adc_tools.c
false
false
-
+
true
true
- KmodTerm
+ Kmo
pt_float
t_iq_none
t_iq10
@@ -600,1115 +600,1115 @@
Src/myXilinx/RS_Functions.c
false
false
-
+
false
false
ROTfinishAddr
pt_int16
t_iq_none
-
+
int
Src/myXilinx/x_example_all.c
false
false
-
+
false
false
RS_Len
pt_arr_uint16
t_iq_none
-
+
unsigned int[70]
Src/myXilinx/RS_Functions.c
false
false
-
+
false
false
R_ADC
pt_arr_uint16
t_iq_none
-
+
const unsigned int[20]
Src/main/adc_tools.c
false
false
-
+
false
false
RotPlaneStartAddr
pt_int16
t_iq_none
-
+
int
Src/myXilinx/x_example_all.c
false
false
-
+
false
false
SQRT_32
pt_int32
t_iq
-
+
_iq
Src/myLibs/mathlib.c
false
false
-
+
false
false
Unites
pt_arr_int16
t_iq_none
-
+
int[8][128]
Src/myLibs/CAN_Setup.c
false
false
-
+
false
false
VAR_FREQ_PWM_XTICS
pt_int16
t_iq_none
-
+
int
Src/main/PWMTools.c
false
false
-
+
false
false
VAR_PERIOD_MAX_XTICS
pt_int16
t_iq_none
-
+
int
Src/main/PWMTools.c
false
false
-
+
false
false
VAR_PERIOD_MIN_BR_XTICS
pt_int16
t_iq_none
-
+
int
Src/main/PWMTools.c
false
false
-
+
false
false
VAR_PERIOD_MIN_XTICS
pt_int16
t_iq_none
-
+
int
Src/main/PWMTools.c
false
false
-
+
false
false
Zpwm
pt_int16
t_iq_none
-
+
int
Src/main/PWMTMSHandle.c
false
false
-
+
false
false
a
pt_struct
t_iq_none
-
+
WINDING
Src/main/PWMTools.c
false
false
-
+
false
false
addrToSent
pt_union
t_iq_none
-
+
volatile AddrToSent
Src/myXilinx/xPeriphSP6_loader.c
false
false
-
+
false
false
adr_read_from_modbus3
pt_uint16
t_iq_none
-
+
unsigned int
Src/myXilinx/RS_Functions_modbus.c
false
false
-
+
false
false
alarm_log_can
pt_struct
t_iq_none
-
+
ALARM_LOG_CAN
Src/myLibs/alarm_log_can.c
false
false
-
+
false
false
alarm_log_can_setup
pt_struct
t_iq_none
-
+
ALARM_LOG_CAN_SETUP
Src/myLibs/CAN_Setup.c
false
false
-
+
false
false
analog
pt_struct
t_iq_none
-
+
ANALOG_VALUE
Src/main/adc_tools.c
false
false
-
+
false
false
ar_sa_all
pt_arr_int16
t_iq_none
-
+
int[3][6][4][7]
Src/main/v_pwm24.c
false
false
-
+
false
false
ar_tph
pt_int32
t_iq
-
+
_iq[7]
Src/main/v_pwm24.c
false
false
-
+
false
false
biTemperatureLimits
pt_arr_int16
t_iq_none
-
+
int[12]
Src/main/init_protect_levels.c
false
true
-
+
false
false
biTemperatureWarnings
pt_arr_int16
t_iq_none
-
+
int[12]
Src/main/init_protect_levels.c
false
true
-
+
false
false
block_size_counter_fast
pt_int16
t_iq_none
-
+
int
Src/myLibs/log_to_memory.c
false
false
-
+
false
false
block_size_counter_slow
pt_int16
t_iq_none
-
+
int
Src/myLibs/log_to_memory.c
false
false
-
+
false
false
break_result_1
pt_int32
t_iq
-
+
_iq
Src/main/break_regul.c
false
false
-
+
false
false
break_result_2
pt_int32
t_iq
-
+
_iq
Src/main/break_regul.c
false
false
-
+
false
false
break_result_3
pt_int32
t_iq
-
+
_iq
Src/main/break_regul.c
false
false
-
+
false
false
break_result_4
pt_int32
t_iq
-
+
_iq
Src/main/break_regul.c
false
false
-
+
false
false
bvTemperatureLimits
pt_arr_int16
t_iq_none
-
+
int[12]
Src/main/init_protect_levels.c
false
true
-
+
false
false
bvTemperatureWarnings
pt_arr_int16
t_iq_none
-
+
int[12]
Src/main/init_protect_levels.c
false
true
-
+
false
false
byte
pt_union
t_iq_none
-
+
Byte
Src/myXilinx/xPeriphSP6_loader.c
false
false
-
+
false
false
c_s
pt_int32
t_iq_none
-
+
long
Src/main/rotation_speed.c
false
false
-
+
false
false
calibration1
pt_int16
t_iq_none
-
+
int
Src/main/isolation.c
false
false
-
+
false
false
calibration2
pt_int16
t_iq_none
-
+
int
Src/main/isolation.c
false
false
-
+
false
false
callfunc
pt_struct
t_iq_none
-
+
test_functions
Src/main/Main.c
false
false
-
+
false
false
canopen_can_setup
pt_struct
t_iq_none
-
+
CANOPEN_CAN_SETUP
Src/myLibs/CAN_Setup.c
false
false
-
+
false
false
capnum0
pt_uint16
t_iq_none
-
+
unsigned int
Src/main/sync_tools.c
false
false
-
+
false
false
capnum1
pt_uint16
t_iq_none
-
+
unsigned int
Src/main/sync_tools.c
false
false
-
+
false
false
capnum2
pt_uint16
t_iq_none
-
+
unsigned int
Src/main/sync_tools.c
false
false
-
+
false
false
capnum3
pt_uint16
t_iq_none
-
+
unsigned int
Src/main/sync_tools.c
false
false
-
+
false
false
chNum
pt_uint16
t_iq_none
-
+
unsigned int
Src/myXilinx/x_example_all.c
false
false
-
+
false
false
chanell1
pt_struct
t_iq_none
-
+
BREAK_PHASE_I
Src/main/detect_phase.c
false
false
-
+
false
false
chanell2
pt_struct
t_iq_none
-
+
BREAK_PHASE_I
Src/main/detect_phase.c
false
false
-
+
false
false
cmd_3_or_16
pt_int16
t_iq_none
-
+
int
Src/myXilinx/RS_Functions_modbus.c
false
false
-
+
false
false
cmd_crc
pt_arr_int8
t_iq_none
-
+
char[4]
Src/myLibs/bender.c
false
true
-
+
false
false
cmd_finish1
pt_int8
t_iq_none
-
+
char
Src/myLibs/bender.c
false
True
-
+
false
false
cmd_finish2
pt_int8
t_iq_none
-
+
char
Src/myLibs/bender.c
false
True
-
+
false
false
cmd_start
pt_arr_int8
t_iq_none
-
+
char[5]
Src/myLibs/bender.c
false
true
-
+
false
false
cmd_txt
pt_arr_int8
t_iq_none
-
+
char[4][8]
Src/myLibs/bender.c
false
true
-
+
false
false
compress_size
pt_int16
t_iq_none
-
+
int
Src/myLibs/alarm_log_can.c
false
false
-
+
false
false
controlReg
pt_union
t_iq_none
-
+
ControlReg
Src/myXilinx/xPeriphSP6_loader.c
false
false
-
+
false
false
cos_fi
pt_struct
t_iq_none
-
+
COS_FI_STRUCT
Src/VectorControl/pwm_vector_regul.c
false
false
-
+
false
false
count_error_sync
pt_uint16
t_iq_none
-
+
unsigned int
Src/main/sync_tools.c
false
false
-
+
false
false
count_modbus_table_changed
pt_int16
t_iq_none
-
+
int
Src/myLibs/modbus_fill_table.c
false
false
-
+
false
false
count_run_pch
pt_int16
t_iq_none
-
+
int
Src/main/PWMTools.c
false
false
-
+
false
false
counterSBWriteErrors
pt_uint16
t_iq_none
-
+
unsigned int
Src/myXilinx/x_serial_bus.c
false
True
-
+
false
false
crc_16_tab
pt_arr_uint16
t_iq_none
-
+
WORD[256]
Src/myXilinx/CRC_Functions.c
false
false
-
+
false
false
crypt
pt_arr_int8
t_iq_none
-
+
char[34]
Src/myLibs/bender.c
false
false
-
+
false
false
cur_position_buf_modbus16
pt_int16
t_iq_none
-
+
int
Src/myLibs/message_modbus.c
false
True
-
+
false
false
cur_position_buf_modbus16_can
pt_int16
t_iq_none
-
+
int
Src/myLibs/message_modbus.c
false
false
-
+
false
false
cur_position_buf_modbus3
pt_int16
t_iq_none
-
+
int
Src/myLibs/message_modbus.c
false
True
-
+
false
false
cycle
pt_arr_struct
t_iq_none
-
+
CYCLE[32]
Src/myLibs/CAN_Setup.c
false
false
-
+
false
false
data_to_umu1_7f
pt_int16
t_iq_none
-
+
int
Src/main/init_protect_levels.c
false
True
-
+
false
false
data_to_umu1_8
pt_int16
t_iq_none
-
+
int
Src/main/init_protect_levels.c
false
True
-
+
false
false
data_to_umu2_7f
pt_int16
t_iq_none
-
+
int
Src/main/init_protect_levels.c
false
True
-
+
false
false
data_to_umu2_8
pt_int16
t_iq_none
-
+
int
Src/main/init_protect_levels.c
false
True
-
+
false
false
delta_capnum
pt_int16
t_iq_none
-
+
int
Src/main/sync_tools.c
false
false
-
+
false
false
delta_error
pt_int16
t_iq_none
-
+
int
Src/main/sync_tools.c
false
false
-
+
false
false
doors
pt_union
t_iq_none
-
+
volatile DOORS_STATUS
Src/main/doors_control.c
false
false
-
+
false
false
dq_to_ab
pt_struct
t_iq_none
-
+
DQ_TO_ALPHABETA
Src/main/v_pwm24.c
false
true
-
+
false
false
enable_can
pt_int16
t_iq_none
-
+
int
Src/myLibs/message_modbus.c
false
false
-
+
false
false
enable_can_recive_after_units_box
pt_int16
t_iq_none
-
+
int
Src/myLibs/CAN_Setup.c
false
false
-
+
false
false
err_level_adc
pt_int32
t_iq
-
+
_iq
Src/main/adc_tools.c
false
false
-
+
false
false
err_level_adc_on_go
pt_int32
t_iq
-
+
_iq
Src/main/adc_tools.c
false
false
-
+
false
false
err_main
pt_uint16
t_iq_none
-
+
unsigned int
Src/main/Main.c
false
false
-
+
false
false
err_modbus16
pt_int16
t_iq_none
-
+
int
Src/myXilinx/RS_Functions_modbus.c
false
false
-
+
false
false
err_modbus3
pt_int16
t_iq_none
-
+
int
Src/myXilinx/RS_Functions_modbus.c
false
false
-
+
false
false
errors
pt_struct
t_iq_none
-
+
ERRORS
Src/main/errors.c
false
false
-
+
false
false
f
pt_struct
t_iq_none
-
+
FLAG
Src/main/Main.c
false
false
-
+
false
false
fail
pt_int16
t_iq_none
-
+
volatile int
Src/myXilinx/xPeriphSP6_loader.c
false
false
-
+
false
false
faults
pt_struct
t_iq_none
-
+
FAULTS
Src/main/errors.c
false
false
-
+
false
false
fifo
pt_struct
t_iq_none
-
+
FIFO
Src/myLibs/CAN_Setup.c
false
false
-
+
false
false
filter
pt_struct
t_iq_none
-
+
ANALOG_VALUE
Src/main/adc_tools.c
false
false
-
+
false
false
flag_buf
pt_int16
t_iq_none
-
+
int
Src/main/rotation_speed.c
false
false
-
+
false
false
flag_enable_can_from_mpu
pt_int16
t_iq_none
-
+
int
Src/myLibs/CAN_Setup.c
false
false
-
+
false
false
flag_enable_can_from_terminal
pt_int16
t_iq_none
-
+
int
Src/myLibs/CAN_Setup.c
false
false
-
+
false
false
flag_on_off_pch
pt_int16
t_iq_none
-
+
int
Src/main/PWMTools.c
false
false
-
+
false
false
flag_received_first_mess_from_MPU
pt_uint16
t_iq_none
-
+
unsigned int
Src/myXilinx/RS_Functions_modbus.c
false
false
-
+
false
false
flag_reverse
pt_uint16
t_iq_none
-
+
unsigned int
Src/myLibs/modbus_read_table.c
false
false
-
+
false
false
flag_send_answer_rs
pt_uint16
t_iq_none
-
+
unsigned int
Src/myXilinx/RS_Functions_modbus.c
false
false
-
+
false
false
flag_test_tabe_filled
pt_int16
t_iq_none
-
+
int
Src/myLibs/modbus_fill_table.c
false
false
-
+
false
false
flag_we_int_pwm_on
pt_int16
t_iq_none
-
+
int
Src/main/PWMTools.c
false
false
-
+
false
false
freq1
pt_int32
t_iq
-
+
_iq
Src/main/PWMTools.c
false
false
-
+
true
true
- freqTerm
+ freqT
pt_float
t_iq_none
t_iq10
@@ -1716,1831 +1716,1831 @@
Src/myXilinx/RS_Functions.c
false
false
-
+
false
false
global_time
pt_struct
t_iq_none
-
+
GLOBAL_TIME
Src/main/global_time.c
false
false
-
+
false
false
hb_logs_data
pt_int16
t_iq_none
-
+
int
Src/myLibs/log_to_memory.c
false
false
-
+
false
false
i
pt_int16
t_iq_none
-
+
int
Src/main/PWMTools.c
false
false
-
+
false
false
i1_out
pt_struct
t_iq_none
-
+
BREAK2_PHASE
Src/main/errors.c
false
false
-
+
false
false
i2_out
pt_struct
t_iq_none
-
+
BREAK2_PHASE
Src/main/errors.c
false
false
-
+
false
false
init_log
pt_arr_int16
t_iq_none
-
+
int[3]
Src/myLibs/log_can.c
false
false
-
+
false
false
iq19_k_norm_ADC
pt_int32
t_iq19
-
+
_iq19[20]
Src/main/adc_tools.c
false
false
-
+
false
false
iq19_zero_ADC
pt_int32
t_iq19
-
+
_iq19[20]
Src/main/adc_tools.c
false
false
-
+
false
false
iq_alfa_coef
pt_int32
t_iq
-
+
_iq
Src/main/v_pwm24.c
false
false
-
+
false
false
iq_k_norm_ADC
pt_int32
t_iq
-
+
_iq[20]
Src/main/adc_tools.c
false
false
-
+
false
false
iq_logpar
pt_struct
t_iq_none
-
+
IQ_LOGSPARAMS
Src/myLibs/log_to_memory.c
false
false
-
+
false
false
iq_max
pt_int32
t_iq
-
+
_iq
Src/myLibs/svgen_dq_v2.c
false
false
-
+
false
false
iq_norm_ADC
pt_int32
t_iq
-
+
_iq[20]
Src/main/adc_tools.c
false
false
-
+
false
false
isolation1
pt_struct
t_iq_none
-
+
ISOLATION
Src/main/isolation.c
false
false
-
+
false
false
isolation2
pt_struct
t_iq_none
-
+
ISOLATION
Src/main/isolation.c
false
false
-
+
false
false
k1
pt_int32
t_iq
-
+
_iq
Src/main/PWMTools.c
false
false
-
+
false
false
kI_D
pt_float
t_iq_none
-
+
float
Src/VectorControl/pwm_vector_regul.c
false
false
-
+
false
false
kI_D_Inv31
pt_float
t_iq_none
-
+
float
Src/VectorControl/pwm_vector_regul.c
false
false
-
+
false
false
kI_Q
pt_float
t_iq_none
-
+
float
Src/VectorControl/pwm_vector_regul.c
false
false
-
+
false
false
kI_Q_Inv31
pt_float
t_iq_none
-
+
float
Src/VectorControl/pwm_vector_regul.c
false
false
-
+
false
false
kP_D
pt_float
t_iq_none
-
+
float
Src/VectorControl/pwm_vector_regul.c
false
false
-
+
false
false
kP_D_Inv31
pt_float
t_iq_none
-
+
float
Src/VectorControl/pwm_vector_regul.c
false
false
-
+
false
false
kP_Q
pt_float
t_iq_none
-
+
float
Src/VectorControl/pwm_vector_regul.c
false
false
-
+
false
false
kP_Q_Inv31
pt_float
t_iq_none
-
+
float
Src/VectorControl/pwm_vector_regul.c
false
false
-
+
false
false
kan
pt_int16
t_iq_none
-
+
int
Src/myLibs/bender.c
false
True
-
+
false
false
koef_Base_stop_run
pt_int32
t_iq
-
+
_iq
Src/main/break_regul.c
false
false
-
+
false
false
koef_Iabc_filter
pt_int32
t_iq
-
+
_iq
Src/main/adc_tools.c
false
false
-
+
false
false
koef_Im_filter
pt_int32
t_iq
-
+
_iq
Src/main/adc_tools.c
false
false
-
+
false
false
koef_Im_filter_long
pt_int32
t_iq
-
+
_iq
Src/main/adc_tools.c
false
false
-
+
false
false
koef_K_stop_run
pt_int32
t_iq
-
+
_iq
Src/main/break_regul.c
false
false
-
+
false
false
koef_Krecup
pt_int32
t_iq
-
+
_iq
Src/main/break_regul.c
false
false
-
+
false
false
koef_Min_recup
pt_int32
t_iq
-
+
_iq
Src/main/break_regul.c
false
false
-
+
false
false
koef_TemperBSU_long_filter
pt_int32
t_iq
-
+
_iq
Src/main/adc_tools.c
false
false
-
+
false
false
koef_Ud_fast_filter
pt_int32
t_iq
-
+
_iq
Src/main/adc_tools.c
false
false
-
+
false
false
koef_Ud_long_filter
pt_int32
t_iq
-
+
_iq
Src/main/adc_tools.c
false
false
-
+
false
false
koef_Wlong
pt_int32
t_iq
-
+
_iq
Src/main/adc_tools.c
false
false
-
+
false
false
koef_Wout_filter
pt_int32
t_iq
-
+
_iq
Src/main/rotation_speed.c
false
false
-
+
false
false
koef_Wout_filter_long
pt_int32
t_iq
-
+
_iq
Src/main/rotation_speed.c
false
false
-
+
false
false
koeff_Fs_filter
pt_int32
t_iq_none
-
+
long
Src/VectorControl/pwm_vector_regul.c
false
false
-
+
false
false
koeff_Idq_filter
pt_int32
t_iq_none
-
+
long
Src/VectorControl/pwm_vector_regul.c
false
false
-
+
false
false
koeff_Iq_filter
pt_int32
t_iq
-
+
_iq
Src/VectorControl/regul_power.c
false
false
-
+
false
false
koeff_Iq_filter_slow
pt_int32
t_iq_none
-
+
long
Src/VectorControl/pwm_vector_regul.c
false
false
-
+
false
false
koeff_Ud_filter
pt_int32
t_iq_none
-
+
long
Src/VectorControl/pwm_vector_regul.c
false
false
-
+
false
false
koeff_Uq_filter
pt_int32
t_iq_none
-
+
long
Src/VectorControl/pwm_vector_regul.c
false
false
-
+
false
false
kom
pt_int16
t_iq_none
-
+
int
Src/myLibs/bender.c
false
True
-
+
false
false
length
pt_uint32
t_iq_none
-
+
volatile unsigned long
Src/myXilinx/xPeriphSP6_loader.c
false
false
-
+
false
false
level_on_off_break
pt_int32
t_iq
-
+
_iq[13][2]
Src/main/break_tools.c
false
false
-
+
false
false
log_can
pt_struct
t_iq_none
-
+
logcan_TypeDef
Src/myLibs/log_can.c
false
false
-
+
false
false
log_can_setup
pt_struct
t_iq_none
-
+
LOG_CAN_SETUP
Src/myLibs/CAN_Setup.c
false
false
-
+
false
false
log_params
pt_struct
t_iq_none
-
+
TYPE_LOG_PARAMS
Src/myLibs/log_params.c
false
false
-
+
false
false
logbuf_sync1
pt_arr_int32
t_iq_none
-
+
long[10]
Src/main/sync_tools.c
false
false
-
+
false
false
logpar
pt_struct
t_iq_none
-
+
LOGSPARAMS
Src/myLibs/log_to_memory.c
false
false
-
+
false
false
mPWM_a
pt_int16
t_iq_none
-
+
int
Src/main/PWMTMSHandle.c
false
True
-
+
false
false
mPWM_b
pt_int16
t_iq_none
-
+
int
Src/main/PWMTMSHandle.c
false
True
-
+
false
false
m_PWM
pt_int16
t_iq_none
-
+
int
Src/main/PWMTMSHandle.c
false
false
-
+
false
false
mailboxs_can_setup
pt_struct
t_iq_none
-
+
MAILBOXS_CAN_SETUP
Src/myLibs/CAN_Setup.c
false
false
-
+
false
false
manufactorerAndProductID
pt_int16
t_iq_none
-
+
int
Src/myXilinx/xPeriphSP6_loader.c
false
false
-
+
false
false
modbus_table_can_in
pt_ptr_union
t_iq_none
-
+
MODBUS_REG_STRUCT *
Src/myLibs/modbus_table.c
false
false
-
+
false
false
modbus_table_can_out
pt_ptr_union
t_iq_none
-
+
MODBUS_REG_STRUCT *
Src/myLibs/modbus_table.c
false
false
-
+
false
false
modbus_table_in
pt_arr_union
t_iq_none
-
+
MODBUS_REG_STRUCT[450]
Src/myLibs/modbus_table.c
false
false
-
+
false
false
modbus_table_out
pt_arr_union
t_iq_none
-
+
MODBUS_REG_STRUCT[450]
Src/myLibs/modbus_table.c
false
false
-
+
false
false
modbus_table_rs_in
pt_ptr_union
t_iq_none
-
+
MODBUS_REG_STRUCT *
Src/myLibs/modbus_table.c
false
false
-
+
false
false
modbus_table_rs_out
pt_ptr_union
t_iq_none
-
+
MODBUS_REG_STRUCT *
Src/myLibs/modbus_table.c
false
false
-
+
false
false
modbus_table_test
pt_arr_union
t_iq_none
-
+
MODBUS_REG_STRUCT[450]
Src/myLibs/modbus_table.c
false
false
-
+
false
false
mpu_can_setup
pt_struct
t_iq_none
-
+
MPU_CAN_SETUP
Src/myLibs/CAN_Setup.c
false
false
-
+
false
false
mzz_limit_100
pt_int16
t_iq_none
-
+
int
Src/myLibs/modbus_read_table.c
false
True
-
+
false
false
mzz_limit_1000
pt_int16
t_iq_none
-
+
int
Src/myLibs/modbus_read_table.c
false
True
-
+
false
false
mzz_limit_1100
pt_int16
t_iq_none
-
+
int
Src/myLibs/modbus_read_table.c
false
True
-
+
false
false
mzz_limit_1200
pt_int16
t_iq_none
-
+
int
Src/myLibs/modbus_read_table.c
false
True
-
+
false
false
mzz_limit_1400
pt_int16
t_iq_none
-
+
int
Src/myLibs/modbus_read_table.c
false
True
-
+
false
false
mzz_limit_1500
pt_int16
t_iq_none
-
+
int
Src/myLibs/modbus_read_table.c
false
True
-
+
false
false
mzz_limit_2000
pt_int16
t_iq_none
-
+
int
Src/myLibs/modbus_read_table.c
false
True
-
+
false
false
mzz_limit_500
pt_int16
t_iq_none
-
+
int
Src/myLibs/modbus_read_table.c
false
True
-
+
false
false
new_cycle_fifo
pt_struct
t_iq_none
-
+
NEW_CYCLE_FIFO
Src/myLibs/CAN_Setup.c
false
false
-
+
false
false
no_write
pt_int16
t_iq_none
-
+
int
Src/myLibs/log_to_memory.c
false
false
-
+
false
false
no_write_slow
pt_int16
t_iq_none
-
+
int
Src/myLibs/log_to_memory.c
false
false
-
+
false
false
number_modbus_table_changed
pt_int16
t_iq_none
-
+
int
Src/myLibs/modbus_fill_table.c
false
false
-
+
false
false
optical_read_data
pt_struct
t_iq_none
-
+
OPTICAL_BUS_DATA
Src/main/optical_bus.c
false
false
-
+
false
false
optical_write_data
pt_struct
t_iq_none
-
+
OPTICAL_BUS_DATA
Src/main/optical_bus.c
false
false
-
+
false
false
options_controller
pt_arr_union
t_iq_none
-
+
MODBUS_REG_STRUCT[200]
Src/myXilinx/RS_Functions_modbus.c
false
false
-
+
false
false
pidCur_Ki
pt_int32
t_iq
-
+
_iq
Src/main/v_pwm24.c
false
false
-
+
false
false
pidD
pt_struct
t_iq_none
-
+
PIDREG3
Src/VectorControl/pwm_vector_regul.c
false
false
-
+
false
false
pidD2
pt_struct
t_iq_none
-
+
PIDREG3
Src/VectorControl/pwm_vector_regul.c
false
false
-
+
false
false
pidFvect
pt_struct
t_iq_none
-
+
PIDREG3
Src/VectorControl/regul_turns.c
false
false
-
+
false
false
pidFvectKi_test
pt_int16
t_iq_none
-
+
int
Src/main/message2.c
false
false
-
+
false
false
pidFvectKp_test
pt_int16
t_iq_none
-
+
int
Src/main/message2.c
false
false
-
+
false
false
pidPvect
pt_struct
t_iq_none
-
+
PIDREG3
Src/VectorControl/regul_power.c
false
false
-
+
false
false
pidQ
pt_struct
t_iq_none
-
+
PIDREG3
Src/VectorControl/pwm_vector_regul.c
false
false
-
+
false
false
pidQ2
pt_struct
t_iq_none
-
+
PIDREG3
Src/VectorControl/pwm_vector_regul.c
false
false
-
+
false
false
pidReg_koeffs
pt_struct
t_iq_none
-
+
PIDREG_KOEFFICIENTS
Src/VectorControl/pwm_vector_regul.c
false
false
-
+
false
false
pidTetta
pt_struct
t_iq_none
-
+
PIDREG3
Src/VectorControl/teta_calc.c
false
false
-
+
false
false
power_ratio
pt_struct
t_iq_none
-
+
POWER_RATIO
Src/myLibs/modbus_read_table.c
false
false
-
+
false
false
prev_flag_buf
pt_int16
t_iq_none
-
+
int
Src/main/rotation_speed.c
false
false
-
+
false
false
prev_status_received
pt_uint16
t_iq_none
-
+
unsigned int
Src/myLibs/log_can.c
false
false
-
+
false
false
pwmd
pt_struct
t_iq_none
-
+
PWMGEND
Src/main/PWMTMSHandle.c
false
false
-
+
false
false
r_c_sbus
pt_struct
t_iq_none
-
+
T_controller_read
Src/myXilinx/x_serial_bus.c
false
false
-
+
false
false
r_controller
pt_struct
t_iq_none
-
+
T_controller_read
Src/myXilinx/xp_hwp.c
false
false
-
+
false
false
refo
pt_struct
t_iq_none
-
+
FIFO
Src/myLibs/CAN_Setup.c
false
false
-
+
false
false
reply
pt_struct
t_iq_none
-
+
TMS_TO_TERMINAL_STRUCT
Src/myXilinx/RS_Functions_modbus.c
false
false
-
+
false
false
reply_test_all
pt_struct
t_iq_none
-
+
TMS_TO_TERMINAL_TEST_ALL_STRUCT
Src/myXilinx/RS_Functions_modbus.c
false
false
-
+
false
false
return_var
pt_int32
t_iq_none
-
+
long
Src/main/Main.c
false
false
-
+
false
false
rmp_freq
pt_struct
t_iq_none
-
+
RMP_MY1
Src/main/PWMTools.c
false
false
-
+
false
false
rmp_wrot
pt_struct
t_iq_none
-
+
RMP_MY1
Src/main/rotation_speed.c
false
false
-
+
false
false
rotation_sensor
pt_struct
t_iq_none
-
+
T_rotation_sensor
Src/myXilinx/xp_rotation_sensor.c
false
false
-
+
false
false
rotor
pt_struct
t_iq_none
-
+
ROTOR_VALUE
Src/main/rotation_speed.c
false
false
-
+
false
false
rs_a
pt_struct
t_iq_none
-
+
RS_DATA_STRUCT
Src/myXilinx/RS_Functions.c
false
false
-
+
false
false
rs_b
pt_struct
t_iq_none
-
+
RS_DATA_STRUCT
Src/myXilinx/RS_Functions.c
false
false
-
+
false
false
sincronisationFault
pt_uint16
t_iq_none
-
+
unsigned int
Src/myLibs/modbus_read_table.c
false
false
-
+
false
false
size_cmd15
pt_int8
t_iq_none
-
+
char
Src/myXilinx/RS_Functions.c
false
false
-
+
false
false
size_cmd16
pt_int8
t_iq_none
-
+
char
Src/myXilinx/RS_Functions.c
false
false
-
+
false
false
size_fast_done
pt_int16
t_iq_none
-
+
int
Src/myLibs/log_to_memory.c
false
false
-
+
false
false
size_slow_done
pt_int16
t_iq_none
-
+
int
Src/myLibs/log_to_memory.c
false
false
-
+
false
false
stop_log
pt_int16
t_iq_none
-
+
int
Src/myLibs/log_to_memory.c
false
false
-
+
false
false
stop_log_slow
pt_int16
t_iq_none
-
+
int
Src/myLibs/log_to_memory.c
false
false
-
+
false
false
svgen_dq_1
pt_struct
t_iq_none
-
+
SVGENDQ
Src/main/v_pwm24.c
false
false
-
+
false
false
svgen_dq_2
pt_struct
t_iq_none
-
+
SVGENDQ
Src/main/v_pwm24.c
false
false
-
+
false
false
svgen_pwm24_1
pt_struct
t_iq_none
-
+
SVGEN_PWM24
Src/main/v_pwm24.c
false
false
-
+
false
false
svgen_pwm24_2
pt_struct
t_iq_none
-
+
SVGEN_PWM24
Src/main/v_pwm24.c
false
false
-
+
false
false
temp
pt_uint16
t_iq_none
-
+
unsigned int
Src/main/sync_tools.c
false
false
-
+
false
false
temperature_limit_koeff
pt_int32
t_iq
-
+
_iq
Src/main/errors_temperature.c
false
false
-
+
false
false
temperature_warning_BI1
pt_union
t_iq_none
-
+
INVERTER_TEMPERATURES
Src/main/errors.c
false
false
-
+
false
false
temperature_warning_BI2
pt_union
t_iq_none
-
+
INVERTER_TEMPERATURES
Src/main/errors.c
false
false
-
+
false
false
temperature_warning_BV1
pt_union
t_iq_none
-
+
RECTIFIER_TEMPERATURES
Src/main/errors.c
false
false
-
+
false
false
temperature_warning_BV2
pt_union
t_iq_none
-
+
RECTIFIER_TEMPERATURES
Src/main/errors.c
false
false
-
+
false
false
terminal_can_setup
pt_struct
t_iq_none
-
+
TERMINAL_CAN_SETUP
Src/myLibs/CAN_Setup.c
false
false
-
+
false
false
tetta_calc
pt_struct
t_iq_none
-
+
TETTA_CALC
Src/VectorControl/teta_calc.c
false
false
-
+
false
false
timCNT_alg
pt_int16
t_iq_none
-
+
int
Src/myXilinx/Spartan2E_Functions.c
false
false
-
+
false
false
timCNT_prev
pt_int16
t_iq_none
-
+
int
Src/myXilinx/Spartan2E_Functions.c
false
false
-
+
false
false
time
pt_uint16
t_iq_none
-
+
unsigned int
Src/myXilinx/Spartan2E_Functions.c
false
false
-
+
false
false
timePauseBENDER_Messages
pt_uint16
t_iq_none
-
+
unsigned int
Src/main/main22220.c
false
True
-
+
false
false
timePauseCAN_Messages
pt_uint16
t_iq_none
-
+
unsigned int
Src/main/main22220.c
false
True
-
+
false
false
time_alg
pt_float
t_iq_none
-
+
float
Src/myXilinx/Spartan2E_Functions.c
false
false
-
+
false
false
time_pause_enable_can_from_mpu
pt_int32
t_iq_none
-
+
long
Src/myLibs/CAN_Setup.c
false
false
-
+
false
false
time_pause_enable_can_from_terminal
pt_int32
t_iq_none
-
+
long
Src/myLibs/CAN_Setup.c
false
false
-
+
false
false
time_pause_logs
pt_int16
t_iq_none
-
+
int
Src/myLibs/log_can.c
false
false
-
+
false
false
time_pause_titles
pt_int16
t_iq_none
-
+
int
Src/myLibs/log_can.c
false
false
-
+
false
false
tryNumb
pt_int16
t_iq_none
-
+
volatile int
Src/myXilinx/xPeriphSP6_loader.c
false
false
-
+
false
false
unites_can_setup
pt_struct
t_iq_none
-
+
UNITES_CAN_SETUP
Src/myLibs/CAN_Setup.c
false
false
-
+
false
false
var_numb
pt_int32
t_iq_none
-
+
long
Src/main/Main.c
false
false
-
+
false
false
vect_control
pt_struct
t_iq_none
-
+
VECTOR_CONTROL
Src/VectorControl/pwm_vector_regul.c
false
false
-
+
false
false
water_cooler
pt_struct
t_iq_none
-
+
WaterCooler
Src/myLibs/can_watercool.c
false
false
-
+
false
false
winding_displacement
pt_int32
t_iq
-
+
_iq
Src/main/v_pwm24.c
false
false
-
+
false
false
word
pt_union
t_iq_none
-
+
Word
Src/myXilinx/xPeriphSP6_loader.c
false
false
-
+
false
false
wordReversed
pt_union
t_iq_none
-
+
WordReversed
Src/myXilinx/xPeriphSP6_loader.c
false
false
-
+
false
false
wordToReverse
pt_union
t_iq_none
-
+
WordToReverse
Src/myXilinx/xPeriphSP6_loader.c
false
false
-
+
false
false
x_parallel_bus_project
pt_struct
t_iq_none
-
+
X_PARALLEL_BUS
Src/myXilinx/x_parallel_bus.c
false
false
-
+
false
false
x_serial_bus_project
pt_struct
t_iq_none
-
+
X_SERIAL_BUS
Src/myXilinx/x_serial_bus.c
false
false
-
+
false
false
xeeprom_controll_fast
pt_uint16
t_iq_none
-
+
unsigned int
Src/myXilinx/Spartan2E_Functions.c
false
false
-
+
false
false
xeeprom_controll_store
pt_uint16
t_iq_none
-
+
unsigned int
Src/myXilinx/Spartan2E_Functions.c
false
false
-
+
false
false
xpwm_time
pt_struct
t_iq_none
-
+
XPWM_TIME
Src/myXilinx/xp_write_xpwm_time.c
false
false
-
+
false
false
zadan_Id_min
pt_int32
t_iq
-
+
_iq
Src/VectorControl/pwm_vector_regul.c
false
false
-
+
false
false
zero_ADC
pt_arr_int16
t_iq_none
-
+
int[20]
Src/main/adc_tools.c
false
false
-
+
true
true
@@ -3552,7 +3552,7 @@
Src/main/adc_tools.c
false
false
-
+
true
true
@@ -3564,7 +3564,7 @@
Src/main/adc_tools.c
false
false
-
+
true
true
@@ -3576,7 +3576,7 @@
Src/main/adc_tools.c
false
false
-
+
true
true
@@ -3588,7 +3588,7 @@
Src/main/adc_tools.c
false
false
-
+
true
true
@@ -3600,7 +3600,7 @@
Src/main/adc_tools.c
false
false
-
+
true
true
@@ -3612,7 +3612,7 @@
Src/main/adc_tools.c
false
false
-
+
true
true
@@ -3624,7 +3624,7 @@
Src/main/adc_tools.c
false
false
-
+
true
true
@@ -3636,7 +3636,7 @@
Src/main/adc_tools.c
false
false
-
+
true
true
@@ -3648,7 +3648,7 @@
Src/main/adc_tools.c
false
false
-
+
true
true
@@ -3660,7 +3660,7 @@
Src/main/adc_tools.c
false
false
-
+
true
true
@@ -3672,7 +3672,7 @@
Src/main/adc_tools.c
false
false
-
+
true
true
@@ -3684,7 +3684,7 @@
Src/main/adc_tools.c
false
false
-
+
true
true
@@ -3696,7 +3696,7 @@
Src/main/adc_tools.c
false
false
-
+
true
true
@@ -3708,7 +3708,7 @@
Src/main/adc_tools.c
false
false
-
+
true
true
@@ -3720,7 +3720,7 @@
Src/main/adc_tools.c
false
false
-
+
true
true
@@ -3732,43 +3732,43 @@
Src/main/adc_tools.c
false
false
-
+
false
false
ADC_f
pt_arr_int16
t_iq_none
-
+
int[2][16]
Src/main/adc_tools.c
false
false
-
+
false
false
ADC_sf
pt_arr_int16
t_iq_none
-
+
int[2][16]
Src/main/adc_tools.c
false
false
-
+
false
false
project
pt_struct
t_iq_none
-
+
T_project
Src/myXilinx/xp_project.c
false
false
-
+
true
true
@@ -3780,7 +3780,7 @@
Src/myLibs/bender.c
false
false
-
+
true
true
@@ -3792,7 +3792,7 @@
Src/myLibs/bender.c
false
false
-
+
true
true
@@ -3804,37 +3804,37 @@
Src/myLibs/bender.c
false
false
-
-
+
+ truetrueproject.controller.buildpt_uint16t_iq_nonet_iq_noneunsigned intSrc/myXilinx/xp_project.cfalsefalsetruetrueproject.controller.read.errors.allpt_uint16t_iq_nonet_iq_noneUInt16Src/myXilinx/xp_project.cfalsefalse
- Src/main/vector.h
- Src/main/errors.h
- Src/myXilinx/RS_Functions_modbus.h
Src/myXilinx/xp_project.h
- Src/main/adc_tools.h
- Src/VectorControl/pwm_vector_regul.h
- Src/myLibs/log_can.h
- Src/main/f281xpwm.h
- Src/main/v_pwm24.h
- Src/myXilinx/xp_write_xpwm_time.h
- Src/VectorControl/dq_to_alphabeta_cos.h
+ Src/myXilinx/RS_Functions_modbus.h
Src/VectorControl/teta_calc.h
+ Src/main/vector.h
+ Src/main/v_pwm24.h
+ Src/main/errors.h
+ Src/VectorControl/pwm_vector_regul.h
+ Src/main/f281xpwm.h
+ Src/main/adc_tools.h
Src/main/rotation_speed.h
- Src/myLibs/detect_phase_break2.h
- Src/myXilinx/RS_Functions.h
- Src/myXilinx/Spartan2E_Functions.h
- Src/myXilinx/xp_controller.h
- Src/myXilinx/xp_rotation_sensor.h
- Src/myXilinx/x_serial_bus.h
- Src/myXilinx/x_parallel_bus.h
+ Src/myXilinx/xp_write_xpwm_time.h
+ Src/myLibs/log_can.h
+ Src/VectorControl/dq_to_alphabeta_cos.h
Src/myXilinx/xPeriphSP6_loader.h
- Src/myLibs/log_params.h
- Src/myLibs/CAN_Setup.h
- Src/myXilinx/CRC_Functions.h
+ Src/myXilinx/x_serial_bus.h
+ Src/myXilinx/Spartan2E_Functions.h
+ Src/myXilinx/x_parallel_bus.h
+ Src/myXilinx/xp_rotation_sensor.h
+ Src/myXilinx/xp_controller.h
+ Src/myXilinx/RS_Functions.h
+ Src/myLibs/svgen_dq.h
+ Src/myLibs/detect_phase_break2.h
+ Src/myLibs/pid_reg3.h
Src/myLibs/log_to_memory.h
Src/main/global_time.h
- Src/myLibs/svgen_dq.h
- Src/myLibs/pid_reg3.h
+ Src/myLibs/log_params.h
+ Src/myXilinx/CRC_Functions.h
+ Src/myLibs/CAN_Setup.h
Src/myLibs/IQmathLib.h
Src/main/doors_control.h
Src/main/isolation.h
@@ -3846,1063 +3846,1063 @@
Src/myLibs/detect_phase_break.h
Src/myLibs/modbus_read_table.h
Src/myLibs/rmp_cntl_my1.h
-
+
int
Src/myXilinx/x_example_all.c
-
+
int
Src/myXilinx/x_example_all.c
-
+
int
Src/myXilinx/x_example_all.c
-
+
int
Src/myXilinx/x_example_all.c
-
+
int
Src/myXilinx/x_example_all.c
-
+
int
Src/myXilinx/x_example_all.c
-
+
int[2][16]
Src/main/adc_tools.c
-
+
int[2][16]
Src/main/adc_tools.c
-
+
int
Src/myXilinx/RS_Functions.c
-
+
int
Src/myLibs/CAN_Setup.c
-
+
BENDER[2]
Src/myLibs/bender.c
-
+
int[32]
Src/myLibs/CAN_Setup.c
-
+
int[8]
Src/myLibs/CAN_Setup.c
-
+
int[32]
Src/myLibs/CAN_Setup.c
-
+
int[32]
Src/myLibs/CAN_Setup.c
-
+
int[32]
Src/myLibs/CAN_Setup.c
-
+
int[32]
Src/myLibs/CAN_Setup.c
-
+
int[32]
Src/myLibs/CAN_Setup.c
-
+
int
Src/myXilinx/RS_Functions.c
-
+
const int
Src/myXilinx/RS_Functions.c
-
+
_iq
Src/myLibs/mathlib.c
-
+
_iq
Src/myLibs/mathlib.c
-
+
int[30]
Src/myLibs/CAN_Setup.c
-
+
int
Src/myLibs/CAN_Setup.c
-
+
XControll_reg
Src/myXilinx/Spartan2E_Functions.c
-
+
int
Src/main/PWMTMSHandle.c
-
+
int
Src/main/PWMTMSHandle.c
-
+
int
Src/main/PWMTMSHandle.c
-
+
int
Src/main/281xEvTimersInit.c
-
+
int
Src/main/281xEvTimersInit.c
-
+
int
Src/main/281xEvTimersInit.c
-
+
int
Src/main/281xEvTimersInit.c
-
+
int
Src/main/PWMTMSHandle.c
-
+
int
Src/myXilinx/x_example_all.c
-
+
int
Src/myXilinx/x_example_all.c
-
+
int
Src/myXilinx/x_example_all.c
-
+
int
Src/myXilinx/x_example_all.c
-
+
int
Src/myXilinx/x_example_all.c
-
+
int
Src/myXilinx/x_example_all.c
-
+
float
Src/main/params_i_out.c
-
+
long
Src/main/params_i_out.c
-
+
long
Src/main/params_i_out.c
-
+
float
Src/main/params_i_out.c
-
+
long
Src/main/params_i_out.c
-
+
long
Src/main/params_i_out.c
-
+
_iq
Src/VectorControl/regul_power.c
-
+
_iq
Src/VectorControl/regul_power.c
-
+
_iq
Src/main/params_i_out.c
-
+
_iq
Src/main/params_i_out.c
-
+
const unsigned long[20]
Src/main/adc_tools.c
-
+
float
Src/myXilinx/RS_Functions.c
-
+
int
Src/myXilinx/x_example_all.c
-
+
unsigned int[70]
Src/myXilinx/RS_Functions.c
-
+
const unsigned int[20]
Src/main/adc_tools.c
-
+
int
Src/myXilinx/x_example_all.c
-
+
_iq
Src/myLibs/mathlib.c
-
+
int[8][128]
Src/myLibs/CAN_Setup.c
-
+
int
Src/main/PWMTools.c
-
+
int
Src/main/PWMTools.c
-
+
int
Src/main/PWMTools.c
-
+
int
Src/main/PWMTools.c
-
+
int
Src/main/PWMTMSHandle.c
-
+
WINDING
Src/main/PWMTools.c
-
+
volatile AddrToSent
Src/myXilinx/xPeriphSP6_loader.c
-
+
unsigned int
Src/myXilinx/RS_Functions_modbus.c
-
+
ALARM_LOG_CAN
Src/myLibs/alarm_log_can.c
-
+
ALARM_LOG_CAN_SETUP
Src/myLibs/CAN_Setup.c
-
+
ANALOG_VALUE
Src/main/adc_tools.c
-
+
int[3][6][4][7]
Src/main/v_pwm24.c
-
+
_iq[7]
Src/main/v_pwm24.c
-
+
int
Src/myLibs/log_to_memory.c
-
+
int
Src/myLibs/log_to_memory.c
-
+
_iq
Src/main/break_regul.c
-
+
_iq
Src/main/break_regul.c
-
+
_iq
Src/main/break_regul.c
-
+
_iq
Src/main/break_regul.c
-
+
Byte
Src/myXilinx/xPeriphSP6_loader.c
-
+
long
Src/main/rotation_speed.c
-
+
int
Src/main/isolation.c
-
+
int
Src/main/isolation.c
-
+
test_functions
Src/main/Main.c
-
+
CANOPEN_CAN_SETUP
Src/myLibs/CAN_Setup.c
-
+
unsigned int
Src/main/sync_tools.c
-
+
unsigned int
Src/main/sync_tools.c
-
+
unsigned int
Src/main/sync_tools.c
-
+
unsigned int
Src/main/sync_tools.c
-
+
unsigned int
Src/myXilinx/x_example_all.c
-
+
BREAK_PHASE_I
Src/main/detect_phase.c
-
+
BREAK_PHASE_I
Src/main/detect_phase.c
-
+
int
Src/myXilinx/RS_Functions_modbus.c
-
+
int
Src/myLibs/alarm_log_can.c
-
+
ControlReg
Src/myXilinx/xPeriphSP6_loader.c
-
+
COS_FI_STRUCT
Src/VectorControl/pwm_vector_regul.c
-
+
unsigned int
Src/main/sync_tools.c
-
+
int
Src/myLibs/modbus_fill_table.c
-
+
int
Src/main/PWMTools.c
-
+
WORD[256]
Src/myXilinx/CRC_Functions.c
-
+
char[34]
Src/myLibs/bender.c
-
+
int
Src/myLibs/message_modbus.c
-
+
CYCLE[32]
Src/myLibs/CAN_Setup.c
-
+
int
Src/main/sync_tools.c
-
+
int
Src/main/sync_tools.c
-
+
volatile DOORS_STATUS
Src/main/doors_control.c
-
+
int
Src/myLibs/message_modbus.c
-
+
int
Src/myLibs/CAN_Setup.c
-
+
_iq
Src/main/adc_tools.c
-
+
_iq
Src/main/adc_tools.c
-
+
unsigned int
Src/main/Main.c
-
+
int
Src/myXilinx/RS_Functions_modbus.c
-
+
int
Src/myXilinx/RS_Functions_modbus.c
-
+
ERRORS
Src/main/errors.c
-
+
FLAG
Src/main/Main.c
-
+
volatile int
Src/myXilinx/xPeriphSP6_loader.c
-
+
FAULTS
Src/main/errors.c
-
+
FIFO
Src/myLibs/CAN_Setup.c
-
+
ANALOG_VALUE
Src/main/adc_tools.c
-
+
int
Src/main/rotation_speed.c
-
+
int
Src/myLibs/CAN_Setup.c
-
+
int
Src/myLibs/CAN_Setup.c
-
+
int
Src/main/PWMTools.c
-
+
unsigned int
Src/myXilinx/RS_Functions_modbus.c
-
+
unsigned int
Src/myLibs/modbus_read_table.c
-
+
unsigned int
Src/myXilinx/RS_Functions_modbus.c
-
+
int
Src/myLibs/modbus_fill_table.c
-
+
int
Src/main/PWMTools.c
-
+
_iq
Src/main/PWMTools.c
-
+
float
Src/myXilinx/RS_Functions.c
-
+
GLOBAL_TIME
Src/main/global_time.c
-
+
int
Src/myLibs/log_to_memory.c
-
+
int
Src/main/PWMTools.c
-
+
BREAK2_PHASE
Src/main/errors.c
-
+
BREAK2_PHASE
Src/main/errors.c
-
+
int[3]
Src/myLibs/log_can.c
-
+
_iq19[20]
Src/main/adc_tools.c
-
+
_iq19[20]
Src/main/adc_tools.c
-
+
_iq
Src/main/v_pwm24.c
-
+
_iq[20]
Src/main/adc_tools.c
-
+
IQ_LOGSPARAMS
Src/myLibs/log_to_memory.c
-
+
_iq
Src/myLibs/svgen_dq_v2.c
-
+
_iq[20]
Src/main/adc_tools.c
-
+
ISOLATION
Src/main/isolation.c
-
+
ISOLATION
Src/main/isolation.c
-
+
_iq
Src/main/PWMTools.c
-
+
float
Src/VectorControl/pwm_vector_regul.c
-
+
float
Src/VectorControl/pwm_vector_regul.c
-
+
float
Src/VectorControl/pwm_vector_regul.c
-
+
float
Src/VectorControl/pwm_vector_regul.c
-
+
float
Src/VectorControl/pwm_vector_regul.c
-
+
float
Src/VectorControl/pwm_vector_regul.c
-
+
float
Src/VectorControl/pwm_vector_regul.c
-
+
float
Src/VectorControl/pwm_vector_regul.c
-
+
_iq
Src/main/break_regul.c
-
+
_iq
Src/main/adc_tools.c
-
+
_iq
Src/main/adc_tools.c
-
+
_iq
Src/main/adc_tools.c
-
+
_iq
Src/main/break_regul.c
-
+
_iq
Src/main/break_regul.c
-
+
_iq
Src/main/break_regul.c
-
+
_iq
Src/main/adc_tools.c
-
+
_iq
Src/main/adc_tools.c
-
+
_iq
Src/main/adc_tools.c
-
+
_iq
Src/main/adc_tools.c
-
+
_iq
Src/main/rotation_speed.c
-
+
_iq
Src/main/rotation_speed.c
-
+
long
Src/VectorControl/pwm_vector_regul.c
-
+
long
Src/VectorControl/pwm_vector_regul.c
-
+
_iq
Src/VectorControl/regul_power.c
-
+
long
Src/VectorControl/pwm_vector_regul.c
-
+
long
Src/VectorControl/pwm_vector_regul.c
-
+
long
Src/VectorControl/pwm_vector_regul.c
-
+
volatile unsigned long
Src/myXilinx/xPeriphSP6_loader.c
-
+
_iq[13][2]
Src/main/break_tools.c
-
+
logcan_TypeDef
Src/myLibs/log_can.c
-
+
LOG_CAN_SETUP
Src/myLibs/CAN_Setup.c
-
+
TYPE_LOG_PARAMS
Src/myLibs/log_params.c
-
+
long[10]
Src/main/sync_tools.c
-
+
LOGSPARAMS
Src/myLibs/log_to_memory.c
-
+
int
Src/main/PWMTMSHandle.c
-
+
MAILBOXS_CAN_SETUP
Src/myLibs/CAN_Setup.c
-
+
int
Src/myXilinx/xPeriphSP6_loader.c
-
+
MODBUS_REG_STRUCT *
Src/myLibs/modbus_table.c
-
+
MODBUS_REG_STRUCT *
Src/myLibs/modbus_table.c
-
+
MODBUS_REG_STRUCT[450]
Src/myLibs/modbus_table.c
-
+
MODBUS_REG_STRUCT[450]
Src/myLibs/modbus_table.c
-
+
MODBUS_REG_STRUCT *
Src/myLibs/modbus_table.c
-
+
MODBUS_REG_STRUCT *
Src/myLibs/modbus_table.c
-
+
MODBUS_REG_STRUCT[450]
Src/myLibs/modbus_table.c
-
+
MPU_CAN_SETUP
Src/myLibs/CAN_Setup.c
-
+
NEW_CYCLE_FIFO
Src/myLibs/CAN_Setup.c
-
+
int
Src/myLibs/log_to_memory.c
-
+
int
Src/myLibs/log_to_memory.c
-
+
int
Src/myLibs/modbus_fill_table.c
-
+
OPTICAL_BUS_DATA
Src/main/optical_bus.c
-
+
OPTICAL_BUS_DATA
Src/main/optical_bus.c
-
+
MODBUS_REG_STRUCT[200]
Src/myXilinx/RS_Functions_modbus.c
-
+
_iq
Src/main/v_pwm24.c
-
+
PIDREG3
Src/VectorControl/pwm_vector_regul.c
-
+
PIDREG3
Src/VectorControl/pwm_vector_regul.c
-
+
PIDREG3
Src/VectorControl/regul_turns.c
-
+
int
Src/main/message2.c
-
+
int
Src/main/message2.c
-
+
PIDREG3
Src/VectorControl/regul_power.c
-
+
PIDREG3
Src/VectorControl/pwm_vector_regul.c
-
+
PIDREG3
Src/VectorControl/pwm_vector_regul.c
-
+
PIDREG_KOEFFICIENTS
Src/VectorControl/pwm_vector_regul.c
-
+
PIDREG3
Src/VectorControl/teta_calc.c
-
+
POWER_RATIO
Src/myLibs/modbus_read_table.c
-
+
int
Src/main/rotation_speed.c
-
+
unsigned int
Src/myLibs/log_can.c
-
+
T_project
Src/myXilinx/xp_project.c
-
+
PWMGEND
Src/main/PWMTMSHandle.c
-
+
T_controller_read
Src/myXilinx/x_serial_bus.c
-
+
T_controller_read
Src/myXilinx/xp_hwp.c
-
+
FIFO
Src/myLibs/CAN_Setup.c
-
+
TMS_TO_TERMINAL_STRUCT
Src/myXilinx/RS_Functions_modbus.c
-
+
TMS_TO_TERMINAL_TEST_ALL_STRUCT
Src/myXilinx/RS_Functions_modbus.c
-
+
RMP_MY1
Src/main/PWMTools.c
-
+
RMP_MY1
Src/main/rotation_speed.c
-
+
T_rotation_sensor
Src/myXilinx/xp_rotation_sensor.c
-
+
ROTOR_VALUE
Src/main/rotation_speed.c
-
+
RS_DATA_STRUCT
Src/myXilinx/RS_Functions.c
-
+
RS_DATA_STRUCT
Src/myXilinx/RS_Functions.c
-
+
unsigned int
Src/myLibs/modbus_read_table.c
-
+
char
Src/myXilinx/RS_Functions.c
-
+
char
Src/myXilinx/RS_Functions.c
-
+
int
Src/myLibs/log_to_memory.c
-
+
int
Src/myLibs/log_to_memory.c
-
+
int
Src/myLibs/log_to_memory.c
-
+
int
Src/myLibs/log_to_memory.c
-
+
SVGENDQ
Src/main/v_pwm24.c
-
+
SVGENDQ
Src/main/v_pwm24.c
-
+
SVGEN_PWM24
Src/main/v_pwm24.c
-
+
SVGEN_PWM24
Src/main/v_pwm24.c
-
+
unsigned int
Src/main/sync_tools.c
-
+
_iq
Src/main/errors_temperature.c
-
+
INVERTER_TEMPERATURES
Src/main/errors.c
-
+
INVERTER_TEMPERATURES
Src/main/errors.c
-
+
RECTIFIER_TEMPERATURES
Src/main/errors.c
-
+
RECTIFIER_TEMPERATURES
Src/main/errors.c
-
+
TERMINAL_CAN_SETUP
Src/myLibs/CAN_Setup.c
-
+
TETTA_CALC
Src/VectorControl/teta_calc.c
-
+
int
Src/myXilinx/Spartan2E_Functions.c
-
+
int
Src/myXilinx/Spartan2E_Functions.c
-
+
unsigned int
Src/myXilinx/Spartan2E_Functions.c
-
+
float
Src/myXilinx/Spartan2E_Functions.c
-
+
long
Src/myLibs/CAN_Setup.c
-
+
long
Src/myLibs/CAN_Setup.c
-
+
int
Src/myLibs/log_can.c
-
+
int
Src/myLibs/log_can.c
-
+
volatile int
Src/myXilinx/xPeriphSP6_loader.c
-
+
UNITES_CAN_SETUP
Src/myLibs/CAN_Setup.c
-
+
VECTOR_CONTROL
Src/VectorControl/pwm_vector_regul.c
-
+
WaterCooler
Src/myLibs/can_watercool.c
-
+
_iq
Src/main/v_pwm24.c
-
+
Word
Src/myXilinx/xPeriphSP6_loader.c
-
+
WordReversed
Src/myXilinx/xPeriphSP6_loader.c
-
+
WordToReverse
Src/myXilinx/xPeriphSP6_loader.c
-
+
X_PARALLEL_BUS
Src/myXilinx/x_parallel_bus.c
-
+
X_SERIAL_BUS
Src/myXilinx/x_serial_bus.c
-
+
unsigned int
Src/myXilinx/Spartan2E_Functions.c
-
+
unsigned int
Src/myXilinx/Spartan2E_Functions.c
-
+
XPWM_TIME
Src/myXilinx/xp_write_xpwm_time.c
-
+
_iq
Src/VectorControl/pwm_vector_regul.c
-
+
int[20]
Src/main/adc_tools.c
-
-
-
+
+
+