UNPKG

@dcrackel/meyersquaredui

Version:

This template should help get you started developing with Vue 3 in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.

90 lines (70 loc) 2.78 kB
// utils/splitBracketByFinal.js import { roundIndex } from "../layout/roundOrder"; /** * Splits a DE bracket into left/right halves by finding the Final bout, * then taking the two semifinal subtrees feeding into it. */ export function splitBracketByFinal(bouts) { const byId = new Map(); const childrenByParent = new Map(); for (const b of bouts) { if (b?.DEBoutId != null) byId.set(b.DEBoutId, b); const fromId = b?.DEBoutId; const toId = b?.DENextBoutId; if (fromId == null || toId == null) continue; if (!childrenByParent.has(toId)) childrenByParent.set(toId, []); childrenByParent.get(toId).push(fromId); } const thirdPlaceBout = bouts.find(b => b?.RoundLabel === "Third Place") || null; // Prefer explicit "Final"; fallback to deepest round let finalBout = bouts.find(b => b?.RoundLabel === "Final") || [...bouts].sort((a, b) => roundIndex(b?.RoundLabel) - roundIndex(a?.RoundLabel))[0] || null; if (!finalBout || finalBout.DEBoutId == null) { return { leftBouts: bouts, rightBouts: [], finalBout: null, thirdPlaceBout }; } const finalId = finalBout.DEBoutId; const semis = (childrenByParent.get(finalId) || []) .map(id => byId.get(id)) .filter(Boolean); // If we can't find two semis (data weird), bail safely if (semis.length < 2) { return { leftBouts: bouts.filter(b => b?.RoundLabel !== "Third Place"), rightBouts: [], finalBout, thirdPlaceBout, }; } // Collect subtree for each semi by walking DOWN via childrenByParent function collectSubtree(rootId, acc) { const stack = [rootId]; const seen = new Set(); while (stack.length) { const id = stack.pop(); if (id == null || seen.has(id)) continue; seen.add(id); const bout = byId.get(id); if (bout) acc.push(bout); const kids = childrenByParent.get(id) || []; for (const k of kids) stack.push(k); } } const left = []; const right = []; // stable pick: top semi goes left, bottom semi goes right (by screen y if present later) const semiA = semis[0].DEBoutId; const semiB = semis[1].DEBoutId; collectSubtree(semiA, left); collectSubtree(semiB, right); // remove Final + Third Place from halves const strip = (arr) => arr.filter(b => b?.DEBoutId !== finalId && b?.RoundLabel !== "Third Place"); return { leftBouts: strip(left), rightBouts: strip(right), finalBout, thirdPlaceBout, }; }