# Path: sark/code/line.py
# def lines(start=None, end=None, reverse=False, selection=False):
#     """Iterate lines in range.
# 
#     Args:
#         start: Starting address, start of IDB if `None`.
#         end: End address, end of IDB if `None`.
#         reverse: Set to true to iterate in reverse order.
#         selection: If set to True, replaces start and end with current selection.
# 
#     Returns:
#         iterator of `Line` objects.
#     """
#     if selection:
#         start, end = get_selection()
# 
#     else:
#         start, end = fix_addresses(start, end)
# 
#     if not reverse:
#         item = idaapi.get_item_head(start)
#         while item < end:
#             yield Line(item)
#             item += idaapi.get_item_size(item)
# 
#     else:  # if reverse:
#         item = idaapi.get_item_head(end - 1)
#         while item >= start:
#             yield Line(item)
#             item = idaapi.get_item_head(item - 1)
# 
# Path: sark/code/function.py
# def functions(start=None, end=None):
#     """Get all functions in range.
# 
#     Args:
#         start: Start address of the range. Defaults to IDB start.
#         end: End address of the range. Defaults to IDB end.
# 
#     Returns:
#         This is a generator that iterates over all the functions in the IDB.
#     """
#     start, end = fix_addresses(start, end)
# 
#     for func_t in idautils.Functions(start, end):
#         yield Function(func_t)
# 
# Path: sark/core.py
# def get_func(func_ea):
#     """get_func(func_t or ea) -> func_t
# 
#     Take an IDA function (``idaapi.func_t``) or an address (EA) and return
#     an IDA function object.
# 
#     Use this when APIs can take either a function or an address.
# 
#     Args:
#         func_ea: ``idaapi.func_t`` or ea of the function.
# 
#     Returns:
#         An ``idaapi.func_t`` object for the given address. If a ``func_t`` is
#         provided, it is returned.
#     """
#     if isinstance(func_ea, idaapi.func_t):
#         return func_ea
#     func = idaapi.get_func(func_ea)
#     if func is None:
#         raise exceptions.SarkNoFunction("No function at 0x{:08X}".format(func_ea))
# 
#     return func
# 
# def fix_addresses(start=None, end=None):
#     """Set missing addresses to start and end of IDB.
# 
#     Take a start and end addresses. If an address is None or `BADADDR`,
#     return start or end addresses of the IDB instead.
# 
#     Args
#         start: Start EA. Use `None` to get IDB start.
#         end:  End EA. Use `None` to get IDB end.
# 
#     Returns:
#         (start, end)
#     """
#     if start in (None, idaapi.BADADDR):
#         start = idaapi.cvar.inf.minEA
# 
#     if end in (None, idaapi.BADADDR):
#         end = idaapi.cvar.inf.maxEA
# 
#     return start, end


import networkx
import idaapi
from .code import lines, functions
from .core import get_func, fix_addresses

    @color.setter
    def color(self, color):
        self.set_color(color)

    def __repr__(self):
        return "<CodeBlock(start_ea=0x{:08X}, end_ea=0x{:08X})>".format(self.start_ea, self.end_ea)

    def __eq__(self, other):
        return self.start_ea == other.start_ea


class FlowChart(idaapi.FlowChart):
    def __init__(self, f=None, bounds=None, flags=idaapi.FC_PREDS, ignore_external=False):
        if f is None and bounds is None:
            f = idaapi.get_screen_ea()
        if f is not None:
            f = get_func(f)
        if ignore_external:
            flags |= idaapi.FC_NOEXT

        super(FlowChart, self).__init__(f=f, bounds=bounds, flags=flags)

    def _getitem(self, index):
        return CodeBlock(index, self._q[index], self)


def get_flowchart(ea=None):
    if ea is None:
        ea = idaapi.get_screen_ea()

# Path: sark/code/line.py
# def lines(start=None, end=None, reverse=False, selection=False):
#     """Iterate lines in range.
# 
#     Args:
#         start: Starting address, start of IDB if `None`.
#         end: End address, end of IDB if `None`.
#         reverse: Set to true to iterate in reverse order.
#         selection: If set to True, replaces start and end with current selection.
# 
#     Returns:
#         iterator of `Line` objects.
#     """
#     if selection:
#         start, end = get_selection()
# 
#     else:
#         start, end = fix_addresses(start, end)
# 
#     if not reverse:
#         item = idaapi.get_item_head(start)
#         while item < end:
#             yield Line(item)
#             item += idaapi.get_item_size(item)
# 
#     else:  # if reverse:
#         item = idaapi.get_item_head(end - 1)
#         while item >= start:
#             yield Line(item)
#             item = idaapi.get_item_head(item - 1)
# 
# Path: sark/code/function.py
# def functions(start=None, end=None):
#     """Get all functions in range.
# 
#     Args:
#         start: Start address of the range. Defaults to IDB start.
#         end: End address of the range. Defaults to IDB end.
# 
#     Returns:
#         This is a generator that iterates over all the functions in the IDB.
#     """
#     start, end = fix_addresses(start, end)
# 
#     for func_t in idautils.Functions(start, end):
#         yield Function(func_t)
# 
# Path: sark/core.py
# def get_func(func_ea):
#     """get_func(func_t or ea) -> func_t
# 
#     Take an IDA function (``idaapi.func_t``) or an address (EA) and return
#     an IDA function object.
# 
#     Use this when APIs can take either a function or an address.
# 
#     Args:
#         func_ea: ``idaapi.func_t`` or ea of the function.
# 
#     Returns:
#         An ``idaapi.func_t`` object for the given address. If a ``func_t`` is
#         provided, it is returned.
#     """
#     if isinstance(func_ea, idaapi.func_t):
#         return func_ea
#     func = idaapi.get_func(func_ea)
#     if func is None:
#         raise exceptions.SarkNoFunction("No function at 0x{:08X}".format(func_ea))
# 
#     return func
# 
# def fix_addresses(start=None, end=None):
#     """Set missing addresses to start and end of IDB.
# 
#     Take a start and end addresses. If an address is None or `BADADDR`,
#     return start or end addresses of the IDB instead.
# 
#     Args
#         start: Start EA. Use `None` to get IDB start.
#         end:  End EA. Use `None` to get IDB end.
# 
#     Returns:
#         (start, end)
#     """
#     if start in (None, idaapi.BADADDR):
#         start = idaapi.cvar.inf.minEA
# 
#     if end in (None, idaapi.BADADDR):
#         end = idaapi.cvar.inf.maxEA
# 
#     return start, end


# Path: sark/codeblock.py
import networkx
import idaapi
from .code import lines, functions
from .core import get_func, fix_addresses


    @color.setter
    def color(self, color):
        self.set_color(color)

    def __repr__(self):
        return "<CodeBlock(start_ea=0x{:08X}, end_ea=0x{:08X})>".format(self.start_ea, self.end_ea)

    def __eq__(self, other):
        return self.start_ea == other.start_ea


class FlowChart(idaapi.FlowChart):
    def __init__(self, f=None, bounds=None, flags=idaapi.FC_PREDS, ignore_external=False):
        if f is None and bounds is None:
            f = idaapi.get_screen_ea()
        if f is not None:
            f = get_func(f)
        if ignore_external:
            flags |= idaapi.FC_NOEXT

        super(FlowChart, self).__init__(f=f, bounds=bounds, flags=flags)

    def _getitem(self, index):
        return CodeBlock(index, self._q[index], self)


def get_flowchart(ea=None):
    if ea is None:
        ea = idaapi.get_screen_ea()

    func = idaapi.get_func(ea)