static int core_analysis_graph_nodes(RzCore *core, RzAnalysisFunction *fcn, int opts, PJ *pj) {
	rz_return_val_if_fail(fcn && fcn->bbs, -1);
	int is_json = opts & RZ_CORE_ANALYSIS_JSON;
	int is_keva = opts & RZ_CORE_ANALYSIS_KEYVALUE;
	int nodes = 0;
	Sdb *DB = NULL;
	char *pal_jump = palColorFor("graph.true");
	char *pal_fail = palColorFor("graph.false");
	char *pal_trfa = palColorFor("graph.ujump");
	char *pal_curr = palColorFor("graph.current");
	char *pal_traced = palColorFor("graph.traced");
	char *pal_box4 = palColorFor("graph.box4");

	if (is_keva) {
		char ns[64];
		DB = sdb_ns(core->analysis->sdb, "graph", 1);
		snprintf(ns, sizeof(ns), "fcn.0x%08" PFMT64x, fcn->addr);
		DB = sdb_ns(DB, ns, 1);
	}

	if (is_keva) {
		char *ename = sdb_encode((const ut8 *)fcn->name, -1);
		sdb_set(DB, "name", fcn->name, 0);
		sdb_set(DB, "ename", ename, 0);
		free(ename);
		sdb_num_set(DB, "size", rz_analysis_function_linear_size(fcn), 0);
		if (fcn->maxstack > 0) {
			sdb_num_set(DB, "stack", fcn->maxstack, 0);
		}
		sdb_set(DB, "pos", "0,0", 0); // needs to run layout
		sdb_set(DB, "type", rz_analysis_fcntype_tostring(fcn->type), 0);
	} else if (is_json) {
		// TODO: show vars, refs and xrefs
		char *fcn_name_escaped = rz_str_escape_utf8_for_json(fcn->name, -1);
		pj_o(pj);
		pj_ks(pj, "name", rz_str_get_null(fcn_name_escaped));
		free(fcn_name_escaped);
		pj_kn(pj, "offset", fcn->addr);
		pj_ki(pj, "ninstr", fcn->ninstr);
		pj_ki(pj, "nargs",
			rz_analysis_var_count(core->analysis, fcn, 'r', 1) +
				rz_analysis_var_count(core->analysis, fcn, 's', 1) +
				rz_analysis_var_count(core->analysis, fcn, 'b', 1));
		pj_ki(pj, "nlocals",
			rz_analysis_var_count(core->analysis, fcn, 'r', 0) +
				rz_analysis_var_count(core->analysis, fcn, 's', 0) +
				rz_analysis_var_count(core->analysis, fcn, 'b', 0));
		pj_kn(pj, "size", rz_analysis_function_linear_size(fcn));
		pj_ki(pj, "stack", fcn->maxstack);
		pj_ks(pj, "type", rz_analysis_fcntype_tostring(fcn->type));
		pj_k(pj, "blocks");
		pj_a(pj);
	}
	nodes += core_analysis_graph_construct_nodes(core, fcn, opts, pj, DB);
	nodes += core_analysis_graph_construct_edges(core, fcn, opts, pj, DB);
	if (is_json) {
		pj_end(pj);
		pj_end(pj);
	}
	free(pal_jump);
	free(pal_fail);
	free(pal_trfa);
	free(pal_curr);
	free(pal_traced);
	free(pal_box4);
	return nodes;
}
static int core_analysis_graph_nodes(RzCore *core, RzAnalysisFunction *fcn, int opts, PJ *pj) {
	rz_return_val_if_fail(fcn && fcn->bbs, -1);
	int is_json = opts & RZ_CORE_ANALYSIS_JSON;
	int is_keva = opts & RZ_CORE_ANALYSIS_KEYVALUE;
	int nodes = 0;
	Sdb *DB = NULL;
	char *pal_jump = palColorFor("graph.true");
	char *pal_fail = palColorFor("graph.false");
	char *pal_trfa = palColorFor("graph.ujump");
	char *pal_curr = palColorFor("graph.current");
	char *pal_traced = palColorFor("graph.traced");
	char *pal_box4 = palColorFor("graph.box4");

	if (is_keva) {
		char ns[64];
		DB = sdb_ns(core->analysis->sdb, "graph", 1);
		snprintf(ns, sizeof(ns), "fcn.0x%08" PFMT64x, fcn->addr);
		DB = sdb_ns(DB, ns, 1);
	}

	if (is_keva) {
		char *ename = sdb_encode((const ut8 *)fcn->name, -1);
		sdb_set(DB, "name", fcn->name, 0);
		sdb_set(DB, "ename", ename, 0);
		free(ename);
		sdb_num_set(DB, "size", rz_analysis_function_linear_size(fcn), 0);
		if (fcn->maxstack > 0) {
			sdb_num_set(DB, "stack", fcn->maxstack, 0);
		}
		sdb_set(DB, "pos", "0,0", 0);  
		sdb_set(DB, "type", rz_analysis_fcntype_tostring(fcn->type), 0);
	} else if (is_json) {
		 
		char *fcn_name_escaped = rz_str_escape_utf8_for_json(fcn->name, -1);
		pj_o(pj);
		pj_ks(pj, "name", rz_str_get_null(fcn_name_escaped));
		free(fcn_name_escaped);
		pj_kn(pj, "offset", fcn->addr);
		pj_ki(pj, "ninstr", fcn->ninstr);
		pj_ki(pj, "nargs",
			rz_analysis_var_count(core->analysis, fcn, 'r', 1) +
				rz_analysis_var_count(core->analysis, fcn, 's', 1) +
				rz_analysis_var_count(core->analysis, fcn, 'b', 1));
		pj_ki(pj, "nlocals",
			rz_analysis_var_count(core->analysis, fcn, 'r', 0) +
				rz_analysis_var_count(core->analysis, fcn, 's', 0) +
				rz_analysis_var_count(core->analysis, fcn, 'b', 0));
		pj_kn(pj, "size", rz_analysis_function_linear_size(fcn));
		pj_ki(pj, "stack", fcn->maxstack);
		pj_ks(pj, "type", rz_analysis_fcntype_tostring(fcn->type));
		pj_k(pj, "blocks");
		pj_a(pj);
	}
	nodes += core_analysis_graph_construct_nodes(core, fcn, opts, pj, DB);
	nodes += core_analysis_graph_construct_edges(core, fcn, opts, pj, DB);
	if (is_json) {
		pj_end(pj);
		pj_end(pj);
	}
	free(pal_jump);
	free(pal_fail);
	free(pal_trfa);
	free(pal_curr);
	free(pal_traced);
	free(pal_box4);
	return nodes;
}