Python anytree.RenderTree() Examples

The following are 26 code examples of anytree.RenderTree(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module anytree , or try the search function .
Example #1
Source File: groups_scanner_test.py    From forseti-security with Apache License 2.0 7 votes vote down vote up
def _render_ascii(self, starting_node, attr):
        """Render an ascii representation of the tree structure.

        Args:
            starting_node: The starting node to render the ascii.

        Returns:
            attr: String of the attribute to render.
        """
        rows = []
        for pre, fill, node in anytree.RenderTree(starting_node,
                                                  style=anytree.AsciiStyle()):
            value = getattr(node, attr, "")
            if isinstance(value, (list, tuple)):
                lines = value
            else:
                lines = str(value).split("\n")
            rows.append(u"%s%s" % (pre,
                                   json.dumps(lines[0], sort_keys=True)))
            for line in lines[1:]:
                rows.append(u"%s%s" % (fill,
                                       json.dumps(line, sort_keys=True)))

        return '\n'.join(rows) 
Example #2
Source File: reencode.py    From Offensive-Security-Certified-Professional with MIT License 6 votes vote down vote up
def process(self, data):
        root = anytree.Node('None', decoded = data)
        prev = root

        for (name, curr, branch) in self.generateEncodingTree(data):
            ReEncoder.log('[*] Generator returned: ("{}", "{}", {})'.format(
                name, curr[:20], str(branch)
            ))

            currNode = anytree.Node(name, parent = prev, decoded = curr)
            if branch:
                pass
            else:
                prev = currNode

        for pre, fill, node in anytree.RenderTree(root):
            if node.name != 'None':
                ReEncoder.log("%s%s (%s)" % (pre, node.name, node.decoded[:20].decode('ascii', 'ignore')))

        self.encodings = self.getWinningDecodePath(root)
        ReEncoder.log('[+] Selected encodings: {}'.format(str(self.encodings))) 
Example #3
Source File: burpContextAwareFuzzer.py    From burpContextAwareFuzzer with GNU General Public License v3.0 6 votes vote down vote up
def process(self, data):
        root = anytree.Node('None', decoded = data)
        prev = root

        for (name, curr, branch) in self.generateEncodingTree(data):
            ReEncoder.log('[*] Generator returned: ("{}", "{}", {})'.format(
                name, curr[:20], str(branch)
            ))

            currNode = anytree.Node(name, parent = prev, decoded = curr)
            if branch:
                pass
            else:
                prev = currNode

        for pre, fill, node in anytree.RenderTree(root):
            if node.name != 'None':
                ReEncoder.log("%s%s (%s)" % (pre, node.name, node.decoded[:20].decode('ascii', 'ignore')))

        self.encodings = self.getWinningDecodePath(root)
        ReEncoder.log('[+] Selected encodings: {}'.format(str(self.encodings))) 
Example #4
Source File: test_render.py    From anytree with Apache License 2.0 6 votes vote down vote up
def test_maxlevel():
    root = anytree.Node("root", lines=["c0fe", "c0de"])
    s0 = anytree.Node("sub0", parent=root, lines=["ha", "ba"])
    s0b = anytree.Node("sub0B", parent=s0, lines=["1", "2", "3"])
    s0a = anytree.Node("sub0A", parent=s0, lines=["a", "b"])
    s1 = anytree.Node("sub1", parent=root, lines=["Z"])

    r = anytree.RenderTree(root, maxlevel=2)
    result = [(pre, node) for pre, _, node in r]
    expected = [
        (u'', root),
        (u'├── ', s0),
        (u'└── ', s1),
    ]
    print(expected)
    print(result)
    eq_(result, expected) 
Example #5
Source File: analyzer.py    From bigquery-view-analyzer with MIT License 6 votes vote down vote up
def format_tree(self, show_key=False, show_status=False):
        log.info(f"Formatting tree...")
        tree_string = ""
        key = {
            "project": (Fore.CYAN + "◉" + Fore.RESET + " = Project".ljust(12)),
            "dataset": (Fore.YELLOW + "◉" + Fore.RESET + " = Dataset".ljust(12)),
            "table": (Fore.RED + "◉" + Fore.RESET + " = Table".ljust(12)),
            "view": (Fore.GREEN + "◉" + Fore.RESET + " = View".ljust(12)),
        }
        if show_key:
            tree_string += "Key:\n{}{}\n{}{}\n\n".format(
                key["project"], key["table"], key["dataset"], key["view"]
            )
        for pre, _, node in RenderTree(self.tree):
            tree_string += "%s%s\n" % (
                pre,
                node.pretty_name(show_authorization_status=show_status),
            )
        return tree_string 
Example #6
Source File: groups_scanner.py    From forseti-security with Apache License 2.0 6 votes vote down vote up
def _build_group_tree(self):
        """Build a tree of all the groups in the organization.

        Returns:
            node: The tree structure of all the groups in the organization.
        """
        root = MemberNode(MY_CUSTOMER, MY_CUSTOMER)
        model_manager = self.service_config.model_manager
        scoped_session, data_access = model_manager.get(self.model_name)
        with scoped_session as session:
            all_groups = data_access.iter_groups(session)

            for group in all_groups:
                group_node = MemberNode(group.name,
                                        group.member_name,
                                        group.type,
                                        'ACTIVE',
                                        root)
                self._get_recursive_members(group_node)

        LOGGER.debug(anytree.RenderTree(
            root, style=anytree.AsciiStyle()).by_attr('member_email'))

        return root 
Example #7
Source File: test_examples.py    From anytree with Apache License 2.0 6 votes vote down vote up
def test_stackoverflow():
    """Example from stackoverflow."""
    udo = Node("Udo")
    marc = Node("Marc", parent=udo)
    Node("Lian", parent=marc)
    dan = Node("Dan", parent=udo)
    Node("Jet", parent=dan)
    Node("Jan", parent=dan)
    joe = Node("Joe", parent=dan)

    eq_(str(udo), "Node('/Udo')")
    eq_(str(joe), "Node('/Udo/Dan/Joe')")

    eq_(["%s%s" % (pre, node.name) for pre, fill, node in RenderTree(udo)], [
        u"Udo",
        u"├── Marc",
        u"│   └── Lian",
        u"└── Dan",
        u"    ├── Jet",
        u"    ├── Jan",
        u"    └── Joe",
    ])
    eq_(str(dan.children),
        "(Node('/Udo/Dan/Jet'), Node('/Udo/Dan/Jan'), Node('/Udo/Dan/Joe'))") 
Example #8
Source File: test_node_sep.py    From anytree with Apache License 2.0 6 votes vote down vote up
def test_render():
    """Render string cast."""
    root = MyNode("root")
    s0 = MyNode("sub0", parent=root)
    MyNode("sub0B", parent=s0)
    MyNode("sub0A", parent=s0)
    MyNode("sub1", parent=root)
    r = at.RenderTree(root)

    expected = u"\n".join([
        u"MyNode('|root')",
        u"├── MyNode('|root|sub0')",
        u"│   ├── MyNode('|root|sub0|sub0B')",
        u"│   └── MyNode('|root|sub0|sub0A')",
        u"└── MyNode('|root|sub1')",
    ])
    if six.PY2:
        eq_(str(r).decode('utf-8'), expected)
    else:
        eq_(str(r), expected) 
Example #9
Source File: decision_tree.py    From Data-Science-Algorithms-in-a-Week with MIT License 5 votes vote down vote up
def display_tree(tree):
    anytree = convert_tree_to_anytree(tree)
    for pre, fill, node in RenderTree(anytree):
        pre = pre.encode(encoding='UTF-8', errors='strict')
        print("%s%s" % (pre, node.name))

# A simple textual output of a tree without the visualization. 
Example #10
Source File: securityheader.py    From securityheaders with Apache License 2.0 5 votes vote down vote up
def get_all_checker_names_as_tree_string(self):
        return RenderTree(self.get_all_checker_names_as_tree(), style=ContStyle(), childiter=lambda items: sorted(items, key=lambda item: item.name)).by_attr("name") 
Example #11
Source File: noder.py    From catcli with GNU General Public License v3.0 5 votes vote down vote up
def print_tree(self, node, style=anytree.ContRoundStyle()):
        '''print the tree similar to unix tool "tree"'''
        rend = anytree.RenderTree(node, childiter=self._sort_tree)
        for pre, fill, node in rend:
            self._print_node(node, pre=pre, withdepth=True) 
Example #12
Source File: explorer.py    From ioc-explorer with MIT License 5 votes vote down vote up
def main(ioc_file, output_dir):

    with open(ioc_file) as csvfile:
        iocreader = csv.reader(csvfile, delimiter=',')
        for row in iocreader:
            root = AnyNode(id=row[1], type=row[0])

            logger.info('=========Start to explore IOC: %s', root.id)

            ioc_list = build_ioc_relation(root)

            timestamp = datetime.now().strftime('%Y%m%d%H%M')
            query_depth = config.get('general','depth')

            txtfile = output_dir + root.id + '_depth_'+ query_depth + '_'+timestamp + '.txt'
            file = open(txtfile, "w")
            file.write(str(RenderTree(root)))
            file.close()

            logger.info('Export IOCs to TXT file: %s', txtfile)

            jsonfile = output_dir + root.id + '_depth_'+ query_depth + '_'+timestamp + '.json'
            file = open(jsonfile, "w")
            exporter = JsonExporter(indent=2, sort_keys=False)
            exporter.write(root, file)
            file.close()

            logger.info('Export IOCs to JSON file: %s', jsonfile)

            logger.info('=========Done exploration for IOC: %s', root.id)

    return 
Example #13
Source File: test_render.py    From anytree with Apache License 2.0 5 votes vote down vote up
def test_by_attr():
    """by attr."""
    root = anytree.Node("root", lines=["root"])
    s0 = anytree.Node("sub0", parent=root, lines=["su", "b0"])
    anytree.Node("sub0B", parent=s0, lines=["sub", "0B"])
    anytree.Node("sub0A", parent=s0)
    anytree.Node("sub1", parent=root, lines=["sub1"])
    eq_(anytree.RenderTree(root).by_attr(),
        u"root\n├── sub0\n│   ├── sub0B\n│   └── sub0A\n└── sub1")
    eq_(anytree.RenderTree(root).by_attr("lines"),
        u"root\n├── su\n│   b0\n│   ├── sub\n│   │   0B\n│   └── \n└── sub1")
    eq_(anytree.RenderTree(root).by_attr(lambda node: ":".join(node.name)),
        u"r:o:o:t\n├── s:u:b:0\n│   ├── s:u:b:0:B\n│   └── s:u:b:0:A\n└── s:u:b:1") 
Example #14
Source File: test_render.py    From anytree with Apache License 2.0 5 votes vote down vote up
def test_render():
    """Rendering."""
    root = anytree.Node("root", lines=["c0fe", "c0de"])
    s0 = anytree.Node("sub0", parent=root, lines=["ha", "ba"])
    s0b = anytree.Node("sub0B", parent=s0, lines=["1", "2", "3"])
    s0a = anytree.Node("sub0A", parent=s0, lines=["a", "b"])
    s1 = anytree.Node("sub1", parent=root, lines=["Z"])

    r = anytree.RenderTree(root, style=anytree.DoubleStyle)
    result = [(pre, node) for pre, _, node in r]
    expected = [
        (u'', root),
        (u'╠══ ', s0),
        (u'║   ╠══ ', s0b),
        (u'║   ╚══ ', s0a),
        (u'╚══ ', s1),
    ]
    eq_(result, expected)

    def multi(root):
        for pre, fill, node in anytree.RenderTree(root):
            yield "%s%s" % (pre, node.lines[0]), node
            for line in node.lines[1:]:
                yield "%s%s" % (fill, line), node
    result = list(multi(root))
    expected = [
        (u'c0fe', root),
        (u'c0de', root),
        (u'├── ha', s0),
        (u'│   ba', s0),
        (u'│   ├── 1', s0b),
        (u'│   │   2', s0b),
        (u'│   │   3', s0b),
        (u'│   └── a', s0a),
        (u'│       b', s0a),
        (u'└── Z', s1),
    ]
    eq_(result, expected) 
Example #15
Source File: test_render.py    From anytree with Apache License 2.0 5 votes vote down vote up
def test_render_str():
    """Render string cast."""
    root = anytree.Node("root")
    s0 = anytree.Node("sub0", parent=root)
    anytree.Node("sub0B", parent=s0)
    anytree.Node("sub0A", parent=s0)
    anytree.Node("sub1", parent=root)
    r = anytree.RenderTree(root)

    expected = u"\n".join([
        u"Node('/root')",
        u"├── Node('/root/sub0')",
        u"│   ├── Node('/root/sub0/sub0B')",
        u"│   └── Node('/root/sub0/sub0A')",
        u"└── Node('/root/sub1')",
    ])
    eq_str(str(r), expected)

    r = anytree.RenderTree(root, childiter=lambda nodes: [n for n in nodes if len(n.name) < 5])

    expected = u"\n".join([
        u"Node('/root')",
        u"├── Node('/root/sub0')",
        u"└── Node('/root/sub1')",
    ])
    eq_str(str(r), expected) 
Example #16
Source File: test_dictimporter.py    From anytree with Apache License 2.0 5 votes vote down vote up
def test_dict_importer_node():
    """Dict Importer."""
    importer = DictImporter(Node)
    exporter = DictExporter()
    refdata = {
        'name': 'root', 'children': [
            {'name': 'sub0', 'children': [
                {'name': 'sub0B'},
                {'name': 'sub0A'}
            ]},
            {'name': 'sub1', 'children': [
                {'name': 'sub1A'},
                {'name': 'sub1B'},
                {'name': 'sub1C', 'children': [
                    {'name': 'sub1Ca'}
                ]}
            ]}
        ]}
    data = deepcopy(refdata)
    root = importer.import_(data)
    eq_(data, refdata)
    eq_(exporter.export(root), data)
    r = RenderTree(root)
    expected = u"\n".join([
        u"Node('/root')",
        u"├── Node('/root/sub0')",
        u"│   ├── Node('/root/sub0/sub0B')",
        u"│   └── Node('/root/sub0/sub0A')",
        u"└── Node('/root/sub1')",
        u"    ├── Node('/root/sub1/sub1A')",
        u"    ├── Node('/root/sub1/sub1B')",
        u"    └── Node('/root/sub1/sub1C')",
        u"        └── Node('/root/sub1/sub1C/sub1Ca')",
    ])
    eq_str(str(r), expected) 
Example #17
Source File: test_dictimporter.py    From anytree with Apache License 2.0 5 votes vote down vote up
def test_dict_importer():
    """Dict Importer."""
    importer = DictImporter()
    exporter = DictExporter()
    refdata = {
        'id': 'root', 'children': [
            {'id': 'sub0', 'children': [
                {'id': 'sub0B'},
                {'id': 'sub0A'}
            ]},
            {'id': 'sub1', 'children': [
                {'id': 'sub1A'},
                {'id': 'sub1B'},
                {'id': 'sub1C', 'children': [
                    {'id': 'sub1Ca'}
                ]}
            ]}
        ]}
    data = deepcopy(refdata)
    root = importer.import_(data)
    eq_(data, refdata)
    eq_(exporter.export(root), data)
    r = RenderTree(root)
    expected = u"\n".join([
        u"AnyNode(id='root')",
        u"├── AnyNode(id='sub0')",
        u"│   ├── AnyNode(id='sub0B')",
        u"│   └── AnyNode(id='sub0A')",
        u"└── AnyNode(id='sub1')",
        u"    ├── AnyNode(id='sub1A')",
        u"    ├── AnyNode(id='sub1B')",
        u"    └── AnyNode(id='sub1C')",
        u"        └── AnyNode(id='sub1Ca')",
    ])
    eq_str(str(r), expected) 
Example #18
Source File: __init__.py    From apkutils with MIT License 5 votes vote down vote up
def pretty_print(node):
        """漂亮地打印一个节点

        Args:
            node (TYPE): Description
        """
        for pre, _, node in RenderTree(node):
            print('{}{}'.format(pre, node.name)) 
Example #19
Source File: tree.py    From devito with MIT License 5 votes vote down vote up
def render(stree):
    return RenderTree(stree, style=ContStyle()).by_attr('__repr_render__') 
Example #20
Source File: reinsurance_layer.py    From OasisLMF with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def _log_tree(self, program_node):
        if self.logger:
            self.logger.debug('program_node tree: "{}"'.format(self.name))
            self.logger.debug(anytree.RenderTree(program_node)) 
Example #21
Source File: dptmount.py    From dpt-rp1-py with MIT License 5 votes vote down vote up
def __init__(
        self,
        dpt_ip_address=None,
        dpt_serial_number=None,
        dpt_key=None,
        dpt_client_id=None,
        uid=None,
        gid=None,
    ):
        self.dpt_ip_address = dpt_ip_address
        self.dpt_serial_number = dpt_serial_number
        self.dpt_key = os.path.expanduser(dpt_key)
        self.dpt_client_id = os.path.expanduser(dpt_client_id)
        self.uid = uid
        self.gid = gid
        self.__authenticate__()

        # Create root node
        self.__init_empty_tree()

        # Cache this for the session
        logger.info("Loading initial document list")
        self._load_document_list()
        logger.debug(anytree.RenderTree(self.root))

        self.handle = {}
        self.files = {}
        self.fd = 0 
Example #22
Source File: lib.py    From johnnydep with MIT License 5 votes vote down vote up
def gen_table(johnnydist, extra_cols=()):
    extra_cols = OrderedDict.fromkeys(extra_cols)  # de-dupe and preserve ordering
    extra_cols.pop("name", None)  # this is always included anyway, no need to ask for it
    johnnydist.log.debug("generating table")
    for pre, _fill, node in anytree.RenderTree(johnnydist):
        row = OrderedDict()
        name = str(node.req)
        if "specifier" in extra_cols:
            name = wimpy.strip_suffix(name, str(node.specifier))
        row["name"] = pre + name
        for col in extra_cols:
            val = getattr(node, col, "")
            if isinstance(val, list):
                val = ", ".join(val)
            row[col] = val
        yield row 
Example #23
Source File: decision_tree.py    From Data-Science-Algorithms-in-a-Week-Second-Edition with MIT License 5 votes vote down vote up
def display_tree(tree):
    anytree = convert_tree_to_anytree(tree)
    for pre, fill, node in RenderTree(anytree):
        pre = pre.encode(encoding='UTF-8', errors='strict')
        print("%s%s" % (pre, node.name))

# A simple textual output of a tree without the visualization. 
Example #24
Source File: utils.py    From ocdeployer with MIT License 4 votes vote down vote up
def get_build_tree(buildconfigs):
    """
    Analyze build configurations to find which builds are 'linked'.

    Linked builds are those which output to an ImageStream that another BuildConfig then
    uses as its 'from' image.

    Returns a list of lists where item 0 in each list is the parent build and the items following
    it are all child build configs that will be fired at some point after the parent completes
    """
    bcs_using_input_image = {}
    bc_creating_output_image = {None: None}
    node_for_bc = {}
    for bc in buildconfigs:
        bc_name = bc["metadata"]["name"]
        node_for_bc[bc_name] = Node(bc_name)

        # look up output image
        if traverse_keys(bc, ["spec", "output", "to", "kind"], "").lower() == "imagestreamtag":
            output_image = bc["spec"]["output"]["to"]["name"]
            bc_creating_output_image[output_image] = bc_name

        # look up input image
        for trigger in traverse_keys(bc, ["spec", "triggers"], []):
            if trigger.get("type", "").lower() == "imagechange":
                input_image = get_input_image(bc, trigger)
                if input_image not in bcs_using_input_image:
                    bcs_using_input_image[input_image] = []
                bcs_using_input_image[input_image].append(bc_name)

    # attach each build to its parent build
    for input_image, bc_names in bcs_using_input_image.items():
        for bc_name in bc_names:
            parent_bc = bc_creating_output_image.get(input_image)
            if parent_bc:
                node_for_bc[bc_name].parent = node_for_bc[parent_bc]

    rendered_trees = []
    root_nodes = [n for _, n in node_for_bc.items() if n.is_root]
    for root_node in root_nodes:
        for pre, _, node in RenderTree(root_node):
            rendered_trees.append(f"  {pre}{node.name}")

    if rendered_trees:
        log.info("build config tree:\n\n%s", "\n".join(rendered_trees))

    return [[node.name for node in PreOrderIter(root_node)] for root_node in root_nodes] 
Example #25
Source File: analytics_api.py    From Apfell with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
def analytics_payload_tree_api(request, user):
    if user['auth'] not in ['access_token', 'apitoken']:
        abort(status_code=403, message="Cannot access via Cookies. Use CLI or access via JS in browser")
    # each payload is the root of a tree, all of the corresponding callbacks that use it are under that tree
    try:
        query = await db_model.operation_query()
        operation = await db_objects.get(query, name=user['current_operation'])
        query = await db_model.payload_query()
        dbpayloads = await db_objects.execute(query.where(Payload.operation == operation))
    except Exception as e:
        return json({'status': 'error', 'error': 'failed to find operation or payloads'})
    display_config = {}
    display_config['inactive'] = False  # by default, include only active callbacks
    display_config['strikethrough'] = False
    if request.method == 'POST':
        data = request.json
        if 'inactive' in data:
            display_config['inactive'] = data['inactive']
        if 'strikethrough' in data:
            display_config['strikethrough'] = data['strikethrough']
    tree = []
    for p in dbpayloads:
        display = await analytics_payload_tree_api_function(p, display_config)
        if display_config['inactive'] or (not display_config['inactive'] and not p.deleted):
            ptree = Node(str(p.id), display=display)
            # now get all callbacks that have this payload tied to it
            query = await db_model.callback_query()
            if display_config['inactive']:
                # we want to display the inactive ones as well
                using_callbacks = await db_objects.execute(query.where(Callback.registered_payload==p))
            else:
                using_callbacks = await db_objects.execute(query.where( (Callback.registered_payload==p) &
                                                                                    (Callback.active == True)))
            tree.append(ptree)
            for c in using_callbacks:
                # each of these callbacks has ptree as an associated payload
                callback_display = await analytics_callback_tree_api_function(c.to_json(), display_config)
                Node(str(c.id), parent=ptree, display=callback_display)
    output = ""
    for t in tree:
        # this is iterating over each payload-based tree
        output += str(RenderTree(t, style=DoubleStyle).by_attr("display")) + "\n"
    return json({'status': 'success', 'output': output}) 
Example #26
Source File: plot.py    From VerticaPy with Apache License 2.0 4 votes vote down vote up
def plot_tree(tree, 
			  metric: str = "probability", 
			  pic_path: str = ""):
	try:
		from anytree import Node, RenderTree
	except:
		raise Exception("You must install the anytree module to be able to plot trees.")
	check_types([
		("metric", metric, [str], False),
		("pic_path", pic_path, [str], False)])
	try:
		import shutil
		screen_columns = shutil.get_terminal_size().columns
	except:
		import os
		screen_rows, screen_columns = os.popen('stty size', 'r').read().split()
	tree_id, nb_nodes, tree_depth, tree_breadth = tree["tree_id"][0], len(tree["node_id"]), max(tree["node_depth"]), sum([1 if item else 0 for item in tree["is_leaf"]])
	print("-" * int(screen_columns))
	print("Tree Id: {}".format(tree_id))
	print("Number of Nodes: {}".format(nb_nodes))
	print("Tree Depth: {}".format(tree_depth))
	print("Tree Breadth: {}".format(tree_breadth))
	print("-" * int(screen_columns))
	tree_nodes = {}
	for idx in range(nb_nodes):
		op = "<" if not(tree["is_categorical_split"][idx]) else "="
		if (tree["is_leaf"][idx]):
			tree_nodes[tree["node_id"][idx]] = Node('[{}] => {} ({} = {})'.format(tree["node_id"][idx], tree["prediction"][idx], metric, tree["probability/variance"][idx]))
		else:
			tree_nodes[tree["node_id"][idx]] = Node('[{}] ({} {} {} ?)'.format(tree["node_id"][idx], tree["split_predictor"][idx], op, tree["split_value"][idx]))
	for idx, node_id in enumerate(tree["node_id"]):
		if not(tree["is_leaf"][idx]):
			tree_nodes[node_id].children = [tree_nodes[tree["left_child_id"][idx]], tree_nodes[tree["right_child_id"][idx]]]
	for pre, fill, node in RenderTree(tree_nodes[1]):
		print("%s%s" % (pre,node.name)) 
	if (pic_path): 
		from anytree.dotexport import RenderTreeGraph
		RenderTreeGraph(tree_nodes[1]).to_picture(pic_path)
		if (isnotebook()):
			from IPython.core.display import HTML, display
			display(HTML("<img src='{}'>".format(pic_path)))
#---#