# Path: momo/plugins/flask/filters.py
# def txt_type(s):
# def get_attr(node, attrname, default=None):
# def get_parents(node):
# def slugify(s):
# def attr_image(node):
# def attr_path(node):
# def node_to_path(node):
# def split_path(path):
# def sort_attrs(attrs):
# def pin_attrs(attrs):
# def safe_quote(s):
# 
# Path: momo/plugins/flask/functions.py
# def paginate(page, total, per_page, config):
# def _paginate(page, total, per_page, record_name, display_msg):
# def get_page(request):
# def toggle_arg(endpoint, request, arg, value, **kwargs):
# 
# Path: momo/plugins/flask/utils.py
# def get_public_functions(module):
#     """Get public functions in a module. Return a dictionary of function names
#     to objects."""
#     return {
#         o[0]: o[1] for o in getmembers(module, isfunction)
#         if not o[0].startswith('_')
#     }
# 
# Path: momo/plugins/flask/sorting.py
# def sort_nodes_by_request(nodes, request, g, default_terms=None):
#     """High-level function to sort nodes with a request object."""
#     sorting_terms = request.args.getlist('sort') or default_terms
#     desc = request.args.get('desc', default=False, type=str_to_bool)
#     if not sorting_terms:
#         if desc:
#             nodes.reverse()
#     else:
#         nodes = sort_nodes_by_terms(
#             terms=sorting_terms,
#             nodes=nodes,
#             desc=desc,
#             functions=g.sorting_functions,
#         )
#     return nodes
# 
# Path: momo/plugins/flask/nodes.py
# def merge_nodes(nodes):
#     """
#     Merge nodes to deduplicate same-name nodes and add a "parents"
#     attribute to each node, which is a list of Node objects.
#     """
# 
#     def add_parent(unique_node, parent):
#         if getattr(unique_node, 'parents', None):
#             if parent.name not in unique_node.parents:
#                 unique_node.parents[parent.name] = parent
#         else:
#             unique_node.parents = {parent.name: parent}
# 
#     names = OrderedDict()
#     for node in nodes:
#         if node.name not in names:
#             names[node.name] = node
#             add_parent(names[node.name], node.parent)
#         else:
#             add_parent(names[node.name], node.parent)
#     return names.values()
# 
# Path: momo/utils.py
# def open_default(path):
#     if platform.system() == 'Darwin':
#         sh.open(path)
#     elif os.name == 'nt':
#         os.startfile(path)
#     elif os.name == 'posix':
#         run = sh.Command('xdg-open')
#         run(path)


import os
from flask import (
    Flask,
    g,
    redirect,
    render_template,
    request,
    send_from_directory,
)
from flask_bootstrap import Bootstrap
from momo.plugins.flask import filters, functions
from momo.plugins.flask.utils import get_public_functions
from momo.plugins.flask.sorting import sort_nodes_by_request
from momo.plugins.flask.nodes import merge_nodes
from momo.utils import open_default
        request.args.get('view') or
        app.config['MOMO_VIEW_SEARCH'] or
        app.config['MOMO_VIEW']
    )
    g.per_page = int(
        request.args.get(
            'per_page', app.config['MOMO_PAGINATION_SEARCH_PER_PAGE'])
    )

    g.case_insensitive = app.config['MOMO_CASE_INSENSITIVE']
    g.string_separator = app.config['MOMO_STRING_SEPARATOR']

    funcs['pre_search'](
        root=root,
        term=term,
        request=request,
    )

    nodes = funcs['process_search'](
        root=root,
        term=term,
        request=request,
    )

    # sort nodes by request args
    default_reverse = app.config['MOMO_ROOT_REVERSED']
    if default_reverse:
        nodes.reverse()

    if app.config['MOMO_MERGE_NODES']:

# Path: momo/plugins/flask/filters.py
# def txt_type(s):
# def get_attr(node, attrname, default=None):
# def get_parents(node):
# def slugify(s):
# def attr_image(node):
# def attr_path(node):
# def node_to_path(node):
# def split_path(path):
# def sort_attrs(attrs):
# def pin_attrs(attrs):
# def safe_quote(s):
# 
# Path: momo/plugins/flask/functions.py
# def paginate(page, total, per_page, config):
# def _paginate(page, total, per_page, record_name, display_msg):
# def get_page(request):
# def toggle_arg(endpoint, request, arg, value, **kwargs):
# 
# Path: momo/plugins/flask/utils.py
# def get_public_functions(module):
#     """Get public functions in a module. Return a dictionary of function names
#     to objects."""
#     return {
#         o[0]: o[1] for o in getmembers(module, isfunction)
#         if not o[0].startswith('_')
#     }
# 
# Path: momo/plugins/flask/sorting.py
# def sort_nodes_by_request(nodes, request, g, default_terms=None):
#     """High-level function to sort nodes with a request object."""
#     sorting_terms = request.args.getlist('sort') or default_terms
#     desc = request.args.get('desc', default=False, type=str_to_bool)
#     if not sorting_terms:
#         if desc:
#             nodes.reverse()
#     else:
#         nodes = sort_nodes_by_terms(
#             terms=sorting_terms,
#             nodes=nodes,
#             desc=desc,
#             functions=g.sorting_functions,
#         )
#     return nodes
# 
# Path: momo/plugins/flask/nodes.py
# def merge_nodes(nodes):
#     """
#     Merge nodes to deduplicate same-name nodes and add a "parents"
#     attribute to each node, which is a list of Node objects.
#     """
# 
#     def add_parent(unique_node, parent):
#         if getattr(unique_node, 'parents', None):
#             if parent.name not in unique_node.parents:
#                 unique_node.parents[parent.name] = parent
#         else:
#             unique_node.parents = {parent.name: parent}
# 
#     names = OrderedDict()
#     for node in nodes:
#         if node.name not in names:
#             names[node.name] = node
#             add_parent(names[node.name], node.parent)
#         else:
#             add_parent(names[node.name], node.parent)
#     return names.values()
# 
# Path: momo/utils.py
# def open_default(path):
#     if platform.system() == 'Darwin':
#         sh.open(path)
#     elif os.name == 'nt':
#         os.startfile(path)
#     elif os.name == 'posix':
#         run = sh.Command('xdg-open')
#         run(path)


# Path: momo/plugins/flask/app.py
import os
from flask import (
    Flask,
    g,
    redirect,
    render_template,
    request,
    send_from_directory,
)
from flask_bootstrap import Bootstrap
from momo.plugins.flask import filters, functions
from momo.plugins.flask.utils import get_public_functions
from momo.plugins.flask.sorting import sort_nodes_by_request
from momo.plugins.flask.nodes import merge_nodes
from momo.utils import open_default

        request.args.get('view') or
        app.config['MOMO_VIEW_SEARCH'] or
        app.config['MOMO_VIEW']
    )
    g.per_page = int(
        request.args.get(
            'per_page', app.config['MOMO_PAGINATION_SEARCH_PER_PAGE'])
    )

    g.case_insensitive = app.config['MOMO_CASE_INSENSITIVE']
    g.string_separator = app.config['MOMO_STRING_SEPARATOR']

    funcs['pre_search'](
        root=root,
        term=term,
        request=request,
    )

    nodes = funcs['process_search'](
        root=root,
        term=term,
        request=request,
    )

    # sort nodes by request args
    default_reverse = app.config['MOMO_ROOT_REVERSED']
    if default_reverse:
        nodes.reverse()

    if app.config['MOMO_MERGE_NODES']:

        nodes = merge_nodes(nodes)