# Path: moonlight/util/functional_ops.py
# def flat_map_fn(fn, elems, dtype=None):
#   def compute(i, results):
# 
# Path: moonlight/util/memoize.py
# class MemoizedFunction(object):
#   def __init__(self, function):
#   def __call__(self, *args):
# 
# Path: moonlight/util/segments.py
# class SegmentsMode(enum.Enum):
#   STARTS = 1
#   CENTERS = 2
# def true_segments_1d(segments,
#                      mode=SegmentsMode.CENTERS,
#                      max_gap=0,
#                      min_length=0,
#                      name=None):
# def _segments_1d(values, mode, name=None):
#     def do_segments(values):
#     def empty_segments():
# def peaks(values, minval=None, invalidate_distance=0, name=None):
#     def loop_condition(_, current_peaks):
#     def loop_body(accepted_peaks, current_peaks):
# 
# Path: moonlight/vision/images.py
# def translate(image, x, y):
# 
# Path: moonlight/vision/morphology.py
# def binary_erosion(image, n):
# def binary_dilation(image, n):
# def _repeated_morphological_op(float_image, binary_op, n):
#   def body(i, image):
# def _single_morphological_op(float_image, binary_op):


import numpy as np
import tensorflow as tf
from moonlight.util import functional_ops
from moonlight.util import memoize
from moonlight.util import segments
from moonlight.vision import images
from moonlight.vision import morphology
  def lines(self):
    """The vertical lines.

    Returns:
      int32 tensor of shape (num_lines, 2, 2), storing lines as
          ((start_x, start_y), (end_x, end_y)).
    """
    columns = tf.range(tf.shape(self.image)[1])

    def map_max_gap(max_gap):
      """Process all columns with the given value for max_gap."""
      return functional_ops.flat_map_fn(
          lambda column: self._verticals_in_column(max_gap, column), columns)

    return functional_ops.flat_map_fn(map_max_gap, self.max_gap)

  def _verticals_in_column(self, max_gap, column):
    """Gets the verticals from a single column.

    Args:
      max_gap: The scalar max_gap value to use. int tensor.
      column: The scalar column index. int tensor.

    Returns:
      int32 tensor of shape (num_lines_in_column, 2, 2). All start_x and end_x
          values are equal to column.
    """
    image_column = self.filtered_image[:, column]
    run_starts, run_lengths = segments.true_segments_1d(
        image_column,

# Path: moonlight/util/functional_ops.py
# def flat_map_fn(fn, elems, dtype=None):
#   def compute(i, results):
# 
# Path: moonlight/util/memoize.py
# class MemoizedFunction(object):
#   def __init__(self, function):
#   def __call__(self, *args):
# 
# Path: moonlight/util/segments.py
# class SegmentsMode(enum.Enum):
#   STARTS = 1
#   CENTERS = 2
# def true_segments_1d(segments,
#                      mode=SegmentsMode.CENTERS,
#                      max_gap=0,
#                      min_length=0,
#                      name=None):
# def _segments_1d(values, mode, name=None):
#     def do_segments(values):
#     def empty_segments():
# def peaks(values, minval=None, invalidate_distance=0, name=None):
#     def loop_condition(_, current_peaks):
#     def loop_body(accepted_peaks, current_peaks):
# 
# Path: moonlight/vision/images.py
# def translate(image, x, y):
# 
# Path: moonlight/vision/morphology.py
# def binary_erosion(image, n):
# def binary_dilation(image, n):
# def _repeated_morphological_op(float_image, binary_op, n):
#   def body(i, image):
# def _single_morphological_op(float_image, binary_op):


# Path: moonlight/structure/verticals.py
import numpy as np
import tensorflow as tf
from moonlight.util import functional_ops
from moonlight.util import memoize
from moonlight.util import segments
from moonlight.vision import images
from moonlight.vision import morphology

  def lines(self):
    """The vertical lines.

    Returns:
      int32 tensor of shape (num_lines, 2, 2), storing lines as
          ((start_x, start_y), (end_x, end_y)).
    """
    columns = tf.range(tf.shape(self.image)[1])

    def map_max_gap(max_gap):
      """Process all columns with the given value for max_gap."""
      return functional_ops.flat_map_fn(
          lambda column: self._verticals_in_column(max_gap, column), columns)

    return functional_ops.flat_map_fn(map_max_gap, self.max_gap)

  def _verticals_in_column(self, max_gap, column):
    """Gets the verticals from a single column.

    Args:
      max_gap: The scalar max_gap value to use. int tensor.
      column: The scalar column index. int tensor.

    Returns:
      int32 tensor of shape (num_lines_in_column, 2, 2). All start_x and end_x
          values are equal to column.
    """
    image_column = self.filtered_image[:, column]
    run_starts, run_lengths = segments.true_segments_1d(
        image_column,

        mode=segments.SegmentsMode.STARTS,