static int core_analysis_graph_construct_edges(RzCore *core, RzAnalysisFunction *fcn, int opts, PJ *pj, Sdb *DB) {
	RzAnalysisBlock *bbi;
	RzListIter *iter;
	int is_keva = opts & RZ_CORE_ANALYSIS_KEYVALUE;
	int is_star = opts & RZ_CORE_ANALYSIS_STAR;
	int is_json = opts & RZ_CORE_ANALYSIS_JSON;
	int is_html = rz_cons_singleton()->is_html;
	char *pal_jump = palColorFor("graph.true");
	char *pal_fail = palColorFor("graph.false");
	char *pal_trfa = palColorFor("graph.ujump");
	int nodes = 0;
	rz_list_foreach (fcn->bbs, iter, bbi) {
		if (bbi->jump != UT64_MAX) {
			nodes++;
			if (is_keva) {
				char key[128];
				char val[128];
				snprintf(key, sizeof(key), "bb.0x%08" PFMT64x ".to", bbi->addr);
				if (bbi->fail != UT64_MAX) {
					snprintf(val, sizeof(val), "0x%08" PFMT64x, bbi->jump);
				} else {
					snprintf(val, sizeof(val), "0x%08" PFMT64x ",0x%08" PFMT64x,
						bbi->jump, bbi->fail);
				}
				// bb.<addr>.to=<jump>,<fail>
				sdb_set(DB, key, val, 0);
			} else if (is_html) {
				rz_cons_printf("<div class=\"connector _0x%08" PFMT64x " _0x%08" PFMT64x "\">\n"
					       "  <img class=\"connector-end\" src=\"img/arrow.gif\" /></div>\n",
					bbi->addr, bbi->jump);
			} else if (!is_json && !is_keva) {
				if (is_star) {
					char *from = get_title(bbi->addr);
					char *to = get_title(bbi->jump);
					rz_cons_printf("age %s %s\n", from, to);
					free(from);
					free(to);
				} else {
					rz_cons_printf("        \"0x%08" PFMT64x "\" -> \"0x%08" PFMT64x "\" "
						       "[color=\"%s\"];\n",
						bbi->addr, bbi->jump,
						bbi->fail != -1 ? pal_jump : pal_trfa);
					core_analysis_color_curr_node(core, bbi);
				}
			}
		}
		if (bbi->fail != -1) {
			nodes++;
			if (is_html) {
				rz_cons_printf("<div class=\"connector _0x%08" PFMT64x " _0x%08" PFMT64x "\">\n"
					       "  <img class=\"connector-end\" src=\"img/arrow.gif\"/></div>\n",
					bbi->addr, bbi->fail);
			} else if (!is_keva && !is_json) {
				if (is_star) {
					char *from = get_title(bbi->addr);
					char *to = get_title(bbi->fail);
					rz_cons_printf("age %s %s\n", from, to);
					free(from);
					free(to);
				} else {
					rz_cons_printf("        \"0x%08" PFMT64x "\" -> \"0x%08" PFMT64x "\" "
						       "[color=\"%s\"];\n",
						bbi->addr, bbi->fail, pal_fail);
					core_analysis_color_curr_node(core, bbi);
				}
			}
		}
		if (bbi->switch_op) {
			RzAnalysisCaseOp *caseop;
			RzListIter *iter;

			if (bbi->fail != UT64_MAX) {
				if (is_html) {
					rz_cons_printf("<div class=\"connector _0x%08" PFMT64x " _0x%08" PFMT64x "\">\n"
						       "  <img class=\"connector-end\" src=\"img/arrow.gif\"/></div>\n",
						bbi->addr, bbi->fail);
				} else if (!is_keva && !is_json) {
					if (is_star) {
						char *from = get_title(bbi->addr);
						char *to = get_title(bbi->fail);
						rz_cons_printf("age %s %s\n", from, to);
						free(from);
						free(to);
					} else {
						rz_cons_printf("        \"0x%08" PFMT64x "\" -> \"0x%08" PFMT64x "\" "
							       "[color=\"%s\"];\n",
							bbi->addr, bbi->fail, pal_fail);
						core_analysis_color_curr_node(core, bbi);
					}
				}
			}
			rz_list_foreach (bbi->switch_op->cases, iter, caseop) {
				nodes++;
				if (is_keva) {
					char key[128];
					snprintf(key, sizeof(key),
						"bb.0x%08" PFMT64x ".switch.%" PFMT64d,
						bbi->addr, caseop->value);
					sdb_num_set(DB, key, caseop->jump, 0);
					snprintf(key, sizeof(key),
						"bb.0x%08" PFMT64x ".switch", bbi->addr);
					sdb_array_add_num(DB, key, caseop->value, 0);
				} else if (is_html) {
					rz_cons_printf("<div class=\"connector _0x%08" PFMT64x " _0x%08" PFMT64x "\">\n"
						       "  <img class=\"connector-end\" src=\"img/arrow.gif\"/></div>\n",
						caseop->addr, caseop->jump);
				} else if (!is_json && !is_keva) {
					if (is_star) {
						char *from = get_title(caseop->addr);
						char *to = get_title(caseop->jump);
						rz_cons_printf("age %s %s\n", from, to);
						free(from);
						free(to);
					} else {
						rz_cons_printf("        \"0x%08" PFMT64x "\" -> \"0x%08" PFMT64x "\" "
							       "[color2=\"%s\"];\n",
							caseop->addr, caseop->jump, pal_fail);
						core_analysis_color_curr_node(core, bbi);
					}
				}
			}
		}
	}
	free(pal_jump);
	free(pal_fail);
	free(pal_trfa);
	return nodes;
}