1
0
mirror of https://gitlab.com/animath/si/plateforme.git synced 2024-12-25 17:42:24 +00:00

Reorder teams for 5-teams pools

Signed-off-by: Emmy D'Anello <emmy.danello@animath.fr>
This commit is contained in:
Emmy D'Anello 2023-03-25 07:54:53 +01:00
parent 3cd40ee192
commit 942c96dbfa
Signed by: ynerant
GPG Key ID: 3A75C55819C8CF85
4 changed files with 244 additions and 182 deletions

View File

@ -1,6 +1,6 @@
# Copyright (C) 2023 by Animath # Copyright (C) 2023 by Animath
# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-License-Identifier: GPL-3.0-or-later
from collections import OrderedDict
from random import randint from random import randint
from asgiref.sync import sync_to_async from asgiref.sync import sync_to_async
@ -436,6 +436,37 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
{'type': 'draw.box_visibility', 'visible': True}) {'type': 'draw.box_visibility', 'visible': True})
else: else:
# Pool is ended # Pool is ended
if pool.size == 5:
# Maybe reorder teams if the same problem is presented twice
problems = OrderedDict()
async for td in pool.team_draws:
problems.setdefault(td.accepted, [])
problems[td.accepted].append(td)
p_index = 0
for pb, tds in problems.items():
if len(tds) == 2:
tds[0].passage_index = p_index
tds[1].passage_index = p_index + 1
p_index += 2
await sync_to_async(tds[0].save)()
await sync_to_async(tds[1].save)()
for pb, tds in problems.items():
if len(tds) == 1:
tds[0].passage_index = p_index
p_index += 1
await sync_to_async(tds[0].save)()
print(p_index)
await self.channel_layer.group_send(f"tournament-{self.tournament.id}", {
'type': 'draw.reorder_pool',
'round': r.number,
'pool': pool.get_letter_display(),
'teams': [td.participation.team.trigram
async for td in pool.team_draws.prefetch_related('participation__team')],
'problems': [td.accepted async for td in pool.team_draws],
})
msg += f"<br><br>Le tirage de la poule {pool.get_letter_display()}{r.number} est terminé. " \ msg += f"<br><br>Le tirage de la poule {pool.get_letter_display()}{r.number} est terminé. " \
f"Le tableau récapitulatif est en bas." f"Le tableau récapitulatif est en bas."
self.tournament.draw.last_message = msg self.tournament.draw.last_message = msg
@ -451,7 +482,6 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
else: else:
# Round is ended # Round is ended
# TODO: For the final tournament, add some adjustments # TODO: For the final tournament, add some adjustments
# TODO: Make some adjustments for 5-teams-pools
if r.number == 1: if r.number == 1:
# Next round # Next round
r2 = await self.tournament.draw.round_set.filter(number=2).aget() r2 = await self.tournament.draw.round_set.filter(number=2).aget()
@ -583,3 +613,8 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
async def draw_reject_problem(self, content): async def draw_reject_problem(self, content):
await self.send_json({'type': 'reject_problem', 'round': content['round'], await self.send_json({'type': 'reject_problem', 'round': content['round'],
'team': content['team'], 'rejected': content['rejected']}) 'team': content['team'], 'rejected': content['rejected']})
async def draw_reorder_pool(self, content):
await self.send_json({'type': 'reorder_poule', 'round': content['round'],
'poule': content['pool'], 'teams': content['teams'],
'problems': content['problems']})

View File

@ -238,7 +238,7 @@ document.addEventListener('DOMContentLoaded', () => {
tablesRoundDiv = document.createElement('div') tablesRoundDiv = document.createElement('div')
tablesRoundDiv.id = `tables-${tournament.id}-round-${round}` tablesRoundDiv.id = `tables-${tournament.id}-round-${round}`
tablesRoundDiv.classList.add('card-body') tablesRoundDiv.classList.add('card-body', 'd-flex', 'flex-wrap')
card.append(tablesRoundDiv) card.append(tablesRoundDiv)
} }
@ -246,148 +246,153 @@ document.addEventListener('DOMContentLoaded', () => {
if (poule.teams.length === 0) if (poule.teams.length === 0)
continue continue
let pouleTable = document.getElementById(`table-${tournament.id}-${round}-${poule.letter}`) updatePouleTable(round, poule)
if (pouleTable === null) { }
// Create table }
let card = document.createElement('div') }
card.classList.add('card', 'my-3')
tablesRoundDiv.append(card)
let cardHeader = document.createElement('div') function updatePouleTable(round, poule) {
cardHeader.classList.add('card-header') let tablesRoundDiv = document.getElementById(`tables-${tournament.id}-round-${round}`)
cardHeader.innerHTML = `<h2>Poule ${poule.letter}</h2>` let pouleTable = document.getElementById(`table-${tournament.id}-${round}-${poule.letter}`)
card.append(cardHeader) if (pouleTable === null) {
// Create table
let card = document.createElement('div')
card.classList.add('card', 'w-100', 'my-3', `order-${poule.letter.charCodeAt(0) - 64}`)
tablesRoundDiv.append(card)
let cardBody = document.createElement('div') let cardHeader = document.createElement('div')
cardBody.classList.add('card-body') cardHeader.classList.add('card-header')
card.append(cardBody) cardHeader.innerHTML = `<h2>Poule ${poule.letter}${round}</h2>`
card.append(cardHeader)
pouleTable = document.createElement('table') let cardBody = document.createElement('div')
pouleTable.id = `table-${tournament.id}-${round}-${poule.letter}` cardBody.classList.add('card-body')
pouleTable.classList.add('table', 'table-stripped') card.append(cardBody)
cardBody.append(pouleTable)
let thead = document.createElement('thead') pouleTable = document.createElement('table')
pouleTable.append(thead) pouleTable.id = `table-${tournament.id}-${round}-${poule.letter}`
pouleTable.classList.add('table', 'table-stripped')
cardBody.append(pouleTable)
let phaseTr = document.createElement('tr') let thead = document.createElement('thead')
thead.append(phaseTr) pouleTable.append(thead)
let teamTh = document.createElement('th') let phaseTr = document.createElement('tr')
teamTh.classList.add('text-center') thead.append(phaseTr)
teamTh.rowSpan = poule.teams.length === 5 ? 3 : 2
teamTh.textContent = "Équipe"
phaseTr.append(teamTh)
for (let i = 1; i <= (poule.teams.length === 4 ? 4 : 3); ++i) { let teamTh = document.createElement('th')
let phaseTh = document.createElement('th') teamTh.classList.add('text-center')
phaseTh.classList.add('text-center') teamTh.rowSpan = poule.teams.length === 5 ? 3 : 2
if (poule.teams.length === 5 && i < 3) teamTh.textContent = "Équipe"
phaseTh.colSpan = 2 phaseTr.append(teamTh)
phaseTh.textContent = `Phase ${i}`
phaseTr.append(phaseTh) for (let i = 1; i <= (poule.teams.length === 4 ? 4 : 3); ++i) {
let phaseTh = document.createElement('th')
phaseTh.classList.add('text-center')
if (poule.teams.length === 5 && i < 3)
phaseTh.colSpan = 2
phaseTh.textContent = `Phase ${i}`
phaseTr.append(phaseTh)
}
if (poule.teams.length === 5) {
let roomTr = document.createElement('tr')
thead.append(roomTr)
for (let i = 0; i < 5; ++i) {
let roomTh = document.createElement('th')
roomTh.classList.add('text-center')
roomTh.textContent = `Salle ${1 + (i % 2)}`
roomTr.append(roomTh)
}
}
let problemTr = document.createElement('tr')
thead.append(problemTr)
for (let team of poule.teams) {
let problemTh = document.createElement('th')
problemTh.classList.add('text-center')
problemTh.innerHTML = `Pb. <span id="table-${tournament.id}-round-${round}-problem-${team}">?</span>`
problemTr.append(problemTh)
}
let tbody = document.createElement('tbody')
pouleTable.append(tbody)
for (let i = 0; i < poule.teams.length; ++i) {
let team = poule.teams[i]
let teamTr = document.createElement('tr')
tbody.append(teamTr)
let teamTd = document.createElement('td')
teamTd.classList.add('text-center')
teamTd.innerText = team
teamTr.append(teamTd)
let defenderTd = document.createElement('td')
defenderTd.classList.add('text-center')
defenderTd.innerText = 'Déf'
let opponentTd = document.createElement('td')
opponentTd.classList.add('text-center')
opponentTd.innerText = 'Opp'
let reporterTd = document.createElement('td')
reporterTd.classList.add('text-center')
reporterTd.innerText = 'Rap'
let emptyTd = document.createElement('td')
let emptyTd2 = document.createElement('td')
if (poule.teams.length === 3) {
switch (i) {
case 0:
teamTr.append(defenderTd, reporterTd, opponentTd)
break
case 1:
teamTr.append(opponentTd, defenderTd, reporterTd)
break
case 2:
teamTr.append(reporterTd, opponentTd, defenderTd)
break
} }
}
if (poule.teams.length === 5) { else if (poule.teams.length === 4) {
let roomTr = document.createElement('tr') switch (i) {
thead.append(roomTr) case 0:
teamTr.append(defenderTd, emptyTd, reporterTd, opponentTd)
for (let i = 0; i < 5; ++i) { break
let roomTh = document.createElement('th') case 1:
roomTh.classList.add('text-center') teamTr.append(opponentTd, defenderTd, emptyTd, reporterTd)
roomTh.textContent = `Salle ${1 + (i % 2)}` break
roomTr.append(roomTh) case 2:
} teamTr.append(reporterTd, opponentTd, defenderTd, emptyTd)
break
case 3:
teamTr.append(emptyTd, reporterTd, opponentTd, defenderTd)
break
} }
}
let problemTr = document.createElement('tr') else if (poule.teams.length === 5) {
thead.append(problemTr) switch (i) {
case 0:
for (let team of poule.teams) { teamTr.append(defenderTd, emptyTd, opponentTd, reporterTd, emptyTd2)
let problemTh = document.createElement('th') break
problemTh.classList.add('text-center') case 1:
problemTh.innerHTML = `Pb. <span id="table-${tournament.id}-round-${round}-problem-${team}">?</span>` teamTr.append(emptyTd, defenderTd, reporterTd, emptyTd2, opponentTd)
problemTr.append(problemTh) break
} case 2:
teamTr.append(opponentTd, emptyTd, defenderTd, emptyTd2, reporterTd)
let tbody = document.createElement('tbody') break
pouleTable.append(tbody) case 3:
teamTr.append(reporterTd, opponentTd, emptyTd, defenderTd, emptyTd2)
for (let i = 0; i < poule.teams.length; ++i) { break
let team = poule.teams[i] case 4:
teamTr.append(emptyTd, reporterTd, emptyTd2, opponentTd, defenderTd)
let teamTr = document.createElement('tr') break
tbody.append(teamTr)
let teamTd = document.createElement('td')
teamTd.classList.add('text-center')
teamTd.innerText = team
teamTr.append(teamTd)
let defenderTd = document.createElement('td')
defenderTd.classList.add('text-center')
defenderTd.innerText = 'Déf'
let opponentTd = document.createElement('td')
opponentTd.classList.add('text-center')
opponentTd.innerText = 'Opp'
let reporterTd = document.createElement('td')
reporterTd.classList.add('text-center')
reporterTd.innerText = 'Rap'
let emptyTd = document.createElement('td')
let emptyTd2 = document.createElement('td')
if (poule.teams.length === 3) {
switch (i) {
case 0:
teamTr.append(defenderTd, reporterTd, opponentTd)
break
case 1:
teamTr.append(opponentTd, defenderTd, reporterTd)
break
case 2:
teamTr.append(reporterTd, opponentTd, defenderTd)
break
}
}
else if (poule.teams.length === 4) {
switch (i) {
case 0:
teamTr.append(defenderTd, emptyTd, reporterTd, opponentTd)
break
case 1:
teamTr.append(opponentTd, defenderTd, emptyTd, reporterTd)
break
case 2:
teamTr.append(reporterTd, opponentTd, defenderTd, emptyTd)
break
case 3:
teamTr.append(emptyTd, reporterTd, opponentTd, defenderTd)
break
}
}
else if (poule.teams.length === 5) {
switch (i) {
case 0:
teamTr.append(defenderTd, emptyTd, opponentTd, reporterTd, emptyTd2)
break
case 1:
teamTr.append(emptyTd, defenderTd, reporterTd, emptyTd2, opponentTd)
break
case 2:
teamTr.append(opponentTd, emptyTd, defenderTd, emptyTd2, reporterTd)
break
case 3:
teamTr.append(reporterTd, opponentTd, emptyTd, defenderTd, emptyTd2)
break
case 4:
teamTr.append(emptyTd, reporterTd, emptyTd2, opponentTd, defenderTd)
break
}
}
} }
} }
} }
@ -442,6 +447,20 @@ document.addEventListener('DOMContentLoaded', () => {
} }
} }
function reorderPoule(round, poule, teams, problems) {
let table = document.getElementById(`table-${tournament.id}-${round}-${poule}`)
table.parentElement.parentElement.remove()
updatePouleTable(round, {'letter': poule, 'teams': teams})
for (let i = 0; i < teams.length; ++i) {
let team = teams[i]
let problem = problems[i]
setProblemAccepted(round, team, problem)
}
}
socket.addEventListener('message', e => { socket.addEventListener('message', e => {
const data = JSON.parse(e.data) const data = JSON.parse(e.data)
console.log(data) console.log(data)
@ -486,6 +505,9 @@ document.addEventListener('DOMContentLoaded', () => {
case 'reject_problem': case 'reject_problem':
setProblemRejected(data.round, data.team, data.rejected) setProblemRejected(data.round, data.team, data.rejected)
break break
case 'reorder_poule':
reorderPoule(data.round, data.poule, data.teams, data.problems)
break
} }
}) })

View File

@ -160,10 +160,10 @@
{{ round }} {{ round }}
</h2> </h2>
</div> </div>
<div id="tables-{{ tournament.id }}-round-{{ round.number }}" class="card-body"> <div id="tables-{{ tournament.id }}-round-{{ round.number }}" class="card-body d-flex flex-wrap">
{% for pool in round.pool_set.all %} {% for pool in round.pool_set.all %}
{% if pool.teamdraw_set.count %} {% if pool.teamdraw_set.count %}
<div class="card my-3"> <div class="card w-100 my-3 order-{{ pool.letter }}">
<div class="card-header"> <div class="card-header">
<h3> <h3>
{% trans "pool"|capfirst %} {{ pool }} {% trans "pool"|capfirst %} {{ pool }}

View File

@ -7,7 +7,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: TFJM\n" "Project-Id-Version: TFJM\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-03-24 12:29+0100\n" "POT-Creation-Date: 2023-03-25 07:20+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Emmy D'Anello <emmy.danello@animath.fr>\n" "Last-Translator: Emmy D'Anello <emmy.danello@animath.fr>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@ -25,53 +25,54 @@ msgstr "API"
msgid "Draw" msgid "Draw"
msgstr "Tirage au sort" msgstr "Tirage au sort"
#: draw/consumers.py:20 #: draw/consumers.py:21
msgid "You are not an organizer." msgid "You are not an organizer."
msgstr "Vous n'êtes pas un⋅e organisateur⋅rice." msgstr "Vous n'êtes pas un⋅e organisateur⋅rice."
#: draw/consumers.py:81 #: draw/consumers.py:91
msgid "Invalid format" msgid "Invalid format"
msgstr "Format invalide" msgstr "Format invalide"
#: draw/consumers.py:85 #: draw/consumers.py:95
#, python-brace-format #, python-brace-format
msgid "The sum must be equal to the number of teams: expected {len}, got {sum}" msgid "The sum must be equal to the number of teams: expected {len}, got {sum}"
msgstr "" msgstr ""
"La somme doit être égale au nombre d'équipes : attendu {len}, obtenu {sum}" "La somme doit être égale au nombre d'équipes : attendu {len}, obtenu {sum}"
#: draw/consumers.py:105 #: draw/consumers.py:121
msgid "Draw started!" msgid "Draw started!"
msgstr "Le tirage a commencé !" msgstr "Le tirage a commencé !"
#: draw/consumers.py:115 #: draw/consumers.py:131
#, python-brace-format #, python-brace-format
msgid "The draw for the tournament {tournament} will start." msgid "The draw for the tournament {tournament} will start."
msgstr "Le tirage au sort du tournoi {tournament} va commencer." msgstr "Le tirage au sort du tournoi {tournament} va commencer."
#: draw/consumers.py:121 #: draw/consumers.py:142
#, python-brace-format #, python-brace-format
msgid "The draw for the tournament {tournament} is aborted." msgid "The draw for the tournament {tournament} is aborted."
msgstr "Le tirage au sort du tournoi {tournament} est annulé." msgstr "Le tirage au sort du tournoi {tournament} est annulé."
#: draw/consumers.py:141 draw/consumers.py:144 #: draw/consumers.py:176 draw/consumers.py:179
msgid "You've already launched the dice." msgid "You've already launched the dice."
msgstr "Vous avez déjà lancé le dé." msgstr "Vous avez déjà lancé le dé."
#: draw/consumers.py:147 #: draw/consumers.py:182
msgid "It is not your turn." msgid "It is not your turn."
msgstr "Ce n'est pas votre tour." msgstr "Ce n'est pas votre tour."
#: draw/consumers.py:149 #: draw/consumers.py:184 draw/consumers.py:353 draw/consumers.py:392
#: draw/consumers.py:510
msgid "This is not the time for this." msgid "This is not the time for this."
msgstr "Ce n'est pas le moment pour cela." msgstr "Ce n'est pas le moment pour cela."
#: draw/consumers.py:182 draw/consumers.py:279 #: draw/consumers.py:217 draw/consumers.py:316
#, python-brace-format #, python-brace-format
msgid "Dices from teams {teams} are identical. Please relaunch your dices." msgid "Dices from teams {teams} are identical. Please relaunch your dices."
msgstr "" msgstr ""
"Les dés des équipes {teams} sont identiques. Merci de relancer vos dés." "Les dés des équipes {teams} sont identiques. Merci de relancer vos dés."
#: draw/consumers.py:216 #: draw/consumers.py:251
msgid "Two pools are identical. Please relaunch your dices." msgid "Two pools are identical. Please relaunch your dices."
msgstr "Deux poules sont identiques. Merci de relancer vos dés." msgstr "Deux poules sont identiques. Merci de relancer vos dés."
@ -88,98 +89,98 @@ msgstr "tour actuel"
msgid "last message" msgid "last message"
msgstr "dernier message" msgstr "dernier message"
#: draw/models.py:102 draw/models.py:110 #: draw/models.py:104 draw/models.py:112
msgid "draw" msgid "draw"
msgstr "tirage au sort" msgstr "tirage au sort"
#: draw/models.py:103 #: draw/models.py:105
msgid "draws" msgid "draws"
msgstr "tirages au sort" msgstr "tirages au sort"
#: draw/models.py:115 #: draw/models.py:117
msgid "Round 1" msgid "Round 1"
msgstr "Tour 1" msgstr "Tour 1"
#: draw/models.py:116 #: draw/models.py:118
msgid "Round 2" msgid "Round 2"
msgstr "Tour 2" msgstr "Tour 2"
#: draw/models.py:118 #: draw/models.py:120
msgid "number" msgid "number"
msgstr "numéro" msgstr "numéro"
#: draw/models.py:127 #: draw/models.py:129
msgid "current pool" msgid "current pool"
msgstr "poule actuelle" msgstr "poule actuelle"
#: draw/models.py:138 draw/models.py:199 participation/models.py:355 #: draw/models.py:144 draw/models.py:215 participation/models.py:355
msgid "round" msgid "round"
msgstr "tour" msgstr "tour"
#: draw/models.py:139 #: draw/models.py:145
msgid "rounds" msgid "rounds"
msgstr "tours" msgstr "tours"
#: draw/models.py:154 #: draw/models.py:160
msgid "letter" msgid "letter"
msgstr "lettre" msgstr "lettre"
#: draw/models.py:158 #: draw/models.py:164
#: participation/templates/participation/tournament_detail.html:15 #: participation/templates/participation/tournament_detail.html:15
msgid "size" msgid "size"
msgstr "taille" msgstr "taille"
#: draw/models.py:167 #: draw/models.py:173
msgid "current team" msgid "current team"
msgstr "équipe actuelle" msgstr "équipe actuelle"
#: draw/models.py:185 draw/models.py:207 #: draw/models.py:201 draw/models.py:223
#: draw/templates/draw/tournament_content.html:70 #: draw/templates/draw/tournament_content.html:70
#: draw/templates/draw/tournament_content.html:151 participation/models.py:407 #: draw/templates/draw/tournament_content.html:169 participation/models.py:407
#: participation/models.py:415 #: participation/models.py:415
msgid "pool" msgid "pool"
msgstr "poule" msgstr "poule"
#: draw/models.py:186 participation/models.py:408 #: draw/models.py:202 participation/models.py:408
msgid "pools" msgid "pools"
msgstr "poules" msgstr "poules"
#: draw/models.py:193 participation/models.py:342 participation/models.py:539 #: draw/models.py:209 participation/models.py:342 participation/models.py:539
#: participation/models.py:569 participation/models.py:607 #: participation/models.py:569 participation/models.py:607
msgid "participation" msgid "participation"
msgstr "participation" msgstr "participation"
#: draw/models.py:214 #: draw/models.py:230
msgid "passage index" msgid "passage index"
msgstr "numéro de passage" msgstr "numéro de passage"
#: draw/models.py:221 #: draw/models.py:237
msgid "choose index" msgid "choose index"
msgstr "numéro de choix" msgstr "numéro de choix"
#: draw/models.py:226 draw/models.py:242 participation/models.py:422 #: draw/models.py:242 draw/models.py:258 participation/models.py:422
#: participation/models.py:576 #: participation/models.py:576
#, python-brace-format #, python-brace-format
msgid "Problem #{problem}" msgid "Problem #{problem}"
msgstr "Problème n°{problem}" msgstr "Problème n°{problem}"
#: draw/models.py:230 draw/models.py:246 #: draw/models.py:246 draw/models.py:262
msgid "accepted problem" msgid "accepted problem"
msgstr "problème accepté" msgstr "problème accepté"
#: draw/models.py:237 #: draw/models.py:253
msgid "last dice" msgid "last dice"
msgstr "dernier dé" msgstr "dernier dé"
#: draw/models.py:251 #: draw/models.py:267
msgid "rejected problems" msgid "rejected problems"
msgstr "problèmes rejetés" msgstr "problèmes rejetés"
#: draw/models.py:258 #: draw/models.py:275
msgid "team draw" msgid "team draw"
msgstr "tirage d'équipe" msgstr "tirage d'équipe"
#: draw/models.py:259 #: draw/models.py:276
msgid "team draws" msgid "team draws"
msgstr "tirages d'équipe" msgstr "tirages d'équipe"
@ -203,28 +204,32 @@ msgstr "Derniers jets de dés"
msgid "Abort" msgid "Abort"
msgstr "Annuler" msgstr "Annuler"
#: draw/templates/draw/tournament_content.html:118 #: draw/templates/draw/tournament_content.html:119
msgid "Launch dice" msgid "Launch dice"
msgstr "Lancer le dé" msgstr "Lancer le dé"
#: draw/templates/draw/tournament_content.html:125 #: draw/templates/draw/tournament_content.html:132
msgid "Draw a problem"
msgstr "Tirer un problème"
#: draw/templates/draw/tournament_content.html:142
msgid "Accept" msgid "Accept"
msgstr "Accepter" msgstr "Accepter"
#: draw/templates/draw/tournament_content.html:128 #: draw/templates/draw/tournament_content.html:145
msgid "Decline" msgid "Decline"
msgstr "Refuser" msgstr "Refuser"
#: draw/templates/draw/tournament_content.html:158 participation/models.py:125 #: draw/templates/draw/tournament_content.html:176 participation/models.py:125
#: participation/models.py:310 registration/models.py:127 #: participation/models.py:310 registration/models.py:127
msgid "team" msgid "team"
msgstr "équipe" msgstr "équipe"
#: draw/templates/draw/tournament_content.html:168 #: draw/templates/draw/tournament_content.html:186
#: draw/templates/draw/tournament_content.html:169 #: draw/templates/draw/tournament_content.html:187
#: draw/templates/draw/tournament_content.html:170 #: draw/templates/draw/tournament_content.html:188
#: draw/templates/draw/tournament_content.html:171 #: draw/templates/draw/tournament_content.html:189
#: draw/templates/draw/tournament_content.html:172 #: draw/templates/draw/tournament_content.html:190
msgid "Room" msgid "Room"
msgstr "Salle" msgstr "Salle"