# Исходный код components.json_container_component

    """Модуль для работы с JSON-контейнерами на веб-страницах.

    Содержит компонент для чтения и проверки JSON-данных в контейнерах.
    Использует playwright для взаимодействия с элементами страницы.
    """

    import json
    import re
    from typing import Any, Dict
    import jsondiff
    from playwright.sync_api import Page
    from tools.logger import get_logger
    from components.base_component import BaseComponent

    logger = get_logger("JSON_CONTAINER")

    class JsonContainerComponent(BaseComponent):
        """Компонент для работы с JSON-данными на странице.

        Предоставляет методы чтения и проверки JSON-данных в контейнерах.
        """

        def __init__(self, page: Page) -> None:
            """Инициализирует JSON-контейнер.

            Args:
                page: Экземпляр страницы Playwright.
            """
            self.page = page

        def format_json_string(self, json_string: str) -> str:
            """Форматирует строку JSON для корректного парсинга.

            Args:
                json_string: Сырая строка с JSON-данными.

            Returns:
                str: Отформатированная строка JSON.
            """
            lines = json_string.splitlines()
            formatted_lines = []
            stack = []  # Стек для отслеживания вложенности
            current_indent = 0

            for line in lines:
                line = line.strip()
                if not line:
                    continue

                # Определяем тип текущей строки
                if line in ['{', '[']:
                    formatted_lines.append('  ' * current_indent + line)
                    stack.append(line)
                    current_indent += 1
                elif line in ['}', ']']:
                    current_indent -= 1
                    if stack and stack[-1] in ['{', '[']:
                        stack.pop()
                    formatted_lines.append('  ' * current_indent + line)
                elif re.match(r'^\d+:\{', line):
                    formatted_lines.append('  ' * current_indent + '{')
                    stack.append('{')
                    current_indent += 1
                elif ':' in line:
                    key, value = line.split(':', 1)
                    key = key.strip()
                    value = value.strip()

                    if not (key.startswith('"') and key.endswith('"')):
                        key = f'"{key}"'

                    if value in ['{', '[']:
                        formatted_line = f'{key}: {value}'
                        formatted_lines.append('  ' * current_indent + formatted_line)
                        stack.append(value)
                        current_indent += 1
                    elif value in ['}', ']']:
                        current_indent -= 1
                        formatted_line = f'{key}: {value}'
                        formatted_lines.append('  ' * current_indent + formatted_line)
                        if stack:
                            stack.pop()
                    else:
                        if (value and not value.isdigit() and
                            not value.replace('.', '', 1).isdigit() and
                            value not in ['true', 'false', 'null'] and
                            not value.startswith('"') and not value.endswith('"') and
                            not value.startswith('{') and not value.startswith('[')):
                            value = f'"{value}"'

                        formatted_line = f'{key}: {value}'
                        formatted_lines.append('  ' * current_indent + formatted_line)
                else:
                    formatted_lines.append('  ' * current_indent + line)

            # Добавляем запятые где необходимо
            result = []
            total_lines = len(formatted_lines)

            for i, current_line in enumerate(formatted_lines):
                if i < total_lines - 1:
                    next_line = formatted_lines[i + 1]
                    in_array = any(bracket == '[' for bracket in stack)

                    # Упрощенная проверка условий для запятой
                    no_comma_condition1 = current_line.endswith(('{', '[', ','))
                    no_comma_condition2 = next_line.strip().endswith(('}', ']'))
                    no_comma_condition3 = next_line.strip().startswith(('}', ']'))
                    no_comma_condition4 = in_array and next_line.strip() == ']'

                    should_add_comma = not (no_comma_condition1 or no_comma_condition2 or
                                          no_comma_condition3 or no_comma_condition4)

                    # Специальный случай для элементов массива
                    if (in_array and current_line.strip() == '}' and
                        next_line.strip() != ']' and not next_line.strip().startswith('}')):
                        should_add_comma = True

                    if should_add_comma:
                        current_line += ','

                result.append(current_line)

            return '\n'.join(result)

        def read_data(self, locator: Any) -> Dict:
            """Читает и форматирует JSON-данные из указанного локатора.

            Args:
                locator: Локатор элемента с JSON-данными.

            Returns:
                dict: Распарсенный JSON-объект.

            Raises:
                json.JSONDecodeError: Если данные не могут быть преобразованы в JSON.
            """
            loc = self.get_locator(locator)
            json_string = loc.inner_text()
            formatted_json_string = self.format_json_string(json_string)

            try:
                data = json.loads(formatted_json_string)
            except json.JSONDecodeError as e:
                logger.error("JSON decode error: %s", e)
                logger.error("Formatted JSON: %s", formatted_json_string)
                assert False, f"Invalid json content. Error: {e}"

            return data

        def check_json_equals(self, actual: Any, expected: Any, msg: str) -> None:
            """Сравнивает JSON-объекты на идентичность.

            Args:
                actual: Фактический JSON-объект.
                expected: Ожидаемый JSON-объект.
                msg: Сообщение об ошибке.

            Raises:
                AssertionError: Если объекты не идентичны.
            """
            diff = jsondiff.diff(expected, actual, syntax='symmetric')
            assert len(diff) == 0, f"{msg}. DIFF is {diff}"